mirror of
https://github.com/vicliu624/trail-mate.git
synced 2026-08-27 21:19:46 +00:00
feat(cardputerzero): record Linux session contracts
This commit is contained in:
@@ -23,6 +23,20 @@ framebuffer and evdev owner are promoted into this shell.
|
||||
- LoRa: SX1262 on `/dev/spidev0.1`, 500000 Hz, Reset=26, IRQ/DIO1=23,
|
||||
Busy=22, DIO2 RF switch enabled, DIO3 TCXO enabled
|
||||
|
||||
## Linux Session Component Facts
|
||||
|
||||
- notifications: standard `org.freedesktop.Notifications` D-Bus provider
|
||||
supplied by the Cardputer Zero user session
|
||||
- notification shell IPC: `$XDG_RUNTIME_DIR/cardputer-zero/notifyd.sock`,
|
||||
status/control only, never a notification creation path
|
||||
- input method: Fcitx5 text input through the normal Linux frontend path
|
||||
- IME display bridge: `cardputerzero-ui` Fcitx5 UI addon exports panel state to
|
||||
`$XDG_RUNTIME_DIR/cardputer-zero/ime-panel.sock`
|
||||
- IME panel: `cardputer-zero-ime-panel` renders candidate/preedit state as a
|
||||
Wayland layer-shell projection and does not submit text
|
||||
- expected session environment: `XMODIFIERS=@im=fcitx`,
|
||||
`SDL_IM_MODULE=fcitx`
|
||||
|
||||
## Build Entrypoint
|
||||
|
||||
- `builds/linux_cmake`
|
||||
@@ -37,6 +51,9 @@ May:
|
||||
- own future framebuffer, evdev, packaging, and launch details for this device
|
||||
- own future Trail Mate Linux SX1262 packet-radio wiring for the documented
|
||||
Cardputer Zero LoRa endpoint
|
||||
- route application notifications through the standard freedesktop notification
|
||||
contract
|
||||
- respect the Cardputer Zero Fcitx5 user-session boundary for text input
|
||||
|
||||
Must not:
|
||||
|
||||
@@ -45,6 +62,12 @@ Must not:
|
||||
- define protocol, chat, map, or storage semantics
|
||||
- absorb shared Linux runtime code that belongs in `platform/linux/common`
|
||||
- hide missing real-device hardware integration behind simulator naming
|
||||
- use Cardputer Zero notifyd shell IPC to create notifications
|
||||
- embed or fork the Cardputer Zero notifyd store, toast, or notification-center
|
||||
implementation
|
||||
- turn the IME panel socket into a text submission path
|
||||
- embed the Cardputer Zero Fcitx5 addon, panel renderer, input method engine,
|
||||
dictionary, or candidate selection policy inside Trail Mate
|
||||
|
||||
## Thin App Shell Entrypoint Declaration
|
||||
|
||||
|
||||
@@ -12,6 +12,8 @@ include("${TRAIL_MATE_REPO_ROOT}/cmake/TrailMateUxPacks.cmake")
|
||||
trailmate_add_ui_lvgl_ux_packs(trailmate_ui_lvgl_ux_packs)
|
||||
|
||||
add_library(trailmate_linux_cardputer_zero_shell
|
||||
src/cardputer_zero_input_method_port.cpp
|
||||
src/cardputer_zero_notification_port.cpp
|
||||
src/linux_cardputer_zero_app_shell.cpp
|
||||
"${TRAIL_MATE_REPO_ROOT}/modules/product_composition/src/target_profile.cpp"
|
||||
"${TRAIL_MATE_REPO_ROOT}/modules/product_composition/src/target_ux_binding.cpp")
|
||||
|
||||
@@ -17,4 +17,19 @@ Known hardware facts in this repo:
|
||||
- LoRa: SX1262 on `/dev/spidev0.1`, 500000 Hz, Reset=26, IRQ/DIO1=23,
|
||||
Busy=22, DIO2 RF switch and DIO3 TCXO enabled
|
||||
|
||||
Known Cardputer Zero Linux session facts in this shell:
|
||||
|
||||
- notifications are created through the standard
|
||||
`org.freedesktop.Notifications` D-Bus interface; the
|
||||
`$XDG_RUNTIME_DIR/cardputer-zero/notifyd.sock` channel is status/control only
|
||||
- text entry uses Fcitx5 through the normal Linux toolkit/frontend path
|
||||
- the Cardputer Zero IME addon/panel pair uses
|
||||
`$XDG_RUNTIME_DIR/cardputer-zero/ime-panel.sock` only to display preedit,
|
||||
candidates, and input-method state
|
||||
- Trail Mate does not own the notification daemon implementation, Fcitx5 UI
|
||||
addon, IME panel renderer, input method engine, dictionaries, or text commit
|
||||
path
|
||||
- the shared embedded touch/pinyin IME is not the Cardputer Zero Linux input
|
||||
method strategy
|
||||
|
||||
The simulator remains a separate development shell under `apps/linux_sim_shell`.
|
||||
|
||||
@@ -0,0 +1,82 @@
|
||||
#include "cardputer_zero_input_method_port.h"
|
||||
|
||||
#include <cstring>
|
||||
|
||||
namespace trailmate
|
||||
{
|
||||
namespace apps
|
||||
{
|
||||
namespace linux_cardputer_zero
|
||||
{
|
||||
namespace
|
||||
{
|
||||
|
||||
constexpr CardputerZeroInputMethodContract kContract = {
|
||||
"fcitx5",
|
||||
"Fcitx5 -> Linux toolkit frontend -> application",
|
||||
"cardputerzero-ui",
|
||||
"libcardputerzero-ui",
|
||||
"cardputer-zero-ime-panel",
|
||||
"cardputer-zero-ime-session",
|
||||
"cardputer-zero-ime.service",
|
||||
"cardputer-zero/ime-panel.sock",
|
||||
"unix-jsonl-addon-to-panel",
|
||||
"panel.update",
|
||||
"panel.hide",
|
||||
"state.update",
|
||||
"@im=fcitx",
|
||||
"fcitx",
|
||||
"Control+space",
|
||||
320,
|
||||
170,
|
||||
3,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
||||
const CardputerZeroInputMethodContract& CardputerZeroInputMethodPort::contract() const
|
||||
{
|
||||
return kContract;
|
||||
}
|
||||
|
||||
bool CardputerZeroInputMethodPort::validate() const
|
||||
{
|
||||
const auto& c = contract();
|
||||
return std::strcmp(c.framework_name, "fcitx5") == 0 &&
|
||||
std::strcmp(c.text_submission_path,
|
||||
"Fcitx5 -> Linux toolkit frontend -> application") == 0 &&
|
||||
std::strcmp(c.ui_addon_name, "cardputerzero-ui") == 0 &&
|
||||
std::strcmp(c.ui_addon_library, "libcardputerzero-ui") == 0 &&
|
||||
std::strcmp(c.panel_executable, "cardputer-zero-ime-panel") == 0 &&
|
||||
std::strcmp(c.session_executable, "cardputer-zero-ime-session") == 0 &&
|
||||
std::strcmp(c.user_service, "cardputer-zero-ime.service") == 0 &&
|
||||
std::strcmp(c.panel_socket_suffix, "cardputer-zero/ime-panel.sock") == 0 &&
|
||||
std::strcmp(c.panel_transport, "unix-jsonl-addon-to-panel") == 0 &&
|
||||
std::strcmp(c.panel_update_message, "panel.update") == 0 &&
|
||||
std::strcmp(c.panel_hide_message, "panel.hide") == 0 &&
|
||||
std::strcmp(c.state_update_message, "state.update") == 0 &&
|
||||
std::strcmp(c.xmodifiers, "@im=fcitx") == 0 &&
|
||||
std::strcmp(c.sdl_im_module, "fcitx") == 0 &&
|
||||
std::strcmp(c.trigger_key, "Control+space") == 0 &&
|
||||
c.screen_width == 320 &&
|
||||
c.screen_height == 170 &&
|
||||
c.max_exported_candidates == 3 &&
|
||||
!c.app_owns_input_method_engine &&
|
||||
!c.app_owns_candidate_display &&
|
||||
!c.app_owns_text_commit &&
|
||||
!c.panel_socket_commits_text &&
|
||||
!c.panel_requests_keyboard_focus &&
|
||||
!c.missing_panel_blocks_text_input &&
|
||||
!c.uses_embedded_touch_ime;
|
||||
}
|
||||
|
||||
} // namespace linux_cardputer_zero
|
||||
} // namespace apps
|
||||
} // namespace trailmate
|
||||
@@ -0,0 +1,48 @@
|
||||
#pragma once
|
||||
|
||||
namespace trailmate
|
||||
{
|
||||
namespace apps
|
||||
{
|
||||
namespace linux_cardputer_zero
|
||||
{
|
||||
|
||||
struct CardputerZeroInputMethodContract
|
||||
{
|
||||
const char* framework_name;
|
||||
const char* text_submission_path;
|
||||
const char* ui_addon_name;
|
||||
const char* ui_addon_library;
|
||||
const char* panel_executable;
|
||||
const char* session_executable;
|
||||
const char* user_service;
|
||||
const char* panel_socket_suffix;
|
||||
const char* panel_transport;
|
||||
const char* panel_update_message;
|
||||
const char* panel_hide_message;
|
||||
const char* state_update_message;
|
||||
const char* xmodifiers;
|
||||
const char* sdl_im_module;
|
||||
const char* trigger_key;
|
||||
int screen_width;
|
||||
int screen_height;
|
||||
int max_exported_candidates;
|
||||
bool app_owns_input_method_engine;
|
||||
bool app_owns_candidate_display;
|
||||
bool app_owns_text_commit;
|
||||
bool panel_socket_commits_text;
|
||||
bool panel_requests_keyboard_focus;
|
||||
bool missing_panel_blocks_text_input;
|
||||
bool uses_embedded_touch_ime;
|
||||
};
|
||||
|
||||
class CardputerZeroInputMethodPort
|
||||
{
|
||||
public:
|
||||
const CardputerZeroInputMethodContract& contract() const;
|
||||
bool validate() const;
|
||||
};
|
||||
|
||||
} // namespace linux_cardputer_zero
|
||||
} // namespace apps
|
||||
} // namespace trailmate
|
||||
@@ -0,0 +1,107 @@
|
||||
#include "cardputer_zero_notification_port.h"
|
||||
|
||||
#include <cstring>
|
||||
|
||||
namespace trailmate
|
||||
{
|
||||
namespace apps
|
||||
{
|
||||
namespace linux_cardputer_zero
|
||||
{
|
||||
namespace
|
||||
{
|
||||
|
||||
constexpr FreedesktopNotificationsContract kContract = {
|
||||
"org.freedesktop.Notifications",
|
||||
"/org/freedesktop/Notifications",
|
||||
"org.freedesktop.Notifications",
|
||||
"Notify",
|
||||
"susssasa{sv}i",
|
||||
"u",
|
||||
"CloseNotification",
|
||||
"GetCapabilities",
|
||||
"GetServerInformation",
|
||||
"NotificationClosed",
|
||||
"ActionInvoked",
|
||||
"body",
|
||||
"actions",
|
||||
"persistence",
|
||||
"urgency",
|
||||
"desktop-entry",
|
||||
"transient",
|
||||
"category",
|
||||
"resident",
|
||||
"cardputer-zero/notifyd.sock",
|
||||
false,
|
||||
};
|
||||
|
||||
const char* safeString(const char* value)
|
||||
{
|
||||
return value != nullptr ? value : "";
|
||||
}
|
||||
|
||||
std::uint8_t urgencyHint(NotificationUrgency urgency)
|
||||
{
|
||||
switch (urgency)
|
||||
{
|
||||
case NotificationUrgency::Low:
|
||||
return 0;
|
||||
case NotificationUrgency::Critical:
|
||||
return 2;
|
||||
case NotificationUrgency::Normal:
|
||||
default:
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
const FreedesktopNotificationsContract& CardputerZeroNotificationPort::contract() const
|
||||
{
|
||||
return kContract;
|
||||
}
|
||||
|
||||
FreedesktopNotifyCall
|
||||
CardputerZeroNotificationPort::makeNotifyCall(const NotificationRequest& request) const
|
||||
{
|
||||
FreedesktopNotifyCall call;
|
||||
call.contract = &contract();
|
||||
call.app_name = safeString(request.app_name);
|
||||
call.replaces_id = request.replaces_id;
|
||||
call.app_icon = safeString(request.app_icon);
|
||||
call.summary = safeString(request.summary);
|
||||
call.body = safeString(request.body);
|
||||
call.urgency_hint = urgencyHint(request.urgency);
|
||||
call.expire_timeout_ms = request.expire_timeout_ms;
|
||||
return call;
|
||||
}
|
||||
|
||||
bool CardputerZeroNotificationPort::validate() const
|
||||
{
|
||||
const auto& c = contract();
|
||||
return std::strcmp(c.bus_name, "org.freedesktop.Notifications") == 0 &&
|
||||
std::strcmp(c.object_path, "/org/freedesktop/Notifications") == 0 &&
|
||||
std::strcmp(c.interface_name, "org.freedesktop.Notifications") == 0 &&
|
||||
std::strcmp(c.notify_method, "Notify") == 0 &&
|
||||
std::strcmp(c.notify_signature, "susssasa{sv}i") == 0 &&
|
||||
std::strcmp(c.notify_return_signature, "u") == 0 &&
|
||||
std::strcmp(c.close_method, "CloseNotification") == 0 &&
|
||||
std::strcmp(c.get_capabilities_method, "GetCapabilities") == 0 &&
|
||||
std::strcmp(c.get_server_information_method, "GetServerInformation") == 0 &&
|
||||
std::strcmp(c.notification_closed_signal, "NotificationClosed") == 0 &&
|
||||
std::strcmp(c.action_invoked_signal, "ActionInvoked") == 0 &&
|
||||
std::strcmp(c.capability_body, "body") == 0 &&
|
||||
std::strcmp(c.capability_actions, "actions") == 0 &&
|
||||
std::strcmp(c.capability_persistence, "persistence") == 0 &&
|
||||
std::strcmp(c.hint_urgency, "urgency") == 0 &&
|
||||
std::strcmp(c.hint_desktop_entry, "desktop-entry") == 0 &&
|
||||
std::strcmp(c.hint_transient, "transient") == 0 &&
|
||||
std::strcmp(c.hint_category, "category") == 0 &&
|
||||
std::strcmp(c.hint_resident, "resident") == 0 &&
|
||||
std::strcmp(c.shell_ipc_socket_suffix, "cardputer-zero/notifyd.sock") == 0 &&
|
||||
!c.shell_ipc_creates_notifications;
|
||||
}
|
||||
|
||||
} // namespace linux_cardputer_zero
|
||||
} // namespace apps
|
||||
} // namespace trailmate
|
||||
@@ -0,0 +1,77 @@
|
||||
#pragma once
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
namespace trailmate
|
||||
{
|
||||
namespace apps
|
||||
{
|
||||
namespace linux_cardputer_zero
|
||||
{
|
||||
|
||||
enum class NotificationUrgency : std::uint8_t
|
||||
{
|
||||
Low = 0,
|
||||
Normal = 1,
|
||||
Critical = 2,
|
||||
};
|
||||
|
||||
struct NotificationRequest
|
||||
{
|
||||
const char* app_name = "Trail Mate";
|
||||
const char* summary = "";
|
||||
const char* body = "";
|
||||
const char* app_icon = "";
|
||||
std::uint32_t replaces_id = 0;
|
||||
NotificationUrgency urgency = NotificationUrgency::Normal;
|
||||
int expire_timeout_ms = -1;
|
||||
};
|
||||
|
||||
struct FreedesktopNotificationsContract
|
||||
{
|
||||
const char* bus_name;
|
||||
const char* object_path;
|
||||
const char* interface_name;
|
||||
const char* notify_method;
|
||||
const char* notify_signature;
|
||||
const char* notify_return_signature;
|
||||
const char* close_method;
|
||||
const char* get_capabilities_method;
|
||||
const char* get_server_information_method;
|
||||
const char* notification_closed_signal;
|
||||
const char* action_invoked_signal;
|
||||
const char* capability_body;
|
||||
const char* capability_actions;
|
||||
const char* capability_persistence;
|
||||
const char* hint_urgency;
|
||||
const char* hint_desktop_entry;
|
||||
const char* hint_transient;
|
||||
const char* hint_category;
|
||||
const char* hint_resident;
|
||||
const char* shell_ipc_socket_suffix;
|
||||
bool shell_ipc_creates_notifications;
|
||||
};
|
||||
|
||||
struct FreedesktopNotifyCall
|
||||
{
|
||||
const FreedesktopNotificationsContract* contract = nullptr;
|
||||
const char* app_name = "";
|
||||
std::uint32_t replaces_id = 0;
|
||||
const char* app_icon = "";
|
||||
const char* summary = "";
|
||||
const char* body = "";
|
||||
std::uint8_t urgency_hint = 1;
|
||||
int expire_timeout_ms = -1;
|
||||
};
|
||||
|
||||
class CardputerZeroNotificationPort
|
||||
{
|
||||
public:
|
||||
const FreedesktopNotificationsContract& contract() const;
|
||||
FreedesktopNotifyCall makeNotifyCall(const NotificationRequest& request) const;
|
||||
bool validate() const;
|
||||
};
|
||||
|
||||
} // namespace linux_cardputer_zero
|
||||
} // namespace apps
|
||||
} // namespace trailmate
|
||||
@@ -47,6 +47,16 @@ LinuxCardputerZeroAppShell::boardFacts() const
|
||||
return boards::cardputerzero::kBoardFacts;
|
||||
}
|
||||
|
||||
const CardputerZeroNotificationPort& LinuxCardputerZeroAppShell::notificationPort() const
|
||||
{
|
||||
return notification_port_;
|
||||
}
|
||||
|
||||
const CardputerZeroInputMethodPort& LinuxCardputerZeroAppShell::inputMethodPort() const
|
||||
{
|
||||
return input_method_port_;
|
||||
}
|
||||
|
||||
bool LinuxCardputerZeroAppShell::validate() const
|
||||
{
|
||||
const auto& facts = boardFacts();
|
||||
@@ -76,7 +86,9 @@ bool LinuxCardputerZeroAppShell::validate() const
|
||||
product_composition::findTargetUxBinding(targetId()) != nullptr &&
|
||||
config_.ux_pack_id != nullptr &&
|
||||
std::strcmp(config_.ux_pack_id, activeUxPackId()) == 0 &&
|
||||
ui_lvgl_ux::findUxPackById(activeUxPackId()) != nullptr;
|
||||
ui_lvgl_ux::findUxPackById(activeUxPackId()) != nullptr &&
|
||||
notificationPort().validate() &&
|
||||
inputMethodPort().validate();
|
||||
}
|
||||
|
||||
} // namespace linux_cardputer_zero
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
#pragma once
|
||||
|
||||
#include "boards/cardputerzero/board_facts.h"
|
||||
#include "cardputer_zero_input_method_port.h"
|
||||
#include "cardputer_zero_notification_port.h"
|
||||
|
||||
#include "product_composition/target_profile.h"
|
||||
|
||||
@@ -28,10 +30,14 @@ class LinuxCardputerZeroAppShell
|
||||
const product_composition::TargetProfile* targetProfile() const;
|
||||
const char* activeUxPackId() const;
|
||||
const boards::cardputerzero::CardputerZeroBoardFacts& boardFacts() const;
|
||||
const CardputerZeroNotificationPort& notificationPort() const;
|
||||
const CardputerZeroInputMethodPort& inputMethodPort() const;
|
||||
bool validate() const;
|
||||
|
||||
private:
|
||||
LinuxCardputerZeroAppShellConfig config_{};
|
||||
CardputerZeroNotificationPort notification_port_{};
|
||||
CardputerZeroInputMethodPort input_method_port_{};
|
||||
};
|
||||
|
||||
} // namespace linux_cardputer_zero
|
||||
|
||||
@@ -38,6 +38,49 @@ int main()
|
||||
assert(facts.lora_dio2_as_rf_switch);
|
||||
assert(facts.lora_dio3_tcxo_voltage);
|
||||
|
||||
const auto& notifications = shell.notificationPort().contract();
|
||||
assert(std::strcmp(notifications.bus_name, "org.freedesktop.Notifications") == 0);
|
||||
assert(std::strcmp(notifications.object_path, "/org/freedesktop/Notifications") == 0);
|
||||
assert(std::strcmp(notifications.notify_signature, "susssasa{sv}i") == 0);
|
||||
assert(std::strcmp(notifications.capability_body, "body") == 0);
|
||||
assert(std::strcmp(notifications.capability_actions, "actions") == 0);
|
||||
assert(std::strcmp(notifications.capability_persistence, "persistence") == 0);
|
||||
assert(std::strcmp(notifications.shell_ipc_socket_suffix,
|
||||
"cardputer-zero/notifyd.sock") == 0);
|
||||
assert(!notifications.shell_ipc_creates_notifications);
|
||||
|
||||
trailmate::apps::linux_cardputer_zero::NotificationRequest notification_request;
|
||||
notification_request.summary = "Mesh";
|
||||
notification_request.body = "Message received";
|
||||
notification_request.urgency =
|
||||
trailmate::apps::linux_cardputer_zero::NotificationUrgency::Critical;
|
||||
const auto notify_call = shell.notificationPort().makeNotifyCall(notification_request);
|
||||
assert(notify_call.contract == ¬ifications);
|
||||
assert(std::strcmp(notify_call.summary, "Mesh") == 0);
|
||||
assert(std::strcmp(notify_call.body, "Message received") == 0);
|
||||
assert(notify_call.urgency_hint == 2);
|
||||
|
||||
const auto& input_method = shell.inputMethodPort().contract();
|
||||
assert(std::strcmp(input_method.framework_name, "fcitx5") == 0);
|
||||
assert(std::strcmp(input_method.ui_addon_name, "cardputerzero-ui") == 0);
|
||||
assert(std::strcmp(input_method.panel_socket_suffix,
|
||||
"cardputer-zero/ime-panel.sock") == 0);
|
||||
assert(std::strcmp(input_method.panel_update_message, "panel.update") == 0);
|
||||
assert(std::strcmp(input_method.panel_hide_message, "panel.hide") == 0);
|
||||
assert(std::strcmp(input_method.state_update_message, "state.update") == 0);
|
||||
assert(std::strcmp(input_method.xmodifiers, "@im=fcitx") == 0);
|
||||
assert(std::strcmp(input_method.sdl_im_module, "fcitx") == 0);
|
||||
assert(input_method.screen_width == 320);
|
||||
assert(input_method.screen_height == 170);
|
||||
assert(input_method.max_exported_candidates == 3);
|
||||
assert(!input_method.app_owns_input_method_engine);
|
||||
assert(!input_method.app_owns_candidate_display);
|
||||
assert(!input_method.app_owns_text_commit);
|
||||
assert(!input_method.panel_socket_commits_text);
|
||||
assert(!input_method.panel_requests_keyboard_focus);
|
||||
assert(!input_method.missing_panel_blocks_text_input);
|
||||
assert(!input_method.uses_embedded_touch_ime);
|
||||
|
||||
const auto* profile = shell.targetProfile();
|
||||
assert(profile != nullptr);
|
||||
assert(profile->platform == product_composition::TargetPlatform::Linux);
|
||||
|
||||
@@ -26,6 +26,11 @@ This record describes current repo evidence for the Linux Cardputer Zero route.
|
||||
- LoRa SPI speed: 500000 Hz
|
||||
- LoRa GPIO control lines: Reset=26, IRQ/DIO1=23, Busy=22
|
||||
- LoRa DIO2 RF switch and DIO3 TCXO voltage control are required
|
||||
- Cardputer Zero user-session notifications are provided through the standard
|
||||
`org.freedesktop.Notifications` D-Bus interface, not through a private app API
|
||||
- Cardputer Zero user-session input method display is provided by a Fcitx5 UI
|
||||
addon plus Wayland panel; text submission stays on the normal Linux input
|
||||
method path
|
||||
- display/input ownership for the real Pi OS path is not yet closed
|
||||
- current dedicated app shell baseline is build-owned by
|
||||
`apps/linux_cardputer_zero`
|
||||
@@ -36,6 +41,7 @@ This record describes current repo evidence for the Linux Cardputer Zero route.
|
||||
- evdev keyboard mapping sampled from the real device
|
||||
- Trail Mate Linux SX1262 runtime validation against `/dev/spidev0.1` and the
|
||||
documented GPIO lines
|
||||
- notification daemon and Fcitx5 user-session integration on real device image
|
||||
- launch/package route for the portable Linux device
|
||||
|
||||
The Linux simulator remains a separate target under `apps/linux_sim_shell`.
|
||||
|
||||
@@ -19,7 +19,7 @@ routes.
|
||||
| `twatch` | `twatch` | `builds/esp_idf` | `apps/esp32_lvgl` | ESP-IDF | LVGL | `watch_compact` | `compatibility` | `watch_compact_ui` | `watch_compact_manifest` | `watch_compact` | `PendingHardwareValidation` | current repo evidence is board and variant data, not migrated IDF defaults | `apps/esp32_lvgl + builds/esp_idf + boards/twatch` |
|
||||
| `uconsole` | `uconsole` | `builds/linux_cmake` | `apps/linux_uconsole_gtk` | Linux | GTK | `uconsole_desktop` | `uconsole_desktop` | `uconsole_desktop_ui` | `uconsole_desktop_manifest` | `uconsole_desktop` | `Active` | none for UX pack selection | `apps/linux_uconsole_gtk + builds/linux_cmake + boards/uconsole` |
|
||||
| `linux_sim` | `linux_sim` | `builds/linux_cmake` | `apps/linux_sim_shell` | Linux | ASCII | `simulator_full` | `simulator_full` | `simulator_full_ui` | `simulator_full_manifest` | `simulator_full` | `Active` | none for simulator UX pack selection | `apps/linux_sim_shell + builds/linux_cmake` |
|
||||
| `cardputerzero` | `cardputerzero` | `builds/linux_cmake` | `apps/linux_cardputer_zero` | Linux | ASCII | `cardputer_compact` | `cardputer_compact` | `cardputer_compact_ui` | `cardputer_compact_manifest` | `cardputer_compact` | `PendingHardwareValidation` | framebuffer, evdev, launch, and packaging still need real device validation | `apps/linux_cardputer_zero + builds/linux_cmake + boards/cardputerzero` |
|
||||
| `cardputerzero` | `cardputerzero` | `builds/linux_cmake` | `apps/linux_cardputer_zero` | Linux | ASCII | `cardputer_compact` | `cardputer_compact` | `cardputer_compact_ui` | `cardputer_compact_manifest` | `cardputer_compact` | `PendingHardwareValidation` | framebuffer, evdev, notifyd session, Fcitx5 session, launch, and packaging still need real device validation | `apps/linux_cardputer_zero + builds/linux_cmake + boards/cardputerzero` |
|
||||
| `gat562_mesh_evb_pro` | `gat562_mesh_evb_pro` | `builds/pio_nrf52` | `apps/nrf52_node` | PlatformIO | Headless | `node_headless` | `tiny_node_status` | `node_headless_ui` | `node_headless_manifest` | `headless_node` | `Headless` | current executable UX pack is `tiny_node_status`; board hardware still records a 128 x 64 display | `apps/nrf52_node + builds/pio_nrf52 + boards/gat562_mesh_evb_pro` |
|
||||
|
||||
## Pending Evidence
|
||||
@@ -29,7 +29,7 @@ routes.
|
||||
| `tlora_pager` | ESP-IDF target defaults and hardware validation for the requested IDF route | `builds/esp_idf + boards/tlora_pager` |
|
||||
| `tdeck` | ESP-IDF target defaults and hardware validation for the requested IDF route | `builds/esp_idf + boards/tdeck` |
|
||||
| `twatch` | ESP-IDF target defaults and hardware validation for the requested IDF route | `builds/esp_idf + boards/twatch` |
|
||||
| `cardputerzero` | real Cardputer Zero framebuffer, evdev, launch, and packaging validation | `apps/linux_cardputer_zero + boards/cardputerzero` |
|
||||
| `cardputerzero` | real Cardputer Zero framebuffer, evdev, notifyd session, Fcitx5 session, launch, and packaging validation | `apps/linux_cardputer_zero + boards/cardputerzero` |
|
||||
|
||||
## Batch 2 Status Tokens
|
||||
|
||||
|
||||
@@ -35,7 +35,8 @@ absorb GTK, simulator, framebuffer, device-shell, or runtime behavior into
|
||||
|
||||
`cardputerzero` is no longer described as a future Raspberry Pi simulator path.
|
||||
Its current owner is `apps/linux_cardputer_zero`; the remaining work is real
|
||||
Cardputer Zero framebuffer, evdev, launch, and package validation.
|
||||
Cardputer Zero framebuffer, evdev, notification daemon session, Fcitx5 session,
|
||||
launch, and package validation.
|
||||
|
||||
## Non-Goals
|
||||
|
||||
|
||||
@@ -9,6 +9,11 @@ Compact 320 x 170 landscape keyboard device.
|
||||
Keyboard-first input. Pointer, touch, and trackball are absent in the current
|
||||
Cardputer Zero board facts.
|
||||
|
||||
On the Linux device route, text composition is owned by the user-session Fcitx5
|
||||
stack. Trail Mate's compact UX accepts committed text from the normal Linux
|
||||
input frontend path; the Cardputer Zero IME panel socket is display-only and is
|
||||
not a Trail Mate text submission API.
|
||||
|
||||
## Feature Set
|
||||
|
||||
Compact chat/status workflow with compact map and practical GPS/team actions.
|
||||
@@ -44,7 +49,7 @@ uses ASCII renderer until framebuffer ownership is validated.
|
||||
|
||||
## Deferred Decisions
|
||||
|
||||
Real-device keyboard sampling, framebuffer handoff, launch, and packaging remain
|
||||
deferred.
|
||||
Real-device keyboard sampling, framebuffer handoff, notification daemon session
|
||||
validation, Fcitx5 session validation, launch, and packaging remain deferred.
|
||||
|
||||
Board describes. Target chooses. UX Pack presents. Renderer draws.
|
||||
|
||||
Reference in New Issue
Block a user