[gnome-flashback/gnome-3-36] screensaver: queue key events while unlock dialog is not ready
- From: Alberts Muktupāvels <muktupavels src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-flashback/gnome-3-36] screensaver: queue key events while unlock dialog is not ready
- Date: Thu, 23 Apr 2020 20:24:28 +0000 (UTC)
commit 7699da660b7fbe9ccc69b12ef0659e130c53df43
Author: Alberts Muktupāvels <alberts muktupavels gmail com>
Date: Thu Apr 23 20:28:09 2020 +0300
screensaver: queue key events while unlock dialog is not ready
Unlock dialog is created in idle after keyboard and/or mouse
activity and its visibility/readiness depends on PAM.
This means that first key event will never reach unlock dialog if
it was not already created/ready. If user is fast enough more key
events might not reach dialog.
Queue key events in this case and forward to password entry when
dialog becomes visible.
https://gitlab.gnome.org/GNOME/gnome-flashback/-/issues/49
gnome-flashback/libscreensaver/gf-unlock-dialog.c | 7 ++++
gnome-flashback/libscreensaver/gf-unlock-dialog.h | 3 ++
gnome-flashback/libscreensaver/gf-window.c | 46 +++++++++++++++++++++++
3 files changed, 56 insertions(+)
---
diff --git a/gnome-flashback/libscreensaver/gf-unlock-dialog.c
b/gnome-flashback/libscreensaver/gf-unlock-dialog.c
index 5e07bbd..c13380e 100644
--- a/gnome-flashback/libscreensaver/gf-unlock-dialog.c
+++ b/gnome-flashback/libscreensaver/gf-unlock-dialog.c
@@ -1049,3 +1049,10 @@ gf_unlock_dialog_set_user_switch_enabled (GfUnlockDialog *self,
update_user_switch_button (self);
}
+
+void
+gf_unlock_dialog_forward_key_event (GfUnlockDialog *self,
+ GdkEvent *event)
+{
+ gtk_widget_event (self->prompt_entry, event);
+}
diff --git a/gnome-flashback/libscreensaver/gf-unlock-dialog.h
b/gnome-flashback/libscreensaver/gf-unlock-dialog.h
index 2719c40..8a9afc8 100644
--- a/gnome-flashback/libscreensaver/gf-unlock-dialog.h
+++ b/gnome-flashback/libscreensaver/gf-unlock-dialog.h
@@ -43,6 +43,9 @@ void gf_unlock_dialog_set_input_sources (GfUnlockDialog *self,
void gf_unlock_dialog_set_user_switch_enabled (GfUnlockDialog *self,
gboolean user_switch_enabled);
+void gf_unlock_dialog_forward_key_event (GfUnlockDialog *self,
+ GdkEvent *event);
+
G_END_DECLS
#endif
diff --git a/gnome-flashback/libscreensaver/gf-window.c b/gnome-flashback/libscreensaver/gf-window.c
index cd5a5a5..3c3d832 100644
--- a/gnome-flashback/libscreensaver/gf-window.c
+++ b/gnome-flashback/libscreensaver/gf-window.c
@@ -26,6 +26,8 @@
#include "gf-panel.h"
#include "gf-unlock-dialog.h"
+#define MAX_QUEUED_EVENTS 16
+
struct _GfWindow
{
GtkWindow parent;
@@ -41,6 +43,8 @@ struct _GfWindow
GfInputSources *input_sources;
+ GList *key_events;
+
gboolean lock_enabled;
gboolean user_switch_enabled;
@@ -177,6 +181,21 @@ unlock_dialog_close_cb (GfUnlockDialog *dialog,
popdown_dialog (self);
}
+static void
+unlock_dialog_show_cb (GtkWidget *widget,
+ GfWindow *self)
+{
+ GList *l;
+
+ self->key_events = g_list_reverse (self->key_events);
+
+ for (l = self->key_events; l != NULL; l = l->next)
+ gf_unlock_dialog_forward_key_event (GF_UNLOCK_DIALOG (widget), l->data);
+
+ g_list_free_full (self->key_events, (GDestroyNotify) gdk_event_free);
+ self->key_events = NULL;
+}
+
static void
popup_dialog (GfWindow *self)
{
@@ -199,6 +218,9 @@ popup_dialog (GfWindow *self)
g_signal_connect (self->unlock_dialog, "close",
G_CALLBACK (unlock_dialog_close_cb), self);
+ g_signal_connect (self->unlock_dialog, "show",
+ G_CALLBACK (unlock_dialog_show_cb), self);
+
gtk_box_pack_start (GTK_BOX (self->vbox), self->unlock_dialog, TRUE, TRUE, 0);
}
@@ -285,6 +307,12 @@ gf_window_finalize (GObject *object)
g_clear_pointer (&self->surface, cairo_surface_destroy);
+ if (self->key_events != NULL)
+ {
+ g_list_free_full (self->key_events, (GDestroyNotify) gdk_event_free);
+ self->key_events = NULL;
+ }
+
if (self->emit_deactivated_idle_id != 0)
{
g_source_remove (self->emit_deactivated_idle_id);
@@ -392,6 +420,24 @@ gf_window_key_press_event (GtkWidget *widget,
return TRUE;
}
+ if (self->unlock_dialog == NULL ||
+ !gtk_widget_is_visible (self->unlock_dialog))
+ {
+ /* Only cache MAX_QUEUED_EVENTS key events. If there are any more
+ * than this then something is wrong.
+ *
+ * Don't queue keys that may cause focus navigation in the dialog.
+ */
+ if (g_list_length (self->key_events) < MAX_QUEUED_EVENTS &&
+ event->keyval != GDK_KEY_Tab &&
+ event->keyval != GDK_KEY_Up &&
+ event->keyval != GDK_KEY_Down)
+ {
+ self->key_events = g_list_prepend (self->key_events,
+ gdk_event_copy ((GdkEvent *) event));
+ }
+ }
+
return GTK_WIDGET_CLASS (gf_window_parent_class)->key_press_event (widget,
event);
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]