comparison src/frame-x.c @ 355:182f72e8cd0d r21-1-7

Import from CVS: tag r21-1-7
author cvs
date Mon, 13 Aug 2007 10:56:21 +0200
parents 19dcec799385
children cc15677e0335
comparison
equal deleted inserted replaced
354:3729bef672e0 355:182f72e8cd0d
101 /* Like x_window_to_frame but also compares the window with the widget's 101 /* Like x_window_to_frame but also compares the window with the widget's
102 windows */ 102 windows */
103 struct frame * 103 struct frame *
104 x_any_window_to_frame (struct device *d, Window wdesc) 104 x_any_window_to_frame (struct device *d, Window wdesc)
105 { 105 {
106 Widget w;
107 assert (DEVICE_X_P (d));
108
109 w = XtWindowToWidget (DEVICE_X_DISPLAY (d), wdesc);
110
111 if (!w)
112 return 0;
113
114 /* We used to map over all frames here and then map over all widgets
115 belonging to that frame. However it turns out that this was very fragile
116 as it requires our display stuctures to be in sync _and_ that the
117 loop is told about every new widget somebody adds. Therefore we
118 now let Xt find it for us (which does a bottom-up search which
119 could even be faster) */
120 return x_any_widget_or_parent_to_frame (d, w);
121 }
122
123 static struct frame *
124 x_find_frame_for_window (struct device *d, Window wdesc)
125 {
106 Lisp_Object tail, frame; 126 Lisp_Object tail, frame;
107 struct frame *f; 127 struct frame *f;
108
109 assert (DEVICE_X_P (d));
110
111 /* This function was previously written to accept only a window argument 128 /* This function was previously written to accept only a window argument
112 (and to loop over all devices looking for a matching window), but 129 (and to loop over all devices looking for a matching window), but
113 that is incorrect because window ID's are not unique across displays. */ 130 that is incorrect because window ID's are not unique across displays. */
114 131
115 for (tail = DEVICE_FRAME_LIST (d); CONSP (tail); tail = XCDR (tail)) 132 for (tail = DEVICE_FRAME_LIST (d); CONSP (tail); tail = XCDR (tail))
116 { 133 {
117 int i;
118
119 frame = XCAR (tail); 134 frame = XCAR (tail);
120 f = XFRAME (frame); 135 f = XFRAME (frame);
121 /* This frame matches if the window is any of its widgets. */ 136 /* This frame matches if the window is any of its widgets. */
122 if (wdesc == XtWindow (FRAME_X_SHELL_WIDGET (f)) || 137 if (wdesc == XtWindow (FRAME_X_SHELL_WIDGET (f)) ||
123 wdesc == XtWindow (FRAME_X_CONTAINER_WIDGET (f)) || 138 wdesc == XtWindow (FRAME_X_CONTAINER_WIDGET (f)) ||
136 for this statement is that, in the old (broken) event loop, where 151 for this statement is that, in the old (broken) event loop, where
137 not all events went through XtDispatchEvent(), psheet events 152 not all events went through XtDispatchEvent(), psheet events
138 would incorrectly get sucked away by Emacs if this function matched 153 would incorrectly get sucked away by Emacs if this function matched
139 on psheet widgets. */ 154 on psheet widgets. */
140 155
141 for (i = 0; i < FRAME_X_NUM_TOP_WIDGETS (f); i++) 156 /* Note: that this called only from
142 { 157 x_any_widget_or_parent_to_frame it is unnecessary to iterate
143 Widget wid = FRAME_X_TOP_WIDGETS (f)[i]; 158 over the top level widgets. */
144 if (wid && XtIsManaged (wid) && wdesc == XtWindow (wid)) 159
145 return f; 160 /* Note: we use to special case scrollbars but this turns out to be a bad idea
146 } 161 because
147 162 1. We sometimes get events for _unmapped_ scrollbars and our
148 #ifdef HAVE_SCROLLBARS 163 callers don't want us to fail.
149 /* Match if the window is one of this frame's scrollbars. */ 164 2. Starting with the 21.2 widget stuff there are now loads of
150 if (x_window_is_scrollbar (f, wdesc)) 165 widgets to check and it is easy to forget adding them in a loop here.
151 return f; 166 See x_any_window_to_frame
152 #endif 167 3. We pick up all widgets now anyway. */
153 } 168 }
154 169
155 return 0; 170 return 0;
156 } 171 }
157 172
158 struct frame * 173 struct frame *
159 x_any_widget_or_parent_to_frame (struct device *d, Widget widget) 174 x_any_widget_or_parent_to_frame (struct device *d, Widget widget)
160 { 175 {
161 while (widget) 176 while (widget)
162 { 177 {
163 struct frame *f = x_any_window_to_frame (d, XtWindow (widget)); 178 struct frame *f = x_find_frame_for_window (d, XtWindow (widget));
164 if (f) 179 if (f)
165 return f; 180 return f;
166 widget = XtParent (widget); 181 widget = XtParent (widget);
167 } 182 }
168 183