summaryrefslogtreecommitdiffhomepage
path: root/packages/kernel/src/server_impl.hpp
diff options
context:
space:
mode:
authorAdam Malczewski <[email protected]>2026-06-13 00:17:33 +0900
committerAdam Malczewski <[email protected]>2026-06-13 00:17:33 +0900
commit803fd2687a5f6ead0644f9c952bed6e3e4ef7ed9 (patch)
tree68d727df9c0f08a7a08c2c464f95d8c82fb8789e /packages/kernel/src/server_impl.hpp
parentc102a1b67a70149b6f9c9b2cfd8b31ceb52c09b7 (diff)
downloadunbox-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.hpp37
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