2013-01-29
[Microblog] Transient Turtles
The Georgian Bay Turtle Hospital won $5000 of funding through Aviva Canada. My housemate has been advocating it, and loving turtles, yay!
2013-01-20
[Microblog] Transient Satisfaction
Reading Will Grayson, Will Grayson and watching snow fall outside my new home.
[General] JOSH RITTER!
One of my favourite artists (if not my favourite artist!) is coming to Ontario again this winter/spring, and will be in Waterloo in just one month! VICTORY TO HE WHO HATH ACQUIRED THE LAST TICKET ONLINE (me!). Tragically, I could not acquire the last two tickets online, so I can not bring a friend ;_;
2013-01-19
[Microblog] Photo back log
I had sort of forgot to actually share the photos I've been taking, so Christmas and early January are now available. The cabin weekend (150 photos selected out of about 400) and my birthweek (:D) to come soon. :|
[Microblog] Embarrassment
Posted by
Richard
at
00:51
Labels: #Microblog, awkward, embarrassment, friends, magic, pagans, spell
Labels: #Microblog, awkward, embarrassment, friends, magic, pagans, spell
I proposed performing a spell to a pagan friend, who I thought might just stare at me like I was an idiot who watched too much TV. She was in the midst of planning a spell, and didn't know if I'd think she was silly. Phew, that was almost awkward.
2013-01-10
[Technology] "sudo:effective uid is not 0, is sudo installed setuid root?"
Uh oh.
I updated from Fedora 17 to Fedora 18 Beta with fedup.
http://fedoraproject.org/wiki/ FedUp
Then I followed the post-upgrade clean up guide.
http://fedorasolved.org/ Members/fenris02/post_upgrade_ cleanup
It told me to run this
rpm -a --setugids; rpm -a --setperms;
and rpm broke my system.
While it ran the first rpm command, there were a lot of error messages about files not being found. That was apparently fine. When the second rpm command ran, there were a lot of messages about being unable to set permissions. Uh oh.
When I rebooted, GDM couldn't load (well, a GTK+ GUI still showed an error message). Logging in to a VT, I couldn't sudo from my user to root. I also couldn't su. Uh oh! sudo gave me this message:
I could still log in as root directly from a VT's login prompt. I did that. I found the relevant bug 881835,and there they note a new rpm that should fix the problem, version 4.10.2.
NM was still able to connect to the Internet despite the lack of GUI (w00t! if it doesn't for you, try using nmcli from the command-line), so I could still use yum to install the new RPM. So, as root
# yum --enablerepo=updates-testing rpm
Then I re-ran just
# rpm -a --setperms
And suddenly everything was normal again. :)
I updated from Fedora 17 to Fedora 18 Beta with fedup.
http://fedoraproject.org/wiki/
Then I followed the post-upgrade clean up guide.
http://fedorasolved.org/
It told me to run this
rpm -a --setugids; rpm -a --setperms;
and rpm broke my system.
While it ran the first rpm command, there were a lot of error messages about files not being found. That was apparently fine. When the second rpm command ran, there were a lot of messages about being unable to set permissions. Uh oh.
When I rebooted, GDM couldn't load (well, a GTK+ GUI still showed an error message). Logging in to a VT, I couldn't sudo from my user to root. I also couldn't su. Uh oh! sudo gave me this message:
sudo: effective uid is not 0, is sudo installed setuid root?The issue apparently is that rpm reset permissions without re-setting the setuid bit anywhere. Uh oh.
I could still log in as root directly from a VT's login prompt. I did that. I found the relevant bug 881835,and there they note a new rpm that should fix the problem, version 4.10.2.
NM was still able to connect to the Internet despite the lack of GUI (w00t! if it doesn't for you, try using nmcli from the command-line), so I could still use yum to install the new RPM. So, as root
# yum --enablerepo=updates-testing rpm
Then I re-ran just
# rpm -a --setperms
And suddenly everything was normal again. :)
2013-01-08
[Technology] Fedora 18 Beta, FedUp, and GNOME Shell's excessive CPU usage
Posted by
Richard
at
04:29
Labels: #Technology, fedora, fedora 17, fedora 18, gnome, gnome shell, yum
Labels: #Technology, fedora, fedora 17, fedora 18, gnome, gnome shell, yum
Summary: updating to F18 caused GNOME Shell to take up too much CPU; this was because I ran fedup upgrading to F18 beta from F17, and the some of the packages at the time the F18 beta was set have versions below F17 currently, so F17 packages were kept, like my Xorg intel driver, which could no longer load in F18, and consequently GNOME Shell was using llvmpipe and running on the CPU and not the GPU. Solution was to run yum distro-sync
Fedora 18 has been delayed by almost two months. They delayed it by another week until next week, but I am fed up!, so I used FedUp to update it to Fedora 18's current pre-release status. Mwahaha.
After doing so, I noticed my computer running quite hot, and that gnome-shell is consuming all available CPU. Why?
Poking around, I noticed that yum says stuff like:
ibus-1.4.99.20121109-9.fc17.x86_64 has missing requires of libdconf.so.0()(64bit)
ibus-1.4.99.20121109-9.fc17.x86_64 has missing requires of libgnomekbd.so.7()(64bit)
ibus-1.4.99.20121109-9.fc17.x86_64 has missing requires of libgnomekbdui.so.7()(64bit)
libpinyin-0.8.0-2.fc17.x86_64 has missing requires of libdb-5.2.so()(64bit)
xorg-x11-drv-intel-2.20.16-1.fc17.x86_64 has missing requires of libudev.so.0()(64bit)
xorg-x11-drv-intel-2.20.16-1.fc17.x86_64 has missing requires of xserver-abi(videodrv-12) >= ('0', '1', None)
Uh oh, isn't that my video card driver? Reading bug 812624 about GNOME Shell and high CPU usage also suggested that it might be being rendered via llvmpipe, on the CPU, rather than by my video card. A quick check confirms it:
# glxinfo | grep renderer
OpenGL renderer string: Gallium 0.4 on llvmpipe (LLVM 0x301)
Uh oh.
I checked /var/log/Xorg.0.log to confirm the suspicion that the intel driver wasn't loading, and as expected,
Failed to load /usr/lib64/xorg/modules/drivers/intel_drv.so: libudev.so.0: cannot open shared object file: No such file or directory
Trying to do a yum whatprovides **/libudev.so.0 unfortunately turned up nothing, but googling the error gave me bug 888085. There contained was the obvious tip of using yum distro-sync to make sure I have Fedora 18's packages and not some old ones from Fedora 17. Sheesh.
Fedora 18 has been delayed by almost two months. They delayed it by another week until next week, but I am fed up!, so I used FedUp to update it to Fedora 18's current pre-release status. Mwahaha.
After doing so, I noticed my computer running quite hot, and that gnome-shell is consuming all available CPU. Why?
Poking around, I noticed that yum says stuff like:
ibus-1.4.99.20121109-9.fc17.x86_64 has missing requires of libdconf.so.0()(64bit)
ibus-1.4.99.20121109-9.fc17.x86_64 has missing requires of libgnomekbd.so.7()(64bit)
ibus-1.4.99.20121109-9.fc17.x86_64 has missing requires of libgnomekbdui.so.7()(64bit)
libpinyin-0.8.0-2.fc17.x86_64 has missing requires of libdb-5.2.so()(64bit)
xorg-x11-drv-intel-2.20.16-1.fc17.x86_64 has missing requires of libudev.so.0()(64bit)
xorg-x11-drv-intel-2.20.16-1.fc17.x86_64 has missing requires of xserver-abi(videodrv-12) >= ('0', '1', None)
Uh oh, isn't that my video card driver? Reading bug 812624 about GNOME Shell and high CPU usage also suggested that it might be being rendered via llvmpipe, on the CPU, rather than by my video card. A quick check confirms it:
# glxinfo | grep renderer
OpenGL renderer string: Gallium 0.4 on llvmpipe (LLVM 0x301)
Uh oh.
I checked /var/log/Xorg.0.log to confirm the suspicion that the intel driver wasn't loading, and as expected,
Failed to load /usr/lib64/xorg/modules/drivers/intel_drv.so: libudev.so.0: cannot open shared object file: No such file or directory
Trying to do a yum whatprovides **/libudev.so.0 unfortunately turned up nothing, but googling the error gave me bug 888085. There contained was the obvious tip of using yum distro-sync to make sure I have Fedora 18's packages and not some old ones from Fedora 17. Sheesh.
2013-01-07
[Microblog] Transient Errors
I once received an e-mail from a web developer containing a client's new e-mail and account name. I later met that web developer 8 years later at a conference.
I just received someone's banking information. Oh my.
I just received someone's banking information. Oh my.
[General] Moving Out
I'm moving. Almost certainly.
I am going to become housemates with my best friend in Guelph. We've considered this before, and her most recent housemate suddenly evaporated, so now's the time.
I've really enjoyed my apartment and living alone.
It's a bit weird to think that this is the longest I've lived in one place since high school. Here is a diagram demonstrating this:
I am going to become housemates with my best friend in Guelph. We've considered this before, and her most recent housemate suddenly evaporated, so now's the time.
I've really enjoyed my apartment and living alone.
- complete control; things are always exactly as I left them; no mess, no unexpected surprises; everything is to my preference
- privacy; I can do whatever I want and it doesn't matter to anyone
- guests; I can have whoever I like over!
- cleanliness; this also fits under complete control, but cleanliness is to my own standard, or if it isn't, I'm the one responsible
- kitchen; I know what's in my fridge, I know what needs cleaning; I know what doesn't; my counter is as free as I want it; it's all vegan
- quiet; I can focus and have no disturbances, besides the neighbours through the walls, which is minor
- washroom; it's ready for me whenever I need it, and isn't cluttered by weird stuff
- decor; also fits under complete control; I have my posters, and stars, and birds, and maps up
- high ceilings, making it possible to practise jodo and kendo and iaido at home
- close to downtown and right next to the Farmers' Market
- spacious living quarters
- buses right next door!
- it can be lonely; having S around the past couple of months has been nice, and before then my best friend came by a lot, but that's not really feasible or reliable. Loneliness isn't actually a big deal for me any more, but it will be nice having other humans around
- cats!; I'm not prepared to own one myself yet, but she has two! And the bird and fish that I've pet sat for the past while
- money!; while living alone has been great, it's been expensive. I could have saved several thousands of dollars over the past 16 months if I had moved in with housemates; let the saving begin now.
- Internet!; I cleverly use my WIND data plan for my home Internet, but with that I only have 10GB/month at full speed. That's actually enough if I'm being conservative, but I don't always want to be conservative; I want to watch Netflix ad nauseam
- better prospect; my current window looks out at a grey building; the new apartment looks out at a nice lawn an residential houses
- closer to campus! There are bus stops right outside for each direction, like my current place, but it's 10 minutes closer to campus than my current abode
- her! She's an awesome friend
![]() |
The bed, canopy, stars, and birds |
![]() |
The window, my plants, and dresser |
![]() |
The television and game cupboard, desk, dresser |
![]() |
My friend's piano, comic strips, etc. |
![]() |
The broken futon |
![]() |
My (text)book collection, and jars of strange things (coins) |
![]() |
The hallway! with bike, and sword corner, and maps |
![]() |
Kichen and stuff |
![]() |
[Technology] Writing a Rhythmbox Plugin: Rhythmbox DJ
Posted by
Richard
at
18:18
Labels: #Technology, automake, gnome, gtk, rhythmbox, speech dispatcher, vala
Labels: #Technology, automake, gnome, gtk, rhythmbox, speech dispatcher, vala
I don't like being anchored to my computer, so I want it to communicate more information to me while I'm doing something else at home. When music is playing and I want to know the artist and track name of a song, I want Rhythmbox to announce that aloud.
I previously wrote djaqua which did this, but was written in Python. That bit rotted for me, and rather than updating it, I took an opportunity to try writing a Rhythmbox plugin in Vala. I really like Vala. Despite bugs, it works surprisingly well for what it tries to do, and it helps structure and simplify so much in GNOME development. The biggest challenge I encounter with it is availability of existing bindings, which I think is important to persuading other developers to consider Vala (and GNOME), however, I can figure out how to wrap them for the most part.
The source code can currently be found here:
https://gitorious.org/rhythmbox-dj
Disclaimer: I am neither a vala nor a Rhythmbox expert, so I may give lots of bad advice below, so please send in corrections! For now, this has worked for me, though.
For a Rhythmbox plugin based on libpeas we want
The plugin file is in a .ini like format. We have [sections] and key=value pairs. We want one section, "[Plugin]", and the following keys, Module, IAge, Name, Description, Authors, Copyright, and Website. (I'm not sure which are strictly necessary; let me know if you do ;).
To manage this, we write djaqua.plugin.in
[Plugin]
Module=djaqua
IAge=2
_Name=Rhythmbox DJ
_Description=Announces tracks at start and close
Authors=Richard Schwarting <aquarichy@gmail.com>, James Livingston <doclivingston@gmail.com>
Copyright=Copyright © 2012 Richard Schwarting, James Livingston
Website=http://www.rhythmbox.org/
Name and Description will be visible in Rhythmbox's Plugins menu, and so we want them to be localisable, which is why we create an .in file and prefix two those fields with _. Since I haven't actually done much localisation before, I may not have done this step correctly. :D
These include directories,
plugindir: set to $(PLUGINDIR)/djaqua
plugindatadir: set to $(PLUGINDATADIR)/djaqua
gtkbuilderdir: optional, when using GtkBuilder for UI, set to $(plugindatadir)
Files,
plugin_LTLIBRARIES: points to our .la, libdjaqua.la
libdjaqua_la_SOURCES: set to our .vala source file
INCLUDES: set to a whole whack of things; some probably unnecessary :)
plugin_in_file: the plugin.in file that will generate our .plugin file
gsettings_SCHEMAS: optional if you use GSettings for preferences, ours is org.gnome.rhythmbox.plugins.djaqua.gschema.xml, which is a real file. :)
gtkbuilder_DATA: optional if using GtkBuilder, ours is djaqua.ui, and it's the XML file generated by Glade 3.
plugin_DATA: an expression evaluating to our .plugin file to be.
EXTRA_DIST: additional files to distribute, including our gtkbuilder_DATA file, our plugin files, and our GSettings schema. I might be specifying the wrong plugin file?
CLEANFILES: files that you want removed during make clean, should be most generated files, maybe not all; I might be omitting some
DISTCLEANFILES: files that you want removed during make distclean, should be all generated files that you don't absolutely need. Mine is just set to CLEANFILES right now. :)
Flags,
libdjaqua_la_LDFLAGS: Flags for linking, I use PLUGIN_LIBTOOL_FLAGS and -lspeechd (since I use speechd :D)
libdjaqua_la_CFLAGS: Any compilation flags; just using WNOERROR_CFLAGS here.
VALAFLAGS: Since my plugin is coded in vala, I have a bunch of flags I need to pass, like --vapidir's to find custom bindings, --pkg's to specify which packages/bindnigs I will use, and for my project, --thread, --target-glib
Some rules
@GSETTINGS_RULES@: this appears on its own line.
And some targets, like
%.plugin: includes a fancy rule that deals with internationalising the plugin description from the .plugin.in. I actually don't do that yet.
%.c %.h: generate .c and .h files from the .vala source.
Later, we'll also implement the PeasGtk.Configurable interface.
Within our plugin class, we'll require:
a "object" member: public GLib.Object object { owned get; construct; } This will be set by Rhythmbox after constructing your object to an Rb.Shell object, so you can access it.
an "activate" method: public void activate () This will be called when a user first activates your plugin, and subsequently when Rhythmbox starts and activates it. It should feature most setup.
a "deactivate" method: public void deactivate ()
an "update_state" method: public void update_state (). I actually didn't require this, so mine is empty.
Outside of the class, as its own method, we'll want a ModuleInit method, peas_register_type:
[ModuleInit]
public void peas_register_types (GLib.TypeModule module) {
var objectmodule = module as Peas.ObjectModule;
objmodule.register_extension_type (typeof (Peas.Activatable), typeof (DJAquaPlugin));
}
The most important required method will probably be "activate". To interact with Rhythmbox, you'll want to use the "object" member. I set it to a new RB.Shell variable, like "RB.Shell shell = (RB.Shell)this.object". You may also want access to the RB.ShellPlayer, which is a property within RB.Shell, so you can use "RB.ShellPlayer shell_player; shell.get ("shell-player", out shell_player);" to get a reference to it. From there, you can use their APIs to manipulate Rhythmbox and connect to their signals to interact with play.
In "deactivate", you'll want to clean up anything you set up in activate () that rhythmbox will no longer need. In my case, I set up a connection to Speech Dispatcher which I will then want to remove.
I wanted the user to be able to control a few settings for the plugin, mostly which voice they hear. For that, your plugin should implement PeasGtk.Configurable. This binding isn't shipped right now, so I created mine own, which I'll submit a patch for, and for now will be available with my code.
So, our class signature becomes this:
class DJAquaPlugin : Peas.ExtensionBase, Peas.Activatable, PeasGtk.Configurable {
and we impement the required method:
public Gtk.Widget create_configure_widget ()
There are some important points:
NOTE: To be able to locate the GtkBuilder file, I had to use RB.find_plugin_data_file (), which I needed to add a binding more. I'll submit a patch for that. There's autofoo in the Makefile.am that ensures it gets distributed (EXTRA_DIST I think) and will be where find_plugin_data_file looks.
<schemalist>
<schema id="org.gnome.rhythmbox.plugins.djaqua" path="/org/gnome/rhythmbox/plugins/djaqua/">
<key name="output-module" type="s">
<default>'espeak'</default>
<summary>Speech Engine</summary>
<description>The installed system to synthesise voice for you.
Different systems have different sets of voices and
quality. Some examples are flite, espeak, festival, etc. You
may need to install them.</description>
</key>
<key name="voice" type="s">
<default>'MALE1'</default>
<summary>Voice</summary>
<description>The voice to speak in.</description>
</key>
</schema>
</schemalist
I only have one schema in my schemalist, the one for my plugin. I have two keys; these can be numbers, sets of options, strings, etc. In my case, each key is associated with a single string value (the "s" for type indicates string). Each key has a default value, a summary (name), and a description of what the key is for.
NOTE: while working on this, I was installing everything under ~/.local, rather than into my system. GSettings currently only checks for setting schemas installed under XDG_DATA_DIRS (e.g. /usr/share and /usr/local/share) in a glib-2.0/schemas directory. That's fine, but you can't extend XDG_DATA_DIRS easily in your .bash_profile in the same way you can PATH or LD_LIBRARY_PATH, etc. Trying to do
XDG_DATA_DIRS=$XDG_DATA_DIRS:$HOME/.local/share
results in an almost broken GNOME session because XDG_DATA_DIRS isn't a known, set variable right while reading .bash_profile. :( Instead, for testing, I do
XDG_DATA_DIRS=/usr/local/share:/usr/share:$HOME/.local/share
in .bash_profile. Let me know if you have a better solution. I intend on filing a bug some day.
For code with settings, I created a GSettings object for my schema, and connected to its "changed" signal, so if a preference changed in the preferences dialogue, I could change the plugins behaviour (e.g. change the voice).
Inside my preferences code, I created its own GSettings object (my preferences code is in its own class), and bound the Gtk.ComboBox's I use to their corresponding GSettings. In particular, I set the "id-column" property on my Gtk.ComboBox's to be the string I needed to give Speech Dispatcher, and then bound the "active-id" property for the Gtk.ComboBox's to the settings. It got a bit confusing, but you can see the code yourself if you need something similar.
Vala can access other compiled libraries written in other languages: hooray! Unfortunately, it needs a .vapi file to tell it how to provide a Vala API for that library. Boo!, but necessary. There are parts of libpeas that are not bound yet, and libspeechd (Speech Dispatcher) was not bound at all. So, when working in Vala, sometimes you'll have to bind additional methods, or an entire library.
I created two custom bindings
Writing VAPI files is not that hard. You can look in /usr/share/vala-*/vapi to model a custom one off of those. In the .vapi file, you generally
I previously wrote djaqua which did this, but was written in Python. That bit rotted for me, and rather than updating it, I took an opportunity to try writing a Rhythmbox plugin in Vala. I really like Vala. Despite bugs, it works surprisingly well for what it tries to do, and it helps structure and simplify so much in GNOME development. The biggest challenge I encounter with it is availability of existing bindings, which I think is important to persuading other developers to consider Vala (and GNOME), however, I can figure out how to wrap them for the most part.
The source code can currently be found here:
https://gitorious.org/rhythmbox-dj
Disclaimer: I am neither a vala nor a Rhythmbox expert, so I may give lots of bad advice below, so please send in corrections! For now, this has worked for me, though.
For a Rhythmbox plugin based on libpeas we want
- a .plugin file describing it: generated from djaqua.plugin.in
- source code: rb-djaqua-plugin.vala
- a Makefile: generated from Makefile.am
- a PeasGtkConfigurable configure window, built from a GtkBuilder file: djaqua.ui
- a GSettings schema: org.gnome.rhythmbox.plugins.djaqua.gschema.xml)
- libpeas-gtk-1.0.vapi
- libspeechd.vapi
Plugin File
The plugin file is in a .ini like format. We have [sections] and key=value pairs. We want one section, "[Plugin]", and the following keys, Module, IAge, Name, Description, Authors, Copyright, and Website. (I'm not sure which are strictly necessary; let me know if you do ;).
To manage this, we write djaqua.plugin.in
[Plugin]
Module=djaqua
IAge=2
_Name=Rhythmbox DJ
_Description=Announces tracks at start and close
Authors=Richard Schwarting <aquarichy@gmail.com>, James Livingston <doclivingston@gmail.com>
Copyright=Copyright © 2012 Richard Schwarting, James Livingston
Website=http://www.rhythmbox.org/
Name and Description will be visible in Rhythmbox's Plugins menu, and so we want them to be localisable, which is why we create an .in file and prefix two those fields with _. Since I haven't actually done much localisation before, I may not have done this step correctly. :D
Makefile
Cryptic autofoo here. We will write a Makefile.am that will define many of the directories and flags we want to compile with.These include directories,
plugindir: set to $(PLUGINDIR)/djaqua
plugindatadir: set to $(PLUGINDATADIR)/djaqua
gtkbuilderdir: optional, when using GtkBuilder for UI, set to $(plugindatadir)
Files,
plugin_LTLIBRARIES: points to our .la, libdjaqua.la
libdjaqua_la_SOURCES: set to our .vala source file
INCLUDES: set to a whole whack of things; some probably unnecessary :)
plugin_in_file: the plugin.in file that will generate our .plugin file
gsettings_SCHEMAS: optional if you use GSettings for preferences, ours is org.gnome.rhythmbox.plugins.djaqua.gschema.xml, which is a real file. :)
gtkbuilder_DATA: optional if using GtkBuilder, ours is djaqua.ui, and it's the XML file generated by Glade 3.
plugin_DATA: an expression evaluating to our .plugin file to be.
EXTRA_DIST: additional files to distribute, including our gtkbuilder_DATA file, our plugin files, and our GSettings schema. I might be specifying the wrong plugin file?
CLEANFILES: files that you want removed during make clean, should be most generated files, maybe not all; I might be omitting some
DISTCLEANFILES: files that you want removed during make distclean, should be all generated files that you don't absolutely need. Mine is just set to CLEANFILES right now. :)
Flags,
libdjaqua_la_LDFLAGS: Flags for linking, I use PLUGIN_LIBTOOL_FLAGS and -lspeechd (since I use speechd :D)
libdjaqua_la_CFLAGS: Any compilation flags; just using WNOERROR_CFLAGS here.
VALAFLAGS: Since my plugin is coded in vala, I have a bunch of flags I need to pass, like --vapidir's to find custom bindings, --pkg's to specify which packages/bindnigs I will use, and for my project, --thread, --target-glib
Some rules
@GSETTINGS_RULES@: this appears on its own line.
And some targets, like
%.plugin: includes a fancy rule that deals with internationalising the plugin description from the .plugin.in. I actually don't do that yet.
%.c %.h: generate .c and .h files from the .vala source.
Source code: in vala
The plugin system is based on libpeas, so our plugin will be a Peas plugin. We're going to create a class named DJAquaPlugin that extends and implements Peas.ExtensionBase, and Peas.Activatable: class DJAquaPlugin : Peas.ExtensionBase, Peas.Activatable. I believe the order there matters.Later, we'll also implement the PeasGtk.Configurable interface.
Within our plugin class, we'll require:
a "object" member: public GLib.Object object { owned get; construct; } This will be set by Rhythmbox after constructing your object to an Rb.Shell object, so you can access it.
an "activate" method: public void activate () This will be called when a user first activates your plugin, and subsequently when Rhythmbox starts and activates it. It should feature most setup.
a "deactivate" method: public void deactivate ()
an "update_state" method: public void update_state (). I actually didn't require this, so mine is empty.
Outside of the class, as its own method, we'll want a ModuleInit method, peas_register_type:
[ModuleInit]
public void peas_register_types (GLib.TypeModule module) {
var objectmodule = module as Peas.ObjectModule;
objmodule.register_extension_type (typeof (Peas.Activatable), typeof (DJAquaPlugin));
}
The most important required method will probably be "activate". To interact with Rhythmbox, you'll want to use the "object" member. I set it to a new RB.Shell variable, like "RB.Shell shell = (RB.Shell)this.object". You may also want access to the RB.ShellPlayer, which is a property within RB.Shell, so you can use "RB.ShellPlayer shell_player; shell.get ("shell-player", out shell_player);" to get a reference to it. From there, you can use their APIs to manipulate Rhythmbox and connect to their signals to interact with play.
In "deactivate", you'll want to clean up anything you set up in activate () that rhythmbox will no longer need. In my case, I set up a connection to Speech Dispatcher which I will then want to remove.
Rhythmbox plugin configuration: Peas.Configurable
I wanted the user to be able to control a few settings for the plugin, mostly which voice they hear. For that, your plugin should implement PeasGtk.Configurable. This binding isn't shipped right now, so I created mine own, which I'll submit a patch for, and for now will be available with my code.
So, our class signature becomes this:
class DJAquaPlugin : Peas.ExtensionBase, Peas.Activatable, PeasGtk.Configurable {
and we impement the required method:
public Gtk.Widget create_configure_widget ()
There are some important points:
- every time you open the preferences, it calls create_configure_widget and expects a new widget
- every time you close the preferences, it destroys the widget you had previously given it
- therefore, you cannot be clever and save a reference to your widget once created and keep returning the same one; if you try, you'll encounter memory errors since your widget will have been unallocated.
- the widget should not be a window itself (in Glade, you can create top level widgets that are not windows)
NOTE: To be able to locate the GtkBuilder file, I had to use RB.find_plugin_data_file (), which I needed to add a binding more. I'll submit a patch for that. There's autofoo in the Makefile.am that ensures it gets distributed (EXTRA_DIST I think) and will be where find_plugin_data_file looks.
Rhythmbox plugin configuration: GSettings
GSettings requires a schema file be installed, as well as code to read and set your settings. You should have a namespaced ID for your settings. My namespaced ID is "org.gnome.rhythmbox.plugins.djaqua". My file is pretty simple, and looks like this<schemalist>
<schema id="org.gnome.rhythmbox.plugins.djaqua" path="/org/gnome/rhythmbox/plugins/djaqua/">
<key name="output-module" type="s">
<default>'espeak'</default>
<summary>Speech Engine</summary>
<description>The installed system to synthesise voice for you.
Different systems have different sets of voices and
quality. Some examples are flite, espeak, festival, etc. You
may need to install them.</description>
</key>
<key name="voice" type="s">
<default>'MALE1'</default>
<summary>Voice</summary>
<description>The voice to speak in.</description>
</key>
</schema>
</schemalist
I only have one schema in my schemalist, the one for my plugin. I have two keys; these can be numbers, sets of options, strings, etc. In my case, each key is associated with a single string value (the "s" for type indicates string). Each key has a default value, a summary (name), and a description of what the key is for.
NOTE: while working on this, I was installing everything under ~/.local, rather than into my system. GSettings currently only checks for setting schemas installed under XDG_DATA_DIRS (e.g. /usr/share and /usr/local/share) in a glib-2.0/schemas directory. That's fine, but you can't extend XDG_DATA_DIRS easily in your .bash_profile in the same way you can PATH or LD_LIBRARY_PATH, etc. Trying to do
XDG_DATA_DIRS=$XDG_DATA_DIRS:$HOME/.local/share
results in an almost broken GNOME session because XDG_DATA_DIRS isn't a known, set variable right while reading .bash_profile. :( Instead, for testing, I do
XDG_DATA_DIRS=/usr/local/share:/usr/share:$HOME/.local/share
in .bash_profile. Let me know if you have a better solution. I intend on filing a bug some day.
For code with settings, I created a GSettings object for my schema, and connected to its "changed" signal, so if a preference changed in the preferences dialogue, I could change the plugins behaviour (e.g. change the voice).
Inside my preferences code, I created its own GSettings object (my preferences code is in its own class), and bound the Gtk.ComboBox's I use to their corresponding GSettings. In particular, I set the "id-column" property on my Gtk.ComboBox's to be the string I needed to give Speech Dispatcher, and then bound the "active-id" property for the Gtk.ComboBox's to the settings. It got a bit confusing, but you can see the code yourself if you need something similar.
Custom Bindings
Vala can access other compiled libraries written in other languages: hooray! Unfortunately, it needs a .vapi file to tell it how to provide a Vala API for that library. Boo!, but necessary. There are parts of libpeas that are not bound yet, and libspeechd (Speech Dispatcher) was not bound at all. So, when working in Vala, sometimes you'll have to bind additional methods, or an entire library.
I created two custom bindings
- libpeas-gtk-1.0.vapi
- libspeechd.vapi
Writing VAPI files is not that hard. You can look in /usr/share/vala-*/vapi to model a custom one off of those. In the .vapi file, you generally
- specify a namespace
- specify enums and classes, that will want to know things like what
- the name of the underlying C structure is,
- what .h file declares its methods,
- what prefixes its types go by
- names of its public members
- names of its methods (and corresponding C names)
- any special considerations (e.g. how to handle array parametres)
- free, destroy, copy, and constructor functions
[General] Feeling happy and exercise
Yesterday, my friend Liljana suggested my soul was dead. I didn't know how to respond, but I understood what she meant. I sort of had no will to do anything. That obviously cannot be allowed to persist, so knowing that regular exercise makes me happy, I resumed my morning exercises (on vacation while I was on Christmas vacation) and forced myself to go to iaido. By the end of it, I was back to my chipper self. I wonder how consistent the effect is for me.
Subscribe to:
Posts (Atom)
Labels
#General
#Microblog
friends
#Technology
life
gnome
music
google
iaido
guelph
fedora
vegan
bugs
food
school
#GNOME
linux
technology
#School
jodo
blogger
gxml
#Budo
#Photos
work
web
nature
happy
vala
firefox
android
art
Flesherton
anime
internet
travel
home
open source
stress
kendo
kosmokaryote
writing
animals
birthday
dad
science
security
canada
computers
environment
future
cookies
development
german
language
photos
programming
reading
sick
sleep
snow
video
winter
GUADEC
cell phones
css
fun
learning
love
me
movies
people
phone
picasaweb
ta
time
christmas
evolution
vancouver
vegetarianism
#Vegan
Toronto
ai
git
gsoc
identity
new zealand
society
speech
vlogbrothers
adventure
birds
communication
dreams
facebook
google+
gseta
happiness
libgdata
netflix
night
responsibility
skedge
stars
tea
tv
video games
wind mobile
Nintendo
baking
cake
consumerism
design
fedora 17
javascript
memories
nlp
organisation
photography
quote
tablet
uoguelph
Josh Ritter
animalia
blogging
books
bug
encryption
family
humanity
magic
meaning
memory
money
pidgin
rain
recipes
speechdispatcher
sushi
weather
#Reading
Spain
TAing
The Frames
cat
chocolate
cold
cycling
death
emusic
film
flight
genderguesser
gitorious
halloween
health
knowledge
languages
liv
mail
new years
nightmares
politics
productivity
psychology
software
swords
the legend of zelda
ubuntu
web development
xml
xorg
youtube
Thanksgiving
acer
bc
busy
change
conversation
cooking
duolingo
emacs
fedora 18
galaxy nexus
gay rights
gmail
japan
libxml2
martial arts
materialism
mozilla
nerdfighteria
nostalgia
privacy
rhythmbox
sound
space
university
upgrade
valentines
wahoo
walking
water
web design
Con-G
Europe
John Green
Scott Pilgrim
age
animal welfare
apple
autumn
bash
blog
brain
brave
breath of fire II
calm
camera
canada day
clothing
comments
confidence
conservation
creativity
culture
dance
dataloss
djaqua
duplicity
e-mail
emotion
english
errors
feminism
gdom
germany
goals
google reader
gtk
humour
intelligence
japanese
laundry
law
light
math
morning
moving
ottawa
peterborough
pets
philosophy
pie
quality
research
sei do kai
shopping
spring
style
summer
value village
vday
vonage
website
x11
#Life
New York
alone
anime north
anxiety
argument
backup
budo
buffy
business
cats
computer science
concert
copyright
data loss
diy
eating
economy
education
energy
exercise
failure
fedora 19
feelings
file systems
flowers
freedom
french
friend
games
gdata
greyhound
growth
habits
heat
history
house
html
ice cream
im
information
java
joy
koryu
laptop
living
lost
microsoft
mood
moon
muffins
mystery
news
nz
pain
photo
php
physics
pirates
pizza
play
poverty
preupgrade
progress
purple
python
rae spoon
reality
reflection
religion
rss
self
serialisation
sharing
skating
social
sun
synergy
tachi uchi
testing
themes
thesis
thinking
thought
thoughts
transit
turtles
veggie challenge
velociraptors
violin
weekend
weird
yum
zellers
API
Air Canada
Empathy
Grimes
Hank Green
Hugo
Jane Austen
Lord of the Rings
Nexus One
OCUS
Sudbury
Trick or Eat
arboretum
audible
autonomous automobiles
beauty
bike
blogs
browsers
camping
cancer
canoeing
celebration
charity
chrome
cleaning
colour
community
content
corporations
crafts
decay
decor
depression
depth
disaster
drawing
epic
equality
experience
faery fest
farmer's market
fedora 12
fedora 16
fedora 20
fedora 22
fedup
fireworks
gender
ghetto
ghosts
glib
gnome blog
gnome shell
google talk
green
hair
hobocore
hungry
icarus
instant messaging
interest
introspection
jobs
last exile
luks
macbook
mail-notification
mario
meat in vitro
mind
mom
moon festival
motivation
mtp
ninjas
oh the humanity
pagans
pants
papers
past
performance
perl
phones
picnics
pitivi
plastic
pride
pumpkin
pumpkin pie
quiet thrill
receipts
rogers
rpm
seminar
sewing
simple
simplicity
sleep deprivation
smells
soy milk
speech dispatcher
sports
stories
story telling
strange
streamlines
swimming
telephone
temperature
texting
thrift stores
time management
time travel
tragedy
truth
understanding
united states
urban ecosystems
usability
usb
veganism
voice
volunteering
webschwerver
wild
wireless
working
world
yojimbo
zoology
Avatar: The Last Airbender
Blassreiter
CIS*2750
CIS*6890
Czech Republic
Diablo
Dresden Codak
Dunedin
Dutch Blitz
Electric Networked Vehicle
Elliott Brood
Ender's Game
France
Fringe
GNOME 3
HTC
Hayao Miyazaki
Mario Kart
Montréal
Network Manager
Newfoundland
Nintendo Switch
Ontario
Ouran Host Club
Richard
SVC
Samsung
Samurai Champloo
Santa Claus
Studio Ghibli
TCAF
US
academics
adb
advertising
aeroport
algonquin
amusing
animal agriculture
apartment
ask
automation
awkward
bad movies
banana
bats
battery
beard
belladonna
beta
bicycle
book
branding
breakfast
brno
bus
buses
buy nothing day
cabin
calgary
candy
cards
cars
catastrophe
celebrate
celtic
chat
cheap
cheese
childhood
china
chinese calendar
cities
clarity
clean
clock
comics
compassion
compiler
computer
conspiracy theorists
consumption
context
convention
cookie
cool
cornerstone
cosplay
cottage
country
court
creation
cthulhu
cupcakes
curiosity
cute
dancing
dark themes
dbus
definition
deja-dup
democracy
despair
detachment
dinosaurs
discomfort
dns
dodgeball
dragon
dress
dust
dystopia
earth
earth day
efficiency
eggs
elections
email
enhanced history
ethics
evil
exhausted
expectations
exploring
ext3
ext4
fail
fair trade
fall
fashion
favourite
feedly
ferry
focus
fonts
formal
free
friendship
fruit
fudge
full moon
furniture
gaelic
game boards
garden
gardening
gee
generosity
genetics
gimp
gir
gobject
good
google hangouts
google wave
government
grading
gratitude
green roofs
groups
gsec
guerilla gardening
haircut
hakama
help
homosexuality
honesty
howl
hp
human rights
humanitarianism
humility
hypocrisy
ice
images
imaqua
instagram
integration
intellectual property
internet explorer
jabber
jazz
jelly bean
jokes
kernel
keyboard
knife
labs
last exile: fam the silver wing
laurena
lazy
letters
library
libxml
livejournal
lizzie bennet
loneliness
loss
lovely
lyrics
maps
maturity
meditation
melancholy
metadata
microbes
microfinancing
microwaves
moon cake
morality
mother
music concert
muso jikiden eishin ryu
myth
namespaces
nasa
nautilus
nerdfighter
neural networks
nintendo 3ds
normal
normality
notes
obsolescence
oceans
open
open souce
open standards
panasonic
paper
parties
patches
peanut butter
perception
personal
perspectives
philanthropy
plants
pleasant
poem
politeness
potluck
preparation
problems
ptp
pulseaudio
quidditch
racism
recreate
redundancy
relationships
relax
repairs
resizing
richard's room
roomba
roses
rsync
running
sad
sadness
salsa
samurai
sanity
scary
schwarting
seasons
self-esteem
self-navigating car
selinux
semiformal
senility
sensitivity
sentimental
sheep
ships
silicon motion
sleeping in
sms
social justice
software engineering
solitude
solutions
songs
soup
speed
spelling
ssh
star wars
strangers
stupid
success
sunset
surreality
survival skills
suspense
sustainability
sweet
sympathy
symphony
tardigrades
tasks
teaching
technical communication and research methods
test
tests
thrift
tim tams
time and space
tired
tools
tracker
tradition
tranquillity
transience
trees
trust
tumblr
twitter
update
user experience
utopia
via
vihart
vlog
waffles
warmth
waste
waterloo
wave
web comic
webfonts
webkit
wii
wiki
winter is coming
wizard
wonder
woods
words
xmpp
yoga
youth
zoo
#Gaming
#Wishlist
#anime #general
1. is anyone reading this?
1602
1984
2. you win a prize!
2008
2014
24fps
3. gimme a call to collect
404
A Short Hike
All My Children
Andy Griffith
Argentina
Armstrong House
Avatar: The Legend of Korra
BarTab
Beach House
Boston
Boston Summit
British Columbia
Businesses
C
CIS*6050
Cambridge
Christopher Plummer
Claymore
Creatures
Darker than Black
David Attenborough
Dear Wendy
Docking Station
Dollhouse
Earthbound
England
Excalibur
FOMO
February
Fergus
Final Fantasy IX
Fire Emblem
GError
GNOME Files
GSA
Go
Google Play Music
Hunger Games
I am not okay with this
I believe in a thing called love
I'm a wizard
IRC
Ikea
Ireland
JRR Tolkien
King Arthur
Lost Lagoon
MIT
Mac OS X
Madrid
March
Massachusetts
Matlock
McGuinty
Melodies of Life
Merlin
Michael Cera
Mother Mother
Mr. Tumnus
Narnia
Neil Gaiman
New York Philharmonic
Nick and Norah's Infinite Playlist
Nintendorks
Norns
North Korea
NotesFromNewYork
Olympic
OpenShot
Orphen
Orson Scott Card
Oscars
PEAP
Pauline Johnson
Pete Peterson
Planet Fedora
Porco Rosso
Questionable Content
R
ROM
Rent
S
SIM Wireless
Sauble Beach
Sega
Sega Genesis
Selenium
Shakespeare
She-Ra
Snakes and Lattes
Splatoon
Star Trek
Steve Grand
Stranger Things
ThanksLiving
The Darkness
The Devil is a Part-Timer
The Fifth Estate
The Guild
The Hobbit
The Stand
Tianjin
Tim Hortons
Tolkien
UI
UK
UX
VPN
Will Grayson Will Grayson
Wolves in the Wall
WordPerfect
Xiki
[General]
abrt
absolutism
abuse
academia
accessibility
active
activism
activity
addiction
adreama
adrift
adulthood
advertisement
air
airport express
airship
ajax
al gore
alarm clock
albums
aldiko
alice in wonderland
alien
alistair summerlee
amateur
amazon
ambience
ambition
amy winfrey
anaconda
and imperfection
angle
angry birds
anhosting
animal cognition
animation
anon
anonymity
ant
apache
apology
appearances
appreciation
aqualab
arcade
architecture
arduino
arrogance
assassins
assignments
association analysis
astrid
asus eee top
asynchronous
ati
attachment
attitude
attribution
audio
aural abuse
authentication
authenticity
automake
automarker
avatars
awesome
b43
backpain
backtrack3
backyard bounty
bad
bagel
bandwidth
banjo
banks
barbarians
barefoot
baseball
bathroom
beaches
beautiful
bed
bees
beetles
being
belief
bellaqua
benedict cumberbatch
berlin
bertrand russell
bill gates
biofabrication
biology
biometrics
bit rot
bitcoin
black and white
blame
blockbuster
bloomberg
blue
board games
bohemian
bold
bon thé place
bonds
border
boredom
botany
boxing day
boy
brain scoop
brickworks
broadcom
broccoli
browsing
bubbles
bubbly
buildings
bunnies
burn
bus stops
butterflies
buttons
c#
c++
cafe
calendaring
calligraphy
camel
camera obscura
cameras
canadian english
canopy
capitalism
captivity
careless
caring
cast
causality
cbc
cedar row
cello
censorship
certainty
cgi
chalk
challenger
changing locks
chaos theory
charm
cherry blossoms
chickadee
chickens
chivalry
choir
chopsticks
chores
christchurch
christianity
chudan
church
cijf
cinnamon
classes
clif
clorox
clorox green works
cloud
cloud atlas
clubs
cname
coca cola
codeine
codeviz
cognition
coincidence
coins
color
comfort
commons
communism
competence
competition
competitive coughing
complaints
completeness
compliments
conference
configuration
conflicted
confusion
consciousness
consent
conservatives
conservativism
console
construction
constructive criticism
contagion
contest
contributing
convenience
corpses
cough suppressants
coughing
coupons
courageous
crashes
crates
crayons
crazy
creative commons
criminals
crisps
criticism
crosscanada
crowd
crtc
cry
crying
cryptic
cryptozoology
csh
cuddles
cult
currency
current tv
curse
customer service
customisation
cuttlefish
cvs
daily grind
data
data mining
databases
dating
david bowie
dconf
debate
debug symbols
debugging
delicious
design patterns
desktop
desktop summit
destiny
dftba
diet
difficult
digimon
digital receipts
disabilities
disappointment
discordianism
discourse
discoverability
dispute
dissection kit
distraction
diyode
dnf
doctor who
doctors
documentation
dokuwiki
doubt
doughnut
dpkg
drab
drano
drano prevention
dream
dreaming
drinking
drm
drowning
dryers
drying
dtwydt
ducks
dvds
dying
dynamic typing
ease
easter
easy
ebony jewelwing
ebooks
ecards
economics
editors
eeetop
el paso
elder neglect
electronic receipts
elements
elitism
ellen page
embarrassment
emily graslie
emptiness
empty
enchant
end of
enterprising
environmental science symposium
eog
epiphany
eplugin
equipment
essentialism
ether
euphoria
evoaqua
experiment
experimenting
expertise
extensions
extortion
facades
faith
falafel
familiarity
fan
fancy
fantasy
fascism
faun
favicon
fears
fedora 11
feed me
feedback
festival
fibonacci
fiction
fiddler crab
field guide
field identification
figment
figures of speech
file formats
finances
fire
fish
fitness
fixing
flac
flash light
flesherton fling
flexibility
flour
flow
flying
footprints
forceps
forgottotagit
fork
fortunate
fortune
found
fragaria
frameworks
fraud
fred penner
free time
freezing
french fries
fresh
friday
friend's wedding
frog
fspot
funding
funerals
funny
fury
fuse
gargoyles
gdb
geek
geeks
gf3
gi
gifts
gio
gitlab
gjs
glass
globalnewtgames
glory
gloves
glue
gluten
gm
gmo
gnome keyring
gnome software
gnome-control-center
go ninja go
go transit
goat
gods
goodbye
goodfella's
google assistant
google books
google calendar
google chrome
google wallet
gp2x
gqe
grad
graffiti
grammar
graphing
graphviz
grass
green beaver
grey county
groceries
growing up
gtest
gtg
guts
gvfs
gvfs metadata
gypsies
habit
hal
halls
hard
hard drive
hard drives
hardship
hardware
harry potter
hdtv
heart
heart break
heaven 17
hemlock grove
hewlett packard
hijinx
hiking
hoaxes
hobbies
holidays
homelessness
homework
honey badgers
honour
horatio hornblower
horror
hostels
hosting
hot
house of cards
hp lovecraft
hugs
humblebundle
humbleness
hunting
hyperlinking
hyrule
i am a carpet
ibm thinkpad x41
icalendar
ice cream sandwich
ice rain
icthyology
ignorant
ill
image
image editing
imagination
impermanence
inadequacy
inaturalist
inconvenience
independence
india
individuals
industry
infinity
ingrid michaelson
inhumanity
injuries
ink
innovation
insects
installation
intel
interactivity
interlocutor
internet tv
invertabrates
io
irish
irony
isolation
it
it is indigo
james bond
java 13
jedi
jikiden
joke
journalism
journey
judgement
julian assange
julie thiel
justice
kata
kayak
keys
ki-ai
killme
kim taylor
kinder
kindness
kirby
kitchen
kitzl
kiva
knights
knots
kodak
koodo
kung fu
labels
landau sacamoto
late
laundromat
led
legend
lending
lenovo
lessons
letsencrypt
letstrace
letter writing
liberalism
liberals
libnotify
libreoffice
librpm
lifehacker
lilo
limericks
limits
linksys
liquid
lists
live wallpapers
livecd
liveusb
loans
local
local food
local install
login
london
losher
lots of hugs
mac mini
machine learning
machine vision
madness
mae
magic school bus
magical
maintainership
majesty
malaria
malls
mantis shrimp
marine life
marketing
marking
massages
matrices
maturation
may seminar
meat
media
medicine
mel's diner
memory leaks
mental health
meow
mercy
messaging
metacity
metaphor
methodology
mezzo forte
micropayments
mild
mild weather
military
milk
mindhacks
minimalism
misanthropy
miscellany
misery
misfortune
missed the boat
missing
mlp
modelling
moisture
mold
molly parker
monitors
monologue
more cats
mosquitoes
moss
mother's day
mounting
mouse
moxies
muffin
muffinfilms
mundane
murder
museum
mushishi
mushroom soup
mushrooms
musicals
mutual funds
my slumbering heart
mysql
nameservers
nanowrimo
national treasure
natural language processing
naturalism
nausicaa
navigating
necessity
neighbours
nervous
netgear
network
new
new users
newspaper hat
next year
ninja turtles
nodelist
nointernet
noise
noisy
nominate
non-root
norse
noses
not really dying
notebooks
notification-daemon
novels
november fair
nuclear war
numbers
numix
obama
obligation
obliviousness
obscure
ocz
ogg
oggenc
olap
olive
omote
open formats
open music
openness
openoffice
optimisation
optimism
orcas
orchestra
oreo
oreos
org-mode
origami
oscar
otr
overheat
owen sound
package management
packagekit
packing
paint shedding
pan
pancakes
panda
parallelism
paranoia
passport
patents
patience
pattern recognition
pdo
peace
peaceful
pen
pence
pender
penguins
penmanship
perfection
pet rocks
physical
piano
pickman's model
picnik
pidgin plugins
pikmin
pintsize
pipelight
pirate festival
pizza hut
plagiarism
planning
plans
playground
playlists
plumbing
plushies
podcast
poetry
points
pokemon
polls
pomplamoose
positions
posse
post
posters
postmodernism
potatoes
potlucks
power
ppc
practise
prejudice
premier
pressure
pretty
pride and prejudice
priorities
private
processes
professionalism
progressive web apps
projects
promise
protest
proud
purchases
pwa
qt
quarantine
rad
radeon
railroad
randall munroe
raop
rats
reagan
recursion
recycling
redhat
reductionism
refactoring
refrigerators
regret
relativism
release
renew
renfrew
repetition
report
resolutions
resolve
resumes
reuse
reuters
reviews
revolution
rhino
rhps
ricola
risk
road trips
roar
robots
rockwood
rot
rover
rtm
ruby day
ryu
safety
sanctuary
sand
satisfaction
savages
scary movies
scheduling
schneier
scholarships
scooters
scp
screenshots
script
seals
search
secret world of arrietty
secrets
seitei
self-interest
self-respect
self-sufficiency
self-worth
semesters
senescence
sessions
setbuilder
settlers of catan
sftp
shame
sheepo pistachio
sheila patek
shell
shells
sherlock holmes
shipping
shogun
shotwell
shoulder bag
sigh
signal
sim city
simafort
simpsons
sincerity
singing
sjr
skill
skunks
sky
slackware
slashdot
sliver
small
smartphones
smiling
snails
sneezing
snowboarding
soccer
social dance
social media
socis
soft
solemn
someonesmotherwantstoadoptme
song
sony
sophistication
sorbet
sorrow
sparklers
speed river
spell
spellchecking
spies
spilt milk
splendid
splendor
splinter
spoilers
sponges
sql
squaresville
sr
ssd
sshd
stanley park
starry night
starving
steampunk
storage
strawberries
strength
structured information
struggle
stuff
stylus
suburi
sucks
sugar
super mario
super mario land 3d
superiority
superstition
surprise
surprises
surreal sushi
surrender
swings
systemd
systems
tabs
tachi uchi no kurai
tail coats
tameshigiri
tarot
taxes
tears
technocracy
teddy bears
tedtalk
term
termcap
terror
the duke
the fault in our stars
the hulk
the human league
the irregular at magic high school
the onion
theatre
theory
thingsidon'twanttodo
tim berners-lee
tim mcgraw
timber timbre
timeliness
tin tin
toaster
todo
toilets
tolerance
tonight
toomuch
touch screen
touchpack
tour
tourniquet
towels
toys
trac
trailer
translation
travel buddy
treestyle view
trex
triumf
triumph
trivia
trouble
tweak
twist
tx2500
tx2617
typing
ugly logos
umbrellas
un dinaru
underwold
unemployment
universe
unlimited blade works
updates
upgrades
uploading
urban agriculture
urban ecology
urchins
vagrancy
vagrant
vague but exciting
valadoc
validation
values
vampires
vanilla ice
variety
vegetables
velvet burger
verb
version control
vi
vinegar
violence
voip
vpnc
vulnerable
waf
wandering
wanting
war
warm
wayland
weapons
web hosting
webcomic
webcomics
werewolves
whales
what a wonderful town
whatsbetter
whic are also lazer powered
white spot
wifi
wii u
wikisource
will
williams
wings
wisdom
wishes
wizardry
wolf
wonderland
wordplay
world cup
world water day
writing voice
xenophobia
xephyr
xinput
xkcd
xpath
yahoo
yay
yyz
z-index
Blog Archive
-
▼
2013
(218)
-
▼
January
(11)
- [Microblog] Transient Turtles
- [Microblog] Transient Satisfaction
- [General] JOSH RITTER!
- [Microblog] Photo back log
- [Microblog] Embarrassment
- [Technology] "sudo:effective uid is not 0, is sudo...
- [Technology] Fedora 18 Beta, FedUp, and GNOME Shel...
- [Microblog] Transient Errors
- [General] Moving Out
- [Technology] Writing a Rhythmbox Plugin: Rhythmbox DJ
- [General] Feeling happy and exercise
-
▼
January
(11)