From 59944ddbfe915f195e757c509246b597048116cf Mon Sep 17 00:00:00 2001 From: fujiwarat Date: Sat, 25 Nov 2023 13:42:31 +0900 Subject: [PATCH] client/wayland: Implement preedit color in Plasma Wayland Wayland input-method protocol version 1 supports the preedit style with text-input protocol version 1 in Plasma Wayland. GNOME Wayland uses text-input version 3 which deletes the preedit style. Now IBus supports the preedit color for anthy, hangul, table, typing-booster. This change now also supports ibus_engine_update_preedit_text_with_mode() Rf. https://github.com/ibus/ibus/wiki/Wayland-Colors BUG=rhbz#2237486 --- client/wayland/Makefile.am | 1 + client/wayland/ibuswaylandim.c | 204 ++++- .../text-input-unstable-v1-client-protocol.h | 847 ++++++++++++++++++ src/ibusattribute.h | 52 +- 4 files changed, 1101 insertions(+), 3 deletions(-) create mode 100644 client/wayland/text-input-unstable-v1-client-protocol.h diff --git a/client/wayland/Makefile.am b/client/wayland/Makefile.am index 7e8d18af..94e357b4 100644 --- a/client/wayland/Makefile.am +++ b/client/wayland/Makefile.am @@ -31,6 +31,7 @@ DISTCLEANFILES = protocol_sources = \ input-method-unstable-v1-client-protocol.h \ input-method-unstable-v1-protocol.c \ + text-input-unstable-v1-client-protocol.h \ $(NULL) ibus_wayland_SOURCES = \ diff --git a/client/wayland/ibuswaylandim.c b/client/wayland/ibuswaylandim.c index 8f938288..9e8f651e 100644 --- a/client/wayland/ibuswaylandim.c +++ b/client/wayland/ibuswaylandim.c @@ -32,6 +32,7 @@ #include #include "input-method-unstable-v1-client-protocol.h" +#include "text-input-unstable-v1-client-protocol.h" #include "ibuswaylandim.h" enum { @@ -58,6 +59,7 @@ struct _IBusWaylandIMPrivate IBusInputContext *ibuscontext; IBusText *preedit_text; guint preedit_cursor_pos; + guint preedit_mode; IBusModifierType modifiers; struct xkb_context *xkb_context; @@ -266,12 +268,204 @@ _context_forward_key_event_cb (IBusInputContext *context, } +/** + * ibus_wayland_im_update_preedit_style: + * @wlim: An #IBusWaylandIM + * + * Convert RGB values to IBusAttrPreedit at first. + * Convert IBusAttrPreedit to zwp_text_input_v1_preedit_style at second. + * + * RF. https://github.com/ibus/ibus/wiki/Wayland-Colors + */ +static void +ibus_wayland_im_update_preedit_style (IBusWaylandIM *wlim) +{ + IBusWaylandIMPrivate *priv; + IBusAttrList *attrs; + guint i; + const char *str; + uint32_t whole_wstyle = ZWP_TEXT_INPUT_V1_PREEDIT_STYLE_DEFAULT; + uint32_t prev_start = 0; + uint32_t prev_end = 0; + + g_return_if_fail (IBUS_IS_WAYLAND_IM (wlim)); + priv = ibus_wayland_im_get_instance_private (wlim); + if (!priv->preedit_text) + return; + attrs = priv->preedit_text->attrs; + if (!attrs) + return; + for (i = 0; ; i++) { + IBusAttribute *attr = ibus_attr_list_get (attrs, i); + IBusAttrPreedit istyle = IBUS_ATTR_PREEDIT_DEFAULT; + uint32_t wstyle = ZWP_TEXT_INPUT_V1_PREEDIT_STYLE_DEFAULT; + uint32_t start, end; + if (attr == NULL) + break; + switch (attr->type) { + case IBUS_ATTR_TYPE_UNDERLINE: + istyle = IBUS_ATTR_PREEDIT_WHOLE; + break; + case IBUS_ATTR_TYPE_FOREGROUND: + switch (attr->value) { + case 0x7F7F7F: /* typing-booster */ + istyle = IBUS_ATTR_PREEDIT_PREDICTION; + break; + case 0xF90F0F: /* table */ + istyle = IBUS_ATTR_PREEDIT_PREFIX; + break; + case 0x1EDC1A: /* table */ + istyle = IBUS_ATTR_PREEDIT_SUFFIX; + break; + case 0xA40000: /* typing-booster, table */ + istyle = IBUS_ATTR_PREEDIT_ERROR_SPELLING; + break; + case 0xFF00FF: /* typing-booster */ + istyle = IBUS_ATTR_PREEDIT_ERROR_COMPOSE; + break; + case 0x0: /* Japanese */ + case 0xFF000000: + break; + case 0xFFFFFF: /* hangul */ + case 0xFFFFFFFF: + istyle = IBUS_ATTR_PREEDIT_SELECTION; + break; + default: /* Custom */ + istyle = IBUS_ATTR_PREEDIT_NONE; + } + break; + case IBUS_ATTR_TYPE_BACKGROUND: + switch (attr->value) { + case 0xC8C8F0: /* Japanese */ + case 0xFFC8C8F0: + istyle = IBUS_ATTR_PREEDIT_SELECTION; + break; + default:; /* Custom */ + } + break; + default: + istyle = IBUS_ATTR_PREEDIT_NONE; + } + switch (istyle) { + case IBUS_ATTR_PREEDIT_NONE: + wstyle = ZWP_TEXT_INPUT_V1_PREEDIT_STYLE_NONE; + break; + case IBUS_ATTR_PREEDIT_WHOLE: + wstyle = ZWP_TEXT_INPUT_V1_PREEDIT_STYLE_UNDERLINE; + break; + case IBUS_ATTR_PREEDIT_SELECTION: + wstyle = ZWP_TEXT_INPUT_V1_PREEDIT_STYLE_SELECTION; + break; + case IBUS_ATTR_PREEDIT_PREDICTION: + wstyle = ZWP_TEXT_INPUT_V1_PREEDIT_STYLE_INACTIVE; + break; + case IBUS_ATTR_PREEDIT_PREFIX: + wstyle = ZWP_TEXT_INPUT_V1_PREEDIT_STYLE_HIGHLIGHT; + break; + case IBUS_ATTR_PREEDIT_SUFFIX: + wstyle = ZWP_TEXT_INPUT_V1_PREEDIT_STYLE_INACTIVE; + break; + case IBUS_ATTR_PREEDIT_ERROR_SPELLING: + wstyle = ZWP_TEXT_INPUT_V1_PREEDIT_STYLE_INCORRECT; + break; + case IBUS_ATTR_PREEDIT_ERROR_COMPOSE: + wstyle = ZWP_TEXT_INPUT_V1_PREEDIT_STYLE_INCORRECT; + break; + default:; + } + if (wstyle == ZWP_TEXT_INPUT_V1_PREEDIT_STYLE_DEFAULT) + continue; + str = priv->preedit_text->text; + start = g_utf8_offset_to_pointer (str, attr->start_index) - str; + end = g_utf8_offset_to_pointer (str, attr->end_index) - str; + /* Double styles cannot be applied likes the underline and + * preedit color. */ + if (start == 0 && strlen (str) == end && + (i > 0 || ibus_attr_list_get (attrs, i + 1))) { + whole_wstyle = wstyle; + continue; + } + if (end < prev_start) { + if (priv->log) { + fprintf (priv->log, + "Reverse order is not supported in end %d for %s " + "against start %d.\n", end, str, prev_start); + fflush (priv->log); + } + continue; + } + if (prev_end > end) { + if (priv->log) { + fprintf (priv->log, + "Nested styles are not supported in end %d for %s " + "against end %d.\n", end, str, prev_end); + fflush (priv->log); + } + continue; + } + if (prev_end > start && prev_start >= start) + start = prev_end; + if (start >= end) { + if (priv->log) { + fprintf (priv->log, "Wrong start %d and end %d for %s.\n", + start, end, str); + fflush (priv->log); + } + return; + } + zwp_input_method_context_v1_preedit_styling (priv->context, + start, + end - start, + wstyle); + prev_start = start; + prev_end = end; + } + if (whole_wstyle != ZWP_TEXT_INPUT_V1_PREEDIT_STYLE_DEFAULT) { + uint32_t whole_start = 0; + uint32_t whole_end = strlen (str); + uint32_t start, end; + for (i = 0; ; i++) { + IBusAttribute *attr = ibus_attr_list_get (attrs, i); + if (!attr) + break; + start = g_utf8_offset_to_pointer (str, attr->start_index) - str; + end = g_utf8_offset_to_pointer (str, attr->end_index) - str; + if (start == 0 && strlen (str) == end) + continue; + if (start == 0) { + whole_start = end; + } else if (strlen (str) == end) { + whole_end = start; + } else { + whole_end = start; + if (whole_start < whole_end) { + zwp_input_method_context_v1_preedit_styling ( + priv->context, + whole_start, + whole_end - whole_start, + whole_wstyle); + } + whole_start = end; + whole_end = strlen (str); + } + } + if (whole_start < whole_end) { + zwp_input_method_context_v1_preedit_styling ( + priv->context, + whole_start, + whole_end - whole_start, + whole_wstyle); + } + } +} + static void _context_show_preedit_text_cb (IBusInputContext *context, IBusWaylandIM *wlim) { IBusWaylandIMPrivate *priv; uint32_t cursor; + const char *commit = ""; g_return_if_fail (IBUS_IS_WAYLAND_IM (wlim)); priv = ibus_wayland_im_get_instance_private (wlim); /* CURSOR is byte offset. */ @@ -282,10 +476,13 @@ _context_show_preedit_text_cb (IBusInputContext *context, zwp_input_method_context_v1_preedit_cursor (priv->context, cursor); + ibus_wayland_im_update_preedit_style (wlim); + if (priv->preedit_mode == IBUS_ENGINE_PREEDIT_COMMIT) + commit = priv->preedit_text->text; zwp_input_method_context_v1_preedit_string (priv->context, priv->serial, priv->preedit_text->text, - priv->preedit_text->text); + commit); } @@ -308,6 +505,7 @@ _context_update_preedit_text_cb (IBusInputContext *context, IBusText *text, gint cursor_pos, gboolean visible, + guint mode, IBusWaylandIM *wlim) { IBusWaylandIMPrivate *priv; @@ -317,6 +515,7 @@ _context_update_preedit_text_cb (IBusInputContext *context, g_object_unref (priv->preedit_text); priv->preedit_text = g_object_ref_sink (text); priv->preedit_cursor_pos = cursor_pos; + priv->preedit_mode = mode; if (visible) _context_show_preedit_text_cb (context, wlim); @@ -971,7 +1170,7 @@ _create_input_context_done (GObject *object, G_CALLBACK (_context_forward_key_event_cb), wlim); - g_signal_connect (priv->ibuscontext, "update-preedit-text", + g_signal_connect (priv->ibuscontext, "update-preedit-text-with-mode", G_CALLBACK (_context_update_preedit_text_cb), wlim); g_signal_connect (priv->ibuscontext, "show-preedit-text", @@ -988,6 +1187,7 @@ _create_input_context_done (GObject *object, capabilities |= IBUS_CAP_SYNC_PROCESS_KEY_V2; ibus_input_context_set_capabilities (priv->ibuscontext, capabilities); + ibus_input_context_set_client_commit_preedit (priv->ibuscontext, TRUE); if (_use_sync_mode == 1) { ibus_input_context_set_post_process_key_event (priv->ibuscontext, TRUE); diff --git a/client/wayland/text-input-unstable-v1-client-protocol.h b/client/wayland/text-input-unstable-v1-client-protocol.h new file mode 100644 index 00000000..71069ec7 --- /dev/null +++ b/client/wayland/text-input-unstable-v1-client-protocol.h @@ -0,0 +1,847 @@ +/* Generated by wayland-scanner 1.22.0 */ + +#ifndef TEXT_INPUT_UNSTABLE_V1_CLIENT_PROTOCOL_H +#define TEXT_INPUT_UNSTABLE_V1_CLIENT_PROTOCOL_H + +#include +#include +#include "wayland-client.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @page page_text_input_unstable_v1 The text_input_unstable_v1 protocol + * @section page_ifaces_text_input_unstable_v1 Interfaces + * - @subpage page_iface_zwp_text_input_v1 - text input + * - @subpage page_iface_zwp_text_input_manager_v1 - text input manager + * @section page_copyright_text_input_unstable_v1 Copyright + *
+ *
+ * Copyright © 2012, 2013 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ * 
+ */ +struct wl_seat; +struct wl_surface; +struct zwp_text_input_manager_v1; +struct zwp_text_input_v1; + +#ifndef ZWP_TEXT_INPUT_V1_INTERFACE +#define ZWP_TEXT_INPUT_V1_INTERFACE +/** + * @page page_iface_zwp_text_input_v1 zwp_text_input_v1 + * @section page_iface_zwp_text_input_v1_desc Description + * + * An object used for text input. Adds support for text input and input + * methods to applications. A text_input object is created from a + * wl_text_input_manager and corresponds typically to a text entry in an + * application. + * + * Requests are used to activate/deactivate the text_input object and set + * state information like surrounding and selected text or the content type. + * The information about entered text is sent to the text_input object via + * the pre-edit and commit events. Using this interface removes the need + * for applications to directly process hardware key events and compose text + * out of them. + * + * Text is generally UTF-8 encoded, indices and lengths are in bytes. + * + * Serials are used to synchronize the state between the text input and + * an input method. New serials are sent by the text input in the + * commit_state request and are used by the input method to indicate + * the known text input state in events like preedit_string, commit_string, + * and keysym. The text input can then ignore events from the input method + * which are based on an outdated state (for example after a reset). + * + * Warning! The protocol described in this file is experimental and + * backward incompatible changes may be made. Backward compatible changes + * may be added together with the corresponding interface version bump. + * Backward incompatible changes are done by bumping the version number in + * the protocol and interface names and resetting the interface version. + * Once the protocol is to be declared stable, the 'z' prefix and the + * version number in the protocol and interface names are removed and the + * interface version number is reset. + * @section page_iface_zwp_text_input_v1_api API + * See @ref iface_zwp_text_input_v1. + */ +/** + * @defgroup iface_zwp_text_input_v1 The zwp_text_input_v1 interface + * + * An object used for text input. Adds support for text input and input + * methods to applications. A text_input object is created from a + * wl_text_input_manager and corresponds typically to a text entry in an + * application. + * + * Requests are used to activate/deactivate the text_input object and set + * state information like surrounding and selected text or the content type. + * The information about entered text is sent to the text_input object via + * the pre-edit and commit events. Using this interface removes the need + * for applications to directly process hardware key events and compose text + * out of them. + * + * Text is generally UTF-8 encoded, indices and lengths are in bytes. + * + * Serials are used to synchronize the state between the text input and + * an input method. New serials are sent by the text input in the + * commit_state request and are used by the input method to indicate + * the known text input state in events like preedit_string, commit_string, + * and keysym. The text input can then ignore events from the input method + * which are based on an outdated state (for example after a reset). + * + * Warning! The protocol described in this file is experimental and + * backward incompatible changes may be made. Backward compatible changes + * may be added together with the corresponding interface version bump. + * Backward incompatible changes are done by bumping the version number in + * the protocol and interface names and resetting the interface version. + * Once the protocol is to be declared stable, the 'z' prefix and the + * version number in the protocol and interface names are removed and the + * interface version number is reset. + */ +extern const struct wl_interface zwp_text_input_v1_interface; +#endif +#ifndef ZWP_TEXT_INPUT_MANAGER_V1_INTERFACE +#define ZWP_TEXT_INPUT_MANAGER_V1_INTERFACE +/** + * @page page_iface_zwp_text_input_manager_v1 zwp_text_input_manager_v1 + * @section page_iface_zwp_text_input_manager_v1_desc Description + * + * A factory for text_input objects. This object is a global singleton. + * @section page_iface_zwp_text_input_manager_v1_api API + * See @ref iface_zwp_text_input_manager_v1. + */ +/** + * @defgroup iface_zwp_text_input_manager_v1 The zwp_text_input_manager_v1 interface + * + * A factory for text_input objects. This object is a global singleton. + */ +extern const struct wl_interface zwp_text_input_manager_v1_interface; +#endif + +#ifndef ZWP_TEXT_INPUT_V1_CONTENT_HINT_ENUM +#define ZWP_TEXT_INPUT_V1_CONTENT_HINT_ENUM +/** + * @ingroup iface_zwp_text_input_v1 + * content hint + * + * Content hint is a bitmask to allow to modify the behavior of the text + * input. + */ +enum zwp_text_input_v1_content_hint { + /** + * no special behaviour + */ + ZWP_TEXT_INPUT_V1_CONTENT_HINT_NONE = 0x0, + /** + * auto completion, correction and capitalization + */ + ZWP_TEXT_INPUT_V1_CONTENT_HINT_DEFAULT = 0x7, + /** + * hidden and sensitive text + */ + ZWP_TEXT_INPUT_V1_CONTENT_HINT_PASSWORD = 0xc0, + /** + * suggest word completions + */ + ZWP_TEXT_INPUT_V1_CONTENT_HINT_AUTO_COMPLETION = 0x1, + /** + * suggest word corrections + */ + ZWP_TEXT_INPUT_V1_CONTENT_HINT_AUTO_CORRECTION = 0x2, + /** + * switch to uppercase letters at the start of a sentence + */ + ZWP_TEXT_INPUT_V1_CONTENT_HINT_AUTO_CAPITALIZATION = 0x4, + /** + * prefer lowercase letters + */ + ZWP_TEXT_INPUT_V1_CONTENT_HINT_LOWERCASE = 0x8, + /** + * prefer uppercase letters + */ + ZWP_TEXT_INPUT_V1_CONTENT_HINT_UPPERCASE = 0x10, + /** + * prefer casing for titles and headings (can be language dependent) + */ + ZWP_TEXT_INPUT_V1_CONTENT_HINT_TITLECASE = 0x20, + /** + * characters should be hidden + */ + ZWP_TEXT_INPUT_V1_CONTENT_HINT_HIDDEN_TEXT = 0x40, + /** + * typed text should not be stored + */ + ZWP_TEXT_INPUT_V1_CONTENT_HINT_SENSITIVE_DATA = 0x80, + /** + * just latin characters should be entered + */ + ZWP_TEXT_INPUT_V1_CONTENT_HINT_LATIN = 0x100, + /** + * the text input is multiline + */ + ZWP_TEXT_INPUT_V1_CONTENT_HINT_MULTILINE = 0x200, +}; +#endif /* ZWP_TEXT_INPUT_V1_CONTENT_HINT_ENUM */ + +#ifndef ZWP_TEXT_INPUT_V1_CONTENT_PURPOSE_ENUM +#define ZWP_TEXT_INPUT_V1_CONTENT_PURPOSE_ENUM +/** + * @ingroup iface_zwp_text_input_v1 + * content purpose + * + * The content purpose allows to specify the primary purpose of a text + * input. + * + * This allows an input method to show special purpose input panels with + * extra characters or to disallow some characters. + */ +enum zwp_text_input_v1_content_purpose { + /** + * default input, allowing all characters + */ + ZWP_TEXT_INPUT_V1_CONTENT_PURPOSE_NORMAL = 0, + /** + * allow only alphabetic characters + */ + ZWP_TEXT_INPUT_V1_CONTENT_PURPOSE_ALPHA = 1, + /** + * allow only digits + */ + ZWP_TEXT_INPUT_V1_CONTENT_PURPOSE_DIGITS = 2, + /** + * input a number (including decimal separator and sign) + */ + ZWP_TEXT_INPUT_V1_CONTENT_PURPOSE_NUMBER = 3, + /** + * input a phone number + */ + ZWP_TEXT_INPUT_V1_CONTENT_PURPOSE_PHONE = 4, + /** + * input an URL + */ + ZWP_TEXT_INPUT_V1_CONTENT_PURPOSE_URL = 5, + /** + * input an email address + */ + ZWP_TEXT_INPUT_V1_CONTENT_PURPOSE_EMAIL = 6, + /** + * input a name of a person + */ + ZWP_TEXT_INPUT_V1_CONTENT_PURPOSE_NAME = 7, + /** + * input a password (combine with password or sensitive_data hint) + */ + ZWP_TEXT_INPUT_V1_CONTENT_PURPOSE_PASSWORD = 8, + /** + * input a date + */ + ZWP_TEXT_INPUT_V1_CONTENT_PURPOSE_DATE = 9, + /** + * input a time + */ + ZWP_TEXT_INPUT_V1_CONTENT_PURPOSE_TIME = 10, + /** + * input a date and time + */ + ZWP_TEXT_INPUT_V1_CONTENT_PURPOSE_DATETIME = 11, + /** + * input for a terminal + */ + ZWP_TEXT_INPUT_V1_CONTENT_PURPOSE_TERMINAL = 12, +}; +#endif /* ZWP_TEXT_INPUT_V1_CONTENT_PURPOSE_ENUM */ + +#ifndef ZWP_TEXT_INPUT_V1_PREEDIT_STYLE_ENUM +#define ZWP_TEXT_INPUT_V1_PREEDIT_STYLE_ENUM +enum zwp_text_input_v1_preedit_style { + /** + * default style for composing text + */ + ZWP_TEXT_INPUT_V1_PREEDIT_STYLE_DEFAULT = 0, + /** + * style should be the same as in non-composing text + */ + ZWP_TEXT_INPUT_V1_PREEDIT_STYLE_NONE = 1, + ZWP_TEXT_INPUT_V1_PREEDIT_STYLE_ACTIVE = 2, + ZWP_TEXT_INPUT_V1_PREEDIT_STYLE_INACTIVE = 3, + ZWP_TEXT_INPUT_V1_PREEDIT_STYLE_HIGHLIGHT = 4, + ZWP_TEXT_INPUT_V1_PREEDIT_STYLE_UNDERLINE = 5, + ZWP_TEXT_INPUT_V1_PREEDIT_STYLE_SELECTION = 6, + ZWP_TEXT_INPUT_V1_PREEDIT_STYLE_INCORRECT = 7, +}; +#endif /* ZWP_TEXT_INPUT_V1_PREEDIT_STYLE_ENUM */ + +#ifndef ZWP_TEXT_INPUT_V1_TEXT_DIRECTION_ENUM +#define ZWP_TEXT_INPUT_V1_TEXT_DIRECTION_ENUM +enum zwp_text_input_v1_text_direction { + /** + * automatic text direction based on text and language + */ + ZWP_TEXT_INPUT_V1_TEXT_DIRECTION_AUTO = 0, + /** + * left-to-right + */ + ZWP_TEXT_INPUT_V1_TEXT_DIRECTION_LTR = 1, + /** + * right-to-left + */ + ZWP_TEXT_INPUT_V1_TEXT_DIRECTION_RTL = 2, +}; +#endif /* ZWP_TEXT_INPUT_V1_TEXT_DIRECTION_ENUM */ + +/** + * @ingroup iface_zwp_text_input_v1 + * @struct zwp_text_input_v1_listener + */ +struct zwp_text_input_v1_listener { + /** + * enter event + * + * Notify the text_input object when it received focus. Typically + * in response to an activate request. + */ + void (*enter)(void *data, + struct zwp_text_input_v1 *zwp_text_input_v1, + struct wl_surface *surface); + /** + * leave event + * + * Notify the text_input object when it lost focus. Either in + * response to a deactivate request or when the assigned surface + * lost focus or was destroyed. + */ + void (*leave)(void *data, + struct zwp_text_input_v1 *zwp_text_input_v1); + /** + * modifiers map + * + * Transfer an array of 0-terminated modifier names. The position + * in the array is the index of the modifier as used in the + * modifiers bitmask in the keysym event. + */ + void (*modifiers_map)(void *data, + struct zwp_text_input_v1 *zwp_text_input_v1, + struct wl_array *map); + /** + * state of the input panel + * + * Notify when the visibility state of the input panel changed. + */ + void (*input_panel_state)(void *data, + struct zwp_text_input_v1 *zwp_text_input_v1, + uint32_t state); + /** + * pre-edit + * + * Notify when a new composing text (pre-edit) should be set + * around the current cursor position. Any previously set composing + * text should be removed. + * + * The commit text can be used to replace the preedit text on reset + * (for example on unfocus). + * + * The text input should also handle all preedit_style and + * preedit_cursor events occurring directly before preedit_string. + * @param serial serial of the latest known text input state + */ + void (*preedit_string)(void *data, + struct zwp_text_input_v1 *zwp_text_input_v1, + uint32_t serial, + const char *text, + const char *commit); + /** + * pre-edit styling + * + * Sets styling information on composing text. The style is + * applied for length bytes from index relative to the beginning of + * the composing text (as byte offset). Multiple styles can be + * applied to a composing text by sending multiple preedit_styling + * events. + * + * This event is handled as part of a following preedit_string + * event. + */ + void (*preedit_styling)(void *data, + struct zwp_text_input_v1 *zwp_text_input_v1, + uint32_t index, + uint32_t length, + uint32_t style); + /** + * pre-edit cursor + * + * Sets the cursor position inside the composing text (as byte + * offset) relative to the start of the composing text. When index + * is a negative number no cursor is shown. + * + * This event is handled as part of a following preedit_string + * event. + */ + void (*preedit_cursor)(void *data, + struct zwp_text_input_v1 *zwp_text_input_v1, + int32_t index); + /** + * commit + * + * Notify when text should be inserted into the editor widget. + * The text to commit could be either just a single character after + * a key press or the result of some composing (pre-edit). It could + * also be an empty text when some text should be removed (see + * delete_surrounding_text) or when the input cursor should be + * moved (see cursor_position). + * + * Any previously set composing text should be removed. + * @param serial serial of the latest known text input state + */ + void (*commit_string)(void *data, + struct zwp_text_input_v1 *zwp_text_input_v1, + uint32_t serial, + const char *text); + /** + * set cursor to new position + * + * Notify when the cursor or anchor position should be modified. + * + * This event should be handled as part of a following + * commit_string event. + */ + void (*cursor_position)(void *data, + struct zwp_text_input_v1 *zwp_text_input_v1, + int32_t index, + int32_t anchor); + /** + * delete surrounding text + * + * Notify when the text around the current cursor position should + * be deleted. + * + * Index is relative to the current cursor (in bytes). Length is + * the length of deleted text (in bytes). + * + * This event should be handled as part of a following + * commit_string event. + */ + void (*delete_surrounding_text)(void *data, + struct zwp_text_input_v1 *zwp_text_input_v1, + int32_t index, + uint32_t length); + /** + * keysym + * + * Notify when a key event was sent. Key events should not be + * used for normal text input operations, which should be done with + * commit_string, delete_surrounding_text, etc. The key event + * follows the wl_keyboard key event convention. Sym is an XKB + * keysym, state a wl_keyboard key_state. Modifiers are a mask for + * effective modifiers (where the modifier indices are set by the + * modifiers_map event) + * @param serial serial of the latest known text input state + */ + void (*keysym)(void *data, + struct zwp_text_input_v1 *zwp_text_input_v1, + uint32_t serial, + uint32_t time, + uint32_t sym, + uint32_t state, + uint32_t modifiers); + /** + * language + * + * Sets the language of the input text. The "language" argument + * is an RFC-3066 format language tag. + * @param serial serial of the latest known text input state + */ + void (*language)(void *data, + struct zwp_text_input_v1 *zwp_text_input_v1, + uint32_t serial, + const char *language); + /** + * text direction + * + * Sets the text direction of input text. + * + * It is mainly needed for showing an input cursor on the correct + * side of the editor when there is no input done yet and making + * sure neutral direction text is laid out properly. + * @param serial serial of the latest known text input state + */ + void (*text_direction)(void *data, + struct zwp_text_input_v1 *zwp_text_input_v1, + uint32_t serial, + uint32_t direction); +}; + +/** + * @ingroup iface_zwp_text_input_v1 + */ +static inline int +zwp_text_input_v1_add_listener(struct zwp_text_input_v1 *zwp_text_input_v1, + const struct zwp_text_input_v1_listener *listener, void *data) +{ + return wl_proxy_add_listener((struct wl_proxy *) zwp_text_input_v1, + (void (**)(void)) listener, data); +} + +#define ZWP_TEXT_INPUT_V1_ACTIVATE 0 +#define ZWP_TEXT_INPUT_V1_DEACTIVATE 1 +#define ZWP_TEXT_INPUT_V1_SHOW_INPUT_PANEL 2 +#define ZWP_TEXT_INPUT_V1_HIDE_INPUT_PANEL 3 +#define ZWP_TEXT_INPUT_V1_RESET 4 +#define ZWP_TEXT_INPUT_V1_SET_SURROUNDING_TEXT 5 +#define ZWP_TEXT_INPUT_V1_SET_CONTENT_TYPE 6 +#define ZWP_TEXT_INPUT_V1_SET_CURSOR_RECTANGLE 7 +#define ZWP_TEXT_INPUT_V1_SET_PREFERRED_LANGUAGE 8 +#define ZWP_TEXT_INPUT_V1_COMMIT_STATE 9 +#define ZWP_TEXT_INPUT_V1_INVOKE_ACTION 10 + +/** + * @ingroup iface_zwp_text_input_v1 + */ +#define ZWP_TEXT_INPUT_V1_ENTER_SINCE_VERSION 1 +/** + * @ingroup iface_zwp_text_input_v1 + */ +#define ZWP_TEXT_INPUT_V1_LEAVE_SINCE_VERSION 1 +/** + * @ingroup iface_zwp_text_input_v1 + */ +#define ZWP_TEXT_INPUT_V1_MODIFIERS_MAP_SINCE_VERSION 1 +/** + * @ingroup iface_zwp_text_input_v1 + */ +#define ZWP_TEXT_INPUT_V1_INPUT_PANEL_STATE_SINCE_VERSION 1 +/** + * @ingroup iface_zwp_text_input_v1 + */ +#define ZWP_TEXT_INPUT_V1_PREEDIT_STRING_SINCE_VERSION 1 +/** + * @ingroup iface_zwp_text_input_v1 + */ +#define ZWP_TEXT_INPUT_V1_PREEDIT_STYLING_SINCE_VERSION 1 +/** + * @ingroup iface_zwp_text_input_v1 + */ +#define ZWP_TEXT_INPUT_V1_PREEDIT_CURSOR_SINCE_VERSION 1 +/** + * @ingroup iface_zwp_text_input_v1 + */ +#define ZWP_TEXT_INPUT_V1_COMMIT_STRING_SINCE_VERSION 1 +/** + * @ingroup iface_zwp_text_input_v1 + */ +#define ZWP_TEXT_INPUT_V1_CURSOR_POSITION_SINCE_VERSION 1 +/** + * @ingroup iface_zwp_text_input_v1 + */ +#define ZWP_TEXT_INPUT_V1_DELETE_SURROUNDING_TEXT_SINCE_VERSION 1 +/** + * @ingroup iface_zwp_text_input_v1 + */ +#define ZWP_TEXT_INPUT_V1_KEYSYM_SINCE_VERSION 1 +/** + * @ingroup iface_zwp_text_input_v1 + */ +#define ZWP_TEXT_INPUT_V1_LANGUAGE_SINCE_VERSION 1 +/** + * @ingroup iface_zwp_text_input_v1 + */ +#define ZWP_TEXT_INPUT_V1_TEXT_DIRECTION_SINCE_VERSION 1 + +/** + * @ingroup iface_zwp_text_input_v1 + */ +#define ZWP_TEXT_INPUT_V1_ACTIVATE_SINCE_VERSION 1 +/** + * @ingroup iface_zwp_text_input_v1 + */ +#define ZWP_TEXT_INPUT_V1_DEACTIVATE_SINCE_VERSION 1 +/** + * @ingroup iface_zwp_text_input_v1 + */ +#define ZWP_TEXT_INPUT_V1_SHOW_INPUT_PANEL_SINCE_VERSION 1 +/** + * @ingroup iface_zwp_text_input_v1 + */ +#define ZWP_TEXT_INPUT_V1_HIDE_INPUT_PANEL_SINCE_VERSION 1 +/** + * @ingroup iface_zwp_text_input_v1 + */ +#define ZWP_TEXT_INPUT_V1_RESET_SINCE_VERSION 1 +/** + * @ingroup iface_zwp_text_input_v1 + */ +#define ZWP_TEXT_INPUT_V1_SET_SURROUNDING_TEXT_SINCE_VERSION 1 +/** + * @ingroup iface_zwp_text_input_v1 + */ +#define ZWP_TEXT_INPUT_V1_SET_CONTENT_TYPE_SINCE_VERSION 1 +/** + * @ingroup iface_zwp_text_input_v1 + */ +#define ZWP_TEXT_INPUT_V1_SET_CURSOR_RECTANGLE_SINCE_VERSION 1 +/** + * @ingroup iface_zwp_text_input_v1 + */ +#define ZWP_TEXT_INPUT_V1_SET_PREFERRED_LANGUAGE_SINCE_VERSION 1 +/** + * @ingroup iface_zwp_text_input_v1 + */ +#define ZWP_TEXT_INPUT_V1_COMMIT_STATE_SINCE_VERSION 1 +/** + * @ingroup iface_zwp_text_input_v1 + */ +#define ZWP_TEXT_INPUT_V1_INVOKE_ACTION_SINCE_VERSION 1 + +/** @ingroup iface_zwp_text_input_v1 */ +static inline void +zwp_text_input_v1_set_user_data(struct zwp_text_input_v1 *zwp_text_input_v1, void *user_data) +{ + wl_proxy_set_user_data((struct wl_proxy *) zwp_text_input_v1, user_data); +} + +/** @ingroup iface_zwp_text_input_v1 */ +static inline void * +zwp_text_input_v1_get_user_data(struct zwp_text_input_v1 *zwp_text_input_v1) +{ + return wl_proxy_get_user_data((struct wl_proxy *) zwp_text_input_v1); +} + +static inline uint32_t +zwp_text_input_v1_get_version(struct zwp_text_input_v1 *zwp_text_input_v1) +{ + return wl_proxy_get_version((struct wl_proxy *) zwp_text_input_v1); +} + +/** @ingroup iface_zwp_text_input_v1 */ +static inline void +zwp_text_input_v1_destroy(struct zwp_text_input_v1 *zwp_text_input_v1) +{ + wl_proxy_destroy((struct wl_proxy *) zwp_text_input_v1); +} + +/** + * @ingroup iface_zwp_text_input_v1 + * + * Requests the text_input object to be activated (typically when the + * text entry gets focus). + * + * The seat argument is a wl_seat which maintains the focus for this + * activation. The surface argument is a wl_surface assigned to the + * text_input object and tracked for focus lost. The enter event + * is emitted on successful activation. + */ +static inline void +zwp_text_input_v1_activate(struct zwp_text_input_v1 *zwp_text_input_v1, struct wl_seat *seat, struct wl_surface *surface) +{ + wl_proxy_marshal_flags((struct wl_proxy *) zwp_text_input_v1, + ZWP_TEXT_INPUT_V1_ACTIVATE, NULL, wl_proxy_get_version((struct wl_proxy *) zwp_text_input_v1), 0, seat, surface); +} + +/** + * @ingroup iface_zwp_text_input_v1 + * + * Requests the text_input object to be deactivated (typically when the + * text entry lost focus). The seat argument is a wl_seat which was used + * for activation. + */ +static inline void +zwp_text_input_v1_deactivate(struct zwp_text_input_v1 *zwp_text_input_v1, struct wl_seat *seat) +{ + wl_proxy_marshal_flags((struct wl_proxy *) zwp_text_input_v1, + ZWP_TEXT_INPUT_V1_DEACTIVATE, NULL, wl_proxy_get_version((struct wl_proxy *) zwp_text_input_v1), 0, seat); +} + +/** + * @ingroup iface_zwp_text_input_v1 + * + * Requests input panels (virtual keyboard) to show. + */ +static inline void +zwp_text_input_v1_show_input_panel(struct zwp_text_input_v1 *zwp_text_input_v1) +{ + wl_proxy_marshal_flags((struct wl_proxy *) zwp_text_input_v1, + ZWP_TEXT_INPUT_V1_SHOW_INPUT_PANEL, NULL, wl_proxy_get_version((struct wl_proxy *) zwp_text_input_v1), 0); +} + +/** + * @ingroup iface_zwp_text_input_v1 + * + * Requests input panels (virtual keyboard) to hide. + */ +static inline void +zwp_text_input_v1_hide_input_panel(struct zwp_text_input_v1 *zwp_text_input_v1) +{ + wl_proxy_marshal_flags((struct wl_proxy *) zwp_text_input_v1, + ZWP_TEXT_INPUT_V1_HIDE_INPUT_PANEL, NULL, wl_proxy_get_version((struct wl_proxy *) zwp_text_input_v1), 0); +} + +/** + * @ingroup iface_zwp_text_input_v1 + * + * Should be called by an editor widget when the input state should be + * reset, for example after the text was changed outside of the normal + * input method flow. + */ +static inline void +zwp_text_input_v1_reset(struct zwp_text_input_v1 *zwp_text_input_v1) +{ + wl_proxy_marshal_flags((struct wl_proxy *) zwp_text_input_v1, + ZWP_TEXT_INPUT_V1_RESET, NULL, wl_proxy_get_version((struct wl_proxy *) zwp_text_input_v1), 0); +} + +/** + * @ingroup iface_zwp_text_input_v1 + * + * Sets the plain surrounding text around the input position. Text is + * UTF-8 encoded. Cursor is the byte offset within the + * surrounding text. Anchor is the byte offset of the + * selection anchor within the surrounding text. If there is no selected + * text anchor, then it is the same as cursor. + */ +static inline void +zwp_text_input_v1_set_surrounding_text(struct zwp_text_input_v1 *zwp_text_input_v1, const char *text, uint32_t cursor, uint32_t anchor) +{ + wl_proxy_marshal_flags((struct wl_proxy *) zwp_text_input_v1, + ZWP_TEXT_INPUT_V1_SET_SURROUNDING_TEXT, NULL, wl_proxy_get_version((struct wl_proxy *) zwp_text_input_v1), 0, text, cursor, anchor); +} + +/** + * @ingroup iface_zwp_text_input_v1 + * + * Sets the content purpose and content hint. While the purpose is the + * basic purpose of an input field, the hint flags allow to modify some + * of the behavior. + * + * When no content type is explicitly set, a normal content purpose with + * default hints (auto completion, auto correction, auto capitalization) + * should be assumed. + */ +static inline void +zwp_text_input_v1_set_content_type(struct zwp_text_input_v1 *zwp_text_input_v1, uint32_t hint, uint32_t purpose) +{ + wl_proxy_marshal_flags((struct wl_proxy *) zwp_text_input_v1, + ZWP_TEXT_INPUT_V1_SET_CONTENT_TYPE, NULL, wl_proxy_get_version((struct wl_proxy *) zwp_text_input_v1), 0, hint, purpose); +} + +/** + * @ingroup iface_zwp_text_input_v1 + */ +static inline void +zwp_text_input_v1_set_cursor_rectangle(struct zwp_text_input_v1 *zwp_text_input_v1, int32_t x, int32_t y, int32_t width, int32_t height) +{ + wl_proxy_marshal_flags((struct wl_proxy *) zwp_text_input_v1, + ZWP_TEXT_INPUT_V1_SET_CURSOR_RECTANGLE, NULL, wl_proxy_get_version((struct wl_proxy *) zwp_text_input_v1), 0, x, y, width, height); +} + +/** + * @ingroup iface_zwp_text_input_v1 + * + * Sets a specific language. This allows for example a virtual keyboard to + * show a language specific layout. The "language" argument is an RFC-3066 + * format language tag. + * + * It could be used for example in a word processor to indicate the + * language of the currently edited document or in an instant message + * application which tracks languages of contacts. + */ +static inline void +zwp_text_input_v1_set_preferred_language(struct zwp_text_input_v1 *zwp_text_input_v1, const char *language) +{ + wl_proxy_marshal_flags((struct wl_proxy *) zwp_text_input_v1, + ZWP_TEXT_INPUT_V1_SET_PREFERRED_LANGUAGE, NULL, wl_proxy_get_version((struct wl_proxy *) zwp_text_input_v1), 0, language); +} + +/** + * @ingroup iface_zwp_text_input_v1 + */ +static inline void +zwp_text_input_v1_commit_state(struct zwp_text_input_v1 *zwp_text_input_v1, uint32_t serial) +{ + wl_proxy_marshal_flags((struct wl_proxy *) zwp_text_input_v1, + ZWP_TEXT_INPUT_V1_COMMIT_STATE, NULL, wl_proxy_get_version((struct wl_proxy *) zwp_text_input_v1), 0, serial); +} + +/** + * @ingroup iface_zwp_text_input_v1 + */ +static inline void +zwp_text_input_v1_invoke_action(struct zwp_text_input_v1 *zwp_text_input_v1, uint32_t button, uint32_t index) +{ + wl_proxy_marshal_flags((struct wl_proxy *) zwp_text_input_v1, + ZWP_TEXT_INPUT_V1_INVOKE_ACTION, NULL, wl_proxy_get_version((struct wl_proxy *) zwp_text_input_v1), 0, button, index); +} + +#define ZWP_TEXT_INPUT_MANAGER_V1_CREATE_TEXT_INPUT 0 + + +/** + * @ingroup iface_zwp_text_input_manager_v1 + */ +#define ZWP_TEXT_INPUT_MANAGER_V1_CREATE_TEXT_INPUT_SINCE_VERSION 1 + +/** @ingroup iface_zwp_text_input_manager_v1 */ +static inline void +zwp_text_input_manager_v1_set_user_data(struct zwp_text_input_manager_v1 *zwp_text_input_manager_v1, void *user_data) +{ + wl_proxy_set_user_data((struct wl_proxy *) zwp_text_input_manager_v1, user_data); +} + +/** @ingroup iface_zwp_text_input_manager_v1 */ +static inline void * +zwp_text_input_manager_v1_get_user_data(struct zwp_text_input_manager_v1 *zwp_text_input_manager_v1) +{ + return wl_proxy_get_user_data((struct wl_proxy *) zwp_text_input_manager_v1); +} + +static inline uint32_t +zwp_text_input_manager_v1_get_version(struct zwp_text_input_manager_v1 *zwp_text_input_manager_v1) +{ + return wl_proxy_get_version((struct wl_proxy *) zwp_text_input_manager_v1); +} + +/** @ingroup iface_zwp_text_input_manager_v1 */ +static inline void +zwp_text_input_manager_v1_destroy(struct zwp_text_input_manager_v1 *zwp_text_input_manager_v1) +{ + wl_proxy_destroy((struct wl_proxy *) zwp_text_input_manager_v1); +} + +/** + * @ingroup iface_zwp_text_input_manager_v1 + * + * Creates a new text_input object. + */ +static inline struct zwp_text_input_v1 * +zwp_text_input_manager_v1_create_text_input(struct zwp_text_input_manager_v1 *zwp_text_input_manager_v1) +{ + struct wl_proxy *id; + + id = wl_proxy_marshal_flags((struct wl_proxy *) zwp_text_input_manager_v1, + ZWP_TEXT_INPUT_MANAGER_V1_CREATE_TEXT_INPUT, &zwp_text_input_v1_interface, wl_proxy_get_version((struct wl_proxy *) zwp_text_input_manager_v1), 0, NULL); + + return (struct zwp_text_input_v1 *) id; +} + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/src/ibusattribute.h b/src/ibusattribute.h index fe4cab45..10190921 100644 --- a/src/ibusattribute.h +++ b/src/ibusattribute.h @@ -2,7 +2,8 @@ /* vim:set et sts=4: */ /* IBus - The Input Bus * Copyright (C) 2008-2013 Peng Huang - * Copyright (C) 2008-2013 Red Hat, Inc. + * Copyright (C) 2011-2023 Takao Fujiwara + * Copyright (C) 2008-2023 Red Hat, Inc. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -91,6 +92,55 @@ typedef enum { IBUS_ATTR_UNDERLINE_ERROR = 4, } IBusAttrUnderline; + +/** + * IBusAttrPreedit: + * @IBUS_ATTR_PREEDIT_DEFAULT: Default style for composing text. + * @IBUS_ATTR_PREEDIT_NONE: Style should be the same as in non-composing text. + * @IBUS_ATTR_PREEDIT_WHOLE: Most language engines wish to draw underline in + * the typed whole preedit string except for the + * prediction string. (Chinese, Japanese, + * Typing-booster) + * @IBUS_ATTR_PREEDIT_SELECTION: Modifying an active segment is distinguished + * against whole the preedit text. (Hangul, + * Japanese) + * @IBUS_ATTR_PREEDIT_PREDICTION: A prediction string can be appended after the + * typed string. (Typing-booster) + * @IBUS_ATTR_PREEDIT_PREFIX: A prefix string can be an informative color. + * (Table) + * @IBUS_ATTR_PREEDIT_SUFFIX: A suffix string can be an informative color. + * (Table) + * @IBUS_ATTR_PREEDIT_ERROR_SPELLING: An detected typo could be an error color + * with a spelling check or the word could + * not be found in a dictionary. The + * underline color also might be more + * visible. (Typing-booster, Table) + * @IBUS_ATTR_PREEDIT_ERROR_COMPOSE: A wrong compose key could be an error + * color. (Typing-booster) + * + * Type of Pre-edit style as the semantic name. + * The Wayland specs prefers to express the semantic values rather than RGB + * values and text-input protocol version 1 defines some values: + * https://gitlab.freedesktop.org/wayland/wayland-protocols/-/blob/main/unstable/text-input/text-input-unstable-v1.xml?ref_type=heads#L251 + * + * IBus compiled the values for major input method engines: + * https://github.com/ibus/ibus/wiki/Wayland-Colors + * + * Since: 1.5.29 + * Stability: Unstable + */ +typedef enum { + IBUS_ATTR_PREEDIT_DEFAULT = 0, + IBUS_ATTR_PREEDIT_NONE, + IBUS_ATTR_PREEDIT_WHOLE, + IBUS_ATTR_PREEDIT_SELECTION, + IBUS_ATTR_PREEDIT_PREDICTION, + IBUS_ATTR_PREEDIT_PREFIX, + IBUS_ATTR_PREEDIT_SUFFIX, + IBUS_ATTR_PREEDIT_ERROR_SPELLING, + IBUS_ATTR_PREEDIT_ERROR_COMPOSE, +} IBusAttrPreedit; + typedef struct _IBusAttribute IBusAttribute; typedef struct _IBusAttributeClass IBusAttributeClass; -- 2.41.0 From 1be3e2f79b384a374b2a69a31c88a4f36e1dd868 Mon Sep 17 00:00:00 2001 From: fujiwarat Date: Wed, 15 Nov 2023 17:19:02 +0900 Subject: [PATCH] client/gtk2: Call strdup() after g_return_if_fail() --- client/gtk2/ibusimcontext.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/client/gtk2/ibusimcontext.c b/client/gtk2/ibusimcontext.c index b5a44da0..cfc08c20 100644 --- a/client/gtk2/ibusimcontext.c +++ b/client/gtk2/ibusimcontext.c @@ -2417,7 +2417,7 @@ _create_input_context_done (IBusBus *bus, static void _create_input_context (IBusIMContext *ibusimcontext) { - gchar *prgname = g_strdup (g_get_prgname()); + gchar *prgname; gchar *client_name; IDEBUG ("%s", __FUNCTION__); @@ -2425,6 +2425,7 @@ _create_input_context (IBusIMContext *ibusimcontext) g_return_if_fail (ibusimcontext->cancellable == NULL); + prgname = g_strdup (g_get_prgname()); ibusimcontext->cancellable = g_cancellable_new (); if (!prgname) -- 2.41.0 From 0a7a4d1dfa580dfcc65d76a697f40094085e55a2 Mon Sep 17 00:00:00 2001 From: fujiwarat Date: Sat, 25 Nov 2023 13:42:07 +0900 Subject: [PATCH] ui/gtk3: Error handling with display == null BUG=rhbz#2188800 --- ui/gtk3/bindingcommon.vala | 6 +++++- ui/gtk3/panel.vala | 14 ++++++++++---- 2 files changed, 15 insertions(+), 5 deletions(-) diff --git a/ui/gtk3/bindingcommon.vala b/ui/gtk3/bindingcommon.vala index da324f70..588be17a 100644 --- a/ui/gtk3/bindingcommon.vala +++ b/ui/gtk3/bindingcommon.vala @@ -263,10 +263,14 @@ class BindingCommon { return m_default_is_xdisplay; } - public static Gdk.X11.Display get_xdisplay() { + public static Gdk.X11.Display? get_xdisplay() { if (m_xdisplay != null) return m_xdisplay; var display = Gdk.Display.get_default(); + if (display == null) { + error("You should open a display for IBus panel."); + return null; + } Type instance_type = display.get_type(); Type x11_type = typeof(Gdk.X11.Display); if (instance_type.is_a(x11_type)) { diff --git a/ui/gtk3/panel.vala b/ui/gtk3/panel.vala index f1bbd720..783ec842 100644 --- a/ui/gtk3/panel.vala +++ b/ui/gtk3/panel.vala @@ -1422,9 +1422,12 @@ class Panel : IBus.PanelService { Gdk.Display display_backup = null; if (use_x11 && !BindingCommon.default_is_xdisplay()) { + var display = BindingCommon.get_xdisplay(); display_backup = Gdk.Display.get_default(); - Gdk.DisplayManager.get().set_default_display( - (Gdk.Display)BindingCommon.get_xdisplay()); + if (display != null) { + Gdk.DisplayManager.get().set_default_display( + (Gdk.Display)display); + } } // Show system menu @@ -1476,9 +1479,12 @@ class Panel : IBus.PanelService { private Gtk.Menu create_activate_menu(bool use_x11 = false) { Gdk.Display display_backup = null; if (use_x11 && !BindingCommon.default_is_xdisplay()) { + var display = BindingCommon.get_xdisplay(); display_backup = Gdk.Display.get_default(); - Gdk.DisplayManager.get().set_default_display( - (Gdk.Display)BindingCommon.get_xdisplay()); + if (display != null) { + Gdk.DisplayManager.get().set_default_display( + (Gdk.Display)display); + } } m_ime_menu = new Gtk.Menu(); -- 2.41.0