autorun: integrate with the shell sniffer process
If possible, use the results from the sniffer process in order to have less-generic alternatives to the file manager in the proposed autorun choices. https://bugzilla.gnome.org/show_bug.cgi?id=653520
This commit is contained in:
parent
0b9c726b4e
commit
6786aee5ed
@ -1,6 +1,7 @@
|
|||||||
/* -*- mode: js2; js2-basic-offset: 4; indent-tabs-mode: nil -*- */
|
/* -*- mode: js2; js2-basic-offset: 4; indent-tabs-mode: nil -*- */
|
||||||
|
|
||||||
const Lang = imports.lang;
|
const Lang = imports.lang;
|
||||||
|
const DBus = imports.dbus;
|
||||||
const Gio = imports.gi.Gio;
|
const Gio = imports.gi.Gio;
|
||||||
const St = imports.gi.St;
|
const St = imports.gi.St;
|
||||||
|
|
||||||
@ -62,6 +63,26 @@ function startAppForMount(app, mount) {
|
|||||||
|
|
||||||
/******************************************/
|
/******************************************/
|
||||||
|
|
||||||
|
const HotplugSnifferIface = {
|
||||||
|
name: 'org.gnome.Shell.HotplugSniffer',
|
||||||
|
methods: [{ name: 'SniffURI',
|
||||||
|
inSignature: 's',
|
||||||
|
outSignature: 'as' }]
|
||||||
|
};
|
||||||
|
|
||||||
|
const HotplugSniffer = function() {
|
||||||
|
this._init();
|
||||||
|
};
|
||||||
|
|
||||||
|
HotplugSniffer.prototype = {
|
||||||
|
_init: function() {
|
||||||
|
DBus.session.proxifyObject(this,
|
||||||
|
'org.gnome.Shell.HotplugSniffer',
|
||||||
|
'/org/gnome/Shell/HotplugSniffer');
|
||||||
|
},
|
||||||
|
};
|
||||||
|
DBus.proxifyPrototype(HotplugSniffer.prototype, HotplugSnifferIface);
|
||||||
|
|
||||||
function ContentTypeDiscoverer(callback) {
|
function ContentTypeDiscoverer(callback) {
|
||||||
this._init(callback);
|
this._init(callback);
|
||||||
}
|
}
|
||||||
@ -88,12 +109,41 @@ ContentTypeDiscoverer.prototype = {
|
|||||||
+ ': ' + e.toString());
|
+ ': ' + e.toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (contentTypes.length) {
|
||||||
|
this._emitCallback(mount, contentTypes);
|
||||||
|
} else {
|
||||||
|
let root = mount.get_root();
|
||||||
|
|
||||||
|
let hotplugSniffer = new HotplugSniffer();
|
||||||
|
hotplugSniffer.SniffURIRemote
|
||||||
|
(root.get_uri(), DBus.CALL_FLAG_START,
|
||||||
|
Lang.bind(this, function(contentTypes) {
|
||||||
|
this._emitCallback(mount, contentTypes);
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
_emitCallback: function(mount, contentTypes) {
|
||||||
|
if (!contentTypes)
|
||||||
|
contentTypes = [];
|
||||||
|
|
||||||
// we're not interested in win32 software content types here
|
// we're not interested in win32 software content types here
|
||||||
contentTypes = contentTypes.filter(function(type) {
|
contentTypes = contentTypes.filter(function(type) {
|
||||||
return (type != 'x-content/win32-software');
|
return (type != 'x-content/win32-software');
|
||||||
});
|
});
|
||||||
|
|
||||||
this._callback(mount, contentTypes);
|
let apps = [];
|
||||||
|
contentTypes.forEach(function(type) {
|
||||||
|
let app = Gio.app_info_get_default_for_type(type, false);
|
||||||
|
|
||||||
|
if (app)
|
||||||
|
apps.push(app);
|
||||||
|
});
|
||||||
|
|
||||||
|
if (apps.length == 0)
|
||||||
|
apps.push(Gio.app_info_get_default_for_type('inode/directory', false));
|
||||||
|
|
||||||
|
this._callback(mount, apps, contentTypes);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -123,8 +173,8 @@ AutorunManager.prototype = {
|
|||||||
|
|
||||||
mounts.forEach(Lang.bind(this, function (mount) {
|
mounts.forEach(Lang.bind(this, function (mount) {
|
||||||
let discoverer = new ContentTypeDiscoverer(Lang.bind (this,
|
let discoverer = new ContentTypeDiscoverer(Lang.bind (this,
|
||||||
function (mount, contentTypes) {
|
function (mount, apps) {
|
||||||
this._residentSource.addMount(mount, contentTypes);
|
this._residentSource.addMount(mount, apps);
|
||||||
}));
|
}));
|
||||||
|
|
||||||
discoverer.guessContentTypes(mount);
|
discoverer.guessContentTypes(mount);
|
||||||
@ -138,9 +188,9 @@ AutorunManager.prototype = {
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
let discoverer = new ContentTypeDiscoverer(Lang.bind (this,
|
let discoverer = new ContentTypeDiscoverer(Lang.bind (this,
|
||||||
function (mount, contentTypes) {
|
function (mount, apps, contentTypes) {
|
||||||
this._transDispatcher.addMount(mount, contentTypes);
|
this._transDispatcher.addMount(mount, apps, contentTypes);
|
||||||
this._residentSource.addMount(mount, contentTypes);
|
this._residentSource.addMount(mount, apps);
|
||||||
}));
|
}));
|
||||||
|
|
||||||
discoverer.guessContentTypes(mount);
|
discoverer.guessContentTypes(mount);
|
||||||
@ -191,7 +241,7 @@ AutorunResidentSource.prototype = {
|
|||||||
this._setSummaryIcon(this.createNotificationIcon(HOTPLUG_ICON_SIZE));
|
this._setSummaryIcon(this.createNotificationIcon(HOTPLUG_ICON_SIZE));
|
||||||
},
|
},
|
||||||
|
|
||||||
addMount: function(mount, contentTypes) {
|
addMount: function(mount, apps) {
|
||||||
if (ignoreAutorunForMount(mount))
|
if (ignoreAutorunForMount(mount))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@ -202,7 +252,7 @@ AutorunResidentSource.prototype = {
|
|||||||
if (filtered.length != 0)
|
if (filtered.length != 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
let element = { mount: mount, contentTypes: contentTypes };
|
let element = { mount: mount, apps: apps };
|
||||||
this._mounts.push(element);
|
this._mounts.push(element);
|
||||||
this._redisplay();
|
this._redisplay();
|
||||||
},
|
},
|
||||||
@ -269,13 +319,13 @@ AutorunResidentNotification.prototype = {
|
|||||||
for (let idx = 0; idx < mounts.length; idx++) {
|
for (let idx = 0; idx < mounts.length; idx++) {
|
||||||
let element = mounts[idx];
|
let element = mounts[idx];
|
||||||
|
|
||||||
let actor = this._itemForMount(element.mount, element.contentTypes);
|
let actor = this._itemForMount(element.mount, element.apps);
|
||||||
this._layout.add(actor, { x_fill: true,
|
this._layout.add(actor, { x_fill: true,
|
||||||
expand: true });
|
expand: true });
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
_itemForMount: function(mount, contentTypes) {
|
_itemForMount: function(mount, apps) {
|
||||||
let item = new St.BoxLayout();
|
let item = new St.BoxLayout();
|
||||||
|
|
||||||
// prepare the mount button content
|
// prepare the mount button content
|
||||||
@ -312,16 +362,9 @@ AutorunResidentNotification.prototype = {
|
|||||||
child: ejectIcon });
|
child: ejectIcon });
|
||||||
item.add(ejectButton, { x_align: St.Align.END });
|
item.add(ejectButton, { x_align: St.Align.END });
|
||||||
|
|
||||||
// TODO: need to do something better here...
|
|
||||||
if (!contentTypes.length)
|
|
||||||
contentTypes.push('inode/directory');
|
|
||||||
|
|
||||||
// now connect signals
|
// now connect signals
|
||||||
mountButton.connect('clicked', Lang.bind(this, function(actor, event) {
|
mountButton.connect('clicked', Lang.bind(this, function(actor, event) {
|
||||||
let app = Gio.app_info_get_default_for_type(contentTypes[0], false);
|
startAppForMount(apps[0], mount);
|
||||||
|
|
||||||
if (app)
|
|
||||||
startAppForMount(app, mount);
|
|
||||||
}));
|
}));
|
||||||
|
|
||||||
ejectButton.connect('clicked', Lang.bind(this, function() {
|
ejectButton.connect('clicked', Lang.bind(this, function() {
|
||||||
@ -373,17 +416,17 @@ AutorunTransientDispatcher.prototype = {
|
|||||||
return null;
|
return null;
|
||||||
},
|
},
|
||||||
|
|
||||||
_addSource: function(mount, contentTypes) {
|
_addSource: function(mount, apps) {
|
||||||
// if we already have a source showing for this
|
// if we already have a source showing for this
|
||||||
// mount, return
|
// mount, return
|
||||||
if (this._getSourceForMount(mount))
|
if (this._getSourceForMount(mount))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// add a new source
|
// add a new source
|
||||||
this._sources.push(new AutorunTransientSource(mount, contentTypes));
|
this._sources.push(new AutorunTransientSource(mount, apps));
|
||||||
},
|
},
|
||||||
|
|
||||||
addMount: function(mount, contentTypes) {
|
addMount: function(mount, apps, contentTypes) {
|
||||||
// if autorun is disabled globally, return
|
// if autorun is disabled globally, return
|
||||||
if (this._settings.get_boolean(SETTING_DISABLE_AUTORUN))
|
if (this._settings.get_boolean(SETTING_DISABLE_AUTORUN))
|
||||||
return;
|
return;
|
||||||
@ -414,7 +457,7 @@ AutorunTransientDispatcher.prototype = {
|
|||||||
// we fallback here also in case the settings did not specify 'ask',
|
// we fallback here also in case the settings did not specify 'ask',
|
||||||
// but we failed launching the default app or the default file manager
|
// but we failed launching the default app or the default file manager
|
||||||
if (!success)
|
if (!success)
|
||||||
this._addSource(mount, contentTypes);
|
this._addSource(mount, apps);
|
||||||
},
|
},
|
||||||
|
|
||||||
removeMount: function(mount) {
|
removeMount: function(mount) {
|
||||||
@ -429,18 +472,18 @@ AutorunTransientDispatcher.prototype = {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function AutorunTransientSource(mount, contentTypes) {
|
function AutorunTransientSource(mount, apps) {
|
||||||
this._init(mount, contentTypes);
|
this._init(mount, apps);
|
||||||
}
|
}
|
||||||
|
|
||||||
AutorunTransientSource.prototype = {
|
AutorunTransientSource.prototype = {
|
||||||
__proto__: MessageTray.Source.prototype,
|
__proto__: MessageTray.Source.prototype,
|
||||||
|
|
||||||
_init: function(mount, contentTypes) {
|
_init: function(mount, apps) {
|
||||||
MessageTray.Source.prototype._init.call(this, mount.get_name());
|
MessageTray.Source.prototype._init.call(this, mount.get_name());
|
||||||
|
|
||||||
this.mount = mount;
|
this.mount = mount;
|
||||||
this.contentTypes = contentTypes;
|
this.apps = apps;
|
||||||
|
|
||||||
this._notification = new AutorunTransientNotification(this);
|
this._notification = new AutorunTransientNotification(this);
|
||||||
this._setSummaryIcon(this.createNotificationIcon(this.ICON_SIZE));
|
this._setSummaryIcon(this.createNotificationIcon(this.ICON_SIZE));
|
||||||
@ -474,25 +517,14 @@ AutorunTransientNotification.prototype = {
|
|||||||
|
|
||||||
this._mount = source.mount;
|
this._mount = source.mount;
|
||||||
|
|
||||||
source.contentTypes.forEach(Lang.bind(this, function (type) {
|
source.apps.forEach(Lang.bind(this, function (app) {
|
||||||
let actor = this._buttonForContentType(type);
|
let actor = this._buttonForApp(app);
|
||||||
|
|
||||||
if (actor)
|
if (actor)
|
||||||
this._box.add(actor, { x_fill: true,
|
this._box.add(actor, { x_fill: true,
|
||||||
x_align: St.Align.START });
|
x_align: St.Align.START });
|
||||||
}));
|
}));
|
||||||
|
|
||||||
// TODO: ideally we never want to show the file manager entry here,
|
|
||||||
// but we want to detect which kind of files are present on the device,
|
|
||||||
// and use those to present a more meaningful choice.
|
|
||||||
if (this._contentTypes.length == 0) {
|
|
||||||
let button = this._buttonForContentType('inode/directory');
|
|
||||||
|
|
||||||
if (button)
|
|
||||||
this._box.add (button, { x_fill: true,
|
|
||||||
x_align: St.Align.START });
|
|
||||||
}
|
|
||||||
|
|
||||||
this._box.add(this._buttonForEject(), { x_fill: true,
|
this._box.add(this._buttonForEject(), { x_fill: true,
|
||||||
x_align: St.Align.START });
|
x_align: St.Align.START });
|
||||||
|
|
||||||
@ -502,14 +534,8 @@ AutorunTransientNotification.prototype = {
|
|||||||
this.setUrgency(MessageTray.Urgency.CRITICAL);
|
this.setUrgency(MessageTray.Urgency.CRITICAL);
|
||||||
},
|
},
|
||||||
|
|
||||||
_buttonForContentType: function(type) {
|
_buttonForApp: function(app) {
|
||||||
let app = Gio.app_info_get_default_for_type(type, false);
|
|
||||||
|
|
||||||
if (!app)
|
|
||||||
return null;
|
|
||||||
|
|
||||||
let box = new St.BoxLayout();
|
let box = new St.BoxLayout();
|
||||||
|
|
||||||
let icon = new St.Icon({ gicon: app.get_icon(),
|
let icon = new St.Icon({ gicon: app.get_icon(),
|
||||||
style_class: 'hotplug-notification-item-icon' });
|
style_class: 'hotplug-notification-item-icon' });
|
||||||
box.add(icon);
|
box.add(icon);
|
||||||
@ -521,6 +547,8 @@ AutorunTransientNotification.prototype = {
|
|||||||
box.add(label);
|
box.add(label);
|
||||||
|
|
||||||
let button = new St.Button({ child: box,
|
let button = new St.Button({ child: box,
|
||||||
|
x_fill: true,
|
||||||
|
x_align: St.Align.START,
|
||||||
button_mask: St.ButtonMask.ONE,
|
button_mask: St.ButtonMask.ONE,
|
||||||
style_class: 'hotplug-notification-item' });
|
style_class: 'hotplug-notification-item' });
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user