AirJD 焦点
AirJD

没有录音文件
00:00/00:00
加收藏

Go在Linux桌面环境中的应用

发布者 golang
发布于 1431734825042  浏览 7748 关键词 Go 
分享到

第1页

Go in Linux Desktop Environment

2015年4月

夏彬 武汉深之度



第2页

Linux桌面环境

Gnome (Gtk) KDE (Qt) Lxde (Gtk) LxQt(Qt5) Xfce (Gtk) DDE (Gtk) .......



第3页

DE组件

Windows Manager Input Method Launcher Panel (dock) Session Manager Appearance Configure Modules many service daemon, like

audio, network, volume, power, login

Basic Applications

Document Reader、Browser、File Manager



第4页

Why golang?

简洁一致 开发效率与运行效率间的平衡 编译型语言相对来说更适合长期项目



第5页

Question: DE是否应该努力追求本身独立?

可以跑在更多发行版上 更多的受众,更多的反馈 但DE最终会与底层服务甚至特定版进行交互,完全独立很难走到完美。 造成更多的开发包袱 Linux不会被统一,所以DE最好还是拥有更好的内聚性。 但应该打包更多的系统在一起, 从更多的地方优化用户体验,无折腾。

基础文件系统 +仓库 +DE+软件商店(各种应用软件才是正常用户需要的,基础设施不应该放到用户面前)

相关实验性项目

Gnome SDK + sandboxed appliations Deepin XX ?



第6页

遇到的问题

与其他组件的融合 X11



第7页

解决方式

using CGO to get anything Pure golang library



第8页

CGO Tips

Go-C C-Go struct array



第9页

CGO Tips: Go call C functions && types convert

package main

//#include <stdlib.h> //#include <time.h> import "C" import "fmt"

func main() { s := C.time(nil) C.srandom(C.uint(s)) r := C.random() fmt.Println(r)

}

Easy to use. Just using the C pseudo package.

The code of glue-C is far less than perl、python ...



Run



第10页

CGO Tips: Even more convenient than C at make time

package main

/* #cgo pkg-config: gtk+-3.0 #include <gtk/gtk.h> void write_c_function_in_go_source(GtkWidget* w) {

GtkWidget* color = gtk_color_chooser_widget_new(); gtk_window_set_position(GTK_WINDOW(w), GTK_WIN_POS_CENTER); gtk_container_add(GTK_CONTAINER(w), color); } */ import "C"

func main() { C.gtk_init(nil, nil) w := C.gtk_window_new(C.GTK_WINDOW_TOPLEVEL) C.write_c_function_in_go_source(w) C.gtk_widget_show_all(w) C.gtk_main()

}



Run



第11页

CGO Tips: Struct is also easy to use

package main

/* #include <time.h> #include <stdlib.h> struct tm* tms[2]; void init_array_times() {

struct tm* local, *gmt; time_t now = time(0); tms[0] = gmtime(&now); tms[1] = localtime(&now); } */ import "C" import "fmt"

func main() { C.init_array_times() fmt.Println("Tody is", C.tms[1].tm_year, C.tms[1].tm_mon+1, C.tms[1].tm_mday+1)

}



Run



第12页

CGO Tips: Passing array type is annoying

package main

/* #include <time.h> #include <stdlib.h> struct tm** tms; void init_array_times() {

struct tm* local, *gmt; tms = malloc(sizeof(struct tm*) * 2); time_t now = time(0); tms[0] = gmtime(&now); tms[1] = localtime(&now); } */ import "C" import "fmt"

func main() { C.init_array_times() fmt.Println("This will failed", C.tms[1].tm_year)

}



Run



第13页

CGO Tips: Passing array type is annoying

convert **struct_tm to *[size]*C.struct_tm

func main() { C.init_array_times() tms := (*[4](*C.struct_tm))(unsafe.Pointer(C.tms)) fmt.Println("type of C.tms:", reflect.TypeOf(C.tms)) fmt.Println("type of tms:", reflect.TypeOf(tms)) fmt.Println("This will OK", tms[0].tm_year, len(tms))

}

Why we choose 4 as the array length



Run



第14页

CGO Tips: Passing array type is annoying

In practice, the array length must be given at compile time.

we can simply use a larger one and make a slice value, like

n := calacLength(C.tms) tms := (*[1<<12](*C.struct_tm))(unsafe.Pointer(C.tms))[:n:n]



第15页

CGO Problems: We have more troubles

GC

C.free(unsafe.Pointer(foo)) // malloc and free foo.Ref() and foo.Unref() // C library reference system

ease the pain

runtime.SetFinalizer(obj interface{}, finalizer interface{}) runtime.GC()

thread safe

goroutine with GUI (main loop、work loop) goroutine with POSIX thread



第16页

CGO: automatically generate code

swig (http://www.swig.org/Doc2.0/Go.html) go-cxxdict (https://github.com/sbinet/go-cxxdict) gir-generator (https://github.com/snyh/gir-generator)



第17页

GIR: GObject Introspection repository (GIR)

The middleware layer between GObject libraries and language bindings. After the first FooObject built, all C libraries which based on GObject can be directly used by the Foo Language users. The first guy in Golang is

nsf/gogobject (https://github.com/nsf/gogobject)

the first line of README

WARNING! This project is no longer maintained. Probably doesn't even compile.

And it's true. There has an workable and improved version. snyh/gir-generator (https://github.com/snyh/gir-generator)



第18页

GIR: How GIR does this ?

They has defined a IDL which is worked well with GObject.

They offer the libgirepository.so to read the IDL file.

Using the information offered by IDL file, you can communicate with any libraries based on GObject.

Bindings type - static binding - dynamic binding



第19页

GIR: How many GIR libraries we can use?

apt-filesearch/usr/lib/girepository-1.0/|awk'{print$1}' |uniq|wc 171 171 3513

gstreamer appindicator anjuta atspi clutter gudev webkit wnck freedesktop (freetype2、xlib、fontconfig、DBus、xrandr) all libraries based on GObject (use g-ir-scanner to generate the IDL file)



第20页

GIR: use gir udev to inspect device information

package main

import "fmt" import "pkg.linuxdeepin.com/lib/gudev" import "pkg.linuxdeepin.com/lib/glib-2.0"

func main() { c := gudev.NewClient(nil) c.Connect("uevent", func(client *gudev.Client, action string, dev *gudev.Device) { fmt.Println("A:", action, "D:", dev.GetSysfsPath(), "Brightness:", dev.GetSysfsAttr("bri

ghtness")) })

all := c.QueryBySubsystem("backlight") for _, bl := range all {

fmt.Printf(`name: %v path: %v brightness: %v type:%v

`, bl.GetName(), bl.GetSysfsPath(), bl.GetSysfsAttr("brightness"), bl.GetSysfsAttr("type")) } glib.StartLoop()

} Run



第22页

GIR: create the new gudev binding in 5 minutes

{ "namespace": "GUdev", "version": "1.0"

}

package gudev /* #include "gudev.gen.h" #cgo pkg-config: gudev-1.0 */ import "C" import "unsafe" import (

"pkg.linuxdeepin.com/lib/gobject-2.0" ) [<.go_utils_no_cb>] [<.go_bindings>]

and run

gir-generator gudev.go.in

the result is an usable go package.



第23页

Pure golang packages:

X Go Binding xgb (https://github.com/BurntSushi/xgb)

native Go client bindings for D-Bus message bus system go.dbus (https://github.com/guelfey/go.dbus)



第24页

What is D-Bus ?

a message bus system. advanced IPC support Method, Property and Signal support ACL automatically start services supported by GNOME, KDE, Systemd, upstart ... D-Bus FreeDesktop(http://dbus.freedesktop.org)

others Kernel "dbus-like" code for the Linux kernel(https://github.com/gregkh/kdbus)



第25页

go-dbus: The Easy Frame-less D-Bus Go Interface

go-dbus us(https://gitcafe.com/Deepin/go-lib/tree/master/dbus) go.dbus as transport layer.

Automatically export Properties/Methods/Signals from Go to D-Bus. Automatically update property value with other system, like GSettings.



第26页

go-dbus: example dbus-services, define service

type DService struct { Name string Version string

Enabled bool `access:"readwrite"`

Changed func(int64) //signals

service []string }

go-dbus us(https://gitcafe.com/Deepin/go-lib/tree/master/dbus) go.dbus as transport layer.



第27页

go-dbus: example dbus-services, install service

//give the dbus service, path and interface information func (*DService) GetDBusInfo() dbus.DBusInfo {

return dbus.DBusInfo{ "org.snyh.test", "/org/snyh/test", "org.snyh.test",

} }

func main() { d := &DService{"TestSerivce", "0.1", false, nil, []string{"Close", "Check"}}

if err := dbus.InstallOnSession(d); err != nil { fmt.Println("Install failed:", err) return

} if err := dbus.Wait(); err != nil {

fmt.Println("Bus error:", err) return } }



Run



第28页

go-dbus: defect

lost struct filed name (D-Bus caused) lost argument name (go-dbus caused)

reflect package doesn't support query arguments name of a function at runtime.

Should we using go generate to generate stub code at build time ?



第29页

dbus-generator: Generate D-Bus binding codes

It can generate dbus-binding for QML/PyQt/Golang. https://gowalker.org/github.com/linuxdeepin/go-dbus-generator https://github.com/linuxdeepin/dbus-factory



第30页

Other Go Project in Deepin

deepin id (online services for linux Desktop) Go for loongson(https://github.com/emb-team/loongson-golang) many IT infrastructures for internal use



第31页

hack project

dui (https://github.com/snyh/dui)

webkit without javascript runtime golang play with DOM directly small memory footprint



第32页

dui: How it look like ?



hello := f.NewElement("input") hello.Set("type", "button") hello.Set("value", "hello") hello.Set("id", "hello") f.Add(hello)



txt.Set("style", "text-shadow: 2px 2px 2px red; font-size: 18px; -webkit-transform: rotate(20deg);")

txt.SetContent("DUI Test")



var flag bool hello.Connect("click", func(e dui.MouseEvent) {

fmt.Printf("x:%d, y:%d\n", e.X, e.Y) flag = !flag if flag {

txt.SetContent("one two three") println(txt.Content()) } else { txt.SetContent("three two one") println(txt.Content()) } runtime.GC() })



Run



第34页

湖北的同学们可以回家啦

Go to 武汉 Deepin 武汉光谷金融港 http://deepin.org Slide源码 (https://github.com/snyh/slide/tree/master/gopherchina2015)



第35页

Thank you

2015年4月 Tags: golang, deepin, DE, linux(#ZgotmplZ)

夏彬 武汉深之度 snyh@snyh.org (mailto:snyh@snyh.org)



支持文件格式:*.pdf
上传最后阶段需要进行在线转换,可能需要1~2分钟,请耐心等待。