From f6e1b0ac172eeaea7ea4805bae4e2253f359d00a Mon Sep 17 00:00:00 2001 From: Alexander Larsson Date: Thu, 18 Dec 2008 11:30:10 +0100 Subject: [PATCH] Ensure that we're properly hiding impl window if one of its parent non-impl windows are hidden Also, add some debug printing code to list the GdkWindow tree --- gdk/gdkoffscreenwindow.c | 72 +-------------------- gdk/gdkwindow.c | 133 ++++++++++++++++++++++++++++++++++++++- gdk/gdkwindowimpl.h | 3 +- gdk/x11/gdkwindow-x11.c | 106 +++++++++++-------------------- 4 files changed, 170 insertions(+), 144 deletions(-) diff --git a/gdk/gdkoffscreenwindow.c b/gdk/gdkoffscreenwindow.c index 408a27dc57..703dcfa7ff 100644 --- a/gdk/gdkoffscreenwindow.c +++ b/gdk/gdkoffscreenwindow.c @@ -828,29 +828,10 @@ gdk_offscreen_window_move_resize (GdkWindow *window, } static void -gdk_offscreen_window_show (GdkWindow *window, gboolean raise) +gdk_offscreen_window_show (GdkWindow *window) { GdkWindowObject *private = (GdkWindowObject *)window; - GdkOffscreenWindow *offscreen; - if (GDK_WINDOW_IS_MAPPED (window)) - return; - - offscreen = GDK_OFFSCREEN_WINDOW (private->impl); - - private->state = 0; - - /* gdk_window_show already changed the stacking order if needed */ - - if (private->event_mask & GDK_STRUCTURE_MASK) - _gdk_make_event (GDK_WINDOW (private), GDK_MAP, NULL, FALSE); - - if (private->parent && private->parent->event_mask & GDK_SUBSTRUCTURE_MASK) - _gdk_make_event (GDK_WINDOW (private), GDK_MAP, NULL, FALSE); - - if (gdk_window_is_viewable (window)) - _gdk_syntesize_crossing_events_for_geometry_change (window); - gdk_window_clear_area_e (window, 0, 0, private->width, private->height); } @@ -868,9 +849,6 @@ gdk_offscreen_window_hide (GdkWindow *window) private = (GdkWindowObject*) window; offscreen = GDK_OFFSCREEN_WINDOW (private->impl); - if (!GDK_WINDOW_IS_MAPPED (private)) - return; - /* May need to break grabs on children */ display = gdk_drawable_get_display (window); @@ -888,16 +866,6 @@ gdk_offscreen_window_hide (GdkWindow *window) gdk_display_pointer_ungrab (display, GDK_CURRENT_TIME); } } - - if (private->event_mask & GDK_STRUCTURE_MASK) - _gdk_make_event (GDK_WINDOW (private), GDK_UNMAP, NULL, FALSE); - - if (private->parent && private->parent->event_mask & GDK_SUBSTRUCTURE_MASK) - _gdk_make_event (GDK_WINDOW (private), GDK_UNMAP, NULL, FALSE); - - private->state = GDK_WINDOW_STATE_WITHDRAWN; - - _gdk_syntesize_crossing_events_for_geometry_change (window); } static void @@ -917,44 +885,6 @@ gdk_offscreen_window_set_events (GdkWindow *window, { } -static GdkGC * -setup_backing_rect_gc (GdkWindow *window, int x_offset, int y_offset) -{ - GdkWindowObject *private = (GdkWindowObject *)window; - GdkGC *gc; - - if (private->bg_pixmap == GDK_PARENT_RELATIVE_BG && private->parent) - { - x_offset += private->x; - y_offset += private->y; - - return setup_backing_rect_gc (GDK_WINDOW (private->parent), x_offset, y_offset); - } - else if (private->bg_pixmap && - private->bg_pixmap != GDK_PARENT_RELATIVE_BG && - private->bg_pixmap != GDK_NO_BG) - { - guint gc_mask; - GdkGCValues gc_values; - - gc_values.fill = GDK_TILED; - gc_values.tile = private->bg_pixmap; - gc_values.ts_x_origin = -x_offset; - gc_values.ts_y_origin = -y_offset; - - gc_mask = GDK_GC_FILL | GDK_GC_TILE | GDK_GC_TS_X_ORIGIN | GDK_GC_TS_Y_ORIGIN; - - return gdk_gc_new_with_values (window, &gc_values, gc_mask); - } - else - { - gc = _gdk_drawable_get_scratch_gc (window, FALSE); - g_object_ref (gc); - gdk_gc_set_foreground (gc, &private->bg_color); - return gc; - } -} - static void gdk_offscreen_window_set_background (GdkWindow *window, const GdkColor *color) diff --git a/gdk/gdkwindow.c b/gdk/gdkwindow.c index 392a515162..695dfdebad 100644 --- a/gdk/gdkwindow.c +++ b/gdk/gdkwindow.c @@ -35,6 +35,8 @@ #include "gdkscreen.h" #include "gdkalias.h" +#undef DEBUG_WINDOW_PRINTING + #ifdef GDK_WINDOWING_X11 #include "x11/gdkx.h" /* For workaround */ #endif @@ -5126,6 +5128,23 @@ gdk_window_raise_internal (GdkWindow *window) } } +static void +show_all_visible_impls (GdkWindowObject *private) +{ + GdkWindowObject *child; + GList *l; + + for (l = private->children; l != NULL; l = l->next) + { + child = l->data; + if (GDK_WINDOW_IS_MAPPED (child)) + show_all_visible_impls (child); + } + + if (gdk_window_has_impl (private)) + GDK_WINDOW_IMPL_GET_IFACE (private->impl)->show ((GdkWindow *)private); +} + static void gdk_window_show_internal (GdkWindow *window, gboolean raise) { @@ -5144,10 +5163,21 @@ gdk_window_show_internal (GdkWindow *window, gboolean raise) { /* Keep children in (reverse) stacking order */ gdk_window_raise_internal (window); + + if (gdk_window_has_impl (private)) + GDK_WINDOW_IMPL_GET_IFACE (private->impl)->raise (window); } if (gdk_window_has_impl (private)) - GDK_WINDOW_IMPL_GET_IFACE (private->impl)->show (window, raise); + { + if (!GDK_WINDOW_IS_MAPPED (window)) + gdk_synthesize_window_state (window, + GDK_WINDOW_STATE_WITHDRAWN, + 0); + + if (gdk_window_is_viewable (window)) + show_all_visible_impls (private); + } else { if (GDK_WINDOW_IS_MAPPED (window)) @@ -5330,6 +5360,25 @@ gdk_window_show (GdkWindow *window) gdk_window_show_internal (window, TRUE); } +static void +hide_all_visible_impls (GdkWindowObject *private) +{ + GdkWindowObject *child; + GList *l; + + for (l = private->children; l != NULL; l = l->next) + { + child = l->data; + + if (GDK_WINDOW_IS_MAPPED (child)) + hide_all_visible_impls (child); + } + + if (gdk_window_has_impl (private)) + GDK_WINDOW_IMPL_GET_IFACE (private->impl)->hide ((GdkWindow *)private); +} + + /** * gdk_window_hide: * @window: a #GdkWindow @@ -5343,7 +5392,7 @@ void gdk_window_hide (GdkWindow *window) { GdkWindowObject *private; - gboolean was_mapped; + gboolean was_mapped, was_viewable; g_return_if_fail (GDK_IS_WINDOW (window)); @@ -5354,7 +5403,17 @@ gdk_window_hide (GdkWindow *window) was_mapped = GDK_WINDOW_IS_MAPPED (private); if (gdk_window_has_impl (private)) - GDK_WINDOW_IMPL_GET_IFACE (private->impl)->hide (window); + { + was_viewable = gdk_window_is_viewable (window); + + if (GDK_WINDOW_IS_MAPPED (window)) + gdk_synthesize_window_state (window, + 0, + GDK_WINDOW_STATE_WITHDRAWN); + + if (was_viewable) + hide_all_visible_impls (private); + } else if (was_mapped) { GdkDisplay *display; @@ -7751,6 +7810,64 @@ proxy_button_event (GdkEvent *source_event) return TRUE; /* Always unlink original, we want to obey the emulated event mask */ } +#ifdef DEBUG_WINDOW_PRINTING +static void +gdk_window_print (GdkWindowObject *window, + int indent) +{ + GdkRectangle r; + + g_print ("%*s%p: [%s] %d,%d %dx%d", indent, "", window, + window->user_data ? g_type_name_from_instance (window->user_data) : "no widget", + window->x, window->y, + window->width, window->height + ); + + if (gdk_window_has_impl (window)) + { + g_print (" impl(0x%lx)", gdk_x11_drawable_get_xid (GDK_DRAWABLE (window))); + } + + if (window->input_only) + g_print (" input-only"); + + if (!gdk_window_is_visible ((GdkWindow *)window)) + g_print (" hidden"); + + g_print (" abs[%d,%d]", + window->abs_x, window->abs_y); + + gdk_region_get_clipbox (window->clip_region, &r); + if (gdk_region_empty (window->clip_region)) + g_print (" clipbox[empty]"); + else + g_print (" clipbox[%d,%d %dx%d]", r.x, r.y, r.width, r.height); + + g_print ("\n"); +} + + +static void +gdk_window_print_tree (GdkWindow *window, + int indent, + gboolean include_input_only) +{ + GdkWindowObject *private; + GList *l; + + private = (GdkWindowObject *)window; + + if (private->input_only && !include_input_only) + return; + + gdk_window_print (private, indent); + + for (l = private->children; l != NULL; l = l->next) + gdk_window_print_tree (l->data, indent + 4, include_input_only); +} + +#endif /* DEBUG_WINDOW_PRINTING */ + void _gdk_windowing_got_event (GdkDisplay *display, GList *event_link, @@ -7767,6 +7884,16 @@ _gdk_windowing_got_event (GdkDisplay *display, event_private = GDK_WINDOW_OBJECT (event_window); +#ifdef DEBUG_WINDOW_PRINTING + if (event->type == GDK_KEY_PRESS && + (event->key.keyval == 0xa7 || + event->key.keyval == 0xbd)) + { + gdk_window_print_tree (event_window, 0, + event->key.keyval == 0xbd); + } +#endif + if (!(is_button_type (event->type) || is_motion_type (event->type))) return; diff --git a/gdk/gdkwindowimpl.h b/gdk/gdkwindowimpl.h index dacaf747a7..d6bd1bb32c 100644 --- a/gdk/gdkwindowimpl.h +++ b/gdk/gdkwindowimpl.h @@ -43,8 +43,7 @@ struct _GdkWindowImplIface { GTypeInterface g_iface; - void (* show) (GdkWindow *window, - gboolean raise); + void (* show) (GdkWindow *window); void (* hide) (GdkWindow *window); void (* withdraw) (GdkWindow *window); void (* raise) (GdkWindow *window); diff --git a/gdk/x11/gdkwindow-x11.c b/gdk/x11/gdkwindow-x11.c index f2641f7d1f..4f58d1320a 100644 --- a/gdk/x11/gdkwindow-x11.c +++ b/gdk/x11/gdkwindow-x11.c @@ -1278,63 +1278,45 @@ set_initial_hints (GdkWindow *window) } static void -gdk_window_x11_show (GdkWindow *window, - gboolean raise) +gdk_window_x11_show (GdkWindow *window) { - GdkWindowObject *private; + GdkWindowObject *private = (GdkWindowObject*) window; GdkDisplay *display; GdkDisplayX11 *display_x11; GdkToplevelX11 *toplevel; - - private = (GdkWindowObject*) window; - if (!private->destroyed) + GdkWindowImplX11 *impl = GDK_WINDOW_IMPL_X11 (private->impl); + Display *xdisplay = GDK_WINDOW_XDISPLAY (window); + Window xwindow = GDK_WINDOW_XID (window); + gboolean unset_bg; + + set_initial_hints (window); + + if (WINDOW_IS_TOPLEVEL (window)) { - GdkWindowImplX11 *impl = GDK_WINDOW_IMPL_X11 (private->impl); - Display *xdisplay = GDK_WINDOW_XDISPLAY (window); - Window xwindow = GDK_WINDOW_XID (window); - gboolean unset_bg; + display = gdk_drawable_get_display (window); + display_x11 = GDK_DISPLAY_X11 (display); + toplevel = _gdk_x11_window_get_toplevel (window); - if (raise) - XRaiseWindow (xdisplay, xwindow); - - if (!GDK_WINDOW_IS_MAPPED (window)) - { - set_initial_hints (window); - - gdk_synthesize_window_state (window, - GDK_WINDOW_STATE_WITHDRAWN, - 0); - } - - g_assert (GDK_WINDOW_IS_MAPPED (window)); - - if (WINDOW_IS_TOPLEVEL (window)) - { - display = gdk_drawable_get_display (window); - display_x11 = GDK_DISPLAY_X11 (display); - toplevel = _gdk_x11_window_get_toplevel (window); - - if (toplevel->user_time != 0 && + if (toplevel->user_time != 0 && display_x11->user_time != 0 && - XSERVER_TIME_IS_LATER (display_x11->user_time, toplevel->user_time)) - gdk_x11_window_set_user_time (window, display_x11->user_time); - } - - unset_bg = !private->input_only && - (private->window_type == GDK_WINDOW_CHILD || - impl->override_redirect) && - gdk_window_is_viewable (window); - - if (unset_bg) - _gdk_x11_window_tmp_unset_bg (window, TRUE); - - XMapWindow (xdisplay, xwindow); - - if (unset_bg) - { - _gdk_x11_window_tmp_reset_bg (window, TRUE); - gdk_window_invalidate_rect (window, NULL, TRUE); - } + XSERVER_TIME_IS_LATER (display_x11->user_time, toplevel->user_time)) + gdk_x11_window_set_user_time (window, display_x11->user_time); + } + + unset_bg = !private->input_only && + (private->window_type == GDK_WINDOW_CHILD || + impl->override_redirect) && + gdk_window_is_viewable (window); + + if (unset_bg) + _gdk_x11_window_tmp_unset_bg (window, TRUE); + + XMapWindow (xdisplay, xwindow); + + if (unset_bg) + { + _gdk_x11_window_tmp_reset_bg (window, TRUE); + gdk_window_invalidate_rect (window, NULL, TRUE); } } @@ -1416,24 +1398,12 @@ gdk_window_x11_hide (GdkWindow *window) break; } - if (!private->destroyed) - { - if (GDK_WINDOW_IS_MAPPED (window)) - gdk_synthesize_window_state (window, - 0, - GDK_WINDOW_STATE_WITHDRAWN); - - g_assert (!GDK_WINDOW_IS_MAPPED (window)); - - _gdk_window_clear_update_area (window); - - pre_unmap (window); - - XUnmapWindow (GDK_WINDOW_XDISPLAY (window), - GDK_WINDOW_XID (window)); - - post_unmap (window); - } + _gdk_window_clear_update_area (window); + + pre_unmap (window); + XUnmapWindow (GDK_WINDOW_XDISPLAY (window), + GDK_WINDOW_XID (window)); + post_unmap (window); } static void