UI direction and right-to-left layouts¶
eepp shapes and renders bidirectional text with HarfBuzz and SheenBidi. On top of that, every widget has a UI direction that decides how logical UI concepts resolve to physical sides. A layout authored with logical properties works unchanged in left-to-right (LTR) and right-to-left (RTL) applications.
The central rule:
Direction changes the meaning of logical UI concepts; it never changes the meaning of explicitly physical concepts.
Logical (direction-sensitive) |
Physical (never mirrored) |
Control RTL behavior ===================== ==================================================================================================================== CheckBox, RadioButton Indicator at the right, text before it PushButton Menu items Shortcut at the inline-end (left); icon gutter at the right Submenus Arrow at the left, mirrored; the submenu prefers opening to the left and still flips when it does not fit MenuBar First menu at the right; menus hang from the button’s right edge; Left/Right keys move to the visually adjacent menu TabWidget Tab 0 at the right; indexes, next/previous and drag reordering stay logical TreeView Indentation and expander at the right; expanders mirrored; cells default to TableView, ListView Cells default to Window chrome Title buttons mirrored to the left (custom eepp decorations only) ===================== ====================================================================================================================
The default themes use logical properties where spacing means “before” or “after”. Application themes should do the same for directional spacing.
Directional icons¶
Mirroring is opt-in: arbitrary images, media controls and code never mirror. Framework-owned affordances (submenu arrows, tree expanders) mirror automatically. Applications can opt in for back/forward style icons with setMirrorOnRTL( true ) or the mirror-on-rtl: true CSS property.
Current limitations¶
dir="auto"andunicode-bidiare not modeled;autobehaves asinherit.Vertical writing modes and logical border/inset properties are not implemented.
Scrollbars keep their physical side and scroll offsets stay physical.
Table column order and native window decorations are not mirrored.
Inline box decorations (padding/borders of inline elements split across reordered RTL items) use their logical start/end only approximately.
Inline bidi placement operates at item granularity. Full paragraph bidi across mixed-direction styling boundaries and wrapped-line context is not yet modeled.
See src/examples/ui_rtl/ui_rtl.cpp for a runnable example that toggles the direction at runtime.