Detectable auto-repeat - make a repeating key generate

Sat Mar  3 16:26:33 2001  Owen Taylor  <otaylor@redhat.com>

	* gdk/x11/gdkmain-x11.c gdk/x11/gdkkeys-x11.c
	  gdk/x11/gdkevents-x11.c gdk/x11/gdkprivate-x11.c:

	Detectable auto-repeat - make a repeating key generate
	press/press/press/release instead of press/release pairs.

	If we have Xkb and XkbSetDectableAutoRepeat supports
	that, we do it that way. Otherwise, when we get
	a release event, we check ahead with XPending to see
	if the next key is a KeyPress with the same keycode
	and timestamp. (Not 100% reliable, but pretty close.)

Tue Feb 27 02:16:14 2001  Owen Taylor  <otaylor@redhat.com>

  	* gtk/gtkmain.c (gtk_propagate_event): Only do special
        special key-press grab handling for widgets within
        GtkWindows. Otherwise, fall through to normal case.

        This prevents key events being sent twice to GtkInvisible
        widgets, which can cause all sorts of mischief.
This commit is contained in:
Owen Taylor 2001-03-03 21:34:19 +00:00 committed by Owen Taylor
parent a859fa13af
commit 445e90fa82
12 changed files with 285 additions and 14 deletions

View File

@ -1,3 +1,32 @@
Sat Mar 3 16:26:33 2001 Owen Taylor <otaylor@redhat.com>
* gdk/x11/gdkmain-x11.c gdk/x11/gdkkeys-x11.c
gdk/x11/gdkevents-x11.c gdk/x11/gdkprivate-x11.c:
Detectable auto-repeat - make a repeating key generate
press/press/press/release instead of press/release pairs.
If we have Xkb and XkbSetDectableAutoRepeat supports
that, we do it that way. Otherwise, when we get
a release event, we check ahead with XPending to see
if the next key is a KeyPress with the same keycode
and timestamp. (Not 100% reliable, but pretty close.)
Tue Feb 27 02:16:14 2001 Owen Taylor <otaylor@redhat.com>
* gtk/gtkmain.c (gtk_propagate_event): Only do special
special key-press grab handling for widgets within
GtkWindows. Otherwise, fall through to normal case.
This prevents key events being sent twice to GtkInvisible
widgets, which can cause all sorts of mischief.
Fri Feb 2 13:20:12 2001 Owen Taylor <otaylor@redhat.com>
* gtk/gtkmain.c (gtk_propagate_event): When a grab
widget is in effect, give the grab widget a first
crack at KEY_PRESS/RELEASE events. (#424)
Sat Mar 3 15:39:49 2001 Owen Taylor <otaylor@redhat.com>
* gtk/gtkentry.c (gtk_entry_button_press): Add shift-clicking

View File

@ -1,3 +1,32 @@
Sat Mar 3 16:26:33 2001 Owen Taylor <otaylor@redhat.com>
* gdk/x11/gdkmain-x11.c gdk/x11/gdkkeys-x11.c
gdk/x11/gdkevents-x11.c gdk/x11/gdkprivate-x11.c:
Detectable auto-repeat - make a repeating key generate
press/press/press/release instead of press/release pairs.
If we have Xkb and XkbSetDectableAutoRepeat supports
that, we do it that way. Otherwise, when we get
a release event, we check ahead with XPending to see
if the next key is a KeyPress with the same keycode
and timestamp. (Not 100% reliable, but pretty close.)
Tue Feb 27 02:16:14 2001 Owen Taylor <otaylor@redhat.com>
* gtk/gtkmain.c (gtk_propagate_event): Only do special
special key-press grab handling for widgets within
GtkWindows. Otherwise, fall through to normal case.
This prevents key events being sent twice to GtkInvisible
widgets, which can cause all sorts of mischief.
Fri Feb 2 13:20:12 2001 Owen Taylor <otaylor@redhat.com>
* gtk/gtkmain.c (gtk_propagate_event): When a grab
widget is in effect, give the grab widget a first
crack at KEY_PRESS/RELEASE events. (#424)
Sat Mar 3 15:39:49 2001 Owen Taylor <otaylor@redhat.com>
* gtk/gtkentry.c (gtk_entry_button_press): Add shift-clicking

View File

@ -1,3 +1,32 @@
Sat Mar 3 16:26:33 2001 Owen Taylor <otaylor@redhat.com>
* gdk/x11/gdkmain-x11.c gdk/x11/gdkkeys-x11.c
gdk/x11/gdkevents-x11.c gdk/x11/gdkprivate-x11.c:
Detectable auto-repeat - make a repeating key generate
press/press/press/release instead of press/release pairs.
If we have Xkb and XkbSetDectableAutoRepeat supports
that, we do it that way. Otherwise, when we get
a release event, we check ahead with XPending to see
if the next key is a KeyPress with the same keycode
and timestamp. (Not 100% reliable, but pretty close.)
Tue Feb 27 02:16:14 2001 Owen Taylor <otaylor@redhat.com>
* gtk/gtkmain.c (gtk_propagate_event): Only do special
special key-press grab handling for widgets within
GtkWindows. Otherwise, fall through to normal case.
This prevents key events being sent twice to GtkInvisible
widgets, which can cause all sorts of mischief.
Fri Feb 2 13:20:12 2001 Owen Taylor <otaylor@redhat.com>
* gtk/gtkmain.c (gtk_propagate_event): When a grab
widget is in effect, give the grab widget a first
crack at KEY_PRESS/RELEASE events. (#424)
Sat Mar 3 15:39:49 2001 Owen Taylor <otaylor@redhat.com>
* gtk/gtkentry.c (gtk_entry_button_press): Add shift-clicking

View File

@ -1,3 +1,32 @@
Sat Mar 3 16:26:33 2001 Owen Taylor <otaylor@redhat.com>
* gdk/x11/gdkmain-x11.c gdk/x11/gdkkeys-x11.c
gdk/x11/gdkevents-x11.c gdk/x11/gdkprivate-x11.c:
Detectable auto-repeat - make a repeating key generate
press/press/press/release instead of press/release pairs.
If we have Xkb and XkbSetDectableAutoRepeat supports
that, we do it that way. Otherwise, when we get
a release event, we check ahead with XPending to see
if the next key is a KeyPress with the same keycode
and timestamp. (Not 100% reliable, but pretty close.)
Tue Feb 27 02:16:14 2001 Owen Taylor <otaylor@redhat.com>
* gtk/gtkmain.c (gtk_propagate_event): Only do special
special key-press grab handling for widgets within
GtkWindows. Otherwise, fall through to normal case.
This prevents key events being sent twice to GtkInvisible
widgets, which can cause all sorts of mischief.
Fri Feb 2 13:20:12 2001 Owen Taylor <otaylor@redhat.com>
* gtk/gtkmain.c (gtk_propagate_event): When a grab
widget is in effect, give the grab widget a first
crack at KEY_PRESS/RELEASE events. (#424)
Sat Mar 3 15:39:49 2001 Owen Taylor <otaylor@redhat.com>
* gtk/gtkentry.c (gtk_entry_button_press): Add shift-clicking

View File

@ -1,3 +1,32 @@
Sat Mar 3 16:26:33 2001 Owen Taylor <otaylor@redhat.com>
* gdk/x11/gdkmain-x11.c gdk/x11/gdkkeys-x11.c
gdk/x11/gdkevents-x11.c gdk/x11/gdkprivate-x11.c:
Detectable auto-repeat - make a repeating key generate
press/press/press/release instead of press/release pairs.
If we have Xkb and XkbSetDectableAutoRepeat supports
that, we do it that way. Otherwise, when we get
a release event, we check ahead with XPending to see
if the next key is a KeyPress with the same keycode
and timestamp. (Not 100% reliable, but pretty close.)
Tue Feb 27 02:16:14 2001 Owen Taylor <otaylor@redhat.com>
* gtk/gtkmain.c (gtk_propagate_event): Only do special
special key-press grab handling for widgets within
GtkWindows. Otherwise, fall through to normal case.
This prevents key events being sent twice to GtkInvisible
widgets, which can cause all sorts of mischief.
Fri Feb 2 13:20:12 2001 Owen Taylor <otaylor@redhat.com>
* gtk/gtkmain.c (gtk_propagate_event): When a grab
widget is in effect, give the grab widget a first
crack at KEY_PRESS/RELEASE events. (#424)
Sat Mar 3 15:39:49 2001 Owen Taylor <otaylor@redhat.com>
* gtk/gtkentry.c (gtk_entry_button_press): Add shift-clicking

View File

@ -1,3 +1,32 @@
Sat Mar 3 16:26:33 2001 Owen Taylor <otaylor@redhat.com>
* gdk/x11/gdkmain-x11.c gdk/x11/gdkkeys-x11.c
gdk/x11/gdkevents-x11.c gdk/x11/gdkprivate-x11.c:
Detectable auto-repeat - make a repeating key generate
press/press/press/release instead of press/release pairs.
If we have Xkb and XkbSetDectableAutoRepeat supports
that, we do it that way. Otherwise, when we get
a release event, we check ahead with XPending to see
if the next key is a KeyPress with the same keycode
and timestamp. (Not 100% reliable, but pretty close.)
Tue Feb 27 02:16:14 2001 Owen Taylor <otaylor@redhat.com>
* gtk/gtkmain.c (gtk_propagate_event): Only do special
special key-press grab handling for widgets within
GtkWindows. Otherwise, fall through to normal case.
This prevents key events being sent twice to GtkInvisible
widgets, which can cause all sorts of mischief.
Fri Feb 2 13:20:12 2001 Owen Taylor <otaylor@redhat.com>
* gtk/gtkmain.c (gtk_propagate_event): When a grab
widget is in effect, give the grab widget a first
crack at KEY_PRESS/RELEASE events. (#424)
Sat Mar 3 15:39:49 2001 Owen Taylor <otaylor@redhat.com>
* gtk/gtkentry.c (gtk_entry_button_press): Add shift-clicking

View File

@ -1,3 +1,32 @@
Sat Mar 3 16:26:33 2001 Owen Taylor <otaylor@redhat.com>
* gdk/x11/gdkmain-x11.c gdk/x11/gdkkeys-x11.c
gdk/x11/gdkevents-x11.c gdk/x11/gdkprivate-x11.c:
Detectable auto-repeat - make a repeating key generate
press/press/press/release instead of press/release pairs.
If we have Xkb and XkbSetDectableAutoRepeat supports
that, we do it that way. Otherwise, when we get
a release event, we check ahead with XPending to see
if the next key is a KeyPress with the same keycode
and timestamp. (Not 100% reliable, but pretty close.)
Tue Feb 27 02:16:14 2001 Owen Taylor <otaylor@redhat.com>
* gtk/gtkmain.c (gtk_propagate_event): Only do special
special key-press grab handling for widgets within
GtkWindows. Otherwise, fall through to normal case.
This prevents key events being sent twice to GtkInvisible
widgets, which can cause all sorts of mischief.
Fri Feb 2 13:20:12 2001 Owen Taylor <otaylor@redhat.com>
* gtk/gtkmain.c (gtk_propagate_event): When a grab
widget is in effect, give the grab widget a first
crack at KEY_PRESS/RELEASE events. (#424)
Sat Mar 3 15:39:49 2001 Owen Taylor <otaylor@redhat.com>
* gtk/gtkentry.c (gtk_entry_button_press): Add shift-clicking

View File

@ -530,7 +530,7 @@ gdk_event_translate (GdkEvent *event,
case KeyPress:
/* Lookup the string corresponding to the given keysym.
*/
#ifdef USE_XIM
if (buf_len == 0)
{
@ -613,6 +613,24 @@ gdk_event_translate (GdkEvent *event,
case KeyRelease:
/* Lookup the string corresponding to the given keysym.
*/
/* Emulate detectable auto-repeat by checking to see
* if the next event is a key press with the same
* keycode and timestamp, and if so, ignoring the event.
*/
if (!_gdk_have_xkb_autorepeat && XPending (gdk_display))
{
XEvent next_event;
XPeekEvent (gdk_display, &next_event);
if (next_event.type == KeyPress &&
next_event.xkey.keycode == xevent->xkey.keycode &&
next_event.xkey.time == xevent->xkey.time)
break;
}
#ifdef USE_XIM
if (buf_len == 0)
{

View File

@ -82,6 +82,12 @@ get_xkb (void)
}
#endif /* HAVE_XKB */
/* Whether we were able to turn on detectable-autorepeat using
* XkbSetDetectableAutorepeat. If FALSE, we'll fall back
* to checking the next event with XPending().
*/
gboolean _gdk_have_xkb_autorepeat = FALSE;
static KeySym* keymap = NULL;
static gint keysyms_per_keycode = 0;
static XModifierKeymap* mod_keymap = NULL;

View File

@ -214,12 +214,23 @@ _gdk_windowing_init_check (int argc, char **argv)
if (XkbQueryExtension (gdk_display, NULL, NULL, NULL,
&xkb_major, &xkb_minor))
{
Bool detectable_autorepeat_supported;
_gdk_use_xkb = TRUE;
XkbSelectEvents (gdk_display,
XkbUseCoreKbd,
XkbMapNotifyMask,
XkbMapNotifyMask);
XkbSetDetectableAutoRepeat (gdk_display,
True,
&detectable_autorepeat_supported);
GDK_NOTE (MISC, g_message ("Detectable autorepeat %s.",
detectable_autorepeat_supported ? "supported" : "not supported"));
_gdk_have_xkb_autorepeat = detectable_autorepeat_supported;
}
}
}

View File

@ -113,8 +113,15 @@ extern GdkWindow *gdk_xim_window; /* currently using Window */
/* Used to detect not-up-to-date keymap */
extern guint _gdk_keymap_serial;
#ifdef HAVE_XKB
extern gboolean _gdk_use_xkb;
#endif
/* Whether we were able to turn on detectable-autorepeat using
* XkbSetDetectableAutorepeat. If FALSE, we'll fall back
* to checking the next event with XPending().
*/
extern gboolean _gdk_have_xkb_autorepeat;
#endif /* __GDK_PRIVATE_X11_H__ */

View File

@ -1509,6 +1509,8 @@ gtk_propagate_event (GtkWidget *widget,
handled_event = FALSE;
gtk_widget_ref (widget);
if ((event->type == GDK_KEY_PRESS) ||
(event->type == GDK_KEY_RELEASE))
{
@ -1520,29 +1522,53 @@ gtk_propagate_event (GtkWidget *widget,
GtkWidget *window;
window = gtk_widget_get_ancestor (widget, GTK_TYPE_WINDOW);
if (window)
{
if (GTK_WIDGET_IS_SENSITIVE (window))
gtk_widget_event (window, event);
handled_event = TRUE; /* don't send to widget */
}
if (window)
{
/* If there is a grab within the window, give the grab widget
* a first crack at the key event
*/
if (widget != window && GTK_WIDGET_HAS_GRAB (widget))
handled_event = gtk_widget_event (widget, event);
if (!handled_event)
{
window = gtk_widget_get_ancestor (widget, GTK_TYPE_WINDOW);
if (window)
{
if (GTK_WIDGET_IS_SENSITIVE (window))
gtk_widget_event (window, event);
}
}
handled_event = TRUE; /* don't send to widget */
}
}
/* Other events get propagated up the widget tree
* so that parents can see the button and motion
* events of the children.
*/
while (!handled_event && widget)
if (!handled_event)
{
GtkWidget *tmp;
while (TRUE)
{
GtkWidget *tmp;
handled_event = !GTK_WIDGET_IS_SENSITIVE (widget) || gtk_widget_event (widget, event);
tmp = widget->parent;
gtk_widget_unref (widget);
gtk_widget_ref (widget);
handled_event = !GTK_WIDGET_IS_SENSITIVE (widget) || gtk_widget_event (widget, event);
tmp = widget->parent;
gtk_widget_unref (widget);
widget = tmp;
widget = tmp;
if (!handled_event && widget)
gtk_widget_ref (widget);
else
break;
}
}
else
gtk_widget_unref (widget);
}
#if 0