スポンサーリンク

T.Ishii's Software Library

HTML5 レトロ風ゲーム館

無料ブログはココログ

« あと少しなんだが | トップページ | コード整理とか »

本題に戻った

今は、Mirror-DTC for Ubuntu Ver1.4.1の開発中で、今回の開発では、Windows版に続いてトランスポーターを追加する予定なので、ここ数日は、その関連開発を行っていたのだが、ウインドウの特殊操作については大体試したので、本題に戻った。

Ubuntu版Mirror-DTCでは、デスクトップの画像をキャプチャーしたり、キー入力やマウス入力のエミュレーションを行っているのだが、これらの処理の為には、GUI開発に使っているgtkmmの処理コードは使っていない。それでは、どんなコードを使っているのか、というと、X-Windowの関数を直接使っている。

で、X-Windowの関数というのは、UbuntuのGUIの中では、最もプリミティブな処理が行えるので、それらを使えば、gtkmmでは行えない様な処理も可能になるのだが、今回、トランスポーターを開発するにあたっても、X-Windowの関数を使っている。

もっとも、今までとは違って、それらの中でも、ウインドウのプロパティを扱う関数を多用しているのだが、X-Windowのプリミティブな世界では、このプロパティには意味はない訳だ。

つまり、今回扱っているプロパティというのは、X-Windowの仕様とは別の所で定義されているので、それを使おうとする開発者的には、より一層、判りづらい感じになっている。

具体的には、ネットを見ていても、このプロパティについては明確なドキュメントは存在しないので、xpropのソースコードを参照する必要がある、みたいな書込みが、結構、見られたりした。

と、言うことで、今回の開発では、そういった、今までとは毛色が違うウインドウのプロパティを扱うコードを色々と試してみたのだが、それらの中には、使えそうなモノもあったのだが、マトモに使えないモノもあった。

何故なら、これらのプロパティというのは、基本的には、ウインドウマネージャーに要求を出すために使う格好になるのだが、ウインドウマネージャーによっては、それらの要求にマトモに答えない場合もあるからだ。

更に言えば、X-Windowの関数についても、ウインドウマネージャーが処理関数を書き換えて通常のX-Windowの処理通りには処理させなくしたりしている訳だ。

例えば、今回、トランスポーターを開発するにあたり、ウインドウを隠す方法を決めるのに苦労しているのだが、その理由は、X-Windowの関数が素直に動作するのであれば、デスクトップ領域の外にウインドウを移動させるだけで、ウインドウは隠せるのだが、この処理関数がウインドウマネージャーに干渉されてしまうので、デスクトップ領域の外にウインドウを移動する事が出来ないからだ。

また、X-Windowの関数には、XLowerWindowという関数もあって、この関数を使えば、最前面に移動の逆の事が行える事になっている。

つまり、今現在存在している全てのウインドウの後ろに表示を持っていける事になっているのだが、Ubuntu18.04LTS環境で、この関数を使っても、そんな事象は発生しない訳だ。

これについても、ウインドウマネージャーが干渉しているからで、その証拠に、以下のコードを先に実行すれば、背面に移動する様になる。

XSetWindowAttributes att;
att.override_redirect = True;
XChangeWindowAttributes(m_display, winid, CWOverrideRedirect, &att);

上記のコードを実行すれば、ウインドウマネージャーの干渉を無くせるので、そのあとで、XLowerWindowを実行すれば、普通に実行される様になるのだが、デスクトップ上の他のウインドウをクリックしてみると、背面に移動していたウインドウは、元々あった位置に戻ってしまう訳だ。

つまり、上記の様にして、ウインドウマネージャーの干渉を無くして処理を実行してみても、そのうち、また、ウインドウマネージャーが自分の世界を構築し直す格好になるので、あまり意味は無かったりする。

と、言うことで、Linux用のOSでは、GUIはX-Windowがベースになっているので、X-Windowの処理関数も色々と使えはするのだが、その上位層にはウインドウマネージャーが存在しているので、アプリケーションプログラムでは、その干渉を受けて、X-Windowの処理関数を自由に使えるという訳でもない感じだ。

しかしまあ、今回の開発で色々と試してみた所では、ウインドウの透明化については、比較的自由に行える感じだし、他ソフトのタイトルバーを削除しつつマウス入力リージョンを制限する事で、マウス操作もスルーさせる事が可能だという事が判った。

なので、何か他のソフトを作る時には、そういった手法を使える感じになったのだが、今回の開発では、トランスポーターを完成させなければならないので、今日から、その開発を先に進める事にした訳だ。

ちなみに、結局、ウインドウを透明化してマウス入力が行われない様にしたウインドウについても、他ウインドウがフォーカスを失ったりすると、キーボードフォーカスが与えられてしまう、という問題については解決出来なかった。

ネットを見ている人の中には、「WM_TAKE_FOCUS」というプロパティを取り去れば良いだけなのに!なんて事を思っている人もいるかもしれないのだが、作者的には、2日くらい前に、そういった事はやってみていたのだが、意味はなかった訳だ。

それはX-Windowの仕様なのかウインドウマネージャーの仕様なのかは判らないのだが、既に存在しているウインドウから上記のプロパティを削除した後、xpropでプロパティを見てみると、通常のウインドウでは、「WM_HITS」の表示で「Client accepts input or input focus: True」となっている所が、Falseにはなるのだが、その後も、普通にフォーカスは与えられてしまう訳だ。

なので、前述のXLowerWindow関数を使って、せめて、他にウインドウがある場合には、それらのウインドウに先にフォーカスが与えられる様にしようか、と、やってみたのだが、前述の通りの結果となった訳だ。

このため、キーボードフォーカスについてはどうしようもないので、タイマー処理でウインドウの状態を監視し、もし、フォーカスが与えられてしまった場合には、トランスポーターがX-Windowの関数を使って、フォーカスを別のウインドウに与える格好にする事にした。

そんな事が出来るのなら、最初からそうすれば良いじゃないか! と、思った人もいるかもしれないのだが、問題になるのは、作者的には、隠しているウインドウがフォーカスを得てしまったのが、他ウインドウがクローズされたからなのか、タスクバーアイコンがクリックされたからなのかが判らない、という事だ。

つまり、Windows版トランスポーターでは、タスクバーアイコンをクリックするだけで、隠しているウインドウを再表示して操作可能になるのだが、Ubuntu版では、ウインドウ操作には、もう少し複雑なシーケンスが必要になるので、出来れば、そんな事にはしたくなかった訳だ。

もっとも、複雑な操作というのは、Ctrlキーを押しながら、タスクバーアイコンをクリックすれば、再表示する、程度の事にも出来る筈だし、最悪、トランスポーターのダイアログからしか再表示は出来ない、という事にしてみても、大して困りはしないかもしれない。

何れにしても、まだ、トランスポーターのメイン処理は何も動作しない状況なので、今日から、そういった処理の実装を先に進め、上記については、最後の仕上げ時にどうするかを決める事になる筈だ。

« あと少しなんだが | トップページ | コード整理とか »

2019年8月
        1 2 3
4 5 6 7 8 9 10
11 12 13 14 15 16 17
18 19 20 21 22 23 24
25 26 27 28 29 30 31

広告

プライバシーポリシー

  • 当サイトでは、第三者配信による広告(Google Adsense)サービスを利用しています。

    Google を含む第三者配信事業者は、Cookie を使用して、ユーザーのウェブサイトでの閲覧履歴に基づく広告を配信します。 Google 広告 Cookie を使用することにより、Google や Google のパートナーは当サイトや他のサイトへのアクセス情報に基づく広告をユーザーに表示できます。

    収集された情報がGoogleによってどの様に使用されるか、収集される情報をユーザーが管理する方法については、以下のリンクを参照下さい。

    ポリシーと規約 - Google