|
|
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.