首页 > C/C++ > Hybrid开发手记之聊天窗口的WebKit支持

Hybrid开发手记之聊天窗口的WebKit支持

2011年8月5日 发表评论 阅读评论 9,930 人阅读过  

近两天给Hybrid(https://github.com/levin108/hybrid)的聊天窗口加上了WebKit支持,之前没有实际用过WebKit,而且Web前台开发功力也不强,草草做了一个界面,但相比用GtkTextView来实现看上去还是要舒服好多,先上个图吧:

本篇没有什么高深的东西,作为一个简单的开发文档。

一,主题组件化的方法

聊天窗口的显示区域已经组件化,并没有进行深层次的模块化,代码还是在一起编译的,只是逻辑上组件化了。

之前是固定的由GtkTextView实现,在加入GtkWebKit的时候同时也保留了GtkTextView的实现,这两者是可选的,不管是GtkWebKit还是GtkTextView都需要实现四个最基本的函数:

typedef GtkWidget* (*text_create)(void);
typedef void (*text_append)(GtkWidget *, HybridAccount *,
							HybridBuddy *,	const gchar *, time_t);
typedef void (*text_notify)(GtkWidget *, const gchar *, gint);
typedef void (*theme_set_ops_func)(void);

前三个函数是组件的操作函数,功能分别是创建聊天区域,向聊天区域中添加消息,向聊天区域中添加提示消息,最后一个是设置操作集合的钩子函数。

对于这两种不同的实现分别定义了两个文件,chat-textview.c和chat-webkit.c,这两个文件里面分别是两者各自的实现,而它们对外的接口只是一个GtkWidget,这得利于GOBJECT的这种类似多态的特性。

对于不同的实现会定义操作集变量:

static HybridChatTextOps webkit_ops = {
	hybrid_chat_webkit_create,
	hybrid_chat_webkit_append,
	hybrid_chat_webkit_notify
};

聊天窗口当前使用的聊天区域实现方式全由该操作集来确定,而使用哪个操作集可以由两种方式各自的theme_set_ops_func函数来设置。

我们可以把两种组件看成两个不同的主题,在聊天窗口文件中定义了该主题的列表:

struct _HybridChatTheme {
	const gchar *name;
	theme_set_ops_func func;
};
 
static HybridChatTheme theme_list[] = {
#ifdef USE_WEBKIT
	{
		"webkit",
		hybrid_chat_set_webkit_ops
	}, 
#endif
	{
		"textview",
		hybrid_chat_set_textview_ops
	}, {
		NULL, NULL
	}
};

运行时程序会根据用户的当前配置情况来选择使用哪种主题。

二,WebKit遇到的问题

关于WebKit有几点小问题,第一次用难免会碰到些小问题,不过幸好还是解决掉了。

1. undefined @1: ReferenceError: Can’t find variable

WebKit外部来操作DOM模型主要是通过从外部调用webkit_web_view_execute_script()来实现的,当然我看最新的GtkWebKit API里面已经支持直接操作DOM了,但貌似手头的系统上安装的版本都还没有这个API函数,为了兼容性的考虑还是采用了传统的方法。在HTML模块中用Javascript定义了函数appendMessage(html),通过这个函数向WebKit中定义聊天信息,但当收到消息自动弹出的时候会提示undefined @1: ReferenceError: Can’t find variable appendMessage(),这种情况的原因很简单,函数是定义了但找不到,原因只能是因为模板字符串还没有加载完成便调用了appendMessage()函数,因此会出现这样的错误,因此在对WebKit进行脚本操作之前首先要等它初始化完成,也就是等它load_finished之后,WebKit提供了load_finished事件,但这个事件目前已经Deprecated了,替代的方法是使用load_status属性,属性和事件的使用方法明显不一样,关于WebKit deprecate load_finished事件的原因我没去仔细想,load_status属性的方法只能是轮询,在收到消息时检测load_status,或未加载完成,则调用g_timeout_add()将操作延时后执行,执行中再检测load_status,若仍未完成则继续延时,直到加载完成为止,实际上在实现的时候我给g_timeout_add的第一个参数写了0,事实证明在进入加调函数时需要的那个简单的HTML模板就已经加载完成了,这时候再去调用webkit_web_view_execute_script()去添加一条新消息。

2. Message: console message: undefined @1: SyntaxError: Parse error

同样是在调用webkit_web_view_execute_script()遇到了上面的错误,通过对比和分析发现我传入的字符串参数中夹带了\n字符,把这个字符换成空格后便没有这个问题了,但换行在HTML中应该是
,于是需要把\n替换成
,C语言以及glibc都没有提供形如replace()这种方便的函数,于是我用GString,把字符一个一个的贴过去,遇到\n就贴一个
在后面,效率是低点,但实现起来比较方便,代码如下:

static gchar*
escape_string(const gchar *str)
{
	GString *res;
 
	res = g_string_sized_new(strlen(str));
 
	while (str && *str) {
		switch (*str) {
			case 13:
				res = g_string_append(res, "<br/>");
				break;
			case '\"':
				res = g_string_append(res, "\\\"");
				break;
			case '\t':
				break;
			default:
				res = g_string_append_c(res, *str);
				break;
		}
		str ++;
	}
 
	return g_string_free(res, FALSE);
}

以上大致完成了文章开头图片的样式,已经可以正常使用,但字体在我这slackware系统上还有些不太完美,也可能是我系统字体设置有问题,这个等后期再处理。

原创文章,转载请注明: 转载自basic coder

本文链接地址: http://basiccoder.com/hybrid_dev_note_webkit_support_in_chat_window.html

分类: C/C++ 标签: ,
  1. guanguan
    2011年8月5日20:57 | #1

    尝试hybrid的飞信功能时,发现如果要输验证字符的话就无可奈何了,然后状态就一直卡在start sipc authenticating那里了…希望能早点把这个bug解决了~~ ;-)

    • 2011年8月5日21:27 | #2

      这个问题一直给忘了,过几天修复一下,等这个问题修好了就正式发布一个版本

  2. 2011年8月8日08:58 | #3

    等待正式版本呀,不知道能不能支持purple的插件,,也就是pidgin的插件目录。支持那个协议api的话,可以在上面用QQ了。因为你之前说hybrid的框架和pidgin的差不多。

  3. xx
    2011年8月9日13:06 | #4

    在windows上面跑如何编译呢

  4. wmz
    2011年8月14日16:47 | #5

    软件看起来很舒服 linux对我来说编译太难 希望能用放出安装包 还有purple的插件支持吗 平时就只用gtalk qq fetion 要是三个协议都有多好啊 或者可以用pidgin插件 ;-)

  5. haoyue
    2011年9月7日11:47 | #6

    哈,什么时候发布正式版呢,期待。

  6. ian
    2011年9月14日17:10 | #7

    什么时候出正式版本啊?支持64位系统吗?

  7. 2011年9月18日13:42 | #8

    期待待图片功能的,哇哈哈 :lol:

  8. 2011年9月19日11:27 | #9

    CC许可的2.5跟3.0到底有什么区别不?为什么你用2.5的呢? :roll:

  9. 2011年9月21日13:05 | #10

    那个代码加亮用的是什么插件啊 :roll:

  10. grace
    2011年11月1日18:06 | #11

    楼主,今天我在ubuntu11.10修改编译了一下hybird,感觉效果不好,gtk代码过于繁琐,你是否考虑python开发?msn客户端emesene就是一个非常出色的python的msn客户端,日常工作中你也可以参考下。

  11. Authur
    2011年11月2日09:26 | #12

    不知道会不会增加dbus接口?这个样子可以支持不少语言~~ 还是希望能够提供python接口

  12. zhydyhm
    2011年11月3日02:35 | #13

    好期待待图片功能呀!! :razz:

  13. 2011年11月27日20:59 | #14

    @grace emesene 确实很出色,可是 bug 也最多

  14. adcros
    2012年3月6日17:19 | #15

    你好,提交了个问题:https://github.com/levin108/hybrid/issues/25

  15. 2012年4月19日12:57 | #16

    是否hybrid还在继续?没有更新的公告

注意: 评论者允许使用'@user空格'的方式将自己的评论通知另外评论者。例如, ABC是本文的评论者之一,则使用'@ABC '(不包括单引号)将会自动将您的评论发送给ABC。使用'@all ',将会将评论发送给之前所有其它评论者。请务必注意user必须和评论者名相匹配(大小写一致)。