Re: Fixing the flicker problem when toplevel windows pop up over a running screensaver


On 7/23/07, Ray Strode <halfline gmail com> wrote:
And, of course, I mixed two of Bryan's email addresses into one when
sending the mail, so it bounced...  Resending so he gets it.  It would
be better if replies went to this message instead of the first one.

On 7/23/07, Ray Strode <halfline gmail com> wrote:
> Hi guys,
> So while at GUADEC, Alex Larsson and Bryan Clark asked me about the
> feasibility of setting up GDM to autologin a user at boot up and then
> immediately lock the screen.
> The idea is that someone owns a laptop that only that person users,
> they go to boot it up in the morning and while its booting go to get
> coffee or something.  When they come back it would be neat if the
> session was already loaded and just needed to be unlocked.
> Anyway, I briefly looked into the idea and came up with one bit of
> unpleasantness.  As everything loads..the gnome-session splash screen,
> nautilus, the panel, etc, there is a lot of flicker as each window is
> raised and then the screensaver window is re-raised.
> There are two ways to fix this I think:
> 1) Use the composite overlay window
> 2) Use the MIT x screensaver extension
> Both provide an overlay window that is always on top.  Note, the first
> one won't work if the user is running a compositing manager because
> the compositing manager will already be using the window for it's own
> drawing.
> I don't remember all the problems with the screensaver extension that
> has prevented its use in gnome-screensaver before, but I kind of
> vaguely remember two issues:
> 1) No way to do fade in
> 2) No way to run different screensavers on different monitors
> I played around a bit during the last couple of days of GUADEC and
> wrote a lame little test app that comes up with solutions for those
> two problems.  You can get it with
> git clone git://
> It solves the first problem by making the screensaver window have a
> None background pixmap so that when the screensaver window gets mapped
> the contents that were on screen stay on screen.  It does mean you
> won't see windows update during the fade in, but that could be fixed
> if a compositing manager is running by giving the window an alpha
> value I think (although I didn't try yet).
> It solves the second problem by not actually using the screensaver
> window, but instead creating child windows on the screensaver window.
> Note, the test app isn't anything but an example program to show that
> those two problems are fixable.  The app doesn't do a real-time fade
> animation (it just paints progressively darker in a loop basically),
> it doesn't show anything interesting while active, etc.
> Jon, can you think of other problems that made the screensaver
> extension infeasible?  I sort of vaguely remember Keith saying the
> screensaver extension was supposed to break grabs, but that ended up
> being unimplemented.  Was there some impedance mismatch between its
> concept of idle and gnome-screensaver's concept of idle?

Cool.  Thanks for looking into this.  Yeah, my recollection is
basically the same as yours. Last year I put some notes here:

So, yeah, I think the remaining issues relate to the concept of idle.
And from what I heard in Ajax's talk at GUADEC there isn't agreement
among Xorg developers for what idle time in the server even means.
I'm pretty sceptical that they can solve the problem without
introducing policy.

Stepping back a bit...
I guess this autologin/lock model would work OK.  However, you'd
likely have some a11y issues.  I'm not sure we can really get the
screensaver working perfectly in that case.  It is likely much easier
to handle at the GDM greeter.

Looks like you have gotten the MIT screensaver pretty much working.
I'm attaching a patch for some minor bugs.  There still seems to be a
race creating a toplevel:
** (process:18654): DEBUG: opening display ':0.0'
** (test-screensaver-extension:18654): DEBUG: creating test
screensaver on screen 0
** (test-screensaver-extension:18654): DEBUG: registering test
screensaver on screen 0
** (test-screensaver-extension:18654): DEBUG: checking for screensaver extension
** (test-screensaver-extension:18654): DEBUG: notify event number is 67
** (test-screensaver-extension:18654): DEBUG: setting screensaver
background to be clear
** (test-screensaver-extension:18654): DEBUG: listening for screensaver events
** (test-screensaver-extension:18654): DEBUG: setting up head geometry
** (test-screensaver-extension:18654): DEBUG: monitor 0 has geometry
** (test-screensaver-extension:18654): DEBUG: head 0 has geometry 0x0+1920+1200
** (test-screensaver-extension:18654): DEBUG: simulating idle
** (test-screensaver-extension:18654): DEBUG: running event loop
** (test-screensaver-extension:18654): DEBUG: received screensaver event
** (test-screensaver-extension:18654): DEBUG: querying for updated
server screensaver state information
** (test-screensaver-extension:18654): DEBUG: updating internal state
from server screensaver state informati
** (test-screensaver-extension:18654): DEBUG: server says screensaver is active
** (test-screensaver-extension:18654): DEBUG: updating toplevel window
from server screensaver state informat

** ERROR **: could not set up screensaver toplevel for 0x63

diff --git a/Makefile b/Makefile
index b1925f7..30fa3bb 100644
--- a/Makefile
+++ b/Makefile
@@ -2,4 +2,4 @@ all: test-screensaver-extension
 test-screensaver-extension: test-screensaver-extension.c
-	gcc `pkg-config --cflags --libs gdk-x11-2.0 xscrnsaver` ${CFLAGS} $< -o $@
+	gcc -g `pkg-config --cflags --libs gdk-x11-2.0 xscrnsaver` ${CFLAGS} $< -o $@
diff --git a/test-screensaver-extension.c b/test-screensaver-extension.c
index 753514f..81129e9 100644
--- a/test-screensaver-extension.c
+++ b/test-screensaver-extension.c
@@ -123,7 +123,7 @@ test_screensaver_engine_new (GdkWindow    *toplevel_window,
     TestScreensaverEngine *engine;
-    engine = g_slice_new (TestScreensaverEngine);
+    engine = g_slice_new0 (TestScreensaverEngine);
     engine->window = create_engine_window (toplevel_window, area);
     engine->draw = test_screensaver_engine_do_draw;
@@ -135,7 +135,7 @@ void
 test_screensaver_engine_free (TestScreensaverEngine *engine)
     gdk_window_destroy (engine->window);
-    free (engine);
+    g_slice_free (TestScreensaverEngine, engine);
 TestScreensaverHead *
@@ -144,7 +144,7 @@ test_screensaver_head_new (int           monitor_number,
     TestScreensaverHead *head;
-    head = g_slice_new (TestScreensaverHead);
+    head = g_slice_new0 (TestScreensaverHead);
     head->number = monitor_number;
     head->area = *area;
     head->engine = NULL;
@@ -171,7 +171,7 @@ test_screensaver_new (GMainContext *context,
     root_window = gdk_screen_get_root_window (screen);
-    screensaver = g_slice_new (TestScreensaver);
+    screensaver = g_slice_new0 (TestScreensaver);
     screensaver->context = g_main_context_ref (context);
     screensaver->screen = screen;
     screensaver->drawable = GDK_DRAWABLE (root_window);
@@ -288,7 +288,7 @@ update_screensaver_toplevel_window_from_info (TestScreensaver  *screensaver,
             screensaver->toplevel_window = toplevel_window;
-            g_error ("could not set up screensaver toplevel ");
+          g_error ("could not set up screensaver toplevel for 0x%x", info->window);
         g_debug ("screensaver toplevel is already set up");

[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]