Demos/CatDog: Introduce inspector & artist states based on open programs

These two new main states are determined by looking at the programs the
user has open. The artist state, using the new artist catdog, is
triggered by PixelPaint and FontEditor, and the inspector state is
triggered by Inspector, Profiler and SystemMonitor. This requires CatDog
to unveil /proc/all, and, for some reason, /etc/passwd.
This commit is contained in:
kleines Filmröllchen 2022-02-26 19:44:30 +01:00 committed by Andreas Kling
parent 93bb943394
commit 145f983ee1
3 changed files with 43 additions and 3 deletions

View file

@ -6,11 +6,34 @@
*/
#include "CatDog.h"
#include <LibCore/ProcessStatisticsReader.h>
#include <LibGUI/Painter.h>
#include <LibGUI/Window.h>
void CatDog::timer_event(Core::TimerEvent&)
{
auto maybe_proc_info = Core::ProcessStatisticsReader::get_all(m_proc_all);
if (maybe_proc_info.has_value()) {
auto proc_info = maybe_proc_info.release_value();
auto maybe_paint_program = proc_info.processes.first_matching([](auto& process) {
return process.name.equals_ignoring_case("pixelpaint") || process.name.equals_ignoring_case("fonteditor");
});
if (maybe_paint_program.has_value()) {
m_main_state = MainState::Artist;
} else {
auto maybe_inspector_program = proc_info.processes.first_matching([](auto& process) {
return process.name.equals_ignoring_case("inspector") || process.name.equals_ignoring_case("systemmonitor") || process.name.equals_ignoring_case("profiler");
});
if (maybe_inspector_program.has_value())
m_main_state = MainState::Inspector;
// If we currently have an application state but that app isn't open anymore, go back to idle.
else if (!is_non_application_state(m_main_state))
m_main_state = MainState::Idle;
}
}
if (!m_roaming)
return;
if (m_temp_pos.x() > 48) {

View file

@ -8,6 +8,7 @@
#include <AK/NonnullRefPtr.h>
#include <AK/RefPtr.h>
#include <LibCore/ElapsedTimer.h>
#include <LibCore/File.h>
#include <LibGUI/Menu.h>
#include <LibGUI/MouseTracker.h>
#include <LibGUI/Widget.h>
@ -23,9 +24,11 @@ class CatDog final : public GUI::Widget
public:
// The general state, does not contain movement direction or whether CatDog is roaming.
enum class MainState {
Idle, // default state
Alerted, // woken by mouse cursor or speaking after being idle
Sleeping, // mouse hasn't moved in some time
Idle, // default state
Alerted, // woken by mouse cursor or speaking after being idle
Sleeping, // mouse hasn't moved in some time
Artist, // PixelPaint or FontEditor are open
Inspector, // SystemServer, Profiler or Inspector are open
};
static bool is_non_application_state(MainState state)
{
@ -69,9 +72,13 @@ private:
bool m_up, m_down, m_left, m_right;
bool m_roaming { true };
RefPtr<Core::File> m_proc_all;
NonnullRefPtr<Gfx::Bitmap> m_alert = *Gfx::Bitmap::try_load_from_file("/res/icons/catdog/alert.png").release_value_but_fixme_should_propagate_errors();
NonnullRefPtr<Gfx::Bitmap> m_artist = *Gfx::Bitmap::try_load_from_file("/res/icons/catdog/artist.png").release_value_but_fixme_should_propagate_errors();
NonnullRefPtr<Gfx::Bitmap> m_erun1 = *Gfx::Bitmap::try_load_from_file("/res/icons/catdog/erun1.png").release_value_but_fixme_should_propagate_errors();
NonnullRefPtr<Gfx::Bitmap> m_erun2 = *Gfx::Bitmap::try_load_from_file("/res/icons/catdog/erun2.png").release_value_but_fixme_should_propagate_errors();
NonnullRefPtr<Gfx::Bitmap> m_inspector = *Gfx::Bitmap::try_load_from_file("/res/icons/catdog/inspector.png").release_value_but_fixme_should_propagate_errors();
NonnullRefPtr<Gfx::Bitmap> m_nerun1 = *Gfx::Bitmap::try_load_from_file("/res/icons/catdog/nerun1.png").release_value_but_fixme_should_propagate_errors();
NonnullRefPtr<Gfx::Bitmap> m_nerun2 = *Gfx::Bitmap::try_load_from_file("/res/icons/catdog/nerun2.png").release_value_but_fixme_should_propagate_errors();
NonnullRefPtr<Gfx::Bitmap> m_nrun1 = *Gfx::Bitmap::try_load_from_file("/res/icons/catdog/nrun1.png").release_value_but_fixme_should_propagate_errors();
@ -108,11 +115,18 @@ private:
else
m_curr_bmp = m_sleep2;
break;
case MainState::Artist:
m_curr_bmp = m_artist;
break;
case MainState::Inspector:
m_curr_bmp = m_inspector;
break;
}
}
CatDog()
: m_temp_pos { 0, 0 }
, m_proc_all(MUST(Core::File::open("/proc/all", Core::OpenMode::ReadOnly)))
{
set_image_by_main_state();
}

View file

@ -26,6 +26,9 @@ ErrorOr<int> serenity_main(Main::Arguments arguments)
TRY(Core::System::pledge("stdio recvfd sendfd rpath"));
TRY(Core::System::unveil("/res", "r"));
TRY(Core::System::unveil("/proc/all", "r"));
// FIXME: For some reason, this is needed in the /proc/all shenanigans.
TRY(Core::System::unveil("/etc/passwd", "r"));
TRY(Core::System::unveil(nullptr, nullptr));
auto window = TRY(GUI::Window::try_create());