Merge lp://qastaging/~bratsche/xsplash/compositing-fixes into lp://qastaging/xsplash

Proposed by Cody Russell
Status: Merged
Approved by: Cody Russell
Approved revision: 54
Merged at revision: not available
Proposed branch: lp://qastaging/~bratsche/xsplash/compositing-fixes
Merge into: lp://qastaging/xsplash
Diff against target: None lines
To merge this branch: bzr merge lp://qastaging/~bratsche/xsplash/compositing-fixes
Reviewer Review Type Date Requested Status
David Barth (community) Approve
Review via email: mp+10667@code.qastaging.launchpad.net

This proposal supersedes a proposal from 2009-08-24.

Commit message

compositing improvements

To post a comment you must log in.
Revision history for this message
Cody Russell (bratsche) wrote : Posted in a previous version of this proposal

The previous flicker-free branch broke xsplash for non-composited environments. This branch fixes the problem.

We initialize the compositing overlay window as we did before, and we forcefully redirect the splash window to it until a real compositing manager starts. Once that happens we remove the window redirection and set our window to rgba and allow the compositing manager to take over the work.

Another improvement this branch introduces is that xsplash appears to the user much faster than it did before, in either compiz or metacity.

Revision history for this message
Mirco Müller (macslow) wrote : Posted in a previous version of this proposal

> The previous flicker-free branch broke xsplash for non-composited
> environments. This branch fixes the problem.
>
> We initialize the compositing overlay window as we did before, and we
> forcefully redirect the splash window to it until a real compositing manager
> starts. Once that happens we remove the window redirection and set our window
> to rgba and allow the compositing manager to take over the work.
>
> Another improvement this branch introduces is that xsplash appears to the user
> much faster than it did before, in either compiz or metacity.

Trying to run autogen.sh I get this error "shift: 370: can't shift that many". Any idea how to fix this or what's actually causing this?

review: Needs Information
Revision history for this message
Mirco Müller (macslow) wrote : Posted in a previous version of this proposal

> > The previous flicker-free branch broke xsplash for non-composited
> > environments. This branch fixes the problem.
> >
> > We initialize the compositing overlay window as we did before, and we
> > forcefully redirect the splash window to it until a real compositing manager
> > starts. Once that happens we remove the window redirection and set our
> window
> > to rgba and allow the compositing manager to take over the work.
> >
> > Another improvement this branch introduces is that xsplash appears to the
> user
> > much faster than it did before, in either compiz or metacity.
>
> Trying to run autogen.sh I get this error "shift: 370: can't shift that many".
> Any idea how to fix this or what's actually causing this?

Found it myself already. It seems to be a limitation of dash (linked to by /bin/sh). Changing the magic line in autogen.sh to read #!/bin/bash fixes the error. I wonder if you need to change that in ./autogen.sh or the sym-link in Karmic needs to be fixed.

review: Needs Information
Revision history for this message
Cody Russell (bratsche) wrote : Posted in a previous version of this proposal

> Found it myself already. It seems to be a limitation of dash (linked to by
> /bin/sh). Changing the magic line in autogen.sh to read #!/bin/bash fixes the
> error. I wonder if you need to change that in ./autogen.sh or the sym-link in
> Karmic needs to be fixed.

Thanks. I went ahead and committed that to master.

Revision history for this message
David Barth (dbarth) wrote : Posted in a previous version of this proposal

What happens if the compositing manager is slow to activate? or signals are received in a different order?

I guess you could detect that have_composite is false, then get a signal that composited-changed. But then if you get the realize signal, you may not pass the test checking if (have_xcomposite && ! is_composited). Similarly, if you get the composited-changed signal after the realize one, you may do the wrong redirection.

BTW, you may have compositing, but not an overlay if the server does not implement v0.3, as I read in the docs. So I think it would be safe to wrap calls to XComposite... with gdk_error_trap_push/pop to avoid unexpected application exits.

review: Needs Information
Revision history for this message
Cody Russell (bratsche) wrote : Posted in a previous version of this proposal

> What happens if the compositing manager is slow to activate? or signals are
> received in a different order?

If the CM starts slow, or doesn't start at all, then you won't get a fade.

> BTW, you may have compositing, but not an overlay if the server does not
> implement v0.3, as I read in the docs. So I think it would be safe to wrap
> calls to XComposite... with gdk_error_trap_push/pop to avoid unexpected
> application exits.

gdk_display_supports_composite() should tell us if this is not true, plus every X server we ship supports the necessary X11 extensions so this really shouldn't be a problem. But I'll add some error detection anyway.

54. By Cody Russell

gdk_flush()

Revision history for this message
David Barth (dbarth) wrote :

with the added gdk_flush to trap the error, i think the rest of the code is fine. Please land on trunk. Thanks

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'src/xsplash.c'
2--- src/xsplash.c 2009-08-20 20:23:09 +0000
3+++ src/xsplash.c 2009-08-25 15:45:19 +0000
4@@ -57,7 +57,8 @@
5 DBusGConnection *system_bus;
6 DBusGProxy *bus_proxy;
7
8- Window cow;
9+ GdkWindow *cow;
10+ GdkScreen *screen;
11
12 gboolean nautilus_done;
13 gboolean panel_done;
14@@ -79,6 +80,9 @@
15 static gchar *throbber_image = NULL;
16 static guint throbber_frames = 50;
17 static gboolean ping_pong = FALSE;
18+static gboolean have_xcomposite = FALSE;
19+static gboolean is_composited = FALSE;
20+static gboolean redirected = FALSE;
21
22 static GOptionEntry entries[] = {
23 { "gdm-session", 'g', 0, G_OPTION_ARG_NONE, &gdm_session, "Run in gdm session", NULL },
24@@ -169,11 +173,18 @@
25 {
26 XsplashServerPrivate *priv = XSPLASH_SERVER_GET_PRIVATE (object);
27
28- XCompositeReleaseOverlayWindow (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()),
29- GDK_DRAWABLE_XID (GDK_WINDOW_ROOT));
30-
31- g_object_unref (priv->throbber_pixbuf);
32- g_object_unref (priv->window);
33+ if (have_xcomposite && priv->cow)
34+ {
35+ XCompositeReleaseOverlayWindow (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()),
36+ GDK_DRAWABLE_XID (GDK_WINDOW_ROOT));
37+ g_object_unref (priv->cow);
38+ }
39+
40+ if (priv->throbber_pixbuf)
41+ g_object_unref (priv->throbber_pixbuf);
42+
43+ if (priv->window)
44+ g_object_unref (priv->window);
45 }
46
47 static void
48@@ -281,12 +292,35 @@
49 }
50
51 static void
52+composited_changed (GdkScreen *screen,
53+ gpointer data)
54+{
55+ XsplashServer *server = (XsplashServer *)data;
56+ XsplashServerPrivate *priv = XSPLASH_SERVER_GET_PRIVATE (server);
57+
58+ is_composited = gdk_screen_is_composited (screen);
59+
60+ if (GTK_WIDGET_REALIZED (priv->window))
61+ {
62+ if (is_composited)
63+ {
64+ if (redirected)
65+ {
66+ gdk_window_remove_redirection (priv->window->window);
67+ }
68+
69+ gtk_widget_set_colormap (priv->window,
70+ gdk_screen_get_rgba_colormap (priv->screen));
71+ }
72+ }
73+}
74+
75+static void
76 xsplash_server_init (XsplashServer *server)
77 {
78 XsplashServerPrivate *priv = XSPLASH_SERVER_GET_PRIVATE (server);
79 GdkPixbuf *pixbuf;
80 GdkPixbuf *logo;
81- GdkScreen *screen;
82 GtkWidget *image;
83 GtkWidget *fixed;
84
85@@ -294,19 +328,38 @@
86 priv->system_bus = NULL;
87 priv->bus_proxy = NULL;
88
89- priv->cow = XCompositeGetOverlayWindow (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()),
90- GDK_DRAWABLE_XID (gdk_get_default_root_window ()));
91+ if (gdk_display_supports_composite (gdk_display_get_default ()))
92+ {
93+ have_xcomposite = TRUE;
94+ }
95+
96+ if (have_xcomposite)
97+ {
98+ Window window;
99+
100+ gdk_error_trap_push ();
101+
102+ window = XCompositeGetOverlayWindow (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()),
103+ GDK_DRAWABLE_XID (gdk_get_default_root_window ()));
104+ priv->cow = gdk_window_foreign_new (window);
105+
106+ gdk_error_trap_pop ();
107+ }
108
109 priv->window = g_object_new (gtk_window_get_type (),
110 "name", "xsplash-window",
111 "type-hint", GDK_WINDOW_TYPE_HINT_DOCK,
112 NULL);
113+
114 //gtk_window_fullscreen (GTK_WINDOW (priv->window));
115 gtk_window_set_keep_above (GTK_WINDOW (priv->window), TRUE);
116 gtk_window_set_decorated (GTK_WINDOW (priv->window), FALSE);
117
118- gtk_widget_set_colormap (priv->window,
119- gdk_screen_get_rgba_colormap (gdk_screen_get_default ()));
120+ priv->screen = gtk_widget_get_screen (priv->window);
121+ g_signal_connect (G_OBJECT (priv->screen),
122+ "composited-changed",
123+ G_CALLBACK (composited_changed),
124+ server);
125
126 g_signal_connect (priv->window,
127 "realize",
128@@ -317,10 +370,8 @@
129 G_CALLBACK (key_press_event),
130 server);
131
132- screen = gtk_widget_get_screen (priv->window);
133-
134- pixbuf = get_pixbuf (gdk_screen_get_width (screen),
135- gdk_screen_get_height (screen));
136+ pixbuf = get_pixbuf (gdk_screen_get_width (priv->screen),
137+ gdk_screen_get_height (priv->screen));
138 logo = gdk_pixbuf_new_from_file (logo_image, NULL);
139
140 fixed = gtk_fixed_new ();
141@@ -336,20 +387,22 @@
142 if (throbber_image && throbber_frames)
143 {
144 priv->throbber_pixbuf = gdk_pixbuf_new_from_file (throbber_image, NULL);
145+
146 if (priv->throbber_pixbuf != NULL)
147- {
148- priv->throbber = gtk_image_new ();
149- gtk_widget_show (priv->throbber);
150+ {
151+ priv->throbber = gtk_image_new ();
152+ gtk_widget_show (priv->throbber);
153
154- gtk_fixed_put (GTK_FIXED (fixed), priv->throbber,
155- gdk_pixbuf_get_width (pixbuf) / 2 - gdk_pixbuf_get_width (priv->throbber_pixbuf) / 2,
156- gdk_pixbuf_get_height (pixbuf) / 3 + gdk_pixbuf_get_height (logo) + gdk_pixbuf_get_height (priv->throbber_pixbuf) / ((throbber_frames - 1) * 2));
157- start_throbber (server);
158- }
159+ gtk_fixed_put (GTK_FIXED (fixed), priv->throbber,
160+ gdk_pixbuf_get_width (pixbuf) / 2 - gdk_pixbuf_get_width (priv->throbber_pixbuf) / 2,
161+ gdk_pixbuf_get_height (pixbuf) / 3 + gdk_pixbuf_get_height (logo) + gdk_pixbuf_get_height (priv->throbber_pixbuf) / ((throbber_frames - 1) * 2));
162+ start_throbber (server);
163+ }
164 else
165- g_debug ("couldn't load throbber image from file (%s); "
166- "disabling throbber", throbber_image);
167-
168+ {
169+ g_debug ("couldn't load throbber image from file (%s); "
170+ "disabling throbber", throbber_image);
171+ }
172 }
173
174 gtk_container_add (GTK_CONTAINER (priv->window), fixed);
175@@ -422,6 +475,11 @@
176 if (!fading)
177 {
178 priv = XSPLASH_SERVER_GET_PRIVATE (server);
179+
180+ /* The throbber can draw incorrectly while we're fading out under
181+ * some conditions, so let's just hide it first. */
182+ gtk_widget_hide (priv->throbber);
183+
184 timeline = gty_timeline_new (800);
185 context = anim_context_new (server,
186 timeline,
187@@ -537,9 +595,16 @@
188 cursor);
189 gdk_cursor_unref (cursor);
190
191- XCompositeRedirectWindow (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()),
192- GDK_DRAWABLE_XID (priv->window->window),
193- CompositeRedirectAutomatic);
194+ if (have_xcomposite && !is_composited)
195+ {
196+ gdk_window_redirect_to_drawable (window->window,
197+ priv->cow,
198+ 0, 0,
199+ 0, 0,
200+ window->allocation.width,
201+ window->allocation.height);
202+ redirected = TRUE;
203+ }
204 }
205
206 gboolean

Subscribers

People subscribed via source and target branches