A patch has been merged upstream that adds an "Unlock" button. The button positioning is not yet finalised but it should at least be an improvement from the current dialog.
I have an early version of the change available that will patch against the current (4.24-5) version of XScreenSaver in Debian if you're interested. It is not the same as what went in upstream because of subsequent changes (and because upstream is now up to version 5.01). The patch and a screenshot are attached. -- tedp
(c) 2007, Quest Software, Inc. All rights reserved.
This file is part of XScreenSaver,
Copyright (c) 1993-2006 Jamie Zawinski <[EMAIL PROTECTED]>
Permission to use, copy, modify, distribute, and sell this software and its
documentation for any purpose is hereby granted without fee, provided that
the above copyright notice appear in all copies and that both that
copyright notice and this permission notice appear in supporting
documentation. No representations are made about the suitability of this
software for any purpose. It is provided "as is" without express or
implied warranty.
diff -ru xscreensaver-4.24/driver/lock.c xscreensaver-4.24-new/driver/lock.c
--- xscreensaver-4.24/driver/lock.c 2007-01-22 16:29:03.000000000 +1000
+++ xscreensaver-4.24-new/driver/lock.c 2007-01-30 15:22:16.000000000 +1000
@@ -108,6 +108,7 @@
char *date_label;
char *user_string;
char *passwd_string;
+ char *unlock_label;
char *login_label;
XFontStruct *heading_font;
@@ -137,6 +138,9 @@
Dimension passwd_field_x, passwd_field_y;
Dimension passwd_field_width, passwd_field_height;
+ Dimension unlock_button_x, unlock_button_y;
+ Dimension unlock_button_width, unlock_button_height;
+
Dimension login_button_x, login_button_y;
Dimension login_button_width, login_button_height;
@@ -149,6 +153,7 @@
unsigned long *logo_pixels;
Cursor passwd_cursor;
+ Bool unlock_button_down_p;
Bool login_button_down_p;
Bool login_button_p;
Bool login_button_enabled_p;
@@ -161,7 +166,7 @@
float ratio);
static void destroy_passwd_window (saver_info *si);
static void undo_vp_motion (saver_info *si);
-static void handle_passwd_button (saver_info *si, XEvent *event);
+static void finished_typing_passwd (saver_info *si, passwd_dialog_data *pw);
static void
@@ -206,6 +211,8 @@
"Dialog.Label.Label");
pw->passwd_label = get_string_resource ("passwd.passwd.label",
"Dialog.Label.Label");
+ pw->unlock_label = get_string_resource ("passwd.unlock.label",
+ "Dialog.Button.Label");
pw->login_label = get_string_resource ("passwd.login.label",
"Dialog.Button.Label");
@@ -218,6 +225,7 @@
if (!pw->user_label) pw->user_label = strdup("ERROR");
if (!pw->passwd_label) pw->passwd_label = strdup("ERROR");
if (!pw->date_label) pw->date_label = strdup("ERROR");
+ if (!pw->unlock_label) pw->unlock_label = strdup("ERROR (UNLOCK)");
if (!pw->login_label) pw->login_label = strdup ("ERROR (LOGIN)") ;
/* Put the version number in the label. */
@@ -378,6 +386,26 @@
w2 = w2 + w3 + (pw->shadow_width * 2);
h2 = MAX (h2, h3);
+ /* The "Unlock" button. */
+ XTextExtents (pw->label_font,
+ pw->unlock_label, strlen(pw->unlock_label),
+ &direction, &ascent, &descent, &overall);
+ button_w = overall.width;
+ button_h = ascent + descent;
+
+ /* Add some horizontal padding inside the button. */
+ button_w += ascent;
+
+ button_w += ((ascent + descent) / 2) + (pw->shadow_width * 2);
+ button_h += ((ascent + descent) / 2) + (pw->shadow_width * 2);
+
+ pw->unlock_button_width = button_w;
+ pw->unlock_button_height = button_h;
+
+ w2 = MAX (w2, button_w);
+ h2 += button_h * 1.5;
+
+ /* The "New Login" button */
pw->login_button_width = 0;
pw->login_button_height = 0;
@@ -554,10 +582,9 @@
(pw->shadow_width * 4)))) +
pw->date_font->ascent + pw->date_font->descent);
- if (pw->login_button_p)
- height += ((pw->button_font->ascent + pw->button_font->descent) * 2 +
- 2 * pw->shadow_width);
-
+ height += ((pw->button_font->ascent + pw->button_font->descent) * 2 +
+ 2 * pw->shadow_width) * (pw->login_button_p ? 2 : 1);
+
spacing = (((pw->height
- ((pw->login_button_p ? 4 : 2) * pw->shadow_width)
- pw->internal_border - height))
@@ -689,13 +716,37 @@
XDrawString (si->dpy, si->passwd_dialog, gc1, x2, y1, buf, strlen(buf));
}
+ /* Set up the GCs for the "New Login" and "Unlock" buttons.
+ */
+ XSetForeground(si->dpy, gc1, pw->button_foreground);
+ XSetForeground(si->dpy, gc2, pw->button_background);
+ XSetFont(si->dpy, gc1, pw->button_font->fid);
+
+ /* The "Unlock" button */
+ x2 = pw->width - pw->internal_border - (pw->shadow_width * 2);
+
+ /* centered button */
+ x1 = (pw->logo_width + pw->thermo_width + (pw->shadow_width * 3) +
+ pw->internal_border);
+ x1 = x1 + (x2 - x1 - pw->unlock_button_width) / 2;
+
+ y1 = (pw->height - pw->internal_border - pw->unlock_button_height -
+ pw->login_button_height - (2 *spacing));
+
+ y2 = (y1 +
+ ((pw->unlock_button_height -
+ (pw->button_font->ascent + pw->button_font->descent))
+ / 2) - pw->login_button_height / 2 +
+ pw->button_font->ascent);
+
+ pw->unlock_button_x = x1;
+ pw->unlock_button_y = y1;
+
/* The "New Login" button
*/
if (pw->login_button_p)
{
- XSetForeground (si->dpy, gc1, pw->button_foreground);
- XSetForeground (si->dpy, gc2, pw->button_background);
- XSetFont (si->dpy, gc1, pw->button_font->fid);
+ /* Using the same GC as for the Unlock button */
sw = string_width (pw->button_font, pw->login_label);
@@ -719,6 +770,29 @@
pw->login_button_x = x1;
pw->login_button_y = y1;
+
+ /* The button separator line.
+ * x1 is 1/8 the distance in from the left of the blank area.
+ * x2 is 7/8 the distance in from the left of the blank area.
+ * y1 is 1/2 the distance between y2 of the unlock button and
+ * y1 of the login button.
+ * y2 = y1.
+ */
+ /* The width of the gear on the left that we don't want to go near */
+ x3 = pw->logo_width + pw->thermo_width + (pw->shadow_width * 2) +
+ pw->internal_border;
+ /* 1/8 the width of the blank space */
+ x2 = (pw->width - x3 - pw->internal_border) / 8;
+ x1 = x3 + x2;
+ x2 = x2 * 7 + x3;
+
+ y1 = pw->login_button_y -
+ (pw->login_button_y -
+ (pw->unlock_button_y + pw->unlock_button_height))
+ / 2;
+ y2 = y1;
+
+ XDrawLine(si->dpy, si->passwd_dialog, gc1, x1, y1, x2, y2);
}
/* The logo
@@ -813,7 +887,7 @@
passwd_dialog_data *pw = si->pw_data;
XGCValues gcv;
GC gc1, gc2;
- int x, y;
+ int x, y, sw;
XRectangle rects[1];
pw->ratio = ratio;
@@ -885,17 +959,48 @@
MAX (0, pw->thermo_field_height - y - 2));
}
+ /* The "Unlock" button
+ */
+ XSetFont (si->dpy, gc1, pw->button_font->fid);
+ XSetForeground (si->dpy, gc1, pw->button_foreground);
+ XSetForeground (si->dpy, gc2, pw->button_background);
+
+ XFillRectangle (si->dpy, si->passwd_dialog, gc2,
+ pw->unlock_button_x, pw->unlock_button_y,
+ pw->unlock_button_width, pw->unlock_button_height);
+ sw = string_width (pw->button_font, pw->unlock_label);
+ x = pw->unlock_button_x + ((pw->unlock_button_width - sw) / 2);
+ y = (pw->unlock_button_y +
+ ((pw->unlock_button_height -
+ (pw->button_font->ascent + pw->button_font->descent))
+ / 2) +
+ pw->button_font->ascent);
+
+ XDrawString (si->dpy, si->passwd_dialog, gc1, x, y,
+ pw->unlock_label, strlen(pw->unlock_label));
+
+ draw_shaded_rectangle (si->dpy, si->passwd_dialog,
+ pw->unlock_button_x, pw->unlock_button_y,
+ pw->unlock_button_width, pw->unlock_button_height,
+ pw->shadow_width,
+ (pw->unlock_button_down_p
+ ? pw->shadow_bottom
+ : pw->shadow_top),
+ (pw->unlock_button_down_p
+ ? pw->shadow_top
+ : pw->shadow_bottom));
+
/* The "New Login" button
*/
if (pw->login_button_p)
{
- int x2, y2, sw;
- XSetFont (si->dpy, gc1, pw->button_font->fid);
+ int x2, y2;
+
+ /* (Font and gc2 (background) already set) */
XSetForeground (si->dpy, gc1,
(pw->login_button_enabled_p
? pw->passwd_foreground
: pw->shadow_bottom));
- XSetForeground (si->dpy, gc2, pw->button_background);
XFillRectangle (si->dpy, si->passwd_dialog, gc2,
pw->login_button_x, pw->login_button_y,
@@ -1378,11 +1483,52 @@
fork_and_exec (ssi, p->new_login_command);
}
+static void
+handle_unlock_button (saver_info *si, XEvent *event)
+{
+ Bool mouse_in_box = False;
+ passwd_dialog_data *pw = si->pw_data;
+
+ mouse_in_box =
+ (event->xbutton.x >= pw->unlock_button_x &&
+ event->xbutton.x <= pw->unlock_button_x + pw->unlock_button_width &&
+ event->xbutton.y >= pw->unlock_button_y &&
+ event->xbutton.y <= pw->unlock_button_y + pw->unlock_button_height);
+
+ if (ButtonRelease == event->xany.type &&
+ pw->unlock_button_down_p &&
+ mouse_in_box)
+ finished_typing_passwd (si, pw);
+
+ pw->unlock_button_down_p = (mouse_in_box &&
+ ButtonRelease != event->xany.type);
+}
+
+static void
+finished_typing_passwd (saver_info *si, passwd_dialog_data *pw)
+{
+ char *typed_passwd = pw->typed_passwd;
+ saver_preferences *p = &si->prefs;
+
+ if (pw->state != pw_read)
+ ; /* already done? */
+ else if (typed_passwd[0] == 0)
+ pw->state = pw_null;
+ else
+ {
+ update_passwd_window (si, "Checking...", pw->ratio);
+ XSync (si->dpy, False);
+ if (passwd_valid_p (typed_passwd, p->verbose_p))
+ pw->state = pw_ok;
+ else
+ pw->state = pw_fail;
+ update_passwd_window (si, "", pw->ratio);
+ }
+}
static void
handle_passwd_key (saver_info *si, XKeyEvent *event)
{
- saver_preferences *p = &si->prefs;
passwd_dialog_data *pw = si->pw_data;
int pw_size = sizeof (pw->typed_passwd) - 1;
char *typed_passwd = pw->typed_passwd;
@@ -1413,20 +1559,7 @@
break;
case '\012': case '\015': /* Enter */
- if (pw->state != pw_read)
- ; /* already done? */
- else if (typed_passwd[0] == 0)
- pw->state = pw_null;
- else
- {
- update_passwd_window (si, "Checking...", pw->ratio);
- XSync (si->dpy, False);
- if (passwd_valid_p (typed_passwd, p->verbose_p))
- pw->state = pw_ok;
- else
- pw->state = pw_fail;
- update_passwd_window (si, "", pw->ratio);
- }
+ finished_typing_passwd(si, pw);
break;
default:
@@ -1488,10 +1621,13 @@
handle_passwd_key (si, &event.xkey);
caps_p = (event.xkey.state & LockMask);
}
- else if ((event.xany.type == ButtonPress ||
- event.xany.type == ButtonRelease) &&
- si->pw_data->login_button_p)
- handle_passwd_button (si, &event);
+ else if (event.xany.type == ButtonPress ||
+ event.xany.type == ButtonRelease)
+ {
+ handle_unlock_button (si, &event);
+ if (si->pw_data->login_button_p)
+ handle_passwd_button (si, &event);
+ }
else
XtDispatchEvent (&event);
}
diff -ru xscreensaver-4.24/driver/XScreenSaver.ad.in xscreensaver-4.24-new/driver/XScreenSaver.ad.in
--- xscreensaver-4.24/driver/XScreenSaver.ad.in 2007-01-22 16:29:03.000000000 +1000
+++ xscreensaver-4.24-new/driver/XScreenSaver.ad.in 2007-01-25 12:03:09.000000000 +1000
@@ -480,6 +480,7 @@
*passwd.heading.label: XScreenSaver %s
*passwd.body.label: Please enter your password.
+*passwd.unlock.label: Unlock
*passwd.login.label: New Login
*passwd.user.label: Username:
*passwd.passwd.label: Password:
unlock.png
Description: PNG image

