OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include <msctf.h> | 5 #include <msctf.h> |
6 #include "base/logging.h" | 6 #include "base/logging.h" |
7 #include "base/memory/ref_counted.h" | 7 #include "base/memory/ref_counted.h" |
8 #include "base/memory/scoped_ptr.h" | 8 #include "base/memory/scoped_ptr.h" |
9 #include "base/memory/singleton.h" | 9 #include "base/memory/singleton.h" |
10 #include "base/message_loop.h" | 10 #include "base/message_loop.h" |
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
97 | 97 |
98 DCHECK(text_store_.get()); | 98 DCHECK(text_store_.get()); |
99 text_store_.reset(); | 99 text_store_.reset(); |
100 client_id_ = TF_CLIENTID_NULL; | 100 client_id_ = TF_CLIENTID_NULL; |
101 } | 101 } |
102 | 102 |
103 // TsfBridge override. | 103 // TsfBridge override. |
104 virtual bool EnableIME() OVERRIDE { | 104 virtual bool EnableIME() OVERRIDE { |
105 DCHECK_EQ(MessageLoop::TYPE_UI, MessageLoop::current()->type()); | 105 DCHECK_EQ(MessageLoop::TYPE_UI, MessageLoop::current()->type()); |
106 DCHECK(IsInitialized()); | 106 DCHECK(IsInitialized()); |
107 if (SUCCEEDED(thread_manager_->SetFocus(document_manager_))) { | 107 |
108 return true; | 108 // Since EnableIME and DisableIME are designed to be a swap operation of |
109 } | 109 // |document_manager_| and |disabled_document_manager_|, do nothing unless |
110 return false; | 110 // the current focused document manager is |disabled_document_manager_|. |
| 111 // In other words, ITfThreadMgr::SetFocus should be called if and only if |
| 112 // TsfBridge actually has TSF input focus. Otherwise, TSF input focus will |
| 113 // be inconsistent with Win32 input focus. |
| 114 if (!IsFocused(disabled_document_manager_)) |
| 115 return false; |
| 116 |
| 117 return SUCCEEDED(thread_manager_->SetFocus(document_manager_)); |
111 } | 118 } |
112 | 119 |
113 // TsfBridge override. | 120 // TsfBridge override. |
114 virtual bool DisableIME() OVERRIDE { | 121 virtual bool DisableIME() OVERRIDE { |
115 DCHECK_EQ(MessageLoop::TYPE_UI, MessageLoop::current()->type()); | 122 DCHECK_EQ(MessageLoop::TYPE_UI, MessageLoop::current()->type()); |
116 DCHECK(IsInitialized()); | 123 DCHECK(IsInitialized()); |
117 if (SUCCEEDED(thread_manager_->SetFocus(disabled_document_manager_))) { | 124 |
118 return true; | 125 // Do nothing unless the current focused document manager is |
119 } | 126 // |document_manager_|. See the comment in EnableIME. |
120 return false; | 127 if (!IsFocused(document_manager_)) |
| 128 return false; |
| 129 |
| 130 return SUCCEEDED(thread_manager_->SetFocus(disabled_document_manager_)); |
121 } | 131 } |
122 | 132 |
123 // TsfBridge override. | 133 // TsfBridge override. |
124 virtual bool CancelComposition() OVERRIDE { | 134 virtual bool CancelComposition() OVERRIDE { |
125 DCHECK_EQ(MessageLoop::TYPE_UI, MessageLoop::current()->type()); | 135 DCHECK_EQ(MessageLoop::TYPE_UI, MessageLoop::current()->type()); |
126 DCHECK(IsInitialized()); | 136 DCHECK(IsInitialized()); |
127 // If current focused document manager is not |document_manager_|, do | 137 // If the current focused document manager is not |document_manager_|, do |
128 // nothing here. | 138 // nothing here. |
129 base::win::ScopedComPtr<ITfDocumentMgr> focused_document_mangaer; | 139 if (!IsFocused(document_manager_)) |
130 if (FAILED(thread_manager_->GetFocus(focused_document_mangaer.Receive()))) | |
131 return false; | |
132 if (!focused_document_mangaer.IsSameObject(document_manager_)) | |
133 return false; | 140 return false; |
134 | 141 |
135 base::win::ScopedComPtr<ITfContext> context; | 142 base::win::ScopedComPtr<ITfContext> context; |
136 if (FAILED(document_manager_->GetTop(context.Receive()))) { | 143 if (FAILED(document_manager_->GetTop(context.Receive()))) { |
137 VLOG(1) << "Failed to get top context."; | 144 VLOG(1) << "Failed to get top context."; |
138 return false; | 145 return false; |
139 } | 146 } |
140 | 147 |
141 base::win::ScopedComPtr<ITfContextOwnerCompositionServices> owner; | 148 base::win::ScopedComPtr<ITfContextOwnerCompositionServices> owner; |
142 if (FAILED(owner.QueryFrom(context))) { | 149 if (FAILED(owner.QueryFrom(context))) { |
(...skipping 143 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
286 } | 293 } |
287 | 294 |
288 if (FAILED(disabled_document_manager_->Push(disabled_context))) { | 295 if (FAILED(disabled_document_manager_->Push(disabled_context))) { |
289 VLOG(1) << "Failed to push disabled context."; | 296 VLOG(1) << "Failed to push disabled context."; |
290 return false; | 297 return false; |
291 } | 298 } |
292 | 299 |
293 return true; | 300 return true; |
294 } | 301 } |
295 | 302 |
| 303 // Returns true if |document_manager| is the focused document manager. |
| 304 bool IsFocused(base::win::ScopedComPtr<ITfDocumentMgr> document_manager) { |
| 305 base::win::ScopedComPtr<ITfDocumentMgr> focused_document_mangaer; |
| 306 if (FAILED(thread_manager_->GetFocus(focused_document_mangaer.Receive()))) |
| 307 return false; |
| 308 return focused_document_mangaer.IsSameObject(document_manager); |
| 309 } |
| 310 |
296 // Returns true if already initialized. | 311 // Returns true if already initialized. |
297 bool IsInitialized() { | 312 bool IsInitialized() { |
298 return client_id_ != TF_CLIENTID_NULL; | 313 return client_id_ != TF_CLIENTID_NULL; |
299 } | 314 } |
300 | 315 |
301 // An ITfContext object to be used in normal text field. | 316 // An ITfContext object to be used in normal text field. |
302 base::win::ScopedComPtr<ITfDocumentMgr> document_manager_; | 317 base::win::ScopedComPtr<ITfDocumentMgr> document_manager_; |
303 | 318 |
304 // Altough TSF support IME enable/disable switching without context changing, | 319 // Altough TSF support IME enable/disable switching without context changing, |
305 // some IMEs don't change their state. So we should switch a focus to a | 320 // some IMEs don't change their state. So we should switch a focus to a |
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
357 VLOG(1) << "Do not use TsfBridge without UI thread."; | 372 VLOG(1) << "Do not use TsfBridge without UI thread."; |
358 return NULL; | 373 return NULL; |
359 } | 374 } |
360 TsfBridgeDelegate* delegate = | 375 TsfBridgeDelegate* delegate = |
361 static_cast<TsfBridgeDelegate*>(tls_tsf_bridge.Get()); | 376 static_cast<TsfBridgeDelegate*>(tls_tsf_bridge.Get()); |
362 DCHECK(delegate) << "Do no call GetInstance before TsfBridge::Initialize."; | 377 DCHECK(delegate) << "Do no call GetInstance before TsfBridge::Initialize."; |
363 return delegate; | 378 return delegate; |
364 } | 379 } |
365 | 380 |
366 } // namespace ui | 381 } // namespace ui |
OLD | NEW |