Essence » Wiki » Message Processing

Introduction

Messaging is a system used for UI elements to communicate with each other, and for the system to communicate with processes.

For example, sending the message OS_MESSAGE_PAINT to a UI element informs it to paint itself. Also, the window manager might send a window a OS_MESSAGE_KEY_PRESSED message, to inform it that a key has been pressed.

Messages from the system are stored in the process's message queue. The API reads each message from the queue in turn until the program exits. If no message is available, it will wait until one is available.

When a message from the system is processed, it will cause several messages to be passed between UI elements to perform the necessary updates to the UI and window's surface.

When the API is processing messages, the mutex osMessageMutex is acquired. The mutex must be acquired to interact with the UI.

Special system messages are sent to the osSystemMessages element. By providing the name of a systemMessageCallback function in the program section of your manifest, as shown below, you can receive and process these messages.

1
2
[program]
systemMessageCallback = ProcessSystemMessage;

Standard messages

The type of the message is stored in the type field of the OSMessage structure. User-defined messages should use a type from OS_MESSAGE_USER_START (0x8000) to OS_MESSAGE_USER_END (0xBFFF).

GUI messages

os_message_layout<_code>>OS_MESSAGE_LAYOUT

1
2
3
4
5
struct {
    int left, right, top, bottom;
    OSRectangle clip;
    bool force;
} layout;

Sent to a UI element to set its bounds.

left, right, top and bottom should become the cellBounds of the element. The clip rectangle should be used to set the inputBounds of the element. If force is set to true, the element should relayout itself even it did not request to be relayout.

This message is processed by grids and controls to update their bounds.

os_message_measure<_code>>OS_MESSAGE_MEASURE

1
2
3
4
struct {
    int parentWidth, parentHeight;
    int preferredWidth, preferredHeight;
} measure;

Get the preferredWidth and preferredHeight of a UI element. Grids send this messages to their children to lay them out correctly. parentWidth and parentHeight will be set where possible to enable wrapping.

os_message_paint<_code>>OS_MESSAGE_PAINT

1
2
3
4
5
struct {
    OSHandle surface;
    OSRectangle clip;
    bool force;
} paint;

Sent to a UI element to paint it. surface contains a handle to the Surface object to draw on. clip contains a rectangle to which all draw operations should be clipped. If force is set to true, then the element should repaint itself even it did not request to be repainted.

os_message_paint_background<_code>>OS_MESSAGE_PAINT_BACKGROUND

1
2
3
4
struct {
    OSHandle surface;
    OSRectangle clip;
} paintBackground;

Sent by a child element to its parent to request it to draw its background onto the surface, clipped to the clip rectangle.

os_message_destroy<_code>>OS_MESSAGE_DESTROY

Sent to a UI element to destroy it. This means all memory should be deallocated. The element will not receive any more messages after this.

os_message_text_updated<_code>>OS_MESSAGE_TEXT_UPDATED

Sent to a control to inform it that its text has been modified using OSControlSetText.

os_message_hit_test<_code>>OS_MESSAGE_HIT_TEST

1
2
3
4
struct {
    int positionX, positionY;
    bool result;
} hitTest;

Sent to a UI element to test whether a point is within its bounds. Store true in result if the point was inside the bounds.

os_message_caret_blink<_code>>OS_MESSAGE_CARET_BLINK

Sent to a control to blink its caret.

os_message_remove_child<_code>>OS_MESSAGE_REMOVE_CHILD

1
2
3
struct {
    OSObject child;
} removeChild;

Sent to a UI element when a child is removed from it using OSElementRemoveFromParent.

os_message_get_cursor<_code>>OS_MESSAGE_GET_CURSOR

1
2
3
struct {
    OSCursorStyle cursor;
} getCursor;

Sent to a UI element to get the cursor that should be displayed when the mouse cursor is within its bounds.

os_message_clicked<_code>>OS_MESSAGE_CLICKED

Sent when a control is clicked. A click is registered when the left mouse button is pressed and released over the same control.

If click repeat is enable, then this message will be repeatedly sent until the mouse button is released.

os_message_start_hover<_code>>OS_MESSAGE_START_HOVER

Sent when the mouse enters the bounds of a control.

os_message_end_hover<_code>>OS_MESSAGE_END_HOVER

Sent when the mouse leaves the bounds of a control.

os_message_start_press<_code>>OS_MESSAGE_START_PRESS

1
2
3
4
5
6
7
8
9
struct {
    int positionX;
    int positionY;
    int positionXScreen;
    int positionYScreen;
    uint8_t clickChainCount;
    uint8_t activationClick : 1;
    uint8_t alt : 1, ctrl : 1, shift : 1;
} mousePressed;

Sent when a mouse button is pressed on a control.

clickChainCount contains the number of presses that have been registered in quick succession. For example, to check for a double-click, this value will be set to 2.

activationClick is set if the mouse click that caused this message to be sent also activated the window. You may wish to ignore the message if this is set.

alt, ctrl, shift are set when the respective keys are held when the event occurs.

os_message_end_press<_code>>OS_MESSAGE_END_PRESS

Sent to a control when the mouse button is released.

os_message_start_drag<_code>>OS_MESSAGE_START_DRAG

Sent to a control when a drag operation starts. A drag operation is registered when the mouse moves a specified distance from the point at which is was pressed without being released.

os_message_start_focus<_code>>OS_MESSAGE_START_FOCUS

Sent to a control when it receives keyboard focus.

os_message_end_focus<_code>>OS_MESSAGE_END_FOCUS

Sent to a control when it loses keyboard focus, but no new element has received keyboard focus.

os_message_end_last_focus<_code>>OS_MESSAGE_END_LAST_FOCUS

Sent to a control that last had keyboard focus when a new control gains keyboard focus.

os_message_mouse_dragged<_code>>OS_MESSAGE_MOUSE_DRAGGED

1
2
3
4
5
6
7
8
struct {
    int originalPositionX;
    int newPositionX;
    int originalPositionY;
    int newPositionY;
    int newPositionXScreen;
    int newPositionYScreen;
} mouseDragged;

Repeatedly sent to a control during a drag operation, to notify it of the current mouse position (newPositionX/Y).

originalPositionX/Y contains the position where the drag operation started.

os_message_key_typed<_code>>OS_MESSAGE_KEY_TYPED

1
2
3
4
5
6
struct {
    unsigned scancode; 
    uint8_t alt : 1, ctrl : 1, shift : 1, 
        numpad : 1;
    OSObject notHandledBy;
} keyboard;

Sent to a control with keyboard focus when a key is typed.

scancode is a scancode. See api/os.h for a list of scancodes, all of which start with OS_SCANCODE_.

numpad indicates whether the key press came from the number pad, rather than the standard keys.

os_message_disable<_code>>OS_MESSAGE_DISABLE

Sent to a UI element to disable it. On receiving this message, you may wish to disable your child elements.

Window manager messages

os_message_mouse_moved<_code>>OS_MESSAGE_MOUSE_MOVED

os_message_mouse_left_pressed<_code>>OS_MESSAGE_MOUSE_LEFT_PRESSED

os_message_mouse_left_released<_code>>OS_MESSAGE_MOUSE_LEFT_RELEASED

os_message_key_pressed<_code>>OS_MESSAGE_KEY_PRESSED

os_message_key_released<_code>>OS_MESSAGE_KEY_RELEASED

os_message_window_created<_code>>OS_MESSAGE_WINDOW_CREATED

os_message_wm_timer<_code>>OS_MESSAGE_WM_TIMER

os_message_window_activated<_code>>OS_MESSAGE_WINDOW_ACTIVATED

os_message_window_deactivated<_code>>OS_MESSAGE_WINDOW_DEACTIVATED

os_message_window_destroyed<_code>>OS_MESSAGE_WINDOW_DESTROYED

os_message_mouse_exit<_code>>OS_MESSAGE_MOUSE_EXIT

os_message_mouse_enter<_code>>OS_MESSAGE_MOUSE_ENTER

os_message_mouse_right_pressed<_code>>OS_MESSAGE_MOUSE_RIGHT_PRESSED

os_message_mouse_right_released<_code>>OS_MESSAGE_MOUSE_RIGHT_RELEASED

os_message_mouse_middle_pressed<_code>>OS_MESSAGE_MOUSE_MIDDLE_PRESSED

os_message_mouse_middle_released<_code>>OS_MESSAGE_MOUSE_MIDDLE_RELEASED

os_message_modal_parent_clicked<_code>>OS_MESSAGE_MODAL_PARENT_CLICKED

os_message_update_window<_code>>OS_MESSAGE_UPDATE_WINDOW

os_message_click_repeat<_code>>OS_MESSAGE_CLICK_REPEAT

os_message_minimise_window<_code>>OS_MESSAGE_MINIMISE_WINDOW

Miscellaneous messages

os_message_clipboard_updated<_code>>OS_MESSAGE_CLIPBOARD_UPDATED

os_message_set_property<_code>>OS_MESSAGE_SET_PROPERTY

os_message_idle<_code>>OS_MESSAGE_IDLE

os_message_system_constant_updated<_code>>OS_MESSAGE_SYSTEM_CONSTANT_UPDATED

Reference

OSMessageForward

1
OSResponse OSMessageForward(OSObject target, OSMessageCallback callback, OSMessage *message);

Forward a message to another message callback.

This is used to override existing UI elements, as described in Controls.

OSMessagePost

1
OSError OSMessagePost(OSMessage *message);

Add a message to the current processes' message queue. It will be processed at the API's next convenience.

OSMessagePostRemote

1
OSError OSMessagePostRemote(OSHandle process, OSMessage *message);

Add a message to a different processes' message queue. It will be processed at the API's next convenience.

OSMessageProcess

1
void OSMessageProcess();

Start processing messages. This function never returns.

This function is automatically called by the ProgramEntry function generated by the manifest parser.

OSMessageRelayToChild

1
OSResponse OSMessageRelayToChild(OSObject parent, OSObject child, OSMessage *message);

Relay a message to a UI element's child element.

OSMessageSend

1
OSResponse OSMessageSend(OSObject target, OSMessage *message);

Send a message to a UI element, and wait for the response.

OSMessageSendIdle

1
void OSMessageSendIdle(bool enabled);

Request sending OS_MESSAGE_IDLE messages when the program is idling.

OSMessageSetCallback

1
OSMessageCallback OSMessageSetCallback(OSObject element, OSMessageCallback callback);   

Set the message callback of a UI element. Returns the old message callback. Use OSMessageForward to send unhandled messages to the old callback.

You can create a OSMessageCallback using OS_MAKE_MESSAGE_CALLBACK(function, context). A message callback function has the following signature:

1
OSResponse OSMessageCallbackFunction(OSObject object, OSMessage *message);

The context is passed in the context field of the message.

OSResponse

A response to a message or notification callback.

One of:

  • OS_CALLBACK_NOT_HANDLED: the callback was not handled
  • OS_CALLBACK_HANDLED: the callback was handled successfully
  • OS_CALLBACK_REJECTED: the callback was handled unsuccessfully; abort operation