2
25
2017
17

中键的功能

鼠标中键,就是左键和右键之间的那个键啦。常见的鼠标上它在滚轮上。所以你知道了,滚轮是可以往下按的哦。如果是触摸板并且没有中键的话,可以配置双指点击来作为中键使用的(synclient ClickFinger2=3)。

中键具有以下好用的功能哦~(括号里是适用的场景)

  • 粘贴选择区,不用按复制和粘贴的快捷键了~不过选择区的寿命通常比较短,只适合快速的粘贴操作。另见 X Window 中的剪贴板一文。(Linux 桌面、macOS 终端、gpm)
  • 在后台新标签页打开链接(火狐、Google Chrome 等浏览器都支持)
  • 关闭标签页(基本上也是用于网页浏览器。我自己的 GVim 也支持)
  • 定位滚动条,可以快速地定位到开头、结尾,或者之前的位置。不需要拖来拖去的麻烦。可惜 GTK 3 里这个功能不好用的了。(GTK 2、Qt)
  • 移动画布(GIMP、Inkscape 等作图软件、GNOME 的文档查看器 Evince)

这只是比较通用的功能。我的 Awesome 还配置了使用中键关闭窗口呢(「关闭标签页」语义的扩展)。火狐的一些菜单项也支持中键点击,比如书签菜单,右键的「查看图像」菜单,比如前进/后退按钮,以及在它上边点击右键出来的历史记录项目。

总结一下中键的语义:

  • 在可以粘贴的地方,粘贴
  • 在打开对象时,打开新对象而不取代已有者
  • 在打开的对象本身上时,关闭之
  • 在可定位对象上,移动之
Category: Linux | Tags: linux X Window X window
2
25
2017
17

中键的功能

鼠标中键,就是左键和右键之间的那个键啦。常见的鼠标上它在滚轮上。所以你知道了,滚轮是可以往下按的哦。如果是触摸板并且没有中键的话,可以配置双指点击来作为中键使用的(synclient ClickFinger2=3)。

中键具有以下好用的功能哦~(括号里是适用的场景)

  • 粘贴选择区,不用按复制和粘贴的快捷键了~不过选择区的寿命通常比较短,只适合快速的粘贴操作。另见 X Window 中的剪贴板一文。(Linux 桌面、macOS 终端、gpm)
  • 在后台新标签页打开链接(火狐、Google Chrome 等浏览器都支持)
  • 关闭标签页(基本上也是用于网页浏览器。我自己的 GVim 也支持)
  • 定位滚动条,可以快速地定位到开头、结尾,或者之前的位置。不需要拖来拖去的麻烦。可惜 GTK 3 里这个功能不好用的了。(GTK 2、Qt)
  • 移动画布(GIMP、Inkscape 等作图软件、GNOME 的文档查看器 Evince)

这只是比较通用的功能。我的 Awesome 还配置了使用中键关闭窗口呢(「关闭标签页」语义的扩展)。火狐的一些菜单项也支持中键点击,比如书签菜单,右键的「查看图像」菜单,比如前进/后退按钮,以及在它上边点击右键出来的历史记录项目。

总结一下中键的语义:

  • 在可以粘贴的地方,粘贴
  • 在打开对象时,打开新对象而不取代已有者
  • 在打开的对象本身上时,关闭之
  • 在可定位对象上,移动之
Category: Linux | Tags: linux X Window X window
11
4
2015
23

从 slim 到 lightdm

从一开始使用 Arch Linux,我就选择了 slim 作为登录管理器。因为它轻量嘛,而且配合 Arch Linux 自己做的主题也挺漂亮的:

slim 登录界面

所以即使 slim 不再使用配置文件来指定有哪些桌面环境可用,改用无法指定顺序的 .desktop 文件,我只好告诉 pacman,不要升级 slim 了。

于是就这么用了很久,直到 lightdm 出世,直到 slim 所使用的托管网站关闭、停止开发,我也依然在用 slim。

直到有一天,那是在 systemd 开始使用用户级别的 session D-Bus 之后。我登出了会话,再次登入时,发现整个系统都不好了,因为 DBUS_SESSION_BUS_ADDRESS 环境变量没有被设置,导致程序找不到 session bus 而自动启动了一个。可我用户级别的 systemd 还在旧的 session bus 里呢,联系不上了。当然 tmux 里所使用的 session bus 也开始混乱了(我有让 tmux 从环境里更新各种 window 中的 DBUS_SESSION_BUS_ADDRESS 变量)。

究其原因,是因为 slim 没有正确地处理 sesssion。从 loginctl 及 systemd-cgls 可以看到,重新登录 slim 之后,进程并没有处在新的会话里,而是复用了旧的会话。

systemd 上,会话管理是 pam_systemd 来管理的,同时它会引入 DBUS_SESSION_BUS_ADDRESS 环境变量。PAM 会话是有一个 leader 进程的,它的结束标志着这个会话的结束(当然里边存活的进程还会继续存在)。比如文本终端登录用的 login,每一次登录都是一个新进程。比如 sshd,每个连接都是由单独的子进程来处理,PAM 会话也是那个时候打开的。然而 slim 却是在父进程里打开了 PAM 会话。于是 pam_systemd 一看,这个 session leader 怎么又要打开会话啦?报错:

8月 02 21:54:32 lilyforest slim[669]: pam_systemd(slim:session): Cannot create session: Already running in a session

所以,slim 下,只有第一次登录是正常的……

所以是时候换个跟得上时代的登录管理器了。那就 lightdm + GTK greeter 好了。

这个我以前也用过,不过没怎么配置所以背景一片漆黑,难看死了。这次制作了张背景图,在/etc/lightdm/lightdm-gtk-greeter.conf里配置一下

[greeter]
background=/usr/local/share/pixmaps/background.png

咦?还有头像?那就放一个~/.face好了。什么?lightdm 你没权限读取它?OK,给你权限:

setfacl -m u:lightdm:x ~
setfacl -m u:lightdm:r ~/.face

我的 HOME 目录的权限是 750,别人(other)进不来的,所以要给 lightdm x 权限。

最终的样子就是这样,也挺漂亮的,功能还挺全 :-)

lightdm 登录界面

Category: Linux | Tags: linux X Window systemd X window
11
4
2015
23

从 slim 到 lightdm

从一开始使用 Arch Linux,我就选择了 slim 作为登录管理器。因为它轻量嘛,而且配合 Arch Linux 自己做的主题也挺漂亮的:

slim 登录界面

所以即使 slim 不再使用配置文件来指定有哪些桌面环境可用,改用无法指定顺序的 .desktop 文件,我只好告诉 pacman,不要升级 slim 了。

于是就这么用了很久,直到 lightdm 出世,直到 slim 所使用的托管网站关闭、停止开发,我也依然在用 slim。

直到有一天,那是在 systemd 开始使用用户级别的 session D-Bus 之后。我登出了会话,再次登入时,发现整个系统都不好了,因为 DBUS_SESSION_BUS_ADDRESS 环境变量没有被设置,导致程序找不到 session bus 而自动启动了一个。可我用户级别的 systemd 还在旧的 session bus 里呢,联系不上了。当然 tmux 里所使用的 session bus 也开始混乱了(我有让 tmux 从环境里更新各种 window 中的 DBUS_SESSION_BUS_ADDRESS 变量)。

究其原因,是因为 slim 没有正确地处理 sesssion。从 loginctl 及 systemd-cgls 可以看到,重新登录 slim 之后,进程并没有处在新的会话里,而是复用了旧的会话。

systemd 上,会话管理是 pam_systemd 来管理的,同时它会引入 DBUS_SESSION_BUS_ADDRESS 环境变量。PAM 会话是有一个 leader 进程的,它的结束标志着这个会话的结束(当然里边存活的进程还会继续存在)。比如文本终端登录用的 login,每一次登录都是一个新进程。比如 sshd,每个连接都是由单独的子进程来处理,PAM 会话也是那个时候打开的。然而 slim 却是在父进程里打开了 PAM 会话。于是 pam_systemd 一看,这个 session leader 怎么又要打开会话啦?报错:

8月 02 21:54:32 lilyforest slim[669]: pam_systemd(slim:session): Cannot create session: Already running in a session

所以,slim 下,只有第一次登录是正常的……

所以是时候换个跟得上时代的登录管理器了。那就 lightdm + GTK greeter 好了。

这个我以前也用过,不过没怎么配置所以背景一片漆黑,难看死了。这次制作了张背景图,在/etc/lightdm/lightdm-gtk-greeter.conf里配置一下

[greeter]
background=/usr/local/share/pixmaps/background.png

咦?还有头像?那就放一个~/.face好了。什么?lightdm 你没权限读取它?OK,给你权限:

setfacl -m u:lightdm:x ~
setfacl -m u:lightdm:r ~/.face

我的 HOME 目录的权限是 750,别人(other)进不来的,所以要给 lightdm x 权限。

最终的样子就是这样,也挺漂亮的,功能还挺全 :-)

lightdm 登录界面

Category: Linux | Tags: linux X Window systemd X window
11
24
2013
2

X Window 中的剪贴板

这原本是我在知乎上的一个回答,现在略作修改,放在博客上。


很多 Linux 用户知道,除了通用的Ctrl-C/Ctrl-V剪贴板外,Linux 桌面上还有另一套剪贴板可以用。

首先澄清一下,这个功能不属于 Linux,而是属于它(目前)所广泛使用的显示服务程序——X WindowX Window 的历史比 LinuxVim 都要古老呢。现在所使用的版本 X11 也是 1987 年就已经发布了的。

X Window 目前被广泛使用的用于 X Window 客户端(使用 X Window 的程序)间交换数据的剪贴板有两个:primary selectionclipboard

Primary selection,通常,内容被选择时会被放到这里,按鼠标中键时被获取并粘贴。

例外一火狐浏览器中只有用户主动选择的内容才会被放到 primary selection,由网页代码导致的选择不会修改用户的 primary selection。
例外二Vim / GVim 的「可视」选择默认并不放到 primary selection。有选项可以设置成这样。
例外三:一些网站(如 GitHub)用的 Ace 在线编辑器,在用户「选择」时并不创建真正的选择区,它只在用户按Ctrl-C等键时做一些处理,因此在 Ace 编辑器中选中复制、中键粘贴无效。
例外四Wine 不支持 primary selection。

Clipboard,这就是大家熟悉的剪贴板了,图形界面程序中Ctrl-C复制,Ctrl-V粘贴。终端里因为快捷键会冲突,所以这些图形界面常用的快捷键使用的时候都要按住 Shift 键。

关 于 X Window 剪贴板要注意的地方:以上剪贴板的内容都不是保存在 X 服务器上的,而是客户端程序说,「我请求提供这个剪贴板的数据」(X 服务器通常会允许这样的请求)。另外的程序要粘贴时就会通过 X 服务器向这个程序请求:「请把 XX 剪贴板的数据给我。」所以,X Window 剪贴板上的内容会在拥有它的程序退出后自动被清除。所以一般人会需要用剪贴板管理器来更持久一些地保存剪贴板数据。

关于 X 协议细节可能有些不对,不过大体上是这个样子的啦。

还有没什么程序用到的 secondary selection,以及 Vim 偶尔会用到的 cut buffers(共8个,Vim 和 xterm 会用第一个)。Cut buffers 似乎是由 X 服务器保存数据的。Vim 在挂起时为了避免请求剪贴板数据的程序长时间等待会把自己的选择区内容写到 CUT_BUFFER0。

火狐似乎设置了很短的剪贴板请求超时时间,因此,从远程程序请求剪贴板数据时,可能因为网络延迟导致火狐没有及时得到数据而放弃。

Category: Linux | Tags: linux X Window X window
11
24
2013
2

X Window 中的剪贴板

这原本是我在知乎上的一个回答,现在略作修改,放在博客上。


很多 Linux 用户知道,除了通用的Ctrl-C/Ctrl-V剪贴板外,Linux 桌面上还有另一套剪贴板可以用。

首先澄清一下,这个功能不属于 Linux,而是属于它(目前)所广泛使用的显示服务程序——X WindowX Window 的历史比 LinuxVim 都要古老呢。现在所使用的版本 X11 也是 1987 年就已经发布了的。

X Window 目前被广泛使用的用于 X Window 客户端(使用 X Window 的程序)间交换数据的剪贴板有两个:primary selectionclipboard

Primary selection,通常,内容被选择时会被放到这里,按鼠标中键时被获取并粘贴。

例外一火狐浏览器中只有用户主动选择的内容才会被放到 primary selection,由网页代码导致的选择不会修改用户的 primary selection。
例外二Vim / GVim 的「可视」选择默认并不放到 primary selection。有选项可以设置成这样。
例外三:一些网站(如 GitHub)用的 Ace 在线编辑器,在用户「选择」时并不创建真正的选择区,它只在用户按Ctrl-C等键时做一些处理,因此在 Ace 编辑器中选中复制、中键粘贴无效。
例外四Wine 不支持 primary selection。

Clipboard,这就是大家熟悉的剪贴板了,图形界面程序中Ctrl-C复制,Ctrl-V粘贴。终端里因为快捷键会冲突,所以这些图形界面常用的快捷键使用的时候都要按住 Shift 键。

关 于 X Window 剪贴板要注意的地方:以上剪贴板的内容都不是保存在 X 服务器上的,而是客户端程序说,「我请求提供这个剪贴板的数据」(X 服务器通常会允许这样的请求)。另外的程序要粘贴时就会通过 X 服务器向这个程序请求:「请把 XX 剪贴板的数据给我。」所以,X Window 剪贴板上的内容会在拥有它的程序退出后自动被清除。所以一般人会需要用剪贴板管理器来更持久一些地保存剪贴板数据。

关于 X 协议细节可能有些不对,不过大体上是这个样子的啦。

还有没什么程序用到的 secondary selection,以及 Vim 偶尔会用到的 cut buffers(共8个,Vim 和 xterm 会用第一个)。Cut buffers 似乎是由 X 服务器保存数据的。Vim 在挂起时为了避免请求剪贴板数据的程序长时间等待会把自己的选择区内容写到 CUT_BUFFER0。

火狐似乎设置了很短的剪贴板请求超时时间,因此,从远程程序请求剪贴板数据时,可能因为网络延迟导致火狐没有及时得到数据而放弃。

Category: Linux | Tags: linux X Window X window
11
15
2013
5

在 Awesome 下对 Wine 运行的 TM.exe 使用 Alt+数字键来切换标签页

现在我一直在使用 Wine 运行 TM2013。这个版本支持一个窗口里以标签页的方式放多个对话了。然后就遇到一个问题——不同平台切换标签页的快捷键是不同的!

Linux 使用Alt+数字,Mac OS X 使用⌘数字,而 Windows 则使用Ctrl+数字。像火狐这种多平台支持得非常好的程序,不仅有一个适合其所运行平台的默认值,而且也可以通过手动修改about:config来使用其它平台上的习惯。但是,TM 显然不可能这么体贴。

不过我是 Linux + Awesome 用户嘛,怎么可能轻易就妥协呢。既然 TM 自己不认,那我让 Awesome 在Alt+数字时给 TM 的窗口发Ctrl+数字就好了嘛。想法是好的,现实却不那么美好,Awesome 不支持直接给窗口发送指定按键。于是只好调用 xdotool 命令了。因为按 Awesome 快捷键的时候,焦点会暂时移出原窗口,所以我指定了窗口 ID。延时的解决方法没这个优雅:

-- {{{ bind_alt_switch_tab_keys
alt_switch_keys = awful.util.table.join(
    -- it's easier for a vimer to manage this than figuring out a nice way to loop and concat
    awful.key({'Mod1'}, 1, function(c) awful.util.spawn('xdotool key --window ' .. c.window .. ' ctrl+1') end),
    awful.key({'Mod1'}, 2, function(c) awful.util.spawn('xdotool key --window ' .. c.window .. ' ctrl+2') end),
    awful.key({'Mod1'}, 3, function(c) awful.util.spawn('xdotool key --window ' .. c.window .. ' ctrl+3') end),
    awful.key({'Mod1'}, 4, function(c) awful.util.spawn('xdotool key --window ' .. c.window .. ' ctrl+4') end),
    awful.key({'Mod1'}, 5, function(c) awful.util.spawn('xdotool key --window ' .. c.window .. ' ctrl+5') end),
    awful.key({'Mod1'}, 6, function(c) awful.util.spawn('xdotool key --window ' .. c.window .. ' ctrl+6') end),
    awful.key({'Mod1'}, 7, function(c) awful.util.spawn('xdotool key --window ' .. c.window .. ' ctrl+7') end),
    awful.key({'Mod1'}, 8, function(c) awful.util.spawn('xdotool key --window ' .. c.window .. ' ctrl+8') end),
    awful.key({'Mod1'}, 9, function(c) awful.util.spawn('xdotool key --window ' .. c.window .. ' ctrl+9') end)
)
function bind_alt_switch_tab_keys(client)
    client:keys(awful.util.table.join(client:keys(), alt_switch_keys))
end -- }}}

然后在 TM 的窗口上调用这个函数就可以了。唯一有点小遗憾的是,fcitx 的图标在按 Awesome 快捷键时会切换一下。

Category: Linux | Tags: wIne Awesome X Window TM
11
15
2013
5

在 Awesome 下对 Wine 运行的 TM.exe 使用 Alt+数字键来切换标签页

现在我一直在使用 Wine 运行 TM2013。这个版本支持一个窗口里以标签页的方式放多个对话了。然后就遇到一个问题——不同平台切换标签页的快捷键是不同的!

Linux 使用Alt+数字,Mac OS X 使用⌘数字,而 Windows 则使用Ctrl+数字。像火狐这种多平台支持得非常好的程序,不仅有一个适合其所运行平台的默认值,而且也可以通过手动修改about:config来使用其它平台上的习惯。但是,TM 显然不可能这么体贴。

不过我是 Linux + Awesome 用户嘛,怎么可能轻易就妥协呢。既然 TM 自己不认,那我让 Awesome 在Alt+数字时给 TM 的窗口发Ctrl+数字就好了嘛。想法是好的,现实却不那么美好,Awesome 不支持直接给窗口发送指定按键。于是只好调用 xdotool 命令了。因为按 Awesome 快捷键的时候,焦点会暂时移出原窗口,所以我指定了窗口 ID。延时的解决方法没这个优雅:

-- {{{ bind_alt_switch_tab_keys
alt_switch_keys = awful.util.table.join(
    -- it's easier for a vimer to manage this than figuring out a nice way to loop and concat
    awful.key({'Mod1'}, 1, function(c) awful.util.spawn('xdotool key --window ' .. c.window .. ' ctrl+1') end),
    awful.key({'Mod1'}, 2, function(c) awful.util.spawn('xdotool key --window ' .. c.window .. ' ctrl+2') end),
    awful.key({'Mod1'}, 3, function(c) awful.util.spawn('xdotool key --window ' .. c.window .. ' ctrl+3') end),
    awful.key({'Mod1'}, 4, function(c) awful.util.spawn('xdotool key --window ' .. c.window .. ' ctrl+4') end),
    awful.key({'Mod1'}, 5, function(c) awful.util.spawn('xdotool key --window ' .. c.window .. ' ctrl+5') end),
    awful.key({'Mod1'}, 6, function(c) awful.util.spawn('xdotool key --window ' .. c.window .. ' ctrl+6') end),
    awful.key({'Mod1'}, 7, function(c) awful.util.spawn('xdotool key --window ' .. c.window .. ' ctrl+7') end),
    awful.key({'Mod1'}, 8, function(c) awful.util.spawn('xdotool key --window ' .. c.window .. ' ctrl+8') end),
    awful.key({'Mod1'}, 9, function(c) awful.util.spawn('xdotool key --window ' .. c.window .. ' ctrl+9') end)
)
function bind_alt_switch_tab_keys(client)
    client:keys(awful.util.table.join(client:keys(), alt_switch_keys))
end -- }}}

然后在 TM 的窗口上调用这个函数就可以了。唯一有点小遗憾的是,fcitx 的图标在按 Awesome 快捷键时会切换一下。

Category: Linux | Tags: wIne Awesome X Window TM
8
23
2013
11

xmodmap 和 fcitx 配合使用

很早之前,因为有了 fcitx-keyboard,fcitx 能够管理键盘布局了。于是乎,经常干了什么事情之后,xmodmap 的效果就没了。

为了解决这个问题,fcitx 可以在相关事件时自动调用 xmodmap 命令。然后我发现,xmodmap 命令经常会调用很多很多次。我笔记本的配置还好,那个 xmodmap 配置调用多次会有命令失败,所以只要调整下顺序就可以保证键映射正确:

keysym Pause = Print
remove Lock = Caps_Lock
keysym Escape = Caps_Lock
keysym Caps_Lock = Escape
add Lock = Caps_Lock
keycode 107 = Super_R Sys_Req Super_R Sys_Req

这样子日志里会多一些消息,无所谓了,反正桌面日志我只保留最近的一份。

可是,我另外的系统上只需要交换 EscCaps Lock 这两个键:

remove Lock = Caps_Lock
keysym Escape = Caps_Lock
keysym Caps_Lock = Escape
add Lock = Caps_Lock

于是,当 fcitx 调用偶数次 xmodmap 时,这两个键就给交换回去了……实际的效果是,我几乎每次从挂起中恢复,都需要手动执行一次 xmodmap。更烦的是,几乎每次在 gnome-screensaver 里输入密码时,大小写切换键默认是开着的。这时候我得按按 Esc 或者 Caps Lock,或者是输入一个字符后再按它们中的一个。一直以来没找到规律……

最后,终于查阅 xmodmap 手册,写了下面这个简单的脚本:

#!/bin/bash -e

[[ -n $(xmodmap -pk | awk '$1 == 66 && $3 == "(Escape)"') ]] || xmodmap ~/.Xmodmap

如果 Esc 键已经交换过了,就不要再交换一次了。

再设置 fcitx 执行这个我自己的脚本就可以了:

fcitx 中的 xmodmap 配置

2013年8月28日更新:csslayer 最近已经修复了 fcitx 多次调用 xmodmap 的问题,不再需要这样特别的设置了。感谢 csslayer 的及时修正=w=

Category: Linux | Tags: fcitx X Window X window xmodmap
8
23
2013
11

xmodmap 和 fcitx 配合使用

很早之前,因为有了 fcitx-keyboard,fcitx 能够管理键盘布局了。于是乎,经常干了什么事情之后,xmodmap 的效果就没了。

为了解决这个问题,fcitx 可以在相关事件时自动调用 xmodmap 命令。然后我发现,xmodmap 命令经常会调用很多很多次。我笔记本的配置还好,那个 xmodmap 配置调用多次会有命令失败,所以只要调整下顺序就可以保证键映射正确:

keysym Pause = Print
remove Lock = Caps_Lock
keysym Escape = Caps_Lock
keysym Caps_Lock = Escape
add Lock = Caps_Lock
keycode 107 = Super_R Sys_Req Super_R Sys_Req

这样子日志里会多一些消息,无所谓了,反正桌面日志我只保留最近的一份。

可是,我另外的系统上只需要交换 EscCaps Lock 这两个键:

remove Lock = Caps_Lock
keysym Escape = Caps_Lock
keysym Caps_Lock = Escape
add Lock = Caps_Lock

于是,当 fcitx 调用偶数次 xmodmap 时,这两个键就给交换回去了……实际的效果是,我几乎每次从挂起中恢复,都需要手动执行一次 xmodmap。更烦的是,几乎每次在 gnome-screensaver 里输入密码时,大小写切换键默认是开着的。这时候我得按按 Esc 或者 Caps Lock,或者是输入一个字符后再按它们中的一个。一直以来没找到规律……

最后,终于查阅 xmodmap 手册,写了下面这个简单的脚本:

#!/bin/bash -e

[[ -n $(xmodmap -pk | awk '$1 == 66 && $3 == "(Escape)"') ]] || xmodmap ~/.Xmodmap

如果 Esc 键已经交换过了,就不要再交换一次了。

再设置 fcitx 执行这个我自己的脚本就可以了:

fcitx 中的 xmodmap 配置

2013年8月28日更新:csslayer 最近已经修复了 fcitx 多次调用 xmodmap 的问题,不再需要这样特别的设置了。感谢 csslayer 的及时修正=w=

Category: Linux | Tags: fcitx X Window X window xmodmap

Mastodon | Theme: Aeros 2.0 by TheBuckmaker.com