Annotation of micropolis/src/notes/to.ouster, revision 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.