diff options
| author | Adam Malczewski <[email protected]> | 2026-06-13 00:17:33 +0900 |
|---|---|---|
| committer | Adam Malczewski <[email protected]> | 2026-06-13 00:17:33 +0900 |
| commit | 803fd2687a5f6ead0644f9c952bed6e3e4ef7ed9 (patch) | |
| tree | 68d727df9c0f08a7a08c2c464f95d8c82fb8789e /packages/kernel/src/server_impl.hpp | |
| parent | c102a1b67a70149b6f9c9b2cfd8b31ceb52c09b7 (diff) | |
| download | unbox-803fd2687a5f6ead0644f9c952bed6e3e4ef7ed9.tar.gz unbox-803fd2687a5f6ead0644f9c952bed6e3e4ef7ed9.zip | |
Slice 5: real ui substrate + unified input routing + touch-mode; spike retired
The ui substrate is now the extension-facing contract (unbox/kernel/ui.hpp):
Host::ui() -> UiSubstrate::create_surface(spec) -> UiSurface with typed
scalar bindings (int/double/bool/string getters), data-event callbacks
(error-isolated per extension), dirty(), geometry/visibility — RMLUi and
GL stay kernel-private. Production sync: glFinish replaced by
EGL_KHR_fence_sync + 2-deep wlr_swapchain. ui_spike retired (orientation
guard + dirty-cycle coverage live on as substrate tests).
Input: ONE kernel routing path feeds pointer AND touch into ui surfaces
with consume-or-pass semantics and implicit-grab ownership (the consumer
of a press owns the matching release; per touch point too) — fixes
drag-release-over-ui sticking. touch-mode: state machine + debounce +
on_touch_mode_changed notification, NO visual scaling (user decision
after hardware hands-on; dp-ratio stays 1.0; see plan §2).
ext-xdg-shell: GrabMachine generalized to pointer-OR-touch interaction
source (touch titlebar drag works; originating-point pinning); fixed the
seat implicit-grab leak (suppressed release after forwarded press
swallowed all later touch-downs — pointer/touch alternation doctested);
factory renamed create(). ext-layer-shell: on_demand keyboard
interactivity via scene hit resolution. host-bin: --ui-demo extension
(temporary acceptance demo on the public contract, dies in slice 6).
User hands-on verified: same surface by mouse and finger, tap counter,
touch-mode neutrality, no click-through, drag alternation, fuzzel
on_demand. 113 doctest cases green, ASan/UBSan clean (our code), idle
RSS ≈78 MiB. Harness: UX-feel hands-on lesson (ORCHESTRATOR §2.6),
nested-run pkill/setsid notes, touch-mode glossary redefinition.
Diffstat (limited to 'packages/kernel/src/server_impl.hpp')
| -rw-r--r-- | packages/kernel/src/server_impl.hpp | 37 |
1 files changed, 31 insertions, 6 deletions
diff --git a/packages/kernel/src/server_impl.hpp b/packages/kernel/src/server_impl.hpp index c5615b2..3407883 100644 --- a/packages/kernel/src/server_impl.hpp +++ b/packages/kernel/src/server_impl.hpp @@ -2,10 +2,11 @@ #include <unbox/kernel/host.hpp> #include <unbox/kernel/server.hpp> +#include <unbox/kernel/ui.hpp> #include <unbox/kernel/wlr.hpp> #include "listener.hpp" -#include "ui_spike.hpp" +#include "ui_substrate.hpp" #include <array> #include <cstdint> @@ -83,9 +84,10 @@ struct Server::Impl : detail::DisableSink { // attach nodes via Host::scene_layer(); the kernel owns them. std::array<wlr_scene_tree*, 5> scene_layers{}; - // Slice-3 spike (kernel-internal; not a contract). Torn down in shutdown() - // BEFORE scene/renderer/allocator. - std::unique_ptr<UiSpike> ui_spike; + // The ui substrate (the kernel's RMLUi subsystem behind <unbox/kernel/ui.hpp>). + // Kernel-owned; torn down in shutdown() BEFORE scene/renderer/allocator. Its + // per-extension facades (PerExtensionUi, one per HostImpl) borrow it. + std::unique_ptr<Substrate> substrate; std::list<std::unique_ptr<Output>> outputs; std::list<std::unique_ptr<Keyboard>> keyboards; @@ -148,7 +150,7 @@ struct Server::Impl : detail::DisableSink { void init(); // throws std::runtime_error on any component failure void shutdown(); void handle_new_output(wlr_output* output); - void start_ui_spike(); // slice-3 spike; never throws, may no-op + void start_substrate(); // builds the ui substrate; never throws, may be unavailable void register_hook(detail::HookBase& hook); // track for purge/disable // server.cpp — extension host @@ -166,11 +168,32 @@ struct Server::Impl : detail::DisableSink { void emit_pointer_motion(std::uint32_t time_msec); }; +// ---- Per-extension ui-substrate facade -------------------------------------- +// +// The public UiSubstrate an extension gets from Host::ui(). Injects the owning +// extension id (for error isolation) and resolves a UiSurfaceSpec's SceneLayer +// to the kernel's scene-layer tree, then delegates to the shared Substrate. +// Owned by its HostImpl; borrows the kernel-owned Substrate. + +class PerExtensionUi final : public UiSubstrate { +public: + PerExtensionUi(Server::Impl* server, ExtensionId id) : server_(server), id_(id) {} + + auto create_surface(const UiSurfaceSpec& spec) -> std::unique_ptr<UiSurface> override; + auto available() const -> bool override; + auto touch_mode() const -> bool override; + void set_touch_mode_override(TouchModeOverride ov) override; + +private: + Server::Impl* server_; + ExtensionId id_; +}; + // ---- Per-extension Host facade ---------------------------------------------- class HostImpl final : public Host { public: - HostImpl(Server::Impl* server, ExtensionId id) : server_(server), id_(id) {} + HostImpl(Server::Impl* server, ExtensionId id) : server_(server), id_(id), ui_(server, id) {} auto display() -> wl_display* override { return server_->display; } auto scene() -> wlr_scene* override { return server_->scene; } @@ -181,6 +204,7 @@ public: auto scene_layer(SceneLayer layer) -> wlr_scene_tree* override { return server_->scene_layers[static_cast<std::size_t>(layer)]; } + auto ui() -> UiSubstrate& override { return ui_; } auto on_output_added() -> Event<const OutputEvent&>& override { return server_->ev_output_added; @@ -231,6 +255,7 @@ protected: private: Server::Impl* server_; ExtensionId id_; + PerExtensionUi ui_; }; } // namespace unbox::kernel |
