~timo-jyrinki/ubuntu/trusty/maliit-framework/fix_qt52

« back to all changes in this revision

Viewing changes to connection/waylandinputmethodconnection.cpp

  • Committer: Package Import Robot
  • Author(s): Ricardo Salveti de Araujo, Sergio Schvezov, Ricardo Salveti de Araujo
  • Date: 2013-07-23 19:47:04 UTC
  • mfrom: (1.1.2) (1.2.1 experimental)
  • Revision ID: package-import@ubuntu.com-20130723194704-1lsy1kmlda069cea
Tags: 0.99.0+git20130615+97e8335-0ubuntu1
[ Sergio Schvezov ]
* New build from HEAD 97e8335.
* Packaging import from lp:phablet-extras/maliit-framework.

[ Ricardo Salveti de Araujo ]
* debian/control: adding vcs and fixing dependencies
* General package cleanup

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* * This file is part of Maliit framework *
 
2
 *
 
3
 * Copyright (C) 2012 Canonical Ltd
 
4
 *
 
5
 * Contact: maliit-discuss@lists.maliit.org
 
6
 *
 
7
 * This library is free software; you can redistribute it and/or
 
8
 * modify it under the terms of the GNU Lesser General Public
 
9
 * License version 2.1 as published by the Free Software Foundation
 
10
 * and appearing in the file LICENSE.LGPL included in the packaging
 
11
 * of this file.
 
12
 */
 
13
 
 
14
#include <cerrno> // for errno
 
15
#include <cstring> // for strerror
 
16
#include <QGuiApplication>
 
17
#include <QKeyEvent>
 
18
#include <qpa/qplatformnativeinterface.h>
 
19
 
 
20
#include "wayland-client.h"
 
21
#include <qwayland-input-method.h>
 
22
#include <qwayland-text.h>
 
23
 
 
24
#include <xkbcommon/xkbcommon.h>
 
25
 
 
26
#include "waylandinputmethodconnection.h"
 
27
 
 
28
namespace {
 
29
 
 
30
// TODO: Deduplicate it. Those values are used in
 
31
// minputcontextconnection, mimpluginmanager,
 
32
// mattributeextensionmanager and in input context implementations.
 
33
const char * const FocusStateAttribute = "focusState";
 
34
const char * const ContentTypeAttribute = "contentType";
 
35
const char * const CorrectionAttribute = "correctionEnabled";
 
36
const char * const PredictionAttribute = "predictionEnabled";
 
37
const char * const AutoCapitalizationAttribute = "autocapitalizationEnabled";
 
38
const char * const SurroundingTextAttribute = "surroundingText";
 
39
const char * const AnchorPositionAttribute = "anchorPosition";
 
40
const char * const CursorPositionAttribute = "cursorPosition";
 
41
const char * const HasSelectionAttribute = "hasSelection";
 
42
const char * const HiddenTextAttribute = "hiddenText";
 
43
 
 
44
typedef QPair<Qt::KeyboardModifiers, const char *> Modifier;
 
45
const Modifier modifiers[] = {
 
46
    Modifier(Qt::ShiftModifier, XKB_MOD_NAME_SHIFT),
 
47
    Modifier(Qt::ControlModifier, XKB_MOD_NAME_CTRL),
 
48
    Modifier(Qt::AltModifier, XKB_MOD_NAME_ALT),
 
49
    Modifier(Qt::MetaModifier, XKB_MOD_NAME_LOGO),
 
50
    Modifier(Qt::KeypadModifier, XKB_LED_NAME_NUM)
 
51
};
 
52
 
 
53
QByteArray modifiersMap()
 
54
{
 
55
    QByteArray mod_map;
 
56
    for (unsigned int iter(0); iter < (sizeof(modifiers) / sizeof(modifiers[0])); ++iter) {
 
57
        mod_map.append(modifiers[iter].second);
 
58
    }
 
59
    return mod_map;
 
60
}
 
61
 
 
62
xkb_mod_mask_t modifiersFromQt(const Qt::KeyboardModifiers qt_mods)
 
63
{
 
64
    xkb_mod_mask_t mod_mask(0);
 
65
 
 
66
    if (qt_mods == Qt::NoModifier) {
 
67
        return mod_mask;
 
68
    }
 
69
 
 
70
    for (unsigned int iter(0); iter < (sizeof(modifiers) / sizeof(modifiers[0])); ++iter) {
 
71
        if ((qt_mods & modifiers[iter].first) == modifiers[iter].first) {
 
72
            mod_mask |= 1 << iter;
 
73
        }
 
74
    }
 
75
 
 
76
    return mod_mask;
 
77
}
 
78
 
 
79
xkb_keysym_t keyFromQt(int qt_key)
 
80
{
 
81
    switch (qt_key) {
 
82
    case Qt::Key_Backspace:
 
83
        return XKB_KEY_BackSpace;
 
84
    case Qt::Key_Return:
 
85
        return XKB_KEY_Return;
 
86
    case Qt::Key_Left:
 
87
        return XKB_KEY_Left;
 
88
    case Qt::Key_Up:
 
89
        return XKB_KEY_Up;
 
90
    case Qt::Key_Right:
 
91
        return XKB_KEY_Right;
 
92
    case Qt::Key_Down:
 
93
        return XKB_KEY_Down;
 
94
    default:
 
95
        return XKB_KEY_NoSymbol;
 
96
    }
 
97
}
 
98
 
 
99
QtWayland::wl_text_input::preedit_style preeditStyleFromMaliit(Maliit::PreeditFace face)
 
100
{
 
101
    switch (face) {
 
102
    case Maliit::PreeditDefault:
 
103
        return QtWayland::wl_text_input::preedit_style_default;
 
104
    case Maliit::PreeditNoCandidates:
 
105
        return QtWayland::wl_text_input::preedit_style_incorrect;
 
106
    case Maliit::PreeditKeyPress:
 
107
        return QtWayland::wl_text_input::preedit_style_highlight;
 
108
    case Maliit::PreeditUnconvertible:
 
109
        return QtWayland::wl_text_input::preedit_style_inactive;
 
110
    case Maliit::PreeditActive:
 
111
        return QtWayland::wl_text_input::preedit_style_active;
 
112
    default:
 
113
        return QtWayland::wl_text_input::preedit_style_none;
 
114
    }
 
115
}
 
116
 
 
117
Maliit::TextContentType contentTypeFromWayland(uint32_t purpose)
 
118
{
 
119
    switch (purpose) {
 
120
    case QtWayland::wl_text_input::content_purpose_normal:
 
121
        return Maliit::FreeTextContentType;
 
122
    case QtWayland::wl_text_input::content_purpose_number:
 
123
        return Maliit::NumberContentType;
 
124
    case QtWayland::wl_text_input::content_purpose_phone:
 
125
        return Maliit::PhoneNumberContentType;
 
126
    case QtWayland::wl_text_input::content_purpose_url:
 
127
        return Maliit::UrlContentType;
 
128
    case QtWayland::wl_text_input::content_purpose_email:
 
129
        return Maliit::EmailContentType;
 
130
    default:
 
131
        return Maliit::CustomContentType;
 
132
    }
 
133
}
 
134
 
 
135
bool matchesFlag(int value,
 
136
                 int flag)
 
137
{
 
138
    return ((value & flag) == flag);
 
139
}
 
140
 
 
141
const unsigned int wayland_connection_id(1);
 
142
 
 
143
} // unnamed namespace
 
144
 
 
145
namespace Maliit {
 
146
namespace Wayland {
 
147
 
 
148
class InputMethodContext;
 
149
 
 
150
class InputMethod : public QtWayland::wl_input_method
 
151
{
 
152
public:
 
153
    InputMethod(MInputContextConnection *connection, struct wl_registry *registry, int id);
 
154
    ~InputMethod();
 
155
 
 
156
    InputMethodContext *context() const;
 
157
 
 
158
protected:
 
159
    void input_method_activate(struct ::wl_input_method *object, struct ::wl_input_method_context *id) Q_DECL_OVERRIDE;
 
160
    void input_method_deactivate(struct ::wl_input_method_context *context) Q_DECL_OVERRIDE;
 
161
 
 
162
private:
 
163
    MInputContextConnection *m_connection;
 
164
    QScopedPointer<InputMethodContext> m_context;
 
165
};
 
166
 
 
167
class InputMethodContext : public QtWayland::wl_input_method_context
 
168
{
 
169
public:
 
170
    InputMethodContext(MInputContextConnection *connection, struct ::wl_input_method_context *object);
 
171
    ~InputMethodContext();
 
172
 
 
173
    QString selection() const;
 
174
    uint32_t serial() const;
 
175
 
 
176
protected:
 
177
    void input_method_context_commit_state(uint32_t serial) Q_DECL_OVERRIDE;
 
178
    void input_method_context_content_type(uint32_t hint, uint32_t purpose) Q_DECL_OVERRIDE;
 
179
    void input_method_context_invoke_action(uint32_t button, uint32_t index) Q_DECL_OVERRIDE;
 
180
    void input_method_context_preferred_language(const QString &language) Q_DECL_OVERRIDE;
 
181
    void input_method_context_reset() Q_DECL_OVERRIDE;
 
182
    void input_method_context_surrounding_text(const QString &text, uint32_t cursor, uint32_t anchor) Q_DECL_OVERRIDE;
 
183
 
 
184
private:
 
185
    MInputContextConnection *m_connection;
 
186
    QVariantMap m_stateInfo;
 
187
    uint32_t m_serial;
 
188
    QString m_selection;
 
189
};
 
190
 
 
191
}
 
192
}
 
193
 
 
194
struct WaylandInputMethodConnectionPrivate
 
195
{
 
196
    Q_DECLARE_PUBLIC(WaylandInputMethodConnection)
 
197
 
 
198
    WaylandInputMethodConnectionPrivate(WaylandInputMethodConnection *connection);
 
199
    ~WaylandInputMethodConnectionPrivate();
 
200
 
 
201
    void handleRegistryGlobal(uint32_t name,
 
202
                              const char *interface,
 
203
                              uint32_t version);
 
204
    void handleRegistryGlobalRemove(uint32_t name);
 
205
 
 
206
    Maliit::Wayland::InputMethodContext *context();
 
207
 
 
208
    WaylandInputMethodConnection *q_ptr;
 
209
    wl_display *display;
 
210
    wl_registry *registry;
 
211
    QScopedPointer<Maliit::Wayland::InputMethod> input_method;
 
212
};
 
213
 
 
214
namespace {
 
215
 
 
216
void registryGlobal(void *data,
 
217
                    wl_registry *registry,
 
218
                    uint32_t name,
 
219
                    const char *interface,
 
220
                    uint32_t version)
 
221
{
 
222
    qDebug() << __PRETTY_FUNCTION__;
 
223
    WaylandInputMethodConnectionPrivate *d =
 
224
            static_cast<WaylandInputMethodConnectionPrivate *>(data);
 
225
 
 
226
    Q_UNUSED(registry);
 
227
    d->handleRegistryGlobal(name, interface, version);
 
228
}
 
229
 
 
230
void registryGlobalRemove(void *data,
 
231
                          wl_registry *registry,
 
232
                          uint32_t name)
 
233
{
 
234
    qDebug() << __PRETTY_FUNCTION__;
 
235
    WaylandInputMethodConnectionPrivate *d =
 
236
            static_cast<WaylandInputMethodConnectionPrivate *>(data);
 
237
 
 
238
    Q_UNUSED(registry);
 
239
    d->handleRegistryGlobalRemove(name);
 
240
}
 
241
 
 
242
const wl_registry_listener maliit_registry_listener = {
 
243
    registryGlobal,
 
244
    registryGlobalRemove
 
245
};
 
246
 
 
247
 
 
248
} // unnamed namespace
 
249
 
 
250
WaylandInputMethodConnectionPrivate::WaylandInputMethodConnectionPrivate(WaylandInputMethodConnection *connection)
 
251
    : q_ptr(connection),
 
252
      display(0),
 
253
      registry(0),
 
254
      input_method()
 
255
{
 
256
    display = static_cast<wl_display *>(QGuiApplication::platformNativeInterface()->nativeResourceForIntegration("display"));
 
257
    if (!display) {
 
258
        qCritical() << Q_FUNC_INFO << "Failed to get a display.";
 
259
        return;
 
260
    }
 
261
    registry = wl_display_get_registry(display);
 
262
    wl_registry_add_listener(registry, &maliit_registry_listener, this);
 
263
}
 
264
 
 
265
WaylandInputMethodConnectionPrivate::~WaylandInputMethodConnectionPrivate()
 
266
{
 
267
    input_method.reset();
 
268
    if (registry) {
 
269
        wl_registry_destroy(registry);
 
270
    }
 
271
}
 
272
 
 
273
void WaylandInputMethodConnectionPrivate::handleRegistryGlobal(uint32_t name,
 
274
                                                               const char *interface,
 
275
                                                               uint32_t version)
 
276
{
 
277
    Q_UNUSED(version);
 
278
    Q_Q(WaylandInputMethodConnection);
 
279
 
 
280
    if (!strcmp(interface, "wl_input_method")) {
 
281
        input_method.reset(new Maliit::Wayland::InputMethod(q, registry, name));
 
282
    }
 
283
}
 
284
 
 
285
void WaylandInputMethodConnectionPrivate::handleRegistryGlobalRemove(uint32_t name)
 
286
{
 
287
    qDebug() << Q_FUNC_INFO << name;
 
288
}
 
289
 
 
290
Maliit::Wayland::InputMethodContext *WaylandInputMethodConnectionPrivate::context()
 
291
{
 
292
    return input_method ? input_method->context() : 0;
 
293
}
 
294
 
 
295
// MInputContextWestonIMProtocolConnection
 
296
 
 
297
WaylandInputMethodConnection::WaylandInputMethodConnection()
 
298
    : d_ptr(new WaylandInputMethodConnectionPrivate(this))
 
299
{
 
300
}
 
301
 
 
302
WaylandInputMethodConnection::~WaylandInputMethodConnection()
 
303
{
 
304
}
 
305
 
 
306
void WaylandInputMethodConnection::sendPreeditString(const QString &string,
 
307
                                                     const QList<Maliit::PreeditTextFormat> &preedit_formats,
 
308
                                                     int replace_start,
 
309
                                                     int replace_length,
 
310
                                                     int cursor_pos)
 
311
{
 
312
    Q_D(WaylandInputMethodConnection);
 
313
 
 
314
    qDebug() << Q_FUNC_INFO << string << replace_start << replace_length << cursor_pos;
 
315
 
 
316
    if (!d->context())
 
317
        return;
 
318
 
 
319
    MInputContextConnection::sendPreeditString(string, preedit_formats,
 
320
                                               replace_start, replace_length,
 
321
                                               cursor_pos);
 
322
 
 
323
    if (replace_length > 0) {
 
324
        int cursor = widgetState().value(CursorPositionAttribute).toInt();
 
325
        uint32_t index = string.midRef(qMin(cursor + replace_start, cursor), qAbs(replace_start)).toUtf8().size();
 
326
        uint32_t length = string.midRef(cursor + replace_start, replace_length).toUtf8().size();
 
327
        d->context()->delete_surrounding_text(index, length);
 
328
    }
 
329
 
 
330
    Q_FOREACH (const Maliit::PreeditTextFormat& format, preedit_formats) {
 
331
        QtWayland::wl_text_input::preedit_style style = preeditStyleFromMaliit(format.preeditFace);
 
332
        uint32_t index = string.leftRef(format.start).toUtf8().size();
 
333
        uint32_t length = string.leftRef(format.start + format.length).toUtf8().size() - index;
 
334
        qDebug() << Q_FUNC_INFO << "preedit_styling" << index << length;
 
335
        d->context()->preedit_styling(index, length, style);
 
336
    }
 
337
 
 
338
    // TODO check if defined like that/required
 
339
    if (cursor_pos < 0) {
 
340
        cursor_pos = string.size() + 1 - cursor_pos;
 
341
    }
 
342
 
 
343
    qDebug() << Q_FUNC_INFO << "preedit_cursor" << string.leftRef(cursor_pos).toUtf8().size();
 
344
    d->context()->preedit_cursor(string.leftRef(cursor_pos).toUtf8().size());
 
345
    qDebug() << Q_FUNC_INFO << "preedit_string" << string;
 
346
    d->context()->preedit_string(d->context()->serial(), string, string);
 
347
}
 
348
 
 
349
 
 
350
void WaylandInputMethodConnection::sendCommitString(const QString &string,
 
351
                                                    int replace_start,
 
352
                                                    int replace_length,
 
353
                                                    int cursor_pos)
 
354
{
 
355
    Q_D(WaylandInputMethodConnection);
 
356
 
 
357
    qDebug() << Q_FUNC_INFO << string << replace_start << replace_length << cursor_pos;
 
358
 
 
359
    if (!d->context())
 
360
        return;
 
361
 
 
362
    MInputContextConnection::sendCommitString(string, replace_start, replace_length, cursor_pos);
 
363
 
 
364
    if (cursor_pos != 0) {
 
365
        qWarning() << Q_FUNC_INFO << "cursor_pos:" << cursor_pos << "!= 0 not supported yet";
 
366
        cursor_pos = 0;
 
367
    }
 
368
 
 
369
    if (replace_length > 0) {
 
370
        int cursor = widgetState().value(CursorPositionAttribute).toInt();
 
371
        uint32_t index = string.midRef(qMin(cursor + replace_start, cursor), qAbs(replace_start)).toUtf8().size();
 
372
        uint32_t length = string.midRef(cursor + replace_start, replace_length).toUtf8().size();
 
373
        d->context()->delete_surrounding_text(index, length);
 
374
    }
 
375
 
 
376
    cursor_pos = string.leftRef(cursor_pos).toUtf8().size();
 
377
    d->context()->cursor_position(cursor_pos, cursor_pos);
 
378
    d->context()->commit_string(d->context()->serial(), string);
 
379
}
 
380
 
 
381
void WaylandInputMethodConnection::sendKeyEvent(const QKeyEvent &keyEvent,
 
382
                                                Maliit::EventRequestType requestType)
 
383
{
 
384
    Q_D(WaylandInputMethodConnection);
 
385
 
 
386
    qDebug() << Q_FUNC_INFO;
 
387
 
 
388
    if (!d->context())
 
389
        return;
 
390
 
 
391
    xkb_keysym_t sym(keyFromQt(keyEvent.key()));
 
392
 
 
393
    if (sym == XKB_KEY_NoSymbol) {
 
394
        qWarning() << "No conversion from Qt::Key:" << keyEvent.key() << "to XKB key. Update the keyFromQt() function.";
 
395
        return;
 
396
    }
 
397
 
 
398
    wl_keyboard_key_state state;
 
399
 
 
400
    switch (keyEvent.type()) {
 
401
    case QEvent::KeyPress:
 
402
        state = WL_KEYBOARD_KEY_STATE_PRESSED;
 
403
        break;
 
404
 
 
405
    case QEvent::KeyRelease:
 
406
        state = WL_KEYBOARD_KEY_STATE_RELEASED;
 
407
        break;
 
408
 
 
409
    default:
 
410
        qWarning() << "Unknown QKeyEvent type:" << keyEvent.type();
 
411
        return;
 
412
    }
 
413
 
 
414
    xkb_mod_mask_t modifiers(modifiersFromQt(keyEvent.modifiers()));
 
415
 
 
416
    MInputContextConnection::sendKeyEvent(keyEvent, requestType);
 
417
 
 
418
    d->context()->keysym(d->context()->serial(),
 
419
                         keyEvent.timestamp(),
 
420
                         sym, state, modifiers);
 
421
}
 
422
 
 
423
QString WaylandInputMethodConnection::selection(bool &valid)
 
424
{
 
425
    Q_D(WaylandInputMethodConnection);
 
426
 
 
427
    qDebug() << Q_FUNC_INFO;
 
428
 
 
429
    Maliit::Wayland::InputMethodContext *context = d->input_method->context();
 
430
 
 
431
    valid = context && !context->selection().isEmpty();
 
432
    return context ? context->selection() : QString();
 
433
}
 
434
 
 
435
void WaylandInputMethodConnection::setLanguage(const QString &language)
 
436
{
 
437
    Q_D(WaylandInputMethodConnection);
 
438
 
 
439
    qDebug() << Q_FUNC_INFO;
 
440
 
 
441
    if (!d->context())
 
442
        return;
 
443
 
 
444
    d->context()->language(d->context()->serial(), language);
 
445
}
 
446
 
 
447
void WaylandInputMethodConnection::setSelection(int start, int length)
 
448
{
 
449
    Q_D (WaylandInputMethodConnection);
 
450
 
 
451
    qDebug() << Q_FUNC_INFO;
 
452
 
 
453
    if (!d->context())
 
454
        return;
 
455
 
 
456
    QString surrounding = widgetState().value(SurroundingTextAttribute).toString();
 
457
    uint32_t index(surrounding.leftRef(start + length).toUtf8().size());
 
458
    uint32_t anchor(surrounding.leftRef(start).toUtf8().size());
 
459
 
 
460
    d->context()->cursor_position(index, anchor);
 
461
    d->context()->commit_string(d->context()->serial(), QString());
 
462
}
 
463
 
 
464
namespace Maliit {
 
465
namespace Wayland {
 
466
 
 
467
InputMethod::InputMethod(MInputContextConnection *connection, struct wl_registry *registry, int id)
 
468
    : QtWayland::wl_input_method(registry, id)
 
469
    , m_connection(connection)
 
470
    , m_context()
 
471
{
 
472
}
 
473
 
 
474
InputMethod::~InputMethod()
 
475
{
 
476
}
 
477
 
 
478
InputMethodContext *InputMethod::context() const
 
479
{
 
480
    return m_context.data();
 
481
}
 
482
 
 
483
void InputMethod::input_method_activate(struct ::wl_input_method *, struct ::wl_input_method_context *id)
 
484
{
 
485
    qDebug() << Q_FUNC_INFO;
 
486
 
 
487
    m_context.reset(new InputMethodContext(m_connection, id));
 
488
 
 
489
    m_context->modifiers_map(modifiersMap());
 
490
 
 
491
}
 
492
 
 
493
void InputMethod::input_method_deactivate(struct wl_input_method_context *)
 
494
{
 
495
    qDebug() << Q_FUNC_INFO;
 
496
 
 
497
    m_context.reset();
 
498
 
 
499
    m_connection->handleDisconnection(wayland_connection_id);
 
500
}
 
501
 
 
502
InputMethodContext::InputMethodContext(MInputContextConnection *connection, struct ::wl_input_method_context *object)
 
503
    : QtWayland::wl_input_method_context(object)
 
504
    , m_connection(connection)
 
505
    , m_stateInfo()
 
506
    , m_serial(0)
 
507
    , m_selection()
 
508
{
 
509
    qDebug() << Q_FUNC_INFO;
 
510
 
 
511
    m_stateInfo[FocusStateAttribute] = true;
 
512
    m_connection->activateContext(wayland_connection_id);
 
513
    m_connection->showInputMethod(wayland_connection_id);
 
514
}
 
515
 
 
516
InputMethodContext::~InputMethodContext()
 
517
{
 
518
    qDebug() << Q_FUNC_INFO;
 
519
 
 
520
    m_stateInfo.clear();
 
521
    m_stateInfo[FocusStateAttribute] = false;
 
522
    m_connection->updateWidgetInformation(wayland_connection_id, m_stateInfo, true);
 
523
    m_connection->hideInputMethod(wayland_connection_id);
 
524
}
 
525
 
 
526
QString InputMethodContext::selection() const
 
527
{
 
528
    return m_selection;
 
529
}
 
530
 
 
531
uint32_t InputMethodContext::serial() const
 
532
{
 
533
    return m_serial;
 
534
}
 
535
 
 
536
void InputMethodContext::input_method_context_commit_state(uint32_t serial)
 
537
{
 
538
    qDebug() << Q_FUNC_INFO;
 
539
 
 
540
    m_serial = serial;
 
541
    m_connection->updateWidgetInformation(wayland_connection_id, m_stateInfo, false);
 
542
}
 
543
 
 
544
void InputMethodContext::input_method_context_content_type(uint32_t hint, uint32_t purpose)
 
545
{
 
546
    qDebug() << Q_FUNC_INFO;
 
547
 
 
548
    m_stateInfo[ContentTypeAttribute] = contentTypeFromWayland(purpose);
 
549
    m_stateInfo[AutoCapitalizationAttribute] = matchesFlag(hint, QtWayland::wl_text_input::content_hint_auto_capitalization);
 
550
    m_stateInfo[CorrectionAttribute] = matchesFlag(hint, QtWayland::wl_text_input::content_hint_auto_correction);
 
551
    m_stateInfo[PredictionAttribute] = matchesFlag(hint, QtWayland::wl_text_input::content_hint_auto_completion);
 
552
    m_stateInfo[HiddenTextAttribute] = matchesFlag(hint, QtWayland::wl_text_input::content_hint_hidden_text);
 
553
}
 
554
 
 
555
void InputMethodContext::input_method_context_invoke_action(uint32_t button, uint32_t index)
 
556
{
 
557
    qDebug() << Q_FUNC_INFO << button << index;
 
558
}
 
559
 
 
560
void InputMethodContext::input_method_context_preferred_language(const QString &language)
 
561
{
 
562
    qDebug() << Q_FUNC_INFO << language;
 
563
}
 
564
 
 
565
void InputMethodContext::input_method_context_reset()
 
566
{
 
567
    qDebug() << Q_FUNC_INFO;
 
568
 
 
569
    m_connection->reset(wayland_connection_id);
 
570
}
 
571
 
 
572
void InputMethodContext::input_method_context_surrounding_text(const QString &text, uint32_t cursor, uint32_t anchor)
 
573
{
 
574
    qDebug() << Q_FUNC_INFO;
 
575
 
 
576
    const QByteArray &utf8_text(text.toUtf8());
 
577
 
 
578
    m_stateInfo[SurroundingTextAttribute] = text;
 
579
    m_stateInfo[CursorPositionAttribute] = QString::fromUtf8(utf8_text.constData(), cursor).size();
 
580
    m_stateInfo[AnchorPositionAttribute] = QString::fromUtf8(utf8_text.constData(), anchor).size();
 
581
    if (cursor == anchor) {
 
582
        m_stateInfo[HasSelectionAttribute] = false;
 
583
        m_selection.clear();
 
584
    } else {
 
585
        m_stateInfo[HasSelectionAttribute] = true;
 
586
        uint32_t begin = qMin(anchor, cursor);
 
587
        uint32_t end = qMax(anchor, cursor);
 
588
        m_selection = QString::fromUtf8(utf8_text.constData() + begin, end - begin);
 
589
    }
 
590
}
 
591
 
 
592
}
 
593
}