9

画面上のすべてのウィンドウの上にいくつかのプリミティブを描画したいと思います。C でいくつかのコードを見つけ、Python の xlib を使用するように移植しようとしました。

from Xlib.display import Display
from Xlib import X
from Xlib import protocol

display = Display(':0')
root = display.screen().root
gc = root.create_gc()
root.fill_rectangle(gc, 100, 100, 500, 500)

しかし、画面には何も表示されません (ただし、ルート ウィンドウが割り当てられています: 動作後にキーボードを取得します)。これを正しく行う方法は?

4

1 に答える 1

6

ルート ウィンドウに描画できます。コードはおそらく機能しますが、ルート ウィンドウはある種のデスクトップ ウィンドウ (nautilus、kde デスクトップなど) によって隠される場合があります。プログラムを実行せずに X セッションを開始すると、更新が表示されます (これには Xephyr または Xnest を使用できます)。

別のアプローチは、透明なウィンドウを作成し、それを一番上にして、その表面に描画することです。マウス イベントを下層のウィンドウに手動で伝達する必要があります。

実際にすべてのウィンドウの上に描画するには、単純な複合マネージャーを作成する必要があります。または、既に CM が実行されている場合は、オーバーレイ ウィンドウを使用します。

複合プロトコル仕様から:

プロトコルのバージョン 0.3 は、コンポジット オーバーレイ ウィンドウを追加します。これは、コンポジット マネージャに干渉なしで描画できるサーフェスを提供します。このウィンドウは常に通常のウィンドウの上にあり、常にスクリーン セーバー ウィンドウの下にあります。これは、幅と高さが画面の寸法である入出力ウィンドウです。そのビジュアルはルート ビジュアルであり、その境界線の幅はゼロです。複合拡張機能を使用してリダイレクトしようとしても無視されます。このウィンドウは、QueryTree 要求の応答には表示されません。これはオーバーライド リダイレクト ウィンドウでもあります。これらの最後の 2 つの機能により、ウィンドウ マネージャーや他の X11 クライアントからは見えなくなります。このウィンドウの XID にアクセスする唯一の方法は、CompositeGetOverlayWindow リクエストを使用することです。最初は、コンポジット オーバーレイ ウィンドウはマップされていません。

CompositeGetOverlayWindow は、コンポジット オーバーレイ ウィンドウの XID を返します。ウィンドウがまだマップされていない場合は、このリクエストによってマップされます。このリクエストを呼び出したすべてのクライアントが X11 接続を終了すると、ウィンドウはマップ解除されます。

複合マネージャーは、複合オーバーレイ ウィンドウに直接レンダリングするか、他のウィンドウの親を変更してこのウィンドウの子にし、それらにレンダリングすることができます。複数のクライアントが複合オーバーレイ ウィンドウにレンダリングし、その子ウィンドウを作成し、形状を変更し、入力領域を再定義することができますが、これらのクライアントが従う特定の調停規則は、この仕様では定義されていません。これらのポリシーは、クライアント自身が定義する必要があります。

于 2013-01-11T00:46:40.840 に答える