Annotation of micropolis/src/notes/to.ouster, revision 1.1.1.1

1.1       root        1: To: [email protected]
                      2: Cc: hopkins
                      3: Subject: more multiple display stuff
                      4: --text follows this line--
                      5: A problem I fixed is that the "focus" command only returns the focus
                      6: of the main window's display, and there's no way to find out the focus
                      7: on other displays.  I fixed this by adding a "focus -query .window"
                      8: form, that returns the focus of the display of the named window.  When
                      9: the tcl menu tracking code supports multiple displays, it will need to
                     10: use this form to save the focus of the appropriate display before
                     11: popping up a menu. 
                     12: 
                     13: A problem I haven't fixed yet is with the "selection" command, which
                     14: right now will only retrieve the selection from the display of the
                     15: main window.  Pasting into a text field on another display with ^V
                     16: inserts the selection from the main display.  It could be changed to
                     17: take a window argument similar to "focus". 
                     18: 
                     19: I wish I could think of a better flag name than "-query"...  
                     20: 
                     21: I had a go at hacking the Tk C code to keep track of one focus per
                     22: display instead of per main window.  (Should I be using one main
                     23: window per display?  I'm not now, I'm just creating remote toplevels
                     24: with the -screen argument.)  I moved the "struct TkWindow *focusPtr;"
                     25: from the TkMainInfo to the TkDisplay structure, and modified the code
                     26: in tkEvent.c that handled it and tkWindow.c that initialized it.  
                     27: 
                     28: In tkEvent.c, I changed 3 "winPtr->mainPtr->focusPtr"'s to
                     29: "winPtr->dispPtr->focusPtr", in Tk_HandleEvent and TkEventDeadWindow.  
                     30: I worked over Tk_FocusCmd and TkFocusEventProc, included below.  
                     31: I'm not sure what the "winPtr == winPtr->dispPtr->mouseMainPtr" test
                     32: at the end of Tk_FocusCmd really intends, but the transformation was
                     33: pretty straightforward, and it seems to work for my cases.  
                     34: 
                     35: I've looked at the tcl code to try to figure out how to make it track
                     36: properly with multiple displays.  I think I'll need a function that
                     37: given the name of a window, returns a unique string describing the
                     38: display, that I can use to make tk_priv keys that distinguish between
                     39: displays.  The tcl functions tk_mbUnpost, tk_nextMenu, and
                     40: tk_nextMenuEntry all need to take an argument so they can figure out
                     41: which display to work on. 
                     42: 
                     43: Another unrelated fix I made to Tk and Tcl was to put the TK_LIBRARY
                     44: and TCL_LIBRARY strings into global variables, and refer to those
                     45: variables instead of embeding strings in the code, so it's possible to
                     46: set them up properly before initializing, since I want to be able to
                     47: set a couple environment variables and run the application with no
                     48: installation.  Is there a more appropriate way to do this? 
                     49: 
                     50:        -Don
                     51: 
                     52: Here is the code for Tk_FocusCmd and TkFocusEventProc:
                     53: 
                     54: 
                     55: /*
                     56:  *--------------------------------------------------------------
                     57:  *
                     58:  * Tk_FocusCmd --
                     59:  *
                     60:  *     This procedure is invoked to process the "focus" Tcl command.
                     61:  *     See the user documentation for details on what it does.
                     62:  *
                     63:  * Results:
                     64:  *     A standard Tcl result.
                     65:  *
                     66:  * Side effects:
                     67:  *     See the user documentation.
                     68:  *
                     69:  *--------------------------------------------------------------
                     70:  */
                     71: 
                     72: int
                     73: Tk_FocusCmd(clientData, interp, argc, argv)
                     74:     ClientData clientData;     /* Main window associated with
                     75:                                 * interpreter. */
                     76:     Tcl_Interp *interp;                /* Current interpreter. */
                     77:     int argc;                  /* Number of arguments. */
                     78:     char **argv;               /* Argument strings. */
                     79: {
                     80:     Tk_Window tkwin = (Tk_Window) clientData;
                     81:     register TkWindow *winPtr = (TkWindow *) clientData;
                     82:     register TkWindow *newPtr;
                     83: 
                     84:     if (argc > 3) {
                     85:        focusSyntax:
                     86:        Tcl_AppendResult(interp, "too many args: should be \"",
                     87:                argv[0], " ?-query? ?window?\"", (char *) NULL);
                     88:        return TCL_ERROR;
                     89:     }
                     90: 
                     91:     if (argc == 1) {
                     92:        if (winPtr->dispPtr->focusPtr == NULL) {
                     93:            interp->result = "none";
                     94:        } else {
                     95:            interp->result = winPtr->dispPtr->focusPtr->pathName;
                     96:        }
                     97:        return TCL_OK;
                     98:     }
                     99: 
                    100:     if (argv[1][0] == '-') {
                    101:        int switchLength;
                    102: 
                    103:        switchLength = strlen(argv[1]);
                    104:        if ((switchLength >= 2)
                    105:                && (strncmp(argv[1], "-query", switchLength) == 0)) {
                    106: 
                    107:            if (argc != 3) {
                    108:                goto focusSyntax;
                    109:            }
                    110: 
                    111:            newPtr = (TkWindow *) Tk_NameToWindow(interp, argv[2], tkwin);
                    112:            if (newPtr == NULL) {
                    113:                return TCL_ERROR;
                    114:            }
                    115:            if (newPtr->dispPtr->focusPtr == NULL) {
                    116:                interp->result = "none";
                    117:            } else {
                    118:                interp->result = newPtr->dispPtr->focusPtr->pathName;
                    119:            }
                    120:            return TCL_OK;
                    121:        }
                    122:     }
                    123: 
                    124:     if (argc != 2) {
                    125:        goto focusSyntax;
                    126:     }
                    127: 
                    128:     if (strcmp(argv[1], "none") == 0) {
                    129:        newPtr = NULL;
                    130:     } else {
                    131:        newPtr = (TkWindow *) Tk_NameToWindow(interp, argv[1], tkwin);
                    132:        if (newPtr == NULL) {
                    133:            return TCL_ERROR;
                    134:        }
                    135:     }
                    136:     if (newPtr->dispPtr->focusPtr == newPtr) {
                    137:        return TCL_OK;
                    138:     }
                    139:     if (winPtr == newPtr->dispPtr->mouseMainPtr) { /* XXX: ??? presumably */
                    140:        if ((newPtr->dispPtr->focusPtr != NULL)
                    141:                && (newPtr->dispPtr->focusPtr->focusProc != NULL)) {
                    142:            (*newPtr->dispPtr->focusPtr->focusProc)(
                    143:                    newPtr->dispPtr->focusPtr->focusData, 0);
                    144:        }
                    145:        newPtr->dispPtr->focusPtr = newPtr;
                    146:        if ((newPtr != NULL) && (newPtr->focusProc != NULL)) {
                    147:            (*newPtr->focusProc)(newPtr->focusData, 1);
                    148:        }
                    149:     } else {
                    150:        newPtr->dispPtr->focusPtr = newPtr;
                    151:     }
                    152:     return TCL_OK;
                    153: }
                    154: 
                    155: /*
                    156:  *--------------------------------------------------------------
                    157:  *
                    158:  * TkFocusEventProc --
                    159:  *
                    160:  *     This procedure is invoked whenever the pointer enters
                    161:  *     or leaves a top-level window.  It notifies the current
                    162:  *     owner of the focus, if any.
                    163:  *
                    164:  * Results:
                    165:  *     None.
                    166:  *
                    167:  * Side effects:
                    168:  *     None.
                    169:  *
                    170:  *--------------------------------------------------------------
                    171:  */
                    172: 
                    173: void
                    174: TkFocusEventProc(winPtr, eventPtr)
                    175:     register TkWindow *winPtr; /* Top-level window just entered or left. */
                    176:     XEvent *eventPtr;          /* EnterWindow or LeaveWindow event. */
                    177: {
                    178:     register TkWindow *focusPtr;
                    179:     TkWindow *newMouseMainPtr = NULL;
                    180: 
                    181:     if (eventPtr->type == EnterNotify) {
                    182:        newMouseMainPtr = winPtr->mainPtr->winPtr;
                    183:     }
                    184:     if (winPtr->dispPtr->mouseMainPtr == newMouseMainPtr) {
                    185:        return;
                    186:     }
                    187:     if (winPtr->dispPtr->mouseMainPtr != NULL) {
                    188:        focusPtr = winPtr->dispPtr->focusPtr;
                    189:        if ((focusPtr != NULL)
                    190:                && (focusPtr->focusProc != NULL)) {
                    191:            (*focusPtr->focusProc)(focusPtr->focusData, 0);
                    192:        }
                    193:     }
                    194:     winPtr->dispPtr->mouseMainPtr = newMouseMainPtr;
                    195:     if (newMouseMainPtr != NULL) {
                    196:        focusPtr = newMouseMainPtr->dispPtr->focusPtr;
                    197:        if ((focusPtr != NULL)
                    198:                && (focusPtr->focusProc != NULL)) {
                    199:            (*focusPtr->focusProc)(focusPtr->focusData, 1);
                    200:        }
                    201:     }
                    202: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.