Compare commits
33 Commits
wip/gdbus-
...
wip/re-sea
Author | SHA1 | Date | |
---|---|---|---|
![]() |
555d45f06c | ||
![]() |
0a8713770b | ||
![]() |
7d3ea1ac68 | ||
![]() |
7785710964 | ||
![]() |
3730dc01cf | ||
![]() |
66bf0df737 | ||
![]() |
4590b33f2e | ||
![]() |
6538f60322 | ||
![]() |
4b0ba8b7b8 | ||
![]() |
bc8965fe63 | ||
![]() |
e7fcce3484 | ||
![]() |
b1e4d3335c | ||
![]() |
a3a3f24ed3 | ||
![]() |
96191a9c96 | ||
![]() |
f4814d200b | ||
![]() |
52156930d3 | ||
![]() |
cbaa999ced | ||
![]() |
9491f6bd23 | ||
![]() |
afe8198d4b | ||
![]() |
6aa8f14285 | ||
![]() |
e073670c4d | ||
![]() |
17a3d2c63f | ||
![]() |
ca38e05ed4 | ||
![]() |
9841e56ebf | ||
![]() |
c0d3a14ac2 | ||
![]() |
d485fcf9ec | ||
![]() |
ce2c5106f8 | ||
![]() |
5e96c3dfb4 | ||
![]() |
a72b642f3e | ||
![]() |
8507d3c4e4 | ||
![]() |
c985fdccba | ||
![]() |
1d7c2b1c26 | ||
![]() |
ab60c628e7 |
@@ -113,9 +113,13 @@
|
|||||||
<doc:summary>
|
<doc:summary>
|
||||||
<doc:para>
|
<doc:para>
|
||||||
A dictionary describing the given search result, containing
|
A dictionary describing the given search result, containing
|
||||||
'id', 'name' (both strings) and either 'icon' (a serialized
|
'id' and 'name' (both strings). Optionally, either 'gicon' (a
|
||||||
GIcon) or 'icon-data' (raw image data as (iiibiiay) - width,
|
serialized GIcon) or 'icon-data' (raw image data as (iiibiiay)
|
||||||
height, rowstride, has-alpha, bits per sample, channels, data)
|
- width, height, rowstride, has-alpha, bits per sample,
|
||||||
|
channels, data) can be specified if the result can be better
|
||||||
|
served with a thumbnail of the content (such as with images).
|
||||||
|
A 'description' field (string) may also be specified if more
|
||||||
|
context would help the user find the desired result.
|
||||||
</doc:para>
|
</doc:para>
|
||||||
</doc:summary>
|
</doc:summary>
|
||||||
</doc:doc>
|
</doc:doc>
|
||||||
@@ -143,5 +147,25 @@
|
|||||||
</doc:doc>
|
</doc:doc>
|
||||||
</arg>
|
</arg>
|
||||||
</method>
|
</method>
|
||||||
|
|
||||||
|
<method name="LaunchSearch">
|
||||||
|
<doc:doc>
|
||||||
|
<doc:description>
|
||||||
|
<doc:para>
|
||||||
|
Called when the user clicks on the provider icon. The provider
|
||||||
|
application should open and run the active search term itself.
|
||||||
|
</doc:para>
|
||||||
|
</doc:description>
|
||||||
|
</doc:doc>
|
||||||
|
<arg type="as" direction="in">
|
||||||
|
<doc:doc>
|
||||||
|
<doc:summary>
|
||||||
|
<doc:para>
|
||||||
|
The current search term(s).
|
||||||
|
</doc:para>
|
||||||
|
</doc:summary>
|
||||||
|
</doc:doc>
|
||||||
|
</arg>
|
||||||
|
</method>
|
||||||
</interface>
|
</interface>
|
||||||
</node>
|
</node>
|
||||||
|
@@ -577,6 +577,10 @@ StScrollBar StButton#vhandle:active {
|
|||||||
spacing: 40px;
|
spacing: 40px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#overview-group {
|
||||||
|
spacing: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
.window-caption {
|
.window-caption {
|
||||||
spacing: 25px;
|
spacing: 25px;
|
||||||
}
|
}
|
||||||
@@ -711,7 +715,7 @@ StScrollBar StButton#vhandle:active {
|
|||||||
|
|
||||||
#searchResultsContent {
|
#searchResultsContent {
|
||||||
padding-right: 20px;
|
padding-right: 20px;
|
||||||
spacing: 36px;
|
spacing: 16px;
|
||||||
}
|
}
|
||||||
|
|
||||||
#searchResultsContent:rtl {
|
#searchResultsContent:rtl {
|
||||||
@@ -719,6 +723,25 @@ StScrollBar StButton#vhandle:active {
|
|||||||
padding-left: 20px;
|
padding-left: 20px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.search-section {
|
||||||
|
/* This should be equal to #searchResultsContent spacing */
|
||||||
|
spacing: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.search-section-separator {
|
||||||
|
-gradient-height: 1px;
|
||||||
|
-gradient-start: rgba(255,255,255,0);
|
||||||
|
-gradient-end: rgba(255,255,255,0.5);
|
||||||
|
-margin-horizontal: 1.5em;
|
||||||
|
height: 1px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.search-section-content {
|
||||||
|
/* This is the space between the provider icon and the results container */
|
||||||
|
spacing: 25px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.search-statustext,
|
||||||
.search-section-header {
|
.search-section-header {
|
||||||
padding: 4px 12px;
|
padding: 4px 12px;
|
||||||
spacing: 4px;
|
spacing: 4px;
|
||||||
@@ -744,6 +767,14 @@ StScrollBar StButton#vhandle:active {
|
|||||||
spacing: 4px;
|
spacing: 4px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.search-providers-box {
|
||||||
|
spacing: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.results-list {
|
||||||
|
spacing: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
/* Text labels are an odd number of pixels tall. The uneven top and bottom
|
/* Text labels are an odd number of pixels tall. The uneven top and bottom
|
||||||
* padding compensates for this and ensures that the label is vertically
|
* padding compensates for this and ensures that the label is vertically
|
||||||
* centered */
|
* centered */
|
||||||
@@ -824,7 +855,10 @@ StScrollBar StButton#vhandle:active {
|
|||||||
|
|
||||||
.app-well-app > .overview-icon,
|
.app-well-app > .overview-icon,
|
||||||
.show-apps > .overview-icon,
|
.show-apps > .overview-icon,
|
||||||
.search-result-content > .overview-icon {
|
.remove-favorite > .overview-icon,
|
||||||
|
.search-section-icon-bin,
|
||||||
|
.search-result,
|
||||||
|
.grid-search-result-content > .overview-icon {
|
||||||
border-radius: 4px;
|
border-radius: 4px;
|
||||||
padding: 3px;
|
padding: 3px;
|
||||||
border: 1px rgba(0,0,0,0);
|
border: 1px rgba(0,0,0,0);
|
||||||
@@ -840,7 +874,10 @@ StScrollBar StButton#vhandle:active {
|
|||||||
|
|
||||||
.app-well-app:hover > .overview-icon,
|
.app-well-app:hover > .overview-icon,
|
||||||
.show-apps:hover > .overview-icon,
|
.show-apps:hover > .overview-icon,
|
||||||
.search-result-content:hover > .overview-icon {
|
.remove-favorite:hover > .overview-icon,
|
||||||
|
.search-section-icon-bin:hover,
|
||||||
|
.search-result:hover,
|
||||||
|
.grid-search-result-content:hover > .overview-icon {
|
||||||
background-color: rgba(255,255,255,0.1);
|
background-color: rgba(255,255,255,0.1);
|
||||||
text-shadow: black 0px 2px 2px;
|
text-shadow: black 0px 2px 2px;
|
||||||
transition-duration: 100;
|
transition-duration: 100;
|
||||||
@@ -875,13 +912,39 @@ StScrollBar StButton#vhandle:active {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.app-well-app:focus > .overview-icon,
|
.app-well-app:focus > .overview-icon,
|
||||||
.search-result-content:focus > .overview-icon,
|
|
||||||
.show-apps:focus > .overview-icon,
|
.show-apps:focus > .overview-icon,
|
||||||
|
.search-section-icon-bin:focus,
|
||||||
|
.search-result:focus,
|
||||||
|
.grid-search-result-content:focus > .overview-icon,
|
||||||
.app-well-app:selected > .overview-icon,
|
.app-well-app:selected > .overview-icon,
|
||||||
.search-result-content:selected > .overview-icon {
|
.search-section-icon-bin:selected,
|
||||||
|
.search-result:selected,
|
||||||
|
.grid-search-result-content:selected > .overview-icon {
|
||||||
background-color: rgba(255,255,255,0.33);
|
background-color: rgba(255,255,255,0.33);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* List Results */
|
||||||
|
|
||||||
|
.search-result {
|
||||||
|
padding: 15px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.search-result-content {
|
||||||
|
spacing: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.search-result-details {
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
|
.search-result-details-title {
|
||||||
|
font-size: 16pt;
|
||||||
|
}
|
||||||
|
|
||||||
|
.search-result-details-description {
|
||||||
|
font-size: 14pt;
|
||||||
|
}
|
||||||
|
|
||||||
/* LookingGlass */
|
/* LookingGlass */
|
||||||
|
|
||||||
#LookingGlassDialog {
|
#LookingGlassDialog {
|
||||||
|
@@ -41,6 +41,7 @@ nobase_dist_js_DATA = \
|
|||||||
ui/boxpointer.js \
|
ui/boxpointer.js \
|
||||||
ui/calendar.js \
|
ui/calendar.js \
|
||||||
ui/checkBox.js \
|
ui/checkBox.js \
|
||||||
|
ui/centerLayout.js \
|
||||||
ui/ctrlAltTab.js \
|
ui/ctrlAltTab.js \
|
||||||
ui/dash.js \
|
ui/dash.js \
|
||||||
ui/dateMenu.js \
|
ui/dateMenu.js \
|
||||||
|
@@ -21,16 +21,7 @@ const GnomeShellIface = <interface name="org.gnome.Shell.Extensions">
|
|||||||
</signal>
|
</signal>
|
||||||
</interface>;
|
</interface>;
|
||||||
|
|
||||||
const GnomeShellProxy = new Gio.DBusProxyClass({
|
const GnomeShellProxy = Gio.DBusProxy.makeProxyWrapper(GnomeShellIface);
|
||||||
Name: 'GnomeShellProxy',
|
|
||||||
Interface: GnomeShellIface,
|
|
||||||
|
|
||||||
_init: function() {
|
|
||||||
this.parent({ g_bus_type: Gio.BusType.SESSION,
|
|
||||||
g_name: 'org.gnome.Shell',
|
|
||||||
g_object_path: '/org/gnome/Shell' });
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
function stripPrefix(string, prefix) {
|
function stripPrefix(string, prefix) {
|
||||||
if (string.slice(0, prefix.length) == prefix)
|
if (string.slice(0, prefix.length) == prefix)
|
||||||
@@ -200,8 +191,7 @@ const Application = new Lang.Class({
|
|||||||
|
|
||||||
this._extensionPrefsBin.add(label);
|
this._extensionPrefsBin.add(label);
|
||||||
|
|
||||||
this._shellProxy = new GnomeShellProxy();
|
this._shellProxy = new GnomeShellProxy(Gio.DBus.session, 'org.gnome.Shell', '/org/gnome/Shell');
|
||||||
this._shellProxy.init(null);
|
|
||||||
this._shellProxy.connectSignal('ExtensionStatusChanged', Lang.bind(this, function(proxy, senderName, [uuid, state, error]) {
|
this._shellProxy.connectSignal('ExtensionStatusChanged', Lang.bind(this, function(proxy, senderName, [uuid, state, error]) {
|
||||||
if (ExtensionUtils.extensions[uuid] !== undefined)
|
if (ExtensionUtils.extensions[uuid] !== undefined)
|
||||||
this._scanExtensions();
|
this._scanExtensions();
|
||||||
|
@@ -11,14 +11,16 @@ const FprintManagerIface = <interface name='net.reactivated.Fprint.Manager'>
|
|||||||
</method>
|
</method>
|
||||||
</interface>;
|
</interface>;
|
||||||
|
|
||||||
const FprintManager = new Gio.DBusProxyClass({
|
const FprintManagerInfo = Gio.DBusInterfaceInfo.new_for_xml(FprintManagerIface);
|
||||||
Name: 'FprintManager',
|
|
||||||
Interface: FprintManagerIface,
|
|
||||||
|
|
||||||
_init: function() {
|
function FprintManager() {
|
||||||
this.parent({ g_bus_type: Gio.BusType.SYSTEM,
|
var self = new Gio.DBusProxy({ g_connection: Gio.DBus.system,
|
||||||
|
g_interface_name: FprintManagerInfo.name,
|
||||||
|
g_interface_info: FprintManagerInfo,
|
||||||
g_name: 'net.reactivated.Fprint',
|
g_name: 'net.reactivated.Fprint',
|
||||||
g_object_path: '/net/reactivated/Fprint/Manager',
|
g_object_path: '/net/reactivated/Fprint/Manager',
|
||||||
g_flags: (Gio.DBusProxyFlags.DO_NOT_LOAD_PROPERTIES) });
|
g_flags: (Gio.DBusProxyFlags.DO_NOT_LOAD_PROPERTIES) });
|
||||||
|
|
||||||
|
self.init(null);
|
||||||
|
return self;
|
||||||
}
|
}
|
||||||
});
|
|
||||||
|
@@ -1089,7 +1089,7 @@ const LoginDialog = new Lang.Class({
|
|||||||
}));
|
}));
|
||||||
},
|
},
|
||||||
|
|
||||||
_onNotListedClicked: function() {
|
_onNotListedClicked: function(user) {
|
||||||
let tasks = [function() {
|
let tasks = [function() {
|
||||||
return this._userList.hideItems();
|
return this._userList.hideItems();
|
||||||
},
|
},
|
||||||
|
@@ -35,13 +35,7 @@ const PowerMenuButton = new Lang.Class({
|
|||||||
/* Translators: accessible name of the power menu in the login screen */
|
/* Translators: accessible name of the power menu in the login screen */
|
||||||
this.parent('system-shutdown-symbolic', _("Power"));
|
this.parent('system-shutdown-symbolic', _("Power"));
|
||||||
|
|
||||||
LoginManager.getLoginManager(Lang.bind(this, function(manager) {
|
this._loginManager = LoginManager.getLoginManager();
|
||||||
this._loginManager = manager;
|
|
||||||
|
|
||||||
this._updateHaveShutdown();
|
|
||||||
this._updateHaveRestart();
|
|
||||||
this._updateHaveSuspend();
|
|
||||||
}));
|
|
||||||
|
|
||||||
this._settings = new Gio.Settings({ schema: GdmUtil.LOGIN_SCREEN_SCHEMA });
|
this._settings = new Gio.Settings({ schema: GdmUtil.LOGIN_SCREEN_SCHEMA });
|
||||||
this._settings.connect('changed::disable-restart-buttons',
|
this._settings.connect('changed::disable-restart-buttons',
|
||||||
@@ -70,12 +64,6 @@ const PowerMenuButton = new Lang.Class({
|
|||||||
},
|
},
|
||||||
|
|
||||||
_updateHaveShutdown: function() {
|
_updateHaveShutdown: function() {
|
||||||
if (!this._loginManager) {
|
|
||||||
this._haveShutdown = false;
|
|
||||||
this._powerOffItem.actor.visible = false;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
this._loginManager.canPowerOff(Lang.bind(this, function(result) {
|
this._loginManager.canPowerOff(Lang.bind(this, function(result) {
|
||||||
this._haveShutdown = result;
|
this._haveShutdown = result;
|
||||||
this._powerOffItem.actor.visible = this._haveShutdown;
|
this._powerOffItem.actor.visible = this._haveShutdown;
|
||||||
@@ -84,12 +72,6 @@ const PowerMenuButton = new Lang.Class({
|
|||||||
},
|
},
|
||||||
|
|
||||||
_updateHaveRestart: function() {
|
_updateHaveRestart: function() {
|
||||||
if (!this._loginManager) {
|
|
||||||
this._haveRestart = false;
|
|
||||||
this._restartItem.actor.visible = false;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
this._loginManager.canReboot(Lang.bind(this, function(result) {
|
this._loginManager.canReboot(Lang.bind(this, function(result) {
|
||||||
this._haveRestart = result;
|
this._haveRestart = result;
|
||||||
this._restartItem.actor.visible = this._haveRestart;
|
this._restartItem.actor.visible = this._haveRestart;
|
||||||
@@ -98,12 +80,6 @@ const PowerMenuButton = new Lang.Class({
|
|||||||
},
|
},
|
||||||
|
|
||||||
_updateHaveSuspend: function() {
|
_updateHaveSuspend: function() {
|
||||||
if (!this._loginManager) {
|
|
||||||
this._haveSuspend = false;
|
|
||||||
this._suspendItem.actor.visible = false;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
this._loginManager.canSuspend(Lang.bind(this, function(result) {
|
this._loginManager.canSuspend(Lang.bind(this, function(result) {
|
||||||
this._haveSuspend = result;
|
this._haveSuspend = result;
|
||||||
this._suspendItem.actor.visible = this._haveSuspend;
|
this._suspendItem.actor.visible = this._haveSuspend;
|
||||||
|
@@ -1,7 +1,6 @@
|
|||||||
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
|
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
|
||||||
|
|
||||||
const Gio = imports.gi.Gio;
|
const Gio = imports.gi.Gio;
|
||||||
const GLib = imports.gi.GLib;
|
|
||||||
const Lang = imports.lang;
|
const Lang = imports.lang;
|
||||||
const Shell = imports.gi.Shell;
|
const Shell = imports.gi.Shell;
|
||||||
const Signals = imports.signals;
|
const Signals = imports.signals;
|
||||||
@@ -17,16 +16,7 @@ const ProviderIface = <interface name='org.freedesktop.realmd.Provider'>
|
|||||||
<arg name="realm" type="ao" direction="out"/>
|
<arg name="realm" type="ao" direction="out"/>
|
||||||
</method>
|
</method>
|
||||||
</interface>;
|
</interface>;
|
||||||
const Provider = new Gio.DBusProxyClass({
|
const Provider = Gio.DBusProxy.makeProxyWrapper(ProviderIface);
|
||||||
Name: 'RealmdProvider',
|
|
||||||
Interface: ProviderIface,
|
|
||||||
|
|
||||||
_init: function() {
|
|
||||||
this.parent({ g_bus_type: Gio.BusType.SYSTEM,
|
|
||||||
g_name: 'org.freedesktop.realmd',
|
|
||||||
g_object_path: '/org/freedesktop/realmd' });
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
const ServiceIface = <interface name="org.freedesktop.realmd.Service">
|
const ServiceIface = <interface name="org.freedesktop.realmd.Service">
|
||||||
<method name="Cancel">
|
<method name="Cancel">
|
||||||
@@ -41,16 +31,7 @@ const ServiceIface = <interface name="org.freedesktop.realmd.Service">
|
|||||||
<arg name="operation" type="s"/>
|
<arg name="operation" type="s"/>
|
||||||
</signal>
|
</signal>
|
||||||
</interface>;
|
</interface>;
|
||||||
const Service = new Gio.DBusProxyClass({
|
const Service = Gio.DBusProxy.makeProxyWrapper(ServiceIface);
|
||||||
Name: 'RealmdService',
|
|
||||||
Interface: ServiceIface,
|
|
||||||
|
|
||||||
_init: function(service) {
|
|
||||||
this.parent({ g_bus_type: Gio.BusType.SYSTEM,
|
|
||||||
g_name: 'org.freedesktop.realmd',
|
|
||||||
g_object_path: service });
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
const RealmIface = <interface name="org.freedesktop.realmd.Realm">
|
const RealmIface = <interface name="org.freedesktop.realmd.Realm">
|
||||||
<property name="Name" type="s" access="read"/>
|
<property name="Name" type="s" access="read"/>
|
||||||
@@ -70,22 +51,16 @@ const RealmIface = <interface name="org.freedesktop.realmd.Realm">
|
|||||||
<arg name="options" type="a{sv}" direction="in"/>
|
<arg name="options" type="a{sv}" direction="in"/>
|
||||||
</method>
|
</method>
|
||||||
</interface>;
|
</interface>;
|
||||||
const Realm = new Gio.DBusProxyClass({
|
const Realm = Gio.DBusProxy.makeProxyWrapper(RealmIface);
|
||||||
Name: 'RealmdRealm',
|
|
||||||
Interface: RealmIface,
|
|
||||||
|
|
||||||
_init: function(realm) {
|
|
||||||
this.parent({ g_bus_type: Gio.BusType.SYSTEM,
|
|
||||||
g_name: 'org.freedesktop.realmd',
|
|
||||||
g_object_path: realm });
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
const Manager = new Lang.Class({
|
const Manager = new Lang.Class({
|
||||||
Name: 'Manager',
|
Name: 'Manager',
|
||||||
|
|
||||||
_init: function(parentActor) {
|
_init: function(parentActor) {
|
||||||
this._aggregateProvider = new Provider();
|
this._aggregateProvider = Provider(Gio.DBus.system,
|
||||||
|
'org.freedesktop.realmd',
|
||||||
|
'/org/freedesktop/realmd',
|
||||||
|
Lang.bind(this, this._reloadRealms))
|
||||||
this._realms = {};
|
this._realms = {};
|
||||||
|
|
||||||
this._aggregateProvider.connect('g-properties-changed',
|
this._aggregateProvider.connect('g-properties-changed',
|
||||||
@@ -93,16 +68,6 @@ const Manager = new Lang.Class({
|
|||||||
if ('Realms' in properties.deep_unpack())
|
if ('Realms' in properties.deep_unpack())
|
||||||
this._reloadRealms();
|
this._reloadRealms();
|
||||||
}));
|
}));
|
||||||
|
|
||||||
this._aggregateProvider.init_async(GLib.PRIORITY_DEFAULT, null, Lang.bind(this, function(proxy, result) {
|
|
||||||
try {
|
|
||||||
proxy.init_finish(result);
|
|
||||||
} catch(e) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
this._reloadRealms();
|
|
||||||
}));
|
|
||||||
},
|
},
|
||||||
|
|
||||||
_reloadRealms: function() {
|
_reloadRealms: function() {
|
||||||
@@ -112,8 +77,10 @@ const Manager = new Lang.Class({
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
for (let i = 0; i < realmPaths.length; i++) {
|
for (let i = 0; i < realmPaths.length; i++) {
|
||||||
let realm = new Realm(realmPaths[i]);
|
let realm = Realm(Gio.DBus.system,
|
||||||
realm.init_async(GLib.PRIORITY_DEFAULT, null, Lang.bind(this, this._onRealmLoaded));
|
'org.freedesktop.realmd',
|
||||||
|
realmPaths[i],
|
||||||
|
Lang.bind(this, this._onRealmLoaded));
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
@@ -130,10 +97,9 @@ const Manager = new Lang.Class({
|
|||||||
this._updateLoginFormat();
|
this._updateLoginFormat();
|
||||||
},
|
},
|
||||||
|
|
||||||
_onRealmLoaded: function(realm, result) {
|
_onRealmLoaded: function(realm, error) {
|
||||||
try {
|
if (error)
|
||||||
realm.init_finish(result);
|
return;
|
||||||
} catch(e) { return; }
|
|
||||||
|
|
||||||
this._reloadRealm(realm);
|
this._reloadRealm(realm);
|
||||||
|
|
||||||
|
@@ -82,8 +82,6 @@ const ShellUserVerifier = new Lang.Class({
|
|||||||
this._settings = new Gio.Settings({ schema: LOGIN_SCREEN_SCHEMA });
|
this._settings = new Gio.Settings({ schema: LOGIN_SCREEN_SCHEMA });
|
||||||
|
|
||||||
this._fprintManager = new Fprint.FprintManager();
|
this._fprintManager = new Fprint.FprintManager();
|
||||||
this._fprintManager.init(null);
|
|
||||||
|
|
||||||
this._realmManager = new Realmd.Manager();
|
this._realmManager = new Realmd.Manager();
|
||||||
|
|
||||||
this._failCounter = 0;
|
this._failCounter = 0;
|
||||||
@@ -139,13 +137,10 @@ const ShellUserVerifier = new Lang.Class({
|
|||||||
if (!this._settings.get_boolean(FINGERPRINT_AUTHENTICATION_KEY))
|
if (!this._settings.get_boolean(FINGERPRINT_AUTHENTICATION_KEY))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
this._fprintManager.GetDefaultDeviceRemote(this._cancellable, Lang.bind(this, function(manager, result) {
|
this._fprintManager.GetDefaultDeviceRemote(Gio.DBusCallFlags.NONE, this._cancellable, Lang.bind(this,
|
||||||
try {
|
function(device, error) {
|
||||||
let device = manager.GetDefaultDeviceFinish(result);
|
if (!error && device)
|
||||||
this._haveFingerprintReader = !!device;
|
this._haveFingerprintReader = true;
|
||||||
} catch(e) {
|
|
||||||
this._haveFingerprintReader = false;
|
|
||||||
}
|
|
||||||
}));
|
}));
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@@ -21,16 +21,11 @@ const PresenceStatus = {
|
|||||||
IDLE: 3
|
IDLE: 3
|
||||||
};
|
};
|
||||||
|
|
||||||
const Presence = new Gio.DBusProxyClass({
|
var PresenceProxy = Gio.DBusProxy.makeProxyWrapper(PresenceIface);
|
||||||
Name: 'GnomeSessionPresence',
|
function Presence(initCallback, cancellable) {
|
||||||
Interface: PresenceIface,
|
return new PresenceProxy(Gio.DBus.session, 'org.gnome.SessionManager',
|
||||||
|
'/org/gnome/SessionManager/Presence', initCallback, cancellable);
|
||||||
_init: function() {
|
|
||||||
this.parent({ g_bus_type: Gio.BusType.SESSION,
|
|
||||||
g_name: 'org.gnome.SessionManager',
|
|
||||||
g_object_path: '/org/gnome/SessionManager/Presence' });
|
|
||||||
}
|
}
|
||||||
});
|
|
||||||
|
|
||||||
// Note inhibitors are immutable objects, so they don't
|
// Note inhibitors are immutable objects, so they don't
|
||||||
// change at runtime (changes always come in the form
|
// change at runtime (changes always come in the form
|
||||||
@@ -44,16 +39,10 @@ const InhibitorIface = <interface name="org.gnome.SessionManager.Inhibitor">
|
|||||||
</method>
|
</method>
|
||||||
</interface>;
|
</interface>;
|
||||||
|
|
||||||
const Inhibitor = new Gio.DBusProxyClass({
|
var InhibitorProxy = Gio.DBusProxy.makeProxyWrapper(InhibitorIface);
|
||||||
Name: 'GnomeSessionInhibitor',
|
function Inhibitor(objectPath, initCallback, cancellable) {
|
||||||
Interface: InhibitorIface,
|
return new InhibitorProxy(Gio.DBus.session, 'org.gnome.SessionManager', objectPath, initCallback, cancellable);
|
||||||
|
|
||||||
_init: function(inhibitor) {
|
|
||||||
this.parent({ g_bus_type: Gio.BusType.SESSION,
|
|
||||||
g_name: 'org.gnome.SessionManager',
|
|
||||||
g_object_path: inhibitor });
|
|
||||||
}
|
}
|
||||||
});
|
|
||||||
|
|
||||||
// Not the full interface, only the methods we use
|
// Not the full interface, only the methods we use
|
||||||
const SessionManagerIface = <interface name="org.gnome.SessionManager">
|
const SessionManagerIface = <interface name="org.gnome.SessionManager">
|
||||||
@@ -77,14 +66,7 @@ const SessionManagerIface = <interface name="org.gnome.SessionManager">
|
|||||||
</signal>
|
</signal>
|
||||||
</interface>;
|
</interface>;
|
||||||
|
|
||||||
const SessionManager = new Gio.DBusProxyClass({
|
var SessionManagerProxy = Gio.DBusProxy.makeProxyWrapper(SessionManagerIface);
|
||||||
Name: 'GnomeSessionManager',
|
function SessionManager(initCallback, cancellable) {
|
||||||
Interface: SessionManagerIface,
|
return new SessionManagerProxy(Gio.DBus.session, 'org.gnome.SessionManager', '/org/gnome/SessionManager', initCallback, cancellable);
|
||||||
|
}
|
||||||
_init: function() {
|
|
||||||
this.parent({ g_bus_type: Gio.BusType.SESSION,
|
|
||||||
g_name: 'org.gnome.SessionManager',
|
|
||||||
g_object_path: '/org/gnome/SessionManager' });
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
|
@@ -2,7 +2,6 @@
|
|||||||
|
|
||||||
const GLib = imports.gi.GLib;
|
const GLib = imports.gi.GLib;
|
||||||
const Gio = imports.gi.Gio;
|
const Gio = imports.gi.Gio;
|
||||||
const GObject = imports.gi.GObject;
|
|
||||||
const Lang = imports.lang;
|
const Lang = imports.lang;
|
||||||
const Mainloop = imports.mainloop;
|
const Mainloop = imports.mainloop;
|
||||||
const Shell = imports.gi.Shell;
|
const Shell = imports.gi.Shell;
|
||||||
@@ -34,26 +33,8 @@ const SystemdLoginSessionIface = <interface name='org.freedesktop.login1.Session
|
|||||||
<signal name='Unlock' />
|
<signal name='Unlock' />
|
||||||
</interface>;
|
</interface>;
|
||||||
|
|
||||||
const SystemdLoginManager = new Gio.DBusProxyClass({
|
const SystemdLoginManager = Gio.DBusProxy.makeProxyWrapper(SystemdLoginManagerIface);
|
||||||
Name: 'SystemdLoginManager',
|
const SystemdLoginSession = Gio.DBusProxy.makeProxyWrapper(SystemdLoginSessionIface);
|
||||||
Interface: SystemdLoginManagerIface,
|
|
||||||
|
|
||||||
_init: function() {
|
|
||||||
this.parent({ g_bus_type: Gio.BusType.SYSTEM,
|
|
||||||
g_name: 'org.freedesktop.login1',
|
|
||||||
g_object_path: '/org/freedesktop/login1' });
|
|
||||||
}
|
|
||||||
});
|
|
||||||
const SystemdLoginSession = new Gio.DBusProxyClass({
|
|
||||||
Name: 'SystemdLoginSession',
|
|
||||||
Interface: SystemdLoginSessionIface,
|
|
||||||
|
|
||||||
_init: function(session) {
|
|
||||||
this.parent({ g_bus_type: Gio.BusType.SYSTEM,
|
|
||||||
g_name: 'org.freedesktop.login1',
|
|
||||||
g_object_path: session });
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
const ConsoleKitManagerIface = <interface name='org.freedesktop.ConsoleKit.Manager'>
|
const ConsoleKitManagerIface = <interface name='org.freedesktop.ConsoleKit.Manager'>
|
||||||
<method name='CanRestart'>
|
<method name='CanRestart'>
|
||||||
@@ -80,128 +61,51 @@ const ConsoleKitSessionIface = <interface name='org.freedesktop.ConsoleKit.Sessi
|
|||||||
<signal name='Unlock' />
|
<signal name='Unlock' />
|
||||||
</interface>;
|
</interface>;
|
||||||
|
|
||||||
const ConsoleKitSession = new Gio.DBusProxyClass({
|
const ConsoleKitSession = Gio.DBusProxy.makeProxyWrapper(ConsoleKitSessionIface);
|
||||||
Name: 'ConsoleKitSession',
|
const ConsoleKitManager = Gio.DBusProxy.makeProxyWrapper(ConsoleKitManagerIface);
|
||||||
Interface: ConsoleKitSessionIface,
|
|
||||||
|
|
||||||
_init: function(session) {
|
|
||||||
this.parent({ g_bus_type: Gio.BusType.SYSTEM,
|
|
||||||
g_name: 'org.freedesktop.ConsoleKit',
|
|
||||||
g_object_path: session });
|
|
||||||
}
|
|
||||||
});
|
|
||||||
const ConsoleKitManager = new Gio.DBusProxyClass({
|
|
||||||
Name: 'ConsoleKitManager',
|
|
||||||
Interface: ConsoleKitManagerIface,
|
|
||||||
|
|
||||||
_init: function() {
|
|
||||||
this.parent({ g_bus_type: Gio.BusType.SYSTEM,
|
|
||||||
g_name: 'org.freedesktop.ConsoleKit',
|
|
||||||
g_object_path: '/org/freedesktop/ConsoleKit/Manager' });
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
function haveSystemd() {
|
function haveSystemd() {
|
||||||
return GLib.access("/sys/fs/cgroup/systemd", 0) >= 0;
|
return GLib.access("/sys/fs/cgroup/systemd", 0) >= 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
let _loginManager = null;
|
let _loginManager = null;
|
||||||
let _pendingAsyncCallbacks = [];
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* LoginManager:
|
* LoginManager:
|
||||||
* An abstraction over systemd/logind and ConsoleKit.
|
* An abstraction over systemd/logind and ConsoleKit.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
function getLoginManager(asyncCallback) {
|
function getLoginManager() {
|
||||||
if (_loginManager == null) {
|
if (_loginManager == null) {
|
||||||
if (_pendingAsyncCallbacks.length == 0) {
|
|
||||||
let manager;
|
|
||||||
|
|
||||||
if (haveSystemd())
|
if (haveSystemd())
|
||||||
manager = new LoginManagerSystemd();
|
_loginManager = new LoginManagerSystemd();
|
||||||
else
|
else
|
||||||
manager = new LoginManagerConsoleKit();
|
_loginManager = new LoginManagerConsoleKit();
|
||||||
|
|
||||||
manager.initAsync(null, function(obj, result) {
|
|
||||||
obj.initFinish(result);
|
|
||||||
|
|
||||||
_loginManager = manager;
|
|
||||||
|
|
||||||
_pendingAsyncCallbacks.forEach(function (f) { f(obj) });
|
|
||||||
_pendingAsyncCallbacks = [];
|
|
||||||
});
|
|
||||||
|
|
||||||
_pendingAsyncCallbacks = [asyncCallback];
|
|
||||||
} else {
|
|
||||||
_pendingAsyncCallbacks.push(asyncCallback);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
GLib.idle_add(GLib.PRIORITY_DEFAULT, function() {
|
|
||||||
asyncCallback(_loginManager);
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return _loginManager;
|
||||||
}
|
}
|
||||||
|
|
||||||
const LoginManagerSystemd = new Lang.Class({
|
const LoginManagerSystemd = new Lang.Class({
|
||||||
Name: 'LoginManagerSystemd',
|
Name: 'LoginManagerSystemd',
|
||||||
Extends: GObject.Object,
|
|
||||||
|
|
||||||
_init: function() {
|
_init: function() {
|
||||||
this.parent();
|
this._proxy = new SystemdLoginManager(Gio.DBus.system,
|
||||||
|
'org.freedesktop.login1',
|
||||||
this._proxy = new SystemdLoginManager();
|
'/org/freedesktop/login1');
|
||||||
},
|
|
||||||
|
|
||||||
initAsync: function(cancellable, asyncCallback) {
|
|
||||||
let simpleResult = Gio.SimpleAsyncResult.new(this, asyncCallback, null);
|
|
||||||
simpleResult.set_check_cancellable(cancellable);
|
|
||||||
|
|
||||||
this._proxy.init_async(GLib.PRIORITY_DEFAULT, cancellable, Lang.bind(this, function(proxy, result) {
|
|
||||||
try {
|
|
||||||
proxy.init_finish(result);
|
|
||||||
|
|
||||||
if (cancellable && cancellable.is_cancelled())
|
|
||||||
return;
|
|
||||||
|
|
||||||
this._fetchCurrentSession(cancellable, simpleResult);
|
|
||||||
} catch(e if e instanceof GLib.Error) {
|
|
||||||
simpleResult.set_from_error(e);
|
|
||||||
simpleResult.complete();
|
|
||||||
}
|
|
||||||
}));
|
|
||||||
},
|
|
||||||
|
|
||||||
initFinish: function(simpleResult) {
|
|
||||||
if (!simpleResult.propagate_error())
|
|
||||||
return simpleResult.get_op_res_gboolean();
|
|
||||||
|
|
||||||
return true;
|
|
||||||
},
|
|
||||||
|
|
||||||
_fetchCurrentSession: function(cancellable, simpleResult) {
|
|
||||||
this._currentSession = new SystemdLoginSession('/org/freedesktop/login1/session/' +
|
|
||||||
GLib.getenv('XDG_SESSION_ID'));
|
|
||||||
|
|
||||||
this._currentSession.init_async(GLib.PRIORITY_DEFAULT, cancellable, Lang.bind(this, function(proxy, result) {
|
|
||||||
try {
|
|
||||||
proxy.init_finish(result);
|
|
||||||
|
|
||||||
simpleResult.set_op_res_gboolean(true);
|
|
||||||
} catch(e if e instanceof GLib.Error) {
|
|
||||||
simpleResult.set_from_error(e);
|
|
||||||
}
|
|
||||||
|
|
||||||
simpleResult.complete();
|
|
||||||
}));
|
|
||||||
},
|
},
|
||||||
|
|
||||||
// Having this function is a bit of a hack since the Systemd and ConsoleKit
|
// Having this function is a bit of a hack since the Systemd and ConsoleKit
|
||||||
// session objects have different interfaces - but in both cases there are
|
// session objects have different interfaces - but in both cases there are
|
||||||
// Lock/Unlock signals, and that's all we count upon at the moment.
|
// Lock/Unlock signals, and that's all we count upon at the moment.
|
||||||
//
|
|
||||||
// This is only valid after async initialization
|
|
||||||
getCurrentSessionProxy: function() {
|
getCurrentSessionProxy: function() {
|
||||||
|
if (!this._currentSession) {
|
||||||
|
this._currentSession = new SystemdLoginSession(Gio.DBus.system,
|
||||||
|
'org.freedesktop.login1',
|
||||||
|
'/org/freedesktop/login1/session/' +
|
||||||
|
GLib.getenv('XDG_SESSION_ID'));
|
||||||
|
}
|
||||||
|
|
||||||
return this._currentSession;
|
return this._currentSession;
|
||||||
},
|
},
|
||||||
|
|
||||||
@@ -210,126 +114,66 @@ const LoginManagerSystemd = new Lang.Class({
|
|||||||
},
|
},
|
||||||
|
|
||||||
canPowerOff: function(asyncCallback) {
|
canPowerOff: function(asyncCallback) {
|
||||||
this._proxy.CanPowerOffRemote(null, function(proxy, result) {
|
this._proxy.CanPowerOffRemote(function(result, error) {
|
||||||
let val = false;
|
if (error)
|
||||||
|
asyncCallback(false);
|
||||||
try {
|
else
|
||||||
val = proxy.CanPowerOffFinish(result)[0] != 'no';
|
asyncCallback(result[0] != 'no');
|
||||||
} catch(e) { }
|
|
||||||
|
|
||||||
asyncCallback(val);
|
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
canReboot: function(asyncCallback) {
|
canReboot: function(asyncCallback) {
|
||||||
this._proxy.CanRebootRemote(null, function(proxy, result) {
|
this._proxy.CanRebootRemote(function(result, error) {
|
||||||
let val = false;
|
if (error)
|
||||||
|
asyncCallback(false);
|
||||||
try {
|
else
|
||||||
val = proxy.CanRebootFinish(result)[0] != 'no';
|
asyncCallback(result[0] != 'no');
|
||||||
} catch(e) { }
|
|
||||||
|
|
||||||
asyncCallback(val);
|
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
canSuspend: function(asyncCallback) {
|
canSuspend: function(asyncCallback) {
|
||||||
this._proxy.CanSuspendRemote(null, function(proxy, result) {
|
this._proxy.CanSuspendRemote(function(result, error) {
|
||||||
let val = false;
|
if (error)
|
||||||
|
asyncCallback(false);
|
||||||
try {
|
else
|
||||||
val = proxy.CanRebootFinish(result)[0] != 'no';
|
asyncCallback(result[0] != 'no');
|
||||||
} catch(e) { }
|
|
||||||
|
|
||||||
asyncCallback(val);
|
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
powerOff: function() {
|
powerOff: function() {
|
||||||
this._proxy.PowerOffRemote(true, null, null);
|
this._proxy.PowerOffRemote(true);
|
||||||
},
|
},
|
||||||
|
|
||||||
reboot: function() {
|
reboot: function() {
|
||||||
this._proxy.RebootRemote(true, null, null);
|
this._proxy.RebootRemote(true);
|
||||||
},
|
},
|
||||||
|
|
||||||
suspend: function() {
|
suspend: function() {
|
||||||
this._proxy.SuspendRemote(true, null, null);
|
this._proxy.SuspendRemote(true);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
const LoginManagerConsoleKit = new Lang.Class({
|
const LoginManagerConsoleKit = new Lang.Class({
|
||||||
Name: 'LoginManagerConsoleKit',
|
Name: 'LoginManagerConsoleKit',
|
||||||
Extends: GObject.Object,
|
|
||||||
|
|
||||||
_init: function() {
|
_init: function() {
|
||||||
this.parent();
|
this._proxy = new ConsoleKitManager(Gio.DBus.system,
|
||||||
|
'org.freedesktop.ConsoleKit',
|
||||||
this._proxy = new ConsoleKitManager();
|
'/org/freedesktop/ConsoleKit/Manager');
|
||||||
this._upClient = new UPowerGlib.Client();
|
this._upClient = new UPowerGlib.Client();
|
||||||
},
|
},
|
||||||
|
|
||||||
initAsync: function(cancellable, asyncCallback) {
|
|
||||||
let simpleResult = Gio.SimpleAsyncResult.new(this, asyncCallback, null);
|
|
||||||
simpleResult.set_check_cancellable(cancellable);
|
|
||||||
|
|
||||||
this._proxy.init_async(GLib.PRIORITY_DEFAULT, cancellable, Lang.bind(this, function(proxy, result) {
|
|
||||||
try {
|
|
||||||
proxy.init_finish(result);
|
|
||||||
|
|
||||||
if (cancellable && cancellable.is_cancelled())
|
|
||||||
return;
|
|
||||||
|
|
||||||
this._fetchCurrentSession(cancellable, simpleResult);
|
|
||||||
} catch(e if e instanceof GLib.Error) {
|
|
||||||
simpleResult.set_from_error(e);
|
|
||||||
simpleResult.complete();
|
|
||||||
}
|
|
||||||
}));
|
|
||||||
},
|
|
||||||
|
|
||||||
initFinish: function(simpleResult) {
|
|
||||||
if (!simpleResult.propagate_error())
|
|
||||||
return simpleResult.get_op_res_gboolean();
|
|
||||||
|
|
||||||
return true;
|
|
||||||
},
|
|
||||||
|
|
||||||
_fetchCurrentSession: function(cancellable, simpleResult) {
|
|
||||||
this._proxy.GetCurrentSessionRemote(cancellable, Lang.bind(this, function(proxy, result) {
|
|
||||||
try {
|
|
||||||
let [currentSessionId] = proxy.GetCurrentSessionFinish(result);
|
|
||||||
|
|
||||||
if (cancellable && cancellable.is_cancelled())
|
|
||||||
return;
|
|
||||||
|
|
||||||
this._createSessionProxy(currentSessionId, cancellable, simpleResult);
|
|
||||||
} catch(e if e instanceof GLib.Error) {
|
|
||||||
simpleResult.set_from_error(e);
|
|
||||||
simpleResult.complete();
|
|
||||||
}
|
|
||||||
}));
|
|
||||||
},
|
|
||||||
|
|
||||||
_createSessionProxy: function(currentSessionId, cancellable, simpleResult) {
|
|
||||||
this._currentSession = new ConsoleKitSession(currentSessionId);
|
|
||||||
this._currentSession.init_async(GLib.PRIORITY_DEFAULT, cancellable, Lang.bind(this, function(proxy, result) {
|
|
||||||
try {
|
|
||||||
proxy.init_finish(result);
|
|
||||||
|
|
||||||
simpleResult.set_op_res_gboolean(true);
|
|
||||||
} catch(e if e instanceof GLib.Error) {
|
|
||||||
simpleResult.set_from_error(e);
|
|
||||||
}
|
|
||||||
|
|
||||||
simpleResult.complete();
|
|
||||||
}));
|
|
||||||
},
|
|
||||||
|
|
||||||
// Having this function is a bit of a hack since the Systemd and ConsoleKit
|
// Having this function is a bit of a hack since the Systemd and ConsoleKit
|
||||||
// session objects have different interfaces - but in both cases there are
|
// session objects have different interfaces - but in both cases there are
|
||||||
// Lock/Unlock signals, and that's all we count upon at the moment.
|
// Lock/Unlock signals, and that's all we count upon at the moment.
|
||||||
getCurrentSessionProxy: function() {
|
getCurrentSessionProxy: function() {
|
||||||
|
if (!this._currentSession) {
|
||||||
|
let [currentSessionId] = this._proxy.GetCurrentSessionSync();
|
||||||
|
this._currentSession = new ConsoleKitSession(Gio.DBus.system,
|
||||||
|
'org.freedesktop.ConsoleKit',
|
||||||
|
currentSessionId);
|
||||||
|
}
|
||||||
|
|
||||||
return this._currentSession;
|
return this._currentSession;
|
||||||
},
|
},
|
||||||
|
|
||||||
@@ -341,32 +185,26 @@ const LoginManagerConsoleKit = new Lang.Class({
|
|||||||
session.connectSignal('ActiveChanged', Lang.bind(this, function(object, senderName, [isActive]) {
|
session.connectSignal('ActiveChanged', Lang.bind(this, function(object, senderName, [isActive]) {
|
||||||
this._sessionActive = isActive;
|
this._sessionActive = isActive;
|
||||||
}));
|
}));
|
||||||
[this._sessionActive] = session.IsActiveSync(null);
|
[this._sessionActive] = session.IsActiveSync();
|
||||||
|
|
||||||
return this._sessionActive;
|
return this._sessionActive;
|
||||||
},
|
},
|
||||||
|
|
||||||
canPowerOff: function(asyncCallback) {
|
canPowerOff: function(asyncCallback) {
|
||||||
this._proxy.CanStopRemote(null, function(proxy, result) {
|
this._proxy.CanStopRemote(function(result, error) {
|
||||||
let val = false;
|
if (error)
|
||||||
|
asyncCallback(false);
|
||||||
try {
|
else
|
||||||
[val] = proxy.CanStopFinish(result);
|
asyncCallback(result[0]);
|
||||||
} catch(e) { }
|
|
||||||
|
|
||||||
asyncCallback(val);
|
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
canReboot: function(asyncCallback) {
|
canReboot: function(asyncCallback) {
|
||||||
this._proxy.CanRestartRemote(null, function(proxy, result) {
|
this._proxy.CanRestartRemote(function(result, error) {
|
||||||
let val = false;
|
if (error)
|
||||||
|
asyncCallback(false);
|
||||||
try {
|
else
|
||||||
[val] = proxy.CanRestartFinish(result);
|
asyncCallback(result[0]);
|
||||||
} catch(e) { }
|
|
||||||
|
|
||||||
asyncCallback(val);
|
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
@@ -378,11 +216,11 @@ const LoginManagerConsoleKit = new Lang.Class({
|
|||||||
},
|
},
|
||||||
|
|
||||||
powerOff: function() {
|
powerOff: function() {
|
||||||
this._proxy.StopRemote(null, null);
|
this._proxy.StopRemote();
|
||||||
},
|
},
|
||||||
|
|
||||||
reboot: function() {
|
reboot: function() {
|
||||||
this._proxy.RestartRemote(null, null);
|
this._proxy.RestartRemote();
|
||||||
},
|
},
|
||||||
|
|
||||||
suspend: function() {
|
suspend: function() {
|
||||||
|
@@ -1,7 +1,6 @@
|
|||||||
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
|
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
|
||||||
|
|
||||||
const Gio = imports.gi.Gio;
|
const Gio = imports.gi.Gio;
|
||||||
const GLib = imports.gi.GLib;
|
|
||||||
const Lang = imports.lang;
|
const Lang = imports.lang;
|
||||||
const Shell = imports.gi.Shell;
|
const Shell = imports.gi.Shell;
|
||||||
const Signals = imports.signals;
|
const Signals = imports.signals;
|
||||||
@@ -27,16 +26,7 @@ const ModemGsmNetworkInterface = <interface name="org.freedesktop.ModemManager.M
|
|||||||
</signal>
|
</signal>
|
||||||
</interface>;
|
</interface>;
|
||||||
|
|
||||||
const ModemGsmNetworkProxy = new Gio.DBusProxyClass({
|
const ModemGsmNetworkProxy = Gio.DBusProxy.makeProxyWrapper(ModemGsmNetworkInterface);
|
||||||
Name: 'ModemGsmNetworkProxy',
|
|
||||||
Interface: ModemGsmNetworkInterface,
|
|
||||||
|
|
||||||
_init: function(modem) {
|
|
||||||
this.parent({ g_bus_type: Gio.BusType.SYSTEM,
|
|
||||||
g_name: 'org.freedesktop.ModemManager',
|
|
||||||
g_object_path: modem });
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
const ModemCdmaInterface = <interface name="org.freedesktop.ModemManager.Modem.Cdma">
|
const ModemCdmaInterface = <interface name="org.freedesktop.ModemManager.Modem.Cdma">
|
||||||
<method name="GetSignalQuality">
|
<method name="GetSignalQuality">
|
||||||
@@ -50,16 +40,7 @@ const ModemCdmaInterface = <interface name="org.freedesktop.ModemManager.Modem.C
|
|||||||
</signal>
|
</signal>
|
||||||
</interface>;
|
</interface>;
|
||||||
|
|
||||||
const ModemCdmaProxy = new Gio.DBusProxyClass({
|
const ModemCdmaProxy = Gio.DBusProxy.makeProxyWrapper(ModemCdmaInterface);
|
||||||
Name: 'ModemCdmaProxy',
|
|
||||||
Interface: ModemCdmaInterface,
|
|
||||||
|
|
||||||
_init: function(modem) {
|
|
||||||
this.parent({ g_bus_type: Gio.BusType.SYSTEM,
|
|
||||||
g_name: 'org.freedesktop.ModemManager',
|
|
||||||
g_object_path: modem });
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
let _providersTable;
|
let _providersTable;
|
||||||
function _getProvidersTable() {
|
function _getProvidersTable() {
|
||||||
@@ -73,18 +54,11 @@ const ModemGsm = new Lang.Class({
|
|||||||
Name: 'ModemGsm',
|
Name: 'ModemGsm',
|
||||||
|
|
||||||
_init: function(path) {
|
_init: function(path) {
|
||||||
this._proxy = new ModemGsmNetworkProxy(path);
|
this._proxy = new ModemGsmNetworkProxy(Gio.DBus.system, 'org.freedesktop.ModemManager', path);
|
||||||
this._proxy.init_async(GLib.PRIORITY_DEFAULT, null, Lang.bind(this, function(obj, result) {
|
|
||||||
obj.init_finish(result);
|
|
||||||
|
|
||||||
this._finishInit();
|
|
||||||
}));
|
|
||||||
|
|
||||||
this.signal_quality = 0;
|
this.signal_quality = 0;
|
||||||
this.operator_name = null;
|
this.operator_name = null;
|
||||||
},
|
|
||||||
|
|
||||||
_finishInit: function() {
|
|
||||||
// Code is duplicated because the function have different signatures
|
// Code is duplicated because the function have different signatures
|
||||||
this._proxy.connectSignal('SignalQuality', Lang.bind(this, function(proxy, sender, [quality]) {
|
this._proxy.connectSignal('SignalQuality', Lang.bind(this, function(proxy, sender, [quality]) {
|
||||||
this.signal_quality = quality;
|
this.signal_quality = quality;
|
||||||
@@ -94,19 +68,24 @@ const ModemGsm = new Lang.Class({
|
|||||||
this.operator_name = this._findOperatorName(name, code);
|
this.operator_name = this._findOperatorName(name, code);
|
||||||
this.emit('notify::operator-name');
|
this.emit('notify::operator-name');
|
||||||
}));
|
}));
|
||||||
this._proxy.GetRegistrationInfoRemote(null, Lang.bind(this, function(proxy, result) {
|
this._proxy.GetRegistrationInfoRemote(Lang.bind(this, function([result], err) {
|
||||||
let [status, code, name] = proxy.GetRegistrationInfoFinish(result);
|
if (err) {
|
||||||
|
log(err);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
let [status, code, name] = result;
|
||||||
this.operator_name = this._findOperatorName(name, code);
|
this.operator_name = this._findOperatorName(name, code);
|
||||||
this.emit('notify::operator-name');
|
this.emit('notify::operator-name');
|
||||||
}));
|
}));
|
||||||
this._proxy.GetSignalQualityRemote(null, Lang.bind(this, function(proxy, result) {
|
this._proxy.GetSignalQualityRemote(Lang.bind(this, function(result, err) {
|
||||||
try {
|
if (err) {
|
||||||
[this.signal_quality] = proxy.GetSignalQualityFinish(result);
|
|
||||||
} catch(e) {
|
|
||||||
// it will return an error if the device is not connected
|
// it will return an error if the device is not connected
|
||||||
this.signal_quality = 0;
|
this.signal_quality = 0;
|
||||||
|
} else {
|
||||||
|
let [quality] = result;
|
||||||
|
this.signal_quality = quality;
|
||||||
}
|
}
|
||||||
|
|
||||||
this.emit('notify::signal-quality');
|
this.emit('notify::signal-quality');
|
||||||
}));
|
}));
|
||||||
},
|
},
|
||||||
@@ -178,18 +157,10 @@ const ModemCdma = new Lang.Class({
|
|||||||
Name: 'ModemCdma',
|
Name: 'ModemCdma',
|
||||||
|
|
||||||
_init: function(path) {
|
_init: function(path) {
|
||||||
this._proxy = new ModemCdmaProxy(path);
|
this._proxy = new ModemCdmaProxy(Gio.DBus.system, 'org.freedesktop.ModemManager', path);
|
||||||
this._proxy.init_async(GLib.PRIORITY_DEFAULT, null, Lang.bind(this, function(obj, result) {
|
|
||||||
obj.init_finish(result);
|
|
||||||
|
|
||||||
this._finishInit();
|
|
||||||
}));
|
|
||||||
|
|
||||||
this.signal_quality = 0;
|
this.signal_quality = 0;
|
||||||
this.operator_name = null;
|
this.operator_name = null;
|
||||||
},
|
|
||||||
|
|
||||||
_finishInit: function() {
|
|
||||||
this._proxy.connectSignal('SignalQuality', Lang.bind(this, function(proxy, sender, params) {
|
this._proxy.connectSignal('SignalQuality', Lang.bind(this, function(proxy, sender, params) {
|
||||||
this.signal_quality = params[0];
|
this.signal_quality = params[0];
|
||||||
this.emit('notify::signal-quality');
|
this.emit('notify::signal-quality');
|
||||||
@@ -199,31 +170,30 @@ const ModemCdma = new Lang.Class({
|
|||||||
if (this.operator_name == null)
|
if (this.operator_name == null)
|
||||||
this._refreshServingSystem();
|
this._refreshServingSystem();
|
||||||
}));
|
}));
|
||||||
this._proxy.GetSignalQualityRemote(null, Lang.bind(this, function(proxy, result) {
|
this._proxy.GetSignalQualityRemote(Lang.bind(this, function(result, err) {
|
||||||
try {
|
if (err) {
|
||||||
[this.signal_quality] = proxy.GetSignalQualityFinish(result);
|
|
||||||
} catch(e) {
|
|
||||||
// it will return an error if the device is not connected
|
// it will return an error if the device is not connected
|
||||||
this.signal_quality = 0;
|
this.signal_quality = 0;
|
||||||
|
} else {
|
||||||
|
let [quality] = result;
|
||||||
|
this.signal_quality = quality;
|
||||||
}
|
}
|
||||||
|
|
||||||
this.emit('notify::signal-quality');
|
this.emit('notify::signal-quality');
|
||||||
}));
|
}));
|
||||||
},
|
},
|
||||||
|
|
||||||
_refreshServingSystem: function() {
|
_refreshServingSystem: function() {
|
||||||
this._proxy.GetServingSystemRemote(null, Lang.bind(this, function(proxy, result) {
|
this._proxy.GetServingSystemRemote(Lang.bind(this, function([result], err) {
|
||||||
try {
|
if (err) {
|
||||||
let [bandClass, band, name] = proxy.GetServingSystemFinish(result);
|
|
||||||
if (name.length > 0)
|
|
||||||
this.operator_name = this._findProviderForSid(name);
|
|
||||||
else
|
|
||||||
this.operator_name = null;
|
|
||||||
} catch(e) {
|
|
||||||
// it will return an error if the device is not connected
|
// it will return an error if the device is not connected
|
||||||
this.operator_name = null;
|
this.operator_name = null;
|
||||||
|
} else {
|
||||||
|
let [bandClass, band, id] = result;
|
||||||
|
if (name.length > 0)
|
||||||
|
this.operator_name = this._findProviderForSid(id);
|
||||||
|
else
|
||||||
|
this.operator_name = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
this.emit('notify::operator-name');
|
this.emit('notify::operator-name');
|
||||||
}));
|
}));
|
||||||
},
|
},
|
||||||
|
@@ -1,6 +1,7 @@
|
|||||||
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
|
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
|
||||||
|
|
||||||
const Clutter = imports.gi.Clutter;
|
const Clutter = imports.gi.Clutter;
|
||||||
|
const Gio = imports.gi.Gio;
|
||||||
const GLib = imports.gi.GLib;
|
const GLib = imports.gi.GLib;
|
||||||
const Gtk = imports.gi.Gtk;
|
const Gtk = imports.gi.Gtk;
|
||||||
const GMenu = imports.gi.GMenu;
|
const GMenu = imports.gi.GMenu;
|
||||||
@@ -371,6 +372,8 @@ const SettingsSearchProvider = new Lang.Class({
|
|||||||
|
|
||||||
this._appSys = Shell.AppSystem.get_default();
|
this._appSys = Shell.AppSystem.get_default();
|
||||||
this._gnomecc = this._appSys.lookup_app('gnome-control-center.desktop');
|
this._gnomecc = this._appSys.lookup_app('gnome-control-center.desktop');
|
||||||
|
let appInfo = Gio.DesktopAppInfo.new('gnome-control-center.desktop');
|
||||||
|
this.icon = appInfo.get_icon();
|
||||||
},
|
},
|
||||||
|
|
||||||
getResultMetas: function(prefs, callback) {
|
getResultMetas: function(prefs, callback) {
|
||||||
@@ -379,9 +382,7 @@ const SettingsSearchProvider = new Lang.Class({
|
|||||||
let pref = prefs[i];
|
let pref = prefs[i];
|
||||||
metas.push({ 'id': pref,
|
metas.push({ 'id': pref,
|
||||||
'name': pref.get_name(),
|
'name': pref.get_name(),
|
||||||
'createIcon': function(size) {
|
'createIcon': function(size) { return; }
|
||||||
return pref.create_icon_texture(size);
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
callback(metas);
|
callback(metas);
|
||||||
@@ -461,15 +462,15 @@ const AppWellIcon = new Lang.Class({
|
|||||||
this._draggable.connect('drag-begin', Lang.bind(this,
|
this._draggable.connect('drag-begin', Lang.bind(this,
|
||||||
function () {
|
function () {
|
||||||
this._removeMenuTimeout();
|
this._removeMenuTimeout();
|
||||||
Main.overview.beginItemDrag(this);
|
Main.overview.beginAppDrag(this);
|
||||||
}));
|
}));
|
||||||
this._draggable.connect('drag-cancelled', Lang.bind(this,
|
this._draggable.connect('drag-cancelled', Lang.bind(this,
|
||||||
function () {
|
function () {
|
||||||
Main.overview.cancelledItemDrag(this);
|
Main.overview.cancelledAppDrag(this);
|
||||||
}));
|
}));
|
||||||
this._draggable.connect('drag-end', Lang.bind(this,
|
this._draggable.connect('drag-end', Lang.bind(this,
|
||||||
function () {
|
function () {
|
||||||
Main.overview.endItemDrag(this);
|
Main.overview.endAppDrag(this);
|
||||||
}));
|
}));
|
||||||
|
|
||||||
this.actor.connect('destroy', Lang.bind(this, this._onDestroy));
|
this.actor.connect('destroy', Lang.bind(this, this._onDestroy));
|
||||||
|
@@ -1,7 +1,6 @@
|
|||||||
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
|
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
|
||||||
|
|
||||||
const Clutter = imports.gi.Clutter;
|
const Clutter = imports.gi.Clutter;
|
||||||
const GLib = imports.gi.GLib;
|
|
||||||
const Gio = imports.gi.Gio;
|
const Gio = imports.gi.Gio;
|
||||||
const Lang = imports.lang;
|
const Lang = imports.lang;
|
||||||
const St = imports.gi.St;
|
const St = imports.gi.St;
|
||||||
@@ -201,17 +200,19 @@ const CalendarServerIface = <interface name="org.gnome.Shell.CalendarServer">
|
|||||||
<signal name="Changed" />
|
<signal name="Changed" />
|
||||||
</interface>;
|
</interface>;
|
||||||
|
|
||||||
const CalendarServer = new Gio.DBusProxyClass({
|
const CalendarServerInfo = Gio.DBusInterfaceInfo.new_for_xml(CalendarServerIface);
|
||||||
Name: 'CalendarServer',
|
|
||||||
Interface: CalendarServerIface,
|
|
||||||
|
|
||||||
_init: function() {
|
function CalendarServer() {
|
||||||
this.parent({ g_bus_type: Gio.BusType.SESSION,
|
var self = new Gio.DBusProxy({ g_connection: Gio.DBus.session,
|
||||||
|
g_interface_name: CalendarServerInfo.name,
|
||||||
|
g_interface_info: CalendarServerInfo,
|
||||||
g_name: 'org.gnome.Shell.CalendarServer',
|
g_name: 'org.gnome.Shell.CalendarServer',
|
||||||
g_object_path: '/org/gnome/Shell/CalendarServer',
|
g_object_path: '/org/gnome/Shell/CalendarServer',
|
||||||
g_flags: Gio.DBusProxyFlags.DO_NOT_LOAD_PROPERTIES });
|
g_flags: Gio.DBusProxyFlags.DO_NOT_LOAD_PROPERTIES });
|
||||||
|
|
||||||
|
self.init(null);
|
||||||
|
return self;
|
||||||
}
|
}
|
||||||
});
|
|
||||||
|
|
||||||
function _datesEqual(a, b) {
|
function _datesEqual(a, b) {
|
||||||
if (a < b)
|
if (a < b)
|
||||||
@@ -241,15 +242,11 @@ const DBusEventSource = new Lang.Class({
|
|||||||
this._dbusProxy = new CalendarServer();
|
this._dbusProxy = new CalendarServer();
|
||||||
this._dbusProxy.connectSignal('Changed', Lang.bind(this, this._onChanged));
|
this._dbusProxy.connectSignal('Changed', Lang.bind(this, this._onChanged));
|
||||||
|
|
||||||
this._dbusProxy.init_async(GLib.PRIORITY_DEFAULT, null, Lang.bind(this, function(proxy, result) {
|
this._dbusProxy.connect('notify::g-name-owner', Lang.bind(this, function() {
|
||||||
try {
|
if (this._dbusProxy.g_name_owner)
|
||||||
proxy.init_finish(result);
|
this._onNameAppeared();
|
||||||
} catch(e) {
|
else
|
||||||
return;
|
this._onNameVanished();
|
||||||
}
|
|
||||||
|
|
||||||
this._resetCache();
|
|
||||||
this.emit('changed');
|
|
||||||
}));
|
}));
|
||||||
},
|
},
|
||||||
|
|
||||||
@@ -259,20 +256,24 @@ const DBusEventSource = new Lang.Class({
|
|||||||
this._lastRequestEnd = null;
|
this._lastRequestEnd = null;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
_onNameAppeared: function(owner) {
|
||||||
|
this._resetCache();
|
||||||
|
this._loadEvents(true);
|
||||||
|
},
|
||||||
|
|
||||||
|
_onNameVanished: function(oldOwner) {
|
||||||
|
this._resetCache();
|
||||||
|
this.emit('changed');
|
||||||
|
},
|
||||||
|
|
||||||
_onChanged: function() {
|
_onChanged: function() {
|
||||||
this._loadEvents(false);
|
this._loadEvents(false);
|
||||||
},
|
},
|
||||||
|
|
||||||
_onEventsReceived: function(proxy, result) {
|
_onEventsReceived: function(results, error) {
|
||||||
let appointments;
|
|
||||||
try {
|
|
||||||
[appointments] = proxy.call_finish(result).deep_unpack();
|
|
||||||
} catch(e if e instanceof GLib.Error) {
|
|
||||||
// ignore errors coming from DBus
|
|
||||||
appointments = [];
|
|
||||||
}
|
|
||||||
|
|
||||||
let newEvents = [];
|
let newEvents = [];
|
||||||
|
let appointments = results ? results[0] : null;
|
||||||
|
if (appointments != null) {
|
||||||
for (let n = 0; n < appointments.length; n++) {
|
for (let n = 0; n < appointments.length; n++) {
|
||||||
let a = appointments[n];
|
let a = appointments[n];
|
||||||
let date = new Date(a[4] * 1000);
|
let date = new Date(a[4] * 1000);
|
||||||
@@ -285,6 +286,7 @@ const DBusEventSource = new Lang.Class({
|
|||||||
newEvents.sort(function(event1, event2) {
|
newEvents.sort(function(event1, event2) {
|
||||||
return event1.date.getTime() - event2.date.getTime();
|
return event1.date.getTime() - event2.date.getTime();
|
||||||
});
|
});
|
||||||
|
}
|
||||||
|
|
||||||
this._events = newEvents;
|
this._events = newEvents;
|
||||||
this.emit('changed');
|
this.emit('changed');
|
||||||
@@ -292,19 +294,14 @@ const DBusEventSource = new Lang.Class({
|
|||||||
|
|
||||||
_loadEvents: function(forceReload) {
|
_loadEvents: function(forceReload) {
|
||||||
if (this._curRequestBegin && this._curRequestEnd){
|
if (this._curRequestBegin && this._curRequestEnd){
|
||||||
/* Can't use GetEventsRemote because we need to pass the
|
|
||||||
flags here */
|
|
||||||
let callFlags = Gio.DBusCallFlags.NO_AUTO_START;
|
let callFlags = Gio.DBusCallFlags.NO_AUTO_START;
|
||||||
if (forceReload)
|
if (forceReload)
|
||||||
callFlags = Gio.DBusCallFlags.NONE;
|
callFlags = Gio.DBusCallFlags.NONE;
|
||||||
this._dbusProxy.call("GetEvents",
|
this._dbusProxy.GetEventsRemote(this._curRequestBegin.getTime() / 1000,
|
||||||
GLib.Variant.new("(xxb)", [this._curRequestBegin.getTime() / 1000,
|
|
||||||
this._curRequestEnd.getTime() / 1000,
|
this._curRequestEnd.getTime() / 1000,
|
||||||
forceReload]),
|
forceReload,
|
||||||
callFlags,
|
Lang.bind(this, this._onEventsReceived),
|
||||||
-1,
|
callFlags);
|
||||||
null,
|
|
||||||
Lang.bind(this, this._onEventsReceived));
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
@@ -397,6 +394,7 @@ const Calendar = new Lang.Class({
|
|||||||
this._eventSourceChangedId = this._eventSource.connect('changed', Lang.bind(this, function() {
|
this._eventSourceChangedId = this._eventSource.connect('changed', Lang.bind(this, function() {
|
||||||
this._update(false);
|
this._update(false);
|
||||||
}));
|
}));
|
||||||
|
this._update(true);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
93
js/ui/centerLayout.js
Normal file
93
js/ui/centerLayout.js
Normal file
@@ -0,0 +1,93 @@
|
|||||||
|
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
|
||||||
|
|
||||||
|
const Lang = imports.lang;
|
||||||
|
const Clutter = imports.gi.Clutter;
|
||||||
|
const St = imports.gi.St;
|
||||||
|
|
||||||
|
function connectLayoutManager(layoutManager, styleChanged) {
|
||||||
|
let widget, styleChangedId;
|
||||||
|
|
||||||
|
function _styleChanged() {
|
||||||
|
let themeNode = widget.get_theme_node();
|
||||||
|
styleChanged(themeNode, widget);
|
||||||
|
}
|
||||||
|
|
||||||
|
function actorChanged() {
|
||||||
|
if (widget) {
|
||||||
|
widget.disconnect(styleChangedId);
|
||||||
|
styleChangedId = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
let actor = layoutManager.get_actor();
|
||||||
|
if (actor && actor instanceof St.Widget) {
|
||||||
|
widget = actor;
|
||||||
|
styleChangedId = widget.connect('style-changed', _styleChanged);
|
||||||
|
_styleChanged();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
layoutManager.connect('notify::actor', actorChanged);
|
||||||
|
return layoutManager;
|
||||||
|
}
|
||||||
|
|
||||||
|
function connectSpacing(layoutManager) {
|
||||||
|
return connectLayoutManager(layoutManager, function(themeNode, widget) {
|
||||||
|
layoutManager.spacing = themeNode.get_length('spacing');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
const CenterLayout = new Lang.Class({
|
||||||
|
Name: 'CenterLayout',
|
||||||
|
Extends: Clutter.BoxLayout,
|
||||||
|
|
||||||
|
vfunc_allocate: function(container, box, flags) {
|
||||||
|
let rtl = container.get_text_direction() == Clutter.TextDirection.RTL;
|
||||||
|
|
||||||
|
let availWidth = box.x2 - box.x1;
|
||||||
|
let availHeight = box.y2 - box.y1;
|
||||||
|
|
||||||
|
// Assume that these are the first three widgets and they are all visible.
|
||||||
|
let [left, center, right] = container.get_children();
|
||||||
|
|
||||||
|
// Only support horizontal layouts for now.
|
||||||
|
let [centerMinWidth, centerNaturalWidth] = center.get_preferred_width(availWidth);
|
||||||
|
|
||||||
|
let sideWidth = (availWidth - centerNaturalWidth) / 2;
|
||||||
|
|
||||||
|
let childBox = new Clutter.ActorBox();
|
||||||
|
childBox.y1 = box.y1;
|
||||||
|
childBox.y2 = box.y1 + availHeight;
|
||||||
|
|
||||||
|
if (left) {
|
||||||
|
let [leftMinWidth, leftNaturalWidth] = left.get_preferred_width(availWidth);
|
||||||
|
let leftSide = Math.min(Math.floor(sideWidth), leftNaturalWidth);
|
||||||
|
if (rtl) {
|
||||||
|
childBox.x1 = availWidth - leftSide;
|
||||||
|
childBox.x2 = availWidth;
|
||||||
|
} else {
|
||||||
|
childBox.x1 = 0;
|
||||||
|
childBox.x2 = leftSide;
|
||||||
|
}
|
||||||
|
childBox.x1 += box.x1;
|
||||||
|
left.allocate(childBox, flags);
|
||||||
|
}
|
||||||
|
|
||||||
|
childBox.x1 = box.x1 + Math.ceil(sideWidth);
|
||||||
|
childBox.x2 = childBox.x1 + centerNaturalWidth;
|
||||||
|
center.allocate(childBox, flags);
|
||||||
|
|
||||||
|
if (right) {
|
||||||
|
let [rightMinWidth, rightNaturalWidth] = right.get_preferred_width(availWidth);
|
||||||
|
let rightSide = Math.min(Math.floor(sideWidth), rightNaturalWidth);
|
||||||
|
if (rtl) {
|
||||||
|
childBox.x1 = 0;
|
||||||
|
childBox.x2 = rightSide;
|
||||||
|
} else {
|
||||||
|
childBox.x1 = availWidth - rightSide;
|
||||||
|
childBox.x2 = availWidth;
|
||||||
|
}
|
||||||
|
childBox.x1 += box.x1;
|
||||||
|
right.allocate(childBox, flags);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
@@ -33,9 +33,7 @@ const AutomountManager = new Lang.Class({
|
|||||||
Lang.bind(this, this._InhibitorsChanged));
|
Lang.bind(this, this._InhibitorsChanged));
|
||||||
this._inhibited = false;
|
this._inhibited = false;
|
||||||
|
|
||||||
LoginManager.getLoginManager(Lang.bind(this, function(manager) {
|
this._loginManager = LoginManager.getLoginManager();
|
||||||
this._loginManager = manager;
|
|
||||||
}));
|
|
||||||
this._volumeMonitor = Gio.VolumeMonitor.get();
|
this._volumeMonitor = Gio.VolumeMonitor.get();
|
||||||
},
|
},
|
||||||
|
|
||||||
@@ -87,7 +85,7 @@ const AutomountManager = new Lang.Class({
|
|||||||
_onDriveConnected: function() {
|
_onDriveConnected: function() {
|
||||||
// if we're not in the current ConsoleKit session,
|
// if we're not in the current ConsoleKit session,
|
||||||
// or screensaver is active, don't play sounds
|
// or screensaver is active, don't play sounds
|
||||||
if (!this._loginManager || !this._loginManager.sessionActive)
|
if (!this._loginManager.sessionActive)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
global.play_theme_sound(0, 'device-added-media');
|
global.play_theme_sound(0, 'device-added-media');
|
||||||
@@ -96,7 +94,7 @@ const AutomountManager = new Lang.Class({
|
|||||||
_onDriveDisconnected: function() {
|
_onDriveDisconnected: function() {
|
||||||
// if we're not in the current ConsoleKit session,
|
// if we're not in the current ConsoleKit session,
|
||||||
// or screensaver is active, don't play sounds
|
// or screensaver is active, don't play sounds
|
||||||
if (!this._loginManager || !this._loginManager.sessionActive)
|
if (!this._loginManager.sessionActive)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
global.play_theme_sound(0, 'device-removed-media');
|
global.play_theme_sound(0, 'device-removed-media');
|
||||||
@@ -105,7 +103,7 @@ const AutomountManager = new Lang.Class({
|
|||||||
_onDriveEjectButton: function(monitor, drive) {
|
_onDriveEjectButton: function(monitor, drive) {
|
||||||
// TODO: this code path is not tested, as the GVfs volume monitor
|
// TODO: this code path is not tested, as the GVfs volume monitor
|
||||||
// doesn't emit this signal just yet.
|
// doesn't emit this signal just yet.
|
||||||
if (!this._loginManager || !this._loginManager.sessionActive)
|
if (!this._loginManager.sessionActive)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// we force stop/eject in this case, so we don't have to pass a
|
// we force stop/eject in this case, so we don't have to pass a
|
||||||
@@ -145,7 +143,7 @@ const AutomountManager = new Lang.Class({
|
|||||||
if (params.checkSession) {
|
if (params.checkSession) {
|
||||||
// if we're not in the current ConsoleKit session,
|
// if we're not in the current ConsoleKit session,
|
||||||
// don't attempt automount
|
// don't attempt automount
|
||||||
if (!this._loginManager || !this._loginManager.sessionActive)
|
if (!this._loginManager.sessionActive)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -2,7 +2,6 @@
|
|||||||
|
|
||||||
const Lang = imports.lang;
|
const Lang = imports.lang;
|
||||||
const Gio = imports.gi.Gio;
|
const Gio = imports.gi.Gio;
|
||||||
const GLib = imports.gi.GLib;
|
|
||||||
const St = imports.gi.St;
|
const St = imports.gi.St;
|
||||||
|
|
||||||
const LoginManager = imports.misc.loginManager;
|
const LoginManager = imports.misc.loginManager;
|
||||||
@@ -83,16 +82,12 @@ const HotplugSnifferIface = <interface name="org.gnome.Shell.HotplugSniffer">
|
|||||||
</method>
|
</method>
|
||||||
</interface>;
|
</interface>;
|
||||||
|
|
||||||
const HotplugSniffer = new Gio.DBusProxyClass({
|
const HotplugSnifferProxy = Gio.DBusProxy.makeProxyWrapper(HotplugSnifferIface);
|
||||||
Name: 'HotplugSnifferProxy',
|
function HotplugSniffer() {
|
||||||
Interface: HotplugSnifferIface,
|
return new HotplugSnifferProxy(Gio.DBus.session,
|
||||||
|
'org.gnome.Shell.HotplugSniffer',
|
||||||
_init: function() {
|
'/org/gnome/Shell/HotplugSniffer');
|
||||||
this.parent({ g_bus_type: Gio.BusType.SESSION,
|
|
||||||
g_name: 'org.gnome.Shell.HotplugSniffer',
|
|
||||||
g_object_path: '/org/gnome/Shell/HotplugSniffer' });
|
|
||||||
}
|
}
|
||||||
});
|
|
||||||
|
|
||||||
const ContentTypeDiscoverer = new Lang.Class({
|
const ContentTypeDiscoverer = new Lang.Class({
|
||||||
Name: 'ContentTypeDiscoverer',
|
Name: 'ContentTypeDiscoverer',
|
||||||
@@ -132,14 +127,10 @@ const ContentTypeDiscoverer = new Lang.Class({
|
|||||||
let root = mount.get_root();
|
let root = mount.get_root();
|
||||||
|
|
||||||
let hotplugSniffer = new HotplugSniffer();
|
let hotplugSniffer = new HotplugSniffer();
|
||||||
hotplugSniffer.init_async(GLib.PRIORITY_DEFAULT, null, Lang.bind(this, function(proxy, result) {
|
hotplugSniffer.SniffURIRemote(root.get_uri(),
|
||||||
proxy.init_finish(result);
|
Lang.bind(this, function([contentTypes]) {
|
||||||
|
|
||||||
proxy.SniffURIRemote(root.get_uri(), null, Lang.bind(this, function(proxy, result) {
|
|
||||||
let [contentTypes] = proxy.SniffURIFinish(result);
|
|
||||||
this._emitCallback(mount, contentTypes);
|
this._emitCallback(mount, contentTypes);
|
||||||
}));
|
}));
|
||||||
}));
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
@@ -171,9 +162,7 @@ const AutorunManager = new Lang.Class({
|
|||||||
Name: 'AutorunManager',
|
Name: 'AutorunManager',
|
||||||
|
|
||||||
_init: function() {
|
_init: function() {
|
||||||
LoginManager.getLoginManager(Lang.bind(this, function(manager) {
|
this._loginManager = LoginManager.getLoginManager();
|
||||||
this._loginManager = manager;
|
|
||||||
}));
|
|
||||||
|
|
||||||
this._volumeMonitor = Gio.VolumeMonitor.get();
|
this._volumeMonitor = Gio.VolumeMonitor.get();
|
||||||
|
|
||||||
@@ -226,7 +215,7 @@ const AutorunManager = new Lang.Class({
|
|||||||
_onMountAdded: function(monitor, mount) {
|
_onMountAdded: function(monitor, mount) {
|
||||||
// don't do anything if our session is not the currently
|
// don't do anything if our session is not the currently
|
||||||
// active one
|
// active one
|
||||||
if (!this._loginManager || !this._loginManager.sessionActive)
|
if (!this._loginManager.sessionActive)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
this._processMount(mount, true);
|
this._processMount(mount, true);
|
||||||
|
@@ -372,6 +372,9 @@ const Dash = new Lang.Class({
|
|||||||
this._maxHeight = -1;
|
this._maxHeight = -1;
|
||||||
this.iconSize = 64;
|
this.iconSize = 64;
|
||||||
this._shownInitially = false;
|
this._shownInitially = false;
|
||||||
|
this.visible = false;
|
||||||
|
this._hiddenX;
|
||||||
|
this._targetX;
|
||||||
|
|
||||||
this._dragPlaceholder = null;
|
this._dragPlaceholder = null;
|
||||||
this._dragPlaceholderPos = -1;
|
this._dragPlaceholderPos = -1;
|
||||||
@@ -399,6 +402,7 @@ const Dash = new Lang.Class({
|
|||||||
function() {
|
function() {
|
||||||
if (this._maxHeight != this.actor.height)
|
if (this._maxHeight != this.actor.height)
|
||||||
this._queueRedisplay();
|
this._queueRedisplay();
|
||||||
|
if (this.actor.height > this._maxHeight)
|
||||||
this._maxHeight = this.actor.height;
|
this._maxHeight = this.actor.height;
|
||||||
}));
|
}));
|
||||||
|
|
||||||
@@ -410,11 +414,11 @@ const Dash = new Lang.Class({
|
|||||||
AppFavorites.getAppFavorites().connect('changed', Lang.bind(this, this._queueRedisplay));
|
AppFavorites.getAppFavorites().connect('changed', Lang.bind(this, this._queueRedisplay));
|
||||||
this._appSystem.connect('app-state-changed', Lang.bind(this, this._queueRedisplay));
|
this._appSystem.connect('app-state-changed', Lang.bind(this, this._queueRedisplay));
|
||||||
|
|
||||||
Main.overview.connect('item-drag-begin',
|
Main.overview.connect('app-drag-begin',
|
||||||
Lang.bind(this, this._onDragBegin));
|
Lang.bind(this, this._onDragBegin));
|
||||||
Main.overview.connect('item-drag-end',
|
Main.overview.connect('app-drag-end',
|
||||||
Lang.bind(this, this._onDragEnd));
|
Lang.bind(this, this._onDragEnd));
|
||||||
Main.overview.connect('item-drag-cancelled',
|
Main.overview.connect('app-drag-cancelled',
|
||||||
Lang.bind(this, this._onDragCancelled));
|
Lang.bind(this, this._onDragCancelled));
|
||||||
Main.overview.connect('window-drag-begin',
|
Main.overview.connect('window-drag-begin',
|
||||||
Lang.bind(this, this._onDragBegin));
|
Lang.bind(this, this._onDragBegin));
|
||||||
@@ -546,6 +550,17 @@ const Dash = new Lang.Class({
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
_computeDashX: function() {
|
||||||
|
this._targetX = this.actor.get_x();
|
||||||
|
|
||||||
|
let rtl = (this.actor.get_text_direction() == Clutter.TextDirection.RTL);
|
||||||
|
|
||||||
|
if (rtl)
|
||||||
|
this._hiddenX = this._targetX + this.actor.width;
|
||||||
|
else
|
||||||
|
this._hiddenX = -this.actor.width;
|
||||||
|
},
|
||||||
|
|
||||||
_adjustIconSize: function() {
|
_adjustIconSize: function() {
|
||||||
// For the icon size, we only consider children which are "proper"
|
// For the icon size, we only consider children which are "proper"
|
||||||
// icons (i.e. ignoring drag placeholders) and which are not
|
// icons (i.e. ignoring drag placeholders) and which are not
|
||||||
@@ -641,6 +656,8 @@ const Dash = new Lang.Class({
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this._computeDashX();
|
||||||
},
|
},
|
||||||
|
|
||||||
_redisplay: function () {
|
_redisplay: function () {
|
||||||
@@ -757,6 +774,7 @@ const Dash = new Lang.Class({
|
|||||||
// of items, to avoid all items zooming in at once
|
// of items, to avoid all items zooming in at once
|
||||||
if (!this._shownInitially) {
|
if (!this._shownInitially) {
|
||||||
this._shownInitially = true;
|
this._shownInitially = true;
|
||||||
|
this.visible = true;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -901,6 +919,34 @@ const Dash = new Lang.Class({
|
|||||||
}));
|
}));
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
},
|
||||||
|
|
||||||
|
show: function() {
|
||||||
|
if (this.visible)
|
||||||
|
return;
|
||||||
|
|
||||||
|
this.visible = true;
|
||||||
|
|
||||||
|
this.actor.show();
|
||||||
|
Tweener.addTween(this.actor, { translation_x: this._targetX,
|
||||||
|
transition: 'easeOutQuad',
|
||||||
|
time: DASH_ANIMATION_TIME
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
hide: function() {
|
||||||
|
if (!this.visible)
|
||||||
|
return;
|
||||||
|
|
||||||
|
this.visible = false;
|
||||||
|
|
||||||
|
Tweener.addTween(this.actor, { translation_x: this._hiddenX,
|
||||||
|
transition: 'easeOutQuad',
|
||||||
|
time: DASH_ANIMATION_TIME,
|
||||||
|
onComplete: Lang.bind(this, function () {
|
||||||
|
this.actor.hide();
|
||||||
|
})
|
||||||
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@@ -105,7 +105,7 @@ const restartDialogContent = {
|
|||||||
endDescription: _("Restarting the system."),
|
endDescription: _("Restarting the system."),
|
||||||
confirmButtons: [{ signal: 'ConfirmedReboot',
|
confirmButtons: [{ signal: 'ConfirmedReboot',
|
||||||
label: C_("button", "Restart") }],
|
label: C_("button", "Restart") }],
|
||||||
iconName: 'view-refresh-symbolic',
|
iconName: 'system-shutdown-symbolic',
|
||||||
iconStyleClass: 'end-session-dialog-shutdown-icon'
|
iconStyleClass: 'end-session-dialog-shutdown-icon'
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -218,34 +218,6 @@ function init() {
|
|||||||
_endSessionDialog = new EndSessionDialog();
|
_endSessionDialog = new EndSessionDialog();
|
||||||
}
|
}
|
||||||
|
|
||||||
const EndSessionExporter = new Gio.DBusImplementerClass({
|
|
||||||
Name: 'EndSessionExporter',
|
|
||||||
Interface: EndSessionDialogIface,
|
|
||||||
|
|
||||||
_init: function() {
|
|
||||||
this.parent();
|
|
||||||
|
|
||||||
this.export(Gio.DBus.session, '/org/gnome/SessionManager/EndSessionDialog');
|
|
||||||
},
|
|
||||||
|
|
||||||
OpenAsync: function(parameters, invocation) {
|
|
||||||
this.emit('open', parameters, invocation);
|
|
||||||
},
|
|
||||||
|
|
||||||
close: function() {
|
|
||||||
this.emit_signal('Closed');
|
|
||||||
},
|
|
||||||
|
|
||||||
cancel: function() {
|
|
||||||
this.emit_signal('Canceled');
|
|
||||||
},
|
|
||||||
|
|
||||||
confirm: function(type) {
|
|
||||||
this.emit_signal(type);
|
|
||||||
},
|
|
||||||
});
|
|
||||||
Signals.addSignalMethods(EndSessionExporter.prototype);
|
|
||||||
|
|
||||||
const EndSessionDialog = new Lang.Class({
|
const EndSessionDialog = new Lang.Class({
|
||||||
Name: 'EndSessionDialog',
|
Name: 'EndSessionDialog',
|
||||||
Extends: ModalDialog.ModalDialog,
|
Extends: ModalDialog.ModalDialog,
|
||||||
@@ -323,8 +295,8 @@ const EndSessionDialog = new Lang.Class({
|
|||||||
scrollView.hide();
|
scrollView.hide();
|
||||||
}));
|
}));
|
||||||
|
|
||||||
this._exporter = new EndSessionExporter();
|
this._dbusImpl = Gio.DBusExportedObject.wrapJSObject(EndSessionDialogIface, this);
|
||||||
this._exporter.connect('open', Lang.bind(this, this._onOpenRequest));
|
this._dbusImpl.export(Gio.DBus.session, '/org/gnome/SessionManager/EndSessionDialog');
|
||||||
},
|
},
|
||||||
|
|
||||||
_onDestroy: function() {
|
_onDestroy: function() {
|
||||||
@@ -415,19 +387,19 @@ const EndSessionDialog = new Lang.Class({
|
|||||||
|
|
||||||
close: function() {
|
close: function() {
|
||||||
this.parent();
|
this.parent();
|
||||||
this._exporter.close();
|
this._dbusImpl.emit_signal('Closed', null);
|
||||||
},
|
},
|
||||||
|
|
||||||
cancel: function() {
|
cancel: function() {
|
||||||
this._stopTimer();
|
this._stopTimer();
|
||||||
this._exporter.cancel();
|
this._dbusImpl.emit_signal('Canceled', null);
|
||||||
this.close(global.get_current_time());
|
this.close(global.get_current_time());
|
||||||
},
|
},
|
||||||
|
|
||||||
_confirm: function(signal) {
|
_confirm: function(signal) {
|
||||||
this._fadeOutDialog();
|
this._fadeOutDialog();
|
||||||
this._stopTimer();
|
this._stopTimer();
|
||||||
this._exporter.confirm(signal);
|
this._dbusImpl.emit_signal(signal, null);
|
||||||
},
|
},
|
||||||
|
|
||||||
_onOpened: function() {
|
_onOpened: function() {
|
||||||
@@ -480,7 +452,7 @@ const EndSessionDialog = new Lang.Class({
|
|||||||
this._updateContent();
|
this._updateContent();
|
||||||
},
|
},
|
||||||
|
|
||||||
_onOpenRequest: function(exporter, parameters, invocation) {
|
OpenAsync: function(parameters, invocation) {
|
||||||
let [type, timestamp, totalSecondsToStayOpen, inhibitorObjectPaths] = parameters;
|
let [type, timestamp, totalSecondsToStayOpen, inhibitorObjectPaths] = parameters;
|
||||||
this._totalSecondsToStayOpen = totalSecondsToStayOpen;
|
this._totalSecondsToStayOpen = totalSecondsToStayOpen;
|
||||||
this._inhibitors = [];
|
this._inhibitors = [];
|
||||||
@@ -494,10 +466,7 @@ const EndSessionDialog = new Lang.Class({
|
|||||||
}
|
}
|
||||||
|
|
||||||
for (let i = 0; i < inhibitorObjectPaths.length; i++) {
|
for (let i = 0; i < inhibitorObjectPaths.length; i++) {
|
||||||
let inhibitor = new GnomeSession.Inhibitor(inhibitorObjectPaths[i]);
|
let inhibitor = new GnomeSession.Inhibitor(inhibitorObjectPaths[i], Lang.bind(this, function(proxy, error) {
|
||||||
inhibitor.init_async(GLib.PRIORITY_DEFAULT, null, Lang.bind(this, function(proxy, result) {
|
|
||||||
proxy.init_finish(result);
|
|
||||||
|
|
||||||
this._onInhibitorLoaded(proxy);
|
this._onInhibitorLoaded(proxy);
|
||||||
}));
|
}));
|
||||||
|
|
||||||
|
@@ -198,7 +198,11 @@ const IconGrid = new Lang.Class({
|
|||||||
|
|
||||||
_getPreferredHeight: function (grid, forWidth, alloc) {
|
_getPreferredHeight: function (grid, forWidth, alloc) {
|
||||||
let children = this._getVisibleChildren();
|
let children = this._getVisibleChildren();
|
||||||
let [nColumns, usedWidth] = this._computeLayout(forWidth);
|
let nColumns;
|
||||||
|
if (forWidth < 0)
|
||||||
|
nColumns = children.length;
|
||||||
|
else
|
||||||
|
nColumns = this._computeLayout(forWidth)[0];
|
||||||
let nRows;
|
let nRows;
|
||||||
if (nColumns > 0)
|
if (nColumns > 0)
|
||||||
nRows = Math.ceil(children.length / nColumns);
|
nRows = Math.ceil(children.length / nColumns);
|
||||||
|
@@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
const Caribou = imports.gi.Caribou;
|
const Caribou = imports.gi.Caribou;
|
||||||
const Clutter = imports.gi.Clutter;
|
const Clutter = imports.gi.Clutter;
|
||||||
|
const DBus = imports.dbus;
|
||||||
const Gdk = imports.gi.Gdk;
|
const Gdk = imports.gi.Gdk;
|
||||||
const Gio = imports.gi.Gio;
|
const Gio = imports.gi.Gio;
|
||||||
const GLib = imports.gi.GLib;
|
const GLib = imports.gi.GLib;
|
||||||
@@ -190,14 +191,13 @@ const Key = new Lang.Class({
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
const Keyboard = new Gio.DBusImplementerClass({
|
const Keyboard = new Lang.Class({
|
||||||
// HACK: we can't set Name, because it collides with Name dbus property
|
// HACK: we can't set Name, because it collides with Name dbus property
|
||||||
// Name: 'Keyboard',
|
// Name: 'Keyboard',
|
||||||
Interface: CaribouKeyboardIface,
|
|
||||||
|
|
||||||
_init: function () {
|
_init: function () {
|
||||||
this.parent();
|
this._impl = Gio.DBusExportedObject.wrapJSObject(CaribouKeyboardIface, this);
|
||||||
this.export(Gio.DBus.session, '/org/gnome/Caribou/Keyboard');
|
this._impl.export(Gio.DBus.session, '/org/gnome/Caribou/Keyboard');
|
||||||
|
|
||||||
this.actor = null;
|
this.actor = null;
|
||||||
this._focusInTray = false;
|
this._focusInTray = false;
|
||||||
|
@@ -96,15 +96,14 @@ const ZoomRegionIface = <interface name={ZOOM_SERVICE_NAME}>
|
|||||||
// '/org/gnome/Magnifier/ZoomRegion/zoomer1', etc.
|
// '/org/gnome/Magnifier/ZoomRegion/zoomer1', etc.
|
||||||
let _zoomRegionInstanceCount = 0;
|
let _zoomRegionInstanceCount = 0;
|
||||||
|
|
||||||
const ShellMagnifier = new Gio.DBusImplementerClass({
|
const ShellMagnifier = new Lang.Class({
|
||||||
Name: 'ShellMagnifier',
|
Name: 'ShellMagnifier',
|
||||||
Interface: MagnifierIface,
|
|
||||||
|
|
||||||
_init: function() {
|
_init: function() {
|
||||||
this.parent();
|
|
||||||
this.export(Gio.DBus.session, MAG_SERVICE_PATH);
|
|
||||||
|
|
||||||
this._zoomers = {};
|
this._zoomers = {};
|
||||||
|
|
||||||
|
this._dbusImpl = Gio.DBusExportedObject.wrapJSObject(MagnifierIface, this);
|
||||||
|
this._dbusImpl.export(Gio.DBus.session, MAG_SERVICE_PATH);
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -333,15 +332,14 @@ const ShellMagnifier = new Gio.DBusImplementerClass({
|
|||||||
* @zoomerObjectPath: String that is the path to a DBus ZoomRegion.
|
* @zoomerObjectPath: String that is the path to a DBus ZoomRegion.
|
||||||
* @zoomRegion: The actual zoom region associated with the object path.
|
* @zoomRegion: The actual zoom region associated with the object path.
|
||||||
*/
|
*/
|
||||||
const ShellMagnifierZoomRegion = new Gio.DBusImplementerClass({
|
const ShellMagnifierZoomRegion = new Lang.Class({
|
||||||
Name: 'ShellMagnifierZoomRegion',
|
Name: 'ShellMagnifierZoomRegion',
|
||||||
Interface: ZoomRegionIface,
|
|
||||||
|
|
||||||
_init: function(zoomerObjectPath, zoomRegion) {
|
_init: function(zoomerObjectPath, zoomRegion) {
|
||||||
this.parent();
|
|
||||||
this.export(Gio.DBus.session, zoomerObjectPath);
|
|
||||||
|
|
||||||
this._zoomRegion = zoomRegion;
|
this._zoomRegion = zoomRegion;
|
||||||
|
|
||||||
|
this._dbusImpl = Gio.DBusExportedObject.wrapJSObject(ZoomRegionIface, this);
|
||||||
|
this._dbusImpl.export(Gio.DBus.session, zoomerObjectPath);
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -419,6 +417,6 @@ const ShellMagnifierZoomRegion = new Gio.DBusImplementerClass({
|
|||||||
},
|
},
|
||||||
|
|
||||||
destroy: function() {
|
destroy: function() {
|
||||||
this.unexport();
|
this._dbusImpl.unexport();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@@ -1365,16 +1365,13 @@ const MessageTray = new Lang.Class({
|
|||||||
Name: 'MessageTray',
|
Name: 'MessageTray',
|
||||||
|
|
||||||
_init: function() {
|
_init: function() {
|
||||||
this._presence = new GnomeSession.Presence();
|
this._presence = new GnomeSession.Presence(Lang.bind(this, function(proxy, error) {
|
||||||
this._presence.init_async(GLib.PRIORITY_DEFAULT, null, Lang.bind(this, function(proxy, result) {
|
|
||||||
proxy.init_finish(result);
|
|
||||||
|
|
||||||
this._onStatusChanged(proxy.status);
|
this._onStatusChanged(proxy.status);
|
||||||
|
}));
|
||||||
|
this._busy = false;
|
||||||
this._presence.connectSignal('StatusChanged', Lang.bind(this, function(proxy, senderName, [status]) {
|
this._presence.connectSignal('StatusChanged', Lang.bind(this, function(proxy, senderName, [status]) {
|
||||||
this._onStatusChanged(status);
|
this._onStatusChanged(status);
|
||||||
}));
|
}));
|
||||||
}));
|
|
||||||
this._busy = false;
|
|
||||||
|
|
||||||
this.actor = new St.Widget({ name: 'message-tray',
|
this.actor = new St.Widget({ name: 'message-tray',
|
||||||
reactive: true,
|
reactive: true,
|
||||||
@@ -1501,7 +1498,7 @@ const MessageTray = new Lang.Class({
|
|||||||
this._overviewVisible = true;
|
this._overviewVisible = true;
|
||||||
this._grabHelper.ungrab(); // drop modal grab if necessary
|
this._grabHelper.ungrab(); // drop modal grab if necessary
|
||||||
this.actor.add_style_pseudo_class('overview');
|
this.actor.add_style_pseudo_class('overview');
|
||||||
this._updateState();
|
this.show();
|
||||||
}));
|
}));
|
||||||
Main.overview.connect('hiding', Lang.bind(this,
|
Main.overview.connect('hiding', Lang.bind(this,
|
||||||
function() {
|
function() {
|
||||||
@@ -1739,6 +1736,11 @@ const MessageTray = new Lang.Class({
|
|||||||
this._updateState();
|
this._updateState();
|
||||||
},
|
},
|
||||||
|
|
||||||
|
show: function() {
|
||||||
|
this._traySummoned = true;
|
||||||
|
this._updateState();
|
||||||
|
},
|
||||||
|
|
||||||
_onNotify: function(source, notification) {
|
_onNotify: function(source, notification) {
|
||||||
if (this._summaryBoxPointerItem && this._summaryBoxPointerItem.source == source) {
|
if (this._summaryBoxPointerItem && this._summaryBoxPointerItem.source == source) {
|
||||||
if (this._summaryBoxPointerState == State.HIDING) {
|
if (this._summaryBoxPointerState == State.HIDING) {
|
||||||
@@ -1981,7 +1983,7 @@ const MessageTray = new Lang.Class({
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Summary
|
// Summary
|
||||||
let summarySummoned = this._pointerInSummary || this._overviewVisible || this._traySummoned;
|
let summarySummoned = this._pointerInSummary || this._traySummoned;
|
||||||
let summaryPinned = this._pointerInTray || summarySummoned || this._locked;
|
let summaryPinned = this._pointerInTray || summarySummoned || this._locked;
|
||||||
let summaryHovered = this._pointerInTray || this._pointerInSummary;
|
let summaryHovered = this._pointerInTray || this._pointerInSummary;
|
||||||
|
|
||||||
@@ -1989,7 +1991,7 @@ const MessageTray = new Lang.Class({
|
|||||||
this._notificationState == State.SHOWN);
|
this._notificationState == State.SHOWN);
|
||||||
let notificationsDone = !notificationsVisible && !notificationsPending;
|
let notificationsDone = !notificationsVisible && !notificationsPending;
|
||||||
|
|
||||||
let summaryOptionalInOverview = this._overviewVisible && !this._locked && !summaryHovered;
|
let summaryOptionalInOverview = !this._locked && !summaryHovered;
|
||||||
let mustHideSummary = (notificationsPending && (notificationUrgent || summaryOptionalInOverview))
|
let mustHideSummary = (notificationsPending && (notificationUrgent || summaryOptionalInOverview))
|
||||||
|| notificationsVisible || !Main.sessionMode.hasNotifications;
|
|| notificationsVisible || !Main.sessionMode.hasNotifications;
|
||||||
|
|
||||||
|
@@ -25,19 +25,10 @@ const BusIface = <interface name="org.freedesktop.DBus">
|
|||||||
</method>
|
</method>
|
||||||
</interface>;
|
</interface>;
|
||||||
|
|
||||||
const Bus = new Gio.DBusProxyClass({
|
var BusProxy = Gio.DBusProxy.makeProxyWrapper(BusIface);
|
||||||
Name: 'SessionBusProxy',
|
function Bus() {
|
||||||
Interface: BusIface,
|
return new BusProxy(Gio.DBus.session, 'org.freedesktop.DBus', '/org/freedesktop/DBus');
|
||||||
|
|
||||||
_init: function() {
|
|
||||||
this.parent({ g_bus_type: Gio.BusType.SESSION,
|
|
||||||
g_name: 'org.freedesktop.DBus',
|
|
||||||
g_object_path: '/org/freedesktop/DBus',
|
|
||||||
g_flags: (Gio.DBusProxyFlags.DO_NOT_LOAD_PROPERTIES |
|
|
||||||
Gio.DBusProxyFlags.DO_NOT_CONNECT_SIGNALS |
|
|
||||||
Gio.DBusProxyFlags.DO_NOT_AUTO_START) });
|
|
||||||
}
|
}
|
||||||
});
|
|
||||||
|
|
||||||
const NotificationDaemonIface = <interface name="org.freedesktop.Notifications">
|
const NotificationDaemonIface = <interface name="org.freedesktop.Notifications">
|
||||||
<method name="Notify">
|
<method name="Notify">
|
||||||
@@ -112,20 +103,17 @@ const STANDARD_TRAY_ICON_IMPLEMENTATIONS = {
|
|||||||
'ibus-ui-gtk': 'keyboard'
|
'ibus-ui-gtk': 'keyboard'
|
||||||
};
|
};
|
||||||
|
|
||||||
const NotificationDaemon = new Gio.DBusImplementerClass({
|
const NotificationDaemon = new Lang.Class({
|
||||||
Name: 'NotificationDaemon',
|
Name: 'NotificationDaemon',
|
||||||
Interface: NotificationDaemonIface,
|
|
||||||
|
|
||||||
_init: function() {
|
_init: function() {
|
||||||
this.parent();
|
this._dbusImpl = Gio.DBusExportedObject.wrapJSObject(NotificationDaemonIface, this);
|
||||||
this.export(Gio.DBus.session, '/org/freedesktop/Notifications');
|
this._dbusImpl.export(Gio.DBus.session, '/org/freedesktop/Notifications');
|
||||||
|
|
||||||
this._sources = [];
|
this._sources = [];
|
||||||
this._senderToPid = {};
|
this._senderToPid = {};
|
||||||
this._notifications = {};
|
this._notifications = {};
|
||||||
this._busProxy = new Bus();
|
this._busProxy = new Bus();
|
||||||
// This is synchronous but fast because of the flags we use.
|
|
||||||
this._busProxy.init(null);
|
|
||||||
|
|
||||||
this._trayManager = new Shell.TrayManager();
|
this._trayManager = new Shell.TrayManager();
|
||||||
this._trayIconAddedId = this._trayManager.connect('tray-icon-added', Lang.bind(this, this._onTrayIconAdded));
|
this._trayIconAddedId = this._trayManager.connect('tray-icon-added', Lang.bind(this, this._onTrayIconAdded));
|
||||||
@@ -328,20 +316,18 @@ const NotificationDaemon = new Gio.DBusImplementerClass({
|
|||||||
return invocation.return_value(GLib.Variant.new('(u)', [id]));;
|
return invocation.return_value(GLib.Variant.new('(u)', [id]));;
|
||||||
}
|
}
|
||||||
|
|
||||||
this._busProxy.GetConnectionUnixProcessIDRemote(sender, null, Lang.bind(this, function (proxy, result) {
|
this._busProxy.GetConnectionUnixProcessIDRemote(sender, Lang.bind(this, function (result, excp) {
|
||||||
// The app may have updated or removed the notification
|
// The app may have updated or removed the notification
|
||||||
ndata = this._notifications[id];
|
ndata = this._notifications[id];
|
||||||
if (!ndata)
|
if (!ndata)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
let pid;
|
if (excp) {
|
||||||
try {
|
|
||||||
[pid] = proxy.GetConnectionUnixProcessIDFinish(result);
|
|
||||||
} catch(excp) {
|
|
||||||
logError(excp, 'Call to GetConnectionUnixProcessID failed');
|
logError(excp, 'Call to GetConnectionUnixProcessID failed');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let [pid] = result;
|
||||||
source = this._getSource(appName, pid, ndata, sender, null);
|
source = this._getSource(appName, pid, ndata, sender, null);
|
||||||
|
|
||||||
// We only store sender-pid entries for persistent sources.
|
// We only store sender-pid entries for persistent sources.
|
||||||
@@ -501,11 +487,13 @@ const NotificationDaemon = new Gio.DBusImplementerClass({
|
|||||||
},
|
},
|
||||||
|
|
||||||
_emitNotificationClosed: function(id, reason) {
|
_emitNotificationClosed: function(id, reason) {
|
||||||
this.emit_signal('NotificationClosed', id, reason);
|
this._dbusImpl.emit_signal('NotificationClosed',
|
||||||
|
GLib.Variant.new('(uu)', [id, reason]));
|
||||||
},
|
},
|
||||||
|
|
||||||
_emitActionInvoked: function(id, action) {
|
_emitActionInvoked: function(id, action) {
|
||||||
this.emit_signal('ActionInvoked', id, action);
|
this._dbusImpl.emit_signal('ActionInvoked',
|
||||||
|
GLib.Variant.new('(us)', [id, action]));
|
||||||
},
|
},
|
||||||
|
|
||||||
_onTrayIconAdded: function(o, icon) {
|
_onTrayIconAdded: function(o, icon) {
|
||||||
|
@@ -10,6 +10,7 @@ const St = imports.gi.St;
|
|||||||
const Shell = imports.gi.Shell;
|
const Shell = imports.gi.Shell;
|
||||||
const Gdk = imports.gi.Gdk;
|
const Gdk = imports.gi.Gdk;
|
||||||
|
|
||||||
|
const CenterLayout = imports.ui.centerLayout;
|
||||||
const Dash = imports.ui.dash;
|
const Dash = imports.ui.dash;
|
||||||
const DND = imports.ui.dnd;
|
const DND = imports.ui.dnd;
|
||||||
const Main = imports.ui.main;
|
const Main = imports.ui.main;
|
||||||
@@ -23,9 +24,6 @@ const WorkspaceThumbnail = imports.ui.workspaceThumbnail;
|
|||||||
// Time for initial animation going into Overview mode
|
// Time for initial animation going into Overview mode
|
||||||
const ANIMATION_TIME = 0.25;
|
const ANIMATION_TIME = 0.25;
|
||||||
|
|
||||||
// XXX -- grab this automatically. Hard to do.
|
|
||||||
const DASH_MAX_WIDTH = 96;
|
|
||||||
|
|
||||||
const DND_WINDOW_SWITCH_TIMEOUT = 1250;
|
const DND_WINDOW_SWITCH_TIMEOUT = 1250;
|
||||||
|
|
||||||
const SwipeScrollDirection = {
|
const SwipeScrollDirection = {
|
||||||
@@ -119,23 +117,18 @@ const Overview = new Lang.Class({
|
|||||||
this._desktopFade = new St.Bin();
|
this._desktopFade = new St.Bin();
|
||||||
global.overlay_group.add_actor(this._desktopFade);
|
global.overlay_group.add_actor(this._desktopFade);
|
||||||
|
|
||||||
this._spacing = 0;
|
|
||||||
|
|
||||||
/* Translators: This is the main view to select
|
/* Translators: This is the main view to select
|
||||||
activities. See also note for "Activities" string. */
|
activities. See also note for "Activities" string. */
|
||||||
this._group = new St.Widget({ name: 'overview',
|
this._overview = new St.BoxLayout({ name: 'overview',
|
||||||
accessible_name: _("Overview"),
|
accessible_name: _("Overview"),
|
||||||
reactive: true });
|
reactive: true,
|
||||||
this._group._delegate = this;
|
vertical: true });
|
||||||
this._group.connect('style-changed',
|
this._overview._delegate = this;
|
||||||
Lang.bind(this, function() {
|
|
||||||
let node = this._group.get_theme_node();
|
let layout = new CenterLayout.CenterLayout();
|
||||||
let spacing = node.get_length('spacing');
|
CenterLayout.connectSpacing(layout);
|
||||||
if (spacing != this._spacing) {
|
this._group = new St.Widget({ name: 'overview-group',
|
||||||
this._spacing = spacing;
|
layout_manager: layout });
|
||||||
this._relayout();
|
|
||||||
}
|
|
||||||
}));
|
|
||||||
|
|
||||||
this._scrollDirection = SwipeScrollDirection.NONE;
|
this._scrollDirection = SwipeScrollDirection.NONE;
|
||||||
this._scrollAdjustment = null;
|
this._scrollAdjustment = null;
|
||||||
@@ -148,18 +141,19 @@ const Overview = new Lang.Class({
|
|||||||
this._modal = false; // have a modal grab
|
this._modal = false; // have a modal grab
|
||||||
this.animationInProgress = false;
|
this.animationInProgress = false;
|
||||||
this._hideInProgress = false;
|
this._hideInProgress = false;
|
||||||
|
this.searchActive = false;
|
||||||
|
this.appsActive = false;
|
||||||
|
|
||||||
// During transitions, we raise this to the top to avoid having the overview
|
// During transitions, we raise this to the top to avoid having the overview
|
||||||
// area be reactive; it causes too many issues such as double clicks on
|
// area be reactive; it causes too many issues such as double clicks on
|
||||||
// Dash elements, or mouseover handlers in the workspaces.
|
// Dash elements, or mouseover handlers in the workspaces.
|
||||||
this._coverPane = new Clutter.Rectangle({ opacity: 0,
|
this._coverPane = new Clutter.Rectangle({ opacity: 0,
|
||||||
reactive: true });
|
reactive: true });
|
||||||
this._group.add_actor(this._coverPane);
|
this._overview.add_actor(this._coverPane);
|
||||||
this._coverPane.connect('event', Lang.bind(this, function (actor, event) { return true; }));
|
this._coverPane.connect('event', Lang.bind(this, function (actor, event) { return true; }));
|
||||||
|
|
||||||
|
this._overview.hide();
|
||||||
this._group.hide();
|
global.overlay_group.add_actor(this._overview);
|
||||||
global.overlay_group.add_actor(this._group);
|
|
||||||
|
|
||||||
this._coverPane.hide();
|
this._coverPane.hide();
|
||||||
|
|
||||||
@@ -171,6 +165,8 @@ const Overview = new Lang.Class({
|
|||||||
Main.xdndHandler.connect('drag-begin', Lang.bind(this, this._onDragBegin));
|
Main.xdndHandler.connect('drag-begin', Lang.bind(this, this._onDragBegin));
|
||||||
Main.xdndHandler.connect('drag-end', Lang.bind(this, this._onDragEnd));
|
Main.xdndHandler.connect('drag-end', Lang.bind(this, this._onDragEnd));
|
||||||
|
|
||||||
|
global.screen.connect('restacked', Lang.bind(this, this._onRestacked));
|
||||||
|
|
||||||
this._windowSwitchTimeoutId = 0;
|
this._windowSwitchTimeoutId = 0;
|
||||||
this._windowSwitchTimestamp = 0;
|
this._windowSwitchTimestamp = 0;
|
||||||
this._lastActiveWorkspaceIndex = -1;
|
this._lastActiveWorkspaceIndex = -1;
|
||||||
@@ -193,6 +189,13 @@ const Overview = new Lang.Class({
|
|||||||
|
|
||||||
this._shellInfo = new ShellInfo();
|
this._shellInfo = new ShellInfo();
|
||||||
|
|
||||||
|
// Add a clone of the panel to the overview so spacing and such is
|
||||||
|
// automatic
|
||||||
|
this._panelGhost = new St.Bin({ child: new Clutter.Clone({ source: Main.panel.actor }),
|
||||||
|
reactive: false,
|
||||||
|
opacity: 0 });
|
||||||
|
this._overview.add_actor(this._panelGhost);
|
||||||
|
|
||||||
this._searchEntry = new St.Entry({ name: 'searchEntry',
|
this._searchEntry = new St.Entry({ name: 'searchEntry',
|
||||||
/* Translators: this is the text displayed
|
/* Translators: this is the text displayed
|
||||||
in the search entry when no search is
|
in the search entry when no search is
|
||||||
@@ -201,16 +204,13 @@ const Overview = new Lang.Class({
|
|||||||
hint_text: _("Type to search..."),
|
hint_text: _("Type to search..."),
|
||||||
track_hover: true,
|
track_hover: true,
|
||||||
can_focus: true });
|
can_focus: true });
|
||||||
this._group.add_actor(this._searchEntry);
|
this._searchEntryBin = new St.Bin({ child: this._searchEntry,
|
||||||
|
x_align: St.Align.MIDDLE });
|
||||||
this._dash = new Dash.Dash();
|
this._overview.add_actor(this._searchEntryBin);
|
||||||
this._viewSelector = new ViewSelector.ViewSelector(this._searchEntry,
|
|
||||||
this._dash.showAppsButton);
|
|
||||||
this._group.add_actor(this._viewSelector.actor);
|
|
||||||
this._group.add_actor(this._dash.actor);
|
|
||||||
|
|
||||||
// TODO - recalculate everything when desktop size changes
|
// TODO - recalculate everything when desktop size changes
|
||||||
this._dash.actor.add_constraint(this._viewSelector.constrainHeight);
|
this._dash = new Dash.Dash();
|
||||||
|
this._group.add_actor(this._dash.actor);
|
||||||
this.dashIconSize = this._dash.iconSize;
|
this.dashIconSize = this._dash.iconSize;
|
||||||
this._dash.connect('icon-size-changed',
|
this._dash.connect('icon-size-changed',
|
||||||
Lang.bind(this, function() {
|
Lang.bind(this, function() {
|
||||||
@@ -221,6 +221,82 @@ const Overview = new Lang.Class({
|
|||||||
// the left of the overview
|
// the left of the overview
|
||||||
Main.ctrlAltTabManager.addGroup(this._dash.actor, _("Dash"), 'user-bookmarks-symbolic');
|
Main.ctrlAltTabManager.addGroup(this._dash.actor, _("Dash"), 'user-bookmarks-symbolic');
|
||||||
|
|
||||||
|
this._viewSelector = new ViewSelector.ViewSelector(this._searchEntry,
|
||||||
|
this._dash.showAppsButton);
|
||||||
|
this._group.add_actor(this._viewSelector.actor);
|
||||||
|
|
||||||
|
this._thumbnailsBox = new WorkspaceThumbnail.ThumbnailsBox();
|
||||||
|
this._group.add_actor(this._thumbnailsBox.actor);
|
||||||
|
|
||||||
|
// TODO: unique icon
|
||||||
|
Main.ctrlAltTabManager.addGroup(this._thumbnailsBox.actor, _("Workspaces"), 'user-bookmarks-symbolic');
|
||||||
|
|
||||||
|
// Add our same-line elements after the search entry
|
||||||
|
this._overview.add_actor(this._group);
|
||||||
|
|
||||||
|
// Then account for message tray
|
||||||
|
this._messageTrayGhost = new St.Bin({ child: new Clutter.Clone({ source: Main.messageTray.actor }),
|
||||||
|
reactive: false,
|
||||||
|
opacity: 0 });
|
||||||
|
this._overview.add_actor(this._messageTrayGhost);
|
||||||
|
|
||||||
|
this._viewSelector.connect('search-begin', Lang.bind(this,
|
||||||
|
function() {
|
||||||
|
this.searchActive = true;
|
||||||
|
this._dash.hide();
|
||||||
|
this._thumbnailsBox.hide();
|
||||||
|
Main.messageTray.hide();
|
||||||
|
}));
|
||||||
|
this._viewSelector.connect('search-cancelled', Lang.bind(this,
|
||||||
|
function() {
|
||||||
|
this.searchActive = false;
|
||||||
|
this._dash.show();
|
||||||
|
this._thumbnailsBox.show();
|
||||||
|
// search-cancelled is emitted if we leave the overview
|
||||||
|
// directly from searching. That means the message tray will
|
||||||
|
// be shown when we reach the workspace. Don't do this, only
|
||||||
|
// show the message tray on search-cancelled if we are still
|
||||||
|
// in the overview/not transitioning out of it.
|
||||||
|
if (this.visible && !this.animationInProgress)
|
||||||
|
Main.messageTray.show();
|
||||||
|
}));
|
||||||
|
this._viewSelector.connect('apps-button-checked', Lang.bind(this,
|
||||||
|
function(vs, checked) {
|
||||||
|
this.appsActive = checked;
|
||||||
|
if (checked) {
|
||||||
|
this._thumbnailsBox.hide();
|
||||||
|
Main.messageTray.hide();
|
||||||
|
} else {
|
||||||
|
this._thumbnailsBox.show();
|
||||||
|
if (this.visible && !this.animationInProgress)
|
||||||
|
Main.messageTray.show();
|
||||||
|
}
|
||||||
|
}));
|
||||||
|
|
||||||
|
this.connect('app-drag-begin',
|
||||||
|
Lang.bind(this, function () {
|
||||||
|
this._dash.show();
|
||||||
|
this._thumbnailsBox.show();
|
||||||
|
}));
|
||||||
|
this.connect('app-drag-cancelled',
|
||||||
|
Lang.bind(this, function () {
|
||||||
|
if (this.searchActive) {
|
||||||
|
this._dash.hide();
|
||||||
|
this._thumbnailsBox.hide();
|
||||||
|
} else if (this.appsActive) {
|
||||||
|
this._thumbnailsBox.hide();
|
||||||
|
}
|
||||||
|
}));
|
||||||
|
this.connect('app-drag-end',
|
||||||
|
Lang.bind(this, function () {
|
||||||
|
if (this.searchActive) {
|
||||||
|
this._dash.hide();
|
||||||
|
this._thumbnailsBox.hide();
|
||||||
|
} else if (this.appsActive) {
|
||||||
|
this._thumbnailsBox.hide();
|
||||||
|
}
|
||||||
|
}));
|
||||||
|
|
||||||
Main.layoutManager.connect('monitors-changed', Lang.bind(this, this._relayout));
|
Main.layoutManager.connect('monitors-changed', Lang.bind(this, this._relayout));
|
||||||
this._relayout();
|
this._relayout();
|
||||||
},
|
},
|
||||||
@@ -486,55 +562,41 @@ const Overview = new Lang.Class({
|
|||||||
this.hide();
|
this.hide();
|
||||||
|
|
||||||
let primary = Main.layoutManager.primaryMonitor;
|
let primary = Main.layoutManager.primaryMonitor;
|
||||||
let rtl = (Clutter.get_default_text_direction() == Clutter.TextDirection.RTL);
|
|
||||||
|
|
||||||
let contentY = Main.panel.actor.height;
|
let contentY = Main.panel.actor.height;
|
||||||
let contentHeight = primary.height - contentY - Main.messageTray.actor.height;
|
let contentHeight = primary.height - contentY - Main.messageTray.actor.height;
|
||||||
|
|
||||||
this._group.set_position(primary.x, primary.y);
|
this._overview.set_position(primary.x, primary.y);
|
||||||
this._group.set_size(primary.width, primary.height);
|
this._overview.set_size(primary.width, primary.height);
|
||||||
|
|
||||||
this._coverPane.set_position(0, contentY);
|
this._coverPane.set_position(0, contentY);
|
||||||
this._coverPane.set_size(primary.width, contentHeight);
|
this._coverPane.set_size(primary.width, contentHeight);
|
||||||
|
},
|
||||||
|
|
||||||
let searchWidth = this._searchEntry.get_width();
|
_onRestacked: function() {
|
||||||
let searchHeight = this._searchEntry.get_height();
|
let stack = global.get_window_actors();
|
||||||
let searchX = (primary.width - searchWidth) / 2;
|
let stackIndices = {};
|
||||||
let searchY = contentY + this._spacing;
|
|
||||||
|
|
||||||
let dashWidth = DASH_MAX_WIDTH;
|
for (let i = 0; i < stack.length; i++) {
|
||||||
let dashY = searchY + searchHeight + this._spacing;
|
// Use the stable sequence for an integer to use as a hash key
|
||||||
let dashX;
|
stackIndices[stack[i].get_meta_window().get_stable_sequence()] = i;
|
||||||
if (rtl) {
|
|
||||||
this._dash.actor.set_anchor_point_from_gravity(Clutter.Gravity.NORTH_EAST);
|
|
||||||
dashX = primary.width;
|
|
||||||
} else {
|
|
||||||
dashX = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
let viewX = rtl ? 0 : dashWidth + this._spacing;
|
this.emit('sync-window-stacking', stackIndices);
|
||||||
let viewY = searchY + searchHeight + this._spacing;
|
|
||||||
let viewWidth = primary.width - dashWidth - this._spacing;
|
|
||||||
let viewHeight = contentHeight - this._spacing - viewY;
|
|
||||||
|
|
||||||
this._searchEntry.set_position(searchX, searchY);
|
|
||||||
this._dash.actor.set_position(dashX, dashY);
|
|
||||||
this._viewSelector.actor.set_position(viewX, viewY);
|
|
||||||
this._viewSelector.actor.set_size(viewWidth, viewHeight);
|
|
||||||
},
|
},
|
||||||
|
|
||||||
//// Public methods ////
|
//// Public methods ////
|
||||||
|
|
||||||
beginItemDrag: function(source) {
|
beginAppDrag: function(source) {
|
||||||
this.emit('item-drag-begin');
|
this.emit('app-drag-begin');
|
||||||
},
|
},
|
||||||
|
|
||||||
cancelledItemDrag: function(source) {
|
cancelledAppDrag: function(source) {
|
||||||
this.emit('item-drag-cancelled');
|
this.emit('app-drag-cancelled');
|
||||||
},
|
},
|
||||||
|
|
||||||
endItemDrag: function(source) {
|
endAppDrag: function(source) {
|
||||||
this.emit('item-drag-end');
|
this.emit('app-drag-end');
|
||||||
},
|
},
|
||||||
|
|
||||||
beginWindowDrag: function(source) {
|
beginWindowDrag: function(source) {
|
||||||
@@ -558,13 +620,13 @@ const Overview = new Lang.Class({
|
|||||||
if (this._shown)
|
if (this._shown)
|
||||||
return;
|
return;
|
||||||
// Do this manually instead of using _syncInputMode, to handle failure
|
// Do this manually instead of using _syncInputMode, to handle failure
|
||||||
if (!Main.pushModal(this._group))
|
if (!Main.pushModal(this._overview))
|
||||||
return;
|
return;
|
||||||
this._modal = true;
|
this._modal = true;
|
||||||
this._animateVisible();
|
this._animateVisible();
|
||||||
this._shown = true;
|
this._shown = true;
|
||||||
|
|
||||||
this._buttonPressId = this._group.connect('button-press-event',
|
this._buttonPressId = this._overview.connect('button-press-event',
|
||||||
Lang.bind(this, this._onButtonPress));
|
Lang.bind(this, this._onButtonPress));
|
||||||
},
|
},
|
||||||
|
|
||||||
@@ -608,12 +670,12 @@ const Overview = new Lang.Class({
|
|||||||
// Disable unredirection while in the overview
|
// Disable unredirection while in the overview
|
||||||
Meta.disable_unredirect_for_screen(global.screen);
|
Meta.disable_unredirect_for_screen(global.screen);
|
||||||
global.window_group.hide();
|
global.window_group.hide();
|
||||||
this._group.show();
|
this._overview.show();
|
||||||
this._background.show();
|
this._background.show();
|
||||||
this._viewSelector.show();
|
this._viewSelector.show();
|
||||||
|
|
||||||
this._group.opacity = 0;
|
this._overview.opacity = 0;
|
||||||
Tweener.addTween(this._group,
|
Tweener.addTween(this._overview,
|
||||||
{ opacity: 255,
|
{ opacity: 255,
|
||||||
transition: 'easeOutQuad',
|
transition: 'easeOutQuad',
|
||||||
time: ANIMATION_TIME,
|
time: ANIMATION_TIME,
|
||||||
@@ -667,7 +729,7 @@ const Overview = new Lang.Class({
|
|||||||
this._syncInputMode();
|
this._syncInputMode();
|
||||||
|
|
||||||
if (this._buttonPressId > 0)
|
if (this._buttonPressId > 0)
|
||||||
this._group.disconnect(this._buttonPressId);
|
this._overview.disconnect(this._buttonPressId);
|
||||||
this._buttonPressId = 0;
|
this._buttonPressId = 0;
|
||||||
},
|
},
|
||||||
|
|
||||||
@@ -709,20 +771,20 @@ const Overview = new Lang.Class({
|
|||||||
|
|
||||||
if (this._shown) {
|
if (this._shown) {
|
||||||
if (!this._modal) {
|
if (!this._modal) {
|
||||||
if (Main.pushModal(this._group))
|
if (Main.pushModal(this._overview))
|
||||||
this._modal = true;
|
this._modal = true;
|
||||||
else
|
else
|
||||||
this.hide();
|
this.hide();
|
||||||
}
|
}
|
||||||
} else if (this._shownTemporarily) {
|
} else if (this._shownTemporarily) {
|
||||||
if (this._modal) {
|
if (this._modal) {
|
||||||
Main.popModal(this._group);
|
Main.popModal(this._overview);
|
||||||
this._modal = false;
|
this._modal = false;
|
||||||
}
|
}
|
||||||
global.stage_input_mode = Shell.StageInputMode.FULLSCREEN;
|
global.stage_input_mode = Shell.StageInputMode.FULLSCREEN;
|
||||||
} else {
|
} else {
|
||||||
if (this._modal) {
|
if (this._modal) {
|
||||||
Main.popModal(this._group);
|
Main.popModal(this._overview);
|
||||||
this._modal = false;
|
this._modal = false;
|
||||||
}
|
}
|
||||||
else if (global.stage_input_mode == Shell.StageInputMode.FULLSCREEN)
|
else if (global.stage_input_mode == Shell.StageInputMode.FULLSCREEN)
|
||||||
@@ -740,7 +802,7 @@ const Overview = new Lang.Class({
|
|||||||
this._viewSelector.zoomFromOverview();
|
this._viewSelector.zoomFromOverview();
|
||||||
|
|
||||||
// Make other elements fade out.
|
// Make other elements fade out.
|
||||||
Tweener.addTween(this._group,
|
Tweener.addTween(this._overview,
|
||||||
{ opacity: 0,
|
{ opacity: 0,
|
||||||
transition: 'easeOutQuad',
|
transition: 'easeOutQuad',
|
||||||
time: ANIMATION_TIME,
|
time: ANIMATION_TIME,
|
||||||
@@ -782,7 +844,7 @@ const Overview = new Lang.Class({
|
|||||||
this._viewSelector.hide();
|
this._viewSelector.hide();
|
||||||
this._desktopFade.hide();
|
this._desktopFade.hide();
|
||||||
this._background.hide();
|
this._background.hide();
|
||||||
this._group.hide();
|
this._overview.hide();
|
||||||
|
|
||||||
this.visible = false;
|
this.visible = false;
|
||||||
this.animationInProgress = false;
|
this.animationInProgress = false;
|
||||||
|
121
js/ui/panel.js
121
js/ui/panel.js
@@ -15,6 +15,7 @@ const Signals = imports.signals;
|
|||||||
const Atk = imports.gi.Atk;
|
const Atk = imports.gi.Atk;
|
||||||
|
|
||||||
|
|
||||||
|
const CenterLayout = imports.ui.centerLayout;
|
||||||
const Config = imports.misc.config;
|
const Config = imports.misc.config;
|
||||||
const CtrlAltTab = imports.ui.ctrlAltTab;
|
const CtrlAltTab = imports.ui.ctrlAltTab;
|
||||||
const DND = imports.ui.dnd;
|
const DND = imports.ui.dnd;
|
||||||
@@ -931,12 +932,47 @@ try {
|
|||||||
log('NMApplet is not supported. It is possible that your NetworkManager version is too old');
|
log('NMApplet is not supported. It is possible that your NetworkManager version is too old');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const PanelLayout = new Lang.Class({
|
||||||
|
Name: 'PanelLayout',
|
||||||
|
Extends: CenterLayout.CenterLayout,
|
||||||
|
|
||||||
|
vfunc_allocate: function(container, box, flags) {
|
||||||
|
this.parent(container, box, flags);
|
||||||
|
|
||||||
|
let availWidth = box.x2 - box.x1;
|
||||||
|
let availHeight = box.y2 - box.y1;
|
||||||
|
|
||||||
|
let [left, center, right, leftCorner, rightCorner] = container.get_children();
|
||||||
|
let childBox = new Clutter.ActorBox();
|
||||||
|
|
||||||
|
let cornerMinWidth, cornerMinHeight;
|
||||||
|
let cornerWidth, cornerHeight;
|
||||||
|
|
||||||
|
[cornerMinWidth, cornerWidth] = leftCorner.get_preferred_width(-1);
|
||||||
|
[cornerMinHeight, cornerHeight] = leftCorner.get_preferred_height(-1);
|
||||||
|
childBox.x1 = 0;
|
||||||
|
childBox.x2 = cornerWidth;
|
||||||
|
childBox.y1 = availHeight;
|
||||||
|
childBox.y2 = availHeight + cornerHeight;
|
||||||
|
leftCorner.allocate(childBox, flags);
|
||||||
|
|
||||||
|
[cornerMinWidth, cornerWidth] = rightCorner.get_preferred_width(-1);
|
||||||
|
[cornerMinHeight, cornerHeight] = rightCorner.get_preferred_height(-1);
|
||||||
|
childBox.x1 = availWidth - cornerWidth;
|
||||||
|
childBox.x2 = availWidth;
|
||||||
|
childBox.y1 = availHeight;
|
||||||
|
childBox.y2 = availHeight + cornerHeight;
|
||||||
|
rightCorner.allocate(childBox, flags);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
const Panel = new Lang.Class({
|
const Panel = new Lang.Class({
|
||||||
Name: 'Panel',
|
Name: 'Panel',
|
||||||
|
|
||||||
_init : function() {
|
_init : function() {
|
||||||
this.actor = new Shell.GenericContainer({ name: 'panel',
|
this.actor = new St.Widget({ name: 'panel',
|
||||||
reactive: true });
|
reactive: true,
|
||||||
|
layoutManager: new PanelLayout() });
|
||||||
this.actor._delegate = this;
|
this.actor._delegate = this;
|
||||||
|
|
||||||
this.statusArea = {};
|
this.statusArea = {};
|
||||||
@@ -961,7 +997,6 @@ const Panel = new Lang.Class({
|
|||||||
this._leftCorner = new PanelCorner(this._rightBox, St.Side.LEFT);
|
this._leftCorner = new PanelCorner(this._rightBox, St.Side.LEFT);
|
||||||
else
|
else
|
||||||
this._leftCorner = new PanelCorner(this._leftBox, St.Side.LEFT);
|
this._leftCorner = new PanelCorner(this._leftBox, St.Side.LEFT);
|
||||||
|
|
||||||
this.actor.add_actor(this._leftCorner.actor);
|
this.actor.add_actor(this._leftCorner.actor);
|
||||||
|
|
||||||
if (this.actor.get_text_direction() == Clutter.TextDirection.RTL)
|
if (this.actor.get_text_direction() == Clutter.TextDirection.RTL)
|
||||||
@@ -970,9 +1005,6 @@ const Panel = new Lang.Class({
|
|||||||
this._rightCorner = new PanelCorner(this._rightBox, St.Side.RIGHT);
|
this._rightCorner = new PanelCorner(this._rightBox, St.Side.RIGHT);
|
||||||
this.actor.add_actor(this._rightCorner.actor);
|
this.actor.add_actor(this._rightCorner.actor);
|
||||||
|
|
||||||
this.actor.connect('get-preferred-width', Lang.bind(this, this._getPreferredWidth));
|
|
||||||
this.actor.connect('get-preferred-height', Lang.bind(this, this._getPreferredHeight));
|
|
||||||
this.actor.connect('allocate', Lang.bind(this, this._allocate));
|
|
||||||
this.actor.connect('button-press-event', Lang.bind(this, this._onButtonPress));
|
this.actor.connect('button-press-event', Lang.bind(this, this._onButtonPress));
|
||||||
|
|
||||||
Main.layoutManager.panelBox.add(this.actor);
|
Main.layoutManager.panelBox.add(this.actor);
|
||||||
@@ -983,83 +1015,6 @@ const Panel = new Lang.Class({
|
|||||||
this._updatePanel();
|
this._updatePanel();
|
||||||
},
|
},
|
||||||
|
|
||||||
_getPreferredWidth: function(actor, forHeight, alloc) {
|
|
||||||
alloc.min_size = -1;
|
|
||||||
alloc.natural_size = Main.layoutManager.primaryMonitor.width;
|
|
||||||
},
|
|
||||||
|
|
||||||
_getPreferredHeight: function(actor, forWidth, alloc) {
|
|
||||||
// We don't need to implement this; it's forced by the CSS
|
|
||||||
alloc.min_size = -1;
|
|
||||||
alloc.natural_size = -1;
|
|
||||||
},
|
|
||||||
|
|
||||||
_allocate: function(actor, box, flags) {
|
|
||||||
let allocWidth = box.x2 - box.x1;
|
|
||||||
let allocHeight = box.y2 - box.y1;
|
|
||||||
|
|
||||||
let [leftMinWidth, leftNaturalWidth] = this._leftBox.get_preferred_width(-1);
|
|
||||||
let [centerMinWidth, centerNaturalWidth] = this._centerBox.get_preferred_width(-1);
|
|
||||||
let [rightMinWidth, rightNaturalWidth] = this._rightBox.get_preferred_width(-1);
|
|
||||||
|
|
||||||
let sideWidth, centerWidth;
|
|
||||||
centerWidth = centerNaturalWidth;
|
|
||||||
sideWidth = (allocWidth - centerWidth) / 2;
|
|
||||||
|
|
||||||
let childBox = new Clutter.ActorBox();
|
|
||||||
|
|
||||||
childBox.y1 = 0;
|
|
||||||
childBox.y2 = allocHeight;
|
|
||||||
if (this.actor.get_text_direction() == Clutter.TextDirection.RTL) {
|
|
||||||
childBox.x1 = allocWidth - Math.min(Math.floor(sideWidth),
|
|
||||||
leftNaturalWidth);
|
|
||||||
childBox.x2 = allocWidth;
|
|
||||||
} else {
|
|
||||||
childBox.x1 = 0;
|
|
||||||
childBox.x2 = Math.min(Math.floor(sideWidth),
|
|
||||||
leftNaturalWidth);
|
|
||||||
}
|
|
||||||
this._leftBox.allocate(childBox, flags);
|
|
||||||
|
|
||||||
childBox.x1 = Math.ceil(sideWidth);
|
|
||||||
childBox.y1 = 0;
|
|
||||||
childBox.x2 = childBox.x1 + centerWidth;
|
|
||||||
childBox.y2 = allocHeight;
|
|
||||||
this._centerBox.allocate(childBox, flags);
|
|
||||||
|
|
||||||
childBox.y1 = 0;
|
|
||||||
childBox.y2 = allocHeight;
|
|
||||||
if (this.actor.get_text_direction() == Clutter.TextDirection.RTL) {
|
|
||||||
childBox.x1 = 0;
|
|
||||||
childBox.x2 = Math.min(Math.floor(sideWidth),
|
|
||||||
rightNaturalWidth);
|
|
||||||
} else {
|
|
||||||
childBox.x1 = allocWidth - Math.min(Math.floor(sideWidth),
|
|
||||||
rightNaturalWidth);
|
|
||||||
childBox.x2 = allocWidth;
|
|
||||||
}
|
|
||||||
this._rightBox.allocate(childBox, flags);
|
|
||||||
|
|
||||||
let cornerMinWidth, cornerMinHeight;
|
|
||||||
let cornerWidth, cornerHeight;
|
|
||||||
|
|
||||||
[cornerMinWidth, cornerWidth] = this._leftCorner.actor.get_preferred_width(-1);
|
|
||||||
[cornerMinHeight, cornerHeight] = this._leftCorner.actor.get_preferred_height(-1);
|
|
||||||
childBox.x1 = 0;
|
|
||||||
childBox.x2 = cornerWidth;
|
|
||||||
childBox.y1 = allocHeight;
|
|
||||||
childBox.y2 = allocHeight + cornerHeight;
|
|
||||||
this._leftCorner.actor.allocate(childBox, flags);
|
|
||||||
|
|
||||||
[cornerMinWidth, cornerWidth] = this._rightCorner.actor.get_preferred_width(-1);
|
|
||||||
[cornerMinHeight, cornerHeight] = this._rightCorner.actor.get_preferred_height(-1);
|
|
||||||
childBox.x1 = allocWidth - cornerWidth;
|
|
||||||
childBox.x2 = allocWidth;
|
|
||||||
childBox.y1 = allocHeight;
|
|
||||||
childBox.y2 = allocHeight + cornerHeight;
|
|
||||||
this._rightCorner.actor.allocate(childBox, flags);
|
|
||||||
},
|
|
||||||
|
|
||||||
_onButtonPress: function(actor, event) {
|
_onButtonPress: function(actor, event) {
|
||||||
if (event.get_source() != actor)
|
if (event.get_source() != actor)
|
||||||
return false;
|
return false;
|
||||||
|
@@ -404,9 +404,17 @@ const PopupSeparatorMenuItem = new Lang.Class({
|
|||||||
this.parent({ reactive: false,
|
this.parent({ reactive: false,
|
||||||
can_focus: false});
|
can_focus: false});
|
||||||
|
|
||||||
this._drawingArea = new St.DrawingArea({ style_class: 'popup-separator-menu-item' });
|
this._separator = new HorzSeparator({ style_class: 'popup-separator-menu-item' });
|
||||||
this.addActor(this._drawingArea, { span: -1, expand: true });
|
this.addActor(this._separator.actor, { span: -1, expand: true });
|
||||||
this._drawingArea.connect('repaint', Lang.bind(this, this._onRepaint));
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
const HorzSeparator = new Lang.Class({
|
||||||
|
Name: 'HorzSeparator',
|
||||||
|
|
||||||
|
_init: function (params) {
|
||||||
|
this.actor = new St.DrawingArea(params);
|
||||||
|
this.actor.connect('repaint', Lang.bind(this, this._onRepaint));
|
||||||
},
|
},
|
||||||
|
|
||||||
_onRepaint: function(area) {
|
_onRepaint: function(area) {
|
||||||
|
@@ -27,17 +27,13 @@ const SearchProviderIface = <interface name="org.gnome.Shell.SearchProvider">
|
|||||||
<method name="ActivateResult">
|
<method name="ActivateResult">
|
||||||
<arg type="s" direction="in" />
|
<arg type="s" direction="in" />
|
||||||
</method>
|
</method>
|
||||||
|
<method name="LaunchSearch">
|
||||||
|
<arg type="as" direction="in" />
|
||||||
|
</method>
|
||||||
</interface>;
|
</interface>;
|
||||||
|
|
||||||
var SearchProviderProxy = new Gio.DBusProxyClass({
|
var SearchProviderProxy = Gio.DBusProxy.makeProxyWrapper(SearchProviderIface);
|
||||||
Name: 'SearchProviderProxy',
|
|
||||||
Interface: SearchProviderIface,
|
|
||||||
|
|
||||||
_init: function(params) {
|
|
||||||
params.g_bus_type = Gio.BusType.SESSION;
|
|
||||||
this.parent(params);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
function loadRemoteSearchProviders(addProviderCallback) {
|
function loadRemoteSearchProviders(addProviderCallback) {
|
||||||
let dataDirs = GLib.get_system_data_dirs();
|
let dataDirs = GLib.get_system_data_dirs();
|
||||||
@@ -97,22 +93,13 @@ function loadRemoteSearchProvidersFromDir(dir, loadedProviders, addProviderCallb
|
|||||||
icon,
|
icon,
|
||||||
busName,
|
busName,
|
||||||
objectPath);
|
objectPath);
|
||||||
remoteProvider.initAsync(null, function(obj, result) {
|
|
||||||
try {
|
|
||||||
remoteProvider.initFinish(result);
|
|
||||||
} catch(e) {
|
|
||||||
log('Failed to add search provider "%s": %s'.format(title, e.toString()));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
addProviderCallback(remoteProvider);
|
|
||||||
});
|
|
||||||
|
|
||||||
loadedProviders[objectPath] = remoteProvider;
|
loadedProviders[objectPath] = remoteProvider;
|
||||||
} catch(e) {
|
} catch(e) {
|
||||||
log('Failed to add search provider "%s": %s'.format(title, e.toString()));
|
log('Failed to add search provider "%s": %s'.format(title, e.toString()));
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
addProviderCallback(remoteProvider);
|
||||||
}
|
}
|
||||||
}));
|
}));
|
||||||
|
|
||||||
@@ -123,39 +110,12 @@ const RemoteSearchProvider = new Lang.Class({
|
|||||||
Extends: Search.SearchProvider,
|
Extends: Search.SearchProvider,
|
||||||
|
|
||||||
_init: function(title, icon, dbusName, dbusPath) {
|
_init: function(title, icon, dbusName, dbusPath) {
|
||||||
|
this._proxy = new SearchProviderProxy(Gio.DBus.session,
|
||||||
|
dbusName, dbusPath);
|
||||||
|
|
||||||
this.parent(title.toUpperCase());
|
this.parent(title.toUpperCase());
|
||||||
|
|
||||||
this._proxy = new SearchProviderProxy({ g_name: dbusName,
|
|
||||||
g_object_path: dbusPath });
|
|
||||||
this._cancellable = new Gio.Cancellable();
|
this._cancellable = new Gio.Cancellable();
|
||||||
},
|
this.icon = icon;
|
||||||
|
|
||||||
initAsync: function(cancellable, asyncCallback) {
|
|
||||||
// Can't pass "this" as source object, because RemoteSearchProvider
|
|
||||||
// is not a GObject.Object (and in gjs you can't inherit from a JS
|
|
||||||
// type that in turn inherits from GObject)
|
|
||||||
|
|
||||||
let simpleResult = Gio.SimpleAsyncResult.new(null, asyncCallback, null);
|
|
||||||
simpleResult.set_check_cancellable(cancellable);
|
|
||||||
|
|
||||||
this._proxy.init_async(GLib.PRIORITY_DEFAULT, cancellable, Lang.bind(this, function(proxy, result) {
|
|
||||||
try {
|
|
||||||
proxy.init_finish(result);
|
|
||||||
|
|
||||||
simpleResult.set_op_res_gboolean(true);
|
|
||||||
} catch(e if e instanceof GLib.Error) {
|
|
||||||
simpleResult.set_from_error(e);
|
|
||||||
}
|
|
||||||
|
|
||||||
simpleResult.complete();
|
|
||||||
}));
|
|
||||||
},
|
|
||||||
|
|
||||||
initFinish: function(simpleResult) {
|
|
||||||
if (!simpleResult.propagate_error())
|
|
||||||
return simpleResult.get_op_res_gboolean();
|
|
||||||
|
|
||||||
return false;
|
|
||||||
},
|
},
|
||||||
|
|
||||||
createIcon: function(size, meta) {
|
createIcon: function(size, meta) {
|
||||||
@@ -170,22 +130,13 @@ const RemoteSearchProvider = new Lang.Class({
|
|||||||
width, height, rowStride, size);
|
width, height, rowStride, size);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Ugh, but we want to fall back to something ...
|
return null;
|
||||||
return new St.Icon({ icon_name: 'text-x-generic',
|
|
||||||
icon_size: size });
|
|
||||||
},
|
},
|
||||||
|
|
||||||
_getResultsFinished: function(proxy, result) {
|
_getResultsFinished: function(results, error) {
|
||||||
try {
|
if (error)
|
||||||
// We rely on a small implementation detail of the
|
return;
|
||||||
// GDBus bindings here: all *Finish are equal
|
this.searchSystem.pushResults(this, results[0]);
|
||||||
|
|
||||||
let [results] = proxy.GetInitialResultSetFinish(result);
|
|
||||||
this.searchSystem.pushResults(this, results);
|
|
||||||
} catch(e) {
|
|
||||||
if (!e.matches(Gio.IOErrorEnum, Gio.IOErrorEnum.CANCELLED))
|
|
||||||
log('Received error from search provider %s: %s'.format(this.title, String(e)));
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
|
|
||||||
getInitialResultSet: function(terms) {
|
getInitialResultSet: function(terms) {
|
||||||
@@ -193,8 +144,8 @@ const RemoteSearchProvider = new Lang.Class({
|
|||||||
this._cancellable.reset();
|
this._cancellable.reset();
|
||||||
try {
|
try {
|
||||||
this._proxy.GetInitialResultSetRemote(terms,
|
this._proxy.GetInitialResultSetRemote(terms,
|
||||||
this._cancellable,
|
Lang.bind(this, this._getResultsFinished),
|
||||||
Lang.bind(this, this._getResultsFinished));
|
this._cancellable);
|
||||||
} catch(e) {
|
} catch(e) {
|
||||||
log('Error calling GetInitialResultSet for provider %s: %s'.format( this.title, e.toString()));
|
log('Error calling GetInitialResultSet for provider %s: %s'.format( this.title, e.toString()));
|
||||||
this.searchSystem.pushResults(this, []);
|
this.searchSystem.pushResults(this, []);
|
||||||
@@ -206,17 +157,20 @@ const RemoteSearchProvider = new Lang.Class({
|
|||||||
this._cancellable.reset();
|
this._cancellable.reset();
|
||||||
try {
|
try {
|
||||||
this._proxy.GetSubsearchResultSetRemote(previousResults, newTerms,
|
this._proxy.GetSubsearchResultSetRemote(previousResults, newTerms,
|
||||||
this._cancellable,
|
Lang.bind(this, this._getResultsFinished),
|
||||||
Lang.bind(this, this._getResultsFinished))
|
this._cancellable);
|
||||||
} catch(e) {
|
} catch(e) {
|
||||||
log('Error calling GetSubsearchResultSet for provider %s: %s'.format(this.title, e.toString()));
|
log('Error calling GetSubsearchResultSet for provider %s: %s'.format(this.title, e.toString()));
|
||||||
this.searchSystem.pushResults(this, []);
|
this.searchSystem.pushResults(this, []);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
_getResultMetasFinished: function(proxy, result, callback) {
|
_getResultMetasFinished: function(results, error, callback) {
|
||||||
try {
|
if (error) {
|
||||||
let [metas] = results.GetResultMetasFinish(result);
|
callback([]);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
let metas = results[0];
|
||||||
let resultMetas = [];
|
let resultMetas = [];
|
||||||
for (let i = 0; i < metas.length; i++) {
|
for (let i = 0; i < metas.length; i++) {
|
||||||
for (let prop in metas[i])
|
for (let prop in metas[i])
|
||||||
@@ -227,9 +181,6 @@ const RemoteSearchProvider = new Lang.Class({
|
|||||||
this.createIcon, metas[i]) });
|
this.createIcon, metas[i]) });
|
||||||
}
|
}
|
||||||
callback(resultMetas);
|
callback(resultMetas);
|
||||||
} catch(e) {
|
|
||||||
callback([]);
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
|
|
||||||
getResultMetas: function(ids, callback) {
|
getResultMetas: function(ids, callback) {
|
||||||
@@ -237,8 +188,8 @@ const RemoteSearchProvider = new Lang.Class({
|
|||||||
this._cancellable.reset();
|
this._cancellable.reset();
|
||||||
try {
|
try {
|
||||||
this._proxy.GetResultMetasRemote(ids,
|
this._proxy.GetResultMetasRemote(ids,
|
||||||
this._cancellable,
|
Lang.bind(this, this._getResultMetasFinished, callback),
|
||||||
Lang.bind(this, this._getResultMetasFinished, callback));
|
this._cancellable);
|
||||||
} catch(e) {
|
} catch(e) {
|
||||||
log('Error calling GetResultMetas for provider %s: %s'.format(this.title, e.toString()));
|
log('Error calling GetResultMetas for provider %s: %s'.format(this.title, e.toString()));
|
||||||
callback([]);
|
callback([]);
|
||||||
@@ -246,7 +197,11 @@ const RemoteSearchProvider = new Lang.Class({
|
|||||||
},
|
},
|
||||||
|
|
||||||
activateResult: function(id) {
|
activateResult: function(id) {
|
||||||
this._proxy.ActivateResultRemote(id, null, null);
|
this._proxy.ActivateResultRemote(id);
|
||||||
|
},
|
||||||
|
|
||||||
|
launchSearch: function(terms) {
|
||||||
|
this._proxy.LaunchSearchRemote(terms);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@@ -418,11 +418,10 @@ const ScreenShield = new Lang.Class({
|
|||||||
|
|
||||||
this._screenSaverDBus = new ShellDBus.ScreenSaverDBus(this);
|
this._screenSaverDBus = new ShellDBus.ScreenSaverDBus(this);
|
||||||
|
|
||||||
LoginManager.getLoginManager(Lang.bind(this, function(manager) {
|
this._loginManager = LoginManager.getLoginManager();
|
||||||
this._loginSession = manager.getCurrentSessionProxy();
|
this._loginSession = this._loginManager.getCurrentSessionProxy();
|
||||||
this._loginSession.connectSignal('Lock', Lang.bind(this, function() { this.lock(false); }));
|
this._loginSession.connectSignal('Lock', Lang.bind(this, function() { this.lock(false); }));
|
||||||
this._loginSession.connectSignal('Unlock', Lang.bind(this, function() { this.unlock(); }));
|
this._loginSession.connectSignal('Unlock', Lang.bind(this, function() { this.unlock(); }));
|
||||||
}));
|
|
||||||
|
|
||||||
this._settings = new Gio.Settings({ schema: SCREENSAVER_SCHEMA });
|
this._settings = new Gio.Settings({ schema: SCREENSAVER_SCHEMA });
|
||||||
|
|
||||||
@@ -876,7 +875,6 @@ const ScreenShieldFallback = new Lang.Class({
|
|||||||
g_flags: (Gio.DBusProxyFlags.DO_NOT_AUTO_START |
|
g_flags: (Gio.DBusProxyFlags.DO_NOT_AUTO_START |
|
||||||
Gio.DBusProxyFlags.DO_NOT_LOAD_PROPERTIES),
|
Gio.DBusProxyFlags.DO_NOT_LOAD_PROPERTIES),
|
||||||
});
|
});
|
||||||
// This is synchronous but it is the fallback case.
|
|
||||||
this._proxy.init(null);
|
this._proxy.init(null);
|
||||||
|
|
||||||
this._proxy.connect('g-signal', Lang.bind(this, this._onSignal));
|
this._proxy.connect('g-signal', Lang.bind(this, this._onSignal));
|
||||||
|
@@ -80,23 +80,15 @@ const PerfHelperIface = <interface name="org.gnome.Shell.PerfHelper">
|
|||||||
<method name="DestroyWindows" />
|
<method name="DestroyWindows" />
|
||||||
</interface>;
|
</interface>;
|
||||||
|
|
||||||
const PerfHelper = new Gio.DBusProxyClass({
|
var PerfHelperProxy = Gio.DBusProxy.makeProxyWrapper(PerfHelperIface);
|
||||||
Name: 'PerfHelperProxy',
|
function PerfHelper() {
|
||||||
Interface: PerfHelperIface,
|
return new PerfHelperProxy(Gio.DBus.session, 'org.gnome.Shell.PerfHelper', '/org/gnome/Shell/PerfHelper');
|
||||||
|
|
||||||
_init: function() {
|
|
||||||
this.parent({ g_bus_type: Gio.BusType.SESSION,
|
|
||||||
g_name: 'org.gnome.Shell.PerfHelper',
|
|
||||||
g_object_path: '/org/gnome/Shell/PerfHelper' });
|
|
||||||
}
|
}
|
||||||
});
|
|
||||||
|
|
||||||
let _perfHelper = null;
|
let _perfHelper = null;
|
||||||
function _getPerfHelper() {
|
function _getPerfHelper() {
|
||||||
if (_perfHelper == null) {
|
if (_perfHelper == null)
|
||||||
_perfHelper = new PerfHelper();
|
_perfHelper = new PerfHelper();
|
||||||
_perfHelper.init(null);
|
|
||||||
}
|
|
||||||
|
|
||||||
return _perfHelper;
|
return _perfHelper;
|
||||||
}
|
}
|
||||||
@@ -119,8 +111,7 @@ function createTestWindow(width, height, alpha, maximized) {
|
|||||||
let perfHelper = _getPerfHelper();
|
let perfHelper = _getPerfHelper();
|
||||||
|
|
||||||
perfHelper.CreateWindowRemote(width, height, alpha, maximized,
|
perfHelper.CreateWindowRemote(width, height, alpha, maximized,
|
||||||
null,
|
function(result, excp) {
|
||||||
function(proxy, result) {
|
|
||||||
if (cb)
|
if (cb)
|
||||||
cb();
|
cb();
|
||||||
});
|
});
|
||||||
@@ -140,7 +131,7 @@ function waitTestWindows() {
|
|||||||
let cb;
|
let cb;
|
||||||
let perfHelper = _getPerfHelper();
|
let perfHelper = _getPerfHelper();
|
||||||
|
|
||||||
perfHelper.WaitWindowsRemote(null, function(proxy, result) {
|
perfHelper.WaitWindowsRemote(function(result, excp) {
|
||||||
if (cb)
|
if (cb)
|
||||||
cb();
|
cb();
|
||||||
});
|
});
|
||||||
@@ -163,7 +154,7 @@ function destroyTestWindows() {
|
|||||||
let cb;
|
let cb;
|
||||||
let perfHelper = _getPerfHelper();
|
let perfHelper = _getPerfHelper();
|
||||||
|
|
||||||
perfHelper.DestroyWindowsRemote(null, function(proxy, result) {
|
perfHelper.DestroyWindowsRemote(function(result, excp) {
|
||||||
if (cb)
|
if (cb)
|
||||||
cb();
|
cb();
|
||||||
});
|
});
|
||||||
|
@@ -2,7 +2,6 @@
|
|||||||
|
|
||||||
const Gio = imports.gi.Gio;
|
const Gio = imports.gi.Gio;
|
||||||
const GLib = imports.gi.GLib;
|
const GLib = imports.gi.GLib;
|
||||||
const GObject = imports.gi.GObject;
|
|
||||||
const Lang = imports.lang;
|
const Lang = imports.lang;
|
||||||
const Signals = imports.signals;
|
const Signals = imports.signals;
|
||||||
const Shell = imports.gi.Shell;
|
const Shell = imports.gi.Shell;
|
||||||
@@ -76,8 +75,6 @@ const SearchProvider = new Lang.Class({
|
|||||||
Name: 'SearchProvider',
|
Name: 'SearchProvider',
|
||||||
|
|
||||||
_init: function(title) {
|
_init: function(title) {
|
||||||
this.parent();
|
|
||||||
|
|
||||||
this.title = title;
|
this.title = title;
|
||||||
this.searchSystem = null;
|
this.searchSystem = null;
|
||||||
},
|
},
|
||||||
@@ -166,6 +163,16 @@ const SearchProvider = new Lang.Class({
|
|||||||
*/
|
*/
|
||||||
activateResult: function(id) {
|
activateResult: function(id) {
|
||||||
throw new Error('Not implemented');
|
throw new Error('Not implemented');
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* launchSearch:
|
||||||
|
* @terms: Current search terms
|
||||||
|
*
|
||||||
|
* Called when the user clicks the provider icon.
|
||||||
|
*/
|
||||||
|
launchSearch: function(terms) {
|
||||||
|
throw new Error('Not implemented');
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
Signals.addSignalMethods(SearchProvider.prototype);
|
Signals.addSignalMethods(SearchProvider.prototype);
|
||||||
@@ -264,5 +271,11 @@ const SearchSystem = new Lang.Class({
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
launchSearch: function(provider) {
|
||||||
|
let terms = this.getTerms();
|
||||||
|
provider.launchSearch(terms);
|
||||||
|
Main.overview.toggle();
|
||||||
|
}
|
||||||
});
|
});
|
||||||
Signals.addSignalMethods(SearchSystem.prototype);
|
Signals.addSignalMethods(SearchSystem.prototype);
|
||||||
|
@@ -4,25 +4,191 @@ const Clutter = imports.gi.Clutter;
|
|||||||
const Lang = imports.lang;
|
const Lang = imports.lang;
|
||||||
const Gtk = imports.gi.Gtk;
|
const Gtk = imports.gi.Gtk;
|
||||||
const Meta = imports.gi.Meta;
|
const Meta = imports.gi.Meta;
|
||||||
|
const Signals = imports.signals;
|
||||||
const St = imports.gi.St;
|
const St = imports.gi.St;
|
||||||
const Atk = imports.gi.Atk;
|
const Atk = imports.gi.Atk;
|
||||||
|
|
||||||
|
const AppDisplay = imports.ui.appDisplay;
|
||||||
const DND = imports.ui.dnd;
|
const DND = imports.ui.dnd;
|
||||||
const IconGrid = imports.ui.iconGrid;
|
const IconGrid = imports.ui.iconGrid;
|
||||||
const Main = imports.ui.main;
|
const Main = imports.ui.main;
|
||||||
const Overview = imports.ui.overview;
|
const Overview = imports.ui.overview;
|
||||||
|
const PopupMenu = imports.ui.popupMenu;
|
||||||
const Search = imports.ui.search;
|
const Search = imports.ui.search;
|
||||||
|
|
||||||
const MAX_SEARCH_RESULTS_ROWS = 1;
|
const MAX_SEARCH_RESULTS_ROWS = 3;
|
||||||
|
const MAX_GRID_SEARCH_RESULTS_ROWS = 1;
|
||||||
|
|
||||||
|
|
||||||
const SearchResult = new Lang.Class({
|
const ListSearchResult = new Lang.Class({
|
||||||
Name: 'SearchResult',
|
Name: 'ListSearchResult',
|
||||||
|
|
||||||
|
ICON_SIZE: 64,
|
||||||
|
|
||||||
_init: function(provider, metaInfo, terms) {
|
_init: function(provider, metaInfo, terms) {
|
||||||
this.provider = provider;
|
this.provider = provider;
|
||||||
this.metaInfo = metaInfo;
|
this.metaInfo = metaInfo;
|
||||||
this.actor = new St.Button({ style_class: 'search-result',
|
this.actor = new St.Button({ style_class: 'search-result',
|
||||||
|
reactive: true,
|
||||||
|
can_focus: true,
|
||||||
|
track_hover: true,
|
||||||
|
x_align: St.Align.START,
|
||||||
|
x_fill: true,
|
||||||
|
y_fill: true });
|
||||||
|
this.actor._delegate = this;
|
||||||
|
|
||||||
|
let content = new St.BoxLayout({ style_class: 'search-result-content',
|
||||||
|
vertical: false });
|
||||||
|
this._content = content;
|
||||||
|
this.actor.set_child(content);
|
||||||
|
|
||||||
|
// An icon for, or thumbnail of, content
|
||||||
|
let icon = this.metaInfo['createIcon'](this.ICON_SIZE);
|
||||||
|
if (icon) {
|
||||||
|
let iconBin = new St.Bin({ style_class: 'search-result-icon',
|
||||||
|
child: icon });
|
||||||
|
content.add(iconBin);
|
||||||
|
}
|
||||||
|
|
||||||
|
let details = new St.BoxLayout({ style_class: 'search-result-details',
|
||||||
|
vertical: true });
|
||||||
|
content.add(details, { x_fill: true,
|
||||||
|
y_fill: false,
|
||||||
|
x_align: St.Align.START,
|
||||||
|
y_align: St.Align.MIDDLE });
|
||||||
|
|
||||||
|
let title = new St.Label({ style_class: 'search-result-details-title',
|
||||||
|
text: this.metaInfo['name'] })
|
||||||
|
details.add(title, { x_fill: true,
|
||||||
|
y_fill: false,
|
||||||
|
x_align: St.Align.START,
|
||||||
|
y_align: St.Align.START });
|
||||||
|
|
||||||
|
// TODO: could highlight terms in the description here, or should
|
||||||
|
// providers provide what should be highlighted?
|
||||||
|
if (this.metaInfo['description']) {
|
||||||
|
let description = new St.Label({ style_class: 'search-result-details-description',
|
||||||
|
text: this.metaInfo['description'] });
|
||||||
|
details.add(description, { x_fill: false,
|
||||||
|
y_fill: true,
|
||||||
|
x_align: St.Align.START,
|
||||||
|
y_align: St.Align.END });
|
||||||
|
}
|
||||||
|
|
||||||
|
this.actor.connect('clicked', Lang.bind(this, this._onResultClicked));
|
||||||
|
},
|
||||||
|
|
||||||
|
setSelected: function(selected) {
|
||||||
|
if (selected)
|
||||||
|
this.actor.add_style_pseudo_class('selected');
|
||||||
|
else
|
||||||
|
this.actor.remove_style_pseudo_class('selected');
|
||||||
|
},
|
||||||
|
|
||||||
|
activate: function() {
|
||||||
|
this.provider.activateResult(this.metaInfo.id);
|
||||||
|
Main.overview.toggle();
|
||||||
|
},
|
||||||
|
|
||||||
|
_onResultClicked: function(actor) {
|
||||||
|
this.activate();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
const ListSearchResults = new Lang.Class({
|
||||||
|
Name: 'ListSearchResults',
|
||||||
|
Extends: Search.SearchResultDisplay,
|
||||||
|
|
||||||
|
_init: function(provider) {
|
||||||
|
this.parent(provider);
|
||||||
|
|
||||||
|
this.actor = new St.BoxLayout({ style_class: 'results-list',
|
||||||
|
vertical: true });
|
||||||
|
this.actor.connect('notify::width', Lang.bind(this, function() {
|
||||||
|
Meta.later_add(Meta.LaterType.BEFORE_REDRAW, Lang.bind(this, function() {
|
||||||
|
let results = this.getResultsForDisplay();
|
||||||
|
if (results.length == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
provider.getResultMetas(results, Lang.bind(this, this.renderResults));
|
||||||
|
}));
|
||||||
|
}));
|
||||||
|
this._notDisplayedResult = [];
|
||||||
|
this._terms = [];
|
||||||
|
this._pendingClear = false;
|
||||||
|
},
|
||||||
|
|
||||||
|
getResultsForDisplay: function() {
|
||||||
|
let alreadyVisible = this._pendingClear ? 0 : this.getVisibleResultCount();
|
||||||
|
let canDisplay = MAX_SEARCH_RESULTS_ROWS - alreadyVisible;
|
||||||
|
|
||||||
|
let numResults = Math.min(this._notDisplayedResult.length, canDisplay);
|
||||||
|
|
||||||
|
return this._notDisplayedResult.splice(0, numResults);
|
||||||
|
},
|
||||||
|
|
||||||
|
getVisibleResultCount: function() {
|
||||||
|
return this.actor.get_n_children();
|
||||||
|
},
|
||||||
|
|
||||||
|
hasMoreResults: function() {
|
||||||
|
return this._notDisplayedResult.length > 0;
|
||||||
|
},
|
||||||
|
|
||||||
|
setResults: function(results, terms) {
|
||||||
|
// copy the lists
|
||||||
|
this._notDisplayedResult = results.slice(0);
|
||||||
|
this._terms = terms.slice(0);
|
||||||
|
this._pendingClear = true;
|
||||||
|
},
|
||||||
|
|
||||||
|
renderResults: function(metas) {
|
||||||
|
for (let i = 0; i < metas.length; i++) {
|
||||||
|
let display = new ListSearchResult(this.provider, metas[i], this._terms);
|
||||||
|
this.addItem(display.actor);
|
||||||
|
|
||||||
|
display.actor.connect('key-focus-in', Lang.bind(this, this._onFocusedProviderChanged));
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
clear: function () {
|
||||||
|
this.actor.destroy_all_children();
|
||||||
|
this._pendingClear = false;
|
||||||
|
},
|
||||||
|
|
||||||
|
getFirstResult: function() {
|
||||||
|
if (this.getVisibleResultCount() > 0)
|
||||||
|
return this.getItemAtIndex(0)._delegate;
|
||||||
|
else
|
||||||
|
return null;
|
||||||
|
},
|
||||||
|
|
||||||
|
addItem: function(actor, index) {
|
||||||
|
if (index !== undefined)
|
||||||
|
this.actor.insert_child_at_index(actor, index);
|
||||||
|
else
|
||||||
|
this.actor.add_actor(actor);
|
||||||
|
},
|
||||||
|
|
||||||
|
getItemAtIndex: function(index) {
|
||||||
|
return this.actor.get_child_at_index(index);
|
||||||
|
},
|
||||||
|
|
||||||
|
_onFocusedProviderChanged: function() {
|
||||||
|
this.emit('focused-provider-changed');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
Signals.addSignalMethods(ListSearchResults.prototype);
|
||||||
|
|
||||||
|
|
||||||
|
const GridSearchResult = new Lang.Class({
|
||||||
|
Name: 'GridSearchResult',
|
||||||
|
|
||||||
|
_init: function(provider, metaInfo, terms) {
|
||||||
|
this.provider = provider;
|
||||||
|
this.metaInfo = metaInfo;
|
||||||
|
this.actor = new St.Button({ style_class: 'grid-search-result',
|
||||||
reactive: true,
|
reactive: true,
|
||||||
x_align: St.Align.START,
|
x_align: St.Align.START,
|
||||||
y_fill: true });
|
y_fill: true });
|
||||||
@@ -31,7 +197,7 @@ const SearchResult = new Lang.Class({
|
|||||||
|
|
||||||
let content = provider.createResultActor(metaInfo, terms);
|
let content = provider.createResultActor(metaInfo, terms);
|
||||||
if (content == null) {
|
if (content == null) {
|
||||||
content = new St.Bin({ style_class: 'search-result-content',
|
content = new St.Bin({ style_class: 'grid-search-result-content',
|
||||||
reactive: true,
|
reactive: true,
|
||||||
can_focus: true,
|
can_focus: true,
|
||||||
track_hover: true,
|
track_hover: true,
|
||||||
@@ -45,7 +211,7 @@ const SearchResult = new Lang.Class({
|
|||||||
if (content._delegate && content._delegate.getDragActorSource)
|
if (content._delegate && content._delegate.getDragActorSource)
|
||||||
this._dragActorSource = content._delegate.getDragActorSource();
|
this._dragActorSource = content._delegate.getDragActorSource();
|
||||||
}
|
}
|
||||||
this._content = content;
|
this.content = content;
|
||||||
this.actor.set_child(content);
|
this.actor.set_child(content);
|
||||||
|
|
||||||
this.actor.connect('clicked', Lang.bind(this, this._onResultClicked));
|
this.actor.connect('clicked', Lang.bind(this, this._onResultClicked));
|
||||||
@@ -53,23 +219,23 @@ const SearchResult = new Lang.Class({
|
|||||||
let draggable = DND.makeDraggable(this.actor);
|
let draggable = DND.makeDraggable(this.actor);
|
||||||
draggable.connect('drag-begin',
|
draggable.connect('drag-begin',
|
||||||
Lang.bind(this, function() {
|
Lang.bind(this, function() {
|
||||||
Main.overview.beginItemDrag(this);
|
Main.overview.beginAppDrag(this);
|
||||||
}));
|
}));
|
||||||
draggable.connect('drag-cancelled',
|
draggable.connect('drag-cancelled',
|
||||||
Lang.bind(this, function() {
|
Lang.bind(this, function() {
|
||||||
Main.overview.cancelledItemDrag(this);
|
Main.overview.cancelledAppDrag(this);
|
||||||
}));
|
}));
|
||||||
draggable.connect('drag-end',
|
draggable.connect('drag-end',
|
||||||
Lang.bind(this, function() {
|
Lang.bind(this, function() {
|
||||||
Main.overview.endItemDrag(this);
|
Main.overview.endAppDrag(this);
|
||||||
}));
|
}));
|
||||||
},
|
},
|
||||||
|
|
||||||
setSelected: function(selected) {
|
setSelected: function(selected) {
|
||||||
if (selected)
|
if (selected)
|
||||||
this._content.add_style_pseudo_class('selected');
|
this.content.add_style_pseudo_class('selected');
|
||||||
else
|
else
|
||||||
this._content.remove_style_pseudo_class('selected');
|
this.content.remove_style_pseudo_class('selected');
|
||||||
},
|
},
|
||||||
|
|
||||||
activate: function() {
|
activate: function() {
|
||||||
@@ -85,7 +251,7 @@ const SearchResult = new Lang.Class({
|
|||||||
if (this._dragActorSource)
|
if (this._dragActorSource)
|
||||||
return this._dragActorSource;
|
return this._dragActorSource;
|
||||||
// not exactly right, but alignment problems are hard to notice
|
// not exactly right, but alignment problems are hard to notice
|
||||||
return this._content;
|
return this.content;
|
||||||
},
|
},
|
||||||
|
|
||||||
getDragActor: function(stageX, stageY) {
|
getDragActor: function(stageX, stageY) {
|
||||||
@@ -108,11 +274,11 @@ const GridSearchResults = new Lang.Class({
|
|||||||
_init: function(provider, grid) {
|
_init: function(provider, grid) {
|
||||||
this.parent(provider);
|
this.parent(provider);
|
||||||
|
|
||||||
this._grid = grid || new IconGrid.IconGrid({ rowLimit: MAX_SEARCH_RESULTS_ROWS,
|
this._grid = grid || new IconGrid.IconGrid({ rowLimit: MAX_GRID_SEARCH_RESULTS_ROWS,
|
||||||
xAlign: St.Align.START });
|
xAlign: St.Align.START });
|
||||||
this.actor = new St.Bin({ x_align: St.Align.START });
|
this.actor = new St.Bin({ x_align: St.Align.MIDDLE });
|
||||||
|
|
||||||
this.actor.set_child(this._grid.actor);
|
this.actor.set_child(this._grid.actor);
|
||||||
|
|
||||||
this._width = 0;
|
this._width = 0;
|
||||||
this.actor.connect('notify::width', Lang.bind(this, function() {
|
this.actor.connect('notify::width', Lang.bind(this, function() {
|
||||||
this._width = this.actor.width;
|
this._width = this.actor.width;
|
||||||
@@ -130,6 +296,7 @@ const GridSearchResults = new Lang.Class({
|
|||||||
},
|
},
|
||||||
|
|
||||||
getResultsForDisplay: function() {
|
getResultsForDisplay: function() {
|
||||||
|
this._grid.actor.ensure_style();
|
||||||
let alreadyVisible = this._pendingClear ? 0 : this._grid.visibleItemsCount();
|
let alreadyVisible = this._pendingClear ? 0 : this._grid.visibleItemsCount();
|
||||||
let canDisplay = this._grid.childrenInRow(this._width) * this._grid.getRowLimit()
|
let canDisplay = this._grid.childrenInRow(this._width) * this._grid.getRowLimit()
|
||||||
- alreadyVisible;
|
- alreadyVisible;
|
||||||
@@ -143,6 +310,10 @@ const GridSearchResults = new Lang.Class({
|
|||||||
return this._grid.visibleItemsCount();
|
return this._grid.visibleItemsCount();
|
||||||
},
|
},
|
||||||
|
|
||||||
|
hasMoreResults: function() {
|
||||||
|
return this._notDisplayedResult.length > 0;
|
||||||
|
},
|
||||||
|
|
||||||
setResults: function(results, terms) {
|
setResults: function(results, terms) {
|
||||||
// copy the lists
|
// copy the lists
|
||||||
this._notDisplayedResult = results.slice(0);
|
this._notDisplayedResult = results.slice(0);
|
||||||
@@ -152,8 +323,10 @@ const GridSearchResults = new Lang.Class({
|
|||||||
|
|
||||||
renderResults: function(metas) {
|
renderResults: function(metas) {
|
||||||
for (let i = 0; i < metas.length; i++) {
|
for (let i = 0; i < metas.length; i++) {
|
||||||
let display = new SearchResult(this.provider, metas[i], this._terms);
|
let display = new GridSearchResult(this.provider, metas[i], this._terms);
|
||||||
this._grid.addItem(display.actor);
|
this._grid.addItem(display.actor);
|
||||||
|
|
||||||
|
display.content.connect('key-focus-in', Lang.bind(this, this._onFocusedProviderChanged));
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
@@ -167,11 +340,17 @@ const GridSearchResults = new Lang.Class({
|
|||||||
return this._grid.getItemAtIndex(0)._delegate;
|
return this._grid.getItemAtIndex(0)._delegate;
|
||||||
else
|
else
|
||||||
return null;
|
return null;
|
||||||
|
},
|
||||||
|
|
||||||
|
_onFocusedProviderChanged: function() {
|
||||||
|
this.emit('focused-provider-changed');
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
Signals.addSignalMethods(GridSearchResults.prototype);
|
||||||
|
|
||||||
const SearchResults = new Lang.Class({
|
|
||||||
Name: 'SearchResults',
|
const SearchDisplay = new Lang.Class({
|
||||||
|
Name: 'SearchDisplay',
|
||||||
|
|
||||||
_init: function(searchSystem) {
|
_init: function(searchSystem) {
|
||||||
this._searchSystem = searchSystem;
|
this._searchSystem = searchSystem;
|
||||||
@@ -222,19 +401,43 @@ const SearchResults = new Lang.Class({
|
|||||||
createProviderMeta: function(provider) {
|
createProviderMeta: function(provider) {
|
||||||
let providerBox = new St.BoxLayout({ style_class: 'search-section',
|
let providerBox = new St.BoxLayout({ style_class: 'search-section',
|
||||||
vertical: true });
|
vertical: true });
|
||||||
let title = new St.Label({ style_class: 'search-section-header',
|
let providerBoxContent = new St.BoxLayout({ style_class: 'search-section-content' });
|
||||||
text: provider.title });
|
let isAppsProvider = (provider instanceof AppDisplay.AppSearchProvider);
|
||||||
providerBox.add(title, { x_fill: false, x_align: St.Align.START });
|
|
||||||
|
let providerIcon;
|
||||||
|
if (!isAppsProvider) {
|
||||||
|
let separator = new PopupMenu.HorzSeparator({ style_class: 'search-section-separator' });
|
||||||
|
providerBox.add(separator.actor, { expand: true });
|
||||||
|
|
||||||
|
providerIcon = new ProviderIcon(provider);
|
||||||
|
providerIcon.connect('launch-search', Lang.bind(this, function(providerIcon) {
|
||||||
|
this._searchSystem.launchSearch(providerIcon.provider);
|
||||||
|
}));
|
||||||
|
providerBoxContent.add(providerIcon.actor, { x_fill: false,
|
||||||
|
y_fill: false,
|
||||||
|
x_align: St.Align.START,
|
||||||
|
y_align: St.Align.START });
|
||||||
|
}
|
||||||
|
|
||||||
let resultDisplayBin = new St.Bin({ style_class: 'search-section-results',
|
let resultDisplayBin = new St.Bin({ style_class: 'search-section-results',
|
||||||
x_fill: true,
|
x_fill: true,
|
||||||
y_fill: true });
|
y_fill: true });
|
||||||
providerBox.add(resultDisplayBin, { expand: true });
|
providerBoxContent.add(resultDisplayBin, { expand: true });
|
||||||
let resultDisplay = new GridSearchResults(provider);
|
|
||||||
|
providerBox.add(providerBoxContent);
|
||||||
|
|
||||||
|
let resultDisplay;
|
||||||
|
if (isAppsProvider)
|
||||||
|
resultDisplay = new GridSearchResults(provider);
|
||||||
|
else
|
||||||
|
resultDisplay = new ListSearchResults(provider);
|
||||||
|
|
||||||
|
resultDisplay.connect('focused-provider-changed', Lang.bind(this, this._updateProviderIconCanFocus));
|
||||||
resultDisplayBin.set_child(resultDisplay.actor);
|
resultDisplayBin.set_child(resultDisplay.actor);
|
||||||
|
|
||||||
this._providerMeta.push({ provider: provider,
|
this._providerMeta.push({ provider: provider,
|
||||||
actor: providerBox,
|
actor: providerBox,
|
||||||
|
icon: providerIcon,
|
||||||
resultDisplay: resultDisplay });
|
resultDisplay: resultDisplay });
|
||||||
this._content.add(providerBox);
|
this._content.add(providerBox);
|
||||||
},
|
},
|
||||||
@@ -255,6 +458,7 @@ const SearchResults = new Lang.Class({
|
|||||||
let meta = this._providerMeta[i];
|
let meta = this._providerMeta[i];
|
||||||
meta.resultDisplay.clear();
|
meta.resultDisplay.clear();
|
||||||
meta.actor.hide();
|
meta.actor.hide();
|
||||||
|
if (meta.icon) meta.icon.actor.can_focus = false;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
@@ -262,6 +466,7 @@ const SearchResults = new Lang.Class({
|
|||||||
let meta = this._metaForProvider(provider);
|
let meta = this._metaForProvider(provider);
|
||||||
meta.resultDisplay.clear();
|
meta.resultDisplay.clear();
|
||||||
meta.actor.hide();
|
meta.actor.hide();
|
||||||
|
if (meta.icon) meta.icon.actor.can_focus = false;
|
||||||
},
|
},
|
||||||
|
|
||||||
reset: function() {
|
reset: function() {
|
||||||
@@ -284,6 +489,11 @@ const SearchResults = new Lang.Class({
|
|||||||
return this._providerMeta[this._providers.indexOf(provider)];
|
return this._providerMeta[this._providers.indexOf(provider)];
|
||||||
},
|
},
|
||||||
|
|
||||||
|
_metaForProvidersExcept: function(provider) {
|
||||||
|
let skip = this._providers.indexOf(provider);
|
||||||
|
return this._providerMeta.filter(function(meta, index) { return index != skip }, this);
|
||||||
|
},
|
||||||
|
|
||||||
_maybeSetInitialSelection: function() {
|
_maybeSetInitialSelection: function() {
|
||||||
let newDefaultResult = null;
|
let newDefaultResult = null;
|
||||||
|
|
||||||
@@ -341,6 +551,9 @@ const SearchResults = new Lang.Class({
|
|||||||
meta.resultDisplay.setResults(providerResults, terms);
|
meta.resultDisplay.setResults(providerResults, terms);
|
||||||
let results = meta.resultDisplay.getResultsForDisplay();
|
let results = meta.resultDisplay.getResultsForDisplay();
|
||||||
|
|
||||||
|
if (meta.icon)
|
||||||
|
meta.icon.moreIcon.visible = meta.resultDisplay.hasMoreResults();
|
||||||
|
|
||||||
provider.getResultMetas(results, Lang.bind(this, function(metas) {
|
provider.getResultMetas(results, Lang.bind(this, function(metas) {
|
||||||
this._clearDisplayForProvider(provider);
|
this._clearDisplayForProvider(provider);
|
||||||
meta.actor.show();
|
meta.actor.show();
|
||||||
@@ -374,6 +587,15 @@ const SearchResults = new Lang.Class({
|
|||||||
this._defaultResult.setSelected(highlight);
|
this._defaultResult.setSelected(highlight);
|
||||||
},
|
},
|
||||||
|
|
||||||
|
_updateProviderIconCanFocus: function(resultDisplay) {
|
||||||
|
let meta = this._metaForProvider(resultDisplay.provider);
|
||||||
|
if (meta.icon)
|
||||||
|
meta.icon.actor.can_focus = true;
|
||||||
|
|
||||||
|
let others = this._metaForProvidersExcept(resultDisplay.provider);
|
||||||
|
others.forEach(function(meta) { if (meta.icon) meta.icon.actor.can_focus = false; });
|
||||||
|
},
|
||||||
|
|
||||||
navigateFocus: function(direction) {
|
navigateFocus: function(direction) {
|
||||||
let rtl = this.actor.get_text_direction() == Clutter.TextDirection.RTL;
|
let rtl = this.actor.get_text_direction() == Clutter.TextDirection.RTL;
|
||||||
if (direction == Gtk.DirectionType.TAB_BACKWARD ||
|
if (direction == Gtk.DirectionType.TAB_BACKWARD ||
|
||||||
@@ -393,3 +615,65 @@ const SearchResults = new Lang.Class({
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const ProviderIcon = new Lang.Class({
|
||||||
|
Name: 'ProviderIcon',
|
||||||
|
|
||||||
|
PROVIDER_ICON_SIZE: 48,
|
||||||
|
|
||||||
|
MORE_ICON_SIZE: 16,
|
||||||
|
|
||||||
|
_init: function(provider) {
|
||||||
|
this.provider = provider;
|
||||||
|
|
||||||
|
this.actor = new St.Button({ style_class: 'search-section-icon-bin',
|
||||||
|
reactive: true,
|
||||||
|
track_hover: true });
|
||||||
|
this.actor.connect('clicked', Lang.bind(this, this._onIconClicked));
|
||||||
|
|
||||||
|
this._content = new St.Widget({ layout_manager: new Clutter.BinLayout() });
|
||||||
|
this.actor.set_child(this._content);
|
||||||
|
|
||||||
|
let rtl = (this.actor.get_text_direction() == Clutter.TextDirection.RTL);
|
||||||
|
|
||||||
|
this.moreIcon = new St.Icon({ style_class: 'search-section-icon-more',
|
||||||
|
icon_size: this.MORE_ICON_SIZE,
|
||||||
|
icon_name: 'list-add-symbolic',
|
||||||
|
visible: false,
|
||||||
|
x_align: rtl ? Clutter.ActorAlign.START : Clutter.ActorAlign.END,
|
||||||
|
y_align: Clutter.ActorAlign.END,
|
||||||
|
// HACK: without these, ClutterBinLayout
|
||||||
|
// ignores alignment properties on the actor
|
||||||
|
x_expand: true,
|
||||||
|
y_expand: true });
|
||||||
|
|
||||||
|
this._iconBin = new St.Bin({ style_class: 'search-section-icon',
|
||||||
|
width: this.PROVIDER_ICON_SIZE,
|
||||||
|
height: this.PROVIDER_ICON_SIZE });
|
||||||
|
|
||||||
|
this._content.add_actor(this._iconBin);
|
||||||
|
this._content.add_actor(this.moreIcon);
|
||||||
|
|
||||||
|
this._createProviderIcon();
|
||||||
|
},
|
||||||
|
|
||||||
|
_createProviderIcon: function() {
|
||||||
|
let icon = new St.Icon({ icon_size: this.PROVIDER_ICON_SIZE });
|
||||||
|
|
||||||
|
if (this.provider.icon)
|
||||||
|
icon.gicon = this.provider.icon;
|
||||||
|
else
|
||||||
|
icon.icon_name = 'application-x-executable';
|
||||||
|
|
||||||
|
this._iconBin.set_child(icon);
|
||||||
|
},
|
||||||
|
|
||||||
|
activate: function() {
|
||||||
|
this.emit('launch-search');
|
||||||
|
},
|
||||||
|
|
||||||
|
_onIconClicked: function(actor) {
|
||||||
|
this.activate();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
Signals.addSignalMethods(ProviderIcon.prototype);
|
||||||
|
@@ -67,16 +67,14 @@ const ScreenSaverIface = <interface name="org.gnome.ScreenSaver">
|
|||||||
</signal>
|
</signal>
|
||||||
</interface>;
|
</interface>;
|
||||||
|
|
||||||
const GnomeShell = new Gio.DBusImplementerClass({
|
const GnomeShell = new Lang.Class({
|
||||||
Name: 'GnomeShellDBus',
|
Name: 'GnomeShellDBus',
|
||||||
Interface: GnomeShellIface,
|
|
||||||
|
|
||||||
_init: function() {
|
_init: function() {
|
||||||
this.parent();
|
this._dbusImpl = Gio.DBusExportedObject.wrapJSObject(GnomeShellIface, this);
|
||||||
|
this._dbusImpl.export(Gio.DBus.session, '/org/gnome/Shell');
|
||||||
|
|
||||||
this.export(Gio.DBus.session, '/org/gnome/Shell');
|
this._extensionsSerivce = new GnomeShellExtensions();
|
||||||
|
|
||||||
this._extensionsService = new GnomeShellExtensions();
|
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -238,14 +236,12 @@ const GnomeShellExtensionsIface = <interface name="org.gnome.Shell.Extensions">
|
|||||||
<property name="ShellVersion" type="s" access="read" />
|
<property name="ShellVersion" type="s" access="read" />
|
||||||
</interface>;
|
</interface>;
|
||||||
|
|
||||||
const GnomeShellExtensions = new Gio.DBusImplementerClass({
|
const GnomeShellExtensions = new Lang.Class({
|
||||||
Name: 'GnomeShellExtensionsDBus',
|
Name: 'GnomeShellExtensionsDBus',
|
||||||
Interface: GnomeShellExtensionsIface,
|
|
||||||
|
|
||||||
_init: function() {
|
_init: function() {
|
||||||
this.parent();
|
this._dbusImpl = Gio.DBusExportedObject.wrapJSObject(GnomeShellExtensionsIface, this);
|
||||||
|
this._dbusImpl.export(Gio.DBus.session, '/org/gnome/Shell');
|
||||||
this.export(Gio.DBus.session, '/org/gnome/Shell');
|
|
||||||
ExtensionSystem.connect('extension-state-changed',
|
ExtensionSystem.connect('extension-state-changed',
|
||||||
Lang.bind(this, this._extensionStateChanged));
|
Lang.bind(this, this._extensionStateChanged));
|
||||||
},
|
},
|
||||||
@@ -339,23 +335,25 @@ const GnomeShellExtensions = new Gio.DBusImplementerClass({
|
|||||||
ShellVersion: Config.PACKAGE_VERSION,
|
ShellVersion: Config.PACKAGE_VERSION,
|
||||||
|
|
||||||
_extensionStateChanged: function(_, newState) {
|
_extensionStateChanged: function(_, newState) {
|
||||||
this.emit_signal('ExtensionStatusChanged', newState.uuid, newState.state, newState.error);
|
this._dbusImpl.emit_signal('ExtensionStatusChanged',
|
||||||
|
GLib.Variant.new('(sis)', [newState.uuid, newState.state, newState.error]));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
const ScreenSaverDBus = new Gio.DBusImplementerClass({
|
const ScreenSaverDBus = new Lang.Class({
|
||||||
Name: 'ScreenSaverDBus',
|
Name: 'ScreenSaverDBus',
|
||||||
Interface: ScreenSaverIface,
|
|
||||||
|
|
||||||
_init: function(screenShield) {
|
_init: function(screenShield) {
|
||||||
this.parent();
|
this.parent();
|
||||||
|
|
||||||
this._screenShield = screenShield;
|
this._screenShield = screenShield;
|
||||||
screenShield.connect('lock-status-changed', Lang.bind(this, function(shield) {
|
screenShield.connect('lock-status-changed', Lang.bind(this, function(shield) {
|
||||||
this.emit_signal('ActiveChanged', shield.locked);
|
this._dbusImpl.emit_signal('ActiveChanged', GLib.Variant.new('(b)', [shield.locked]));
|
||||||
}));
|
}));
|
||||||
|
|
||||||
this.export(Gio.DBus.session, '/org/gnome/ScreenSaver');
|
this._dbusImpl = Gio.DBusExportedObject.wrapJSObject(ScreenSaverIface, this);
|
||||||
|
this._dbusImpl.export(Gio.DBus.session, '/org/gnome/ScreenSaver');
|
||||||
|
|
||||||
Gio.DBus.session.own_name('org.gnome.ScreenSaver', Gio.BusNameOwnerFlags.REPLACE, null, null);
|
Gio.DBus.session.own_name('org.gnome.ScreenSaver', Gio.BusNameOwnerFlags.REPLACE, null, null);
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@@ -554,15 +554,13 @@ const ShellMountOperationType = {
|
|||||||
SHOW_PROCESSES: 3
|
SHOW_PROCESSES: 3
|
||||||
};
|
};
|
||||||
|
|
||||||
const GnomeShellMountOpHandler = new Gio.DBusImplementerClass({
|
const GnomeShellMountOpHandler = new Lang.Class({
|
||||||
Name: 'GnomeShellMountOpHandler',
|
Name: 'GnomeShellMountOpHandler',
|
||||||
Interface: GnomeShellMountOpIface,
|
|
||||||
|
|
||||||
_init: function() {
|
_init: function() {
|
||||||
this.parent();
|
this._dbusImpl = Gio.DBusExportedObject.wrapJSObject(GnomeShellMountOpIface, this);
|
||||||
|
this._dbusImpl.export(Gio.DBus.session, '/org/gtk/MountOperationHandler');
|
||||||
this.export(Gio.DBus.session, '/org/gtk/MountOperationHandler');
|
Gio.bus_own_name_on_connection(Gio.DBus.session, 'org.gtk.MountOperationHandler',
|
||||||
Gio.DBus.session.own_name('org.gtk.MountOperationHandler',
|
|
||||||
Gio.BusNameOwnerFlags.REPLACE, null, null);
|
Gio.BusNameOwnerFlags.REPLACE, null, null);
|
||||||
|
|
||||||
this._dialog = null;
|
this._dialog = null;
|
||||||
|
@@ -1629,44 +1629,7 @@ const NMApplet = new Lang.Class({
|
|||||||
this.secondaryIcon = this.addIcon(new Gio.ThemedIcon({ name: 'network-vpn-symbolic' }));
|
this.secondaryIcon = this.addIcon(new Gio.ThemedIcon({ name: 'network-vpn-symbolic' }));
|
||||||
this.secondaryIcon.hide();
|
this.secondaryIcon.hide();
|
||||||
|
|
||||||
// Device types
|
this._client = NMClient.Client.new();
|
||||||
this._dtypes = { };
|
|
||||||
this._dtypes[NetworkManager.DeviceType.ETHERNET] = NMDeviceWired;
|
|
||||||
this._dtypes[NetworkManager.DeviceType.WIFI] = NMDeviceWireless;
|
|
||||||
this._dtypes[NetworkManager.DeviceType.MODEM] = NMDeviceModem;
|
|
||||||
this._dtypes[NetworkManager.DeviceType.BT] = NMDeviceBluetooth;
|
|
||||||
// TODO: WiMax support
|
|
||||||
|
|
||||||
// Connection types
|
|
||||||
this._ctypes = { };
|
|
||||||
this._ctypes[NetworkManager.SETTING_WIRELESS_SETTING_NAME] = NMConnectionCategory.WIRELESS;
|
|
||||||
this._ctypes[NetworkManager.SETTING_WIRED_SETTING_NAME] = NMConnectionCategory.WIRED;
|
|
||||||
this._ctypes[NetworkManager.SETTING_PPPOE_SETTING_NAME] = NMConnectionCategory.WIRED;
|
|
||||||
this._ctypes[NetworkManager.SETTING_PPP_SETTING_NAME] = NMConnectionCategory.WIRED;
|
|
||||||
this._ctypes[NetworkManager.SETTING_BLUETOOTH_SETTING_NAME] = NMConnectionCategory.WWAN;
|
|
||||||
this._ctypes[NetworkManager.SETTING_CDMA_SETTING_NAME] = NMConnectionCategory.WWAN;
|
|
||||||
this._ctypes[NetworkManager.SETTING_GSM_SETTING_NAME] = NMConnectionCategory.WWAN;
|
|
||||||
this._ctypes[NetworkManager.SETTING_VPN_SETTING_NAME] = NMConnectionCategory.VPN;
|
|
||||||
|
|
||||||
NMClient.Client.new_async(null, Lang.bind(this, this._clientGot));
|
|
||||||
NMClient.RemoteSettings.new_async(null, null, Lang.bind(this, this._remoteSettingsGot));
|
|
||||||
},
|
|
||||||
|
|
||||||
_clientGot: function(obj, result) {
|
|
||||||
this._client = NMClient.Client.new_finish(result);
|
|
||||||
|
|
||||||
this._tryLateInit();
|
|
||||||
},
|
|
||||||
|
|
||||||
_remoteSettingsGot: function(obj, result) {
|
|
||||||
this._settings = NMClient.RemoteSettings.new_finish(result);
|
|
||||||
|
|
||||||
this._tryLateInit();
|
|
||||||
},
|
|
||||||
|
|
||||||
_tryLateInit: function() {
|
|
||||||
if (!this._client || !this._settings)
|
|
||||||
return;
|
|
||||||
|
|
||||||
this._statusSection = new PopupMenu.PopupMenuSection();
|
this._statusSection = new PopupMenu.PopupMenuSection();
|
||||||
this._statusItem = new PopupMenu.PopupMenuItem('', { reactive: false });
|
this._statusItem = new PopupMenu.PopupMenuItem('', { reactive: false });
|
||||||
@@ -1727,10 +1690,35 @@ const NMApplet = new Lang.Class({
|
|||||||
this.menu.addMenuItem(new PopupMenu.PopupSeparatorMenuItem());
|
this.menu.addMenuItem(new PopupMenu.PopupSeparatorMenuItem());
|
||||||
this.menu.addSettingsAction(_("Network Settings"), 'gnome-network-panel.desktop');
|
this.menu.addSettingsAction(_("Network Settings"), 'gnome-network-panel.desktop');
|
||||||
|
|
||||||
|
// Device types
|
||||||
|
this._dtypes = { };
|
||||||
|
this._dtypes[NetworkManager.DeviceType.ETHERNET] = NMDeviceWired;
|
||||||
|
this._dtypes[NetworkManager.DeviceType.WIFI] = NMDeviceWireless;
|
||||||
|
this._dtypes[NetworkManager.DeviceType.MODEM] = NMDeviceModem;
|
||||||
|
this._dtypes[NetworkManager.DeviceType.BT] = NMDeviceBluetooth;
|
||||||
|
// TODO: WiMax support
|
||||||
|
|
||||||
|
// Connection types
|
||||||
|
this._ctypes = { };
|
||||||
|
this._ctypes[NetworkManager.SETTING_WIRELESS_SETTING_NAME] = NMConnectionCategory.WIRELESS;
|
||||||
|
this._ctypes[NetworkManager.SETTING_WIRED_SETTING_NAME] = NMConnectionCategory.WIRED;
|
||||||
|
this._ctypes[NetworkManager.SETTING_PPPOE_SETTING_NAME] = NMConnectionCategory.WIRED;
|
||||||
|
this._ctypes[NetworkManager.SETTING_PPP_SETTING_NAME] = NMConnectionCategory.WIRED;
|
||||||
|
this._ctypes[NetworkManager.SETTING_BLUETOOTH_SETTING_NAME] = NMConnectionCategory.WWAN;
|
||||||
|
this._ctypes[NetworkManager.SETTING_CDMA_SETTING_NAME] = NMConnectionCategory.WWAN;
|
||||||
|
this._ctypes[NetworkManager.SETTING_GSM_SETTING_NAME] = NMConnectionCategory.WWAN;
|
||||||
|
this._ctypes[NetworkManager.SETTING_VPN_SETTING_NAME] = NMConnectionCategory.VPN;
|
||||||
|
|
||||||
|
this._settings = NMClient.RemoteSettings.new(null);
|
||||||
|
this._connectionsReadId = this._settings.connect('connections-read', Lang.bind(this, function() {
|
||||||
this._readConnections();
|
this._readConnections();
|
||||||
this._readDevices();
|
this._readDevices();
|
||||||
this._syncNMState();
|
this._syncNMState();
|
||||||
|
|
||||||
|
// Connect to signals late so that early signals don't find in inconsistent state
|
||||||
|
// and connect only once (this signal handler can be called again if NetworkManager goes up and down)
|
||||||
|
if (!this._inited) {
|
||||||
|
this._inited = true;
|
||||||
this._client.connect('notify::manager-running', Lang.bind(this, this._syncNMState));
|
this._client.connect('notify::manager-running', Lang.bind(this, this._syncNMState));
|
||||||
this._client.connect('notify::networking-enabled', Lang.bind(this, this._syncNMState));
|
this._client.connect('notify::networking-enabled', Lang.bind(this, this._syncNMState));
|
||||||
this._client.connect('notify::state', Lang.bind(this, this._syncNMState));
|
this._client.connect('notify::state', Lang.bind(this, this._syncNMState));
|
||||||
@@ -1738,6 +1726,8 @@ const NMApplet = new Lang.Class({
|
|||||||
this._client.connect('device-added', Lang.bind(this, this._deviceAdded));
|
this._client.connect('device-added', Lang.bind(this, this._deviceAdded));
|
||||||
this._client.connect('device-removed', Lang.bind(this, this._deviceRemoved));
|
this._client.connect('device-removed', Lang.bind(this, this._deviceRemoved));
|
||||||
this._settings.connect('new-connection', Lang.bind(this, this._newConnection));
|
this._settings.connect('new-connection', Lang.bind(this, this._newConnection));
|
||||||
|
}
|
||||||
|
}));
|
||||||
},
|
},
|
||||||
|
|
||||||
_ensureSource: function() {
|
_ensureSource: function() {
|
||||||
|
@@ -1,7 +1,6 @@
|
|||||||
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
|
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
|
||||||
|
|
||||||
const Gio = imports.gi.Gio;
|
const Gio = imports.gi.Gio;
|
||||||
const GLib = imports.gi.GLib;
|
|
||||||
const Lang = imports.lang;
|
const Lang = imports.lang;
|
||||||
const St = imports.gi.St;
|
const St = imports.gi.St;
|
||||||
|
|
||||||
@@ -46,16 +45,7 @@ const PowerManagerInterface = <interface name="org.gnome.SettingsDaemon.Power">
|
|||||||
<property name="Icon" type="s" access="read" />
|
<property name="Icon" type="s" access="read" />
|
||||||
</interface>;
|
</interface>;
|
||||||
|
|
||||||
const PowerManagerProxy = new Gio.DBusProxyClass({
|
const PowerManagerProxy = Gio.DBusProxy.makeProxyWrapper(PowerManagerInterface);
|
||||||
Name: 'PowerManagerProxy',
|
|
||||||
Interface: PowerManagerInterface,
|
|
||||||
|
|
||||||
_init: function() {
|
|
||||||
this.parent({ g_bus_type: Gio.BusType.SESSION,
|
|
||||||
g_name: BUS_NAME,
|
|
||||||
g_object_path: OBJECT_PATH });
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
const Indicator = new Lang.Class({
|
const Indicator = new Lang.Class({
|
||||||
Name: 'PowerIndicator',
|
Name: 'PowerIndicator',
|
||||||
@@ -64,7 +54,7 @@ const Indicator = new Lang.Class({
|
|||||||
_init: function() {
|
_init: function() {
|
||||||
this.parent('battery-missing-symbolic', _("Battery"));
|
this.parent('battery-missing-symbolic', _("Battery"));
|
||||||
|
|
||||||
this._proxy = new PowerManagerProxy();
|
this._proxy = new PowerManagerProxy(Gio.DBus.session, BUS_NAME, OBJECT_PATH);
|
||||||
|
|
||||||
this._deviceItems = [ ];
|
this._deviceItems = [ ];
|
||||||
this._hasPrimary = false;
|
this._hasPrimary = false;
|
||||||
@@ -83,26 +73,18 @@ const Indicator = new Lang.Class({
|
|||||||
|
|
||||||
this._proxy.connect('g-properties-changed',
|
this._proxy.connect('g-properties-changed',
|
||||||
Lang.bind(this, this._devicesChanged));
|
Lang.bind(this, this._devicesChanged));
|
||||||
this._proxy.init_async(GLib.PRIORITY_DEFAULT, null, Lang.bind(this, function(proxy, result) {
|
|
||||||
proxy.init_finish(result);
|
|
||||||
|
|
||||||
this._devicesChanged();
|
this._devicesChanged();
|
||||||
}));
|
|
||||||
},
|
},
|
||||||
|
|
||||||
_readPrimaryDevice: function() {
|
_readPrimaryDevice: function() {
|
||||||
this._proxy.GetPrimaryDeviceRemote(null, Lang.bind(this, function(proxy, result) {
|
this._proxy.GetPrimaryDeviceRemote(Lang.bind(this, function(result, error) {
|
||||||
let device_id, device_type, icon, percentage, state, seconds;
|
if (error) {
|
||||||
try {
|
|
||||||
[[device_id, device_type, icon, percentage, state, seconds]] =
|
|
||||||
proxy.GetPrimaryDeviceFinish(result);
|
|
||||||
} catch(e) {
|
|
||||||
this._hasPrimary = false;
|
this._hasPrimary = false;
|
||||||
this._primaryDeviceId = null;
|
this._primaryDeviceId = null;
|
||||||
this._batteryItem.actor.hide();
|
this._batteryItem.actor.hide();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
let [[device_id, device_type, icon, percentage, state, seconds]] = result;
|
||||||
if (device_type == UPDeviceType.BATTERY) {
|
if (device_type == UPDeviceType.BATTERY) {
|
||||||
this._hasPrimary = true;
|
this._hasPrimary = true;
|
||||||
let time = Math.round(seconds / 60);
|
let time = Math.round(seconds / 60);
|
||||||
@@ -139,18 +121,16 @@ const Indicator = new Lang.Class({
|
|||||||
},
|
},
|
||||||
|
|
||||||
_readOtherDevices: function() {
|
_readOtherDevices: function() {
|
||||||
this._proxy.GetDevicesRemote(null, Lang.bind(this, function(proxy, result) {
|
this._proxy.GetDevicesRemote(Lang.bind(this, function(result, error) {
|
||||||
this._deviceItems.forEach(function(i) { i.destroy(); });
|
this._deviceItems.forEach(function(i) { i.destroy(); });
|
||||||
this._deviceItems = [];
|
this._deviceItems = [];
|
||||||
|
|
||||||
let devices;
|
if (error) {
|
||||||
try {
|
|
||||||
[devices] = proxy.GetDevicesFinish(result);
|
|
||||||
} catch(e) {
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
let position = 0;
|
let position = 0;
|
||||||
|
let [devices] = result;
|
||||||
for (let i = 0; i < devices.length; i++) {
|
for (let i = 0; i < devices.length; i++) {
|
||||||
let [device_id, device_type] = devices[i];
|
let [device_id, device_type] = devices[i];
|
||||||
if (device_type == UPDeviceType.AC_POWER || device_id == this._primaryDeviceId)
|
if (device_type == UPDeviceType.AC_POWER || device_id == this._primaryDeviceId)
|
||||||
|
@@ -195,13 +195,9 @@ const IMStatusChooserItem = new Lang.Class({
|
|||||||
Lang.bind(this, this._changeIMStatus));
|
Lang.bind(this, this._changeIMStatus));
|
||||||
|
|
||||||
this._presence = new GnomeSession.Presence();
|
this._presence = new GnomeSession.Presence();
|
||||||
this._presence.init_async(GLib.PRIORITY_DEFAULT, null, Lang.bind(this, function(obj, result) {
|
|
||||||
obj.init_finish(result);
|
|
||||||
|
|
||||||
this._presence.connectSignal('StatusChanged', Lang.bind(this, function(proxy, senderName, [status]) {
|
this._presence.connectSignal('StatusChanged', Lang.bind(this, function(proxy, senderName, [status]) {
|
||||||
this._sessionStatusChanged(status);
|
this._sessionStatusChanged(status);
|
||||||
}));
|
}));
|
||||||
}));
|
|
||||||
|
|
||||||
this._sessionPresenceRestored = false;
|
this._sessionPresenceRestored = false;
|
||||||
this._imPresenceRestored = false;
|
this._imPresenceRestored = false;
|
||||||
@@ -484,33 +480,14 @@ const UserMenuButton = new Lang.Class({
|
|||||||
this._userManager = AccountsService.UserManager.get_default();
|
this._userManager = AccountsService.UserManager.get_default();
|
||||||
|
|
||||||
this._user = this._userManager.get_user(GLib.get_user_name());
|
this._user = this._userManager.get_user(GLib.get_user_name());
|
||||||
|
|
||||||
this._presence = new GnomeSession.Presence();
|
this._presence = new GnomeSession.Presence();
|
||||||
this._presence.init_async(GLib.PRIORITY_DEFAULT, null, Lang.bind(this, function(proxy, result) {
|
this._session = new GnomeSession.SessionManager();
|
||||||
proxy.init_finish(result);
|
|
||||||
|
|
||||||
this._updateSwitch(this._presence.status);
|
|
||||||
this._presence.connectSignal('StatusChanged', Lang.bind(this, function (proxy, senderName, [status]) {
|
|
||||||
this._updateSwitch(status);
|
|
||||||
}));
|
|
||||||
}));
|
|
||||||
|
|
||||||
let session = new GnomeSession.SessionManager();
|
|
||||||
session.init_async(GLib.PRIORITY_DEFAULT, null, Lang.bind(this, function(proxy, result) {
|
|
||||||
// This should never fail.
|
|
||||||
proxy.init_finish(result);
|
|
||||||
|
|
||||||
this._session = proxy;
|
|
||||||
this._updateHaveShutdown();
|
|
||||||
}));
|
|
||||||
this._haveShutdown = true;
|
this._haveShutdown = true;
|
||||||
this._haveSuspend = true;
|
this._haveSuspend = true;
|
||||||
|
|
||||||
this._accountMgr = Tp.AccountManager.dup();
|
this._accountMgr = Tp.AccountManager.dup();
|
||||||
|
|
||||||
LoginManager.getLoginManager(Lang.bind(this, function(manager) {
|
this._loginManager = LoginManager.getLoginManager();
|
||||||
this._loginManager = manager;
|
|
||||||
}));
|
|
||||||
this.actor.connect('destroy', Lang.bind(this, this._onDestroy));
|
this.actor.connect('destroy', Lang.bind(this, this._onDestroy));
|
||||||
|
|
||||||
this._iconBox = new St.Bin();
|
this._iconBox = new St.Bin();
|
||||||
@@ -556,6 +533,11 @@ const UserMenuButton = new Lang.Class({
|
|||||||
|
|
||||||
this._createSubMenu();
|
this._createSubMenu();
|
||||||
|
|
||||||
|
this._updateSwitch(this._presence.status);
|
||||||
|
this._presence.connectSignal('StatusChanged', Lang.bind(this, function (proxy, senderName, [status]) {
|
||||||
|
this._updateSwitch(status);
|
||||||
|
}));
|
||||||
|
|
||||||
this._userManager.connect('notify::is-loaded',
|
this._userManager.connect('notify::is-loaded',
|
||||||
Lang.bind(this, this._updateMultiUser));
|
Lang.bind(this, this._updateMultiUser));
|
||||||
this._userManager.connect('notify::has-multiple-users',
|
this._userManager.connect('notify::has-multiple-users',
|
||||||
@@ -655,29 +637,17 @@ const UserMenuButton = new Lang.Class({
|
|||||||
},
|
},
|
||||||
|
|
||||||
_updateHaveShutdown: function() {
|
_updateHaveShutdown: function() {
|
||||||
if (!this._session) {
|
this._session.CanShutdownRemote(Lang.bind(this,
|
||||||
this._haveShutdown = false;
|
function(result, error) {
|
||||||
return;
|
if (!error) {
|
||||||
}
|
this._haveShutdown = result[0];
|
||||||
|
|
||||||
this._session.CanShutdownRemote(null, Lang.bind(this, function(proxy, result) {
|
|
||||||
try {
|
|
||||||
[this._haveShutdown] = proxy.CanShutdownFinish(result);
|
|
||||||
} catch(e) {
|
|
||||||
this._haveShutdown = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
this._updateInstallUpdates();
|
this._updateInstallUpdates();
|
||||||
this._updateSuspendOrPowerOff();
|
this._updateSuspendOrPowerOff();
|
||||||
|
}
|
||||||
}));
|
}));
|
||||||
},
|
},
|
||||||
|
|
||||||
_updateHaveSuspend: function() {
|
_updateHaveSuspend: function() {
|
||||||
if (!this._loginManager) {
|
|
||||||
this._haveSuspend = false;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
this._loginManager.canSuspend(Lang.bind(this,
|
this._loginManager.canSuspend(Lang.bind(this,
|
||||||
function(result) {
|
function(result) {
|
||||||
this._haveSuspend = result;
|
this._haveSuspend = result;
|
||||||
@@ -867,17 +837,14 @@ const UserMenuButton = new Lang.Class({
|
|||||||
|
|
||||||
_onQuitSessionActivate: function() {
|
_onQuitSessionActivate: function() {
|
||||||
Main.overview.hide();
|
Main.overview.hide();
|
||||||
|
this._session.LogoutRemote(0);
|
||||||
if (this._session)
|
|
||||||
this._session.LogoutRemote(0, null, null);
|
|
||||||
},
|
},
|
||||||
|
|
||||||
_onInstallUpdatesActivate: function() {
|
_onInstallUpdatesActivate: function() {
|
||||||
Main.overview.hide();
|
Main.overview.hide();
|
||||||
Util.spawn(['pkexec', '/usr/libexec/pk-trigger-offline-update']);
|
Util.spawn(['pkexec', '/usr/libexec/pk-trigger-offline-update']);
|
||||||
|
|
||||||
if (this._haveShutdown)
|
this._session.RebootRemote();
|
||||||
this._session.RebootRemote(null, null);
|
|
||||||
},
|
},
|
||||||
|
|
||||||
_onSuspendOrPowerOffActivate: function() {
|
_onSuspendOrPowerOffActivate: function() {
|
||||||
@@ -885,8 +852,8 @@ const UserMenuButton = new Lang.Class({
|
|||||||
|
|
||||||
if (this._haveShutdown &&
|
if (this._haveShutdown &&
|
||||||
this._suspendOrPowerOffItem.state == PopupMenu.PopupAlternatingMenuItemState.DEFAULT) {
|
this._suspendOrPowerOffItem.state == PopupMenu.PopupAlternatingMenuItemState.DEFAULT) {
|
||||||
this._session.ShutdownRemote(null, null);
|
this._session.ShutdownRemote();
|
||||||
} else if (this._haveSuspend) {
|
} else {
|
||||||
if (this._screenSaverSettings.get_boolean(LOCK_ENABLED_KEY)) {
|
if (this._screenSaverSettings.get_boolean(LOCK_ENABLED_KEY)) {
|
||||||
let tmpId = Main.screenShield.connect('lock-screen-shown', Lang.bind(this, function() {
|
let tmpId = Main.screenShield.connect('lock-screen-shown', Lang.bind(this, function() {
|
||||||
Main.screenShield.disconnect(tmpId);
|
Main.screenShield.disconnect(tmpId);
|
||||||
|
@@ -52,7 +52,7 @@ const ViewSelector = new Lang.Class({
|
|||||||
|
|
||||||
this._activePage = null;
|
this._activePage = null;
|
||||||
|
|
||||||
this.active = false;
|
this.entryNonEmpty = false;
|
||||||
this._searchPending = false;
|
this._searchPending = false;
|
||||||
this._searchTimeoutId = 0;
|
this._searchTimeoutId = 0;
|
||||||
|
|
||||||
@@ -90,7 +90,7 @@ const ViewSelector = new Lang.Class({
|
|||||||
this._appsPage = this._addPage(this._appDisplay.actor, null,
|
this._appsPage = this._addPage(this._appDisplay.actor, null,
|
||||||
_("Applications"), 'system-run-symbolic');
|
_("Applications"), 'system-run-symbolic');
|
||||||
|
|
||||||
this._searchResults = new SearchDisplay.SearchResults(this._searchSystem);
|
this._searchResults = new SearchDisplay.SearchDisplay(this._searchSystem);
|
||||||
this._searchPage = this._addPage(this._searchResults.actor, this._entry,
|
this._searchPage = this._addPage(this._searchResults.actor, this._entry,
|
||||||
_("Search"), 'edit-find-symbolic');
|
_("Search"), 'edit-find-symbolic');
|
||||||
|
|
||||||
@@ -114,9 +114,6 @@ const ViewSelector = new Lang.Class({
|
|||||||
|
|
||||||
global.focus_manager.add_group(this._searchResults.actor);
|
global.focus_manager.add_group(this._searchResults.actor);
|
||||||
|
|
||||||
Main.overview.connect('item-drag-begin',
|
|
||||||
Lang.bind(this, this._resetShowAppsButton));
|
|
||||||
|
|
||||||
this._stageKeyPressId = 0;
|
this._stageKeyPressId = 0;
|
||||||
Main.overview.connect('showing', Lang.bind(this,
|
Main.overview.connect('showing', Lang.bind(this,
|
||||||
function () {
|
function () {
|
||||||
@@ -133,17 +130,6 @@ const ViewSelector = new Lang.Class({
|
|||||||
}
|
}
|
||||||
}));
|
}));
|
||||||
|
|
||||||
// Public constraints which may be used to tie actors' height or
|
|
||||||
// vertical position to the current tab's content; as the content's
|
|
||||||
// height and position depend on the view selector's style properties
|
|
||||||
// (e.g. font size, padding, spacing, ...) it would be extremely hard
|
|
||||||
// and ugly to get these from the outside. While it would be possible
|
|
||||||
// to use position and height properties directly, outside code would
|
|
||||||
// need to ensure that the content is properly allocated before
|
|
||||||
// accessing the properties.
|
|
||||||
this.constrainHeight = new Clutter.BindConstraint({ source: this._pageArea,
|
|
||||||
coordinate: Clutter.BindCoordinate.HEIGHT });
|
|
||||||
|
|
||||||
global.display.add_keybinding('toggle-application-view',
|
global.display.add_keybinding('toggle-application-view',
|
||||||
new Gio.Settings({ schema: SHELL_KEYBINDINGS_SCHEMA }),
|
new Gio.Settings({ schema: SHELL_KEYBINDINGS_SCHEMA }),
|
||||||
Meta.KeyBindingFlags.NONE,
|
Meta.KeyBindingFlags.NONE,
|
||||||
@@ -230,7 +216,9 @@ const ViewSelector = new Lang.Class({
|
|||||||
},
|
},
|
||||||
|
|
||||||
_onShowAppsButtonToggled: function() {
|
_onShowAppsButtonToggled: function() {
|
||||||
if (this.active)
|
this.emit('apps-button-checked', this._showAppsButton.checked);
|
||||||
|
|
||||||
|
if (this.entryNonEmpty)
|
||||||
this.reset();
|
this.reset();
|
||||||
else
|
else
|
||||||
this._showPage(this._showAppsButton.checked ? this._appsPage
|
this._showPage(this._showAppsButton.checked ? this._appsPage
|
||||||
@@ -246,7 +234,7 @@ const ViewSelector = new Lang.Class({
|
|||||||
let symbol = event.get_key_symbol();
|
let symbol = event.get_key_symbol();
|
||||||
|
|
||||||
if (symbol == Clutter.Escape) {
|
if (symbol == Clutter.Escape) {
|
||||||
if (this.active)
|
if (this.entryNonEmpty)
|
||||||
this.reset();
|
this.reset();
|
||||||
else if (this._showAppsButton.checked)
|
else if (this._showAppsButton.checked)
|
||||||
this._resetShowAppsButton();
|
this._resetShowAppsButton();
|
||||||
@@ -254,9 +242,9 @@ const ViewSelector = new Lang.Class({
|
|||||||
Main.overview.hide();
|
Main.overview.hide();
|
||||||
return true;
|
return true;
|
||||||
} else if (Clutter.keysym_to_unicode(symbol) ||
|
} else if (Clutter.keysym_to_unicode(symbol) ||
|
||||||
(symbol == Clutter.BackSpace && this.active)) {
|
(symbol == Clutter.BackSpace && this.entryNonEmpty)) {
|
||||||
this.startSearch(event);
|
this.startSearch(event);
|
||||||
} else if (!this.active) {
|
} else if (!this.entryNonEmpty) {
|
||||||
if (symbol == Clutter.Tab || symbol == Clutter.Down) {
|
if (symbol == Clutter.Tab || symbol == Clutter.Down) {
|
||||||
this._activePage.navigate_focus(null, Gtk.DirectionType.TAB_FORWARD, false);
|
this._activePage.navigate_focus(null, Gtk.DirectionType.TAB_FORWARD, false);
|
||||||
return true;
|
return true;
|
||||||
@@ -269,6 +257,7 @@ const ViewSelector = new Lang.Class({
|
|||||||
},
|
},
|
||||||
|
|
||||||
_searchCancelled: function() {
|
_searchCancelled: function() {
|
||||||
|
this.emit('search-cancelled');
|
||||||
this._showPage(this._showAppsButton.checked ? this._appsPage
|
this._showPage(this._showAppsButton.checked ? this._appsPage
|
||||||
: this._workspacesPage);
|
: this._workspacesPage);
|
||||||
|
|
||||||
@@ -330,13 +319,14 @@ const ViewSelector = new Lang.Class({
|
|||||||
},
|
},
|
||||||
|
|
||||||
_onTextChanged: function (se, prop) {
|
_onTextChanged: function (se, prop) {
|
||||||
let searchPreviouslyActive = this.active;
|
let searchPreviouslyActive = this.entryNonEmpty;
|
||||||
this.active = this._entry.get_text() != '';
|
this.entryNonEmpty = this._entry.get_text() != '';
|
||||||
this._searchPending = this.active && !searchPreviouslyActive;
|
this._searchPending = this.entryNonEmpty && !searchPreviouslyActive;
|
||||||
if (this._searchPending) {
|
if (this._searchPending) {
|
||||||
this._searchResults.startingSearch();
|
this._searchResults.startingSearch();
|
||||||
}
|
}
|
||||||
if (this.active) {
|
if (this.entryNonEmpty) {
|
||||||
|
this.emit('search-begin');
|
||||||
this._entry.set_secondary_icon(this._activeIcon);
|
this._entry.set_secondary_icon(this._activeIcon);
|
||||||
|
|
||||||
if (this._iconClickedId == 0) {
|
if (this._iconClickedId == 0) {
|
||||||
@@ -353,7 +343,7 @@ const ViewSelector = new Lang.Class({
|
|||||||
this._entry.set_secondary_icon(this._inactiveIcon);
|
this._entry.set_secondary_icon(this._inactiveIcon);
|
||||||
this._searchCancelled();
|
this._searchCancelled();
|
||||||
}
|
}
|
||||||
if (!this.active) {
|
if (!this.entryNonEmpty) {
|
||||||
if (this._searchTimeoutId > 0) {
|
if (this._searchTimeoutId > 0) {
|
||||||
Mainloop.source_remove(this._searchTimeoutId);
|
Mainloop.source_remove(this._searchTimeoutId);
|
||||||
this._searchTimeoutId = 0;
|
this._searchTimeoutId = 0;
|
||||||
@@ -381,7 +371,7 @@ const ViewSelector = new Lang.Class({
|
|||||||
}
|
}
|
||||||
this._searchResults.activateDefault();
|
this._searchResults.activateDefault();
|
||||||
return true;
|
return true;
|
||||||
} else if (this.active) {
|
} else if (this.entryNonEmpty) {
|
||||||
let arrowNext, nextDirection;
|
let arrowNext, nextDirection;
|
||||||
if (entry.get_text_direction() == Clutter.TextDirection.RTL) {
|
if (entry.get_text_direction() == Clutter.TextDirection.RTL) {
|
||||||
arrowNext = Clutter.Left;
|
arrowNext = Clutter.Left;
|
||||||
|
@@ -1073,6 +1073,9 @@ const Workspace = new Lang.Class({
|
|||||||
* ANIMATE - Indicates that we need animate changing position.
|
* ANIMATE - Indicates that we need animate changing position.
|
||||||
*/
|
*/
|
||||||
positionWindows: function(flags) {
|
positionWindows: function(flags) {
|
||||||
|
if (this.leavingOverview)
|
||||||
|
return;
|
||||||
|
|
||||||
this._positionWindowsFlags |= flags;
|
this._positionWindowsFlags |= flags;
|
||||||
|
|
||||||
if (this._positionWindowsId > 0)
|
if (this._positionWindowsId > 0)
|
||||||
|
@@ -493,6 +493,7 @@ const ThumbnailsBox = new Lang.Class({
|
|||||||
_init: function() {
|
_init: function() {
|
||||||
this.actor = new Shell.GenericContainer({ reactive: true,
|
this.actor = new Shell.GenericContainer({ reactive: true,
|
||||||
style_class: 'workspace-thumbnails',
|
style_class: 'workspace-thumbnails',
|
||||||
|
can_focus: true,
|
||||||
request_mode: Clutter.RequestMode.WIDTH_FOR_HEIGHT });
|
request_mode: Clutter.RequestMode.WIDTH_FOR_HEIGHT });
|
||||||
this.actor.connect('get-preferred-width', Lang.bind(this, this._getPreferredWidth));
|
this.actor.connect('get-preferred-width', Lang.bind(this, this._getPreferredWidth));
|
||||||
this.actor.connect('get-preferred-height', Lang.bind(this, this._getPreferredHeight));
|
this.actor.connect('get-preferred-height', Lang.bind(this, this._getPreferredHeight));
|
||||||
@@ -526,6 +527,8 @@ const ThumbnailsBox = new Lang.Class({
|
|||||||
this._dropPlaceholder = new St.Bin({ style_class: 'placeholder' });
|
this._dropPlaceholder = new St.Bin({ style_class: 'placeholder' });
|
||||||
this.actor.add_actor(this._dropPlaceholder);
|
this.actor.add_actor(this._dropPlaceholder);
|
||||||
|
|
||||||
|
this.visible = true;
|
||||||
|
|
||||||
this._targetScale = 0;
|
this._targetScale = 0;
|
||||||
this._scale = 0;
|
this._scale = 0;
|
||||||
this._pendingScaleUpdate = false;
|
this._pendingScaleUpdate = false;
|
||||||
@@ -541,12 +544,21 @@ const ThumbnailsBox = new Lang.Class({
|
|||||||
|
|
||||||
this.actor.connect('button-press-event', function() { return true; });
|
this.actor.connect('button-press-event', function() { return true; });
|
||||||
this.actor.connect('button-release-event', Lang.bind(this, this._onButtonRelease));
|
this.actor.connect('button-release-event', Lang.bind(this, this._onButtonRelease));
|
||||||
|
this.actor.connect('scroll-event',
|
||||||
|
Lang.bind(this, this._onScrollEvent));
|
||||||
|
this.actor.connect('key-release-event',
|
||||||
|
Lang.bind(this, this._onKeyRelease));
|
||||||
|
|
||||||
Main.overview.connect('item-drag-begin',
|
Main.overview.connect('showing',
|
||||||
|
Lang.bind(this, this._createThumbnails));
|
||||||
|
Main.overview.connect('hidden',
|
||||||
|
Lang.bind(this, this._destroyThumbnails));
|
||||||
|
|
||||||
|
Main.overview.connect('app-drag-begin',
|
||||||
Lang.bind(this, this._onDragBegin));
|
Lang.bind(this, this._onDragBegin));
|
||||||
Main.overview.connect('item-drag-end',
|
Main.overview.connect('app-drag-end',
|
||||||
Lang.bind(this, this._onDragEnd));
|
Lang.bind(this, this._onDragEnd));
|
||||||
Main.overview.connect('item-drag-cancelled',
|
Main.overview.connect('app-drag-cancelled',
|
||||||
Lang.bind(this, this._onDragCancelled));
|
Lang.bind(this, this._onDragCancelled));
|
||||||
Main.overview.connect('window-drag-begin',
|
Main.overview.connect('window-drag-begin',
|
||||||
Lang.bind(this, this._onDragBegin));
|
Lang.bind(this, this._onDragBegin));
|
||||||
@@ -719,10 +731,16 @@ const ThumbnailsBox = new Lang.Class({
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
show: function() {
|
_createThumbnails: function() {
|
||||||
this._switchWorkspaceNotifyId =
|
this._switchWorkspaceNotifyId =
|
||||||
global.window_manager.connect('switch-workspace',
|
global.window_manager.connect('switch-workspace',
|
||||||
Lang.bind(this, this._activeWorkspaceChanged));
|
Lang.bind(this, this._activeWorkspaceChanged));
|
||||||
|
this._nWorkspacesNotifyId =
|
||||||
|
global.screen.connect('notify::n-workspaces',
|
||||||
|
Lang.bind(this, this._workspacesChanged));
|
||||||
|
this._syncStackingId =
|
||||||
|
Main.overview.connect('sync-window-stacking',
|
||||||
|
Lang.bind(this, this.syncStacking));
|
||||||
|
|
||||||
this._targetScale = 0;
|
this._targetScale = 0;
|
||||||
this._scale = 0;
|
this._scale = 0;
|
||||||
@@ -746,17 +764,86 @@ const ThumbnailsBox = new Lang.Class({
|
|||||||
this.addThumbnails(0, global.screen.n_workspaces);
|
this.addThumbnails(0, global.screen.n_workspaces);
|
||||||
},
|
},
|
||||||
|
|
||||||
hide: function() {
|
_destroyThumbnails: function() {
|
||||||
if (this._switchWorkspaceNotifyId > 0) {
|
if (this._switchWorkspaceNotifyId > 0) {
|
||||||
global.window_manager.disconnect(this._switchWorkspaceNotifyId);
|
global.window_manager.disconnect(this._switchWorkspaceNotifyId);
|
||||||
this._switchWorkspaceNotifyId = 0;
|
this._switchWorkspaceNotifyId = 0;
|
||||||
}
|
}
|
||||||
|
if (this._nWorkspacesNotifyId > 0) {
|
||||||
|
global.screen.disconnect(this._nWorkspacesNotifyId);
|
||||||
|
this._nWorkspacesNotifyId = 0;
|
||||||
|
}
|
||||||
|
if (this._syncStackingId > 0) {
|
||||||
|
Main.overview.disconnect(this._syncStackingId);
|
||||||
|
this._syncStackingId = 0;
|
||||||
|
}
|
||||||
|
|
||||||
for (let w = 0; w < this._thumbnails.length; w++)
|
for (let w = 0; w < this._thumbnails.length; w++)
|
||||||
this._thumbnails[w].destroy();
|
this._thumbnails[w].destroy();
|
||||||
this._thumbnails = [];
|
this._thumbnails = [];
|
||||||
},
|
},
|
||||||
|
|
||||||
|
_computeThumbnailsX: function() {
|
||||||
|
this._targetX = this.actor.get_x();
|
||||||
|
|
||||||
|
let rtl = (this.actor.get_text_direction() == Clutter.TextDirection.RTL);
|
||||||
|
|
||||||
|
if (rtl)
|
||||||
|
this._hiddenX = -this.actor.width;
|
||||||
|
else
|
||||||
|
this._hiddenX = this._targetX + this.actor.width;
|
||||||
|
},
|
||||||
|
|
||||||
|
show: function() {
|
||||||
|
if (this.visible)
|
||||||
|
return;
|
||||||
|
|
||||||
|
this.visible = true;
|
||||||
|
|
||||||
|
this.actor.show();
|
||||||
|
Tweener.addTween(this.actor, { translation_x: this._targetX,
|
||||||
|
transition: 'easeOutQuad',
|
||||||
|
time: SLIDE_ANIMATION_TIME
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
hide: function() {
|
||||||
|
if (!this.visible)
|
||||||
|
return;
|
||||||
|
|
||||||
|
this.visible = false;
|
||||||
|
|
||||||
|
Tweener.addTween(this.actor, { translation_x: this._hiddenX,
|
||||||
|
transition: 'easeOutQuad',
|
||||||
|
time: SLIDE_ANIMATION_TIME,
|
||||||
|
onComplete: Lang.bind(this, function () {
|
||||||
|
this.actor.hide();
|
||||||
|
})
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
_workspacesChanged: function() {
|
||||||
|
let oldNumWorkspaces = this._thumbnails.length;
|
||||||
|
let newNumWorkspaces = global.screen.n_workspaces;
|
||||||
|
let active = global.screen.get_active_workspace_index();
|
||||||
|
|
||||||
|
if (newNumWorkspaces > oldNumWorkspaces) {
|
||||||
|
this.addThumbnails(oldNumWorkspaces, newNumWorkspaces - oldNumWorkspaces);
|
||||||
|
} else {
|
||||||
|
let removedIndex;
|
||||||
|
let removedNum = oldNumWorkspaces - newNumWorkspaces;
|
||||||
|
for (let w = 0; w < oldNumWorkspaces; w++) {
|
||||||
|
let metaWorkspace = global.screen.get_workspace_by_index(w);
|
||||||
|
if (this._thumbnails[w].metaWorkspace != metaWorkspace) {
|
||||||
|
removedIndex = w;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
this.removeThumbnails(removedIndex, removedNum);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
addThumbnails: function(start, count) {
|
addThumbnails: function(start, count) {
|
||||||
for (let k = start; k < start + count; k++) {
|
for (let k = start; k < start + count; k++) {
|
||||||
let metaWorkspace = global.screen.get_workspace_by_index(k);
|
let metaWorkspace = global.screen.get_workspace_by_index(k);
|
||||||
@@ -802,7 +889,7 @@ const ThumbnailsBox = new Lang.Class({
|
|||||||
this._queueUpdateStates();
|
this._queueUpdateStates();
|
||||||
},
|
},
|
||||||
|
|
||||||
syncStacking: function(stackIndices) {
|
syncStacking: function(actor, stackIndices) {
|
||||||
for (let i = 0; i < this._thumbnails.length; i++)
|
for (let i = 0; i < this._thumbnails.length; i++)
|
||||||
this._thumbnails[i].syncStacking(stackIndices);
|
this._thumbnails[i].syncStacking(stackIndices);
|
||||||
},
|
},
|
||||||
@@ -924,6 +1011,8 @@ const ThumbnailsBox = new Lang.Class({
|
|||||||
onCompleteScope: this
|
onCompleteScope: this
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
this._computeThumbnailsX();
|
||||||
},
|
},
|
||||||
|
|
||||||
_queueUpdateStates: function() {
|
_queueUpdateStates: function() {
|
||||||
@@ -1157,5 +1246,30 @@ const ThumbnailsBox = new Lang.Class({
|
|||||||
},
|
},
|
||||||
onCompleteScope: this
|
onCompleteScope: this
|
||||||
});
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
_onScrollEvent: function (actor, event) {
|
||||||
|
switch (event.get_scroll_direction()) {
|
||||||
|
case Clutter.ScrollDirection.UP:
|
||||||
|
Main.wm.actionMoveWorkspace(Meta.MotionDirection.UP);
|
||||||
|
break;
|
||||||
|
case Clutter.ScrollDirection.DOWN:
|
||||||
|
Main.wm.actionMoveWorkspace(Meta.MotionDirection.DOWN);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
_onKeyRelease: function (actor, event) {
|
||||||
|
switch (event.get_key_symbol()) {
|
||||||
|
case Clutter.KEY_Up:
|
||||||
|
Main.wm.actionMoveWorkspace(Meta.MotionDirection.UP);
|
||||||
|
break;
|
||||||
|
case Clutter.KEY_Down:
|
||||||
|
Main.wm.actionMoveWorkspace(Meta.MotionDirection.DOWN);
|
||||||
|
break;
|
||||||
|
case Clutter.KEY_Return:
|
||||||
|
Main.overview.toggle();
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@@ -22,8 +22,6 @@ const MAX_WORKSPACES = 16;
|
|||||||
|
|
||||||
const OVERRIDE_SCHEMA = 'org.gnome.shell.overrides';
|
const OVERRIDE_SCHEMA = 'org.gnome.shell.overrides';
|
||||||
|
|
||||||
const CONTROLS_POP_IN_TIME = 0.1;
|
|
||||||
|
|
||||||
|
|
||||||
const WorkspacesView = new Lang.Class({
|
const WorkspacesView = new Lang.Class({
|
||||||
Name: 'WorkspacesView',
|
Name: 'WorkspacesView',
|
||||||
@@ -106,9 +104,9 @@ const WorkspacesView = new Lang.Class({
|
|||||||
global.window_manager.connect('switch-workspace',
|
global.window_manager.connect('switch-workspace',
|
||||||
Lang.bind(this, this._activeWorkspaceChanged));
|
Lang.bind(this, this._activeWorkspaceChanged));
|
||||||
|
|
||||||
this._itemDragBeginId = Main.overview.connect('item-drag-begin',
|
this._appDragBeginId = Main.overview.connect('app-drag-begin',
|
||||||
Lang.bind(this, this._dragBegin));
|
Lang.bind(this, this._dragBegin));
|
||||||
this._itemDragEndId = Main.overview.connect('item-drag-end',
|
this._appDragEndId = Main.overview.connect('app-drag-end',
|
||||||
Lang.bind(this, this._dragEnd));
|
Lang.bind(this, this._dragEnd));
|
||||||
this._windowDragBeginId = Main.overview.connect('window-drag-begin',
|
this._windowDragBeginId = Main.overview.connect('window-drag-begin',
|
||||||
Lang.bind(this, this._dragBegin));
|
Lang.bind(this, this._dragBegin));
|
||||||
@@ -327,13 +325,13 @@ const WorkspacesView = new Lang.Class({
|
|||||||
if (this._inDrag)
|
if (this._inDrag)
|
||||||
this._dragEnd();
|
this._dragEnd();
|
||||||
|
|
||||||
if (this._itemDragBeginId > 0) {
|
if (this._appDragBeginId > 0) {
|
||||||
Main.overview.disconnect(this._itemDragBeginId);
|
Main.overview.disconnect(this._appDragBeginId);
|
||||||
this._itemDragBeginId = 0;
|
this._appDragBeginId = 0;
|
||||||
}
|
}
|
||||||
if (this._itemDragEndId > 0) {
|
if (this._appDragEndId > 0) {
|
||||||
Main.overview.disconnect(this._itemDragEndId);
|
Main.overview.disconnect(this._appDragEndId);
|
||||||
this._itemDragEndId = 0;
|
this._appDragEndId = 0;
|
||||||
}
|
}
|
||||||
if (this._windowDragBeginId > 0) {
|
if (this._windowDragBeginId > 0) {
|
||||||
Main.overview.disconnect(this._windowDragBeginId);
|
Main.overview.disconnect(this._windowDragBeginId);
|
||||||
@@ -460,25 +458,8 @@ const WorkspacesDisplay = new Lang.Class({
|
|||||||
this.actor.connect('parent-set', Lang.bind(this, this._parentSet));
|
this.actor.connect('parent-set', Lang.bind(this, this._parentSet));
|
||||||
this.actor.set_clip_to_allocation(true);
|
this.actor.set_clip_to_allocation(true);
|
||||||
|
|
||||||
let controls = new St.Bin({ style_class: 'workspace-controls',
|
|
||||||
request_mode: Clutter.RequestMode.WIDTH_FOR_HEIGHT,
|
|
||||||
y_align: St.Align.START,
|
|
||||||
y_fill: true });
|
|
||||||
this._controls = controls;
|
|
||||||
this.actor.add_actor(controls);
|
|
||||||
|
|
||||||
controls.reactive = true;
|
|
||||||
controls.track_hover = true;
|
|
||||||
controls.connect('notify::hover',
|
|
||||||
Lang.bind(this, this._onControlsHoverChanged));
|
|
||||||
controls.connect('scroll-event',
|
|
||||||
Lang.bind(this, this._onScrollEvent));
|
|
||||||
|
|
||||||
this._primaryIndex = Main.layoutManager.primaryIndex;
|
this._primaryIndex = Main.layoutManager.primaryIndex;
|
||||||
|
|
||||||
this._thumbnailsBox = new WorkspaceThumbnail.ThumbnailsBox();
|
|
||||||
controls.add_actor(this._thumbnailsBox.actor);
|
|
||||||
|
|
||||||
this._workspacesViews = null;
|
this._workspacesViews = null;
|
||||||
this._primaryScrollAdjustment = null;
|
this._primaryScrollAdjustment = null;
|
||||||
|
|
||||||
@@ -491,34 +472,14 @@ const WorkspacesDisplay = new Lang.Class({
|
|||||||
this._inDrag = false;
|
this._inDrag = false;
|
||||||
this._cancelledDrag = false;
|
this._cancelledDrag = false;
|
||||||
|
|
||||||
this._controlsInitiallyHovered = false;
|
|
||||||
this._alwaysZoomOut = false;
|
|
||||||
this._zoomOut = false;
|
|
||||||
this._zoomFraction = 0;
|
|
||||||
|
|
||||||
this._updateAlwaysZoom();
|
|
||||||
|
|
||||||
// If we stop hiding the overview on layout changes, we will need to
|
|
||||||
// update the _workspacesViews here
|
|
||||||
Main.layoutManager.connect('monitors-changed', Lang.bind(this, this._updateAlwaysZoom));
|
|
||||||
|
|
||||||
Main.xdndHandler.connect('drag-begin', Lang.bind(this, function(){
|
|
||||||
this._alwaysZoomOut = true;
|
|
||||||
}));
|
|
||||||
|
|
||||||
Main.xdndHandler.connect('drag-end', Lang.bind(this, function(){
|
|
||||||
this._alwaysZoomOut = false;
|
|
||||||
this._updateAlwaysZoom();
|
|
||||||
}));
|
|
||||||
|
|
||||||
global.screen.connect('notify::n-workspaces',
|
global.screen.connect('notify::n-workspaces',
|
||||||
Lang.bind(this, this._workspacesChanged));
|
Lang.bind(this, this._workspacesChanged));
|
||||||
|
|
||||||
this._switchWorkspaceNotifyId = 0;
|
this._switchWorkspaceNotifyId = 0;
|
||||||
|
|
||||||
this._itemDragBeginId = 0;
|
this._appDragBeginId = 0;
|
||||||
this._itemDragCancelledId = 0;
|
this._appDragCancelledId = 0;
|
||||||
this._itemDragEndId = 0;
|
this._appDragEndId = 0;
|
||||||
this._windowDragBeginId = 0;
|
this._windowDragBeginId = 0;
|
||||||
this._windowDragCancelledId = 0;
|
this._windowDragCancelledId = 0;
|
||||||
this._windowDragEndId = 0;
|
this._windowDragEndId = 0;
|
||||||
@@ -538,41 +499,20 @@ const WorkspacesDisplay = new Lang.Class({
|
|||||||
},
|
},
|
||||||
|
|
||||||
show: function() {
|
show: function() {
|
||||||
if(!this._alwaysZoomOut) {
|
|
||||||
let [mouseX, mouseY] = global.get_pointer();
|
|
||||||
let [x, y] = this._controls.get_transformed_position();
|
|
||||||
let [width, height] = this._controls.get_transformed_size();
|
|
||||||
let visibleWidth = this._controls.get_theme_node().get_length('visible-width');
|
|
||||||
let rtl = (Clutter.get_default_text_direction () == Clutter.TextDirection.RTL);
|
|
||||||
if(rtl)
|
|
||||||
x = x + width - visibleWidth;
|
|
||||||
if(mouseX > x - 0.5 && mouseX < x + visibleWidth + 0.5 &&
|
|
||||||
mouseY > y - 0.5 && mouseY < y + height + 0.5)
|
|
||||||
this._controlsInitiallyHovered = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
this._zoomOut = this._alwaysZoomOut;
|
|
||||||
this._zoomFraction = this._alwaysZoomOut ? 1 : 0;
|
|
||||||
this._updateZoom();
|
|
||||||
|
|
||||||
this._controls.show();
|
|
||||||
this._thumbnailsBox.show();
|
|
||||||
this._updateSwitcherVisibility();
|
|
||||||
|
|
||||||
this._updateWorkspacesViews();
|
this._updateWorkspacesViews();
|
||||||
|
|
||||||
this._restackedNotifyId =
|
this._restackedNotifyId =
|
||||||
global.screen.connect('restacked',
|
Main.overview.connect('sync-window-stacking',
|
||||||
Lang.bind(this, this._onRestacked));
|
Lang.bind(this, this._onRestacked));
|
||||||
|
|
||||||
if (this._itemDragBeginId == 0)
|
if (this._appDragBeginId == 0)
|
||||||
this._itemDragBeginId = Main.overview.connect('item-drag-begin',
|
this._appDragBeginId = Main.overview.connect('app-drag-begin',
|
||||||
Lang.bind(this, this._dragBegin));
|
Lang.bind(this, this._dragBegin));
|
||||||
if (this._itemDragCancelledId == 0)
|
if (this._appDragCancelledId == 0)
|
||||||
this._itemDragCancelledId = Main.overview.connect('item-drag-cancelled',
|
this._appDragCancelledId = Main.overview.connect('app-drag-cancelled',
|
||||||
Lang.bind(this, this._dragCancelled));
|
Lang.bind(this, this._dragCancelled));
|
||||||
if (this._itemDragEndId == 0)
|
if (this._appDragEndId == 0)
|
||||||
this._itemDragEndId = Main.overview.connect('item-drag-end',
|
this._appDragEndId = Main.overview.connect('app-drag-end',
|
||||||
Lang.bind(this, this._dragEnd));
|
Lang.bind(this, this._dragEnd));
|
||||||
if (this._windowDragBeginId == 0)
|
if (this._windowDragBeginId == 0)
|
||||||
this._windowDragBeginId = Main.overview.connect('window-drag-begin',
|
this._windowDragBeginId = Main.overview.connect('window-drag-begin',
|
||||||
@@ -583,8 +523,6 @@ const WorkspacesDisplay = new Lang.Class({
|
|||||||
if (this._windowDragEndId == 0)
|
if (this._windowDragEndId == 0)
|
||||||
this._windowDragEndId = Main.overview.connect('window-drag-end',
|
this._windowDragEndId = Main.overview.connect('window-drag-end',
|
||||||
Lang.bind(this, this._dragEnd));
|
Lang.bind(this, this._dragEnd));
|
||||||
|
|
||||||
this._onRestacked();
|
|
||||||
},
|
},
|
||||||
|
|
||||||
zoomFromOverview: function() {
|
zoomFromOverview: function() {
|
||||||
@@ -594,27 +532,21 @@ const WorkspacesDisplay = new Lang.Class({
|
|||||||
},
|
},
|
||||||
|
|
||||||
hide: function() {
|
hide: function() {
|
||||||
this._controls.hide();
|
|
||||||
this._thumbnailsBox.hide();
|
|
||||||
|
|
||||||
if (!this._alwaysZoomOut)
|
|
||||||
this.zoomFraction = 0;
|
|
||||||
|
|
||||||
if (this._restackedNotifyId > 0){
|
if (this._restackedNotifyId > 0){
|
||||||
global.screen.disconnect(this._restackedNotifyId);
|
Main.overview.disconnect(this._restackedNotifyId);
|
||||||
this._restackedNotifyId = 0;
|
this._restackedNotifyId = 0;
|
||||||
}
|
}
|
||||||
if (this._itemDragBeginId > 0) {
|
if (this._appDragBeginId > 0) {
|
||||||
Main.overview.disconnect(this._itemDragBeginId);
|
Main.overview.disconnect(this._appDragBeginId);
|
||||||
this._itemDragBeginId = 0;
|
this._appDragBeginId = 0;
|
||||||
}
|
}
|
||||||
if (this._itemDragCancelledId > 0) {
|
if (this._appDragCancelledId > 0) {
|
||||||
Main.overview.disconnect(this._itemDragCancelledId);
|
Main.overview.disconnect(this._appDragCancelledId);
|
||||||
this._itemDragCancelledId = 0;
|
this._appDragCancelledId = 0;
|
||||||
}
|
}
|
||||||
if (this._itemDragEndId > 0) {
|
if (this._appDragEndId > 0) {
|
||||||
Main.overview.disconnect(this._itemDragEndId);
|
Main.overview.disconnect(this._appDragEndId);
|
||||||
this._itemDragEndId = 0;
|
this._appDragEndId = 0;
|
||||||
}
|
}
|
||||||
if (this._windowDragBeginId > 0) {
|
if (this._windowDragBeginId > 0) {
|
||||||
Main.overview.disconnect(this._windowDragBeginId);
|
Main.overview.disconnect(this._windowDragBeginId);
|
||||||
@@ -745,73 +677,15 @@ const WorkspacesDisplay = new Lang.Class({
|
|||||||
return this._getPrimaryView().getActiveWorkspace().hasMaximizedWindows();
|
return this._getPrimaryView().getActiveWorkspace().hasMaximizedWindows();
|
||||||
},
|
},
|
||||||
|
|
||||||
// zoomFraction property allows us to tween the controls sliding in and out
|
|
||||||
set zoomFraction(fraction) {
|
|
||||||
this._zoomFraction = fraction;
|
|
||||||
this.actor.queue_relayout();
|
|
||||||
},
|
|
||||||
|
|
||||||
get zoomFraction() {
|
|
||||||
return this._zoomFraction;
|
|
||||||
},
|
|
||||||
|
|
||||||
_updateAlwaysZoom: function() {
|
|
||||||
// Always show the pager if workspaces are actually used,
|
|
||||||
// e.g. there are windows on more than one
|
|
||||||
this._alwaysZoomOut = global.screen.n_workspaces > 2;
|
|
||||||
|
|
||||||
if (this._alwaysZoomOut)
|
|
||||||
return;
|
|
||||||
|
|
||||||
let monitors = Main.layoutManager.monitors;
|
|
||||||
let primary = Main.layoutManager.primaryMonitor;
|
|
||||||
|
|
||||||
/* Look for any monitor to the right of the primary, if there is
|
|
||||||
* one, we always keep zoom out, otherwise its hard to reach
|
|
||||||
* the thumbnail area without passing into the next monitor. */
|
|
||||||
for (let i = 0; i < monitors.length; i++) {
|
|
||||||
if (monitors[i].x >= primary.x + primary.width) {
|
|
||||||
this._alwaysZoomOut = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
_getPreferredWidth: function (actor, forHeight, alloc) {
|
_getPreferredWidth: function (actor, forHeight, alloc) {
|
||||||
// pass through the call in case the child needs it, but report 0x0
|
// pass through the call in case the child needs it, but report 0x0
|
||||||
this._controls.get_preferred_width(forHeight);
|
|
||||||
},
|
},
|
||||||
|
|
||||||
_getPreferredHeight: function (actor, forWidth, alloc) {
|
_getPreferredHeight: function (actor, forWidth, alloc) {
|
||||||
// pass through the call in case the child needs it, but report 0x0
|
// pass through the call in case the child needs it, but report 0x0
|
||||||
this._controls.get_preferred_height(forWidth);
|
|
||||||
},
|
},
|
||||||
|
|
||||||
_allocate: function (actor, box, flags) {
|
_allocate: function (actor, box, flags) {
|
||||||
let childBox = new Clutter.ActorBox();
|
|
||||||
|
|
||||||
let totalWidth = box.x2 - box.x1;
|
|
||||||
|
|
||||||
// width of the controls
|
|
||||||
let [controlsMin, controlsNatural] = this._controls.get_preferred_width(box.y2 - box.y1);
|
|
||||||
|
|
||||||
// Amount of space on the screen we reserve for the visible control
|
|
||||||
let controlsVisible = this._controls.get_theme_node().get_length('visible-width');
|
|
||||||
let controlsReserved = controlsVisible * (1 - this._zoomFraction) + controlsNatural * this._zoomFraction;
|
|
||||||
|
|
||||||
let rtl = (Clutter.get_default_text_direction () == Clutter.TextDirection.RTL);
|
|
||||||
if (rtl) {
|
|
||||||
childBox.x2 = controlsReserved;
|
|
||||||
childBox.x1 = childBox.x2 - controlsNatural;
|
|
||||||
} else {
|
|
||||||
childBox.x1 = totalWidth - controlsReserved;
|
|
||||||
childBox.x2 = childBox.x1 + controlsNatural;
|
|
||||||
}
|
|
||||||
|
|
||||||
childBox.y1 = 0;
|
|
||||||
childBox.y2 = box.y2- box.y1;
|
|
||||||
this._controls.allocate(childBox, flags);
|
|
||||||
|
|
||||||
this._updateWorkspacesGeometry();
|
this._updateWorkspacesGeometry();
|
||||||
},
|
},
|
||||||
|
|
||||||
@@ -851,24 +725,15 @@ const WorkspacesDisplay = new Lang.Class({
|
|||||||
let width = fullWidth;
|
let width = fullWidth;
|
||||||
let height = fullHeight;
|
let height = fullHeight;
|
||||||
|
|
||||||
let [controlsMin, controlsNatural] = this._controls.get_preferred_width(height);
|
|
||||||
let controlsVisible = this._controls.get_theme_node().get_length('visible-width');
|
|
||||||
|
|
||||||
let [x, y] = this.actor.get_transformed_position();
|
let [x, y] = this.actor.get_transformed_position();
|
||||||
|
|
||||||
let rtl = (Clutter.get_default_text_direction () == Clutter.TextDirection.RTL);
|
let rtl = (Clutter.get_default_text_direction () == Clutter.TextDirection.RTL);
|
||||||
|
|
||||||
let clipWidth = width - controlsVisible;
|
let clipWidth = width;
|
||||||
let clipHeight = fullHeight;
|
let clipHeight = fullHeight;
|
||||||
let clipX = rtl ? x + controlsVisible : x;
|
let clipX = x;
|
||||||
let clipY = y + (fullHeight - clipHeight) / 2;
|
let clipY = y + (fullHeight - clipHeight) / 2;
|
||||||
|
|
||||||
let widthAdjust = this._zoomOut ? controlsNatural : controlsVisible;
|
|
||||||
widthAdjust += Main.overview._spacing;
|
|
||||||
width -= widthAdjust;
|
|
||||||
if (rtl)
|
|
||||||
x += widthAdjust;
|
|
||||||
|
|
||||||
let monitors = Main.layoutManager.monitors;
|
let monitors = Main.layoutManager.monitors;
|
||||||
let m = 0;
|
let m = 0;
|
||||||
for (let i = 0; i < monitors.length; i++) {
|
for (let i = 0; i < monitors.length; i++) {
|
||||||
@@ -891,25 +756,12 @@ const WorkspacesDisplay = new Lang.Class({
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
_onRestacked: function() {
|
_onRestacked: function(actor, stackIndices) {
|
||||||
let stack = global.get_window_actors();
|
|
||||||
let stackIndices = {};
|
|
||||||
|
|
||||||
for (let i = 0; i < stack.length; i++) {
|
|
||||||
// Use the stable sequence for an integer to use as a hash key
|
|
||||||
stackIndices[stack[i].get_meta_window().get_stable_sequence()] = i;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (let i = 0; i < this._workspacesViews.length; i++)
|
for (let i = 0; i < this._workspacesViews.length; i++)
|
||||||
this._workspacesViews[i].syncStacking(stackIndices);
|
this._workspacesViews[i].syncStacking(stackIndices);
|
||||||
|
|
||||||
this._thumbnailsBox.syncStacking(stackIndices);
|
|
||||||
},
|
},
|
||||||
|
|
||||||
_workspacesChanged: function() {
|
_workspacesChanged: function() {
|
||||||
this._updateAlwaysZoom();
|
|
||||||
this._updateZoom();
|
|
||||||
|
|
||||||
if (this._workspacesViews == null)
|
if (this._workspacesViews == null)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@@ -934,8 +786,6 @@ const WorkspacesDisplay = new Lang.Class({
|
|||||||
}
|
}
|
||||||
m++;
|
m++;
|
||||||
}
|
}
|
||||||
|
|
||||||
this._thumbnailsBox.addThumbnails(oldNumWorkspaces, newNumWorkspaces - oldNumWorkspaces);
|
|
||||||
} else {
|
} else {
|
||||||
// Assume workspaces are only removed sequentially
|
// Assume workspaces are only removed sequentially
|
||||||
// (e.g. 2,3,4 - not 2,4,7)
|
// (e.g. 2,3,4 - not 2,4,7)
|
||||||
@@ -958,8 +808,6 @@ const WorkspacesDisplay = new Lang.Class({
|
|||||||
lostWorkspaces[l].destroy();
|
lostWorkspaces[l].destroy();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
this._thumbnailsBox.removeThumbnails(removedIndex, removedNum);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for (let i = 0; i < this._workspacesViews.length; i++)
|
for (let i = 0; i < this._workspacesViews.length; i++)
|
||||||
@@ -968,35 +816,6 @@ const WorkspacesDisplay = new Lang.Class({
|
|||||||
this._updateSwitcherVisibility();
|
this._updateSwitcherVisibility();
|
||||||
},
|
},
|
||||||
|
|
||||||
_updateZoom : function() {
|
|
||||||
if (Main.overview.animationInProgress)
|
|
||||||
return;
|
|
||||||
|
|
||||||
let shouldZoom = this._alwaysZoomOut || this._controls.hover;
|
|
||||||
if (shouldZoom != this._zoomOut) {
|
|
||||||
this._zoomOut = shouldZoom;
|
|
||||||
this._updateWorkspacesGeometry();
|
|
||||||
|
|
||||||
if (!this._workspacesViews)
|
|
||||||
return;
|
|
||||||
|
|
||||||
Tweener.addTween(this,
|
|
||||||
{ zoomFraction: this._zoomOut ? 1 : 0,
|
|
||||||
time: WORKSPACE_SWITCH_TIME,
|
|
||||||
transition: 'easeOutQuad' });
|
|
||||||
|
|
||||||
for (let i = 0; i < this._workspacesViews.length; i++)
|
|
||||||
this._workspacesViews[i].updateWindowPositions();
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
_onControlsHoverChanged: function() {
|
|
||||||
if(!this._controls.hover)
|
|
||||||
this._controlsInitiallyHovered = false;
|
|
||||||
if(!this._controlsInitiallyHovered)
|
|
||||||
this._updateZoom();
|
|
||||||
},
|
|
||||||
|
|
||||||
_dragBegin: function() {
|
_dragBegin: function() {
|
||||||
this._inDrag = true;
|
this._inDrag = true;
|
||||||
this._cancelledDrag = false;
|
this._cancelledDrag = false;
|
||||||
@@ -1012,33 +831,11 @@ const WorkspacesDisplay = new Lang.Class({
|
|||||||
},
|
},
|
||||||
|
|
||||||
_onDragMotion: function(dragEvent) {
|
_onDragMotion: function(dragEvent) {
|
||||||
let controlsHovered = this._controls.contains(dragEvent.targetActor);
|
|
||||||
this._controls.set_hover(controlsHovered);
|
|
||||||
|
|
||||||
return DND.DragMotionResult.CONTINUE;
|
return DND.DragMotionResult.CONTINUE;
|
||||||
},
|
},
|
||||||
|
|
||||||
_dragEnd: function() {
|
_dragEnd: function() {
|
||||||
this._inDrag = false;
|
this._inDrag = false;
|
||||||
|
|
||||||
// We do this deferred because drag-end is emitted before dnd.js emits
|
|
||||||
// event/leave events that were suppressed during the drag. If we didn't
|
|
||||||
// defer this, we'd zoom out then immediately zoom in because of the
|
|
||||||
// enter event we received. That would normally be invisible but we
|
|
||||||
// might as well avoid it.
|
|
||||||
Meta.later_add(Meta.LaterType.BEFORE_REDRAW,
|
|
||||||
Lang.bind(this, this._updateZoom));
|
|
||||||
},
|
|
||||||
|
|
||||||
_onScrollEvent: function (actor, event) {
|
|
||||||
switch ( event.get_scroll_direction() ) {
|
|
||||||
case Clutter.ScrollDirection.UP:
|
|
||||||
Main.wm.actionMoveWorkspace(Meta.MotionDirection.UP);
|
|
||||||
break;
|
|
||||||
case Clutter.ScrollDirection.DOWN:
|
|
||||||
Main.wm.actionMoveWorkspace(Meta.MotionDirection.DOWN);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
Signals.addSignalMethods(WorkspacesDisplay.prototype);
|
Signals.addSignalMethods(WorkspacesDisplay.prototype);
|
||||||
|
30
tests/interactive/center-layout.js
Normal file
30
tests/interactive/center-layout.js
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
|
||||||
|
|
||||||
|
const Clutter = imports.gi.Clutter;
|
||||||
|
const St = imports.gi.St;
|
||||||
|
|
||||||
|
const CenterLayout = imports.ui.centerLayout;
|
||||||
|
const UI = imports.testcommon.ui;
|
||||||
|
|
||||||
|
function test() {
|
||||||
|
let stage = new Clutter.Stage({ user_resizable: true });
|
||||||
|
UI.init(stage);
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
let container = new St.Widget({ style: 'border: 2px solid black;',
|
||||||
|
layout_manager: new CenterLayout.CenterLayout() });
|
||||||
|
container.add_constraint(new Clutter.BindConstraint({ coordinate: Clutter.BindCoordinate.SIZE, source: stage }));
|
||||||
|
stage.add_actor(container);
|
||||||
|
|
||||||
|
let left = new Clutter.Actor({ background_color: Clutter.Color.get_static(Clutter.StaticColor.RED), width: 300 });
|
||||||
|
let center = new Clutter.Actor({ background_color: Clutter.Color.get_static(Clutter.StaticColor.BLUE), width: 100 });
|
||||||
|
let right = new Clutter.Actor({ background_color: Clutter.Color.get_static(Clutter.StaticColor.YELLOW), width: 200 });
|
||||||
|
|
||||||
|
container.add_actor(left);
|
||||||
|
container.add_actor(center);
|
||||||
|
container.add_actor(right);
|
||||||
|
|
||||||
|
UI.main(stage);
|
||||||
|
}
|
||||||
|
test();
|
Reference in New Issue
Block a user