Mercurial > dwindows
comparison gtk/dw.c @ 1509:02bfae9fd3e7
Rewrote part of _dw_get_frame_extents() on GTK2 to not use XIfEvent() since
it will block if it never gets an event... even with our timeout code.
Instead use a property notify GTK signal handler and wait up to a second
for the notification using dw_main_iteration().
Also fixed a problem with dw_main_iteration() not updating the _dw_thread properly.
author | bsmith@81767d24-ef19-dc11-ae90-00e081727c95 |
---|---|
date | Wed, 28 Dec 2011 13:12:12 +0000 |
parents | 308bfa8426db |
children | 218c85939040 |
comparison
equal
deleted
inserted
replaced
1508:9b2600034473 | 1509:02bfae9fd3e7 |
---|---|
2251 /* | 2251 /* |
2252 * Processes a single message iteration and returns. | 2252 * Processes a single message iteration and returns. |
2253 */ | 2253 */ |
2254 void dw_main_iteration(void) | 2254 void dw_main_iteration(void) |
2255 { | 2255 { |
2256 gdk_threads_enter(); | 2256 pthread_t orig = _dw_thread; |
2257 _dw_thread = pthread_self(); | 2257 pthread_t curr = pthread_self(); |
2258 gtk_main_iteration(); | 2258 |
2259 _dw_thread = (pthread_t)-1; | 2259 if(_dw_thread == (pthread_t)-1) |
2260 gdk_threads_leave(); | 2260 { |
2261 _dw_thread = curr; | |
2262 gdk_threads_enter(); | |
2263 } | |
2264 if(curr == _dw_thread && gtk_events_pending()) | |
2265 gtk_main_iteration(); | |
2266 else | |
2267 #ifdef __sun__ | |
2268 sched_yield(); | |
2269 #else | |
2270 pthread_yield(); | |
2271 #endif | |
2272 if(orig == (pthread_t)-1) | |
2273 { | |
2274 _dw_thread = (pthread_t)-1; | |
2275 gdk_threads_leave(); | |
2276 } | |
2261 } | 2277 } |
2262 | 2278 |
2263 /* | 2279 /* |
2264 * Free's memory allocated by dynamic windows. | 2280 * Free's memory allocated by dynamic windows. |
2265 * Parameters: | 2281 * Parameters: |
3478 | 3494 |
3479 gtk_table_attach(GTK_TABLE(table), box, 0, 1, 1, 2, GTK_EXPAND | GTK_FILL | GTK_SHRINK, GTK_EXPAND | GTK_FILL | GTK_SHRINK, 0, 0); | 3495 gtk_table_attach(GTK_TABLE(table), box, 0, 1, 1, 2, GTK_EXPAND | GTK_FILL | GTK_SHRINK, GTK_EXPAND | GTK_FILL | GTK_SHRINK, 0, 0); |
3480 gtk_container_add(GTK_CONTAINER(tmp), table); | 3496 gtk_container_add(GTK_CONTAINER(tmp), table); |
3481 gtk_object_set_data(GTK_OBJECT(tmp), "_dw_boxhandle", (gpointer)box); | 3497 gtk_object_set_data(GTK_OBJECT(tmp), "_dw_boxhandle", (gpointer)box); |
3482 gtk_object_set_data(GTK_OBJECT(tmp), "_dw_table", (gpointer)table); | 3498 gtk_object_set_data(GTK_OBJECT(tmp), "_dw_table", (gpointer)table); |
3499 gtk_widget_add_events(GTK_WIDGET(tmp), GDK_PROPERTY_CHANGE_MASK); | |
3483 } | 3500 } |
3484 gtk_object_set_data(GTK_OBJECT(tmp), "_dw_style", GINT_TO_POINTER(flStyle)); | 3501 gtk_object_set_data(GTK_OBJECT(tmp), "_dw_style", GINT_TO_POINTER(flStyle)); |
3485 DW_MUTEX_UNLOCK; | 3502 DW_MUTEX_UNLOCK; |
3486 return tmp; | 3503 return tmp; |
3487 } | 3504 } |
10134 { | 10151 { |
10135 _dw_box_pack(box, item, 0, width, height, hsize, vsize, pad, "dw_box_pack_end()"); | 10152 _dw_box_pack(box, item, 0, width, height, hsize, vsize, pad, "dw_box_pack_end()"); |
10136 } | 10153 } |
10137 | 10154 |
10138 union extents_union { guchar **gu_extents; unsigned long **extents; }; | 10155 union extents_union { guchar **gu_extents; unsigned long **extents; }; |
10139 static Atom extents_atom = 0; | 10156 static GdkAtom extents_atom = 0; |
10140 static time_t extents_time = 0; | 10157 static time_t extents_time; |
10141 | 10158 |
10142 static Bool property_notify_predicate(Display *xdisplay, XEvent *event, XPointer window_id) | 10159 static gboolean _dw_property_notify(GtkWidget *window, GdkEventProperty* event, GdkWindow *gdkwindow) |
10143 { | 10160 { |
10144 unsigned long *window = (unsigned long *)window_id; | 10161 /* Check to see if we got a property change */ |
10145 time_t currtime = time(NULL); | 10162 if(event->state == GDK_PROPERTY_NEW_VALUE && event->atom == extents_atom && event->window == gdkwindow) |
10146 | 10163 extents_time = 0; |
10147 /* If it is the event we are looking for... or if the timeout has expired */ | 10164 return FALSE; |
10148 if((event->xany.type == PropertyNotify && event->xany.window == *window && event->xproperty.atom == extents_atom) || | |
10149 (currtime - extents_time) > 1) | |
10150 return True; | |
10151 return False; | |
10152 } | 10165 } |
10153 | 10166 |
10154 /* Internal function to figure out the frame extents of an unmapped window */ | 10167 /* Internal function to figure out the frame extents of an unmapped window */ |
10155 void _dw_get_frame_extents(GtkWidget *window, int *vert, int *horz) | 10168 void _dw_get_frame_extents(GtkWidget *window, int *vert, int *horz) |
10156 { | 10169 { |
10158 { | 10171 { |
10159 const char *request = "_NET_REQUEST_FRAME_EXTENTS"; | 10172 const char *request = "_NET_REQUEST_FRAME_EXTENTS"; |
10160 unsigned long *extents = NULL; | 10173 unsigned long *extents = NULL; |
10161 union extents_union eu; | 10174 union extents_union eu; |
10162 GdkAtom request_extents = gdk_atom_intern(request, FALSE); | 10175 GdkAtom request_extents = gdk_atom_intern(request, FALSE); |
10176 | |
10177 if(!extents_atom) | |
10178 extents_atom = gdk_atom_intern("_NET_FRAME_EXTENTS", FALSE); | |
10163 | 10179 |
10164 /* Set some rational defaults.. just in case */ | 10180 /* Set some rational defaults.. just in case */ |
10165 *vert = 28; | 10181 *vert = 28; |
10166 *horz = 12; | 10182 *horz = 12; |
10167 | 10183 |
10172 Display *xdisplay = GDK_DISPLAY_XDISPLAY(display); | 10188 Display *xdisplay = GDK_DISPLAY_XDISPLAY(display); |
10173 GdkWindow *root_window = gdk_get_default_root_window(); | 10189 GdkWindow *root_window = gdk_get_default_root_window(); |
10174 Window xroot_window = GDK_WINDOW_XID(root_window); | 10190 Window xroot_window = GDK_WINDOW_XID(root_window); |
10175 Atom extents_request_atom = gdk_x11_get_xatom_by_name_for_display(display, request); | 10191 Atom extents_request_atom = gdk_x11_get_xatom_by_name_for_display(display, request); |
10176 unsigned long window_id = GDK_WINDOW_XID(GDK_DRAWABLE(window->window)); | 10192 unsigned long window_id = GDK_WINDOW_XID(GDK_DRAWABLE(window->window)); |
10177 XEvent notify_xevent, xevent = {0}; | 10193 XEvent xevent = {0}; |
10178 | 10194 time_t currtime; |
10179 if(!extents_atom) | 10195 gulong connid; |
10180 { | |
10181 const char *extents_name = "_NET_FRAME_EXTENTS"; | |
10182 extents_atom = gdk_x11_get_xatom_by_name_for_display(display, extents_name); | |
10183 } | |
10184 | 10196 |
10185 xevent.xclient.type = ClientMessage; | 10197 xevent.xclient.type = ClientMessage; |
10186 xevent.xclient.message_type = extents_request_atom; | 10198 xevent.xclient.message_type = extents_request_atom; |
10187 xevent.xclient.display = xdisplay; | 10199 xevent.xclient.display = xdisplay; |
10188 xevent.xclient.window = window_id; | 10200 xevent.xclient.window = window_id; |
10191 /* Send the property request */ | 10203 /* Send the property request */ |
10192 XSendEvent(xdisplay, xroot_window, False, | 10204 XSendEvent(xdisplay, xroot_window, False, |
10193 (SubstructureRedirectMask | SubstructureNotifyMask), | 10205 (SubstructureRedirectMask | SubstructureNotifyMask), |
10194 &xevent); | 10206 &xevent); |
10195 | 10207 |
10208 /* Connect a signal to look for the property change */ | |
10209 connid = gtk_signal_connect(GTK_OBJECT(window), "property_notify_event", GTK_SIGNAL_FUNC(_dw_property_notify), window->window); | |
10210 | |
10196 /* Record the request time */ | 10211 /* Record the request time */ |
10197 time(&extents_time); | 10212 time(&extents_time); |
10198 | 10213 |
10199 /* Look for the property notify event */ | 10214 /* Look for the property notify event */ |
10200 XIfEvent(xdisplay, ¬ify_xevent, property_notify_predicate, (XPointer)&window_id); | 10215 do |
10201 | 10216 { |
10202 /* If we didn't get the notification... put the event back onto the stack */ | 10217 dw_main_iteration(); |
10203 if(notify_xevent.xany.type != PropertyNotify || notify_xevent.xany.window != window_id | 10218 time(&currtime); |
10204 || notify_xevent.xproperty.atom != extents_atom) | 10219 } |
10205 XPutBackEvent(xdisplay, ¬ify_xevent); | 10220 while(currtime - extents_time < 2); |
10221 | |
10222 /* Remove the signal handler now that we are done */ | |
10223 gtk_signal_disconnect(GTK_OBJECT(window), connid); | |
10206 } | 10224 } |
10207 | 10225 |
10208 /* Attempt to retrieve window's frame extents. */ | 10226 /* Attempt to retrieve window's frame extents. */ |
10209 eu.extents = &extents; | 10227 eu.extents = &extents; |
10210 if(gdk_property_get(window->window, | 10228 if(gdk_property_get(window->window, |
10211 gdk_atom_intern("_NET_FRAME_EXTENTS", FALSE), | 10229 extents_atom, |
10212 gdk_atom_intern("CARDINAL", FALSE), | 10230 gdk_atom_intern("CARDINAL", FALSE), |
10213 0, sizeof(unsigned long)*4, FALSE, | 10231 0, sizeof(unsigned long)*4, FALSE, |
10214 NULL, NULL, NULL, eu.gu_extents)) | 10232 NULL, NULL, NULL, eu.gu_extents)) |
10215 { | 10233 { |
10216 *horz = extents[0] + extents[1]; | 10234 *horz = extents[0] + extents[1]; |