折腾Linux桌面中让人迷惑的形容词

用桌面的很多人都对自己的桌面有评价,但很多用词对我来说总是难以把握具体含义。

所以对使用以下描述的词评论都无视。描述个人感受不做到精确(concrete),那和对牛弹琴没什么两样。

1、字体清晰/锐利

这也就是我不和别人讨论字体设置的原因。因为清晰/锐利是个模糊的概念。

想要做到精确,上来第一句话应该先回答,是使用位图字体,还是矢量字体?对有些人来说,清晰/锐利等于位图,对有些人来说,清晰/锐利是使用在矢量字体的前提下的,所以经常会看到一群人互相对牛弹琴。

2、降低效率/专注

这是个主观概念,而且几乎总是预设别人了解你到底平时在干什么。

如果一个人没事就是只对着一个浏览器上网的话,这个概念也许对他完全就没意义。

我直到现在都没明白有些人执着的高效是什么意思。

3、花俏

这又是个模糊的概念,问题在于形容的对象是什么?有些人似乎形容的是动画效果,有些人形容的是样式。那么对应的反义词前者应该是不平滑、或者静态,后者应该是朴素。

4、轻快/轻量

首先很多人把“功能多”和“重量”联系在一起,这显然不是一个正确的联系。功能多寡取决于你的需要。

其次就是不了解内部实现就评价轻量或者重量。

当然由于主观因素过多,最没有价值的评论还是人云亦云,而且还无法区分;以及因果倒错,很多人应该打回去学逻辑。

欢迎补充。

Posted in Linux | 15 Comments

Fcitx Keyboard

Video demonstration:

Fcitx will support spell checker based word hint, and automatically keyboard layout switch.

1. You can use keyboard layout as a single input method, and use corresponding language spell checker.

2. Input method can gives a hint about what keyboard layout it requires, for instance, pinyin will request us layout and fcitx-keyboard can then switch to us layout once pinyin is used.

You can take a look at the code at: https://github.com/fcitx/fcitx-keyboard

Posted in fcitx development | Tagged | 2 Comments

Memory pool

自从fcitx的内核从古老的gbk转向了utf8之后,自带拼音和码表的字符串就带来了一些问题。

首先情况是这样的在我的系统上,fcitx的自带拼音加载后将占用28MB的内存,考虑下的话,其中有个 (2int+2pointer)*词数的数据结构,其次是词本身,有约4MB,词总数约20万。那么估计一下的话拼音应该占用约8.5M。考虑刚刚启动不加载的时候,占用约6M,总计应该在14M左右。那多出来的14M都干啥去了呢?(并无内存泄露)

之前也一直没有关注这件事情,不过在前几天在 @henryhu 的建议下增加了一个Memory pool的实现。这个实现非常naive,乃至于不能单独释放申请的内存(只能整体释放)。不过对于fcitx自身拼音和码表的实现这个情况来说,是一个非常合适的选择。

首先有兴趣的人可以来做一个实验,写一个for循环,每次使用malloc申请1字节,循环申请1M次。然后看看操作系统的内存使用量。然后修改下,每次申请16字节,循环申请64k次,总量也是1MB,然后再看看操作系统内存使用量。

具体实现如下,内存不足时默认每次申请8k字节的内存块,如果一次申请超过8k就申请8k的2的n次方那么大的内存。每个块使用一个offset标记里面当前free的位置,当offset和容量的差距小于某个threshold的时候,就将其从可申请的list中移除,保证在遍历候选内存块的列表时的效率,那些不使用的部分成为可以忽略的内存碎片。(实际设定threshold = 16,16相比 8k 可忽略不计)

对于码表和拼音来说,其中的数据是几乎不用单独释放的,这正好可以采用这种naive的实现(而不是使用比较复杂的full functional的memory pool)。

那么最终的效果就是在我的系统上fcitx自带拼音加载后使用内存达到14MB,符合最开始的预期使用。

Ref:

http://code.google.com/p/fcitx/issues/detail?id=133

http://en.wikipedia.org/wiki/Memory_pool

Posted in fcitx development | 8 Comments

My CMake Tutorial 3

我的风格其实极其诡异,因为我只想讲我乐意讲的,但保证实用性,除了第一次的类hello world,全部脚本都在实际项目中使用(当然很多是fcitx的 😛 )。学习曲线什么的,谁管啊。

如果你想找前面的内容,请猛击 https://www.csslayer.info/wordpress/category/cmake/

顺带一提,本人近期一直占据oholh cmake 语言提交 http://www.ohloh.net/languages/74 排行中的一名。(有段生猛的时间也挤进过C语言的排名……不过现在出来了 :P)

本次大容量,包括三个内容,创建自己的可以被find_package使用的CMake脚本,复杂自定义文件生成,Gettext整合。

Continue reading

Posted in cmake | Tagged | 3 Comments

My CMake Tutorial 2

其实我的感觉是大家都被我第一篇给蒙骗了……从第二篇开始我就要开始走非主流路线。

如何 make uninstall

cmake是没有make uninstall支持的。

你可能觉得很无语。不过还是有方法的,这个方法也被应用于fcitx的每个项目当中。另外如果你使用KDE的话 – find_package(KDE4) – 那么KDE也会自动提供uninstall,不用你麻烦了。

那么现在来看看这是怎么实现的。

在make install的时候,cmake会生成一个文件 install_manifest.txt ,里面是要安装的文件。而uninstall的基本思想就是读他,然后把里面列出的文件删掉。

一般而言我会这么做,新建一个文件夹叫cmake,然后在里面放上以下内容的文件,命名为cmake_uninstall.cmake.in。

if (NOT EXISTS "@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt")
    message(FATAL_ERROR "Cannot find install manifest: \"@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt\"")
endif(NOT EXISTS "@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt")

file(READ "@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt" files)
string(REGEX REPLACE "\n" ";" files "${files}")
foreach (file ${files})
    message(STATUS "Uninstalling \"$ENV{DESTDIR}${file}\"")
    if (EXISTS "$ENV{DESTDIR}${file}" OR IS_SYMLINK "$ENV{DESTDIR}${file}")
        execute_process(
            COMMAND @CMAKE_COMMAND@ -E remove "$ENV{DESTDIR}${file}"
            OUTPUT_VARIABLE rm_out
            RESULT_VARIABLE rm_retval
        )
        if(NOT ${rm_retval} EQUAL 0)
            message(FATAL_ERROR "Problem when removing \"$ENV{DESTDIR}${file}\"")
        endif (NOT ${rm_retval} EQUAL 0)
    else (EXISTS "$ENV{DESTDIR}${file}" OR IS_SYMLINK "$ENV{DESTDIR}${file}")
        message(STATUS "File \"$ENV{DESTDIR}${file}\" does not exist.")
    endif (EXISTS "$ENV{DESTDIR}${file}" OR IS_SYMLINK "$ENV{DESTDIR}${file}")
endforeach(file)

然后在你的源代码根目录的CMakeLists.txt 里面写上

# uninstall target
configure_file(
    "${CMAKE_CURRENT_SOURCE_DIR}/cmake/cmake_uninstall.cmake.in"
    "${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake"
    IMMEDIATE @ONLY)

add_custom_target(uninstall
    COMMAND ${CMAKE_COMMAND} -P ${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake)

就大功告成了。

顺带一提,这里列出的版本比cmake wiki上的好用,大家可以自行对比(http://www.cmake.org/Wiki/CMake_FAQ#Can_I_do_.22make_uninstall.22_with_CMake.3F

那么原理是什么?就从主文件的CMakeLists.txt 开始吧。首先是 configure_file 命令。熟悉autotools的同学知道,经常有些内容是配置完才能决定的,configure_file就是这样的命令,甚至语法和autotools都一样(采用@扩起需要替换的部分)。

第一个,第二个参数分别是输入和输出文件,考虑和cmake向下兼容性的问题,请使用绝对路径,否则2.6之前的版本是构建根目录,2.8则是相对当前CMakeLists.txt的目录。@ONLY 表示只对使用 @ 括起的变量进行替换。

add_custom_target 则是建立一个自己的target,并且对应的命令为COMMAND后面指定的命令。target的概念熟悉Makefile的人都知道了。

Posted in cmake | Tagged | 3 Comments