http://wmfs.info/projects/wmfs
原来就一平铺式窗口管理器的项目, 小失望, 不过看它官网上吹的云里雾里, 我还是看了看screenshot并试了下.
感觉最舒服的就是它类似于dwm的那种status-bar, dwm最舒畅的就是不需要window list, 而且可以把高度自定义的系统状态信息放在status-bar上, wmfs比dwm好的地方在于status-bar是彩色的, 醒目且漂亮, 还可以去掉focused窗口的title, 节约了大量空间给系统状态信息.
wmfs的平铺方案有好多种, 常见的几种都有了, 虽然我一般只用"tile_right"和"free"两种, 但有的选还是不错的
ewmh, xft, imlib2这些就不说了, 这年代, 没这些都不敢出来混, 连dwm都开始通过patch支持
配置文件是普通的文本格式, 语法一目了然, 可以快速重载入, 相当快捷, 也可以像dwm一样改源码(config.c).
提供很多函数, 对tag和client的操作功能很强, 这点上dwm和musca望尘莫及
曾在musca下折腾了半天matlab, 相当蛋疼, 好在wmfs支持不错, 连matlab这厮都能起来, 还怕其他的java程序吗?
dwm下很多程序(特别是kdelibs的), 无法正常自动平铺, wmfs正常
代码不多wc的结果:11843, dwm是2000+, 可见功能上还是增加了很多
我用gcc编译(默认CFLAGS), 大概120多K, icc(CFLAGS="-O3 -fast"), 324K, 果然比较lightweight, 大约只是dwm的3倍, 运行时内存占用差不多
缺点:
和dwm一样, 对弹出窗口支持不佳
它是动态平铺, 我个人更喜欢musca这样的手动平铺
总的来说,我将他作为dwm的替代, musca虽然是手动平铺, 但小问题不断
wmfs比较像dwm, 并能够搞定dwm的多处不足, 所以接下来一段时间我就转战wmfs了
附上我的截图: 附上wmfsrc:
代码: 全选
[misc]
font = "DejaVu Sans YuanTi-8"
raisefocus = false
focus_follow_mouse = true
opacity = 255
focus_pointer_click = true
status_path = "/home/stesen/tools/scripts/sysres-wmfs.pl"
status_timing = 5 #seconds
[/misc]
[bar]
bg = "#181818"
fg = "#D4D4D4"
border = false
height = 16
[systray]
active = true
spacing = 2
screen = 0
[/systray]
[mouse] button = "3" func = "menu" cmd = "rootmenu" [/mouse]
[mouse] button = "4" func = "tag_next" [/mouse]
[mouse] button = "5" func = "tag_prev" [/mouse]
[/bar]
[layouts]
bg = "#181818"
fg = "#666666"
border = false
system = "menu"
placement = "right"
keep_layout_geo = "true"
selected_layout_symbol = "*"
layout_button_width = 50
[layout] type = "tile_right" symbol = "Right" [/layout]
[layout] type = "tile_grid" symbol = "Grid" [/layout]
[layout] type = "tile_top" symbol = "Top" [/layout]
[layout] type = "tile_bottom" symbol = "Bottom" [/layout]
[layout] type = "max" symbol = "Max" [/layout]
[layout] type = "free" symbol = "Free" [/layout]
[/layouts]
[tags]
tag_round = true
occupied_bg = "#666666"
sel_fg = "#C0C0C0"
sel_bg = "#F0F0F0"
urgent_bg = "#FFCC00"
urgent_fg = "#333333"
name_count = false
border = false
autohide = false
mouse_button_tag_sel = "1"
mouse_button_tag_transfert = "2"
mouse_button_tag_add = "3"
mouse_button_tag_next = "4"
mouse_button_tag_prev = "5"
[tag]
name = "乾"
screen = 0
mwfact = 0.55
nmaster = 1
resizehint = false
infobar_position = "top"
[/tag]
[tag]
name = "坤"
screen = 0
mwfact = 0.55
nmaster = 1
resizehint = false
infobar_position = "top"
[/tag]
[tag]
name = "震"
screen = 0
mwfact = 0.55
nmaster = 1
resizehint = false
infobar_position = "top"
[/tag]
[tag]
name = "巽"
screen = 0
mwfact = 0.55
nmaster = 1
resizehint = false
infobar_position = "top"
[/tag]
[tag]
name = "艮"
screen = 0
mwfact = 0.55
nmaster = 1
resizehint = false
infobar_position = "top"
[/tag]
[tag]
name = "兑"
screen = 0
mwfact = 0.55
nmaster = 1
resizehint = false
infobar_position = "top"
[/tag]
[tag]
name = "坎"
screen = 0
mwfact = 0.55
nmaster = 1
resizehint = false
infobar_position = "top"
[/tag]
[tag]
name = "离"
screen = 0
mwfact = 0.55
nmaster = 1
resizehint = false
infobar_position = "top"
[/tag]
[/tags]
[root]
background_command = "$HOME/.config/wmfs/autostart.sh &"
[mouse] button = "5" func = "tag_next" [/mouse]
[mouse] button = "4" func = "tag_prev" [/mouse]
[mouse] button = "3" func = "menu" cmd = "rootmenu" [/mouse]
[/root]
[client]
client_round = true
border_height = 0
border_shadow = false
border_normal = "#181818"
border_focus = "#181818"
resize_corner_normal = "#181818"
resize_corner_focus = "#181818"
padding = 4
modifier = "Super"
autofree = "Vlc,feh,xarchive,xcalc,mplayer,smplayer,gimp"
[mouse] button = "1" func = "client_raise" [/mouse]
[mouse] button = "1" func = "mouse_move" [/mouse]
[mouse] button = "3" func = "client_raise" [/mouse]
[mouse] button = "3" func = "mouse_resize" [/mouse]
# Remove this section to delete the titlebar.
[titlebar]
stipple = false
height = 12
fg_normal = "#dddddd"
fg_focus = "#bbbbbb"
[mouse] button = "1" func = "client_raise" [/mouse]
[mouse] button = "1" func = "mouse_move" [/mouse]
[mouse] button = "3" func = "client_raise" [/mouse]
[mouse] button = "3" func = "mouse_resize" [/mouse]
[button]
# Available "free", "max", "tile" flags of button.
flags = "free,max,tile"
[mouse] button = "1" func = "client_kill" [/mouse]
[mouse] button = "3" func = "menu" cmd = "clientmenu"[/mouse]
[line] coord = {1, 1, 4, 1} [/line]
[line] coord = {1, 1, 1, 4} [/line]
[line] coord = {1, 4, 4, 4} [/line]
[/button]
[/titlebar]
[/client]
[menu]
# Default menu, binded on the root window, button 3.
[set_menu]
name = "rootmenu"
# place_at_mouse = false
# x = 40 y = 50
# Available "center", "left", "right" menu align. Default: "center".
align = "left"
fg_focus = "#ffffff" bg_focus = "#68696b"
fg_normal = "#606060" bg_normal = "#ecedee"
[item] name = "Terminal" func = "spawn" cmd = "urxvtcd.sh" [/item]
[item] name = "Thunar" func = "spawn" cmd = "thunar" [/item]
[item] name = "Browser" func = "spawn" cmd = "firefox" [/item]
[item] name = "Apps" submenu = "appmenu" [/item]
[item] name = "Tools" submenu = "toolmenu" [/item]
[item] name = "Style" submenu = "stylemenu" [/item]
[item] name = "Wmfs" submenu = "wmfsmenu" [/item]
[item] name = "Exit" func = "spawn" cmd = "/home/stesen/.config/wmfs/myexit" [/item]
[/set_menu]
[set_menu]
name = "appmenu"
align = "left"
fg_focus = "#ffffff" bg_focus = "#68696b"
fg_normal = "#606060" bg_normal = "#ecedee"
#[item] name = "Alsamixer" func = "spawn" cmd = "urxvtc -alsamixer" [/item]
[item] name = "Chromium" func = "spawn" cmd = "chromium" [/item]
[/set_menu]
[set_menu]
name = "toolmenu"
align = "left"
fg_focus = "#ffffff" bg_focus = "#68696b"
fg_normal = "#606060" bg_normal = "#ecedee"
[item] name = "Emacs" func = "spawn" cmd = "emacs" [/item]
[item] name = "Gvim" func = "spawn" cmd = "gvim" [/item]
[/set_menu]
[set_menu]
name = "stylemenu"
align = "left"
fg_focus = "#ffffff" bg_focus = "#68696b"
fg_normal = "#606060" bg_normal = "#ecedee"
[item] name = "Lxapp" func = "spawn" cmd = "lxappearance" [/item]
[/set_menu]
[set_menu]
name = "wmfsmenu"
align = "left"
fg_focus = "#ffffff" bg_focus = "#68696b"
fg_normal = "#606060" bg_normal = "#ecedee"
[item] name = "Reload wmfs" func = "reload" [/item]
[item] name = "Next tag" func = "tag_next" [/item]
[item] name = "Previous tag" func = "tag_prev" [/item]
[item] name = "Next layout" func = "layout_next" [/item]
[item] name = "Previous layout" func = "layout_prev" [/item]
[item] name = "Toggle infobar" func = "toggle_infobar_position" [/item]
[item] name = "Quit WMFS" func = "quit" [/item]
[/set_menu]
[set_menu]
name = "exitmenu"
align = "left"
fg_focus = "#ffffff" bg_focus = "#68696b"
fg_normal = "#606060" bg_normal = "#ecedee"
# [item] name = "EXIT" func = "spawn" cmd = "sudo reboot" [/item]
# [item] name = "Shutdown" func = "spawn" cmd = "sudo halt" [/item]
[/set_menu]
# [set_menu]
# name = "clientmenu"
#
# fg_focus = "#ffffff" bg_focus = "#68696b"
# fg_normal = "#606060" bg_normal = "#ecedee"
# Check items: possible 'check_max' or 'check_free'.
# [item] name = "Close" func = "client_kill" [/item]
# [item] name = "Maximize" func = "toggle_max" check = "check_max" [/item]
# [item] name = "Free" func = "toggle_free" check = "check_free" [/item]
# [/set_menu]
[/menu]
[launcher]
[set_launcher]
name = "launcher_exec"
prompt = "Exec: "
command = "exec"
[/set_launcher]
#ViWMFS : manage wmfs with vi-based command.
[set_launcher]
name = "viwmfs"
prompt = "> "
command = "wmfs -V"
[/set_launcher]
[/launcher]
[keys]
[key] mod = {"Super","Tab"} func = "client_next" [/key]
[key] mod = {"Super","Shift","Tab"} func = "client_prev" [/key]
[key] mod = {"Super"} key = "Right" func = "tag_next" [/key]
[key] mod = {"Super"} key = "Left" func = "tag_prev" [/key]
[key] mod = {"Super"} key = "Down" func = "tag_prev_sel" [/key]
[key] mod = {"Control"} key = "Right" func = "client_swap_next" [/key]
[key] mod = {"Control"} key = "Left" func = "client_swap_prev" [/key]
[key] mod = {"Control","Super"} key = "Right" func = "set_mwfact" cmd = "+0.025" [/key]
[key] mod = {"Control","Super"} key = "Left" func = "set_mwfact" cmd = "-0.025" [/key]
[key] mod = {"Control","Alt"} key = "Right" func = "set_nmaster" cmd = "+1" [/key]
[key] mod = {"Control","Alt"} key = "Left" func = "set_nmaster" cmd = "-1" [/key]
[key] mod = {"Super"} key = "u" func = "tag_urgent" [/key]
[key] mod = {"Alt"} key = "F4" func = "client_kill" [/key]
[key] mod = {"Control","Alt"} key = "r" func = "reload" [/key]
[key] mod = {"Alt"} key = "m" func = "toggle_max" [/key]
[key] mod = {"Alt"} key = "f" func = "toggle_free" [/key]
[key] mod = {"Alt"} key = "b" func = "toggle_infobar_position" [/key]
[key] mod = {"Alt"} key = "r" func = "toggle_resizehint" [/key]
[key] mod = {"Alt"} key = "space" func = "layout_next" [/key]
[key] mod = {"Super","Alt"} key = "space" func = "layout_prev" [/key]
[key] mod = {"Super"} key = "Return" func = "spawn" cmd = "urxvtcd.sh" [/key]
[key] mod = {"Super"} key = "e" func = "spawn" cmd = "emacs" [/key]
[key] mod = {"Super"} key = "q" func = "spawn" cmd = "/home/stesen/.config/wmfs/myexit" [/key]
[key] mod = {"Super"} key = "f" func = "spawn" cmd = "thunar" [/key]
[key] mod = {"Super"} key = "i" func = "spawn" cmd = "firefox" [/key]
[key] mod = {"Control","Super"} key = "i" func = "spawn" cmd = "chromium-browser" [/key]
[key] mod = {"Super"} key = "x" func = "spawn" cmd = "dmenu_run -hist /home/stesen/.dmenu_hist -fn 'WenQuanYi Micro Hei 7' -nb '#2e3436' -nf '#f0f0f0' -sb '#2e3436' -sf '#729fcf'" [/key]
[key] mod = {"Alt"} key = "u" func = "launcher" cmd = "viwmfs" [/key]
[key] mod = {"Alt"} key = "F2" func = "launcher" cmd = "launcher_exec" [/key]
# Set the tag x.
[key] mod = {"Super"} key = "1" func = "tag" cmd = "1" [/key]
[key] mod = {"Super"} key = "2" func = "tag" cmd = "2" [/key]
[key] mod = {"Super"} key = "3" func = "tag" cmd = "3" [/key]
[key] mod = {"Super"} key = "4" func = "tag" cmd = "4" [/key]
[key] mod = {"Super"} key = "5" func = "tag" cmd = "5" [/key]
[key] mod = {"Super"} key = "6" func = "tag" cmd = "6" [/key]
[key] mod = {"Super"} key = "7" func = "tag" cmd = "7" [/key]
[key] mod = {"Super"} key = "8" func = "tag" cmd = "8" [/key]
# Transfert selected client to x.
[key] mod = {"Alt"} key = "1" func = "tag_transfert" cmd ="1" [/key]
[key] mod = {"Alt"} key = "2" func = "tag_transfert" cmd ="2" [/key]
[key] mod = {"Alt"} key = "3" func = "tag_transfert" cmd ="3" [/key]
[key] mod = {"Alt"} key = "4" func = "tag_transfert" cmd ="4" [/key]
[key] mod = {"Alt"} key = "5" func = "tag_transfert" cmd ="5" [/key]
[key] mod = {"Alt"} key = "6" func = "tag_transfert" cmd ="6" [/key]
[key] mod = {"Alt"} key = "7" func = "tag_transfert" cmd ="7" [/key]
[key] mod = {"Alt"} key = "8" func = "tag_transfert" cmd ="8" [/key]
# Toggle additional tags (x) on the current tag
[key] mod = {"Alt","Super"} key = "1" func = "tag_toggle_additional" cmd ="1" [/key]
[key] mod = {"Alt","Super"} key = "2" func = "tag_toggle_additional" cmd ="2" [/key]
[key] mod = {"Alt","Super"} key = "3" func = "tag_toggle_additional" cmd ="3" [/key]
[key] mod = {"Alt","Super"} key = "4" func = "tag_toggle_additional" cmd ="4" [/key]
[key] mod = {"Alt","Super"} key = "5" func = "tag_toggle_additional" cmd ="5" [/key]
[key] mod = {"Alt","Super"} key = "6" func = "tag_toggle_additional" cmd ="6" [/key]
[key] mod = {"Alt","Super"} key = "7" func = "tag_toggle_additional" cmd ="7" [/key]
[key] mod = {"Alt","Super"} key = "8" func = "tag_toggle_additional" cmd ="8" [/key]
# Toggle the tag_autohide mode
#[key] mod = {"Shift", "Control"} key = "t" func = "toggle_tagautohide" [/key]
# Select the next visible tag.
#[key] mod = {"Control","Alt"} key = "Right" func = "tag_next_visible" [/key]
# Select the previous visible tag.
#[key] mod = {"Control","Alt"} key = "Left" func = "tag_prev_visible" [/key]
[/keys]
代码: 全选
#!/usr/bin/perl
my $batt = &battery;
my $statline;
$red="\\#BF4D80\\";
$yel="\\#C4A1E6\\";
$blu="\\#477AB3\\";
$grn="\\#53A6A6\\";
$cyn="\\#6096BF\\";
$mag="\\#7E62B3\\";
$gry="\\#666666\\";
$wht="\\#C0C0C0\\";
if ($batt eq "100%") {
$statline = sprintf("${grn}音乐.${mag}%s | ${grn}处理器.${wht}%2d%% %s| ${grn}内存.${wht}%4dM | ${grn}温度.${wht}%3d°C | ${grn}网络.${wht}%s | ${grn}音量.${wht}%3d%% | ${yel}%s", &musicinfo, &cpu_calc, &load_avg, &mem_calc, &temp_read, &net_calc, &volume, &timeinfo);
} else {
$statline = sprintf("${grn}音乐.${mag}%s | ${grn}处理器.%2d%% %s| ${grn}内存.%4dM | ${grn}温度.%3d°C | ${grn}网络. %s | ${grn}电池. %s | ${grn}音量.%3d%% | ${yel}%s", &musicinfo, &cpu_calc, &load_avg, &mem_calc, &temp_read, &net_calc, $batt, &volume, &timeinfo);
}
`wmfs -s "$statline"`;
1;
sub cpu_read {
my $cpu_file = '/proc/stat';
my ($cpu_name, $cpu_usr, $cpu_nice, $cpu_system, $cpu_idle, $cpu_lines);
my @ret;
open F, "$cpu_file" or die "Can't open $cpu_file for read.\n";
$cpu_lines = <F>;
chomp ($cpu_lines);
($cpu_name, $cpu_usr, $cpu_nice, $cpu_system, $cpu_idle) = split / +/, $cpu_lines;
($cpu_usr + $cpu_system), ($cpu_usr + $cpu_nice + $cpu_system + $cpu_idle);
}
sub cpu_calc {
my @cpu_info1 = &cpu_read;
sleep 1;
my @cpu_info2 = &cpu_read;
my $cpu_useage = (($cpu_info2[0] - $cpu_info1[0]) * 100 / ($cpu_info2[1] - $cpu_info1[1]));
}
sub load_avg {
my $ldavg = `uptime`;
$ldavg =~ s/.+average://;
chomp($ldavg);
$ldavg;
}
sub mem_calc {
my $mem_file = '/proc/meminfo';
my ($mem_total, $mem_free, $mem_buf, $mem_cache);
open F, "$mem_file" or die "Can't open $mem_file for read.\n";
$mem_total = <F>;
chomp($mem_total);
$mem_total =~ s/MemTotal: +(\d+).*/$1/;
$mem_free = <F>;
chomp($mem_free);
$mem_free =~ s/MemFree: +(\d+).*/$1/;
$mem_buf = <F>;
chomp($mem_buf);
$mem_buf =~ s/Buffers: +(\d+).*/$1/;
$mem_cache = <F>;
chomp($mem_cache);
$mem_cache =~ s/Cached: +(\d+).*/$1/;
($mem_total - $mem_free - $mem_buf - $mem_cache) / 1024
}
sub net_calc {
my @a = `ifstat -i eth0,wlan0 -q 1 1`;
#my @a = `ifstat -q 1 1`;
$a[0] =~ m/(\w+) *(\w+)/;
my $ifname1 = $1;
my $ifname2 = $2;
return unless($ifname1);
if($ifname2) {
chomp($a[2]);
$a[2] =~ s/^ +(\d+)\.\d+ +(\d+).\d+ +(\d+).\d+ +(\d+).\d+/$1\/$2kb $3\/$4kb/;
} else {
chomp($a[2]);
chomp($a[0]);
$a[0] =~ s/ //g;
$a[2] =~ s/^ +(\d+)\.\d+ +(\d+).\d+/$a[0]: $1\/$2kb/;
}
#if ($a[0] =~ /wlan0/) {
# $a[2] .= " " . &wireless_read;
#}
$a[2];
}
sub temp_read {
my $temp_file = '/proc/acpi/thermal_zone/TZS0/temperature';
open F, "$temp_file" or die "Can't open $temp_file for read.\n";
my $temp = <F>;
chomp($temp);
$temp =~ s/.* (\d+) C/$1/;
$temp;
}
sub battery {
my @bat = split / +/, `acpi -b`;
$bat[3] .= $bat[4] if ($bat[4]);
chomp($bat[3]);
$bat[3];
}
sub volume {
my @vol = `amixer get Master`;
$vol[5] =~ s/.*\[(\d+)\%\].*/$1/;
chomp($vol[5]);
$vol[5];
}
sub timeinfo {
my ($sec,$min,$hour,$day,$mon,$year,$weekday,$yeardate,$savinglightday, $ret, @cn_weekday);
($sec,$min,$hour,$day,$mon,$year,$weekday,$yeardate,$savinglightday) = (localtime(time));
$sec = ($sec < 10) ? "0$sec" : $sec;
$min = ($min < 10) ? "0$min" : $min;
$hour = ($hour < 10) ? "0$hour" : $hour;
$day = ($day < 10) ? "0$day" : $day;
$mon = ($mon < 9) ? "0".($mon+1) : ($mon+1);
$year += 1900;
@cn_weekday = qw(周日 周一 周二 周三 周四 周五 周六);
$ret = "$cn_weekday[$weekday] $year-$mon-$day $hour:$min ";
$ret;
}
sub musicinfo {
my $name = `mocp -i|head -2|tail -1`;
chomp($name);
$name =~ s/\b.*\///g;
$name =~ s/(\.mp3)|(\.wma)|(\.ogg)|(\.flac)//g;
$name =~ s/\b(.{0,25}).*\b/$1/;
$name;
}