16

次のコードはどのようにしてウィンドウの境界線を削除しますか?

//note the struct is declared elsewhere, is here just for clarity.
//code is from [http://tonyobryan.com/index.php?article=9][1]
typedef struct Hints
{
    unsigned long   flags;
    unsigned long   functions;
    unsigned long   decorations;
    long            inputMode;
    unsigned long   status;
} Hints;

//code to remove decoration
Hints hints;
Atom property;
hints.flags = 2;
hints.decorations = 0;
property = XInternAtom(display, "_MOTIF_WM_HINTS", true);
XChangeProperty(display,window,property,property,32,PropModeReplace,(unsigned char *)&hints,5);
XMapWindow(display, window);

これまでのところ、Atomはウィンドウやディスプレイに似た一種の識別子であると収集しましたが、ヒント構造または「_MOTIF_WM_HINTS」がどこから来たのかわかりません。誰かが私のためにこのコードのすべてを説明できますか?よろしくお願いします。

4

2 に答える 2

16

どんな種類の「公式」に見える標準などで入手するのは難しいですが、_MOTIF_WM_HINTSプロパティは... Motifツールキットから来ているようです(わかりました、あなたはそれを推測しました:-))。MotifZoneサイトを参照してください。

警告:以下は不完全ですが、私が望むいくつかの光を当てる必要があります。

ツールキットのXmNmwmDecorations、XmNmwmFunctions、およびXmNmwmInputMode関数のドキュメントには、プロパティが、ウィンドウマネージャーが提供/提供する必要のある外観、関数(サイズ変更、移動など)、および入力モードを制御するために使用されるさまざまな値のビットマスクであることが示されています。窓。man vendorshell、またはOreilly Motifの参考書、Vol6aの第16章を参照してください。

プロパティはX11全体の一部です。ウィンドウには、任意の数のプロパティを定義できます。プロパティには名前がありますが、プロパティの設定/取得は「アトム」(ソートの識別子)を介して行われ、get/set呼び出しごとに文字列全体がネットワークに送信されるのを防ぎます。プロパティと原子を参照してください

現在のウィンドウマネージャー(存在する場合)は、適切なイベントフィルターを設定してPropertyNotifyイベントを処理するか、ウィンドウがマップされる(または移動されるなど)ときにウィンドウが持つプロパティを検査することで、ウィンドウプロパティの変更に対応できます。ウィンドウマネージャーが_MOTIF_WM_HINTプロパティを知っている場合、ウィンドウマネージャーはそれらを解釈し、(うまくいけば)必要なことを実行します。(注:その特権がウィンドウマネージャーに委譲されているかどうか、または他のウィンドウがそれらの「PropertyNotify」イベントをリッスンできるかどうかはよくわかりません。それが実際にあなたの質問に関連しているかどうかはわかりません。)

したがって、ウィンドウマネージャが_MOTIF_WM_HINTSプロパティを認識している限り、使用しているコードは問題なく機能します。

XInternAtomを使用してアトム(識別子/ショートカット)を取得し、ウィンドウが実際にMapWindow()を介して描画される前に、XChangeProperty()を介してその値を設定することから始めます(MapWindow()の後に実行した場合に機能するかどうかはわかりません) 、それはあなたのウィンドウマネージャーに依存するかもしれません)。

[編集:.decorations部分をゼロに設定すると、すべての装飾ビットがクリアされるため、ウィンドウマネージャーは基本的に境界線をそのままにしておく必要があります。]

その構造体の定義を「公式」に思いつくことはできません。これは、openmotif-2.3.3ディストリビューションのlib / X11/MwmUtils.hで定義されています。.flagsエントリがどのように使用されているかはわかりませんが(私の人生のコードが見つかりません:-/)、{decoration、function、inputMode}の「サブプロパティ」のどれであるかを示すために使用されていると思われますに基づいて行動する。(私の言葉を信じないでください。)

ちなみに、現時点では_MOTIF_WM_HINTSを使用するのが最善の選択肢ではない可能性があります。freedesktopでExtendedWindowManagerのヒントの仕様やその他の情報/標準/ドラフトを見たことがありますか?ほとんどの「最新の」ウィンドウマネージャー/デスクトップ環境/キッチンシンクは、Motifとの下位互換性を維持するのではなく、それに準拠する傾向があります。すべてはあなたがコーディングしているものに依存していると思います。

読んでくれてありがとう :-)

于 2011-03-03T20:40:54.177 に答える
0

宿泊施設をご覧ください_MOTIF_WM_HINTS。コードを動作状態に変更しました:

#include <X11/Xlib.h>
#include <X11/Xatom.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
 
#define MAPIT
#undef REPEAT

void waitxevt(Display* d, int type)

{

    XEvent e; /* XEvent holder */

    do { XNextEvent(d, &e); } while (e.type != type);

}

void frame(Display* d, Window w, int e)

{

    Atom window_type;
    Atom motif_hints;
    long value;

#ifdef MAPIT
    XUnmapWindow(d, w);
    waitxevt(d, UnmapNotify);
#endif
    window_type = XInternAtom(d, "_NET_WM_WINDOW_TYPE", False);
    if (e) value = XInternAtom(d, "_NET_WM_WINDOW_TYPE_NORMAL", False);
    else value = XInternAtom(d, "_NET_WM_WINDOW_TYPE_DOCK", False);
    XChangeProperty(d, w, window_type, XA_ATOM, 32, PropModeReplace, (unsigned char *) &value, 1);
    
    long hints[5] = {e ? 0 : 2, 0, 0, 0, 0};
    motif_hints = XInternAtom(d, "_MOTIF_WM_HINTS", False);

    XChangeProperty(d, w, motif_hints, motif_hints, 32, PropModeReplace, (unsigned char *)&hints, 5);
    
#ifdef MAPIT
    XMapWindow(d, w);
    waitxevt(d, MapNotify);
#endif

}

int main(void) {

    Display*     d;
    Window       w;
    XEvent       e;
    const char*  msg = "Hello, World!";
    int          s;
    GC           gracxt;
    int          frmenb = 0;
 
    d = XOpenDisplay(NULL);
    if (d == NULL) {

        fprintf(stderr, "Cannot open display\n");
        exit(1);

    }
 
    s = DefaultScreen(d);
    gracxt = XDefaultGC(d, s);

    w = XCreateSimpleWindow(d, RootWindow(d, s), 10, 10, 640, 480, 5,
                            BlackPixel(d, s), WhitePixel(d, s));
    XSelectInput(d, w, ExposureMask|KeyPressMask|StructureNotifyMask);
    XMapWindow(d, w);
    waitxevt(d, MapNotify);

    while (1) {

        XNextEvent(d, &e);
        if (e.type == Expose) XDrawString(d, w, gracxt, 10, 50, msg, strlen(msg));
        if (e.type == KeyPress) {

            frame(d, w, frmenb);
            frmenb = frmenb == 0 ? 1 : 0;
#ifdef REPEAT
            frame(d, w, frmenb);
            frmenb = !frmenb;
#endif

        }

    }

    XCloseDisplay(d);

    return 0;

}

変更されたのは、ヒントを含めることだけです。

于 2021-08-18T19:38:36.010 に答える