客户间通信协定手册

在计算技术中，客户间通信协定手册（Inter-Client Communication Conventions Manual：缩写为ICCCM或I39L即“I, 39个字母, L”）是X窗口系统的标准协议。它规定有一个共同的X服务器的客户间的通信。它主要用于在窗口管理器和X服务器的其他客户之间的通信。

历史

它由MIT X联盟的在1988年设计，其版本1.0发行于1989年7月而版本2.0发行于1994年早期。

背景

X刻意的规定窗口交互的“机制而非政策”。因此，客户互操作需要超出X协议自身的额外规定。

特征

ICCCM规定剪切和粘贴缓冲区，窗口管理器交互，会话任务管理，如何操纵共享资源和如何管理设备颜色。这些底层功能一般实现在部件工具箱或桌面环境之内。这把应用编程者隔离于直接与ICCCM自身打交道，因为这些功能被委托给了实现工具箱。

批评

ICCCM声名狼藉于有歧义和难于正确实现。进而有些部分被废除或不再实践上去实现。

针对目前需要而更新和澄清ICCCM的努力导致了扩展窗口管理器提示（EWMH），它获得了相当广泛接受并随着需要出现而被持续扩展。

窗口管理器的基本工作原理
下面以Nick Welch写的极小化的窗口管理器TinyWM的源代码，展示窗口管理器的基本工作原理，它做四件基本工作：通过Alt+Button1（鼠标左键）拖动来交互式的移动（move）窗口，通过Alt+Button3（鼠标右键）拖动来交互式的调整大小（resize）窗口，通过Alt+F1来前置（raise）窗口，通过鼠标指针来聚焦（focus）窗口。
/* TinyWM is written by Nick Welch <mack@incise.org>, 2005.
 *
 * This software is in the public domain
 * and is provided AS IS, with NO WARRANTY. */

#include <X11/Xlib.h>

#define MAX(a, b) ((a) > (b) ? (a) : (b))

int main()
{
    Display * dpy;
    Window root;
    XWindowAttributes attr;
    XButtonEvent start;
    XEvent ev;

    if(!(dpy = XOpenDisplay(0x0))) return 1;

    root = DefaultRootWindow(dpy);

    XGrabKey(dpy, XKeysymToKeycode(dpy, XStringToKeysym("F1")), Mod1Mask, root,
            True, GrabModeAsync, GrabModeAsync);
    XGrabButton(dpy, 1, Mod1Mask, root, True, ButtonPressMask, GrabModeAsync,
            GrabModeAsync, None, None);
    XGrabButton(dpy, 3, Mod1Mask, root, True, ButtonPressMask, GrabModeAsync,
            GrabModeAsync, None, None);

    for(;;)
    {
        XNextEvent(dpy, &ev);
        if(ev.type == KeyPress && ev.xkey.subwindow != None)
            XRaiseWindow(dpy, ev.xkey.subwindow);
        else if(ev.type == ButtonPress && ev.xbutton.subwindow != None)
        {
            XGrabPointer(dpy, ev.xbutton.subwindow, True,
                    PointerMotionMask|ButtonReleaseMask, GrabModeAsync,
                    GrabModeAsync, None, None, CurrentTime);
            XGetWindowAttributes(dpy, ev.xbutton.subwindow, &attr);
            start = ev.xbutton;
        }
        else if(ev.type == MotionNotify)
        {
            int xdiff, ydiff;
            while(XCheckTypedEvent(dpy, MotionNotify, &ev));
            xdiff = ev.xbutton.x_root - start.x_root;
            ydiff = ev.xbutton.y_root - start.y_root;
            XMoveResizeWindow(dpy, ev.xmotion.window,
                attr.x + (start.button==1 ? xdiff : 0),
                attr.y + (start.button==1 ? ydiff : 0),
                MAX(1, attr.width + (start.button==3 ? xdiff : 0)),
                MAX(1, attr.height + (start.button==3 ? ydiff : 0)));
        }
        else if(ev.type == ButtonRelease)
            XUngrabPointer(dpy, CurrentTime);
    }
}

引用

外部链接 
 Inter-Client Communication Conventions Manual, Version 2.0
 Inter-Client Communication Conventions Manual Version 2.0

进程间通信
X Window系统