diff options
author | Owen Taylor <otaylor@redhat.com> | 2001-06-08 16:07:00 +0000 |
---|---|---|
committer | Owen Taylor <otaylor@src.gnome.org> | 2001-06-08 16:07:00 +0000 |
commit | da562f4dc8db7722ffc89198d42eb9e2efbda62a (patch) | |
tree | 2b8c0442454fe272752ac51a961df4628298160b | |
parent | 11699349bb47a354bc602ad1bf0f57a0975c9b24 (diff) | |
download | gtk+-da562f4dc8db7722ffc89198d42eb9e2efbda62a.tar.gz |
Add a direction-changed signal, and gdk_keymap_get_current_direction().
Fri Jun 8 12:03:07 2001 Owen Taylor <otaylor@redhat.com>
* gdk/gdkkeys.[ch]: Add a direction-changed signal,
and gdk_keymap_get_current_direction().
* gdk/x11/gdkevents-x11.c gdk/x11/gdkkeys-x11.c
gdk/x11/gdkmain-x11.c gdk/x11/gdkprivate-x11.h: Track
the current locked group, use it to set the keymap
direction.
* gtk/gtksettings.c: Add a new gtk-split-cursor setting
to determine whether we draw a split cursor or use
a jumping cursor based on the current direction.
* gtk/gtkentry.c gtk/gtktextview.c gtk/gtktextlayout.[ch]:
Obey the split cursor setting.
Fri Jun 8 11:57:50 2001 Owen Taylor <otaylor@redhat.com>
* gtk/gtkimmulticontext.c (activate_cb): Only activate
when toggling on, not when toggling off... (#55906)
Wed Jun 6 10:37:07 2001 Owen Taylor <otaylor@redhat.com>
* gtk/gtkwidget.c (gtk_widget_set_double_buffered):
s/gdk_window_begin_paint/gdk_window_begin_paint_region/
in docs. (#55812, Vitaly Tishkov)
-rw-r--r-- | ChangeLog | 28 | ||||
-rw-r--r-- | ChangeLog.pre-2-0 | 28 | ||||
-rw-r--r-- | ChangeLog.pre-2-10 | 28 | ||||
-rw-r--r-- | ChangeLog.pre-2-2 | 28 | ||||
-rw-r--r-- | ChangeLog.pre-2-4 | 28 | ||||
-rw-r--r-- | ChangeLog.pre-2-6 | 28 | ||||
-rw-r--r-- | ChangeLog.pre-2-8 | 28 | ||||
-rw-r--r-- | docs/reference/gtk/tmpl/gtkrc.sgml | 1 | ||||
-rw-r--r-- | gdk/gdkkeys.c | 28 | ||||
-rw-r--r-- | gdk/gdkkeys.h | 41 | ||||
-rw-r--r-- | gdk/x11/gdkevents-x11.c | 46 | ||||
-rw-r--r-- | gdk/x11/gdkkeys-x11.c | 70 | ||||
-rw-r--r-- | gdk/x11/gdkmain-x11.c | 10 | ||||
-rw-r--r-- | gdk/x11/gdkprivate-x11.h | 3 | ||||
-rw-r--r-- | gtk/gtkentry.c | 90 | ||||
-rw-r--r-- | gtk/gtkimmulticontext.c | 13 | ||||
-rw-r--r-- | gtk/gtksettings.c | 9 | ||||
-rw-r--r-- | gtk/gtktextbtree.c | 4 | ||||
-rw-r--r-- | gtk/gtktextlayout.c | 148 | ||||
-rw-r--r-- | gtk/gtktextlayout.h | 7 | ||||
-rw-r--r-- | gtk/gtktextview.c | 70 | ||||
-rw-r--r-- | gtk/gtkwidget.c | 2 |
22 files changed, 607 insertions, 131 deletions
@@ -1,3 +1,31 @@ +Fri Jun 8 12:03:07 2001 Owen Taylor <otaylor@redhat.com> + + * gdk/gdkkeys.[ch]: Add a direction-changed signal, + and gdk_keymap_get_current_direction(). + + * gdk/x11/gdkevents-x11.c gdk/x11/gdkkeys-x11.c + gdk/x11/gdkmain-x11.c gdk/x11/gdkprivate-x11.h: Track + the current locked group, use it to set the keymap + direction. + + * gtk/gtksettings.c: Add a new gtk-split-cursor setting + to determine whether we draw a split cursor or use + a jumping cursor based on the current direction. + + * gtk/gtkentry.c gtk/gtktextview.c gtk/gtktextlayout.[ch]: + Obey the split cursor setting. + +Fri Jun 8 11:57:50 2001 Owen Taylor <otaylor@redhat.com> + + * gtk/gtkimmulticontext.c (activate_cb): Only activate + when toggling on, not when toggling off... (#55906) + +Wed Jun 6 10:37:07 2001 Owen Taylor <otaylor@redhat.com> + + * gtk/gtkwidget.c (gtk_widget_set_double_buffered): + s/gdk_window_begin_paint/gdk_window_begin_paint_region/ + in docs. (#55812, Vitaly Tishkov) + 2001-06-08 Anders Carlsson <andersca@codefactory.se> * demos/gtk-demo/main.c (create_tree): Changed signal name from diff --git a/ChangeLog.pre-2-0 b/ChangeLog.pre-2-0 index 4a9feeb65b..9a40e26083 100644 --- a/ChangeLog.pre-2-0 +++ b/ChangeLog.pre-2-0 @@ -1,3 +1,31 @@ +Fri Jun 8 12:03:07 2001 Owen Taylor <otaylor@redhat.com> + + * gdk/gdkkeys.[ch]: Add a direction-changed signal, + and gdk_keymap_get_current_direction(). + + * gdk/x11/gdkevents-x11.c gdk/x11/gdkkeys-x11.c + gdk/x11/gdkmain-x11.c gdk/x11/gdkprivate-x11.h: Track + the current locked group, use it to set the keymap + direction. + + * gtk/gtksettings.c: Add a new gtk-split-cursor setting + to determine whether we draw a split cursor or use + a jumping cursor based on the current direction. + + * gtk/gtkentry.c gtk/gtktextview.c gtk/gtktextlayout.[ch]: + Obey the split cursor setting. + +Fri Jun 8 11:57:50 2001 Owen Taylor <otaylor@redhat.com> + + * gtk/gtkimmulticontext.c (activate_cb): Only activate + when toggling on, not when toggling off... (#55906) + +Wed Jun 6 10:37:07 2001 Owen Taylor <otaylor@redhat.com> + + * gtk/gtkwidget.c (gtk_widget_set_double_buffered): + s/gdk_window_begin_paint/gdk_window_begin_paint_region/ + in docs. (#55812, Vitaly Tishkov) + 2001-06-08 Anders Carlsson <andersca@codefactory.se> * demos/gtk-demo/main.c (create_tree): Changed signal name from diff --git a/ChangeLog.pre-2-10 b/ChangeLog.pre-2-10 index 4a9feeb65b..9a40e26083 100644 --- a/ChangeLog.pre-2-10 +++ b/ChangeLog.pre-2-10 @@ -1,3 +1,31 @@ +Fri Jun 8 12:03:07 2001 Owen Taylor <otaylor@redhat.com> + + * gdk/gdkkeys.[ch]: Add a direction-changed signal, + and gdk_keymap_get_current_direction(). + + * gdk/x11/gdkevents-x11.c gdk/x11/gdkkeys-x11.c + gdk/x11/gdkmain-x11.c gdk/x11/gdkprivate-x11.h: Track + the current locked group, use it to set the keymap + direction. + + * gtk/gtksettings.c: Add a new gtk-split-cursor setting + to determine whether we draw a split cursor or use + a jumping cursor based on the current direction. + + * gtk/gtkentry.c gtk/gtktextview.c gtk/gtktextlayout.[ch]: + Obey the split cursor setting. + +Fri Jun 8 11:57:50 2001 Owen Taylor <otaylor@redhat.com> + + * gtk/gtkimmulticontext.c (activate_cb): Only activate + when toggling on, not when toggling off... (#55906) + +Wed Jun 6 10:37:07 2001 Owen Taylor <otaylor@redhat.com> + + * gtk/gtkwidget.c (gtk_widget_set_double_buffered): + s/gdk_window_begin_paint/gdk_window_begin_paint_region/ + in docs. (#55812, Vitaly Tishkov) + 2001-06-08 Anders Carlsson <andersca@codefactory.se> * demos/gtk-demo/main.c (create_tree): Changed signal name from diff --git a/ChangeLog.pre-2-2 b/ChangeLog.pre-2-2 index 4a9feeb65b..9a40e26083 100644 --- a/ChangeLog.pre-2-2 +++ b/ChangeLog.pre-2-2 @@ -1,3 +1,31 @@ +Fri Jun 8 12:03:07 2001 Owen Taylor <otaylor@redhat.com> + + * gdk/gdkkeys.[ch]: Add a direction-changed signal, + and gdk_keymap_get_current_direction(). + + * gdk/x11/gdkevents-x11.c gdk/x11/gdkkeys-x11.c + gdk/x11/gdkmain-x11.c gdk/x11/gdkprivate-x11.h: Track + the current locked group, use it to set the keymap + direction. + + * gtk/gtksettings.c: Add a new gtk-split-cursor setting + to determine whether we draw a split cursor or use + a jumping cursor based on the current direction. + + * gtk/gtkentry.c gtk/gtktextview.c gtk/gtktextlayout.[ch]: + Obey the split cursor setting. + +Fri Jun 8 11:57:50 2001 Owen Taylor <otaylor@redhat.com> + + * gtk/gtkimmulticontext.c (activate_cb): Only activate + when toggling on, not when toggling off... (#55906) + +Wed Jun 6 10:37:07 2001 Owen Taylor <otaylor@redhat.com> + + * gtk/gtkwidget.c (gtk_widget_set_double_buffered): + s/gdk_window_begin_paint/gdk_window_begin_paint_region/ + in docs. (#55812, Vitaly Tishkov) + 2001-06-08 Anders Carlsson <andersca@codefactory.se> * demos/gtk-demo/main.c (create_tree): Changed signal name from diff --git a/ChangeLog.pre-2-4 b/ChangeLog.pre-2-4 index 4a9feeb65b..9a40e26083 100644 --- a/ChangeLog.pre-2-4 +++ b/ChangeLog.pre-2-4 @@ -1,3 +1,31 @@ +Fri Jun 8 12:03:07 2001 Owen Taylor <otaylor@redhat.com> + + * gdk/gdkkeys.[ch]: Add a direction-changed signal, + and gdk_keymap_get_current_direction(). + + * gdk/x11/gdkevents-x11.c gdk/x11/gdkkeys-x11.c + gdk/x11/gdkmain-x11.c gdk/x11/gdkprivate-x11.h: Track + the current locked group, use it to set the keymap + direction. + + * gtk/gtksettings.c: Add a new gtk-split-cursor setting + to determine whether we draw a split cursor or use + a jumping cursor based on the current direction. + + * gtk/gtkentry.c gtk/gtktextview.c gtk/gtktextlayout.[ch]: + Obey the split cursor setting. + +Fri Jun 8 11:57:50 2001 Owen Taylor <otaylor@redhat.com> + + * gtk/gtkimmulticontext.c (activate_cb): Only activate + when toggling on, not when toggling off... (#55906) + +Wed Jun 6 10:37:07 2001 Owen Taylor <otaylor@redhat.com> + + * gtk/gtkwidget.c (gtk_widget_set_double_buffered): + s/gdk_window_begin_paint/gdk_window_begin_paint_region/ + in docs. (#55812, Vitaly Tishkov) + 2001-06-08 Anders Carlsson <andersca@codefactory.se> * demos/gtk-demo/main.c (create_tree): Changed signal name from diff --git a/ChangeLog.pre-2-6 b/ChangeLog.pre-2-6 index 4a9feeb65b..9a40e26083 100644 --- a/ChangeLog.pre-2-6 +++ b/ChangeLog.pre-2-6 @@ -1,3 +1,31 @@ +Fri Jun 8 12:03:07 2001 Owen Taylor <otaylor@redhat.com> + + * gdk/gdkkeys.[ch]: Add a direction-changed signal, + and gdk_keymap_get_current_direction(). + + * gdk/x11/gdkevents-x11.c gdk/x11/gdkkeys-x11.c + gdk/x11/gdkmain-x11.c gdk/x11/gdkprivate-x11.h: Track + the current locked group, use it to set the keymap + direction. + + * gtk/gtksettings.c: Add a new gtk-split-cursor setting + to determine whether we draw a split cursor or use + a jumping cursor based on the current direction. + + * gtk/gtkentry.c gtk/gtktextview.c gtk/gtktextlayout.[ch]: + Obey the split cursor setting. + +Fri Jun 8 11:57:50 2001 Owen Taylor <otaylor@redhat.com> + + * gtk/gtkimmulticontext.c (activate_cb): Only activate + when toggling on, not when toggling off... (#55906) + +Wed Jun 6 10:37:07 2001 Owen Taylor <otaylor@redhat.com> + + * gtk/gtkwidget.c (gtk_widget_set_double_buffered): + s/gdk_window_begin_paint/gdk_window_begin_paint_region/ + in docs. (#55812, Vitaly Tishkov) + 2001-06-08 Anders Carlsson <andersca@codefactory.se> * demos/gtk-demo/main.c (create_tree): Changed signal name from diff --git a/ChangeLog.pre-2-8 b/ChangeLog.pre-2-8 index 4a9feeb65b..9a40e26083 100644 --- a/ChangeLog.pre-2-8 +++ b/ChangeLog.pre-2-8 @@ -1,3 +1,31 @@ +Fri Jun 8 12:03:07 2001 Owen Taylor <otaylor@redhat.com> + + * gdk/gdkkeys.[ch]: Add a direction-changed signal, + and gdk_keymap_get_current_direction(). + + * gdk/x11/gdkevents-x11.c gdk/x11/gdkkeys-x11.c + gdk/x11/gdkmain-x11.c gdk/x11/gdkprivate-x11.h: Track + the current locked group, use it to set the keymap + direction. + + * gtk/gtksettings.c: Add a new gtk-split-cursor setting + to determine whether we draw a split cursor or use + a jumping cursor based on the current direction. + + * gtk/gtkentry.c gtk/gtktextview.c gtk/gtktextlayout.[ch]: + Obey the split cursor setting. + +Fri Jun 8 11:57:50 2001 Owen Taylor <otaylor@redhat.com> + + * gtk/gtkimmulticontext.c (activate_cb): Only activate + when toggling on, not when toggling off... (#55906) + +Wed Jun 6 10:37:07 2001 Owen Taylor <otaylor@redhat.com> + + * gtk/gtkwidget.c (gtk_widget_set_double_buffered): + s/gdk_window_begin_paint/gdk_window_begin_paint_region/ + in docs. (#55812, Vitaly Tishkov) + 2001-06-08 Anders Carlsson <andersca@codefactory.se> * demos/gtk-demo/main.c (create_tree): Changed signal name from diff --git a/docs/reference/gtk/tmpl/gtkrc.sgml b/docs/reference/gtk/tmpl/gtkrc.sgml index 244dd09a1b..e6727ce356 100644 --- a/docs/reference/gtk/tmpl/gtkrc.sgml +++ b/docs/reference/gtk/tmpl/gtkrc.sgml @@ -495,7 +495,6 @@ This can later be composited together with other #GtkRcStyle structures to form a #GtkStyle. </para> -@parent_instance: @name: @bg_pixmap_name: @font_desc: diff --git a/gdk/gdkkeys.c b/gdk/gdkkeys.c index 9b5911fd30..a47d8a9a59 100644 --- a/gdk/gdkkeys.c +++ b/gdk/gdkkeys.c @@ -27,12 +27,19 @@ #include "gdkkeys.h" #include <config.h> +enum { + DIRECTION_CHANGED, + LAST_SIGNAL +}; + static void gdk_keymap_init (GdkKeymap *keymap); static void gdk_keymap_class_init (GdkKeymapClass *klass); static void gdk_keymap_finalize (GObject *object); static gpointer parent_class = NULL; +static guint signals[LAST_SIGNAL] = { 0 }; + GType gdk_keymap_get_type (void) { @@ -75,6 +82,16 @@ gdk_keymap_class_init (GdkKeymapClass *klass) parent_class = g_type_class_peek_parent (klass); object_class->finalize = gdk_keymap_finalize; + + signals[DIRECTION_CHANGED] = + g_signal_newc ("direction_changed", + G_OBJECT_CLASS_TYPE (object_class), + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (GdkKeymapClass, direction_changed), + NULL, NULL, + g_cclosure_marshal_VOID__VOID, + G_TYPE_NONE, + 0); } static void @@ -85,17 +102,6 @@ gdk_keymap_finalize (GObject *object) G_OBJECT_CLASS (parent_class)->finalize (object); } -GdkKeymap* -gdk_keymap_get_default (void) -{ - static GdkKeymap *keymap = NULL; - - if (keymap == NULL) - keymap = g_object_new (gdk_keymap_get_type (), NULL); - - return keymap; -} - /* Other key-handling stuff diff --git a/gdk/gdkkeys.h b/gdk/gdkkeys.h index 20d50348cd..d5877c791c 100644 --- a/gdk/gdkkeys.h +++ b/gdk/gdkkeys.h @@ -70,6 +70,8 @@ struct _GdkKeymap struct _GdkKeymapClass { GObjectClass parent_class; + + void (*direction_changed) (void); }; GType gdk_keymap_get_type (void) G_GNUC_CONST; @@ -77,25 +79,26 @@ GType gdk_keymap_get_type (void) G_GNUC_CONST; GdkKeymap* gdk_keymap_get_default (void); -guint gdk_keymap_lookup_key (GdkKeymap *keymap, - const GdkKeymapKey *key); -gboolean gdk_keymap_translate_keyboard_state (GdkKeymap *keymap, - guint hardware_keycode, - GdkModifierType state, - gint group, - guint *keyval, - gint *effective_group, - gint *level, - GdkModifierType *unused_modifiers); -gboolean gdk_keymap_get_entries_for_keyval (GdkKeymap *keymap, - guint keyval, - GdkKeymapKey **keys, - gint *n_keys); -gboolean gdk_keymap_get_entries_for_keycode (GdkKeymap *keymap, - guint hardware_keycode, - GdkKeymapKey **keys, - guint **keyvals, - gint *n_entries); +guint gdk_keymap_lookup_key (GdkKeymap *keymap, + const GdkKeymapKey *key); +gboolean gdk_keymap_translate_keyboard_state (GdkKeymap *keymap, + guint hardware_keycode, + GdkModifierType state, + gint group, + guint *keyval, + gint *effective_group, + gint *level, + GdkModifierType *unused_modifiers); +gboolean gdk_keymap_get_entries_for_keyval (GdkKeymap *keymap, + guint keyval, + GdkKeymapKey **keys, + gint *n_keys); +gboolean gdk_keymap_get_entries_for_keycode (GdkKeymap *keymap, + guint hardware_keycode, + GdkKeymapKey **keys, + guint **keyvals, + gint *n_entries); +PangoDirection gdk_keymap_get_direction (GdkKeymap *keymap); /* Key values */ diff --git a/gdk/x11/gdkevents-x11.c b/gdk/x11/gdkevents-x11.c index a102e2b827..a0302943aa 100644 --- a/gdk/x11/gdkevents-x11.c +++ b/gdk/x11/gdkevents-x11.c @@ -1428,24 +1428,38 @@ gdk_event_translate (GdkEvent *event, return_val = FALSE; break; -#ifdef HAVE_XKB - case XkbMapNotify: - ++_gdk_keymap_serial; - return_val = FALSE; - break; -#endif - default: - /* something else - (e.g., a Xinput event) */ - - if (window_private && - !GDK_WINDOW_DESTROYED (window_private) && - (window_private->extension_events != 0)) - return_val = _gdk_input_other_event(event, xevent, window); +#ifdef HAVE_XKB + if (xevent->type == _gdk_xkb_event_type) + { + XkbEvent *xkb_event = (XkbEvent *)xevent; + + switch (xkb_event->any.xkb_type) + { + case XkbMapNotify: + ++_gdk_keymap_serial; + return_val = FALSE; + break; + + case XkbStateNotify: + _gdk_keymap_state_changed (); + break; + } + } else - return_val = FALSE; - - break; +#endif + { + /* something else - (e.g., a Xinput event) */ + + if (window_private && + !GDK_WINDOW_DESTROYED (window_private) && + (window_private->extension_events != 0)) + return_val = _gdk_input_other_event(event, xevent, window); + else + return_val = FALSE; + + break; + } } done: diff --git a/gdk/x11/gdkkeys-x11.c b/gdk/x11/gdkkeys-x11.c index f5a163a767..6e18a6337e 100644 --- a/gdk/x11/gdkkeys-x11.c +++ b/gdk/x11/gdkkeys-x11.c @@ -56,6 +56,7 @@ update_keyrange (void) #include <X11/XKBlib.h> gboolean _gdk_use_xkb = FALSE; +gint _gdk_xkb_event_type; static XkbDescPtr xkb_desc = NULL; static XkbDescPtr @@ -70,10 +71,13 @@ get_xkb (void) xkb_desc = XkbGetMap (gdk_display, XkbKeySymsMask, XkbUseCoreKbd); if (xkb_desc == NULL) g_error ("Failed to get keymap"); + + XkbGetNames (gdk_display, XkbGroupNamesMask, xkb_desc); } else if (current_serial != _gdk_keymap_serial) { XkbGetUpdatedMap (gdk_display, XkbKeySymsMask, xkb_desc); + XkbGetNames (gdk_display, XkbGroupNamesMask, xkb_desc); } current_serial = _gdk_keymap_serial; @@ -92,6 +96,18 @@ static KeySym* keymap = NULL; static gint keysyms_per_keycode = 0; static XModifierKeymap* mod_keymap = NULL; static GdkModifierType group_switch_mask = 0; +static PangoDirection current_direction; +static gboolean have_direction = FALSE; +static GdkKeymap *default_keymap = NULL; + +GdkKeymap* +gdk_keymap_get_default (void) +{ + if (default_keymap == NULL) + default_keymap = g_object_new (gdk_keymap_get_type (), NULL); + + return default_keymap; +} static void update_keymaps (void) @@ -175,6 +191,60 @@ get_keymap (void) return keymap; } +#if HAVE_XKB + +PangoDirection +get_direction (void) +{ + XkbDescRec *xkb = get_xkb (); + char *name; + XkbStateRec state_rec; + PangoDirection result; + + XkbGetState (gdk_display, XkbUseCoreKbd, &state_rec); + + name = gdk_atom_name (xkb->names->groups[state_rec.locked_group]); + if (g_strcasecmp (name, "arabic") == 0 || + g_strcasecmp (name, "hebrew") == 0 || + g_strcasecmp (name, "israelian") == 0) + result = PANGO_DIRECTION_RTL; + else + result = PANGO_DIRECTION_LTR; + + g_free (name); + + return result; +} + +void +_gdk_keymap_state_changed (void) +{ + if (default_keymap) + { + PangoDirection new_direction = get_direction (); + + if (!have_direction || new_direction != current_direction) + { + have_direction = TRUE; + current_direction = new_direction; + g_signal_emit_by_name (G_OBJECT (default_keymap), "direction_changed"); + } + } +} +#endif /* HAVE_XKB */ + +PangoDirection +gdk_keymap_get_direction (GdkKeymap *keymap) +{ + if (!have_direction) + { + current_direction = get_direction (); + have_direction = TRUE; + } + + return current_direction; +} + /** * gdk_keymap_get_entries_for_keyval: * @keymap: a #GdkKeymap, or %NULL to use the default keymap diff --git a/gdk/x11/gdkmain-x11.c b/gdk/x11/gdkmain-x11.c index 6074834024..27da88cd75 100644 --- a/gdk/x11/gdkmain-x11.c +++ b/gdk/x11/gdkmain-x11.c @@ -170,21 +170,23 @@ _gdk_windowing_init_check (int argc, char **argv) { gint xkb_major = XkbMajorVersion; gint xkb_minor = XkbMinorVersion; + gint xkb_event_type; if (XkbLibraryVersion (&xkb_major, &xkb_minor)) { xkb_major = XkbMajorVersion; xkb_minor = XkbMinorVersion; - if (XkbQueryExtension (gdk_display, NULL, NULL, NULL, + + if (XkbQueryExtension (gdk_display, NULL, &_gdk_xkb_event_type, NULL, &xkb_major, &xkb_minor)) { Bool detectable_autorepeat_supported; - + _gdk_use_xkb = TRUE; XkbSelectEvents (gdk_display, XkbUseCoreKbd, - XkbMapNotifyMask, - XkbMapNotifyMask); + XkbMapNotifyMask | XkbStateNotifyMask, + XkbMapNotifyMask | XkbStateNotifyMask); XkbSetDetectableAutoRepeat (gdk_display, True, diff --git a/gdk/x11/gdkprivate-x11.h b/gdk/x11/gdkprivate-x11.h index 7652f3d73f..3dad11d434 100644 --- a/gdk/x11/gdkprivate-x11.h +++ b/gdk/x11/gdkprivate-x11.h @@ -95,6 +95,8 @@ void _gdk_region_get_xrectangles (GdkRegion *region, void _gdk_moveresize_handle_event (XEvent *event); void _gdk_moveresize_configure_done (void); +void _gdk_keymap_state_changed (void); + extern GdkDrawableClass _gdk_x11_drawable_class; extern gboolean gdk_use_xshm; extern Atom gdk_wm_delete_window; @@ -115,6 +117,7 @@ extern guint _gdk_keymap_serial; #ifdef HAVE_XKB extern gboolean _gdk_use_xkb; extern gboolean _gdk_have_xkb_autorepeat; +extern gint _gdk_xkb_event_type; #endif /* Whether we were able to turn on detectable-autorepeat using diff --git a/gtk/gtkentry.c b/gtk/gtkentry.c index b2e4d61349..77608ee441 100644 --- a/gtk/gtkentry.c +++ b/gtk/gtkentry.c @@ -211,6 +211,8 @@ static void gtk_entry_toggle_overwrite (GtkEntry *entry); static void gtk_entry_real_activate (GtkEntry *entry); static void gtk_entry_popup_menu (GtkWidget *widget); +static void gtk_entry_keymap_direction_changed (GdkKeymap *keymap, + GtkEntry *entry); /* IM Context Callbacks */ static void gtk_entry_commit_cb (GtkIMContext *context, @@ -1511,6 +1513,11 @@ gtk_entry_focus_in (GtkWidget *widget, entry->need_im_reset = TRUE; gtk_im_context_focus_in (entry->im_context); + g_signal_connect_data (gdk_keymap_get_default (), + "direction_changed", + G_CALLBACK (gtk_entry_keymap_direction_changed), entry, NULL, + FALSE, FALSE); + gtk_entry_check_cursor_blink (entry); return FALSE; @@ -1530,6 +1537,10 @@ gtk_entry_focus_out (GtkWidget *widget, gtk_entry_check_cursor_blink (entry); + g_signal_disconnect_by_func (gdk_keymap_get_default (), + gtk_entry_keymap_direction_changed, + entry); + return FALSE; } @@ -2006,6 +2017,13 @@ gtk_entry_real_activate (GtkEntry *entry) } } +static void +gtk_entry_keymap_direction_changed (GdkKeymap *keymap, + GtkEntry *entry) +{ + gtk_entry_queue_draw (entry); +} + /* IM Context Callbacks */ @@ -2408,29 +2426,64 @@ static void gtk_entry_draw_cursor (GtkEntry *entry, CursorType type) { + GtkTextDirection keymap_direction = + (gdk_keymap_get_direction (gdk_keymap_get_default ()) == PANGO_DIRECTION_LTR) ? + GTK_TEXT_DIR_LTR : GTK_TEXT_DIR_RTL; + GtkTextDirection widget_direction = gtk_widget_get_direction (GTK_WIDGET (entry)); + g_return_if_fail (entry != NULL); g_return_if_fail (GTK_IS_ENTRY (entry)); if (GTK_WIDGET_DRAWABLE (entry)) { GtkWidget *widget = GTK_WIDGET (entry); + gboolean split_cursor; gint xoffset = INNER_BORDER - entry->scroll_offset; gint strong_x, weak_x; gint text_area_height; + GdkGC *gc1 = NULL; + GdkGC *gc2 = NULL; + gint x1 = 0; + gint x2 = 0; gdk_window_get_size (entry->text_area, NULL, &text_area_height); gtk_entry_get_cursor_locations (entry, type, &strong_x, &weak_x); + + g_object_get (gtk_settings_get_global (), + "gtk-split-cursor", &split_cursor, + NULL); + + if (split_cursor) + { + gc1 = entry->cursor_gc; + x1 = strong_x; + + if (weak_x != strong_x) + { + gc2 = widget->style->text_gc[GTK_STATE_NORMAL]; + x2 = weak_x; + } + } + else + { + gc1 = entry->cursor_gc; + + if (keymap_direction == widget_direction) + x1 = strong_x; + else + x1 = weak_x; + } - gdk_draw_line (entry->text_area, entry->cursor_gc, - xoffset + strong_x, INNER_BORDER, - xoffset + strong_x, text_area_height - INNER_BORDER); + gdk_draw_line (entry->text_area, gc1, + xoffset + x1, INNER_BORDER, + xoffset + x1, text_area_height - INNER_BORDER); - if (weak_x != strong_x) - gdk_draw_line (entry->text_area, widget->style->text_gc[GTK_STATE_NORMAL], - xoffset + weak_x, INNER_BORDER, - xoffset + weak_x, text_area_height - INNER_BORDER); + if (gc2) + gdk_draw_line (entry->text_area, gc2, + xoffset + x2, INNER_BORDER, + xoffset + x2, text_area_height - INNER_BORDER); } } @@ -2624,15 +2677,32 @@ gtk_entry_move_visually (GtkEntry *entry, while (count != 0) { int new_index, new_trailing; + gboolean split_cursor; + gboolean strong; + + g_object_get (gtk_settings_get_global (), + "gtk-split-cursor", &split_cursor, + NULL); + + if (split_cursor) + strong = TRUE; + else + { + GtkTextDirection keymap_direction = + (gdk_keymap_get_direction (gdk_keymap_get_default ()) == PANGO_DIRECTION_LTR) ? + GTK_TEXT_DIR_LTR : GTK_TEXT_DIR_RTL; + + strong = keymap_direction == gtk_widget_get_direction (GTK_WIDGET (entry)); + } if (count > 0) { - pango_layout_move_cursor_visually (layout, index, 0, 1, &new_index, &new_trailing); + pango_layout_move_cursor_visually (layout, strong, index, 0, 1, &new_index, &new_trailing); count--; } else { - pango_layout_move_cursor_visually (layout, index, 0, -1, &new_index, &new_trailing); + pango_layout_move_cursor_visually (layout, strong, index, 0, -1, &new_index, &new_trailing); count++; } @@ -3630,5 +3700,3 @@ gtk_entry_pend_cursor_blink (GtkEntry *entry) show_cursor (entry); } } - - diff --git a/gtk/gtkimmulticontext.c b/gtk/gtkimmulticontext.c index 186dc503f6..b1c2ad87f4 100644 --- a/gtk/gtkimmulticontext.c +++ b/gtk/gtkimmulticontext.c @@ -313,12 +313,15 @@ static void activate_cb (GtkWidget *menuitem, GtkIMMulticontext *context) { - const gchar *id = gtk_object_get_data (GTK_OBJECT (menuitem), "gtk-context-id"); - - gtk_im_context_reset (GTK_IM_CONTEXT (context)); + if (GTK_CHECK_MENU_ITEM (menuitem)->active) + { + const gchar *id = gtk_object_get_data (GTK_OBJECT (menuitem), "gtk-context-id"); - global_context_id = id; - gtk_im_multicontext_set_slave (context, NULL); + gtk_im_context_reset (GTK_IM_CONTEXT (context)); + + global_context_id = id; + gtk_im_multicontext_set_slave (context, NULL); + } } /** diff --git a/gtk/gtksettings.c b/gtk/gtksettings.c index 3fe8f49277..637b011e9f 100644 --- a/gtk/gtksettings.c +++ b/gtk/gtksettings.c @@ -24,6 +24,7 @@ enum { PROP_DOUBLE_CLICK_TIME, PROP_CURSOR_BLINK, PROP_CURSOR_BLINK_TIME, + PROP_SPLIT_CURSOR }; @@ -151,6 +152,14 @@ gtk_settings_class_init (GtkSettingsClass *class) G_PARAM_READWRITE), NULL); g_assert (result == PROP_CURSOR_BLINK_TIME); + result = settings_install_property_parser (class, + g_param_spec_boolean ("gtk-split-cursor", + _("Split Cursor"), + _("Whether two cursors should be displayed for mixed left-to-right and right-to-left text"), + TRUE, + G_PARAM_READWRITE), + NULL); + g_assert (result == PROP_SPLIT_CURSOR); } static void diff --git a/gtk/gtktextbtree.c b/gtk/gtktextbtree.c index df58227fca..a10baa9481 100644 --- a/gtk/gtktextbtree.c +++ b/gtk/gtktextbtree.c @@ -409,13 +409,13 @@ _gtk_text_btree_new (GtkTextTagTable *table, tree->tag_changed_handler = g_signal_connect_data (G_OBJECT (tree->table), "tag_changed", - tag_changed_cb, + G_CALLBACK (tag_changed_cb), tree, NULL, FALSE, FALSE); tree->tag_removed_handler = g_signal_connect_data (G_OBJECT (tree->table), "tag_removed", - tag_removed_cb, + G_CALLBACK (tag_removed_cb), tree, NULL, FALSE, FALSE); diff --git a/gtk/gtktextlayout.c b/gtk/gtktextlayout.c index 7bbc0d7395..2aef53e598 100644 --- a/gtk/gtktextlayout.c +++ b/gtk/gtktextlayout.c @@ -94,14 +94,15 @@ static GtkTextLineData *gtk_text_layout_real_wrap (GtkTextLayout *layout, static void gtk_text_layout_invalidated (GtkTextLayout *layout); -static void gtk_text_layout_real_invalidate (GtkTextLayout *layout, - const GtkTextIter *start, - const GtkTextIter *end); -static void gtk_text_layout_invalidate_cache (GtkTextLayout *layout, - GtkTextLine *line); -static void gtk_text_layout_real_free_line_data (GtkTextLayout *layout, - GtkTextLine *line, - GtkTextLineData *line_data); +static void gtk_text_layout_real_invalidate (GtkTextLayout *layout, + const GtkTextIter *start, + const GtkTextIter *end); +static void gtk_text_layout_invalidate_cache (GtkTextLayout *layout, + GtkTextLine *line); +static void gtk_text_layout_invalidate_cursor_line (GtkTextLayout *layout); +static void gtk_text_layout_real_free_line_data (GtkTextLayout *layout, + GtkTextLine *line, + GtkTextLineData *line_data); static void gtk_text_layout_invalidate_all (GtkTextLayout *layout); @@ -338,6 +339,30 @@ gtk_text_layout_set_contexts (GtkTextLayout *layout, gtk_text_layout_invalidate_all (layout); } +/** + * gtk_text_layout_set_cursor_direction: + * @direction: the new direction(s) for which to draw cursors. + * %GTK_TEXT_DIR_NONE means draw cursors for both + * left-to-right insertion and right-to-left insertion. + * (The two cursors will be visually distinguished.) + * + * Sets which text directions (left-to-right and/or right-to-left) for + * which cursors will be drawn for the insertion point. The visual + * point at which new text is inserted depends on whether the new + * text is right-to-left or left-to-right, so it may be desired to + * make the drawn position of the cursor depend on the keyboard state. + **/ +void +gtk_text_layout_set_cursor_direction (GtkTextLayout *layout, + GtkTextDirection direction) +{ + if (direction != layout->cursor_direction) + { + layout->cursor_direction = direction; + gtk_text_layout_invalidate_cursor_line (layout); + } +} + void gtk_text_layout_set_screen_width (GtkTextLayout *layout, gint width) { @@ -420,10 +445,6 @@ gtk_text_layout_set_preedit_string (GtkTextLayout *layout, PangoAttrList *preedit_attrs, gint cursor_pos) { - GtkTextIter iter; - GtkTextLine *line; - GtkTextLineData *line_data; - g_return_if_fail (GTK_IS_TEXT_LAYOUT (layout)); g_return_if_fail (preedit_attrs != NULL || preedit_string == NULL); @@ -451,19 +472,7 @@ gtk_text_layout_set_preedit_string (GtkTextLayout *layout, layout->preedit_cursor = 0; } - /* Now invalidate the paragraph containing the cursor - */ - gtk_text_buffer_get_iter_at_mark (layout->buffer, &iter, - gtk_text_buffer_get_mark (layout->buffer, "insert")); - - line = _gtk_text_iter_get_text_line (&iter); - line_data = _gtk_text_line_get_data (line, layout); - if (line_data) - { - gtk_text_layout_invalidate_cache (layout, line); - _gtk_text_line_invalidate_wrap (line, line_data); - gtk_text_layout_invalidated (layout); - } + gtk_text_layout_invalidate_cursor_line (layout); } void @@ -647,6 +656,28 @@ gtk_text_layout_invalidate_cache (GtkTextLayout *layout, } } +/* Now invalidate the paragraph containing the cursor + */ +static void +gtk_text_layout_invalidate_cursor_line (GtkTextLayout *layout) +{ + GtkTextIter iter; + GtkTextLine *line; + GtkTextLineData *line_data; + + gtk_text_buffer_get_iter_at_mark (layout->buffer, &iter, + gtk_text_buffer_get_mark (layout->buffer, "insert")); + + line = _gtk_text_iter_get_text_line (&iter); + line_data = _gtk_text_line_get_data (line, layout); + if (line_data) + { + gtk_text_layout_invalidate_cache (layout, line); + _gtk_text_line_invalidate_wrap (line, line_data); + gtk_text_layout_invalidated (layout); + } +} + static void gtk_text_layout_real_invalidate (GtkTextLayout *layout, const GtkTextIter *start, @@ -1403,8 +1434,10 @@ add_cursor (GtkTextLayout *layout, gint start) { PangoRectangle strong_pos, weak_pos; - GtkTextCursorDisplay *cursor; - + GtkTextCursorDisplay *cursor = NULL; /* Quiet GCC */ + gboolean add_weak = FALSE; + gboolean add_strong = FALSE; + /* Hide insertion cursor when we have a selection or the layout * user has hidden the cursor. */ @@ -1416,29 +1449,44 @@ add_cursor (GtkTextLayout *layout, pango_layout_get_cursor_pos (display->layout, start, &strong_pos, &weak_pos); - cursor = g_new (GtkTextCursorDisplay, 1); - - cursor->x = PANGO_PIXELS (strong_pos.x); - cursor->y = PANGO_PIXELS (strong_pos.y); - cursor->height = PANGO_PIXELS (strong_pos.height); - cursor->is_strong = TRUE; - display->cursors = g_slist_prepend (display->cursors, cursor); - - if (weak_pos.x == strong_pos.x) - cursor->is_weak = TRUE; - else + if (layout->cursor_direction == GTK_TEXT_DIR_NONE) { - cursor->is_weak = FALSE; + add_strong = TRUE; + add_weak = TRUE; + } + else if (display->direction == layout->cursor_direction) + add_strong = TRUE; + else + add_weak = TRUE; + if (add_strong) + { cursor = g_new (GtkTextCursorDisplay, 1); - cursor->x = PANGO_PIXELS (weak_pos.x); - cursor->y = PANGO_PIXELS (weak_pos.y); - cursor->height = PANGO_PIXELS (weak_pos.height); - cursor->is_strong = FALSE; - cursor->is_weak = TRUE; + cursor->x = PANGO_PIXELS (strong_pos.x); + cursor->y = PANGO_PIXELS (strong_pos.y); + cursor->height = PANGO_PIXELS (strong_pos.height); + cursor->is_strong = TRUE; + cursor->is_weak = FALSE; display->cursors = g_slist_prepend (display->cursors, cursor); } + + if (add_weak) + { + if (weak_pos.x == strong_pos.x && add_strong) + cursor->is_weak = TRUE; + else + { + cursor = g_new (GtkTextCursorDisplay, 1); + + cursor->x = PANGO_PIXELS (weak_pos.x); + cursor->y = PANGO_PIXELS (weak_pos.y); + cursor->height = PANGO_PIXELS (weak_pos.height); + cursor->is_strong = FALSE; + cursor->is_weak = TRUE; + display->cursors = g_slist_prepend (display->cursors, cursor); + } + } } static gboolean @@ -2838,25 +2886,31 @@ gtk_text_layout_move_iter_visually (GtkTextLayout *layout, GtkTextLine *line = _gtk_text_iter_get_text_line (iter); gint line_byte; gint extra_back = 0; + gboolean strong; int byte_count = _gtk_text_line_byte_count (line); int new_index; int new_trailing; - if (!display) display = gtk_text_layout_get_line_display (layout, line, FALSE); + + if (layout->cursor_direction == GTK_TEXT_DIR_NONE) + strong = TRUE; + else + strong = display->direction == layout->cursor_direction; + line_byte = line_display_iter_to_index (layout, display, iter); if (count > 0) { - pango_layout_move_cursor_visually (display->layout, line_byte, 0, 1, &new_index, &new_trailing); + pango_layout_move_cursor_visually (display->layout, strong, line_byte, 0, 1, &new_index, &new_trailing); count--; } else { - pango_layout_move_cursor_visually (display->layout, line_byte, 0, -1, &new_index, &new_trailing); + pango_layout_move_cursor_visually (display->layout, strong, line_byte, 0, -1, &new_index, &new_trailing); count++; } diff --git a/gtk/gtktextlayout.h b/gtk/gtktextlayout.h index 4e0ed1f228..56ed1b5b83 100644 --- a/gtk/gtktextlayout.h +++ b/gtk/gtktextlayout.h @@ -157,6 +157,11 @@ struct _GtkTextLayout /* Whether to show the insertion cursor */ guint cursor_visible : 1; + /* For what GtkTextDirection to draw cursor GTK_TEXT_DIR_NONE - + * means draw both cursors. + */ + gint cursor_direction : 2; + /* The preedit string and attributes, if any */ gchar *preedit_string; @@ -248,6 +253,8 @@ void gtk_text_layout_set_default_style (GtkTextLayout *layout, void gtk_text_layout_set_contexts (GtkTextLayout *layout, PangoContext *ltr_context, PangoContext *rtl_context); +void gtk_text_layout_set_cursor_direction (GtkTextLayout *layout, + GtkTextDirection direction); void gtk_text_layout_default_style_changed (GtkTextLayout *layout); void gtk_text_layout_set_screen_width (GtkTextLayout *layout, diff --git a/gtk/gtktextview.c b/gtk/gtktextview.c index 6ebce8533e..99da996ca5 100644 --- a/gtk/gtktextview.c +++ b/gtk/gtktextview.c @@ -237,20 +237,21 @@ static void gtk_text_view_update_layout_width (GtkTextView *tex static void gtk_text_view_set_attributes_from_style (GtkTextView *text_view, GtkTextAttributes *values, GtkStyle *style); -static void gtk_text_view_ensure_layout (GtkTextView *text_view); -static void gtk_text_view_destroy_layout (GtkTextView *text_view); -static void gtk_text_view_reset_im_context (GtkTextView *text_view); -static void gtk_text_view_start_selection_drag (GtkTextView *text_view, - const GtkTextIter *iter, - GdkEventButton *event); -static gboolean gtk_text_view_end_selection_drag (GtkTextView *text_view, - GdkEventButton *event); -static void gtk_text_view_start_selection_dnd (GtkTextView *text_view, - const GtkTextIter *iter, - GdkEventMotion *event); -static void gtk_text_view_check_cursor_blink (GtkTextView *text_view); -static void gtk_text_view_pend_cursor_blink (GtkTextView *text_view); -static void gtk_text_view_stop_cursor_blink (GtkTextView *text_view); +static void gtk_text_view_ensure_layout (GtkTextView *text_view); +static void gtk_text_view_destroy_layout (GtkTextView *text_view); +static void gtk_text_view_check_keymap_direction (GtkTextView *text_view); +static void gtk_text_view_reset_im_context (GtkTextView *text_view); +static void gtk_text_view_start_selection_drag (GtkTextView *text_view, + const GtkTextIter *iter, + GdkEventButton *event); +static gboolean gtk_text_view_end_selection_drag (GtkTextView *text_view, + GdkEventButton *event); +static void gtk_text_view_start_selection_dnd (GtkTextView *text_view, + const GtkTextIter *iter, + GdkEventMotion *event); +static void gtk_text_view_check_cursor_blink (GtkTextView *text_view); +static void gtk_text_view_pend_cursor_blink (GtkTextView *text_view); +static void gtk_text_view_stop_cursor_blink (GtkTextView *text_view); static void gtk_text_view_value_changed (GtkAdjustment *adj, GtkTextView *view); @@ -3344,6 +3345,13 @@ gtk_text_view_button_release_event (GtkWidget *widget, GdkEventButton *event) return FALSE; } +static void +keymap_direction_changed (GdkKeymap *keymap, + GtkTextView *text_view) +{ + gtk_text_view_check_keymap_direction (text_view); +} + static gint gtk_text_view_focus_in_event (GtkWidget *widget, GdkEventFocus *event) { @@ -3358,6 +3366,12 @@ gtk_text_view_focus_in_event (GtkWidget *widget, GdkEventFocus *event) gtk_text_view_check_cursor_blink (text_view); } + g_signal_connect_data (gdk_keymap_get_default (), + "direction_changed", + G_CALLBACK (keymap_direction_changed), text_view, NULL, + FALSE, FALSE); + gtk_text_view_check_keymap_direction (text_view); + text_view->need_im_reset = TRUE; gtk_im_context_focus_in (GTK_TEXT_VIEW (widget)->im_context); @@ -3378,6 +3392,10 @@ gtk_text_view_focus_out_event (GtkWidget *widget, GdkEventFocus *event) gtk_text_view_check_cursor_blink (text_view); } + g_signal_disconnect_by_func (gdk_keymap_get_default (), + keymap_direction_changed, + text_view); + text_view->need_im_reset = TRUE; gtk_im_context_focus_out (GTK_TEXT_VIEW (widget)->im_context); @@ -4275,6 +4293,28 @@ gtk_text_view_set_attributes_from_style (GtkTextView *text_view, } static void +gtk_text_view_check_keymap_direction (GtkTextView *text_view) +{ + if (text_view->layout) + { + gboolean split_cursor; + GtkTextDirection new_dir; + + g_object_get (gtk_settings_get_global (), + "gtk-split-cursor", &split_cursor, + NULL); + if (split_cursor) + new_dir = GTK_TEXT_DIR_NONE; + else + new_dir = (gdk_keymap_get_direction (gdk_keymap_get_default ()) == PANGO_DIRECTION_LTR) ? + GTK_TEXT_DIR_LTR : GTK_TEXT_DIR_RTL; + + if (text_view->layout->cursor_direction != new_dir) + gtk_text_layout_set_cursor_direction (text_view->layout, new_dir); + } +} + +static void gtk_text_view_ensure_layout (GtkTextView *text_view) { GtkWidget *widget; @@ -4327,6 +4367,8 @@ gtk_text_view_ensure_layout (GtkTextView *text_view) g_object_unref (G_OBJECT (ltr_context)); g_object_unref (G_OBJECT (rtl_context)); + gtk_text_view_check_keymap_direction (text_view); + style = gtk_text_attributes_new (); gtk_widget_ensure_style (widget); diff --git a/gtk/gtkwidget.c b/gtk/gtkwidget.c index f2ea169225..f8c4a58c17 100644 --- a/gtk/gtkwidget.c +++ b/gtk/gtkwidget.c @@ -3204,7 +3204,7 @@ gtk_widget_set_app_paintable (GtkWidget *widget, * * Widgets are double buffered by default; you can use this function * to turn off the buffering. "Double buffered" simply means that - * gdk_window_begin_paint() and gdk_window_end_paint() are called + * gdk_window_begin_paint_region() and gdk_window_end_paint() are called * automatically around expose events sent to the * widget. gdk_window_begin_paint() diverts all drawing to a widget's * window to an offscreen buffer, and gdk_window_end_paint() draws the |