[ruby-dev:38323] [1.8.7][1.9.1][tk] 自前実装の拡張 widget を使いたい場合

View: New views
20 Messages — Rating Filter:   Alert me  
< Prev | 1 - 2 | Next >

[ruby-dev:38323] [1.8.7][1.9.1][tk] 自前実装の拡張 widget を使いたい場合

by oshida :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

押田です。

最近の(?) Ruby/Tk に関してご教示賜りたくメールしました。
用例としては結構ニッチだろうと自負しています(^^;


Ruby/Tk の famous extention サポート標準化により、
オリジナル Tk に存在しない widget に関しては
標準で extention 側のファイルを require するよう autoload 登録されます。
それら extention が存在しない環境にて、
例えば TkCombobox だけを自前実装して使いたい場合、
この autoload が働いて存在しないファイルを読みにいってしまい、
TkPackage にて RuntimeError 終了してしまいます。

「sample/tkcombobox.rb が動かなくなっています」
という表現の方がシンプルで良いかも知れません。

もし、tk/ttk_selector.rb の
"Ttk is a standard library on Tcl/Tk8.5+"
が 8.4 サポートの terminate を意味しないのであれば、
autoload 登録を見合せていただければありがたいです。


また、ひとまず手元では、

Object.const_set(:TkCombobox, Class.new(XXX))
class TkCombobox < XXX

とすることで autoload を無効化しています。

より適切な解法があればお教え下さい。


宜しくお願いします。


[ruby-dev:38331] Re: [1.8.7][1.9.1][tk] 自前実装の拡張 widget を使いたい場合

by Hidetoshi NAGAI :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

永井@知能.九工大です.

From: oshida@...
Subject: [ruby-dev:38323] [1.8.7][1.9.1][tk] 自前実装の拡張 widget を使いたい場合
Date: Fri, 24 Apr 2009 21:28:42 +0900
Message-ID: <1240576111.49f1b06fabf64@...>
> 「sample/tkcombobox.rb が動かなくなっています」
> という表現の方がシンプルで良いかも知れません。
>
> もし、tk/ttk_selector.rb の
> "Ttk is a standard library on Tcl/Tk8.5+"
> が 8.4 サポートの terminate を意味しないのであれば、
> autoload 登録を見合せていただければありがたいです。

8.4 と 8.5 との間で互換性のあるスクリプトを
書きやすいようにと考えていたのですが,
「小さな親切,大きなお世話」になってしまったようですね.
ごめんなさい.

ですが,将来の機能強化の際にも同様の問題が出てしまうであろうことや
default_widget_set の切替え機能のことを考えると,
登録を削ってしまうのも少々辛いです.

> また、ひとまず手元では、
>
> Object.const_set(:TkCombobox, Class.new(XXX))
> class TkCombobox < XXX
>
> とすることで autoload を無効化しています。

衝突するクラス (この場合は TkCombobox クラス) を定義する前に
------------------------------------------------------------------------------
Object.instance_eval{remove_const :TkCombobox} if Object.autoload? :TkCombobox
------------------------------------------------------------------------------
として autoload を無効化してください.

# sample/tkcombobox.rb には,これを追加しておくようにします.

また,default_widget_set 切替えとの整合も取らせたいのであれば,
------------------------------------------------------------------------------
class MyTkCombobox < TkEntry; ... ; end
Tk.__set_toplevel_aliases__(:Tk, MyTkCombobox, :TkCombobox, TkComboBox)
------------------------------------------------------------------------------
などとして登録を行ってください.
この例では MyTkCombobox というクラスを default_widget_set が Tk の時に
TkCombobox および TkComboBox の名前で使えるようにしています.
--
永井 秀利  (nagai@...)
九州工業大学 大学院情報工学研究院 知能情報工学研究系 知能情報メディア部門


[ruby-dev:38339] Re: [1.8.7][1.9.1][tk] 自前実装の拡張 widget を使いたい場合

by oshida :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

押田です。

すばやい御返答ありがとうございます。


> 「小さな親切,大きなお世話」になってしまったようですね.
> ごめんなさい.

とんでもないです。
あくまでも当方の極めてニッチなユースケースでの話と自覚しています。

色々な処理系、JRuby や IronRuby, RubyCocoa ? など、
Ruby のプリミティブが Native Object にバインドされている様も
素晴らしいと思っていましたが、
永井さんの Tk Wrapper の巧妙さも、また別の意味で素晴らしいと思います。
Tk への愛を感じます :-)


> ですが,将来の機能強化の際にも同様の問題が出てしまうであろうことや
> default_widget_set の切替え機能のことを考えると,
> 登録を削ってしまうのも少々辛いです.

そうですね。
原則、やはり進化の方向であるべきと考えます。
本件は引き続きローカルで対処します。

もしどこかに、
Ruby/Tk 的に予約語となっている物のリストや、
8.4 環境での衝突回避方法など、
Mini HowTo としてまとまっていればと思いますが、
それもニーズの規模によりけりですしね。

そういう意味では ML が Tiny HowTo になるべきでしょうが、
私のメールの書き方だと tag になる単語が不足しているかも(^^;
発現時のエラーメッセージを貼っておきます(^^;;;

> /usr/lib/ruby/1.8/tk/package.rb:86:in `require': TkPackage can't find package
tile (RuntimeError)


> Object.instance_eval{remove_const :TkCombobox} if Object.autoload? :TkCombobox

なるほど、こうなっていましたか。
ありがとうございます。
さっそく取り入れます。


[ruby-dev:38340] Re: [1.8.7][1.9.1][tk] 自前実装の拡張 widget を使いたい場合

by Hidetoshi NAGAI :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

永井@知能.九工大です.

From: oshida@...
Subject: [ruby-dev:38339] Re: [1.8.7][1.9.1][tk] 自前実装の拡張 widget を使いたい場合
Date: Mon, 27 Apr 2009 11:02:40 +0900
Message-ID: <1240797746.49f512321cf3d@...>
> > ですが,将来の機能強化の際にも同様の問題が出てしまうであろうことや
> > default_widget_set の切替え機能のことを考えると,
> > 登録を削ってしまうのも少々辛いです.
>
> そうですね。
> 原則、やはり進化の方向であるべきと考えます。
> 本件は引き続きローカルで対処します。

両方を殺さずに何とかできそうな対処案を思い付きました.
ちょっと今は本業の方が忙しいのですぐとはいかないかもしれませんが,
もう少しつめてみて,仕上りましたら本 ML で連絡します.
もし良かったら,その際にテストしていただけますと助かります.

申し訳ないのですが,それまでの間は応急処置でローカルに
対応しておいていただけますようお願いいたします.
--
永井 秀利  (nagai@...)
九州工業大学 大学院情報工学研究院 知能情報工学研究系 知能情報メディア部門


[ruby-dev:38342] Re: [1.8.7][1.9.1][tk] 自前実装の拡張 widget を使いたい場合

by oshida :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

押田です。


> もし良かったら,その際にテストしていただけますと助かります.

了解しました。
ご協力させて頂きます。

ちなみに当方、RHEL 5.x x86_64 が主な環境です。

RHEL 5.x オリジナルは 1.8.5 なんですが、
ちょっと限界が見えてきた気がするので、
1.8.7 / 1.9.1 に移行する事を検討・検証中です。

#spawn は喉から手が出ているのですが、やはり、1.9 対応は少し難航しそうです。

あと Cygwin も消極的にサポートしています。
ごく稀に Solaris (IA-32) も使います。


> 申し訳ないのですが,それまでの間は応急処置でローカルに
> 対応しておいていただけますようお願いいたします.

申し訳ないだなんて(^^;
リポジトリにコミットする変更が
十分に建設的な内容とは言えないのであれば、
ローカル対応を続けるべきだと考えています。


[ruby-dev:38697] Re: [1.8.7][1.9.1][tk] 自前実装の拡張 widget を使いたい場合

by Hidetoshi NAGAI :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

永井@知能.九工大です.

From: Hidetoshi NAGAI <nagai@...>
Subject: [ruby-dev:38340] Re: [1.8.7][1.9.1][tk] 自前実装の拡張 widget を使いたい場合
Date: Mon, 27 Apr 2009 12:04:48 +0900
Message-ID: <20090427.120447.74747064.nagai@...>
> 両方を殺さずに何とかできそうな対処案を思い付きました.
> ちょっと今は本業の方が忙しいのですぐとはいかないかもしれませんが,
> もう少しつめてみて,仕上りましたら本 ML で連絡します.
> もし良かったら,その際にテストしていただけますと助かります.

長らく放置状態で申し訳ありませんでしたが,
近い内に仕上げて commit できそうです.

方針を簡単に説明しておきますと,以下のようになります.

まず
・widget_set と toplevel 名の symbol とを管理する TABLE[set][sym]
・toplevel の alias を定義するモジュール ALIASES
・toplevel の alias (sym) を管理する OWNER[sym]
というようなものを用意しておき,
ALIASES を Oject クラスに Mix-in します.
操作時の条件は少しややこしいのですが,
必要に応じて Object クラス上にも ALIASES と同じものを定義します.

例えば TkButton(Tk::Button) と TkCombobox(Ttk::Combobox) において
         ALIASES                      Object
  ----------------------------------------------------
   TkButton(Tk::Button)       <-  TkButton(Tk::Button)
   TkCombobox(Ttk::Combobox)  <-  未定義
というような状況になるわけです.

これにより,TkButton, TkCombobox 共に見えつつも
TkCombobox については独自クラスを定義することが可能です.
その場合,
         ALIASES                      Object
  ----------------------------------------------------
   TkButton(Tk::Button)       <-  TkButton(Tk::Button)
   TkCombobox(Ttk::Combobox)      TkCombobox(独自定義)
となります.

もし TkCombobox に独自クラスを定義せずに TkCombobox.new などと
TkCombobox(Ttk::Combobox) を参照した場合は
         ALIASES                      Object
  ----------------------------------------------------
   TkButton(Tk::Button)       <-  TkButton(Tk::Button)
   TkCombobox(Ttk::Combobox)  <-  TkCombobox(Ttk::Combobox)
となります.

唯一(?)の問題は TkCombobox が Object クラス上で未定義の状態で
TkCombobox に機能追加しようとして class TkCombobox とした場合です.
この場合,新しいクラスが定義されてしまい,期待通りにはなりません.
ですが,Ttk::Combobox を直接に参照した場合や
先に default_widget_set を :Ttk に切替えた場合には
Object クラスへの定義を行うのでこの問題は生じませんし,
明示的に現在の default_widget_set の要素とするように宣言することで
Object クラスへ定義させることも可能ですので
許容できるレベルではないかと思います.
--
永井 秀利  (nagai@...)
九州工業大学 大学院情報工学研究院 知能情報工学研究系 知能情報メディア部門


[ruby-dev:38711] Re: [1.8.7][1.9.1][tk] 自前実装の拡張 widget を使いたい場合

by oshida :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

押田です。

永井さん、お世話になっております。


> 長らく放置状態で申し訳ありませんでしたが,

いえいえ。


> 近い内に仕上げて commit できそうです.

了解です。
手元のコードでテストさせて頂きます。


> 唯一(?)の問題は TkCombobox が Object クラス上で未定義の状態で
> TkCombobox に機能追加しようとして class TkCombobox とした場合です.
> この場合,新しいクラスが定義されてしまい,期待通りにはなりません.

これは・・・さもありなん、という気がしないでもないです。
こういうユースケースが想像出来ませんでした。

#そういえば Array やらに機能追加する時は、未定義検証していませんが・・・


[ruby-dev:38723] Re: [1.8.7][1.9.1][tk] 自前実装の拡張 widget を使いたい場合

by Hidetoshi NAGAI :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

永井@知能.九工大です.

From: oshida@...
Subject: [ruby-dev:38711] Re: [1.8.7][1.9.1][tk] 自前実装の拡張 widget を使いたい場合
Date: Wed, 24 Jun 2009 10:33:13 +0900
Message-ID: <1245807188.4a418254527a2@...>
> > 近い内に仕上げて commit できそうです.
>
> 了解です。
> 手元のコードでテストさせて頂きます。

問題の箇所については出来上がったと思います.
できれば完了させたいと思っている BWidget 1.8 対応などがまだなので
現時点では commit はしていませんが,
現状での差分ファイルを用意しましたのでお試しいただけますと幸いです.

# Tk 拡張の最新バージョンへの対応以外の点では作業完了だと思います.
# Tcl/Tk8,6b1 への対応も完了しているつもりです.

Ruby 1.9 と 1.8 とでのファイルの共通化作業のために
差分ファイルが少々大きくなってしまいましたので,
以下の場所に置いています.
revision 23917 からの差分です.

 http://www.dumbo.ai.kyutech.ac.jp/~nagai/rbtk19-diff.20090701
 http://www.dumbo.ai.kyutech.ac.jp/~nagai/rbtk18-diff.20090701

# 1.9 の方は 6692 行 (207KB),1.8 の方は 48325 行 (2004KB) あります.

なお,ext/tk/extconf.rb における
Tcl/Tk ライブラリの探索能力強化も行っていますので,
まずはオプションを全く与えずに configure を実行
(--enable-pthread くらいは必要かも) してみてください.
デフォルトでは ActiveTcl 優先で頑張って探してくると思います.

よろしくお願いいたします.
--
永井 秀利  (nagai@...)
九州工業大学 大学院情報工学研究院 知能情報工学研究系 知能情報メディア部門


[ruby-dev:38743] Re: [1.8.7][1.9.1][tk] 自前実装の拡張 widget を使いたい場合

by oshida :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

押田です。

反応が悪くて申し訳ありません。


頂いた差分ですが、
ひとまず 1.8 にて正常動作確認できました。

RHEL 5.3 x86_64
branches/ruby_1_8@23917
./configure --enable-shared --enable-pthread

RHEL の autoconf が 2.59 と古かったので、
2.63 を取ってきて使いました。
#これはあまり関係ないですね。

branches/ruby_1_8_7@23917 だと数ファイルで reject されましたが、
このパッチの適用は 1.8.8 からになりますか?

(そうだとしても当方としても特別困ることは無いと予想しますが・・・)


他の環境についても、追ってレポートします。


[ruby-dev:38747] Re: [1.8.7][1.9.1][tk] 自前実装の拡張 widget を使いたい場合

by Hidetoshi NAGAI :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

永井@知能.九工大です.

From: oshida@...
Subject: [ruby-dev:38743] Re: [1.8.7][1.9.1][tk] 自前実装の拡張 widget を使いたい場合
Date: Tue, 7 Jul 2009 20:22:48 +0900
Message-ID: <1246965753.4a532ff91d5a4@...>
> 反応が悪くて申し訳ありません。

いえ,そんなことはありません.大変助かっています.

> 頂いた差分ですが、
> ひとまず 1.8 にて正常動作確認できました。

良かった.少し安心できました.(^_^)

> RHEL の autoconf が 2.59 と古かったので、
> 2.63 を取ってきて使いました。
> #これはあまり関係ないですね。

そう思います.

> branches/ruby_1_8_7@23917 だと数ファイルで reject されましたが、
> このパッチの適用は 1.8.8 からになりますか?

どのファイルで reject されたのでしょうか?
これまでの修正の一部がまだバックポートされていないのかもしれませんね.

ちなみに,1.8.4 以降くらいなら,ext/tk 以下全体をまるまる置き換えても
大丈夫だろうとは思ってます.

# 現在,Ruby/Tk の更新作業は完了に近付き,
# 残るは BWidget 拡張の新規機能追加くらいという状態です.

> 他の環境についても、追ってレポートします。

ありがとうございます.よろしくお願いいたします.
--
永井 秀利  (nagai@...)
九州工業大学 大学院情報工学研究院 知能情報工学研究系 知能情報メディア部門


[ruby-dev:38748] Re: [1.8.7][1.9.1][tk] 自前実装の拡張 widget を使いたい場合

by oshida :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

押田です。


小出しですみません、
同環境における 1.9 (trunk@23917) でも正常動作を確認しました。


> > branches/ruby_1_8_7@23917 だと数ファイルで reject されましたが、
> どのファイルで reject されたのでしょうか?
> これまでの修正の一部がまだバックポートされていないのかもしれませんね.

改めて branches/ruby_1_8_7 最新(23972)でやってみました。

$ find -name "*.rej"
./ext/tk/tcltklib.c.rej
./ext/tk/tkutil/tkutil.c.rej
./ext/tk/lib/tkextlib/version.rb.rej
./ext/tk/lib/tkextlib/blt/tabnotebook.rb.rej
./ext/tk/lib/tk.rb.rej
./ext/tk/sample/demos-jp/msgbox2.rb.rej
./ext/tk/sample/demos-en/msgbox2.rb.rej
./ext/tk/sample/tkcombobox.rb.rej
./ext/tk/extconf.rb.rej


同様に branches/ruby_1_9_1 最新(23845)だと下記のようになります。
このうち tkextlib/* は "reversed patch detected" しています。

./ext/tk/lib/tkextlib/tile/tradiobutton.rb.rej
./ext/tk/lib/tkextlib/tile/tlabelframe.rb.rej
./ext/tk/lib/tkextlib/tile/tmenubutton.rb.rej
./ext/tk/lib/tkextlib/tile/tcheckbutton.rb.rej
./ext/tk/lib/tkextlib/tile/tpaned.rb.rej
./ext/tk/lib/tk.rb.rej
./ext/tk/lib/tk/autoload.rb.rej
./ext/tk/lib/tk/checkbutton.rb.rej
./ext/tk/lib/tk/menu.rb.rej
./ext/tk/lib/tk/panedwindow.rb.rej
./ext/tk/lib/tk/ttk_selector.rb.rej
./ext/tk/lib/tk/radiobutton.rb.rej
./ext/tk/sample/tktextframe.rb.rej
./ext/tk/sample/tkballoonhelp.rb.rej
./ext/tk/sample/tkcombobox.rb.rej
./ext/tk/sample/editable_listbox.rb.rej
./ext/tk/sample/tkalignbox.rb.rej
./ext/tk/extconf.rb.rej


> ちなみに,1.8.4 以降くらいなら,ext/tk 以下全体をまるまる置き換えても
> 大丈夫だろうとは思ってます.

なるほど。
情報ありがとうございます。
必要に応じてやってみます。


余談になりますが。

個人的には、
1.8.6 の REXML で結構な痛い目を見ていることもあり、
stable release での積極的すぎる変更は歓迎しかねる部分もあります。

それと同じ理屈で言えば、私個人は、
1.8.7 に今回の修正を入れて頂く事には反対、と、
主張すべきなのだと思っています。

#たとえ、それが当方のコードの動作に影響しないとしても。


[ruby-dev:38749] Re: [1.8.7][1.9.1][tk] 自前実装の拡張 widget を使いたい場合

by Hidetoshi NAGAI :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

永井@知能.九工大です.

From: oshida@...
Subject: [ruby-dev:38748] Re: [1.8.7][1.9.1][tk] 自前実装の拡張 widget を使いたい場合
Date: Wed, 8 Jul 2009 16:07:42 +0900
Message-ID: <1247036852.4a5445b4140c9@...>
> 小出しですみません、
> 同環境における 1.9 (trunk@23917) でも正常動作を確認しました。

重ね重ねありがとうございます.

> > > branches/ruby_1_8_7@23917 だと数ファイルで reject されましたが、
> > どのファイルで reject されたのでしょうか?
> > これまでの修正の一部がまだバックポートされていないのかもしれませんね.
>
> 改めて branches/ruby_1_8_7 最新(23972)でやってみました。

こちらはともかくとして

> 同様に branches/ruby_1_9_1 最新(23845)だと下記のようになります。

こちらにまでというのは中田さんに変更していただいた箇所の影響でしょうね.
差分は trunk に対するものですので.

> 余談になりますが。
>
> 個人的には、
> 1.8.6 の REXML で結構な痛い目を見ていることもあり、
> stable release での積極的すぎる変更は歓迎しかねる部分もあります。
>
> それと同じ理屈で言えば、私個人は、
> 1.8.7 に今回の修正を入れて頂く事には反対、と、
> 主張すべきなのだと思っています。

現在作業中の改訂を私自身が 1.8.7 に直接 commit することはありません.
1.8.7 のリリースマネージャの判断にお任せすることになります.
規模が大きいため,バックポートされないんじゃないかと思ってます.(^_^;

私自身は以前のバージョンとの基本的な互換性は維持するように
しているつもりですが,さすがに 100 % とは言えません.
言うまでもないことですが,バグ修正などのため,どうしても差異が生じます.

その一例として,現在の手元の修正では
TkUtil::None.to_s が "" となるように変更されました.
以前は inspect, to_s 共に "None" だったのですが,
マイナーなケースにおいて to_s が "None" だとうまく動かないため
仕方なく変更しています.

# TkUtil::None は Ruby/Tk の内部処理上はかなり重要なのですが,
# 一般ユーザが直接に利用することはめずらしいというような存在です.

以前にその「マイナーなケース」に出会っていた人は
None かどうかを調べるような対策を施しているはずで,
今回の変更はそれとは衝突しないはずです.
ですが,想定外の使われ方が存在しないとは断言できないため
POTENTIALLY INCOMPATIBLE な点ということになります.

Ruby のバージョンが極端に違うものでなければ,
新しい Ruby に旧いバージョンとか
旧い Ruby に新しいバージョンとかでも動くと思うので,
いざとなれば site_ruby とかの RUBYLIB 上での優先順位の高い場所に
動かしたいバージョンの Ruby/Tk をまるまる置いてもらえばいいと思います.
--
永井 秀利  (nagai@...)
九州工業大学 大学院情報工学研究院 知能情報工学研究系 知能情報メディア部門




[ruby-dev:38750] Re: [1.8.7][1.9.1][tk] 自前実装の拡張 widget を使いたい場合

by oshida :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

押田です。


> 1.8.7 のリリースマネージャの判断にお任せすることになります.

はい。
それでよいと考えます。


> いざとなれば site_ruby とかの RUBYLIB 上での優先順位の高い場所に
> 動かしたいバージョンの Ruby/Tk をまるまる置いてもらえばいいと思います.

これも余談になりますが、、、
RedHat (RHEL / Fedora) の Ruby/Tk は、
パッケージ上は本体とは別になっています。

上記のような差し替えを想定したものでは無いでしょうけれど、
もしかすると、将来的に、
このパッケージング・ポリシーが役に立つ事があるのかな、
なんて思ったりしました。


さて本題です。
Cygwin での結果です。

1.8 は期待通りです。

1.9 は残念ながら期待通りではありません。
sample/tkcombobox.rb でも同様の挙動であったため、
そちらの結果をお伝えします。

1.9 では、ノッペラな窓が出るのみで固まってしまいます。
タイトルバーの [X] ボタンでも終了しません。
C-c すると下記が出てきます。

$ ruby ext/tk/sample/tkcombobox.rb
/usr/local/lib/ruby/1.9.1/tk.rb:1363:in `_invoke': Interrupt
        from /usr/local/lib/ruby/1.9.1/tk.rb:1363:in `<module:TkCore>'
        from /usr/local/lib/ruby/1.9.1/tk.rb:1110:in `<top (required)>'
        from ext/tk/sample/tkcombobox.rb:6:in `require'
        from ext/tk/sample/tkcombobox.rb:6:in `<main>'


Cygwin は「今日付の最新」です(^^;

gcc-3.4.4-999
tcltk-20080420-1 (8.4.1)


昨今 Cygwin は頻繁には稼働していないのですが、
タイミングが合えば動作確認することは可能です。

#動作確認用に Cygwin ホスティングが欲しいですね。
#言い出したらキリがないですが :-p


[ruby-dev:38752] Re: [1.8.7][1.9.1][tk] 自前実装の拡張 widget を使いたい場合

by Hidetoshi NAGAI :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

永井@知能.九工大です.

From: oshida@...
Subject: [ruby-dev:38750] Re: [1.8.7][1.9.1][tk] 自前実装の拡張 widget を使いたい場合
Date: Wed, 8 Jul 2009 19:57:43 +0900
Message-ID: <1247050663.4a547ba7531f6@...>
> 押田です。

お世話になっております.

> さて本題です。
> Cygwin での結果です。
>
> 1.8 は期待通りです。
>
> 1.9 は残念ながら期待通りではありません。
> sample/tkcombobox.rb でも同様の挙動であったため、
> そちらの結果をお伝えします。
>
> 1.9 では、ノッペラな窓が出るのみで固まってしまいます。
> タイトルバーの [X] ボタンでも終了しません。
> C-c すると下記が出てきます。
>
> $ ruby ext/tk/sample/tkcombobox.rb
> /usr/local/lib/ruby/1.9.1/tk.rb:1363:in `_invoke': Interrupt
>         from /usr/local/lib/ruby/1.9.1/tk.rb:1363:in `<module:TkCore>'
>         from /usr/local/lib/ruby/1.9.1/tk.rb:1110:in `<top (required)>'
>         from ext/tk/sample/tkcombobox.rb:6:in `require'
>         from ext/tk/sample/tkcombobox.rb:6:in `<main>'

ぁぅ...
Ruby 1.9 で必要になる Tcl インタープリタ専用スレッドが
落ちちゃっているんでしょうね.
以下ではいかがでしょうか?

--- ext/tk/lib/tk.rb (revision 23988)
+++ ext/tk/lib/tk.rb (working copy)
@@ -15,7 +15,9 @@
 class TclTkIp
   # backup original (without encoding) _eval and _invoke
   alias _eval_without_enc _eval
+  alias __eval__ _eval
   alias _invoke_without_enc _invoke
+  alias __invoke__ _invoke
 
   def _ip_id_
     # for RemoteTkIp
@@ -113,17 +115,24 @@
       gen_class_name = ruby_class_name
       classname_def = ''
     else # ruby_class == nil
-      mods = TkExtlibAutoloadModule.find_all{|m| m.const_defined?(tk_class)}
-      mods.each{|mod|
-        begin
-          mod.const_get(tk_class)  # auto_load
-          break if (ruby_class = WidgetClassNames[tk_class])
-        rescue LoadError
-          # ignore load error
-        end
-      }
+      if Tk.const_defined?(tk_class)
+        mod.const_get(tk_class)  # auto_load
+        ruby_class = WidgetClassNames[tk_class]
+      end
 
       unless ruby_class
+        mods = TkExtlibAutoloadModule.find_all{|m| m.const_defined?(tk_class)}
+        mods.each{|mod|
+          begin
+            mod.const_get(tk_class)  # auto_load
+            break if (ruby_class = WidgetClassNames[tk_class])
+          rescue LoadError
+            # ignore load error
+          end
+        }
+      end
+
+      unless ruby_class
         std_class = 'Tk' << tk_class
         if Object.const_defined?(std_class)
           Object.const_get(std_class)  # auto_load
@@ -131,6 +140,14 @@
         end
       end
 
+      unless ruby_class
+        if Tk.const_defined?('TOPLEVEL_ALIASES') &&
+            Tk::TOPLEVEL_ALIASES.const_defined?(std_class)
+          Tk::TOPLEVEL_ALIASES.const_get(std_class)  # auto_load
+          ruby_class = WidgetClassNames[tk_class]
+        end
+      end
+
       if ruby_class
         # found
         ruby_class_name = ruby_class.name
@@ -613,11 +630,35 @@
       val
     end
   end
-  private :bool, :number, :string, :num_or_str
-  private :list, :simplelist, :window, :procedure
-  module_function :bool, :number, :num_or_str, :string
+  private :bool, :number, :num_or_str, :num_or_nil, :string
+  private :list, :simplelist, :window, :image_obj, :procedure
+  module_function :bool, :number, :num_or_str, :num_or_nil, :string
   module_function :list, :simplelist, :window, :image_obj, :procedure
 
+  if (RUBY_VERSION.split('.').map{|n| n.to_i} <=> [1,8,7]) < 0
+    def slice_ary(ary, size)
+      sliced = []
+      wk_ary = ary.dup
+      until wk_ary.size.zero?
+        sub_ary = []
+        size.times{ sub_ary << wk_ary.shift }
+        yield(sub_ary) if block_given?
+        sliced << sub_ary
+      end
+      (block_given?)? ary: sliced
+    end
+  else
+    def slice_ary(ary, size, &b)
+      if b
+        ary.each_slice(size, &b)
+      else
+        ary.each_slice(size).to_a
+      end
+    end
+  end
+  private :slice_ary
+  module_function :slice_ary
+
   def subst(str, *opts)
     # opts := :nobackslashes | :nocommands | novariables
     tk_call('subst',
@@ -1130,30 +1171,42 @@
       opts = ''
     end
 
-    if WITH_RUBY_VM ### check Ruby 1.9 !!!!!!!
-      # *** NEED TO FIX ***
-      ip = TclTkIp.new(name, opts)
-      if ip._invoke_without_enc('tk', 'windowingsystem') == 'aqua' &&
-          (TclTkLib.get_version <=> [8,4,TclTkLib::RELEASE_TYPE::FINAL,9]) > 0
-        # *** KNOWN BUG ***
-        #   Main event loop thread of TkAqua (> Tk8.4.9) must be the main
-        #   application thread. So, ruby1.9 users must call Tk.mainloop on
-        #   the main application thread.
-        RUN_EVENTLOOP_ON_MAIN_THREAD = true
-        INTERP = ip
-      else
-        unless self.const_defined? :RUN_EVENTLOOP_ON_MAIN_THREAD
-          RUN_EVENTLOOP_ON_MAIN_THREAD = false
-        end
-        if RUN_EVENTLOOP_ON_MAIN_THREAD
+    unless self.const_defined? :RUN_EVENTLOOP_ON_MAIN_THREAD
+      if WITH_RUBY_VM ### check Ruby 1.9 !!!!!!!
+        # *** NEED TO FIX ***
+        ip = TclTkIp.new(name, opts)
+        if ip._invoke_without_enc('tk', 'windowingsystem') == 'aqua' &&
+            (TclTkLib.get_version<=>[8,4,TclTkLib::RELEASE_TYPE::FINAL,6]) > 0
+          # *** KNOWN BUG ***
+          #   Main event loop thread of TkAqua (> Tk8.4.9) must be the main
+          #   application thread. So, ruby1.9 users must call Tk.mainloop on
+          #   the main application thread.
+          #
+          # *** ADD (2009/05/10) ***
+          #   In some cases (I don't know the description of conditions),
+          #   TkAqua 8.4.7 has a same kind of hang-up trouble.
+          #   So, if 8.4.7 or later, set RUN_EVENTLOOP_ON_MAIN_THREAD to true.
+          #   When you want to control this mode, please call the following
+          #   (set true/false as you want) before "require 'tk'".
+          #   ----------------------------------------------------------
+          #   module TkCore; RUN_EVENTLOOP_ON_MAIN_THREAD = true; end
+          #   ----------------------------------------------------------
+          #
+          RUN_EVENTLOOP_ON_MAIN_THREAD = true
           INTERP = ip
         else
-          ip.delete
+          unless self.const_defined? :RUN_EVENTLOOP_ON_MAIN_THREAD
+            RUN_EVENTLOOP_ON_MAIN_THREAD = false
+          end
+          if RUN_EVENTLOOP_ON_MAIN_THREAD
+            INTERP = ip
+          else
+            ip.delete
+          end
         end
-      end
-      ip = nil
-    else
-      unless self.const_defined? :RUN_EVENTLOOP_ON_MAIN_THREAD
+        ip = nil
+
+      else # Ruby 1.8.x
         RUN_EVENTLOOP_ON_MAIN_THREAD = false
       end
     end
@@ -1183,13 +1236,29 @@
         #sleep
 
         begin
-          Thread.current[:status].value = TclTkLib.mainloop(true)
-        rescue Exception=>e
-          Thread.current[:status].value = e
+          begin
+            #TclTkLib.mainloop_abort_on_exception = false
+            #Thread.current[:status].value = TclTkLib.mainloop(true)
+            interp.mainloop_abort_on_exception = true
+            Thread.current[:status].value = interp.mainloop(true)
+          rescue SystemExit=>e
+            Thread.current[:status].value = e
+          rescue Exception=>e
+            Thread.current[:status].value = e
+            retry if interp.has_mainwindow?
+          ensure
+            INTERP_MUTEX.synchronize{ INTERP_ROOT_CHECK.broadcast }
+          end
+
+          #Thread.current[:status].value = TclTkLib.mainloop(false)
+          Thread.current[:status].value = interp.mainloop(false)
+
         ensure
-          INTERP_MUTEX.synchronize{ INTERP_ROOT_CHECK.broadcast }
+          # interp must be deleted before the thread for interp is dead.
+          # If not, raise Tcl_Panic on Tcl_AsyncDelete because async handler
+          # deleted by the wrong thread.
+          interp.delete
         end
-        Thread.current[:status].value = TclTkLib.mainloop(false)
       }
 
       until INTERP_THREAD[:interp]
@@ -1321,7 +1390,8 @@
         @add_tk_procs.delete_if{|elem|
           elem.kind_of?(Array) && elem[0].to_s == name
         }
-        self._invoke('rename', name, '')
+        #self._invoke('rename', name, '')
+        self.__invoke__('rename', name, '')
       }
     end
     def INTERP.init_ip_internal
@@ -1704,11 +1774,14 @@
 
     elsif TkCore::RUN_EVENTLOOP_ON_MAIN_THREAD
       # if TclTkLib::WINDOWING_SYSTEM == 'aqua' &&
-      if TkCore::INTERP._invoke_without_enc('tk','windowingsystem')=='aqua' &&
-          Thread.current != Thread.main &&
-          (TclTkLib.get_version <=> [8,4,TclTkLib::RELEASE_TYPE::FINAL,9]) > 0
-        raise RuntimeError,
-              "eventloop on TkAqua ( > Tk8.4.9 ) works on the main thread only"
+      #if TkCore::INTERP._invoke_without_enc('tk','windowingsystem')=='aqua' &&
+      #    Thread.current != Thread.main &&
+      #    (TclTkLib.get_version <=> [8,4,TclTkLib::RELEASE_TYPE::FINAL,9]) > 0
+      #  raise RuntimeError,
+      #       "eventloop on TkAqua ( > Tk8.4.9 ) works on the main thread only"
+      #end
+      if Thread.current != Thread.main
+        raise RuntimeError, "Tk.mainloop is allowed on the main thread only"
       end
       TclTkLib.mainloop(check_root)
 
@@ -3028,7 +3101,7 @@
 
 =begin
     if ext_enc_obj == Tk::Encoding::UNKNOWN
-      if defind? DEFAULT_TK_ENCODING
+      if defined? DEFAULT_TK_ENCODING
         if DEFAULT_TK_ENCODING.kind_of?(::Encoding)
           tk_enc_name    = DEFAULT_TK_ENCODING.name
           tksys_enc_name = DEFAULT_TK_ENCODING.name
@@ -3126,7 +3199,7 @@
           #if ext_enc_name && ext_enc_name != tksys_enc_name
           int_enc_name = Tk::Encoding::ENCODING_TABLE.get_name(int_enc_obj)
           if int_enc_name
-            # use default_external
+            # use default_internal
             enc_name = int_enc_name
           else
             # use Tk.encoding_system
@@ -3279,10 +3352,10 @@
         TkFont.init_widget_font(pathname, *__confinfo_cmd)
     else
       fonts = {}
-      optkeys.each{|key|
-        key = key.to_s
-        pathname = [win, tag, key].join(';')
-        fonts[key] =
+      optkeys.each{|k|
+        k = k.to_s
+        pathname = [win, tag, k].join(';')
+        fonts[k] =
           TkFont.used_on(pathname) ||
           TkFont.init_widget_font(pathname, *__confinfo_cmd)
       }
@@ -3407,7 +3480,7 @@
       if fobj.kind_of?(TkFont)
         if ltn.kind_of?(TkFont)
           conf = {}
-          ltn.latin_configinfo.each{|key,val| conf[key] = val}
+          ltn.latin_configinfo.each{|k,val| conf[k] = val}
           if keys
             fobj.latin_configure(conf.update(keys))
           else
@@ -3467,7 +3540,7 @@
       if fobj.kind_of?(TkFont)
         if knj.kind_of?(TkFont)
           conf = {}
-          knj.kanji_configinfo.each{|key,val| conf[key] = val}
+          knj.kanji_configinfo.each{|k,val| conf[k] = val}
           if keys
             fobj.kanji_configure(conf.update(keys))
           else
@@ -3701,11 +3774,17 @@
     val
   end
 
+  def cget_tkstring(option)
+    opt = option.to_s
+    fail ArgumentError, "Invalid option `#{option.inspect}'" if opt.length == 0
+    tk_call_without_enc(*(__cget_cmd << "-#{opt}"))
+  end
+
   def __cget_core(slot)
     orig_slot = slot
     slot = slot.to_s
 
-   if slot.length == 0
+    if slot.length == 0
       fail ArgumentError, "Invalid option `#{orig_slot.inspect}'"
     end
 
@@ -4106,7 +4185,8 @@
 
           else
             # conf = tk_split_list(_fromUTF8(tk_call_without_enc(*(__confinfo_cmd << "-#{slot}"))))
-            conf = tk_split_list(tk_call_without_enc(*(__confinfo_cmd << "-#{slot}")), 0, false, true)
+            # conf = tk_split_list(tk_call_without_enc(*(__confinfo_cmd << "-#{slot}")), 0, false, true)
+            conf = tk_split_list(tk_call_without_enc(*(__confinfo_cmd << "-#{slot}")), 1, false, true)
           end
           conf[__configinfo_struct[:key]] =
             conf[__configinfo_struct[:key]][1..-1]
@@ -4296,8 +4376,8 @@
             end
           }
 
-          __methodcall_optkeys.each{|optkey, method|
-            ret << [optkey.to_s, '', '', '', self.__send__(method)]
+          __methodcall_optkeys.each{|optkey, m|
+            ret << [optkey.to_s, '', '', '', self.__send__(m)]
           }
 
           ret
@@ -4335,7 +4415,7 @@
         if slot
           slot = slot.to_s
 
-          alias_name, real_name = __optkey_aliases.find{|k, v| k.to_s == slot}
+          alias_name, real_name = __optkey_aliases.find{|k,var| k.to_s == slot}
           if real_name
             slot = real_name.to_s
           end
@@ -4682,8 +4762,8 @@
             end
           }
 
-          __methodcall_optkeys.each{|optkey, method|
-            ret[optkey.to_s] = ['', '', '', self.__send__(method)]
+          __methodcall_optkeys.each{|optkey, m|
+            ret[optkey.to_s] = ['', '', '', self.__send__(m)]
           }
 
           ret
@@ -4721,18 +4801,18 @@
           "there is a configure alias loop about '#{org_slot}'"
       else
         ret = {}
-        configinfo().each{|conf|
+        configinfo().each{|cnf|
           if ( ! __configinfo_struct[:alias] \
-              || conf.size > __configinfo_struct[:alias] + 1 )
-            ret[conf[0]] = conf[-1]
+              || cnf.size > __configinfo_struct[:alias] + 1 )
+            ret[cnf[0]] = cnf[-1]
           end
         }
         ret
       end
     else # ! TkComm::GET_CONFIGINFO_AS_ARRAY
       ret = {}
-      configinfo(slot).each{|key, conf|
-        ret[key] = conf[-1] if conf.kind_of?(Array)
+      configinfo(slot).each{|key, cnf|
+        ret[key] = cnf[-1] if cnf.kind_of?(Array)
       }
       ret
     end
@@ -4864,6 +4944,7 @@
   include TkWinfo
   extend TkBindCore
   include Tk::Wm_for_General
+  include Tk::Busy
 
   @@WIDGET_INSPECT_FULL = false
   def TkWindow._widget_inspect_full_?
@@ -5551,7 +5632,7 @@
 #Tk.freeze
 
 module Tk
-  RELEASE_DATE = '2009-01-13'.freeze
+  RELEASE_DATE = '2009-07-08'.freeze
 
   autoload :AUTO_PATH,        'tk/variable'
   autoload :TCL_PACKAGE_PATH, 'tk/variable'

--
永井 秀利  (nagai@...)
九州工業大学 大学院情報工学研究院 知能情報工学研究系 知能情報メディア部門


[ruby-dev:38754] Re: [1.8.7][1.9.1][tk] 自前実装の拡張 widget を使いたい場合

by oshida :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

押田です。


> お世話になっております.

いえいえ(^^;
こちらこそ大変おせわになっております。


> 以下ではいかがでしょうか?

ext/tk/lib/tk.rb だけ revert して patch し直しまして、
trunk@23996 での結果は、いぜん動作せず、でして・・・

/usr/local/lib/ruby/1.9.1/tk.rb:1410:in `_invoke': Interrupt
        from /usr/local/lib/ruby/1.9.1/tk.rb:1410:in `<module:TkCore>'
        from /usr/local/lib/ruby/1.9.1/tk.rb:1149:in `<top (required)>'
        from ext/tk/sample/tkcombobox.rb:6:in `require'
        from ext/tk/sample/tkcombobox.rb:6:in `<main>'
Tcl_Release couldn't find reference for 0x10341550
Aborted (core dumped)

ダンプ内容は、、、省略します。


[ruby-dev:38755] Re: [1.8.7][1.9.1][tk] 自前実装の拡張 widget を使いたい場合

by Hidetoshi NAGAI :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

永井@知能.九工大です.

From: oshida@...
Subject: [ruby-dev:38754] Re: [1.8.7][1.9.1][tk] 自前実装の拡張 widget を使いたい場合
Date: Thu, 9 Jul 2009 16:39:06 +0900
Message-ID: <1247125129.4a559e89e67b8@...>

> ext/tk/lib/tk.rb だけ revert して patch し直しまして、
> trunk@23996 での結果は、いぜん動作せず、でして・・・
>
> /usr/local/lib/ruby/1.9.1/tk.rb:1410:in `_invoke': Interrupt
>         from /usr/local/lib/ruby/1.9.1/tk.rb:1410:in `<module:TkCore>'
>         from /usr/local/lib/ruby/1.9.1/tk.rb:1149:in `<top (required)>'
>         from ext/tk/sample/tkcombobox.rb:6:in `require'
>         from ext/tk/sample/tkcombobox.rb:6:in `<main>'
> Tcl_Release couldn't find reference for 0x10341550
> Aborted (core dumped)
>
> ダンプ内容は、、、省略します。

ダメでしたか.(;_;)
1.9 なので,native thread 絡みの部分だろうとは思うのですが...

わずかな可能性として,require 'tk' の前に
-------------------------------------------------------
module TkCore
  RUN_EVENTLOOP_ON_MAIN_THREAD = true
end
-------------------------------------------------------
を実行するようにしてみていただけませんか?

Ruby 1.9 でこれを設定すると,
Tk.mainloop は main thread でしか実行できなくなりますが
( Thread.new{Tk.mainloop} はうまく機能しません ),
eventloop と nativethread の絡みで hang up しているようなケースは
回避できる可能性があります.

もしこれで回避できるなら,Cygwin 環境ではこの設定としておくことで
当面の回避策としたいと思います.
これでもダメなら,目前は対応が間に合いそうにないので
残念ながら Cygwin 環境での Ruby 1.9 の Ruby/Tk は非サポート
(少なくとも当面は) とさせていただこうと思います.
--
永井 秀利  (nagai@...)
九州工業大学 大学院情報工学研究院 知能情報工学研究系 知能情報メディア部門



[ruby-dev:38759] Re: [1.8.7][1.9.1][tk] 自前実装の拡張 widget を使いたい場合

by oshida :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

押田です。


> module TkCore
>   RUN_EVENTLOOP_ON_MAIN_THREAD = true
> end

これを ext/tk/sample/tkcombobox.rb の require 'tk' の直前に挿入した結果です。

/usr/local/lib/ruby/1.9.1/tk.rb:1786: [BUG] Segmentation fault
ruby 1.9.2dev (2009-07-08) [i386-cygwin]

-- control frame ----------
c:0005 p:---- s:0017 b:0017 l:000016 d:000016 CFUNC  :mainloop
c:0004 p:0120 s:0013 b:0013 l:000012 d:000012 METHOD
/usr/local/lib/ruby/1.9.1/tk.rb:1786
c:0003 p:0404 s:0009 b:0009 l:0005f4 d:001258 EVAL   tkcombobox.rb:431
c:0002 p:---- s:0004 b:0004 l:000003 d:000003 FINISH
c:0001 p:0000 s:0002 b:0002 l:0005f4 d:0005f4 TOP
---------------------------
tkcombobox.rb:431:in `<main>'
/usr/local/lib/ruby/1.9.1/tk.rb:1786:in `mainloop'
/usr/local/lib/ruby/1.9.1/tk.rb:1786:in `mainloop'

[NOTE]
You may have encountered a bug in the Ruby interpreter or extension libraries.
Bug reports are welcome.
For details: http://www.ruby-lang.org/bugreport.html

Aborted


こちらで追いかける事ができず、すみません。
あまり 1.9 の事を理解していないので・・・


[ruby-dev:38768] Re: [1.8.7][1.9.1][tk] 自前実装の拡張 widget を使いたい場合

by Hidetoshi NAGAI :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

永井@知能.九工大です.

From: oshida@...
Subject: [ruby-dev:38759] Re: [1.8.7][1.9.1][tk] 自前実装の拡張 widget を使いたい場合
Date: Fri, 10 Jul 2009 14:45:40 +0900
Message-ID: <1247204729.4a56d579b341e@...>
> /usr/local/lib/ruby/1.9.1/tk.rb:1786: [BUG] Segmentation fault
> ruby 1.9.2dev (2009-07-08) [i386-cygwin]

ごめんなさい.
環境を準備する時間がなく,結局,現時点では原因がわかりませんでした.
仕方なく,Cygwin 環境でダメな状況は known bug として,
trunk と ruby_1_8 とに commit しました.

> こちらで追いかける事ができず、すみません。
> あまり 1.9 の事を理解していないので・・・

少なくとも,調べねばならない相手がわかるだけでも本当に助かります.

tcltklib のイベントループでは,実行依頼が Ruby 側からであったり
Tcl/Tk 側からのコールバックであったりと様々な上,
依頼元が同一スレッドであったり別スレッドであったり,
実際に処理を行うべきが Tcl/Tk 上であったり Ruby 上であったり,
結果の値の返却を要求していたり不要だったり,
といった具合で,かなりややこしいことになっています.
ひとつのコールバック処理でも Ruby と Tcl/Tk との間を行ったり来たりで,
追いかけるのも非常に面倒です.
これにスレッド切替え,特に native thread まで絡んでくると,
もう何というか...(^_^;

とりあえず今回の commit では Cygwin 環境での 1.9 対応を諦めましたが
Cygwin 対応そのものを諦めたわけではありません.
できるだけ早い内に時間を作って再挑戦しようと思います.

その際,たとえ些細な情報でも解決の糸口になる可能性がありますので,
何かお気付きの点があれば,気軽に報告いただけますと助かります.
--
永井 秀利  (nagai@...)
九州工業大学 大学院情報工学研究院 知能情報工学研究系 知能情報メディア部門


[ruby-dev:38781] Re: [1.8.7][1.9.1][tk] 自前実装の拡張 widget を使いたい場合

by oshida :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

押田です。


> 環境を準備する時間がなく,結局,現時点では原因がわかりませんでした.

お力になれず、すみませんです。。。


> その際,たとえ些細な情報でも解決の糸口になる可能性がありますので,
> 何かお気付きの点があれば,気軽に報告いただけますと助かります.

はい、何か気付いた事があればご連絡致します。


そそういえば・・・
Windows での Cygwin : Native (MSWin32, etc) 比率ってどのくらいなのでしょう。
そういった情報はあるでしょうか。
確か Cygwin はメンテナを募集されていたような・・・
そういう意味では少数派なのでしょうか。


[ruby-dev:38803] Re: [1.8.7][1.9.1][tk] 自前実装の拡張 widget を使いたい場合

by oshida :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

押田です。


Bug #1774 の件、ruby-dev:38792 で

> mingwやcygwinはここ数年見てません...

とありましたので、trunk@24117 を Cygwin で make してみたのです。
#それはそれで、あちらにレスしようと思います。

そうしたら、、、動いてしまいました(^^;

ruby は trunk@24117 素の状態で、
ext/tk/sample/tkcombobox.rb には ruby-dev:38755 のパッチ、
↓を充てた状態です。

> module TkCore
>   RUN_EVENTLOOP_ON_MAIN_THREAD = true
> end


パッチを充てない tkcombobox.rb は、
前回と同様に固まってしまいます。

これで、一件落着、でしょうか?(^^;

< Prev | 1 - 2 | Next >