Use native Windows API for converting keystrokes to characters
Instead of using the incomplete GTK-internal emulation, use the WM_CHAR messages sent by Windows. Make the IME input method the default for all languages on Windows.
This commit is contained in:
committed by
Philip Zander
parent
dd5fd12343
commit
e6f05da6ef
@ -33,7 +33,9 @@
|
||||
|
||||
#include "gdk/gdkkeysyms-compat.h"
|
||||
#include "gdk/win32/gdkwin32.h"
|
||||
#include "gdk/win32/gdkprivate-win32.h"
|
||||
#include "gdk/gdkkeysyms.h"
|
||||
#include "gdk/gdkinternals.h"
|
||||
|
||||
#include <pango/pango.h>
|
||||
|
||||
@ -59,10 +61,6 @@ typedef enum {
|
||||
GTK_WIN32_IME_FOCUS_BEHAVIOR_FOLLOW,
|
||||
} GtkWin32IMEFocusBehavior;
|
||||
|
||||
#define IS_DEAD_KEY(k) \
|
||||
((k) >= GDK_dead_grave && (k) <= (GDK_dead_dasia+1))
|
||||
|
||||
|
||||
struct _GtkIMContextIMEPrivate
|
||||
{
|
||||
/* When pretend_empty_preedit is set to TRUE,
|
||||
@ -80,7 +78,6 @@ struct _GtkIMContextIMEPrivate
|
||||
* https://gitlab.gnome.org/GNOME/gtk/commit/c255ba68fc2c918dd84da48a472e7973d3c00b03
|
||||
*/
|
||||
gboolean pretend_empty_preedit;
|
||||
guint32 dead_key_keyval;
|
||||
GtkWin32IMEFocusBehavior focus_behavior;
|
||||
};
|
||||
|
||||
@ -318,125 +315,30 @@ gtk_im_context_ime_set_client_window (GtkIMContext *context,
|
||||
g_return_if_fail (GDK_IS_WINDOW (context_ime->toplevel));
|
||||
}
|
||||
|
||||
static gunichar
|
||||
_gtk_im_context_ime_dead_key_unichar (guint keyval,
|
||||
gboolean spacing)
|
||||
{
|
||||
switch (keyval)
|
||||
{
|
||||
#define CASE(keysym, unicode, spacing_unicode) \
|
||||
case GDK_dead_##keysym: return (spacing) ? spacing_unicode : unicode;
|
||||
|
||||
CASE (grave, 0x0300, 0x0060);
|
||||
CASE (acute, 0x0301, 0x00b4);
|
||||
CASE (circumflex, 0x0302, 0x005e);
|
||||
CASE (tilde, 0x0303, 0x007e); /* Also used with perispomeni, 0x342. */
|
||||
CASE (macron, 0x0304, 0x00af);
|
||||
CASE (breve, 0x0306, 0x02d8);
|
||||
CASE (abovedot, 0x0307, 0x02d9);
|
||||
CASE (diaeresis, 0x0308, 0x00a8);
|
||||
CASE (hook, 0x0309, 0);
|
||||
CASE (abovering, 0x030A, 0x02da);
|
||||
CASE (doubleacute, 0x030B, 0x2dd);
|
||||
CASE (caron, 0x030C, 0x02c7);
|
||||
CASE (abovecomma, 0x0313, 0); /* Equivalent to psili */
|
||||
CASE (abovereversedcomma, 0x0314, 0); /* Equivalent to dasia */
|
||||
CASE (horn, 0x031B, 0); /* Legacy use for psili, 0x313 (or 0x343). */
|
||||
CASE (belowdot, 0x0323, 0);
|
||||
CASE (cedilla, 0x0327, 0x00b8);
|
||||
CASE (ogonek, 0x0328, 0); /* Legacy use for dasia, 0x314.*/
|
||||
CASE (iota, 0x0345, 0);
|
||||
|
||||
#undef CASE
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
_gtk_im_context_ime_commit_unichar (GtkIMContextIME *context_ime,
|
||||
gunichar c)
|
||||
{
|
||||
gchar utf8[10];
|
||||
int len;
|
||||
|
||||
if (context_ime->priv->dead_key_keyval != 0)
|
||||
{
|
||||
gunichar combining;
|
||||
|
||||
combining =
|
||||
_gtk_im_context_ime_dead_key_unichar (context_ime->priv->dead_key_keyval,
|
||||
FALSE);
|
||||
g_unichar_compose (c, combining, &c);
|
||||
}
|
||||
|
||||
len = g_unichar_to_utf8 (c, utf8);
|
||||
utf8[len] = 0;
|
||||
|
||||
g_signal_emit_by_name (context_ime, "commit", utf8);
|
||||
context_ime->priv->dead_key_keyval = 0;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gtk_im_context_ime_filter_keypress (GtkIMContext *context,
|
||||
GdkEventKey *event)
|
||||
{
|
||||
GtkIMContextIME *context_ime;
|
||||
gboolean retval = FALSE;
|
||||
guint32 c;
|
||||
GdkEventPrivate *event_priv;
|
||||
gchar *utf8;
|
||||
|
||||
g_return_val_if_fail (GTK_IS_IM_CONTEXT_IME (context), FALSE);
|
||||
g_return_val_if_fail (event, FALSE);
|
||||
|
||||
if (event->type == GDK_KEY_RELEASE)
|
||||
return FALSE;
|
||||
|
||||
if (event->state & GDK_CONTROL_MASK)
|
||||
return FALSE;
|
||||
|
||||
context_ime = GTK_IM_CONTEXT_IME (context);
|
||||
|
||||
if (!context_ime->focus)
|
||||
g_return_val_if_fail (gdk_event_is_allocated(event), FALSE);
|
||||
|
||||
event_priv = (GdkEventPrivate*)event;
|
||||
if (event_priv->translation_len == 0)
|
||||
return FALSE;
|
||||
|
||||
if (!GDK_IS_WINDOW (context_ime->client_window))
|
||||
return FALSE;
|
||||
utf8 = g_utf16_to_utf8(event_priv->translation, event_priv->translation_len, NULL, NULL, NULL);
|
||||
g_signal_emit_by_name (context_ime, "commit", utf8);
|
||||
g_free(utf8);
|
||||
|
||||
if (event->keyval == GDK_space &&
|
||||
context_ime->priv->dead_key_keyval != 0)
|
||||
{
|
||||
c = _gtk_im_context_ime_dead_key_unichar (context_ime->priv->dead_key_keyval, TRUE);
|
||||
context_ime->priv->dead_key_keyval = 0;
|
||||
_gtk_im_context_ime_commit_unichar (context_ime, c);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
c = gdk_keyval_to_unicode (event->keyval);
|
||||
|
||||
if (c)
|
||||
{
|
||||
_gtk_im_context_ime_commit_unichar (context_ime, c);
|
||||
retval = TRUE;
|
||||
}
|
||||
else if (IS_DEAD_KEY (event->keyval))
|
||||
{
|
||||
gunichar dead_key;
|
||||
|
||||
dead_key = _gtk_im_context_ime_dead_key_unichar (event->keyval, FALSE);
|
||||
|
||||
/* Emulate double input of dead keys */
|
||||
if (dead_key && event->keyval == context_ime->priv->dead_key_keyval)
|
||||
{
|
||||
c = _gtk_im_context_ime_dead_key_unichar (context_ime->priv->dead_key_keyval, TRUE);
|
||||
context_ime->priv->dead_key_keyval = 0;
|
||||
_gtk_im_context_ime_commit_unichar (context_ime, c);
|
||||
_gtk_im_context_ime_commit_unichar (context_ime, c);
|
||||
}
|
||||
else
|
||||
context_ime->priv->dead_key_keyval = event->keyval;
|
||||
}
|
||||
|
||||
return retval;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user