forked from AuroraMiddleware/gtk
Merge branch 'ime-load-fix' into 'master'
Ime load fix (GTK4) See merge request GNOME/gtk!662
This commit is contained in:
commit
0615668dd9
@ -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);
|
||||
|
||||
|
@ -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:
|
||||
|
@ -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;
|
||||
|
@ -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));
|
||||
|
@ -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;
|
||||
}
|
||||
|
172
gdk/win32/gdkwin32langnotification.c
Normal file
172
gdk/win32/gdkwin32langnotification.c
Normal 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 ();
|
||||
}
|
26
gdk/win32/gdkwin32langnotification.h
Normal file
26
gdk/win32/gdkwin32langnotification.h
Normal 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
|
@ -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',
|
||||
|
Loading…
Reference in New Issue
Block a user