Friday, January 29, 2016

Avoiding Unsafe Code in Vala

CSharp uses the 'unsafe' keyword to mark sections of code that ignore type safety. Vala doesn't have this,  but if it did, if would apply to variable length argument lists.

What's wrong with variable length arguments? The tutorial shows a great use case:

actor.animate (AnimationMode.EASE_OUT_BOUNCE, 3000, x: 100.0, y: 200.0, rotation_angle_z: 500.0, opacity: 0);

Coming from a scripting world, this looks like a friendly idiom. In fact, this example has a bug that causes unpredictable results. See that last parameter 'opacity: 0'? That '0' should be a '0.0', because the receiving method:

double val = l.arg();

is requesting a double. Now the stack is out of alignment. If you are lucky, your program will crash with a segmentation fault. Lucky? Yes, because any other result is unpredictable. In my case, the values of all 4 variables became changed to 0, and the program continued running. But the other part of the example seemed to work correctly:

actor.animate (AnimationMode.EASE_OUT_BOUNCE, 3000, "x", 100.0, "y", 200.0, "rotation-angle-z", 500.0, "opacity", 0);

This was giving me the correct results. So I assumed that the problem was with the alternate syntax, which uses a colon. Then I swapped the two, expecting the error to move with it. But it didn't. Now the alternate syntax was working. That should have been my first clue that there was a memory corruption. Instead, seeing that I was using an older version of Vala libraries, I upgraded to the newest. And the problem went away. I thought I'd fixed it. But it wasn't fixed.

I was wrong. Later the next day, it started doing it again. Sorry stackoverflow, you were right. It's been a long time since I've coded using c.

That's when I noticed the '0'. I changed that to '0.0' and it started working. This is how a memory bug presents in C - it wants you to pull your hair out. My advice - don't use variable length argument lists. This 'wolf in sheeps clothing' masquerades as a friendly looking idiom but it's not.

Wednesday, January 27, 2016

What's up with Vala?

The vala landscape is strewn with abandonware. The Gnomite wiki has more dead links than a Gnecrominicon. Vala 1.0 , the next version afer 0.4 never materialized, and the roadmap this link refers to is now itself just another dead link.

But something is happening - Geary is built with Vala, as is the ElementaryOS desktop that I currently love. Version 0.30 was release last fall (still no version 1.0). So there must be something to this. Right?

Maybe - if there were some viable tooling. I spent about a week trying to get various dev tools from Gnome to work. Only 1 would actually install and run - Valama - and it is very unfinished. There is always Geany, but that is so last millenia.

So I've decided that it's best for me to ignore all of that Gnomite stuff. I'm starting over using Atom. I've installed the language-vala plugin. I'm using my own simple make script, and run it using atom-buil plugin. I modified autocomplete-clang to include vala - (You're welcome to try it, but I'll warn you that it, too, is unfinished. But then, the bar is pretty low :)) - And I'm just now starting to get productive.

Now I'm trying to find a unit test that actually works. Honestly - is there any other language whose ecosystem is in such shabby state? It is said that there are 2 kinds of computer languages. The ones that everyone complains about, and the ones that no one uses. Maybe there just haven't been enough complaints about  Vala.

Wednesday, January 20, 2016

Order Out Of Chaos - Finding My Desktop in Elementary OS / Freya

I'm becoming a fan of the Elementary design aesthetic. At first I fought it. I replaced Plank with Docky, only to realize that this added no functionality, just distractions. So I've gone back to the minimalistic, focused desktop that Freya delivers.

In the end, I have only 1 thing I need to change - I need to be able to put files on my desktop. Some 3rd party software will bork without this - try to 'Add to Desktop' in Chrome or create a desktop shortcut in any IntelliJ IDE.

So, to start with, I just created a ~/Desktop folder. This solves the issues with applications that expect a Desktop folder. But it's still not convenient. I found this excellent article https://elementaryforums.com/index.php?threads/enable-desktop-icons-and-right-click-in-elementaryos-freya.198/ which gives me back my standard desktop.

But now I have a new problem. When I click on my Home icon, is opens in nautilis, not the native pantheon-files. I end up using 2 different file managers at the same time, and this is the road back to the typical Linux chaos that I'm trying to avoid.

So, first, lets go back into dconf-editor and roll back one change. Under org->gnome->nautilis->desktop and set the home-icon-visible, network-icon-visible, and trash-icon-visible properties off.

Next, open scratch, and enter:


#!/usr/bin/env xdg-open
[Desktop Entry]
Version=1.0
Terminal=false
Type=Application
Name=Bruce
Exec=pantheon-files /home/bruce
Icon=/usr/share/icons/elementary/places/64/user-home.svg

Instead of 'bruce', use your own account name. Save it as ~/Desktop/Home.desktop
Make it executable:

$ chmod +x ~/Desktop/Home.desktop

Now we have our own custom Home icon. When we click on it, it will open our home folder in the native file manager. We have restored our working desktop and minimized the chaos.

Tuesday, January 19, 2016

Using Gmail Inbox Tabs in Geary

I'm one of those odd people that likes the Gmail inbox tabs. I don't even customize them, they work just great for me out of the box. Mainly, I just don't like to think about my email. Which is why I'm liking Geary. But it doesn't see my Gmail tabs. Actually, any client will have this problem, not just Geary. Gmail doesn't export the property. But there is a way around this by using filters.

I'm not going to show you how to create filters - Google has better help than I can give you - just search for 'gmail filters'  https://support.google.com/mail/answer/3055016?hl=en.

So, a filter is basically a saved search, and we can set some rules. By selecting the tab as our search criteria, we can create a filter based on a tab. To create a label for the Forums tab, I set these options:



WARNING: This is destructive. When this is working, your tabs will always be empty. But you'll need to leave them active for this to continue working. So Gmail won't look as pretty, cause you'll always have those empty tabs sitting there.

Do the same for each tab. When you are done, and you click on the tab, it will now be empty. The contents will be auto archived and labeled with the same name as the tab. And now, you can view them as Labels in Geary.


Sunday, January 10, 2016

Using Coffee Script for Gnome Desktop Scripting

The Cinnamon desktop uses javascript for scripting applets and desklets. Specifially, it uses an older version of spidermonkey. I'm not sure which, but it includes only 2 ES6 features - let and const. No other new, more useful ES6 features seem to work. This is troubling, since the semantics for let and const have changed - only slightly, but enough to break some plugins.

So basically, desktop scripting in Gnome, and therefore Cinnamon, is stuck with a deprecated version of javascript. Since most of my javascript is for the browser, I don't really want to learn how to use it the wrong way. But we know a fix for this - Coffee Script!

Applet = imports.ui.applet
GLib = imports.gi.GLib
Util = imports.misc.util
Gettext = imports.gettext.domain('cinnamon-applets')
_ = Gettext.gettext

class MyApplet
    __proto__: base = Applet.IconApplet.prototype
  
    name: 'Gracie'

    constructor:(orientation)->
        base._init.call(this, orientation);
        try 
            @set_applet_icon_name("gnome-info")
            @set_applet_tooltip(_("Say Hello, #{@name}"))
            return
        
        catch e
            global.logError(e)
            return
            
    on_applet_clicked:(evtdata) =>
        notification = "notify-send \"Hello #{@name}\"  -a TEST -t 10 -u low"
        Util.spawnCommandLine(notification)
        return
        

main = (metadata, orientation)-> new MyApplet(orientation)


Note there is now no need for Lang.Class and Lang.Bind. Insted of coffee's extend, I've set the __proto__ property. You can still use extends for your own class hierarchy, but for a GObject based hierarchy, you'll need to use __proto__.

Compile with the bare flag:

$ coffee -bc applet.coffee

And breath some new life into that stale interface!