如何给 Qt 贡献 Patch

最近给 Qt 5 写了几个傻瓜都能写的 Patch ……目的是修复一些输入法相关的 Bug。当然这不是重点,重点是怎么给 Qt 写 Patch 并提交。

首先 Qt 自从转向开放管理之后,给 Qt 写 Patch 就成为了一件非常简单的事情。

首先不用说,你需要注册个账号,先到这个网站注册个账号,bugreports.qt-project.org,然后打开codereview.qt-project.org ,选择 sign in,sign in之后需要做的就是和一般的代码管理网站一样,添加你的ssh key,然后还需要做的是签署一个协议,在Agreements里面,作为一般人签个 Invidudual的就好,另一种是如果你代表公司向 Qt 贡献,那么则是签那个,然后大概就是需要等这个审核通过,效率还是非常高的,喝口茶大概最多几个小时之后就ok了,然后你就可以通过 gerrit (qt的code review 系统提交 patch 了)。

gerrit 这个东西是个非常神奇的东西,非常好用,如果你熟悉 git 的开发的话就更好了。

其实 Qt 上已经有了非常详细的说明,我这里只简单介绍一下。

首先要配置你的ssh_config ,code review的ssh并非是传统的22端口,而是一个自定义端口,在你的~/.ssh/config 中加入:

 Host codereview.qt-project.org
   Port 29418

首先在你 clone 下来代码之后(from gitorous或者code review都行),

$ git clone ssh://<username>@codereview.qt-project.org/qt/qtbase.git
Cloning into qtbase...
remote: Counting objects: 33523, done
remote: Finding sources: 100% (33523/33523)
Receiving objects: 100% (33523/33523), 69.45 MiB | 901 KiB/s, done.
remote: Total 33523 (delta 16501), reused 33523 (delta 16501)
Resolving deltas: 100% (16501/16501), done.
$

首先需要配置的是 commit msg和commit hook,它能自动生成一个changeid,也就是将来标示你这个修改的id。

$ scp -P 29418 <username>@codereview.qt-project.org:hooks/commit-msg .git/hooks

另外就是需要 clone 一个 qtrepotools,并且把 git-hooks/git_post_commit_hook 链接到你的 .git/hooks/post-commit

并且要保持这两个文件可执行哦。

之后你就可以做你的修改了,做了commit之后你可以git log看看,是不是有 Change-Id: I3db87fdffdb5b01404047e905793ae6e10bb1e90 这样的字样,如果没有的话可是不行的哦,那样你需要检查下你的commit-msg是不是有问题?

如果顺利的话,那么你可以提交你的 review了

$ git push ssh://<username>@codereview.qt-project.org:29418/qt/qtbase HEAD:refs/for/master
Counting objects: 6, done.
Delta compression using up to 2 threads.
Compressing objects: 100% (3/3), done.
Writing objects: 100% (4/4), 407 bytes, done.
Total 4 (delta 2), reused 0 (delta 0)
remote: Resolving deltas:   0% (0/2)
To ssh://<username>@codereview.qt-project.org:29418/qt/qtbase
 * [new branch]      HEAD -> refs/for/master
$

然后会生成一个链接给你,可以用来在网站上track状态。

然后需要做的一件事就是找reviewer,那么找谁呢?有以下两种办法…一个是看看你这个文件的修改历史,都有谁review过,reviewer的名字会用 Reviewed-by: 标明,嘛……命中多的大概就相关吧……

还有就是你可以到 #qt-labs @ freenode.net 这个irc频道去询问一下,也会得到回复的。

然后就是等着review了。

运气好的话,可能接下来就你啥事了,当然像我这种二逼青年……头一次就犯了各种傻到家的错误……那你可能需要修改你的代码,这要怎么做呢?

其实非常简单(下面是我自己使用的办法,不知道是否完全正确,不过至少work),首先到网页上找到 git fetch https://codereview.qt-project.org/p/qt/qtbase refs/changes/xx/xxxxx/x && git checkout FETCH_HEAD ,像这样就能找回你的提交,然后做出对应的修改,你可能需要rebase到master或者做一些相关的操作。(我个人建议是不要merge,那样会生成额外的不必要的提交……)

这种时候 git commit –amend 就派上用场,你可以修改你的提交,然后修改完成后再用最开始和提交code review一样的命令,就可以了。注意的是Change-Id 当然是不能改的,否则系统就会认为这是一个新的review。

那么就是这样,Qt的网站上也有很多相关的内容,甚至有视频演示,链接都列在下面可以查看。

http://qt-project.org/wiki/Category:Developing_Qt

http://qt-project.org/wiki/Code_Reviews

http://developer.qt.nokia.com/videos/watch/gerrit_contributing_and_reviewing_a_change

Posted in Qt | Tagged | 4 Comments

Kimpanel for Gnome Shell Update

地址在此
https://extensions.gnome.org/extension/261/kimpanel/

不过更新应该还在审核中,可以自己去:

https://github.com/csslayer/kimpanel-for-gnome-shell/  抓代码,执行 ./install.sh 即可安装。

 

那么有什么更新呢?其实也都是一些基本功能的更新。那么有视频有真相。

https://github.com/csslayer/kimpanel-for-gnome-shell/

Posted in fcitx development | Leave a comment

Accidental Key Theme Support

一个意外收获。当初虽然没有这么想过,不过意外的有了实现个功能的办法。苦恼Fcitx没法使用Emacs按键绑定的可以试试。

由于最初一些实现本来就不是设计来做这个功能的,因此只有部分输入法支持这个功能,支持的输入法大概包括码表,自带拼音,Libpinyin,Chewing,Google Pinyin。Sunpinyin不支持。

代码的地址在这里,使用时自担风险。安装方法和一般编译安装 Fcitx 的模块方法一样。

https://github.com/yuyichao/fcitx-keytheme

使用上就是可以用于覆盖Fcitx的一些标准按键,需要自行配置。

感谢 @yuyichao

Posted in fcitx development | 3 Comments

My Gtk Tutorial 4

其实说到这里,我才发现,你可能压根还不知道如何开始一个项目。

当然最简单的办法之一,就是让半残的anjuta替你建立一个gtk项目的skeleton,然后把他扔一边,继续用你的vim,emacs去。

不过在这么多年之后,其实我已经不会写autotools的代码了,那么下面我就无聊来介绍下怎么用CMake和Gtk。

关于我曾经的CMake介绍,可以参考这里。

https://www.csslayer.info/wordpress/category/cmake/

有些人喜欢录视频写代码?这次录个视频好了。

代码下载:

gtk_test.tar.gz

P. S.

也许这篇文章会勾引出一些严重的autotools粉,例如啊glib/gtk的项目都是用autotools啊,glib/gtk项目用autotools集成好啊。我用了这么多年现在早忘了autotools 怎么写了,我写不出来,就这样。

构建脚本用什么写都没本质差别。照样有人用cmake生成GObjectIntrospection(附注:第一个这么干的当然不是我)。

Posted in Gtk | 8 Comments

My Gtk Tutorial 3

所谓的具体类的实现,其实这个Widget功能不得不说是Gtk里面缺少的功能,虽然其实Qt里面也没,不过我在写代码的时候可以没什么顾虑的用 KDE 提供的 UI 库,于是我又爽了。

这次的Widget就是一个捕获快捷键用的Widget,具体里面代码的实现我是当初从ccsm(compiz那个配置工具)里面的python代码翻译过来的,啊一想起那个青涩的年代……

相信这是个人民群众喜闻乐见的Widget。

原理很简单,本身是一个button,button按下时显示一个window,window负责捕捉按键,捕捉到的按键再存起来。

当然我的实现里面使用了一些Fcitx自己的parse和toString的函数,你当然建议使用GtkAccelerator的方式 来进行parse(如果你需要字符串的话)。

https://github.com/fcitx/fcitx-configtool/blob/master/gtk3/keygrab.h

https://github.com/fcitx/fcitx-configtool/blob/master/gtk3/keygrab.c

具体的实现就是上面的代码(于是我还看到当初有些蛋疼的注释……)

首先就是我继承了一个GtkButton,定义了一个Signal,触发按键在变化时的事件。

    gtk_widget_set_size_request(GTK_WIDGET(keygrabbutton), 150, -1);
    g_signal_connect(G_OBJECT(keygrabbutton), “clicked”, (GCallback) begin_key_grab, NULL);

按键创建时,绑了一个signal给clicked事件,用来显示一个popup。

在clicked里面的回调函数中。

    KeyGrabButton* b = KEYGRAB_BUTTON(self);
    b->popup = popup_new(GTK_WIDGET(self), _("Please press the new key combination"), FALSE);
    gtk_widget_add_events(GTK_WIDGET(b->popup), GDK_KEY_PRESS_MASK | GDK_KEY_RELEASE_MASK);
    gtk_widget_show_all(b->popup);
    gtk_window_present(GTK_WINDOW(b->popup));
    b->handler = g_signal_connect(G_OBJECT(b->popup), "key-press-event", (GCallback)on_key_press_event, b);
    GdkWindow* window = gtk_widget_get_window(GTK_WIDGET(b->popup));
    GdkDisplay* display = gdk_window_get_display (window);
    GdkDeviceManager* device_manager = gdk_display_get_device_manager (display);
    GdkDevice* pointer = gdk_device_manager_get_client_pointer (device_manager);
    GdkDevice* keyboard = gdk_device_get_associated_device (pointer);

    while (gdk_device_grab(
        keyboard,
        window,
        GDK_OWNERSHIP_WINDOW, TRUE,
        GDK_KEY_PRESS | GDK_KEY_RELEASE,
        NULL,
        GDK_CURRENT_TIME) != GDK_GRAB_SUCCESS)
        usleep(100);

进行了这样的操作,popup new中的实现其实很简单,就是弹出一个window,并且将其parent设置为顶层窗口,如果你的函数中需要使用dialog,或者设置为modal窗口的话,你会经常用到gtk_widget_get_toplevel,用于获得顶层的GtkWindow对象,参数就是任意一个已经在GtkWidget树中的Widget即可。

这里的grab事件的地方是非常tricky的,说实话也比gtk2的时候罗嗦了不少,不过大概的意思还是比较好懂,首先是要获得keyboard的GdkDevice指针,然后就是罗嗦个半天获得了,然后就是一个死循环,不断的尝试grab,事件呢则通过key-press-event传递给对应的window,里面 GDK_OWNERSHIP_WINDOW 就是指定了要grab 的事件是针对这个window的。后面的mask则是指定了要grab什么样的事件。这里就是key press和key release。

需要注意的就是,在最后还需要用  gdk_device_ungrab 来结束grab的影响。

P. S.

当然我写完也不会认为这样的文字有什么直接帮助,你觉得有什么帮助吗?我觉得没有,我写了这么久代码之后,我觉得只要给我文档,再没什么外力帮助下再写这些内容对我来说就像呼吸一样简单。一来我也不知道想要了解的人需要知道什么,因为编程本身就是一个自学成才的工作。如果你在大学学习学习过比如数据结构,算法设计等等课程,你可能也注意到了老师是从来不教给你具体编程的技巧的,如果妄图光是看着代码而不去实际尝试做点什么,你一定死得很惨。

有问题留言是欢迎的。

Posted in Gtk | 1 Comment