A frame is a top-level window in the desktop
environment. It hosts a collection of window instances and
mediates between them and the OS window manager: it carries the title,
decorations, geometry, modality and close/save handlers.
The frame's interior is tiled: the member windows together cover the
entire client area without overlap. Layout is managed by a tile
object associated with the frame.
Every window needs a frame before it can be opened. For simple applications the user does not need to deal with frames explicitly — opening a single window creates a frame as a side-effect. Windows delegate messages they don't understand to their associated frame.
Subclasses of frame are common in user-defined
applications that need to coordinate several sub-windows. The set of
windows and their spatial relationships may be changed after the frame
has been opened.
The underlying driver is SDL3 across all platforms; legacy X11 behaviour and window-manager protocol names (WM_DELETE_WINDOW, WM_SAVE_YOURSELF, ...) are preserved as identifiers but no longer imply X-specific semantics.
|pixmap
= @_dialog_bg->busy_cursor
when the call site does not pass a cursor.<-confirm_done:
whether frame->wm_delete
should pop up a confirmation dialog.->create/frame->open.
When @nil, the
size is determined by the contained windows and the position by the OS.
<->can_resize.->fit
after each frame->append.
Convenient while interactively assembling a frame; usually left @off
in production code which builds the layout up-front and then calls
frame->fit
(or frame->open)
once.<-member
to find frames in an application. Defaults to object<-class_name.
See also frame<->label.
->modal.->create
is not allowed.|pixmapSee also frame->set, frame<-bounding_box
and frame->geometry.
->create
to position the frame. Filled by frame->initialise
from the frame.geometry
class variable, or
by frame->geometry.
Class frame itself does not provide a default; subclasses
commonly do so end users can override the position in ~/.xpce/Defaults.
See library(persistent_frame) for a frame subclass that
persists its geometry and sub-window layout.
For the syntax see frame->geometry.
window_decorator.
The getter frame<-members
returns the chain of undecorated windows.
toplevel — ordinary application window: title bar,
can be minimised and resized through the OS. Default.
transient — dialog box / inspector window for a
parent
toplevel. Usually decorated but skipped from the task
switcher.
popup — completely invisible to the OS window
manager. Used for tooltips and popup menus. Cannot normally receive
keyboard input; use transient if you need text input.
The kind can only be changed before frame->create.
.g.
its parent toplevel). Only meaningful when frame<-kind
is transient.
->transient_for
and frame->unlink.
Used to propagate state changes (mapped/exposed/hidden) to the
transients.
transient blocks just the frame in frame<-transient_for;
application blocks every frame in the same frame<-application.
Typical pattern:
display_for(Owner, Result) :-
new(D, dialog('Enter information')),
send(D, transient_for, Owner),
send(D, modal, transient),
<fill the dialog>
get(D, confirm_centered,
Owner?area?center, Return),
send(D, destroy),
Return \== @nil.
See also frame<-confirm, frame->transient_for
and class application.
unmapped — no OS counterpart yet (the frame exists
only as an xpce object).
hidden — OS counterpart exists but is not visible.
Used to stash a frame for later reuse.
iconic — minimised.
window (also written open) — fully
visible. Reached via
frame->open.
full_screen — maximised across the entire screen.
Reach it with send(F, status, full_screen) after frame->create.
See also frame->open, frame<-confirm
and frame->wait. frame->show
and
frame->closed
map to this slot for backward compatibility.
.g.
clicking the close button). Defaults to @on.
->create
to lock the size.->wm_delete).
Defaults to the value of the confirm_done class variable
(off).
On change to @on
the frame sends window->input_focus
to frame<-keyboard_focus
(or to the window under the pointer). On change to @off
the window that currently owns input focus is sent window->input_focus.
->busy_cursor
when block_input is @on.->return
until frame<-confirm
picks it up.
->wm_protocol/frame->done_message/frame->save_message
family of OS close/save handlers.
Defaults:
label untitled kind toplevel display @display
->free.->busy_cursor
and restore the normal cursor.show slot into frame<-status.background)
when loading older saved instances..g. when the host
moves the frame to another monitor). Applications normally do not call
this.
:- pce_begin_class(mail, frame, "Simple mail tool").
initialise(M) :->
"Create mail tool"::
send(M, send_super, initialise, mail),
/* append the various parts to the tool */
send(M, append, new(B, browser)),
send(M, append, new(V, view)),
send(M, append, new(D, dialog)),
/* specify the layout of the parts in the tool */
send(V, below, B),
send(D, below, V),
...
->append,
window->left, window->above,
...
->enforce
on the root tile;
->_compute_desired_size
on each sub-window (currently only dialog implements this);
->enforce
on the root tile;
->set
to the root-tile's ideal width/height. Normally called from frame->create;
user code calls it after runtime layout changes (e.g.
after graphical->size
or after modifying a dialog window).
<-tile
hierarchy and create a tile_adjuster object for each tile
whose frame<-can_resize
is @on; free
adjusters of non-resizable tiles. Called from frame->create.When the frame is already shown, the request is sent asynchronously
to the OS; the slots are updated when the OS confirms. A successful size
change triggers frame->resize.
->set.->set
that change one axis.->set
with the point's x and y.->position.->set
from the four fields of the argument area.->create).
The syntax is
<width>x<height>[+-]<X>[+-]<Y>[@<monitor>]
All five components are optional. A negative X / Y is measured from the right / bottom edge of the screen. Example:
400x200+0-0
means a 400x200 frame anchored at the bottom-left. The size applies to the client area; the position to the frame including borders.
The @<monitor> suffix, where <monitor>
is a value from
display_manager<-members,
picks the monitor used as the origin. This syntax follows the FVWM
convention. If the
display argument is given explicitly, @<monitor>
is ignored.
<-display
if needed.
<-frames.
->fit
to lay out sub-windows.
->create
each member window.
-geometry if set. 10. frame->update_tile_adjusters.
->create
if not yet created.
->set
the position if supplied.
->status.
If grab is @on
the frame grabs the pointer (see
window->grab_pointer).
|frame],
display=[display], grab=[bool]->open
but centres the frame on the given point (or the centre of frame<-display
if omitted).->open
and frame->status.->show
on transients to follow the main frame.->flush
and frame->synchronise.<-status). open
is a synonym for window.->closed
opens the frame (frame->status), frame->closed
iconifies it.
->closed
(in case the frame was iconic) and then asks SDL to raise the OS window.
On success frame->exposed
is invoked via the resulting OS event.
->expose
to each transient frame.
->hide to each transient frame.
.busy_cursor)
on every sub-window of the frame. When block_input is @on,
all pointer and keyboard events are blocked while the cursor is active. frame->busy_cursor
restores the normal cursor and re-enables input.
.e.
when the pointer is on the area between sub-windows). Used by frame->event
while resizing tiles.<-keyboard_focus
or the window currently under the pointer.
<-input_focus
window: forward to that window;
|event_id<-confirm
call on this frame return with the given value. Stores it in -return_value.
->report
that walks a frame's report chain:
<-report_to;
if it returns a value other than
frame<-display,
forward frame->report
there.
->report
on each frame<-members
window until one succeeds. Windows by default delegate back to their
frame, so the loop detects and breaks this cycle.
<-transient_for.
->report.
Historically these names matched X11's WM_PROTOCOLS messages, notably WM_DELETE_WINDOW (close request) and WM_SAVE_YOURSELF (session save). On SDL3 only the close-request path remains; the others are accepted but never triggered.
->wm_protocol.->wm_protocol.
Default: message(@receiver, wm_delete).
->wm_protocol.
Kept for completeness; SDL3 does not emit this event.
<-can_delete
is @off.
<-confirm_done
is @on, pop up
display->confirm.
Fail if the user cancels.
->destroy
the frame. @see frame->done_message
@see frame<-can_delete
@see frame<-confirm_done
->kind,
@off to frame->kind.
New code should use frame->kind..g.
dialog or inspector) for the argument frame. Effects:
<-transients
chain. Called by frame->transient_for
and frame->unlink;
user code rarely invokes them directly.<-display.<-members.window_decorator wrappers automatically.<window_name>_member to the corresponding member
window:
?- new(@f, frame), send(@f, append, new(V, view)), send(new(D, dialog), below, V), send(V, open). ?- send(@f?view_member, format, 'Hello World\n').
<-area.<-area
on the display.->geometry.<-status
is open; @off
otherwise.->return
is invoked. Used to implement modal prompts.
When grab is @on
the frame grabs the pointer. If the frame is freed while the confirmer
is blocking, the call fails.
Typical use:
ask_name(Name) :-
new(D, dialog('Name Prompter')),
send(D, append, new(N, text_item(name, ''))),
send(D, append,
button(ok, message(D, return, N?selection))),
send(D, append,
button(cancel, message(D, return, @nil))),
send(D, default_button, ok),
get(D, confirm, Answer),
send(D, destroy),
Answer \== @nil,
Name = Answer.
|frame],
display=[display], grab=[bool] -> return_value=any<-confirm
but centres on center (or on the screen if omitted) rather
than placing the top-left there.|chain
filters — chain of tuple objects, each tuple(Name, Extensions)
where Extensions is a ;-separated list or a
chain of char_array. Example:
chain(tuple('Prolog', chain(pl,prolog))).
default — absolute file name used as initial
selection.
allow_many — if @on,
allow multi-select and return a chain of file names; otherwise return a
single name.
<-open_file
minus allow_many.