diff options
author | kleines Filmröllchen <filmroellchen@serenityos.org> | 2022-03-24 13:30:52 +0100 |
---|---|---|
committer | Andreas Kling <kling@serenityos.org> | 2022-04-03 12:21:05 +0200 |
commit | 7af87e8e6ba5fee7fe486cf97f9a5e8d40b3d483 (patch) | |
tree | e27d982658bbcd1212f92e3f4aec3f15a1cdf9be | |
parent | 452bbcaa84b364cb76e99c46950ad2bedf0ca7be (diff) | |
download | serenity-7af87e8e6ba5fee7fe486cf97f9a5e8d40b3d483.zip |
SystemMonitor: Move process window to GML
Extra stuff done in this commit to facilitate the above (if you want to
really push my commit count, ask for more atomicisation):
- Register a bunch of widgets that are used in the process window.
- Allow setting the pid after the fact for the process state widget.
13 files changed, 181 insertions, 64 deletions
diff --git a/Userland/Applications/SystemMonitor/CMakeLists.txt b/Userland/Applications/SystemMonitor/CMakeLists.txt index 30c42dab12..6a2c192997 100644 --- a/Userland/Applications/SystemMonitor/CMakeLists.txt +++ b/Userland/Applications/SystemMonitor/CMakeLists.txt @@ -5,6 +5,7 @@ serenity_component( ) compile_gml(SystemMonitor.gml SystemMonitorGML.h system_monitor_gml) +compile_gml(ProcessWindow.gml ProcessWindowGML.h process_window_gml) set(SOURCES GraphWidget.cpp @@ -18,6 +19,7 @@ set(SOURCES ProcessStateWidget.cpp ThreadStackWidget.cpp SystemMonitorGML.h + ProcessWindowGML.h ) serenity_app(SystemMonitor ICON app-system-monitor) diff --git a/Userland/Applications/SystemMonitor/ProcessFileDescriptorMapWidget.cpp b/Userland/Applications/SystemMonitor/ProcessFileDescriptorMapWidget.cpp index 9607dd9623..4131632763 100644 --- a/Userland/Applications/SystemMonitor/ProcessFileDescriptorMapWidget.cpp +++ b/Userland/Applications/SystemMonitor/ProcessFileDescriptorMapWidget.cpp @@ -11,6 +11,10 @@ #include <LibGUI/SortingProxyModel.h> #include <LibGUI/TableView.h> +REGISTER_WIDGET(SystemMonitor, ProcessFileDescriptorMapWidget) + +namespace SystemMonitor { + ProcessFileDescriptorMapWidget::ProcessFileDescriptorMapWidget() { set_layout<GUI::VerticalBoxLayout>(); @@ -49,3 +53,5 @@ void ProcessFileDescriptorMapWidget::set_pid(pid_t pid) m_pid = pid; m_model->set_json_path(String::formatted("/proc/{}/fds", m_pid)); } + +} diff --git a/Userland/Applications/SystemMonitor/ProcessFileDescriptorMapWidget.h b/Userland/Applications/SystemMonitor/ProcessFileDescriptorMapWidget.h index 001766b6d5..05165434ea 100644 --- a/Userland/Applications/SystemMonitor/ProcessFileDescriptorMapWidget.h +++ b/Userland/Applications/SystemMonitor/ProcessFileDescriptorMapWidget.h @@ -9,6 +9,8 @@ #include <LibGUI/Widget.h> +namespace SystemMonitor { + class ProcessFileDescriptorMapWidget final : public GUI::Widget { C_OBJECT(ProcessFileDescriptorMapWidget); @@ -24,3 +26,5 @@ private: RefPtr<GUI::JsonArrayModel> m_model; pid_t m_pid { -1 }; }; + +} diff --git a/Userland/Applications/SystemMonitor/ProcessMemoryMapWidget.cpp b/Userland/Applications/SystemMonitor/ProcessMemoryMapWidget.cpp index 5216c90a4a..f25c17cf98 100644 --- a/Userland/Applications/SystemMonitor/ProcessMemoryMapWidget.cpp +++ b/Userland/Applications/SystemMonitor/ProcessMemoryMapWidget.cpp @@ -14,6 +14,10 @@ #include <LibGUI/TableView.h> #include <LibGfx/Palette.h> +REGISTER_WIDGET(SystemMonitor, ProcessMemoryMapWidget) + +namespace SystemMonitor { + class PagemapPaintingDelegate final : public GUI::TableCellPaintingDelegate { public: virtual ~PagemapPaintingDelegate() override = default; @@ -121,3 +125,5 @@ void ProcessMemoryMapWidget::refresh() if (m_pid != -1) m_json_model->invalidate(); } + +} diff --git a/Userland/Applications/SystemMonitor/ProcessMemoryMapWidget.h b/Userland/Applications/SystemMonitor/ProcessMemoryMapWidget.h index b710a0b89a..0b97d0d819 100644 --- a/Userland/Applications/SystemMonitor/ProcessMemoryMapWidget.h +++ b/Userland/Applications/SystemMonitor/ProcessMemoryMapWidget.h @@ -9,6 +9,8 @@ #include <LibGUI/Widget.h> +namespace SystemMonitor { + class ProcessMemoryMapWidget final : public GUI::Widget { C_OBJECT(ProcessMemoryMapWidget); @@ -25,3 +27,5 @@ private: pid_t m_pid { -1 }; RefPtr<Core::Timer> m_timer; }; + +} diff --git a/Userland/Applications/SystemMonitor/ProcessStateWidget.cpp b/Userland/Applications/SystemMonitor/ProcessStateWidget.cpp index 41f20aa08d..10684b241a 100644 --- a/Userland/Applications/SystemMonitor/ProcessStateWidget.cpp +++ b/Userland/Applications/SystemMonitor/ProcessStateWidget.cpp @@ -12,9 +12,14 @@ #include <LibGUI/HeaderView.h> #include <LibGUI/Painter.h> #include <LibGUI/TableView.h> +#include <LibGUI/Widget.h> #include <LibGfx/FontDatabase.h> #include <LibGfx/Palette.h> +REGISTER_WIDGET(SystemMonitor, ProcessStateWidget) + +namespace SystemMonitor { + class ProcessStateModel final : public GUI::Model , public GUI::ModelClient { @@ -75,18 +80,33 @@ public: did_update(GUI::Model::UpdateFlag::DontInvalidateIndices); } + void set_pid(pid_t pid) + { + m_pid = pid; + refresh(); + } + pid_t pid() const { return m_pid; } + private: ProcessModel& m_target; GUI::ModelIndex m_target_index; pid_t m_pid { -1 }; }; -ProcessStateWidget::ProcessStateWidget(pid_t pid) +ProcessStateWidget::ProcessStateWidget() { set_layout<GUI::VerticalBoxLayout>(); layout()->set_margins(4); m_table_view = add<GUI::TableView>(); - m_table_view->set_model(adopt_ref(*new ProcessStateModel(ProcessModel::the(), pid))); + m_table_view->set_model(adopt_ref(*new ProcessStateModel(ProcessModel::the(), 0))); m_table_view->column_header().set_visible(false); m_table_view->column_header().set_section_size(0, 90); } + +void ProcessStateWidget::set_pid(pid_t pid) +{ + static_cast<ProcessStateModel*>(m_table_view->model())->set_pid(pid); + update(); +} + +} diff --git a/Userland/Applications/SystemMonitor/ProcessStateWidget.h b/Userland/Applications/SystemMonitor/ProcessStateWidget.h index a2fd3e7bd7..0c90b5996a 100644 --- a/Userland/Applications/SystemMonitor/ProcessStateWidget.h +++ b/Userland/Applications/SystemMonitor/ProcessStateWidget.h @@ -9,13 +9,19 @@ #include <LibGUI/Widget.h> +namespace SystemMonitor { + class ProcessStateWidget final : public GUI::Widget { C_OBJECT(ProcessStateWidget); public: virtual ~ProcessStateWidget() override = default; + void set_pid(pid_t); + private: - explicit ProcessStateWidget(pid_t); + ProcessStateWidget(); RefPtr<GUI::TableView> m_table_view; }; + +} diff --git a/Userland/Applications/SystemMonitor/ProcessUnveiledPathsWidget.cpp b/Userland/Applications/SystemMonitor/ProcessUnveiledPathsWidget.cpp index 4678192477..ba5a5c5187 100644 --- a/Userland/Applications/SystemMonitor/ProcessUnveiledPathsWidget.cpp +++ b/Userland/Applications/SystemMonitor/ProcessUnveiledPathsWidget.cpp @@ -10,6 +10,11 @@ #include <LibGUI/JsonArrayModel.h> #include <LibGUI/SortingProxyModel.h> #include <LibGUI/TableView.h> +#include <LibGUI/Widget.h> + +REGISTER_WIDGET(SystemMonitor, ProcessUnveiledPathsWidget) + +namespace SystemMonitor { ProcessUnveiledPathsWidget::ProcessUnveiledPathsWidget() { @@ -32,3 +37,5 @@ void ProcessUnveiledPathsWidget::set_pid(pid_t pid) m_pid = pid; m_model->set_json_path(String::formatted("/proc/{}/unveil", m_pid)); } + +} diff --git a/Userland/Applications/SystemMonitor/ProcessUnveiledPathsWidget.h b/Userland/Applications/SystemMonitor/ProcessUnveiledPathsWidget.h index eec1f4a332..7617af2568 100644 --- a/Userland/Applications/SystemMonitor/ProcessUnveiledPathsWidget.h +++ b/Userland/Applications/SystemMonitor/ProcessUnveiledPathsWidget.h @@ -9,6 +9,8 @@ #include <LibGUI/Widget.h> +namespace SystemMonitor { + class ProcessUnveiledPathsWidget final : public GUI::Widget { C_OBJECT(ProcessUnveiledPathsWidget); @@ -24,3 +26,5 @@ private: RefPtr<GUI::JsonArrayModel> m_model; pid_t m_pid { -1 }; }; + +} diff --git a/Userland/Applications/SystemMonitor/ProcessWindow.gml b/Userland/Applications/SystemMonitor/ProcessWindow.gml new file mode 100644 index 0000000000..4a1a6a1e6d --- /dev/null +++ b/Userland/Applications/SystemMonitor/ProcessWindow.gml @@ -0,0 +1,65 @@ +@GUI::Widget { + fill_with_background_color: true + layout: @GUI::VerticalBoxLayout {} + + @GUI::Widget { + shrink_to_fit: true + layout: @GUI::HorizontalBoxLayout { + margins: [4] + spacing: 8 + } + + @GUI::Label { + name: "icon_label" + fixed_size: [32, 32] + } + + @GUI::Label { + name: "process_name" + font_weight: "Bold" + text_alignment: "CenterLeft" + text: "This is the process name." + } + } + + @GUI::HorizontalSeparator { + fixed_height: 2 + } + + @GUI::StackWidget { + name: "widget_stack" + + @SystemMonitor::UnavailableProcessWidget { + name: "unavailable_process" + } + + @GUI::TabWidget { + name: "available_process" + + @SystemMonitor::ProcessStateWidget { + name: "process_state" + title: "State" + } + + @SystemMonitor::ProcessMemoryMapWidget { + name: "memory_map" + title: "Memory map" + } + + @SystemMonitor::ProcessFileDescriptorMapWidget { + name: "open_files" + title: "Open files" + } + + @SystemMonitor::ProcessUnveiledPathsWidget { + name: "unveiled_paths" + title: "Unveiled paths" + } + + @SystemMonitor::ThreadStackWidget { + name: "thread_stack" + title: "Stack" + } + } + } +} diff --git a/Userland/Applications/SystemMonitor/ThreadStackWidget.cpp b/Userland/Applications/SystemMonitor/ThreadStackWidget.cpp index d63d7660ee..998cb50868 100644 --- a/Userland/Applications/SystemMonitor/ThreadStackWidget.cpp +++ b/Userland/Applications/SystemMonitor/ThreadStackWidget.cpp @@ -9,9 +9,14 @@ #include <LibCore/Timer.h> #include <LibGUI/BoxLayout.h> #include <LibGUI/Model.h> +#include <LibGUI/Widget.h> #include <LibSymbolication/Symbolication.h> #include <LibThreading/BackgroundAction.h> +REGISTER_WIDGET(SystemMonitor, ThreadStackWidget) + +namespace SystemMonitor { + class ThreadStackModel final : public GUI::Model { enum Column { @@ -127,3 +132,5 @@ void ThreadStackWidget::custom_event(Core::CustomEvent& event) auto& completion_event = verify_cast<CompletionEvent>(event); verify_cast<ThreadStackModel>(m_stack_table->model())->set_symbols(completion_event.symbols()); } + +} diff --git a/Userland/Applications/SystemMonitor/ThreadStackWidget.h b/Userland/Applications/SystemMonitor/ThreadStackWidget.h index 25756a1821..75bf61fa8a 100644 --- a/Userland/Applications/SystemMonitor/ThreadStackWidget.h +++ b/Userland/Applications/SystemMonitor/ThreadStackWidget.h @@ -10,6 +10,8 @@ #include <LibGUI/TableView.h> #include <LibGUI/Widget.h> +namespace SystemMonitor { + class ThreadStackWidget final : public GUI::Widget { C_OBJECT(ThreadStackWidget) public: @@ -30,3 +32,5 @@ private: RefPtr<GUI::TableView> m_stack_table; RefPtr<Core::Timer> m_timer; }; + +} diff --git a/Userland/Applications/SystemMonitor/main.cpp b/Userland/Applications/SystemMonitor/main.cpp index 68c46550ea..59af7b682f 100644 --- a/Userland/Applications/SystemMonitor/main.cpp +++ b/Userland/Applications/SystemMonitor/main.cpp @@ -7,6 +7,7 @@ */ #include "GraphWidget.h" +#include "LibCore/EventLoop.h" #include "LibCore/Object.h" #include "MemoryStatsWidget.h" #include "NetworkStatisticsWidget.h" @@ -17,6 +18,7 @@ #include "ProcessUnveiledPathsWidget.h" #include "ThreadStackWidget.h" #include <AK/NumberFormat.h> +#include <Applications/SystemMonitor/ProcessWindowGML.h> #include <Applications/SystemMonitor/SystemMonitorGML.h> #include <LibConfig/Client.h> #include <LibCore/ArgsParser.h> @@ -60,18 +62,42 @@ static void build_performance_tab(GUI::Widget&); static RefPtr<GUI::Statusbar> statusbar; +namespace SystemMonitor { + +class ProgressbarPaintingDelegate final : public GUI::TableCellPaintingDelegate { +public: + virtual ~ProgressbarPaintingDelegate() override = default; + + virtual void paint(GUI::Painter& painter, Gfx::IntRect const& a_rect, Palette const& palette, GUI::ModelIndex const& index) override + { + auto rect = a_rect.shrunken(2, 2); + auto percentage = index.data(GUI::ModelRole::Custom).to_i32(); + + auto data = index.data(); + String text; + if (data.is_string()) + text = data.as_string(); + Gfx::StylePainter::paint_progressbar(painter, rect, palette, 0, 100, percentage, text); + painter.draw_rect(rect, Color::Black); + } +}; + class UnavailableProcessWidget final : public GUI::Frame { C_OBJECT(UnavailableProcessWidget) public: virtual ~UnavailableProcessWidget() override = default; String const& text() const { return m_text; } - void set_text(String text) { m_text = move(text); } + void set_text(String text) + { + m_text = move(text); + update(); + } private: - UnavailableProcessWidget(String text) - : m_text(move(text)) + UnavailableProcessWidget() { + REGISTER_STRING_PROPERTY("text", text, set_text); } virtual void paint_event(GUI::PaintEvent& event) override @@ -87,10 +113,6 @@ private: String m_text; }; -class ProgressbarPaintingDelegate; - -namespace SystemMonitor { - class HardwareTabWidget final : public GUI::LazyWidget { C_OBJECT(HardwareTabWidget) @@ -287,6 +309,7 @@ public: REGISTER_WIDGET(SystemMonitor, HardwareTabWidget) REGISTER_WIDGET(SystemMonitor, StorageTabWidget) +REGISTER_WIDGET(SystemMonitor, UnavailableProcessWidget) static bool can_access_pid(pid_t pid) { @@ -308,7 +331,7 @@ ErrorOr<int> serenity_main(Main::Arguments arguments) TRY(Core::System::pledge("stdio thread proc recvfd sendfd rpath exec unix")); - auto app = TRY(GUI::Application::try_create(arguments)); + auto app = TRY(GUI::Application::try_create(arguments, Core::EventLoop::MakeInspectable::Yes)); Config::pledge_domain("SystemMonitor"); @@ -564,24 +587,6 @@ ErrorOr<int> serenity_main(Main::Arguments arguments) return app->exec(); } -class ProgressbarPaintingDelegate final : public GUI::TableCellPaintingDelegate { -public: - virtual ~ProgressbarPaintingDelegate() override = default; - - virtual void paint(GUI::Painter& painter, Gfx::IntRect const& a_rect, Palette const& palette, const GUI::ModelIndex& index) override - { - auto rect = a_rect.shrunken(2, 2); - auto percentage = index.data(GUI::ModelRole::Custom).to_i32(); - - auto data = index.data(); - String text; - if (data.is_string()) - text = data.as_string(); - Gfx::StylePainter::paint_progressbar(painter, rect, palette, 0, 100, percentage, text); - painter.draw_rect(rect, Color::Black); - } -}; - ErrorOr<NonnullRefPtr<GUI::Window>> build_process_window(pid_t pid) { auto window = GUI::Window::construct(); @@ -592,17 +597,7 @@ ErrorOr<NonnullRefPtr<GUI::Window>> build_process_window(pid_t pid) window->set_icon(app_icon.bitmap_for_size(16)); auto main_widget = TRY(window->try_set_main_widget<GUI::Widget>()); - main_widget->set_fill_with_background_color(true); - main_widget->set_layout<GUI::VerticalBoxLayout>(); - - auto& hero_container = main_widget->add<GUI::Widget>(); - hero_container.set_shrink_to_fit(true); - hero_container.set_layout<GUI::HorizontalBoxLayout>(); - hero_container.layout()->set_margins(4); - hero_container.layout()->set_spacing(8); - - auto& icon_label = hero_container.add<GUI::Label>(); - icon_label.set_fixed_size(32, 32); + main_widget->load_from_gml(process_window_gml); GUI::ModelIndex process_index; for (int row = 0; row < ProcessModel::the().row_count({}); ++row) { @@ -615,36 +610,23 @@ ErrorOr<NonnullRefPtr<GUI::Window>> build_process_window(pid_t pid) VERIFY(process_index.is_valid()); if (auto icon_data = process_index.sibling_at_column(ProcessModel::Column::Icon).data(); icon_data.is_icon()) { - icon_label.set_icon(icon_data.as_icon().bitmap_for_size(32)); + main_widget->find_descendant_of_type_named<GUI::Label>("icon_label")->set_icon(icon_data.as_icon().bitmap_for_size(32)); } - auto& process_name_label = hero_container.add<GUI::Label>(); - process_name_label.set_font(Gfx::FontDatabase::default_font().bold_variant()); - process_name_label.set_text_alignment(Gfx::TextAlignment::CenterLeft); - process_name_label.set_text(String::formatted("{} (PID {})", - process_index.sibling_at_column(ProcessModel::Column::Name).data().to_string(), - pid)); - - auto& separator = main_widget->add<GUI::HorizontalSeparator>(); - separator.set_fixed_height(2); - - auto& widget_stack = main_widget->add<GUI::StackWidget>(); - auto& unavailable_process_widget = widget_stack.add<UnavailableProcessWidget>(String::formatted("Unable to access PID {}", pid)); + main_widget->find_descendant_of_type_named<GUI::Label>("process_name")->set_text(String::formatted("{} (PID {})", process_index.sibling_at_column(ProcessModel::Column::Name).data().to_string(), pid)); - auto& process_tab_widget = widget_stack.add<GUI::TabWidget>(); - process_tab_widget.add_tab<ProcessStateWidget>("State", pid); - auto& memory_map_widget = process_tab_widget.add_tab<ProcessMemoryMapWidget>("Memory map"); - auto& open_files_widget = process_tab_widget.add_tab<ProcessFileDescriptorMapWidget>("Open files"); - auto& unveiled_paths_widget = process_tab_widget.add_tab<ProcessUnveiledPathsWidget>("Unveiled paths"); - auto& thread_stack_widget = process_tab_widget.add_tab<ThreadStackWidget>("Stack"); + main_widget->find_descendant_of_type_named<SystemMonitor::ProcessStateWidget>("process_state")->set_pid(pid); + main_widget->find_descendant_of_type_named<SystemMonitor::ProcessFileDescriptorMapWidget>("open_files")->set_pid(pid); + main_widget->find_descendant_of_type_named<SystemMonitor::ThreadStackWidget>("thread_stack")->set_ids(pid, pid); + main_widget->find_descendant_of_type_named<SystemMonitor::ProcessMemoryMapWidget>("memory_map")->set_pid(pid); + main_widget->find_descendant_of_type_named<SystemMonitor::ProcessUnveiledPathsWidget>("unveiled_paths")->set_pid(pid); - 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); + auto& widget_stack = *main_widget->find_descendant_of_type_named<GUI::StackWidget>("widget_stack"); + auto& unavailable_process_widget = *widget_stack.find_descendant_of_type_named<SystemMonitor::UnavailableProcessWidget>("unavailable_process"); + unavailable_process_widget.set_text(String::formatted("Unable to access PID {}", pid)); if (can_access_pid(pid)) - widget_stack.set_active_widget(&process_tab_widget); + widget_stack.set_active_widget(widget_stack.find_descendant_of_type_named<GUI::TabWidget>("available_process")); else widget_stack.set_active_widget(&unavailable_process_widget); |