第3章 从使用者介面的面貌概观X
在本章,我们将观察重点摆到系统控制的使用者介面,例如,系统如何显示有人使用它,以及包含那些结构等。
X设计的目标之一就是能支援许多不同型式的使用者介面,一般其它的视窗系统提供特殊的交谈方法,而X则提供一般性的架构,让系统建立者(system builder)据以建造所需的交谈的风格。例如,在一个X系统中你可藉从选单中选一个动作来构建视窗,但其他对视窗的操作则全靠滑鼠来做,这种弹性允许系统开发者(developers)完全在X的基础上产生全新的介面,也因为介面并未内建於视窗系统,因此使用者在任何时刻根据他们特别的需求可选用适当的介面。例如,对於完成一些相同的工作 -- 建立、移动、重定大小萤幕上的视窗,初学者较老手喜欢简单的系统,而X可分别提供最适合他们的使用者界面。
使用者界面分为两个部份:
管理界面:命令最高层的视窗如何在萤幕上建构或重建构(re-configured),也就是说,如何管理你的案头。
应用界面:决定你和应用程式间交谈的”风格”(style): 你如何利用视窗系统的设备程式来控制应用程式及输入资料给它。
3.1 管理界面:视窗管理器
管理界面(management interface)是系统的一部份,用以控制你萤幕上最上层的视窗(换句话说:如何重新建构你的案头),这个部份在系统中称之为视窗管理器(window manager),它的功能有改变视窗的大小或位置、将视窗在堆叠 (stack)中重新安排位置、或将视窗改变成表徵图 (icon) 等等。
在X中,视窗管理器只是另一个client程式而已,它以及系统介面的发展,和server是完全分开的,因此你可以更换它们,这类似於Unix系统中的shell命令列直译器(interpreter) :shell 只是一个使用者处理程式(process) ,如果你改变它,你也改变了系统的使用者介面。
3.1.1 手动的和自动的视窗管理器
有两类的视窗管理器:手动的和自动的。手动的视窗管理器,视窗在萤幕上的位置和大小完全由使用者控制,手动的视窗管理器只是使用者用来完成工作的工具,大部份的手动视窗管理器允许应用视窗重叠。
相对的,自动的视窗管理器尽可能的由它自己来控制案头,对於萤幕的布置尽可能让使用者少插手。它在新建立一个视窗时自动决定视窗的大小和位置,和当视窗移动时如何重新安排其馀的视窗,通常自动的视窗管理器将萤幕分成一块块像磁砖一样(tile)的区域,也就是说安排应用视窗彼此不会重叠,而且尽量占用最多的萤幕空间。
手动的视窗管理器如何工作 -- 攫取(Grabbing)
通常当你告诉手动的视窗管理器你要完成什麽动作时,是藉著使用选单或者结合了按滑鼠的按钮和移动指标,例如,重新摆放一个视窗的位置,你可以移动指标进入视窗,按住左边的按钮,移动指标然後在新位置松开按钮,视窗管理器是如何知道这些滑鼠 "事件" 的意图的?或是换个角度,server是如何知道 "事件" 是来自应用视窗或视窗管理器?
答案是由视窗管理器告知server有哪些特定的 "事件" (碰触按钮等等)需要被送达,这和哪一个视窗发生的无关,这种处理称之为攫取(Grabbing),视窗管理器可以指定哪一个滑鼠按钮希望被攫取,而这攫取发生在滑鼠的按钮被按下且键盘上一些特定的键(一般称为修饰键(modifer) )也被按住(例如当CONTROL 和SHIFT 两个键被按住时且滑鼠中间的按钮被按下),当按钮被按下时,攫取开始动作,server送出所有滑鼠的事件(包括滑鼠的移动事件)到视窗管理器直到按钮再度松开,视窗管理器把这些 "事件" 的资料解释成来自使用者的指令来工作。以移动视窗为例,视窗管理器在按钮按下时被告知指标的 位置,而当按钮松开时再度被告知,对指标的位移做一些简单计算便可据以移动视窗。
有一件事需要使用者配合,那就是滑鼠和修饰键组合而成的攫取不应该为应用程式所知道,所以必需确定视窗管理器这种攫取键的组合不会和应用程式冲突,大多数的视窗管理器可以很容易的定义这些攫取的组合键,而保留给它自己使用。
3.1.2 视窗管理器额外提供的功能
视窗管理器除了具有重新建构视窗的基本功能外,也提供额外的功能改进介面的品质,通常,加入额外功能的目的是为了降低键盘输入的需要,而改成尽量多用指标。
一个常见的功能是提供一个你自己可以建构的一般性选单,这样你只要选取一个选单选项便可启动视窗应用程式。这个启动的命令通常包含了指示应用视窗在何处出现,大小多少,本文用什麽颜色等等。所以应用程式不需要太多的使用者输入便能启动。一个常见的选单用法为当你在网路上工作时,你可以定义一个选单列出所有你在网路上可用的主机,如此你便可藉著在选单上选择主机名称便能和任一主机建立连接。
3.1.3 视窗管理器和表徵图
当一个视窗转换成一个表徵图时,表徵图是如何来的?视窗又发生了哪些事?
表徵图的结构非常的简单,它只是视窗的代表图案,当系统表徵图化(iconify)一个应用视窗,视窗管理器只是不对应出(unmap) 这视窗(也就是说,告诉server不再显示这个视窗到萤幕上)而把表徵图视窗对应出来。解除表徵图化(deiconify)则把上述的处理反过来。视窗管理器可以办得到的原因是它没有” 存取控制”(access control)或许可限制来防止一个client(例如视窗管理器)不对应出其它的client的视窗,所有在同一个server上的client都可以对任意视窗或多或少做一些动作。
视窗管理器通常提供预设的表徵图,但是client可以提供它自己的表徵图并建议使用它,有些视窗管理器接受这个要求,有些则忽略不接受仍用自己的表徵图,只把这个需求当作给视窗管理器的暗示(hint)。
当应用程式被表徵图化,它的主视窗便不再被对应出来,如果视窗管理器因任何理由中断了,则这个视窗永远也无法再对应出来了。要避免这点,当视窗管理器表徵图化一个视窗时,它把这个视窗加入一个名为save set的名单中,这个名单由server负责维护,如此当视窗管理器被中断时便可重新对应出来。
3.1.4 应用程式传递建构资讯给视窗管理器
就如同要求显示一个特定的表徵图一般,应用程式也能传递其它的暗示或建构资讯给视窗管理器,这包括:
. 应用程式和表徵图视窗的名称。
. 当应用程式和表徵图视窗被建立时,它们在萤幕上位置的资讯。
. 对视窗大小的限制(例如,client可以宣告”我所占用的视窗大小绝不可小於宽度若干x 长度若干”)。
. 对视窗重定大小的特别要求(例如,一个显示本文的视窗,可以要求在重定大小时按特定的间隔放大或缩小,以使得视窗内的字元永远是完整的一个,不致视窗边框的那一行 (列) 有半个字的情况出现。)。
这种将讯息传递给视窗管理器的结构称之为性质结构(property mechanism),下一节我们会讨论它。
我们可以注意到大部份重定大小或表徵图化的事是由视窗管理器做的,这是因为它是一个公有的client,任何client均可随意重定大小,但如果所有client都这样做,便会造成混乱,因此要这些应用程式和平共存的原则是:不要自行重定大小,把它交给视窗管理器,也就是让使用者去决定。
在第6章中我们会看到一个视窗管理器uwm 如何使用。
3.2 应用程式介面和工具箱
应用程式介面决定了使用者和应用程式间交谈的风格,举例来说,如何用指标选一个选项等,X不提供标准的应用程式介面,只提供基本的结构以便建造它们。
当那些具有一贯性的应用程式介面被放在一起,便叫做工具箱(toolkit),它是基础视窗系统软体中最高最有效率的层次,较低层次的细节,被隐藏起来,因此简化程式和维持介面的一贯风格变得容易执行,当使用者控制应用程式时好像有一套”虚拟文法(virtul grammer)”一般,需要注意很重要的一点是,工具箱在编译程式的时候被指定,所以一个client的应用程式介面在编译的时候就被决定了,如果不重新编译便无法改变。
MIT 版的X大多数的应用程式均使用标准的工具箱和一套来自MIT 的工具箱软体构成要素,这造成你可以得到一致性的介面。除此之外,有些结构更提供了定制的应用程式操作方法和设定它们的预设值。
3.3 其它的系统面貌
在本节中,我们讨论将应用程式之间传递资讯所用的性质结构(property mechanism),视窗的树状阶层组织,和X不包含在作业系统中的优点。
3.3.1 client之间的通讯 -- ”性质”
client和server之间的通讯是藉著送出 "需求" 和接收 "事件" ,但有时client需要和其它的client传递资讯,例如,正常的应用程式需要告诉视窗管理器它的位置和大小,这就需要X的性质结构了。
”性质”是一小段资料的名称,这一小段资料存在server中且关联到一个特定的视窗,任何client均可向server查询某一特定视窗”性质”的值。
让我们看一个client如何把它所喜欢的表徵图名称传递给视窗管理器的范例:client把表徵图名称存到这个视窗的WIM_ICON_NAME ”性质”去,当视窗管理器执行表徵图化这个应用视窗时,它会去找这个应用视窗的WIM_ICON_NAME的”性质”,而後显示”性质”中的表徵图名称。
应用程式也可以和不是视窗管理器的其它的应用程式通讯,一个常见的例子是在分属不同应用程式的视窗之间做剪贴(cut-and-paste) 操作,一段本文从一个应用程式中”切下”(cut) 稍後再”贴”到另一个应用视窗,”性质”在此被用到,”性质”依序编成”CUT_BUFFER0”,”CUT_BUFFER1”…等等,所有的应用视窗便可藉此交换资料。
最後一个例子是称为resources 的”性质”,它被用来定义应用程式的预设值设定,在根视窗(root window) 中有一个名为RESOURSE_MANAGER的性质存放著所有设定的名单,它会被所有的应用程式存取,用来做是否要执行任何设定的依据。
3.3.2 在X中视窗的阶层性
本节描述视窗在系统中的组织及如何建立,和对应用程式的影响。
所有在X中的视窗都可视为一个树状结构阶层 (hierarchy)的一部份,树的根部便是根视窗,涵盖了整个萤幕,应用视窗都是根视窗的子代(children),上层的视窗可以拥有它自己的子视窗,图3-1 有两个应用视窗。
┌———————————————┐
│ p34 fig 3.1 (???) │
│ │
│ 图3-1 在萤幕上重叠的视窗 │
└———————————————┘
”paint ”程式包含了一个被当做选单用的子视窗,对每一个选择又有一个子视窗对应,相关的视窗树见图3-2 。
┌———————————————┐
│ p35 fig 3.2 │
│ │
│ 图3-2 视窗的树状结构阶层 │
└———————————————┘
在X的设计理念下,制造一个视窗非常容易,你可以利用视窗来控制选项,像选单、卷动棒(scrollbars)、控制钮(control button)等等,即使是大量也无妨,例如像试算表中的一个cell等。这种观点从程式设计师的角度大於使用者,但的确对使用者当他”定制”(customising) 特定的程式时有影响,在本章以後的章节会再度提到。
为了允许应用程式有子视窗,X提供了大量的设备程式供client程式使用,如此不但能达成一致性,也避免了相同的需求造成了重复的工作,例如像图3-1的下拉式选单,可以在应用程式中以一致子视窗完成,这个子视窗有它们自己的选单选择方框(pane),和用以侦测使用者碰触滑鼠按钮的标准结构,如果没有子视窗,复杂的程式和输入处理将无可避免。
子视窗的位置和大小并不受父视窗的限制,子视窗可大可小,可以大过父视窗或只占父视窗的一部份,但是它会被父视窗剪裁(clipped) ,也就是说,子视窗所有超出父视窗的部份将会消失不见。见图3-3
┌———————————————┐
│ p36 fig 3.3 (???) │
│ │
│ 图3-3 受父视窗限制的子视窗 │
└———————————————┘
在实际的应用上,你可以将上层的视窗定义成几乎占住整个萤幕,就不必担心子视窗有些部份会看不到了。
另外一种方式就是把下拉式选单定义成为根视窗的子视窗,如此选单便可以比应用视窗还大,如图3-4
┌————————————————┐
│ p36 fig 3.4 (???) │
│ │
│ 图3-4 选单比用它的应用视窗还大 │
└————————————————┘
3.3.3 X不是深植於作业系统
不像其它大多数的系统,X并非深植(embedded)於作业系统中,而只是比使用者层次稍高而已。更精确地说,X不需要深植於系统,虽然有些制造厂商可能是为了效率(performance) 的理由将server和作业系统结合在一起,但不深植於作业系统的结构有下列利益:
.易於安装和改版,或甚至去除。这种工作不需要重新启始系统,也不会对其它应用程式造成干扰。
.第三集团很容易支援加强它的功能。例如你的制造厂商提供的系统不够好,你可以向别人买更好或更快的版本。
.X不会指定作业系统,因此成为一种标准,这也是第三集团发展软体的原动力。
.为了发展者利益。在server上发展工作时,当程式当掉只会当掉视窗系统,不会造成机器的损坏或作业系统核心的破坏,没有作业系统核心码的程式也较易除错。
3.4 结论
在本章中我们描述了许多X提供的使用者介面,我们介绍了你用以管理案头的程式 -- 视窗管理器的概念,也描述了被用来做使用者和client应用程式间交互作用的设备程式。我们介绍了用来做client间通讯的性质结构,X视窗的阶层结构对系统的影响,最後对视窗系统不深植於作业系统的好处做一摘要。
本章所强调的著眼点,在於针对你每天都用到的视窗系统的部份作一整体性的概观,了解这些将帮助你学习得更快,更能好好地运用系统。
本书第一部份 -- 系统概观就此结束,下一个部份将告诉你如何实际使用系统。
第4章 术语和符号
本书大部分使用的术语是在第一次碰到时再作解释,但有些术语我们认为应该先在本章作一个介绍,此外在本章中我们介绍了一些本书使用符号的习惯,以及本书中所有范例所使用的机器场景 (scenario).
4.1 术语
在X中,一个视窗 (WINDOW) 是指萤幕上的一块长方形区域,它的边平行於萤幕的边,大多数的视窗以一种颜色作为背景色 (background),而以另一种颜色作为前景色 (foreground),例如一个典型的文字视窗,背景色为白色,前景色 (也就是文字本身) 则为黑色.视窗可以有一个边框 (border),通常边框的颜色和背景色不同. 有些视窗在视窗上方可能有一个标题棒
(title bar) 或控制棒 (control bar), 在某些情况下用以显示有关这个视窗的资讯, 你可以对控制棒作某些固定的动作来管理视窗. 系统会显示一个指标 (pointer,有时也称为游标 (cursor))在萤幕上, 当你移动滑鼠, 整个萤幕只有一个指标在对应移动. 相对的, 萤幕上许多文字视窗拥有自己专属的文字游标, 这些游标通常指示你输入文字的位置. 以上的术语可由图 4-1
来解释.
┌———————————————┐
│ p. 42 图 4-1 (???) │
│ │
│ │
│ │
│ 图 4 - 1 视窗的元素 │
└———————————————┘
geometry -- 位置和大小
X用到一些几何学的术语来说明一个视窗的位置和大小, 大部份的X程式接受一个含有geometry的命令列 (command line) 来启动 (stratup)它们, 这个命令列说明了这个程式的视窗有多大, 以及在萤幕的哪一个位置显示
. 通常geometry的格式如下:
宽度 x 高度 + X偏移量 + Y偏移量
宽度和高度的单位为像素 (pixel,萤幕上的一点) 或字元 (character), 视应用的状况而定, 程式的说明通常会告诉你用什麽单位. 上述的式子是说明建立一个大小为宽 x 高 的视窗, 视窗的位置为左边框距萤幕左边界 X偏移量个像素, 上边框距萤幕上边界 Y偏移量个像素. 例如假设一个程式以字元为视窗大小单位, 则格式
80 x 24 + 600 + 400
的意义为: 建立一个 80 字元宽 24 字元高的视窗, 并且视窗的左边框距萤幕左边界 600个像素, 上边框距萤幕上边界 400个像素.
如果需要的话, 也可以只指定大小或只指定位置, 程式对未指定的部份会使用预设值 (default value), 或给你一些提示, 视实际在系统中执行的状况而定.
滑鼠和指标的术语:
有一些输入装置会在执行X时在显示器上指出萤幕上你有兴趣的项目或区域,通常为一个有数个按钮 (button) 的滑鼠 (一般为三个按钮,分别称为左按钮, 中按钮, 右按钮).当你移动滑鼠, 系统会对应地移动萤幕上的指标.接下来, 我们对滑鼠上的三种操作术语作一严谨的定义:
碰触按钮 (clicking a button): 按下滑鼠的按钮随即松开, 按钮被按下的时间, 仅有一瞬间而已.
按住按钮 (pressing a button): 将滑鼠的按钮按下, 且一直保持按住按钮的状态.
松开按钮 (releasing a button): 将先前按住的按钮松开.
通常碰触按钮被用来指定萤幕上的一个物件, 按住按钮再松开按钮 (一般在这期间会移动滑鼠) 往往用来移动或描绘一块区域.
拖拽 (dragging) 一个物件: 利用指标指定一个物件, 按住按钮, 保持按住状态移动指标直到某处再松开按钮。做这种操作时, 系统通常有一些方式来表示物件被移动, 例如在拖拽一个物件的期间, 系统会将物件周围加上一个细线的方框.
我们常常利用拖拽方式来改变一个物件的大小, 通常系统显示方框, 根据你的拖拽动作改变大小, 此种方法叫作橡皮筋法 (rubber-banding). (因为方框好像用橡皮筋做的一样.)
在本书的图形表示法中, 我们用一个下箭头表示按钮被压住, 虚线表示滑鼠 (指标) 的移动, 上箭头表示松开按钮, 见图 4 - 2
┌———————————————————┐
│ 43 页 , 图 4 - 2 │
│ │
│ │
│ │
│图 4 - 2 滑鼠拖拽的图形表示法 │
└———————————————————┘
键盘的术语:
标准的终端机键: SHIFT, DELETE, BACKSPACE, ESC 或 ESCAPE, RETURN, CAPSLOCK.
游标控制键: 采有上下左右箭头的键, 如 UP, DOWN, LEFT, RIGHT.
特殊键: 压住CTRL或CONTROL 键, 再按其它的键 (例如 A键),用CTRL-A表示, 有些终端机有META键, 也同样的用META-A表示.
4.2 符号
连续数列
在一些情况下, 你输入的命令列或系统输出的文字, 因为太长而无法在同一列而必需分为数列, 如果它是shell 命令, 或是一段 C语言程式码, 我们在第一列的最後加上一个倒斜线(backslash"")後, 在下一列继续, 例如:
mkfontdir/usr/lib/X11/fonts/misc
/usr/lib/X11/fonts/15dpi
/usr/lib/X11/fonts/100dpi
然而极少数的情况下, 我们用符号 "(contd.)" 表示本列因排版限制的缘故在下列继续,如:
PID TT STAT TIME COMMAD
1901 c0 S 0:01 x :0
1902 c0 S 0:01 xterm -geometry +1+1 (contd.)
-n login -display unix:0 -c
1903 p1 S 0:00 -sh (csh)
当X装设时, 需要定一些目录树 (directory tree). 我们把目录树的顶端定为$TOP, 在我们的系统中, $TOP对应的目录为 /usr/local/src/X11,相同地,家目录 (home directory) 参考自 $HOME。
4.3 本书范例的场景
本书使用大量的范例来说明,这些范例是假设我们在一个拥有下列机器的网路下工作:
venus 彩色萤幕,普通解析度
saturn 单色萤幕,普通解析度,档案工作站(file server)
mars 彩色萤幕,高解析度
neptune 非图形萤幕,拥有磁碟储存装置,电脑工作站(computer server)
我们所拥有的工作站是 venus,大部分的时间我们使用它,当我们需要更高的解析度或在单色萤幕检查某些情况时,我们会使用 mars 或 saturn,当然,我们会在我们自己的工作站,以远端(remote)的方式使用所有的机器.
saturn是 venus和 mars 的档案工作站, 三者之间共享相同的档案系统,( 例如,它们存取档案 $HOME/.login 时,实际上是同一个档案) .neptune
拥有它自己的档案系统,不和其他的工作站共享.
4.4 本书使用的工作站架构
在本书中,所讨论的一些范例、程式名称、程式码的片段可能和你系统的有些差异,那是因为系统不同的关系,本书假设使用的系统为:
.硬体:SUN 3/50 工作站,三个按钮的滑鼠,萤幕大小为 1152x900个像素,单色萤幕。
.作业系统:SunOS 3.4, 以 BSD 4.2 Unix 为基础。
.视窗软体:X的 MIT标准版,第11版第3 次发行。