Beispiel #1
0
static void
fcitx_im_context_focus_out(ClutterIMContext *context)
{
    FcitxLog(LOG_LEVEL, "fcitx_im_context_focus_out");
    FcitxIMContext *fcitxcontext = FCITX_IM_CONTEXT(context);

    if (!fcitxcontext->has_focus) {
        return;
    }

    fcitxcontext->has_focus = false;

    if (IsFcitxIMClientValid(fcitxcontext->client)) {
        FcitxIMClientFocusOut(fcitxcontext->client);
    }


    if (fcitxcontext->preedit_string != NULL)
        g_free(fcitxcontext->preedit_string);
    fcitxcontext->preedit_string = NULL;
    fcitxcontext->cursor_pos = 0;
    g_signal_emit(fcitxcontext, _signal_preedit_changed_id, 0);
    g_signal_emit(fcitxcontext, _signal_preedit_end_id, 0);

    return;
}
Beispiel #2
0
static void
fcitx_im_context_reset(ClutterIMContext *context)
{
    FcitxLog(LOG_LEVEL, "fcitx_im_context_reset");
    FcitxIMContext *fcitxcontext = FCITX_IM_CONTEXT(context);

    if (IsFcitxIMClientValid(fcitxcontext->client)) {
        FcitxIMClientReset(fcitxcontext->client);
    }
}
Beispiel #3
0
static void
_set_cursor_location_internal(FcitxIMContext *fcitxcontext)
{
    ClutterIMContext* context = CLUTTER_IM_CONTEXT(fcitxcontext);
    ClutterActor *stage = clutter_actor_get_stage (context->actor);
    Window current_window, root, parent, *childs;
    unsigned int nchild;
    XWindowAttributes winattr;
    Display *xdpy;
    float fx, fy;
    gint x, y;

    if (!stage)
        return;

    clutter_actor_get_transformed_position (context->actor, &fx, &fy);
    x = fx;
    y = fy;

    xdpy = clutter_x11_get_default_display ();
    current_window = clutter_x11_get_stage_window(CLUTTER_STAGE(stage));

    if (!xdpy || !current_window)
        return;

    while(1) {
        XGetWindowAttributes (xdpy, current_window, &winattr);
        x += winattr.x;
        y += winattr.y;

        XQueryTree(xdpy, current_window, &root, &parent, &childs, &nchild);
        current_window = parent;
        if (root == parent)
        break;
    }

    if (fcitxcontext->area.x != x || fcitxcontext->area.y != y) {
        fcitxcontext->area.x = x;
        fcitxcontext->area.y = y;
    }

    if (context->actor == NULL ||
        !IsFcitxIMClientValid(fcitxcontext->client)) {
        return;
    }

    ClutterIMRectangle area = fcitxcontext->area;
    if (area.x == -1 && area.y == -1 && area.width == 0 && area.height == 0) {
        area.y = 0;
        area.x = 0;
    }

    FcitxIMClientSetCursorLocation(fcitxcontext->client, area.x, area.y + area.height);
    return;
}
Beispiel #4
0
void
_fcitx_im_context_set_capacity(FcitxIMContext* fcitxcontext)
{
    if (IsFcitxIMClientValid(fcitxcontext->client)) {
        FcitxCapacityFlags flags = CAPACITY_NONE;
        if (fcitxcontext->use_preedit)
            flags |= CAPACITY_PREEDIT;
        FcitxIMClientSetCapacity(fcitxcontext->client, flags);

    }
}
Beispiel #5
0
void fcitx_im_context_hide(ClutterIMContext* context)
{
    FcitxLog(LOG_LEVEL, "fcitx_im_context_focus_out");
    FcitxIMContext *fcitxcontext = FCITX_IM_CONTEXT(context);
    
    if (IsFcitxIMClientValid(fcitxcontext->client) && IsFcitxIMClientEnabled(fcitxcontext->client)) {
        FcitxIMClientCloseIC(fcitxcontext->client);
    }

    if (fcitxcontext->has_focus) {
        clutter_im_context_focus_out(context);
    }
}
Beispiel #6
0
void _fcitx_im_context_connect_cb(FcitxIMClient* client, void* user_data)
{
    FcitxIMContext* context =  FCITX_IM_CONTEXT(user_data);
    if (IsFcitxIMClientValid(client)) {
        FcitxIMClientConnectSignal(client,
                                   G_CALLBACK(_fcitx_im_context_enable_im_cb),
                                   G_CALLBACK(_fcitx_im_context_close_im_cb),
                                   G_CALLBACK(_fcitx_im_context_commit_string_cb),
                                   G_CALLBACK(_fcitx_im_context_forward_key_cb),
                                   G_CALLBACK(_fcitx_im_context_update_preedit_cb),
                                   context,
                                   NULL);
        _fcitx_im_context_set_capacity(context);
    }

}
Beispiel #7
0
static void
fcitx_im_context_get_preedit_string(ClutterIMContext   *context,
                                    gchar         **str,
                                    PangoAttrList **attrs,
                                    gint           *cursor_pos)
{
    FcitxLog(LOG_LEVEL, "fcitx_im_context_get_preedit_string");
    FcitxIMContext *fcitxcontext = FCITX_IM_CONTEXT(context);

    if (IsFcitxIMClientValid(fcitxcontext->client) && IsFcitxIMClientEnabled(fcitxcontext->client)) {
        if (str) {
            if (fcitxcontext->preedit_string)
                *str = strdup(fcitxcontext->preedit_string);
            else
                *str = strdup("");
        }
        if (attrs) {
            *attrs = pango_attr_list_new();

            if (str) {
                PangoAttribute *pango_attr;
                pango_attr = pango_attr_underline_new(PANGO_UNDERLINE_SINGLE);
                pango_attr->start_index = 0;
                pango_attr->end_index = strlen(*str);
                pango_attr_list_insert(*attrs, pango_attr);
            }
        }
        if (cursor_pos)
            *cursor_pos = fcitxcontext->cursor_pos;

    } else {
        if (str) {
            *str = g_strdup("");
        }
        if (attrs) {
            *attrs = pango_attr_list_new();
        }
        if (cursor_pos)
            *cursor_pos = 0;
    }
    return ;
}
Beispiel #8
0
static void
fcitx_im_context_set_cursor_location(ClutterIMContext *context,
                                     ClutterIMRectangle *area)
{
    FcitxLog(LOG_LEVEL, "fcitx_im_context_set_cursor_location %d %d %d %d", area->x, area->y, area->height, area->width);
    FcitxIMContext *fcitxcontext = FCITX_IM_CONTEXT(context);

    if (fcitxcontext->area.x == area->x &&
            fcitxcontext->area.y == area->y &&
            fcitxcontext->area.width == area->width &&
            fcitxcontext->area.height == area->height) {
        return;
    }
    fcitxcontext->area = *area;

    if (IsFcitxIMClientValid(fcitxcontext->client)) {
        _set_cursor_location_internal(fcitxcontext);
    }

    return;
}
Beispiel #9
0
static gboolean
fcitx_im_context_filter_keypress(ClutterIMContext *context,
                                 ClutterKeyEvent  *event)
{
    FcitxLog(LOG_LEVEL, "fcitx_im_context_filter_keypress");
    FcitxIMContext *fcitxcontext = FCITX_IM_CONTEXT(context);

    if (G_UNLIKELY(event->modifier_state & FcitxKeyState_HandledMask))
        return TRUE;

    if (G_UNLIKELY(event->modifier_state & FcitxKeyState_IgnoredMask))
        return FALSE;

    if (IsFcitxIMClientValid(fcitxcontext->client) && fcitxcontext->has_focus) {
        if (!IsFcitxIMClientEnabled(fcitxcontext->client)) {
            if (!FcitxIsHotKey(event->keyval, event->modifier_state, FcitxIMClientGetTriggerKey(fcitxcontext->client)))
                return FALSE;
        }

        fcitxcontext->time = event->time;

        int ret = FcitxIMClientProcessKeySync(fcitxcontext->client,
                                                event->keyval,
                                                event->hardware_keycode,
                                                event->modifier_state,
                                                (event->type == CLUTTER_KEY_PRESS) ? (FCITX_PRESS_KEY) : (FCITX_RELEASE_KEY),
                                                event->time);
        if (ret <= 0) {
            event->modifier_state |= FcitxKeyState_IgnoredMask;
            return FALSE;
        } else {
            event->modifier_state |= FcitxKeyState_HandledMask;
            return TRUE;
        }
    } else {
        return FALSE;
    }
    return FALSE;
}
Beispiel #10
0
void _fcitx_fbterm_connect_cb(FcitxIMClient* client, void* user_data)
{
    if (IsFcitxIMClientValid(client))
    {
        FcitxIMClientConnectSignal(client,
                                   G_CALLBACK(_fcitx_fbterm_enable_im_cb),
                                   G_CALLBACK(_fcitx_fbterm_close_im_cb),
                                   G_CALLBACK(_fcitx_fbterm_commit_string_cb),
                                   G_CALLBACK(_fcitx_fbterm_forward_key_cb),
                                   G_CALLBACK(_fcitx_fbterm_update_client_side_ui_cb),
                                   user_data,
                                   NULL);

        CapacityFlags flags = CAPACITY_CLIENT_SIDE_UI;
        FcitxIMClientSetCapacity(client, flags);

        if (active)
        {
            FcitxIMClientFocusIn(client);
            FcitxIMClientEnableIC(client);
        }
    }
}
Beispiel #11
0
static void
fcitx_im_context_focus_in(ClutterIMContext *context)
{
    FcitxLog(LOG_LEVEL, "fcitx_im_context_focus_in");
    FcitxIMContext *fcitxcontext = FCITX_IM_CONTEXT(context);

    if (fcitxcontext->has_focus)
        return;

    fcitxcontext->has_focus = true;

    if (IsFcitxIMClientValid(fcitxcontext->client)) {
        FcitxIMClientFocusIn(fcitxcontext->client);
    }

    /* set_cursor_location_internal() will get origin from X server,
     * it blocks UI. So delay it to idle callback. */
    g_idle_add_full(G_PRIORITY_DEFAULT_IDLE,
                    (GSourceFunc) _set_cursor_location_internal,
                    g_object_ref(fcitxcontext),
                    (GDestroyNotify) g_object_unref);

    return;
}