Ubuntu – How to move the lock window on the lock-screen


Is it possible to move the window where you input your password on the lock screen away from the center, e.g. at the lower edge?

Best Answer

For Unity/Gnome, the position is hard coded and requires patching the gnome-screensaver source and rebuilding it

I don’t expect this to be very difficult

Sorry, but it is, because it's hard-coded, at least for Unity and Gnome:

  • The lock dialog and lock screen are part of the gnome-screensaver package.
  • The position of the dialog is controlled via this bit of code at/around line 1212 in gnome-screensaver/src/gs-window-x11.c:

        window->priv->lock_box = gtk_alignment_new (0.5, 0.5, 0, 0);
  • The 0.5, 0.5 are the relative X- and Y-dimension center coordinates of the lock dialog (ranging from 0=left/top to 1=right/bottom).

  • Setting it to e.g. 0.1, 0.9 gives your desired bottom-left alignment. Of course, this requires recompiling from source :(
  • Result:

    enter image description here older widescreen screenshot

The patch

--- gnome-screensaver-3.4.1.orig/src/gs-window-x11.c    2012-06-04 18:14:11.000000000 -0700
+++ gnome-screensaver-3.4.1/src/gs-window-x11.c 2012-06-04 18:14:36.972433823 -0700
@@ -1209,7 +1209,7 @@
                     guint32   id)
         window->priv->lock_socket = gtk_socket_new ();
-        window->priv->lock_box = gtk_alignment_new (0.5, 0.5, 0, 0);
+        window->priv->lock_box = gtk_alignment_new (0.1, 0.9, 0, 0);
         gtk_widget_show (window->priv->lock_box);
         gtk_box_pack_start (GTK_BOX (window->priv->vbox), window->priv->lock_box, TRUE, TRUE, 0);

or see raw pastebin

  • Customize the 0.1, 0.9 to taste.

To build and install

sudo apt-get install build-essential dpkg-dev
sudo apt-get build-dep gnome-screensaver
mkdir gssrc && cd gssrc
apt-get source gnome-screensaver
wget -Olockbox-left.patch http://pastebin.com/raw.php?i=pqDYRrW1
patch -i lockbox-left.patch
cd gnome-screensaver-3.4.1
dpkg-source --commit
dpkg-buildpackage -us -uc
cd ..
sudo dpkg -i gnome-screensaver_3.4.1-0ubuntu1_{i386|amd64}.deb
cd ..
rm -rf gssrc
killall /usr/bin/gnome-screensaver

No logout or reboot needed. To uninstall, simply do an apt-get --reinstall install gnome-screensaver. You'll need to repeat the whole patch-build-install process whenever gnome-screensaver is updated, so hold it to make life easier and update when you're ready.

How did you figure this out? (by request)

No, I'm not one of the developers, but I have a decent knowledge of C/C++. Otherwise, it's all Google and heuristics. :)

  1. Google tells you there is no obvious way to answer this question.
  2. It also tells you the lock dialog is provided by gnome-screensaver
  3. Download source and examine. Hmm, gs-lock-plug.c sounds interesting:
    • create_page_one (GSLockPlug *plug)
      GtkWidget            *align;
      align = gtk_alignment_new (0.5, 0.5, 1, 1);
  4. That could be it! Look up gtk_alignment_new syntax, change to 0.1, 0.9 and rebuild. Doesn't work :(
  5. Notice debug-screensaver.sh in source folder, run it, and then lock and login. Output contains:
    • [find_window_at_pointer] gs-manager.c:668 (19:26:42):    Requesting unlock for screen 0
      [gs_window_request_unlock] gs-window-x11.c:1522 (19:26:42):  Requesting unlock
      [window_dialog_up_changed_cb] gs-manager.c:909 (19:26:42):   Handling window dialog up changed: up
      [handle_window_dialog_up] gs-manager.c:851 (19:26:42):   Handling dialog up
  6. Look at gs-manager.h, which includes:
    • gboolean gs_manager_request_unlock (GSManager *manager);
  7. Examine gs-manager.c:
    • gs_manager_request_unlock (GSManager *manager)
      GSWindow * window;
      /* Find the GSWindow that contains the pointer */
      window = find_window_at_pointer (manager);
      gs_window_request_unlock (window);
  8. gs_window_request_unlock isn't from gs-manager. grep -i -r -n gs_window_request . reveals:
    • ./gs-manager.c:1353:        gs_window_request_unlock (window);
      ./gs-window.h:92:void        gs_window_request_unlock     (GSWindow  *window);
      ./test-window.c:66:        gs_window_request_unlock (window);
      ./gs-window-x11.c:1518:gs_window_request_unlock (GSWindow *window)
  9. Heuristically jump to line 1518 in gs-window-x11.c; gs_window_request_unlock doesn't help directly but contains a number of window->priv mentions.
  10. Look at struct GSWindowPrivate near the beginning of gs-window-x11.c. It contains GtkWidget *lock_box and GtkWidget *lock_socket
  11. Search for occurrences of lock_box in file; third result is:
    • window->priv->lock_box = gtk_alignment_new (0.5, 0.5, 0, 0);
  12. Do a little mental victory dance, change, build, test, succeed, post answer, edit answer..and win bounty? :)