Commit 3bbbbb2e authored by Makoto Kato's avatar Makoto Kato
Browse files

Bug 968647 - Part 3. TSF should use postion change notification instead of nsITimer. r=masayuki

parent 0cbf66c2
Loading
Loading
Loading
Loading
+0 −4
Original line number Diff line number Diff line
@@ -2575,10 +2575,6 @@ pref("intl.tsf.enable", false);
// Support IMEs implemented with IMM in TSF mode.
pref("intl.tsf.support_imm", true);

// 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);

// Enables/Disables hack for specific TIP.

// Whether creates native caret for ATOK or not.
+2 −0
Original line number Diff line number Diff line
@@ -183,6 +183,8 @@ IMEHandler::NotifyIME(nsWindow* aWindow,
          nsTextStore::CommitComposition(true);
        }
        return NS_OK;
      case NOTIFY_IME_OF_POSITION_CHANGE:
        return nsTextStore::OnLayoutChange();
      default:
        return NS_ERROR_NOT_IMPLEMENTED;
    }
+3 −56
Original line number Diff line number Diff line
@@ -29,8 +29,6 @@ using namespace mozilla;
using namespace mozilla::widget;

static const char* kPrefNameTSFEnabled = "intl.tsf.enable";
static const char* kPrefNameLayoutChangeInternal =
                     "intl.tsf.on_layout_change_interval";

static const char* kLegacyPrefNameTSFEnabled = "intl.enable_tsf_support";

@@ -636,8 +634,6 @@ nsTextStore::~nsTextStore()
      }
    }
  }

  mComposition.EnsureLayoutChangeTimerStopped();
}

bool
@@ -1047,7 +1043,6 @@ nsTextStore::FlushPendingActions()
        if (!mWidget || mWidget->Destroyed()) {
          break;
        }
        mComposition.StartLayoutChangeTimer(this);
        break;
      }
      case PendingAction::COMPOSITION_UPDATE: {
@@ -1137,8 +1132,6 @@ nsTextStore::FlushPendingActions()
                "flushing COMPOSITION_END={ mData=\"%s\" }",
                this, NS_ConvertUTF16toUTF8(action.mData).get()));

        mComposition.EnsureLayoutChangeTimerStopped();

        action.mData.ReplaceSubstring(NS_LITERAL_STRING("\r\n"),
                                      NS_LITERAL_STRING("\n"));
        if (action.mData != mComposition.mLastData) {
@@ -1207,8 +1200,6 @@ nsTextStore::FlushPendingActions()
      continue;
    }

    mComposition.EnsureLayoutChangeTimerStopped();

    PR_LOG(sTextStoreLog, PR_LOG_ALWAYS,
           ("TSF: 0x%p   nsTextStore::FlushPendingActions(), "
            "qutting since the mWidget has gone", this));
@@ -3178,6 +3169,7 @@ nsTextStore::GetIMEUpdatePreference()
      nsIMEUpdatePreference updatePreference(
        nsIMEUpdatePreference::NOTIFY_SELECTION_CHANGE |
        nsIMEUpdatePreference::NOTIFY_TEXT_CHANGE |
        nsIMEUpdatePreference::NOTIFY_POSITION_CHANGE |
        nsIMEUpdatePreference::NOTIFY_DURING_DEACTIVE);
      // nsTextStore shouldn't notify TSF of selection change and text change
      // which are caused by composition.
@@ -3299,17 +3291,13 @@ nsTextStore::OnSelectionChangeInternal(void)
}

nsresult
nsTextStore::OnLayoutChange()
nsTextStore::OnLayoutChangeInternal()
{
  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.
  PR_LOG(sTextStoreLog, PR_LOG_ALWAYS,
         ("TSF: 0x%p   nsTextStore::OnLayoutChange(), calling "
         ("TSF: 0x%p   nsTextStore::OnLayoutChangeInternal(), calling "
          "mSink->OnLayoutChange()...", this));
  HRESULT hr = mSink->OnLayoutChange(TS_LC_CHANGE, TEXTSTORE_DEFAULT_VIEW);
  NS_ENSURE_TRUE(SUCCEEDED(hr), NS_ERROR_FAILURE);
@@ -3992,47 +3980,6 @@ nsTextStore::Composition::End()
  mString.Truncate();
}

void
nsTextStore::Composition::StartLayoutChangeTimer(nsTextStore* aTextStore)
{
  MOZ_ASSERT(!mLayoutChangeTimer);
  mLayoutChangeTimer = do_CreateInstance(NS_TIMER_CONTRACTID);
  mLayoutChangeTimer->InitWithFuncCallback(TimerCallback, aTextStore,
    GetLayoutChangeIntervalTime(), nsITimer::TYPE_REPEATING_SLACK);
}

void
nsTextStore::Composition::EnsureLayoutChangeTimerStopped()
{
  if (!mLayoutChangeTimer) {
    return;
  }
  mLayoutChangeTimer->Cancel();
  mLayoutChangeTimer = nullptr;
}

// static
void
nsTextStore::Composition::TimerCallback(nsITimer* aTimer, void* aClosure)
{
  nsTextStore *ts = static_cast<nsTextStore*>(aClosure);
  ts->OnLayoutChange();
}

// static
uint32_t
nsTextStore::Composition::GetLayoutChangeIntervalTime()
{
  static int32_t sTime = -1;
  if (sTime > 0) {
    return static_cast<uint32_t>(sTime);
  }

  sTime = std::max(10,
    Preferences::GetInt(kPrefNameLayoutChangeInternal, 100));
  return static_cast<uint32_t>(sTime);
}

/******************************************************************************
 *  nsTextStore::Content
 *****************************************************************************/
+7 −13
Original line number Diff line number Diff line
@@ -9,7 +9,6 @@
#include "nsAutoPtr.h"
#include "nsString.h"
#include "nsCOMPtr.h"
#include "nsITimer.h"
#include "nsIWidget.h"
#include "nsWindowBase.h"
#include "mozilla/Attributes.h"
@@ -148,6 +147,12 @@ public:
    return sTsfTextStore->OnSelectionChangeInternal();
  }

  static nsresult OnLayoutChange()
  {
    NS_ENSURE_TRUE(sTsfTextStore, NS_ERROR_NOT_AVAILABLE);
    return sTsfTextStore->OnLayoutChangeInternal();
  }

  static nsIMEUpdatePreference GetIMEUpdatePreference();

  // Returns the address of the pointer so that the TSF automatic test can
@@ -276,7 +281,7 @@ protected:
  // and clear it.
  void     FlushPendingActions();

  nsresult OnLayoutChange();
  nsresult OnLayoutChangeInternal();
  HRESULT  ProcessScopeRequest(DWORD dwFlags,
                               ULONG cFilterAttrs,
                               const TS_ATTRID *paFilterAttrs);
@@ -350,17 +355,6 @@ protected:
               LONG aCompositionStartOffset,
               const nsAString& aCompositionString);
    void End();

    void StartLayoutChangeTimer(nsTextStore* aTextStore);
    void EnsureLayoutChangeTimerStopped();

  private:
    // Timer for calling ITextStoreACPSink::OnLayoutChange(). This is only used
    // during composing.
    nsCOMPtr<nsITimer> mLayoutChangeTimer;

    static void TimerCallback(nsITimer* aTimer, void *aClosure);
    static uint32_t GetLayoutChangeIntervalTime();
  };
  // While the document is locked, we cannot dispatch any events which cause
  // DOM events since the DOM events' handlers may modify the locked document.
+2 −0
Original line number Diff line number Diff line
@@ -1604,6 +1604,8 @@ MetroWidget::NotifyIME(const IMENotification& aIMENotification)
      return nsTextStore::OnSelectionChange();
    case NOTIFY_IME_OF_TEXT_CHANGE:
      return nsTextStore::OnTextChange(aIMENotification);
    case NOTIFY_IME_OF_POSITION_CHANGE:
      return nsTextStore::OnLayoutChange();
    default:
      return NS_ERROR_NOT_IMPLEMENTED;
  }