KDOC 201: スクリーンルーラーを作る

この文書のステータス

  • 作成
    • 2024-07-20 貴島
  • レビュー
    • 2024-07-22 貴島

DONE プロジェクトステータス

プロジェクトは完了である。

概要

X Window Systemでスクリーンルーラーを作る。

Tasks

TODO イベントループを使う

ルーラー追従を、単純なループにsleepを入れて実装していてすごいダサい。カーソルイベントを受け取って同期したい。

DONE 動作するようにする

swillner/highlight-pointer的な感じで自作したい。

  • 極小のウィンドウを作って、それをカーソル周辺に描画しているように見える
XRectangle rect;
XserverRegion region = XFixesCreateRegion(dpy, &rect, 1);
XFixesSetWindowShapeRegion(dpy, win, ShapeInput, 0, 0, region);
XFixesDestroyRegion(dpy, region);

} else if (highlight_visible) { get_pointer_position(&x, &y); XMoveWindow(dpy, win, x - total_radius - 1, y - total_radius - 1); * unfortunately, this causes increase of the X server’s cpu usage * }

static void set_window_mask() {

static void redraw() { XSetForeground(dpy, gc, button_pressed ? pressed_color.pixel : released_color.pixel); if (options.outline) { XSetLineAttributes(dpy, gc, options.outline, LineSolid, CapButt, JoinBevel); XDrawArc(dpy, win, gc, options.outline, options.outline, 2 * options.radius + 1, 2 * options.radius + 1, 0, 360 * 64); } else { XFillArc(dpy, win, gc, options.outline, options.outline, 2 * options.radius + 1, 2 * options.radius + 1, 0, 360 * 64); } }

static int init_events() { XIEventMask events; unsigned char mask[(XI_LASTEVENT + 7) / 8]; memset(mask, 0, sizeof(mask));

XISetMask(mask, XI_RawButtonPress); XISetMask(mask, XI_RawButtonRelease); XISetMask(mask, XI_RawMotion);

events.deviceid = XIAllMasterDevices; events.mask = mask; events.mask_len = sizeof(mask);

XISelectEvents(dpy, root, &events, 1);

return 0; }

  • イベントマスクとは、特定のイベントが発生したときに通知を受け取るための機構。一般的に、イベントマスクはビットマスクとして表現され、各ビットが特定のイベントタイプに対応している

static void show_highlight() { int x, y; int total_radius = options.radius + options.outline; get_pointer_position(&x, &y); XMoveWindow(dpy, win, x - total_radius - 1, y - total_radius - 1); XMapWindow(dpy, win); redraw(); highlight_visible = 1; }

  • 新しく作成されるウィンドウはウィンドウマネージャによって制御されず、直接画面に表示される
  • valueMaskで、ビット形式で指定したマスクに対して、可変長引数の値を設定していく
  • xfixesで対象領域のクリックを無視する
BadRequest {NiceName: Request, Sequence: 2, BadValue: 0, MinorOpcode: 5, MajorOpcode: 138}
exit status 1
xdpyinfo -queryExtensions | grep opcode

BIG-REQUESTS (opcode: 133) Composite (opcode: 142) DAMAGE (opcode: 143, base event: 91, base error: 152) DOUBLE-BUFFER (opcode: 145, base error: 153) DPMS (opcode: 147) DRI2 (opcode: 155, base event: 119) DRI3 (opcode: 149) GLX (opcode: 152, base event: 95, base error: 158) Generic Event Extension (opcode: 128) MIT-SCREEN-SAVER (opcode: 144, base event: 92) MIT-SHM (opcode: 130, base event: 65, base error: 128) Present (opcode: 148) RANDR (opcode: 140, base event: 89, base error: 147) RECORD (opcode: 146, base error: 154) RENDER (opcode: 139, base error: 142) SECURITY (opcode: 137, base event: 86, base error: 138) SHAPE (opcode: 129, base event: 64) SYNC (opcode: 134, base event: 83, base error: 134) X-Resource (opcode: 150) XC-MISC (opcode: 136) XFIXES (opcode: 138, base event: 87, base error: 140) XFree86-DGA (opcode: 154, base event: 112, base error: 179) XFree86-VidModeExtension (opcode: 153, base error: 172) XINERAMA (opcode: 141) XInputExtension (opcode: 131, base event: 66, base error: 129) XKEYBOARD (opcode: 135, base event: 85, base error: 137) XTEST (opcode: 132) XVideo (opcode: 151, base event: 93, base error: 155)

  • コードは138で、 XFIXES である。ここからは何もわからない

xtrace -o output.log ./xpoint
001:<:0003: 16: XFIXES-Request(138,5): CreateRegion region=0x05600001 rectangles={x=0 y=0 w=0 h=0};
001:<:0004:  4: Request(43): GetInputFocus
001:>:0003:Error 1=Request: major=138, minor=5, bad=0x00000000, seq=0003
000:<:0009: 12: XFIXES-Request(138,0): QueryVersion major version=6 minor version=0
000:>:0009:32: Reply to QueryVersion: major version=6 minor version=0
000:<:000a: 16: XFIXES-Request(138,5): CreateRegion region=0x05400002 rectangles={x=0 y=0 w=0 h=0};
000:<:000b: 20: XFIXES-Request(138,21): SetWindowShapeRegion window=0x05400001 kind=Input(0x02) x offset=0 y offset=0 region=0x05400002
000:<:000c:  8: XFIXES-Request(138,10): DestroyRegion region=0x05400002
000:<:000d: 24: Request(98): QueryExtension name='XInputExtension'
  • 正常なプログラムではXFIXESがまとまって存在しているが、エラーが起きるコードでは見知らぬGetInputFocusが混じっている。こいつがうまくいっていない可能性がある
  • なぜか先にバージョンを確認すると動作するようになった

DONE 透明度を設定する

半透明にする。

  • comptonが起動してないと透明にならない
  • X Window Systemは透明の表示をサポートしてない。受け取れるが描画はできない
  • comptonはコンポジットマネージャ。コンポジットマネージャはウィンドウを描画し合成する責任を持つ

DONE コード整理する

きれいにする。

関連

なし。

Backlinks