/* * Zeitgeist * * Copyright (C) 2010, 2012 Michal Hruby * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . * * Authored by Michal Hruby * */ using Zeitgeist; public class DesktopLaunchListener : DataProvider { public DesktopLaunchListener (DataHub datahub) { GLib.Object (unique_id: "com.zeitgeist-project,datahub,gio-launch-listener", name: "Launched desktop files", description: "Logs events about launched desktop files using GIO", datahub: datahub); } // if vala didn't have bug in construct-only properties, the properties // would be construct-only public override string unique_id { get; construct set; } public override string name { get; construct set; } public override string description { get; construct set; } public override DataHub datahub { get; construct set; } public override bool enabled { get; set; default = true; } public override bool register { get; construct set; default = true; } private GLib.DBusConnection bus; private uint launched_signal_id = 0; construct { try { bus = GLib.Bus.get_sync (GLib.BusType.SESSION); } catch (IOError err) { warning ("%s", err.message); } unowned string desktop_env = Environment.get_variable ("XDG_CURRENT_DESKTOP"); if (desktop_env != null) { DesktopAppInfo.set_desktop_env (desktop_env); return; } } public override void start () { if (launched_signal_id != 0) return; launched_signal_id = bus.signal_subscribe (null, "org.gtk.gio.DesktopAppInfo", "Launched", "/org/gtk/gio/DesktopAppInfo", null, 0, this.signal_received); } private void signal_received (GLib.DBusConnection connection, string? sender, string object_path, string interface_name, string signal_name, Variant parameters) { // unpack the variant Variant desktop_variant; VariantIter uris; Variant dict; int64 pid; parameters.get ("(@aysxas@a{sv})", out desktop_variant, null, out pid, out uris, out dict); string desktop_file = desktop_variant.get_bytestring (); if (desktop_file == "") return; // are we going to do anything with these? string uri; while (uris.next ("s", out uri)) { debug ("ran with uri: %s", uri); } // here we should be able to get info about the origin of the launch HashTable extra_params = (HashTable) dict; DesktopAppInfo? dai; string launched_uri = Utils.get_actor_for_desktop_file (desktop_file, out dai); if (launched_uri == null) { warning ("Unable to open desktop file '%s'", desktop_file); return; } string? launcher_uri = null; unowned Variant origin_df = extra_params.lookup ("origin-desktop-file"); if (origin_df != null) { launcher_uri = Utils.get_actor_for_desktop_file (origin_df.get_bytestring ()); } else { unowned Variant origin_prgname = extra_params.lookup ("origin-prgname"); if (origin_prgname != null) { unowned string? prgname = origin_prgname.get_bytestring (); string origin_desktop_id = prgname + ".desktop"; DesktopAppInfo id_check = new DesktopAppInfo (origin_desktop_id); if (id_check != null) launcher_uri = "application://%s".printf (origin_desktop_id); } } if (!dai.should_show ()) { // FIXME: do something else? Log with WORLD_EVENT? return; } var event = new Zeitgeist.Event (); var subject = new Zeitgeist.Subject (); event.actor = launcher_uri; event.interpretation = ZG.ACCESS_EVENT; event.manifestation = ZG.USER_ACTIVITY; event.add_subject (subject); subject.uri = launched_uri; subject.interpretation = NFO.SOFTWARE; subject.manifestation = NFO.SOFTWARE_ITEM; subject.mimetype = "application/x-desktop"; subject.text = dai.get_display_name (); var arr = new GenericArray (); arr.add (event); items_available (arr); } public override void stop () { if (launched_signal_id != 0) { bus.signal_unsubscribe (launched_signal_id); launched_signal_id = 0; } } }