Bug 113310.
Sat Jul 10 00:37:45 2004 Soeren Sandmann <sandmann@daimi.au.dk> Bug 113310. * gdk/x11/gdkwindow-x11.c (_gdk_x11_window_tmp_{un|re}set_bg): New functions that can do a recursive unset/reset bg. * gdk/x11/gdkgeometry-x11.c: Remove gdk_window_tmp_{un|re}set_bg(). * gdk/x11/gdkwindow-x11.c (pre_unmap, post_unmap): New functions called before and after unmapping a window. They unset the background of all other windows to prevent flicker from the X server repainting the background. post_unmap() also invalidates the parent of the unmapped window to draw it without roundtrips. * gdk/x11/gdkwindow-x11.c (show_window_internal): Unset background of newly mapped windows and all desendants to prevent flicker.
This commit is contained in:
committed by
Søren Sandmann Pedersen
parent
b22258e6a6
commit
69ab514aef
@ -137,6 +137,7 @@
|
||||
#include "gdkinternals.h"
|
||||
#include "gdkscreen-x11.h"
|
||||
#include "gdkdisplay-x11.h"
|
||||
#include "gdkwindow-x11.h"
|
||||
|
||||
typedef struct _GdkWindowQueueItem GdkWindowQueueItem;
|
||||
typedef struct _GdkWindowParentPos GdkWindowParentPos;
|
||||
@ -183,8 +184,6 @@ static void gdk_window_postmove (GdkWindow *window,
|
||||
static void gdk_window_queue_translation (GdkWindow *window,
|
||||
gint dx,
|
||||
gint dy);
|
||||
static void gdk_window_tmp_unset_bg (GdkWindow *window);
|
||||
static void gdk_window_tmp_reset_bg (GdkWindow *window);
|
||||
static void gdk_window_clip_changed (GdkWindow *window,
|
||||
GdkRectangle *old_clip,
|
||||
GdkRectangle *new_clip);
|
||||
@ -324,7 +323,7 @@ gdk_window_guffaw_scroll (GdkWindow *window,
|
||||
parent_pos.x11_y += new_info.y;
|
||||
parent_pos.clip_rect = new_info.clip_rect;
|
||||
|
||||
gdk_window_tmp_unset_bg (window);
|
||||
_gdk_x11_window_tmp_unset_bg (window, FALSE);;
|
||||
|
||||
if (dx > 0 || dy > 0)
|
||||
gdk_window_queue_translation (window, MAX (dx, 0), MAX (dy, 0));
|
||||
@ -361,7 +360,7 @@ gdk_window_guffaw_scroll (GdkWindow *window,
|
||||
impl->position_info.width, impl->position_info.height);
|
||||
|
||||
if (impl->position_info.no_bg)
|
||||
gdk_window_tmp_reset_bg (window);
|
||||
_gdk_x11_window_tmp_reset_bg (window, FALSE);
|
||||
|
||||
impl->position_info = new_info;
|
||||
|
||||
@ -548,7 +547,7 @@ _gdk_window_move_resize_child (GdkWindow *window,
|
||||
new_info.x, new_info.y, new_info.width, new_info.height);
|
||||
|
||||
if (impl->position_info.no_bg)
|
||||
gdk_window_tmp_reset_bg (window);
|
||||
_gdk_x11_window_tmp_reset_bg (window, FALSE);
|
||||
|
||||
if (!impl->position_info.mapped && new_info.mapped && GDK_WINDOW_IS_MAPPED (obj))
|
||||
XMapWindow (GDK_WINDOW_XDISPLAY (window), GDK_WINDOW_XID (window));
|
||||
@ -594,7 +593,7 @@ _gdk_window_move_resize_child (GdkWindow *window,
|
||||
}
|
||||
|
||||
if (impl->position_info.no_bg)
|
||||
gdk_window_tmp_reset_bg (window);
|
||||
_gdk_x11_window_tmp_reset_bg (window, FALSE);
|
||||
|
||||
if (!impl->position_info.mapped && new_info.mapped && GDK_WINDOW_IS_MAPPED (obj))
|
||||
XMapWindow (GDK_WINDOW_XDISPLAY (window), GDK_WINDOW_XID (window));
|
||||
@ -854,7 +853,7 @@ gdk_window_postmove (GdkWindow *window,
|
||||
XMapWindow (GDK_DRAWABLE_XDISPLAY (window), GDK_DRAWABLE_XID (window));
|
||||
|
||||
if (impl->position_info.no_bg)
|
||||
gdk_window_tmp_reset_bg (window);
|
||||
_gdk_x11_window_tmp_reset_bg (window, FALSE);
|
||||
|
||||
impl->position_info = new_info;
|
||||
|
||||
@ -1063,56 +1062,6 @@ _gdk_window_process_expose (GdkWindow *window,
|
||||
gdk_region_destroy (clip_region);
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_window_tmp_unset_bg (GdkWindow *window)
|
||||
{
|
||||
GdkWindowImplX11 *impl;
|
||||
GdkWindowObject *obj;
|
||||
|
||||
obj = (GdkWindowObject *) window;
|
||||
impl = GDK_WINDOW_IMPL_X11 (obj->impl);
|
||||
|
||||
impl->position_info.no_bg = TRUE;
|
||||
|
||||
if (obj->bg_pixmap != GDK_NO_BG)
|
||||
XSetWindowBackgroundPixmap (GDK_DRAWABLE_XDISPLAY (window),
|
||||
GDK_DRAWABLE_XID (window), None);
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_window_tmp_reset_bg (GdkWindow *window)
|
||||
{
|
||||
GdkWindowImplX11 *impl;
|
||||
GdkWindowObject *obj;
|
||||
|
||||
obj = (GdkWindowObject *) window;
|
||||
impl = GDK_WINDOW_IMPL_X11 (obj->impl);
|
||||
|
||||
impl->position_info.no_bg = FALSE;
|
||||
|
||||
if (obj->bg_pixmap == GDK_NO_BG)
|
||||
return;
|
||||
|
||||
if (obj->bg_pixmap)
|
||||
{
|
||||
Pixmap xpixmap;
|
||||
|
||||
if (obj->bg_pixmap == GDK_PARENT_RELATIVE_BG)
|
||||
xpixmap = ParentRelative;
|
||||
else
|
||||
xpixmap = GDK_DRAWABLE_XID (obj->bg_pixmap);
|
||||
|
||||
XSetWindowBackgroundPixmap (GDK_DRAWABLE_XDISPLAY (window),
|
||||
GDK_DRAWABLE_XID (window), xpixmap);
|
||||
}
|
||||
else
|
||||
{
|
||||
XSetWindowBackground (GDK_DRAWABLE_XDISPLAY (window),
|
||||
GDK_DRAWABLE_XID (window),
|
||||
obj->bg_color.pixel);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_window_clip_changed (GdkWindow *window, GdkRectangle *old_clip, GdkRectangle *new_clip)
|
||||
{
|
||||
@ -1145,7 +1094,7 @@ gdk_window_clip_changed (GdkWindow *window, GdkRectangle *old_clip, GdkRectangle
|
||||
gdk_region_subtract (new_clip_region, old_clip_region);
|
||||
if (!gdk_region_empty (new_clip_region))
|
||||
{
|
||||
gdk_window_tmp_unset_bg (window);
|
||||
_gdk_x11_window_tmp_unset_bg (window, FALSE);;
|
||||
gdk_window_invalidate_region (window, new_clip_region, FALSE);
|
||||
}
|
||||
|
||||
|
||||
@ -217,6 +217,118 @@ gdk_window_impl_x11_finalize (GObject *object)
|
||||
G_OBJECT_CLASS (parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
static void
|
||||
tmp_unset_bg (GdkWindow *window)
|
||||
{
|
||||
GdkWindowImplX11 *impl;
|
||||
GdkWindowObject *obj;
|
||||
|
||||
obj = (GdkWindowObject *) window;
|
||||
impl = GDK_WINDOW_IMPL_X11 (obj->impl);
|
||||
|
||||
impl->position_info.no_bg = TRUE;
|
||||
|
||||
if (obj->bg_pixmap != GDK_NO_BG)
|
||||
XSetWindowBackgroundPixmap (GDK_DRAWABLE_XDISPLAY (window),
|
||||
GDK_DRAWABLE_XID (window), None);
|
||||
}
|
||||
|
||||
static void
|
||||
tmp_reset_bg (GdkWindow *window)
|
||||
{
|
||||
GdkWindowImplX11 *impl;
|
||||
GdkWindowObject *obj;
|
||||
|
||||
obj = (GdkWindowObject *) window;
|
||||
impl = GDK_WINDOW_IMPL_X11 (obj->impl);
|
||||
|
||||
impl->position_info.no_bg = FALSE;
|
||||
|
||||
if (obj->bg_pixmap == GDK_NO_BG)
|
||||
return;
|
||||
|
||||
if (obj->bg_pixmap)
|
||||
{
|
||||
Pixmap xpixmap;
|
||||
|
||||
if (obj->bg_pixmap == GDK_PARENT_RELATIVE_BG)
|
||||
xpixmap = ParentRelative;
|
||||
else
|
||||
xpixmap = GDK_DRAWABLE_XID (obj->bg_pixmap);
|
||||
|
||||
XSetWindowBackgroundPixmap (GDK_DRAWABLE_XDISPLAY (window),
|
||||
GDK_DRAWABLE_XID (window), xpixmap);
|
||||
}
|
||||
else
|
||||
{
|
||||
XSetWindowBackground (GDK_DRAWABLE_XDISPLAY (window),
|
||||
GDK_DRAWABLE_XID (window),
|
||||
obj->bg_color.pixel);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
_gdk_x11_window_tmp_unset_bg (GdkWindow *window,
|
||||
gboolean recurse)
|
||||
{
|
||||
GdkWindowObject *private;
|
||||
|
||||
g_return_if_fail (GDK_IS_WINDOW (window));
|
||||
|
||||
private = (GdkWindowObject *)window;
|
||||
|
||||
if (private->input_only || private->destroyed || !GDK_WINDOW_IS_MAPPED (window))
|
||||
return;
|
||||
|
||||
/* Don't unset the background of windows that don't select for expose
|
||||
* events. Such windows don't get drawn, so we need the X server
|
||||
* drawing them to prevent them from containing garbage
|
||||
*/
|
||||
if (private->window_type != GDK_WINDOW_ROOT &&
|
||||
private->window_type != GDK_WINDOW_FOREIGN &&
|
||||
(private->event_mask & GDK_EXPOSURE_MASK))
|
||||
{
|
||||
tmp_unset_bg (window);
|
||||
}
|
||||
|
||||
if (recurse)
|
||||
{
|
||||
GList *l;
|
||||
|
||||
for (l = private->children; l != NULL; l = l->next)
|
||||
_gdk_x11_window_tmp_unset_bg (l->data, TRUE);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
_gdk_x11_window_tmp_reset_bg (GdkWindow *window,
|
||||
gboolean recurse)
|
||||
{
|
||||
GdkWindowObject *private;
|
||||
|
||||
g_return_if_fail (GDK_IS_WINDOW (window));
|
||||
|
||||
private = (GdkWindowObject *)window;
|
||||
|
||||
if (private->input_only || private->destroyed || !GDK_WINDOW_IS_MAPPED (window))
|
||||
return;
|
||||
|
||||
if (private->window_type != GDK_WINDOW_ROOT &&
|
||||
private->window_type != GDK_WINDOW_FOREIGN &&
|
||||
(private->event_mask & GDK_EXPOSURE_MASK))
|
||||
{
|
||||
tmp_reset_bg (window);
|
||||
}
|
||||
|
||||
if (recurse)
|
||||
{
|
||||
GList *l;
|
||||
|
||||
for (l = private->children; l != NULL; l = l->next)
|
||||
_gdk_x11_window_tmp_reset_bg (l->data, TRUE);
|
||||
}
|
||||
}
|
||||
|
||||
static GdkColormap*
|
||||
gdk_window_impl_x11_get_colormap (GdkDrawable *drawable)
|
||||
{
|
||||
@ -987,6 +1099,14 @@ _gdk_windowing_window_destroy_foreign (GdkWindow *window)
|
||||
gdk_error_trap_pop ();
|
||||
}
|
||||
|
||||
static GdkWindow *
|
||||
get_root (GdkWindow *window)
|
||||
{
|
||||
GdkScreen *screen = gdk_drawable_get_screen (window);
|
||||
|
||||
return gdk_screen_get_root_window (screen);
|
||||
}
|
||||
|
||||
/* This function is called when the XWindow is really gone.
|
||||
*/
|
||||
void
|
||||
@ -1227,6 +1347,7 @@ show_window_internal (GdkWindow *window,
|
||||
impl->override_redirect) &&
|
||||
gdk_window_is_viewable (window))
|
||||
{
|
||||
_gdk_x11_window_tmp_reset_bg (window, TRUE);
|
||||
gdk_window_invalidate_rect (window, NULL, TRUE);
|
||||
}
|
||||
}
|
||||
@ -1277,6 +1398,55 @@ gdk_window_show (GdkWindow *window)
|
||||
show_window_internal (window, TRUE);
|
||||
}
|
||||
|
||||
static void
|
||||
pre_unmap (GdkWindow *window)
|
||||
{
|
||||
GdkWindow *start_window = NULL;
|
||||
GdkWindowObject *private = (GdkWindowObject *)window;
|
||||
|
||||
if (private->input_only)
|
||||
return;
|
||||
|
||||
if (private->window_type == GDK_WINDOW_CHILD)
|
||||
start_window = (GdkWindow *)private->parent;
|
||||
else if (private->window_type == GDK_WINDOW_TEMP)
|
||||
start_window = get_root (window);
|
||||
|
||||
if (start_window)
|
||||
_gdk_x11_window_tmp_unset_bg (start_window, TRUE);
|
||||
}
|
||||
|
||||
static void
|
||||
post_unmap (GdkWindow *window)
|
||||
{
|
||||
GdkWindow *start_window = NULL;
|
||||
GdkWindowObject *private = (GdkWindowObject *)window;
|
||||
|
||||
if (private->input_only)
|
||||
return;
|
||||
|
||||
if (private->window_type == GDK_WINDOW_CHILD)
|
||||
start_window = private->parent;
|
||||
else if (private->window_type == GDK_WINDOW_TEMP)
|
||||
start_window = get_root (window);
|
||||
|
||||
if (start_window)
|
||||
{
|
||||
_gdk_x11_window_tmp_reset_bg (start_window, TRUE);
|
||||
|
||||
if (private->window_type == GDK_WINDOW_CHILD && private->parent)
|
||||
{
|
||||
GdkRectangle invalid_rect;
|
||||
|
||||
gdk_window_get_position (window, &invalid_rect.x, &invalid_rect.y);
|
||||
gdk_drawable_get_size (GDK_DRAWABLE (window),
|
||||
&invalid_rect.width, &invalid_rect.height);
|
||||
gdk_window_invalidate_rect ((GdkWindow *)private->parent,
|
||||
&invalid_rect, TRUE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* gdk_window_hide:
|
||||
* @window: a #GdkWindow
|
||||
@ -1329,9 +1499,13 @@ gdk_window_hide (GdkWindow *window)
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1360,9 +1534,13 @@ gdk_window_withdraw (GdkWindow *window)
|
||||
GDK_WINDOW_STATE_WITHDRAWN);
|
||||
|
||||
g_assert (!GDK_WINDOW_IS_MAPPED (window));
|
||||
|
||||
pre_unmap (window);
|
||||
|
||||
XWithdrawWindow (GDK_WINDOW_XDISPLAY (window),
|
||||
GDK_WINDOW_XID (window), 0);
|
||||
|
||||
post_unmap (window);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -127,6 +127,11 @@ GType gdk_window_impl_x11_get_type (void);
|
||||
GdkToplevelX11 *_gdk_x11_window_get_toplevel (GdkWindow *window);
|
||||
void gdk_x11_window_set_user_time (GdkWindow *window,
|
||||
guint32 timestamp);
|
||||
void _gdk_x11_window_tmp_unset_bg (GdkWindow *window,
|
||||
gboolean recurse);
|
||||
void _gdk_x11_window_tmp_reset_bg (GdkWindow *window,
|
||||
gboolean recurse);
|
||||
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
|
||||
Reference in New Issue
Block a user