An XEmbed message is an X11 client message with message type "_XEMBED". The format is 32, the first three data longs carry the toolkit's X time (l[0]), the message's major opcode (l[1]) and the message's detail code (l[2]). If no detail is required, the value passed has to be 0. The remaining two data longs (l[3] and l[4]) are reserved for data1 and data2. Unused bytes of the client message are set to 0. The event is sent to the target window with no event mask and propagation turned off.
The valid XEmbed messages are:
/* XEMBED messages */ #define XEMBED_EMBEDDED_NOTIFY 0 #define XEMBED_WINDOW_ACTIVATE 1 #define XEMBED_WINDOW_DEACTIVATE 2 #define XEMBED_REQUEST_FOCUS 3 #define XEMBED_FOCUS_IN 4 #define XEMBED_FOCUS_OUT 5 #define XEMBED_FOCUS_NEXT 6 #define XEMBED_FOCUS_PREV 7 /* 8-9 were used for XEMBED_GRAB_KEY/XEMBED_UNGRAB_KEY */ #define XEMBED_MODALITY_ON 10 #define XEMBED_MODALITY_OFF 11 #define XEMBED_REGISTER_ACCELERATOR 12 #define XEMBED_UNREGISTER_ACCELERATOR 13 #define XEMBED_ACTIVATE_ACCELERATOR 14
A detail code is required for XEMBED_FOCUS_IN. The following values are valid:
/* Details for XEMBED_FOCUS_IN: */ #define XEMBED_FOCUS_CURRENT 0 #define XEMBED_FOCUS_FIRST 1 #define XEMBED_FOCUS_LAST 2
Sent from the embedder to the client on embedding, after reparenting and mapping the client's X window. A client that receives this messages knows that its window was embedded by an XEmbed site and not simply reparented by a window manager. To support toolkits that do not keep track of reparenting events, the message carries the embedder's window handle as data1:
data1 | The embedder's window handle. |
data2 | The protocol version in use (see the description of _XEMBED_INFO). |
Sent from the embedder to the client when the window becomes active or inactive, i.e. when the window gets or looses the keyboard input focus. If the client contains embedders itself, those have to pass the message through to their clients.
Note that no XEMBED_FOCUS_IN or XEMBED_FOCUS_OUT messages should be sent when the toplevel window gains or loses focus. The XEMBED_FOCUS_IN and XEMBED_FOCUS_OUT messages refer only to focus within the toplevel window and are independent of toplevel activation state. This independence is necessary so that input focus within a toplevel can be moved programmatically when the toplevel doesn't have input focus.
Widgets within the client should typically be displayed with the focus only when the client both has focus and is active.
Sent from the client to the embedder when the client wants focus. The most common occasion is when the user clicks into one of the client's child widgets, for example a line editor, in order to type something in.
The message is passed along to the topmost embedder that eventually responds with a XEMBED_FOCUS_IN message. The focus in message is passed all the way back until it reaches the original focus requester. In the end, not only the original client has focus, but also all its ancestor embedders.
Sent from the embedder to the client when it gets focus. The detail code determines, where the client shall move its own logical focus to. Three possibilities exist:
Normal activation, does not move the clients logical focus.
Used when the user tabs onto a client. It indicates that the client should put its logical focus onto the widget that comes first in its own tab focus chain.
Used when the user tabs onto a client. It indicates that the client should put its logical focus onto the widget that comes first in its own tab focus chain.
Sent from the embedder to the client when it looses focus.
Sent from the client to the embedder when it reaches the end of its logical tab chain after the user tabbed forward. If the embedder has siblings that accept tab focus, it will do a virtual tab forward. As a result, it will loose focus itself and consequently send an XEMBED_FOCUS_OUT message to the client
Sent from the client to the embedder when it reaches the beginning of its logical tab chain after the user tabbed backward. If the embedder has siblings that accept tab focus, it will do a virtual tab backward. As a result, it will loose focus itself and consequently send an XEMBED_FOCUS_OUT message to the client
A client that needs to reserve a certain key/modifier combination as shortcut or accelerators, sends a XEMBED_REGISTER_ACCELERATOR message to its embedder. As long as the embedder itself is a child of a client, the accelerator will be propagated up to the toplevel.
detail | accelerator_id |
data1 | X key symbol |
data2 | bit field of modifier values |
The accelerator_id is used to identify the accelerator when activating the accelerator. The reason for using an accelerator ID instead of identifying accelerators simply by key symbol and modifiers is to allow the correct handling of overloaded accelerators with embedded widgets. (An accelerator is overloaded if there multiple accelerators on the same key, usually because of accidental collisions.) When an overloaded accelerator is pressed repeatedly, the toplevel activates accelerators on that key in round-robin fashion. If this round-robin behavior is not supported by the embedding toolkit, picking an arbitrary accelerator for the key and activating it is acceptable. Well designed applications should avoid collisions in any case.
Ordering the round-robin of conflicting accelerators in a predictable (geometric or in focus chain) order is desirable. This can be achieved if the toplevel sorts the conflicting accelerators as if they applied to the client instead of widgets within the client and then each client does the same sort on the subset of conflicting accelerators within it. To get this to work properly if there are conflicting accelerators within a client, say widget A and B both have the same mnemonic, then instead of registering one accelerator for widget A and one for widget B, the client should register two accelerators that corresponds to both A and B, and then when XEMBED_ACTIVATE_ACCELERATOR is received for either accelerator, implement round robin between A and B with the correct sorting.
The modified bit field is a bitwise OR of values indicating various modifiers; these indicate logical accelerator keys rather than corresponding directly to the bits in the XKeyEvent state field.
/* Modifiers field for XEMBED_REGISTER_ACCELERATOR */ #define XEMBED_MODIFIER_SHIFT (1 << 0) #define XEMBED_MODIFIER_CONTROL (1 << 1) #define XEMBED_MODIFIER_ALT (1 << 2) #define XEMBED_MODIFIER_SUPER (1 << 3) #define XEMBED_MODIFIER_HYPER (1 << 4)
(Meta is intentionally left out here because if you try to separate Alt and Meta, a large fraction of users will experience problems with their keyboard setups... there is no reliably standard of which one is the primary modifier key and on the Alt key.)
On activation, the topmost embedder will send XEMBED_ACTIVATE_ACCELERATOR to its client; if the accelerator was registered by an embedder inside that client, the embedder will send XEMBED_ACTIVATE_ACCELERATOR to its client and so forth.
Note that the assignment of ID's is private for each pair of client and embedder and when accelerators are being propagated through multiple client/embedder pairs, a different accelerator ID may be used for each pair.
The XEMBED_UNREGISTER_ACCELERATOR message releases the key combination again.
detail | integer ID passed to XEMBED_REGISTER_ACCELERATOR |
Hint to implementors: It is the responsibility of the embedder to keep track of all forwarded accelerators and to remove them when the client window dies.
The XEMBED_ACTIVATE_ACCELERATOR message is sent when a accelerator previously registered with XEMBED_REGISTER_ACCELERATOR is activated on the toplevel containing the embedder.
detail | integer ID passed when registering the accelerator |
data1 | flags. |
The following bit is defined for the flags field; all other bits must be zero.
/* Flags for XEMBED_ACTIVATE_ACCELERATOR */ #define XEMBED_ACCELERATOR_OVERLOADED (1 << 0)
This flag indicates that multiple accelerators exist for the key combination within the toplevel. The toolkit may modify the behavior of the accelerator based on this value. For instance, if the accelerator is a mnemonic for a button, it might activate the the button immediately if the accelerator is not overloaded, but when overloaded, it would only focus the button.
Sent from the embedder to the client when the window becomes shadowed by a modal dialog, or when it is released again. If the client contains embedders itself, those have to pass the message through to their clients. An embedded control should ignore mouse input while modality is active. Note that that keyboard input is blocked anyway by XEmbed, since the topmost embedder will not pass keyboard events through in modal state.