Merge branch 'ime-load-fix' into 'master'

Ime load fix (GTK4)

See merge request GNOME/gtk!662
This commit is contained in:
LRN 2019-03-22 21:10:35 +00:00
commit 0615668dd9
8 changed files with 220 additions and 5 deletions

View File

@ -38,6 +38,8 @@
#include <dwmapi.h>
#include "gdkwin32langnotification.h"
static int debug_indent = 0;
/**
@ -536,6 +538,7 @@ _gdk_win32_display_open (const gchar *display_name)
NULL);
_gdk_device_manager->display = _gdk_display;
_gdk_win32_lang_notification_init ();
_gdk_drag_init ();
_gdk_drop_init ();
@ -701,6 +704,7 @@ gdk_win32_display_finalize (GObject *object)
_gdk_win32_display_finalize_cursors (display_win32);
_gdk_win32_dnd_exit ();
_gdk_win32_lang_notification_exit ();
g_ptr_array_free (display_win32->monitors, TRUE);

View File

@ -2113,7 +2113,6 @@ gdk_event_translate (MSG *msg,
case WM_INPUTLANGCHANGE:
_gdk_input_locale = (HKL) msg->lParam;
_gdk_win32_keymap_set_active_layout (GDK_WIN32_KEYMAP (_gdk_win32_display_get_keymap (_gdk_display)), _gdk_input_locale);
_gdk_input_locale_is_ime = ImmIsIME (_gdk_input_locale);
GetLocaleInfo (MAKELCID (LOWORD (_gdk_input_locale), SORT_DEFAULT),
LOCALE_IDEFAULTANSICODEPAGE,
buf, sizeof (buf));
@ -2125,6 +2124,20 @@ gdk_event_translate (MSG *msg,
(gpointer) msg->lParam, _gdk_input_locale_is_ime ? " (IME)" : "",
_gdk_input_codepage));
gdk_display_setting_changed (display, "gtk-im-module");
/* Generate a dummy key event to "nudge" IMContext */
event = gdk_event_new (GDK_KEY_PRESS);
event->any.surface = window;
event->key.time = _gdk_win32_get_next_tick (msg->time);
event->key.keyval = GDK_KEY_VoidSymbol;
event->key.hardware_keycode = 0;
event->key.group = 0;
gdk_event_set_scancode (event, 0);
gdk_event_set_device (event, device_manager_win32->core_keyboard);
gdk_event_set_source_device (event, device_manager_win32->system_keyboard);
event->key.is_modifier = FALSE;
event->key.state = 0;
_gdk_win32_append_event (event);
break;
case WM_SYSKEYUP:

View File

@ -39,7 +39,7 @@ HINSTANCE _gdk_app_hmodule;
gint _gdk_input_ignore_core;
HKL _gdk_input_locale;
gboolean _gdk_input_locale_is_ime;
gboolean _gdk_input_locale_is_ime = FALSE;
UINT _gdk_input_codepage;
gint _gdk_input_ignore_wintab = FALSE;

View File

@ -83,7 +83,6 @@ _gdk_win32_surfaceing_init (void)
_gdk_display_hdc = CreateDC ("DISPLAY", NULL, NULL, NULL);
_gdk_input_locale = GetKeyboardLayout (0);
_gdk_win32_keymap_set_active_layout (GDK_WIN32_KEYMAP (_gdk_win32_display_get_keymap (_gdk_display)), _gdk_input_locale);
_gdk_input_locale_is_ime = ImmIsIME (_gdk_input_locale);
GetLocaleInfo (MAKELCID (LOWORD (_gdk_input_locale), SORT_DEFAULT),
LOCALE_IDEFAULTANSICODEPAGE,
buf, sizeof (buf));

View File

@ -215,9 +215,9 @@ _gdk_win32_get_setting (const gchar *name,
else if (strcmp ("gtk-im-module", name) == 0)
{
if (_gdk_input_locale_is_ime)
g_value_set_string (value, "ime");
g_value_set_static_string (value, "ime");
else
g_value_set_string (value, "");
g_value_set_static_string (value, "");
return TRUE;
}

View File

@ -0,0 +1,172 @@
/* GDK - The GIMP Drawing Kit
* Copyright (C) 2019 Руслан Ижбулатов <lrn1986@gmail.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
*/
#include "config.h"
#define COBJMACROS
#include <msctf.h>
#include <gdk/gdk.h>
#include "gdkprivate-win32.h"
struct _GdkWin32ALPNSink
{
ITfActiveLanguageProfileNotifySink itf_alpn_sink;
gint ref_count;
};
typedef struct _GdkWin32ALPNSink GdkWin32ALPNSink;
static GdkWin32ALPNSink *actlangchangenotify = NULL;
static ITfSource *itf_source = NULL;
static DWORD actlangchangenotify_id = 0;
static ULONG STDMETHODCALLTYPE
alpn_sink_addref (ITfActiveLanguageProfileNotifySink *This)
{
GdkWin32ALPNSink *alpn_sink = (GdkWin32ALPNSink *) This;
int ref_count = ++alpn_sink->ref_count;
return ref_count;
}
static HRESULT STDMETHODCALLTYPE
alpn_sink_queryinterface (ITfActiveLanguageProfileNotifySink *This,
REFIID riid,
LPVOID *ppvObject)
{
*ppvObject = NULL;
if (IsEqualGUID (riid, &IID_IUnknown))
{
ITfActiveLanguageProfileNotifySink_AddRef (This);
*ppvObject = This;
return S_OK;
}
if (IsEqualGUID (riid, &IID_ITfActiveLanguageProfileNotifySink))
{
ITfActiveLanguageProfileNotifySink_AddRef (This);
*ppvObject = This;
return S_OK;
}
return E_NOINTERFACE;
}
static ULONG STDMETHODCALLTYPE
alpn_sink_release (ITfActiveLanguageProfileNotifySink *This)
{
GdkWin32ALPNSink *alpn_sink = (GdkWin32ALPNSink *) This;
int ref_count = --alpn_sink->ref_count;
if (ref_count == 0)
{
g_free (This);
}
return ref_count;
}
static HRESULT STDMETHODCALLTYPE
alpn_sink_on_activated (ITfActiveLanguageProfileNotifySink *This,
REFCLSID clsid,
REFGUID guidProfile,
BOOL fActivated)
{
_gdk_input_locale_is_ime = fActivated;
return S_OK;
}
static ITfActiveLanguageProfileNotifySinkVtbl alpn_sink_vtbl = {
alpn_sink_queryinterface,
alpn_sink_addref,
alpn_sink_release,
alpn_sink_on_activated,
};
static GdkWin32ALPNSink *
alpn_sink_new ()
{
GdkWin32ALPNSink *result;
result = g_new0 (GdkWin32ALPNSink, 1);
result->itf_alpn_sink.lpVtbl = &alpn_sink_vtbl;
result->ref_count = 0;
ITfActiveLanguageProfileNotifySink_AddRef (&result->itf_alpn_sink);
return result;
}
void
_gdk_win32_lang_notification_init ()
{
HRESULT hr;
ITfThreadMgr *itf_threadmgr;
CoInitializeEx (NULL, COINIT_APARTMENTTHREADED);
if (actlangchangenotify != NULL)
return;
hr = CoCreateInstance (&CLSID_TF_ThreadMgr,
NULL,
CLSCTX_INPROC_SERVER,
&IID_ITfThreadMgr,
(LPVOID *) &itf_threadmgr);
if (!SUCCEEDED (hr))
return;
hr = ITfThreadMgr_QueryInterface (itf_threadmgr, &IID_ITfSource, (VOID **) &itf_source);
ITfThreadMgr_Release (itf_threadmgr);
if (!SUCCEEDED (hr))
return;
actlangchangenotify = alpn_sink_new ();
hr = ITfSource_AdviseSink (itf_source,
&IID_ITfActiveLanguageProfileNotifySink,
(IUnknown *) actlangchangenotify,
&actlangchangenotify_id);
if (!SUCCEEDED (hr))
{
ITfActiveLanguageProfileNotifySink_Release (&actlangchangenotify->itf_alpn_sink);
actlangchangenotify = NULL;
ITfSource_Release (itf_source);
itf_source = NULL;
}
}
void
_gdk_win32_lang_notification_exit ()
{
if (actlangchangenotify != NULL && itf_source != NULL)
{
ITfSource_UnadviseSink (itf_source, actlangchangenotify_id);
ITfSource_Release (itf_source);
ITfActiveLanguageProfileNotifySink_Release (&actlangchangenotify->itf_alpn_sink);
}
CoUninitialize ();
}

View File

@ -0,0 +1,26 @@
/*
* gdkwin32langnotification.h
*
* Copyright 2019 Руслан Ижбулатов <lrn1986@gmail.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef __GDK_WIN32_LANGNOTIFICATION_H__
#define __GDK_WIN32_LANGNOTIFICATION_H__
void _gdk_win32_lang_notification_init (void);
void _gdk_win32_lang_notification_exit (void);
#endif

View File

@ -17,6 +17,7 @@ gdk_win32_sources = files([
'gdkglobals-win32.c',
'gdkhdataoutputstream-win32.c',
'gdkkeys-win32.c',
'gdkwin32langnotification.c',
'gdkmain-win32.c',
'gdkmonitor-win32.c',
'gdkproperty-win32.c',