API — ICoreBlocks/ICoreStudio/StudioObjects/Panels/Terminal
The public contract of 5 header(s) under src/ICoreBlocks/ICoreStudio/StudioObjects/Panels/Terminal — 5 class/struct definition(s), 66 declaration(s). Each section shows the header's banner and its public (and protected-virtual) surface exactly as the file writes it.
| Header | Defines | Declarations | Bases |
|---|---|---|---|
ICoreTerminalHost.h | ICoreTerminalHost | 1 | — |
ICoreTerminalHostClient.h | ICoreTerminalHostClient | 17 | — |
ICoreTerminalSession.h | ICoreTerminalSession | 16 | — |
ICoreTerminalGridView.h | ICoreTerminalGridView | 29 | public ICoreWidget |
ICoreTerminalMenuPanel.h | ICoreTerminalMenuPanel | 3 | public ICoreWidget |
ICoreTerminalHost.h#
src/ICoreBlocks/ICoreStudio/StudioObjects/Panels/Terminal/ICoreTerminalHost.h
ICoreTerminalHost#
ICoreTerminalHost.h:42 · class · final · 1 declaration(s)
ICoreTerminalHost The process that owns a Terminal panel's shell, so the shell -- and a coding agent running in it -- outlives the app (AGENT_BRIDGE.md AB.32).
class ICoreTerminalHost final {
public:
enum Frame : char {
// client -> host
Attach = 'A', // payload: the client's process id, in decimal
Input = 'D', // payload: bytes for the shell (also host -> client: its output)
Resize = 'R', // payload: "<columns> <rows>"
Kill = 'K', // no payload: hang the shell up and end; accepted without an Attach
// host -> client
Hello = 'H', // payload: "shellPid=<n> reattached=<0|1>"
Output = 'D',
Replayed = 'Y', // after the kept output that follows a Hello: payload "1" on a reattach
Exited = 'X', // payload: "<exit code> <1 if a signal ended it, else 0>"
};
// A process that sets this to the write end of a pipe and starts
// `--terminal-host ...` gets the daemon directly (no stage 1): it writes
// "R<host pid> <shell pid>" or "E<why>" there once, and closes it.
static constexpr const char* kReadyVariable = "ICORE_TERMINAL_HOST_READY_FD";
// Output a host keeps for a client that attaches later.
static constexpr long kHistoryBytes = 1L << 20;
// The first argument main() checks for.
static constexpr const char* kSwitch = "--terminal-host";
// The whole process, given main()'s arguments. Returns its exit status.
static int run(int argc, char** argv);
};
};
ICoreTerminalHostClient.h#
src/ICoreBlocks/ICoreStudio/StudioObjects/Panels/Terminal/ICoreTerminalHostClient.h
ICoreTerminalHostClient#
ICoreTerminalHostClient.h:32 · class · final · pImpl · nested HostInfo · 17 declaration(s)
ICoreTerminalHostClient The app's end of an ICoreTerminalHost: the Terminal panel's shell lives in that separate process, so it -- and a coding agent running in it -- outlives an app that crashes (...
class ICoreTerminalHostClient final {
public:
ICoreTerminalHostClient();
~ICoreTerminalHostClient();
ICoreTerminalHostClient(const ICoreTerminalHostClient&) = delete;
ICoreTerminalHostClient& operator=(const ICoreTerminalHostClient&) = delete;
// Whether this platform has a host, and it was not turned off with
// ICORE_TERMINAL_IN_PROCESS.
[[nodiscard]] static bool isAvailable();
// Callbacks first: delivery may begin as soon as start() or adopt() returns.
void onBytesRead(std::function<void(const ICoreByteArray& bytes)> fn);
void onClosed(std::function<void(int exitCode, bool crashed)> fn);
// After the output a host kept has been delivered; `reattached` is true when
// this client took over a shell another app left behind.
void onReplayed(std::function<void(bool reattached)> fn);
// Starts a host running `program` in `workingDirectory`, with this process's
// environment plus `environment` (later names win). False, with
// errorString(), when the host did not come up.
bool start(const ICoreString& program, const ICoreStringList& arguments,
const std::vector<std::pair<std::string, std::string>>& environment,
const ICoreString& workingDirectory, int columns, int rows);
// Takes over a host whose app is gone, the newest first. False when there
// is none.
bool adopt(int columns, int rows);
[[nodiscard]] bool isRunning() const;
void write(const ICoreByteArray& data);
void setViewport(int columns, int rows);
[[nodiscard]] ICoreString errorString() const;
void clearCallbacks();
// <application home>/terminals: one JSON file per live host.
[[nodiscard]] static std::filesystem::path registryFolder();
struct HostInfo {
int hostPid = 0;
int shellPid = 0;
int ownerPid = 0; // the app attached last; 0 or a dead pid when none is
bool orphaned = false; // no live app holds it
std::string cwd;
std::string program;
std::string socket;
};
// The live hosts in the registry; files of hosts that are gone are removed.
[[nodiscard]] static std::vector<HostInfo> hosts();
// Ends a host (and its shell). False when it was not reachable.
static bool endHost(const HostInfo& host);
private:
class Impl; // the two-line residue; state lives here
std::unique_ptr<Impl> impl;
};
ICoreTerminalSession.h#
src/ICoreBlocks/ICoreStudio/StudioObjects/Panels/Terminal/ICoreTerminalSession.h
ICoreTerminalSession#
ICoreTerminalSession.h:53 · class · pImpl · 16 declaration(s)
A live shell under a pseudo-terminal, and the terminal state it is drawing.
class ICoreTerminalSession {
public:
ICoreTerminalSession();
~ICoreTerminalSession();
ICoreTerminalSession(const ICoreTerminalSession&) = delete;
ICoreTerminalSession& operator=(const ICoreTerminalSession&) = delete;
// --- setup, before start() ----------------------------------------------
// Where the shell starts. Ignored after start(): moving a live shell is
// the user's job, through the shell, which is the whole point of T5.3.
void setWorkingDirectory(const ICoreString& directory);
// --- running ------------------------------------------------------------
// Starts the login shell at `columns` x `rows` cells. False if the shell
// could not be started, with the reason already written to the screen so
// the user sees it rather than an empty panel.
bool start(int columns, int rows);
[[nodiscard]] bool isRunning() const;
// Take the shell down and bring a fresh one up in the same directory. What
// the panel offers after a shell exits.
void restart(int columns, int rows);
// Cells, not pixels. Resizes the screen AND tells the pty, which is what
// raises SIGWINCH so a full-screen program redraws itself.
void setViewport(int columns, int rows);
// Bytes from the view: keystrokes, paste, mouse reports.
void write(const std::string& bytes);
// Ctrl+C. Offered as a method because the panel has a button for it, and
// because "interrupt" is clearer at a call site than a magic byte.
void interrupt();
// Clear the visible screen AND the scrollback, locally. Deliberately does
// NOT run `clear` in the shell: injecting a command would land in whatever
// the user was halfway through typing.
void clearScreenAndScrollback();
// --- what the view draws ------------------------------------------------
// Owned here, borrowed by the view. Never null.
[[nodiscard]] ICoreTerminalScreen* screen();
// --- what the shell reports ---------------------------------------------
// The shell's own cwd when it reports one (OSC 7); the start directory
// otherwise. ⚠ An empty answer means "the shell has not said", never "/".
[[nodiscard]] ICoreString workingDirectory() const;
[[nodiscard]] ICoreString title() const;
// The shell this platform will use, for display ("zsh", "bash", ...).
[[nodiscard]] static ICoreString shellDisplayName();
// --- notifications, all on the GUI thread -------------------------------
// The screen changed. The view answers by repainting the dirty lines --
// this deliberately carries no payload, because the screen already knows
// exactly which rows moved and the view already knows how to ask.
ICoreSignal<> onScreenChanged;
ICoreSignal<ICoreString> onWorkingDirectoryChanged;
ICoreSignal<ICoreString> onTitleChanged;
// The shell exited. Exit code, and whether a signal killed it.
ICoreSignal<int, bool> onClosed;
private:
class Impl; // the two-line residue; state lives here
std::unique_ptr<Impl> impl;
};
ICoreTerminalGridView.h#
src/ICoreBlocks/ICoreStudio/StudioObjects/Panels/Terminal/UI/ICoreTerminalGridView.h
ICoreTerminalGridView#
ICoreTerminalGridView.h:35 · class · bases public ICoreWidget · pImpl · 29 declaration(s)
ICoreTerminalGridView -- draws an ICoreTerminalScreen.
class ICoreTerminalGridView : public ICoreWidget {
public:
explicit ICoreTerminalGridView(ICoreWidget* parent = nullptr);
~ICoreTerminalGridView() override;
// Borrowed, not owned, and must outlive this view. Null is legal and
// paints an empty terminal rather than crashing.
void setScreen(ICoreTerminalScreen* screen);
// --- T3.7: font and cell metrics ---------------------------------------
// The monospace face comes from ICoreFontCatalog::fixedFont(); this sets
// its size. Changing it re-measures the cell and re-reports the viewport.
void setFontPointSize(double points);
[[nodiscard]] double fontPointSize() const;
// One cell, in device-independent pixels. Measured from the font's advance
// width -- NOT assumed integral, because it is not on most faces at most
// sizes, and rounding it per cell accumulates into a visible drift across
// an 80-column line.
[[nodiscard]] double cellWidth() const;
[[nodiscard]] double cellHeight() const;
// How many whole cells fit the widget right now. This is what the pty's
// setViewport() wants -- cells, never pixels.
[[nodiscard]] int viewportColumns() const;
[[nodiscard]] int viewportRows() const;
// Raised when the cell geometry changes -- a resize, or a font change --
// carrying the new (columns, rows). The owner forwards it to
// ICorePty::setViewport and to ICoreTerminalScreen::resize; this view
// deliberately does neither itself, because it does not own either one.
ICoreSignal<int, int> onViewportResized;
// --- T3.2: damage ------------------------------------------------------
// Repaint just the rows the screen has marked dirty, then clear its flags.
// Call this after feeding bytes to the parser. Repainting everything on
// every chunk is what makes a build log pin the GUI thread.
void repaintDirtyLines();
// --- T3.5: the scrollback viewport -------------------------------------
// How many lines above the live screen the view is showing. 0 is pinned to
// the bottom, which is where it returns on any keystroke and on any new
// output -- a terminal that stays scrolled up while a build runs is a
// terminal you have to chase.
[[nodiscard]] int scrollOffset() const;
void setScrollOffset(int linesAboveBottom);
void scrollToBottom();
[[nodiscard]] bool isScrolledBack() const;
// --- §T4: input --------------------------------------------------------
// The bytes this view wants written to the pty: keystrokes, paste, mouse
// reports. The view has no pty and never will -- the owner connects this
// to ICorePty::write, which is what keeps the view testable and stops it
// owning a process.
ICoreSignal<std::string> onBytesToPty;
// Paste the clipboard, framed per the screen's bracketed-paste mode.
// Exposed so a context menu or a shortcut can call it.
void pasteFromClipboard();
// --- T3.4: selection ---------------------------------------------------
// The selected text, rows joined by newlines and trailing blanks trimmed
// off each. Empty when nothing is selected.
[[nodiscard]] std::string selectedText() const;
[[nodiscard]] bool hasSelection() const;
void clearSelection();
// Put the selection on the clipboard. A no-op when there is none -- it
// deliberately does NOT fall back to copying everything, which is what a
// Ctrl+C mapped to "copy or interrupt" would otherwise do on an empty
// selection.
void copySelectionToClipboard();
// --- T3.3: cursor ------------------------------------------------------
// Blinking is on by default and stops while the view is unfocused, where
// the cursor is drawn hollow instead. A blinking cursor in a panel nobody
// is typing into is just a distraction that also costs a repaint a second.
void setCursorBlinkEnabled(bool enabled);
protected:
void paintContent(ICorePainter& painter, const ICoreRect& dirty) override;
void resized(const ICoreSizeF& newSize, const ICoreSizeF& oldSize) override;
void focusGained(const ICoreFocusEvent& event) override;
void focusLost(const ICoreFocusEvent& event) override;
// ⚠ keyPressed returns TRUE for almost everything, and that is the point
// of row T4.2. A terminal must swallow Ctrl+C, Ctrl+D, Ctrl+Z, Tab and the
// arrows and put them on the wire as bytes; if an application shortcut
// claims one first, the byte never ships and the terminal looks hung with
// no diagnostic anywhere.
bool keyPressed(const ICoreKeyEvent& event) override;
bool mousePressed(const ICoreMouseEvent& event) override;
bool mouseReleased(const ICoreMouseEvent& event) override;
bool mouseMoved(const ICoreMouseEvent& event) override;
bool wheelScrolled(const ICoreWheelEvent& event) override;
private:
class Impl; // the two-line residue; state lives here
std::unique_ptr<Impl> impl;
};
ICoreTerminalMenuPanel.h#
src/ICoreBlocks/ICoreStudio/StudioObjects/Panels/Terminal/UI/ICoreTerminalMenuPanel.h
ICoreTerminalMenuPanel#
ICoreTerminalMenuPanel.h:32 · class · bases public ICoreWidget · pImpl · 3 declaration(s)
Left-panel page holding a REAL TERMINAL: a login shell under a pseudo- terminal, drawn as a cell grid.
class ICoreTerminalMenuPanel : public ICoreWidget {
public:
explicit ICoreTerminalMenuPanel(ICoreWidget* parent = nullptr);
~ICoreTerminalMenuPanel() override;
protected:
// The panel lives in an ICoreStackedLayout; start the shell the first time
// it becomes visible, and put focus on the grid so typing goes to the
// shell rather than nowhere.
void shown() override;
private:
class Impl; // the two-line residue; state lives here
std::unique_ptr<Impl> impl;
};