Второй важной компонентой оконной системы X являются X-клиенты — приложения, получающие в свое распоряжение окна и отображающие в них графическую информацию.
Точнее, X-клиенты всего лишь взаимодействуют с сервер при помощи X-протокола и могут вовсе не создавать окон, как это делают «простейшие» xdpyinfo, xrandr и glxinfo, xlsclients, xwininfo, xprop, но «полновесные» X-клиенты всегда создают хотя бы одно окно.
Список созданных окон (упорядоченный в дерево) и системные атрибуты каждого из них можно запросить у X-сервера при помощи xwininfo.
В листинге ниже построено полное дерево окон (начиная с «корневого» окна самого X-сервера), среди которых отобраны окна с именем gnome-terminal (предположительно принадлежащие gnome-terminal, узнать явно нет возможности).
При этом оказывается, что только одно окно изображается X-сервером на дисплее, а еще одно находится в скрытом состоянии.
Содержимое
Дерево окон X-сервера и их атрибуты
homer@ubuntu:~$ xwininfo -tree -root | grep gnome-terminal
0x4400001 «Терминал»: («gnome-termtnal» «Gnome-terminal») 10×10+10+10 +10+10
0x4400006 «homer@ubuntu: («gnome-terminal» «Gnome-terminal») 882×530+0+0 +483+51
homer@ubuntu:~$ xwininfo -id 0x4400001
Map State: IsUnMapped
homer@ubuntu:~$ xwininfo -id 0x4400006
Absolute upper-left X: 483
Absolute upper-left Y: 51
Width: 882
Height: 530
Depth: 32
Map State: IsVlewable
Кроме системных атрибутов, каждое окно наделяется свойствами (properties), широко используемыми для взаимодействия между X-клиентами (см. W:[ICCCM]), особенно между «обычными» клиентами и оконным менеджером (window manager). Оконный менеджер является «особенным» X-клиентом, обрабатывающим события создания окон «обычных» X-клиентов.
Именно он добавляет к «чужим» создаваемым окнам «свои» декорирующие элементы: заголовок (title) окна — для его перемещения, бордюр (border) — для изменения его размеров и т. д.
В листинге ниже показаны некоторые свойства окна, установленные программой-владельцем окна для оконного менеджера.
Например, свойство WM_NAME используется оконным менеджером для текста заголовка (отображаемых) окон, свойство WM_LOCALE_NAME указывает на язык и кодировку текста, содержащегося в WM_NAME, свойство WM_CLIENT_MACHINE содержит имя сетевого узла X-клиента, а свойство WM_COMMAND — команду, при помощи которой был запущен клиент.
Свойства окон X-сервера
homer@ubuntu:~$ xprop -id 0x4400001
WM_CLASS(STRING) = «gnome-terminal», «Gnome-terminal»
WM_COMMAND(STRING) = { «gnome-terminal» }
WM_CLIENT_MACHINE(STRING) = «ubuntu»
WM_LOCALE_NAME(STRING) = «ru_RU.UTF-8»
WM_ICON_NAME(STRING) = «gnome-terminal»
WM_NAME(COMPOUND_TEXT) = «Терминал»
homer@ubuntu:~$ xprop -id 0x4400006
WM_NAME(STRING) = «homer@ubuntu:
Свойства окон X-клиентов могут использоваться не только оконным менеджером, но и другими клиентами, например xlsclients, который опрашивает X-сервер и выводит список «клиентов», имеющих окна с установленными свойствами WM_CLIENT_MACHINE и WM_COMMAND, которые в действительности устанавливаются (не всегда) X-клиентами только для «основных» окон.
Список клиентов X-сервера
homer@ubuntu:~$ xlsclients -l | grep -С 3 gnome-terminal
Window 0x4400001:
Machine: ubuntu
Name: «unknown type C0MP0UN0_TEXT (363) or format 8>
Icon Name: gnome-terminal Command: gnome-terminal
Instance/Class: gnome-terminal/Gnome-terminal
Window 0x3000001:
Machine: ubuntu
Name: gdu-nottftcation-daemon
Взаимодействие X-клиентов и X-сервера происходит при помощи локальных или сетевых сокетов в зависимости от их взаимного месторасположения и согласно адресу подключения, указываемому на стороне X-клиентов при помощи переменной окружения DISPLAY в формате host:number.
Адрес подключения состоит из имени (или IP-адреса) узла X-сервера host и номера его дисплея number (например, DISPLAY=ubuntu.local:9 или 192.168.0.5:6). В качестве host может выступать любое имя, для которого можно получить IP-адрес, используя службу имен, а в случае локального взаимодействия host не указывается вовсе (т. е. displays:0).
Номер дисплея указывает на экземпляр X-сервера, запущенного на узле host для управления некоторым набором оборудования, (графическими дисплеями видеокартами и мониторами, клавиатурами и пр.).
Проиллюстрировать разные виды X-взаимодействия проще всего при помощи «виртуальных» X-серверов Xnest и Xephyr, В отличие от «обычного» X-сервера, организующего доступ X-клиентов к аппаратному дисплею, эти серверы организуют доступ своих клиентов к виртуальному «дисплею», в качестве которого выступает их собственное окно аппаратного сервера.
В листинге ниже показан запуск X-сервера Xnest с, номером дисплея :1 (т. к. дисплей :0 обычно занят аппаратным X-сервером), который создает сокет семейства ip для подключения сетевых клиентов и сокет семейства unix для локальных.
Виртуальный X-сервер Xnest
homer@ubuntu:~$ Xnest :0 &
Fatal server error:
Server is already active for display 0
If this server is no longer running, remove /tmp/.X0-lock and start again.
homer@ubuntu:~$ Xnest :1 &
[1] 10365
homer@ubuntu:~$ lsof -p 16365
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
Xnest 10365 homer cwd DIR 252,0 69632 20316162 /home/kotoff
Xnest 10365 homer rtd DIR 252,0 40% 2 /
Xnest 10365 homer txt REG 252,0 1754384 3831580 /usr/bin/Xnest
Xnest 10365 homer 1u IPv4 17552891 0t0 TCP ftxll-1 (LISTEN)
Xnest 10365 homer 2u CHR 136,1 0t0 4 /dev/pts/1
Xnest 10365 homer 3u Unix 0x00000000 0t0 17552892 socket
Xnest 10365 homer 4u unix 0x00000000 0t0 17552893 /tmp/.X11-unix/X1
Xnest 10365 homer 5r REG . 252,0 31246 6817286 /usr/lib/xorg/protocol.txt
Xnest 10365 homer 6u unix 0x00000000 0t0 175528% socket
В примере из листинга ниже показана трассировка демонстрационного X-клиента xeyes, иллюстрирующая использование клиентом локального и сетевого сокетов, в зависимости от значения переменной окружения DISPLAY.
Сетевые и локальные подключения клиента X-сервера
homer@ubuntu:~$ DISPLAY=:1 strace -fe connect xeyes
connect(3, {sa_family=AF_FILE, path=@»/tmp/.X11-unix</X1″}, 20) = 0
^C
honer@ubuntu:~$ DISPLAY=ubuntu.local:1 strace -fe connect xeyes
connect(3, {sa_family=AF_INET, sin_port=htons(6001), sin_addr=inet_addr(«192.168.100.5)}, 16) = 0
При работе в оконной системе переменную display обычно устанавливают в начале сеанса, а затем при запуске X-клиентов их вывод будет попадать на нужный X-сервер, как это показано на примере сервера Xnest и клиентов xterm, xcalc и xeyes.
Впоследствии при запуске одними X-клиентами других X-клиентов (например, по команде пользователя из эмулятора терминала xterm, переменная окружения наследуется порожденными процессами, и вывод запускаемых клиентов «интуитивным» (так же как и стандартные потоки вводам вывода) образом попадает на тот же X-сервер.
X-сеанс пользователя
honer@ubuntu:~$ export DISPLAY=:1
honer@ubuntu:~$ xterm & xcalc & xeyes &
[1] 2803
[2] 2804
[3] 2805
Нужно заметить, что все окна по умолчанию открываются в левом верхнем углу (координата +0+0) экрана, а возможность управлять их размером и местоположением отсутствует.
Каждый X-клиент может самостоятельно управлять размером и местоположением своих окон, и даже многие из них запоминают при выходе эти параметры в своих dot-файлах, а при последующем запуске восстанавливают окна в прежних размерах и местах, но интерактивным перемещением окон и изменением их размера занимается оконный менеджер.