我在GNU/Linux下使用的桌面环境工具组合
为了使GNU/Linux桌面环境下加载的程序较少以节省内存资源和提高启动时间,我目前并不使用重量级的桌面环境KDE和Gnome,甚至连登录窗界面gdm或xdm都不用,而是直接启动到控制台,登录后调用startx进入X视窗环境。所使用的工具组合列举如下:
- X视窗环境启动:startx
- 窗口管理器:Sawfish
- amixer:系统音量设置
- 键盘与鼠标配置:xmodmap
- 网络管理器:wicd(需删除NetworkManager)
- xscreensaver:屏幕保护程序
- 类似于Windows的底部工具栏:perlpanel
- shutter:截屏工具
- amor:屏幕宠物玩具
- workrave:定时休息、活动提醒工具,用于缓解视疲劳,身体疲劳
- xclock:桌面模拟或数字时钟
- knotes:桌面即时贴
在~/.bashrc中设置音频
首先介绍登录到控制台时,在~/.bashrc中定义的一些环境变量,它们会在启动X Window后,由amixer命令使用,用于系统音量控制。
# Default sound device export DEFAULT_SOUND=numid=3,iface=MIXER,name="'Master Playback Volume'" # Max sound for the two channels supported by the sound card declare -i MAX_SOUND_VOLUME export MAX_SOUND_VOLUME=65536 # Default sound volume percentage for the two channels when starting X window declare -i DEFAULT_LSOUND_VOLUME_PERCENTAGE DEFAULT_RSOUND_VOLUME_PERCENTAGE export DEFAULT_LSOUND_VOLUME_PERCENTAGE=40 export DEFAULT_RSOUND_VOLUME_PERCENTAGE=40 # Default sound volume for the two channels when starting X window declare -i DEFAULT_LSOUND_VOLUME DEFAULT_RSOUND_VOLUME export DEFAULT_LSOUND_VOLUME=$(($MAX_SOUND_VOLUME * $DEFAULT_LSOUND_VOLUME_PERCENTAGE / 100)) export DEFAULT_RSOUND_VOLUME=$(($MAX_SOUND_VOLUME * $DEFAULT_RSOUND_VOLUME_PERCENTAGE / 100)) # Whether play init sound when starting X window export STARTX_INIT_SOUND=1 # Aliases for starting X with or without soundalias xs="export STARTX_INIT_SOUND=1; startx"alias xq="export STARTX_INIT_SOUND=0; startx"
针对以上代码解释如下:
1. DEFAULT_SOUND变量包含了指定操作系统ALSA声卡驱动调音器设备的编号与名称。amixer以该值为参数,可以控制相应音频的音量。该设备信息可以在命令行执行amixer contents显示出来,如下所示。可以看出,默认音频设备音量的最小值为0,最大值为65536(2字节),最小调整量为1,当前左、右声道音量值均为17790。
numid=4,iface=MIXER,name='Master Playback Switch'; type=BOOLEAN,access=rw------,values=1: values=on numid=3,iface=MIXER,name='Master Playback Volume'; type=INTEGER,access=rw------,values=2,min=0,max=65536,step=1: values=17790,17790 numid=2,iface=MIXER,name='Capture Switch'; type=BOOLEAN,access=rw------,values=1: values=on numid=1,iface=MIXER,name='Capture Volume'; type=INTEGER,access=rw------,values=2,min=0,max=65536,step=1: values=28174,28174
2. MAX_SOUND_VOLUME变量存储了最大音量值65536。
3. DEFAULT_LSOUND_VOLUME_PERCENTAGE与DEFAULT_RSOUND_VOLUME_PERCENTAGE分别为左、右声道的默认音量百分比,目前设为40%。
4. DEFAULT_LSOUND_VOLUME与DEFAULT_RSOUND_VOLUME分别为左、右声道的默认音量整数值。
5. STARTX_INIT_SOUND变量为1时,在调用startx进入X Window时,会自动播放欢迎音乐;为0时则不播放。播放命令在~/.xinitrc中设置。
6. 创建了两个aliases,xs为调用startx时播放欢迎音乐,xq则不播放。
设置~/.xinitrc
在控制台登录后,有了~/.bashrc中的设置,就可以调用xs或xq来启动startx进入X Window视窗环境。启动过程中的相关配置与必要程序加载是在~/.xinitrc中设置的。其内容如下:
# Export ibus environment variables export XMODIFIERS=@im=ibus export GTK_IM_MODULE=ibus export QT_IM_MODULE=ibus# Load NVIDIA configurations nvidia-settings --load-config-only# Load keyboard and mouse configurations xmodmap ~/.xmodmaprc & # Load X server resources xrdb ~/.Xresources &# Load image(s) as desktop wallpaper # set_wallpaper.sh -r 0 -w 1920 -h 1080 -x 1280 -y 0 $picture/wallpapers/sunflower.jpg & set_multi_wallpapers.sh -t 300 & # Set the default sound volume amixer cset numid=3,iface=MIXER,name='Master Playback Volume' $DEFAULT_LSOUND_VOLUME,$DEFAULT_RSOUND_VOLUME & # Play welcome sound: Steve Jobs' speech if [ "$STARTX_INIT_SOUND" = 1 ]; thenmplayer $music/speech/steve\ jobs\ in\ harvard\ clip.mp3 < /dev/null > /dev/null & fi# Adjust touchpad pressure sensitivity if [ "$cur_host_name" = "QuantumBoy" ]; thensynclient PressureMotionMinZ=8synclient PressureMotionMaxZ=80 fi# Start window manager sawfish --display=:0
针对以上代码解释如下:
1. 导出ibus输入法相关的环境变量。
2. 执行nvidia-settings加载NVIDIA配置。
3. 使用xmodmap加载键盘与鼠标配置,主要是交换Caps Lock与左Control键,交换鼠标左右键。具体内容参见这里。
4. 使用xrdb加载视窗资源文件~/.Xresources,其中针对不同的程序设置X显示参数,设置光标主题。其内容如下:
Xcursor.theme: oxy-green XClock.Clock.hourColor: red XClock.Clock.minuteColor: green XClock.Clock.minorColor: blue XClock.Clock.majorColor: black
5. 启动set_multi_wallpapers.sh脚本加载动态壁纸,或调用set_wallpaper.sh加载单张壁纸。具体内容参见这里。
6. 使用amixer设置系统默认音量。左右声道的音量值来自环境变量DEFAULT_LSOUND_VOLUME和DEFAULT_RSOUND_VOLUME。
7. 根据环境变量STARTX_INIT_SOUND的值判断是否加播放启动音频。目前,我播放的是乔布斯说的stay hungray、stay foolish那段话。
8. 根据电脑的主机名判断,如果使用的是自己的笔记本电脑ZaReason Ultralap 440的话,则执行synclient命令设置触摸板压力阈值。
9. 最后,启动Sawfish窗口管理器。
Sawfish设置:~/.sawfishrc
Sawfish是一款轻量级的窗口管理器,基于librep库支持使用Lisp语言对其进行配置:包括窗口显示属性,快捷键绑定等。所以,所谓的轻量级实际上是高性能、省资源,但其功能可以通过编程配置得极为强大。下面介绍我在~/.sawfishrc文件对其的配置。其中主要实现的功能有:
1. 将常用程序绑定到指定的快捷上。按下快捷键后,若与其关联的程序未启动,则将其启动并放到前端;若已启动,则将其提升到前端。该功能的实现依赖于jump-or-exec模块。有了这个功能,则无需频繁地使用鼠标在不同的窗口间切换了,非常方便。目前,我绑定的快捷键如下:
- Win+1:命令行终端程序Konsole;
- Win+2:文件管理器Dolphin;
- Win+3:文本编辑器Emacs;
- Win+4:多国语言电子词典Stardict或Goldendict;
- Win+5:网页浏览器Iceweasel,它是Mozilla Firefox在Debian下的名称;
- Win+6:邮件客户端(亦是RSS阅读器、日历、任务管理,类似于微软的Outlook)Icedove,它是Mozilla Thunderbird在Debian下的名称;
- Win+7:办公软件LibreOffice;
- Win+8:图片、照片浏览器Gwenview。该软件比Windows下的图片查看器好很多:可以看GIF动画,亦可以直接看视频;
- Win+9:音频播放器Audacious,播放无损音乐ape、flac的不二之选;
- Win+0:调用tv_nomen.sh脚本程序播放有线电视,参见这里。
以上功能与设置的代码如下。其中的display-close-message函数用于在屏幕上显示已启动程序的名称,给用户以信息反馈,并在指定时间后自动关闭。
;; Load jump-or-exec module (require 'jump-or-exec);; Display a message which can automatically disappear (defun display-close-message (message seconds &optional attributes)"display MESSAGE for SECONDS seconds and make the message disappeared. The default display-message don't close the message window automatically"(interactive)(display-message message attributes)(make-timer(lambda ()(display-message)) seconds));; KDE terminal konsole (bind-keys global-keymap"Super-1" `(jump-or-exec "^Konsole@",(lambda ()(display-close-message "Start KDE terminal..." alert-msg-time alert-msg-attrib)(system "konsole &")),(lambda (wind)(display-window wind))));; Dolphin file manager (bind-keys global-keymap"Super-2" `(jump-or-exec "Dolphin$",(lambda ()(display-close-message "Start Dolphin file manager..." alert-msg-time alert-msg-attrib)(system "dolphin &")),(lambda (wind)(display-window wind))));; Emacs text editor (bind-keys global-keymap"Super-3" `(jump-or-exec "^Emacs@",(lambda ()(display-close-message "Start Emacs text editor..." alert-msg-time alert-msg-attrib)(system "emacs &")),(lambda (wind)(display-window wind))));; Stardict (bind-keys global-keymap"Super-4" `(jump-or-exec "^StarDict$",(lambda ()(display-close-message "Start Stardict electronic dictionary..." alert-msg-time alert-msg-attrib)(system "stardict &")),(lambda (wind)(display-window wind))));; Iceweasel (bind-keys global-keymap"Super-5" `(jump-or-exec "Iceweasel$",(lambda ()(display-close-message "Start Iceweasel web browser..." alert-msg-time alert-msg-attrib)(system "iceweasel &")),(lambda (wind)(display-window wind))));; Icedove (bind-keys global-keymap"Super-6" `(jump-or-exec "(Mozilla Thunderbird)|(Icedove)",(lambda ()(display-close-message "Start Icedove mail and news..." alert-msg-time alert-msg-attrib)(system "icedove &")),(lambda (wind)(display-window wind))));; LibreOffice (bind-keys global-keymap"Super-7" `(jump-or-exec "LibreOffice",(lambda ()(display-close-message "Start LibreOffice..." alert-msg-time alert-msg-attrib)(system "libreoffice &")),(lambda (wind)(display-window wind))));; Gwenview (bind-keys global-keymap"Super-8" `(jump-or-exec "Gwenview$",(lambda ()(display-close-message "Start Gwenview image viewer..." alert-msg-time alert-msg-attrib)(system "gwenview &")),(lambda (wind)(display-window wind))));; Audacious (bind-keys global-keymap"Super-9" `(jump-or-exec "Audacious",(lambda ()(display-close-message "Start Audacious music player..." alert-msg-time alert-msg-attrib)(system "audacious &")),(lambda (wind)(display-window wind))));; TV (bind-keys global-keymap"Super-0" `(jump-or-exec "MPlayer TV",(lambda ()(display-close-message "Start TV..." alert-msg-time alert-msg-attrib)(system "tv_nomen.sh &")),(lambda (wind)(display-window wind))))
2. 在进入X Window时自动加载指定程序,相当于Windows中的自启动项目。目前我加载的程序有:
- ibus输入法;
- 网络管理器wicd-gtk;
- 允许触摸板点击脚本enable_tapbutton.sh(仅在我的ZaReason Ultralap 440笔记本电脑上有效);
- xscreensaver屏幕保护程序,其中包含了非常酷的屏保特效,我目前使用的是3D骇客帝国;
- 类似于Windows的底部工具栏:perlpanel
- shutter:截屏工具
- amor:屏幕宠物玩具
- workrave:定时休息、活动提醒工具,用于缓解视疲劳,身体疲劳
- xclock:桌面模拟或数字时钟
- knotes:桌面即时贴
相关配置代码如下:
;; Define startup programs (setq startup-programs'(;; Start ibus input method: -x option starts ibus XIM server, -r option;; replaces existing daemon. In addition, the following environment;; variables should be set, otherwise, KDE programs cannot use ibus input;; method.("ibus-daemon" "-xrd");; Start wicd network manager("wicd-gtk" "-t");; Enable touchpad tapping("enable_tapbutton.sh");; Start screensaver("xscreensaver" "-no-splash");; Start panel("perlpanel");; Start Shutter for taking snapshots("shutter");; Start amor toy: white kitty("amor");; Start xclock("xclock");; Start knotes("knotes");; Start workrave("workrave")));; Execute startup programs one by one (mapc (lambda (program)(apply start-process (make-process standard-output) program))startup-programs);; Make sure active processes are killed before sawfish exits (add-hook 'before-exit-hook(lambda ()(mapc stop-process (active-processes))))
3. 音量控制:目前音量控制绑定的快捷键如下
- Win+]:运行volume-up-by-ratio,增加音量1%
- Win+[:运行volume-down-by-ratio,减小音量1%
- Win+\:运行toggle-volume-mute,在当静音与当前音量间切换
其所关联的Sawfish函数会调用amixer命令来完成指定的操作。具体可以查阅amixer相关帮助。Sawfish代码如下:
;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; System sound volume related variables and functions ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; (setq max-volume (string->number (getenv "MAX_SOUND_VOLUME"))) (setq min-volume 0) (setq current-left-volume 0) (setq current-right-volume 0) (setq left-volume-before-mute 0) (setq right-volume-before-mute 0) (setq volume-adjust-ratio-step 0.01) (setq toggle-mute-flag nil);; Get volume for both left and right channels and store them into variables (defun get-volume()"Get the volume string"(interactive)(let* ((res-stream (make-string-output-stream))(proc (make-process res-stream))(res-str)(res-str-splitted))(call-process proc nil "/usr/local/bin/scripts/get_volume.sh")(setq res-str (get-output-stream-string res-stream))(setq res-str-splitted (string-split "," (substring res-str 0 (- (length res-str) 1))))(setq current-left-volume (string->number (nth 0 res-str-splitted)))(setq current-right-volume (string->number (nth 1 res-str-splitted))))) (get-volume);; Get volume percentage string (defun get-volume-percentage-str (vol)"Get the percentage of the specified volume quantity in string format"(interactive)(concat (number->string (round (* (/ vol max-volume) 100))) "%"));; Set volume by ratio (defun set-volume-by-ratio (lft-vol rt-vol)"Set volume by percentage"(interactive)(system (concat "amixer cset " (getenv "DEFAULT_SOUND") " " (number->string (* max-volume lft-vol)) "," (number->string (* max-volume rt-vol)) " &"))(get-volume));; Set volume by value (defun set-volume-by-value (lft-vol rt-vol)"Set volume by value"(interactive)(system (concat "amixer cset " (getenv "DEFAULT_SOUND") " " (number->string lft-vol) "," (number->string rt-vol) " &"))(get-volume));; Increase volume by ratio (defun volume-up-by-ratio (vol)"Increase volume by ratio"(interactive)(let ((tmp-lft-vol)(tmp-rt-vol))(get-volume)(setq tmp-lft-vol (+ current-left-volume (* max-volume vol)))(setq tmp-rt-vol (+ current-right-volume (* max-volume vol)));; Detect if the volume is larger than max-volume(if (> tmp-lft-vol max-volume)(setq tmp-lft-vol max-volume))(if (> tmp-rt-vol max-volume)(setq tmp-rt-vol max-volume))(set-volume-by-value tmp-lft-vol tmp-rt-vol)));; Decrease volume by ratio (defun volume-down-by-ratio (vol)"Decrease volume by ratio"(interactive)(let ((tmp-lft-vol)(tmp-rt-vol))(get-volume)(setq tmp-lft-vol (- current-left-volume (* max-volume vol)))(setq tmp-rt-vol (- current-right-volume (* max-volume vol)));; Detect if the volume is smaller than min-volume(if (< tmp-lft-vol min-volume)(setq tmp-lft-vol min-volume))(if (< tmp-rt-vol min-volume)(setq tmp-rt-vol min-volume))(set-volume-by-value tmp-lft-vol tmp-rt-vol)));; Mute volume (defun volume-mute ()"Mute system sound"(interactive)(set-volume-by-value min-volume min-volume));; Unmute volume (defun volume-unmute ()"Unmute system sound"(interactive)(set-volume-by-value left-volume-before-mute right-volume-before-mute));; Full volume (defun volume-max ()"Set to max sound volume"(interactive)(set-volume-by-value max-volume max-volume));; Toggle mute (defun toggle-volume-mute ()"Toggle between current sound volume and mute"(interactive)(get-volume)(if (and (= current-left-volume min-volume) (= current-right-volume min-volume))(if toggle-mute-flag(progn(volume-unmute)(setq toggle-mute-flag nil)(display-close-message (concat "Sound restored to L:" (get-volume-percentage-str current-left-volume) " R:" (get-volume-percentage-str current-right-volume)) alert-msg-short-time alert-msg-attrib)))(progn(setq left-volume-before-mute current-left-volume)(setq right-volume-before-mute current-right-volume)(volume-mute)(setq toggle-mute-flag t)(display-close-message "Mute" alert-msg-short-time alert-msg-attrib))));; Increase sound volume (bind-keys global-keymap"Super-]" `(progn(volume-up-by-ratio volume-adjust-ratio-step)(display-close-message (concat "Volume L:" (get-volume-percentage-str current-left-volume) " R:" (get-volume-percentage-str current-right-volume)) alert-msg-short-time alert-msg-attrib)));; Decrease sound volume (bind-keys global-keymap"Super-[" `(progn(volume-down-by-ratio volume-adjust-ratio-step)(display-close-message (concat "Volume L:" (get-volume-percentage-str current-left-volume) " R:" (get-volume-percentage-str current-right-volume)) alert-msg-short-time alert-msg-attrib)));; Toggle sound mute and unmute (bind-keys global-keymap"Super-\\" `(toggle-volume-mute))
以上代码中还用到了自己编写的脚本get_volume.sh用于获取系统当前音量,具体如下:
#!/bin/bashamixer cget $DEFAULT_SOUND | gawk '{if(match($0, /values=([[:digit:]]+,[[:digit:]]+)/, res) != 0) print res[1];}'
4. 关闭与激活屏幕保护程序:看电影的时候就不要启动屏保了,所以需要这样的功能。绑定的快捷键为Win+p。相关配置如下。
;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; xscreensaver related variables and functions ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; (setq xscreensaver-enabled t)(defun enable-xscreensaver ()"Enable xscreensaver"(interactive)(system "exec /usr/bin/xscreensaver -no-splash &")(setq xscreensaver-enabled t))(defun disable-xscreensaver ()"Disable xscreensaver"(interactive)(system "exec /usr/bin/xscreensaver-command -exit &")(setq xscreensaver-enabled nil))(defun toggle-xscreensaver-activation ()"Activate/deactivate xscreensaver"(interactive)(if xscreensaver-enabled(disable-xscreensaver)(enable-xscreensaver)))(bind-keys global-keymap"Super-p" `(progn(toggle-xscreensaver-activation)(if xscreensaver-enabled(display-close-message "Screensaver enabled!" alert-msg-short-time alert-msg-attrib)(display-close-message "Screensaver disabled!" alert-msg-short-time alert-msg-attrib))))
5. 关闭与激活触控板按钮(仅对笔记本电脑有效),快捷键为Win+z。相关配置如下:
;; ;;;;;;;;;;;;;;;;;;;; ;; Touchpad operation ;; ;;;;;;;;;;;;;;;;;;;; (setq tapbutton-enabled t) ;; Toggle tap button function of the touchpad (bind-keys global-keymap"Super-z" `(progn(system "toggle_tapbutton.sh &")(setq tapbutton-enabled (not tapbutton-enabled))(if tapbutton-enabled(display-close-message "Tap button enabled!" alert-msg-short-time alert-msg-attrib)(display-close-message "Tap button disabled!" alert-msg-short-time alert-msg-attrib))))
其中调用了自己编写的脚本程序toggle_tapbutton.sh与enable_tapbutton.sh,其内容分别为:
#!/bin/bashscript_name="toggle_tapbutton.sh" script_usage=$(cat <<EOF $script_name EOF ) script_function=$(cat <<EOF This script is used to disable/enable the finger tap function of Synaptics touchpad. EOF ) script_doc=$(cat <<EOF -h Display this help. EOF ) script_examples=$(cat <<EOF EOF ) state_prefix="===" warning_prefix="***" error_prefix="!!!"function display_help() {if [ -n "$script_usage" ]; thenecho -e "Usage: $script_usage"fiif [ -n "$script_function" ]; thenecho -e "$script_function"fiif [ -n "$script_doc" ] ; thenecho -e "\n$script_doc"fiif [ -n "$script_examples" ]; thenecho -e "\nExamples"echo -e "$script_examples"fi }# Process command options while getopts ":h" opt; docase $opt inh ) display_helpexit 0 ;;\? ) display_helpexit 1 ;;esac done shift $(($OPTIND - 1))# Start execute the command if [ $OSTYPE = 'linux-gnu' ]; thentap1=`synclient -l | grep TapButton1 | cut -d '=' -f 2 | tr -d [:space:]`tap2=`synclient -l | grep TapButton2 | cut -d '=' -f 2 | tr -d [:space:]`tap3=`synclient -l | grep TapButton3 | cut -d '=' -f 2 | tr -d [:space:]`if [ "$tap1" = "0" ] && [ "$tap2" = "0" ] && [ "$tap3" = "0" ]; thenenable_tapbutton.shelsedisable_tapbutton.shfiexit 0 fiecho "$warning_prefix Operating system or host name is not supported!"
#!/bin/bashscript_name="enable_tapbutton.sh" script_usage=$(cat <<EOF $script_name EOF ) script_function=$(cat <<EOF This script is used to enable the finger tap function of Synaptics touchpad. EOF ) script_doc=$(cat <<EOF -h Display this help. EOF ) script_examples=$(cat <<EOF EOF ) state_prefix="===" warning_prefix="***" error_prefix="!!!"function display_help() {if [ -n "$script_usage" ]; thenecho -e "Usage: $script_usage"fiif [ -n "$script_function" ]; thenecho -e "$script_function"fiif [ -n "$script_doc" ] ; thenecho -e "\n$script_doc"fiif [ -n "$script_examples" ]; thenecho -e "\nExamples"echo -e "$script_examples"fi }# Process command options while getopts ":h" opt; docase $opt inh ) display_helpexit 0 ;;\? ) display_helpexit 1 ;;esac done shift $(($OPTIND - 1))# Start execute the command if [ $OSTYPE = 'linux-gnu' ]; thensynclient TapButton1=3synclient TapButton2=1synclient TapButton3=2echo "$state_prefix Finger tapping on touchpad has been enabled!"exit 0 fiecho "$warning_prefix Operating system or host name is not supported!"
6. 窗口与桌面操作函数与快捷键:其中一些功能是Sawfish自带的,直接在设置对话窗口中绑定即可。
- Win+e:显示当前窗口信息,包括名称、大小、位置、组编号
;; Display window position and dimension (defun display-window-paras ()"Display the position, dimension and group ID of the current window."(interactive)(let* ((cur-win (input-focus))(win-width (car (window-dimensions cur-win)))(win-height (cdr (window-dimensions cur-win)))(win-x (car (window-position cur-win)))(win-y (cdr (window-position cur-win))))(display-message(concat "Name: " (window-name cur-win) "\n""Dimension: " (number->string win-width) "x" (number->string win-height) "\n""Position: " (number->string win-x) "x" (number->string win-y) "\n""Group ID: " (number->string (window-actual-group-id cur-win)))alert-msg-attrib)))(bind-keys window-keymap"Super-e" `(display-window-paras))
- Win+c:将窗口放置于屏幕(Screen)中心。其中调用了current-head-dimension与current-head-offset,所以可以支持多个显示器。
;; Center to screen (defun center-to-screen (cur-win)"Center the current window to the current screen"(interactive "%f")(let* ((screen-width (car (current-head-dimensions cur-win)))(screen-height (cdr (current-head-dimensions cur-win)))(screen-x (car (current-head-offset cur-win)))(screen-y (cdr (current-head-offset cur-win)))(win-width (car (window-dimensions cur-win)))(win-height (cdr (window-dimensions cur-win)))(win-x (car (window-position cur-win)))(win-y (cdr (window-position cur-win))));; Adjust x position(if (>= win-width screen-width)(setq win-x screen-x)(setq win-x (round (+ (/ (- screen-width win-width) 2) screen-x))));; Adjust y position(if (>= win-height screen-height)(setq win-y screen-y)(setq win-y (round (+ (/ (- screen-height win-height) 2) screen-y))));; Modify window position(move-window-to cur-win win-x win-y)))
- Win+f:显示与隐藏窗口边框。在一些电影上可以看到黑客用的电脑程序没有窗口边框。
;; Toggle window type between default and unframed (defun toggle-window-frame (cur-win)"Toggle window type between default and unframed"(interactive)(if (= (window-type cur-win) 'unframed)(set-window-type cur-win 'default)(set-window-type cur-win 'unframed)))(bind-keys window-keymap"Super-f" `(toggle-window-frame (input-focus)))
- Win+Ctrl+1~9:将窗口添加到指定组,这就像是在玩星际编队。
;; Window group related functions (bind-keys window-keymap"Super-C-1" `(progn(let ((cur-win (input-focus)))(add-window-to-group cur-win 1)(display-close-message (concat "Window " (window-name (input-focus)) " added to group " (number->string 1)) alert-msg-time alert-msg-attrib))))(bind-keys window-keymap"Super-C-2" `(progn(let ((cur-win (input-focus)))(add-window-to-group cur-win 1)(display-close-message (concat "Window " (window-name (input-focus)) " added to group " (number->string 2)) alert-msg-time alert-msg-attrib))))(bind-keys window-keymap"Super-C-3" `(progn(let ((cur-win (input-focus)))(add-window-to-group cur-win 1)(display-close-message (concat "Window " (window-name (input-focus)) " added to group " (number->string 3)) alert-msg-time alert-msg-attrib))))(bind-keys window-keymap"Super-C-4" `(progn(let ((cur-win (input-focus)))(add-window-to-group cur-win 1)(display-close-message (concat "Window " (window-name (input-focus)) " added to group " (number->string 4)) alert-msg-time alert-msg-attrib))))(bind-keys window-keymap"Super-C-5" `(progn(let ((cur-win (input-focus)))(add-window-to-group cur-win 1)(display-close-message (concat "Window " (window-name (input-focus)) " added to group " (number->string 5)) alert-msg-time alert-msg-attrib))))(bind-keys window-keymap"Super-C-6" `(progn(let ((cur-win (input-focus)))(add-window-to-group cur-win 1)(display-close-message (concat "Window " (window-name (input-focus)) " added to group " (number->string 6)) alert-msg-time alert-msg-attrib))))(bind-keys window-keymap"Super-C-7" `(progn(let ((cur-win (input-focus)))(add-window-to-group cur-win 1)(display-close-message (concat "Window " (window-name (input-focus)) " added to group " (number->string 7)) alert-msg-time alert-msg-attrib))))(bind-keys window-keymap"Super-C-8" `(progn(let ((cur-win (input-focus)))(add-window-to-group cur-win 1)(display-close-message (concat "Window " (window-name (input-focus)) " added to group " (number->string 8)) alert-msg-time alert-msg-attrib))))(bind-keys window-keymap"Super-C-9" `(progn(let ((cur-win (input-focus)))(add-window-to-group cur-win 1)(display-close-message (concat "Window " (window-name (input-focus)) " added to group " (number->string 9)) alert-msg-time alert-msg-attrib))))
- Win+i:最小化窗口
(defun iconify-current-group (cur-win)"Iconify current window group"(interactive "%f")(iconify-group cur-win))
- Win+m:在最大化与窗口当前大小间切换
- Win+Shift+v:将窗口在垂直方向上放大
- Win+Shift+h:将窗口在水平方向上放大
- Win+k:杀掉当前窗口
- Win+t:在窗口提升一层与下降一层间切换
- Win+d:显示桌面
- Win+s:在窗口正常状态与收起状态间切换。所谓的收起即将窗口内容隐藏,只剩下标题栏
- Ctrl+Alt+left, right, up, down:在四个桌面间切换
- Win+left, right, up, down:让当前窗口向不同方向移动直至碰到屏幕边界或另一个窗口的边界
- Win+w:显示所有桌面菜单
- Win+SPC:显示当前窗口菜单
- Win+r:显示Sawfish桌面右键菜单
- Win+a:显示系统应用菜单
- Win+TAB:在窗口间循环
- Win+Ctrl+TAB:在窗口间反向循环
- Win+l:显示窗口列表菜单
- Win+`:执行Sawfish函数
- Ctrl+Alt+r:重启Sawfish
- Ctrl+Alt+q:退出Sawfish
7. 显示笔记本电池信息:调用了acpi命令,快捷键为Win+b,代码如下:
;; Display batter information by calling acpi (defun display-batter-info ()"Display batter information by calling acpi"(interactive)(let* ((res-stream (make-string-output-stream))(proc (make-process res-stream))(res-str))(call-process proc nil "acpi" "-i" "-b")(setq res-str (get-output-stream-string res-stream))(display-message res-str alert-msg-attrib)))(bind-keys global-keymap"Super-b" `(display-batter-info))
8. 添加窗口hook(before-add-window-hook)对符合匹配条件的窗口赋以特殊属性,如令其不显示在窗口循环列表中、自启动后保持最大化、指定窗口初始大小、将窗口固定显示在桌面某个位置等。需要用到正则表达式模块rep.regexp匹配字符串,以及sawfish.wm.commands.groups和sawfish.wm.frames模块获取窗口属性。相关配置如下:
(require 'rep.regexp) (require 'sawfish.wm.commands.groups) (require 'sawfish.wm.frames)(defun get-wm-window-type (win)"Get the _NET_WM_WINDOW_TYPE property of a window"(interactive)(aref (nth 2 (get-x-property win '_NET_WM_WINDOW_TYPE)) 0))(defun get-wm-property (win prop)"Get the x window property of a window"(interactive)(nth 2 (get-x-property win prop)));; Set LibreOffice Impress window property ;; Remove window frame of LibreOffice Impress window when it is in fullscreen ;; presentation. (add-hook 'before-add-window-hook(lambda (w)(if (and (string-match "^soffice" (get-wm-property w 'WM_CLASS)) (= (get-wm-window-type w) '_NET_WM_WINDOW_TYPE_NORMAL))(set-window-type w 'unframed)))t);; Set FreeRDP window property (add-hook 'before-add-window-hook(lambda (w)(if (string-match "^FreeRDP" (get-wm-property w 'WM_NAME))(progn(set-window-type w 'unframed))))t);; Set xclock window property (add-hook 'before-add-window-hook(lambda (w)(if (string-match "^xclock$" (get-wm-property w 'WM_NAME))(progn(mark-window-as-dock w)(window-put w 'task-list-skip t)(set-window-type w 'unframed))))t);; Set Audacious window property (add-hook 'before-add-window-hook(lambda (w)(if (string-match "[aA]udacious" (get-wm-property w 'WM_NAME))(progn(mark-window-as-desktop w)(window-put w 'task-list-skip t))))t);; Set Workrave window property (add-hook 'before-add-window-hook(lambda (w)(if (and (string-match "[wW]orkrave" (get-wm-property w 'WM_CLASS)) (string-match "[wW]orkrave" (get-wm-property w 'WM_NAME)))(progn(mark-window-as-dock w)(window-put w 'task-list-skip t))))t);; Set full-window online video window property (played in Iceweasel) (add-hook 'before-add-window-hook(lambda (w)(if (string-match "plugin-container" (get-wm-property w 'WM_NAME))(progn(maximize-window-fullscreen w)))));; Set Wesnoth full-window property (add-hook 'before-add-window-hook(lambda (w)(if (string-match "The Battle for Wesnoth" (get-wm-property w 'WM_NAME))(progn(set-window-type w 'unframed)(move-window-to w 1280 0)))))
总结
由本文介绍可以看出,通过将GNU/Linux下不同的工具组合起来,如startx、Sawfish、xmodmap、amixer等,便可以实现节省系统资源、高效、方便的桌面操作环境。
转载于:https://www.cnblogs.com/quantumman/p/4844745.html
我在GNU/Linux下使用的桌面环境工具组合相关推荐
- Linux下安装KDE桌面环境
Linux中有许多桌面应用环境,在这其中除了deepin的dde桌面之外,界面和功能都很强大好用的就是kde了.下面我来分享一下我的kde安装经过.我的Linux发行版是deepin的v15.11版本 ...
- 【评论】GNU/Linux下有多少是GNU的?
导读:一个葡萄牙的学生写了一篇文章 <How much GNU is there in GNU/Linux?>由酷壳网的陈皓整理编译为<GNU/Linux下有多少是GNU的>. ...
- GNU/Linux下有多少是GNU的?
导读:一个葡萄牙的学生写了一篇文章 <How much GNU is there in GNU/Linux?>由酷壳网的陈皓整理编译为<GNU/Linux下有多少是GNU的>. ...
- linux spyder 目录,linux下创建spyder桌面图标的方法
linux下创建spyder桌面图标的方法 发布时间:2020-07-20 11:08:41 来源:亿速云 阅读:96 作者:清晨 小编给大家分享一下linux下创建spyder桌面图标的方法,希望大 ...
- linux 系统下开源软件 ngspice 仿真实例,调侃Spice历史和GNU/Linux下做Spice电路仿真...
更应该注意一个细节问题:BSD在开发SPICE那时,就已经Open Source么? 经过小小的考证(所以,我说这个文章是"调侃"),原来大家非常熟悉的BSD License最早可 ...
- GNU/Linux下如何设计PCB印刷电路板
GNU/Linux下如何设计PCB印刷电路板 gplEDA This website contains links to Electronic Design Automation(EDA) tools ...
- linux 桌面3d硬件支持,Linux下实现3D桌面的效果
终于实现了Linux下的3d桌面效果! 用的是XGL+Compiz,以前弄了好多次,系统也不知道崩溃了多少次,终于成功了.哈哈. 我的显卡:nVidia 6600LE 说下我怎么实现的吧 1.现在新力 ...
- linux c语言工具,Linux下C语言编程环境的工具.doc
Linux下C语言编程环境的工具 Linux下C语言编程环境的工具 Linux下C语言编程环境的工具 要想在Linux下进行C语言编程,首先得搭建好一个编程环境.这里分别说明一下几个非常有用的软件包. ...
- GCC编译器简明教程(Linux下C语言开发环境的搭建)
GCC编译器简明教程(Linux下C语言开发环境的搭建) 市面上常见的Linux都是发行版本,典型的Linux发行版包含了Linux内核.桌面环境(例如GNOME.KDE.Unity等)和各种常用的必 ...
- 在CentOS 7最小环境下安装Cinnamon桌面环境
在CentOS 7最小环境下安装Cinnamon桌面环境 1 总体目标 学习为CentOS7安装自己喜欢的GUI桌面环境.本次学习使用Cinnamon环境.这个环境是LinuxMint的 ...
最新文章
- 网站seo优化相关性需要了解哪三方面内容?
- 微软免费图书《Introducing Microsoft LINQ》翻译Chapter2.1:C# 3.0 特性(对象初始化表达式\匿名类型\查询表达式)...
- javaweb-服务器输出字符数据到浏览器
- 【Linux系统编程】进程同步与互斥:System V 信号量
- html section 布局,HTML:section标签
- asposeword.dll通过word模板生成word、PDF
- 极大似然估计 摘自维基百科
- 解决Vue开发过程中与后台服务器跨域问题
- Poj 1338 Ugly Numbers(数学推导)
- 中by的用法_经常混淆的介词at、on、in、by用法细讲,收藏学习
- 你需要知道的css布局
- linux centos网卡配置,centos网卡配置详解
- 工资微软微软员工你了解么??
- 进程同步与互斥:POSIX有名信号量
- 来吧,用设计模式来干掉 if-else 啊~
- 分析sql字段_全面解析一条SQL语句执行得很慢的原因有哪些
- 韩立刚老师 -- 1、Linux 入门
- ShadowGun Billboard Blinking God Rays
- 西门子博图指令——Array数据中元素的写入
- 如何在本地搭建网站(图文教程)
热门文章
- endnotex7怎么导入中文文献,EndNote 7.0使用中文详细教程
- SendMessage 函数
- Redis 6.0 源码阅读笔记(3) -- 概述 Redis 重要数据结构及其 6 种数据类型
- Localdatetime的坑
- 面试题--------5、==与equals的区别
- 2.2同步访临界区(Synchronizing Access to Critical Section)
- jQuery操作元素内容的相关方法
- [渝粤教育] 平顶山学院 区域分析与规划 参考 资料
- [渝粤教育] 西南科技大学 计算机网络应用基础 在线考试复习资料2021版(2)
- 05 库的简单操作