зеркало из https://github.com/mozilla/gecko-dev.git
Bug 478146 [TSF] When dragging application window, candidate window is not moved with application window r=chenn, sr=roc
This commit is contained in:
Родитель
ee324a0550
Коммит
9d9a2dd7ec
|
@ -1551,6 +1551,10 @@ pref("intl.keyboard.per_window_layout", false);
|
|||
// Enable/Disable TSF support
|
||||
pref("intl.enable_tsf_support", false);
|
||||
|
||||
// We need to notify the layout change to TSF, but we cannot check the actual
|
||||
// change now, therefore, we always notify it by this fequency.
|
||||
pref("intl.tsf.on_layout_change_interval", 100);
|
||||
|
||||
// See bug 448927, on topmost panel, some IMEs are not usable on Windows.
|
||||
pref("ui.panel.default_level_parent", false);
|
||||
|
||||
|
|
|
@ -77,6 +77,10 @@ nsTextStore::nsTextStore()
|
|||
|
||||
nsTextStore::~nsTextStore()
|
||||
{
|
||||
if (mCompositionTimer) {
|
||||
mCompositionTimer->Cancel();
|
||||
mCompositionTimer = nsnull;
|
||||
}
|
||||
SaveTextEvent(nsnull);
|
||||
}
|
||||
|
||||
|
@ -1204,6 +1208,29 @@ nsTextStore::OnStartCompositionInternal(ITfCompositionView* pComposition,
|
|||
return S_OK;
|
||||
}
|
||||
|
||||
static PRUint32
|
||||
GetLayoutChangeIntervalTime()
|
||||
{
|
||||
static PRInt32 sTime = -1;
|
||||
if (sTime > 0)
|
||||
return PRUint32(sTime);
|
||||
|
||||
sTime = 100;
|
||||
nsCOMPtr<nsIPrefService> prefs = do_GetService(NS_PREFSERVICE_CONTRACTID);
|
||||
if (!prefs)
|
||||
return PRUint32(sTime);
|
||||
nsCOMPtr<nsIPrefBranch> prefBranch;
|
||||
prefs->GetBranch(nsnull, getter_AddRefs(prefBranch));
|
||||
if (!prefBranch)
|
||||
return PRUint32(sTime);
|
||||
nsresult rv =
|
||||
prefBranch->GetIntPref("intl.tsf.on_layout_change_interval", &sTime);
|
||||
if (NS_FAILED(rv))
|
||||
return PRUint32(sTime);
|
||||
sTime = PR_MAX(10, sTime);
|
||||
return PRUint32(sTime);
|
||||
}
|
||||
|
||||
STDMETHODIMP
|
||||
nsTextStore::OnStartComposition(ITfCompositionView* pComposition,
|
||||
BOOL* pfOk)
|
||||
|
@ -1218,9 +1245,18 @@ nsTextStore::OnStartComposition(ITfCompositionView* pComposition,
|
|||
HRESULT hr = pComposition->GetRange(getter_AddRefs(range));
|
||||
NS_ENSURE_TRUE(SUCCEEDED(hr), hr);
|
||||
hr = OnStartCompositionInternal(pComposition, range, PR_FALSE);
|
||||
if (SUCCEEDED(hr))
|
||||
*pfOk = TRUE;
|
||||
return hr;
|
||||
if (FAILED(hr))
|
||||
return hr;
|
||||
|
||||
NS_ASSERTION(!mCompositionTimer, "The timer is alive!");
|
||||
mCompositionTimer = do_CreateInstance(NS_TIMER_CONTRACTID);
|
||||
if (mCompositionTimer) {
|
||||
mCompositionTimer->InitWithFuncCallback(CompositionTimerCallbackFunc, this,
|
||||
GetLayoutChangeIntervalTime(),
|
||||
nsITimer::TYPE_REPEATING_SLACK);
|
||||
}
|
||||
*pfOk = TRUE;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP
|
||||
|
@ -1272,6 +1308,11 @@ nsTextStore::OnEndComposition(ITfCompositionView* pComposition)
|
|||
// Clear the saved text event
|
||||
SaveTextEvent(nsnull);
|
||||
|
||||
if (mCompositionTimer) {
|
||||
mCompositionTimer->Cancel();
|
||||
mCompositionTimer = nsnull;
|
||||
}
|
||||
|
||||
// Use NS_TEXT_TEXT to commit composition string
|
||||
nsTextEvent textEvent(PR_TRUE, NS_TEXT_TEXT, mWindow);
|
||||
mWindow->InitEvent(textEvent);
|
||||
|
@ -1353,6 +1394,22 @@ nsTextStore::OnSelectionChangeInternal(void)
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsTextStore::OnCompositionTimer()
|
||||
{
|
||||
NS_ENSURE_TRUE(mContext, NS_ERROR_FAILURE);
|
||||
NS_ENSURE_TRUE(mSink, NS_ERROR_FAILURE);
|
||||
|
||||
// XXXmnakano We always call OnLayoutChange for now, but this might use CPU
|
||||
// power when the focused editor has very long text. Ideally, we should call
|
||||
// this only when the composition string screen position is changed by window
|
||||
// moving, resizing. And also reflowing and scrolling the contents.
|
||||
HRESULT hr = mSink->OnLayoutChange(TS_LC_CHANGE, TEXTSTORE_DEFAULT_VIEW);
|
||||
NS_ENSURE_TRUE(SUCCEEDED(hr), NS_ERROR_FAILURE);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
void
|
||||
nsTextStore::CommitCompositionInternal(PRBool aDiscard)
|
||||
{
|
||||
|
|
|
@ -41,6 +41,8 @@
|
|||
|
||||
#include "nsAutoPtr.h"
|
||||
#include "nsString.h"
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsITimer.h"
|
||||
|
||||
#include <msctf.h>
|
||||
#include <textstor.h>
|
||||
|
@ -149,6 +151,12 @@ public:
|
|||
return sTsfTextStore->OnSelectionChangeInternal();
|
||||
}
|
||||
|
||||
static void CompositionTimerCallbackFunc(nsITimer *aTimer, void *aClosure)
|
||||
{
|
||||
nsTextStore *ts = static_cast<nsTextStore*>(aClosure);
|
||||
ts->OnCompositionTimer();
|
||||
}
|
||||
|
||||
// Returns the address of the pointer so that the TSF automatic test can
|
||||
// replace the system object with a custom implementation for testing.
|
||||
static void* GetThreadMgr(void)
|
||||
|
@ -193,6 +201,7 @@ protected:
|
|||
TF_DISPLAYATTRIBUTE* aResult);
|
||||
HRESULT SendTextEventForCompositionString();
|
||||
HRESULT SaveTextEvent(const nsTextEvent* aEvent);
|
||||
nsresult OnCompositionTimer();
|
||||
|
||||
// Document manager for the currently focused editor
|
||||
nsRefPtr<ITfDocumentMgr> mDocumentMgr;
|
||||
|
@ -232,6 +241,9 @@ protected:
|
|||
// The latest text event which was dispatched for composition string
|
||||
// of the current composing transaction.
|
||||
nsTextEvent* mLastDispatchedTextEvent;
|
||||
// Timer for calling ITextStoreACPSink::OnLayoutChange. This is only used
|
||||
// during composing.
|
||||
nsCOMPtr<nsITimer> mCompositionTimer;
|
||||
|
||||
// TSF thread manager object for the current application
|
||||
static ITfThreadMgr* sTsfThreadMgr;
|
||||
|
|
Загрузка…
Ссылка в новой задаче