作者归档:mzh

[Gnome-Shell扩展制作指北]第三篇:图标与图片加载

看了题目你可能会奇怪,这有什么不同吗?其实,这里只是两种不同的加载方式。

图标

第一种是图标,或者叫icon,加载的方式是通过系统搜索整个主题库来加载这一图标文件。很难懂?没关系,在/usr/share/icons/下面有很多的图标是吧,那咱们就来加载
face-smile效果图 和上节课有神马不同呢: git diff Lesson_2 Lesson_3_Chapter_1

//…此处省略一些………
+const Gtk = imports.gi.Gtk;
@@ -17,7 +18,17 @@ ExampleIndicator.prototype = {
PanelMenu.Button.prototype._init.call(this, St.Align.END);
this.label = new St.Label({text:"This is Example"});
- this.actor.add_actor(this.label);
+ this.label.add_style_class_name('example');
+
+ //this.actor.add_actor(this.label);
+
+ this.iconTheme = Gtk.IconTheme.get_default();
+ this._icon = new St.Icon({ icon_type: St.IconType.SYMBOLIC,
+ style_class: 'popup-menu-icon',
+ icon_name: 'face-smile',
+ icon_size: 26
+ });
+ this.actor.add_actor(this._icon);
Main.panel._rightBox.add_actor(this.actor);
},
//…此处又省略一些………

iconTheme = Gtk.IconTheme.get_default(),这里是告诉GTK主题系统去寻找当前的主题。也就是「主题设置会影响你的图标显示」。用户换了一个主题,你的图标也有可能改变哦。
你可能要问,如果要添加自定义的图标路径怎么办呢? 这也好办,跟Gtk主题说一声就行了: iconTheme.append_search_path (自定义的图标路径); St.Icon实例的基本组成:

  • icon_type:图标类型,也就两种,全彩(正常的),象征性的(例子里用的)
  • icon_name:图标的名字,这里我们挑了face-smile :)
  • icon_size:图标的大小,要注意这个大小指的高和宽同样的值,如下图

这里要注意图标的命名,如果你选择了象征性的图标,就要在图标文件名后面加上"-symbolic"这样的后缀,例如:face-smile- symbolic.svg 这样加载图标确实很方便,特别是系统本身自带的那些图标上,但是要是加载图片时,总不可能把图片塞进主题里对吧。

CSS式加载图片

当然不只是换了个图片,让我们看看它和Chapter
1有神马区别。 git diff Lesson_3_Chapter_1 Lesson_3_Chapter_2
除了添加了一个新文件以外,实际上只有短短的8行:

+.example_icon{
+ background-image: url(pic/applications-science-symbolic.svg);
+ background-size: contain;
+ width:26px;
+ height:26px;
+}
+ //this.actor.add_actor(this._icon);
+ this._css_icon = new St.Bin({ style_class: "example_icon" });
+ this.actor.add_actor(this._css_icon);

如果你写过CSS,这些对你简直就是小儿科了。不过我还是想罗嗦一下:
首先我们添加了一个St.Bin(暂且把这当容器用吧),然后给这货添加了一个"example_icon"的类。并在css里定义了这个类的表现形式,和第二课里做的其实差不多吧。这和图标式加载有些许不同,那就是Bin的大小不受父级元素控制哦。
其实加载图片还有两种方法,不过我都不推荐:

  • Clutter.Texture.new_from_file,因为要考虑绝对路径的问题,而css可以考虑相对路径
  • GdkPixbuf,actor不能接受这个实例,添加时要转换

当然你觉得好,你可以用哈~不过我觉得样式和程序分离是未来的设计趋势,再说了,CSS就是方便呗。

总结

本节我们学习了:

  • 图标通过GTK主题系统加载
  • 图片通过css加载

这样一来,大家就可以加载自己喜欢的GUI啦~

[Gnome-Shell扩展制作指北]第二篇:文字显示

文字显示在各种面板类插件几乎是必有的项目,比如默认在Gnome-shell的面板正中央就是一个文字类的时间显示器。
废话不说,直接上实现效果:

代码如下,或者去[GITHUB上下载](https://github.com/mengzhuo/gnome-shell-
example/zipball/Lesson_2):

const St = imports.gi.St;
const Main = imports.ui.main;
const PanelMenu = imports.ui.panelMenu;
let metadata,indicator = null;
function ExampleIndicator(){
this._init();
}
ExampleIndicator.prototype = {
__proto__: PanelMenu.Button.prototype,
_init: function (){
global.log('EXAMPLE:Enabled');
PanelMenu.Button.prototype._init.call(this, St.Align.END);
this.label = new St.Label({text:"This is Example"});
this.actor.add_actor(this.label);
Main.panel._rightBox.add_actor(this.actor);
},
destroy: function(){
global.log('EXAMPLE:Disabled');
Main.panel._rightBox.remove_actor(this.actor);
}
}
function enable() {
indicator = new ExampleIndicator();
}
function disable() {
indicator.destroy();
}
function init(metadata) {
global.log('EXAMPLE:%s Initialized '.format(metadata.uuid));
}

你可能会惊呼怎么比第一篇多了这么多代码,简直就反人类嘛! 其实,还是差不多的。看看上次我们说的enable函数,里面是不是变成了

indicator = new ExampleIndicator();

至于为什么这么构造,可以看具体文章「ECMAScript
定义类或对象

借助这种方法我们调用了PanelMenu.Button.prototype这一原型,然后把它放入这一原型的actor中。Actor是clutter中的概念,具体可以看其参考文档「[ClutterActor](http://docs
.clutter-
project.org/docs/clutter/stable/ClutterActor.html)」,不过我个人理解成「要显示的东西都往这塞吧」的容器。
我们这次要放一个文本显示框进去,所以以下代码来构造一个新的St.Label(和GTK里面的很像吧:)

this.label = new St.Label({text:“This is Example”});

这样就好了,是不是很简单呢~

小小的扩展—-CSS控制

用GJS显示文字这么简单,但是这和python到底有什么不同?这就是接下来的部分要讲的啦~用CSS控制其样式! 把上面的创建St.Label实例的代码改成

this.label = new St.Label({text:"This is Example"}); this.label.add_style_class_name('example');

是不是很眼熟?对,就是web前端经常干的事,给DOM添加类。 然后你也猜到了—-修改stylesheet.css呗

.example{color:red;}

Alt+F2后,输入「rt」就可以重载css,不需要重载整个G.S是不是更方便了呢! Vala~!

总结

本章我们学习了文字显示,大家还可以用上篇的LookingGlass来调查这个St.Label实例里还有什么可以玩的,下篇是「图像和图标显示」哦~

[Gnome-Shell扩展制作指北]第一篇:架构简析与简单调试

写给那些和我一样看着网上吹水Gnome-Shell用了CSS+JS这一神奇架构后,想跃跃欲试地参与扩展制作的菜鸟程序员和恐惧编译的前端们。

首先,欢迎来到没有编译、没有烦人的GTK控件设计的新世界。由于Gnome-shell(简称G.S)或者叫Gnome3用了Gnome
JavaScript(GJS)作为运行环境,所以可以轻松加载各种GJS写的扩展程序(extension)。要加载这些扩展,总要搞懂扩展的组成吧~

扩展的基本构成

至少需要2个文件:

  • extension.js: 负责插件的核心文件,工作全包
  • metadata.json: 插件的描述文件,额外数据加载
  • stylesheet.css: 负责外观描述

这里我们就用一个简单的例子来说明:

metadata.json

{
"uuid": "gnome-shell-example@mengzhuo.org",
"shell-version": ["3.4"],
"name": "Example",
"url": "//mengzhuo.org/gnome-shell-example",
"description": "This is an EXAMPLE for gnome-shell extension"
}

一些解释(其实要是你英语够好,解释都可以跳过了):

  • uuid是扩展唯一ID的标识,相当于身份证号码一样,必须有"@"
  • shell-version可以运行的Shell的版本号,本身是个数组
  • name是扩展的名字
  • url告诉用户,可以在哪里搞到这个扩展或者介绍
  • description扩展描述

extension.js

function enable() {}
function disable() {}
function init() {}

这三个函数是固有的,不写的话插件会各种报错,不过只要定义了就没问题啦~,其中:

  • init函数正如其名"initialize",初始化用,扩展系统加载时运行一次
  • enable函数是给扩展开启时用的

小试牛刀

现在把这两个文件放到~/.local/share/gnome-shell/extensions/gnome-shell- example@mengzhuo.org/ 这里你可能注意到了,“gnome-shell-
example@mengzhuo.org"和metadate.json中的uuid描述是一样的,这么写是为了符合G.S的扩展系统的设定:如果文件夹名称和uuid描述不符,就不加载。

使用LookingGlass调试

按下:ALT+F2开启命令模式
这时输入r重载(reload)整个G.S,当然包括你刚才写的扩展。 然后在终端运行Gnome高级配置工具gnome-tweak- tool找到刚才写的扩展:Example,当然,开启它。 ![](/2012/06/2012-06-24-144436的屏幕截图-
377x300.png)

这时,你写的扩展其实已经加载完成了,什么都没有发生是吧……那是因为我们什么都没有写。 打开extension.js,改成这样:

function enable() {
global.log('EXAMPLE:Enabled');
}
function disable() {
global.log('EXAMPLE:Disabled');
}
function init(metadata) {
global.log('EXAMPLE:%s Initialized '.format(metadata.uuid));
//把metadata.json里的内容加载进来,并输出uuid
}

再次重载G.S,不过,这次再进入ALT+F2命令模式,输入"lg”(是LookingGlass简写,不是老公)
然后选择"Error"标签页,就可以看到例子已经做了点什么。 ![](/2012/06/2012-06-24-151358_1280x800_scrot-
450x285.png)

结束咯

你的第一个扩展就这样写好了,是不是很简单啊,下次要讲是文字显示哦! 本篇代码下载点:<https://github.com/mengzhuo/gnome-
shell-example/zipball/Lesson_1>

开站三周年

不知不觉中,距离那个蝉声不断的午后有三年了。
翻翻记录才发现,三年间口水文写了不少,算上这篇正好140篇,相当于两周一篇,也不枉当年定下的"写周记"的想法。写周记这个不敢说是习惯,但是和初中时语文老师的教导还是有一定关系的
—-当年高文老师规定每周要写周记,我也就每周写点口水话糊弄过去—-
现在翻开看当时的周记自己大牙都笑掉了,而且因为我是个平凡的中学生,每天生活也很枯燥,所以还有不少周记是臆造的。当然下面这篇是真人真事。
对于这么难看的字老师还这么认真地批改,衷心地感谢老师,如果是我早就写上"阅"了。

凡事认真,不是我的专长,和我这人喜欢嬉皮笑脸和不计后果有关。不计后果,三年间写了很多脑残文来批各种自己不喜欢的东西,学校啊,公司啊什么的,我也不打算删掉,毕竟这是年轻过的表现;我也有点担心万一哪天我成了名人,有人来这挖坟,可能有些会尴尬

尽管可能性很渺小,总归是"人怕出名猪怕壮"。不过就算发生了,“凡存在皆有理由”,估计我也不怎么会争,和佛教那万物间没有对错上下,只有羁绊的指导思想有点像。
说到关系,写博客虽然在这个微博、SNS盛行的年代很孤单,还有被现实生活窥探的感觉,就像某博友说的"吃力不讨好";但也交到不少朋友,长了不少眼界,学了不少新东西。比起整天看别人的状态、分享、生活,在个人博客上有种"我得思考"的感觉,而不是被动地接受外界的信息。还有,我想舒淇放弃网络是因为她没有认真写博客,而是依靠微博;看看韩寒,有了博客,别人怎么骂都可以坚持下去,因为还有能做主的地盘,看你丫不爽还能删了你的留言,就算开骂,骂声还能比别人大。冲着这三点,不间断地写个人博客就已经很超值了。
再有在毕业到现在也有一年时间里,虽然我在口语考试中对帅哥考官用蹩脚英语斩钉截铁地说,光看电视是种浪费时间,可我不知道自己这样近近啃老学习的时间是不是也浪费了。看看同龄人,大多已经开始辉煌的人生,买车的买车,结婚的结婚,让我倍感光阴似箭,流时无情,一年真的可以改变很多。估计我这样的人在同龄人里也算差得peerless了。
牢骚太多妨碍心情,不如就此打住,开始努力吧。

小内存VPS之Ubuntu配置LNmP

前言

作为Ubuntu
fans,连VPS都是装Ubuntu的,但是因为内存太小(256M),传说中的LAMP(Linux+Apache+Mysql+PHP),因为内存使用率很容易就100%,只好用LNmP(Linux+Nginx+sqlite
+PHP-fastcgi)。而网上的教程基本针对CentOS,就连用了Ubuntu的也是用LNMP安装包—-
从源代码开始安装!!而且把程序都装到/usr/local下,这样很不符合Ubuntu的包管理精神,而网上的教程基本上是一篇(都是互相抄袭嘛)。因此我想通过本文告诉大家,小内存下的Ubuntu不用编译也可以很好地使用,以下是集合我的实际配置经历和网上文章整理
纯粹在apt-get下管理软件,并配置出适合小内存VPS运行的服务器套装。

别看广告,看疗效


去掉我管理时连接ssh和bash(多了2M左右),内存最大占用只有60M,包括sendmail这种内存大头。当然现在VPS上才跑着一个Typecho(博客程序)和一个大波(推忒API),就算按一个站点要15M左右
(独立php-cgi+nginx进程),多出来的200M,应该还能跑10个左右这样的站点哈,特别对是流量比较小的个人博客,简直是太合适了。

配置Ubuntu

首先在VPS面板安装好Ubuntu 10.04后(是有点老,不过文中命令条目可以跨LTS版本执行),删除apache2和mysql-serverapt- get remove apache2 mysql-server-core bind9接下来是安装Nginx php-cgi apt-get install php5-cgi nginx注:网上说的fastcgi其实和这个是一样的,我个人理解是Nginx把得到的参数通过CGI接口转接给PHP进行处理而已。而Spawn-
FCGI就不用下载了,网上那些用了Nginx还去下载LightHttpd的文章真是不知道怎么说了。为什么?请看[什么是CGI、FastCGI、PHP-CGI
、PHP-FPM、Spawn-FCGI?](http://www.mike.org.cn/articles/what-is-cgi-fastcgi-php-
fpm-spawn-fcgi/)

配置PHP-CGI启动项

添加php-cgi作为常驻内存项目,减少服务器开支 wget /2012/04 /php-fastcgi.txt && chmod +x php-fastcgi.txt && mv php-fastcgi.txt /etc/init.d /php-cgi或者手动复制[php-fastcgi](/wp-content/uploads/2012/04
/php-fastcgi.txt)到/etc/init.d/下面 可能需要编辑文件里面的两项 BIND=/tmp/php.socket
#绑定UNIX通道作为CGI传递的路径 PHP_FCGI_CHILDREN=2 #控制进程数(越多程序速度越快,当然内存消耗越大) 修改好后,再运行
update-rc.d php-cgi defaults && service php-cgi start,把这个启动项作为默认启动项,并启动。

配置Nginx

具体网站程序配置,最好网上找,我这里要说的是upstream和event的设定 /etc/nginx/nginx.conf下面要添加

upstream php { server unix:/tmp/php.socket; } events { worker_connections 1024; use epoll; }

然后再具体的网站程序里要添加: location ~ \.php { #你的程序配置 fastcgi_pass php; }
添加好以后用service nginx reload重载即可。 附上我的Typecho的配置文件:

location ~* ^.+\.php(\/.*)*$ {
try_files $uri =404;
include /etc/nginx/fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_split_path_info ^((?U).+\.php)(/?.+)$;
fastcgi_param PATH_INFO $fastcgi_path_info;
fastcgi_pass php;
}
if (!-e $request_filename) {
rewrite ^(.*)$ /index.php$1 last;
}

结尾啦

这样就基本差不多了,重启或者是其他关掉server之后,内存是不是省了很多,又不需要编译这么长的时间呢。