mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2025-06-11 10:18:15 +09:00
HackStudio: Add a widget showing the state of console's running process
We now have a little widget that sits above the terminal view in the build/application console. When a child process is running, we show its PID, name, scheduling counter, and amount of resident memory in a live little overview. This is not working right just yet, since we don't know how to get to the actually active PID on the TTY. Or, well, we find the active PID by looking at the PGID of our fork()ed child. This manages to find children spawned by Shell, but not children spawned by make, for instance. I need to figure out how to find those.
This commit is contained in:
parent
489e451cce
commit
272317bce2
Notes:
sideshowbarker
2024-07-19 11:33:23 +09:00
Author: https://github.com/awesomekling
Commit: 272317bce2
5 changed files with 109 additions and 0 deletions
|
@ -5,6 +5,7 @@ OBJS = \
|
||||||
TextDocument.o \
|
TextDocument.o \
|
||||||
TerminalWrapper.o \
|
TerminalWrapper.o \
|
||||||
FindInFilesWidget.o \
|
FindInFilesWidget.o \
|
||||||
|
ProcessStateWidget.o \
|
||||||
main.o
|
main.o
|
||||||
|
|
||||||
APP = HackStudio
|
APP = HackStudio
|
||||||
|
|
71
DevTools/HackStudio/ProcessStateWidget.cpp
Normal file
71
DevTools/HackStudio/ProcessStateWidget.cpp
Normal file
|
@ -0,0 +1,71 @@
|
||||||
|
#include "ProcessStateWidget.h"
|
||||||
|
#include <LibCore/CProcessStatisticsReader.h>
|
||||||
|
#include <LibCore/CTimer.h>
|
||||||
|
#include <LibGUI/GBoxLayout.h>
|
||||||
|
#include <LibGUI/GLabel.h>
|
||||||
|
|
||||||
|
ProcessStateWidget::ProcessStateWidget(GWidget* parent)
|
||||||
|
: GWidget(parent)
|
||||||
|
{
|
||||||
|
set_size_policy(SizePolicy::Fill, SizePolicy::Fixed);
|
||||||
|
set_preferred_size(0, 20);
|
||||||
|
|
||||||
|
set_layout(make<GBoxLayout>(Orientation::Horizontal));
|
||||||
|
|
||||||
|
auto pid_label_label = GLabel::construct("Process:", this);
|
||||||
|
pid_label_label->set_font(Font::default_bold_font());
|
||||||
|
m_pid_label = GLabel::construct("", this);
|
||||||
|
|
||||||
|
auto state_label_label = GLabel::construct("State:", this);
|
||||||
|
state_label_label->set_font(Font::default_bold_font());
|
||||||
|
m_state_label = GLabel::construct("", this);
|
||||||
|
|
||||||
|
// FIXME: This should show CPU% instead.
|
||||||
|
auto cpu_label_label = GLabel::construct("Times scheduled:", this);
|
||||||
|
cpu_label_label->set_font(Font::default_bold_font());
|
||||||
|
m_cpu_label = GLabel::construct("", this);
|
||||||
|
|
||||||
|
auto memory_label_label = GLabel::construct("Memory (resident):", this);
|
||||||
|
memory_label_label->set_font(Font::default_bold_font());
|
||||||
|
m_memory_label = GLabel::construct("", this);
|
||||||
|
|
||||||
|
m_timer = CTimer::construct(500, [this] {
|
||||||
|
refresh();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
ProcessStateWidget::~ProcessStateWidget()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void ProcessStateWidget::refresh()
|
||||||
|
{
|
||||||
|
if (m_pid == -1) {
|
||||||
|
m_pid_label->set_text("(none)");
|
||||||
|
m_state_label->set_text("n/a");
|
||||||
|
m_cpu_label->set_text("n/a");
|
||||||
|
m_memory_label->set_text("n/a");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto processes = CProcessStatisticsReader::get_all();
|
||||||
|
auto child_process_data = processes.get(m_pid);
|
||||||
|
|
||||||
|
if (!child_process_data.has_value())
|
||||||
|
return;
|
||||||
|
|
||||||
|
auto active_process_data = processes.get(child_process_data.value().pgid);
|
||||||
|
|
||||||
|
auto& data = active_process_data.value();
|
||||||
|
|
||||||
|
m_pid_label->set_text(String::format("%s(%d)", data.name.characters(), m_pid));
|
||||||
|
m_state_label->set_text(data.state);
|
||||||
|
m_cpu_label->set_text(String::format("%d", data.times_scheduled));
|
||||||
|
m_memory_label->set_text(String::format("%d", data.amount_resident));
|
||||||
|
}
|
||||||
|
|
||||||
|
void ProcessStateWidget::set_pid(pid_t pid)
|
||||||
|
{
|
||||||
|
m_pid = pid;
|
||||||
|
refresh();
|
||||||
|
}
|
28
DevTools/HackStudio/ProcessStateWidget.h
Normal file
28
DevTools/HackStudio/ProcessStateWidget.h
Normal file
|
@ -0,0 +1,28 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <LibGUI/GWidget.h>
|
||||||
|
|
||||||
|
class CTimer;
|
||||||
|
class GLabel;
|
||||||
|
|
||||||
|
class ProcessStateWidget final : public GWidget {
|
||||||
|
C_OBJECT(ProcessStateWidget)
|
||||||
|
public:
|
||||||
|
virtual ~ProcessStateWidget() override;
|
||||||
|
|
||||||
|
void set_pid(pid_t);
|
||||||
|
|
||||||
|
private:
|
||||||
|
explicit ProcessStateWidget(GWidget* parent);
|
||||||
|
|
||||||
|
void refresh();
|
||||||
|
|
||||||
|
RefPtr<GLabel> m_pid_label;
|
||||||
|
RefPtr<GLabel> m_state_label;
|
||||||
|
RefPtr<GLabel> m_cpu_label;
|
||||||
|
RefPtr<GLabel> m_memory_label;
|
||||||
|
|
||||||
|
RefPtr<CTimer> m_timer;
|
||||||
|
|
||||||
|
pid_t m_pid { -1 };
|
||||||
|
};
|
|
@ -1,4 +1,5 @@
|
||||||
#include "TerminalWrapper.h"
|
#include "TerminalWrapper.h"
|
||||||
|
#include "ProcessStateWidget.h"
|
||||||
#include <AK/String.h>
|
#include <AK/String.h>
|
||||||
#include <LibCore/CConfigFile.h>
|
#include <LibCore/CConfigFile.h>
|
||||||
#include <LibGUI/GBoxLayout.h>
|
#include <LibGUI/GBoxLayout.h>
|
||||||
|
@ -44,6 +45,7 @@ void TerminalWrapper::run_command(const String& command)
|
||||||
} else if (WIFSIGNALED(wstatus)) {
|
} else if (WIFSIGNALED(wstatus)) {
|
||||||
m_terminal_widget->inject_string(String::format("\033[34;1m(Command signaled with %s!)\033[0m\n", strsignal(WTERMSIG(wstatus))));
|
m_terminal_widget->inject_string(String::format("\033[34;1m(Command signaled with %s!)\033[0m\n", strsignal(WTERMSIG(wstatus))));
|
||||||
}
|
}
|
||||||
|
m_process_state_widget->set_pid(-1);
|
||||||
m_pid = -1;
|
m_pid = -1;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -106,6 +108,9 @@ void TerminalWrapper::run_command(const String& command)
|
||||||
}
|
}
|
||||||
ASSERT_NOT_REACHED();
|
ASSERT_NOT_REACHED();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Parent process, cont'd.
|
||||||
|
m_process_state_widget->set_pid(m_pid);
|
||||||
}
|
}
|
||||||
|
|
||||||
TerminalWrapper::TerminalWrapper(GWidget* parent)
|
TerminalWrapper::TerminalWrapper(GWidget* parent)
|
||||||
|
@ -113,6 +118,8 @@ TerminalWrapper::TerminalWrapper(GWidget* parent)
|
||||||
{
|
{
|
||||||
set_layout(make<GBoxLayout>(Orientation::Vertical));
|
set_layout(make<GBoxLayout>(Orientation::Vertical));
|
||||||
|
|
||||||
|
m_process_state_widget = ProcessStateWidget::construct(this);
|
||||||
|
|
||||||
RefPtr<CConfigFile> config = CConfigFile::get_for_app("Terminal");
|
RefPtr<CConfigFile> config = CConfigFile::get_for_app("Terminal");
|
||||||
m_terminal_widget = TerminalWidget::construct(-1, false, config);
|
m_terminal_widget = TerminalWidget::construct(-1, false, config);
|
||||||
add_child(*m_terminal_widget);
|
add_child(*m_terminal_widget);
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
|
|
||||||
#include <LibGUI/GWidget.h>
|
#include <LibGUI/GWidget.h>
|
||||||
|
|
||||||
|
class ProcessStateWidget;
|
||||||
class TerminalWidget;
|
class TerminalWidget;
|
||||||
|
|
||||||
class TerminalWrapper final : public GWidget {
|
class TerminalWrapper final : public GWidget {
|
||||||
|
@ -14,6 +15,7 @@ public:
|
||||||
private:
|
private:
|
||||||
explicit TerminalWrapper(GWidget* parent);
|
explicit TerminalWrapper(GWidget* parent);
|
||||||
|
|
||||||
|
RefPtr<ProcessStateWidget> m_process_state_widget;
|
||||||
RefPtr<TerminalWidget> m_terminal_widget;
|
RefPtr<TerminalWidget> m_terminal_widget;
|
||||||
pid_t m_pid { -1 };
|
pid_t m_pid { -1 };
|
||||||
};
|
};
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue