From 796dc4b1d76e79ef3c4a95751c33aabf721bfc51 Mon Sep 17 00:00:00 2001 From: Havoc Pennington Date: Thu, 28 Jun 2001 05:24:00 +0000 Subject: [PATCH] new function for mapping a window without fooling with stacking order, but 2001-06-19 Havoc Pennington * gdk/x11/gdkwindow-x11.c (gdk_window_show_unraised): new function for mapping a window without fooling with stacking order, but updating the "withdrawn" flag * gdk/x11/gdkevents-x11.c (gdk_event_translate): Do event filtering as soon as possible, moving move resize and wmspec_check handling after the event filter. Make default filter apply to all events, not just those with no GdkWindow wrapped around the X window. Fix a FIXME about how the window could be a pixmap using RTTI; this of course assumes GDK_IS_WINDOW() is optimized. Also, be robust against events not on a known GdkWindow. * gdk/x11/gdkmain-x11.c (gdk_x11_grab_server, gdk_x11_ungrab_server): export reference-counted server grabs, so other people can grab server over a GDK function that also does so. --- ChangeLog | 20 ++ ChangeLog.pre-2-0 | 20 ++ ChangeLog.pre-2-10 | 20 ++ ChangeLog.pre-2-2 | 20 ++ ChangeLog.pre-2-4 | 20 ++ ChangeLog.pre-2-6 | 20 ++ ChangeLog.pre-2-8 | 20 ++ docs/reference/gtk/tmpl/gtkrc.sgml | 1 - .../reference/gtk/tmpl/gtktreeviewcolumn.sgml | 8 +- docs/reference/gtk/tmpl/gtkwindow.sgml | 5 + gdk/gdkwindow.c | 2 +- gdk/gdkwindow.h | 1 + gdk/x11/gdkdnd-x11.c | 4 +- gdk/x11/gdkevents-x11.c | 244 ++++++++++++------ gdk/x11/gdkgeometry-x11.c | 4 +- gdk/x11/gdkmain-x11.c | 20 ++ gdk/x11/gdkwindow-x11.c | 51 +++- gdk/x11/gdkx.h | 4 + 18 files changed, 380 insertions(+), 104 deletions(-) diff --git a/ChangeLog b/ChangeLog index 0ab82a2157..0ce0065f0f 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,23 @@ +2001-06-19 Havoc Pennington + + * gdk/x11/gdkwindow-x11.c (gdk_window_show_unraised): new function + for mapping a window without fooling with stacking order, but + updating the "withdrawn" flag + + * gdk/x11/gdkevents-x11.c (gdk_event_translate): Do event + filtering as soon as possible, moving move resize and wmspec_check + handling after the event filter. Make default filter apply to all + events, not just those with no GdkWindow wrapped around the X + window. Fix a FIXME about how the window could be a pixmap using + RTTI; this of course assumes GDK_IS_WINDOW() is optimized. + + Also, be robust against events not on a known GdkWindow. + + * gdk/x11/gdkmain-x11.c (gdk_x11_grab_server, + gdk_x11_ungrab_server): export reference-counted server grabs, so + other people can grab server over a GDK function that also does + so. + Wed Jun 27 19:40:31 2001 Jonathan Blandford * gtk/gtktreeviewcolumn.c diff --git a/ChangeLog.pre-2-0 b/ChangeLog.pre-2-0 index 0ab82a2157..0ce0065f0f 100644 --- a/ChangeLog.pre-2-0 +++ b/ChangeLog.pre-2-0 @@ -1,3 +1,23 @@ +2001-06-19 Havoc Pennington + + * gdk/x11/gdkwindow-x11.c (gdk_window_show_unraised): new function + for mapping a window without fooling with stacking order, but + updating the "withdrawn" flag + + * gdk/x11/gdkevents-x11.c (gdk_event_translate): Do event + filtering as soon as possible, moving move resize and wmspec_check + handling after the event filter. Make default filter apply to all + events, not just those with no GdkWindow wrapped around the X + window. Fix a FIXME about how the window could be a pixmap using + RTTI; this of course assumes GDK_IS_WINDOW() is optimized. + + Also, be robust against events not on a known GdkWindow. + + * gdk/x11/gdkmain-x11.c (gdk_x11_grab_server, + gdk_x11_ungrab_server): export reference-counted server grabs, so + other people can grab server over a GDK function that also does + so. + Wed Jun 27 19:40:31 2001 Jonathan Blandford * gtk/gtktreeviewcolumn.c diff --git a/ChangeLog.pre-2-10 b/ChangeLog.pre-2-10 index 0ab82a2157..0ce0065f0f 100644 --- a/ChangeLog.pre-2-10 +++ b/ChangeLog.pre-2-10 @@ -1,3 +1,23 @@ +2001-06-19 Havoc Pennington + + * gdk/x11/gdkwindow-x11.c (gdk_window_show_unraised): new function + for mapping a window without fooling with stacking order, but + updating the "withdrawn" flag + + * gdk/x11/gdkevents-x11.c (gdk_event_translate): Do event + filtering as soon as possible, moving move resize and wmspec_check + handling after the event filter. Make default filter apply to all + events, not just those with no GdkWindow wrapped around the X + window. Fix a FIXME about how the window could be a pixmap using + RTTI; this of course assumes GDK_IS_WINDOW() is optimized. + + Also, be robust against events not on a known GdkWindow. + + * gdk/x11/gdkmain-x11.c (gdk_x11_grab_server, + gdk_x11_ungrab_server): export reference-counted server grabs, so + other people can grab server over a GDK function that also does + so. + Wed Jun 27 19:40:31 2001 Jonathan Blandford * gtk/gtktreeviewcolumn.c diff --git a/ChangeLog.pre-2-2 b/ChangeLog.pre-2-2 index 0ab82a2157..0ce0065f0f 100644 --- a/ChangeLog.pre-2-2 +++ b/ChangeLog.pre-2-2 @@ -1,3 +1,23 @@ +2001-06-19 Havoc Pennington + + * gdk/x11/gdkwindow-x11.c (gdk_window_show_unraised): new function + for mapping a window without fooling with stacking order, but + updating the "withdrawn" flag + + * gdk/x11/gdkevents-x11.c (gdk_event_translate): Do event + filtering as soon as possible, moving move resize and wmspec_check + handling after the event filter. Make default filter apply to all + events, not just those with no GdkWindow wrapped around the X + window. Fix a FIXME about how the window could be a pixmap using + RTTI; this of course assumes GDK_IS_WINDOW() is optimized. + + Also, be robust against events not on a known GdkWindow. + + * gdk/x11/gdkmain-x11.c (gdk_x11_grab_server, + gdk_x11_ungrab_server): export reference-counted server grabs, so + other people can grab server over a GDK function that also does + so. + Wed Jun 27 19:40:31 2001 Jonathan Blandford * gtk/gtktreeviewcolumn.c diff --git a/ChangeLog.pre-2-4 b/ChangeLog.pre-2-4 index 0ab82a2157..0ce0065f0f 100644 --- a/ChangeLog.pre-2-4 +++ b/ChangeLog.pre-2-4 @@ -1,3 +1,23 @@ +2001-06-19 Havoc Pennington + + * gdk/x11/gdkwindow-x11.c (gdk_window_show_unraised): new function + for mapping a window without fooling with stacking order, but + updating the "withdrawn" flag + + * gdk/x11/gdkevents-x11.c (gdk_event_translate): Do event + filtering as soon as possible, moving move resize and wmspec_check + handling after the event filter. Make default filter apply to all + events, not just those with no GdkWindow wrapped around the X + window. Fix a FIXME about how the window could be a pixmap using + RTTI; this of course assumes GDK_IS_WINDOW() is optimized. + + Also, be robust against events not on a known GdkWindow. + + * gdk/x11/gdkmain-x11.c (gdk_x11_grab_server, + gdk_x11_ungrab_server): export reference-counted server grabs, so + other people can grab server over a GDK function that also does + so. + Wed Jun 27 19:40:31 2001 Jonathan Blandford * gtk/gtktreeviewcolumn.c diff --git a/ChangeLog.pre-2-6 b/ChangeLog.pre-2-6 index 0ab82a2157..0ce0065f0f 100644 --- a/ChangeLog.pre-2-6 +++ b/ChangeLog.pre-2-6 @@ -1,3 +1,23 @@ +2001-06-19 Havoc Pennington + + * gdk/x11/gdkwindow-x11.c (gdk_window_show_unraised): new function + for mapping a window without fooling with stacking order, but + updating the "withdrawn" flag + + * gdk/x11/gdkevents-x11.c (gdk_event_translate): Do event + filtering as soon as possible, moving move resize and wmspec_check + handling after the event filter. Make default filter apply to all + events, not just those with no GdkWindow wrapped around the X + window. Fix a FIXME about how the window could be a pixmap using + RTTI; this of course assumes GDK_IS_WINDOW() is optimized. + + Also, be robust against events not on a known GdkWindow. + + * gdk/x11/gdkmain-x11.c (gdk_x11_grab_server, + gdk_x11_ungrab_server): export reference-counted server grabs, so + other people can grab server over a GDK function that also does + so. + Wed Jun 27 19:40:31 2001 Jonathan Blandford * gtk/gtktreeviewcolumn.c diff --git a/ChangeLog.pre-2-8 b/ChangeLog.pre-2-8 index 0ab82a2157..0ce0065f0f 100644 --- a/ChangeLog.pre-2-8 +++ b/ChangeLog.pre-2-8 @@ -1,3 +1,23 @@ +2001-06-19 Havoc Pennington + + * gdk/x11/gdkwindow-x11.c (gdk_window_show_unraised): new function + for mapping a window without fooling with stacking order, but + updating the "withdrawn" flag + + * gdk/x11/gdkevents-x11.c (gdk_event_translate): Do event + filtering as soon as possible, moving move resize and wmspec_check + handling after the event filter. Make default filter apply to all + events, not just those with no GdkWindow wrapped around the X + window. Fix a FIXME about how the window could be a pixmap using + RTTI; this of course assumes GDK_IS_WINDOW() is optimized. + + Also, be robust against events not on a known GdkWindow. + + * gdk/x11/gdkmain-x11.c (gdk_x11_grab_server, + gdk_x11_ungrab_server): export reference-counted server grabs, so + other people can grab server over a GDK function that also does + so. + Wed Jun 27 19:40:31 2001 Jonathan Blandford * gtk/gtktreeviewcolumn.c diff --git a/docs/reference/gtk/tmpl/gtkrc.sgml b/docs/reference/gtk/tmpl/gtkrc.sgml index 82694173c4..5f8876c8fe 100644 --- a/docs/reference/gtk/tmpl/gtkrc.sgml +++ b/docs/reference/gtk/tmpl/gtkrc.sgml @@ -495,7 +495,6 @@ This can later be composited together with other #GtkRcStyle structures to form a #GtkStyle. -@parent_instance: @name: @bg_pixmap_name: @font_desc: diff --git a/docs/reference/gtk/tmpl/gtktreeviewcolumn.sgml b/docs/reference/gtk/tmpl/gtktreeviewcolumn.sgml index 92291010db..06b8f986b7 100644 --- a/docs/reference/gtk/tmpl/gtktreeviewcolumn.sgml +++ b/docs/reference/gtk/tmpl/gtktreeviewcolumn.sgml @@ -42,12 +42,8 @@ GtkTreeViewColumn @displayed_width: @drag_x: @drag_y: -@func: -@func_data: -@destroy: @title: -@cell: -@attributes: +@cell_list: @column_type: @sort_clicked_signal: @sort_column_changed_signal: @@ -103,6 +99,7 @@ GtkTreeViewColumn @tree_column: +@cell_renderer: @attribute: @column: @@ -113,6 +110,7 @@ GtkTreeViewColumn @tree_column: +@cell_renderer: @Varargs: diff --git a/docs/reference/gtk/tmpl/gtkwindow.sgml b/docs/reference/gtk/tmpl/gtkwindow.sgml index 95be4f3df5..7d43fb870a 100644 --- a/docs/reference/gtk/tmpl/gtkwindow.sgml +++ b/docs/reference/gtk/tmpl/gtkwindow.sgml @@ -524,6 +524,11 @@ If the window can be resized to a smaller size by the user. If the window can be resized to a larger size by the user. + + + + + If the window is modal, i.e. it grabs all GTK+ events. diff --git a/gdk/gdkwindow.c b/gdk/gdkwindow.c index 37b3354d0b..67002758ca 100644 --- a/gdk/gdkwindow.c +++ b/gdk/gdkwindow.c @@ -722,7 +722,7 @@ gdk_window_paint_init_bg (GdkWindow *window, * drawing operations performed on @window will be diverted to the * backing store. When you call gdk_window_end_paint(), the backing * store will be copied to @window, making it visible onscreen. Only - * the part of window contained in @region will be modified; that is, + * the part of @window contained in @region will be modified; that is, * drawing operations are clipped to @region. * * The net result of all this is to remove flicker, because the user diff --git a/gdk/gdkwindow.h b/gdk/gdkwindow.h index 90d63ebbdc..d13c5acb08 100644 --- a/gdk/gdkwindow.h +++ b/gdk/gdkwindow.h @@ -263,6 +263,7 @@ GdkWindow* gdk_window_at_pointer (gint *win_x, void gdk_window_show (GdkWindow *window); void gdk_window_hide (GdkWindow *window); void gdk_window_withdraw (GdkWindow *window); +void gdk_window_show_unraised (GdkWindow *window); void gdk_window_move (GdkWindow *window, gint x, gint y); diff --git a/gdk/x11/gdkdnd-x11.c b/gdk/x11/gdkdnd-x11.c index 4dc4d3ce98..3652ab490f 100644 --- a/gdk/x11/gdkdnd-x11.c +++ b/gdk/x11/gdkdnd-x11.c @@ -1149,7 +1149,7 @@ motif_add_to_target_table (GList *targets) */ motif_find_drag_window (TRUE); - XGrabServer(gdk_display); + gdk_x11_grab_server (); motif_read_target_table(); /* Check again, in case it was added in the meantime */ @@ -1225,7 +1225,7 @@ motif_add_to_target_table (GList *targets) 8, PropModeReplace, data, total_size); } - XUngrabServer(gdk_display); + gdk_x11_ungrab_server (); } g_list_free (sorted); diff --git a/gdk/x11/gdkevents-x11.c b/gdk/x11/gdkevents-x11.c index a0302943aa..8352527729 100644 --- a/gdk/x11/gdkevents-x11.c +++ b/gdk/x11/gdkevents-x11.c @@ -438,13 +438,31 @@ gdk_event_translate (GdkEvent *event, gint xoffset, yoffset; return_val = FALSE; + + /* init these, since the done: block uses them */ + window = NULL; + window_private = NULL; + event->any.window = NULL; - /* Find the GdkWindow that this event occurred in. - * - * We handle events with window=None - * specially - they are generated by XFree86's XInput under - * some circumstances. - */ + if (gdk_default_filters) + { + /* Apply global filters */ + GdkFilterReturn result; + result = gdk_event_apply_filters (xevent, event, + gdk_default_filters); + + if (result != GDK_FILTER_CONTINUE) + { + return_val = (result == GDK_FILTER_TRANSLATE) ? TRUE : FALSE; + goto done; + } + } + + /* We handle events with window=None + * specially - they are generated by XFree86's XInput under + * some circumstances. This handling for obvious reasons + * goes before we bother to lookup the event window. + */ if (xevent->xany.window == None) { @@ -455,19 +473,64 @@ gdk_event_translate (GdkEvent *event, else return_val = FALSE; } + + /* Find the GdkWindow that this event occurred in. */ window = gdk_window_lookup (xevent->xany.window); window_private = (GdkWindowObject *) window; - - if (_gdk_moveresize_window && - (xevent->xany.type == MotionNotify || - xevent->xany.type == ButtonRelease)) + + if (window != NULL) { - _gdk_moveresize_handle_event (xevent); - gdk_window_unref (window); - return FALSE; + /* Window may be a pixmap, so check its type. + * (This check is probably too expensive unless + * GLib short-circuits an exact type match, + * which has been proposed) + */ + if (GDK_IS_WINDOW (window)) + { + window_impl = GDK_WINDOW_IMPL_X11 (window_private->impl); + + if (xevent->xany.window != GDK_WINDOW_XID (window)) + { + g_assert (xevent->xany.window == window_impl->focus_window); + + switch (xevent->type) + { + case KeyPress: + case KeyRelease: + xevent->xany.window = GDK_WINDOW_XID (window); + break; + default: + return False; + } + } + } + + g_object_ref (G_OBJECT (window)); } - + + event->any.window = window; + event->any.send_event = xevent->xany.send_event ? TRUE : FALSE; + + if (window_private && GDK_WINDOW_DESTROYED (window)) + { + if (xevent->type != DestroyNotify) + return FALSE; + } + else if (window_private) + { + /* Apply per-window filters */ + GdkFilterReturn result; + result = gdk_event_apply_filters (xevent, event, + window_private->filters); + + if (result != GDK_FILTER_CONTINUE) + { + return_val = (result == GDK_FILTER_TRANSLATE) ? TRUE : FALSE; + goto done; + } + } + if (wmspec_check_window != None && xevent->xany.window == wmspec_check_window) { @@ -480,55 +543,17 @@ gdk_event_translate (GdkEvent *event, if (window == NULL) return FALSE; } + + if (window && + _gdk_moveresize_window && + (xevent->xany.type == MotionNotify || + xevent->xany.type == ButtonRelease)) + { + _gdk_moveresize_handle_event (xevent); + gdk_window_unref (window); + return FALSE; + } - /* FIXME: window might be a GdkPixmap!!! */ - if (window != NULL) - { - window_impl = GDK_WINDOW_IMPL_X11 (window_private->impl); - - if (xevent->xany.window != GDK_WINDOW_XID (window)) - { - g_assert (xevent->xany.window == window_impl->focus_window); - - switch (xevent->type) - { - case KeyPress: - case KeyRelease: - xevent->xany.window = GDK_WINDOW_XID (window); - break; - default: - return False; - } - } - - gdk_window_ref (window); - } - - event->any.window = window; - event->any.send_event = xevent->xany.send_event ? TRUE : FALSE; - - if (window_private && GDK_WINDOW_DESTROYED (window)) - { - if (xevent->type != DestroyNotify) - return FALSE; - } - else - { - /* Check for filters for this window - */ - GdkFilterReturn result; - result = gdk_event_apply_filters (xevent, event, - window_private - ?window_private->filters - :gdk_default_filters); - - if (result != GDK_FILTER_CONTINUE) - { - return_val = (result == GDK_FILTER_TRANSLATE) ? TRUE : FALSE; - goto done; - } - } - /* We do a "manual" conversion of the XEvent to a * GdkEvent. The structures are mostly the same so * the conversion is fairly straightforward. We also @@ -547,10 +572,16 @@ gdk_event_translate (GdkEvent *event, xoffset = 0; yoffset = 0; } - + switch (xevent->type) { case KeyPress: + if (window_private == NULL) + { + return_val = FALSE; + break; + } + /* Lookup the string corresponding to the given keysym. */ @@ -593,6 +624,12 @@ gdk_event_translate (GdkEvent *event, break; case KeyRelease: + if (window_private == NULL) + { + return_val = FALSE; + break; + } + /* Lookup the string corresponding to the given keysym. */ @@ -640,9 +677,9 @@ gdk_event_translate (GdkEvent *event, xevent->xbutton.x, xevent->xbutton.y, xevent->xbutton.button)); - if (window_private && - (window_private->extension_events != 0) && - gdk_input_ignore_core) + if (window_private == NULL || + ((window_private->extension_events != 0) && + gdk_input_ignore_core)) { return_val = FALSE; break; @@ -703,9 +740,9 @@ gdk_event_translate (GdkEvent *event, xevent->xbutton.x, xevent->xbutton.y, xevent->xbutton.button)); - if (window_private && - (window_private->extension_events != 0) && - gdk_input_ignore_core) + if (window_private == NULL || + ((window_private->extension_events != 0) && + gdk_input_ignore_core)) { return_val = FALSE; break; @@ -740,9 +777,9 @@ gdk_event_translate (GdkEvent *event, xevent->xmotion.x, xevent->xmotion.y, (xevent->xmotion.is_hint) ? "true" : "false")); - if (window_private && - (window_private->extension_events != 0) && - gdk_input_ignore_core) + if (window_private == NULL || + ((window_private->extension_events != 0) && + gdk_input_ignore_core)) { return_val = FALSE; break; @@ -768,7 +805,13 @@ gdk_event_translate (GdkEvent *event, xevent->xcrossing.window, xevent->xcrossing.detail, xevent->xcrossing.subwindow)); - + + if (window_private == NULL) + { + return_val = FALSE; + break; + } + /* Handle focusing (in the case where no window manager is running */ if (window && GDK_WINDOW_TYPE (window) != GDK_WINDOW_CHILD && @@ -855,6 +898,12 @@ gdk_event_translate (GdkEvent *event, g_message ("leave notify:\t\twindow: %ld detail: %d subwin: %ld", xevent->xcrossing.window, xevent->xcrossing.detail, xevent->xcrossing.subwindow)); + + if (window_private == NULL) + { + return_val = FALSE; + break; + } /* Handle focusing (in the case where no window manager is running */ if (window && @@ -1017,6 +1066,13 @@ gdk_event_translate (GdkEvent *event, xevent->xexpose.x, xevent->xexpose.y, xevent->xexpose.width, xevent->xexpose.height, event->any.send_event ? " (send)" : "")); + + if (window_private == NULL) + { + return_val = FALSE; + break; + } + { GdkRectangle expose_rect; @@ -1054,7 +1110,13 @@ gdk_event_translate (GdkEvent *event, GDK_NOTE (EVENTS, g_message ("graphics expose:\tdrawable: %ld", xevent->xgraphicsexpose.drawable)); - + + if (window_private == NULL) + { + return_val = FALSE; + break; + } + expose_rect.x = xevent->xgraphicsexpose.x + xoffset; expose_rect.y = xevent->xgraphicsexpose.y + yoffset; expose_rect.width = xevent->xgraphicsexpose.width; @@ -1110,6 +1172,12 @@ gdk_event_translate (GdkEvent *event, } #endif /* G_ENABLE_DEBUG */ + if (window_private == NULL) + { + return_val = FALSE; + break; + } + event->visibility.type = GDK_VISIBILITY_NOTIFY; event->visibility.window = window; @@ -1296,6 +1364,12 @@ gdk_event_translate (GdkEvent *event, atom ? "\"" : ""); g_free (atom); ); + + if (window_private == NULL) + { + return_val = FALSE; + break; + } event->property.type = GDK_PROPERTY_NOTIFY; event->property.window = window; @@ -1406,13 +1480,21 @@ gdk_event_translate (GdkEvent *event, break; case GDK_FILTER_CONTINUE: /* Send unknown ClientMessage's on to Gtk for it to use */ - event->client.type = GDK_CLIENT_EVENT; - event->client.window = window; - event->client.message_type = xevent->xclient.message_type; - event->client.data_format = xevent->xclient.format; - memcpy(&event->client.data, &xevent->xclient.data, - sizeof(event->client.data)); - } + if (window_private == NULL) + { + return_val = FALSE; + } + else + { + event->client.type = GDK_CLIENT_EVENT; + event->client.window = window; + event->client.message_type = xevent->xclient.message_type; + event->client.data_format = xevent->xclient.format; + memcpy(&event->client.data, &xevent->xclient.data, + sizeof(event->client.data)); + } + break; + } } break; diff --git a/gdk/x11/gdkgeometry-x11.c b/gdk/x11/gdkgeometry-x11.c index dff7274f67..28e10fc567 100644 --- a/gdk/x11/gdkgeometry-x11.c +++ b/gdk/x11/gdkgeometry-x11.c @@ -709,7 +709,7 @@ _gdk_window_process_expose (GdkWindow *window, GdkRegion *invalidate_region = gdk_region_rectangle (area); GdkRegion *clip_region; GSList *tmp_list = translate_queue; - + impl = GDK_WINDOW_IMPL_X11 (GDK_WINDOW_OBJECT (window)->impl); while (tmp_list) @@ -747,7 +747,7 @@ _gdk_window_process_expose (GdkWindow *window, if (!gdk_region_empty (invalidate_region)) gdk_window_invalidate_region (window, invalidate_region, FALSE); - + gdk_region_destroy (invalidate_region); gdk_region_destroy (clip_region); } diff --git a/gdk/x11/gdkmain-x11.c b/gdk/x11/gdkmain-x11.c index 27da88cd75..188c64cfa0 100644 --- a/gdk/x11/gdkmain-x11.c +++ b/gdk/x11/gdkmain-x11.c @@ -751,3 +751,23 @@ _gdk_region_get_xrectangles (GdkRegion *region, *rects = rectangles; *n_rects = region->numRects; } + +/* FIXME put in GdkDisplay */ +static gint grab_count = 0; +void +gdk_x11_grab_server (void) +{ + if (grab_count == 0) + XGrabServer (gdk_display); + ++grab_count; +} + +void +gdk_x11_ungrab_server (void) +{ + g_return_if_fail (grab_count > 0); + + --grab_count; + if (grab_count == 0) + XUngrabServer (gdk_display); +} diff --git a/gdk/x11/gdkwindow-x11.c b/gdk/x11/gdkwindow-x11.c index dfb2ea0c29..c4c498e340 100644 --- a/gdk/x11/gdkwindow-x11.c +++ b/gdk/x11/gdkwindow-x11.c @@ -807,8 +807,9 @@ set_initial_hints (GdkWindow *window) } } -void -gdk_window_show (GdkWindow *window) +static void +show_window_internal (GdkWindow *window, + gboolean raise) { GdkWindowObject *private; @@ -817,8 +818,9 @@ gdk_window_show (GdkWindow *window) private = (GdkWindowObject*) window; if (!private->destroyed) { - XRaiseWindow (GDK_WINDOW_XDISPLAY (window), - GDK_WINDOW_XID (window)); + if (raise) + XRaiseWindow (GDK_WINDOW_XDISPLAY (window), + GDK_WINDOW_XID (window)); if (!GDK_WINDOW_IS_MAPPED (window)) { @@ -837,6 +839,31 @@ gdk_window_show (GdkWindow *window) } } +/** + * gdk_window_show_unraised: + * @window: a #GdkWindow + * + * Shows a #GdkWindow onscreen, but does not modify its stacking + * order. In contrast, gdk_window_show() will raise the window + * to the top of the window stack. + * + **/ +void +gdk_window_show_unraised (GdkWindow *window) +{ + g_return_if_fail (GDK_IS_WINDOW (window)); + + show_window_internal (window, FALSE); +} + +void +gdk_window_show (GdkWindow *window) +{ + g_return_if_fail (GDK_IS_WINDOW (window)); + + show_window_internal (window, TRUE); +} + void gdk_window_hide (GdkWindow *window) { @@ -1982,8 +2009,8 @@ gdk_window_at_pointer (gint *win_x, xwindow = GDK_ROOT_WINDOW (); xdisplay = GDK_DISPLAY (); - - XGrabServer (xdisplay); + + gdk_x11_grab_server (); while (xwindow) { xwindow_last = xwindow; @@ -1993,7 +2020,7 @@ gdk_window_at_pointer (gint *win_x, &winx, &winy, &xmask); } - XUngrabServer (xdisplay); + gdk_x11_ungrab_server (); window = gdk_window_lookup (xwindow_last); @@ -3352,10 +3379,10 @@ gdk_window_xid_at_coords (gint x, root = GDK_WINDOW_XID (window); num = g_list_length (excludes); - XGrabServer (xdisplay); + gdk_x11_grab_server (); if (!XQueryTree (xdisplay, root, &root_win, &parent_win, &list, &num)) { - XUngrabServer (xdisplay); + gdk_x11_ungrab_server (); return root; } if (list) @@ -3381,20 +3408,20 @@ gdk_window_xid_at_coords (gint x, if (!g_list_find (excludes, (gpointer *) child)) { XFree (list); - XUngrabServer (xdisplay); + gdk_x11_ungrab_server (); return child; } } else { XFree (list); - XUngrabServer (xdisplay); + gdk_x11_ungrab_server (); return child; } } while (--i > 0); XFree (list); } - XUngrabServer (xdisplay); + gdk_x11_ungrab_server (); return root; } diff --git a/gdk/x11/gdkx.h b/gdk/x11/gdkx.h index ab54d4e758..5feb2bec4f 100644 --- a/gdk/x11/gdkx.h +++ b/gdk/x11/gdkx.h @@ -169,6 +169,10 @@ gpointer gdk_xid_table_lookup (XID xid); guint32 gdk_x11_get_server_time (GdkWindow *window); +/* FIXME should take a GdkDisplay* */ +void gdk_x11_grab_server (void); +void gdk_x11_ungrab_server (void); + /* returns TRUE if we support the given WM spec feature */ gboolean gdk_net_wm_supports (GdkAtom property);