|
|
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: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.