On this page
  1. tecs.platform.os
  2. Capabilities
  3. Clipboard
  4. Process signals
  5. Module contents
    1. Constructors
    2. Types
    3. Functions
  6. Constructors
    1. newSignalListener
  7. Types
    1. Capabilities
    2. DialogFilter
    3. DialogOptions
    4. DialogResult
    5. Locale
    6. Power
    7. ProcessSignal
    8. SignalListener
  8. Functions
    1. capabilities
    2. clearClipboard
    3. clipboardAvailable
    4. clipboardData
    5. clipboardMimeTypes
    6. clipboardText
    7. hasClipboardData
    8. hasClipboardText
    9. hasPrimarySelection
    10. messageBox
    11. openFile
    12. openFolder
    13. openURL
    14. power
    15. preferredLocales
    16. primarySelection
    17. resetCapabilities
    18. saveFile
    19. setClipboardText
    20. setPrimarySelection
    21. updateDialogs

tecs.platform.os

Runtime capabilities, clipboard access, and desktop services.

Capabilities

Ask the installed build instead of inferring support from a target name. capabilities distinguishes targets that share an operating system but differ in JIT, worker, shader, storage, or device support. It reports the process sandbox separately because that environment can restrict filesystem and child process access without changing the target.

Clipboard

The clipboard belongs to the desktop and can change between frames. events.clipboardUpdate reports a change; read the current value when the event arrives or when the user requests paste. Text stays UTF-8, keeps its line endings, and stops at the first NUL. clipboardData preserves NULs.

Headless builds report the clipboard as unavailable. Primary selection remains independent of the clipboard. On platforms without a shared primary selection, reads may return only the value this process wrote.

Process signals

SDL applications already receive SIGINT and SIGTERM as the public tecs.platform.events.on.quit event and then run their normal shutdown lifecycle. A headless loop can retain a SignalListener instead. tecs.runtime.poll transfers signals out of the native handler, and next drains them without waiting:

tecs.scoped(function(scope: tecs.Scope)
    local signals <const> = scope:own(
        tecs.platform.os.newSignalListener()
    )

    local running = true
    while running do
        tecs.runtime.poll()
        local signal <const> = signals:next()
        if signal == "interrupt" or signal == "terminate" then
            running = false
        end
    end
end)

The native handler only sets atomic flags. It never calls Lua, allocates, or locks. Repeated instances of one signal may coalesce before the next runtime poll, as operating-system signals ordinarily may. When different signals are pending in one poll, next returns them in the enum order rather than claiming an arrival order the operating system did not preserve. Closing the last listener stops interception, so a later signal follows the platform's termination behavior again.

Module contents

Constructors

Constructor Description
newSignalListener Creates a listener for process signals in a headless loop.

Types

Type Kind Description
Capabilities record Describes what this build can do on this target.
DialogFilter record Describes one file-type filter.
DialogOptions record Describes dialog configuration.
DialogResult record Describes a completed dialog.
Locale record Describes one language the user prefers.
Power record Describes the machine's power source and remaining charge.
ProcessSignal enum ProcessSignal identifies an interrupt, termination, hangup, or quit request sent to this process.
SignalListener interface A SignalListener receives process signals in a headless loop.

Functions

Function Kind Description
capabilities Static Reads the capabilities of the running build.
clearClipboard Static Withdraws what this application put on the system.
clipboardAvailable Static Reports whether a clipboard is available.
clipboardData Static Returns the clipboard bytes for mimeType, or nil when it offers none.
clipboardMimeTypes Static Returns the clipboard MIME types in platform order.
clipboardText Static Returns the clipboard text, or an empty string when it holds none.
hasClipboardData Static Reports whether the clipboard offers mimeType.
hasClipboardText Static Reports whether the clipboard holds text.
hasPrimarySelection Static Reports whether the primary selection holds text.
messageBox Static Shows a native informational, warning or error dialog.
openFile Static Opens a native file picker.
openFolder Static Opens a native folder picker.
openURL Static Opens an absolute URI with the operating system's preferred application.
power Static Returns the current battery or external-power state.
preferredLocales Static Returns the user's preferred locales in priority order.
primarySelection Static Returns text from the platform's primary selection.
resetCapabilities Static Forgets the cached answer.
saveFile Static Opens a native save-file picker.
setClipboardText Static Puts text on the clipboard, replacing whatever was there.
setPrimarySelection Static Puts text in the primary selection.
updateDialogs Static Settles file and folder dialogs that have answered.

Constructors

tecs.platform.os.newSignalListener Static

Creates a listener for process signals in a headless loop.

The listener receives "interrupt" for SIGINT, "terminate" for SIGTERM, "hangup" for SIGHUP, and "quit" for SIGQUIT on POSIX. Windows maps Ctrl-C and Ctrl-Break to "interrupt", and console close, logoff, and shutdown to "terminate". Unsupported signals simply never arrive on that platform.

SDL applications normally observe tecs.platform.events.on.quit instead. SDL converts SIGINT and SIGTERM to that event and the application performs its normal shutdown lifecycle before the process-wide runtime pump.

function tecs.platform.os.newSignalListener(
    selected: {ProcessSignal}
): SignalListener, string

Arguments

Name Type Description
selected {ProcessSignal} The caller supplies the signal names to retain, or omits the list to retain every supported name. An empty list and duplicate or unknown names raise as programmer errors.

Returns

Type Description
SignalListener Returns a caller-owned listener.
string Returns the platform reason when native signal handling cannot be installed.

Examples

tecs.scoped(function(scope: tecs.Scope)
    local signals, reason = tecs.platform.os.newSignalListener({
        "interrupt", "terminate"
    })
    if signals == nil then
        error(reason)
    end
    scope:own(signals)

    local running = true
    local function update()
        tecs.runtime.poll()
        local signal <const> = signals:next()
        if signal ~= nil then
            running = false
        end
    end

    while running do
        update()
    end
end)

Types

tecs.platform.os.Capabilities record

Describes what this build can do on this target.

record tecs.platform.os.Capabilities
    target: string
    architecture: string
    sandbox: string
    jit: boolean
    ffi: boolean
    dynamicLibraries: boolean
    hotReload: boolean
    runtimeShaders: boolean
    packagedShaders: boolean
    shaderFormats: {string}
    touch: boolean
    gamepad: boolean
    sensors: boolean
    workers: boolean
    cores: integer
    writableStorage: boolean
end

tecs.platform.os.Capabilities.target field

Read-only. This is the platform name, such as "macOS" or "Android". A licensed port answers with its own name instead, since everything here describes the platform actually installed.

tecs.platform.os.Capabilities.target: string

tecs.platform.os.Capabilities.architecture field

Read-only. This is the CPU architecture this build targets.

tecs.platform.os.Capabilities.architecture: string

tecs.platform.os.Capabilities.sandbox field

Read-only. Reports "none", "unknownContainer", "flatpak", "snap" or "macOS" for the process environment SDL detects. A sandbox can restrict filesystem and child-process access independently of the target and the build's other capabilities.

tecs.platform.os.Capabilities.sandbox: string

tecs.platform.os.Capabilities.jit field

Read-only. This reports whether the runtime generates machine code. False on a target that requires interpretation.

tecs.platform.os.Capabilities.jit: boolean

tecs.platform.os.Capabilities.ffi field

Read-only. This is always true because every supported build requires the FFI.

tecs.platform.os.Capabilities.ffi: boolean

tecs.platform.os.Capabilities.dynamicLibraries field

Read-only. Reports whether a library can load by name at run time. It is false where every build links every library into the executable.

tecs.platform.os.Capabilities.dynamicLibraries: boolean

tecs.platform.os.Capabilities.hotReload field

Read-only. Reports whether this build supports development-time content reload. Named independently of any one kind the watcher reloads.

tecs.platform.os.Capabilities.hotReload: boolean

tecs.platform.os.Capabilities.runtimeShaders field

Read-only. Reports whether this build can compile shaders from source at run time.

tecs.platform.os.Capabilities.runtimeShaders: boolean

tecs.platform.os.Capabilities.packagedShaders field

Read-only. Reports whether the engine reads shaders from a packaged artifact. Independent of runtimeShaders: a development build may have both, and a release has only this.

tecs.platform.os.Capabilities.packagedShaders: boolean

tecs.platform.os.Capabilities.shaderFormats field

Read-only. Lists the shader formats this target consumes. It contains one entry, since a build supplies one format.

tecs.platform.os.Capabilities.shaderFormats: {string}

tecs.platform.os.Capabilities.touch field

Read-only. Reports whether the machine currently has a touch device. This describes the machine rather than of the target: a desktop with a touchscreen has one.

tecs.platform.os.Capabilities.touch: boolean

tecs.platform.os.Capabilities.gamepad field

Read-only. Reports true because every target reaches gamepads through the same subsystem, so only the connected devices vary, which the gamepads method on Input answers.

tecs.platform.os.Capabilities.gamepad: boolean

tecs.platform.os.Capabilities.sensors field

Read-only. Reports whether the device carries a gyroscope or an accelerometer. This says nothing about a gamepad's sensors, which hasSensor on Gamepad answers per device.

tecs.platform.os.Capabilities.sensors: boolean

tecs.platform.os.Capabilities.workers field

Read-only. Reports whether work can run off the main thread.

tecs.platform.os.Capabilities.workers: boolean

tecs.platform.os.Capabilities.cores field

Read-only. Reports the number of logical cores for sizing a worker pool.

tecs.platform.os.Capabilities.cores: integer

tecs.platform.os.Capabilities.writableStorage field

Read-only. Reports true because every target has somewhere to write, and tecs.io.files.preferencePath and tecs.io.files.cachePath answer where: the field exists so a caller can ask rather than assume, not because a target answers no.

tecs.platform.os.Capabilities.writableStorage: boolean

tecs.platform.os.DialogFilter record

Describes one file-type filter.

record tecs.platform.os.DialogFilter
    name: string
    pattern: string
end

tecs.platform.os.DialogFilter.name field

Caller-writable. Sets the label shown beside the filter, such as "Images".

tecs.platform.os.DialogFilter.name: string

tecs.platform.os.DialogFilter.pattern field

Caller-writable. Sets semicolon-separated extensions, such as "png;jpg;jpeg".

tecs.platform.os.DialogFilter.pattern: string

tecs.platform.os.DialogOptions record

Describes dialog configuration.

record tecs.platform.os.DialogOptions
    window: Window
    filters: {DialogFilter}
    defaultLocation: string
    multiple: boolean
end

tecs.platform.os.DialogOptions.window field

Caller-writable. Sets the window that owns the dialog.

tecs.platform.os.DialogOptions.window: Window

tecs.platform.os.DialogOptions.filters field

Caller-writable. Sets the available file-type filters.

tecs.platform.os.DialogOptions.filters: {DialogFilter}

tecs.platform.os.DialogOptions.defaultLocation field

Caller-writable. Sets the initial file or folder. Omit it to let the platform choose.

tecs.platform.os.DialogOptions.defaultLocation: string

tecs.platform.os.DialogOptions.multiple field

Caller-writable. Allows the user to select more than one path.

tecs.platform.os.DialogOptions.multiple: boolean

tecs.platform.os.DialogResult record

Describes a completed dialog.

record tecs.platform.os.DialogResult
    paths: {string}
    filter: integer
    canceled: boolean
end

tecs.platform.os.DialogResult.paths field

Read-only. Contains selected paths. It is empty when the user canceled.

tecs.platform.os.DialogResult.paths: {string}

tecs.platform.os.DialogResult.filter field

Read-only. Reports the one-based selected filter, or zero when no filter applies.

tecs.platform.os.DialogResult.filter: integer

tecs.platform.os.DialogResult.canceled field

Read-only. Reports whether the user canceled the dialog.

tecs.platform.os.DialogResult.canceled: boolean

tecs.platform.os.Locale record

Describes one language the user prefers.

record tecs.platform.os.Locale
    language: string
    country: string
end

tecs.platform.os.Locale.language field

Read-only. Contains an ISO 639 language code, such as "en".

tecs.platform.os.Locale.language: string

tecs.platform.os.Locale.country field

Read-only. Contains an ISO 3166 country code, such as "US", or an empty string when the platform names only a language.

tecs.platform.os.Locale.country: string

tecs.platform.os.Power record

Describes the machine's power source and remaining charge.

record tecs.platform.os.Power
    state: string
    seconds: integer
    percent: integer
end

tecs.platform.os.Power.state field

Read-only. Reports "unknown", "onBattery", "noBattery", "charging", "charged" or "error".

tecs.platform.os.Power.state: string

tecs.platform.os.Power.seconds field

Read-only. Reports seconds of battery life remaining, or -1 when unavailable.

tecs.platform.os.Power.seconds: integer

tecs.platform.os.Power.percent field

Read-only. Reports charge percentage in 0..100, or -1 when unavailable.

tecs.platform.os.Power.percent: integer

tecs.platform.os.ProcessSignal enum

ProcessSignal identifies an interrupt, termination, hangup, or quit request sent to this process.

enum tecs.platform.os.ProcessSignal
    "hangup"
    "interrupt"
    "quit"
    "terminate"
end

tecs.platform.os.SignalListener interface

A SignalListener receives process signals in a headless loop.

interface tecs.platform.os.SignalListener is Closeable
    isClosed: function(self): boolean
    next: function(self): ProcessSignal
    pending: function(self): integer
end

Interfaces

Interface
Closeable

tecs.platform.os.SignalListener:isClosed Instance

Returns whether this listener has been closed.

function tecs.platform.os.SignalListener.isClosed(self): boolean
Arguments
Name Type Description
self SignalListener The listener to inspect.
Returns
Type Description
boolean Returns true after close.

tecs.platform.os.SignalListener:next Instance

Removes and returns one queued signal without waiting.

The call returns nil when no selected signal has arrived since the listener was created or last drained. Signals transferred by the same runtime poll are returned in enum order, not arrival order.

function tecs.platform.os.SignalListener.next(self): ProcessSignal
Arguments
Name Type Description
self SignalListener The open listener whose queue advances.
Returns
Type Description
ProcessSignal Returns one selected signal, or nil when none is pending.

tecs.platform.os.SignalListener:pending Instance

Returns the number of signals waiting to be read.

Signals of the same kind may coalesce before a runtime poll. The count covers deliveries already transferred to this listener.

function tecs.platform.os.SignalListener.pending(self): integer
Arguments
Name Type Description
self SignalListener The open listener to inspect.
Returns
Type Description
integer Returns the queued delivery count.

Functions

tecs.platform.os.capabilities Static

Reads the capabilities of the running build.

The function caches its answer because these values do not change while a platform remains installed. The platform generation keys the cache, so installing a platform drops the value without anybody calling resetCapabilities.

function tecs.platform.os.capabilities(): Capabilities

Arguments

None.

Returns

Type Description
Capabilities The same table on every call until the platform changes. Shared, so a caller that means to keep it does not also mean to edit it.

tecs.platform.os.clearClipboard Static

Withdraws what this application put on the system.

The clipboard is left empty rather than restored to what preceded the write, because nothing anywhere remembers what that was.

function tecs.platform.os.clearClipboard(): boolean

Arguments

None.

Returns

Type Description
boolean

tecs.platform.os.clipboardAvailable Static

Reports whether a clipboard is available.

False in a process that never brought up video, where every other function here answers empty or false. Distinguishes that from a clipboard that is simply empty, which no other return value can.

function tecs.platform.os.clipboardAvailable(): boolean

Arguments

None.

Returns

Type Description
boolean

tecs.platform.os.clipboardData Static

Returns the clipboard bytes for mimeType, or nil when it offers none.

The caller releases the returned Buffer. Returns nil rather than an empty buffer because the clipboard can offer a MIME type with no bytes, which differs from not offering that type.

function tecs.platform.os.clipboardData(mimeType: string): IOBuffer

Arguments

Name Type Description
mimeType string

Returns

Type Description
IOBuffer

tecs.platform.os.clipboardMimeTypes Static

Returns the clipboard MIME types in platform order.

The same list clipboardUpdate carries, for a caller that wants to ask rather than wait to be told. Empty when the clipboard is empty.

function tecs.platform.os.clipboardMimeTypes(): {string}

Arguments

None.

Returns

Type Description
{string}

tecs.platform.os.clipboardText Static

Returns the clipboard text, or an empty string when it holds none.

Empty is also the answer when the clipboard holds something that is not text, and when there is no video. Ask hasClipboardText to tell those from text that is genuinely empty.

function tecs.platform.os.clipboardText(): string

Arguments

None.

Returns

Type Description
string

tecs.platform.os.hasClipboardData Static

Reports whether the clipboard offers mimeType.

function tecs.platform.os.hasClipboardData(mimeType: string): boolean

Arguments

Name Type Description
mimeType string

Returns

Type Description
boolean

tecs.platform.os.hasClipboardText Static

Reports whether the clipboard holds text.

Cheaper than reading it: no allocation crosses the boundary, and on a platform where a read negotiates with the owning application, no negotiation happens.

function tecs.platform.os.hasClipboardText(): boolean

Arguments

None.

Returns

Type Description
boolean

tecs.platform.os.hasPrimarySelection Static

Reports whether the primary selection holds text.

function tecs.platform.os.hasPrimarySelection(): boolean

Arguments

None.

Returns

Type Description
boolean

tecs.platform.os.messageBox Static

Shows a native informational, warning or error dialog.

function tecs.platform.os.messageBox(
    kind: string, title: string, message: string, window: Window
): boolean, string

Arguments

Name Type Description
kind string
title string
message string
window Window

Returns

Type Description
boolean
string

tecs.platform.os.openFile Static

Opens a native file picker.

function tecs.platform.os.openFile(
    options: DialogOptions
): Future<DialogResult>

Arguments

Name Type Description
options DialogOptions

Returns

Type Description
Future<DialogResult>

tecs.platform.os.openFolder Static

Opens a native folder picker.

function tecs.platform.os.openFolder(
    options: DialogOptions
): Future<DialogResult>

Arguments

Name Type Description
options DialogOptions

Returns

Type Description
Future<DialogResult>

tecs.platform.os.openURL Static

Opens an absolute URI with the operating system's preferred application.

This is not limited to web URLs. The operating system may route https: to a browser, mailto: to a mail client, and application-specific schemes such as steam: to their registered handler. Tecs passes the string to SDL without parsing it, so the platform decides which schemes it accepts and which application handles them.

function tecs.platform.os.openURL(url: string): boolean, string

Arguments

Name Type Description
url string The caller supplies a non-empty absolute URI. Embedded NUL bytes are not supported by SDL's C-string boundary.

Returns

Type Description
boolean Returns true after the operating system accepts the launch request.
string Returns SDL's reason when the URI is empty, unsupported, malformed, or cannot be opened.

tecs.platform.os.power Static

Returns the current battery or external-power state.

function tecs.platform.os.power(): Power

Arguments

None.

Returns

Type Description
Power

tecs.platform.os.preferredLocales Static

Returns the user's preferred locales in priority order.

function tecs.platform.os.preferredLocales(): {Locale}

Arguments

None.

Returns

Type Description
{Locale}

tecs.platform.os.primarySelection Static

Returns text from the platform's primary selection.

On X11 and Wayland, selecting text places it in a clipboard separate from the ordinary copy-and-paste clipboard, commonly pasted with the middle mouse button. Platforms without that concept expose only the value this process last supplied through setPrimarySelection; other applications do not see it. This function does not read clipboardText.

function tecs.platform.os.primarySelection(): string

Arguments

None.

Returns

Type Description
string Returns UTF-8 text, or an empty string when the selection is empty or no video subsystem is available.

tecs.platform.os.resetCapabilities Static

Forgets the cached answer. Capability lookup notices a platform change without this.

function tecs.platform.os.resetCapabilities()

Arguments

None.

Returns

None.

tecs.platform.os.saveFile Static

Opens a native save-file picker. Returns at most one path.

function tecs.platform.os.saveFile(
    options: DialogOptions
): Future<DialogResult>

Arguments

Name Type Description
options DialogOptions

Returns

Type Description
Future<DialogResult>

tecs.platform.os.setClipboardText Static

Puts text on the clipboard, replacing whatever was there.

The platform copies the string before this call returns. Returns false when the platform refused, which includes having no video.

function tecs.platform.os.setClipboardText(text: string): boolean

Arguments

Name Type Description
text string

Returns

Type Description
boolean

tecs.platform.os.setPrimarySelection Static

Puts text in the primary selection.

Succeeds on a platform that has no shared primary selection, where the value remains visible only to this process.

function tecs.platform.os.setPrimarySelection(text: string): boolean

Arguments

Name Type Description
text string

Returns

Type Description
boolean

tecs.platform.os.updateDialogs Static

Settles file and folder dialogs that have answered.

runtime.poll calls this while a dialog is open. It remains public for a test or a specialized headless loop that deliberately drives dialogs alone.

function tecs.platform.os.updateDialogs(): integer

Arguments

None.

Returns

Type Description
integer