候補ウィンドウの遅延表示機能を追加したのですが(r7323)、
(現状はgtk-immoduleとuim-ximのみ)
インタフェース変更無しで無理やり機能追加したため汚くなっているので、
ブリッジとscm間のインタフェース(C APIとScheme API)に遅延表示用の
追加をしたいと思っています(添付パッチ)。

* 遅延表示の目的
  ユーザが入力時に予測入力やヘルプの処理完了を待たずにすむようにすること。
 + 一定時間キー入力が無い場合のみ予測入力候補やヘルプ(仮想鍵盤等)を表示
   (迷わず入力している間は余計なヘルプは表示しない)。
#  (1文字入力するたびにヘルプを表示すると、表示後すぐ消えてちらちら目ざわり)
#  (文字入力直後にscm側で予測入力候補検索処理を開始すると、
#   その間に入力した文字の表示が検索完了後になるので、使い勝手が良くない。)
 + uim-tutcodeの場合、交ぜ書き変換等で確定した文字に対する
   自動ヘルプ(打鍵シーケンスや部首合成方法)の作成に少し時間がかかるため、
   以降の文字のキーを入力しても、入力した文字が表示されるのは
   自動ヘルプが表示された後になり、使い勝手が良くない問題への対処。

* 現状の遅延表示実装の問題点
  インタフェースの変更無しで機能追加したため、
  get-candidate-handlerのaccel_enum引数に普通は使わない値を入れて、
  候補ウィンドウとscm側でやりとりを行っています。
  インタフェースを用途を外れて使っているため、気持ち悪さがあります。
 
* インタフェース変更
  以下のインタフェースを追加して、書き直したものにしたいと思っています。
  なるべく既存のブリッジやIMは変更不要な形にしています。
# 表形式候補ウィンドウ用display_limit調整機能は削りました。(uim-qtにも
# 表形式候補ウィンドウは追加されましたし、必要な場面は少ないと思うので)

uim.h:
- scm側から遅延表示が依頼された(im-delay-activate-candidate-selector)時に
  呼ばれる関数を登録。
void uim_set_delay_candidate_selector_cb(uim_context uc,
    void (*delay_activate_cb)(void *ptr, int delay));

+ 遅延タイマ満了をscm側に通知。
  scm側は候補リストを作成し、候補数、ページ内表示数、
  選択されているインデックス番号の値を設定して返す。
void uim_delay_activating(uim_context uc, int *nr, int *display_limit,
    int *selected_index);

uim-func.c:
- 遅延表示を依頼
(im-delay-activate-candidate-selector uc delay)

+ 候補ウィンドウが遅延表示に対応しているか調べる
(im-delay-activate-candidate-selector-supported? uc)

im.scm:
+ オプショナルで登録可能なdelay-activating-handlerを追加。
  ブリッジ側からの遅延タイマ満了通知(uim_delay_activating)時に呼ばれる関数。
(im-set-delay-activating-handler! im delay-activating-handler)

* 遅延表示の流れ
candwin                   uim                       tutcode.scm
    uim_set_delay_candidate_selector_cb(delay_activate_cb)
    ----------------------->
                     im-set-delay-activating-handler!(delay-activating-handler)
                           <-----------------------------

                          im-delay-activate-candidate-selector-supported?
                           <-----------------------------
                           -------------#t-------------->
                          im-delay-activate-candidate-selector(遅延秒数)
                           <-----------------------------
    delay_activate_cb(遅延秒数)
    <----------------------
 タイマ設定して待つ
 ...
 タイマ満了
        uim_delay_activating
    ----------------------->
                           delay-activating-handler
                           ----------------------------->
                                                         候補リストを作成する
                           nr,display_limit,selected_indexを返す
                           <-----------------------------
    nr,display_limit,selected_indexを返す
    <----------------------
 通常の候補取得・表示
 selcted_indexが0以上の場合は候補選択


* 参考:インタフェース変更の他の案
+ selected-indexをscm側で保持するかわりに、uimライブラリ側で保持。
  delay-activating-handlerからはselected-indexを返さずに、
  uim側が追加してcandwinに返す。
  + scm側でselected-indexを保持しなくて良い。
  - uimライブラリ側に、shift-pageも考慮してselected-indexを更新する処理を
    追加する必要があり、複雑になる。

+ uim_set_delay_candidate_selector_cb()と
  im-delay-activate-candidate-selector()は追加しないで、
  現状のようにcandidate-window-activate-delay変数で遅延時間を共有する。
  + インタフェース変更が少なくてすむ利点あり。
  + im-delay-activate-candidate-selector()と
    im-activate-candidate-selector()の呼び分けが不要になる利点あり。
  - ブリッジ側からcandidate-window-activate-delay変数を参照するのが
    あまりきれいでない。性能的にも少し気になる。

+ im-activate-candidate-selector()やregister-im()にオプション引数を追加。
  (im-delay-activate-candidate-selector()を追加したり
  im-set-delay-activating-handler!()を使うかわりに)。
  im.scm内部でオプション引数をチェックして遅延用処理と切り替え。
  + IM側でim-delay-activate-candidate-selector()と
    im-activate-candidate-selector()の呼び分けを意識しなくていい利点あり。
  - ブリッジ側と構造が一致しなくなるので少しわかりにくいかも。
  - オプション引数の使用が(わかりやすさや拡張性の面で)適切かどうか少し疑問も。

- uim_set_candidate_selector_cb()に遅延表示用コールバックを指定する引数を追加
  (uim_set_delay_candidate_selector_cb()を追加するかわりに)。
  + コールバックをまとめて登録するインタフェース
  - 遅延表示に対応しないブリッジでもNULLを指定するように変更する必要あり

- uim_set_candidate_selector_cb()で指定するactivate_cbにdelay引数を追加
  (uim_set_delay_candidate_selector_cb()を追加するかわりに)。
  + インタフェースの変更量が少なくてすむ
  - 遅延表示に対応しないブリッジでもコールバック関数定義の変更が必要

- ブリッジからscm側に対し、遅延表示完了の通知インタフェースの追加。
  通知を受けたscm側で、遅延表示待ち中に選択された候補番号を
  im-select-candidate()で指定できるようにするため
  (uim_delay_activating()でselected_indexを返すかわりに)。
  + selected_indexを取得するだけのために
    uim_delay_activating()を呼ぶ必要がなくなる。
  - インタフェースが一つ増える欠点。

-- 
Google Groups "uim-ja" group
uim-ja@googlegroups.com
http://groups.google.com/group/uim-ja/about
Index: scm/tutcode-custom.scm
===================================================================
--- scm/tutcode-custom.scm	(revision 7323)
+++ scm/tutcode-custom.scm	(working copy)
@@ -268,6 +268,12 @@
   (N_ "Show real keys on auto help window")
   (N_ "long description will be here."))
 
+(define-custom 'tutcode-candidate-window-use-delay? #f
+  '(tutcode candwin)
+  '(boolean)
+  (N_ "Use delay showing candidate window")
+  (N_ "long description will be here."))
+
 (define-custom 'tutcode-candidate-window-activate-delay-for-mazegaki 0
   '(tutcode candwin)
   '(integer 0 65535)
Index: scm/tutcode.scm
===================================================================
--- scm/tutcode.scm	(revision 7323)
+++ scm/tutcode.scm	(working copy)
@@ -207,7 +207,7 @@
 ;;;
 ;;; * 次の打鍵がしばらく無い場合に補完/予測入力候補を表示するには、
 ;;;   候補ウィンドウが遅延表示に対応していれば、以下の設定で可能です。
-;;;     candidate-window-use-delay?を#tに設定し、
+;;;     tutcode-candidate-window-use-delay?を#tに設定し、
 ;;;     tutcode-candidate-window-activate-delay-for-{completion,prediction}
 ;;;     の値を1[秒]以上に設定。
 ;;;
@@ -480,12 +480,6 @@
 ;;; 自動ヘルプ作成時間上限[s]
 (define tutcode-auto-help-time-limit 3)
 
-;;; 候補ウィンドウ表示待ち時間[s]
-(define candidate-window-activate-delay 0)
-;;; 候補ウィンドウの遅延表示待ち中に選択された候補のインデックス番号
-(define candidate-window-delay-selected-index -1)
-;;; 候補ウィンドウが遅延表示に対応しているかどうか
-(define tutcode-candidate-window-delay-support? #f)
 ;;; 遅延表示の目的:ユーザが入力時にヘルプや補完の処理完了を待たずにすむように。
 ;;;  + 自動ヘルプの作成に少し時間がかかるため、自動ヘルプが表示されるまでの間に
 ;;;    以降の文字のキー入力をしても入力した文字が表示されない問題に対処
@@ -493,27 +487,23 @@
 ;;;    (迷わず入力している間は余計なヘルプは表示しない)
 ;;; 遅延表示の流れ:
 ;;; candwin                        tutcode.scm
-;;;  [candwin表示時]
+;;; [表示のみを遅延する場合]
 ;;;                                候補リストを作成しnr,display_limitを計算
-;;;                                candidate-window-activate-delayを設定
-;;;                            <-- im-activate-candidate-selector (nr>=0)
-;;;  candidate-window-activate-delayの値が0より大きければタイマ設定して待つ
+;;;                            <-- im-delay-activate-candidate-selector
+;;;  タイマ設定して待つ
 ;;;  タイマ満了
+;;;                            --> delay-activating-handler
+;;;                                nr,display_limit,indexを返す
 ;;;                            --> get-candidate-handler (候補を返す)
 ;;;  候補表示
 ;;;
-;;; さらに、candwinが遅延表示対応なことをscm側が認識すれば、
-;;; 候補リストの作成も遅延可能:
-;;;  [candwinが遅延表示対応なことをscm側に通知(現状はcandwin初回表示時)]
-;;;  --(accel-enum-hint|#x2000)--> get-candidate-handler
-;;;                                  tutcode-candidate-window-delay-support? #t
-;;;  [次回以降のcandwin表示時(遅延表示)]
-;;;                                candidate-window-activate-delayを設定
-;;;                            <-- im-activate-candidate-selector (nr=-1)
-;;;  candidate-window-activate-delayの値が0より大きければタイマ設定して待つ
+;;; [候補リストの作成も遅延する場合]
+;;;                            <-- im-delay-activate-candidate-selector
+;;;  タイマ設定して待つ
 ;;;  タイマ満了
-;;;  --(accel-enum-hint|#x4000)--> get-candidate-handler
-;;;                                  候補リストを作成し、nr,display_limitを返す
+;;;                            --> delay-activating-handler
+;;;                                候補リストを作成し、
+;;;                                nr,display_limit,indexを返す
 ;;;                            --> get-candidate-handler (候補を返す)
 ;;;  候補表示
 ;;;
@@ -733,6 +723,8 @@
      (list 'candidate-window 'tutcode-candidate-window-off)
      ;;; 候補ウィンドウの遅延表示待ち中かどうか
      (list 'candwin-delay-waiting #f)
+     ;;; 候補ウィンドウの遅延表示待ち中に選択された候補のインデックス番号
+     (list 'candwin-delay-selected-index -1)
      ;;; ストローク表
      ;;; 次に入力するキーと文字の対応の、get-candidate-handler用形式でのリスト
      (list 'stroke-help ())
@@ -811,6 +803,7 @@
 ;;; TUT-Codeのコンテキストを新しく生成する。
 ;;; @return 生成したコンテキスト
 (define (tutcode-context-new id im)
+  (im-set-delay-activating-handler! im tutcode-delay-activating-handler)
   (if (not tutcode-dic)
     (if (not (symbol-bound? 'skk-lib-dic-open))
       (begin
@@ -1677,19 +1670,30 @@
 ;;; @param display-limit ページ内候補数
 (define (tutcode-activate-candidate-window pc type delay nr display-limit)
   (tutcode-context-set-candidate-window! pc type)
-  (tutcode-context-set-candwin-delay-waiting! pc #t)
-  (set! candidate-window-delay-selected-index -1)
-  (set! candidate-window-activate-delay delay)
-  (im-activate-candidate-selector pc nr display-limit))
+  (tutcode-context-set-candwin-delay-selected-index! pc -1)
+  (if (tutcode-candidate-window-enable-delay? pc delay)
+    (begin
+      (tutcode-context-set-candwin-delay-waiting! pc #t)
+      (im-delay-activate-candidate-selector pc delay))
+    (begin
+      (tutcode-context-set-candwin-delay-waiting! pc #f)
+      (im-activate-candidate-selector pc nr display-limit))))
 
+;;; 候補ウィンドウの遅延表示を行うかどうかを返す
+;;; @param delay 遅延時間。0の場合は遅延表示はしない。
+(define (tutcode-candidate-window-enable-delay? pc delay)
+  (and tutcode-candidate-window-use-delay?
+       (im-delay-activate-candidate-selector-supported? pc)
+       (> delay 0)))
+
 ;;; 候補ウィンドウ上で候補を選択する
 ;;; @param idx 選択する候補のインデックス番号
 (define (tutcode-select-candidate pc idx)
   (if (tutcode-context-candwin-delay-waiting pc)
     ;; 遅延表示待ち中はcandwinは未作成のためim-select-candidateするとSEGV。
     ;; (XXX (uim api-docに合わせて)candwin側で対処した方がいいかもしれないが、
-    ;;      ブリッジごとに対応が必要なので、とりあえずscm側で。)
-    (set! candidate-window-delay-selected-index idx)
+    ;;      shift-pageとの混在時の計算が面倒なので、とりあえずscm側で。)
+    (tutcode-context-set-candwin-delay-selected-index! pc idx)
     (im-select-candidate pc idx)))
 
 ;;; 仮想鍵盤に表示する候補リストを作って返す
@@ -1766,20 +1770,20 @@
 ;;; 仮想鍵盤の表示を開始する
 (define (tutcode-check-stroke-help-window-begin pc)
   (if (eq? (tutcode-context-candidate-window pc) 'tutcode-candidate-window-off)
-    (if tutcode-candidate-window-delay-support?
+    (if (tutcode-candidate-window-enable-delay? pc
+          tutcode-candidate-window-activate-delay-for-stroke-help)
       ;; XXX:何も表示しない場合にはタイマも動かないようにしたいところ
       (tutcode-activate-candidate-window pc
         'tutcode-candidate-window-stroke-help
         tutcode-candidate-window-activate-delay-for-stroke-help
-        -1
-        tutcode-nr-candidate-max-for-kigou-mode)
+        -1 -1)
       (let ((stroke-help (tutcode-stroke-help-make pc)))
         (if (pair? stroke-help)
           (begin
             (tutcode-context-set-stroke-help! pc stroke-help)
             (tutcode-activate-candidate-window pc
               'tutcode-candidate-window-stroke-help
-              tutcode-candidate-window-activate-delay-for-stroke-help
+              0
               (length stroke-help)
               tutcode-nr-candidate-max-for-kigou-mode)))))))
 
@@ -1974,21 +1978,21 @@
            tutcode-use-auto-help-window?)
     (begin
       (tutcode-context-set-guide-chars! pc ())
-      (if tutcode-candidate-window-delay-support?
+      (if (tutcode-candidate-window-enable-delay? pc
+            tutcode-candidate-window-activate-delay-for-auto-help)
         (begin
           (tutcode-context-set-auto-help! pc (list 'delaytmp strlist yomilist))
           (tutcode-activate-candidate-window pc
             'tutcode-candidate-window-auto-help
             tutcode-candidate-window-activate-delay-for-auto-help
-            -1
-            tutcode-nr-candidate-max-for-kigou-mode))
+            -1 -1))
         (let ((auto-help (tutcode-auto-help-make pc strlist yomilist)))
           (if (pair? auto-help)
             (begin
               (tutcode-context-set-auto-help! pc auto-help)
               (tutcode-activate-candidate-window pc
                 'tutcode-candidate-window-auto-help
-                tutcode-candidate-window-activate-delay-for-auto-help
+                0
                 (length auto-help)
                 tutcode-nr-candidate-max-for-kigou-mode))))))))
 
@@ -2340,21 +2344,19 @@
         (or (>= len tutcode-completion-chars-min)
             (and force-check?
                  (> len 0)))
-        (if (and (not force-check?)
-                 tutcode-candidate-window-delay-support?)
-          (tutcode-activate-candidate-window pc
-            'tutcode-candidate-window-predicting
-            tutcode-candidate-window-activate-delay-for-completion
-            -1
-            tutcode-nr-candidate-max-for-prediction)
-          (if (tutcode-check-completion-make pc force-check? num)
+        (let ((delay
+                (if force-check?
+                  0
+                  tutcode-candidate-window-activate-delay-for-completion)))
+          (if (tutcode-candidate-window-enable-delay? pc delay)
             (tutcode-activate-candidate-window pc
-              'tutcode-candidate-window-predicting
-              (if force-check?
+              'tutcode-candidate-window-predicting delay -1 -1)
+            (if (tutcode-check-completion-make pc force-check? num)
+              (tutcode-activate-candidate-window pc
+                'tutcode-candidate-window-predicting
                 0
-                tutcode-candidate-window-activate-delay-for-completion)
-              (tutcode-context-prediction-nr-all pc)
-              (tutcode-context-prediction-page-limit pc))))))))
+                (tutcode-context-prediction-nr-all pc)
+                (tutcode-context-prediction-page-limit pc)))))))))
 
 ;;; 補完候補を検索して候補リストを作成する
 ;;; @param force-check? 必ず検索を行うかどうか。
@@ -2420,21 +2422,19 @@
       (if
         (or (>= preedit-len tutcode-prediction-start-char-count)
             force-check?)
-        (if (and (not force-check?)
-                 tutcode-candidate-window-delay-support?)
-          (tutcode-activate-candidate-window pc
-            'tutcode-candidate-window-predicting
-            tutcode-candidate-window-activate-delay-for-prediction
-            -1
-            tutcode-nr-candidate-max-for-prediction)
-          (if (tutcode-check-prediction-make pc force-check?)
-            (tutcode-activate-candidate-window pc
-              'tutcode-candidate-window-predicting
+        (let ((delay
               (if force-check?
                 0
-                tutcode-candidate-window-activate-delay-for-prediction)
-              (tutcode-context-prediction-nr-all pc)
-              (tutcode-context-prediction-page-limit pc))))))))
+                tutcode-candidate-window-activate-delay-for-prediction)))
+          (if (tutcode-candidate-window-enable-delay? pc delay)
+            (tutcode-activate-candidate-window pc
+              'tutcode-candidate-window-predicting delay -1 -1)
+            (if (tutcode-check-prediction-make pc force-check?)
+              (tutcode-activate-candidate-window pc
+                'tutcode-candidate-window-predicting
+                0
+                (tutcode-context-prediction-nr-all pc)
+                (tutcode-context-prediction-page-limit pc)))))))))
 
 ;;; 予測入力候補を検索して候補リストを作る
 ;;; @param force-check? 必ず検索を行うかどうか。
@@ -2480,31 +2480,30 @@
 ;;; 部首合成変換中に予測入力候補を検索して候補ウィンドウに(遅延)表示する
 ;;; @param char 入力された部首1
 (define (tutcode-check-bushu-prediction pc char)
-  (if tutcode-candidate-window-delay-support?
+  (if (tutcode-candidate-window-enable-delay? pc
+        tutcode-candidate-window-activate-delay-for-bushu-prediction)
     (begin
       (tutcode-context-set-prediction-bushu! pc char) ; 遅延呼出時用に一時保持
       (tutcode-activate-candidate-window pc
         'tutcode-candidate-window-predicting
         tutcode-candidate-window-activate-delay-for-bushu-prediction
-        -1
-        tutcode-nr-candidate-max-for-prediction))
-    (tutcode-check-bushu-prediction-with-delay pc char
-      tutcode-candidate-window-activate-delay-for-bushu-prediction)))
+        -1 -1))
+    (tutcode-check-bushu-prediction-make pc char #t)))
 
-;;; 部首合成変換中に予測入力候補を検索して候補ウィンドウに表示する
+;;; 部首合成変換中に予測入力候補を検索して候補リストを作成する
 ;;; @param char 入力された部首1
-;;; @param delay 表示待ち時間[s]。遅延呼出しの最中に候補リストを作成する時は-1
-(define (tutcode-check-bushu-prediction-with-delay pc char delay)
+;;; @param show-candwin? 候補リストの作成後候補ウィンドウの表示を行うかどうか
+(define (tutcode-check-bushu-prediction-make pc char show-candwin?)
   (case tutcode-bushu-conversion-algorithm
     ((tc-2.3.1-22.6)
-      (tutcode-check-bushu-prediction-tc23 pc char delay))
+      (tutcode-check-bushu-prediction-tc23 pc char show-candwin?))
     (else ; 'tc-2.1+ml1925
-      (tutcode-check-bushu-prediction-tc21 pc char delay))))
+      (tutcode-check-bushu-prediction-tc21 pc char show-candwin?))))
 
-;;; 部首合成変換中に予測入力候補を検索して候補ウィンドウに表示する
+;;; 部首合成変換中に予測入力候補を検索して候補リストを作成する
 ;;; @param char 入力された部首1
-;;; @param delay 表示待ち時間[s]
-(define (tutcode-check-bushu-prediction-tc21 pc char delay)
+;;; @param show-candwin? 候補リストの作成後候補ウィンドウの表示を行うかどうか
+(define (tutcode-check-bushu-prediction-tc21 pc char show-candwin?)
   (if (eq? (tutcode-context-predicting pc) 'tutcode-predicting-off)
     (let* ((res (tutcode-bushu-predict char tutcode-bushudic))
            (alt (assoc char tutcode-bushudic-altchar))
@@ -2514,12 +2513,12 @@
               ()))
            (resall (append res altres)))
       (tutcode-context-set-prediction-bushu! pc resall)
-      (tutcode-bushu-prediction-show-page pc 0 delay))))
+      (tutcode-bushu-prediction-make-page pc 0 show-candwin?))))
 
-;;; 部首合成変換中に予測入力候補を検索して候補ウィンドウに表示する
+;;; 部首合成変換中に予測入力候補を検索して候補リストを作成する
 ;;; @param char 入力された部首1
-;;; @param delay 表示待ち時間[s]
-(define (tutcode-check-bushu-prediction-tc23 pc char delay)
+;;; @param show-candwin? 候補リストの作成後候補ウィンドウの表示を行うかどうか
+(define (tutcode-check-bushu-prediction-tc23 pc char show-candwin?)
   (if (eq? (tutcode-context-predicting pc) 'tutcode-predicting-off)
     (let*
       ((gosei (tutcode-bushu-compose-tc23 (list char) #f))
@@ -2529,12 +2528,14 @@
             (list #f elem))
           gosei)))
       (tutcode-context-set-prediction-bushu! pc res)
-      (tutcode-bushu-prediction-show-page pc 0 delay))))
+      (tutcode-bushu-prediction-make-page pc 0 show-candwin?))))
 
-;;; 部首合成変換の予測入力候補のうち、指定された番号から始まる候補を表示する。
+;;; 部首合成変換の予測入力候補のうち、
+;;; 指定された番号から始まる1ページぶんの候補リストを作成する。
 ;;; @param start-index 開始番号
-;;; @param delay 表示待ち時間[s]
-(define (tutcode-bushu-prediction-show-page pc start-index delay)
+;;; @param show-candwin? 候補リストの作成後候補ウィンドウの表示を行うかどうか。
+;;;  #fの場合は、候補リストの作成のみ行う(delay-activating-handler時)
+(define (tutcode-bushu-prediction-make-page pc start-index show-candwin?)
   (tutcode-lib-set-bushu-prediction pc start-index)
   (let ((nr (tutcode-lib-get-nr-predictions pc)))
     (if (and nr (> nr 0))
@@ -2556,12 +2557,10 @@
             (tutcode-context-set-prediction-nr-all! pc nr-all)
             (tutcode-context-set-prediction-index! pc 0)
             (tutcode-context-set-predicting! pc 'tutcode-predicting-bushu)
-            (if (>= delay 0) ; -1の場合は遅延呼び出しされている最中
+            (if show-candwin?
               (tutcode-activate-candidate-window pc
                 'tutcode-candidate-window-predicting
-                delay
-                nr-all
-                page-limit))))))))
+                0 nr-all page-limit))))))))
 
 ;;; 補完候補と熟語ガイド表示のためのcandwin用パラメータを計算する
 ;;; @param nr 補完候補数
@@ -3819,7 +3818,7 @@
               (if next?
                 tutcode-nr-candidate-max-for-prediction
                 (- tutcode-nr-candidate-max-for-prediction)))))
-    (tutcode-bushu-prediction-show-page pc n 0)))
+    (tutcode-bushu-prediction-make-page pc n #t)))
 
 ;;; 候補ウィンドウを閉じる
 (define (tutcode-reset-candidate-window pc)
@@ -3828,7 +3827,9 @@
     (begin
       (im-deactivate-candidate-selector pc)
       (tutcode-context-set-candidate-window! pc 'tutcode-candidate-window-off)
-      (tutcode-context-set-predicting! pc 'tutcode-predicting-off))))
+      (tutcode-context-set-predicting! pc 'tutcode-predicting-off)
+      (tutcode-context-set-candwin-delay-waiting! pc #f)
+      (tutcode-context-set-candwin-delay-selected-index! pc -1))))
 
 ;;; 交ぜ書き変換の候補選択状態から、読み入力状態に戻す。
 ;;; @param pc コンテキストリスト
@@ -4645,110 +4646,7 @@
 ;;; 候補ウィンドウが候補文字列を取得するために呼ぶ関数
 (define (tutcode-get-candidate-handler c idx accel-enum-hint)
   (let ((tc (tutcode-find-descendant-context c)))
-    (tutcode-context-set-candwin-delay-waiting! tc #f)
     (cond
-      ;;XXX 表形式候補ウィンドウからのdisplay_limit調整時等。
-      ;;    (API追加する方が良いが影響範囲が大きくなるのでまずは既存の枠組内で)
-      ;;    (表形式候補ウィンドウの無いブリッジを併用する場合(ほとんど無い?)、
-      ;;     表形式候補ウィンドウ用display_limitは大きすぎるので、
-      ;;     uim-prefではnr-candidate-max値は小さい値に設定しておき、
-      ;;     表形式候補ウィンドウのactivate時にdisplay_limitをnegotiate)
-      ((>= accel-enum-hint #x1000)
-        (if (logtest accel-enum-hint #x2000) ; 候補ウィンドウはdelay表示対応
-          (set! tutcode-candidate-window-delay-support? #t))
-        (if (logtest accel-enum-hint #x1000) ; 表形式candwin向けに候補数調整
-          (begin
-            (set! tutcode-nr-candidate-max
-              (length tutcode-heading-label-char-list))
-            (set! tutcode-nr-candidate-max-for-kigou-mode
-              (length tutcode-heading-label-char-list-for-kigou-mode))
-            (set! tutcode-nr-candidate-max-for-history
-              (length tutcode-heading-label-char-list-for-history))
-            (set! tutcode-nr-candidate-max-for-prediction
-              (length tutcode-heading-label-char-list-for-prediction))
-            (set! tutcode-nr-candidate-max-for-guide
-              (- tutcode-nr-candidate-max-for-kigou-mode
-                 tutcode-nr-candidate-max-for-prediction))))
-        (let*
-          ((delay? (logtest accel-enum-hint #x4000)) ; 遅延表示
-           (res
-            (cond
-              ((eq? (tutcode-context-state tc) 'tutcode-state-kigou)
-                (list tutcode-nr-candidate-max-for-kigou-mode
-                      (and delay? (tutcode-context-nr-candidates tc))))
-              ((eq? (tutcode-context-state tc) 'tutcode-state-history)
-                (list tutcode-nr-candidate-max-for-history
-                      (and delay? (tutcode-context-nr-candidates tc))))
-              ((eq? (tutcode-context-candidate-window tc)
-                    'tutcode-candidate-window-predicting)
-                (case (tutcode-context-state tc)
-                  ((tutcode-state-bushu)
-                    (if delay?
-                      (tutcode-check-bushu-prediction-with-delay tc
-                        (tutcode-context-prediction-bushu tc) -1)) ; 候補作成
-                    (list (tutcode-context-prediction-page-limit tc)
-                          (and delay? (tutcode-context-prediction-nr-all tc))))
-                  ((tutcode-state-on)
-                    (if delay?
-                      (if (tutcode-check-completion-make tc #f 0)
-                        (list (tutcode-context-prediction-page-limit tc)
-                              (tutcode-context-prediction-nr-all tc))
-                        (list (tutcode-context-prediction-page-limit tc)
-                              0))
-                      (list (tutcode-context-prediction-page-limit tc)
-                            #f)))
-                  ((tutcode-state-yomi)
-                    (if delay?
-                      (if (tutcode-check-prediction-make tc #f)
-                        (list (tutcode-context-prediction-page-limit tc)
-                              (tutcode-context-prediction-nr-all tc))
-                        (list (tutcode-context-prediction-page-limit tc)
-                              0))
-                      (list (tutcode-context-prediction-page-limit tc)
-                            #f)))))
-              ((eq? (tutcode-context-candidate-window tc)
-                    'tutcode-candidate-window-stroke-help)
-                (if delay?
-                  (let ((stroke-help (tutcode-stroke-help-make tc)))
-                    (if (pair? stroke-help)
-                      (begin
-                        (tutcode-context-set-stroke-help! tc stroke-help)
-                        (list tutcode-nr-candidate-max-for-kigou-mode
-                              (length stroke-help)))
-                      (list tutcode-nr-candidate-max-for-kigou-mode 0)))
-                  (list tutcode-nr-candidate-max-for-kigou-mode #f)))
-              ((eq? (tutcode-context-candidate-window tc)
-                    'tutcode-candidate-window-auto-help)
-                (if delay?
-                  (let*
-                    ((tmp (cdr (tutcode-context-auto-help tc)))
-                     (strlist (car tmp))
-                     (yomilist (cadr tmp))
-                     (auto-help (tutcode-auto-help-make tc strlist yomilist)))
-                    (if (pair? auto-help)
-                      (begin
-                        (tutcode-context-set-auto-help! tc auto-help)
-                        (list tutcode-nr-candidate-max-for-kigou-mode
-                              (length auto-help)))
-                      (list tutcode-nr-candidate-max-for-kigou-mode 0)))
-                  (list tutcode-nr-candidate-max-for-kigou-mode #f)))
-              ((eq? (tutcode-context-state tc)
-                    'tutcode-state-interactive-bushu)
-                (list (tutcode-context-prediction-page-limit tc)
-                      (and delay? (tutcode-context-prediction-nr-all tc))))
-              ((eq? (tutcode-context-candidate-window tc)
-                    'tutcode-candidate-window-converting)
-                (list tutcode-nr-candidate-max
-                      (and delay? (tutcode-context-nr-candidates tc))))
-              (else
-                (list tutcode-nr-candidate-max
-                      (and delay? 0)))))
-           (nrstr (if delay?
-                    (string-append " nr=" (number->string (cadr res)))
-                    "")))
-          (list "" ""
-            (string-append "display_limit=" (number->string (car res))
-                           nrstr))))
       ;; 記号入力
       ((eq? (tutcode-context-state tc) 'tutcode-state-kigou)
         (let* ((cand (tutcode-get-nth-candidate-for-kigou-mode tc idx))
@@ -4889,6 +4787,80 @@
                     (eq? mode 'tutcode-predicting-completion))))
               (tutcode-update-preedit pc))))))))
 
+;;; 遅延表示に対応している候補ウィンドウが、待ち時間満了時に
+;;; (候補数、ページ内候補表示数、選択されたインデックス番号)を
+;;; 取得するために呼ぶ関数
+;;; @param nr 現在候補ウィンドウが認識している候補数
+;;;  (activate時の引数で指定した値)。-1の場合は候補リストの作成が必要
+;;; @param display-limit 現在候補ウィンドウが認識しているdisplay-limit
+;;; @return (nr display-limit selected-index)
+(define (tutcode-delay-activating-handler c)
+  (let ((tc (tutcode-find-descendant-context c)))
+    (tutcode-context-set-candwin-delay-waiting! tc #f)
+    (let
+      ((res
+        (cond
+          ((eq? (tutcode-context-state tc) 'tutcode-state-kigou)
+            (list tutcode-nr-candidate-max-for-kigou-mode
+                  (tutcode-context-nr-candidates tc)))
+          ((eq? (tutcode-context-state tc) 'tutcode-state-history)
+            (list tutcode-nr-candidate-max-for-history
+                  (tutcode-context-nr-candidates tc)))
+          ((eq? (tutcode-context-candidate-window tc)
+                'tutcode-candidate-window-predicting)
+            (case (tutcode-context-state tc)
+              ((tutcode-state-bushu)
+                (tutcode-check-bushu-prediction-make tc
+                  (tutcode-context-prediction-bushu tc) #f) ; 候補リスト作成
+                (list (tutcode-context-prediction-page-limit tc)
+                      (tutcode-context-prediction-nr-all tc)))
+              ((tutcode-state-on)
+                (if (tutcode-check-completion-make tc #f 0)
+                  (list (tutcode-context-prediction-page-limit tc)
+                        (tutcode-context-prediction-nr-all tc))
+                  (list (tutcode-context-prediction-page-limit tc) 0)))
+              ((tutcode-state-yomi)
+                (if (tutcode-check-prediction-make tc #f)
+                  (list (tutcode-context-prediction-page-limit tc)
+                        (tutcode-context-prediction-nr-all tc))
+                  (list (tutcode-context-prediction-page-limit tc) 0)))
+              (else
+                '(0 0))))
+          ((eq? (tutcode-context-candidate-window tc)
+                'tutcode-candidate-window-stroke-help)
+            (let ((stroke-help (tutcode-stroke-help-make tc)))
+              (if (pair? stroke-help)
+                (begin
+                  (tutcode-context-set-stroke-help! tc stroke-help)
+                  (list tutcode-nr-candidate-max-for-kigou-mode
+                        (length stroke-help)))
+                (list tutcode-nr-candidate-max-for-kigou-mode 0))))
+          ((eq? (tutcode-context-candidate-window tc)
+                'tutcode-candidate-window-auto-help)
+            (let*
+              ((tmp (cdr (tutcode-context-auto-help tc)))
+               (strlist (car tmp))
+               (yomilist (cadr tmp))
+               (auto-help (tutcode-auto-help-make tc strlist yomilist)))
+              (if (pair? auto-help)
+                (begin
+                  (tutcode-context-set-auto-help! tc auto-help)
+                  (list tutcode-nr-candidate-max-for-kigou-mode
+                        (length auto-help)))
+                (list tutcode-nr-candidate-max-for-kigou-mode 0))))
+          ((eq? (tutcode-context-state tc)
+                'tutcode-state-interactive-bushu)
+            (list (tutcode-context-prediction-page-limit tc)
+                  (tutcode-context-prediction-nr-all tc)))
+          ((eq? (tutcode-context-candidate-window tc)
+                'tutcode-candidate-window-converting)
+            (list tutcode-nr-candidate-max
+                  (tutcode-context-nr-candidates tc)))
+          (else
+            (list tutcode-nr-candidate-max 0)))))
+      (reverse
+        (cons (tutcode-context-candwin-delay-selected-index tc) res)))))
+
 (tutcode-configure-widgets)
 
 ;;; TUT-Code IMを登録する。
Index: scm/im.scm
===================================================================
--- scm/im.scm	(revision 7323)
+++ scm/im.scm	(working copy)
@@ -105,7 +105,8 @@
    (list 'focus-out-handler           list)
    (list 'place-handler               list)
    (list 'displace-handler            list)
-   (list 'module-name                 "")))
+   (list 'module-name                 "")
+   (list 'delay-activating-handler    #f)))
 
 (define im-custom-set-handler
   (lambda (im)
@@ -147,7 +148,7 @@
 			   get-candidate set-candidate-index prop
 			   input-string focus-in focus-out place displace
 			   currently-loading-module-name))
-               (initial-registration? (not (assq name im-list))))
+	       (initial-registration? (not (assq name im-list))))
 	   (set! im-list (alist-replace im im-list))
 	   (normalize-im-list)
            initial-registration?))))
@@ -527,6 +528,10 @@
   (lambda (uc idx)
     (invoke-handler im-set-candidate-index-handler uc idx)))
 
+(define delay-activating-handler
+  (lambda (uc)
+    (invoke-handler im-delay-activating-handler uc)))
+
 (define im-acquire-text
   (lambda (c id origin former-len latter-len)
     (let ((text-id (cdr (assq id text-area-id-alist)))
Index: scm/im-custom.scm
===================================================================
--- scm/im-custom.scm	(revision 7323)
+++ scm/im-custom.scm	(working copy)
@@ -430,12 +430,6 @@
   (N_ "Candidate window position")
   (N_ "long description will be here."))
 
-(define-custom 'candidate-window-use-delay? #f
-  '(global visual-preference)
-  '(boolean)
-  (N_ "Use delay showing candidate window")
-  (N_ "long description will be here."))
-
 (define-custom 'enable-lazy-loading? #t
   '(global advanced)
   '(boolean)
Index: uim/uim.c
===================================================================
--- uim/uim.c	(revision 7323)
+++ uim/uim.c	(working copy)
@@ -69,6 +69,13 @@
   int enum_hint;
 };
 static void *uim_get_candidate_internal(struct uim_get_candidate_args *args);
+struct uim_delay_activating_args {
+  uim_context uc;
+  int nr;
+  int display_limit;
+  int selected_index;
+};
+static void *uim_delay_activating_internal(struct uim_delay_activating_args *);
 static uim_lisp get_nth_im(uim_context uc, int nth);
 #ifdef ENABLE_ANTHY_STATIC
 void uim_anthy_plugin_instance_init(void);
@@ -787,6 +794,62 @@
 }
 #endif  /* !UIM_USE_NOTIFY_PLUGINS */
 
+void
+uim_set_delay_candidate_selector_cb(uim_context uc,
+                                    void (*delay_activate_cb)(void *ptr,
+                                                              int delay))
+{
+  if (UIM_CATCH_ERROR_BEGIN())
+    return;
+
+  assert(uim_scm_gc_any_contextp());
+  assert(uc);
+
+  uc->candidate_selector_delay_activate_cb = delay_activate_cb;
+
+  UIM_CATCH_ERROR_END();
+}
+
+void
+uim_delay_activating(uim_context uc, int *nr, int *display_limit, int *selected_index)
+{
+  struct uim_delay_activating_args args;
+
+  if (UIM_CATCH_ERROR_BEGIN())
+    return;
+
+  assert(uim_scm_gc_any_contextp());
+  assert(uc);
+
+  args.uc = uc;
+  args.nr = *nr;
+  args.display_limit = *display_limit;
+  args.selected_index = *selected_index;
+
+  uim_scm_call_with_gc_ready_stack((uim_gc_gate_func_ptr)uim_delay_activating_internal, &args);
+  *nr = args.nr;
+  *display_limit = args.display_limit;
+  *selected_index = args.selected_index;
+
+  UIM_CATCH_ERROR_END();
+}
+
+static void *
+uim_delay_activating_internal(struct uim_delay_activating_args *args)
+{
+  uim_context uc;
+  uim_lisp triple;
+
+  uc = args->uc;
+  triple = uim_scm_callf("delay-activating-handler", "p", uc);
+  if (LISTP(triple) && uim_scm_length(triple) == 3) {
+    args->nr = C_INT(CAR(triple));
+    args->display_limit = C_INT(CAR(CDR(triple)));
+    args->selected_index = C_INT(CAR(CDR(CDR(triple))));
+  }
+  return NULL;
+}
+
 /****************************************************************
  * Legacy 'mode' API                                            *
  ****************************************************************/
Index: uim/uim.h
===================================================================
--- uim/uim.h	(revision 7323)
+++ uim/uim.h	(working copy)
@@ -689,6 +689,31 @@
                                    void (*deactivate_cb)(void *ptr));
 
 /**
+ * Set callback function to support delay showing candidate-selection.
+ *
+ * @param uc input context
+ * @param delay_activate_cb called when candidate window should be activated with delay.
+ *
+ * @see uim_create_context
+ */
+void uim_set_delay_candidate_selector_cb(uim_context uc,
+                                         void (*delay_activate_cb)(void *ptr,
+                                                                   int delay));
+
+/**
+ * Notify that the candidate selector is being activated after delay.
+ *
+ * The input context can update number of candidates,
+ * display limit and selected index.
+ *
+ * @param uc input context
+ * @param nr [out] total number of candidates
+ * @param display_limit [out] number of candidates to show on one page
+ * @param selected_index [out] index of selected candidate
+ */
+void uim_delay_activating(uim_context uc, int *nr, int *display_limit, int *selected_index);
+
+/**
  * Get candidate data.
  *
  * @param uc input context
Index: uim/uim-internal.h
===================================================================
--- uim/uim-internal.h	(revision 7323)
+++ uim/uim-internal.h	(working copy)
@@ -105,6 +105,7 @@
   void (*candidate_selector_select_cb)(void *ptr, int index);
   void (*candidate_selector_shift_page_cb)(void *ptr, int direction);
   void (*candidate_selector_deactivate_cb)(void *ptr);
+  void (*candidate_selector_delay_activate_cb)(void *ptr, int delay);
   /* text acquisition */
   int (*acquire_text_cb)(void *ptr,
                          enum UTextArea text_id, enum UTextOrigin origin,
Index: uim/uim-func.c
===================================================================
--- uim/uim-func.c	(revision 7323)
+++ uim/uim-func.c	(working copy)
@@ -288,6 +288,21 @@
 }
 
 static uim_lisp
+im_delay_activate_candidate_selector(uim_lisp uc_, uim_lisp delay_)
+{
+  uim_context uc;
+  int delay;
+
+  uc = retrieve_uim_context(uc_);
+  delay = C_INT(delay_);
+
+  if (uc->candidate_selector_delay_activate_cb)
+    uc->candidate_selector_delay_activate_cb(uc->ptr, delay);
+
+  return uim_scm_f();
+}
+
+static uim_lisp
 im_select_candidate(uim_lisp uc_, uim_lisp idx_)
 {
   uim_context uc;
@@ -333,6 +348,18 @@
 }
 
 static uim_lisp
+im_delay_activate_candidate_selector_supportedp(uim_lisp uc_)
+{
+  uim_context uc;
+
+  uc = retrieve_uim_context(uc_);
+
+  if (uc->candidate_selector_delay_activate_cb)
+    return uim_scm_t();
+  return uim_scm_f();
+}
+
+static uim_lisp
 im_acquire_text(uim_lisp uc_, uim_lisp text_id_, uim_lisp origin_,
 		uim_lisp former_len_, uim_lisp latter_len_)
 {
@@ -460,6 +487,11 @@
   uim_scm_init_proc1("im-deactivate-candidate-selector",
 		     im_deactivate_candidate_selector);
 
+  uim_scm_init_proc2("im-delay-activate-candidate-selector",
+		     im_delay_activate_candidate_selector);
+  uim_scm_init_proc1("im-delay-activate-candidate-selector-supported?",
+		     im_delay_activate_candidate_selector_supportedp);
+
   uim_scm_init_proc5("im-acquire-text-internal", im_acquire_text);
   uim_scm_init_proc5("im-delete-text-internal", im_delete_text);
 
Index: xim/ximserver.cpp
===================================================================
--- xim/ximserver.cpp	(revision 7323)
+++ xim/ximserver.cpp	(working copy)
@@ -421,18 +421,12 @@
 					InputContext::commit_cb);
 
     if (uc) {
-	void (*activate_cb)(void *, int, int) = InputContext::candidate_activate_cb;
-#if UIM_XIM_USE_DELAY
-	if (uim_scm_symbol_value_bool("candidate-window-use-delay?")) {
-	    activate_cb = InputContext::candidate_activate_with_delay_cb;
-	}
-#endif
 	uim_set_preedit_cb(uc,
 			InputContext::clear_cb,
 			InputContext::pushback_cb,
 			InputContext::update_cb);
 	uim_set_candidate_selector_cb(uc,
-			activate_cb,
+			InputContext::candidate_activate_cb,
 			InputContext::candidate_select_cb,
 			InputContext::candidate_shift_page_cb,
 			InputContext::candidate_deactivate_cb);
@@ -447,6 +441,10 @@
 	uim_set_im_switch_request_cb(uc,
 			InputContext::switch_app_global_im_cb,
 			InputContext::switch_system_global_im_cb);
+#if UIM_XIM_USE_DELAY
+	uim_set_delay_candidate_selector_cb(uc,
+			InputContext::candidate_activate_with_delay_cb);
+#endif
 
 	if (mFocusedContext == this)
 	    uim_prop_list_update(uc);
@@ -645,10 +643,10 @@
 }
 
 #if UIM_XIM_USE_DELAY
-void InputContext::candidate_activate_with_delay_cb(void *ptr, int nr, int display_limit)
+void InputContext::candidate_activate_with_delay_cb(void *ptr, int delay)
 {
     InputContext *ic = (InputContext *)ptr;
-    ic->candidate_activate_with_delay(nr, display_limit);
+    ic->candidate_activate_with_delay(delay);
 }
 
 void InputContext::candidate_activate_timeout_cb(void *ptr)
@@ -844,16 +842,12 @@
 #endif
     std::vector<const char *> candidates;
     std::vector<const char *>::iterator it;
+
 #if UIM_XIM_USE_DELAY
-    uim_lisp idx_delay;
+    timer_cancel();
 #endif
-
     Canddisp *disp = canddisp_singleton();
 
-    disp->negotiate_scm(mUc, &nr, &display_limit);
-    if (nr <= 0) {
-        return;
-    }
     mDisplayLimit = display_limit;
     if (display_limit)
 	mNumPage = (nr - 1) / display_limit + 1;
@@ -913,28 +907,14 @@
     current_cand_selection = 0;
     current_page = 0;
     need_hilite_selected_cand = false;
-
-#if UIM_XIM_USE_DELAY
-    idx_delay = uim_scm_symbol_value("candidate-window-delay-selected-index");
-    if (!uim_scm_falsep(idx_delay)) {
-	long idx = uim_scm_c_int(idx_delay);
-	if (idx >= 0) {
-	    InputContext::candidate_select_cb(this, static_cast<int>(idx));
-	}
-    }
-#endif
 }
 
 #if UIM_XIM_USE_DELAY
-void InputContext::candidate_activate_with_delay(int nr, int display_limit)
+void InputContext::candidate_activate_with_delay(int delay)
 {
     timer_cancel();
-    mNumCandidates = nr;
-    mDisplayLimit = display_limit;
-    int timeout = static_cast<int>(uim_scm_symbol_value_int(
-	    "candidate-window-activate-delay"));
-    if (timeout > 0) {
-	timer_set(timeout, InputContext::candidate_activate_timeout_cb, this);
+    if (delay > 0) {
+	timer_set(delay, InputContext::candidate_activate_timeout_cb, this);
     } else {
 	candidate_activate_timeout();
     }
@@ -942,7 +922,14 @@
 
 void InputContext::candidate_activate_timeout()
 {
-    candidate_activate(mNumCandidates, mDisplayLimit);
+    int nr = -1, display_limit = -1, selected_index = -1;
+    uim_delay_activating(mUc, &nr, &display_limit, &selected_index);
+    if (nr > 0) {
+	candidate_activate(nr, display_limit);
+	if (selected_index >= 0) {
+	    candidate_select(selected_index);
+	}
+    }
 }
 #endif
 
Index: xim/canddisp.cpp
===================================================================
--- xim/canddisp.cpp	(revision 7323)
+++ xim/canddisp.cpp	(working copy)
@@ -146,50 +146,13 @@
     return disp;
 }
 
-Canddisp::Canddisp(): negotiated_scm(false)
+Canddisp::Canddisp()
 {
 }
 
 Canddisp::~Canddisp() {
 }
 
-/* XXX: get nr and display_limit for delay || negotiate with scm side */
-void Canddisp::negotiate_scm(uim_context uc, int *nr, int *display_limit)
-{
-    if (*nr < 0 || !negotiated_scm) {
-	int cmd = 0;
-	if (*nr < 0) {
-	    cmd = 0x4000; // get nr and display_limit for delay
-	} else {
-	    if (command && strstr(command, "/uim-candwin-tbl-") != NULL) {
-		cmd |= 0x1000; // adjust display_limit for table style candwin
-	    }
-#if UIM_XIM_USE_DELAY
-	    if (uim_scm_symbol_value_bool("candidate-window-use-delay?")) {
-		cmd |= 0x2000; // notify delay support
-	    }
-#endif
-	    negotiated_scm = true;
-	}
-	if (cmd >= 0x1000) {
-	    uim_candidate c;
-	    const char *s, *p;
-	    c = uim_get_candidate(uc, 0, cmd);
-	    s = uim_candidate_get_annotation_str(c);
-#define LEN_DISPLAY_LIMIT 14
-	    if (strncmp(s, "display_limit=", LEN_DISPLAY_LIMIT) == 0) {
-		*display_limit = atoi(s + LEN_DISPLAY_LIMIT);
-	    }
-	    if (*nr < 0) {
-		if ((p = strstr(s, "nr=")) != NULL) {
-		    *nr = atoi(p + 3);
-		}
-	    }
-	    uim_candidate_free(c);
-	}
-    }
-}
-
 void Canddisp::activate(std::vector<const char *> candidates, int display_limit)
 {
     std::vector<const char *>::iterator i;
Index: xim/ximserver.h
===================================================================
--- xim/ximserver.h	(revision 7323)
+++ xim/ximserver.h	(working copy)
@@ -182,7 +182,7 @@
     void update_preedit();
     void candidate_activate(int nr, int display_limit);
 #if UIM_XIM_USE_DELAY
-    void candidate_activate_with_delay(int nr, int display_limit);
+    void candidate_activate_with_delay(int delay);
     void candidate_activate_timeout();
 #endif
     void candidate_select(int index);
@@ -213,7 +213,7 @@
     static void update_cb(void *ptr);
     static void candidate_activate_cb(void *ptr, int nr, int index);
 #if UIM_XIM_USE_DELAY
-    static void candidate_activate_with_delay_cb(void *ptr, int nr, int display_limit);
+    static void candidate_activate_with_delay_cb(void *ptr, int delay);
     static void candidate_activate_timeout_cb(void *ptr);
 #endif
     static void candidate_select_cb(void *ptr, int index);
Index: xim/canddisp.h
===================================================================
--- xim/canddisp.h	(revision 7323)
+++ xim/canddisp.h	(working copy)
@@ -55,10 +55,8 @@
     void set_page_candidates(int page, CandList candidates);
     void show_page(int page);
 #endif
-    void negotiate_scm(uim_context uc, int *nr, int *display_limit);
 private:
     void check_connection();
-    bool negotiated_scm;
 };
 
 Canddisp *canddisp_singleton();
Index: gtk2/immodule/gtk-im-uim.c
===================================================================
--- gtk2/immodule/gtk-im-uim.c	(revision 7323)
+++ gtk2/immodule/gtk-im-uim.c	(working copy)
@@ -123,6 +123,9 @@
 #elif IM_UIM_USE_TOPLEVEL
 static gboolean handle_key_on_toplevel(GtkWidget *widget, GdkEventKey *event, gpointer data);
 #endif
+#if IM_UIM_USE_DELAY
+static void cand_delay_timer_remove(UIMCandWinGtk *cwin);
+#endif
 static void send_im_list(void);
 static UIMCandWinGtk *im_uim_create_cand_win_gtk(void);
 
@@ -730,45 +733,6 @@
   g_slist_free(candidates);
 }
 #endif /* IM_UIM_USE_NEW_PAGE_HANDLING */
-
-static void
-negotiate_scm(IMUIMContext *uic, int *nr, int *display_limit)
-{
-  gint negotiated_scm = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(uic->cwin), "negotiated_scm"));
-  /* XXX: get nr and display_limit for delay || negotiate with scm side */
-  if (*nr < 0 || !negotiated_scm) {
-    int cmd = 0;
-    if (*nr < 0) {
-      cmd = 0x4000; /* get nr and display_limit for delay */
-    } else {
-      if (UIM_IS_CAND_WIN_TBL_GTK(uic->cwin)) {
-        cmd |= 0x1000; /* adjust display_limit for table style candwin */
-      }
-#if IM_UIM_USE_DELAY
-      if (uim_scm_symbol_value_bool("candidate-window-use-delay?")) {
-        cmd |= 0x2000; /* notify delay support */
-      }
-#endif
-      g_object_set_data(G_OBJECT(uic->cwin), "negotiated_scm", GINT_TO_POINTER(1));
-    }
-    if (cmd >= 0x1000) {
-      uim_candidate c;
-      const char *s, *p;
-      c = uim_get_candidate(uic->uc, 0, cmd);
-      s = uim_candidate_get_annotation_str(c);
-#define LEN_DISPLAY_LIMIT 14
-      if (strncmp(s, "display_limit=", LEN_DISPLAY_LIMIT) == 0) {
-        *display_limit = atoi(s + LEN_DISPLAY_LIMIT);
-      }
-      if (*nr < 0) {
-        if ((p = strstr(s, "nr=")) != NULL) {
-          *nr = atoi(p + 3);
-        }
-      }
-      uim_candidate_free(c);
-    }
-  }
-}
  
 static void
 cand_activate_cb(void *ptr, int nr, int display_limit)
@@ -779,17 +743,13 @@
   uim_candidate cand;
   gint i;
 #endif
+
 #if IM_UIM_USE_DELAY
-  uim_lisp idx_delay;
+  cand_delay_timer_remove(uic->cwin);
 #endif
 
   uic->cwin_is_active = TRUE;
 
-  negotiate_scm(uic, &nr, &display_limit);
-  if (nr <= 0) {
-    uic->cwin_is_active = FALSE;
-    return;
-  }
 #if !IM_UIM_USE_NEW_PAGE_HANDLING
   for (i = 0; i < nr; i++) {
     cand = uim_get_candidate(uic->uc, i, display_limit ? i % display_limit : i);
@@ -821,16 +781,6 @@
     toplevel = gdk_window_get_toplevel(uic->win);
     gdk_window_add_filter(toplevel, toplevel_window_candidate_cb, uic);
   }
-
-#if IM_UIM_USE_DELAY
-  idx_delay = uim_scm_symbol_value("candidate-window-delay-selected-index");
-  if (!uim_scm_falsep(idx_delay)) {
-    long idx = uim_scm_c_int(idx_delay);
-    if (idx >= 0) {
-      cand_select_cb(uic, idx);
-    }
-  }
-#endif
 }
 
 #if IM_UIM_USE_DELAY
@@ -838,12 +788,16 @@
 cand_activate_timeout(gpointer data)
 {
   IMUIMContext *uic = (IMUIMContext *)data;
-  gint nr, display_limit;
+  int nr = -1, display_limit = -1, selected_index = -1;
 
   g_object_set_data(G_OBJECT(uic->cwin), "timeout-tag", GUINT_TO_POINTER(0));
-  nr = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(uic->cwin), "nr-candidates"));
-  display_limit = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(uic->cwin), "display-limit"));
-  cand_activate_cb(uic, nr, display_limit);
+  uim_delay_activating(uic->uc, &nr, &display_limit, &selected_index);
+  if (nr > 0) {
+    cand_activate_cb(uic, nr, display_limit);
+    if (selected_index >= 0) {
+      cand_select_cb(uic, selected_index);
+    }
+  }
   return FALSE;
 }
 
@@ -856,21 +810,15 @@
 }
 
 static void
-cand_activate_with_delay_cb(void *ptr, int nr, int display_limit)
+cand_activate_with_delay_cb(void *ptr, int delay)
 {
   IMUIMContext *uic = (IMUIMContext *)ptr;
-  long timeout;
   guint tag;
 
   cand_delay_timer_remove(uic->cwin);
-
-  g_object_set_data(G_OBJECT(uic->cwin), "nr-candidates", GINT_TO_POINTER(nr));
-  g_object_set_data(G_OBJECT(uic->cwin), "display-limit", GINT_TO_POINTER(display_limit));
-  timeout = uim_scm_symbol_value_int("candidate-window-activate-delay");
-  if (timeout > 0) {
+  if (delay > 0) {
     /* g_timeout_add_seconds() needs GLib 2.14 */
-    tag = g_timeout_add(timeout * 1000, cand_activate_timeout, (gpointer)uic);
-
+    tag = g_timeout_add(delay * 1000, cand_activate_timeout, (gpointer)uic);
     g_object_set_data(G_OBJECT(uic->cwin), "timeout-tag", GUINT_TO_POINTER(tag));
   } else {
     cand_activate_timeout(ptr);
@@ -1686,7 +1634,6 @@
   GObject *obj;
   IMUIMContext *uic;
   const char *im_name;
-  void (*activate_cb)(void *ptr, int nr, int display_limit) = cand_activate_cb;
 
   g_return_val_if_fail(context_id, NULL);
   g_return_val_if_fail(!strcmp(context_id, "uim"), NULL);
@@ -1711,18 +1658,16 @@
 
   uim_set_preedit_cb(uic->uc, clear_cb, pushback_cb, update_cb);
   uim_set_prop_list_update_cb(uic->uc, update_prop_list_cb);
-#if IM_UIM_USE_DELAY
-  if (uim_scm_symbol_value_bool("candidate-window-use-delay?")) {
-    activate_cb = cand_activate_with_delay_cb;
-  }
-#endif
-  uim_set_candidate_selector_cb(uic->uc, activate_cb, cand_select_cb,
+  uim_set_candidate_selector_cb(uic->uc, cand_activate_cb, cand_select_cb,
 				cand_shift_page_cb, cand_deactivate_cb);
   uim_set_configuration_changed_cb(uic->uc, configuration_changed_cb);
   uim_set_im_switch_request_cb(uic->uc,
 			       switch_app_global_im_cb,
 			       switch_system_global_im_cb);
   uim_set_text_acquisition_cb(uic->uc, acquire_text_cb, delete_text_cb);
+#if IM_UIM_USE_DELAY
+  uim_set_delay_candidate_selector_cb(uic->uc, cand_activate_with_delay_cb);
+#endif
 
   uim_prop_list_update(uic->uc);
 

メールによる返信