Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

gtk+-2.0 링킹 삭제 #1

Closed
ghost opened this issue Sep 12, 2018 · 37 comments
Closed

gtk+-2.0 링킹 삭제 #1

ghost opened this issue Sep 12, 2018 · 37 comments

Comments

@ghost
Copy link

ghost commented Sep 12, 2018

안녕하세요.
gtk+-2.0 링킹을 삭제해도 작동할 것 같은데 삭제해보시는 것은 어떨까요?

PKGCONFIG += glib-2.0 gtk+-2.0

@5HARK
Copy link
Owner

5HARK commented Sep 13, 2018

넵 ㅋㅋ 일단 링킹삭제하고 헤더파일만 포함시켜서 다시 빌드해보려구요 지금 시간이 안나서 아직 못하구 있네요

@ghost
Copy link
Author

ghost commented Sep 13, 2018

https://github.com/telegramdesktop/tdesktop/pull/5050/files#diff-2e0c3f7ebaacd73ea4d10ace7152258d

여기보면

      'nimfplatforminputcontextplugin',
      'gio-2.0',
      'gobject-2.0',

아래 부분이 있는데

      'gio-2.0',
      'gobject-2.0',

이것을 삭제하는 방향으로 가야할 것 같아요.
dlopen으로 nimf 프로젝트 내 nimf qt im 소스코드 수정하는 방법을 생각해볼게요.
nimf 프로젝트 내 nimf qt im 소스코드 수정은 제가 담당하겠습니다.

@5HARK
Copy link
Owner

5HARK commented Sep 17, 2018

아하 넵 알겠습니다. 단순히 링킹만 삭제해서는 빌드가 안될것 같아서 말씀하신 dlopen 으로 정적 의존성을 다 제거해야 될것 같다는 생각이였어요.

아직 링킹만 삭제하고 빌드가 되는지는 테스트 해보지 못했습니다.

@5HARK
Copy link
Owner

5HARK commented Oct 25, 2018

일단은 말씀해 주신거 바탕으로 제가 나름대로 im-nimf-qt5.cpp 직접 수정해서 gtk 의존성을 dlopen 으로 제거한걸로 테스트해보니깐 텔레그램에서도 이상없이 잘됩니다. 다만 걸리는건 g_debug 하나때문에 glib 라이브러리에 의존하고 있는데 이걸 g_debug 를 대체할수 있는 함수로 대체하던지 아니면 glib도 그냥 똑같이 gtk 의존성 제거하듯이 dlopen으로 작업해야 하는지 고민입니다.

그리고 수정한 im-nimf-qt.cpp 을 근시일내에 이 저장소에 올릴려고 합니다. 해당 내용에대해 @cogniti 님이 검토해주셔도 괜찮을 것 같습니다.
제가 수정한 부분을 그대로 참고하셔서 직접 수정해주셔도 좋고
아니면 피드백 주시면 다듬어서 제가 nimf 프로젝트에 PR 는 식으로 반영해도 좋고
아니면 그냥 탤래그램 지원 용도로만 지 수정된 모듈을 사용하고 원 nimf 프로젝트에는 반영안하는 식으로 해도 좋을 것 같습니다.

@5HARK
Copy link
Owner

5HARK commented Oct 25, 2018

일단 여기에만 올리자면 이렇습니다.

/* -*- Mode: C++; indent-tabs-mode: nil; c-basic-offset: 2; tab-width: 2 -*- */
/*
 * im-nimf-qt5.cpp
 * This file is part of Nimf.
 *
 * Copyright (C) 2015-2018 Hodong Kim <cogniti@gmail.com>
 *
 * Nimf 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 3 of the License, or
 * (at your option) any later version.
 *
 * Nimf 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 program;  If not, see <http://www.gnu.org/licenses/>.
 */

#include <QTextFormat>
#include <QInputMethodEvent>
#include <QtGui/qpa/qplatforminputcontext.h>
#include <QtGui/qpa/qplatforminputcontextplugin_p.h>
#include <QtWidgets/QApplication>
#include <QtWidgets/QWidget>
#include "nimf-im.h"

#ifdef USE_DLFCN

#include <dlfcn.h>
#include <gtk/gtk.h>
#include <glib.h>

typedef struct
{
  NimfIM * (* im_new)                 (void);
  void     (* im_focus_in)            (NimfIM              *im);
  void     (* im_focus_out)           (NimfIM              *im);
  void     (* im_reset)               (NimfIM              *im);
  gboolean (* im_filter_event)        (NimfIM              *im,
                                       NimfEvent           *event);
  void     (* im_get_preedit_string)  (NimfIM              *im,
                                       gchar              **str,
                                       NimfPreeditAttr   ***attrs,
                                       gint                *cursor_pos);
  void     (* im_set_cursor_location) (NimfIM              *im,
                                       const NimfRectangle *area);
  void     (* im_set_use_preedit)     (NimfIM              *im,
                                       gboolean             use_preedit);
  gboolean (* im_get_surrounding)     (NimfIM              *im,
                                       gchar              **text,
                                       gint                *cursor_index);
  void     (* im_set_surrounding)     (NimfIM              *im,
                                       const char          *text,
                                       gint                 len,
                                       gint                 cursor_index);
  NimfEvent * (* event_new)           (NimfEventType     type);
  void        (* event_free)          (NimfEvent        *event);
  void        (* preedit_attr_freev)  (NimfPreeditAttr **attrs);
} NimfAPI;

typedef struct
{
  gboolean (* g_settings_get_boolean) (GSettings *settings,
                                       gchar *key);
  GSettings * (* g_settings_new) (const gchar *schema_id);
  gulong (* g_signal_connect_data) (gpointer instance,
                                    const gchar *detailed_signal,
                                    GCallback c_handler,
                                    gpointer data,
                                    GClosureNotify destory_data,
                                    GConnectFlags connect_flags);
  void (* g_signal_emit_by_name) (gpointer instance,
                                  const gchar *detailed_signal,
                                  ...);
  void (* g_object_unref) (gpointer object);
  /*  void (* g_log) (const gchar *log_domain,
                  GLogLevelFlags log_level,
                  const gchar *format,
                  ...);

  void (* g_log_structured_standard) (const gchar            *log_domain,
                                      GLogLevelFlags          log_level,
                                      const gchar            *file,
                                      const gchar            *line,
                                      const gchar            *func,
                                      const gchar            *message_format,
                                      ...);*/                                      
} GtkAPI;

void    *libnimf  = NULL;
NimfAPI *nimf_api = NULL;
void    *libgtk     = NULL;
GtkAPI *gtk_api = NULL;

#endif

class NimfEventHandler : public QObject
{
  Q_OBJECT

public:
  NimfEventHandler(NimfIM *im)
  {
    m_im = im;
  };

  ~NimfEventHandler()
  {};

protected:
  bool eventFilter(QObject *obj, QEvent *event);

private:
  NimfIM *m_im;
};

bool NimfEventHandler::eventFilter(QObject *obj, QEvent *event)
{
  if (event->type() == QEvent::MouseButtonPress)
#ifndef USE_DLFCN
    nimf_im_reset (m_im);
#else
    nimf_api->im_reset (m_im);
#endif

  return QObject::eventFilter(obj, event);
}

class NimfInputContext : public QPlatformInputContext
{
  Q_OBJECT
public:
   NimfInputContext ();
  ~NimfInputContext ();

  virtual bool isValid () const;
  virtual void reset ();
  virtual void commit ();
  virtual void update (Qt::InputMethodQueries);
  virtual void invokeAction (QInputMethod::Action, int cursorPosition);
  virtual bool filterEvent (const QEvent *event);
  virtual QRectF keyboardRect () const;
  virtual bool isAnimating () const;
  virtual void showInputPanel ();
  virtual void hideInputPanel ();
  virtual bool isInputPanelVisible () const;
  virtual QLocale locale () const;
  virtual Qt::LayoutDirection inputDirection() const;
  virtual void setFocusObject (QObject *object);

  // nimf signal callbacks
  static void     on_preedit_start        (NimfIM      *im,
                                           gpointer     user_data);
  static void     on_preedit_end          (NimfIM      *im,
                                           gpointer     user_data);
  static void     on_preedit_changed      (NimfIM      *im,
                                           gpointer     user_data);
  static void     on_commit               (NimfIM      *im,
                                           const gchar *text,
                                           gpointer     user_data);
  static gboolean on_retrieve_surrounding (NimfIM      *im,
                                           gpointer     user_data);
  static gboolean on_delete_surrounding   (NimfIM      *im,
                                           gint         offset,
                                           gint         n_chars,
                                           gpointer     user_data);
  static void     on_beep                 (NimfIM      *im,
                                           gpointer     user_data);
  // settings
  static void on_changed_reset_on_mouse_button_press (GSettings *settings,
                                                      gchar     *key,
                                                      gpointer   user_data);
private:
  NimfIM           *m_im          = NULL;
  GSettings        *m_settings    = NULL;
  NimfEventHandler *m_handler     = NULL;
  NimfRectangle     m_cursor_area = {0, 0, 0, 0};
};

/* nimf signal callbacks */
void
NimfInputContext::on_preedit_start (NimfIM *im, gpointer user_data)
{
#ifndef USE_DLFCN
  g_debug (G_STRLOC ": %s", G_STRFUNC);
#else
  //gtk_api->g_log(G_LOG_DOMAIN, G_LOG_LEVEL_DEBUG, G_STRLOC ": %s", G_STRFUNC);
#endif
}

void
NimfInputContext::on_preedit_end (NimfIM *im, gpointer user_data)
{
#ifndef USE_DLFCN
  g_debug (G_STRLOC ": %s", G_STRFUNC);
#else
  //gtk_api->g_log(G_LOG_DOMAIN, G_LOG_LEVEL_DEBUG, G_STRLOC ": %s", G_STRFUNC);
#endif
}

void
NimfInputContext::on_preedit_changed (NimfIM *im, gpointer user_data)
{
#ifndef USE_DLFCN
  g_debug (G_STRLOC ": %s", G_STRFUNC);
#else
  //gtk_api->g_log(G_LOG_DOMAIN, G_LOG_LEVEL_DEBUG, G_STRLOC ": %s", G_STRFUNC);
#endif

  NimfPreeditAttr **preedit_attrs;
  gchar            *str;
  gint              cursor_pos;
  gint              i;

#ifndef USE_DLFCN
  nimf_im_get_preedit_string (im, &str, &preedit_attrs, &cursor_pos);
#else
  nimf_api->im_get_preedit_string (im, &str, &preedit_attrs, &cursor_pos);
#endif

  QString preeditText = QString::fromUtf8 (str);
  g_free (str);
  QList <QInputMethodEvent::Attribute> attrs;

  // preedit text attribute
  for (i = 0; preedit_attrs[i] != NULL; i++)
  {
    QTextCharFormat format;

    switch (preedit_attrs[i]->type)
    {
      case NIMF_PREEDIT_ATTR_HIGHLIGHT:
        format.setBackground(Qt::green);
        format.setForeground(Qt::black);
        break;
      case NIMF_PREEDIT_ATTR_UNDERLINE:
        format.setUnderlineStyle(QTextCharFormat::DashUnderline);
        break;
      default:
        format.setUnderlineStyle(QTextCharFormat::DashUnderline);
        break;
    }

    QInputMethodEvent::Attribute attr (QInputMethodEvent::TextFormat,
                                       preedit_attrs[i]->start_index,
                                       preedit_attrs[i]->end_index - preedit_attrs[i]->start_index,
                                       format);
    attrs << attr;
  }

#ifndef USE_DLFCN
  nimf_preedit_attr_freev (preedit_attrs);
#else
  nimf_api->preedit_attr_freev (preedit_attrs);
#endif

  // cursor attribute
  attrs << QInputMethodEvent::Attribute (QInputMethodEvent::Cursor,
                                         cursor_pos, true, 0);

  QInputMethodEvent event (preeditText, attrs);
  QObject *object = qApp->focusObject ();

  if (!object)
    return;

  QCoreApplication::sendEvent (object, &event);
}

void
NimfInputContext::on_commit (NimfIM      *im,
                             const gchar *text,
                             gpointer     user_data)
{
  #ifndef USE_DLFCN
  g_debug (G_STRLOC ": %s", G_STRFUNC);
#else
  //gtk_api->g_log(G_LOG_DOMAIN, G_LOG_LEVEL_DEBUG, G_STRLOC ": %s", G_STRFUNC);
#endif

  QString str = QString::fromUtf8 (text);
  QInputMethodEvent event;
  event.setCommitString (str);

  QObject *obj = qApp->focusObject();

  if (!obj)
    return;

  QCoreApplication::sendEvent (obj, &event);
}

gboolean
NimfInputContext::on_retrieve_surrounding (NimfIM *im, gpointer user_data)
{
#ifndef USE_DLFCN
  g_debug (G_STRLOC ": %s", G_STRFUNC);
#else
  //gtk_api->g_log(G_LOG_DOMAIN, G_LOG_LEVEL_DEBUG, G_STRLOC ": %s", G_STRFUNC);
#endif
  return FALSE;
}

gboolean
NimfInputContext::on_delete_surrounding (NimfIM   *im,
                                         gint      offset,
                                         gint      n_chars,
                                         gpointer  user_data)
{
#ifndef USE_DLFCN
  g_debug (G_STRLOC ": %s", G_STRFUNC);
#else
  //gtk_api->g_log(G_LOG_DOMAIN, G_LOG_LEVEL_DEBUG, G_STRLOC ": %s", G_STRFUNC);
#endif
  return FALSE;
}

void
NimfInputContext::on_beep (NimfIM *im, gpointer user_data)
{
#ifndef USE_DLFCN
  g_debug (G_STRLOC ": %s", G_STRFUNC);
#else
  //gtk_api->g_log(G_LOG_DOMAIN, G_LOG_LEVEL_DEBUG, G_STRLOC ": %s", G_STRFUNC);
#endif

  QApplication::beep();
}

void
NimfInputContext::on_changed_reset_on_mouse_button_press (GSettings *settings,
                                                          gchar     *key,
                                                          gpointer   user_data)
{
#ifndef USE_DLFCN
  g_debug (G_STRLOC ": %s", G_STRFUNC);
#else
  //gtk_api->g_log(G_LOG_DOMAIN, G_LOG_LEVEL_DEBUG, G_STRLOC ": %s", G_STRFUNC);
#endif

  NimfInputContext *context = static_cast<NimfInputContext *>(user_data);

#ifndef USE_DLFCN
  if (g_settings_get_boolean (settings, key))
#else
  if (gtk_api->g_settings_get_boolean (settings, key))
#endif
  {
    if (context->m_handler == NULL)
    {
      context->m_handler = new NimfEventHandler(context->m_im);
      qApp->installEventFilter(context->m_handler);
    }
  }
  else
  {
    if (context->m_handler)
    {
      qApp->removeEventFilter(context->m_handler);
      delete context->m_handler;
      context->m_handler = NULL;
    }
  }
}

NimfInputContext::NimfInputContext ()
{
#ifndef USE_DLFCN
  g_debug (G_STRLOC ": %s", G_STRFUNC);
#else
  //g_return_if_fail (gtk_api != NULL);
  //gtk_api->g_log(G_LOG_DOMAIN, G_LOG_LEVEL_DEBUG, G_STRLOC ": %s", G_STRFUNC);
#endif

#ifndef USE_DLFCN
  m_im = nimf_im_new ();
#else
  g_return_if_fail (nimf_api != NULL);
  m_im = nimf_api->im_new ();
#endif

#ifndef USE_DLFCN
  m_settings = g_settings_new ("org.nimf.clients.qt5");
#else
  m_settings = gtk_api->g_settings_new ("org.nimf.clients.qt5");
#endif

#ifndef USE_DLFCN
  g_signal_connect (m_im, "preedit-start",
                    G_CALLBACK (NimfInputContext::on_preedit_start), this);
  g_signal_connect (m_im, "preedit-end",
                    G_CALLBACK (NimfInputContext::on_preedit_end), this);
  g_signal_connect (m_im, "preedit-changed",
                    G_CALLBACK (NimfInputContext::on_preedit_changed), this);
  g_signal_connect (m_im, "commit",
                    G_CALLBACK (NimfInputContext::on_commit), this);
  g_signal_connect (m_im, "retrieve-surrounding",
                    G_CALLBACK (NimfInputContext::on_retrieve_surrounding),
                    this);
  g_signal_connect (m_im, "delete-surrounding",
                    G_CALLBACK (NimfInputContext::on_delete_surrounding),
                    this);
  g_signal_connect (m_im, "beep",
                    G_CALLBACK (NimfInputContext::on_beep), this);

  g_signal_connect (m_settings, "changed::reset-on-mouse-button-press",
                    G_CALLBACK (NimfInputContext::on_changed_reset_on_mouse_button_press), this);
  g_signal_emit_by_name (m_settings, "changed::reset-on-mouse-button-press",
                                     "reset-on-mouse-button-press");
#else
  gtk_api->g_signal_connect_data (m_im, "preedit-start",
                                   G_CALLBACK (NimfInputContext::on_preedit_start), this, NULL, (GConnectFlags) 0);
  gtk_api->g_signal_connect_data (m_im, "preedit-end",
                                   G_CALLBACK (NimfInputContext::on_preedit_end), this, NULL, (GConnectFlags) 0);
  gtk_api->g_signal_connect_data (m_im, "preedit-changed",
                                   G_CALLBACK (NimfInputContext::on_preedit_changed), this, NULL, (GConnectFlags) 0);
  gtk_api->g_signal_connect_data (m_im, "commit",
                                   G_CALLBACK (NimfInputContext::on_commit), this, NULL, (GConnectFlags) 0);
  gtk_api->g_signal_connect_data (m_im, "retrieve-surrounding",
                                   G_CALLBACK (NimfInputContext::on_retrieve_surrounding), this, NULL, (GConnectFlags) 0);
  gtk_api->g_signal_connect_data (m_im, "delete-surrounding",
                                   G_CALLBACK (NimfInputContext::on_delete_surrounding), this, NULL, (GConnectFlags) 0);
  gtk_api->g_signal_connect_data (m_im, "beep",
                                   G_CALLBACK (NimfInputContext::on_beep), this, NULL, (GConnectFlags) 0);

  gtk_api->g_signal_connect_data (m_settings, "changed::reset-on-mouse-button-press",
                                   G_CALLBACK (NimfInputContext::on_changed_reset_on_mouse_button_press), this, NULL, (GConnectFlags) 0);
  gtk_api->g_signal_emit_by_name (m_settings, "changed::reset-on-mouse-button-press",
                                   "reset-on-mouse-button-press");
#endif
}

NimfInputContext::~NimfInputContext ()
{
#ifndef USE_DLFCN
  g_debug (G_STRLOC ": %s", G_STRFUNC);
#else
  //gtk_api->g_log(G_LOG_DOMAIN, G_LOG_LEVEL_DEBUG, G_STRLOC ": %s", G_STRFUNC);
#endif

  if (m_handler)
    delete m_handler;
#ifndef USE_DLFCN
  if (m_im)
    g_object_unref (m_im);

  if (m_settings)
    g_object_unref (m_settings);
#else
  if (m_im)
    gtk_api->g_object_unref (m_im);

  if (m_settings)
    gtk_api->g_object_unref (m_settings);
#endif
}

bool
NimfInputContext::isValid () const
{
#ifndef USE_DLFCN
  g_debug (G_STRLOC ": %s", G_STRFUNC);
#else
  //gtk_api->g_log(G_LOG_DOMAIN, G_LOG_LEVEL_DEBUG, G_STRLOC ": %s", G_STRFUNC);
#endif

#ifdef USE_DLFCN
  if (nimf_api == NULL || gtk_api == NULL)
    return false;
#endif
  return true;
}

void
NimfInputContext::reset ()
{
#ifndef USE_DLFCN
  g_debug (G_STRLOC ": %s", G_STRFUNC);
#else
  //gtk_api->g_log(G_LOG_DOMAIN, G_LOG_LEVEL_DEBUG, G_STRLOC ": %s", G_STRFUNC);
#endif

#ifndef USE_DLFCN
  nimf_im_reset (m_im);
#else
  nimf_api->im_reset (m_im);
#endif
}

void
NimfInputContext::commit ()
{
#ifndef USE_DLFCN
  g_debug (G_STRLOC ": %s", G_STRFUNC);
#else
  //gtk_api->g_log(G_LOG_DOMAIN, G_LOG_LEVEL_DEBUG, G_STRLOC ": %s", G_STRFUNC);
#endif

#ifndef USE_DLFCN
  nimf_im_reset (m_im);
#else
  nimf_api->im_reset (m_im);
#endif
}

void
NimfInputContext::update (Qt::InputMethodQueries queries) /* FIXME */
{
#ifndef USE_DLFCN
  g_debug (G_STRLOC ": %s", G_STRFUNC);
#else
  //gtk_api->g_log(G_LOG_DOMAIN, G_LOG_LEVEL_DEBUG, G_STRLOC ": %s", G_STRFUNC);
#endif

  if (queries & Qt::ImCursorRectangle)
  {
    QWidget *widget = qApp->focusWidget ();

    if (widget == NULL)
      return;

    QRect  rect  = widget->inputMethodQuery(Qt::ImCursorRectangle).toRect();
    QPoint point = widget->mapToGlobal (QPoint (0, 0));
    rect.translate (point);

    if (m_cursor_area.x      != rect.x ()     ||
        m_cursor_area.y      != rect.y ()     ||
        m_cursor_area.width  != rect.width () ||
        m_cursor_area.height != rect.height ())
    {
      m_cursor_area.x      = rect.x ();
      m_cursor_area.y      = rect.y ();
      m_cursor_area.width  = rect.width ();
      m_cursor_area.height = rect.height ();

#ifndef USE_DLFCN
      nimf_im_set_cursor_location (m_im, &m_cursor_area);
#else
      nimf_api->im_set_cursor_location (m_im, &m_cursor_area);
#endif
    }
  }
}

void
NimfInputContext::invokeAction(QInputMethod::Action, int cursorPosition)
{
#ifndef USE_DLFCN
  g_debug (G_STRLOC ": %s", G_STRFUNC);
#else
  //gtk_api->g_log(G_LOG_DOMAIN, G_LOG_LEVEL_DEBUG, G_STRLOC ": %s", G_STRFUNC);
#endif
}

bool
NimfInputContext::filterEvent (const QEvent *event)
{
#ifndef USE_DLFCN
  g_debug (G_STRLOC ": %s", G_STRFUNC);
#else
  //gtk_api->g_log(G_LOG_DOMAIN, G_LOG_LEVEL_DEBUG, G_STRLOC ": %s", G_STRFUNC);
#endif

  if (G_UNLIKELY (!qApp->focusObject() || !inputMethodAccepted()))
    return false;

  gboolean         retval;
  const QKeyEvent *key_event = static_cast<const QKeyEvent *>( event );
  NimfEvent       *nimf_event;
  NimfEventType    type = NIMF_EVENT_NOTHING;

  switch (event->type ())
  {
#undef KeyPress
    case QEvent::KeyPress:
      type = NIMF_EVENT_KEY_PRESS;
      break;
#undef KeyRelease
    case QEvent::KeyRelease:
      type = NIMF_EVENT_KEY_RELEASE;
      break;
    default:
      return false;
  }

#ifndef USE_DLFCN
  nimf_event = nimf_event_new (type);
#else
  nimf_event = nimf_api->event_new (type);
#endif

  nimf_event->key.state            = key_event->nativeModifiers  ();
  nimf_event->key.keyval           = key_event->nativeVirtualKey ();
  nimf_event->key.hardware_keycode = key_event->nativeScanCode   (); /* FIXME: guint16 quint32 */

#ifndef USE_DLFCN
  retval = nimf_im_filter_event (m_im, nimf_event);
#else
  retval = nimf_api->im_filter_event (m_im, nimf_event);
#endif

#ifndef USE_DLFCN
  nimf_event_free (nimf_event);
#else
  nimf_api->event_free (nimf_event);
#endif

  return retval;
}

QRectF
NimfInputContext::keyboardRect() const
{
#ifndef USE_DLFCN
  g_debug (G_STRLOC ": %s", G_STRFUNC);
#else
  //gtk_api->g_log(G_LOG_DOMAIN, G_LOG_LEVEL_DEBUG, G_STRLOC ": %s", G_STRFUNC);
#endif
  return QRectF ();
}

bool
NimfInputContext::isAnimating() const
{
#ifndef USE_DLFCN
  g_debug (G_STRLOC ": %s", G_STRFUNC);
#else
  //gtk_api->g_log(G_LOG_DOMAIN, G_LOG_LEVEL_DEBUG, G_STRLOC ": %s", G_STRFUNC);
#endif
  return false;
}

void
NimfInputContext::showInputPanel()
{
#ifndef USE_DLFCN
  g_debug (G_STRLOC ": %s", G_STRFUNC);
#else
  //gtk_api->g_log(G_LOG_DOMAIN, G_LOG_LEVEL_DEBUG, G_STRLOC ": %s", G_STRFUNC);
#endif
}

void
NimfInputContext::hideInputPanel()
{
#ifndef USE_DLFCN
  g_debug (G_STRLOC ": %s", G_STRFUNC);
#else
  //gtk_api->g_log(G_LOG_DOMAIN, G_LOG_LEVEL_DEBUG, G_STRLOC ": %s", G_STRFUNC);
#endif
}

bool
NimfInputContext::isInputPanelVisible() const
{
#ifndef USE_DLFCN
  g_debug (G_STRLOC ": %s", G_STRFUNC);
#else
  //gtk_api->g_log(G_LOG_DOMAIN, G_LOG_LEVEL_DEBUG, G_STRLOC ": %s", G_STRFUNC);
#endif
  return false;
}

QLocale
NimfInputContext::locale() const
{
#ifndef USE_DLFCN
  g_debug (G_STRLOC ": %s", G_STRFUNC);
#else
  //gtk_api->g_log(G_LOG_DOMAIN, G_LOG_LEVEL_DEBUG, G_STRLOC ": %s", G_STRFUNC);
#endif
  return QLocale ();
}

Qt::LayoutDirection
NimfInputContext::inputDirection() const
{
#ifndef USE_DLFCN
  g_debug (G_STRLOC ": %s", G_STRFUNC);
#else
  //gtk_api->g_log(G_LOG_DOMAIN, G_LOG_LEVEL_DEBUG, G_STRLOC ": %s", G_STRFUNC);
#endif
  return Qt::LayoutDirection ();
}

void
NimfInputContext::setFocusObject (QObject *object)
{
#ifndef USE_DLFCN
  g_debug (G_STRLOC ": %s", G_STRFUNC);
#else
  //gtk_api->g_log(G_LOG_DOMAIN, G_LOG_LEVEL_DEBUG, G_STRLOC ": %s", G_STRFUNC);
#endif

  if (!object || !inputMethodAccepted())
#ifndef USE_DLFCN
    nimf_im_focus_out (m_im);
#else
    nimf_api->im_focus_out (m_im);
#endif

  QPlatformInputContext::setFocusObject (object);

  if (object && inputMethodAccepted())
#ifndef USE_DLFCN
    nimf_im_focus_in (m_im);
#else
    nimf_api->im_focus_in (m_im);
#endif

  update (Qt::ImCursorRectangle);
}

/*
 * class NimfInputContextPlugin
 */
class NimfInputContextPlugin : public QPlatformInputContextPlugin
{
  Q_OBJECT
  Q_PLUGIN_METADATA(IID
    QPlatformInputContextFactoryInterface_iid
    FILE "./nimf.json")

public:
  NimfInputContextPlugin ()
  {
#ifdef USE_DLFCN
    libnimf = dlopen ("libnimf.so.0", RTLD_LAZY);

    if (libnimf)
    {
      nimf_api = new NimfAPI;
      nimf_api->im_new                 = reinterpret_cast<NimfIM* (*)()> (dlsym (libnimf, "nimf_im_new"));
      nimf_api->im_focus_in            = reinterpret_cast<void (*)(NimfIM *)> (dlsym (libnimf, "nimf_im_focus_in"));
      nimf_api->im_focus_out           = reinterpret_cast<void (*)(NimfIM *)> (dlsym (libnimf, "nimf_im_focus_out"));
      nimf_api->im_reset               = reinterpret_cast<void (*)(NimfIM *)> (dlsym (libnimf, "nimf_im_reset"));
      nimf_api->im_filter_event        = reinterpret_cast<gboolean (*)(NimfIM *, NimfEvent *)> (dlsym (libnimf, "nimf_im_filter_event"));
      nimf_api->im_get_preedit_string  = reinterpret_cast<void (*)(NimfIM *, gchar **, NimfPreeditAttr ***, gint *)> (dlsym (libnimf, "nimf_im_get_preedit_string"));
      nimf_api->im_set_cursor_location = reinterpret_cast<void (*)(NimfIM *, const NimfRectangle *)> (dlsym (libnimf, "nimf_im_set_cursor_location"));
      nimf_api->im_set_use_preedit     = reinterpret_cast<void (*)(NimfIM *, gboolean)> (dlsym (libnimf, "nimf_im_set_use_preedit"));
      nimf_api->im_get_surrounding     = reinterpret_cast<gboolean (*)(NimfIM *, gchar **, gint *)> (dlsym (libnimf, "nimf_im_get_surrounding"));
      nimf_api->im_set_surrounding     = reinterpret_cast<void (*)(NimfIM *, const char *, gint, gint)> (dlsym (libnimf, "nimf_im_set_surrounding"));
      nimf_api->event_new              = reinterpret_cast<NimfEvent * (*) (NimfEventType)> (dlsym (libnimf, "nimf_event_new"));
      nimf_api->event_free             = reinterpret_cast<void (*) (NimfEvent *)> (dlsym (libnimf, "nimf_event_free"));
      nimf_api->preedit_attr_freev     = reinterpret_cast<void (*) (NimfPreeditAttr **)> (dlsym (libnimf, "nimf_preedit_attr_freev"));
    }

    libgtk = dlopen ("libgtk-3.so.0", RTLD_LAZY);

    if (libgtk)
    {
      gtk_api = new GtkAPI;

      gtk_api->g_settings_get_boolean = reinterpret_cast<gboolean (*) (GSettings *, gchar *)> (dlsym (libgtk, "g_settings_get_boolean"));
      gtk_api->g_settings_new = reinterpret_cast<GSettings* (*) (const gchar *)> (dlsym (libgtk, "g_settings_new"));
      gtk_api->g_signal_connect_data = reinterpret_cast<gulong (*) (gpointer, const gchar *, GCallback, gpointer, GClosureNotify, GConnectFlags)> (dlsym (libgtk, "g_signal_connect_data"));
      gtk_api->g_signal_emit_by_name = reinterpret_cast<void (*) (gpointer, const gchar *, ...)> (dlsym (libgtk, "g_signal_emit_by_name"));
      gtk_api->g_object_unref = reinterpret_cast<void (*) (gpointer)> (dlsym (libgtk, "g_object_unref"));
      // gtk_api->g_log = reinterpret_cast<void (*) (const gchar *, GLogLevelFlags, const gchar *, ...)> (dlsym (libgtk, "g_log"));
    }
#endif

#ifndef USE_DLFCN
  g_debug (G_STRLOC ": %s", G_STRFUNC);
#else
  //gtk_api->g_log(G_LOG_DOMAIN, G_LOG_LEVEL_DEBUG, G_STRLOC ": %s", G_STRFUNC);
#endif
  }

  ~NimfInputContextPlugin ()
  {
#ifndef USE_DLFCN
  g_debug (G_STRLOC ": %s", G_STRFUNC);
#else
  //gtk_api->g_log(G_LOG_DOMAIN, G_LOG_LEVEL_DEBUG, G_STRLOC ": %s", G_STRFUNC);
#endif

#ifdef USE_DLFCN
    if (nimf_api)
    {
      delete nimf_api;
      nimf_api = NULL;
    }

    if (libnimf)
    {
      dlclose (libnimf);
      libnimf = NULL;
    }

    if (gtk_api)
    {
      delete gtk_api;
      gtk_api = NULL;
    }

    if (libgtk)
    {
      dlclose (libgtk);
      libgtk = NULL;
    }
#endif
  }

  virtual QStringList keys () const
  {
#ifndef USE_DLFCN
    g_debug (G_STRLOC ": %s", G_STRFUNC);
#else
    //gtk_api->g_log(G_LOG_DOMAIN, G_LOG_LEVEL_DEBUG, G_STRLOC ": %s", G_STRFUNC);
#endif

    return QStringList () <<  "nimf";
  }

  virtual QPlatformInputContext *create (const QString     &key,
                                         const QStringList &paramList)
  {
#ifndef USE_DLFCN
    g_debug (G_STRLOC ": %s", G_STRFUNC);
#else
    //gtk_api->g_log(G_LOG_DOMAIN, G_LOG_LEVEL_DEBUG, G_STRLOC ": %s", G_STRFUNC);
#endif

    return new NimfInputContext ();
  }
};

#include "im-nimf-qt5.moc"

@ghost
Copy link
Author

ghost commented Oct 28, 2018

g_signal_connect, g_debug 는 glib 에 있는 함수입니다. 라이브러리 이름이 glib 입니다.

그리고 g_debug 는 매크로 함수이고 qDebug 로 대체할 수 있습니다.

g_signal_connect 는 함수 포인터로 대체할 수 있습니다. Qt 에 있는 signal, slot 으로 재작성하는 것이 바람직한 것 같은데, 코드가 조금 더 많아지므로 C언어 자체 기능인 함수 포인터로 대체하는 것이 좋을 것 같습니다. g_signal_connect 가 그 일을 하는 함수입니다.

@ghost
Copy link
Author

ghost commented Oct 28, 2018

빠르면 다음달 11월, 늦으면 내년 2월 작업 예정입니다.

@5HARK
Copy link
Owner

5HARK commented Oct 29, 2018

Nimf 프로젝트에 반영은 @cogniti 님이 직접 수정해서 하신다는 거죠?

저는 저 나름대로 말씀해주신 부분들까지 수정해서 tdesktop 에 일단 PR 제출해도 될까요?

@ghost
Copy link
Author

ghost commented Oct 29, 2018

PR 제출 보류해 주세요. 지금 제출하면 또 수정해야 합니다.

@5HARK
Copy link
Owner

5HARK commented Oct 29, 2018

일단 제가 직접 gtk 의존성 제거하고 g_debug 함수 호출부분만 주석처리한 상태의 im_nimf_qt5.cpp telegram에 합쳐서 빌드해서 테스트 해봤는데 잘 됬습니다.

  1. 님프가 설치 되어 있을때
  2. 님프가 설치되어 있지 않을때

두가지 전부 이상없이 텔레그램에서 한글입력 잘 됬습니다. 그리고 g_settings_new 함수에서 없는 스키마 파일 열려고 할때 프로그램이 종료되는 부분도

  GSettingsSchemaSource *schema_source =  glib_api->g_settings_schema_source_get_default();
  GSettingsSchema *schema = glib_api->g_settings_schema_source_lookup(schema_source, "org.nimf.clients.qt5", 0);
  if(schema == NULL){
    printf("schema is NULL \n");
  }else{
    glib_api->g_settings_new("org.nimf.clients.qt5");
  }

대강 이런 형태로 스키마 파일이 없을때 gracefully 하게 종료하도록 수정할 예정입니다.

아 그리고 g_signal_connect 는 libgtk-3.so 안에 있더라구요. 그래서 libglib-2.0.so 랑 연관되는 함수들은 g_log 밖에 없었습니다. 말씀하신대로 Qt 의 디버그 출력 함수로 대체하면 될 것 같구요.

root@1553429c4ef8:/# readelf -Ws /usr/lib/x86_64-linux-gnu/libglib-2.0.so | grep g_signal_connect
root@1553429c4ef8:/# readelf -Ws /usr/lib/x86_64-linux-gnu/libgtk-3.so | grep g_signal_connect
   268: 0000000000000000     0 FUNC    GLOBAL DEFAULT  UND g_signal_connect_closure
   865: 0000000000000000     0 FUNC    GLOBAL DEFAULT  UND g_signal_connect_closure_by_id
   996: 0000000000000000     0 FUNC    GLOBAL DEFAULT  UND g_signal_connect_data
  2160: 0000000000000000     0 FUNC    GLOBAL DEFAULT  UND g_signal_connect_object

@ghost
Copy link
Author

ghost commented Oct 29, 2018

g_signal_connect 는 glib 에서 제공하는 함수입니다. gtk 가 glib 를 사용합니다.
https://developer.gnome.org/gobject/stable/gobject-Signals.html

nimf qt5 모듈에 버그가 있는 것 같습니다.
https://gitlab.com/nimf-i18n/nimf/issues/144

@5HARK
Copy link
Owner

5HARK commented Nov 14, 2018

아하 그렇군요. 말씀하신대로 일단 작업하시는거 기다리겠습니다.

@ghost
Copy link
Author

ghost commented Nov 14, 2018

사실 제가 컴퓨터가 없어서 오늘에서야 컴퓨터를 조립하여 개발 환경을 준비 중입니다. 기다리시는게 지루하시다는거 알고 있습니다. 제가 최선을 다해 준비 중이니 조금 더 기다려 주시면 고맙겠습니다. 텔레그램을 위한 qt5 업데이트는 하루 이틀 내로는 안되고 우선 순위가 높은 이슈부터 처리한 후에 업데이트 하겠습니다.
기다리시는 김에 조금 더 기다려주시기 바랍니다. 아마 12월까지는 될 것 같습니다.
이 이슈는 개인적으로 매우 흥미롭습니다.
감사합니다.

@ghost
Copy link
Author

ghost commented Nov 19, 2018

방금 업데이트했습니다.
2018.11.20 에서 실수가 있어서
2018.11.20.1 버전 릴리즈했습니다.
glib-2.0, gtk+-2.0 링킹 모두 삭제하고 테스트해보세요.
dlopen 매뉴얼에

   External references in the shared object are resolved using the  shared
   objects  in  that object's dependency list and any other objects previ‐
   ously opened with the RTLD_GLOBAL flag.  If the executable  was  linked
   with  the flag "-rdynamic" (or, synonymously, "--export-dynamic"), then
   the global symbols in the executable will also be used to resolve  ref‐
   erences in a dynamically loaded shared object.

이런 내용이 있습니다. libnimf 가 glib, gobject, gio 를 링킹하기 때문에, libnimf 하나만 dlopen 하면 될 것 같아 그렇게 작업했습니다. 테스트 해보시고 고쳐야 되는 부분이 있는지 알려주세요.

@ghost
Copy link
Author

ghost commented Nov 19, 2018

schema == NULL 일 때 isValid 함수의 반환값이 false 가 되도록 해야 하는데 깜박 했네요.

@ghost
Copy link
Author

ghost commented Nov 21, 2018

단순히 m_im 을 검사함으로써 해결했습니다.
2018.11.21 이상 버전으로 테스트하시면 되겠습니다.
감사합니다.

diff --git a/modules/clients/qt5/im-nimf-qt5.cpp b/modules/clients/qt5/im-nimf-qt5.cpp
index 9b19b7b..0d1cfbb 100644
--- a/modules/clients/qt5/im-nimf-qt5.cpp
+++ b/modules/clients/qt5/im-nimf-qt5.cpp
@@ -475,6 +475,9 @@ NimfInputContext::isValid () const
   g_debug (G_STRLOC ": %s", G_STRFUNC);
 #endif
 
+  if (m_im == NULL)
+    return false;
+
 #ifdef USE_DLFCN
   if (nimf_api == NULL)
     return false;

@5HARK
Copy link
Owner

5HARK commented Nov 24, 2018

넵 말씀하신 버전으로 근시일내에 조속히 테스트 해보겠습니다.
고생많으셨습니다!

@ghost
Copy link
Author

ghost commented Nov 25, 2018

생각해보니까 glib api, gio api 등으로 나누는게 안전하겠네요. 조만간 또 업데이트 하겠습니다.

@ghost
Copy link
Author

ghost commented Nov 26, 2018

업데이트 했습니다. 2018.11.26 버전으로 테스트하시면 되겠습니다.

@5HARK
Copy link
Owner

5HARK commented Nov 27, 2018

네 테스트 해보겠습니다. 혹시 g_debug 매크로에서 문제가 발생할 여지는 없을까요? 저 매크로가 실제 어떤 함수로 호출되는지는 헤더파일에 나와있고 환경에 따라 실제 함수가 호출될 수도 있을때 해당 함수가 동적 로딩되어 준비되있지 않으면 문제가 발생할 수도 있지 않나요?

@5HARK
Copy link
Owner

5HARK commented Nov 27, 2018

아 매크로로 처리해두셨군요. 잘못봤습니다. 바로 테스트 해보겠습니다.
감사합니다.

@ghost
Copy link
Author

ghost commented Nov 27, 2018

argument 가 잘못된 것을 방금 발견하여 업데이트했습니다.

Fixed wrong arguments
https://gitlab.com/nimf-i18n/nimf/commit/bb9948437494173a718108388d162b07d6b9c125

참고 바랍니다. 감사합니다.

@5HARK
Copy link
Owner

5HARK commented Nov 27, 2018

일단 빌드해서 테스트 진행 하였는데요. 한글입력이 되지 않고 있습니다.

Nimf 2018.08.03 버전 및 Ubuntu 18.04 환경에서 테스트 했습니다.

@5HARK
Copy link
Owner

5HARK commented Nov 27, 2018

빌드된 Telegram 바이너리 내에 nimf 관련 함수들이 포함되어 있는것도 확인 하였습니다.

TBuild/pull_request [ nm -an Telegram | c++filt | grep nimf                                             ] 2:55 오후
0000000000000000 a im-nimf-qt5.cpp
0000000000000000 a nimf-client.c
0000000000000000 a nimf-enum-types.c
0000000000000000 a nimf-events.c
0000000000000000 a nimf-im.c
0000000000000000 a nimf-marshalers.c
0000000000000000 a nimf-message.c
0000000000000000 a nimf-private.c
0000000000000000 a nimf-types.c
0000000001629190 t nimf_event_free
00000000016291e0 t nimf_event_keycode_to_qwerty_keyval
0000000001629470 t nimf_event_matches
00000000016294f0 t nimf_event_new
0000000001629520 t nimf_event_copy
0000000001629580 t nimf_event_get_type
00000000016295f0 t nimf_im_init
0000000001629640 t nimf_im_class_intern_init
0000000001629860 t nimf_im_get_type
00000000016298f0 t nimf_im_finalize
0000000001629960 t nimf_im_focus_out
0000000001629a40 t nimf_im_set_cursor_location
0000000001629b30 t nimf_im_set_use_preedit
0000000001629c30 t nimf_im_get_surrounding
0000000001629df0 t nimf_im_set_surrounding
0000000001629f40 t nimf_im_focus_in
000000000162a020 t nimf_im_get_preedit_string
000000000162a0e0 t nimf_im_reset
000000000162a1c0 t nimf_im_filter_event
000000000162a2f0 t nimf_im_new
000000000162a330 t nimf_cclosure_marshal_VOID__STRING_STRING
000000000162a3c0 t nimf_cclosure_marshal_BOOLEAN(int13_t &&) volatile
000000000162a470 t nimf_cclosure_marshal_BOOLEAN__INT_INT
000000000162a530 t nimf_send_message
000000000162a740 t nimf_recv_message
000000000162a940 t nimf_log_default_handler
000000000162aa30 t nimf_result_iteration_until
000000000162aae0 t nimf_error_quark
000000000162ab10 t nimf_key_new
000000000162ab40 t nimf_key_new_from_nicks
000000000162ac50 t nimf_key_newv
000000000162acf0 t nimf_key_free
000000000162ad40 t nimf_key_freev
000000000162adb0 t nimf_preedit_attr_new
000000000162adf0 t nimf_preedit_attrs_copy
000000000162aec0 t nimf_preedit_attr_free
000000000162aef0 t nimf_preedit_attr_freev
000000000162af60 t nimf_client_create_context
000000000162afd0 t nimf_client_class_intern_init
000000000162b030 t nimf_client_get_type
000000000162b650 t nimf_client_is_connected
000000000162b690 t nimf_client_connect
000000000162b9e0 t nimf_client_init
000000000162bc40 t nimf_client_finalize
000000000162bde0 t nimf_key_sym_get_type
000000000162be50 t nimf_message_type_get_type
000000000162bec0 t nimf_error_get_type
000000000162bf30 t nimf_modifier_type_get_type
000000000162bfa0 t nimf_preedit_state_get_type
000000000162c010 t nimf_preedit_attr_type_get_type
000000000162c080 t nimf_message_new_full
000000000162c110 t nimf_message_new
000000000162c150 t nimf_message_ref
000000000162c1a0 t nimf_message_unref
000000000162c200 t nimf_message_get_header
000000000162c230 t nimf_message_get_header_size
000000000162c260 t nimf_message_set_body
000000000162c2b0 t nimf_message_get_body
000000000162c2e0 t nimf_message_get_body_size
000000000162c310 t nimf_message_get_name
000000000162c380 t nimf_message_get_name_by_type
00000000061bdaf8 b nimf_im_parent_class
00000000061bdb08 b nimf_client_socket
00000000061bdb10 b nimf_client_result
00000000061bdb18 b nimf_client_context
00000000061bdb38 b nimf_client_parent_class
00000000061bdb40 b nimf_client_table
00000000061bdb48 b nimf_client_default_source
00000000061bdb50 b nimf_client_socket_source
0000000001627da0 t NimfEventHandler::qt_static_metacall(QObject*, QMetaObject::Call, int, void**)
0000000001627db0 t qt_plugin_query_metadata_QNimfPlatformInputContextPlugin()
0000000001627dc0 t NimfEventHandler::eventFilter(QObject*, QEvent*)
0000000001627e10 t QNimfPlatformInputContext::on_preedit_start(_NimfIM*, void*)
0000000001627e30 t QNimfPlatformInputContext::on_preedit_end(_NimfIM*, void*)
0000000001627e50 t QNimfPlatformInputContext::on_retrieve_surrounding(_NimfIM*, void*)
0000000001627e80 t QNimfPlatformInputContext::on_delete_surrounding(_NimfIM*, int, int, void*)
0000000001627eb0 t QNimfPlatformInputContext::isValid() const
0000000001627ee0 t QNimfPlatformInputContext::reset()
0000000001627f10 t QNimfPlatformInputContext::commit()
0000000001627f40 t QNimfPlatformInputContext::invokeAction(QInputMethod::Action, int)
0000000001627f60 t QNimfPlatformInputContext::isAnimating() const
0000000001627f90 t QNimfPlatformInputContext::showInputPanel()
0000000001627fb0 t QNimfPlatformInputContext::hideInputPanel()
0000000001627fd0 t QNimfPlatformInputContext::isInputPanelVisible() const
0000000001628000 t QNimfPlatformInputContext::inputDirection() const
0000000001628030 t QNimfPlatformInputContext::keyboardRect() const
0000000001628080 t QNimfPlatformInputContext::on_beep(_NimfIM*, void*)
00000000016280b0 t QNimfPlatformInputContext::filterEvent(QEvent const*)
0000000001628160 t QNimfPlatformInputContext::locale() const
0000000001628190 t NimfEventHandler::metaObject() const
00000000016281b0 t QNimfPlatformInputContext::metaObject() const
00000000016281d0 t QNimfPlatformInputContextPlugin::metaObject() const
00000000016281f0 t qt_plugin_instance_QNimfPlatformInputContextPlugin()
0000000001628370 t QNimfPlatformInputContext::update(QFlags<Qt::InputMethodQuery>)
0000000001628520 t QNimfPlatformInputContext::qt_static_metacall(QObject*, QMetaObject::Call, int, void**)
0000000001628530 t QNimfPlatformInputContextPlugin::qt_static_metacall(QObject*, QMetaObject::Call, int, void**)
0000000001628540 t QNimfPlatformInputContext::~QNimfPlatformInputContext()
0000000001628540 t QNimfPlatformInputContext::~QNimfPlatformInputContext()
00000000016285e0 t QNimfPlatformInputContext::~QNimfPlatformInputContext()
0000000001628600 t QNimfPlatformInputContext::on_changed_reset_on_mouse_button_press(_GSettings*, char*, void*)
00000000016287a0 t QNimfPlatformInputContext::QNimfPlatformInputContext()
00000000016287a0 t QNimfPlatformInputContext::QNimfPlatformInputContext()
0000000001628910 t qt_static_plugin_QNimfPlatformInputContextPlugin()
0000000001628920 t QNimfPlatformInputContext::on_preedit_changed(_NimfIM*, void*)
0000000001628c90 t QNimfPlatformInputContext::on_commit(_NimfIM*, char const*, void*)
0000000001628d80 t QNimfPlatformInputContext::setFocusObject(QObject*)
0000000001628e20 t NimfEventHandler::qt_metacast(char const*)
0000000001628e70 t NimfEventHandler::qt_metacall(QMetaObject::Call, int, void**)
0000000001628e80 t QNimfPlatformInputContext::qt_metacast(char const*)
0000000001628ed0 t QNimfPlatformInputContext::qt_metacall(QMetaObject::Call, int, void**)
0000000001628ee0 t QNimfPlatformInputContextPlugin::qt_metacast(char const*)
0000000001628f30 t QNimfPlatformInputContextPlugin::qt_metacall(QMetaObject::Call, int, void**)
0000000001628f40 t NimfEventHandler::~NimfEventHandler()
0000000001628f40 t NimfEventHandler::~NimfEventHandler()
0000000001628f50 t NimfEventHandler::~NimfEventHandler()
0000000001628f80 t QNimfPlatformInputContextPlugin::~QNimfPlatformInputContextPlugin()
0000000001628f80 t QNimfPlatformInputContextPlugin::~QNimfPlatformInputContextPlugin()
0000000001628fc0 t QNimfPlatformInputContextPlugin::~QNimfPlatformInputContextPlugin()
0000000001629000 t QNimfPlatformInputContextPlugin::create(QString const&, QStringList const&)
0000000001629040 t QNimfPlatformInputContextPlugin::keys() const
0000000003b53d20 r QNimfPlatformInputContextPlugin::~QNimfPlatformInputContextPlugin()::__PRETTY_FUNCTION__
0000000003b53d80 r QNimfPlatformInputContextPlugin::create(QString const&, QStringList const&)::__PRETTY_FUNCTION__
0000000003b53e00 r QNimfPlatformInputContextPlugin::keys() const::__PRETTY_FUNCTION__
0000000003b53e60 r QNimfPlatformInputContextPlugin::QNimfPlatformInputContextPlugin()::__PRETTY_FUNCTION__
0000000003b53ec0 r QNimfPlatformInputContext::setFocusObject(QObject*)::__PRETTY_FUNCTION__
0000000003b53f20 r QNimfPlatformInputContext::inputDirection() const::__PRETTY_FUNCTION__
0000000003b53f80 r QNimfPlatformInputContext::locale() const::__PRETTY_FUNCTION__
0000000003b53fc0 r QNimfPlatformInputContext::isInputPanelVisible() const::__PRETTY_FUNCTION__
0000000003b54020 r QNimfPlatformInputContext::hideInputPanel()::__PRETTY_FUNCTION__
0000000003b54060 r QNimfPlatformInputContext::showInputPanel()::__PRETTY_FUNCTION__
0000000003b540a0 r QNimfPlatformInputContext::isAnimating() const::__PRETTY_FUNCTION__
0000000003b540e0 r QNimfPlatformInputContext::keyboardRect() const::__PRETTY_FUNCTION__
0000000003b54120 r QNimfPlatformInputContext::filterEvent(QEvent const*)::__PRETTY_FUNCTION__
0000000003b54180 r QNimfPlatformInputContext::invokeAction(QInputMethod::Action, int)::__PRETTY_FUNCTION__
0000000003b541e0 r QNimfPlatformInputContext::update(QFlags<Qt::InputMethodQuery>)::__PRETTY_FUNCTION__
0000000003b54240 r QNimfPlatformInputContext::commit()::__PRETTY_FUNCTION__
0000000003b54280 r QNimfPlatformInputContext::reset()::__PRETTY_FUNCTION__
0000000003b542c0 r QNimfPlatformInputContext::isValid() const::__PRETTY_FUNCTION__
0000000003b54300 r QNimfPlatformInputContext::~QNimfPlatformInputContext()::__PRETTY_FUNCTION__
0000000003b54340 r QNimfPlatformInputContext::QNimfPlatformInputContext()::__PRETTY_FUNCTION__
0000000003b54380 r QNimfPlatformInputContext::on_changed_reset_on_mouse_button_press(_GSettings*, char*, void*)::__PRETTY_FUNCTION__
0000000003b54400 r QNimfPlatformInputContext::on_beep(_NimfIM*, void*)::__PRETTY_FUNCTION__
0000000003b54460 r QNimfPlatformInputContext::on_delete_surrounding(_NimfIM*, int, int, void*)::__PRETTY_FUNCTION__
0000000003b544c0 r QNimfPlatformInputContext::on_retrieve_surrounding(_NimfIM*, void*)::__PRETTY_FUNCTION__
0000000003b54520 r QNimfPlatformInputContext::on_commit(_NimfIM*, char const*, void*)::__PRETTY_FUNCTION__
0000000003b54580 r QNimfPlatformInputContext::on_preedit_changed(_NimfIM*, void*)::__PRETTY_FUNCTION__
0000000003b545e0 r QNimfPlatformInputContext::on_preedit_end(_NimfIM*, void*)::__PRETTY_FUNCTION__
0000000003b54640 r QNimfPlatformInputContext::on_preedit_start(_NimfIM*, void*)::__PRETTY_FUNCTION__
0000000003b546a0 r qt_meta_data_QNimfPlatformInputContextPlugin
0000000003b546e0 r qt_meta_stringdata_QNimfPlatformInputContextPlugin
0000000003b54720 r qt_meta_data_QNimfPlatformInputContext
0000000003b54760 r qt_meta_stringdata_QNimfPlatformInputContext
0000000003b547a0 r qt_meta_data_NimfEventHandler
0000000003b547e0 r qt_meta_stringdata_NimfEventHandler
0000000003b54810 r typeinfo name for NimfEventHandler
0000000003b54830 r typeinfo name for QNimfPlatformInputContext
0000000003b54860 r typeinfo name for QNimfPlatformInputContextPlugin
000000000611f230 d typeinfo for NimfEventHandler
000000000611f248 d typeinfo for QNimfPlatformInputContext
000000000611f260 d typeinfo for QNimfPlatformInputContextPlugin
000000000611f278 d vtable for NimfEventHandler
000000000611f2e8 d vtable for QNimfPlatformInputContext
000000000611f3d0 d vtable for QNimfPlatformInputContextPlugin
000000000611f460 d QNimfPlatformInputContextPlugin::staticMetaObject
000000000611f4a0 d QNimfPlatformInputContext::staticMetaObject
000000000611f4e0 d NimfEventHandler::staticMetaObject
00000000061bdac0 b guard variable for qt_plugin_instance_QNimfPlatformInputContextPlugin()::_instance
00000000061bdad0 b qt_plugin_instance_QNimfPlatformInputContextPlugin()::_instance
00000000061bdaf0 b NimfIM_private_offset
00000000061bdb30 b NimfClient_private_offset

@5HARK
Copy link
Owner

5HARK commented Nov 27, 2018

이런 오류가 나고 있습니다.

TBuild/pull_request [ ./Telegram                                                                        ] 3:00 오후

** (process:12793): CRITICAL **: 15:00:23.457: include/nimf-client.c:302: nimf_client_connect: Socket file is not found

** (Telegram:12793): CRITICAL **: 15:00:24.806: nimf_im_focus_out: assertion 'nimf_client_is_connected ()' failed

** (Telegram:12793): CRITICAL **: 15:00:24.807: nimf_im_set_cursor_location: assertion 'nimf_client_is_connected ()' failed

** (Telegram:12793): CRITICAL **: 15:00:24.807: nimf_im_focus_out: assertion 'nimf_client_is_connected ()' failed

** (Telegram:12793): CRITICAL **: 15:00:28.522: nimf_im_focus_out: assertion 'nimf_client_is_connected ()' failed

@ghost
Copy link
Author

ghost commented Nov 27, 2018

최신 커밋으로 작업해보세요.
그리고 소켓 파일이 없다고 나오는데, nimf 가 실행 중인지 확인해보세요.
소켓 파일은 nimf 가 실행되면서 /run/user/1000/nimf/lock/run/user/1000/nimf/socket를 생성합니다.
nimf 가 종료되면서 파일이 삭제됩니다.

@5HARK
Copy link
Owner

5HARK commented Nov 27, 2018

테스트 환경의 nimf가 구버전이라 그러는 것인가요. 일단 확인해보겠습니다.

@5HARK
Copy link
Owner

5HARK commented Nov 27, 2018

테스트 환경에서 소켓파일 등은 존재하는걸로 확인됬습니다.
아마 구버전이라 그런가 봅니다. 테스트 환경의 nimf 를 업데이트후 확인해 보겠습니다.

test@test-virtual-machine:~/바탕화면$ ls /run/user/1000/nimf
lock  socket
test@test-virtual-machine:~/바탕화면$ ls /run/user/1000/nimf/lock
/run/user/1000/nimf/lock
test@test-virtual-machine:~/바탕화면$ ls /run/user/1000/nimf/socket
/run/user/1000/nimf/socket
test@test-virtual-machine:~/바탕화면$ 

@ghost
Copy link
Author

ghost commented Nov 27, 2018

구버전이라 그런 것 같지는 않습니다만, nimf 가 실행 중이 아니거나, nimf 를 데몬화하고 indicator 를 실행시키는 로직에 버그가 있을 수 있습니다. 일단 최신 버전으로 업데이트를 하시는 것을 권장합니다.

@5HARK
Copy link
Owner

5HARK commented Nov 27, 2018

테스트 환경 말고 원래 제가 사용하던 시스템에서도 안되는걸 확인했습니다. 시스템의 님프 버전도 구버전입니다.

@ghost
Copy link
Author

ghost commented Nov 27, 2018

0000000003b53d80 r QNimfPlatformInputContextPlugin::create(QString const&, QStringList const&)::__PRETTY_FUNCTION__`
0000000003b54340 r QNimfPlatformInputContext::QNimfPlatformInputContext()::__PRETTY_FUNCTION__

위에 주신 메시지를 보면 QNimfPlatformInputContextPlugin, QNimfPlatformInputContext, __PRETTY_FUNCTION__이 보입니다.
테스트하신 파일이
https://github.com/5HARK/im-nimf-qt5/blob/83d8e4d852a01e9e6f41e4c3f9d86d042bd8b5e6/im-nimf-qt5.cpp
파일과 다른 파일 같습니다.
또한 https://gitlab.com/nimf-i18n/nimf/blob/master/modules/clients/qt5/im-nimf-qt5.cpp
파일과 다른 것 같습니다.
테스트하신 파일이 최신 커밋의 파일인지 확인해 보시고 만약 아니라면
https://gitlab.com/nimf-i18n/nimf/blob/master/modules/clients/qt5/im-nimf-qt5.cpp 이 파일로 다시 해보시기 바랍니다.

@5HARK
Copy link
Owner

5HARK commented Nov 27, 2018

링크해주신 소스파일을 직접 다운로드 받아서 제가 컴파일했던 텔레그램에 들어있던 im-nimf-qt5.cpp 와 diff 비교해봤는데 아무런 차이점이 없었습니다. 또한 님프를 최신버전으로 업데이트 했는데도 소켓파일을 찾을수 없다고 나오고 있습니다. 님프를 이용한 한글 입력에는 문제가 없지만 텔래그램이 켜지지 않고 텔레그램에서의 한글입력도 문제가 있습니다.

일단 혹시 모르니깐 저는 다시 빌드해보겠습니다.

@5HARK
Copy link
Owner

5HARK commented Nov 27, 2018

TBuild/pull_request [ ./Telegram                                                                        ] 6:08 오후

** (process:13715): CRITICAL **: 18:08:57.086: include/nimf-client.c:302: nimf_client_connect: Socket file is not found

** (Telegram:13715): CRITICAL **: 18:08:57.998: nimf_im_focus_out: assertion 'nimf_client_is_connected ()' failed

** (Telegram:13715): CRITICAL **: 18:08:57.999: nimf_im_set_cursor_location: assertion 'nimf_client_is_connected ()' failed

** (Telegram:13715): CRITICAL **: 18:08:57.999: nimf_im_focus_out: assertion 'nimf_client_is_connected ()' failed

** (Telegram:13715): CRITICAL **: 18:09:00.266: nimf_im_focus_in: assertion 'nimf_client_is_connected ()' failed

** (Telegram:13715): CRITICAL **: 18:09:00.266: nimf_im_set_cursor_location: assertion 'nimf_client_is_connected ()' failed

** (Telegram:13715): CRITICAL **: 18:09:00.275: nimf_im_reset: assertion 'nimf_client_is_connected ()' failed

** (Telegram:13715): CRITICAL **: 18:09:00.275: nimf_im_focus_out: assertion 'nimf_client_is_connected ()' failed

** (Telegram:13715): CRITICAL **: 18:09:00.275: nimf_im_set_cursor_location: assertion 'nimf_client_is_connected ()' failed

** (Telegram:13715): CRITICAL **: 18:09:00.275: nimf_im_reset: assertion 'nimf_client_is_connected ()' failed

** (Telegram:13715): CRITICAL **: 18:09:00.275: nimf_im_focus_out: assertion 'nimf_client_is_connected ()' failed

** (Telegram:13715): CRITICAL **: 18:09:00.275: nimf_im_set_cursor_location: assertion 'nimf_client_is_connected ()' failed

** (Telegram:13715): CRITICAL **: 18:09:00.475: nimf_im_focus_in: assertion 'nimf_client_is_connected ()' failed

** (Telegram:13715): CRITICAL **: 18:09:00.475: nimf_im_set_cursor_location: assertion 'nimf_client_is_connected ()' failed

** (Telegram:13715): CRITICAL **: 18:09:01.338: nimf_im_reset: assertion 'nimf_client_is_connected ()' failed

** (Telegram:13715): CRITICAL **: 18:09:01.339: nimf_im_focus_in: assertion 'nimf_client_is_connected ()' failed

** (Telegram:13715): CRITICAL **: 18:09:01.339: nimf_im_set_cursor_location: assertion 'nimf_client_is_connected ()' failed

** (Telegram:13715): CRITICAL **: 18:09:01.352: nimf_im_reset: assertion 'nimf_client_is_connected ()' failed

** (Telegram:13715): CRITICAL **: 18:09:01.352: nimf_im_focus_out: assertion 'nimf_client_is_connected ()' failed

** (Telegram:13715): CRITICAL **: 18:09:01.352: nimf_im_set_cursor_location: assertion 'nimf_client_is_connected ()' failed

** (Telegram:13715): CRITICAL **: 18:09:01.353: nimf_im_reset: assertion 'nimf_client_is_connected ()' failed

** (Telegram:13715): CRITICAL **: 18:09:01.353: nimf_im_focus_out: assertion 'nimf_client_is_connected ()' failed

** (Telegram:13715): CRITICAL **: 18:09:01.353: nimf_im_set_cursor_location: assertion 'nimf_client_is_connected ()' failed

** (Telegram:13715): CRITICAL **: 18:09:01.555: nimf_im_focus_in: assertion 'nimf_client_is_connected ()' failed

** (Telegram:13715): CRITICAL **: 18:09:01.555: nimf_im_set_cursor_location: assertion 'nimf_client_is_connected ()' failed

** (Telegram:13715): CRITICAL **: 18:09:03.951: nimf_im_reset: assertion 'nimf_client_is_connected ()' failed

** (Telegram:13715): CRITICAL **: 18:09:03.951: nimf_im_reset: assertion 'nimf_client_is_connected ()' failed

** (Telegram:13715): CRITICAL **: 18:09:03.951: nimf_im_focus_out: assertion 'nimf_client_is_connected ()' failed

@ghost
Copy link
Author

ghost commented Nov 27, 2018

확인해보겠습니다.

@5HARK
Copy link
Owner

5HARK commented Nov 27, 2018

다시 빌드 하니 됩니다. 빌드 과정에 뭔가 착오가 있었던것 같습니다. 죄송합니다.
정상적으로 한글입력이 잘됩니다.
고생많으셨습니다

@ghost
Copy link
Author

ghost commented Nov 27, 2018

다행이군요. 코드 작성보다 테스트가 더 많은 시간이 소비되는데 수고하셨습니다.
이슈 자체가 또 매우 흥미로워 재미있었습니다.
감사합니다.

@5HARK
Copy link
Owner

5HARK commented Nov 27, 2018

넵 다시한번 고생많으셨습니다.
정리해서 탤래그램측에 PR 제출 하도록 하겠습니다.

@5HARK 5HARK closed this as completed Nov 28, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant