| 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 | 6 |
| 7 #include <map> | 7 #include <map> |
| 8 | 8 |
| 9 #include "base/logging.h" | 9 #include "base/logging.h" |
| 10 #include "base/memory/ref_counted.h" | 10 #include "base/memory/ref_counted.h" |
| (...skipping 21 matching lines...) Expand all Loading... |
| 32 public: | 32 public: |
| 33 TSFBridgeDelegate(); | 33 TSFBridgeDelegate(); |
| 34 virtual ~TSFBridgeDelegate(); | 34 virtual ~TSFBridgeDelegate(); |
| 35 | 35 |
| 36 bool Initialize(); | 36 bool Initialize(); |
| 37 | 37 |
| 38 // TsfBridge: | 38 // TsfBridge: |
| 39 virtual void OnTextInputTypeChanged(const TextInputClient* client) OVERRIDE; | 39 virtual void OnTextInputTypeChanged(const TextInputClient* client) OVERRIDE; |
| 40 virtual void OnTextLayoutChanged() OVERRIDE; | 40 virtual void OnTextLayoutChanged() OVERRIDE; |
| 41 virtual bool CancelComposition() OVERRIDE; | 41 virtual bool CancelComposition() OVERRIDE; |
| 42 virtual bool ConfirmComposition() OVERRIDE; |
| 42 virtual void SetFocusedClient(HWND focused_window, | 43 virtual void SetFocusedClient(HWND focused_window, |
| 43 TextInputClient* client) OVERRIDE; | 44 TextInputClient* client) OVERRIDE; |
| 44 virtual void RemoveFocusedClient(TextInputClient* client) OVERRIDE; | 45 virtual void RemoveFocusedClient(TextInputClient* client) OVERRIDE; |
| 45 virtual base::win::ScopedComPtr<ITfThreadMgr> GetThreadManager() OVERRIDE; | 46 virtual base::win::ScopedComPtr<ITfThreadMgr> GetThreadManager() OVERRIDE; |
| 46 virtual TextInputClient* GetFocusedTextInputClient() const OVERRIDE; | 47 virtual TextInputClient* GetFocusedTextInputClient() const OVERRIDE; |
| 47 | 48 |
| 48 private: | 49 private: |
| 49 // Returns true if |tsf_document_map_| is successfully initialized. This | 50 // Returns true if |tsf_document_map_| is successfully initialized. This |
| 50 // method should be called from and only from Initialize(). | 51 // method should be called from and only from Initialize(). |
| 51 bool InitializeDocumentMapInternal(); | 52 bool InitializeDocumentMapInternal(); |
| (...skipping 154 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 206 return; | 207 return; |
| 207 if (!document->text_store) | 208 if (!document->text_store) |
| 208 return; | 209 return; |
| 209 document->text_store->SendOnLayoutChange(); | 210 document->text_store->SendOnLayoutChange(); |
| 210 } | 211 } |
| 211 | 212 |
| 212 bool TSFBridgeDelegate::CancelComposition() { | 213 bool TSFBridgeDelegate::CancelComposition() { |
| 213 DCHECK_EQ(base::MessageLoop::TYPE_UI, base::MessageLoop::current()->type()); | 214 DCHECK_EQ(base::MessageLoop::TYPE_UI, base::MessageLoop::current()->type()); |
| 214 DCHECK(IsInitialized()); | 215 DCHECK(IsInitialized()); |
| 215 | 216 |
| 216 base::win::ScopedComPtr<ITfDocumentMgr> focused_document_manager; | 217 TSFDocument* document = GetAssociatedDocument(); |
| 217 for (TSFDocumentMap::iterator it = tsf_document_map_.begin(); | 218 if (!document) |
| 218 it != tsf_document_map_.end(); ++it) { | 219 return false; |
| 219 if (IsFocused(it->second.document_manager.get())) { | 220 if (!document->text_store) |
| 220 focused_document_manager = it->second.document_manager.get(); | |
| 221 break; | |
| 222 } | |
| 223 } | |
| 224 | |
| 225 if (focused_document_manager.get() == NULL) | |
| 226 return false; | 221 return false; |
| 227 | 222 |
| 228 base::win::ScopedComPtr<ITfContext> context; | 223 return document->text_store->CancelComposition(); |
| 229 // We should use ITfDocumentMgr::GetBase instead of ITfDocumentMgr::GetTop, | 224 } |
| 230 // which may return a temporal context created by an IME for its modal UI | 225 |
| 231 // handling, to obtain a context against which on-going composition is | 226 bool TSFBridgeDelegate::ConfirmComposition() { |
| 232 // canceled. This is because ITfDocumentMgr::GetBase always returns the | 227 DCHECK_EQ(base::MessageLoop::TYPE_UI, base::MessageLoop::current()->type()); |
| 233 // context that is created by us and owns the on-going composition. | 228 DCHECK(IsInitialized()); |
| 234 // See http://crbug.com/169664 for details. | 229 |
| 235 if (FAILED(focused_document_manager->GetBase(context.Receive()))) { | 230 TSFDocument* document = GetAssociatedDocument(); |
| 236 DVLOG(1) << "Failed to get top context."; | 231 if (!document) |
| 237 return false; | 232 return false; |
| 238 } | 233 if (!document->text_store) |
| 234 return false; |
| 239 | 235 |
| 240 base::win::ScopedComPtr<ITfContextOwnerCompositionServices> owner; | 236 return document->text_store->ConfirmComposition(); |
| 241 if (FAILED(owner.QueryFrom(context))) { | |
| 242 DVLOG(1) << "Failed to get ITfContextOwnerCompositionService."; | |
| 243 return false; | |
| 244 } | |
| 245 // Cancel all compositions. | |
| 246 owner->TerminateComposition(NULL); | |
| 247 return true; | |
| 248 } | 237 } |
| 249 | 238 |
| 250 void TSFBridgeDelegate::SetFocusedClient(HWND focused_window, | 239 void TSFBridgeDelegate::SetFocusedClient(HWND focused_window, |
| 251 TextInputClient* client) { | 240 TextInputClient* client) { |
| 252 DCHECK_EQ(base::MessageLoop::TYPE_UI, base::MessageLoop::current()->type()); | 241 DCHECK_EQ(base::MessageLoop::TYPE_UI, base::MessageLoop::current()->type()); |
| 253 DCHECK(client); | 242 DCHECK(client); |
| 254 DCHECK(IsInitialized()); | 243 DCHECK(IsInitialized()); |
| 255 client_ = client; | 244 client_ = client; |
| 256 | 245 |
| 257 for (TSFDocumentMap::iterator it = tsf_document_map_.begin(); | 246 for (TSFDocumentMap::iterator it = tsf_document_map_.begin(); |
| (...skipping 241 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 499 return delegate; | 488 return delegate; |
| 500 } | 489 } |
| 501 | 490 |
| 502 // static | 491 // static |
| 503 void TSFBridge::Finalize(void* data) { | 492 void TSFBridge::Finalize(void* data) { |
| 504 TSFBridgeDelegate* delegate = static_cast<TSFBridgeDelegate*>(data); | 493 TSFBridgeDelegate* delegate = static_cast<TSFBridgeDelegate*>(data); |
| 505 delete delegate; | 494 delete delegate; |
| 506 } | 495 } |
| 507 | 496 |
| 508 } // namespace ui | 497 } // namespace ui |
| OLD | NEW |