Compare commits
79 Commits
citadel
...
wip/rstrod
Author | SHA1 | Date | |
---|---|---|---|
|
5f571b8531 | ||
|
f4fd379bd6 | ||
|
b9a4340bc8 | ||
|
63b622ccea | ||
|
0ad02321de | ||
|
e55aacaa10 | ||
|
ed1a8c582d | ||
|
99b40d8eaa | ||
|
fd36bbbc10 | ||
|
b301d0582a | ||
|
26589af153 | ||
|
15aaf1a455 | ||
|
c227be4325 | ||
|
6622fae6bd | ||
|
2f24e0701e | ||
|
72e2936f20 | ||
|
a77b7447d7 | ||
|
b5e7e91c78 | ||
|
8331a68ae3 | ||
|
bb2764dc69 | ||
|
0e7c424e50 | ||
|
219adb4510 | ||
|
3f221c28a1 | ||
|
2effcfcc7d | ||
|
deb2e8bc39 | ||
|
608937cb98 | ||
|
d727fe3eeb | ||
|
a52390187b | ||
|
d376b829b4 | ||
|
e11404d1cf | ||
|
585cf9c17d | ||
|
503a9d729c | ||
|
04ea89d683 | ||
|
1220e0124a | ||
|
7d9a39c72c | ||
|
b474ea0b7c | ||
|
d4b211bd23 | ||
|
98e4af9712 | ||
|
c7665b87a6 | ||
|
f7b47666b2 | ||
|
241585479b | ||
|
31612927b2 | ||
|
65229b6299 | ||
|
53f1d46fb5 | ||
|
04d526e9f5 | ||
|
8593532801 | ||
|
1e0ec69c41 | ||
|
9a6054b6b7 | ||
|
54633cb1f6 | ||
|
a506d86139 | ||
|
6ed21e1ce0 | ||
|
9c51c87d8c | ||
|
db2245d60b | ||
|
f26cc3ac23 | ||
|
02c5b4b947 | ||
|
df57829ea1 | ||
|
da96408098 | ||
|
4b2e0247af | ||
|
2c617e5a3a | ||
|
4ff7e84c51 | ||
|
9f76b6e4a2 | ||
|
0ac0f7e85b | ||
|
73b00ff1a7 | ||
|
a52597ac5b | ||
|
9a2597f80b | ||
|
e1ed4b25e1 | ||
|
c70b18764b | ||
|
4398516520 | ||
|
220514d10e | ||
|
18312d9ccd | ||
|
234b1441e4 | ||
|
e909db5848 | ||
|
702338bc7d | ||
|
7c9dbc66d9 | ||
|
0d031dc20f | ||
|
b476e851b7 | ||
|
a27be6a540 | ||
|
4b6a57fabe | ||
|
92758890bb |
28
NEWS
28
NEWS
@ -1,3 +1,31 @@
|
|||||||
|
3.28.3
|
||||||
|
======
|
||||||
|
* Fix lagging pointer when zoomed [Daniel; #682013]
|
||||||
|
* Fix "Clear All" for calendar events [Florian; #325]
|
||||||
|
* Misc. bug fixes [Florian, Mario, Marco; #136, #214, #788931, #791233]
|
||||||
|
|
||||||
|
Contributors:
|
||||||
|
Carlos Garnacho, Florian Müllner, Mario Sanchez Prada, Joe Rabinoff,
|
||||||
|
Didier Roche, Marco Trevisan (Treviño), Daniel van Vugt
|
||||||
|
|
||||||
|
Translators:
|
||||||
|
Pieter Schalk Schoeman [af], Gun Chleoc [gd]
|
||||||
|
|
||||||
|
3.28.2
|
||||||
|
======
|
||||||
|
* Fix lock-up on cancelling polkit dialog [Florian; #221]
|
||||||
|
* Guard against untimely keyboard map changes [Carlos; #240]
|
||||||
|
* Fix blurriness of OSD under some resolutions [Silvère; #782011]
|
||||||
|
* Fix icons in search provider results [Florian; #249]
|
||||||
|
* Misc. bug fixes [Marco, Florian; #792687, #781471]
|
||||||
|
|
||||||
|
Contributors:
|
||||||
|
Carlos Garnacho, Silvère Latchurié, Florian Müllner, Mario Sanchez Prada,
|
||||||
|
Ray Strode, Marco Trevisan (Treviño)
|
||||||
|
|
||||||
|
Translators:
|
||||||
|
Stas Solovey [ru], Rafael Fontenelle [pt_BR]
|
||||||
|
|
||||||
3.28.1
|
3.28.1
|
||||||
======
|
======
|
||||||
* Fix compose characters in shell entries [Carlos; #115]
|
* Fix compose characters in shell entries [Carlos; #115]
|
||||||
|
@ -46,7 +46,8 @@ dbus_interfaces = [
|
|||||||
'org.gnome.Shell.Screencast.xml',
|
'org.gnome.Shell.Screencast.xml',
|
||||||
'org.gnome.Shell.Screenshot.xml',
|
'org.gnome.Shell.Screenshot.xml',
|
||||||
'org.gnome.ShellSearchProvider.xml',
|
'org.gnome.ShellSearchProvider.xml',
|
||||||
'org.gnome.ShellSearchProvider2.xml'
|
'org.gnome.ShellSearchProvider2.xml',
|
||||||
|
'org.gnome.Shell.Introspect.xml'
|
||||||
]
|
]
|
||||||
install_data(dbus_interfaces, install_dir: ifacedir)
|
install_data(dbus_interfaces, install_dir: ifacedir)
|
||||||
|
|
||||||
|
61
data/org.gnome.Shell.Introspect.xml
Normal file
61
data/org.gnome.Shell.Introspect.xml
Normal file
@ -0,0 +1,61 @@
|
|||||||
|
<!DOCTYPE node PUBLIC
|
||||||
|
'-//freedesktop//DTD D-BUS Object Introspection 1.0//EN'
|
||||||
|
'http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd'>
|
||||||
|
<node>
|
||||||
|
|
||||||
|
<!--
|
||||||
|
org.gnome.Shell.Introspect:
|
||||||
|
@short_description: Introspection interface
|
||||||
|
|
||||||
|
The interface used to introspect the state of Shell, such as running
|
||||||
|
applications, currently active application, etc.
|
||||||
|
-->
|
||||||
|
<interface name="org.gnome.Shell.Introspect">
|
||||||
|
|
||||||
|
<!--
|
||||||
|
RunningApplicationsChanged:
|
||||||
|
@short_description: Notifies when the running applications changes
|
||||||
|
-->
|
||||||
|
<signal name="RunningApplicationsChanged" />
|
||||||
|
|
||||||
|
<!--
|
||||||
|
GetRunningApplications:
|
||||||
|
@short_description: Retrieves the description of all running applications
|
||||||
|
|
||||||
|
Each application is associated by an application ID. The details of
|
||||||
|
each application consists of a varlist of keys and values. Available
|
||||||
|
keys are listed below.
|
||||||
|
|
||||||
|
'active-on-seats' - (as) list of seats the application is active on
|
||||||
|
(a seat only has at most one active
|
||||||
|
application)
|
||||||
|
-->
|
||||||
|
<method name="GetRunningApplications">
|
||||||
|
<arg name="apps" direction="out" type="a{sa{sv}}" />
|
||||||
|
</method>
|
||||||
|
|
||||||
|
<!--
|
||||||
|
GetWindows:
|
||||||
|
@short_description: Retrieves the current list of windows and their properties
|
||||||
|
|
||||||
|
A window is exposed as:
|
||||||
|
* t ID: unique ID of the window
|
||||||
|
* a{sv} properties: high-level properties
|
||||||
|
|
||||||
|
Known properties:
|
||||||
|
|
||||||
|
- "title" (s): (readonly) title of the window
|
||||||
|
- "app-id" (s): (readonly) application ID of the window
|
||||||
|
- "wm-class" (s): (readonly) class of the window
|
||||||
|
- "client-type" (u): (readonly) 0 for Wayland, 1 for X11
|
||||||
|
- "is-hidden" (b): (readonly) if the window is currently hidden
|
||||||
|
- "has-focus" (b): (readonly) if the window currently have
|
||||||
|
keyboard focus
|
||||||
|
- "width" (u): (readonly) width of the window
|
||||||
|
- "height" (u): (readonly) height of the window
|
||||||
|
-->
|
||||||
|
<method name="GetWindows">
|
||||||
|
<arg name="windows" direction="out" type="a{ta{sv}}" />
|
||||||
|
</method>
|
||||||
|
</interface>
|
||||||
|
</node>
|
@ -39,7 +39,7 @@
|
|||||||
</description>
|
</description>
|
||||||
</key>
|
</key>
|
||||||
<key name="favorite-apps" type="as">
|
<key name="favorite-apps" type="as">
|
||||||
<default>[ 'epiphany.desktop', 'evolution.desktop', 'rhythmbox.desktop', 'shotwell.desktop', 'org.gnome.Nautilus.desktop', 'org.gnome.Software.desktop' ]</default>
|
<default>[ 'firefox.desktop', 'evolution.desktop', 'rhythmbox.desktop', 'shotwell.desktop', 'org.gnome.Nautilus.desktop', 'org.gnome.Software.desktop', 'yelp.desktop', 'gnome-terminal.desktop' ]</default>
|
||||||
<summary>List of desktop file IDs for favorite applications</summary>
|
<summary>List of desktop file IDs for favorite applications</summary>
|
||||||
<description>
|
<description>
|
||||||
The applications corresponding to these identifiers
|
The applications corresponding to these identifiers
|
||||||
@ -90,6 +90,14 @@
|
|||||||
adapter is ever seen not to have devices associated to it.
|
adapter is ever seen not to have devices associated to it.
|
||||||
</description>
|
</description>
|
||||||
</key>
|
</key>
|
||||||
|
<key name="introspect" type="b">
|
||||||
|
<default>false</default>
|
||||||
|
<summary>Enable introspection API</summary>
|
||||||
|
<description>
|
||||||
|
Enables a D-Bus API that allows to introspect the application state of
|
||||||
|
the shell.
|
||||||
|
</description>
|
||||||
|
</key>
|
||||||
<child name="keybindings" schema="org.gnome.shell.keybindings"/>
|
<child name="keybindings" schema="org.gnome.shell.keybindings"/>
|
||||||
<child name="keyboard" schema="org.gnome.shell.keyboard"/>
|
<child name="keyboard" schema="org.gnome.shell.keyboard"/>
|
||||||
</schema>
|
</schema>
|
||||||
|
@ -776,6 +776,11 @@ StScrollBar {
|
|||||||
//dimensions of the icon are hardcoded
|
//dimensions of the icon are hardcoded
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.panel-logo-icon {
|
||||||
|
padding-right: .4em;
|
||||||
|
icon-size: 1em;
|
||||||
|
}
|
||||||
|
|
||||||
.system-status-icon,
|
.system-status-icon,
|
||||||
.app-menu-icon > StIcon,
|
.app-menu-icon > StIcon,
|
||||||
.popup-menu-arrow {
|
.popup-menu-arrow {
|
||||||
@ -824,6 +829,8 @@ StScrollBar {
|
|||||||
|
|
||||||
.screencast-indicator { color: $warning_color; }
|
.screencast-indicator { color: $warning_color; }
|
||||||
|
|
||||||
|
.remote-access-indicator { color: $warning_color; }
|
||||||
|
|
||||||
&.solid {
|
&.solid {
|
||||||
background-color: black;
|
background-color: black;
|
||||||
/* transition from transparent to solid */
|
/* transition from transparent to solid */
|
||||||
@ -1397,6 +1404,14 @@ StScrollBar {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.app-well-hover-text {
|
||||||
|
text-align: center;
|
||||||
|
color: $osd_fg_color;
|
||||||
|
background-color: $osd_bg_color;
|
||||||
|
border-radius: 5px;
|
||||||
|
padding: 3px;
|
||||||
|
}
|
||||||
|
|
||||||
.app-well-app-running-dot { //running apps indicator
|
.app-well-app-running-dot { //running apps indicator
|
||||||
width: 10px; height: 3px;
|
width: 10px; height: 3px;
|
||||||
background-color: $selected_bg_color;
|
background-color: $selected_bg_color;
|
||||||
@ -1769,7 +1784,12 @@ StScrollBar {
|
|||||||
.login-dialog-banner { color: darken($osd_fg_color,10%); }
|
.login-dialog-banner { color: darken($osd_fg_color,10%); }
|
||||||
.login-dialog-button-box { spacing: 5px; }
|
.login-dialog-button-box { spacing: 5px; }
|
||||||
.login-dialog-message-warning { color: $warning_color; }
|
.login-dialog-message-warning { color: $warning_color; }
|
||||||
.login-dialog-message-hint { padding-top: 0; padding-bottom: 20px; }
|
.login-dialog-message-hint, .login-dialog-message {
|
||||||
|
color: darken($osd_fg_color, 20%);
|
||||||
|
padding-top: 0;
|
||||||
|
padding-bottom: 20px;
|
||||||
|
min-height: 2.75em;
|
||||||
|
}
|
||||||
.login-dialog-user-selection-box { padding: 100px 0px; }
|
.login-dialog-user-selection-box { padding: 100px 0px; }
|
||||||
.login-dialog-not-listed-label {
|
.login-dialog-not-listed-label {
|
||||||
padding-left: 2px;
|
padding-left: 2px;
|
||||||
@ -1825,6 +1845,10 @@ StScrollBar {
|
|||||||
padding-bottom: 12px;
|
padding-bottom: 12px;
|
||||||
spacing: 8px;
|
spacing: 8px;
|
||||||
width: 23em;
|
width: 23em;
|
||||||
|
.login-dialog-timed-login-indicator {
|
||||||
|
height: 2px;
|
||||||
|
background-color: darken($fg_color,40%);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.login-dialog-prompt-label {
|
.login-dialog-prompt-label {
|
||||||
|
@ -23,3 +23,5 @@ foreach style: styles
|
|||||||
],
|
],
|
||||||
depend_files: theme_sources)
|
depend_files: theme_sources)
|
||||||
endforeach
|
endforeach
|
||||||
|
|
||||||
|
install_data('process-working.svg', install_dir: themedir)
|
||||||
|
195
js/gdm/authList.js
Normal file
195
js/gdm/authList.js
Normal file
@ -0,0 +1,195 @@
|
|||||||
|
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
|
||||||
|
/*
|
||||||
|
* Copyright 2017 Red Hat, Inc
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2, or (at your option)
|
||||||
|
* any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
const Clutter = imports.gi.Clutter;
|
||||||
|
const GObject = imports.gi.GObject;
|
||||||
|
const Gtk = imports.gi.Gtk;
|
||||||
|
const Lang = imports.lang;
|
||||||
|
const Meta = imports.gi.Meta;
|
||||||
|
const Signals = imports.signals;
|
||||||
|
const St = imports.gi.St;
|
||||||
|
|
||||||
|
const Tweener = imports.ui.tweener;
|
||||||
|
|
||||||
|
const _SCROLL_ANIMATION_TIME = 0.5;
|
||||||
|
|
||||||
|
const AuthListItem = new Lang.Class({
|
||||||
|
Name: 'AuthListItem',
|
||||||
|
|
||||||
|
_init(key, text) {
|
||||||
|
this.key = key;
|
||||||
|
let label = new St.Label({ style_class: 'auth-list-item-label',
|
||||||
|
y_align: Clutter.ActorAlign.CENTER });
|
||||||
|
label.text = text;
|
||||||
|
|
||||||
|
this.actor = new St.Button({ style_class: 'login-dialog-user-list-item',
|
||||||
|
button_mask: St.ButtonMask.ONE | St.ButtonMask.THREE,
|
||||||
|
can_focus: true,
|
||||||
|
child: label,
|
||||||
|
reactive: true,
|
||||||
|
x_align: St.Align.START,
|
||||||
|
x_fill: true });
|
||||||
|
|
||||||
|
this.actor.connect('key-focus-in', () => {
|
||||||
|
this._setSelected(true);
|
||||||
|
});
|
||||||
|
this.actor.connect('key-focus-out', () => {
|
||||||
|
this._setSelected(false);
|
||||||
|
});
|
||||||
|
this.actor.connect('notify::hover', () => {
|
||||||
|
this._setSelected(this.actor.hover);
|
||||||
|
});
|
||||||
|
|
||||||
|
this.actor.connect('clicked', this._onClicked.bind(this));
|
||||||
|
},
|
||||||
|
|
||||||
|
_onClicked() {
|
||||||
|
this.emit('activate');
|
||||||
|
},
|
||||||
|
|
||||||
|
_setSelected(selected) {
|
||||||
|
if (selected) {
|
||||||
|
this.actor.add_style_pseudo_class('selected');
|
||||||
|
this.actor.grab_key_focus();
|
||||||
|
} else {
|
||||||
|
this.actor.remove_style_pseudo_class('selected');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
Signals.addSignalMethods(AuthListItem.prototype);
|
||||||
|
|
||||||
|
const AuthList = new Lang.Class({
|
||||||
|
Name: 'AuthList',
|
||||||
|
|
||||||
|
_init() {
|
||||||
|
this.actor = new St.BoxLayout({ vertical: true,
|
||||||
|
style_class: 'login-dialog-auth-list-layout' });
|
||||||
|
|
||||||
|
this.label = new St.Label({ style_class: 'prompt-dialog-headline' });
|
||||||
|
this.actor.add_actor(this.label);
|
||||||
|
|
||||||
|
this._scrollView = new St.ScrollView({ style_class: 'login-dialog-user-list-view'});
|
||||||
|
this._scrollView.set_policy(Gtk.PolicyType.NEVER,
|
||||||
|
Gtk.PolicyType.AUTOMATIC);
|
||||||
|
this.actor.add_actor(this._scrollView);
|
||||||
|
|
||||||
|
this._box = new St.BoxLayout({ vertical: true,
|
||||||
|
style_class: 'login-dialog-user-list',
|
||||||
|
pseudo_class: 'expanded' });
|
||||||
|
|
||||||
|
this._scrollView.add_actor(this._box);
|
||||||
|
this._items = {};
|
||||||
|
|
||||||
|
this.actor.connect('key-focus-in', this._moveFocusToItems.bind(this));
|
||||||
|
},
|
||||||
|
|
||||||
|
_moveFocusToItems() {
|
||||||
|
let hasItems = Object.keys(this._items).length > 0;
|
||||||
|
|
||||||
|
if (!hasItems)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (global.stage.get_key_focus() != this.actor)
|
||||||
|
return;
|
||||||
|
|
||||||
|
let focusSet = this.actor.navigate_focus(null, Gtk.DirectionType.TAB_FORWARD, false);
|
||||||
|
if (!focusSet) {
|
||||||
|
Meta.later_add(Meta.LaterType.BEFORE_REDRAW, () => {
|
||||||
|
this._moveFocusToItems();
|
||||||
|
return false;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
_onItemActivated(activatedItem) {
|
||||||
|
this.emit('activate', activatedItem.key);
|
||||||
|
},
|
||||||
|
|
||||||
|
scrollToItem(item) {
|
||||||
|
let box = item.actor.get_allocation_box();
|
||||||
|
|
||||||
|
let adjustment = this._scrollView.get_vscroll_bar().get_adjustment();
|
||||||
|
|
||||||
|
let value = (box.y1 + adjustment.step_increment / 2.0) - (adjustment.page_size / 2.0);
|
||||||
|
Tweener.removeTweens(adjustment);
|
||||||
|
Tweener.addTween (adjustment,
|
||||||
|
{ value: value,
|
||||||
|
time: _SCROLL_ANIMATION_TIME,
|
||||||
|
transition: 'easeOutQuad' });
|
||||||
|
},
|
||||||
|
|
||||||
|
jumpToItem(item) {
|
||||||
|
let box = item.actor.get_allocation_box();
|
||||||
|
|
||||||
|
let adjustment = this._scrollView.get_vscroll_bar().get_adjustment();
|
||||||
|
|
||||||
|
let value = (box.y1 + adjustment.step_increment / 2.0) - (adjustment.page_size / 2.0);
|
||||||
|
|
||||||
|
adjustment.set_value(value);
|
||||||
|
},
|
||||||
|
|
||||||
|
getItem(key) {
|
||||||
|
let item = this._items[key];
|
||||||
|
|
||||||
|
if (!item)
|
||||||
|
return null;
|
||||||
|
|
||||||
|
return item;
|
||||||
|
},
|
||||||
|
|
||||||
|
addItem(key, text) {
|
||||||
|
this.removeItem(key);
|
||||||
|
|
||||||
|
let item = new AuthListItem(key, text);
|
||||||
|
this._box.add(item.actor, { x_fill: true });
|
||||||
|
|
||||||
|
this._items[key] = item;
|
||||||
|
|
||||||
|
item.connect('activate',
|
||||||
|
this._onItemActivated.bind(this));
|
||||||
|
|
||||||
|
// Try to keep the focused item front-and-center
|
||||||
|
item.actor.connect('key-focus-in',
|
||||||
|
() => { this.scrollToItem(item); });
|
||||||
|
|
||||||
|
this._moveFocusToItems();
|
||||||
|
|
||||||
|
this.emit('item-added', item);
|
||||||
|
},
|
||||||
|
|
||||||
|
removeItem(key) {
|
||||||
|
let item = this._items[key];
|
||||||
|
|
||||||
|
if (!item)
|
||||||
|
return;
|
||||||
|
|
||||||
|
item.actor.destroy();
|
||||||
|
delete this._items[key];
|
||||||
|
},
|
||||||
|
|
||||||
|
numItems() {
|
||||||
|
return Object.keys(this._items).length;
|
||||||
|
},
|
||||||
|
|
||||||
|
clear() {
|
||||||
|
this.label.text = "";
|
||||||
|
this._box.destroy_all_children();
|
||||||
|
this._items = {};
|
||||||
|
}
|
||||||
|
});
|
||||||
|
Signals.addSignalMethods(AuthList.prototype);
|
@ -2,14 +2,17 @@
|
|||||||
|
|
||||||
const Clutter = imports.gi.Clutter;
|
const Clutter = imports.gi.Clutter;
|
||||||
const Gio = imports.gi.Gio;
|
const Gio = imports.gi.Gio;
|
||||||
|
const GLib = imports.gi.GLib;
|
||||||
const Lang = imports.lang;
|
const Lang = imports.lang;
|
||||||
const Pango = imports.gi.Pango;
|
const Pango = imports.gi.Pango;
|
||||||
const Signals = imports.signals;
|
const Signals = imports.signals;
|
||||||
const St = imports.gi.St;
|
const St = imports.gi.St;
|
||||||
|
|
||||||
const Animation = imports.ui.animation;
|
const Animation = imports.ui.animation;
|
||||||
|
const AuthList = imports.gdm.authList;
|
||||||
const Batch = imports.gdm.batch;
|
const Batch = imports.gdm.batch;
|
||||||
const GdmUtil = imports.gdm.util;
|
const GdmUtil = imports.gdm.util;
|
||||||
|
const Meta = imports.gi.Meta;
|
||||||
const Params = imports.misc.params;
|
const Params = imports.misc.params;
|
||||||
const ShellEntry = imports.ui.shellEntry;
|
const ShellEntry = imports.ui.shellEntry;
|
||||||
const Tweener = imports.ui.tweener;
|
const Tweener = imports.ui.tweener;
|
||||||
@ -47,6 +50,8 @@ var AuthPrompt = new Lang.Class({
|
|||||||
this._gdmClient = gdmClient;
|
this._gdmClient = gdmClient;
|
||||||
this._mode = mode;
|
this._mode = mode;
|
||||||
|
|
||||||
|
this._idleMonitor = Meta.IdleMonitor.get_core();
|
||||||
|
|
||||||
let reauthenticationOnly;
|
let reauthenticationOnly;
|
||||||
if (this._mode == AuthPromptMode.UNLOCK_ONLY)
|
if (this._mode == AuthPromptMode.UNLOCK_ONLY)
|
||||||
reauthenticationOnly = true;
|
reauthenticationOnly = true;
|
||||||
@ -57,6 +62,7 @@ var AuthPrompt = new Lang.Class({
|
|||||||
|
|
||||||
this._userVerifier.connect('ask-question', this._onAskQuestion.bind(this));
|
this._userVerifier.connect('ask-question', this._onAskQuestion.bind(this));
|
||||||
this._userVerifier.connect('show-message', this._onShowMessage.bind(this));
|
this._userVerifier.connect('show-message', this._onShowMessage.bind(this));
|
||||||
|
this._userVerifier.connect('show-choice-list', this._onShowChoiceList.bind(this));
|
||||||
this._userVerifier.connect('verification-failed', this._onVerificationFailed.bind(this));
|
this._userVerifier.connect('verification-failed', this._onVerificationFailed.bind(this));
|
||||||
this._userVerifier.connect('verification-complete', this._onVerificationComplete.bind(this));
|
this._userVerifier.connect('verification-complete', this._onVerificationComplete.bind(this));
|
||||||
this._userVerifier.connect('reset', this._onReset.bind(this));
|
this._userVerifier.connect('reset', this._onReset.bind(this));
|
||||||
@ -66,11 +72,16 @@ var AuthPrompt = new Lang.Class({
|
|||||||
|
|
||||||
this.connect('next', () => {
|
this.connect('next', () => {
|
||||||
this.updateSensitivity(false);
|
this.updateSensitivity(false);
|
||||||
this.startSpinning();
|
|
||||||
if (this._queryingService) {
|
if (this._queryingService) {
|
||||||
|
this.startSpinning();
|
||||||
this._userVerifier.answerQuery(this._queryingService, this._entry.text);
|
this._userVerifier.answerQuery(this._queryingService, this._entry.text);
|
||||||
} else {
|
} else {
|
||||||
this._preemptiveAnswer = this._entry.text;
|
this._preemptiveAnswer = this._entry.text;
|
||||||
|
|
||||||
|
if (this._preemptiveAnswerWatchId) {
|
||||||
|
this._idleMonitor.remove_watch(this._preemptiveAnswerWatchId);
|
||||||
|
this._preemptiveAnswerWatchId = 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -109,6 +120,33 @@ var AuthPrompt = new Lang.Class({
|
|||||||
|
|
||||||
this._entry.grab_key_focus();
|
this._entry.grab_key_focus();
|
||||||
|
|
||||||
|
this._timedLoginIndicator = new St.Bin({ style_class: 'login-dialog-timed-login-indicator',
|
||||||
|
scale_x: 0 });
|
||||||
|
|
||||||
|
this.actor.add(this._timedLoginIndicator);
|
||||||
|
|
||||||
|
this._authList = new AuthList.AuthList();
|
||||||
|
this._authList.connect('activate', (list, key) => {
|
||||||
|
this._authList.actor.reactive = false;
|
||||||
|
Tweener.addTween(this._authList.actor,
|
||||||
|
{ opacity: 0,
|
||||||
|
time: MESSAGE_FADE_OUT_ANIMATION_TIME,
|
||||||
|
transition: 'easeOutQuad',
|
||||||
|
onComplete: () => {
|
||||||
|
this._authList.clear();
|
||||||
|
this._authList.actor.hide();
|
||||||
|
this._userVerifier.selectChoice(this._queryingService, key);
|
||||||
|
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
this._authList.actor.hide();
|
||||||
|
this.actor.add(this._authList.actor,
|
||||||
|
{ expand: true,
|
||||||
|
x_fill: true,
|
||||||
|
y_fill: false,
|
||||||
|
x_align: St.Align.START });
|
||||||
|
|
||||||
this._message = new St.Label({ opacity: 0,
|
this._message = new St.Label({ opacity: 0,
|
||||||
styleClass: 'login-dialog-message' });
|
styleClass: 'login-dialog-message' });
|
||||||
this._message.clutter_text.line_wrap = true;
|
this._message.clutter_text.line_wrap = true;
|
||||||
@ -134,7 +172,46 @@ var AuthPrompt = new Lang.Class({
|
|||||||
this._defaultButtonWell.add_child(this._spinner.actor);
|
this._defaultButtonWell.add_child(this._spinner.actor);
|
||||||
},
|
},
|
||||||
|
|
||||||
|
showTimedLoginIndicator(time) {
|
||||||
|
let hold = new Batch.Hold();
|
||||||
|
|
||||||
|
this.hideTimedLoginIndicator();
|
||||||
|
|
||||||
|
let startTime = GLib.get_monotonic_time();
|
||||||
|
|
||||||
|
this._timedLoginTimeoutId = GLib.timeout_add (GLib.PRIORITY_DEFAULT, 33,
|
||||||
|
() => {
|
||||||
|
let currentTime = GLib.get_monotonic_time();
|
||||||
|
let elapsedTime = (currentTime - startTime) / GLib.USEC_PER_SEC;
|
||||||
|
this._timedLoginIndicator.scale_x = elapsedTime / time;
|
||||||
|
if (elapsedTime >= time) {
|
||||||
|
this._timedLoginTimeoutId = 0;
|
||||||
|
hold.release();
|
||||||
|
return GLib.SOURCE_REMOVE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return GLib.SOURCE_CONTINUE;
|
||||||
|
});
|
||||||
|
|
||||||
|
GLib.Source.set_name_by_id(this._timedLoginTimeoutId, '[gnome-shell] this._timedLoginTimeoutId');
|
||||||
|
|
||||||
|
return hold;
|
||||||
|
},
|
||||||
|
|
||||||
|
hideTimedLoginIndicator() {
|
||||||
|
if (this._timedLoginTimeoutId) {
|
||||||
|
GLib.source_remove(this._timedLoginTimeoutId);
|
||||||
|
this._timedLoginTimeoutId = 0;
|
||||||
|
}
|
||||||
|
this._timedLoginIndicator.scale_x = 0.;
|
||||||
|
},
|
||||||
|
|
||||||
_onDestroy() {
|
_onDestroy() {
|
||||||
|
if (this._preemptiveAnswerWatchId) {
|
||||||
|
this._idleMonitor.remove_watch(this._preemptiveAnswerWatchId);
|
||||||
|
this._preemptiveAnswerWatchId = 0;
|
||||||
|
}
|
||||||
|
|
||||||
this._userVerifier.destroy();
|
this._userVerifier.destroy();
|
||||||
this._userVerifier = null;
|
this._userVerifier = null;
|
||||||
},
|
},
|
||||||
@ -176,7 +253,7 @@ var AuthPrompt = new Lang.Class({
|
|||||||
this._updateNextButtonSensitivity(this._entry.text.length > 0);
|
this._updateNextButtonSensitivity(this._entry.text.length > 0);
|
||||||
|
|
||||||
this._entry.clutter_text.connect('text-changed', () => {
|
this._entry.clutter_text.connect('text-changed', () => {
|
||||||
if (!this._userVerifier.hasPendingMessages)
|
if (!this._userVerifier.hasPendingMessages && this._queryingService && !this._preemptiveAnswer)
|
||||||
this._fadeOutMessage();
|
this._fadeOutMessage();
|
||||||
|
|
||||||
this._updateNextButtonSensitivity(this._entry.text.length > 0 || this.verificationStatus == AuthPromptStatus.VERIFYING);
|
this._updateNextButtonSensitivity(this._entry.text.length > 0 || this.verificationStatus == AuthPromptStatus.VERIFYING);
|
||||||
@ -213,6 +290,21 @@ var AuthPrompt = new Lang.Class({
|
|||||||
this.emit('prompted');
|
this.emit('prompted');
|
||||||
},
|
},
|
||||||
|
|
||||||
|
_onShowChoiceList(userVerifier, serviceName, promptMessage, choiceList) {
|
||||||
|
if (this._queryingService)
|
||||||
|
this.clear();
|
||||||
|
|
||||||
|
this._queryingService = serviceName;
|
||||||
|
|
||||||
|
if (this._preemptiveAnswer)
|
||||||
|
this._preemptiveAnswer = null;
|
||||||
|
|
||||||
|
this.nextButton.label = _("Next");
|
||||||
|
this.setChoiceList(promptMessage, choiceList);
|
||||||
|
this.updateSensitivity(true);
|
||||||
|
this.emit('prompted');
|
||||||
|
},
|
||||||
|
|
||||||
_onOVirtUserAuthenticated() {
|
_onOVirtUserAuthenticated() {
|
||||||
if (this.verificationStatus != AuthPromptStatus.VERIFICATION_SUCCEEDED)
|
if (this.verificationStatus != AuthPromptStatus.VERIFICATION_SUCCEEDED)
|
||||||
this.reset();
|
this.reset();
|
||||||
@ -341,6 +433,8 @@ var AuthPrompt = new Lang.Class({
|
|||||||
clear() {
|
clear() {
|
||||||
this._entry.text = '';
|
this._entry.text = '';
|
||||||
this.stopSpinning();
|
this.stopSpinning();
|
||||||
|
this._authList.clear();
|
||||||
|
this._authList.actor.hide();
|
||||||
},
|
},
|
||||||
|
|
||||||
setPasswordChar(passwordChar) {
|
setPasswordChar(passwordChar) {
|
||||||
@ -349,14 +443,49 @@ var AuthPrompt = new Lang.Class({
|
|||||||
},
|
},
|
||||||
|
|
||||||
setQuestion(question) {
|
setQuestion(question) {
|
||||||
|
if (this._preemptiveAnswerWatchId) {
|
||||||
|
this._idleMonitor.remove_watch(this._preemptiveAnswerWatchId);
|
||||||
|
this._preemptiveAnswerWatchId = 0;
|
||||||
|
}
|
||||||
|
|
||||||
this._label.set_text(question);
|
this._label.set_text(question);
|
||||||
|
|
||||||
|
this._authList.actor.hide();
|
||||||
this._label.show();
|
this._label.show();
|
||||||
this._entry.show();
|
this._entry.show();
|
||||||
|
|
||||||
this._entry.grab_key_focus();
|
this._entry.grab_key_focus();
|
||||||
},
|
},
|
||||||
|
|
||||||
|
_fadeInChoiceList() {
|
||||||
|
this._authList.actor.opacity = 0;
|
||||||
|
this._authList.actor.show();
|
||||||
|
this._authList.actor.reactive = false;
|
||||||
|
Tweener.addTween(this._authList.actor,
|
||||||
|
{ opacity: 255,
|
||||||
|
time: MESSAGE_FADE_OUT_ANIMATION_TIME,
|
||||||
|
transition: 'easeOutQuad',
|
||||||
|
onComplete: () => {
|
||||||
|
this._authList.actor.reactive = true;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
setChoiceList(promptMessage, choiceList) {
|
||||||
|
this._authList.clear();
|
||||||
|
this._authList.label.text = promptMessage;
|
||||||
|
for (let key in choiceList) {
|
||||||
|
let text = choiceList[key];
|
||||||
|
this._authList.addItem(key, text);
|
||||||
|
}
|
||||||
|
|
||||||
|
this._label.hide();
|
||||||
|
this._entry.hide();
|
||||||
|
if (this._message.text == "")
|
||||||
|
this._message.hide();
|
||||||
|
this._fadeInChoiceList();
|
||||||
|
},
|
||||||
|
|
||||||
getAnswer() {
|
getAnswer() {
|
||||||
let text;
|
let text;
|
||||||
|
|
||||||
@ -392,6 +521,7 @@ var AuthPrompt = new Lang.Class({
|
|||||||
else
|
else
|
||||||
this._message.remove_style_class_name('login-dialog-message-hint');
|
this._message.remove_style_class_name('login-dialog-message-hint');
|
||||||
|
|
||||||
|
this._message.show();
|
||||||
if (message) {
|
if (message) {
|
||||||
Tweener.removeTweens(this._message);
|
Tweener.removeTweens(this._message);
|
||||||
this._message.text = message;
|
this._message.text = message;
|
||||||
@ -407,7 +537,7 @@ var AuthPrompt = new Lang.Class({
|
|||||||
},
|
},
|
||||||
|
|
||||||
updateSensitivity(sensitive) {
|
updateSensitivity(sensitive) {
|
||||||
this._updateNextButtonSensitivity(sensitive && (this._entry.text.length > 0 || this.verificationStatus == AuthPromptStatus.VERIFYING));
|
this._updateNextButtonSensitivity(sensitive && !this._authList.actor.visible && (this._entry.text.length > 0 || this.verificationStatus == AuthPromptStatus.VERIFYING));
|
||||||
this._entry.reactive = sensitive;
|
this._entry.reactive = sensitive;
|
||||||
this._entry.clutter_text.editable = sensitive;
|
this._entry.clutter_text.editable = sensitive;
|
||||||
},
|
},
|
||||||
@ -434,12 +564,31 @@ var AuthPrompt = new Lang.Class({
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
_onUserStoppedTypePreemptiveAnswer() {
|
||||||
|
if (!this._preemptiveAnswerWatchId ||
|
||||||
|
this._preemptiveAnswer ||
|
||||||
|
this._queryingService)
|
||||||
|
return;
|
||||||
|
|
||||||
|
this._idleMonitor.remove_watch(this._preemptiveAnswerWatchId);
|
||||||
|
this._preemptiveAnswerWatchId = 0;
|
||||||
|
|
||||||
|
this._entry.text = '';
|
||||||
|
this.updateSensitivity(false);
|
||||||
|
},
|
||||||
|
|
||||||
reset() {
|
reset() {
|
||||||
let oldStatus = this.verificationStatus;
|
let oldStatus = this.verificationStatus;
|
||||||
this.verificationStatus = AuthPromptStatus.NOT_VERIFYING;
|
this.verificationStatus = AuthPromptStatus.NOT_VERIFYING;
|
||||||
this.cancelButton.reactive = true;
|
this.cancelButton.reactive = true;
|
||||||
this.nextButton.label = _("Next");
|
this.nextButton.label = _("Next");
|
||||||
|
|
||||||
|
if (this._preemptiveAnswerWatchId) {
|
||||||
|
this._idleMonitor.remove_watch(this._preemptiveAnswerWatchId);
|
||||||
|
}
|
||||||
|
this._preemptiveAnswerWatchId = this._idleMonitor.add_idle_watch (500,
|
||||||
|
this._onUserStoppedTypePreemptiveAnswer.bind(this));
|
||||||
|
|
||||||
if (this._userVerifier)
|
if (this._userVerifier)
|
||||||
this._userVerifier.cancel();
|
this._userVerifier.cancel();
|
||||||
|
|
||||||
|
@ -418,6 +418,11 @@ var LoginDialog = new Lang.Class({
|
|||||||
this._userManager = AccountsService.UserManager.get_default()
|
this._userManager = AccountsService.UserManager.get_default()
|
||||||
this._gdmClient = new Gdm.Client();
|
this._gdmClient = new Gdm.Client();
|
||||||
|
|
||||||
|
try {
|
||||||
|
this._gdmClient.set_enabled_extensions([Gdm.UserVerifierChoiceList.interface_info().name]);
|
||||||
|
} catch(e) {
|
||||||
|
}
|
||||||
|
|
||||||
this._settings = new Gio.Settings({ schema_id: GdmUtil.LOGIN_SCREEN_SCHEMA });
|
this._settings = new Gio.Settings({ schema_id: GdmUtil.LOGIN_SCREEN_SCHEMA });
|
||||||
|
|
||||||
this._settings.connect('changed::' + GdmUtil.BANNER_MESSAGE_KEY,
|
this._settings.connect('changed::' + GdmUtil.BANNER_MESSAGE_KEY,
|
||||||
@ -738,6 +743,9 @@ var LoginDialog = new Lang.Class({
|
|||||||
|
|
||||||
if (this._authPrompt.verificationStatus == AuthPrompt.AuthPromptStatus.NOT_VERIFYING)
|
if (this._authPrompt.verificationStatus == AuthPrompt.AuthPromptStatus.NOT_VERIFYING)
|
||||||
this._authPrompt.reset();
|
this._authPrompt.reset();
|
||||||
|
|
||||||
|
if (this._disableUserList && this._timedLoginUserListHold)
|
||||||
|
this._timedLoginUserListHold.release();
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -1019,17 +1027,33 @@ var LoginDialog = new Lang.Class({
|
|||||||
},
|
},
|
||||||
|
|
||||||
_startTimedLogin(userName, delay) {
|
_startTimedLogin(userName, delay) {
|
||||||
|
this._timedLoginUserName = userName;
|
||||||
this._timedLoginItem = null;
|
this._timedLoginItem = null;
|
||||||
this._timedLoginDelay = delay;
|
this._timedLoginDelay = delay;
|
||||||
this._timedLoginAnimationTime = delay;
|
this._timedLoginAnimationTime = delay;
|
||||||
|
|
||||||
let tasks = [() => this._waitForItemForUser(userName),
|
let tasks = [() => {
|
||||||
|
if (this._disableUserList)
|
||||||
|
return;
|
||||||
|
|
||||||
|
this._timedLoginUserListHold = this._waitForItemForUser(userName);
|
||||||
|
|
||||||
|
return this._timedLoginUserListHold;
|
||||||
|
},
|
||||||
|
|
||||||
() => {
|
() => {
|
||||||
|
this._timedLoginUserListHold = null;
|
||||||
|
|
||||||
|
if (this._disableUserList)
|
||||||
|
return;
|
||||||
|
|
||||||
this._timedLoginItem = this._userList.getItemFromUserName(userName);
|
this._timedLoginItem = this._userList.getItemFromUserName(userName);
|
||||||
},
|
},
|
||||||
|
|
||||||
() => {
|
() => {
|
||||||
|
if (this._disableUserList)
|
||||||
|
return;
|
||||||
|
|
||||||
// If we're just starting out, start on the right
|
// If we're just starting out, start on the right
|
||||||
// item.
|
// item.
|
||||||
if (!this._userManager.is_loaded) {
|
if (!this._userManager.is_loaded) {
|
||||||
@ -1040,6 +1064,9 @@ var LoginDialog = new Lang.Class({
|
|||||||
this._blockTimedLoginUntilIdle,
|
this._blockTimedLoginUntilIdle,
|
||||||
|
|
||||||
() => {
|
() => {
|
||||||
|
if (this._disableUserList)
|
||||||
|
return;
|
||||||
|
|
||||||
this._userList.scrollToItem(this._timedLoginItem);
|
this._userList.scrollToItem(this._timedLoginItem);
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -1064,7 +1091,9 @@ var LoginDialog = new Lang.Class({
|
|||||||
if (this._timedLoginItem)
|
if (this._timedLoginItem)
|
||||||
this._timedLoginItem.hideTimedLoginIndicator();
|
this._timedLoginItem.hideTimedLoginIndicator();
|
||||||
|
|
||||||
let userName = this._timedLoginItem.user.get_user_name();
|
this._authPrompt.hideTimedLoginIndicator();
|
||||||
|
|
||||||
|
let userName = this._timedLoginUserName;
|
||||||
|
|
||||||
if (userName)
|
if (userName)
|
||||||
this._startTimedLogin(userName, this._timedLoginDelay);
|
this._startTimedLogin(userName, this._timedLoginDelay);
|
||||||
|
@ -134,7 +134,6 @@ var ShellUserVerifier = new Lang.Class({
|
|||||||
this._settings = new Gio.Settings({ schema_id: LOGIN_SCREEN_SCHEMA });
|
this._settings = new Gio.Settings({ schema_id: LOGIN_SCREEN_SCHEMA });
|
||||||
this._settings.connect('changed',
|
this._settings.connect('changed',
|
||||||
this._updateDefaultService.bind(this));
|
this._updateDefaultService.bind(this));
|
||||||
this._updateDefaultService();
|
|
||||||
|
|
||||||
this._fprintManager = Fprint.FprintManager();
|
this._fprintManager = Fprint.FprintManager();
|
||||||
this._smartcardManager = SmartcardManager.getSmartcardManager();
|
this._smartcardManager = SmartcardManager.getSmartcardManager();
|
||||||
@ -146,6 +145,8 @@ var ShellUserVerifier = new Lang.Class({
|
|||||||
this.smartcardDetected = false;
|
this.smartcardDetected = false;
|
||||||
this._checkForSmartcard();
|
this._checkForSmartcard();
|
||||||
|
|
||||||
|
this._updateDefaultService();
|
||||||
|
|
||||||
this._smartcardInsertedId = this._smartcardManager.connect('smartcard-inserted',
|
this._smartcardInsertedId = this._smartcardManager.connect('smartcard-inserted',
|
||||||
this._checkForSmartcard.bind(this));
|
this._checkForSmartcard.bind(this));
|
||||||
this._smartcardRemovedId = this._smartcardManager.connect('smartcard-removed',
|
this._smartcardRemovedId = this._smartcardManager.connect('smartcard-removed',
|
||||||
@ -199,6 +200,10 @@ var ShellUserVerifier = new Lang.Class({
|
|||||||
if (this._userVerifier) {
|
if (this._userVerifier) {
|
||||||
this._userVerifier.run_dispose();
|
this._userVerifier.run_dispose();
|
||||||
this._userVerifier = null;
|
this._userVerifier = null;
|
||||||
|
if (this._userVerifierChoiceList) {
|
||||||
|
this._userVerifierChoiceList.run_dispose();
|
||||||
|
this._userVerifierChoiceList = null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -226,6 +231,10 @@ var ShellUserVerifier = new Lang.Class({
|
|||||||
this._oVirtCredentialsManager = null;
|
this._oVirtCredentialsManager = null;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
selectChoice(serviceName, key) {
|
||||||
|
this._userVerifierChoiceList.call_select_choice(serviceName, key, this._cancellable, null);
|
||||||
|
},
|
||||||
|
|
||||||
answerQuery(serviceName, answer) {
|
answerQuery(serviceName, answer) {
|
||||||
if (!this.hasPendingMessages) {
|
if (!this.hasPendingMessages) {
|
||||||
this._userVerifier.call_answer_query(serviceName, answer, this._cancellable, null);
|
this._userVerifier.call_answer_query(serviceName, answer, this._cancellable, null);
|
||||||
@ -334,6 +343,8 @@ var ShellUserVerifier = new Lang.Class({
|
|||||||
else if (this._preemptingService == SMARTCARD_SERVICE_NAME)
|
else if (this._preemptingService == SMARTCARD_SERVICE_NAME)
|
||||||
this._preemptingService = null;
|
this._preemptingService = null;
|
||||||
|
|
||||||
|
this._updateDefaultService();
|
||||||
|
|
||||||
this.emit('smartcard-status-changed');
|
this.emit('smartcard-status-changed');
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -364,6 +375,11 @@ var ShellUserVerifier = new Lang.Class({
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (client.get_user_verifier_choice_list)
|
||||||
|
this._userVerifierChoiceList = client.get_user_verifier_choice_list();
|
||||||
|
else
|
||||||
|
this._userVerifierChoiceList = null;
|
||||||
|
|
||||||
this.reauthenticating = true;
|
this.reauthenticating = true;
|
||||||
this._connectSignals();
|
this._connectSignals();
|
||||||
this._beginVerification();
|
this._beginVerification();
|
||||||
@ -381,6 +397,11 @@ var ShellUserVerifier = new Lang.Class({
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (client.get_user_verifier_choice_list)
|
||||||
|
this._userVerifierChoiceList = client.get_user_verifier_choice_list();
|
||||||
|
else
|
||||||
|
this._userVerifierChoiceList = null;
|
||||||
|
|
||||||
this._connectSignals();
|
this._connectSignals();
|
||||||
this._beginVerification();
|
this._beginVerification();
|
||||||
this._hold.release();
|
this._hold.release();
|
||||||
@ -394,6 +415,9 @@ var ShellUserVerifier = new Lang.Class({
|
|||||||
this._userVerifier.connect('conversation-stopped', this._onConversationStopped.bind(this));
|
this._userVerifier.connect('conversation-stopped', this._onConversationStopped.bind(this));
|
||||||
this._userVerifier.connect('reset', this._onReset.bind(this));
|
this._userVerifier.connect('reset', this._onReset.bind(this));
|
||||||
this._userVerifier.connect('verification-complete', this._onVerificationComplete.bind(this));
|
this._userVerifier.connect('verification-complete', this._onVerificationComplete.bind(this));
|
||||||
|
|
||||||
|
if (this._userVerifierChoiceList)
|
||||||
|
this._userVerifierChoiceList.connect('choice-query', this._onChoiceListQuery.bind(this));
|
||||||
},
|
},
|
||||||
|
|
||||||
_getForegroundService() {
|
_getForegroundService() {
|
||||||
@ -412,7 +436,9 @@ var ShellUserVerifier = new Lang.Class({
|
|||||||
},
|
},
|
||||||
|
|
||||||
_updateDefaultService() {
|
_updateDefaultService() {
|
||||||
if (this._settings.get_boolean(PASSWORD_AUTHENTICATION_KEY))
|
if (this._smartcardManager.loggedInWithToken())
|
||||||
|
this._defaultService = SMARTCARD_SERVICE_NAME;
|
||||||
|
else if (this._settings.get_boolean(PASSWORD_AUTHENTICATION_KEY))
|
||||||
this._defaultService = PASSWORD_SERVICE_NAME;
|
this._defaultService = PASSWORD_SERVICE_NAME;
|
||||||
else if (this._settings.get_boolean(SMARTCARD_AUTHENTICATION_KEY))
|
else if (this._settings.get_boolean(SMARTCARD_AUTHENTICATION_KEY))
|
||||||
this._defaultService = SMARTCARD_SERVICE_NAME;
|
this._defaultService = SMARTCARD_SERVICE_NAME;
|
||||||
@ -468,6 +494,13 @@ var ShellUserVerifier = new Lang.Class({
|
|||||||
this._startService(FINGERPRINT_SERVICE_NAME);
|
this._startService(FINGERPRINT_SERVICE_NAME);
|
||||||
},
|
},
|
||||||
|
|
||||||
|
_onChoiceListQuery(client, serviceName, promptMessage, list) {
|
||||||
|
if (!this.serviceIsForeground(serviceName))
|
||||||
|
return;
|
||||||
|
|
||||||
|
this.emit('show-choice-list', serviceName, promptMessage, list.deep_unpack());
|
||||||
|
},
|
||||||
|
|
||||||
_onInfo(client, serviceName, info) {
|
_onInfo(client, serviceName, info) {
|
||||||
if (this.serviceIsForeground(serviceName)) {
|
if (this.serviceIsForeground(serviceName)) {
|
||||||
this._queueMessage(info, MessageType.INFO);
|
this._queueMessage(info, MessageType.INFO);
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<gresources>
|
<gresources>
|
||||||
<gresource prefix="/org/gnome/shell">
|
<gresource prefix="/org/gnome/shell">
|
||||||
|
<file>gdm/authList.js</file>
|
||||||
<file>gdm/authPrompt.js</file>
|
<file>gdm/authPrompt.js</file>
|
||||||
<file>gdm/batch.js</file>
|
<file>gdm/batch.js</file>
|
||||||
<file>gdm/fingerprint.js</file>
|
<file>gdm/fingerprint.js</file>
|
||||||
@ -18,6 +19,7 @@
|
|||||||
<file>misc/history.js</file>
|
<file>misc/history.js</file>
|
||||||
<file>misc/ibusManager.js</file>
|
<file>misc/ibusManager.js</file>
|
||||||
<file>misc/inputMethod.js</file>
|
<file>misc/inputMethod.js</file>
|
||||||
|
<file>misc/introspect.js</file>
|
||||||
<file>misc/jsParse.js</file>
|
<file>misc/jsParse.js</file>
|
||||||
<file>misc/keyboardManager.js</file>
|
<file>misc/keyboardManager.js</file>
|
||||||
<file>misc/loginManager.js</file>
|
<file>misc/loginManager.js</file>
|
||||||
@ -130,6 +132,7 @@
|
|||||||
<file>ui/status/rfkill.js</file>
|
<file>ui/status/rfkill.js</file>
|
||||||
<file>ui/status/volume.js</file>
|
<file>ui/status/volume.js</file>
|
||||||
<file>ui/status/bluetooth.js</file>
|
<file>ui/status/bluetooth.js</file>
|
||||||
|
<file>ui/status/remoteAccess.js</file>
|
||||||
<file>ui/status/screencast.js</file>
|
<file>ui/status/screencast.js</file>
|
||||||
<file>ui/status/system.js</file>
|
<file>ui/status/system.js</file>
|
||||||
<file>ui/status/thunderbolt.js</file>
|
<file>ui/status/thunderbolt.js</file>
|
||||||
|
@ -13,7 +13,8 @@ const FileUtils = imports.misc.fileUtils;
|
|||||||
|
|
||||||
var ExtensionType = {
|
var ExtensionType = {
|
||||||
SYSTEM: 1,
|
SYSTEM: 1,
|
||||||
PER_USER: 2
|
PER_USER: 2,
|
||||||
|
SESSION_MODE: 3
|
||||||
};
|
};
|
||||||
|
|
||||||
// Maps uuid -> metadata object
|
// Maps uuid -> metadata object
|
||||||
|
@ -115,6 +115,11 @@ var IBusManager = new Lang.Class({
|
|||||||
object_path: IBus.PATH_PANEL });
|
object_path: IBus.PATH_PANEL });
|
||||||
this._candidatePopup.setPanelService(this._panelService);
|
this._candidatePopup.setPanelService(this._panelService);
|
||||||
this._panelService.connect('update-property', this._updateProperty.bind(this));
|
this._panelService.connect('update-property', this._updateProperty.bind(this));
|
||||||
|
this._panelService.connect('set-cursor-location', (ps, x, y, w, h) => {
|
||||||
|
let cursorLocation = { x, y, width: w, height: h };
|
||||||
|
this.emit('set-cursor-location', cursorLocation);
|
||||||
|
});
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// IBus versions older than 1.5.10 have a bug which
|
// IBus versions older than 1.5.10 have a bug which
|
||||||
// causes spurious set-content-type emissions when
|
// causes spurious set-content-type emissions when
|
||||||
|
@ -15,6 +15,8 @@ var InputMethod = new Lang.Class({
|
|||||||
this._purpose = 0;
|
this._purpose = 0;
|
||||||
this._enabled = true;
|
this._enabled = true;
|
||||||
this._currentFocus = null;
|
this._currentFocus = null;
|
||||||
|
this._preeditStr = '';
|
||||||
|
this._preeditPos = 0;
|
||||||
this._ibus = IBus.Bus.new_async();
|
this._ibus = IBus.Bus.new_async();
|
||||||
this._ibus.connect('connected', this._onConnected.bind(this));
|
this._ibus.connect('connected', this._onConnected.bind(this));
|
||||||
this._ibus.connect('disconnected', this._clear.bind(this));
|
this._ibus.connect('disconnected', this._clear.bind(this));
|
||||||
@ -64,6 +66,9 @@ var InputMethod = new Lang.Class({
|
|||||||
this._context.connect('commit-text', this._onCommitText.bind(this));
|
this._context.connect('commit-text', this._onCommitText.bind(this));
|
||||||
this._context.connect('delete-surrounding-text', this._onDeleteSurroundingText.bind(this));
|
this._context.connect('delete-surrounding-text', this._onDeleteSurroundingText.bind(this));
|
||||||
this._context.connect('update-preedit-text', this._onUpdatePreeditText.bind(this));
|
this._context.connect('update-preedit-text', this._onUpdatePreeditText.bind(this));
|
||||||
|
this._context.connect('show-preedit-text', this._onShowPreeditText.bind(this));
|
||||||
|
this._context.connect('hide-preedit-text', this._onHidePreeditText.bind(this));
|
||||||
|
this._context.connect('forward-key-event', this._onForwardKeyEvent.bind(this));
|
||||||
|
|
||||||
this._updateCapabilities();
|
this._updateCapabilities();
|
||||||
},
|
},
|
||||||
@ -73,6 +78,8 @@ var InputMethod = new Lang.Class({
|
|||||||
this._hints = 0;
|
this._hints = 0;
|
||||||
this._purpose = 0;
|
this._purpose = 0;
|
||||||
this._enabled = false;
|
this._enabled = false;
|
||||||
|
this._preeditStr = ''
|
||||||
|
this._preeditPos = 0;
|
||||||
},
|
},
|
||||||
|
|
||||||
_emitRequestSurrounding() {
|
_emitRequestSurrounding() {
|
||||||
@ -89,11 +96,36 @@ var InputMethod = new Lang.Class({
|
|||||||
},
|
},
|
||||||
|
|
||||||
_onUpdatePreeditText(context, text, pos, visible) {
|
_onUpdatePreeditText(context, text, pos, visible) {
|
||||||
let str = null;
|
if (text == null)
|
||||||
if (visible && text != null)
|
return;
|
||||||
str = text.get_text();
|
this._preeditStr = text.get_text();
|
||||||
|
this._preeditPos = pos;
|
||||||
|
if (visible)
|
||||||
|
this.set_preedit_text(this._preeditStr, pos);
|
||||||
|
else
|
||||||
|
this.set_preedit_text(null, pos);
|
||||||
|
},
|
||||||
|
|
||||||
this.set_preedit_text(str, pos);
|
_onShowPreeditText(context) {
|
||||||
|
this.set_preedit_text(this._preeditStr, this._preeditPos);
|
||||||
|
},
|
||||||
|
|
||||||
|
_onHidePreeditText(context) {
|
||||||
|
this.set_preedit_text(null, this._preeditPos);
|
||||||
|
},
|
||||||
|
|
||||||
|
_onForwardKeyEvent(context, keyval, keycode, state) {
|
||||||
|
let press = (state & IBus.ModifierType.RELEASE_MASK) == 0;
|
||||||
|
state &= ~(IBus.ModifierType.RELEASE_MASK);
|
||||||
|
|
||||||
|
let curEvent = Clutter.get_current_event();
|
||||||
|
let time;
|
||||||
|
if (curEvent)
|
||||||
|
time = curEvent.get_time();
|
||||||
|
else
|
||||||
|
time = global.display.get_current_time_roundtrip();
|
||||||
|
|
||||||
|
this.forward_key(keyval, keycode + 8, state & Clutter.ModifierType.MODIFIER_MASK, time, press);
|
||||||
},
|
},
|
||||||
|
|
||||||
vfunc_focus_in(focus) {
|
vfunc_focus_in(focus) {
|
||||||
@ -135,8 +167,11 @@ var InputMethod = new Lang.Class({
|
|||||||
},
|
},
|
||||||
|
|
||||||
vfunc_set_surrounding(text, cursor, anchor) {
|
vfunc_set_surrounding(text, cursor, anchor) {
|
||||||
if (this._context)
|
if (!this._context || !text)
|
||||||
this._context.set_surrounding_text(text, cursor, anchor);
|
return;
|
||||||
|
|
||||||
|
let ibusText = IBus.Text.new_from_string(text);
|
||||||
|
this._context.set_surrounding_text(ibusText, cursor, anchor);
|
||||||
},
|
},
|
||||||
|
|
||||||
vfunc_update_content_hints(hints) {
|
vfunc_update_content_hints(hints) {
|
||||||
@ -197,6 +232,7 @@ var InputMethod = new Lang.Class({
|
|||||||
|
|
||||||
if (event.type() == Clutter.EventType.KEY_RELEASE)
|
if (event.type() == Clutter.EventType.KEY_RELEASE)
|
||||||
state |= IBus.ModifierType.RELEASE_MASK;
|
state |= IBus.ModifierType.RELEASE_MASK;
|
||||||
|
|
||||||
this._context.process_key_event_async(event.get_key_symbol(),
|
this._context.process_key_event_async(event.get_key_symbol(),
|
||||||
event.get_key_code() - 8, // Convert XKB keycodes to evcodes
|
event.get_key_code() - 8, // Convert XKB keycodes to evcodes
|
||||||
state, -1, null,
|
state, -1, null,
|
||||||
|
174
js/misc/introspect.js
Normal file
174
js/misc/introspect.js
Normal file
@ -0,0 +1,174 @@
|
|||||||
|
const Gio = imports.gi.Gio;
|
||||||
|
const GLib = imports.gi.GLib;
|
||||||
|
const Lang = imports.lang;
|
||||||
|
const Meta = imports.gi.Meta;
|
||||||
|
const Shell = imports.gi.Shell;
|
||||||
|
|
||||||
|
const INTROSPECT_SCHEMA = 'org.gnome.shell';
|
||||||
|
const INTROSPECT_KEY = 'introspect';
|
||||||
|
const APP_WHITELIST = ['org.freedesktop.impl.portal.desktop.gtk'];
|
||||||
|
|
||||||
|
const IntrospectDBusIface = '<node> \
|
||||||
|
<interface name="org.gnome.Shell.Introspect"> \
|
||||||
|
<signal name="RunningApplicationsChanged" /> \
|
||||||
|
<method name="GetRunningApplications"> \
|
||||||
|
<arg name="apps" direction="out" type="a{sa{sv}}" /> \
|
||||||
|
</method> \
|
||||||
|
<method name="GetWindows"> \
|
||||||
|
<arg name="windows" direction="out" type="a{ta{sv}}" /> \
|
||||||
|
</method> \
|
||||||
|
</interface> \
|
||||||
|
</node>';
|
||||||
|
|
||||||
|
var IntrospectService = new Lang.Class({
|
||||||
|
Name: 'IntrospectService',
|
||||||
|
|
||||||
|
_init() {
|
||||||
|
this._dbusImpl = Gio.DBusExportedObject.wrapJSObject(IntrospectDBusIface,
|
||||||
|
this);
|
||||||
|
this._dbusImpl.export(Gio.DBus.session, '/org/gnome/Shell/Introspect');
|
||||||
|
Gio.DBus.session.own_name('org.gnome.Shell.Introspect',
|
||||||
|
Gio.BusNameOwnerFlags.REPLACE,
|
||||||
|
null, null);
|
||||||
|
|
||||||
|
this._runningApplications = {};
|
||||||
|
this._runningApplicationsDirty = true;
|
||||||
|
this._activeApplication = null;
|
||||||
|
this._activeApplicationDirty = true;
|
||||||
|
|
||||||
|
this._appSystem = Shell.AppSystem.get_default();
|
||||||
|
this._appSystem.connect('app-state-changed',
|
||||||
|
() => {
|
||||||
|
this._runningApplicationsDirty = true;
|
||||||
|
this._syncRunningApplications();
|
||||||
|
});
|
||||||
|
|
||||||
|
this._settings = new Gio.Settings({ schema_id: INTROSPECT_SCHEMA });
|
||||||
|
|
||||||
|
let tracker = Shell.WindowTracker.get_default();
|
||||||
|
tracker.connect('notify::focus-app',
|
||||||
|
() => {
|
||||||
|
this._activeApplicationDirty = true;
|
||||||
|
this._syncRunningApplications();
|
||||||
|
});
|
||||||
|
|
||||||
|
this._syncRunningApplications();
|
||||||
|
},
|
||||||
|
|
||||||
|
_isStandaloneApp(app) {
|
||||||
|
let windows = app.get_windows();
|
||||||
|
|
||||||
|
return app.get_windows().some(w => w.transient_for == null);
|
||||||
|
},
|
||||||
|
|
||||||
|
_isIntrospectEnabled() {
|
||||||
|
return this._settings.get_boolean(INTROSPECT_KEY);
|
||||||
|
},
|
||||||
|
|
||||||
|
_isSenderWhitelisted(sender) {
|
||||||
|
return APP_WHITELIST.includes(sender);
|
||||||
|
},
|
||||||
|
|
||||||
|
_syncRunningApplications() {
|
||||||
|
let tracker = Shell.WindowTracker.get_default();
|
||||||
|
let apps = this._appSystem.get_running();
|
||||||
|
let seatName = "seat0";
|
||||||
|
let newRunningApplications = {};
|
||||||
|
|
||||||
|
let newActiveApplication = null;
|
||||||
|
let focusedApp = tracker.focus_app;
|
||||||
|
|
||||||
|
for (let app of apps) {
|
||||||
|
let appInfo = {};
|
||||||
|
let isAppActive = (focusedApp == app);
|
||||||
|
|
||||||
|
if (!this._isStandaloneApp(app))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (isAppActive) {
|
||||||
|
appInfo['active-on-seats'] = new GLib.Variant('as', [seatName]);
|
||||||
|
newActiveApplication = app.get_id();
|
||||||
|
}
|
||||||
|
|
||||||
|
newRunningApplications[app.get_id()] = appInfo;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this._runningApplicationsDirty ||
|
||||||
|
(this._activeApplicationDirty &&
|
||||||
|
this._activeApplication != newActiveApplication)) {
|
||||||
|
this._runningApplications = newRunningApplications;
|
||||||
|
this._activeApplication = newActiveApplication;
|
||||||
|
|
||||||
|
this._dbusImpl.emit_signal('RunningApplicationsChanged', null);
|
||||||
|
}
|
||||||
|
this._runningApplicationsDirty = false;
|
||||||
|
this._activeApplicationDirty = false;
|
||||||
|
},
|
||||||
|
|
||||||
|
_isEligibleWindow(window) {
|
||||||
|
if (window.is_override_redirect())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
let type = window.get_window_type();
|
||||||
|
return (type == Meta.WindowType.NORMAL ||
|
||||||
|
type == Meta.WindowType.DIALOG ||
|
||||||
|
type == Meta.WindowType.MODAL_DIALOG ||
|
||||||
|
type == Meta.WindowType.UTILITY);
|
||||||
|
},
|
||||||
|
|
||||||
|
GetRunningApplicationsAsync(params, invocation) {
|
||||||
|
if (!this._isIntrospectEnabled() &&
|
||||||
|
!this._isSenderWhitelisted(invocation.get_sender())) {
|
||||||
|
invocation.return_error_literal(Gio.DBusError,
|
||||||
|
Gio.DBusError.ACCESS_DENIED,
|
||||||
|
'App introspection not allowed');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
invocation.return_value(new GLib.Variant('(a{sa{sv}})', [this._runningApplications]));
|
||||||
|
},
|
||||||
|
|
||||||
|
GetWindowsAsync(params, invocation) {
|
||||||
|
let focusWindow = global.display.get_focus_window();
|
||||||
|
let apps = this._appSystem.get_running();
|
||||||
|
let windowsList = {};
|
||||||
|
|
||||||
|
if (!this._isIntrospectEnabled()) {
|
||||||
|
invocation.return_error_literal(Gio.DBusError,
|
||||||
|
Gio.DBusError.ACCESS_DENIED,
|
||||||
|
'App introspection not allowed');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (let app of apps) {
|
||||||
|
let windows = app.get_windows();
|
||||||
|
for (let window of windows) {
|
||||||
|
|
||||||
|
if (!this._isEligibleWindow(window))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
let windowId = window.get_id();
|
||||||
|
let frameRect = window.get_frame_rect();
|
||||||
|
let title = window.get_title();
|
||||||
|
let wmClass = window.get_wm_class();
|
||||||
|
|
||||||
|
windowsList[windowId] = {
|
||||||
|
'app-id': GLib.Variant.new('s', app.get_id()),
|
||||||
|
'client-type': GLib.Variant.new('u', window.get_client_type()),
|
||||||
|
'is-hidden': GLib.Variant.new('b', window.is_hidden()),
|
||||||
|
'has-focus': GLib.Variant.new('b', (window == focusWindow)),
|
||||||
|
'width': GLib.Variant.new('u', frameRect.width),
|
||||||
|
'height': GLib.Variant.new('u', frameRect.height)
|
||||||
|
};
|
||||||
|
|
||||||
|
// These properties may not be available for all windows:
|
||||||
|
if (title != null)
|
||||||
|
windowsList[windowId]['title'] = GLib.Variant.new('s', title);
|
||||||
|
|
||||||
|
if (wmClass != null)
|
||||||
|
windowsList[windowId]['wm-class'] = GLib.Variant.new('s', wmClass);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
invocation.return_value(new GLib.Variant('(a{ta{sv}})', [windowsList]));
|
||||||
|
}
|
||||||
|
});
|
@ -52,11 +52,20 @@ var KeyboardManager = new Lang.Class({
|
|||||||
this._current = null;
|
this._current = null;
|
||||||
this._localeLayoutInfo = this._getLocaleLayout();
|
this._localeLayoutInfo = this._getLocaleLayout();
|
||||||
this._layoutInfos = {};
|
this._layoutInfos = {};
|
||||||
|
this._currentKeymap = null;
|
||||||
},
|
},
|
||||||
|
|
||||||
_applyLayoutGroup(group) {
|
_applyLayoutGroup(group) {
|
||||||
let options = this._buildOptionsString();
|
let options = this._buildOptionsString();
|
||||||
let [layouts, variants] = this._buildGroupStrings(group);
|
let [layouts, variants] = this._buildGroupStrings(group);
|
||||||
|
|
||||||
|
if (this._currentKeymap &&
|
||||||
|
this._currentKeymap.layouts == layouts &&
|
||||||
|
this._currentKeymap.variants == variants &&
|
||||||
|
this._currentKeymap.options == options)
|
||||||
|
return;
|
||||||
|
|
||||||
|
this._currentKeymap = {layouts, variants, options};
|
||||||
Meta.get_backend().set_keymap(layouts, variants, options);
|
Meta.get_backend().set_keymap(layouts, variants, options);
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -112,6 +112,13 @@ var SmartcardManager = new Lang.Class({
|
|||||||
return false;
|
return false;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
},
|
||||||
|
|
||||||
|
loggedInWithToken() {
|
||||||
|
if (this._loginToken)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
});
|
});
|
||||||
|
@ -1628,6 +1628,20 @@ var AppIcon = new Lang.Class({
|
|||||||
this.actor.connect('clicked', this._onClicked.bind(this));
|
this.actor.connect('clicked', this._onClicked.bind(this));
|
||||||
this.actor.connect('popup-menu', this._onKeyboardPopupMenu.bind(this));
|
this.actor.connect('popup-menu', this._onKeyboardPopupMenu.bind(this));
|
||||||
|
|
||||||
|
this._hoverText = null;
|
||||||
|
this._hoverTimeoutId = 0;
|
||||||
|
|
||||||
|
if (this.icon.label) {
|
||||||
|
this._hoverText = new St.Label({ style_class: 'app-well-hover-text',
|
||||||
|
text: this.icon.label.text,
|
||||||
|
visible: false });
|
||||||
|
this._hoverText.clutter_text.line_wrap = true;
|
||||||
|
Main.layoutManager.addChrome(this._hoverText);
|
||||||
|
|
||||||
|
this.actor.connect('notify::hover', this._syncHoverText.bind(this));
|
||||||
|
this.connect('sync-tooltip', this._syncHoverText.bind(this));
|
||||||
|
}
|
||||||
|
|
||||||
this._menu = null;
|
this._menu = null;
|
||||||
this._menuManager = new PopupMenu.PopupMenuManager(this);
|
this._menuManager = new PopupMenu.PopupMenuManager(this);
|
||||||
|
|
||||||
@ -1659,12 +1673,39 @@ var AppIcon = new Lang.Class({
|
|||||||
this.app.disconnect(this._stateChangedId);
|
this.app.disconnect(this._stateChangedId);
|
||||||
this._stateChangedId = 0;
|
this._stateChangedId = 0;
|
||||||
this._removeMenuTimeout();
|
this._removeMenuTimeout();
|
||||||
|
this._removeHoverTimeout();
|
||||||
|
if (this._hoverText)
|
||||||
|
this._hoverText.destroy();
|
||||||
|
this._hoverText = null;
|
||||||
},
|
},
|
||||||
|
|
||||||
_createIcon(iconSize) {
|
_createIcon(iconSize) {
|
||||||
return this.app.create_icon_texture(iconSize);
|
return this.app.create_icon_texture(iconSize);
|
||||||
},
|
},
|
||||||
|
|
||||||
|
_syncHoverText() {
|
||||||
|
if (this.shouldShowTooltip()) {
|
||||||
|
if (this._hoverTimeoutId)
|
||||||
|
return;
|
||||||
|
|
||||||
|
this._hoverTimeoutId = Mainloop.timeout_add(300, () => {
|
||||||
|
this._hoverText.style = `max-width: ${2 * this.icon.iconSize}px;`;
|
||||||
|
this._hoverText.ensure_style();
|
||||||
|
|
||||||
|
let [x, y] = this.icon.label.get_transformed_position();
|
||||||
|
let offset = (this._hoverText.width - this.icon.label.width) / 2;
|
||||||
|
this._hoverText.set_position(Math.floor(x - offset), Math.floor(y));
|
||||||
|
this._hoverText.show();
|
||||||
|
|
||||||
|
this._hoverTimeoutId = 0;
|
||||||
|
return GLib.SOURCE_REMOVE;
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
this._removeHoverTimeout();
|
||||||
|
this._hoverText.hide();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
_removeMenuTimeout() {
|
_removeMenuTimeout() {
|
||||||
if (this._menuTimeoutId > 0) {
|
if (this._menuTimeoutId > 0) {
|
||||||
Mainloop.source_remove(this._menuTimeoutId);
|
Mainloop.source_remove(this._menuTimeoutId);
|
||||||
@ -1672,6 +1713,13 @@ var AppIcon = new Lang.Class({
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
_removeHoverTimeout() {
|
||||||
|
if (this._hoverTimeoutId > 0) {
|
||||||
|
Mainloop.source_remove(this._hoverTimeoutId);
|
||||||
|
this._hoverTimeoutId = 0;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
_updateRunningStyle() {
|
_updateRunningStyle() {
|
||||||
if (this.app.state != Shell.AppState.STOPPED)
|
if (this.app.state != Shell.AppState.STOPPED)
|
||||||
this._dot.show();
|
this._dot.show();
|
||||||
|
@ -41,6 +41,7 @@ const RENAMED_DESKTOP_IDS = {
|
|||||||
'gnotravex.desktop': 'gnome-tetravex.desktop',
|
'gnotravex.desktop': 'gnome-tetravex.desktop',
|
||||||
'gnotski.desktop': 'gnome-klotski.desktop',
|
'gnotski.desktop': 'gnome-klotski.desktop',
|
||||||
'gtali.desktop': 'tali.desktop',
|
'gtali.desktop': 'tali.desktop',
|
||||||
|
'mozilla-firefox.desktop': 'firefox.desktop',
|
||||||
'nautilus.desktop': 'org.gnome.Nautilus.desktop',
|
'nautilus.desktop': 'org.gnome.Nautilus.desktop',
|
||||||
'polari.desktop': 'org.gnome.Polari.desktop',
|
'polari.desktop': 'org.gnome.Polari.desktop',
|
||||||
'totem.desktop': 'org.gnome.Totem.desktop',
|
'totem.desktop': 'org.gnome.Totem.desktop',
|
||||||
|
@ -264,7 +264,7 @@ var Background = new Lang.Class({
|
|||||||
(lm, aboutToSuspend) => {
|
(lm, aboutToSuspend) => {
|
||||||
if (aboutToSuspend)
|
if (aboutToSuspend)
|
||||||
return;
|
return;
|
||||||
this._refreshAnimation();
|
this.emit('changed');
|
||||||
});
|
});
|
||||||
|
|
||||||
this._settingsChangedSignalId = this._settings.connect('changed', () => {
|
this._settingsChangedSignalId = this._settings.connect('changed', () => {
|
||||||
@ -539,10 +539,15 @@ var BackgroundSource = new Lang.Class({
|
|||||||
this._backgrounds = [];
|
this._backgrounds = [];
|
||||||
|
|
||||||
this._monitorsChangedId = global.screen.connect('monitors-changed',
|
this._monitorsChangedId = global.screen.connect('monitors-changed',
|
||||||
this._onMonitorsChanged.bind(this));
|
this._refresh.bind(this));
|
||||||
|
|
||||||
|
global.display.connect('gl-video-memory-purged', () => {
|
||||||
|
Meta.Background.refresh_all();
|
||||||
|
this._refresh();
|
||||||
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
_onMonitorsChanged() {
|
_refresh() {
|
||||||
for (let monitorIndex in this._backgrounds) {
|
for (let monitorIndex in this._backgrounds) {
|
||||||
let background = this._backgrounds[monitorIndex];
|
let background = this._backgrounds[monitorIndex];
|
||||||
|
|
||||||
|
@ -802,6 +802,8 @@ var NotificationMessage = new Lang.Class({
|
|||||||
},
|
},
|
||||||
|
|
||||||
_onDestroy() {
|
_onDestroy() {
|
||||||
|
this.parent();
|
||||||
|
|
||||||
if (this._updatedId)
|
if (this._updatedId)
|
||||||
this.notification.disconnect(this._updatedId);
|
this.notification.disconnect(this._updatedId);
|
||||||
this._updatedId = 0;
|
this._updatedId = 0;
|
||||||
@ -821,6 +823,8 @@ var EventsSection = new Lang.Class({
|
|||||||
this._desktopSettings.connect('changed', this._reloadEvents.bind(this));
|
this._desktopSettings.connect('changed', this._reloadEvents.bind(this));
|
||||||
this._eventSource = new EmptyEventSource();
|
this._eventSource = new EmptyEventSource();
|
||||||
|
|
||||||
|
this._messageById = new Map();
|
||||||
|
|
||||||
this.parent();
|
this.parent();
|
||||||
|
|
||||||
this._title = new St.Button({ style_class: 'events-section-title',
|
this._title = new St.Button({ style_class: 'events-section-title',
|
||||||
@ -875,20 +879,32 @@ var EventsSection = new Lang.Class({
|
|||||||
|
|
||||||
this._reloading = true;
|
this._reloading = true;
|
||||||
|
|
||||||
this._list.destroy_all_children();
|
|
||||||
|
|
||||||
let periodBegin = _getBeginningOfDay(this._date);
|
let periodBegin = _getBeginningOfDay(this._date);
|
||||||
let periodEnd = _getEndOfDay(this._date);
|
let periodEnd = _getEndOfDay(this._date);
|
||||||
let events = this._eventSource.getEvents(periodBegin, periodEnd);
|
let events = this._eventSource.getEvents(periodBegin, periodEnd);
|
||||||
|
|
||||||
|
let ids = events.map(e => e.id);
|
||||||
|
this._messageById.forEach((message, id) => {
|
||||||
|
if (ids.includes(id))
|
||||||
|
return;
|
||||||
|
this._messageById.delete(id);
|
||||||
|
this.removeMessage(message);
|
||||||
|
});
|
||||||
|
|
||||||
for (let i = 0; i < events.length; i++) {
|
for (let i = 0; i < events.length; i++) {
|
||||||
let event = events[i];
|
let event = events[i];
|
||||||
|
|
||||||
let message = new EventMessage(event, this._date);
|
let message = this._messageById.get(event.id);
|
||||||
message.connect('close', () => {
|
if (!message) {
|
||||||
this._ignoreEvent(event);
|
message = new EventMessage(event, this._date);
|
||||||
});
|
message.connect('close', () => {
|
||||||
this.addMessage(message, false);
|
this._ignoreEvent(event);
|
||||||
|
});
|
||||||
|
this._messageById.set(event.id, message);
|
||||||
|
this.addMessage(message, false);
|
||||||
|
} else {
|
||||||
|
this.moveMessage(message, i, false);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
this._reloading = false;
|
this._reloading = false;
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
const Clutter = imports.gi.Clutter;
|
const Clutter = imports.gi.Clutter;
|
||||||
const Gio = imports.gi.Gio;
|
const Gio = imports.gi.Gio;
|
||||||
|
const GLib = imports.gi.GLib;
|
||||||
const GObject = imports.gi.GObject;
|
const GObject = imports.gi.GObject;
|
||||||
const Lang = imports.lang;
|
const Lang = imports.lang;
|
||||||
const Meta = imports.gi.Meta;
|
const Meta = imports.gi.Meta;
|
||||||
@ -13,6 +14,7 @@ const Tweener = imports.ui.tweener;
|
|||||||
|
|
||||||
var FROZEN_WINDOW_BRIGHTNESS = -0.3
|
var FROZEN_WINDOW_BRIGHTNESS = -0.3
|
||||||
var DIALOG_TRANSITION_TIME = 0.15
|
var DIALOG_TRANSITION_TIME = 0.15
|
||||||
|
var ALIVE_TIMEOUT = 5000;
|
||||||
|
|
||||||
var CloseDialog = new Lang.Class({
|
var CloseDialog = new Lang.Class({
|
||||||
Name: 'CloseDialog',
|
Name: 'CloseDialog',
|
||||||
@ -26,6 +28,10 @@ var CloseDialog = new Lang.Class({
|
|||||||
this.parent();
|
this.parent();
|
||||||
this._window = window;
|
this._window = window;
|
||||||
this._dialog = null;
|
this._dialog = null;
|
||||||
|
this._tracked = undefined;
|
||||||
|
this._timeoutId = 0;
|
||||||
|
this._windowFocusChangedId = 0;
|
||||||
|
this._keyFocusChangedId = 0;
|
||||||
},
|
},
|
||||||
|
|
||||||
get window() {
|
get window() {
|
||||||
@ -93,10 +99,57 @@ var CloseDialog = new Lang.Class({
|
|||||||
this.response(Meta.CloseDialogResponse.FORCE_CLOSE);
|
this.response(Meta.CloseDialogResponse.FORCE_CLOSE);
|
||||||
},
|
},
|
||||||
|
|
||||||
|
_onFocusChanged() {
|
||||||
|
if (Meta.is_wayland_compositor())
|
||||||
|
return;
|
||||||
|
|
||||||
|
let focusWindow = global.display.focus_window;
|
||||||
|
let keyFocus = global.stage.key_focus;
|
||||||
|
|
||||||
|
let shouldTrack;
|
||||||
|
if (focusWindow != null)
|
||||||
|
shouldTrack = focusWindow == this._window;
|
||||||
|
else
|
||||||
|
shouldTrack = keyFocus && this._dialog.contains(keyFocus);
|
||||||
|
|
||||||
|
if (this._tracked === shouldTrack)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (shouldTrack)
|
||||||
|
Main.layoutManager.trackChrome(this._dialog,
|
||||||
|
{ affectsInputRegion: true });
|
||||||
|
else
|
||||||
|
Main.layoutManager.untrackChrome(this._dialog);
|
||||||
|
|
||||||
|
// The buttons are broken when they aren't added to the input region,
|
||||||
|
// so disable them properly in that case
|
||||||
|
this._dialog.buttonLayout.get_children().forEach(b => {
|
||||||
|
b.reactive = shouldTrack;
|
||||||
|
});
|
||||||
|
|
||||||
|
this._tracked = shouldTrack;
|
||||||
|
},
|
||||||
|
|
||||||
vfunc_show() {
|
vfunc_show() {
|
||||||
if (this._dialog != null)
|
if (this._dialog != null)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
Meta.disable_unredirect_for_screen(global.screen);
|
||||||
|
|
||||||
|
this._timeoutId = GLib.timeout_add(GLib.PRIORITY_DEFAULT, ALIVE_TIMEOUT,
|
||||||
|
() => {
|
||||||
|
this._window.check_alive(global.display.get_current_time_roundtrip());
|
||||||
|
return GLib.SOURCE_CONTINUE;
|
||||||
|
});
|
||||||
|
|
||||||
|
this._windowFocusChangedId =
|
||||||
|
global.display.connect('notify::focus-window',
|
||||||
|
this._onFocusChanged.bind(this));
|
||||||
|
|
||||||
|
this._keyFocusChangedId =
|
||||||
|
global.stage.connect('notify::key-focus',
|
||||||
|
this._onFocusChanged.bind(this));
|
||||||
|
|
||||||
this._addWindowEffect();
|
this._addWindowEffect();
|
||||||
this._initDialog();
|
this._initDialog();
|
||||||
|
|
||||||
@ -107,9 +160,7 @@ var CloseDialog = new Lang.Class({
|
|||||||
{ scale_y: 1,
|
{ scale_y: 1,
|
||||||
transition: 'linear',
|
transition: 'linear',
|
||||||
time: DIALOG_TRANSITION_TIME,
|
time: DIALOG_TRANSITION_TIME,
|
||||||
onComplete: () => {
|
onComplete: this._onFocusChanged.bind(this)
|
||||||
Main.layoutManager.trackChrome(this._dialog, { affectsInputRegion: true });
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -117,6 +168,17 @@ var CloseDialog = new Lang.Class({
|
|||||||
if (this._dialog == null)
|
if (this._dialog == null)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
Meta.enable_unredirect_for_screen(global.screen);
|
||||||
|
|
||||||
|
GLib.source_remove(this._timeoutId);
|
||||||
|
this._timeoutId = 0;
|
||||||
|
|
||||||
|
global.display.disconnect(this._windowFocusChangedId)
|
||||||
|
this._windowFocusChangedId = 0;
|
||||||
|
|
||||||
|
global.stage.disconnect(this._keyFocusChangedId);
|
||||||
|
this._keyFocusChangedId = 0;
|
||||||
|
|
||||||
let dialog = this._dialog;
|
let dialog = this._dialog;
|
||||||
this._dialog = null;
|
this._dialog = null;
|
||||||
this._removeWindowEffect();
|
this._removeWindowEffect();
|
||||||
|
@ -210,6 +210,10 @@ var AutomountManager = new Lang.Class({
|
|||||||
},
|
},
|
||||||
|
|
||||||
_onVolumeRemoved(monitor, volume) {
|
_onVolumeRemoved(monitor, volume) {
|
||||||
|
if (volume._allowAutorunExpireId && volume._allowAutorunExpireId > 0) {
|
||||||
|
Mainloop.source_remove(volume._allowAutorunExpireId);
|
||||||
|
delete volume._allowAutorunExpireId;
|
||||||
|
}
|
||||||
this._volumeQueue =
|
this._volumeQueue =
|
||||||
this._volumeQueue.filter(element => (element != volume));
|
this._volumeQueue.filter(element => (element != volume));
|
||||||
},
|
},
|
||||||
@ -234,8 +238,10 @@ var AutomountManager = new Lang.Class({
|
|||||||
_allowAutorunExpire(volume) {
|
_allowAutorunExpire(volume) {
|
||||||
let id = Mainloop.timeout_add_seconds(AUTORUN_EXPIRE_TIMEOUT_SECS, () => {
|
let id = Mainloop.timeout_add_seconds(AUTORUN_EXPIRE_TIMEOUT_SECS, () => {
|
||||||
volume.allowAutorun = false;
|
volume.allowAutorun = false;
|
||||||
|
delete volume._allowAutorunExpireId;
|
||||||
return GLib.SOURCE_REMOVE;
|
return GLib.SOURCE_REMOVE;
|
||||||
});
|
});
|
||||||
|
volume._allowAutorunExpireId = id;
|
||||||
GLib.Source.set_name_by_id(id, '[gnome-shell] volume.allowAutorun');
|
GLib.Source.set_name_by_id(id, '[gnome-shell] volume.allowAutorun');
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -655,7 +655,7 @@ var NetworkAgent = new Lang.Class({
|
|||||||
switch (connectionType) {
|
switch (connectionType) {
|
||||||
case '802-11-wireless':
|
case '802-11-wireless':
|
||||||
let wirelessSetting = connection.get_setting_wireless();
|
let wirelessSetting = connection.get_setting_wireless();
|
||||||
let ssid = NM.utils_ssid_to_utf8(wirelessSetting.get_ssid());
|
let ssid = NM.utils_ssid_to_utf8(wirelessSetting.get_ssid().get_data());
|
||||||
title = _("Authentication required by wireless network");
|
title = _("Authentication required by wireless network");
|
||||||
body = _("Passwords or encryption keys are required to access the wireless network “%s”.").format(ssid);
|
body = _("Passwords or encryption keys are required to access the wireless network “%s”.").format(ssid);
|
||||||
break;
|
break;
|
||||||
|
@ -201,7 +201,9 @@ var AuthenticationDialog = new Lang.Class({
|
|||||||
close(timestamp) {
|
close(timestamp) {
|
||||||
this.parent(timestamp);
|
this.parent(timestamp);
|
||||||
|
|
||||||
Main.sessionMode.disconnect(this._sessionUpdatedId);
|
if (this._sessionUpdatedId)
|
||||||
|
Main.sessionMode.disconnect(this._sessionUpdatedId);
|
||||||
|
this._sessionUpdatedId = 0;
|
||||||
},
|
},
|
||||||
|
|
||||||
_ensureOpen() {
|
_ensureOpen() {
|
||||||
|
87
js/ui/dnd.js
87
js/ui/dnd.js
@ -27,6 +27,12 @@ var DragMotionResult = {
|
|||||||
CONTINUE: 3
|
CONTINUE: 3
|
||||||
};
|
};
|
||||||
|
|
||||||
|
var DragState = {
|
||||||
|
INIT: 0,
|
||||||
|
DRAGGING: 1,
|
||||||
|
CANCELLED: 2,
|
||||||
|
};
|
||||||
|
|
||||||
var DRAG_CURSOR_MAP = {
|
var DRAG_CURSOR_MAP = {
|
||||||
0: Meta.Cursor.DND_UNSUPPORTED_TARGET,
|
0: Meta.Cursor.DND_UNSUPPORTED_TARGET,
|
||||||
1: Meta.Cursor.DND_COPY,
|
1: Meta.Cursor.DND_COPY,
|
||||||
@ -78,6 +84,8 @@ var _Draggable = new Lang.Class({
|
|||||||
dragActorOpacity: undefined });
|
dragActorOpacity: undefined });
|
||||||
|
|
||||||
this.actor = actor;
|
this.actor = actor;
|
||||||
|
this._dragState = DragState.INIT;
|
||||||
|
|
||||||
if (!params.manualMode) {
|
if (!params.manualMode) {
|
||||||
this.actor.connect('button-press-event',
|
this.actor.connect('button-press-event',
|
||||||
this._onButtonPress.bind(this));
|
this._onButtonPress.bind(this));
|
||||||
@ -88,7 +96,7 @@ var _Draggable = new Lang.Class({
|
|||||||
this.actor.connect('destroy', () => {
|
this.actor.connect('destroy', () => {
|
||||||
this._actorDestroyed = true;
|
this._actorDestroyed = true;
|
||||||
|
|
||||||
if (this._dragInProgress && this._dragCancellable)
|
if (this._dragState == DragState.DRAGGING && this._dragCancellable)
|
||||||
this._cancelDrag(global.get_current_time());
|
this._cancelDrag(global.get_current_time());
|
||||||
this.disconnectAll();
|
this.disconnectAll();
|
||||||
});
|
});
|
||||||
@ -100,7 +108,6 @@ var _Draggable = new Lang.Class({
|
|||||||
this._dragActorOpacity = params.dragActorOpacity;
|
this._dragActorOpacity = params.dragActorOpacity;
|
||||||
|
|
||||||
this._buttonDown = false; // The mouse button has been pressed and has not yet been released.
|
this._buttonDown = false; // The mouse button has been pressed and has not yet been released.
|
||||||
this._dragInProgress = false; // The drag has been started, and has not been dropped or cancelled yet.
|
|
||||||
this._animationInProgress = false; // The drag is over and the item is in the process of animating to its original position (snapping back or reverting).
|
this._animationInProgress = false; // The drag is over and the item is in the process of animating to its original position (snapping back or reverting).
|
||||||
this._dragCancellable = true;
|
this._dragCancellable = true;
|
||||||
|
|
||||||
@ -206,9 +213,10 @@ var _Draggable = new Lang.Class({
|
|||||||
(event.type() == Clutter.EventType.TOUCH_END &&
|
(event.type() == Clutter.EventType.TOUCH_END &&
|
||||||
global.display.is_pointer_emulating_sequence(event.get_event_sequence()))) {
|
global.display.is_pointer_emulating_sequence(event.get_event_sequence()))) {
|
||||||
this._buttonDown = false;
|
this._buttonDown = false;
|
||||||
if (this._dragInProgress) {
|
if (this._dragState == DragState.DRAGGING) {
|
||||||
return this._dragActorDropped(event);
|
return this._dragActorDropped(event);
|
||||||
} else if (this._dragActor != null && !this._animationInProgress) {
|
} else if ((this._dragActor != null || this._dragState == DragState.CANCELLED) &&
|
||||||
|
!this._animationInProgress) {
|
||||||
// Drag must have been cancelled with Esc.
|
// Drag must have been cancelled with Esc.
|
||||||
this._dragComplete();
|
this._dragComplete();
|
||||||
return Clutter.EVENT_STOP;
|
return Clutter.EVENT_STOP;
|
||||||
@ -222,14 +230,14 @@ var _Draggable = new Lang.Class({
|
|||||||
} else if (event.type() == Clutter.EventType.MOTION ||
|
} else if (event.type() == Clutter.EventType.MOTION ||
|
||||||
(event.type() == Clutter.EventType.TOUCH_UPDATE &&
|
(event.type() == Clutter.EventType.TOUCH_UPDATE &&
|
||||||
global.display.is_pointer_emulating_sequence(event.get_event_sequence()))) {
|
global.display.is_pointer_emulating_sequence(event.get_event_sequence()))) {
|
||||||
if (this._dragInProgress) {
|
if (this._dragActor && this._dragState == DragState.DRAGGING) {
|
||||||
return this._updateDragPosition(event);
|
return this._updateDragPosition(event);
|
||||||
} else if (this._dragActor == null) {
|
} else if (this._dragActor == null && this._dragState != DragState.CANCELLED) {
|
||||||
return this._maybeStartDrag(event);
|
return this._maybeStartDrag(event);
|
||||||
}
|
}
|
||||||
// We intercept KEY_PRESS event so that we can process Esc key press to cancel
|
// We intercept KEY_PRESS event so that we can process Esc key press to cancel
|
||||||
// dragging and ignore all other key presses.
|
// dragging and ignore all other key presses.
|
||||||
} else if (event.type() == Clutter.EventType.KEY_PRESS && this._dragInProgress) {
|
} else if (event.type() == Clutter.EventType.KEY_PRESS && this._dragState == DragState.DRAGGING) {
|
||||||
let symbol = event.get_key_symbol();
|
let symbol = event.get_key_symbol();
|
||||||
if (symbol == Clutter.Escape) {
|
if (symbol == Clutter.Escape) {
|
||||||
this._cancelDrag(event.get_time());
|
this._cancelDrag(event.get_time());
|
||||||
@ -265,7 +273,7 @@ var _Draggable = new Lang.Class({
|
|||||||
*/
|
*/
|
||||||
startDrag(stageX, stageY, time, sequence) {
|
startDrag(stageX, stageY, time, sequence) {
|
||||||
currentDraggable = this;
|
currentDraggable = this;
|
||||||
this._dragInProgress = true;
|
this._dragState = DragState.DRAGGING;
|
||||||
|
|
||||||
// Special-case St.Button: the pointer grab messes with the internal
|
// Special-case St.Button: the pointer grab messes with the internal
|
||||||
// state, so force a reset to a reasonable state here
|
// state, so force a reset to a reasonable state here
|
||||||
@ -342,6 +350,13 @@ var _Draggable = new Lang.Class({
|
|||||||
Shell.util_set_hidden_from_pick(this._dragActor, true);
|
Shell.util_set_hidden_from_pick(this._dragActor, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this._dragActorDestroyId = this._dragActor.connect('destroy', () => {
|
||||||
|
// Cancel ongoing animation (if any)
|
||||||
|
this._finishAnimation();
|
||||||
|
|
||||||
|
this._dragActor = null;
|
||||||
|
this._dragState = DragState.CANCELLED;
|
||||||
|
});
|
||||||
this._dragOrigOpacity = this._dragActor.opacity;
|
this._dragOrigOpacity = this._dragActor.opacity;
|
||||||
if (this._dragActorOpacity != undefined)
|
if (this._dragActorOpacity != undefined)
|
||||||
this._dragActor.opacity = this._dragActorOpacity;
|
this._dragActor.opacity = this._dragActorOpacity;
|
||||||
@ -396,10 +411,15 @@ var _Draggable = new Lang.Class({
|
|||||||
return true;
|
return true;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
_pickTargetActor() {
|
||||||
|
return this._dragActor.get_stage().get_actor_at_pos(Clutter.PickMode.ALL,
|
||||||
|
this._dragX, this._dragY);
|
||||||
|
},
|
||||||
|
|
||||||
_updateDragHover() {
|
_updateDragHover() {
|
||||||
this._updateHoverId = 0;
|
this._updateHoverId = 0;
|
||||||
let target = this._dragActor.get_stage().get_actor_at_pos(Clutter.PickMode.ALL,
|
let target = this._pickTargetActor();
|
||||||
this._dragX, this._dragY);
|
|
||||||
let dragEvent = {
|
let dragEvent = {
|
||||||
x: this._dragX,
|
x: this._dragX,
|
||||||
y: this._dragY,
|
y: this._dragY,
|
||||||
@ -407,6 +427,18 @@ var _Draggable = new Lang.Class({
|
|||||||
source: this.actor._delegate,
|
source: this.actor._delegate,
|
||||||
targetActor: target
|
targetActor: target
|
||||||
};
|
};
|
||||||
|
|
||||||
|
let targetActorDestroyHandlerId;
|
||||||
|
let handleTargetActorDestroyClosure;
|
||||||
|
handleTargetActorDestroyClosure = () => {
|
||||||
|
target = this._pickTargetActor();
|
||||||
|
dragEvent.targetActor = target;
|
||||||
|
targetActorDestroyHandlerId =
|
||||||
|
target.connect('destroy', handleTargetActorDestroyClosure);
|
||||||
|
};
|
||||||
|
targetActorDestroyHandlerId =
|
||||||
|
target.connect('destroy', handleTargetActorDestroyClosure);
|
||||||
|
|
||||||
for (let i = 0; i < dragMonitors.length; i++) {
|
for (let i = 0; i < dragMonitors.length; i++) {
|
||||||
let motionFunc = dragMonitors[i].dragMotion;
|
let motionFunc = dragMonitors[i].dragMotion;
|
||||||
if (motionFunc) {
|
if (motionFunc) {
|
||||||
@ -417,6 +449,7 @@ var _Draggable = new Lang.Class({
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
dragEvent.targetActor.disconnect(targetActorDestroyHandlerId);
|
||||||
|
|
||||||
while (target) {
|
while (target) {
|
||||||
if (target._delegate && target._delegate.handleDragOver) {
|
if (target._delegate && target._delegate.handleDragOver) {
|
||||||
@ -500,7 +533,7 @@ var _Draggable = new Lang.Class({
|
|||||||
event.get_time())) {
|
event.get_time())) {
|
||||||
// If it accepted the drop without taking the actor,
|
// If it accepted the drop without taking the actor,
|
||||||
// handle it ourselves.
|
// handle it ourselves.
|
||||||
if (this._dragActor.get_parent() == Main.uiGroup) {
|
if (this._dragActor && this._dragActor.get_parent() == Main.uiGroup) {
|
||||||
if (this._restoreOnSuccess) {
|
if (this._restoreOnSuccess) {
|
||||||
this._restoreDragActor(event.get_time());
|
this._restoreDragActor(event.get_time());
|
||||||
return true;
|
return true;
|
||||||
@ -508,7 +541,7 @@ var _Draggable = new Lang.Class({
|
|||||||
this._dragActor.destroy();
|
this._dragActor.destroy();
|
||||||
}
|
}
|
||||||
|
|
||||||
this._dragInProgress = false;
|
this._dragState = DragState.INIT;
|
||||||
global.screen.set_cursor(Meta.Cursor.DEFAULT);
|
global.screen.set_cursor(Meta.Cursor.DEFAULT);
|
||||||
this.emit('drag-end', event.get_time(), true);
|
this.emit('drag-end', event.get_time(), true);
|
||||||
this._dragComplete();
|
this._dragComplete();
|
||||||
@ -557,20 +590,22 @@ var _Draggable = new Lang.Class({
|
|||||||
|
|
||||||
_cancelDrag(eventTime) {
|
_cancelDrag(eventTime) {
|
||||||
this.emit('drag-cancelled', eventTime);
|
this.emit('drag-cancelled', eventTime);
|
||||||
this._dragInProgress = false;
|
let wasCancelled = (this._dragState == DragState.CANCELLED);
|
||||||
let [snapBackX, snapBackY, snapBackScale] = this._getRestoreLocation();
|
this._dragState = DragState.CANCELLED;
|
||||||
|
|
||||||
if (this._actorDestroyed) {
|
if (this._actorDestroyed || wasCancelled) {
|
||||||
global.screen.set_cursor(Meta.Cursor.DEFAULT);
|
global.screen.set_cursor(Meta.Cursor.DEFAULT);
|
||||||
if (!this._buttonDown)
|
if (!this._buttonDown)
|
||||||
this._dragComplete();
|
this._dragComplete();
|
||||||
this.emit('drag-end', eventTime, false);
|
this.emit('drag-end', eventTime, false);
|
||||||
if (!this._dragOrigParent)
|
if (!this._dragOrigParent && this._dragActor)
|
||||||
this._dragActor.destroy();
|
this._dragActor.destroy();
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let [snapBackX, snapBackY, snapBackScale] = this._getRestoreLocation();
|
||||||
|
|
||||||
this._animateDragEnd(eventTime,
|
this._animateDragEnd(eventTime,
|
||||||
{ x: snapBackX,
|
{ x: snapBackX,
|
||||||
y: snapBackY,
|
y: snapBackY,
|
||||||
@ -581,7 +616,7 @@ var _Draggable = new Lang.Class({
|
|||||||
},
|
},
|
||||||
|
|
||||||
_restoreDragActor(eventTime) {
|
_restoreDragActor(eventTime) {
|
||||||
this._dragInProgress = false;
|
this._dragState = DragState.INIT;
|
||||||
let [restoreX, restoreY, restoreScale] = this._getRestoreLocation();
|
let [restoreX, restoreY, restoreScale] = this._getRestoreLocation();
|
||||||
|
|
||||||
// fade the actor back in at its original location
|
// fade the actor back in at its original location
|
||||||
@ -596,12 +631,6 @@ var _Draggable = new Lang.Class({
|
|||||||
_animateDragEnd(eventTime, params) {
|
_animateDragEnd(eventTime, params) {
|
||||||
this._animationInProgress = true;
|
this._animationInProgress = true;
|
||||||
|
|
||||||
// finish animation if the actor gets destroyed
|
|
||||||
// during it
|
|
||||||
this._dragActorDestroyId =
|
|
||||||
this._dragActor.connect('destroy',
|
|
||||||
this._finishAnimation.bind(this));
|
|
||||||
|
|
||||||
params['opacity'] = this._dragOrigOpacity;
|
params['opacity'] = this._dragOrigOpacity;
|
||||||
params['transition'] = 'easeOutQuad';
|
params['transition'] = 'easeOutQuad';
|
||||||
params['onComplete'] = this._onAnimationComplete;
|
params['onComplete'] = this._onAnimationComplete;
|
||||||
@ -624,9 +653,6 @@ var _Draggable = new Lang.Class({
|
|||||||
},
|
},
|
||||||
|
|
||||||
_onAnimationComplete(dragActor, eventTime) {
|
_onAnimationComplete(dragActor, eventTime) {
|
||||||
dragActor.disconnect(this._dragActorDestroyId);
|
|
||||||
this._dragActorDestroyId = 0;
|
|
||||||
|
|
||||||
if (this._dragOrigParent) {
|
if (this._dragOrigParent) {
|
||||||
Main.uiGroup.remove_child(this._dragActor);
|
Main.uiGroup.remove_child(this._dragActor);
|
||||||
this._dragOrigParent.add_actor(this._dragActor);
|
this._dragOrigParent.add_actor(this._dragActor);
|
||||||
@ -641,7 +667,7 @@ var _Draggable = new Lang.Class({
|
|||||||
},
|
},
|
||||||
|
|
||||||
_dragComplete() {
|
_dragComplete() {
|
||||||
if (!this._actorDestroyed)
|
if (!this._actorDestroyed && this._dragActor)
|
||||||
Shell.util_set_hidden_from_pick(this._dragActor, false);
|
Shell.util_set_hidden_from_pick(this._dragActor, false);
|
||||||
|
|
||||||
this._ungrabEvents();
|
this._ungrabEvents();
|
||||||
@ -652,7 +678,12 @@ var _Draggable = new Lang.Class({
|
|||||||
this._updateHoverId = 0;
|
this._updateHoverId = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
this._dragActor = undefined;
|
if (this._dragActor) {
|
||||||
|
this._dragActor.disconnect(this._dragActorDestroyId);
|
||||||
|
this._dragActor = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
this._dragState = DragState.INIT;
|
||||||
currentDraggable = null;
|
currentDraggable = null;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -7,6 +7,7 @@ const GLib = imports.gi.GLib;
|
|||||||
const Gio = imports.gi.Gio;
|
const Gio = imports.gi.Gio;
|
||||||
const St = imports.gi.St;
|
const St = imports.gi.St;
|
||||||
|
|
||||||
|
const Config = imports.misc.config;
|
||||||
const ExtensionUtils = imports.misc.extensionUtils;
|
const ExtensionUtils = imports.misc.extensionUtils;
|
||||||
const Main = imports.ui.main;
|
const Main = imports.ui.main;
|
||||||
|
|
||||||
@ -306,6 +307,36 @@ function _onVersionValidationChanged() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function _doUpdateCheck() {
|
||||||
|
let version = Config.PACKAGE_VERSION.split('.');
|
||||||
|
if (parseInt(version[1]) % 2 == 0)
|
||||||
|
version.pop();
|
||||||
|
|
||||||
|
let pkgCacheDir = GLib.get_user_cache_dir() + '/gnome-shell/';
|
||||||
|
let updateStamp = Gio.file_new_for_path(pkgCacheDir +
|
||||||
|
'update-check-' + version.join('.'));
|
||||||
|
if (updateStamp.query_exists(null))
|
||||||
|
return;
|
||||||
|
|
||||||
|
GLib.mkdir_with_parents (pkgCacheDir, 0o755);
|
||||||
|
updateStamp.create(0, null).close(null);
|
||||||
|
|
||||||
|
let nOutdated = enabledExtensions.reduce(function(n, uuid) {
|
||||||
|
let extension = ExtensionUtils.extensions[uuid];
|
||||||
|
if (extension && extension.state == ExtensionState.OUT_OF_DATE)
|
||||||
|
n++;
|
||||||
|
return n;
|
||||||
|
}, 0);
|
||||||
|
|
||||||
|
if (nOutdated == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
Main.notify(ngettext("%d extension is out of date",
|
||||||
|
"%d extensions are out of date",
|
||||||
|
nOutdated).format(nOutdated),
|
||||||
|
_("You can visit http://extensions.gnome.org for updates"));
|
||||||
|
}
|
||||||
|
|
||||||
function _loadExtensions() {
|
function _loadExtensions() {
|
||||||
global.settings.connect('changed::' + ENABLED_EXTENSIONS_KEY, onEnabledExtensionsChanged);
|
global.settings.connect('changed::' + ENABLED_EXTENSIONS_KEY, onEnabledExtensionsChanged);
|
||||||
global.settings.connect('changed::' + DISABLE_USER_EXTENSIONS_KEY, onEnabledExtensionsChanged);
|
global.settings.connect('changed::' + DISABLE_USER_EXTENSIONS_KEY, onEnabledExtensionsChanged);
|
||||||
@ -316,8 +347,11 @@ function _loadExtensions() {
|
|||||||
let finder = new ExtensionUtils.ExtensionFinder();
|
let finder = new ExtensionUtils.ExtensionFinder();
|
||||||
finder.connect('extension-found', (finder, extension) => {
|
finder.connect('extension-found', (finder, extension) => {
|
||||||
loadExtension(extension);
|
loadExtension(extension);
|
||||||
|
if (Main.sessionMode.enabledExtensions.indexOf(extension.uuid) != -1)
|
||||||
|
extension.type = ExtensionUtils.ExtensionType.SESSION_MODE;
|
||||||
});
|
});
|
||||||
finder.scanExtensions();
|
finder.scanExtensions();
|
||||||
|
_doUpdateCheck();
|
||||||
}
|
}
|
||||||
|
|
||||||
function enableAllExtensions() {
|
function enableAllExtensions() {
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
|
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
|
||||||
|
|
||||||
const FocusCaretTracker = imports.ui.focusCaretTracker;
|
|
||||||
const Atspi = imports.gi.Atspi;
|
const Atspi = imports.gi.Atspi;
|
||||||
const Clutter = imports.gi.Clutter;
|
const Clutter = imports.gi.Clutter;
|
||||||
const Gdk = imports.gi.Gdk;
|
const Gdk = imports.gi.Gdk;
|
||||||
@ -13,6 +12,7 @@ const Signals = imports.signals;
|
|||||||
const St = imports.gi.St;
|
const St = imports.gi.St;
|
||||||
const InputSourceManager = imports.ui.status.keyboard;
|
const InputSourceManager = imports.ui.status.keyboard;
|
||||||
|
|
||||||
|
const IBusManager = imports.misc.ibusManager;
|
||||||
const BoxPointer = imports.ui.boxpointer;
|
const BoxPointer = imports.ui.boxpointer;
|
||||||
const Layout = imports.ui.layout;
|
const Layout = imports.ui.layout;
|
||||||
const Main = imports.ui.main;
|
const Main = imports.ui.main;
|
||||||
@ -261,6 +261,7 @@ var Key = new Lang.Class({
|
|||||||
this._extended_keyboard = null;
|
this._extended_keyboard = null;
|
||||||
this._pressTimeoutId = 0;
|
this._pressTimeoutId = 0;
|
||||||
this._capturedPress = false;
|
this._capturedPress = false;
|
||||||
|
|
||||||
this._capturedEventId = 0;
|
this._capturedEventId = 0;
|
||||||
this._unmapId = 0;
|
this._unmapId = 0;
|
||||||
this._longPress = false;
|
this._longPress = false;
|
||||||
@ -484,6 +485,79 @@ var KeyboardModel = new Lang.Class({
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
var FocusTracker = new Lang.Class({
|
||||||
|
Name: 'FocusTracker',
|
||||||
|
|
||||||
|
_init() {
|
||||||
|
this._currentWindow = null;
|
||||||
|
this._currentWindowPositionId = 0;
|
||||||
|
|
||||||
|
global.screen.get_display().connect('notify::focus-window', () => {
|
||||||
|
this._setCurrentWindow(global.screen.get_display().focus_window);
|
||||||
|
this.emit('window-changed', this._currentWindow);
|
||||||
|
});
|
||||||
|
|
||||||
|
/* Valid for wayland clients */
|
||||||
|
Main.inputMethod.connect('cursor-location-changed', (o, rect) => {
|
||||||
|
let newRect = { x: rect.get_x(), y: rect.get_y(), width: rect.get_width(), height: rect.get_height() };
|
||||||
|
this._setCurrentRect(newRect);
|
||||||
|
});
|
||||||
|
|
||||||
|
this._ibusManager = IBusManager.getIBusManager();
|
||||||
|
this._ibusManager.connect('set-cursor-location', (manager, rect) => {
|
||||||
|
/* Valid for X11 clients only */
|
||||||
|
if (Main.inputMethod.currentFocus)
|
||||||
|
return;
|
||||||
|
|
||||||
|
this._setCurrentRect(rect);
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
get currentWindow() {
|
||||||
|
return this._currentWindow;
|
||||||
|
},
|
||||||
|
|
||||||
|
_setCurrentWindow(window) {
|
||||||
|
if (this._currentWindow)
|
||||||
|
this._currentWindow.disconnect(this._currentWindowPositionId);
|
||||||
|
|
||||||
|
this._currentWindow = window;
|
||||||
|
if (window) {
|
||||||
|
this._currentWindowPositionId = this._currentWindow.connect('position-changed', () => {
|
||||||
|
if (global.display.get_grab_op() == Meta.GrabOp.NONE)
|
||||||
|
this.emit('position-changed');
|
||||||
|
else
|
||||||
|
this.emit('reset');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
_setCurrentRect(rect) {
|
||||||
|
if (this._currentWindow) {
|
||||||
|
let frameRect = this._currentWindow.get_frame_rect();
|
||||||
|
rect.x -= frameRect.x;
|
||||||
|
rect.y -= frameRect.y;
|
||||||
|
}
|
||||||
|
|
||||||
|
this._rect = rect;
|
||||||
|
this.emit('position-changed');
|
||||||
|
},
|
||||||
|
|
||||||
|
getCurrentRect() {
|
||||||
|
let rect = { x: this._rect.x, y: this._rect.y,
|
||||||
|
width: this._rect.width, height: this._rect.height };
|
||||||
|
|
||||||
|
if (this._currentWindow) {
|
||||||
|
let frameRect = this._currentWindow.get_frame_rect();
|
||||||
|
rect.x += frameRect.x;
|
||||||
|
rect.y += frameRect.y;
|
||||||
|
}
|
||||||
|
|
||||||
|
return rect;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
Signals.addSignalMethods(FocusTracker.prototype);
|
||||||
|
|
||||||
var Keyboard = new Lang.Class({
|
var Keyboard = new Lang.Class({
|
||||||
Name: 'Keyboard',
|
Name: 'Keyboard',
|
||||||
|
|
||||||
@ -491,15 +565,10 @@ var Keyboard = new Lang.Class({
|
|||||||
this.actor = null;
|
this.actor = null;
|
||||||
this._focusInExtendedKeys = false;
|
this._focusInExtendedKeys = false;
|
||||||
|
|
||||||
this._focusCaretTracker = new FocusCaretTracker.FocusCaretTracker();
|
|
||||||
this._focusCaretTracker.connect('focus-changed', this._onFocusChanged.bind(this));
|
|
||||||
this._focusCaretTracker.connect('caret-moved', this._onCaretMoved.bind(this));
|
|
||||||
this._languagePopup = null;
|
this._languagePopup = null;
|
||||||
this._currentAccessible = null;
|
|
||||||
this._caretTrackingEnabled = false;
|
|
||||||
this._updateCaretPositionId = 0;
|
|
||||||
this._currentFocusWindow = null;
|
this._currentFocusWindow = null;
|
||||||
this._originalWindowY = null;
|
this._animFocusedWindow = null;
|
||||||
|
this._delayedAnimFocusWindow = null;
|
||||||
|
|
||||||
this._enableKeyboard = false; // a11y settings value
|
this._enableKeyboard = false; // a11y settings value
|
||||||
this._enabled = false; // enabled state (by setting or device type)
|
this._enabled = false; // enabled state (by setting or device type)
|
||||||
@ -510,6 +579,14 @@ var Keyboard = new Lang.Class({
|
|||||||
this._lastDeviceId = null;
|
this._lastDeviceId = null;
|
||||||
this._suggestions = null;
|
this._suggestions = null;
|
||||||
|
|
||||||
|
this._focusTracker = new FocusTracker();
|
||||||
|
this._focusTracker.connect('position-changed', this._onFocusPositionChanged.bind(this));
|
||||||
|
this._focusTracker.connect('reset', () => {
|
||||||
|
this._delayedAnimFocusWindow = null;
|
||||||
|
this._animFocusedWindow = null;
|
||||||
|
this._oskFocusWindow = null;
|
||||||
|
});
|
||||||
|
|
||||||
Meta.get_backend().connect('last-device-changed',
|
Meta.get_backend().connect('last-device-changed',
|
||||||
(backend, deviceId) => {
|
(backend, deviceId) => {
|
||||||
let manager = Clutter.DeviceManager.get_default();
|
let manager = Clutter.DeviceManager.get_default();
|
||||||
@ -532,102 +609,15 @@ var Keyboard = new Lang.Class({
|
|||||||
this._keyboardRestingId = 0;
|
this._keyboardRestingId = 0;
|
||||||
|
|
||||||
Main.layoutManager.connect('monitors-changed', this._relayout.bind(this));
|
Main.layoutManager.connect('monitors-changed', this._relayout.bind(this));
|
||||||
//Main.inputMethod.connect('cursor-location-changed', (o, rect) => {
|
|
||||||
// if (this._keyboardVisible) {
|
|
||||||
// let currentWindow = global.screen.get_display().focus_window;
|
|
||||||
// this.setCursorLocation(currentWindow, rect.get_x(), rect.get_y(),
|
|
||||||
// rect.get_width(), rect.get_height());
|
|
||||||
// }
|
|
||||||
//});
|
|
||||||
},
|
},
|
||||||
|
|
||||||
get visible() {
|
get visible() {
|
||||||
return this._keyboardVisible;
|
return this._keyboardVisible;
|
||||||
},
|
},
|
||||||
|
|
||||||
_setCaretTrackerEnabled(enabled) {
|
_onFocusPositionChanged(focusTracker) {
|
||||||
if (this._caretTrackingEnabled == enabled)
|
let rect = focusTracker.getCurrentRect();
|
||||||
return;
|
this.setCursorLocation(focusTracker.currentWindow, rect.x, rect.y, rect.width, rect.height);
|
||||||
|
|
||||||
this._caretTrackingEnabled = enabled;
|
|
||||||
|
|
||||||
if (enabled) {
|
|
||||||
this._focusCaretTracker.registerFocusListener();
|
|
||||||
this._focusCaretTracker.registerCaretListener();
|
|
||||||
} else {
|
|
||||||
this._focusCaretTracker.deregisterFocusListener();
|
|
||||||
this._focusCaretTracker.deregisterCaretListener();
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
_updateCaretPosition(accessible) {
|
|
||||||
if (this._updateCaretPositionId)
|
|
||||||
GLib.source_remove(this._updateCaretPositionId);
|
|
||||||
if (!this._keyboardRequested)
|
|
||||||
return;
|
|
||||||
this._updateCaretPositionId = GLib.idle_add(GLib.PRIORITY_DEFAULT_IDLE, () => {
|
|
||||||
this._updateCaretPositionId = 0;
|
|
||||||
|
|
||||||
let currentWindow = global.screen.get_display().focus_window;
|
|
||||||
if (!currentWindow) {
|
|
||||||
this.setCursorLocation(null);
|
|
||||||
return GLib.SOURCE_REMOVE;
|
|
||||||
}
|
|
||||||
|
|
||||||
let windowRect = currentWindow.get_frame_rect();
|
|
||||||
let text = accessible.get_text_iface();
|
|
||||||
let component = accessible.get_component_iface();
|
|
||||||
|
|
||||||
try {
|
|
||||||
let caretOffset = text.get_caret_offset();
|
|
||||||
let caretRect = text.get_character_extents(caretOffset, Atspi.CoordType.WINDOW);
|
|
||||||
let focusRect = component.get_extents(Atspi.CoordType.WINDOW);
|
|
||||||
|
|
||||||
if (caretRect.width == 0 && caretRect.height == 0)
|
|
||||||
caretRect = focusRect;
|
|
||||||
|
|
||||||
this.setCursorLocation(currentWindow, caretRect.x, caretRect.y, caretRect.width, caretRect.height);
|
|
||||||
} catch (e) {
|
|
||||||
log('Error updating caret position for OSK: ' + e.message);
|
|
||||||
}
|
|
||||||
|
|
||||||
return GLib.SOURCE_REMOVE;
|
|
||||||
});
|
|
||||||
|
|
||||||
GLib.Source.set_name_by_id(this._updateCaretPositionId, '[gnome-shell] this._updateCaretPosition');
|
|
||||||
},
|
|
||||||
|
|
||||||
_focusIsTextEntry(accessible) {
|
|
||||||
try {
|
|
||||||
let role = accessible.get_role();
|
|
||||||
let stateSet = accessible.get_state_set();
|
|
||||||
return stateSet.contains(Atspi.StateType.EDITABLE) || role == Atspi.Role.TERMINAL;
|
|
||||||
} catch (e) {
|
|
||||||
log('Error determining accessible role: ' + e.message);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
_onFocusChanged(caretTracker, event) {
|
|
||||||
let accessible = event.source;
|
|
||||||
if (!this._focusIsTextEntry(accessible))
|
|
||||||
return;
|
|
||||||
|
|
||||||
let focused = event.detail1 != 0;
|
|
||||||
if (focused) {
|
|
||||||
this._currentAccessible = accessible;
|
|
||||||
this._updateCaretPosition(accessible);
|
|
||||||
this.show(Main.layoutManager.focusIndex);
|
|
||||||
} else if (this._currentAccessible == accessible) {
|
|
||||||
this._currentAccessible = null;
|
|
||||||
this.hide();
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
_onCaretMoved(caretTracker, event) {
|
|
||||||
let accessible = event.source;
|
|
||||||
if (this._currentAccessible == accessible)
|
|
||||||
this._updateCaretPosition(accessible);
|
|
||||||
},
|
},
|
||||||
|
|
||||||
_lastDeviceIsTouchscreen() {
|
_lastDeviceIsTouchscreen() {
|
||||||
@ -650,8 +640,6 @@ var Keyboard = new Lang.Class({
|
|||||||
if (!this._enabled && !this._keyboardController)
|
if (!this._enabled && !this._keyboardController)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
this._setCaretTrackerEnabled(this._enabled);
|
|
||||||
|
|
||||||
if (this._enabled && !this._keyboardController)
|
if (this._enabled && !this._keyboardController)
|
||||||
this._setupKeyboard();
|
this._setupKeyboard();
|
||||||
else if (!this._enabled)
|
else if (!this._enabled)
|
||||||
@ -1027,11 +1015,14 @@ var Keyboard = new Lang.Class({
|
|||||||
if (!this._keyboardRequested)
|
if (!this._keyboardRequested)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (this._currentAccessible)
|
|
||||||
this._updateCaretPosition(this._currentAccessible);
|
|
||||||
Main.layoutManager.keyboardIndex = monitor;
|
Main.layoutManager.keyboardIndex = monitor;
|
||||||
this._relayout();
|
this._relayout();
|
||||||
Main.layoutManager.showKeyboard();
|
Main.layoutManager.showKeyboard();
|
||||||
|
|
||||||
|
if (this._delayedAnimFocusWindow) {
|
||||||
|
this._setAnimationWindow(this._delayedAnimFocusWindow);
|
||||||
|
this._delayedAnimFocusWindow = null;
|
||||||
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
hide() {
|
hide() {
|
||||||
@ -1102,8 +1093,9 @@ var Keyboard = new Lang.Class({
|
|||||||
window.move_frame(true, frameRect.x, frameRect.y);
|
window.move_frame(true, frameRect.x, frameRect.y);
|
||||||
},
|
},
|
||||||
|
|
||||||
_animateWindow(window, show, deltaY) {
|
_animateWindow(window, show) {
|
||||||
let windowActor = window.get_compositor_private();
|
let windowActor = window.get_compositor_private();
|
||||||
|
let deltaY = Main.layoutManager.keyboardBox.height;
|
||||||
if (!windowActor)
|
if (!windowActor)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@ -1124,35 +1116,39 @@ var Keyboard = new Lang.Class({
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
setCursorLocation(window, x, y , w, h) {
|
_setAnimationWindow(window) {
|
||||||
if (window == this._oskFocusWindow)
|
if (this._animFocusedWindow == window)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (this._oskFocusWindow) {
|
if (this._animFocusedWindow)
|
||||||
let display = global.screen.get_display();
|
this._animateWindow(this._animFocusedWindow, false);
|
||||||
|
if (window)
|
||||||
|
this._animateWindow(window, true);
|
||||||
|
|
||||||
if (display.get_grab_op() == Meta.GrabOp.NONE ||
|
this._animFocusedWindow = window;
|
||||||
display.get_focus_window() != this._oskFocusWindow)
|
},
|
||||||
this._animateWindow(this._oskFocusWindow, false, this._oskFocusWindowDelta);
|
|
||||||
|
|
||||||
this._oskFocusWindow = null;
|
setCursorLocation(window, x, y , w, h) {
|
||||||
this._oskFocusWindowDelta = null;
|
let monitor = Main.layoutManager.keyboardMonitor;
|
||||||
}
|
|
||||||
|
|
||||||
if (window) {
|
if (window && monitor) {
|
||||||
let monitor = Main.layoutManager.keyboardMonitor;
|
|
||||||
let keyboardHeight = Main.layoutManager.keyboardBox.height;
|
let keyboardHeight = Main.layoutManager.keyboardBox.height;
|
||||||
let frameRect = window.get_frame_rect();
|
let focusObscured = false;
|
||||||
let windowActor = window.get_compositor_private();
|
|
||||||
let delta = 0;
|
|
||||||
|
|
||||||
if (frameRect.y + y + h >= monitor.height - keyboardHeight)
|
if (y + h >= monitor.y + monitor.height - keyboardHeight) {
|
||||||
delta = keyboardHeight;
|
if (this._keyboardVisible)
|
||||||
|
this._setAnimationWindow(window);
|
||||||
this._animateWindow(window, true, delta);
|
else
|
||||||
this._oskFocusWindow = window;
|
this._delayedAnimFocusWindow = window;
|
||||||
this._oskFocusWindowDelta = delta;
|
} else if (y < keyboardHeight) {
|
||||||
|
this._delayedAnimFocusWindow = null;
|
||||||
|
this._setAnimationWindow(null);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
this._setAnimationWindow(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this._oskFocusWindow = window;
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -278,18 +278,6 @@ var LayoutManager = new Lang.Class({
|
|||||||
global.screen.connect('in-fullscreen-changed',
|
global.screen.connect('in-fullscreen-changed',
|
||||||
this._updateFullscreen.bind(this));
|
this._updateFullscreen.bind(this));
|
||||||
this._monitorsChanged();
|
this._monitorsChanged();
|
||||||
|
|
||||||
// NVIDIA drivers don't preserve FBO contents across
|
|
||||||
// suspend/resume, see
|
|
||||||
// https://bugzilla.gnome.org/show_bug.cgi?id=739178
|
|
||||||
if (Shell.util_need_background_refresh()) {
|
|
||||||
LoginManager.getLoginManager().connect('prepare-for-sleep',
|
|
||||||
(lm, suspending) => {
|
|
||||||
if (suspending)
|
|
||||||
return;
|
|
||||||
Meta.Background.refresh_all();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
|
|
||||||
// This is called by Main after everything else is constructed
|
// This is called by Main after everything else is constructed
|
||||||
|
@ -19,7 +19,6 @@ const MagnifierDBus = imports.ui.magnifierDBus;
|
|||||||
const Params = imports.misc.params;
|
const Params = imports.misc.params;
|
||||||
const PointerWatcher = imports.ui.pointerWatcher;
|
const PointerWatcher = imports.ui.pointerWatcher;
|
||||||
|
|
||||||
var MOUSE_POLL_FREQUENCY = 50;
|
|
||||||
var CROSSHAIRS_CLIP_SIZE = [100, 100];
|
var CROSSHAIRS_CLIP_SIZE = [100, 100];
|
||||||
var NO_CHANGE = 0.0;
|
var NO_CHANGE = 0.0;
|
||||||
|
|
||||||
@ -152,8 +151,10 @@ var Magnifier = new Lang.Class({
|
|||||||
* Turn on mouse tracking, if not already doing so.
|
* Turn on mouse tracking, if not already doing so.
|
||||||
*/
|
*/
|
||||||
startTrackingMouse() {
|
startTrackingMouse() {
|
||||||
if (!this._pointerWatch)
|
if (!this._pointerWatch) {
|
||||||
this._pointerWatch = PointerWatcher.getPointerWatcher().addWatch(MOUSE_POLL_FREQUENCY, this.scrollToMousePos.bind(this));
|
let interval = 1000 / Clutter.get_default_frame_rate();
|
||||||
|
this._pointerWatch = PointerWatcher.getPointerWatcher().addWatch(interval, this.scrollToMousePos.bind(this));
|
||||||
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -20,6 +20,7 @@ const Environment = imports.ui.environment;
|
|||||||
const ExtensionSystem = imports.ui.extensionSystem;
|
const ExtensionSystem = imports.ui.extensionSystem;
|
||||||
const ExtensionDownloader = imports.ui.extensionDownloader;
|
const ExtensionDownloader = imports.ui.extensionDownloader;
|
||||||
const InputMethod = imports.misc.inputMethod;
|
const InputMethod = imports.misc.inputMethod;
|
||||||
|
const Introspect = imports.misc.introspect;
|
||||||
const Keyboard = imports.ui.keyboard;
|
const Keyboard = imports.ui.keyboard;
|
||||||
const MessageTray = imports.ui.messageTray;
|
const MessageTray = imports.ui.messageTray;
|
||||||
const ModalDialog = imports.ui.modalDialog;
|
const ModalDialog = imports.ui.modalDialog;
|
||||||
@ -82,6 +83,7 @@ var keyboard = null;
|
|||||||
var layoutManager = null;
|
var layoutManager = null;
|
||||||
var kbdA11yDialog = null;
|
var kbdA11yDialog = null;
|
||||||
var inputMethod = null;
|
var inputMethod = null;
|
||||||
|
var introspectService = null;
|
||||||
let _startDate;
|
let _startDate;
|
||||||
let _defaultCssStylesheet = null;
|
let _defaultCssStylesheet = null;
|
||||||
let _cssStylesheet = null;
|
let _cssStylesheet = null;
|
||||||
@ -187,6 +189,8 @@ function _initializeUI() {
|
|||||||
windowAttentionHandler = new WindowAttentionHandler.WindowAttentionHandler();
|
windowAttentionHandler = new WindowAttentionHandler.WindowAttentionHandler();
|
||||||
componentManager = new Components.ComponentManager();
|
componentManager = new Components.ComponentManager();
|
||||||
|
|
||||||
|
introspectService = new Introspect.IntrospectService();
|
||||||
|
|
||||||
layoutManager.init();
|
layoutManager.init();
|
||||||
overview.init();
|
overview.init();
|
||||||
|
|
||||||
@ -207,7 +211,11 @@ function _initializeUI() {
|
|||||||
return true;
|
return true;
|
||||||
});
|
});
|
||||||
|
|
||||||
global.display.connect('gl-video-memory-purged', loadTheme);
|
global.display.connect('gl-video-memory-purged', () => {
|
||||||
|
let cache = St.TextureCache.get_default();
|
||||||
|
cache.clear();
|
||||||
|
loadTheme();
|
||||||
|
});
|
||||||
|
|
||||||
// Provide the bus object for gnome-session to
|
// Provide the bus object for gnome-session to
|
||||||
// initiate logouts.
|
// initiate logouts.
|
||||||
@ -256,6 +264,14 @@ function _getStylesheet(name) {
|
|||||||
if (stylesheet.query_exists(null))
|
if (stylesheet.query_exists(null))
|
||||||
return stylesheet;
|
return stylesheet;
|
||||||
|
|
||||||
|
let dataDirs = GLib.get_system_data_dirs();
|
||||||
|
for (let i = 0; i < dataDirs.length; i++) {
|
||||||
|
let path = GLib.build_filenamev([dataDirs[i], 'gnome-shell', 'theme', name]);
|
||||||
|
let stylesheet = Gio.file_new_for_path(path);
|
||||||
|
if (stylesheet.query_exists(null))
|
||||||
|
return stylesheet;
|
||||||
|
}
|
||||||
|
|
||||||
stylesheet = Gio.File.new_for_path(global.datadir + '/theme/' + name);
|
stylesheet = Gio.File.new_for_path(global.datadir + '/theme/' + name);
|
||||||
if (stylesheet.query_exists(null))
|
if (stylesheet.query_exists(null))
|
||||||
return stylesheet;
|
return stylesheet;
|
||||||
|
@ -362,7 +362,8 @@ var Message = new Lang.Class({
|
|||||||
this.setBody(body);
|
this.setBody(body);
|
||||||
|
|
||||||
this._closeButton.connect('clicked', this.close.bind(this));
|
this._closeButton.connect('clicked', this.close.bind(this));
|
||||||
this.actor.connect('notify::hover', this._sync.bind(this));
|
let actorHoverId = this.actor.connect('notify::hover', this._sync.bind(this));
|
||||||
|
this._closeButton.connect('destroy', this.actor.disconnect.bind(this.actor, actorHoverId));
|
||||||
this.actor.connect('clicked', this._onClicked.bind(this));
|
this.actor.connect('clicked', this._onClicked.bind(this));
|
||||||
this.actor.connect('destroy', this._onDestroy.bind(this));
|
this.actor.connect('destroy', this._onDestroy.bind(this));
|
||||||
this._sync();
|
this._sync();
|
||||||
|
@ -108,15 +108,30 @@ var OsdWindow = new Lang.Class({
|
|||||||
this._hideTimeoutId = 0;
|
this._hideTimeoutId = 0;
|
||||||
this._reset();
|
this._reset();
|
||||||
|
|
||||||
Main.layoutManager.connect('monitors-changed',
|
this.actor.connect('destroy', this._onDestroy.bind(this));
|
||||||
this._relayout.bind(this));
|
|
||||||
|
this._monitorsChangedId =
|
||||||
|
Main.layoutManager.connect('monitors-changed',
|
||||||
|
this._relayout.bind(this));
|
||||||
let themeContext = St.ThemeContext.get_for_stage(global.stage);
|
let themeContext = St.ThemeContext.get_for_stage(global.stage);
|
||||||
themeContext.connect('notify::scale-factor',
|
this._scaleChangedId =
|
||||||
this._relayout.bind(this));
|
themeContext.connect('notify::scale-factor',
|
||||||
|
this._relayout.bind(this));
|
||||||
this._relayout();
|
this._relayout();
|
||||||
Main.uiGroup.add_child(this.actor);
|
Main.uiGroup.add_child(this.actor);
|
||||||
},
|
},
|
||||||
|
|
||||||
|
_onDestroy() {
|
||||||
|
if (this._monitorsChangedId)
|
||||||
|
Main.layoutManager.disconnect(this._monitorsChangedId);
|
||||||
|
this._monitorsChangedId = 0;
|
||||||
|
|
||||||
|
let themeContext = St.ThemeContext.get_for_stage(global.stage);
|
||||||
|
if (this._scaleChangedId)
|
||||||
|
themeContext.disconnect(this._scaleChangedId);
|
||||||
|
this._scaleChangedId = 0;
|
||||||
|
},
|
||||||
|
|
||||||
setIcon(icon) {
|
setIcon(icon) {
|
||||||
this._icon.gicon = icon;
|
this._icon.gicon = icon;
|
||||||
},
|
},
|
||||||
@ -204,7 +219,7 @@ var OsdWindow = new Lang.Class({
|
|||||||
|
|
||||||
let scaleFactor = St.ThemeContext.get_for_stage(global.stage).scale_factor;
|
let scaleFactor = St.ThemeContext.get_for_stage(global.stage).scale_factor;
|
||||||
this._icon.icon_size = popupSize / (2 * scaleFactor);
|
this._icon.icon_size = popupSize / (2 * scaleFactor);
|
||||||
this._box.translation_y = monitor.height / 4;
|
this._box.translation_y = Math.round(monitor.height / 4);
|
||||||
this._boxConstraint.minSize = popupSize;
|
this._boxConstraint.minSize = popupSize;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -406,11 +406,18 @@ var ActivitiesButton = new Lang.Class({
|
|||||||
|
|
||||||
this.actor.name = 'panelActivities';
|
this.actor.name = 'panelActivities';
|
||||||
|
|
||||||
|
let box = new St.BoxLayout();
|
||||||
|
this.actor.add_actor(box);
|
||||||
|
let iconFile = Gio.File.new_for_path('/usr/share/icons/hicolor/scalable/apps/start-here.svg');
|
||||||
|
this._icon = new St.Icon({ gicon: new Gio.FileIcon({ file: iconFile }),
|
||||||
|
style_class: 'panel-logo-icon' });
|
||||||
|
box.add_actor(this._icon);
|
||||||
|
|
||||||
/* Translators: If there is no suitable word for "Activities"
|
/* Translators: If there is no suitable word for "Activities"
|
||||||
in your language, you can use the word for "Overview". */
|
in your language, you can use the word for "Overview". */
|
||||||
this._label = new St.Label({ text: _("Activities"),
|
this._label = new St.Label({ text: _("Activities"),
|
||||||
y_align: Clutter.ActorAlign.CENTER });
|
y_align: Clutter.ActorAlign.CENTER });
|
||||||
this.actor.add_actor(this._label);
|
box.add_actor(this._label);
|
||||||
|
|
||||||
this.actor.label_actor = this._label;
|
this.actor.label_actor = this._label;
|
||||||
|
|
||||||
@ -709,6 +716,7 @@ var AggregateMenu = new Lang.Class({
|
|||||||
this._bluetooth = null;
|
this._bluetooth = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this._remoteAccess = new imports.ui.status.remoteAccess.RemoteAccessApplet();
|
||||||
this._power = new imports.ui.status.power.Indicator();
|
this._power = new imports.ui.status.power.Indicator();
|
||||||
this._rfkill = new imports.ui.status.rfkill.Indicator();
|
this._rfkill = new imports.ui.status.rfkill.Indicator();
|
||||||
this._volume = new imports.ui.status.volume.Indicator();
|
this._volume = new imports.ui.status.volume.Indicator();
|
||||||
@ -729,6 +737,7 @@ var AggregateMenu = new Lang.Class({
|
|||||||
if (this._bluetooth) {
|
if (this._bluetooth) {
|
||||||
this._indicators.add_child(this._bluetooth.indicators);
|
this._indicators.add_child(this._bluetooth.indicators);
|
||||||
}
|
}
|
||||||
|
this._indicators.add_child(this._remoteAccess.indicators);
|
||||||
this._indicators.add_child(this._rfkill.indicators);
|
this._indicators.add_child(this._rfkill.indicators);
|
||||||
this._indicators.add_child(this._volume.indicators);
|
this._indicators.add_child(this._volume.indicators);
|
||||||
this._indicators.add_child(this._power.indicators);
|
this._indicators.add_child(this._power.indicators);
|
||||||
@ -743,6 +752,7 @@ var AggregateMenu = new Lang.Class({
|
|||||||
if (this._bluetooth) {
|
if (this._bluetooth) {
|
||||||
this.menu.addMenuItem(this._bluetooth.menu);
|
this.menu.addMenuItem(this._bluetooth.menu);
|
||||||
}
|
}
|
||||||
|
this.menu.addMenuItem(this._remoteAccess.menu);
|
||||||
this.menu.addMenuItem(this._location.menu);
|
this.menu.addMenuItem(this._location.menu);
|
||||||
this.menu.addMenuItem(this._rfkill.menu);
|
this.menu.addMenuItem(this._rfkill.menu);
|
||||||
this.menu.addMenuItem(this._power.menu);
|
this.menu.addMenuItem(this._power.menu);
|
||||||
|
@ -394,8 +394,9 @@ var PopupImageMenuItem = new Lang.Class({
|
|||||||
_init(text, icon, params) {
|
_init(text, icon, params) {
|
||||||
this.parent(params);
|
this.parent(params);
|
||||||
|
|
||||||
this._icon = new St.Icon({ style_class: 'popup-menu-icon' });
|
this._icon = new St.Icon({ style_class: 'popup-menu-icon',
|
||||||
this.actor.add_child(this._icon, { align: St.Align.END });
|
x_align: Clutter.ActorAlign.END });
|
||||||
|
this.actor.add_child(this._icon);
|
||||||
this.label = new St.Label({ text: text });
|
this.label = new St.Label({ text: text });
|
||||||
this.actor.add_child(this.label);
|
this.actor.add_child(this.label);
|
||||||
this.actor.label_actor = this.label;
|
this.actor.label_actor = this.label;
|
||||||
|
@ -295,7 +295,7 @@ var RemoteSearchProvider = new Lang.Class({
|
|||||||
name: metas[i]['name'],
|
name: metas[i]['name'],
|
||||||
description: metas[i]['description'],
|
description: metas[i]['description'],
|
||||||
createIcon: size => {
|
createIcon: size => {
|
||||||
this.createIcon(size, metas[i]);
|
return this.createIcon(size, metas[i]);
|
||||||
},
|
},
|
||||||
clipboardText: metas[i]['clipboardText'] });
|
clipboardText: metas[i]['clipboardText'] });
|
||||||
}
|
}
|
||||||
|
@ -515,8 +515,10 @@ var ScreenShield = new Lang.Class({
|
|||||||
this._smartcardManager = SmartcardManager.getSmartcardManager();
|
this._smartcardManager = SmartcardManager.getSmartcardManager();
|
||||||
this._smartcardManager.connect('smartcard-inserted',
|
this._smartcardManager.connect('smartcard-inserted',
|
||||||
(manager, token) => {
|
(manager, token) => {
|
||||||
if (this._isLocked && token.UsedToLogin)
|
if (this._isLocked && token.UsedToLogin) {
|
||||||
|
this._wakeUpScreen();
|
||||||
this._liftShield(true, 0);
|
this._liftShield(true, 0);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
this._oVirtCredentialsManager = OVirt.getOVirtCredentialsManager();
|
this._oVirtCredentialsManager = OVirt.getOVirtCredentialsManager();
|
||||||
|
@ -322,6 +322,10 @@ const GnomeShellExtensionsIface = '<node> \
|
|||||||
</method> \
|
</method> \
|
||||||
<method name="CheckForUpdates"> \
|
<method name="CheckForUpdates"> \
|
||||||
</method> \
|
</method> \
|
||||||
|
<method name="LoadUserExtension"> \
|
||||||
|
<arg type="s" direction="in" name="uuid"/> \
|
||||||
|
<arg type="b" direction="out" name="success"/> \
|
||||||
|
</method> \
|
||||||
<property name="ShellVersion" type="s" access="read" /> \
|
<property name="ShellVersion" type="s" access="read" /> \
|
||||||
</interface> \
|
</interface> \
|
||||||
</node>';
|
</node>';
|
||||||
@ -424,6 +428,22 @@ var GnomeShellExtensions = new Lang.Class({
|
|||||||
ExtensionDownloader.checkForUpdates();
|
ExtensionDownloader.checkForUpdates();
|
||||||
},
|
},
|
||||||
|
|
||||||
|
LoadUserExtension(uuid) {
|
||||||
|
let extension = ExtensionUtils.extensions[uuid];
|
||||||
|
if (extension)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
let dir = Gio.File.new_for_path(GLib.build_filenamev([global.userdatadir, 'extensions', uuid]));
|
||||||
|
try {
|
||||||
|
extension = ExtensionUtils.createExtensionObject(uuid, dir, ExtensionUtils.ExtensionType.PER_USER);
|
||||||
|
ExtensionSystem.loadExtension(extension);
|
||||||
|
} catch (e) {
|
||||||
|
log('Could not load user extension from %s'.format(dir.get_path()));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
},
|
||||||
|
|
||||||
ShellVersion: Config.PACKAGE_VERSION,
|
ShellVersion: Config.PACKAGE_VERSION,
|
||||||
|
|
||||||
_extensionStateChanged(_, newState) {
|
_extensionStateChanged(_, newState) {
|
||||||
|
@ -1944,6 +1944,7 @@ var NMApplet = new Lang.Class({
|
|||||||
this.indicators.visible = this._client.nm_running;
|
this.indicators.visible = this._client.nm_running;
|
||||||
this.menu.actor.visible = this._client.networking_enabled;
|
this.menu.actor.visible = this._client.networking_enabled;
|
||||||
|
|
||||||
|
this._updateIcon();
|
||||||
this._syncConnectivity();
|
this._syncConnectivity();
|
||||||
},
|
},
|
||||||
|
|
||||||
|
81
js/ui/status/remoteAccess.js
Normal file
81
js/ui/status/remoteAccess.js
Normal file
@ -0,0 +1,81 @@
|
|||||||
|
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
|
||||||
|
|
||||||
|
const Lang = imports.lang;
|
||||||
|
const Meta = imports.gi.Meta;
|
||||||
|
|
||||||
|
const PanelMenu = imports.ui.panelMenu;
|
||||||
|
const PopupMenu = imports.ui.popupMenu;
|
||||||
|
|
||||||
|
var RemoteAccessApplet = new Lang.Class({
|
||||||
|
Name: 'RemoteAccessApplet',
|
||||||
|
Extends: PanelMenu.SystemIndicator,
|
||||||
|
|
||||||
|
_init() {
|
||||||
|
this.parent();
|
||||||
|
|
||||||
|
let backend = Meta.get_backend();
|
||||||
|
let controller = backend.get_remote_access_controller();
|
||||||
|
|
||||||
|
if (!controller)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// We can't possibly know about all types of screen sharing on X11, so
|
||||||
|
// showing these controls on X11 might give a false sense of security.
|
||||||
|
// Thus, only enable these controls when using Wayland, where we are
|
||||||
|
// in control of sharing.
|
||||||
|
if (!Meta.is_wayland_compositor())
|
||||||
|
return;
|
||||||
|
|
||||||
|
this._handles = new Set();
|
||||||
|
this._indicator = null;
|
||||||
|
this._menuSection = null;
|
||||||
|
|
||||||
|
controller.connect('new-handle', (controller, handle) => {
|
||||||
|
this._onNewHandle(handle);
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
_ensureControls() {
|
||||||
|
if (this._indicator)
|
||||||
|
return;
|
||||||
|
|
||||||
|
this._indicator = this._addIndicator();
|
||||||
|
this._indicator.icon_name = 'screen-shared-symbolic';
|
||||||
|
this._indicator.add_style_class_name('remote-access-indicator');
|
||||||
|
this._item =
|
||||||
|
new PopupMenu.PopupSubMenuMenuItem(_("Screen is Being Shared"),
|
||||||
|
true);
|
||||||
|
this._item.menu.addAction(_("Turn off"),
|
||||||
|
() => {
|
||||||
|
for (let handle of this._handles)
|
||||||
|
handle.stop();
|
||||||
|
});
|
||||||
|
this._item.icon.icon_name = 'screen-shared-symbolic';
|
||||||
|
this.menu.addMenuItem(this._item);
|
||||||
|
},
|
||||||
|
|
||||||
|
_sync() {
|
||||||
|
if (this._handles.size == 0) {
|
||||||
|
this._indicator.visible = false;
|
||||||
|
this._item.actor.visible = false;
|
||||||
|
} else {
|
||||||
|
this._indicator.visible = true;
|
||||||
|
this._item.actor.visible = true;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
_onStopped(handle) {
|
||||||
|
this._handles.delete(handle);
|
||||||
|
this._sync();
|
||||||
|
},
|
||||||
|
|
||||||
|
_onNewHandle(handle) {
|
||||||
|
this._handles.add(handle);
|
||||||
|
handle.connect('stopped', this._onStopped.bind(this));
|
||||||
|
|
||||||
|
if (this._handles.size == 1) {
|
||||||
|
this._ensureControls();
|
||||||
|
this._sync();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
});
|
@ -58,6 +58,9 @@ var AltSwitcher = new Lang.Class({
|
|||||||
childToShow = this._standard;
|
childToShow = this._standard;
|
||||||
} else if (this._alternate.visible) {
|
} else if (this._alternate.visible) {
|
||||||
childToShow = this._alternate;
|
childToShow = this._alternate;
|
||||||
|
} else {
|
||||||
|
this.actor.hide();
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
let childShown = this.actor.get_child();
|
let childShown = this.actor.get_child();
|
||||||
@ -79,7 +82,7 @@ var AltSwitcher = new Lang.Class({
|
|||||||
global.sync_pointer();
|
global.sync_pointer();
|
||||||
}
|
}
|
||||||
|
|
||||||
this.actor.visible = (childToShow != null);
|
this.actor.show();
|
||||||
},
|
},
|
||||||
|
|
||||||
_onDestroy() {
|
_onDestroy() {
|
||||||
|
@ -69,30 +69,67 @@ function _getTweenState(target) {
|
|||||||
return target.__ShellTweenerState;
|
return target.__ShellTweenerState;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function _ensureHandlers(target) {
|
||||||
|
if (!target.__ShellTweenerHandlers)
|
||||||
|
target.__ShellTweenerHandlers = {};
|
||||||
|
return target.__ShellTweenerHandlers;
|
||||||
|
}
|
||||||
|
|
||||||
function _resetTweenState(target) {
|
function _resetTweenState(target) {
|
||||||
let state = target.__ShellTweenerState;
|
let state = target.__ShellTweenerState;
|
||||||
|
|
||||||
if (state) {
|
if (state) {
|
||||||
if (state.destroyedId)
|
if (state.destroyedId) {
|
||||||
state.actor.disconnect(state.destroyedId);
|
state.actor.disconnect(state.destroyedId);
|
||||||
|
delete state.destroyedId;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_removeHandler(target, 'onComplete', _tweenCompleted);
|
||||||
target.__ShellTweenerState = {};
|
target.__ShellTweenerState = {};
|
||||||
}
|
}
|
||||||
|
|
||||||
function _addHandler(target, params, name, handler) {
|
function _addHandler(target, params, name, handler) {
|
||||||
if (params[name]) {
|
let wrapperNeeded = false;
|
||||||
let oldHandler = params[name];
|
let tweenerHandlers = _ensureHandlers(target);
|
||||||
let oldScope = params[name + 'Scope'];
|
|
||||||
let oldParams = params[name + 'Params'];
|
|
||||||
let eventScope = oldScope ? oldScope : target;
|
|
||||||
|
|
||||||
params[name] = () => {
|
if (!(name in tweenerHandlers)) {
|
||||||
oldHandler.apply(eventScope, oldParams);
|
tweenerHandlers[name] = [];
|
||||||
handler(target);
|
wrapperNeeded = true;
|
||||||
};
|
}
|
||||||
} else
|
|
||||||
params[name] = () => { handler(target); };
|
let handlers = tweenerHandlers[name];
|
||||||
|
handlers.push(handler);
|
||||||
|
|
||||||
|
if (wrapperNeeded) {
|
||||||
|
if (params[name]) {
|
||||||
|
let oldHandler = params[name];
|
||||||
|
let oldScope = params[name + 'Scope'];
|
||||||
|
let oldParams = params[name + 'Params'];
|
||||||
|
let eventScope = oldScope ? oldScope : target;
|
||||||
|
|
||||||
|
params[name] = () => {
|
||||||
|
oldHandler.apply(eventScope, oldParams);
|
||||||
|
handlers.forEach((h) => h(target));
|
||||||
|
};
|
||||||
|
} else {
|
||||||
|
params[name] = () => { handlers.forEach((h) => h(target)); };
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function _removeHandler(target, name, handler) {
|
||||||
|
let tweenerHandlers = _ensureHandlers(target);
|
||||||
|
|
||||||
|
if (name in tweenerHandlers) {
|
||||||
|
let handlers = tweenerHandlers[name];
|
||||||
|
let handlerIndex = handlers.indexOf(handler);
|
||||||
|
|
||||||
|
while (handlerIndex > -1) {
|
||||||
|
handlers.splice(handlerIndex, 1);
|
||||||
|
handlerIndex = handlers.indexOf(handler);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function _actorDestroyed(target) {
|
function _actorDestroyed(target) {
|
||||||
|
@ -51,7 +51,14 @@ var UnlockDialog = new Lang.Class({
|
|||||||
y_expand: true });
|
y_expand: true });
|
||||||
this.actor.add_child(this._promptBox);
|
this.actor.add_child(this._promptBox);
|
||||||
|
|
||||||
this._authPrompt = new AuthPrompt.AuthPrompt(new Gdm.Client(), AuthPrompt.AuthPromptMode.UNLOCK_ONLY);
|
this._gdmClient = new Gdm.Client();
|
||||||
|
|
||||||
|
try {
|
||||||
|
this._gdmClient.set_enabled_extensions([Gdm.UserVerifierChoiceList.interface_info().name]);
|
||||||
|
} catch(e) {
|
||||||
|
}
|
||||||
|
|
||||||
|
this._authPrompt = new AuthPrompt.AuthPrompt(this._gdmClient, AuthPrompt.AuthPromptMode.UNLOCK_ONLY);
|
||||||
this._authPrompt.connect('failed', this._fail.bind(this));
|
this._authPrompt.connect('failed', this._fail.bind(this));
|
||||||
this._authPrompt.connect('cancelled', this._fail.bind(this));
|
this._authPrompt.connect('cancelled', this._fail.bind(this));
|
||||||
this._authPrompt.connect('reset', this._onReset.bind(this));
|
this._authPrompt.connect('reset', this._onReset.bind(this));
|
||||||
|
@ -24,7 +24,7 @@ const EdgeDragAction = imports.ui.edgeDragAction;
|
|||||||
const CloseDialog = imports.ui.closeDialog;
|
const CloseDialog = imports.ui.closeDialog;
|
||||||
const SwitchMonitor = imports.ui.switchMonitor;
|
const SwitchMonitor = imports.ui.switchMonitor;
|
||||||
|
|
||||||
const SHELL_KEYBINDINGS_SCHEMA = 'org.gnome.shell.keybindings';
|
var SHELL_KEYBINDINGS_SCHEMA = 'org.gnome.shell.keybindings';
|
||||||
var MINIMIZE_WINDOW_ANIMATION_TIME = 0.2;
|
var MINIMIZE_WINDOW_ANIMATION_TIME = 0.2;
|
||||||
var SHOW_WINDOW_ANIMATION_TIME = 0.15;
|
var SHOW_WINDOW_ANIMATION_TIME = 0.15;
|
||||||
var DIALOG_SHOW_WINDOW_ANIMATION_TIME = 0.1;
|
var DIALOG_SHOW_WINDOW_ANIMATION_TIME = 0.1;
|
||||||
|
@ -123,6 +123,22 @@ var WindowMenu = new Lang.Class({
|
|||||||
window.change_workspace(workspace.get_neighbor(dir));
|
window.change_workspace(workspace.get_neighbor(dir));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let nWorkspaces = global.screen.n_workspaces;
|
||||||
|
if (nWorkspaces > 1 && !Meta.prefs_get_dynamic_workspaces()) {
|
||||||
|
item = new PopupMenu.PopupSubMenuMenuItem(_("Move to another workspace"));
|
||||||
|
this.addMenuItem(item);
|
||||||
|
|
||||||
|
let currentIndex = global.screen.get_active_workspace_index();
|
||||||
|
for (let i = 0; i < nWorkspaces; i++) {
|
||||||
|
let index = i;
|
||||||
|
let name = Meta.prefs_get_workspace_name(i);
|
||||||
|
let subitem = item.menu.addAction(name, () => {
|
||||||
|
window.change_workspace_by_index(index, false);
|
||||||
|
});
|
||||||
|
subitem.setSensitive(currentIndex != i);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1431,34 +1431,26 @@ var Workspace = new Lang.Class({
|
|||||||
_doRemoveWindow(metaWin) {
|
_doRemoveWindow(metaWin) {
|
||||||
let win = metaWin.get_compositor_private();
|
let win = metaWin.get_compositor_private();
|
||||||
|
|
||||||
// find the position of the window in our list
|
let clone = this._removeWindowClone(metaWin);
|
||||||
let index = this._lookupIndex (metaWin);
|
|
||||||
|
|
||||||
if (index == -1)
|
if (clone) {
|
||||||
return;
|
// If metaWin.get_compositor_private() returned non-NULL, that
|
||||||
|
// means the window still exists (and is just being moved to
|
||||||
let clone = this._windows[index];
|
// another workspace or something), so set its overviewHint
|
||||||
|
// accordingly. (If it returned NULL, then the window is being
|
||||||
this._windows.splice(index, 1);
|
// destroyed; we'd like to animate this, but it's too late at
|
||||||
this._windowOverlays.splice(index, 1);
|
// this point.)
|
||||||
|
if (win) {
|
||||||
// If metaWin.get_compositor_private() returned non-NULL, that
|
let [stageX, stageY] = clone.actor.get_transformed_position();
|
||||||
// means the window still exists (and is just being moved to
|
let [stageWidth, stageHeight] = clone.actor.get_transformed_size();
|
||||||
// another workspace or something), so set its overviewHint
|
win._overviewHint = {
|
||||||
// accordingly. (If it returned NULL, then the window is being
|
x: stageX,
|
||||||
// destroyed; we'd like to animate this, but it's too late at
|
y: stageY,
|
||||||
// this point.)
|
scale: stageWidth / clone.actor.width
|
||||||
if (win) {
|
};
|
||||||
let [stageX, stageY] = clone.actor.get_transformed_position();
|
}
|
||||||
let [stageWidth, stageHeight] = clone.actor.get_transformed_size();
|
clone.destroy();
|
||||||
win._overviewHint = {
|
|
||||||
x: stageX,
|
|
||||||
y: stageY,
|
|
||||||
scale: stageWidth / clone.actor.width
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
clone.destroy();
|
|
||||||
|
|
||||||
|
|
||||||
// We need to reposition the windows; to avoid shuffling windows
|
// We need to reposition the windows; to avoid shuffling windows
|
||||||
// around while the user is interacting with the workspace, we delay
|
// around while the user is interacting with the workspace, we delay
|
||||||
@ -1848,6 +1840,9 @@ var Workspace = new Lang.Class({
|
|||||||
clone.connect('size-changed', () => {
|
clone.connect('size-changed', () => {
|
||||||
this._recalculateWindowPositions(WindowPositionFlags.NONE);
|
this._recalculateWindowPositions(WindowPositionFlags.NONE);
|
||||||
});
|
});
|
||||||
|
clone.actor.connect('destroy', () => {
|
||||||
|
this._removeWindowClone(clone.metaWindow);
|
||||||
|
});
|
||||||
|
|
||||||
this.actor.add_actor(clone.actor);
|
this.actor.add_actor(clone.actor);
|
||||||
|
|
||||||
@ -1869,6 +1864,17 @@ var Workspace = new Lang.Class({
|
|||||||
return [clone, overlay];
|
return [clone, overlay];
|
||||||
},
|
},
|
||||||
|
|
||||||
|
_removeWindowClone(metaWin) {
|
||||||
|
// find the position of the window in our list
|
||||||
|
let index = this._lookupIndex (metaWin);
|
||||||
|
|
||||||
|
if (index == -1)
|
||||||
|
return null;
|
||||||
|
|
||||||
|
this._windowOverlays.splice(index, 1);
|
||||||
|
return this._windows.splice(index, 1).pop();
|
||||||
|
},
|
||||||
|
|
||||||
_onShowOverlayClose(windowOverlay) {
|
_onShowOverlayClose(windowOverlay) {
|
||||||
for (let i = 0; i < this._windowOverlays.length; i++) {
|
for (let i = 0; i < this._windowOverlays.length; i++) {
|
||||||
let overlay = this._windowOverlays[i];
|
let overlay = this._windowOverlays[i];
|
||||||
|
@ -31,7 +31,7 @@ var WORKSPACE_CUT_SIZE = 10;
|
|||||||
|
|
||||||
var WORKSPACE_KEEP_ALIVE_TIME = 100;
|
var WORKSPACE_KEEP_ALIVE_TIME = 100;
|
||||||
|
|
||||||
const OVERRIDE_SCHEMA = 'org.gnome.shell.overrides';
|
var OVERRIDE_SCHEMA = 'org.gnome.shell.overrides';
|
||||||
|
|
||||||
/* A layout manager that requests size only for primary_actor, but then allocates
|
/* A layout manager that requests size only for primary_actor, but then allocates
|
||||||
all using a fixed layout */
|
all using a fixed layout */
|
||||||
@ -241,7 +241,7 @@ var WindowClone = new Lang.Class({
|
|||||||
Signals.addSignalMethods(WindowClone.prototype);
|
Signals.addSignalMethods(WindowClone.prototype);
|
||||||
|
|
||||||
|
|
||||||
const ThumbnailState = {
|
var ThumbnailState = {
|
||||||
NEW : 0,
|
NEW : 0,
|
||||||
ANIMATING_IN : 1,
|
ANIMATING_IN : 1,
|
||||||
NORMAL: 2,
|
NORMAL: 2,
|
||||||
@ -275,8 +275,8 @@ var WorkspaceThumbnail = new Lang.Class({
|
|||||||
|
|
||||||
this._createBackground();
|
this._createBackground();
|
||||||
|
|
||||||
let monitor = Main.layoutManager.primaryMonitor;
|
let workArea = Main.layoutManager.getWorkAreaForMonitor(this.monitorIndex);
|
||||||
this.setPorthole(monitor.x, monitor.y, monitor.width, monitor.height);
|
this.setPorthole(workArea.x, workArea.y, workArea.width, workArea.height);
|
||||||
|
|
||||||
let windows = global.get_window_actors().filter(actor => {
|
let windows = global.get_window_actors().filter(actor => {
|
||||||
let win = actor.meta_window;
|
let win = actor.meta_window;
|
||||||
@ -321,8 +321,6 @@ var WorkspaceThumbnail = new Lang.Class({
|
|||||||
},
|
},
|
||||||
|
|
||||||
setPorthole(x, y, width, height) {
|
setPorthole(x, y, width, height) {
|
||||||
this._portholeX = x;
|
|
||||||
this._portholeY = y;
|
|
||||||
this.actor.set_size(width, height);
|
this.actor.set_size(width, height);
|
||||||
this._contents.set_position(-x, -y);
|
this._contents.set_position(-x, -y);
|
||||||
},
|
},
|
||||||
@ -374,18 +372,9 @@ var WorkspaceThumbnail = new Lang.Class({
|
|||||||
},
|
},
|
||||||
|
|
||||||
_doRemoveWindow(metaWin) {
|
_doRemoveWindow(metaWin) {
|
||||||
let win = metaWin.get_compositor_private();
|
let clone = this._removeWindowClone(metaWin);
|
||||||
|
if (clone)
|
||||||
// find the position of the window in our list
|
clone.destroy();
|
||||||
let index = this._lookupIndex (metaWin);
|
|
||||||
|
|
||||||
if (index == -1)
|
|
||||||
return;
|
|
||||||
|
|
||||||
let clone = this._windows[index];
|
|
||||||
this._windows.splice(index, 1);
|
|
||||||
|
|
||||||
clone.destroy();
|
|
||||||
},
|
},
|
||||||
|
|
||||||
_doAddWindow(metaWin) {
|
_doAddWindow(metaWin) {
|
||||||
@ -537,6 +526,9 @@ var WorkspaceThumbnail = new Lang.Class({
|
|||||||
clone.connect('drag-end', () => {
|
clone.connect('drag-end', () => {
|
||||||
Main.overview.endWindowDrag(clone.metaWindow);
|
Main.overview.endWindowDrag(clone.metaWindow);
|
||||||
});
|
});
|
||||||
|
clone.actor.connect('destroy', () => {
|
||||||
|
this._removeWindowClone(clone.metaWindow);
|
||||||
|
});
|
||||||
this._contents.add_actor(clone.actor);
|
this._contents.add_actor(clone.actor);
|
||||||
|
|
||||||
if (this._windows.length == 0)
|
if (this._windows.length == 0)
|
||||||
@ -549,6 +541,16 @@ var WorkspaceThumbnail = new Lang.Class({
|
|||||||
return clone;
|
return clone;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
_removeWindowClone(metaWin) {
|
||||||
|
// find the position of the window in our list
|
||||||
|
let index = this._lookupIndex (metaWin);
|
||||||
|
|
||||||
|
if (index == -1)
|
||||||
|
return null;
|
||||||
|
|
||||||
|
return this._windows.splice(index, 1).pop();
|
||||||
|
},
|
||||||
|
|
||||||
activate(time) {
|
activate(time) {
|
||||||
if (this.state > ThumbnailState.NORMAL)
|
if (this.state > ThumbnailState.NORMAL)
|
||||||
return;
|
return;
|
||||||
@ -675,11 +677,7 @@ var ThumbnailsBox = new Lang.Class({
|
|||||||
this._settings.connect('changed::dynamic-workspaces',
|
this._settings.connect('changed::dynamic-workspaces',
|
||||||
this._updateSwitcherVisibility.bind(this));
|
this._updateSwitcherVisibility.bind(this));
|
||||||
|
|
||||||
Main.layoutManager.connect('monitors-changed', () => {
|
Main.layoutManager.connect('monitors-changed', this._rebuildThumbnails.bind(this));
|
||||||
this._destroyThumbnails();
|
|
||||||
if (Main.overview.visible)
|
|
||||||
this._createThumbnails();
|
|
||||||
});
|
|
||||||
},
|
},
|
||||||
|
|
||||||
_updateSwitcherVisibility() {
|
_updateSwitcherVisibility() {
|
||||||
@ -872,6 +870,9 @@ var ThumbnailsBox = new Lang.Class({
|
|||||||
Main.overview.connect('windows-restacked',
|
Main.overview.connect('windows-restacked',
|
||||||
this._syncStacking.bind(this));
|
this._syncStacking.bind(this));
|
||||||
|
|
||||||
|
this._workareasChangedId =
|
||||||
|
global.screen.connect('workareas-changed', this._rebuildThumbnails.bind(this));
|
||||||
|
|
||||||
this._targetScale = 0;
|
this._targetScale = 0;
|
||||||
this._scale = 0;
|
this._scale = 0;
|
||||||
this._pendingScaleUpdate = false;
|
this._pendingScaleUpdate = false;
|
||||||
@ -901,12 +902,24 @@ var ThumbnailsBox = new Lang.Class({
|
|||||||
this._syncStackingId = 0;
|
this._syncStackingId = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (this._workareasChangedId > 0) {
|
||||||
|
global.screen.disconnect(this._workareasChangedId);
|
||||||
|
this._workareasChangedId = 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 = [];
|
||||||
this._porthole = null;
|
this._porthole = null;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
_rebuildThumbnails() {
|
||||||
|
this._destroyThumbnails();
|
||||||
|
|
||||||
|
if (Main.overview.visible)
|
||||||
|
this._createThumbnails();
|
||||||
|
},
|
||||||
|
|
||||||
_workspacesChanged() {
|
_workspacesChanged() {
|
||||||
let validThumbnails =
|
let validThumbnails =
|
||||||
this._thumbnails.filter(t => t.state <= ThumbnailState.NORMAL);
|
this._thumbnails.filter(t => t.state <= ThumbnailState.NORMAL);
|
||||||
@ -1159,7 +1172,7 @@ var ThumbnailsBox = new Lang.Class({
|
|||||||
// The "porthole" is the portion of the screen that we show in the
|
// The "porthole" is the portion of the screen that we show in the
|
||||||
// workspaces
|
// workspaces
|
||||||
_ensurePorthole() {
|
_ensurePorthole() {
|
||||||
if (!Main.layoutManager.primaryMonitor)
|
if (!Main.layoutManager.primaryMonitor || !Main.overview.visible)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (!this._porthole)
|
if (!this._porthole)
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
project('gnome-shell', 'c',
|
project('gnome-shell', 'c',
|
||||||
version: '3.28.1',
|
version: '3.28.3',
|
||||||
meson_version: '>= 0.42.0',
|
meson_version: '>= 0.42.0',
|
||||||
license: 'GPLv2+'
|
license: 'GPLv2+'
|
||||||
)
|
)
|
||||||
@ -56,6 +56,7 @@ mozplugindir = join_paths(libdir, 'mozilla', 'plugins')
|
|||||||
portaldir = join_paths(datadir, 'xdg-desktop-portal', 'portals')
|
portaldir = join_paths(datadir, 'xdg-desktop-portal', 'portals')
|
||||||
schemadir = join_paths(datadir, 'glib-2.0', 'schemas')
|
schemadir = join_paths(datadir, 'glib-2.0', 'schemas')
|
||||||
servicedir = join_paths(datadir, 'dbus-1', 'services')
|
servicedir = join_paths(datadir, 'dbus-1', 'services')
|
||||||
|
themedir = join_paths(pkgdatadir, 'theme')
|
||||||
|
|
||||||
plugindir = get_variable('BROWSER_PLUGIN_DIR', mozplugindir)
|
plugindir = get_variable('BROWSER_PLUGIN_DIR', mozplugindir)
|
||||||
|
|
||||||
|
46
po/pt_BR.po
46
po/pt_BR.po
@ -15,22 +15,22 @@
|
|||||||
# Georges Basile Stavracas Neto <georges.stavracas@gmail.com>, 2014.
|
# Georges Basile Stavracas Neto <georges.stavracas@gmail.com>, 2014.
|
||||||
# Felipe Braga <fbobraga@gmail.com>, 2015.
|
# Felipe Braga <fbobraga@gmail.com>, 2015.
|
||||||
# Artur de Aquino Morais <artur.morais93@outlook.com>, 2016.
|
# Artur de Aquino Morais <artur.morais93@outlook.com>, 2016.
|
||||||
# Rafael Fontenelle <rafaelff@gnome.org>, 2013-2017.
|
# Rafael Fontenelle <rafaelff@gnome.org>, 2013-2018.
|
||||||
# Enrico Nicoletto <liverig@gmail.com>, 2013-2018.
|
# Enrico Nicoletto <liverig@gmail.com>, 2013-2018.
|
||||||
msgid ""
|
msgid ""
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Project-Id-Version: gnome-shell\n"
|
"Project-Id-Version: gnome-shell\n"
|
||||||
"Report-Msgid-Bugs-To: https://gitlab.gnome.org/GNOME/gnome-shell/issues\n"
|
"Report-Msgid-Bugs-To: https://gitlab.gnome.org/GNOME/gnome-shell/issues\n"
|
||||||
"POT-Creation-Date: 2018-03-16 21:34+0000\n"
|
"POT-Creation-Date: 2018-04-13 18:31+0000\n"
|
||||||
"PO-Revision-Date: 2018-02-09 21:52-0200\n"
|
"PO-Revision-Date: 2018-05-02 15:45-0200\n"
|
||||||
"Last-Translator: Enrico Nicoletto <liverig@gmail.com>\n"
|
"Last-Translator: Rafael Fontenelle <rafaelff@gnome.org>\n"
|
||||||
"Language-Team: Brazilian Portuguese <gnome-pt_br-list@gnome.org>\n"
|
"Language-Team: Brazilian Portuguese <gnome-pt_br-list@gnome.org>\n"
|
||||||
"Language: pt_BR\n"
|
"Language: pt_BR\n"
|
||||||
"MIME-Version: 1.0\n"
|
"MIME-Version: 1.0\n"
|
||||||
"Content-Type: text/plain; charset=UTF-8\n"
|
"Content-Type: text/plain; charset=UTF-8\n"
|
||||||
"Content-Transfer-Encoding: 8bit\n"
|
"Content-Transfer-Encoding: 8bit\n"
|
||||||
"Plural-Forms: nplurals=2; plural=(n > 1);\n"
|
"Plural-Forms: nplurals=2; plural=(n > 1);\n"
|
||||||
"X-Generator: Poedit 2.0.6\n"
|
"X-Generator: Virtaal 1.0.0-beta1\n"
|
||||||
"X-Project-Style: gnome\n"
|
"X-Project-Style: gnome\n"
|
||||||
|
|
||||||
#: data/50-gnome-shell-system.xml:6
|
#: data/50-gnome-shell-system.xml:6
|
||||||
@ -356,7 +356,7 @@ msgid "There was an error loading the preferences dialog for %s:"
|
|||||||
msgstr "Ocorreu um erro ao carregar o dialogo de preferências para %s:"
|
msgstr "Ocorreu um erro ao carregar o dialogo de preferências para %s:"
|
||||||
|
|
||||||
#: js/gdm/authPrompt.js:147 js/ui/audioDeviceSelection.js:71
|
#: js/gdm/authPrompt.js:147 js/ui/audioDeviceSelection.js:71
|
||||||
#: js/ui/components/networkAgent.js:117 js/ui/components/polkitAgent.js:148
|
#: js/ui/components/networkAgent.js:117 js/ui/components/polkitAgent.js:153
|
||||||
#: js/ui/endSessionDialog.js:482 js/ui/extensionDownloader.js:197
|
#: js/ui/endSessionDialog.js:482 js/ui/extensionDownloader.js:197
|
||||||
#: js/ui/shellMountOperation.js:343 js/ui/status/network.js:919
|
#: js/ui/shellMountOperation.js:343 js/ui/status/network.js:919
|
||||||
msgid "Cancel"
|
msgid "Cancel"
|
||||||
@ -642,7 +642,7 @@ msgstr "Negar acesso"
|
|||||||
|
|
||||||
#: js/ui/accessDialog.js:64 js/ui/status/location.js:396
|
#: js/ui/accessDialog.js:64 js/ui/status/location.js:396
|
||||||
msgid "Grant Access"
|
msgid "Grant Access"
|
||||||
msgstr "Garantir acesso"
|
msgstr "Conceder acesso"
|
||||||
|
|
||||||
#: js/ui/appDisplay.js:793
|
#: js/ui/appDisplay.js:793
|
||||||
msgid "Frequently used applications will appear here"
|
msgid "Frequently used applications will appear here"
|
||||||
@ -676,12 +676,12 @@ msgstr "Adicionar aos favoritos"
|
|||||||
msgid "Show Details"
|
msgid "Show Details"
|
||||||
msgstr "Mostrar detalhes"
|
msgstr "Mostrar detalhes"
|
||||||
|
|
||||||
#: js/ui/appFavorites.js:138
|
#: js/ui/appFavorites.js:140
|
||||||
#, javascript-format
|
#, javascript-format
|
||||||
msgid "%s has been added to your favorites."
|
msgid "%s has been added to your favorites."
|
||||||
msgstr "%s foi adicionado aos seus favoritos."
|
msgstr "%s foi adicionado aos seus favoritos."
|
||||||
|
|
||||||
#: js/ui/appFavorites.js:172
|
#: js/ui/appFavorites.js:174
|
||||||
#, javascript-format
|
#, javascript-format
|
||||||
msgid "%s has been removed from your favorites."
|
msgid "%s has been removed from your favorites."
|
||||||
msgstr "%s foi removido dos seus favoritos."
|
msgstr "%s foi removido dos seus favoritos."
|
||||||
@ -876,7 +876,7 @@ msgstr "Unidade externa desconectada"
|
|||||||
msgid "Open with %s"
|
msgid "Open with %s"
|
||||||
msgstr "Abrir com %s"
|
msgstr "Abrir com %s"
|
||||||
|
|
||||||
#: js/ui/components/keyring.js:107 js/ui/components/polkitAgent.js:284
|
#: js/ui/components/keyring.js:107 js/ui/components/polkitAgent.js:295
|
||||||
msgid "Password:"
|
msgid "Password:"
|
||||||
msgstr "Senha:"
|
msgstr "Senha:"
|
||||||
|
|
||||||
@ -964,15 +964,15 @@ msgstr "Uma senha é necessária para se conectar a “%s”."
|
|||||||
msgid "Network Manager"
|
msgid "Network Manager"
|
||||||
msgstr "Gerenciador de rede"
|
msgstr "Gerenciador de rede"
|
||||||
|
|
||||||
#: js/ui/components/polkitAgent.js:43
|
#: js/ui/components/polkitAgent.js:48
|
||||||
msgid "Authentication Required"
|
msgid "Authentication Required"
|
||||||
msgstr "Autenticação necessária"
|
msgstr "Autenticação necessária"
|
||||||
|
|
||||||
#: js/ui/components/polkitAgent.js:71
|
#: js/ui/components/polkitAgent.js:76
|
||||||
msgid "Administrator"
|
msgid "Administrator"
|
||||||
msgstr "Administrador"
|
msgstr "Administrador"
|
||||||
|
|
||||||
#: js/ui/components/polkitAgent.js:151
|
#: js/ui/components/polkitAgent.js:156
|
||||||
msgid "Authenticate"
|
msgid "Authenticate"
|
||||||
msgstr "Autenticação"
|
msgstr "Autenticação"
|
||||||
|
|
||||||
@ -980,7 +980,7 @@ msgstr "Autenticação"
|
|||||||
#. * requested authentication was not gained; this can happen
|
#. * requested authentication was not gained; this can happen
|
||||||
#. * because of an authentication error (like invalid password),
|
#. * because of an authentication error (like invalid password),
|
||||||
#. * for instance.
|
#. * for instance.
|
||||||
#: js/ui/components/polkitAgent.js:270 js/ui/shellMountOperation.js:327
|
#: js/ui/components/polkitAgent.js:281 js/ui/shellMountOperation.js:327
|
||||||
msgid "Sorry, that didn’t work. Please try again."
|
msgid "Sorry, that didn’t work. Please try again."
|
||||||
msgstr "Desculpe, isto não funcionou. Por favor, tente novamente."
|
msgstr "Desculpe, isto não funcionou. Por favor, tente novamente."
|
||||||
|
|
||||||
@ -1028,7 +1028,7 @@ msgstr "Adicionar relógios mundiais…"
|
|||||||
msgid "World Clocks"
|
msgid "World Clocks"
|
||||||
msgstr "Relógios mundiais"
|
msgstr "Relógios mundiais"
|
||||||
|
|
||||||
#: js/ui/dateMenu.js:225
|
#: js/ui/dateMenu.js:227
|
||||||
msgid "Weather"
|
msgid "Weather"
|
||||||
msgstr "Meteorologia"
|
msgstr "Meteorologia"
|
||||||
|
|
||||||
@ -1036,7 +1036,7 @@ msgstr "Meteorologia"
|
|||||||
#. libgweather for the possible condition strings. If at all
|
#. libgweather for the possible condition strings. If at all
|
||||||
#. possible, the sentence should match the grammatical case etc. of
|
#. possible, the sentence should match the grammatical case etc. of
|
||||||
#. the inserted conditions.
|
#. the inserted conditions.
|
||||||
#: js/ui/dateMenu.js:289
|
#: js/ui/dateMenu.js:291
|
||||||
#, javascript-format
|
#, javascript-format
|
||||||
msgid "%s all day."
|
msgid "%s all day."
|
||||||
msgstr "%s por todo o dia."
|
msgstr "%s por todo o dia."
|
||||||
@ -1045,7 +1045,7 @@ msgstr "%s por todo o dia."
|
|||||||
#. libgweather for the possible condition strings. If at all
|
#. libgweather for the possible condition strings. If at all
|
||||||
#. possible, the sentence should match the grammatical case etc. of
|
#. possible, the sentence should match the grammatical case etc. of
|
||||||
#. the inserted conditions.
|
#. the inserted conditions.
|
||||||
#: js/ui/dateMenu.js:295
|
#: js/ui/dateMenu.js:297
|
||||||
#, javascript-format
|
#, javascript-format
|
||||||
msgid "%s, then %s later."
|
msgid "%s, then %s later."
|
||||||
msgstr "%s, depois %s mais tarde."
|
msgstr "%s, depois %s mais tarde."
|
||||||
@ -1054,30 +1054,30 @@ msgstr "%s, depois %s mais tarde."
|
|||||||
#. libgweather for the possible condition strings. If at all
|
#. libgweather for the possible condition strings. If at all
|
||||||
#. possible, the sentence should match the grammatical case etc. of
|
#. possible, the sentence should match the grammatical case etc. of
|
||||||
#. the inserted conditions.
|
#. the inserted conditions.
|
||||||
#: js/ui/dateMenu.js:301
|
#: js/ui/dateMenu.js:303
|
||||||
#, javascript-format
|
#, javascript-format
|
||||||
msgid "%s, then %s, followed by %s later."
|
msgid "%s, then %s, followed by %s later."
|
||||||
msgstr "%s, depois %s, seguido de %s mais tarde."
|
msgstr "%s, depois %s, seguido de %s mais tarde."
|
||||||
|
|
||||||
#: js/ui/dateMenu.js:312
|
#: js/ui/dateMenu.js:314
|
||||||
msgid "Select a location…"
|
msgid "Select a location…"
|
||||||
msgstr "Selecione uma localização…"
|
msgstr "Selecione uma localização…"
|
||||||
|
|
||||||
#: js/ui/dateMenu.js:315
|
#: js/ui/dateMenu.js:317
|
||||||
msgid "Loading…"
|
msgid "Loading…"
|
||||||
msgstr "Carregando…"
|
msgstr "Carregando…"
|
||||||
|
|
||||||
#. Translators: %s is a temperature with unit, e.g. "23℃"
|
#. Translators: %s is a temperature with unit, e.g. "23℃"
|
||||||
#: js/ui/dateMenu.js:321
|
#: js/ui/dateMenu.js:323
|
||||||
#, javascript-format
|
#, javascript-format
|
||||||
msgid "Feels like %s."
|
msgid "Feels like %s."
|
||||||
msgstr "Sensação térmica de %s."
|
msgstr "Sensação térmica de %s."
|
||||||
|
|
||||||
#: js/ui/dateMenu.js:324
|
#: js/ui/dateMenu.js:326
|
||||||
msgid "Go online for weather information"
|
msgid "Go online for weather information"
|
||||||
msgstr "Conecte-se à internet para obter as informações meteorológicas"
|
msgstr "Conecte-se à internet para obter as informações meteorológicas"
|
||||||
|
|
||||||
#: js/ui/dateMenu.js:326
|
#: js/ui/dateMenu.js:328
|
||||||
msgid "Weather information is currently unavailable"
|
msgid "Weather information is currently unavailable"
|
||||||
msgstr "No momento as informações meteorológicas não estão disponíveis"
|
msgstr "No momento as informações meteorológicas não estão disponíveis"
|
||||||
|
|
||||||
|
40
po/ru.po
40
po/ru.po
@ -18,8 +18,8 @@ msgid ""
|
|||||||
msgstr ""
|
msgstr ""
|
||||||
"Project-Id-Version: gnome-shell\n"
|
"Project-Id-Version: gnome-shell\n"
|
||||||
"Report-Msgid-Bugs-To: https://gitlab.gnome.org/GNOME/gnome-shell/issues\n"
|
"Report-Msgid-Bugs-To: https://gitlab.gnome.org/GNOME/gnome-shell/issues\n"
|
||||||
"POT-Creation-Date: 2018-04-12 11:47+0000\n"
|
"POT-Creation-Date: 2018-04-13 18:31+0000\n"
|
||||||
"PO-Revision-Date: 2018-04-12 16:48+0300\n"
|
"PO-Revision-Date: 2018-04-19 23:31+0300\n"
|
||||||
"Last-Translator: Stas Solovey <whats_up@tut.by>\n"
|
"Last-Translator: Stas Solovey <whats_up@tut.by>\n"
|
||||||
"Language-Team: Русский <gnome-cyr@gnome.org>\n"
|
"Language-Team: Русский <gnome-cyr@gnome.org>\n"
|
||||||
"Language: ru\n"
|
"Language: ru\n"
|
||||||
@ -344,7 +344,7 @@ msgid "There was an error loading the preferences dialog for %s:"
|
|||||||
msgstr "Возникла ошибка загрузки диалогового окна параметров для %s:"
|
msgstr "Возникла ошибка загрузки диалогового окна параметров для %s:"
|
||||||
|
|
||||||
#: js/gdm/authPrompt.js:147 js/ui/audioDeviceSelection.js:71
|
#: js/gdm/authPrompt.js:147 js/ui/audioDeviceSelection.js:71
|
||||||
#: js/ui/components/networkAgent.js:117 js/ui/components/polkitAgent.js:149
|
#: js/ui/components/networkAgent.js:117 js/ui/components/polkitAgent.js:153
|
||||||
#: js/ui/endSessionDialog.js:482 js/ui/extensionDownloader.js:197
|
#: js/ui/endSessionDialog.js:482 js/ui/extensionDownloader.js:197
|
||||||
#: js/ui/shellMountOperation.js:343 js/ui/status/network.js:919
|
#: js/ui/shellMountOperation.js:343 js/ui/status/network.js:919
|
||||||
msgid "Cancel"
|
msgid "Cancel"
|
||||||
@ -563,7 +563,6 @@ msgstr "Вчера, %H∶%M"
|
|||||||
msgid "%A, %H∶%M"
|
msgid "%A, %H∶%M"
|
||||||
msgstr "%A, %H∶%M"
|
msgstr "%A, %H∶%M"
|
||||||
|
|
||||||
# fix даты "11 мар., 20:35"
|
|
||||||
#. Translators: this is the month name and day number
|
#. Translators: this is the month name and day number
|
||||||
#. followed by a time string in 24h format.
|
#. followed by a time string in 24h format.
|
||||||
#. i.e. "May 25, 14:30"
|
#. i.e. "May 25, 14:30"
|
||||||
@ -572,7 +571,6 @@ msgstr "%A, %H∶%M"
|
|||||||
msgid "%B %d, %H∶%M"
|
msgid "%B %d, %H∶%M"
|
||||||
msgstr "%-d %B, %H∶%M"
|
msgstr "%-d %B, %H∶%M"
|
||||||
|
|
||||||
# fix даты
|
|
||||||
#. Translators: this is the month name, day number, year
|
#. Translators: this is the month name, day number, year
|
||||||
#. number followed by a time string in 24h format.
|
#. number followed by a time string in 24h format.
|
||||||
#. i.e. "May 25 2012, 14:30"
|
#. i.e. "May 25 2012, 14:30"
|
||||||
@ -581,7 +579,6 @@ msgstr "%-d %B, %H∶%M"
|
|||||||
msgid "%B %d %Y, %H∶%M"
|
msgid "%B %d %Y, %H∶%M"
|
||||||
msgstr "%-d %B %Y, %H∶%M"
|
msgstr "%-d %B %Y, %H∶%M"
|
||||||
|
|
||||||
# по всей видимости разрабы коммент перепутали c "Translators: Time in 12h format"
|
|
||||||
#. Translators: Time in 12h format
|
#. Translators: Time in 12h format
|
||||||
#: js/misc/util.js:257
|
#: js/misc/util.js:257
|
||||||
msgid "%l∶%M %p"
|
msgid "%l∶%M %p"
|
||||||
@ -823,7 +820,6 @@ msgctxt "calendar heading"
|
|||||||
msgid "%A, %B %d"
|
msgid "%A, %B %d"
|
||||||
msgstr "%A, %-d %B"
|
msgstr "%A, %-d %B"
|
||||||
|
|
||||||
# fix для даты в календаре и на экране блокировки
|
|
||||||
#: js/ui/calendar.js:868
|
#: js/ui/calendar.js:868
|
||||||
msgctxt "calendar heading"
|
msgctxt "calendar heading"
|
||||||
msgid "%A, %B %d, %Y"
|
msgid "%A, %B %d, %Y"
|
||||||
@ -876,7 +872,7 @@ msgstr "Внешний диск отключён"
|
|||||||
msgid "Open with %s"
|
msgid "Open with %s"
|
||||||
msgstr "Открыть с помощью %s"
|
msgstr "Открыть с помощью %s"
|
||||||
|
|
||||||
#: js/ui/components/keyring.js:107 js/ui/components/polkitAgent.js:285
|
#: js/ui/components/keyring.js:107 js/ui/components/polkitAgent.js:295
|
||||||
msgid "Password:"
|
msgid "Password:"
|
||||||
msgstr "Пароль:"
|
msgstr "Пароль:"
|
||||||
|
|
||||||
@ -963,15 +959,15 @@ msgstr "Для подключения к «%s» требуется пароль.
|
|||||||
msgid "Network Manager"
|
msgid "Network Manager"
|
||||||
msgstr "Диспетчер сети"
|
msgstr "Диспетчер сети"
|
||||||
|
|
||||||
#: js/ui/components/polkitAgent.js:44
|
#: js/ui/components/polkitAgent.js:48
|
||||||
msgid "Authentication Required"
|
msgid "Authentication Required"
|
||||||
msgstr "Требуется подтверждение подлинности"
|
msgstr "Требуется подтверждение подлинности"
|
||||||
|
|
||||||
#: js/ui/components/polkitAgent.js:72
|
#: js/ui/components/polkitAgent.js:76
|
||||||
msgid "Administrator"
|
msgid "Administrator"
|
||||||
msgstr "Администратор"
|
msgstr "Администратор"
|
||||||
|
|
||||||
#: js/ui/components/polkitAgent.js:152
|
#: js/ui/components/polkitAgent.js:156
|
||||||
msgid "Authenticate"
|
msgid "Authenticate"
|
||||||
msgstr "Подтвердить"
|
msgstr "Подтвердить"
|
||||||
|
|
||||||
@ -979,7 +975,7 @@ msgstr "Подтвердить"
|
|||||||
#. * requested authentication was not gained; this can happen
|
#. * requested authentication was not gained; this can happen
|
||||||
#. * because of an authentication error (like invalid password),
|
#. * because of an authentication error (like invalid password),
|
||||||
#. * for instance.
|
#. * for instance.
|
||||||
#: js/ui/components/polkitAgent.js:271 js/ui/shellMountOperation.js:327
|
#: js/ui/components/polkitAgent.js:281 js/ui/shellMountOperation.js:327
|
||||||
msgid "Sorry, that didn’t work. Please try again."
|
msgid "Sorry, that didn’t work. Please try again."
|
||||||
msgstr "Не удалось подтвердить подлинность. Попробуйте снова."
|
msgstr "Не удалось подтвердить подлинность. Попробуйте снова."
|
||||||
|
|
||||||
@ -1004,7 +1000,6 @@ msgstr "Показать приложения"
|
|||||||
msgid "Dash"
|
msgid "Dash"
|
||||||
msgstr "Панель приложений"
|
msgstr "Панель приложений"
|
||||||
|
|
||||||
# fix для даты в календаре и на экране блокировки
|
|
||||||
#. Translators: This is the date format to use when the calendar popup is
|
#. Translators: This is the date format to use when the calendar popup is
|
||||||
#. * shown - it is shown just below the time in the shell (e.g. "Tue 9:29 AM").
|
#. * shown - it is shown just below the time in the shell (e.g. "Tue 9:29 AM").
|
||||||
#.
|
#.
|
||||||
@ -1012,7 +1007,6 @@ msgstr "Панель приложений"
|
|||||||
msgid "%B %e %Y"
|
msgid "%B %e %Y"
|
||||||
msgstr "%-d %B %Y"
|
msgstr "%-d %B %Y"
|
||||||
|
|
||||||
# fix для даты в календаре и на экране блокировки
|
|
||||||
#. Translators: This is the accessible name of the date button shown
|
#. Translators: This is the accessible name of the date button shown
|
||||||
#. * below the time in the shell; it should combine the weekday and the
|
#. * below the time in the shell; it should combine the weekday and the
|
||||||
#. * date, e.g. "Tuesday February 17 2015".
|
#. * date, e.g. "Tuesday February 17 2015".
|
||||||
@ -1029,7 +1023,7 @@ msgstr "Добавить мировые часы…"
|
|||||||
msgid "World Clocks"
|
msgid "World Clocks"
|
||||||
msgstr "Мировые часы"
|
msgstr "Мировые часы"
|
||||||
|
|
||||||
#: js/ui/dateMenu.js:225
|
#: js/ui/dateMenu.js:227
|
||||||
msgid "Weather"
|
msgid "Weather"
|
||||||
msgstr "Погода"
|
msgstr "Погода"
|
||||||
|
|
||||||
@ -1037,7 +1031,7 @@ msgstr "Погода"
|
|||||||
#. libgweather for the possible condition strings. If at all
|
#. libgweather for the possible condition strings. If at all
|
||||||
#. possible, the sentence should match the grammatical case etc. of
|
#. possible, the sentence should match the grammatical case etc. of
|
||||||
#. the inserted conditions.
|
#. the inserted conditions.
|
||||||
#: js/ui/dateMenu.js:289
|
#: js/ui/dateMenu.js:291
|
||||||
#, javascript-format
|
#, javascript-format
|
||||||
msgid "%s all day."
|
msgid "%s all day."
|
||||||
msgstr "%s весь день."
|
msgstr "%s весь день."
|
||||||
@ -1046,7 +1040,7 @@ msgstr "%s весь день."
|
|||||||
#. libgweather for the possible condition strings. If at all
|
#. libgweather for the possible condition strings. If at all
|
||||||
#. possible, the sentence should match the grammatical case etc. of
|
#. possible, the sentence should match the grammatical case etc. of
|
||||||
#. the inserted conditions.
|
#. the inserted conditions.
|
||||||
#: js/ui/dateMenu.js:295
|
#: js/ui/dateMenu.js:297
|
||||||
#, javascript-format
|
#, javascript-format
|
||||||
msgid "%s, then %s later."
|
msgid "%s, then %s later."
|
||||||
msgstr "%s, затем позднее %s."
|
msgstr "%s, затем позднее %s."
|
||||||
@ -1055,30 +1049,30 @@ msgstr "%s, затем позднее %s."
|
|||||||
#. libgweather for the possible condition strings. If at all
|
#. libgweather for the possible condition strings. If at all
|
||||||
#. possible, the sentence should match the grammatical case etc. of
|
#. possible, the sentence should match the grammatical case etc. of
|
||||||
#. the inserted conditions.
|
#. the inserted conditions.
|
||||||
#: js/ui/dateMenu.js:301
|
#: js/ui/dateMenu.js:303
|
||||||
#, javascript-format
|
#, javascript-format
|
||||||
msgid "%s, then %s, followed by %s later."
|
msgid "%s, then %s, followed by %s later."
|
||||||
msgstr "%s, затем %s, позже %s."
|
msgstr "%s, затем %s, позже %s."
|
||||||
|
|
||||||
#: js/ui/dateMenu.js:312
|
#: js/ui/dateMenu.js:314
|
||||||
msgid "Select a location…"
|
msgid "Select a location…"
|
||||||
msgstr "Выберите местоположение…"
|
msgstr "Выберите местоположение…"
|
||||||
|
|
||||||
#: js/ui/dateMenu.js:315
|
#: js/ui/dateMenu.js:317
|
||||||
msgid "Loading…"
|
msgid "Loading…"
|
||||||
msgstr "Загрузка…"
|
msgstr "Загрузка…"
|
||||||
|
|
||||||
#. Translators: %s is a temperature with unit, e.g. "23℃"
|
#. Translators: %s is a temperature with unit, e.g. "23℃"
|
||||||
#: js/ui/dateMenu.js:321
|
#: js/ui/dateMenu.js:323
|
||||||
#, javascript-format
|
#, javascript-format
|
||||||
msgid "Feels like %s."
|
msgid "Feels like %s."
|
||||||
msgstr "Ощущается как %s."
|
msgstr "Ощущается как %s."
|
||||||
|
|
||||||
#: js/ui/dateMenu.js:324
|
#: js/ui/dateMenu.js:326
|
||||||
msgid "Go online for weather information"
|
msgid "Go online for weather information"
|
||||||
msgstr "Подключите интернет для получения информации о погоде"
|
msgstr "Подключите интернет для получения информации о погоде"
|
||||||
|
|
||||||
#: js/ui/dateMenu.js:326
|
#: js/ui/dateMenu.js:328
|
||||||
msgid "Weather information is currently unavailable"
|
msgid "Weather information is currently unavailable"
|
||||||
msgstr "Информация о погоде сейчас недоступна"
|
msgstr "Информация о погоде сейчас недоступна"
|
||||||
|
|
||||||
|
11
src/main.c
11
src/main.c
@ -38,6 +38,7 @@ extern GType gnome_shell_plugin_get_type (void);
|
|||||||
|
|
||||||
static gboolean is_gdm_mode = FALSE;
|
static gboolean is_gdm_mode = FALSE;
|
||||||
static char *session_mode = NULL;
|
static char *session_mode = NULL;
|
||||||
|
static char *override_schema = NULL;
|
||||||
static int caught_signal = 0;
|
static int caught_signal = 0;
|
||||||
|
|
||||||
#define DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER 1
|
#define DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER 1
|
||||||
@ -450,6 +451,12 @@ GOptionEntry gnome_shell_options[] = {
|
|||||||
N_("List possible modes"),
|
N_("List possible modes"),
|
||||||
NULL
|
NULL
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"override-schema", 0, 0, G_OPTION_ARG_STRING,
|
||||||
|
&override_schema,
|
||||||
|
N_("Override the override schema"),
|
||||||
|
"SCHEMA"
|
||||||
|
},
|
||||||
{ NULL }
|
{ NULL }
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -507,7 +514,9 @@ main (int argc, char **argv)
|
|||||||
if (session_mode == NULL)
|
if (session_mode == NULL)
|
||||||
session_mode = is_gdm_mode ? (char *)"gdm" : (char *)"user";
|
session_mode = is_gdm_mode ? (char *)"gdm" : (char *)"user";
|
||||||
|
|
||||||
_shell_global_init ("session-mode", session_mode, NULL);
|
_shell_global_init ("session-mode", session_mode,
|
||||||
|
"override-schema", override_schema,
|
||||||
|
NULL);
|
||||||
|
|
||||||
shell_prefs_init ();
|
shell_prefs_init ();
|
||||||
|
|
||||||
|
@ -265,7 +265,7 @@ shell_app_get_name (ShellApp *app)
|
|||||||
const char *name = NULL;
|
const char *name = NULL;
|
||||||
|
|
||||||
if (window)
|
if (window)
|
||||||
name = meta_window_get_wm_class (window);
|
name = meta_window_get_title (window);
|
||||||
if (!name)
|
if (!name)
|
||||||
name = C_("program", "Unknown");
|
name = C_("program", "Unknown");
|
||||||
return name;
|
return name;
|
||||||
@ -1159,7 +1159,7 @@ shell_app_request_quit (ShellApp *app)
|
|||||||
{
|
{
|
||||||
MetaWindow *win = iter->data;
|
MetaWindow *win = iter->data;
|
||||||
|
|
||||||
if (meta_window_is_skip_taskbar (win))
|
if (!meta_window_can_close (win))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
meta_window_delete (win, shell_global_get_current_time (shell_global_get ()));
|
meta_window_delete (win, shell_global_get_current_time (shell_global_get ()));
|
||||||
|
@ -65,6 +65,7 @@ struct _ShellGlobal {
|
|||||||
MetaScreen *meta_screen;
|
MetaScreen *meta_screen;
|
||||||
|
|
||||||
char *session_mode;
|
char *session_mode;
|
||||||
|
char *override_schema;
|
||||||
|
|
||||||
XserverRegion input_region;
|
XserverRegion input_region;
|
||||||
|
|
||||||
@ -96,6 +97,7 @@ enum {
|
|||||||
PROP_0,
|
PROP_0,
|
||||||
|
|
||||||
PROP_SESSION_MODE,
|
PROP_SESSION_MODE,
|
||||||
|
PROP_OVERRIDE_SCHEMA,
|
||||||
PROP_SCREEN,
|
PROP_SCREEN,
|
||||||
PROP_DISPLAY,
|
PROP_DISPLAY,
|
||||||
PROP_SCREEN_WIDTH,
|
PROP_SCREEN_WIDTH,
|
||||||
@ -138,6 +140,10 @@ shell_global_set_property(GObject *object,
|
|||||||
g_clear_pointer (&global->session_mode, g_free);
|
g_clear_pointer (&global->session_mode, g_free);
|
||||||
global->session_mode = g_ascii_strdown (g_value_get_string (value), -1);
|
global->session_mode = g_ascii_strdown (g_value_get_string (value), -1);
|
||||||
break;
|
break;
|
||||||
|
case PROP_OVERRIDE_SCHEMA:
|
||||||
|
g_clear_pointer (&global->override_schema, g_free);
|
||||||
|
global->override_schema = g_value_dup_string (value);
|
||||||
|
break;
|
||||||
case PROP_FRAME_TIMESTAMPS:
|
case PROP_FRAME_TIMESTAMPS:
|
||||||
global->frame_timestamps = g_value_get_boolean (value);
|
global->frame_timestamps = g_value_get_boolean (value);
|
||||||
break;
|
break;
|
||||||
@ -163,6 +169,9 @@ shell_global_get_property(GObject *object,
|
|||||||
case PROP_SESSION_MODE:
|
case PROP_SESSION_MODE:
|
||||||
g_value_set_string (value, shell_global_get_session_mode (global));
|
g_value_set_string (value, shell_global_get_session_mode (global));
|
||||||
break;
|
break;
|
||||||
|
case PROP_OVERRIDE_SCHEMA:
|
||||||
|
g_value_set_string (value, global->override_schema);
|
||||||
|
break;
|
||||||
case PROP_SCREEN:
|
case PROP_SCREEN:
|
||||||
g_value_set_object (value, global->meta_screen);
|
g_value_set_object (value, global->meta_screen);
|
||||||
break;
|
break;
|
||||||
@ -368,6 +377,13 @@ shell_global_class_init (ShellGlobalClass *klass)
|
|||||||
g_param_spec_string ("session-mode",
|
g_param_spec_string ("session-mode",
|
||||||
"Session Mode",
|
"Session Mode",
|
||||||
"The session mode to use",
|
"The session mode to use",
|
||||||
|
NULL,
|
||||||
|
G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
|
||||||
|
g_object_class_install_property (gobject_class,
|
||||||
|
PROP_OVERRIDE_SCHEMA,
|
||||||
|
g_param_spec_string ("override-schema",
|
||||||
|
"Override Schema",
|
||||||
|
"The override schema to use",
|
||||||
"user",
|
"user",
|
||||||
G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
|
G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
|
||||||
g_object_class_install_property (gobject_class,
|
g_object_class_install_property (gobject_class,
|
||||||
@ -1360,7 +1376,9 @@ shell_global_get_overrides_settings (ShellGlobal *global)
|
|||||||
|
|
||||||
if (!settings)
|
if (!settings)
|
||||||
{
|
{
|
||||||
if (strcmp (global->session_mode, "classic") == 0)
|
if (global->override_schema != NULL)
|
||||||
|
schema = global->override_schema;
|
||||||
|
else if (strcmp (global->session_mode, "classic") == 0)
|
||||||
schema = "org.gnome.shell.extensions.classic-overrides";
|
schema = "org.gnome.shell.extensions.classic-overrides";
|
||||||
else if (strcmp (global->session_mode, "user") == 0)
|
else if (strcmp (global->session_mode, "user") == 0)
|
||||||
schema = "org.gnome.shell.overrides";
|
schema = "org.gnome.shell.overrides";
|
||||||
|
@ -396,18 +396,6 @@ get_gl_vendor (void)
|
|||||||
return vendor;
|
return vendor;
|
||||||
}
|
}
|
||||||
|
|
||||||
gboolean
|
|
||||||
shell_util_need_background_refresh (void)
|
|
||||||
{
|
|
||||||
if (!clutter_check_windowing_backend (CLUTTER_WINDOWING_X11))
|
|
||||||
return FALSE;
|
|
||||||
|
|
||||||
if (g_strcmp0 (get_gl_vendor (), "NVIDIA Corporation") == 0)
|
|
||||||
return TRUE;
|
|
||||||
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
canvas_draw_cb (ClutterContent *content,
|
canvas_draw_cb (ClutterContent *content,
|
||||||
cairo_t *cr,
|
cairo_t *cr,
|
||||||
|
@ -142,7 +142,7 @@ libst_gir = gnome.generate_gir(libst,
|
|||||||
sources: st_gir_sources,
|
sources: st_gir_sources,
|
||||||
nsversion: '1.0',
|
nsversion: '1.0',
|
||||||
namespace: 'St',
|
namespace: 'St',
|
||||||
includes: ['Clutter-' + mutter_api_version, 'Gtk-3.0'],
|
includes: ['Clutter-' + mutter_api_version, 'Cally-' + mutter_api_version, 'Gtk-3.0'],
|
||||||
dependencies: [mutter_dep],
|
dependencies: [mutter_dep],
|
||||||
include_directories: include_directories('..'),
|
include_directories: include_directories('..'),
|
||||||
extra_args: ['-DST_COMPILATION', '--quiet'],
|
extra_args: ['-DST_COMPILATION', '--quiet'],
|
||||||
|
@ -180,6 +180,7 @@ st_label_dispose (GObject *object)
|
|||||||
{
|
{
|
||||||
StLabelPrivate *priv = ST_LABEL (object)->priv;
|
StLabelPrivate *priv = ST_LABEL (object)->priv;
|
||||||
|
|
||||||
|
priv->label = NULL;
|
||||||
g_clear_pointer (&priv->text_shadow_pipeline, cogl_object_unref);
|
g_clear_pointer (&priv->text_shadow_pipeline, cogl_object_unref);
|
||||||
|
|
||||||
G_OBJECT_CLASS (st_label_parent_class)->dispose (object);
|
G_OBJECT_CLASS (st_label_parent_class)->dispose (object);
|
||||||
|
@ -37,6 +37,7 @@ struct _StTextureCachePrivate
|
|||||||
|
|
||||||
/* Things that were loaded with a cache policy != NONE */
|
/* Things that were loaded with a cache policy != NONE */
|
||||||
GHashTable *keyed_cache; /* char * -> CoglTexture* */
|
GHashTable *keyed_cache; /* char * -> CoglTexture* */
|
||||||
|
GHashTable *keyed_surface_cache; /* char * -> cairo_surface_t* */
|
||||||
|
|
||||||
/* Presently this is used to de-duplicate requests for GIcons and async URIs. */
|
/* Presently this is used to de-duplicate requests for GIcons and async URIs. */
|
||||||
GHashTable *outstanding_requests; /* char * -> AsyncTextureLoadData * */
|
GHashTable *outstanding_requests; /* char * -> AsyncTextureLoadData * */
|
||||||
@ -104,6 +105,18 @@ st_texture_cache_class_init (StTextureCacheClass *klass)
|
|||||||
G_TYPE_NONE, 1, G_TYPE_FILE);
|
G_TYPE_NONE, 1, G_TYPE_FILE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Evicts all cached textures */
|
||||||
|
void
|
||||||
|
st_texture_cache_clear (StTextureCache *cache)
|
||||||
|
{
|
||||||
|
GHashTableIter iter;
|
||||||
|
gpointer key;
|
||||||
|
gpointer value;
|
||||||
|
|
||||||
|
g_hash_table_remove_all (cache->priv->keyed_cache);
|
||||||
|
g_signal_emit (cache, signals[ICON_THEME_CHANGED], 0);
|
||||||
|
}
|
||||||
|
|
||||||
/* Evicts all cached textures for named icons */
|
/* Evicts all cached textures for named icons */
|
||||||
static void
|
static void
|
||||||
st_texture_cache_evict_icons (StTextureCache *cache)
|
st_texture_cache_evict_icons (StTextureCache *cache)
|
||||||
@ -145,6 +158,10 @@ st_texture_cache_init (StTextureCache *self)
|
|||||||
|
|
||||||
self->priv->keyed_cache = g_hash_table_new_full (g_str_hash, g_str_equal,
|
self->priv->keyed_cache = g_hash_table_new_full (g_str_hash, g_str_equal,
|
||||||
g_free, cogl_object_unref);
|
g_free, cogl_object_unref);
|
||||||
|
self->priv->keyed_surface_cache = g_hash_table_new_full (g_str_hash,
|
||||||
|
g_str_equal,
|
||||||
|
g_free,
|
||||||
|
(GDestroyNotify) cairo_surface_destroy);
|
||||||
self->priv->outstanding_requests = g_hash_table_new_full (g_str_hash, g_str_equal,
|
self->priv->outstanding_requests = g_hash_table_new_full (g_str_hash, g_str_equal,
|
||||||
g_free, NULL);
|
g_free, NULL);
|
||||||
self->priv->file_monitors = g_hash_table_new_full (g_file_hash, (GEqualFunc) g_file_equal,
|
self->priv->file_monitors = g_hash_table_new_full (g_file_hash, (GEqualFunc) g_file_equal,
|
||||||
@ -166,6 +183,7 @@ st_texture_cache_dispose (GObject *object)
|
|||||||
}
|
}
|
||||||
|
|
||||||
g_clear_pointer (&self->priv->keyed_cache, g_hash_table_destroy);
|
g_clear_pointer (&self->priv->keyed_cache, g_hash_table_destroy);
|
||||||
|
g_clear_pointer (&self->priv->keyed_surface_cache, g_hash_table_destroy);
|
||||||
g_clear_pointer (&self->priv->outstanding_requests, g_hash_table_destroy);
|
g_clear_pointer (&self->priv->outstanding_requests, g_hash_table_destroy);
|
||||||
g_clear_pointer (&self->priv->file_monitors, g_hash_table_destroy);
|
g_clear_pointer (&self->priv->file_monitors, g_hash_table_destroy);
|
||||||
|
|
||||||
@ -520,6 +538,8 @@ finish_texture_load (AsyncTextureLoadData *data,
|
|||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
texdata = pixbuf_to_cogl_texture (pixbuf);
|
texdata = pixbuf_to_cogl_texture (pixbuf);
|
||||||
|
if (!texdata)
|
||||||
|
goto out;
|
||||||
|
|
||||||
if (data->policy != ST_TEXTURE_CACHE_POLICY_NONE)
|
if (data->policy != ST_TEXTURE_CACHE_POLICY_NONE)
|
||||||
{
|
{
|
||||||
@ -986,7 +1006,7 @@ file_changed_cb (GFileMonitor *monitor,
|
|||||||
g_free (key);
|
g_free (key);
|
||||||
|
|
||||||
key = g_strdup_printf (CACHE_PREFIX_FILE_FOR_CAIRO "%u", file_hash);
|
key = g_strdup_printf (CACHE_PREFIX_FILE_FOR_CAIRO "%u", file_hash);
|
||||||
g_hash_table_remove (cache->priv->keyed_cache, key);
|
g_hash_table_remove (cache->priv->keyed_surface_cache, key);
|
||||||
g_free (key);
|
g_free (key);
|
||||||
|
|
||||||
g_signal_emit (cache, signals[TEXTURE_FILE_CHANGED], 0, file);
|
g_signal_emit (cache, signals[TEXTURE_FILE_CHANGED], 0, file);
|
||||||
@ -1273,6 +1293,9 @@ st_texture_cache_load_file_sync_to_cogl_texture (StTextureCache *cache,
|
|||||||
texdata = pixbuf_to_cogl_texture (pixbuf);
|
texdata = pixbuf_to_cogl_texture (pixbuf);
|
||||||
g_object_unref (pixbuf);
|
g_object_unref (pixbuf);
|
||||||
|
|
||||||
|
if (!texdata)
|
||||||
|
goto out;
|
||||||
|
|
||||||
if (policy == ST_TEXTURE_CACHE_POLICY_FOREVER)
|
if (policy == ST_TEXTURE_CACHE_POLICY_FOREVER)
|
||||||
{
|
{
|
||||||
cogl_object_ref (texdata);
|
cogl_object_ref (texdata);
|
||||||
@ -1304,7 +1327,7 @@ st_texture_cache_load_file_sync_to_cairo_surface (StTextureCache *cache,
|
|||||||
|
|
||||||
key = g_strdup_printf (CACHE_PREFIX_FILE_FOR_CAIRO "%u", g_file_hash (file));
|
key = g_strdup_printf (CACHE_PREFIX_FILE_FOR_CAIRO "%u", g_file_hash (file));
|
||||||
|
|
||||||
surface = g_hash_table_lookup (cache->priv->keyed_cache, key);
|
surface = g_hash_table_lookup (cache->priv->keyed_surface_cache, key);
|
||||||
|
|
||||||
if (surface == NULL)
|
if (surface == NULL)
|
||||||
{
|
{
|
||||||
@ -1318,7 +1341,8 @@ st_texture_cache_load_file_sync_to_cairo_surface (StTextureCache *cache,
|
|||||||
if (policy == ST_TEXTURE_CACHE_POLICY_FOREVER)
|
if (policy == ST_TEXTURE_CACHE_POLICY_FOREVER)
|
||||||
{
|
{
|
||||||
cairo_surface_reference (surface);
|
cairo_surface_reference (surface);
|
||||||
g_hash_table_insert (cache->priv->keyed_cache, g_strdup (key), surface);
|
g_hash_table_insert (cache->priv->keyed_surface_cache,
|
||||||
|
g_strdup (key), surface);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -52,6 +52,7 @@ typedef enum {
|
|||||||
} StTextureCachePolicy;
|
} StTextureCachePolicy;
|
||||||
|
|
||||||
StTextureCache* st_texture_cache_get_default (void);
|
StTextureCache* st_texture_cache_get_default (void);
|
||||||
|
void st_texture_cache_clear (StTextureCache *cache);
|
||||||
|
|
||||||
ClutterActor *
|
ClutterActor *
|
||||||
st_texture_cache_load_sliced_image (StTextureCache *cache,
|
st_texture_cache_load_sliced_image (StTextureCache *cache,
|
||||||
|
Loading…
Reference in New Issue
Block a user