Merge lp:~njpatel/unity/ibus-support into lp:unity

Proposed by Neil J. Patel
Status: Merged
Merged at revision: 1471
Proposed branch: lp:~njpatel/unity/ibus-support
Merge into: lp:unity
Diff against target: 285 lines (+113/-25)
5 files modified
plugins/unityshell/src/DashView.cpp (+6/-0)
plugins/unityshell/src/IMTextEntry.cpp (+93/-19)
plugins/unityshell/src/IMTextEntry.h (+9/-1)
plugins/unityshell/src/PlacesHomeView.cpp (+2/-2)
tests/standalone_dash.cpp (+3/-3)
To merge this branch: bzr merge lp:~njpatel/unity/ibus-support
Reviewer Review Type Date Requested Status
Jason Smith (community) Approve
Review via email: mp+73586@code.launchpad.net

Description of the change

- Adds support for IBus (either directly or through XIM), plus other, non-async, input methods (working on getting async ones working)
- Adds support for copy-and-paste in the entry

To post a comment you must log in.
Revision history for this message
Neil J. Patel (njpatel) wrote :

- Fixes allocation of dash
- Makes the standalone dash be the size of a 1024x600 screen (minus the launcher + panel), which eases testing.

Revision history for this message
Jason Smith (jassmith) wrote :

+1 looks good, works right

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'plugins/unityshell/src/DashView.cpp'
2--- plugins/unityshell/src/DashView.cpp 2011-08-26 14:07:47 +0000
3+++ plugins/unityshell/src/DashView.cpp 2011-08-31 20:22:26 +0000
4@@ -114,8 +114,13 @@
5 lens_bar_ = new LensBar();
6 lens_bar_->lens_activated.connect(sigc::mem_fun(this, &DashView::OnLensBarActivated));
7 content_layout_->AddView(lens_bar_, 0, nux::MINOR_POSITION_CENTER);
8+
9+ search_bar_->OnGeometryChanged.connect([&] (nux::Area*, nux::Geometry& geo) { Relayout(); });
10+ lens_bar_->OnGeometryChanged.connect([&] (nux::Area*, nux::Geometry& geo) { Relayout(); });
11 }
12
13+
14+
15 void DashView::SetupUBusConnections()
16 {
17 ubus_manager_.RegisterInterest(UBUS_PLACE_ENTRY_ACTIVATE_REQUEST,
18@@ -140,6 +145,7 @@
19 // the bottom of the dash off the screen
20 // not hugely happy with this, so FIXME
21 lenses_layout_->SetMaximumHeight (content_geo_.height - search_bar_->GetGeometry().height - lens_bar_->GetGeometry().height);
22+ lenses_layout_->SetMinimumHeight (content_geo_.height - search_bar_->GetGeometry().height - lens_bar_->GetGeometry().height);
23
24 content_layout_->SetMinMaxSize(content_geo_.width, content_geo_.height);
25
26
27=== modified file 'plugins/unityshell/src/IMTextEntry.cpp'
28--- plugins/unityshell/src/IMTextEntry.cpp 2011-08-24 18:46:52 +0000
29+++ plugins/unityshell/src/IMTextEntry.cpp 2011-08-31 20:22:26 +0000
30@@ -44,14 +44,13 @@
31 , client_window_(0)
32 , im_enabled_(false)
33 , im_active_(false)
34+ , focused_(false)
35 {
36+ g_setenv("IBUS_ENABLE_SYNC_MODE", "1", TRUE);
37 CheckIMEnabled();
38- //FIXME: Make event forwarding work before enabling
39- // im_enabled_ ? SetupMultiIM() : SetupSimpleIM();
40- SetupSimpleIM();
41+ im_enabled_ ? SetupMultiIM() : SetupSimpleIM();
42
43- FocusChanged.connect(sigc::mem_fun(this, &IMTextEntry::OnFocusChanged));
44- OnKeyNavFocusChange.connect(sigc::mem_fun(this, &IMTextEntry::OnFocusChanged));
45+ FocusChanged.connect([&] (nux::Area*) { GetFocused() ? OnFocusIn() : OnFocusOut(); });
46 mouse_up.connect(sigc::mem_fun(this, &IMTextEntry::OnMouseButtonUp));
47 }
48
49@@ -101,19 +100,24 @@
50 {
51 bool propagate_event = !(TryHandleEvent(event_type, keysym, character));
52
53- LOG_DEBUG(logger) << "Input method ("
54+ LOG_DEBUG(logger) << "Input method "
55 << (im_enabled_ ? gtk_im_multicontext_get_context_id(GTK_IM_MULTICONTEXT(im_context_)) : "simple")
56- << ") "
57+ << " "
58 << (propagate_event ? "did not handle " : "handled ")
59 << "event ("
60 << (event_type == NUX_KEYDOWN ? "press" : "release")
61 << ") ";
62
63 if (propagate_event)
64+ propagate_event = !TryHandleSpecial(event_type, keysym, character);
65+
66+ if (propagate_event)
67 {
68 text_input_mode_ = event_type == NUX_KEYDOWN;
69 propagate_event = TextEntry::InspectKeyEvent(event_type, keysym, character);
70 text_input_mode_ = false;
71+
72+ UpdateCursorLocation();
73 }
74 return propagate_event;
75 }
76@@ -139,7 +143,7 @@
77 client_window_ = gdk_x11_window_foreign_new_for_display(gdk_display_get_default(), window);
78 gtk_im_context_set_client_window(im_context_, client_window_);
79
80- if (GetFocused())
81+ if (focused_)
82 {
83 gtk_im_context_focus_in(im_context_);
84 }
85@@ -149,7 +153,6 @@
86 void IMTextEntry::KeyEventToGdkEventKey(Event& event, GdkEventKey& gdk_event)
87 {
88 gdk_event.type = event.e_event == nux::NUX_KEYDOWN ? GDK_KEY_PRESS : GDK_KEY_RELEASE;
89-
90 gdk_event.window = client_window_;
91 gdk_event.send_event = FALSE;
92 gdk_event.time = event.e_x11_timestamp;
93@@ -165,20 +168,66 @@
94 gdk_event.is_modifier = 0;
95 }
96
97-void IMTextEntry::OnFocusChanged(nux::Area* area)
98+bool IMTextEntry::TryHandleSpecial(unsigned int eventType, unsigned int keysym, const char* character)
99 {
100-
101- LOG_DEBUG(logger) << "Focus changed " << boost::lexical_cast<bool>(GetFocused());
102-
103- if (GetFocused())
104- {
105- gtk_im_context_focus_in(im_context_);
106+ nux::Event event = nux::GetGraphicsThread()->GetWindow().GetCurrentEvent();
107+ unsigned int keyval = keysym;
108+ bool shift = (event.GetKeyState() & NUX_STATE_SHIFT);
109+ bool ctrl = (event.GetKeyState() & NUX_STATE_CTRL);
110+
111+ if (eventType != NUX_KEYDOWN)
112+ return false;
113+
114+ if (((keyval == NUX_VK_x) && ctrl && !shift) ||
115+ ((keyval == NUX_VK_DELETE) && shift && !ctrl))
116+ {
117+ Cut();
118+ }
119+ else if (((keyval == NUX_VK_c) && ctrl && (!shift)) ||
120+ ((keyval == NUX_VK_INSERT) && ctrl && (!shift)))
121+ {
122+ Copy();
123+ }
124+ else if (((keyval == NUX_VK_v) && ctrl && (!shift)) ||
125+ ((keyval == NUX_VK_INSERT) && shift && (!ctrl)))
126+ {
127+ Paste();
128 }
129 else
130 {
131- gtk_im_context_focus_out(im_context_);
132- gtk_im_context_reset(im_context_);
133- }
134+ return false;
135+ }
136+ return true;
137+}
138+
139+void IMTextEntry::Cut()
140+{
141+ Copy();
142+ DeleteSelection();
143+}
144+
145+void IMTextEntry::Copy()
146+{
147+ int start=0, end=0;
148+ if (GetSelectionBounds(&start, &end))
149+ {
150+ GtkClipboard* clip = gtk_clipboard_get_for_display(gdk_display_get_default(),
151+ GDK_SELECTION_CLIPBOARD);
152+ gtk_clipboard_set_text(clip, _text.c_str() + start, end - start);
153+ }
154+}
155+
156+void IMTextEntry::Paste()
157+{
158+ GtkClipboard* clip = gtk_clipboard_get_for_display(gdk_display_get_default(),
159+ GDK_SELECTION_CLIPBOARD);
160+ auto callback = [](GtkClipboard* clip, const char* text, gpointer user_data)
161+ {
162+ IMTextEntry* self = static_cast<IMTextEntry*>(user_data);
163+ self->OnCommit (self->im_context_, const_cast<char*>(text));
164+ };
165+
166+ gtk_clipboard_request_text(clip, callback, this);
167 }
168
169 void IMTextEntry::OnCommit(GtkIMContext* context, char* str)
170@@ -191,6 +240,7 @@
171 int cursor = cursor_;
172 SetText(new_text.c_str());
173 SetCursor(cursor + strlen(str));
174+ UpdateCursorLocation();
175 }
176 }
177
178@@ -223,6 +273,30 @@
179 LOG_DEBUG(logger) << "Preedit ended";
180 }
181
182+void IMTextEntry::OnFocusIn()
183+{
184+ focused_ = true;
185+ gtk_im_context_focus_in(im_context_);
186+ gtk_im_context_reset(im_context_);
187+ UpdateCursorLocation();
188+}
189+
190+void IMTextEntry::OnFocusOut()
191+{
192+ focused_ = false;
193+ gtk_im_context_focus_out(im_context_);
194+}
195+
196+void IMTextEntry::UpdateCursorLocation()
197+{
198+ nux::Rect strong, weak;
199+ GetCursorRects(&strong, &weak);
200+ nux::Geometry geo = GetGeometry();
201+
202+ GdkRectangle area = { strong.x + geo.x, strong.y + geo.y, strong.width, strong.height };
203+ gtk_im_context_set_cursor_location(im_context_, &area);
204+}
205+
206 void IMTextEntry::OnMouseButtonUp(int x, int y, unsigned long bflags, unsigned long kflags)
207 {
208 if (nux::GetEventButton(bflags) == 3 && im_enabled_)
209
210=== modified file 'plugins/unityshell/src/IMTextEntry.h'
211--- plugins/unityshell/src/IMTextEntry.h 2011-08-18 15:10:37 +0000
212+++ plugins/unityshell/src/IMTextEntry.h 2011-08-31 20:22:26 +0000
213@@ -53,13 +53,20 @@
214 bool TryHandleEvent(unsigned int eventType, unsigned int keysym, const char* character);
215 void KeyEventToGdkEventKey(Event& event, GdkEventKey& gdk_event);
216 inline void CheckValidClientWindow(Window window);
217+ bool TryHandleSpecial(unsigned int eventType, unsigned int keysym, const char* character);
218+ void Cut();
219+ void Copy();
220+ void Paste();
221
222- void OnFocusChanged(nux::Area* area);
223 void OnCommit(GtkIMContext* context, char* str);
224 void OnPreeditChanged(GtkIMContext* context);
225 void OnPreeditStart(GtkIMContext* context);
226 void OnPreeditEnd(GtkIMContext* context);
227
228+ void OnFocusIn();
229+ void OnFocusOut();
230+ void UpdateCursorLocation();
231+
232 void OnMouseButtonUp(int x, int y, unsigned long bflags, unsigned long kflags);
233
234 private:
235@@ -68,6 +75,7 @@
236 GdkWindow* client_window_;
237 bool im_enabled_;
238 bool im_active_;
239+ bool focused_;
240 };
241
242 }
243
244=== modified file 'plugins/unityshell/src/PlacesHomeView.cpp'
245--- plugins/unityshell/src/PlacesHomeView.cpp 2011-08-24 21:47:34 +0000
246+++ plugins/unityshell/src/PlacesHomeView.cpp 2011-08-31 20:22:26 +0000
247@@ -101,12 +101,12 @@
248 _layout->SetChildrenSize(style->GetHomeTileWidth(), style->GetHomeTileHeight());
249 _layout->EnablePartialVisibility(false);
250 _layout->SetHeightMatchContent(true);
251- _layout->SetVerticalExternalMargin(32);
252+ //_layout->SetVerticalExternalMargin(24);
253 _layout->SetHorizontalExternalMargin(32);
254 _layout->SetVerticalInternalMargin(32);
255 _layout->SetHorizontalInternalMargin(32);
256 _layout->SetMinMaxSize((style->GetHomeTileWidth() * 4) + (32 * 5),
257- (style->GetHomeTileHeight() * 2) + (32 * 3));
258+ (style->GetHomeTileHeight() * 2) + 32);
259
260 _client = gconf_client_get_default();
261 gconf_client_add_dir(_client,
262
263=== modified file 'tests/standalone_dash.cpp'
264--- tests/standalone_dash.cpp 2011-08-26 14:07:47 +0000
265+++ tests/standalone_dash.cpp 2011-08-31 20:22:26 +0000
266@@ -30,8 +30,8 @@
267 #include "FontSettings.h"
268 #include "DashView.h"
269
270-#define WIDTH 1054
271-#define HEIGHT 640
272+#define WIDTH 958
273+#define HEIGHT 574
274
275 using namespace unity::dash;
276
277@@ -103,7 +103,7 @@
278
279 TestRunner *test_runner = new TestRunner ();
280 wt = nux::CreateGUIThread(TEXT("Unity Dash"),
281- WIDTH+12, HEIGHT+12,
282+ WIDTH, HEIGHT,
283 0,
284 &TestRunner::InitWindowThread,
285 test_runner);