Haiku BWindow Size Limits: Connect Layout Constraints to User Resizing
Use Haiku BWindow size limits deliberately, choose between explicit and layout-derived bounds, and test zoom and programmatic resizing separately.
A Haiku window can have a correct layout and still let the user resize it until important content disappears. BWindow::SetSizeLimits() supplies a user-resize envelope, while the Layout API describes the minimum, preferred, and maximum sizes of the top view and its children. Those contracts meet at the window boundary, but they are not interchangeable: one is a limit on interactive window resizing, and the other describes what the content layout can usefully accommodate.
The practical decision is who owns that envelope. Use explicit limits when the window has product-level bounds that are not identical to the current layout’s computed minimum and maximum. Use B_AUTO_UPDATE_SIZE_LIMITS when the top view’s layout constraints should automatically define those limits as layout changes. Avoid mixing the two policies without testing which one updates the effective values.
What SetSizeLimits actually constrains
The public BWindow API takes minimum and maximum width and height values. Its documentation is explicit: the method constrains what the user can do by resizing the window; it does not constrain the program. A later ResizeTo() or ResizeBy() call can still move the window outside that envelope. If application code resizes automatically after loading a document, it must enforce its own bounds and should not treat the user’s resize limits as a general geometry validator.
Choose limits from a real interaction requirement. A minimum should keep essential controls and their labels usable; a maximum might prevent an inspector from becoming mostly empty on an unusually wide display. Avoid copying the current window frame into both min and max values just to suppress a resizing bug. That freezes the window rather than fixing the layout or intrinsic size that caused the problem.
#include <Window.h>
void
InstallEditorResizeLimits(BWindow& window)
{
constexpr float minWidth = 520.0f;
constexpr float maxWidth = 1440.0f;
constexpr float minHeight = 360.0f;
constexpr float maxHeight = 1000.0f;
if (minWidth <= maxWidth && minHeight <= maxHeight) {
window.SetSizeLimits(minWidth, maxWidth, minHeight, maxHeight);
}
}
The example chooses explicit finite values for an editor-like window; they are not universal recommendations. The method returns void, so callers cannot treat it as a status-returning validation API. Check the input policy before calling it, and test the actual result on the Haiku release and display configuration you support. The current upstream implementation ignores a request when a minimum exceeds its maximum; that is an implementation observation at the pinned revision, not a substitute for validating inputs in application code.
Decide whether layout or the window owns the bounds
BLayoutItem exposes MinSize(), PreferredSize(), and MaxSize(). A view hierarchy can aggregate those values into the top view’s constraints. B_AUTO_UPDATE_SIZE_LIMITS tells BWindow to derive its interactive size limits from the top view’s minimum and maximum sizes. UpdateSizeLimits() does nothing without that flag; the current API documentation says the update occurs after a layout invalidation and can be called manually if the bounds must be updated earlier, such as before the first Show().
This automatic policy is useful for a preferences window whose allowed dimensions should follow changing controls or a document view whose constraints are already expressed accurately by its layout. It is not a way to install a separate product cap: the current implementation reads the top view’s MinSize() and MaxSize() and calls SetSizeLimits() with them. If you install fixed limits and also enable automatic updates, a later layout update can replace those values. Pick one source of truth or encode the product bounds in the layout constraints themselves.
The preferred size serves a different purpose. It describes a comfortable starting size, not the minimum or maximum allowed user size. ResizeToPreferred() can be useful when initially sizing a window after its content layout is installed. Do not automatically resize a window back to preferred dimensions after every content update; preserve user-chosen geometry unless the product has a clear reason to change it.
Keep zoom separate from ordinary resize limits
SetZoomLimits() supplies a maximum size for Zoom(). The API documentation describes zoom as choosing the smallest of the screen size, the maximum set by SetZoomLimits(), and the maximum set by SetSizeLimits(). Thus a window can resize interactively within one range and still zoom to a smaller deliberate size. Test the zoom button and programmatic Zoom() independently from dragging a border; a successful border test does not prove the zoom target is useful.
Do not use B_NOT_ZOOMABLE as a substitute for an intentional maximum. That flag controls the window’s zoom affordance, whereas SetSizeLimits() describes user resizing constraints. Also do not infer that window limits prevent application code from violating content constraints: code that calls ResizeTo() still needs to consult its own layout and screen policy.
Test constraint changes as a sequence
Install the root view and its layout before setting explicit limits. For an automatic policy, attach the correct flag when constructing the window and ensure the top view’s layout reports meaningful minimum and maximum sizes. Then test:
- Resize the window to both limits and verify essential controls remain reachable.
- Trigger a layout invalidation after adding or removing content and observe whether automatic limits change as intended.
- Call the application’s own
ResizeTo()path with a value outside the interactive envelope and confirm the application applies its own policy. - Use the zoom button at the target screen size and compare the resulting frame with the expected content and display constraints.
- Repeat with larger fonts, long translated labels, narrow screens, and the smallest supported window configuration.
For diagnosis, log the top view’s minimum, preferred, and maximum sizes separately from BWindow::GetSizeLimits() and the current frame. Record when the layout was invalidated and whether B_AUTO_UPDATE_SIZE_LIMITS is present. Do not call window methods from a worker thread just to observe them; keep UI state inspection on the window’s normal looper path. A single screenshot can show a bad size, but not whether the source was a fixed limit, an aggregate layout constraint, a zoom cap, or a later programmatic resize.
BWindow::SetSizeLimits() is a focused user-interaction contract, not a layout solver. The robust design starts with honest child constraints, chooses one owner for the window envelope, treats zoom and programmatic resizing as separate paths, and verifies the full sequence on the target Haiku build.
Related:
- Haiku BLayoutItem: Custom Measurement and Constraint Negotiation
- Haiku BWindow Workspaces: Masks, Membership, and Activation Hooks
Sources:
- Haiku BWindow API documentation at immutable revision
28a933369dcc6cd8b636be5ecc6bf0546e8cb8f6 - Haiku public BWindow header at immutable revision
28a933369dcc6cd8b636be5ecc6bf0546e8cb8f6 - Haiku BWindow implementation at immutable revision
28a933369dcc6cd8b636be5ecc6bf0546e8cb8f6 - Haiku public BLayoutItem header at immutable revision
28a933369dcc6cd8b636be5ecc6bf0546e8cb8f6