File: unity-extra-utils.vala

package info (click to toggle)
libunity 7.1.4%2B19.04.20190319-5
  • links: PTS
  • area: main
  • in suites: bullseye
  • size: 1,636 kB
  • sloc: makefile: 704; python: 399; ansic: 141; sh: 9; xml: 7
file content (131 lines) | stat: -rw-r--r-- 4,650 bytes parent folder | download | duplicates (3)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
/*
 * Copyright (C) 2012 Canonical Ltd
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 3 as
 * published by the Free Software Foundation.
 *
 * 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 General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 *
 * Authored by Pawel Stolowski <pawel.stolowski@canonical.com>
 */

[CCode (gir_namespace = "UnityExtras", gir_version = "1.0")]
namespace Unity.Extras
{
  private static const string FILE_MANAGER_DBUS_NAME = "org.freedesktop.FileManager1";
  private static const string FILE_MANAGER_DBUS_PATH = "/org/freedesktop/FileManager1";

  public delegate void CreateScopeCallback ();

  [DBus (name = "org.freedesktop.FileManager1")]
  internal interface FileManagerInterface: GLib.Object
  {
    public abstract async void show_items (string[] uris, string startup_id) throws Error;
    /* These methods are currently unused
    public abstract async void show_folders (string[] uris, string startup_id) throws Error;
    public abstract async void show_item_properties (string[] uris, string startup_id) throws Error;*/
  }

  /**
   * Opens file manager showing given uri in its parent folder.
   * It tries to activate file manager using org.freedesktop.FileManager1 interface first and if it fails,
   * uses GLib.AppInfo.launch_default_for_uri.
   */
  public async void show_in_folder (string uri) throws Error
  {
    string[] uris = {uri};

    var file = File.new_for_uri (uri);
    if (file != null)
    {
      File? parent_dir = file.get_parent ();
      if (parent_dir != null)
      {
        // try to launch file manager via dbus interface first
        try
        {
          FileManagerInterface service = yield Bus.get_proxy (BusType.SESSION, FILE_MANAGER_DBUS_NAME, FILE_MANAGER_DBUS_PATH);
          yield service.show_items (uris, "");
          return;
        }
        catch (GLib.Error e)
        {
          warning ("Failed to activate file manager via dbus: '%s', uri '%s'", e.message, uri);
        }

        // fallback
        GLib.AppInfo.launch_default_for_uri (parent_dir.get_uri (), null); // may throw
        return;
      }
      else
      {
        throw new GLib.IOError.FAILED ("Failed to get parent dir for uri: '%s'".printf (uri));
      }
    }
    else
    {
      throw new GLib.IOError.FAILED ("Failed to create file object for uri: '%s'".printf (uri));
    }
  }

  /**
   * Check if a given well known DBus is owned. Failure (exception) means ownership couldn't be determined.
   * WARNING: This does sync IO!
   *
   * @param name DBus name to test for availability
   * @return true if name is available
   */
  public static bool dbus_name_has_owner (string name) throws Error
  {
    bool has_owner;
    DBusConnection bus = Bus.get_sync (BusType.SESSION);
    Variant result = bus.call_sync ("org.freedesktop.DBus",
                                    "/org/freedesktop/dbus",
                                    "org.freedesktop.DBus",
                                    "NameHasOwner",
                                    new Variant ("(s)", name),
                                    new VariantType ("(b)"),
                                    DBusCallFlags.NO_AUTO_START,
                                    -1);
    result.get ("(b)", out has_owner);
    return has_owner;
  }

  /**
   * Attempts to own DBus name (calls dbus_name_has_owner first). CreateScopeCallback should create Lens/Scope object -
   * it will be called after initial dbus name availability check, but before acquiring the name, so this function may
   * still fail even after executing the callback.
   *
   * @param name DBus name to own
   * @param scope_creation_cb callback that creates Lens/Scope object
   * @return application instance (on success)
   */
  public static GLib.Application? dbus_own_name (string name, CreateScopeCallback scope_creation_cb) throws Error
  {
    GLib.Application? app = null;
    if (!dbus_name_has_owner (name))
    {
      scope_creation_cb ();

      app = new Application (name, ApplicationFlags.IS_SERVICE);
      app.register ();
      if (app.get_is_remote ())
      {
        app = null;
      }
      else
      {
        /* Hold()ing the app makes sure the GApplication doesn't exit */
        app.hold ();
      }
    }
    return app;
  }
}