[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
feature/pgtk 232c129 035/100: implement pre-edit input method
From: |
Yuuki Harano |
Subject: |
feature/pgtk 232c129 035/100: implement pre-edit input method |
Date: |
Tue, 24 Nov 2020 08:02:32 -0500 (EST) |
branch: feature/pgtk
commit 232c129fe4ccc091c6b403a4d72b51d3d9687e23
Author: Yuuki Harano <masm+github@masm11.me>
Commit: Jeff Walsh <fejfighter@gmail.com>
implement pre-edit input method
* src/termhooks.h (enum event_kind): new pgtk value
* src/pgtkterm.h (struct pgtk_display_info):
* src/pgtkterm.c (x_free_frame_resources, pgtk_delete_terminal)
(pgtk_enqueue_string, pgtk_enqueue_preedit, key_press_event)
(focus_in_event, focus_out_event, pgtk_term_init): call pgtkim
* src/pgtkim.c: new file
(im_context_commit_cb, im_context_retrieve_surrounding_cb)
(make_color_string, im_context_preedit_changed_cb)
(im_context_preedit_end_cb, im_context_preedit_start_cb)
(pgtk_im_focus_in, pgtk_im_focus_out, pgtk_im_filter_keypress)
(pgtk_im_finish, Fpgtk_use_im_context, syms_of_pgtkim):
* src/pgtkfns.c (check_pgtk_display_info):
* src/keyboard.c (kbd_buffer_get_event, make_lispy_event)
(keys_of_keyboard):
* src/emacs.c (main): add syms_of_pgtkim
* lisp/term/pgtk-win.el (pgtk-preedit-text): new defun
* configure.ac (XWIDGETS_OBJ): add pgtkim.o
input method 対応
preedit を overlay で表示するようにした。
preedit 表示後すぐに反映されなかったのを修正
この機能を ON/OFF できるようにした。
default off.
確定と同時に次の preedit が始まった場合に表示位置がおかしかったのを修正。
sample.
preedit をテキストで渡すようにした
---
configure.ac | 2 +-
lisp/term/pgtk-win.el | 33 +++++++
src/emacs.c | 1 +
src/keyboard.c | 10 +++
src/pgtkfns.c | 2 +-
src/pgtkim.c | 243 ++++++++++++++++++++++++++++++++++++++++++++++++++
src/pgtkterm.c | 55 ++++++++++++
src/pgtkterm.h | 19 ++++
src/termhooks.h | 4 +
9 files changed, 367 insertions(+), 2 deletions(-)
diff --git a/configure.ac b/configure.ac
index 6d3652d..6f5ad44 100644
--- a/configure.ac
+++ b/configure.ac
@@ -2830,7 +2830,7 @@ LIBS=$OLD_LIBS
PGTK_OBJ=
PGTK_LIBS=
if test "$window_system" = "pgtk"; then
- PGTK_OBJ="pgtkfns.o pgtkterm.o pgtkselect.o pgtkmenu.o xsettings.o"
+ PGTK_OBJ="pgtkfns.o pgtkterm.o pgtkselect.o pgtkmenu.o pgtkim.o xsettings.o"
PGTK_LIBS="$GTK_LIBS -ldl"
AC_DEFINE([HAVE_PGTK], 1, [Define to 1 if you have pure Gtk+-3.])
fi
diff --git a/lisp/term/pgtk-win.el b/lisp/term/pgtk-win.el
index 1cf526b..2205ad6 100644
--- a/lisp/term/pgtk-win.el
+++ b/lisp/term/pgtk-win.el
@@ -368,6 +368,39 @@ See the documentation of
`create-fontset-from-fontset-spec' for the format.")
&context (window-system pgtk))
(pgtk-get-selection-internal selection-symbol target-type))
+
+(defvar pgtk-preedit-overlay nil)
+
+(defun pgtk-preedit-text (e)
+ (interactive "e")
+ (when pgtk-preedit-overlay
+ (delete-overlay pgtk-preedit-overlay))
+ (setq pgtk-preedit-overlay nil)
+
+ (let ((ovstr "")
+ (idx 0)
+ atts ov str color face-name)
+ (dolist (part (nth 1 e))
+ (setq str (car part))
+ (setq face-name (intern (format "pgtk-im-%d" idx)))
+ (eval
+ `(defface ,face-name nil "face of input method preedit"))
+ (setq atts nil)
+ (when (setq color (cdr-safe (assq 'fg (cdr part))))
+ (setq atts (append atts `(:foreground ,color))))
+ (when (setq color (cdr-safe (assq 'bg (cdr part))))
+ (setq atts (append atts `(:background ,color))))
+ (when (setq color (cdr-safe (assq 'ul (cdr part))))
+ (setq atts (append atts `(:underline ,color))))
+ (face-spec-set face-name `((t . ,atts)))
+ (add-text-properties 0 (length str) `(face ,face-name) str)
+ (setq ovstr (concat ovstr str))
+ (setq idx (1+ idx)))
+
+ (setq ov (make-overlay (point) (point)))
+ (overlay-put ov 'before-string ovstr)
+ (setq pgtk-preedit-overlay ov)))
+
(provide 'pgtk-win)
(provide 'term/pgtk-win)
diff --git a/src/emacs.c b/src/emacs.c
index 42d9373..ba5c64a 100644
--- a/src/emacs.c
+++ b/src/emacs.c
@@ -1922,6 +1922,7 @@ Using an Emacs configured with --with-x-toolkit=lucid
does not have this problem
syms_of_pgtkfns();
syms_of_pgtkselect ();
syms_of_pgtkmenu ();
+ syms_of_pgtkim ();
syms_of_fontset ();
syms_of_xsettings ();
syms_of_xwidget ();
diff --git a/src/keyboard.c b/src/keyboard.c
index 49261fc..f6c44a1 100644
--- a/src/keyboard.c
+++ b/src/keyboard.c
@@ -3939,6 +3939,9 @@ kbd_buffer_get_event (KBOARD **kbp,
*used_mouse_menu = true;
FALLTHROUGH;
#endif
+#ifdef HAVE_PGTK
+ case PGTK_PREEDIT_TEXT_EVENT:
+#endif
#ifdef HAVE_NTGUI
case END_SESSION_EVENT:
case LANGUAGE_CHANGE_EVENT:
@@ -6047,6 +6050,11 @@ make_lispy_event (struct input_event *event)
return list3 (Qconfig_changed_event,
event->arg, event->frame_or_window);
+#ifdef HAVE_PGTK
+ case PGTK_PREEDIT_TEXT_EVENT:
+ return list2 (intern("pgtk-preedit-text"), event->arg);
+#endif
+
/* The 'kind' field of the event is something we don't recognize. */
default:
emacs_abort ();
@@ -12451,6 +12459,8 @@ keys_of_keyboard (void)
"ns-put-working-text");
initial_define_lispy_key (Vspecial_event_map, "ns-unput-working-text",
"ns-unput-working-text");
+ initial_define_lispy_key (Vspecial_event_map, "pgtk-preedit-text",
+ "pgtk-preedit-text");
/* Here we used to use `ignore-event' which would simple set prefix-arg to
current-prefix-arg, as is done in `handle-switch-frame'.
But `handle-switch-frame is not run from the special-map.
diff --git a/src/pgtkfns.c b/src/pgtkfns.c
index 090ebf5..2525547 100644
--- a/src/pgtkfns.c
+++ b/src/pgtkfns.c
@@ -60,7 +60,7 @@ static const char *pgtk_app_name = "Emacs";
==========================================================================
*/
-static struct pgtk_display_info *
+struct pgtk_display_info *
check_pgtk_display_info (Lisp_Object object)
{
struct pgtk_display_info *dpyinfo = NULL;
diff --git a/src/pgtkim.c b/src/pgtkim.c
new file mode 100644
index 0000000..d9bba7e
--- /dev/null
+++ b/src/pgtkim.c
@@ -0,0 +1,243 @@
+/* Pure Gtk+-3 communication module. -*- coding: utf-8 -*-
+
+Copyright (C) 1989, 1993-1994, 2005-2006, 2008-2018 Free Software
+Foundation, Inc.
+
+This file is part of GNU Emacs.
+
+GNU Emacs is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 3 of the License, or (at
+your option) any later version.
+
+GNU Emacs 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 General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */
+
+/* This should be the first include, as it may set up #defines affecting
+ interpretation of even the system includes. */
+#include <config.h>
+
+#include "pgtkterm.h"
+
+static void im_context_commit_cb(GtkIMContext *imc, gchar *str, gpointer
user_data)
+{
+ struct pgtk_display_info *dpyinfo = user_data;
+ struct frame *f = dpyinfo->im.focused_frame;
+
+ if (dpyinfo->im.context == NULL)
+ return;
+ if (f == NULL)
+ return;
+
+ pgtk_enqueue_string(f, str);
+}
+
+static gboolean im_context_retrieve_surrounding_cb(GtkIMContext *imc, gpointer
user_data)
+{
+ gtk_im_context_set_surrounding(imc, "", -1, 0);
+ return TRUE;
+}
+
+static gboolean im_context_delete_surrounding_cb(GtkIMContext *imc, int
offset, int n_chars, gpointer user_data)
+{
+ return TRUE;
+}
+
+static Lisp_Object make_color_string(PangoAttrColor *pac)
+{
+ char buf[256];
+ sprintf(buf, "#%02x%02x%02x",
+ pac->color.red >> 8,
+ pac->color.green >> 8,
+ pac->color.blue >> 8);
+ return build_string(buf);
+}
+
+static void im_context_preedit_changed_cb(GtkIMContext *imc, gpointer
user_data)
+{
+ struct pgtk_display_info *dpyinfo = user_data;
+ struct frame *f = dpyinfo->im.focused_frame;
+ char *str;
+ PangoAttrList *attrs;
+ int pos;
+
+ if (dpyinfo->im.context == NULL)
+ return;
+ if (f == NULL)
+ return;
+
+ gtk_im_context_get_preedit_string(imc, &str, &attrs, &pos);
+
+
+ /*
+ * (
+ * (TEXT (ul . COLOR) (bg . COLOR) (fg . COLOR))
+ * ...
+ * )
+ */
+ Lisp_Object list = Qnil;
+
+ PangoAttrIterator* iter;
+ iter = pango_attr_list_get_iterator(attrs);
+ do {
+ int st, ed;
+ int has_underline = 0;
+ Lisp_Object part = Qnil;
+
+ pango_attr_iterator_range(iter, &st, &ed);
+
+ if (ed > strlen(str))
+ ed = strlen(str);
+ if (st >= ed)
+ continue;
+
+ Lisp_Object text = make_string(str + st, ed - st);
+ part = Fcons(text, part);
+
+ PangoAttrInt *ul = (PangoAttrInt *) pango_attr_iterator_get(iter,
PANGO_ATTR_UNDERLINE);
+ if (ul != NULL) {
+ if (ul->value != PANGO_UNDERLINE_NONE)
+ has_underline = 1;
+ }
+
+ PangoAttrColor *pac;
+ if (has_underline) {
+ pac = (PangoAttrColor *) pango_attr_iterator_get(iter,
PANGO_ATTR_UNDERLINE_COLOR);
+ if (pac != NULL)
+ part = Fcons(Fcons(Qul, make_color_string(pac)), part);
+ else
+ part = Fcons(Fcons(Qul, Qt), part);
+ }
+
+ pac = (PangoAttrColor *) pango_attr_iterator_get(iter,
PANGO_ATTR_FOREGROUND);
+ if (pac != NULL)
+ part = Fcons(Fcons(Qfg, make_color_string(pac)), part);
+
+ pac = (PangoAttrColor *) pango_attr_iterator_get(iter,
PANGO_ATTR_BACKGROUND);
+ if (pac != NULL)
+ part = Fcons(Fcons(Qbg, make_color_string(pac)), part);
+
+ part = Fnreverse(part);
+ list = Fcons(part, list);
+ } while (pango_attr_iterator_next(iter));
+
+ list = Fnreverse(list);
+ pgtk_enqueue_preedit(f, list);
+
+ g_free(str);
+ pango_attr_list_unref(attrs);
+}
+
+static void im_context_preedit_end_cb(GtkIMContext *imc, gpointer user_data)
+{
+ struct pgtk_display_info *dpyinfo = user_data;
+ struct frame *f = dpyinfo->im.focused_frame;
+
+ if (dpyinfo->im.context == NULL)
+ return;
+ if (f == NULL)
+ return;
+
+ pgtk_enqueue_preedit(f, Qnil);
+}
+
+static void im_context_preedit_start_cb(GtkIMContext *imc, gpointer user_data)
+{
+}
+
+void pgtk_im_focus_in(struct frame *f)
+{
+ struct pgtk_display_info *dpyinfo = FRAME_DISPLAY_INFO (f);
+ if (dpyinfo->im.context != NULL) {
+ gtk_im_context_reset (dpyinfo->im.context);
+ gtk_im_context_set_client_window (dpyinfo->im.context,
gtk_widget_get_window (FRAME_GTK_WIDGET (f)));
+ gtk_im_context_focus_in (dpyinfo->im.context);
+ }
+ dpyinfo->im.focused_frame = f;
+}
+
+void pgtk_im_focus_out(struct frame *f)
+{
+ struct pgtk_display_info *dpyinfo = FRAME_DISPLAY_INFO (f);
+ if (dpyinfo->im.focused_frame == f) {
+ if (dpyinfo->im.context != NULL) {
+ gtk_im_context_reset (dpyinfo->im.context);
+ gtk_im_context_focus_out (dpyinfo->im.context);
+ gtk_im_context_set_client_window (dpyinfo->im.context, NULL);
+ }
+ dpyinfo->im.focused_frame = NULL;
+ }
+}
+
+bool pgtk_im_filter_keypress(struct frame *f, GdkEventKey *ev)
+{
+ struct pgtk_display_info *dpyinfo = FRAME_DISPLAY_INFO (f);
+ if (dpyinfo->im.context != NULL) {
+ if (gtk_im_context_filter_keypress (dpyinfo->im.context, ev))
+ return true;
+ }
+ return false;
+}
+
+void pgtk_im_init(struct pgtk_display_info *dpyinfo)
+{
+ dpyinfo->im.context = NULL;
+}
+
+void pgtk_im_finish(struct pgtk_display_info *dpyinfo)
+{
+ if (dpyinfo->im.context != NULL)
+ g_object_unref(dpyinfo->im.context);
+ dpyinfo->im.context = NULL;
+}
+
+DEFUN ("pgtk-use-im-context", Fpgtk_use_im_context, Spgtk_use_im_context,
+ 1, 2, 0,
+ doc: /* Set whether use Gtk's im context. */)
+ (Lisp_Object use_p, Lisp_Object terminal)
+{
+ struct pgtk_display_info *dpyinfo = check_pgtk_display_info (terminal);
+
+ if (NILP(use_p)) {
+ if (dpyinfo->im.context != NULL) {
+ gtk_im_context_reset (dpyinfo->im.context);
+ gtk_im_context_focus_out (dpyinfo->im.context);
+ gtk_im_context_set_client_window (dpyinfo->im.context, NULL);
+
+ g_object_unref(dpyinfo->im.context);
+ dpyinfo->im.context = NULL;
+ }
+ } else {
+ if (dpyinfo->im.context == NULL) {
+ dpyinfo->im.context = gtk_im_multicontext_new();
+ g_signal_connect(dpyinfo->im.context, "commit",
G_CALLBACK(im_context_commit_cb), dpyinfo);
+ g_signal_connect(dpyinfo->im.context, "retrieve-surrounding",
G_CALLBACK(im_context_retrieve_surrounding_cb), dpyinfo);
+ g_signal_connect(dpyinfo->im.context, "delete-surrounding",
G_CALLBACK(im_context_delete_surrounding_cb), dpyinfo);
+ g_signal_connect(dpyinfo->im.context, "preedit-changed",
G_CALLBACK(im_context_preedit_changed_cb), dpyinfo);
+ g_signal_connect(dpyinfo->im.context, "preedit-end",
G_CALLBACK(im_context_preedit_end_cb), dpyinfo);
+ g_signal_connect(dpyinfo->im.context, "preedit-start",
G_CALLBACK(im_context_preedit_start_cb), dpyinfo);
+ gtk_im_context_set_use_preedit (dpyinfo->im.context, TRUE);
+
+ if (dpyinfo->im.focused_frame)
+ pgtk_im_focus_in(dpyinfo->im.focused_frame);
+ }
+ }
+
+ return Qnil;
+}
+
+void
+syms_of_pgtkim (void)
+{
+ defsubr (&Spgtk_use_im_context);
+
+ DEFSYM (Qpgtk_refresh_preedit, "pgtk-refresh-preedit");
+ DEFSYM (Qul, "ul");
+ DEFSYM (Qfg, "fg");
+ DEFSYM (Qbg, "bg");
+}
diff --git a/src/pgtkterm.c b/src/pgtkterm.c
index fab6e4e..67ff378 100644
--- a/src/pgtkterm.c
+++ b/src/pgtkterm.c
@@ -188,6 +188,7 @@ x_free_frame_resources (struct frame *f)
CLEAR_IF_EQ(last_mouse_frame);
CLEAR_IF_EQ(last_mouse_motion_frame);
CLEAR_IF_EQ(last_mouse_glyph_frame);
+ CLEAR_IF_EQ(im.focused_frame);
#undef CLEAR_IF_EQ
@@ -4282,6 +4283,8 @@ pgtk_delete_terminal (struct terminal *terminal)
block_input ();
+ pgtk_im_finish (dpyinfo);
+
/* Normally, the display is available... */
if (dpyinfo->gdpy)
{
@@ -4952,6 +4955,45 @@ pgtk_emacs_to_gtk_modifiers (struct pgtk_display_info
*dpyinfo, int state)
#define IsKeypadKey(keysym) (0xff80 <= (keysym) && (keysym) < 0xffbe)
#define IsFunctionKey(keysym) (0xffbe <= (keysym) && (keysym) < 0xffe1)
+void
+pgtk_enqueue_string(struct frame *f, gchar *str)
+{
+ gunichar *ustr;
+
+ ustr = g_utf8_to_ucs4 (str, -1, NULL, NULL, NULL);
+ if (ustr == NULL)
+ return;
+ for ( ; *ustr != 0; ustr++) {
+ union buffered_input_event inev;
+ Lisp_Object c = make_fixnum (*ustr);
+ EVENT_INIT (inev.ie);
+ inev.ie.kind = (SINGLE_BYTE_CHAR_P (XFIXNAT (c))
+ ? ASCII_KEYSTROKE_EVENT
+ : MULTIBYTE_CHAR_KEYSTROKE_EVENT);
+ inev.ie.arg = Qnil;
+ inev.ie.code = XFIXNAT (c);
+ XSETFRAME (inev.ie.frame_or_window, f);
+ inev.ie.modifiers = 0;
+ inev.ie.timestamp = 0;
+ evq_enqueue (&inev);
+ }
+
+}
+
+void
+pgtk_enqueue_preedit(struct frame *f, Lisp_Object preedit)
+{
+ union buffered_input_event inev;
+ EVENT_INIT (inev.ie);
+ inev.ie.kind = PGTK_PREEDIT_TEXT_EVENT;
+ inev.ie.arg = preedit;
+ inev.ie.code = 0;
+ XSETFRAME (inev.ie.frame_or_window, f);
+ inev.ie.modifiers = 0;
+ inev.ie.timestamp = 0;
+ evq_enqueue (&inev);
+}
+
static gboolean key_press_event(GtkWidget *widget, GdkEvent *event, gpointer
*user_data)
{
struct coding_system coding;
@@ -4978,6 +5020,11 @@ static gboolean key_press_event(GtkWidget *widget,
GdkEvent *event, gpointer *us
hlinfo->mouse_face_hidden = true;
}
+ if (f != 0) {
+ if (pgtk_im_filter_keypress (f, &event->key))
+ return TRUE;
+ }
+
if (f != 0)
{
guint keysym, orig_keysym;
@@ -5462,6 +5509,9 @@ focus_in_event(GtkWidget *widget, GdkEvent *event,
gpointer *user_data)
FRAME_DISPLAY_INFO(frame), frame, &inev);
if (inev.ie.kind != NO_EVENT)
evq_enqueue (&inev);
+
+ pgtk_im_focus_in (frame);
+
return TRUE;
}
@@ -5483,6 +5533,9 @@ focus_out_event(GtkWidget *widget, GdkEvent *event,
gpointer *user_data)
FRAME_DISPLAY_INFO(frame), frame, &inev);
if (inev.ie.kind != NO_EVENT)
evq_enqueue(&inev);
+
+ pgtk_im_focus_out (frame);
+
return TRUE;
}
@@ -6219,6 +6272,8 @@ pgtk_term_init (Lisp_Object display_name, char
*resource_name)
pgtk_selection_init();
+ pgtk_im_init (dpyinfo);
+
unblock_input ();
return dpyinfo;
diff --git a/src/pgtkterm.h b/src/pgtkterm.h
index a2ba627..694a85b 100644
--- a/src/pgtkterm.h
+++ b/src/pgtkterm.h
@@ -226,6 +226,14 @@ struct pgtk_display_info
/* Modifier masks in gdk */
int meta_mod_mask, alt_mod_mask;
+
+ /* whether to use Gtk's IM context. */
+
+ /* input method */
+ struct {
+ GtkIMContext *context;
+ struct frame *focused_frame;
+ } im;
};
/* This is a chain of structures for all the PGTK displays currently in use.
*/
@@ -579,6 +587,7 @@ extern void syms_of_pgtkterm (void);
extern void syms_of_pgtkfns (void);
extern void syms_of_pgtkmenu (void);
extern void syms_of_pgtkselect (void);
+extern void syms_of_pgtkim (void);
/* Implemented in pgtkselect. */
extern void nxatoms_of_pgtkselect (void);
@@ -602,4 +611,14 @@ extern void pgtk_frame_rehighlight (struct
pgtk_display_info *dpyinfo);
extern void x_change_tab_bar_height (struct frame *, int);
+extern struct pgtk_display_info *check_pgtk_display_info (Lisp_Object object);
+
+extern void pgtk_enqueue_string(struct frame *f, gchar *str);
+extern void pgtk_enqueue_preedit(struct frame *f, Lisp_Object image_data);
+extern void pgtk_im_focus_in(struct frame *f);
+extern void pgtk_im_focus_out(struct frame *f);
+extern bool pgtk_im_filter_keypress(struct frame *f, GdkEventKey *ev);
+extern void pgtk_im_init(struct pgtk_display_info *dpyinfo);
+extern void pgtk_im_finish(struct pgtk_display_info *dpyinfo);
+
#endif /* HAVE_PGTK */
diff --git a/src/termhooks.h b/src/termhooks.h
index 4403d51..c28c3fb 100644
--- a/src/termhooks.h
+++ b/src/termhooks.h
@@ -264,6 +264,10 @@ enum event_kind
, FILE_NOTIFY_EVENT
#endif
+#ifdef HAVE_PGTK
+ /* Pre-edit text was changed. */
+ , PGTK_PREEDIT_TEXT_EVENT
+#endif
};
/* Bit width of an enum event_kind tag at the start of structs and unions. */
- feature/pgtk d109dab 059/100: * src/pgtkfns.c: change coding style, (continued)
- feature/pgtk d109dab 059/100: * src/pgtkfns.c: change coding style, Yuuki Harano, 2020/11/24
- feature/pgtk 9eb35f9 033/100: experimental support of tab-bar., Yuuki Harano, 2020/11/24
- feature/pgtk 25cf592 067/100: Change coding style, Yuuki Harano, 2020/11/24
- feature/pgtk e7190d8 075/100: Fix non-English layout does not work, Yuuki Harano, 2020/11/24
- feature/pgtk 28073ba 083/100: Re-implement childframe with emacsgtkfixed, Yuuki Harano, 2020/11/24
- feature/pgtk 6c43496 074/100: Fix font lock is not applied on continued lines, Yuuki Harano, 2020/11/24
- feature/pgtk 9704e23 081/100: Enable GtkIMContext by default, Yuuki Harano, 2020/11/24
- feature/pgtk b60d4c9 086/100: Fix crash on creating child frames., Yuuki Harano, 2020/11/24
- feature/pgtk b1b7440 098/100: Work around gtk_im_context_filter_keypress() issue with super key, Yuuki Harano, 2020/11/24
- feature/pgtk 992ef48 041/100: update redisplay_interface., Yuuki Harano, 2020/11/24
- feature/pgtk 232c129 035/100: implement pre-edit input method,
Yuuki Harano <=
- feature/pgtk 984f9cc 050/100: restore frame_rehighlight_hook., Yuuki Harano, 2020/11/24
- feature/pgtk 51462ce 078/100: Add PGTK to system-configuration-features, Yuuki Harano, 2020/11/24
- feature/pgtk 7c8da33 084/100: Exclude Xlib's modifier keys, Yuuki Harano, 2020/11/24
- feature/pgtk 2d5ffa5 076/100: Make pointer visible when motion notify event, Yuuki Harano, 2020/11/24
- feature/pgtk 2dd20b2 079/100: Self-implement tooltip, Yuuki Harano, 2020/11/24
- feature/pgtk e75ce03 082/100: Add support for x-support-frames, Yuuki Harano, 2020/11/24
- feature/pgtk 6df8556 080/100: Remove duplicated syms_of_xwidget call, Yuuki Harano, 2020/11/24
- feature/pgtk 948e2fa 094/100: Avoid weird behavior when resizing with top-left corner, Yuuki Harano, 2020/11/24
- feature/pgtk 4dbea5b 090/100: Fix Gtk warnings, Yuuki Harano, 2020/11/24
- feature/pgtk c1fbfb3 093/100: Don't use gtk_window_resize to resize offscreen window, Yuuki Harano, 2020/11/24