Generated reference › API — ICoreBlocks/ICoreStudio/StudioObjects/Panels/Terminal
kind: generated#api#icoreblocks-icorestudio-studioobjects-panels-terminal

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.

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;
};