Openfetion for ubuntu messaging menu开发手记

标签: C/C++ gnome ubuntu | 发表时间:2011-05-03 15:24 | 作者:levin 培培
出处:http://basiccoder.com

自从ubuntu11.04发布之后Openfetion就遇到了一个比较麻烦的问题,把Openfetion飞信最小化到托盘之后就找不到了,没用过ubuntu11.04,不过据说它的unity桌面貌似没有status icon这回事,所以把Openfetion塞进Messaging Menu也成了一个很重要的任务,在这里把开发过程和大家分享。

首先要感谢@YunQiangSu提供的关于ubuntu messaging menu的资料,是在ubuntu wiki上关于Messaging Menu的介绍,链接在此:https://wiki.ubuntu.com/MessagingMenu/,这篇文章是关于Messaging Menu的一个介绍,以及它的行为和样式的一个指南,虽然没有涉及到具体的开发细则,但也不失为一个很重要的参考。很惭愧地说,在这之前我甚至不知道在ubuntu右上角看到的那个信封到底叫什么名字,后来知道它原来是一个Indicator,ubuntu的status icon区域很多软件都是用libappindicator来实现的,所以它们的行为和其它的发行版不太一致,比如Dropbox和Transimission左键点击Status Icon就可以弹出菜单,而在Slackware里面就只能用右键才能弹出菜单,这就是它们的不同,一个是Indicator,一个是普通的Gnome Status Icon,而这里面提到的右上角的那个信封便是Indiactor的一种,名字叫做Messaging Menu。好吧,我相信很多ubuntu用户会过来鄙视我的,写下这些给那些和我一样的小白扫扫盲,有误请指正。

我们可以把软件安装到Messaging Menu里面,这样即使软件没有启动也可以在Messaging Menu里面找到该软件,并可以从那里启动该软件,方法很简单。下面是pidgin的做法:

mkdir -p debian/pidgin/usr/share/indicators/messages/applications
echo /usr/share/applications/pidgin.desktop > \
		 debian/pidgin/usr/share/indicators/messages/applications/pidgin

这两句话的功能一眼就看地出来,无须解释了。

Messaging Menu相关的开发需要用到libindicate这个库,首先得确保在系统里面安装了这个库的开发版本:

sudo apt-get install libindicate-dev

首先我们需要获取默认IndicateServer对象的引用,并对其进行初始化:

IndicateServer *server = indicate_server_ref_default();
/* 这句话给软件分类,主要是保存位置不同 */
indicate_server_set_type(server, "message.openfetion");
/* 这句话比较重要,它会让已安装在Messaging Menu里面的软件项前面带一个箭头,
 * 表示该软件当前正在运行,效果图见下面 */
indicate_server_set_desktop_file(server, DESKTOP_DIR"openfetion.desktop");
indicate_server_show(server);
g_signal_connect(G_OBJECT(server), INDICATE_SERVER_SIGNAL_SERVER_DISPLAY, 
		G_CALLBACK(server_display), fxmain);

当收到好友发送过来的消息时可以在该项后面显示哪个好友发送过来的消息,以及显示未读消息的条数,效果图如下:

这时候就需要给当前的这个IndicateServer对象添加一个IndicateIndicator对象,并为该对象设置相关的属性,如name(即显示Indicator上显示的名字),count(未读消息的数目),time(消息发送的时间),icon(像如发送消息好友的头像),draw-attention(这个属性可以随便设置一个非空字符串,以使Indicator高亮提示用户有消息到达,同理设置空字符串可取消高亮)。
上面的几个属性除了time和icon之外都可以用indicate_indicator_set_property()函数来搞定,该函数设置的属性值都是字符串,time是一个时间值,需要使用indicate_indicator_set_property_time()函数来进行设置,至于icon属性的设置需要用到另外一个库libindicate-gtk,这个库仅提供了两个函数,其中一个便是indicate_indicator_set_proper_icon()用来设置icon属性,属性值是一个GdkPixbuf对象。下面看Openfetion上收到一条消息时Messaging Menu所对的动作:

/* no indicator found, create one :) */
indicator = indicate_indicator_new();
/* add it to the global indicator list */
indicators = g_slist_append(indicators, indicator);
indicate_server_add_indicator(server, indicator);
 
indicate_indicator_set_property(indicator, INDICATE_INDICATOR_MESSAGES_PROP_COUNT, "0");
indicate_indicator_set_property(indicator, "sid", sid);
/* set icon */
snprintf(portrait, sizeof(portrait) - 1, "%s/%s.jpg", fxmain->user->config->iconPath, sid);
pixbuf = gdk_pixbuf_new_from_file(portrait, NULL);
indicate_indicator_set_property_icon(indicator, INDICATE_INDICATOR_MESSAGES_PROP_ICON, pixbuf);
g_object_unref(pixbuf);
 
g_signal_connect(G_OBJECT(indicator), INDICATE_INDICATOR_SIGNAL_DISPLAY,
		G_CALLBACK(message_display), NULL);
 
indicate_indicator_show(indicator);

首先我们需要确定在Messaging Menu中是否已经有该用户对应的Indicator存在,如果有就没有必要再创建一个新的造成重复,而检测重复性这个问题费了我不小的力气,libindicate没有提供获取列表的API,但查了一下它的源码,发现它确实实现了一个获取列表的函数,它把它定义为虚函数,推荐用户从这个类继承,我对GTK的C语言面向对象的机制不太了解,不知道该怎么去继承,但既然有这个函数就可以想办法拿来调用,能获取到Indicator列表,但这个列表简直让我抓狂,一个GArray列表,里面存放的是Indicator的id,一个毫无用处的数字,通过它根本获取不到Indicator对象,更不用说Indicator对象的属性了,因此我只能用自己的方法来实现了,其实很简单,就是每创建一个Indicator对象就把它塞到一个GSList里面,创建之前搜索该链表,如果其中有indicator的sid值与要创建的sid相同,则表示已存在,无需再重新创建,把它的count值加1即可。

有一点需要注意的是libindicate-gtk新旧版本的pc文件名是不同的(感谢@riku的测试),在10.04上是旧版pc文件名是indicate-gtk.pc,因此编译选项可以是

pkg-config --cflags --libs indicate-gtk

而在ubuntu 11.04中文件名是indicate-gtk-0.5.pc,编译选项便是:

pkg-config --cflags --libs indicate-gtk-0.5

我在CMakeLists.txt做了一些处理来让它自动识别这两个版本的不同。

相关 [openfetion for ubuntu] 推荐:

Openfetion for ubuntu messaging menu开发手记

- 培培 - basic coder
自从ubuntu11.04发布之后Openfetion就遇到了一个比较麻烦的问题,把Openfetion飞信最小化到托盘之后就找不到了,没用过ubuntu11.04,不过据说它的unity桌面貌似没有status icon这回事,所以把Openfetion塞进Messaging Menu也成了一个很重要的任务,在这里把开发过程和大家分享.

Ubuntu 速查表

- 威 - Linux爱好者
曾经,FOSSwire 制作了一张 Unix/Linux 命令速查表,为 Unix/Linux 用户带来了方便. 现在,他们又专门针对 Ubuntu 制作了一张速查表,其中包含权限、显示、系统服务、包管理、网络、防火墙、系统等方面的常用命令介绍. 此外,该速查表也介绍了一些特殊的 Ubuntu 包及应用程序名称.

Ubuntu 7 岁了

- Lee Jia - cnBeta.COM
就在7年前的今日,Mark Shuttleworth 和他的团队宣布了第一个Ubuntu 发行版本“Warty Warthog(疣猪)”. Ubuntu 4.10 标志着一个新时代的开始,它是第一个Ubuntu 发行版本. 基于Debian,致力于给用户简单易用、无障碍的Linxu体验. 该版本也开创了免费海运为用户提供Ubuntu CD安装盘模式.

Ubuntu 11.10发布

- 李龑 - Solidot
51开源社区 写道 "代号为Oneiric Ocelot的 Ubuntu 11.10 正式版如期发布. 默认搭载Firefox 7.0.1、Ubuntu One云存储、Banshee 音乐播放器、备份工具Deja Dup、Thunderbird 邮件客户端、LibreOffice3.4.3、Gwibber 3.1.4,基于云的Juju包管理器,Xen虚拟机.

升级到Ubuntu 11.04到 Ubuntu 11.10 Beta

- tackwell - 笨兔兔
Ubuntu 11.10 正式版发布还有35天时间,近日,Ubuntu 11.10 Beta发布. 喜欢尝鲜的同学,是不是有点挺不住了. 将Ubuntu 11.04到 Ubuntu 11.10 Beta. 下面是升级到Ubuntu 11.04到 Ubuntu 11.10 Beta方法. 或者ALT+F2,输入下面命令:.

Ubuntu 11.10 Beta1发布

- tinda - Solidot
Ubuntu 11.10 Oneiric Ocelot发布了第一个beta版. 根据Ubuntu的发布时间表,beta 2将在9月22日发布,正式版将在10月13日发布. beta 1的主要新特别包括:3.0.0-9.15 Ubuntu定制kernel,改进和更新Unity桌面,Ubuntu软件中心加入评分浏览,新的信息检索工具Lenses,Python 3.2、GCC 4.6.1、CUPS 1.5.0、Shotwell 0.11,LibreOffice 3.4.2,备份工具Déjà Dup,Firefox 7 beta和Thunderbird 7 beta.

Ubuntu Linux大型机?

- Jack - Solidot
Vaughan-Nichols引用接近Canonical和IBM的消息来源称,Ubuntu将在不久后获得IBM的认证,能运行在基于Power处理器的System p服务器和System z大型机上. 在这之前,Ubuntu已获得IBM的认证,能运行在其基于x86的System x和BladeCenter服务器上.

Ubuntu 11.10 快捷键

- 超辰 - 〖好记性不如烂笔头─Ubuntu Note〗
对于从Ubuntu10.10直接跳到11.10的我来说,一切又回到了解放前. 熟悉的界面不见了,装个Gnome也跟原来不一样了. 为了快速进入到能工作的状态而不是在桌面里四处探险,再试试快捷键吧. 经验证,目前已经确定能用的如下:. 单击超级键(Windows键),显示快捷键对话框. 按住超级键(Windows键)1秒,然后看你的快捷工具条(屏幕左边那个),看见数字了吧.

BitCoin for Ubuntu 11.04 客户端

- Riku - Wow! Ubuntu
BitCoin 最近很热,大量的媒体、Blog ,甚至叽喳上都在谈论此物. 那么 BitCoin 到底为何物. [以下引用自 ivarptr 的文章,详情请看“通俗易懂讲解什么是 Bitcoin 虚拟货币”一文]. Bitcoin (为了便于书写和理解,下面如果是表示 “Bitcoin币”意思的地方我称呼其为“贝壳币”,取粤语相近的音译)是一种网络虚拟货币,跟腾讯公司的Q币类似,你可以使用贝壳币购买一些虚拟的物品,比如网络游戏当中的衣服、帽子、装备等,只要有人接受,你也可以使用贝壳币购买现实生活当中的物品.

Ubuntu 里使用中文 Man

- charleszhou - Wow! Ubuntu
[提问] Mysql导入sql的乱码问题. 都知道 man 特别给力,有什么不会了就 man 一下,甚至 man 自己也能 man. 不过 Ubuntu 默认的 man 是英文的,看着总归有些累,将 man 改为中文的就易读多了. # 使用方法:打开终端,输入以下命令安装中文 man 手册. 安装完了不够,还要看一下中文 man 手册安装到哪里了,在终端输入.