Skip to content
 
 

Repository files navigation

goibus - golang implementation of libibus

goibus implements the libibus bindings in golang. goibus can be used to create IBus engines aka develop custom input methods.

IBus is an Intelligent Input Bus. It provides full featured and user friendly input method user interface. It also may help developers to develop input method easily.

This library is little bit different than other libibus bindings/wrappers. Instead of wrapping libibus c library or GOBject-Introspection, it implements whole functionality by communicating over DBus IPC. Because of that it is a independent 100% pure golang library without any native dependencies.

####NB: libibus has various classes that are not absolutely required for creating engines. This library only implements engine related classes. Some uncommon class/methods are also skipped for now. You can always implement those and send PR ;)

This table shows the current status of implementation.

libibus - goibus
IBusAttrList ✅ Implemented In text.go
IBusAttribute ✅ Implemented In text.go
IBusBus ✅ Implemented In bus.go
IBusComponent ✅ Implemented In component.go
IBusConfig 🔴 Ignored, not implemented
IBusConfigService 🔴 Ignored, not implemented
IBusEngine ✅ Implemented In engine.go
IBusEngineDesc ✅ Implemented In engineDesc.go
IBusFactory ✅ Implemented In factory.go
IBusHotkeyProfile 🔴 Ignored, not implemented
IBusInputContext 🔵 Ignored, relevant inherited signals implemented in Engine
IBusKeymap 🔵 Ignored for now, will implement
IBusLookupTable ✅ Implemented In lookupTable.go
IBusObject ✅ Ignored, Parent/Interface class, relevant inherited signals implemented in Engine
IBusObservedPath 🔴 Ignored, not implemented
IBusPanelService 🔴 Ignored, not implemented
IBusPropList ✅ Implemented In property.go
IBusProperty ✅ Implemented In property.go
IBusProxy 🔴 Ignored, not implemented
IBusRegistry 🔴 Ignored, not implemented
IBusSerializable ✅ Not needed in golang, All implemented classes are Serializable
IBusService ✅ Ignored, not needed. Parent/Interface class
IBusText ✅ Implemented In text.go

Installation

go get github.com/godbus/dbus
go get github.com/BambooEngine/goibus

check _example directory for a sample engine and ~~ TODO:detailed tutorial ~~. Run the sample engine by _example -standalone to see it in action. sample engine

Connecting to ibus-daemon

IBusBus is created with NewBusE, which reports failures instead of taking the process down:

bus, err := goibus.NewBusE()
if err != nil {
        log.Fatalf("cannot start: %v", err)
}
defer bus.Close()

NewBus is the older constructor. It still panics on failure, which is usually not what you want in a component that ibus-daemon supervises, because the component is respawned and crashes again in a loop.

A component that ibus-daemon spawns can start before the daemon has written its address file, and a component started by hand can inherit a stale address from a previous session. DialWhenAvailable retries until the daemon answers, and re-resolves the address on every attempt so a restarted daemon is picked up:

ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
defer cancel()

bus, err := goibus.DialWhenAvailable(ctx, goibus.DefaultRetryInterval)
if err != nil {
        log.Fatalf("ibus-daemon never became available: %v", err)
}

Address resolution mirrors ibus_get_address(). IBUS_ADDRESS wins, otherwise the address is read from the file named by IBUS_ADDRESS_FILE or $XDG_CONFIG_HOME/ibus/bus/<machine-id>-<hostname>-<display>. Unlike the older GetAddress, GetAddressE parses the IBUS_DAEMON_PID line and checks that the recorded process is still alive, so a socket left behind by a crashed or restarted ibus-daemon is reported as ErrDaemonNotRunning instead of failing later with "connection refused".

Components should also watch for the daemon going away, otherwise they block forever on a dead connection:

// Exit when ibus-daemon restarts; it will respawn us.
<-bus.Done()

To be notified when a new daemon appears, watch the address file the way libibus does with g_file_monitor_file():

go goibus.WatchAddress(ctx, goibus.GetSocketPath(), time.Second, func() {
        log.Println("the ibus daemon address changed")
})

License

goibus - golang implementation of libibus by Sarim Khan

Licensed under Mozilla Public License 1.1 ("MPL"), an open source/free software license.

About

golang implementation of libibus

Resources

Stars

4 stars

Watchers

1 watching

Forks

Releases

Packages

Used by

Contributors

Languages