File: desktopIconsUtil.js

package info (click to toggle)
gnome-shell-extension-desktop-icons 20.04.0%2Bgit20200908-5
  • links: PTS, VCS
  • area: main
  • in suites: bullseye
  • size: 756 kB
  • sloc: javascript: 2,678; sh: 39; xml: 30; makefile: 7; python: 7
file content (164 lines) | stat: -rw-r--r-- 5,896 bytes parent folder | download
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
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
/* Desktop Icons GNOME Shell extension
 *
 * Copyright (C) 2017 Carlos Soriano <csoriano@redhat.com>
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU 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 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/>.
 */

const Gtk = imports.gi.Gtk;
const Gio = imports.gi.Gio;
const GLib = imports.gi.GLib;
const ExtensionUtils = imports.misc.extensionUtils;
const Me = ExtensionUtils.getCurrentExtension();
const Prefs = Me.imports.prefs;
const Main = imports.ui.main;
const ShellMountOperation = imports.ui.shellMountOperation;

const TERMINAL_SCHEMA = 'org.gnome.desktop.default-applications.terminal';
const EXEC_KEY = 'exec';

var DEFAULT_ATTRIBUTES = 'metadata::*,standard::*,access::*,time::modified,unix::mode';

function getDesktopDir() {
    let desktopPath = GLib.get_user_special_dir(GLib.UserDirectory.DIRECTORY_DESKTOP);
    return Gio.File.new_for_commandline_arg(desktopPath);
}

function clamp(value, min, max) {
    return Math.max(Math.min(value, max), min);
};

function launchTerminal(workdir) {
    let terminalSettings = new Gio.Settings({ schema_id: TERMINAL_SCHEMA });
    let exec = terminalSettings.get_string(EXEC_KEY);
    let argv = [exec, `--working-directory=${workdir}`];

    /* The following code has been extracted from GNOME Shell's
     * source code in Misc.Util.trySpawn function and modified to
     * set the working directory.
     *
     * https://gitlab.gnome.org/GNOME/gnome-shell/blob/gnome-3-30/js/misc/util.js
     */

    var success, pid;
    try {
        [success, pid] = GLib.spawn_async(workdir, argv, null,
                                          GLib.SpawnFlags.SEARCH_PATH | GLib.SpawnFlags.DO_NOT_REAP_CHILD,
                                          null);
    } catch (err) {
        /* Rewrite the error in case of ENOENT */
        if (err.matches(GLib.SpawnError, GLib.SpawnError.NOENT)) {
            throw new GLib.SpawnError({ code: GLib.SpawnError.NOENT,
                                        message: _("Command not found") });
        } else if (err instanceof GLib.Error) {
            // The exception from gjs contains an error string like:
            //   Error invoking GLib.spawn_command_line_async: Failed to
            //   execute child process "foo" (No such file or directory)
            // We are only interested in the part in the parentheses. (And
            // we can't pattern match the text, since it gets localized.)
            let message = err.message.replace(/.*\((.+)\)/, '$1');
            throw new (err.constructor)({ code: err.code,
                                          message: message });
        } else {
            throw err;
        }
    }
    // Dummy child watch; we don't want to double-fork internally
    // because then we lose the parent-child relationship, which
    // can break polkit.  See https://bugzilla.redhat.com//show_bug.cgi?id=819275
    GLib.child_watch_add(GLib.PRIORITY_DEFAULT, pid, () => {});
}

function distanceBetweenPoints(x, y, x2, y2) {
    return (Math.pow(x - x2, 2) + Math.pow(y - y2, 2));
}

function getExtraFolders() {
    let extraFolders = new Array();
    if (Prefs.settings.get_boolean('show-home')) {
        extraFolders.push([Gio.File.new_for_commandline_arg(GLib.get_home_dir()), Prefs.FileType.USER_DIRECTORY_HOME]);
    }
    if (Prefs.settings.get_boolean('show-trash')) {
        extraFolders.push([Gio.File.new_for_uri('trash:///'), Prefs.FileType.USER_DIRECTORY_TRASH]);
    }
    return extraFolders;
}

function getFileExtensionOffset(filename, isDirectory) {
    let offset = filename.length;

    if (!isDirectory) {
        let doubleExtensions = ['.gz', '.bz2', '.sit', '.Z', '.bz', '.xz'];
        for (let extension of doubleExtensions) {
            if (filename.endsWith(extension)) {
                offset -= extension.length;
                filename = filename.substring(0, offset);
                break;
            }
        }
        let lastDot = filename.lastIndexOf('.');
        if (lastDot > 0)
            offset = lastDot;
    }
    return offset;
}

function getGtkClassBackgroundColor(classname, state) {
    let widget = new Gtk.WidgetPath();
    widget.append_type(Gtk.Widget);

    let context = new Gtk.StyleContext();
    context.set_path(widget);
    context.add_class(classname);
    return context.get_background_color(state);
}

// Reference the extension org.gnome.shell.extensions.drive-menu
function eject(mount) {
    let unmountArgs = [
        Gio.MountUnmountFlags.NONE,
        (new ShellMountOperation.ShellMountOperation(mount)).mountOp,
        null, // Gio.Cancellable
    ];

    if (mount.can_eject()) {
        mount.eject_with_operation(...unmountArgs,
            _ejectFinish.bind(mount));
    } else {
        mount.unmount_with_operation(...unmountArgs,
            _unmountFinish.bind(mount));
    }
}

function _unmountFinish(mount, result) {
    try {
        mount.unmount_with_operation_finish(result);
    } catch (e) {
        this._reportFailure(e);
    }
}

function _ejectFinish(mount, result) {
    try {
        mount.eject_with_operation_finish(result);
    } catch (e) {
        this._reportFailure(e);
    }
}

function _reportFailure(exception) {
    // TRANSLATORS: %s is the filesystem name
    let msg = _('Ejecting drive ā€œ%sā€ failed:').format(this.mount.get_name());
    Main.notifyError(msg, exception.message);
}