Ver Fonte

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.
kleines Filmröllchen há 3 anos atrás
pai
commit
7af87e8e6b

+ 2 - 0
Userland/Applications/SystemMonitor/CMakeLists.txt

@@ -5,6 +5,7 @@ serenity_component(
 )
 )
 
 
 compile_gml(SystemMonitor.gml SystemMonitorGML.h system_monitor_gml)
 compile_gml(SystemMonitor.gml SystemMonitorGML.h system_monitor_gml)
+compile_gml(ProcessWindow.gml ProcessWindowGML.h process_window_gml)
 
 
 set(SOURCES
 set(SOURCES
     GraphWidget.cpp
     GraphWidget.cpp
@@ -18,6 +19,7 @@ set(SOURCES
     ProcessStateWidget.cpp
     ProcessStateWidget.cpp
     ThreadStackWidget.cpp
     ThreadStackWidget.cpp
     SystemMonitorGML.h
     SystemMonitorGML.h
+    ProcessWindowGML.h
 )
 )
 
 
 serenity_app(SystemMonitor ICON app-system-monitor)
 serenity_app(SystemMonitor ICON app-system-monitor)

+ 6 - 0
Userland/Applications/SystemMonitor/ProcessFileDescriptorMapWidget.cpp

@@ -11,6 +11,10 @@
 #include <LibGUI/SortingProxyModel.h>
 #include <LibGUI/SortingProxyModel.h>
 #include <LibGUI/TableView.h>
 #include <LibGUI/TableView.h>
 
 
+REGISTER_WIDGET(SystemMonitor, ProcessFileDescriptorMapWidget)
+
+namespace SystemMonitor {
+
 ProcessFileDescriptorMapWidget::ProcessFileDescriptorMapWidget()
 ProcessFileDescriptorMapWidget::ProcessFileDescriptorMapWidget()
 {
 {
     set_layout<GUI::VerticalBoxLayout>();
     set_layout<GUI::VerticalBoxLayout>();
@@ -49,3 +53,5 @@ void ProcessFileDescriptorMapWidget::set_pid(pid_t pid)
     m_pid = pid;
     m_pid = pid;
     m_model->set_json_path(String::formatted("/proc/{}/fds", m_pid));
     m_model->set_json_path(String::formatted("/proc/{}/fds", m_pid));
 }
 }
+
+}

+ 4 - 0
Userland/Applications/SystemMonitor/ProcessFileDescriptorMapWidget.h

@@ -9,6 +9,8 @@
 
 
 #include <LibGUI/Widget.h>
 #include <LibGUI/Widget.h>
 
 
+namespace SystemMonitor {
+
 class ProcessFileDescriptorMapWidget final : public GUI::Widget {
 class ProcessFileDescriptorMapWidget final : public GUI::Widget {
     C_OBJECT(ProcessFileDescriptorMapWidget);
     C_OBJECT(ProcessFileDescriptorMapWidget);
 
 
@@ -24,3 +26,5 @@ private:
     RefPtr<GUI::JsonArrayModel> m_model;
     RefPtr<GUI::JsonArrayModel> m_model;
     pid_t m_pid { -1 };
     pid_t m_pid { -1 };
 };
 };
+
+}

+ 6 - 0
Userland/Applications/SystemMonitor/ProcessMemoryMapWidget.cpp

@@ -14,6 +14,10 @@
 #include <LibGUI/TableView.h>
 #include <LibGUI/TableView.h>
 #include <LibGfx/Palette.h>
 #include <LibGfx/Palette.h>
 
 
+REGISTER_WIDGET(SystemMonitor, ProcessMemoryMapWidget)
+
+namespace SystemMonitor {
+
 class PagemapPaintingDelegate final : public GUI::TableCellPaintingDelegate {
 class PagemapPaintingDelegate final : public GUI::TableCellPaintingDelegate {
 public:
 public:
     virtual ~PagemapPaintingDelegate() override = default;
     virtual ~PagemapPaintingDelegate() override = default;
@@ -121,3 +125,5 @@ void ProcessMemoryMapWidget::refresh()
     if (m_pid != -1)
     if (m_pid != -1)
         m_json_model->invalidate();
         m_json_model->invalidate();
 }
 }
+
+}

+ 4 - 0
Userland/Applications/SystemMonitor/ProcessMemoryMapWidget.h

@@ -9,6 +9,8 @@
 
 
 #include <LibGUI/Widget.h>
 #include <LibGUI/Widget.h>
 
 
+namespace SystemMonitor {
+
 class ProcessMemoryMapWidget final : public GUI::Widget {
 class ProcessMemoryMapWidget final : public GUI::Widget {
     C_OBJECT(ProcessMemoryMapWidget);
     C_OBJECT(ProcessMemoryMapWidget);
 
 
@@ -25,3 +27,5 @@ private:
     pid_t m_pid { -1 };
     pid_t m_pid { -1 };
     RefPtr<Core::Timer> m_timer;
     RefPtr<Core::Timer> m_timer;
 };
 };
+
+}

+ 22 - 2
Userland/Applications/SystemMonitor/ProcessStateWidget.cpp

@@ -12,9 +12,14 @@
 #include <LibGUI/HeaderView.h>
 #include <LibGUI/HeaderView.h>
 #include <LibGUI/Painter.h>
 #include <LibGUI/Painter.h>
 #include <LibGUI/TableView.h>
 #include <LibGUI/TableView.h>
+#include <LibGUI/Widget.h>
 #include <LibGfx/FontDatabase.h>
 #include <LibGfx/FontDatabase.h>
 #include <LibGfx/Palette.h>
 #include <LibGfx/Palette.h>
 
 
+REGISTER_WIDGET(SystemMonitor, ProcessStateWidget)
+
+namespace SystemMonitor {
+
 class ProcessStateModel final
 class ProcessStateModel final
     : public GUI::Model
     : public GUI::Model
     , public GUI::ModelClient {
     , public GUI::ModelClient {
@@ -75,18 +80,33 @@ public:
         did_update(GUI::Model::UpdateFlag::DontInvalidateIndices);
         did_update(GUI::Model::UpdateFlag::DontInvalidateIndices);
     }
     }
 
 
+    void set_pid(pid_t pid)
+    {
+        m_pid = pid;
+        refresh();
+    }
+    pid_t pid() const { return m_pid; }
+
 private:
 private:
     ProcessModel& m_target;
     ProcessModel& m_target;
     GUI::ModelIndex m_target_index;
     GUI::ModelIndex m_target_index;
     pid_t m_pid { -1 };
     pid_t m_pid { -1 };
 };
 };
 
 
-ProcessStateWidget::ProcessStateWidget(pid_t pid)
+ProcessStateWidget::ProcessStateWidget()
 {
 {
     set_layout<GUI::VerticalBoxLayout>();
     set_layout<GUI::VerticalBoxLayout>();
     layout()->set_margins(4);
     layout()->set_margins(4);
     m_table_view = add<GUI::TableView>();
     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_visible(false);
     m_table_view->column_header().set_section_size(0, 90);
     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();
+}
+
+}

+ 7 - 1
Userland/Applications/SystemMonitor/ProcessStateWidget.h

@@ -9,13 +9,19 @@
 
 
 #include <LibGUI/Widget.h>
 #include <LibGUI/Widget.h>
 
 
+namespace SystemMonitor {
+
 class ProcessStateWidget final : public GUI::Widget {
 class ProcessStateWidget final : public GUI::Widget {
     C_OBJECT(ProcessStateWidget);
     C_OBJECT(ProcessStateWidget);
 
 
 public:
 public:
     virtual ~ProcessStateWidget() override = default;
     virtual ~ProcessStateWidget() override = default;
 
 
+    void set_pid(pid_t);
+
 private:
 private:
-    explicit ProcessStateWidget(pid_t);
+    ProcessStateWidget();
     RefPtr<GUI::TableView> m_table_view;
     RefPtr<GUI::TableView> m_table_view;
 };
 };
+
+}

+ 7 - 0
Userland/Applications/SystemMonitor/ProcessUnveiledPathsWidget.cpp

@@ -10,6 +10,11 @@
 #include <LibGUI/JsonArrayModel.h>
 #include <LibGUI/JsonArrayModel.h>
 #include <LibGUI/SortingProxyModel.h>
 #include <LibGUI/SortingProxyModel.h>
 #include <LibGUI/TableView.h>
 #include <LibGUI/TableView.h>
+#include <LibGUI/Widget.h>
+
+REGISTER_WIDGET(SystemMonitor, ProcessUnveiledPathsWidget)
+
+namespace SystemMonitor {
 
 
 ProcessUnveiledPathsWidget::ProcessUnveiledPathsWidget()
 ProcessUnveiledPathsWidget::ProcessUnveiledPathsWidget()
 {
 {
@@ -32,3 +37,5 @@ void ProcessUnveiledPathsWidget::set_pid(pid_t pid)
     m_pid = pid;
     m_pid = pid;
     m_model->set_json_path(String::formatted("/proc/{}/unveil", m_pid));
     m_model->set_json_path(String::formatted("/proc/{}/unveil", m_pid));
 }
 }
+
+}

+ 4 - 0
Userland/Applications/SystemMonitor/ProcessUnveiledPathsWidget.h

@@ -9,6 +9,8 @@
 
 
 #include <LibGUI/Widget.h>
 #include <LibGUI/Widget.h>
 
 
+namespace SystemMonitor {
+
 class ProcessUnveiledPathsWidget final : public GUI::Widget {
 class ProcessUnveiledPathsWidget final : public GUI::Widget {
     C_OBJECT(ProcessUnveiledPathsWidget);
     C_OBJECT(ProcessUnveiledPathsWidget);
 
 
@@ -24,3 +26,5 @@ private:
     RefPtr<GUI::JsonArrayModel> m_model;
     RefPtr<GUI::JsonArrayModel> m_model;
     pid_t m_pid { -1 };
     pid_t m_pid { -1 };
 };
 };
+
+}

+ 65 - 0
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"
+            }
+        }
+    }
+}

+ 7 - 0
Userland/Applications/SystemMonitor/ThreadStackWidget.cpp

@@ -9,9 +9,14 @@
 #include <LibCore/Timer.h>
 #include <LibCore/Timer.h>
 #include <LibGUI/BoxLayout.h>
 #include <LibGUI/BoxLayout.h>
 #include <LibGUI/Model.h>
 #include <LibGUI/Model.h>
+#include <LibGUI/Widget.h>
 #include <LibSymbolication/Symbolication.h>
 #include <LibSymbolication/Symbolication.h>
 #include <LibThreading/BackgroundAction.h>
 #include <LibThreading/BackgroundAction.h>
 
 
+REGISTER_WIDGET(SystemMonitor, ThreadStackWidget)
+
+namespace SystemMonitor {
+
 class ThreadStackModel final : public GUI::Model {
 class ThreadStackModel final : public GUI::Model {
 
 
     enum Column {
     enum Column {
@@ -127,3 +132,5 @@ void ThreadStackWidget::custom_event(Core::CustomEvent& event)
     auto& completion_event = verify_cast<CompletionEvent>(event);
     auto& completion_event = verify_cast<CompletionEvent>(event);
     verify_cast<ThreadStackModel>(m_stack_table->model())->set_symbols(completion_event.symbols());
     verify_cast<ThreadStackModel>(m_stack_table->model())->set_symbols(completion_event.symbols());
 }
 }
+
+}

+ 4 - 0
Userland/Applications/SystemMonitor/ThreadStackWidget.h

@@ -10,6 +10,8 @@
 #include <LibGUI/TableView.h>
 #include <LibGUI/TableView.h>
 #include <LibGUI/Widget.h>
 #include <LibGUI/Widget.h>
 
 
+namespace SystemMonitor {
+
 class ThreadStackWidget final : public GUI::Widget {
 class ThreadStackWidget final : public GUI::Widget {
     C_OBJECT(ThreadStackWidget)
     C_OBJECT(ThreadStackWidget)
 public:
 public:
@@ -30,3 +32,5 @@ private:
     RefPtr<GUI::TableView> m_stack_table;
     RefPtr<GUI::TableView> m_stack_table;
     RefPtr<Core::Timer> m_timer;
     RefPtr<Core::Timer> m_timer;
 };
 };
+
+}

+ 43 - 61
Userland/Applications/SystemMonitor/main.cpp

@@ -7,6 +7,7 @@
  */
  */
 
 
 #include "GraphWidget.h"
 #include "GraphWidget.h"
+#include "LibCore/EventLoop.h"
 #include "LibCore/Object.h"
 #include "LibCore/Object.h"
 #include "MemoryStatsWidget.h"
 #include "MemoryStatsWidget.h"
 #include "NetworkStatisticsWidget.h"
 #include "NetworkStatisticsWidget.h"
@@ -17,6 +18,7 @@
 #include "ProcessUnveiledPathsWidget.h"
 #include "ProcessUnveiledPathsWidget.h"
 #include "ThreadStackWidget.h"
 #include "ThreadStackWidget.h"
 #include <AK/NumberFormat.h>
 #include <AK/NumberFormat.h>
+#include <Applications/SystemMonitor/ProcessWindowGML.h>
 #include <Applications/SystemMonitor/SystemMonitorGML.h>
 #include <Applications/SystemMonitor/SystemMonitorGML.h>
 #include <LibConfig/Client.h>
 #include <LibConfig/Client.h>
 #include <LibCore/ArgsParser.h>
 #include <LibCore/ArgsParser.h>
@@ -60,18 +62,42 @@ static void build_performance_tab(GUI::Widget&);
 
 
 static RefPtr<GUI::Statusbar> statusbar;
 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 {
 class UnavailableProcessWidget final : public GUI::Frame {
     C_OBJECT(UnavailableProcessWidget)
     C_OBJECT(UnavailableProcessWidget)
 public:
 public:
     virtual ~UnavailableProcessWidget() override = default;
     virtual ~UnavailableProcessWidget() override = default;
 
 
     String const& text() const { return m_text; }
     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:
 private:
-    UnavailableProcessWidget(String text)
-        : m_text(move(text))
+    UnavailableProcessWidget()
     {
     {
+        REGISTER_STRING_PROPERTY("text", text, set_text);
     }
     }
 
 
     virtual void paint_event(GUI::PaintEvent& event) override
     virtual void paint_event(GUI::PaintEvent& event) override
@@ -87,10 +113,6 @@ private:
     String m_text;
     String m_text;
 };
 };
 
 
-class ProgressbarPaintingDelegate;
-
-namespace SystemMonitor {
-
 class HardwareTabWidget final : public GUI::LazyWidget {
 class HardwareTabWidget final : public GUI::LazyWidget {
     C_OBJECT(HardwareTabWidget)
     C_OBJECT(HardwareTabWidget)
 
 
@@ -287,6 +309,7 @@ public:
 
 
 REGISTER_WIDGET(SystemMonitor, HardwareTabWidget)
 REGISTER_WIDGET(SystemMonitor, HardwareTabWidget)
 REGISTER_WIDGET(SystemMonitor, StorageTabWidget)
 REGISTER_WIDGET(SystemMonitor, StorageTabWidget)
+REGISTER_WIDGET(SystemMonitor, UnavailableProcessWidget)
 
 
 static bool can_access_pid(pid_t pid)
 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"));
     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");
     Config::pledge_domain("SystemMonitor");
 
 
@@ -564,24 +587,6 @@ ErrorOr<int> serenity_main(Main::Arguments arguments)
     return app->exec();
     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)
 ErrorOr<NonnullRefPtr<GUI::Window>> build_process_window(pid_t pid)
 {
 {
     auto window = GUI::Window::construct();
     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));
     window->set_icon(app_icon.bitmap_for_size(16));
 
 
     auto main_widget = TRY(window->try_set_main_widget<GUI::Widget>());
     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;
     GUI::ModelIndex process_index;
     for (int row = 0; row < ProcessModel::the().row_count({}); ++row) {
     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());
     VERIFY(process_index.is_valid());
     if (auto icon_data = process_index.sibling_at_column(ProcessModel::Column::Icon).data(); icon_data.is_icon()) {
     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))
     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
     else
         widget_stack.set_active_widget(&unavailable_process_widget);
         widget_stack.set_active_widget(&unavailable_process_widget);