1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
|
// Copyright (c) 2011 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef VIEWS_IME_INPUT_METHOD_IBUS_H_
#define VIEWS_IME_INPUT_METHOD_IBUS_H_
#pragma once
#include <set>
#include "base/basictypes.h"
#include "base/compiler_specific.h"
#include "base/scoped_ptr.h"
#include "ui/base/gtk/gtk_signal.h"
#include "views/events/event.h"
#include "views/ime/character_composer.h"
#include "views/ime/input_method_base.h"
#include "views/view.h"
// Forward declarations, so that we don't need to include ibus.h in this file.
typedef struct _IBusBus IBusBus;
typedef struct _IBusInputContext IBusInputContext;
typedef struct _IBusText IBusText;
namespace views {
// An InputMethod implementation based on IBus.
class InputMethodIBus : public InputMethodBase {
public:
explicit InputMethodIBus(internal::InputMethodDelegate* delegate);
virtual ~InputMethodIBus();
// Overridden from InputMethod:
virtual void Init(Widget* widget) OVERRIDE;
virtual void OnFocus() OVERRIDE;
virtual void OnBlur() OVERRIDE;
virtual void DispatchKeyEvent(const KeyEvent& key) OVERRIDE;
virtual void OnTextInputTypeChanged(View* view) OVERRIDE;
virtual void OnCaretBoundsChanged(View* view) OVERRIDE;
virtual void CancelComposition(View* view) OVERRIDE;
virtual std::string GetInputLocale() OVERRIDE;
virtual base::i18n::TextDirection GetInputTextDirection() OVERRIDE;
virtual bool IsActive() OVERRIDE;
// Returns true when
// 1) built with GYP_DEFINES="touchui=1" or,
// 2) enabled by SetEnabledInputMethodIBus or,
// 3) enabled by command line flag "--enable-inputmethod-ibus"
static bool IsInputMethodIBusEnabled();
// Enable/Disable InputMethodIBus
static void SetEnableInputMethodIBus(bool enabled);
private:
// A class to hold all data related to a key event being processed by the
// input method but still has no result back yet.
class PendingKeyEvent;
// A class to hold information of a pending request for creating an ibus input
// context.
class PendingCreateICRequest;
// Overridden from InputMethodBase:
virtual void FocusedViewWillChange() OVERRIDE;
virtual void FocusedViewDidChange() OVERRIDE;
// Creates |context_| instance asynchronously.
void CreateContext();
// Sets |context_| or |fake_context_| and hooks necessary signals.
void SetContext(IBusInputContext* ic, bool fake);
// Destroys |context_| instance.
void DestroyContext();
// Asks the client to confirm current composition text.
void ConfirmCompositionText();
// Resets |context_| and abandon all pending results and key events.
void ResetContext();
// Checks the availability of focused text input client and update focus state
// of |context_| and |context_simple_| accordingly.
void UpdateContextFocusState();
// Updates focus state of |fake_context_| accordingly.
void UpdateFakeContextFocusState();
// Process a key returned from the input method.
void ProcessKeyEventPostIME(const KeyEvent& key, guint32 ibus_keycode,
bool handled);
// Processes a key event that was already filtered by the input method.
// A VKEY_PROCESSKEY may be dispatched to the focused View.
void ProcessFilteredKeyPressEvent(const KeyEvent& key);
// Processes a key event that was not filtered by the input method.
void ProcessUnfilteredKeyPressEvent(const KeyEvent& key,
guint32 ibus_keycode);
// Sends input method result caused by the given key event to the focused text
// input client.
void ProcessInputMethodResult(const KeyEvent& key, bool filtered);
// Checks if the pending input method result needs inserting into the focused
// text input client as a single character.
bool NeedInsertChar() const;
// Checks if there is pending input method result.
bool HasInputMethodResult() const;
// Fabricates a key event with VKEY_PROCESSKEY key code and dispatches it to
// the focused View.
void SendFakeProcessKeyEvent(bool pressed) const;
// Called when a pending key event has finished. The event will be removed
// from |pending_key_events_|.
void FinishPendingKeyEvent(PendingKeyEvent* pending_key);
// Abandons all pending key events. It usually happends when we lose keyboard
// focus, the text input type is changed or we are destroyed.
void AbandonAllPendingKeyEvents();
// Event handlers for IBusInputContext:
CHROMEG_CALLBACK_1(InputMethodIBus, void, OnCommitText,
IBusInputContext*, IBusText*);
CHROMEG_CALLBACK_3(InputMethodIBus, void, OnForwardKeyEvent,
IBusInputContext*, guint, guint, guint);
CHROMEG_CALLBACK_0(InputMethodIBus, void, OnShowPreeditText,
IBusInputContext*);
CHROMEG_CALLBACK_3(InputMethodIBus, void, OnUpdatePreeditText,
IBusInputContext*, IBusText*, guint, gboolean);
CHROMEG_CALLBACK_0(InputMethodIBus, void, OnHidePreeditText,
IBusInputContext*);
CHROMEG_CALLBACK_0(InputMethodIBus, void, OnDestroy, IBusInputContext*);
CHROMEG_CALLBACK_0(InputMethodIBus, void, OnFakeDestroy, IBusInputContext*);
// Event handlers for IBusBus:
CHROMEG_CALLBACK_0(InputMethodIBus, void, OnIBusConnected, IBusBus*);
CHROMEG_CALLBACK_0(InputMethodIBus, void, OnIBusDisconnected, IBusBus*);
// Returns the global IBusBus instance.
static IBusBus* GetIBus();
// Callback function for ibus_input_context_process_key_event_async().
static void ProcessKeyEventDone(IBusInputContext* context,
GAsyncResult* res,
PendingKeyEvent* data);
// Callback function for ibus_bus_create_input_context_async().
static void CreateInputContextDone(IBusBus* bus,
GAsyncResult* res,
PendingCreateICRequest* data);
// The input context for actual text input.
IBusInputContext* context_;
// The "fake" input context for hotkey handling, it is only used when there
// is no focused view, or it doesn't support text input.
IBusInputContext* fake_context_;
// All pending key events. Note: we do not own these object, we just save
// pointers to these object so that we can abandon them when necessary.
// They will be deleted in ProcessKeyEventDone().
std::set<PendingKeyEvent*> pending_key_events_;
// The pending request for creating the |context_| instance. We need to keep
// this pointer so that we can receive or abandon the result.
PendingCreateICRequest* pending_create_ic_request_;
// The pending request for creating the |context_| instance. We need to keep
// this pointer so that we can receive or abandon the result.
PendingCreateICRequest* pending_create_fake_ic_request_;
// Pending composition text generated by the current pending key event.
// It'll be sent to the focused text input client as soon as we receive the
// processing result of the pending key event.
ui::CompositionText composition_;
// Pending result text generated by the current pending key event.
// It'll be sent to the focused text input client as soon as we receive the
// processing result of the pending key event.
string16 result_text_;
// Indicates if |context_| and |context_simple_| are focused or not.
bool context_focused_;
// Indicates if there is an ongoing composition text.
bool composing_text_;
// Indicates if the composition text is changed or deleted.
bool composition_changed_;
// If it's true then all input method result received before the next key
// event will be discarded.
bool suppress_next_result_;
// An object to compose a character from a sequence of key presses
// including dead key etc.
CharacterComposer character_composer_;
DISALLOW_COPY_AND_ASSIGN(InputMethodIBus);
};
} // namespace views
#endif // VIEWS_IME_INPUT_METHOD_IBUS_H_
|