I was trying to create a child interpreter which could
create a set of widgets and embed that within a frame
in the main interpreter. Most widgets work fine but
anything that depends on getting focus won't work
reliably on different platforms or with different
window managers.
To reproduce, create an interp within the main
interpreter and create a Tk text widget within the
child. It is difficult to get the text widget to take
the focus by clicking. This means that the "I" cursor
does not get inserted and the black line indicating
that the text area is ready for editing does not
appear. I played around with varying configurations
including packing and depth within the window hierarchy
with different results.
The following example always failed for me on Windows
2000 but seemed to work more often on Solaris using
CDE.
interp create child
toplevel .t
frame .t.f -container 1
pack .t.f -fill both -expand yes
interp eval child "lappend argv -use [winfo id .t.f]"
interp eval child {
load {} Tk
text .text
pack .text -fill both -expand yes
}
Logged In: YES
user_id=372263
The following patch seems to fix my problems under Solaris
2.7/CDE and Windows 2000. I'm applying it locally but more
feedback would be useful.
-Ahran
diff -c tkFocus.c.bak tkFocus.c
*** tkFocus.c.bak Fri Nov 9 15:16:37 2001
--- tkFocus.c Fri Nov 9 15:16:37 2001
***************
*** 645,651 ****
if ((topLevelPtr->flags & TK_EMBEDDED)
&& (displayFocusPtr->focusWinPtr == NULL)) {
! TkpClaimFocus(topLevelPtr, force);
} else if ((displayFocusPtr->focusWinPtr != NULL) ||
force) {
/*
* Generate events to shift focus between Tk windows.
--- 645,665 ----
if ((topLevelPtr->flags & TK_EMBEDDED)
&& (displayFocusPtr->focusWinPtr == NULL)) {
!
! /*
! * Fixes SF BUG 480158 'initial focus fails in child
interp'
! * Generate our own internal focus events just prior
to
! * sending out the external X events.
! */
! serial =
TkpChangeFocus(TkpGetWrapperWindow(topLevelPtr), force);
! if (serial != 0) {
! displayFocusPtr->focusSerial = serial;
! }
! GenerateFocusEvents(displayFocusPtr->focusWinPtr,
winPtr);
! displayFocusPtr->focusWinPtr = winPtr;
! winPtr->dispPtr->focusPtr = winPtr;
!
! TkpClaimFocus(topLevelPtr, force);
} else if ((displayFocusPtr->focusWinPtr != NULL) ||
force) {
/*
* Generate events to shift focus between Tk windows.
Logged In: YES
user_id=72656
This provides focus into the window on Windows (Linux works
before and after), but I still can't type into the window.