XEMBED: Preventing focus loops

Owen Taylor otaylor at redhat.com
Thu Aug 21 16:07:32 EEST 2003


Currently, it's possible to get into loops with focus messages and
XEMBED. The problem occurs when you have a client that doesn't have
any internal focus locations, embedded into a toplevel without
any focus sites.

If we try to focus the first widget in the toplevel (say, when
the toplevel is mapped), we get the following sequence:

 - Embedder sends XEMBED_FOCUS_IN/XEMBED_FOCUS_FIRST to the client
 - Client finds no focus sites, sends XEMBED_FOCUS_NEXT to
   the embedder
 - Embedder takes this as the user hitting Tab again, wraps
   around to the beginning, and sends another XEMBED_FOCUS_IN

If you have nested embedding, then this can occur over two
levels.

My proposed solution to this is to define the currently unused data1
of the XEMBED_FOCUS_IN, XEMBED_FOCUS_PREV and XEMBED_FOCUS next
messages as a flags field, with currently one flag defined:

#define XEMBED_FOCUS_WRAPAROUND         (1 << 0)

When sending one of these messages, the flag is set as follows:

 - If the message is not generated as the result as one of
   these three XEMBED messages, set the bit to zero

 - When generating an XEMBED_FOCUS_IN in response to a
   XEMBED_FOCUS_PREV or XEMBED_FOCUS_NEXT message and the
   focus moved from the bottom of the window to the top
   for a XEMBED_FOCUS_NEXT message or from the top of the
   window to the bottom for a XEMBED_FOCUS_PREV message:

   - If the bit was not set in the generating message, set
     the bit in the new message
   - If the bit was set in the generating message, a loop
     has be detected. DO NOT SEND THE NEW MESSAGE.

 - Otherwise, set the bit to the value found in the 
   generating message.
   
All other bits in the field are unused and must be set to zero.

Notes about the proposal:

 * The only difficult thing about implementing this proposal
   is detecting when XEMBED_FOCUS_NEXT causes a wrap-around
   at the toplevel. It required some hackiness to implement
   in GTK+. I think most toolkits will be similar - a bit
   hacky to do but possible.
 
 * The two other approach that I considered were:

   * assign a unique ID to the focus sequence so that an 
     individual embedder could check if it was repeating
     a focus sequence.

     Assigning a sufficiently unique ID is hard and requires
     using all the remaining free space in the messages
     instead of just one bit.You have to keep a history since 
     it is possible to have multiple interleaved infinite 
     focus loops.

   * Some sort of response message to XEMBED_FOCUS_IN,
     to allow tracking focus sequences without needing
     a globally unique ID for the sequence. 

     This has the same problem with multiple interleaved focus 
     sequences as the prior solution and would also require 
     a lot of complicated bookkeeping to implement.

 * I didn't up the protocol version because it is a highly
   compatible addition - there is nothing you would do
   differently if you knew that the other side didn't
   understand XEMBED_FOCUS_WRAPAROUND.

Thanks for any feedback; if I don't hear anything in the next
few days I'll go ahead and make the changes to the spec.

Regards,
						Owen

-------------- next part --------------
A non-text attachment was scrubbed...
Name: xembed.diff
Type: text/x-patch
Size: 8289 bytes
Desc: Diff to the XEMBED spec
Url : http://lists.freedesktop.org/archives/xdg/attachments/20030821/67905365/attachment.bin 


More information about the xdg mailing list