Commit 445e90fa authored by Owen Taylor's avatar Owen Taylor Committed by Owen Taylor

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.
parent a859fa13
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
......
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
......
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
......
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
......
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
......
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
......
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
......
......@@ -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)
{
......
......@@ -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;
......
......@@ -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;
}
}
}
......
......@@ -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__ */
......@@ -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
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment