diff --git a/data/greeter-autostart/Makefile.am b/data/greeter-autostart/Makefile.am
index d12246b..f5dc7ee 100644
--- a/data/greeter-autostart/Makefile.am
+++ b/data/greeter-autostart/Makefile.am
@@ -19,6 +19,7 @@ desktop_in_files = 	\
 	gnome-power-manager.desktop.in		\
 	gnome-settings-daemon.desktop.in	\
 	gok.desktop.in				\
+	mousetweaks.desktop.in			\
 	metacity.desktop.in			\
 	orca-screen-reader.desktop.in		\
 	polkit-gnome-authentication-agent-1.desktop.in	\
diff --git a/data/greeter-autostart/mousetweaks.desktop.in b/data/greeter-autostart/mousetweaks.desktop.in
new file mode 100644
index 0000000..26e7e0e
--- /dev/null
+++ b/data/greeter-autostart/mousetweaks.desktop.in
@@ -0,0 +1,15 @@
+[Desktop Entry]
+_Name=Mousetweaks
+_Comment=Mouse accessibility enhancements
+TryExec=mousetweaks
+Exec=mousetweaks --enable-dwell --login -c -x 20 -y 20
+Icon=input-mouse
+Terminal=false
+Type=Application
+StartupNotify=false
+Categories=GNOME;GTK;Accessibility;
+AutostartCondition=GNOME /apps/gdm/simple-greeter/accessibility/dwell_click_enabled
+X-GNOME-Bugzilla-Bugzilla=GNOME
+X-GNOME-Bugzilla-Product=mousetweaks
+X-GNOME-Bugzilla-Component=general
+
diff --git a/gui/simple-greeter/Makefile.am b/gui/simple-greeter/Makefile.am
index 1fa87cf..90a74ea 100644
--- a/gui/simple-greeter/Makefile.am
+++ b/gui/simple-greeter/Makefile.am
@@ -101,6 +101,8 @@ test_greeter_panel_SOURCES = 	\
 	gdm-greeter-panel.c	\
 	gdm-clock-widget.h      \
 	gdm-clock-widget.c      \
+	gdm-dwell-button.h      \
+	gdm-dwell-button.c      \
 	gdm-option-widget.h     \
 	gdm-option-widget.c     \
 	gdm-recent-option-widget.h	\
@@ -291,6 +293,8 @@ gdm_simple_greeter_SOURCES =  		\
 	gdm-greeter-panel.c		\
 	gdm-clock-widget.h		\
 	gdm-clock-widget.c		\
+	gdm-dwell-button.h		\
+	gdm-dwell-button.c		\
 	gdm-option-widget.h		\
 	gdm-option-widget.c		\
 	gdm-recent-option-widget.h	\
diff --git a/gui/simple-greeter/gdm-dwell-button.c b/gui/simple-greeter/gdm-dwell-button.c
new file mode 100644
index 0000000..5806c96
--- /dev/null
+++ b/gui/simple-greeter/gdm-dwell-button.c
@@ -0,0 +1,269 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
+ *
+ * Copyright (C) 2009 Gerd Kohlberger <gerdko gmail com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ */
+
+#include <glib/gi18n.h>
+
+#include "gdm-dwell-button.h"
+#include "gdm-timer.h"
+
+#define DEFAULT_DURATION 1.50f
+#define DEFAULT_ICON_NAME "input-mouse"
+
+struct _GdmDwellButtonPrivate
+{
+        GdmTimer *timer;
+        gdouble   duration;
+        gdouble   progress;
+};
+
+enum {
+        PROP_0,
+        PROP_DURATION
+};
+
+static void _timer_tick (GdmTimer *timer, gdouble progress, gpointer data);
+static void _timer_stop (GdmTimer *timer, gpointer data);
+
+G_DEFINE_TYPE (GdmDwellButton, gdm_dwell_button, GTK_TYPE_TOGGLE_BUTTON)
+
+static void
+gdm_dwell_button_init (GdmDwellButton *button)
+{
+        GtkWidget *img;
+        AtkObject *acc;
+
+        button->priv = G_TYPE_INSTANCE_GET_PRIVATE (button,
+                                                    GDM_TYPE_DWELL_BUTTON,
+                                                    GdmDwellButtonPrivate);
+        button->priv->duration = DEFAULT_DURATION;
+        button->priv->timer = gdm_timer_new ();
+        g_signal_connect (button->priv->timer, "tick",
+                          G_CALLBACK (_timer_tick), button);
+        g_signal_connect (button->priv->timer, "stop",
+                          G_CALLBACK (_timer_stop), button);
+
+        img = gtk_image_new_from_icon_name (DEFAULT_ICON_NAME,
+                                            GTK_ICON_SIZE_BUTTON);
+        gtk_container_add (GTK_CONTAINER (button), img);
+        gtk_widget_show (img);
+
+        gtk_button_set_relief (GTK_BUTTON (button), GTK_RELIEF_NONE);
+        gtk_widget_set_tooltip_text (GTK_WIDGET (button),
+                                     _("Activate dwell clicks"));
+
+        acc = gtk_widget_get_accessible (GTK_WIDGET (button));
+        atk_object_set_name (acc, _("Dwell Button"));
+}
+
+static void
+gdm_dwell_button_dispose (GObject *object)
+{
+        GdmDwellButtonPrivate *priv = GDM_DWELL_BUTTON (object)->priv;
+
+        if (priv->timer)
+        {
+                g_object_unref (priv->timer);
+                priv->timer = NULL;
+        }
+        G_OBJECT_CLASS (gdm_dwell_button_parent_class)->dispose (object);
+}
+
+static void
+gdm_dwell_button_get_property (GObject    *object,
+                               guint       prop_id,
+                               GValue     *value,
+                               GParamSpec *pspec)
+{
+        GdmDwellButtonPrivate *priv = GDM_DWELL_BUTTON (object)->priv;
+
+        switch (prop_id) {
+        case PROP_DURATION:
+                g_value_set_double (value, priv->duration);
+                break;
+        default:
+                G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+                break;
+        }
+}
+
+static void
+gdm_dwell_button_set_property (GObject      *object,
+                               guint         prop_id,
+                               const GValue *value,
+                               GParamSpec   *pspec)
+{
+        GdmDwellButtonPrivate *priv = GDM_DWELL_BUTTON (object)->priv;
+
+        switch (prop_id) {
+        case PROP_DURATION:
+                priv->duration = g_value_get_double (value);
+                break;
+        default:
+                G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+                break;
+        }
+}
+
+static void
+gdm_dwell_button_paint_progress (GtkWidget *widget,
+                                 gdouble    progress)
+{
+        cairo_t *cr;
+        GdkColor bg_selected;
+        gdouble x, y, w, h;
+        gint fwidth, fpad;
+
+        gtk_widget_style_get (widget,
+                              "focus-line-width", &fwidth,
+                              "focus-padding", &fpad,
+                              NULL);
+        x = widget->allocation.x + fwidth + fpad;
+        y = widget->allocation.y + fwidth + fpad;
+        w = widget->allocation.width - (fwidth + fpad) * 2;
+        h = widget->allocation.height - (fwidth + fpad) * 2;
+        bg_selected = widget->style->bg[GTK_STATE_SELECTED];
+
+        cr = gdk_cairo_create (widget->window);
+        cairo_set_source_rgba (cr,
+                               bg_selected.red   / 65535.,
+                               bg_selected.green / 65535.,
+                               bg_selected.blue  / 65535.,
+                               0.50);
+        cairo_rectangle (cr, x, y, w, h * progress);
+        cairo_fill (cr);
+        cairo_destroy (cr);
+}
+
+static gboolean
+gdm_dwell_button_expose_event (GtkWidget      *widget,
+                               GdkEventExpose *event)
+{
+        GdmDwellButtonPrivate *priv = GDM_DWELL_BUTTON (widget)->priv;
+        gboolean ret;
+
+        ret = GTK_WIDGET_CLASS (gdm_dwell_button_parent_class)->expose_event (widget, event);
+        if (gdm_timer_is_started (priv->timer))
+        {
+                gdm_dwell_button_paint_progress (widget, priv->progress);
+        }
+        return ret;
+}
+
+static gboolean
+gdm_dwell_button_enter_notify_event (GtkWidget        *widget,
+                                     GdkEventCrossing *event)
+{
+        GdmDwellButtonPrivate *priv = GDM_DWELL_BUTTON (widget)->priv;
+
+        if (!gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (widget)) &&
+            !gdm_timer_is_started (priv->timer))
+        {
+                gdm_timer_start (priv->timer, priv->duration);
+        }
+        return GTK_WIDGET_CLASS (gdm_dwell_button_parent_class)->enter_notify_event (widget, event);
+}
+
+static gboolean
+gdm_dwell_button_leave_notify_event (GtkWidget        *widget,
+                                     GdkEventCrossing *event)
+{
+        GdmDwellButtonPrivate *priv = GDM_DWELL_BUTTON (widget)->priv;
+
+        if (gdm_timer_is_started (priv->timer))
+        {
+                gdm_timer_stop (priv->timer);
+        }
+        return GTK_WIDGET_CLASS (gdm_dwell_button_parent_class)->leave_notify_event (widget, event);
+}
+
+static void
+gdm_dwell_button_class_init (GdmDwellButtonClass *klass)
+{
+        GObjectClass *object_class;
+        GtkWidgetClass *widget_class;
+        GParamSpec *pspec;
+
+        object_class = G_OBJECT_CLASS (klass);
+        object_class->dispose = gdm_dwell_button_dispose;
+        object_class->get_property = gdm_dwell_button_get_property;
+        object_class->set_property = gdm_dwell_button_set_property;
+
+        widget_class = GTK_WIDGET_CLASS (klass);
+        widget_class->expose_event = gdm_dwell_button_expose_event;
+        widget_class->enter_notify_event = gdm_dwell_button_enter_notify_event;
+        widget_class->leave_notify_event = gdm_dwell_button_leave_notify_event;
+
+        pspec = g_param_spec_double ("duration",
+                                     _("Duration"),
+                                     _("Number of seconds until the button is activated"),
+                                     0.0, G_MAXDOUBLE, DEFAULT_DURATION,
+                                     G_PARAM_READWRITE);
+        g_object_class_install_property (object_class, PROP_DURATION, pspec);
+
+        g_type_class_add_private (klass, sizeof (GdmDwellButtonPrivate));
+}
+
+static void
+_timer_tick (GdmTimer *timer, gdouble progress, gpointer data)
+{
+        GdmDwellButton *button = data;
+
+        button->priv->progress = progress;
+        gtk_widget_queue_draw (GTK_WIDGET (button));
+}
+
+static void
+_timer_stop (GdmTimer *timer, gpointer data)
+{
+        GdmDwellButton *button = data;
+
+        if (button->priv->progress == 1.0)
+        {
+                gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button), TRUE);
+        }
+        button->priv->progress = 0.0;
+        gtk_widget_queue_draw (GTK_WIDGET (button));
+}
+
+GtkWidget *
+gdm_dwell_button_new (void)
+{
+        return g_object_new (GDM_TYPE_DWELL_BUTTON, NULL);
+}
+
+void
+gdm_dwell_button_set_duration (GdmDwellButton *button,
+                               gdouble         duration)
+{
+        g_return_if_fail (GDM_IS_DWELL_BUTTON (button));
+        g_return_if_fail (duration > 0.0);
+
+        button->priv->duration = duration;
+        g_object_notify (G_OBJECT (button), "duration");
+}
+
+gdouble
+gdm_dwell_button_get_duration (GdmDwellButton *button)
+{
+        g_return_val_if_fail (GDM_IS_DWELL_BUTTON (button), 0.0);
+
+        return button->priv->duration;
+}
+
diff --git a/gui/simple-greeter/gdm-dwell-button.h b/gui/simple-greeter/gdm-dwell-button.h
new file mode 100644
index 0000000..4f7eeb9
--- /dev/null
+++ b/gui/simple-greeter/gdm-dwell-button.h
@@ -0,0 +1,58 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
+ *
+ * Copyright (C) 2009 Gerd Kohlberger <gerdko gmail com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#ifndef __GDM_DWELL_BUTTON_H
+#define __GDM_DWELL_BUTTON_H
+
+#include <gtk/gtk.h>
+
+G_BEGIN_DECLS
+
+#define GDM_TYPE_DWELL_BUTTON         (gdm_dwell_button_get_type ())
+#define GDM_DWELL_BUTTON(o)           (G_TYPE_CHECK_INSTANCE_CAST ((o), GDM_TYPE_DWELL_BUTTON, GdmDwellButton))
+#define GDM_DWELL_BUTTON_CLASS(k)     (G_TYPE_CHECK_CLASS_CAST((k), GDM_TYPE_DWELL_BUTTON, GdmDwellButtonClass))
+#define GDM_IS_DWELL_BUTTON(o)        (G_TYPE_CHECK_INSTANCE_TYPE ((o), GDM_TYPE_DWELL_BUTTON))
+#define GDM_IS_DWELL_BUTTON_CLASS(k)  (G_TYPE_CHECK_CLASS_TYPE ((k), GDM_TYPE_DWELL_BUTTON))
+#define GDM_DWELL_BUTTON_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), GDM_TYPE_DWELL_BUTTON, GdmDwellButtonClass))
+
+typedef struct _GdmDwellButton GdmDwellButton;
+typedef struct _GdmDwellButtonClass GdmDwellButtonClass;
+typedef struct _GdmDwellButtonPrivate GdmDwellButtonPrivate;
+
+struct _GdmDwellButton
+{
+        GtkToggleButton        parent;
+        GdmDwellButtonPrivate *priv;
+};
+
+struct _GdmDwellButtonClass
+{
+        GtkToggleButtonClass parent;
+};
+
+GType          gdm_dwell_button_get_type       (void) G_GNUC_CONST;
+
+GtkWidget *    gdm_dwell_button_new            (void);
+void           gdm_dwell_button_set_duration   (GdmDwellButton *button,
+                                                gdouble         duration);
+gdouble        gdm_dwell_button_get_duration   (GdmDwellButton *button);
+
+G_END_DECLS
+
+#endif /* __GDM_DWELL_BUTTON_H */
diff --git a/gui/simple-greeter/gdm-greeter-panel.c b/gui/simple-greeter/gdm-greeter-panel.c
index caade7a..5aa30d3 100644
--- a/gui/simple-greeter/gdm-greeter-panel.c
+++ b/gui/simple-greeter/gdm-greeter-panel.c
@@ -53,6 +53,7 @@
 #include "gdm-session-option-widget.h"
 #include "gdm-timer.h"
 #include "gdm-profile.h"
+#include "gdm-dwell-button.h"
 
 #include "na-tray.h"
 
@@ -66,6 +67,8 @@
 
 #define KEY_DISABLE_RESTART_BUTTONS "/apps/gdm/simple-greeter/disable_restart_buttons"
 #define KEY_NOTIFICATION_AREA_PADDING "/apps/notification_area_applet/prefs/padding"
+#define KEY_DISABLE_DWELL_BUTTON "/apps/gdm/simple-greeter/disable_dwell_button"
+#define KEY_DWELL_CLICK_ENABLED "/apps/gdm/simple-greeter/accessibility/dwell_click_enabled"
 
 #define GDM_GREETER_PANEL_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), GDM_TYPE_GREETER_PANEL, GdmGreeterPanelPrivate))
 
@@ -83,6 +86,7 @@ struct GdmGreeterPanelPrivate
         GtkWidget              *language_option_widget;
         GtkWidget              *layout_option_widget;
         GtkWidget              *session_option_widget;
+        GtkWidget              *dwell_button;
 
         GdmTimer               *animation_timer;
         double                  progress;
@@ -831,6 +835,33 @@ on_shutdown_menu_deactivate (GdmGreeterPanel *panel)
                                       FALSE);
 }
 
+static gboolean
+get_disable_dwell_button (GdmGreeterPanel *panel)
+{
+        return gconf_client_get_bool (panel->priv->client,
+                                      KEY_DISABLE_DWELL_BUTTON,
+                                      NULL);
+}
+
+static gboolean
+get_dwell_click_enabled (GdmGreeterPanel *panel)
+{
+        return gconf_client_get_bool (panel->priv->client,
+                                      KEY_DWELL_CLICK_ENABLED,
+                                      NULL);
+}
+
+static void
+on_dwell_button_toggled (GdmGreeterPanel *panel)
+{
+        gboolean active;
+
+        active = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (panel->priv->dwell_button));
+        gconf_client_set_bool (panel->priv->client,
+                               KEY_DWELL_CLICK_ENABLED,
+                               active, NULL);
+}
+
 static void
 gdm_greeter_panel_init (GdmGreeterPanel *panel)
 {
@@ -975,6 +1006,18 @@ gdm_greeter_panel_init (GdmGreeterPanel *panel)
         gtk_widget_show (GTK_WIDGET (tray));
         gdm_greeter_panel_hide_user_options (panel);
 
+        if (!get_disable_dwell_button (panel)) {
+                panel->priv->dwell_button = gdm_dwell_button_new ();
+                gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (panel->priv->dwell_button),
+                                              get_dwell_click_enabled (panel));
+                g_signal_connect_swapped (panel->priv->dwell_button, "toggled",
+                                          G_CALLBACK (on_dwell_button_toggled), panel);
+                gtk_box_pack_end (GTK_BOX (panel->priv->hbox),
+                                  panel->priv->dwell_button,
+                                  FALSE, FALSE, 6);
+                gtk_widget_show (panel->priv->dwell_button);
+        }
+
         panel->priv->progress = 0.0;
         panel->priv->animation_timer = gdm_timer_new ();
         g_signal_connect_swapped (panel->priv->animation_timer,
diff --git a/gui/simple-greeter/gdm-simple-greeter.schemas.in b/gui/simple-greeter/gdm-simple-greeter.schemas.in
index b69335d..5c6e1ea 100644
--- a/gui/simple-greeter/gdm-simple-greeter.schemas.in
+++ b/gui/simple-greeter/gdm-simple-greeter.schemas.in
@@ -67,6 +67,17 @@
       </locale>
     </schema>
     <schema>
+      <key>/schemas/apps/gdm/simple-greeter/disable_dwell_button</key>
+      <applyto>/apps/gdm/simple-greeter/disable_dwell_button</applyto>
+      <owner>gdm-simple-greeter</owner>
+      <type>bool</type>
+      <default>FALSE</default>
+      <locale name="C">
+        <short>Disable showing the dwell button</short>
+        <long>Set to true to disable showing the dwell button in the login window.</long>
+      </locale>
+    </schema>
+    <schema>
       <key>/schemas/apps/gdm/simple-greeter/recent-languages</key>
       <applyto>/apps/gdm/simple-greeter/recent-languages</applyto>
       <owner>gdm-simple-greeter</owner>
@@ -136,6 +147,17 @@
         <long>Set to true to enable the screen magnifier.</long>
       </locale>
     </schema>
+    <schema>
+      <key>/schemas/apps/gdm/simple-greeter/accessibility/dwell_click_enabled</key>
+      <applyto>/apps/gdm/simple-greeter/accessibility/dwell_click_enabled</applyto>
+      <owner>gdm-simple-greeter</owner>
+      <type>bool</type>
+      <default>FALSE</default>
+      <locale name="C">
+        <short>Enable dwell click</short>
+        <long>Set to true to enable dwell click.</long>
+      </locale>
+    </schema>
 
     <schema>
       <key>/schemas/apps/gdm/simple-greeter/settings-manager-plugins/a11y-keyboard/active</key>
diff --git a/po/POTFILES.in b/po/POTFILES.in
index 60b2175..1d1ff48 100644
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -57,6 +57,7 @@ data/greeter-autostart/gnome-settings-daemon.desktop.in.in
 data/greeter-autostart/gnome-mag.desktop.in
 data/greeter-autostart/gok.desktop.in
 data/greeter-autostart/metacity.desktop.in
+data/greeter-autostart/mousetweaks.desktop.in
 data/greeter-autostart/orca-screen-reader.desktop.in
 data/greeter-autostart/polkit-gnome-authentication-agent-1.desktop.in.in
 gui/simple-chooser/gdm-host-chooser-dialog.c
@@ -64,6 +65,7 @@ gui/simple-chooser/gdm-host-chooser-widget.c
 gui/simple-greeter/gdm-cell-renderer-timer.c
 gui/simple-greeter/gdm-chooser-widget.c
 gui/simple-greeter/gdm-clock-widget.c
+gui/simple-greeter/gdm-dwell-button.c
 gui/simple-greeter/gdm-greeter-login-window.c
 gui/simple-greeter/gdm-greeter-login-window.c
 gui/simple-greeter/gdm-greeter-login-window.glade
