1const unsigned int BORDER_WIDTH = 3; 2const unsigned long BORDER_COLOR = 0xff0000; 3const unsigned long BG_COLOR = 0x0000ff; 4  5// 获取窗口属性,主要是尺寸 6XWindowAttributes w_attrs; 7XGetWindowAttributes(display, w, &w_attrs) 8  9// 发送CreateWindow请求,创建一个InputOutput窗口,以根窗口为父窗口 10Window frame = XCreateSimpleWindow(display, root, w_attrs.x, w_attrs.y, 11    w_attrs.width, w_attrs.height, BORDER_WIDTH, BORDER_COLOR, BG_COLOR); 12  13// 告知X11 server将frame直接子窗口的窗口请求和事件转发过来。 14XSelectInput(display, frame, SubstructureRedirectMask | SubstructureNotifyMask); 15  16// 发送ChangeSaveSet (SetModeInsert)请求,告知X11 server保存w叠层次序,WM崩溃后,可复原w原有叠层次序 17XAddToSaveSet(display, w); 18  19// 发送ReparentWindow请求,将w的父窗口由根窗口改为frame窗口 20XReparentWindow(display, w, frame, 0, 0); 21  22// 发送MapWindow请求,显示frame窗口 23XMapWindow(display, frame); 24  25// 在客户端窗口上抓取通用窗口管理操作:移动、缩放、关闭和切换窗口 26// 分别发送GrabButton和GrabKey请求,捕获w窗口指定的鼠标和键盘事件,X11 server将事件转发给frame 27// 发送GrabButton请求,ButtonMotionMask响应MotionNotify事件,ButtonPressMask/ButtonPressMask表示响应按键的两个状态(Press, Release)事件 28// 发送GrabKey请求,捕获按键请求,响应KeyPress和KeyRelease事件 29// 看来Mod1Mask修饰表示Alt,Button1表示left,Button2表示right。两个同时按下,在MotionNotify响应函数时处理 30  31// alt + left按键移动窗口 32XGrabButton(display, Button1, Mod1Mask, w, false, 33    ButtonPressMask | ButtonReleaseMask | ButtonMotionMask, 34    GrabModeAsync, GrabModeAsync, NULL, NULL); 35  36// alt + right按键缩放窗口 37XGrabButton(display, Button3, Mod1Mask, w, false, 38    ButtonPressMask | ButtonReleaseMask | ButtonMotionMask, 39    GrabModeAsync, GrabModeAsync, NULL, NULL); 40  41// alt + f4关闭窗口 42XGrabKey(display, XKeysymToKeycode(display, XK_F4), 43    Mod1Mask, w, false, GrabModeAsync, GrabModeAsync); 44  45// alt + tab切换窗口 46XGrabKey(display, XKeysymToKeycode(display_, XK_Tab), 47    Mod1Mask, w, false, GrabModeAsync, GrabModeAsync);