From 90818e8e3ef09f601ac8bec8750bc80236a8cae5 Mon Sep 17 00:00:00 2001 From: VAN BOSSUYT Nicolas Date: Thu, 2 Jan 2025 16:39:54 +0100 Subject: [PATCH] karm-ui: Cleanup the debug facility. --- src/libs/karm-ui/app.cpp | 69 +---------- src/libs/karm-ui/host.h | 47 +------ src/libs/karm-ui/input.cpp | 4 - src/libs/karm-ui/layout.cpp | 14 +-- src/libs/karm-ui/node.cpp | 12 -- src/libs/karm-ui/node.h | 15 --- src/libs/karm-ui/perf.h | 108 ---------------- src/libs/karm-ui/scroll.cpp | 6 - src/libs/karm-ui/view.cpp | 7 -- src/srvs/grund-shell/api.h | 5 + src/srvs/grund-shell/framebuffer.cpp | 37 ++++++ src/srvs/grund-shell/framebuffer.h | 21 ++++ src/srvs/grund-shell/input.cpp | 95 ++++++++++++++ src/srvs/grund-shell/input.h | 9 ++ src/srvs/grund-shell/main.cpp | 179 +++------------------------ src/srvs/grund-shell/manifest.json | 1 + src/web/vaev-view/view.cpp | 3 - 17 files changed, 193 insertions(+), 439 deletions(-) delete mode 100644 src/libs/karm-ui/node.cpp delete mode 100644 src/libs/karm-ui/perf.h create mode 100644 src/srvs/grund-shell/api.h create mode 100644 src/srvs/grund-shell/framebuffer.cpp create mode 100644 src/srvs/grund-shell/framebuffer.h create mode 100644 src/srvs/grund-shell/input.cpp create mode 100644 src/srvs/grund-shell/input.h diff --git a/src/libs/karm-ui/app.cpp b/src/libs/karm-ui/app.cpp index 63dd908656d..631dcd31b28 100644 --- a/src/libs/karm-ui/app.cpp +++ b/src/libs/karm-ui/app.cpp @@ -8,84 +8,19 @@ #include "_embed.h" #include "app.h" #include "host.h" -#include "input.h" -#include "layout.h" namespace Karm::Ui { -Child inspector(Child child) { - return hflow( - child | Ui::grow(), - separator(), - vflow( - 4, - icon(Mdi::FLASK, 24, GRAY600) | Ui::insets(6) | Ui::center(), - separator(), - button( - [](auto &n) { - debugShowLayoutBounds = !debugShowLayoutBounds; - Ui::shouldLayout(n); - }, - ButtonStyle::subtle(), - Mdi::RULER_SQUARE - ), - button( - [](auto &n) { - debugShowRepaintBounds = !debugShowRepaintBounds; - Ui::shouldLayout(n); - }, - ButtonStyle::subtle(), - Mdi::BRUSH - ), - button( - [](auto &n) { - debugShowEmptyBounds = !debugShowEmptyBounds; - Ui::shouldLayout(n); - }, - ButtonStyle::subtle(), - Mdi::BORDER_NONE_VARIANT - ), - button( - [](auto &n) { - debugShowScrollBounds = !debugShowScrollBounds; - Ui::shouldLayout(n); - }, - ButtonStyle::subtle(), - Mdi::ARROW_UP_DOWN - ), - button( - [](auto &n) { - debugShowPerfGraph = !debugShowPerfGraph; - Ui::shouldLayout(n); - }, - ButtonStyle::subtle(), - Mdi::CHART_HISTOGRAM - ) - ) | - Ui::insets(4) | - Ui::box({ - .backgroundFill = GRAY800, - }) - ); -} - -Res<> runApp(Sys::Context &ctx, Child root) { - auto &args = useArgs(ctx); - if (args.has("--debug")) - root = root | inspector; +Res<> runApp(Sys::Context &, Child root) { return try$(_Embed::makeHost(root))->run(); } void mountApp(Cli::Command &cmd, Slot rootSlot) { - Cli::Flag debugArg = Cli::flag(NONE, "debug"s, "Show debug inspector."s); Cli::Flag mobileArg = Cli::flag(NONE, "mobile"s, "Show mobile layout."s); - cmd.option(debugArg); cmd.option(mobileArg); - cmd.callbackAsync = [rootSlot = std::move(rootSlot), debugArg](Sys::Context &) -> Async::Task<> { + cmd.callbackAsync = [rootSlot = std::move(rootSlot)](Sys::Context &) -> Async::Task<> { auto root = rootSlot(); - if (debugArg) - root = root | inspector; co_return co_try$(_Embed::makeHost(root))->run(); }; } diff --git a/src/libs/karm-ui/host.h b/src/libs/karm-ui/host.h index fdb0b93b71c..98af2300306 100644 --- a/src/libs/karm-ui/host.h +++ b/src/libs/karm-ui/host.h @@ -3,19 +3,21 @@ #include #include #include +#include #include #include "node.h" -#include "perf.h" namespace Karm::Ui { +static constexpr auto FRAME_RATE = 60; +static constexpr auto FRAME_TIME = 1.0 / FRAME_RATE; + struct Host : public Node { Child _root; Opt> _res; Gfx::CpuCanvas _g; Vec _dirty; - PerfGraph _perf; bool _shouldLayout{}; bool _shouldAnimate{}; @@ -30,9 +32,7 @@ struct Host : public Node { virtual Gfx::MutPixels mutPixels() = 0; - Gfx::Pixels pixels() { - return mutPixels(); - } + Gfx::Pixels pixels() { return mutPixels(); } virtual void flip(Slice regions) = 0; @@ -54,38 +54,15 @@ struct Host : public Node { _root->paint(g, r); - if (debugShowRepaintBounds) { - static auto hue = 0.0; - g.strokeStyle(Gfx::stroke(Gfx::hsvToRgb({hue, 1, 1}).withOpacity(0.5)).withWidth(4).withAlign(Gfx::INSIDE_ALIGN)); - hue += 1; - if (hue > 360) - hue = 0; - g.stroke(r.cast()); - } - - if (debugShowPerfGraph) - _perf.paint(_g); - g.pop(); } void paint() { - if (debugShowPerfGraph) - _dirty.pushBack({0, 0, 256, 100}); - _g.begin(mutPixels()); - _perf.record(PerfEvent::PAINT); for (auto &d : _dirty) { paint(_g, d); } - auto elapsed = _perf.end(); - - static auto threshold = TimeSpan::fromMSecs(15); - if (elapsed > threshold) { - logWarn("Stutter detected, paint took {} for {} nodes, threshold raised", elapsed, debugNodeCount); - threshold = elapsed; - } _g.end(); @@ -94,25 +71,11 @@ struct Host : public Node { } void layout(Math::Recti r) override { - _perf.record(PerfEvent::LAYOUT); _root->layout(r); - auto elapsed = _perf.end(); - static auto threshold = TimeSpan::fromMSecs(1); - if (elapsed > threshold) { - logWarn("Stutter detected, layout took {} for {} nodes, threshold raised", elapsed, debugNodeCount); - threshold = elapsed; - } } void event(App::Event &event) override { - _perf.record(PerfEvent::INPUT); _root->event(event); - auto elapsed = _perf.end(); - static auto threshold = TimeSpan::fromMSecs(1); - if (elapsed > threshold) { - logWarn("Stutter detected, event took {} for {} nodes, threshold raised", elapsed, debugNodeCount); - threshold = elapsed; - } } void bubble(App::Event &event) override { diff --git a/src/libs/karm-ui/input.cpp b/src/libs/karm-ui/input.cpp index be3ae0f6564..20f231a0107 100644 --- a/src/libs/karm-ui/input.cpp +++ b/src/libs/karm-ui/input.cpp @@ -310,8 +310,6 @@ struct Input : public View { text.paint(g); g.pop(); - if (debugShowLayoutBounds) - g.plot(bound(), Gfx::CYAN); } void event(App::Event &e) override { @@ -391,8 +389,6 @@ struct SimpleInput : public View { text.paint(g); g.pop(); - if (debugShowLayoutBounds) - g.plot(bound(), Gfx::CYAN); } void event(App::Event &e) override { diff --git a/src/libs/karm-ui/layout.cpp b/src/libs/karm-ui/layout.cpp index 0e4122ca4fd..e4a524cc55b 100644 --- a/src/libs/karm-ui/layout.cpp +++ b/src/libs/karm-ui/layout.cpp @@ -53,14 +53,7 @@ struct Empty : public View { return _size; } - void paint(Gfx::Canvas &g, Math::Recti) override { - if (debugShowEmptyBounds) { - auto b = bound(); - g.plot(b, Gfx::WHITE.withOpacity(0.2)); - g.plot(Math::Edgei{b.topStart(), b.bottomEnd()}, Gfx::WHITE.withOpacity(0.2)); - g.plot(Math::Edgei{b.topEnd(), b.bottomStart()}, Gfx::WHITE.withOpacity(0.2)); - } - } + void paint(Gfx::Canvas &, Math::Recti) override {} }; Child empty(Math::Vec2i size) { @@ -310,9 +303,6 @@ struct Insets : public ProxyNode { void paint(Gfx::Canvas &g, Math::Recti r) override { child().paint(g, r); - if (debugShowLayoutBounds) { - g.plot(child().bound(), Gfx::LIME); - } } void layout(Math::Recti rect) override { @@ -347,8 +337,6 @@ struct AspectRatio : public ProxyNode { void paint(Gfx::Canvas &g, Math::Recti r) override { child().paint(g, r); - if (debugShowLayoutBounds) - g.plot(child().bound(), Gfx::INDIGO); } Math::Vec2i size(Math::Vec2i s, Hint) override { diff --git a/src/libs/karm-ui/node.cpp b/src/libs/karm-ui/node.cpp deleted file mode 100644 index 7510d0b1007..00000000000 --- a/src/libs/karm-ui/node.cpp +++ /dev/null @@ -1,12 +0,0 @@ -#include - -namespace Karm::Ui { - -bool debugShowLayoutBounds = false; -bool debugShowRepaintBounds = false; -bool debugShowEmptyBounds = false; -bool debugShowScrollBounds = false; -bool debugShowPerfGraph = false; -int debugNodeCount = 0; - -} // namespace Karm::Ui diff --git a/src/libs/karm-ui/node.h b/src/libs/karm-ui/node.h index f407efece86..614c7244f4f 100644 --- a/src/libs/karm-ui/node.h +++ b/src/libs/karm-ui/node.h @@ -19,13 +19,6 @@ enum struct Hint { MAX, }; -extern bool debugShowLayoutBounds; -extern bool debugShowRepaintBounds; -extern bool debugShowEmptyBounds; -extern bool debugShowScrollBounds; -extern bool debugShowPerfGraph; -extern int debugNodeCount; - struct Node; using Child = Strong; @@ -51,14 +44,6 @@ struct Node : public App::Dispatch { f64 dt; }; - Node() { - debugNodeCount++; - } - - virtual ~Node() { - debugNodeCount--; - } - Key key() const { return _key; } diff --git a/src/libs/karm-ui/perf.h b/src/libs/karm-ui/perf.h deleted file mode 100644 index c61825e244b..00000000000 --- a/src/libs/karm-ui/perf.h +++ /dev/null @@ -1,108 +0,0 @@ -#pragma once - -#include -#include -#include - -namespace Karm::Ui { - -static constexpr auto FRAME_RATE = 60; -static constexpr auto FRAME_TIME = 1.0 / FRAME_RATE; - -enum struct PerfEvent { - NONE, - PAINT, - LAYOUT, - INPUT, -}; - -struct PerfRecord { - PerfEvent event; - TimeStamp start; - TimeStamp end; - - Gfx::Color color() const { - switch (event) { - case PerfEvent::PAINT: - return duration().toMSecs() > 16 ? Gfx::RED : Gfx::GREEN; - - case PerfEvent::LAYOUT: - return Gfx::PINK; - - case PerfEvent::INPUT: - return Gfx::BLUE; - - default: - return Gfx::BLACK; - } - } - - TimeSpan duration() const { - return end - start; - } -}; - -struct PerfGraph { - usize _index{}; - Array _records{}; - f64 _frameTime = 1; - - void record(PerfEvent e) { - auto now = Sys::now(); - _records[_index % 256] = PerfRecord{e, now, now}; - } - - auto end() { - auto n = Sys::now(); - auto rec = _records[_index % 256]; - auto elapsed = n - rec.start; - _records[_index++ % 256].end = n; - - if (rec.event == PerfEvent::PAINT) { - _frameTime = (_frameTime * 0.9) + (elapsed.toMSecs() * 0.1); - } - return elapsed; - } - - f64 fps() { - return 1000.0 / _frameTime; - } - - Math::Recti bound() { - return {0, 0, 256, 64}; - } - - void paint(Gfx::Canvas &g) { - g.push(); - g.clip(bound()); - g.fillStyle(Gfx::GREEN900.withOpacity(0.5)); - g.fill(bound()); - - g.strokeStyle(Gfx::stroke(Gfx::GREEN.withOpacity(0.5)).withAlign(Gfx::INSIDE_ALIGN)); - g.stroke(); - g.strokeStyle(Gfx::stroke(Gfx::WHITE.withOpacity(0.5)).withAlign(Gfx::INSIDE_ALIGN)); - g.stroke(Math::Edgef{0, (isize)(FRAME_TIME * 1000 * 2), (f64)bound().width, FRAME_TIME * 1000 * 2}); - - for (isize i = 0; i < 256; ++i) { - auto e = _records[(_index + i) % 256]; - - g.plot( - Math::Recti{i, 0, 1, (isize)e.duration().toMSecs() * 2}, - e.color() - ); - } - - auto text = Io::format("FPS: {}", (isize)fps()).take(); - Text::Prose gText{Text::ProseStyle{.font = Text::Font::fallback()}}; - gText.append(text.str()); - gText.layout(256); - - g.fillStyle(Gfx::WHITE); - g.origin({8, 4}); - gText.paint(g); - - g.pop(); - } -}; - -} // namespace Karm::Ui diff --git a/src/libs/karm-ui/scroll.cpp b/src/libs/karm-ui/scroll.cpp index aa3947e7e1b..15fbd79afae 100644 --- a/src/libs/karm-ui/scroll.cpp +++ b/src/libs/karm-ui/scroll.cpp @@ -55,14 +55,8 @@ struct Scroll : public ProxyNode { r.xy = r.xy - _scroll.cast(); child().paint(g, r); - if (debugShowScrollBounds) - g.plot(child().bound(), Gfx::PINK); - g.pop(); - if (debugShowScrollBounds) - g.plot(_bound, Gfx::CYAN); - // draw scroll bar g.push(); g.clip(_bound); diff --git a/src/libs/karm-ui/view.cpp b/src/libs/karm-ui/view.cpp index 2b64119561e..da7d496ffea 100644 --- a/src/libs/karm-ui/view.cpp +++ b/src/libs/karm-ui/view.cpp @@ -238,8 +238,6 @@ struct Text : public View { g.origin(bound().xy.cast()); _prose->paint(g); g.pop(); - if (debugShowLayoutBounds) - g.plot(bound(), Gfx::CYAN); } void layout(Math::Recti bound) override { @@ -284,8 +282,6 @@ struct Icon : public View { if (_color) g.fillStyle(_color.unwrap()); _icon.fill(g, bound().topStart()); - if (debugShowLayoutBounds) - g.plot(bound(), Gfx::CYAN); g.pop(); } @@ -321,9 +317,6 @@ struct Image : public View { g.blit(bound(), _image); } - if (debugShowLayoutBounds) - g.plot(bound(), Gfx::CYAN); - g.pop(); } diff --git a/src/srvs/grund-shell/api.h b/src/srvs/grund-shell/api.h new file mode 100644 index 00000000000..08208ea63c9 --- /dev/null +++ b/src/srvs/grund-shell/api.h @@ -0,0 +1,5 @@ +#pragma once + +namespace Grund::Shell { + +} // namespace Grund::Shell diff --git a/src/srvs/grund-shell/framebuffer.cpp b/src/srvs/grund-shell/framebuffer.cpp new file mode 100644 index 00000000000..ee0b3d6c260 --- /dev/null +++ b/src/srvs/grund-shell/framebuffer.cpp @@ -0,0 +1,37 @@ +#include "framebuffer.h" + +namespace Grund::Shell { + +Res> Framebuffer::open(Sys::Context &ctx) { + auto &handover = useHandover(ctx); + auto *record = handover.findTag(Handover::Tag::FB); + auto vmo = try$(Hj::Vmo::create(Hj::ROOT, record->start, record->size, Hj::VmoFlags::DMA)); + try$(vmo.label("framebuffer")); + return Ok(makeStrong(*record, try$(Hj::map(vmo, Hj::MapFlags::READ | Hj::MapFlags::WRITE)))); +} + +Framebuffer::Framebuffer(Handover::Record record, Hj::Mapped map) + : _record(record), _map(std::move(map)) { + logInfo( + "fb: {x}-{x} {}x{}, {} stride", + _map.range().start, + _map.range().end(), + _record.fb.width, + _record.fb.height, + _record.fb.pitch + ); +} + +Karm::Gfx::MutPixels Framebuffer::mutPixels() { + return { + _map.mutBytes().buf(), + { + _record.fb.width, + _record.fb.height, + }, + _record.fb.pitch, + Gfx::BGRA8888, + }; +} + +} // namespace Grund::Shell diff --git a/src/srvs/grund-shell/framebuffer.h b/src/srvs/grund-shell/framebuffer.h new file mode 100644 index 00000000000..0f56878845b --- /dev/null +++ b/src/srvs/grund-shell/framebuffer.h @@ -0,0 +1,21 @@ +#pragma once + +#include +#include +#include +#include + +namespace Grund::Shell { + +struct Framebuffer : public Gfx::CpuSurface { + static Res> open(Sys::Context &ctx); + + Handover::Record _record; + Hj::Mapped _map; + + Framebuffer(Handover::Record record, Hj::Mapped map); + + Gfx::MutPixels mutPixels(); +}; + +} // namespace Grund::Shell diff --git a/src/srvs/grund-shell/input.cpp b/src/srvs/grund-shell/input.cpp new file mode 100644 index 00000000000..8491213156c --- /dev/null +++ b/src/srvs/grund-shell/input.cpp @@ -0,0 +1,95 @@ +#include +#include + +#include "input.h" + +namespace Grund::Shell { + +struct InputTranslator : public Ui::ProxyNode { + App::MouseEvent _mousePrev = {}; + Math::Vec2i _mousePos = {}; + bool _mouseDirty = false; + + InputTranslator(Ui::Child child) + : Ui::ProxyNode(std::move(child)) { + } + + Math::Ellipsef _cursor() const { + return { + _mousePos.cast(), + {16, 16}, + }; + } + + Math::Recti _cursorDamage() const { + return _cursor().bound().grow(1).cast(); + } + + void event(App::Event &e) override { + if (auto m = e.is()) { + if (not _mouseDirty) { + _mouseDirty = true; + Ui::shouldRepaint(*this, _cursorDamage()); + Ui::shouldAnimate(*this); + } + + _mousePos = _mousePos + m->delta; + _mousePos = _mousePos.min(bound().size() - Math::Vec2i{1, 1}); + _mousePos = _mousePos.max(Math::Vec2i{0, 0}); + e.accept(); + + if (m->delta != Math::Vec2i{}) { + App::MouseEvent mouseMove = *m; + mouseMove.type = App::MouseEvent::MOVE; + mouseMove.pos = _mousePos; + Ui::event(child(), mouseMove); + } + + if (_mousePrev.released(App::MouseButton::LEFT) and + m->pressed(App::MouseButton::LEFT)) { + App::MouseEvent mousePress = *m; + mousePress.type = App::MouseEvent::PRESS; + mousePress.pos = _mousePos; + mousePress.button = App::MouseButton::LEFT; + Ui::event(child(), mousePress); + } + + if (_mousePrev.pressed(App::MouseButton::LEFT) and + m->released(App::MouseButton::LEFT)) { + App::MouseEvent mouseRelease = *m; + mouseRelease.type = App::MouseEvent::RELEASE; + mouseRelease.pos = _mousePos; + mouseRelease.button = App::MouseButton::LEFT; + Ui::event(child(), mouseRelease); + } + + _mousePrev = *m; + } else if (auto k = e.is()) { + if (_mouseDirty) { + _mouseDirty = false; + Ui::shouldRepaint(*this, _cursorDamage()); + } + } + + Ui::ProxyNode::event(e); + } + + void paint(Gfx::Canvas &g, Math::Recti r) override { + child().paint(g, r); + + if (_cursorDamage().colide(r)) { + g.push(); + g.beginPath(); + g.fillStyle(Gfx::WHITE.withOpacity(0.25)); + g.ellipse(_cursor()); + g.fill(Gfx::FillRule::EVENODD); + g.pop(); + } + } +}; + +Ui::Child inputTranslator(Ui::Child child) { + return makeStrong(std::move(child)); +} + +} // namespace Grund::Shell diff --git a/src/srvs/grund-shell/input.h b/src/srvs/grund-shell/input.h new file mode 100644 index 00000000000..00c77649212 --- /dev/null +++ b/src/srvs/grund-shell/input.h @@ -0,0 +1,9 @@ +#pragma once + +#include + +namespace Grund::Shell { + +Ui::Child inputTranslator(Ui::Child child); + +} // namespace Grund::Shell diff --git a/src/srvs/grund-shell/main.cpp b/src/srvs/grund-shell/main.cpp index 6f521919bd6..e67ba55a79d 100644 --- a/src/srvs/grund-shell/main.cpp +++ b/src/srvs/grund-shell/main.cpp @@ -1,155 +1,19 @@ -#include #include -#include #include #include -#include #include +#include #include -#include #include -#include +#include #include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include #include "../grund-bus/api.h" +#include "framebuffer.h" +#include "input.h" namespace Grund::Shell { -struct Framebuffer : public Gfx::CpuSurface { - static Res> open(Sys::Context &ctx) { - auto &handover = useHandover(ctx); - auto *fb = handover.findTag(Handover::Tag::FB); - auto fbVmo = try$(Hj::Vmo::create(Hj::ROOT, fb->start, fb->size, Hj::VmoFlags::DMA)); - try$(fbVmo.label("framebuffer")); - return Ok(makeStrong(*fb, try$(Hj::map(fbVmo, Hj::MapFlags::READ | Hj::MapFlags::WRITE)))); - } - - Handover::Record _record; - Hj::Mapped _map; - - Framebuffer(Handover::Record record, Hj::Mapped map) - : _record(record), _map(std::move(map)) { - logInfo( - "fb: {x}-{x} {}x{}, {} stride", - _map.range().start, - _map.range().end(), - _record.fb.width, - _record.fb.height, - _record.fb.pitch - ); - } - - Gfx::MutPixels mutPixels() { - return { - _map.mutBytes().buf(), - { - _record.fb.width, - _record.fb.height, - }, - _record.fb.pitch, - Gfx::BGRA8888, - }; - } -}; - -struct InputTranslator : public Ui::ProxyNode { - App::MouseEvent _mousePrev = {}; - Math::Vec2i _mousePos = {}; - bool _mouseDirty = false; - - InputTranslator(Ui::Child child) - : Ui::ProxyNode(std::move(child)) { - } - - Math::Ellipsef _cursor() const { - return { - _mousePos.cast(), - {16, 16}, - }; - } - - Math::Recti _cursorDamage() const { - return _cursor().bound().grow(1).cast(); - } - - void event(App::Event &e) override { - if (auto m = e.is()) { - if (not _mouseDirty) { - _mouseDirty = true; - Ui::shouldRepaint(*this, _cursorDamage()); - Ui::shouldAnimate(*this); - } - - _mousePos = _mousePos + m->delta; - _mousePos = _mousePos.min(bound().size() - Math::Vec2i{1, 1}); - _mousePos = _mousePos.max(Math::Vec2i{0, 0}); - e.accept(); - - if (m->delta != Math::Vec2i{}) { - App::MouseEvent mouseMove = *m; - mouseMove.type = App::MouseEvent::MOVE; - mouseMove.pos = _mousePos; - Ui::event(child(), mouseMove); - } - - if (_mousePrev.released(App::MouseButton::LEFT) and - m->pressed(App::MouseButton::LEFT)) { - App::MouseEvent mousePress = *m; - mousePress.type = App::MouseEvent::PRESS; - mousePress.pos = _mousePos; - mousePress.button = App::MouseButton::LEFT; - Ui::event(child(), mousePress); - } - - if (_mousePrev.pressed(App::MouseButton::LEFT) and - m->released(App::MouseButton::LEFT)) { - App::MouseEvent mouseRelease = *m; - mouseRelease.type = App::MouseEvent::RELEASE; - mouseRelease.pos = _mousePos; - mouseRelease.button = App::MouseButton::LEFT; - Ui::event(child(), mouseRelease); - } - - _mousePrev = *m; - } else if (auto k = e.is()) { - if (_mouseDirty) { - _mouseDirty = false; - Ui::shouldRepaint(*this, _cursorDamage()); - } - } - - Ui::ProxyNode::event(e); - } - - void paint(Gfx::Canvas &g, Math::Recti r) override { - child().paint(g, r); - - if (_cursorDamage().colide(r)) { - g.push(); - g.beginPath(); - g.fillStyle(Gfx::WHITE.withOpacity(0.25)); - g.ellipse(_cursor()); - g.fill(Gfx::FillRule::EVENODD); - g.pop(); - } - } -}; - -Ui::Child inputTranslator(Ui::Child child) { - return makeStrong(std::move(child)); -} - struct Root : public Ui::ProxyNode { Vec _dirty; Strong _frontbuffer; @@ -171,7 +35,6 @@ struct Root : public Ui::ProxyNode { g.fillStyle(Ui::GRAY50); g.clip(r.cast()); paint(g, r); - // g.plot(r, Gfx::RED); g.pop(); Gfx::blitUnsafe(_frontbuffer->mutPixels(), _backbuffer->pixels()); @@ -184,9 +47,14 @@ struct Root : public Ui::ProxyNode { Async::Task<> run() { _shouldLayout = true; + TimeStamp lastFrame = Sys::now(); while (true) { - auto e = App::makeEvent(Ui::FRAME_TIME); - event(*e); + auto frameStart = Sys::now(); + while (lastFrame < frameStart) { + auto e = App::makeEvent(Ui::FRAME_TIME); + event(*e); + lastFrame += 16_ms; + } if (_shouldLayout) { layout(bound()); @@ -199,7 +67,7 @@ struct Root : public Ui::ProxyNode { _repaint(); } - co_trya$(Sys::globalSched().sleepAsync(Sys::now() + 16_ms)); + co_trya$(Sys::globalSched().sleepAsync(lastFrame + 16_ms)); } } @@ -239,31 +107,18 @@ struct Root : public Ui::ProxyNode { }; Async::Task<> servAsync(Sys::Context &ctx) { - Hideo::Shell::State state = { .isMobile = false, .dateTime = Sys::dateTime(), .background = co_try$(Image::loadOrFallback("bundle://hideo-shell/wallpapers/winter.qoi"_url)), .noti = {}, .manifests = { - makeStrong(Mdi::INFORMATION_OUTLINE, "About"s, Gfx::BLUE_RAMP), - makeStrong(Mdi::CALCULATOR, "Calculator"s, Gfx::ORANGE_RAMP), - makeStrong(Mdi::PALETTE_SWATCH, "Color Picker"s, Gfx::RED_RAMP), - makeStrong(Mdi::COUNTER, "Counter"s, Gfx::GREEN_RAMP), - makeStrong(Mdi::DUCK, "Demos"s, Gfx::YELLOW_RAMP), - makeStrong(Mdi::FILE, "Files"s, Gfx::ORANGE_RAMP), - makeStrong(Mdi::FORMAT_FONT, "Fonts"s, Gfx::BLUE_RAMP), - makeStrong(Mdi::EMOTICON, "Hello World"s, Gfx::RED_RAMP), - makeStrong(Mdi::IMAGE, "Icons"s, Gfx::GREEN_RAMP), - makeStrong(Mdi::IMAGE, "Image Viewer"s, Gfx::YELLOW_RAMP), - makeStrong(Mdi::COG, "Settings"s, Gfx::ZINC_RAMP), - makeStrong(Mdi::TABLE, "Spreadsheet"s, Gfx::GREEN_RAMP), - makeStrong(Mdi::WIDGETS, "Widget Gallery"s, Gfx::BLUE_RAMP), + makeStrong(Mdi::CALCULATOR, "hideo-calculator.main"s, Gfx::ORANGE_RAMP), }, .instances = {} }; - auto rpc = Sys::Rpc::create(ctx); + auto endpoint = Rpc::Endpoint::create(ctx); auto root = makeStrong( Hideo::Shell::app(std::move(state)) | inputTranslator, co_try$(Framebuffer::open(ctx)) @@ -271,11 +126,11 @@ Async::Task<> servAsync(Sys::Context &ctx) { Async::detach(root->run()); - co_try$(rpc.send(Sys::Port::BUS, Meta::idOf())); - co_try$(rpc.send(Sys::Port::BUS, Meta::idOf())); + co_try$(endpoint.send(Rpc::Port::BUS, Meta::idOf())); + co_try$(endpoint.send(Rpc::Port::BUS, Meta::idOf())); while (true) { - auto msg = co_trya$(rpc.recvAsync()); + auto msg = co_trya$(endpoint.recvAsync()); if (msg.is()) { auto rawEvent = msg.unpack().unwrap(); diff --git a/src/srvs/grund-shell/manifest.json b/src/srvs/grund-shell/manifest.json index fc376d1415c..56f06876e22 100644 --- a/src/srvs/grund-shell/manifest.json +++ b/src/srvs/grund-shell/manifest.json @@ -12,6 +12,7 @@ }, "requires": [ "hideo-shell", + "karm-rpc", "karm-sys" ] } diff --git a/src/web/vaev-view/view.cpp b/src/web/vaev-view/view.cpp index e13d4209493..eac7c558202 100644 --- a/src/web/vaev-view/view.cpp +++ b/src/web/vaev-view/view.cpp @@ -67,9 +67,6 @@ struct View : public Ui::View { g.clear(rect, Gfx::WHITE); paint->paint(g, rect.offset(-bound().xy).cast()); - if (Ui::debugShowLayoutBounds) { - Layout::wireframe(*frag, g); - } g.pop(); }