]> git.zerfleddert.de Git - micropolis/blame - src/notes/to.ouster
src/tk/makefile: Micropolis build fixes for recent macOS
[micropolis] / src / notes / to.ouster
CommitLineData
6a5fa4e0
MG
1To: ouster@sprite.berkeley.edu
2Cc: hopkins
3Subject: more multiple display stuff
4--text follows this line--
5A problem I fixed is that the "focus" command only returns the focus
6of the main window's display, and there's no way to find out the focus
7on other displays. I fixed this by adding a "focus -query .window"
8form, that returns the focus of the display of the named window. When
9the tcl menu tracking code supports multiple displays, it will need to
10use this form to save the focus of the appropriate display before
11popping up a menu.
12
13A problem I haven't fixed yet is with the "selection" command, which
14right now will only retrieve the selection from the display of the
15main window. Pasting into a text field on another display with ^V
16inserts the selection from the main display. It could be changed to
17take a window argument similar to "focus".
18
19I wish I could think of a better flag name than "-query"...
20
21I had a go at hacking the Tk C code to keep track of one focus per
22display instead of per main window. (Should I be using one main
23window per display? I'm not now, I'm just creating remote toplevels
24with the -screen argument.) I moved the "struct TkWindow *focusPtr;"
25from the TkMainInfo to the TkDisplay structure, and modified the code
26in tkEvent.c that handled it and tkWindow.c that initialized it.
27
28In tkEvent.c, I changed 3 "winPtr->mainPtr->focusPtr"'s to
29"winPtr->dispPtr->focusPtr", in Tk_HandleEvent and TkEventDeadWindow.
30I worked over Tk_FocusCmd and TkFocusEventProc, included below.
31I'm not sure what the "winPtr == winPtr->dispPtr->mouseMainPtr" test
32at the end of Tk_FocusCmd really intends, but the transformation was
33pretty straightforward, and it seems to work for my cases.
34
35I've looked at the tcl code to try to figure out how to make it track
36properly with multiple displays. I think I'll need a function that
37given the name of a window, returns a unique string describing the
38display, that I can use to make tk_priv keys that distinguish between
39displays. The tcl functions tk_mbUnpost, tk_nextMenu, and
40tk_nextMenuEntry all need to take an argument so they can figure out
41which display to work on.
42
43Another unrelated fix I made to Tk and Tcl was to put the TK_LIBRARY
44and TCL_LIBRARY strings into global variables, and refer to those
45variables instead of embeding strings in the code, so it's possible to
46set them up properly before initializing, since I want to be able to
47set a couple environment variables and run the application with no
48installation. Is there a more appropriate way to do this?
49
50 -Don
51
52Here is the code for Tk_FocusCmd and TkFocusEventProc:
53
54\f
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
72int
73Tk_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\f
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
173void
174TkFocusEventProc(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}
Impressum, Datenschutz