Compare commits
2 Commits
wip/is-swi
...
wip/gcampa
Author | SHA1 | Date | |
---|---|---|---|
6d4ca1fcc8 | |||
93b1af401f |
102
NEWS
102
NEWS
@ -1,105 +1,3 @@
|
||||
3.8.0.1
|
||||
=======
|
||||
* Background bug fixes [Ray; #696712]
|
||||
|
||||
3.8.0
|
||||
=====
|
||||
* Remove blur and desaturation from lock screen [Jasper; #696322]
|
||||
* Remove scroll view fade near edges [Adel; #696404]
|
||||
* dateMenu: Open calendar component when using Evolution [Florian; #696432]
|
||||
* Fix unlocking on fast user switch [Cosimo; #696287]
|
||||
* Tweak screen shield animation [Rui; #696380]
|
||||
* Fix major memory leak when changing backgrounds [Ray; #696157]
|
||||
* Miscellaneous bug fixes [Jasper, Adel, Florian; #696199, #696212, #696422,
|
||||
#696447, #696235]
|
||||
|
||||
Contributors:
|
||||
Giovanni Campagna, Cosimo Cecchi, Adel Gadllah, Rui Matos, Florian Müllner,
|
||||
Jasper St. Pierre, Ray Strode
|
||||
|
||||
Translations:
|
||||
Alexandre Franke [fr], Victor Ibragimov [tg], Arash Mousavi [fa],
|
||||
Gabor Kelemen [hu], Sandeep Sheshrao Shedmake [mr], ManojKumar Giri [or],
|
||||
Shantha kumar [ta], Rajesh Ranjan [hi], Stas Solovey [ru],
|
||||
Shankar Prasad [kn], Dušan Kazik [sk], Ihar Hrachyshka [be],
|
||||
Wouter Bolsterlee [nl], Kris Thomsen [da], Jiro Matsuzawa [ja],
|
||||
Daniel Korostil [uk], Ani Peter [ml], Krishnababu Krothapalli [te],
|
||||
Mantas Kriaučiūnas [lt], Praveen Illa [te]
|
||||
|
||||
3.7.92
|
||||
======
|
||||
* Drop fallback lock implementation [Florian; #693403]
|
||||
* Don't let the user trigger message-tray when in fullscreen [Jasper; #694997]
|
||||
* Scroll search results when using keynav [Jasper; #689681]
|
||||
* Allow raising the shield by starting to type the password [Jasper; #686740]
|
||||
* Improve tracking of fullscreen windows [Owen; #649748]
|
||||
* Improve animation of new windows in overview [Giovanni; #695582]
|
||||
* workspace switcher: Animate new workspaces created by DND [Giovanni; #685285]
|
||||
* Give user time to read messages on login screen [Ray; #694688]
|
||||
* Misc bug fixes and cleanups [Jasper, Ray, Florian, Cosimo, Giovanni, Adel,
|
||||
Stef, Takao, Rui, Neil; #695154, #694993, #695272, #691578, #694321, #695338,
|
||||
#695409, #695458, #695526, #695601, #695471, #695324, #695650, #695656,
|
||||
#695659, #695485, #695395, #694951, #695824, #695841, #695801, #694321,
|
||||
#693708, #695800, #695607, #695882, #691578, #685851, #694371, #690857,
|
||||
#694092, #695747, #696007, #693438, #696064, #696102
|
||||
|
||||
Contributors:
|
||||
Giovanni Campagna, Cosimo Cecchi, Allan Day, Takao Fujiwara, Adel Gadllah,
|
||||
Tim Lunn, Rui Matos, Florian Müllner, Neil Roberts, Jasper St. Pierre,
|
||||
Ray Strode, Stef Walter, Colin Walters, Owen W. Taylor
|
||||
|
||||
Translations:
|
||||
Nilamdyuti Goswami [as], Chao-Hsiung Liao [zh_HK, zh_TW],
|
||||
Yuri Myasoedov [ru], Gheyret Kenji [ug], Baurzhan Muftakhidinov [kk],
|
||||
Ville-Pekka Vainio [fi], Matej Urbančič [sl],
|
||||
Мирослав Николић [sr, sr@latin], Rūdolfs Mazurs [lv], Christian Kirbach [de],
|
||||
Andika Triwidada [id], Gil Forcada [ca], Mattias Põldaru [et],
|
||||
Duarte Loreto [pt], Adam Matoušek [cs], Changwoo Ryu [ko],
|
||||
Ihar Hrachyshka [be], Carles Ferrando [ca@valencia], Sweta Kothari [gu]
|
||||
|
||||
3.7.91
|
||||
======
|
||||
* overview: Fade out controls during DND that are not targets [Cosimo; #686984]
|
||||
* overview: Keep open when a Control key is held [Florian; #686984]
|
||||
* Improve login screen => session transition [Ray; #694321]
|
||||
* Center application grid horizontally [Florian; #694261]
|
||||
* Fix hiding panel when fullscreen windows span multiple monitors [Adel; 646861]
|
||||
* Tweak thresholds of pressure barrier [Jasper; #694467]
|
||||
* Tweak window picker layout [Jasper; #694902]
|
||||
* Expose key grab DBus API to gnome-settings-daemon [Florian; #643111]
|
||||
* Don't always show message tray in overview, add message indicator
|
||||
[Cosimo; #687787]
|
||||
* Tweak startup animation [Ray; #694326]
|
||||
* Add OSD popups and expose them to gnome-settings-daemon [Florian; #613543]
|
||||
* Move loupe icon to the start of the search entry [Jasper; #695069]
|
||||
* Don't show the input switcher with less than 2 items [Rui; 695000]
|
||||
* Fix auto-completion of system modals immediately upon display [Stef; #692937]
|
||||
* Ignore workspaces in alt-tab [Florian; #661156]
|
||||
* Disable copying text from password entries [Florian; #695104]
|
||||
* Use standard styling for ibus candidate popups [Allan; #694796]
|
||||
* Fix calendar changing height on month changes [Giovanni; #641383]
|
||||
* Port the hot corner to use pressure barriers [Jasper; #663661]
|
||||
* Misc bug fixes and cleanups: [Hashem, Giovanni, Alban, Jasper, Cosimo,
|
||||
Florian, Adel, Daniel, Matthias, Ray, Rui, Guillaume, Stef; #685849, #690643,
|
||||
#694292, #693814, #694234, #694365, #694287, #694336, #694256, #694261,
|
||||
#663601, #694441, #694284, #694463, #694475, #687248, #694394, #694320,
|
||||
#694701, #694784, #694858, #694906, #694327, #694876, #694905, #694969,
|
||||
#694970, #694988, #695006, #695001, #694998, #695023, #695002, #695073,
|
||||
#695126, #687748, #694837, #693907, #679851, #694988]
|
||||
|
||||
Contributors:
|
||||
Giovanni Campagna, Cosimo Cecchi, Matthias Clasen, Alban Crequy, Allan Day,
|
||||
Guillaume Desmottes, Adel Gadllah, Rui Matos, Daniel Mustieles,
|
||||
Hashem Nasarat, Jasper St. Pierre, Ray Strode, Stef Walter
|
||||
|
||||
Translations:
|
||||
Yuri Myasoedov [ru], Adam Matoušek [cs], Piotr Drąg [pl], Matej Urbančič [sl],
|
||||
Sweta Kothari [gu], Kjartan Maraas [nb], Nguyễn Thái Ngọc Duy [vi],
|
||||
Chao-Hsiung Liao [zh_HK, zh_TW], Dimitris Spingos [el],
|
||||
Inaki Larranaga Murgoitio [eu], Luca Ferretti [it], A S Alam [pa],
|
||||
Gheyret Kenji [ug], Stas Solovey [ru], Enrico Nicoletto [pt_BR],
|
||||
Fran Diéguez [gl], Daniel Mustieles [es], Aurimas Černius [lt]
|
||||
|
||||
3.7.90
|
||||
======
|
||||
* Let GNOME Shell work on EGL and GLES2 [Neil; #693225, #693438, #693339]
|
||||
|
@ -1,5 +1,5 @@
|
||||
AC_PREREQ(2.63)
|
||||
AC_INIT([gnome-shell],[3.8.0.1],[https://bugzilla.gnome.org/enter_bug.cgi?product=gnome-shell],[gnome-shell])
|
||||
AC_INIT([gnome-shell],[3.7.90],[https://bugzilla.gnome.org/enter_bug.cgi?product=gnome-shell],[gnome-shell])
|
||||
|
||||
AC_CONFIG_HEADERS([config.h])
|
||||
AC_CONFIG_SRCDIR([src/shell-global.c])
|
||||
@ -63,7 +63,7 @@ AM_CONDITIONAL(BUILD_RECORDER, $build_recorder)
|
||||
CLUTTER_MIN_VERSION=1.13.4
|
||||
GOBJECT_INTROSPECTION_MIN_VERSION=0.10.1
|
||||
GJS_MIN_VERSION=1.35.4
|
||||
MUTTER_MIN_VERSION=3.8.0
|
||||
MUTTER_MIN_VERSION=3.7.90
|
||||
GTK_MIN_VERSION=3.7.9
|
||||
GIO_MIN_VERSION=2.35.0
|
||||
LIBECAL_MIN_VERSION=3.5.3
|
||||
@ -96,7 +96,7 @@ PKG_CHECK_MODULES(GNOME_SHELL, gio-unix-2.0 >= $GIO_MIN_VERSION
|
||||
polkit-agent-1 >= $POLKIT_MIN_VERSION xfixes
|
||||
libnm-glib libnm-util >= $NETWORKMANAGER_MIN_VERSION
|
||||
libnm-gtk >= $NETWORKMANAGER_MIN_VERSION
|
||||
libsecret-unstable gcr-3 >= $GCR_MIN_VERSION)
|
||||
gnome-keyring-1 gcr-3 >= $GCR_MIN_VERSION)
|
||||
|
||||
PKG_CHECK_MODULES(GNOME_SHELL_JS, gio-2.0 gjs-internals-1.0 >= $GJS_MIN_VERSION)
|
||||
PKG_CHECK_MODULES(ST, clutter-1.0 gtk+-3.0 libcroco-0.6 >= 0.6.8 x11)
|
||||
|
@ -1,6 +1,3 @@
|
||||
wandadir = $(pkgdatadir)
|
||||
dist_wanda_DATA = wanda.png
|
||||
|
||||
desktopdir=$(datadir)/applications
|
||||
desktop_DATA = gnome-shell.desktop gnome-shell-extension-prefs.desktop
|
||||
|
||||
|
@ -125,8 +125,7 @@ StScrollBar StButton#vhandle:active {
|
||||
|
||||
/* PopupMenu */
|
||||
|
||||
.popup-menu-boxpointer,
|
||||
.candidate-popup-boxpointer {
|
||||
.popup-menu-boxpointer {
|
||||
-arrow-border-radius: 8px;
|
||||
-arrow-background-color: rgba(0,0,0,0.9);
|
||||
-arrow-border-width: 2px;
|
||||
@ -316,20 +315,10 @@ StScrollBar StButton#vhandle:active {
|
||||
.notification-button:focus,
|
||||
.notification-icon-button:focus,
|
||||
.hotplug-notification-item:focus,
|
||||
.modal-dialog-button:focus,
|
||||
.app-view-control:focus {
|
||||
.modal-dialog-button:focus {
|
||||
border-width: 2px;
|
||||
}
|
||||
|
||||
.app-view-control:focus {
|
||||
padding: 3px;
|
||||
}
|
||||
|
||||
.app-view-control:first-child:ltr:focus,
|
||||
.app-view-control:last-child:rtl:focus {
|
||||
border-right-width: 1px;
|
||||
}
|
||||
|
||||
.candidate-page-button:active,
|
||||
.candidate-page-button:pressed,
|
||||
.notification-button:active,
|
||||
@ -897,8 +886,8 @@ StScrollBar StButton#vhandle:active {
|
||||
.search-display > StBoxLayout,
|
||||
.all-apps > StBoxLayout,
|
||||
.frequent-apps > StBoxLayout {
|
||||
/* horizontal padding to make sure scrollbars or dash don't overlap content */
|
||||
padding: 0px 88px;
|
||||
/* horizontal padding to make sure the scrollbar doesn't overlap content */
|
||||
padding: 0px 18px;
|
||||
}
|
||||
|
||||
.app-folder-icon {
|
||||
@ -974,10 +963,6 @@ StScrollBar StButton#vhandle:active {
|
||||
color:white;
|
||||
}
|
||||
|
||||
.app-display .app-well-app > .overview-icon {
|
||||
border-radius: 10px;
|
||||
}
|
||||
|
||||
.list-search-result:hover .list-search-result-description {
|
||||
text-shadow: rgba(0,0,0,0.8) 0px 1px 2px;
|
||||
}
|
||||
@ -1272,15 +1257,15 @@ StScrollBar StButton#vhandle:active {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.calendar-other-month-day {
|
||||
color: #333333;
|
||||
}
|
||||
|
||||
.calendar-day-with-events {
|
||||
font-weight: bold;
|
||||
color: white;
|
||||
}
|
||||
|
||||
.calendar-other-month-day {
|
||||
color: #333333;
|
||||
}
|
||||
|
||||
.events-header-vbox {
|
||||
spacing: 6pt;
|
||||
padding-right: .5em;
|
||||
@ -2144,12 +2129,23 @@ StScrollBar StButton#vhandle:active {
|
||||
}
|
||||
|
||||
/* IBus Candidate Popup */
|
||||
.candidate-popup-boxpointer {
|
||||
-arrow-border-radius: 8px;
|
||||
-arrow-background-color: #707070;
|
||||
-arrow-border-width: 0px;
|
||||
-arrow-base: 24px;
|
||||
-arrow-rise: 11px;
|
||||
}
|
||||
|
||||
.candidate-popup-content {
|
||||
padding: 0.5em;
|
||||
spacing: 0.3em;
|
||||
}
|
||||
|
||||
.candidate-popup-text {
|
||||
font-size: 9pt;
|
||||
}
|
||||
|
||||
.candidate-index {
|
||||
padding: 0 0.5em 0 0;
|
||||
color: #cccccc;
|
||||
@ -2215,9 +2211,6 @@ StScrollBar StButton#vhandle:active {
|
||||
border: none;
|
||||
background-color: transparent;
|
||||
|
||||
padding-bottom: 80px;
|
||||
padding-top: 80px;
|
||||
|
||||
border-radius: 16px;
|
||||
min-height: 150px;
|
||||
max-height: 700px;
|
||||
|
BIN
data/wanda.png
BIN
data/wanda.png
Binary file not shown.
Before Width: | Height: | Size: 13 KiB |
@ -66,4 +66,11 @@ its dependencies to build from tarballs.</description>
|
||||
<gnome:userid>fmuellner</gnome:userid>
|
||||
</foaf:Person>
|
||||
</maintainer>
|
||||
<maintainer>
|
||||
<foaf:Person>
|
||||
<foaf:name>Ray Strode</foaf:name>
|
||||
<foaf:mbox rdf:resource="mailto:halfline@gmail.com" />
|
||||
<gnome:userid>halfline</gnome:userid>
|
||||
</foaf:Person>
|
||||
</maintainer>
|
||||
</Project>
|
||||
|
@ -594,7 +594,6 @@ const LoginDialog = new Lang.Class({
|
||||
this._promptEntry = new St.Entry({ style_class: 'login-dialog-prompt-entry',
|
||||
can_focus: true });
|
||||
this._promptEntryTextChangedId = 0;
|
||||
this._promptEntryActivateId = 0;
|
||||
this._promptBox.add(this._promptEntry,
|
||||
{ expand: true,
|
||||
x_fill: true,
|
||||
@ -691,8 +690,6 @@ const LoginDialog = new Lang.Class({
|
||||
},
|
||||
|
||||
_reset: function() {
|
||||
this._userVerifier.clear();
|
||||
|
||||
this._updateSensitivity(true);
|
||||
this._promptMessage.hide();
|
||||
this._user = null;
|
||||
@ -814,11 +811,6 @@ const LoginDialog = new Lang.Class({
|
||||
Lang.bind(this, function() {
|
||||
this._updateSignInButtonSensitivity(this._promptEntry.text.length > 0);
|
||||
}));
|
||||
|
||||
this._promptEntryActivateId =
|
||||
this._promptEntry.clutter_text.connect('activate', function() {
|
||||
hold.release();
|
||||
});
|
||||
},
|
||||
|
||||
_updateSensitivity: function(sensitive) {
|
||||
@ -843,11 +835,6 @@ const LoginDialog = new Lang.Class({
|
||||
this._promptEntryTextChangedId = 0;
|
||||
}
|
||||
|
||||
if (this._promptEntryActivateId > 0) {
|
||||
this._promptEntry.clutter_text.disconnect(this._promptEntryActivateId);
|
||||
this._promptEntryActivateId = 0;
|
||||
}
|
||||
|
||||
this._setWorking(false);
|
||||
this._promptBox.hide();
|
||||
this._promptLoginHint.hide();
|
||||
@ -930,7 +917,7 @@ const LoginDialog = new Lang.Class({
|
||||
return batch.run();
|
||||
},
|
||||
|
||||
_startSession: function(serviceName) {
|
||||
_onSessionOpened: function(client, serviceName) {
|
||||
Tweener.addTween(this.dialogLayout,
|
||||
{ opacity: 0,
|
||||
time: _FADE_ANIMATION_TIME,
|
||||
@ -953,18 +940,6 @@ const LoginDialog = new Lang.Class({
|
||||
onCompleteScope: this });
|
||||
},
|
||||
|
||||
_onSessionOpened: function(client, serviceName) {
|
||||
if (!this._userVerifier.hasPendingMessages) {
|
||||
this._startSession(serviceName);
|
||||
} else {
|
||||
let signalId = this._userVerifier.connect('no-more-messages',
|
||||
Lang.bind(this, function() {
|
||||
this._userVerifier.disconnect(signalId);
|
||||
this._startSession(serviceName);
|
||||
}));
|
||||
}
|
||||
},
|
||||
|
||||
_waitForItemForUser: function(userName) {
|
||||
let item = this._userList.getItemFromUserName(userName);
|
||||
|
||||
@ -1028,7 +1003,7 @@ const LoginDialog = new Lang.Class({
|
||||
function() {
|
||||
// If we're just starting out, start on the right
|
||||
// item.
|
||||
if (!this._userManager.is_loaded) {
|
||||
if (!this.is_loaded) {
|
||||
this._userList.jumpToItem(this._timedLoginItem);
|
||||
}
|
||||
},
|
||||
@ -1166,6 +1141,15 @@ const LoginDialog = new Lang.Class({
|
||||
Lang.bind(this, function(userManager, user) {
|
||||
this._userList.removeUser(user);
|
||||
}));
|
||||
|
||||
// emitted in idle so caller doesn't have to explicitly check if
|
||||
// it's loaded immediately after construction
|
||||
// (since there's no way the caller could be listening for
|
||||
// 'loaded' yet)
|
||||
Mainloop.idle_add(Lang.bind(this, function() {
|
||||
this.emit('loaded');
|
||||
this.is_loaded = true;
|
||||
}));
|
||||
},
|
||||
|
||||
_onOpened: function() {
|
||||
@ -1180,9 +1164,5 @@ const LoginDialog = new Lang.Class({
|
||||
this.parent();
|
||||
|
||||
Main.ctrlAltTabManager.removeGroup(this.dialogLayout);
|
||||
},
|
||||
|
||||
addCharacter: function(unichar) {
|
||||
this._promptEntry.clutter_text.insert_unichar(unichar);
|
||||
},
|
||||
}
|
||||
});
|
||||
|
116
js/gdm/util.js
116
js/gdm/util.js
@ -2,7 +2,6 @@
|
||||
|
||||
const Clutter = imports.gi.Clutter;
|
||||
const Gio = imports.gi.Gio;
|
||||
const GLib = imports.gi.GLib;
|
||||
const Lang = imports.lang;
|
||||
const Mainloop = imports.mainloop;
|
||||
const Signals = imports.signals;
|
||||
@ -28,9 +27,6 @@ const ALLOWED_FAILURES_KEY = 'allowed-failures';
|
||||
const LOGO_KEY = 'logo';
|
||||
const DISABLE_USER_LIST_KEY = 'disable-user-list';
|
||||
|
||||
// Give user 16ms to read each character of a PAM message
|
||||
const USER_READ_TIME = 16
|
||||
|
||||
function fadeInActor(actor) {
|
||||
if (actor.opacity == 255 && actor.visible)
|
||||
return null;
|
||||
@ -118,9 +114,6 @@ const ShellUserVerifier = new Lang.Class({
|
||||
|
||||
this._fprintManager = new Fprint.FprintManager();
|
||||
this._realmManager = new Realmd.Manager();
|
||||
this._messageQueue = [];
|
||||
this._messageQueueTimeoutId = 0;
|
||||
this.hasPendingMessages = false;
|
||||
|
||||
this._failCounter = 0;
|
||||
},
|
||||
@ -160,73 +153,13 @@ const ShellUserVerifier = new Lang.Class({
|
||||
this._userVerifier.run_dispose();
|
||||
this._userVerifier = null;
|
||||
}
|
||||
|
||||
this._clearMessageQueue();
|
||||
},
|
||||
|
||||
answerQuery: function(serviceName, answer) {
|
||||
if (!this._userVerifier.hasPendingMessages) {
|
||||
this._userVerifier.call_answer_query(serviceName, answer, this._cancellable, null);
|
||||
} else {
|
||||
let signalId = this._userVerifier.connect('no-more-messages',
|
||||
Lang.bind(this, function() {
|
||||
this._userVerifier.disconnect(signalId);
|
||||
this._userVerifier.call_answer_query(serviceName, answer, this._cancellable, null);
|
||||
}));
|
||||
}
|
||||
},
|
||||
|
||||
_getIntervalForMessage: function(message) {
|
||||
// We probably could be smarter here
|
||||
return message.length * USER_READ_TIME;
|
||||
},
|
||||
|
||||
finishMessageQueue: function() {
|
||||
if (!this.hasPendingMessages)
|
||||
return;
|
||||
|
||||
this._messageQueue = [];
|
||||
|
||||
this.hasPendingMessages = false;
|
||||
this.emit('no-more-messages');
|
||||
},
|
||||
|
||||
_queueMessageTimeout: function() {
|
||||
if (this._messageQueue.length == 0) {
|
||||
this.finishMessageQueue();
|
||||
return;
|
||||
}
|
||||
|
||||
if (this._messageQueueTimeoutId != 0)
|
||||
return;
|
||||
|
||||
let message = this._messageQueue.shift();
|
||||
this.emit('show-message', message.text, message.iconName);
|
||||
|
||||
this._messageQueueTimeoutId = GLib.timeout_add(GLib.PRIORITY_DEFAULT,
|
||||
message.interval,
|
||||
Lang.bind(this, function() {
|
||||
this._messageQueueTimeoutId = 0;
|
||||
this._queueMessageTimeout();
|
||||
}));
|
||||
},
|
||||
|
||||
_queueMessage: function(message, iconName) {
|
||||
let interval = this._getIntervalForMessage(message);
|
||||
|
||||
this.hasPendingMessages = true;
|
||||
this._messageQueue.push({ text: message, interval: interval, iconName: iconName });
|
||||
this._queueMessageTimeout();
|
||||
},
|
||||
|
||||
_clearMessageQueue: function() {
|
||||
this.finishMessageQueue();
|
||||
|
||||
if (this._messageQueueTimeoutId != 0) {
|
||||
GLib.source_remove(this._messageQueueTimeoutId);
|
||||
this._messageQueueTimeoutId = 0;
|
||||
}
|
||||
// Clear any previous message
|
||||
this.emit('show-message', null, null);
|
||||
|
||||
this._userVerifier.call_answer_query(serviceName, answer, this._cancellable, null);
|
||||
},
|
||||
|
||||
_checkForFingerprintReader: function() {
|
||||
@ -246,7 +179,7 @@ const ShellUserVerifier = new Lang.Class({
|
||||
logError(error, where);
|
||||
this._hold.release();
|
||||
|
||||
this._queueMessage(_("Authentication error"), 'login-dialog-message-warning');
|
||||
this.emit('show-message', _("Authentication error"), 'login-dialog-message-warning');
|
||||
this._verificationFailed(false);
|
||||
},
|
||||
|
||||
@ -365,7 +298,7 @@ const ShellUserVerifier = new Lang.Class({
|
||||
// to indicate the user can swipe their finger instead
|
||||
this.emit('show-login-hint', _("(or swipe finger)"));
|
||||
} else if (serviceName == PASSWORD_SERVICE_NAME) {
|
||||
this._queueMessage(info, 'login-dialog-message-info');
|
||||
this.emit('show-message', info, 'login-dialog-message-info');
|
||||
}
|
||||
},
|
||||
|
||||
@ -374,7 +307,7 @@ const ShellUserVerifier = new Lang.Class({
|
||||
// users who haven't enrolled their fingerprint.
|
||||
if (serviceName != PASSWORD_SERVICE_NAME)
|
||||
return;
|
||||
this._queueMessage(problem, 'login-dialog-message-warning');
|
||||
this.emit('show-message', problem, 'login-dialog-message-warning');
|
||||
},
|
||||
|
||||
_showRealmLoginHint: function() {
|
||||
@ -413,6 +346,8 @@ const ShellUserVerifier = new Lang.Class({
|
||||
},
|
||||
|
||||
_onReset: function() {
|
||||
this.clear();
|
||||
|
||||
// Clear previous attempts to authenticate
|
||||
this._failCounter = 0;
|
||||
|
||||
@ -423,15 +358,6 @@ const ShellUserVerifier = new Lang.Class({
|
||||
this.emit('verification-complete');
|
||||
},
|
||||
|
||||
_cancelAndReset: function() {
|
||||
this.cancel();
|
||||
this._onReset();
|
||||
},
|
||||
|
||||
_retry: function() {
|
||||
this.begin(this._userName, new Batch.Hold());
|
||||
},
|
||||
|
||||
_verificationFailed: function(retry) {
|
||||
// For Not Listed / enterprise logins, immediately reset
|
||||
// the dialog
|
||||
@ -443,25 +369,15 @@ const ShellUserVerifier = new Lang.Class({
|
||||
this._failCounter < this._settings.get_int(ALLOWED_FAILURES_KEY);
|
||||
|
||||
if (canRetry) {
|
||||
if (!this._userVerifier.hasPendingMessages) {
|
||||
this._retry();
|
||||
} else {
|
||||
let signalId = this._userVerifier.connect('no-more-messages',
|
||||
Lang.bind(this, function() {
|
||||
this._userVerifier.disconnect(signalId);
|
||||
this._retry();
|
||||
}));
|
||||
}
|
||||
this.clear();
|
||||
this.begin(this._userName, new Batch.Hold());
|
||||
} else {
|
||||
if (!this._userVerifier.hasPendingMessages) {
|
||||
this._cancelAndReset();
|
||||
} else {
|
||||
let signalId = this._userVerifier.connect('no-more-messages',
|
||||
Lang.bind(this, function() {
|
||||
this._userVerifier.disconnect(signalId);
|
||||
this._cancelAndReset();
|
||||
}));
|
||||
}
|
||||
// Allow some time to see the message, then reset everything
|
||||
Mainloop.timeout_add(3000, Lang.bind(this, function() {
|
||||
this.cancel();
|
||||
|
||||
this._onReset();
|
||||
}));
|
||||
}
|
||||
|
||||
this.emit('verification-failed');
|
||||
|
@ -33,10 +33,6 @@ const SystemdLoginManagerIface = <interface name='org.freedesktop.login1.Manager
|
||||
<arg type='s' direction='in'/>
|
||||
<arg type='h' direction='out'/>
|
||||
</method>
|
||||
<method name='GetSession'>
|
||||
<arg type='s' direction='in'/>
|
||||
<arg type='o' direction='out'/>
|
||||
</method>
|
||||
<method name='ListSessions'>
|
||||
<arg name='sessions' type='a(susso)' direction='out'/>
|
||||
</method>
|
||||
@ -76,36 +72,7 @@ const ConsoleKitSession = Gio.DBusProxy.makeProxyWrapper(ConsoleKitSessionIface)
|
||||
const ConsoleKitManager = Gio.DBusProxy.makeProxyWrapper(ConsoleKitManagerIface);
|
||||
|
||||
function haveSystemd() {
|
||||
return GLib.access("/run/systemd/seats", 0) >= 0;
|
||||
}
|
||||
|
||||
function versionCompare(required, reference) {
|
||||
required = required.split('.');
|
||||
reference = reference.split('.');
|
||||
|
||||
for (let i = 0; i < required.length; i++) {
|
||||
if (required[i] != reference[i])
|
||||
return required[i] < reference[i];
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
function canLock() {
|
||||
try {
|
||||
let params = GLib.Variant.new('(ss)', ['org.gnome.DisplayManager.Manager', 'Version']);
|
||||
let result = Gio.DBus.system.call_sync('org.gnome.DisplayManager',
|
||||
'/org/gnome/DisplayManager/Manager',
|
||||
'org.freedesktop.DBus.Properties',
|
||||
'Get', params, null,
|
||||
Gio.DBusCallFlags.NONE,
|
||||
-1, null);
|
||||
|
||||
let version = result.deep_unpack()[0].deep_unpack();
|
||||
return versionCompare('3.5.91', version);
|
||||
} catch(e) {
|
||||
return false;
|
||||
}
|
||||
return GLib.access("/sys/fs/cgroup/systemd", 0) >= 0;
|
||||
}
|
||||
|
||||
let _loginManager = null;
|
||||
@ -140,23 +107,15 @@ const LoginManagerSystemd = new Lang.Class({
|
||||
// Having this function is a bit of a hack since the Systemd and ConsoleKit
|
||||
// session objects have different interfaces - but in both cases there are
|
||||
// Lock/Unlock signals, and that's all we count upon at the moment.
|
||||
getCurrentSessionProxy: function(callback) {
|
||||
if (this._currentSession) {
|
||||
callback (this._currentSession);
|
||||
return;
|
||||
getCurrentSessionProxy: function() {
|
||||
if (!this._currentSession) {
|
||||
this._currentSession = new SystemdLoginSession(Gio.DBus.system,
|
||||
'org.freedesktop.login1',
|
||||
'/org/freedesktop/login1/session/' +
|
||||
GLib.getenv('XDG_SESSION_ID'));
|
||||
}
|
||||
|
||||
this._proxy.GetSessionRemote(GLib.getenv('XDG_SESSION_ID'), Lang.bind(this,
|
||||
function(result, error) {
|
||||
if (error) {
|
||||
logError(error, 'Could not get a proxy for the current session');
|
||||
} else {
|
||||
this._currentSession = new SystemdLoginSession(Gio.DBus.system,
|
||||
'org.freedesktop.login1',
|
||||
result[0]);
|
||||
callback(this._currentSession);
|
||||
}
|
||||
}));
|
||||
return this._currentSession;
|
||||
},
|
||||
|
||||
canPowerOff: function(asyncCallback) {
|
||||
@ -245,23 +204,15 @@ const LoginManagerConsoleKit = new Lang.Class({
|
||||
// Having this function is a bit of a hack since the Systemd and ConsoleKit
|
||||
// session objects have different interfaces - but in both cases there are
|
||||
// Lock/Unlock signals, and that's all we count upon at the moment.
|
||||
getCurrentSessionProxy: function(callback) {
|
||||
if (this._currentSession) {
|
||||
callback (this._currentSession);
|
||||
return;
|
||||
getCurrentSessionProxy: function() {
|
||||
if (!this._currentSession) {
|
||||
let [currentSessionId] = this._proxy.GetCurrentSessionSync();
|
||||
this._currentSession = new ConsoleKitSession(Gio.DBus.system,
|
||||
'org.freedesktop.ConsoleKit',
|
||||
currentSessionId);
|
||||
}
|
||||
|
||||
this._proxy.GetCurrentSessionRemote(Lang.bind(this,
|
||||
function(result, error) {
|
||||
if (error) {
|
||||
logError(error, 'Could not get a proxy for the current session');
|
||||
} else {
|
||||
this._currentSession = new ConsoleKitSession(Gio.DBus.system,
|
||||
'org.freedesktop.ConsoleKit',
|
||||
result[0]);
|
||||
callback(this._currentSession);
|
||||
}
|
||||
}));
|
||||
return this._currentSession;
|
||||
},
|
||||
|
||||
canPowerOff: function(asyncCallback) {
|
||||
|
@ -5,9 +5,6 @@ const GLib = imports.gi.GLib;
|
||||
const St = imports.gi.St;
|
||||
|
||||
const Main = imports.ui.main;
|
||||
const Tweener = imports.ui.tweener;
|
||||
|
||||
const SCROLL_TIME = 0.1;
|
||||
|
||||
// http://daringfireball.net/2010/07/improved_regex_for_matching_urls
|
||||
const _balancedParens = '\\((?:[^\\s()<>]+|(?:\\(?:[^\\s()<>]+\\)))*\\)';
|
||||
@ -237,39 +234,3 @@ function makeCloseButton() {
|
||||
|
||||
return closeButton;
|
||||
}
|
||||
|
||||
function ensureActorVisibleInScrollView(scrollView, actor) {
|
||||
let adjustment = scrollView.vscroll.adjustment;
|
||||
let [value, lower, upper, stepIncrement, pageIncrement, pageSize] = adjustment.get_values();
|
||||
|
||||
let offset = 0;
|
||||
let vfade = scrollView.get_effect("fade");
|
||||
if (vfade)
|
||||
offset = vfade.vfade_offset;
|
||||
|
||||
let box = actor.get_allocation_box();
|
||||
let y1 = box.y1, y2 = box.y2;
|
||||
|
||||
let parent = actor.get_parent();
|
||||
while (parent != scrollView) {
|
||||
if (!parent)
|
||||
throw new Error("actor not in scroll view");
|
||||
|
||||
let box = parent.get_allocation_box();
|
||||
y1 += box.y1;
|
||||
y2 += box.y1;
|
||||
parent = parent.get_parent();
|
||||
}
|
||||
|
||||
if (y1 < value + offset)
|
||||
value = Math.max(0, y1 - offset);
|
||||
else if (y2 > value + pageSize - offset)
|
||||
value = Math.min(upper, y2 + offset - pageSize);
|
||||
else
|
||||
return;
|
||||
|
||||
Tweener.addTween(adjustment,
|
||||
{ value: value,
|
||||
time: SCROLL_TIME,
|
||||
transition: 'easeOutQuad' });
|
||||
}
|
||||
|
@ -232,11 +232,11 @@ const AppSwitcherPopup = new Lang.Class({
|
||||
},
|
||||
|
||||
_finish : function(timestamp) {
|
||||
this.parent();
|
||||
|
||||
let appIcon = this._items[this._selectedIndex];
|
||||
let window = this._currentWindow > 0 ? this._currentWindow : 0;
|
||||
appIcon.app.activate_window(appIcon.cachedWindows[window], timestamp);
|
||||
|
||||
this.parent();
|
||||
},
|
||||
|
||||
_onDestroy : function() {
|
||||
@ -395,9 +395,9 @@ const WindowSwitcherPopup = new Lang.Class({
|
||||
},
|
||||
|
||||
_finish: function() {
|
||||
Main.activateWindow(this._items[this._selectedIndex].window);
|
||||
|
||||
this.parent();
|
||||
|
||||
Main.activateWindow(this._items[this._selectedIndex].window);
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -29,6 +29,7 @@ const Util = imports.misc.util;
|
||||
|
||||
const MAX_APPLICATION_WORK_MILLIS = 75;
|
||||
const MENU_POPUP_TIMEOUT = 600;
|
||||
const SCROLL_TIME = 0.1;
|
||||
const MAX_COLUMNS = 6;
|
||||
|
||||
const INACTIVE_GRID_OPACITY = 77;
|
||||
@ -156,30 +157,6 @@ const FolderView = new Lang.Class({
|
||||
}
|
||||
});
|
||||
|
||||
const AllViewLayout = new Lang.Class({
|
||||
Name: 'AllViewLayout',
|
||||
Extends: Clutter.BinLayout,
|
||||
|
||||
vfunc_get_preferred_height: function(container, forWidth) {
|
||||
let minBottom = 0;
|
||||
let naturalBottom = 0;
|
||||
|
||||
for (let child = container.get_first_child();
|
||||
child;
|
||||
child = child.get_next_sibling()) {
|
||||
let childY = child.y;
|
||||
let [childMin, childNatural] = child.get_preferred_height(forWidth);
|
||||
|
||||
if (childMin + childY > minBottom)
|
||||
minBottom = childMin + childY;
|
||||
|
||||
if (childNatural + childY > naturalBottom)
|
||||
naturalBottom = childNatural + childY;
|
||||
}
|
||||
return [minBottom, naturalBottom];
|
||||
}
|
||||
});
|
||||
|
||||
const AllView = new Lang.Class({
|
||||
Name: 'AllView',
|
||||
Extends: AlphabeticalView,
|
||||
@ -188,7 +165,7 @@ const AllView = new Lang.Class({
|
||||
this.parent();
|
||||
|
||||
let box = new St.BoxLayout({ vertical: true });
|
||||
this._stack = new St.Widget({ layout_manager: new AllViewLayout() });
|
||||
this._stack = new St.Widget({ layout_manager: new Clutter.BinLayout() });
|
||||
this._stack.add_actor(this._grid.actor);
|
||||
this._eventBlocker = new St.Widget({ x_expand: true, y_expand: true });
|
||||
this._stack.add_actor(this._eventBlocker);
|
||||
@ -282,7 +259,29 @@ const AllView = new Lang.Class({
|
||||
},
|
||||
|
||||
_ensureIconVisible: function(icon) {
|
||||
Util.ensureActorVisibleInScrollView(this.actor, icon);
|
||||
let adjustment = this.actor.vscroll.adjustment;
|
||||
let [value, lower, upper, stepIncrement, pageIncrement, pageSize] = adjustment.get_values();
|
||||
|
||||
let offset = 0;
|
||||
let vfade = this.actor.get_effect("fade");
|
||||
if (vfade)
|
||||
offset = vfade.vfade_offset;
|
||||
|
||||
// If this gets called as part of a right-click, the actor
|
||||
// will be needs_allocation, and so "icon.y" would return 0
|
||||
let box = icon.get_allocation_box();
|
||||
|
||||
if (box.y1 < value + offset)
|
||||
value = Math.max(0, box.y1 - offset);
|
||||
else if (box.y2 > value + pageSize - offset)
|
||||
value = Math.min(upper, box.y2 + offset - pageSize);
|
||||
else
|
||||
return;
|
||||
|
||||
Tweener.addTween(adjustment,
|
||||
{ value: value,
|
||||
time: SCROLL_TIME,
|
||||
transition: 'easeOutQuad' });
|
||||
},
|
||||
|
||||
_updateIconOpacities: function(folderOpen) {
|
||||
|
@ -38,7 +38,6 @@ const BackgroundCache = new Lang.Class({
|
||||
_init: function() {
|
||||
this._patterns = [];
|
||||
this._images = [];
|
||||
this._pendingFileLoads = [];
|
||||
this._fileMonitors = {};
|
||||
},
|
||||
|
||||
@ -85,9 +84,9 @@ const BackgroundCache = new Lang.Class({
|
||||
} else {
|
||||
content.load_gradient(params.shadingType, params.color, params.secondColor);
|
||||
}
|
||||
}
|
||||
|
||||
this._patterns.push(content);
|
||||
this._patterns.push(content);
|
||||
}
|
||||
|
||||
return content;
|
||||
},
|
||||
@ -129,73 +128,6 @@ const BackgroundCache = new Lang.Class({
|
||||
this._removeContent(this._images, content);
|
||||
},
|
||||
|
||||
_loadImageContent: function(params) {
|
||||
params = Params.parse(params, { monitorIndex: 0,
|
||||
style: null,
|
||||
filename: null,
|
||||
effects: Meta.BackgroundEffects.NONE,
|
||||
cancellable: null,
|
||||
onFinished: null });
|
||||
|
||||
for (let i = 0; i < this._pendingFileLoads.length; i++) {
|
||||
if (this._pendingFileLoads[i].filename == params.filename &&
|
||||
this._pendingFileLoads[i].style == params.style) {
|
||||
this._pendingFileLoads[i].callers.push({ shouldCopy: true,
|
||||
monitorIndex: params.monitorIndex,
|
||||
effects: params.effects,
|
||||
onFinished: params.onFinished });
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
this._pendingFileLoads.push({ filename: params.filename,
|
||||
style: params.style,
|
||||
callers: [{ shouldCopy: false,
|
||||
monitorIndex: params.monitorIndex,
|
||||
effects: params.effects,
|
||||
onFinished: params.onFinished }] });
|
||||
|
||||
let content = new Meta.Background({ meta_screen: global.screen,
|
||||
monitor: params.monitorIndex,
|
||||
effects: params.effects });
|
||||
|
||||
content.load_file_async(params.filename,
|
||||
params.style,
|
||||
params.cancellable,
|
||||
Lang.bind(this,
|
||||
function(object, result) {
|
||||
try {
|
||||
content.load_file_finish(result);
|
||||
|
||||
this._monitorFile(params.filename);
|
||||
this._images.push(content);
|
||||
} catch(e) {
|
||||
content = null;
|
||||
}
|
||||
|
||||
for (let i = 0; i < this._pendingFileLoads.length; i++) {
|
||||
let pendingLoad = this._pendingFileLoads[i];
|
||||
if (pendingLoad.filename != params.filename ||
|
||||
pendingLoad.style != params.style)
|
||||
continue;
|
||||
|
||||
for (let j = 0; j < pendingLoad.callers.length; j++) {
|
||||
if (pendingLoad.callers[j].onFinished) {
|
||||
if (content && pendingLoad.callers[j].shouldCopy) {
|
||||
content = object.copy(pendingLoad.callers[j].monitorIndex,
|
||||
pendingLoad.callers[j].effects);
|
||||
|
||||
}
|
||||
|
||||
pendingLoad.callers[j].onFinished(content);
|
||||
}
|
||||
}
|
||||
|
||||
this._pendingFileLoads.splice(i, 1);
|
||||
}
|
||||
}));
|
||||
},
|
||||
|
||||
getImageContent: function(params) {
|
||||
params = Params.parse(params, { monitorIndex: 0,
|
||||
style: null,
|
||||
@ -233,19 +165,31 @@ const BackgroundCache = new Lang.Class({
|
||||
|
||||
if (params.cancellable && params.cancellable.is_cancelled())
|
||||
content = null;
|
||||
else
|
||||
this._images.push(content);
|
||||
|
||||
if (params.onFinished)
|
||||
params.onFinished(content);
|
||||
} else {
|
||||
this._loadImageContent({ filename: params.filename,
|
||||
style: params.style,
|
||||
effects: params.effects,
|
||||
monitorIndex: params.monitorIndex,
|
||||
cancellable: params.cancellable,
|
||||
onFinished: params.onFinished });
|
||||
content = new Meta.Background({ meta_screen: global.screen,
|
||||
monitor: params.monitorIndex,
|
||||
effects: params.effects });
|
||||
|
||||
content.load_file_async(params.filename,
|
||||
params.style,
|
||||
params.cancellable,
|
||||
Lang.bind(this,
|
||||
function(object, result) {
|
||||
try {
|
||||
content.load_file_finish(result);
|
||||
|
||||
this._monitorFile(params.filename);
|
||||
this._images.push(content);
|
||||
} catch(e) {
|
||||
content = null;
|
||||
}
|
||||
|
||||
if (params.onFinished)
|
||||
params.onFinished(content);
|
||||
}));
|
||||
}
|
||||
},
|
||||
|
||||
@ -323,9 +267,9 @@ const Background = new Lang.Class({
|
||||
_destroy: function() {
|
||||
this._cancellable.cancel();
|
||||
|
||||
if (this._updateAnimationTimeoutId) {
|
||||
GLib.source_remove (this._updateAnimationTimeoutId);
|
||||
this._updateAnimationTimeoutId = 0;
|
||||
if (this._animationUpdateTimeoutId) {
|
||||
GLib.source_remove (this._animationUpdateTimeoutId);
|
||||
this._animationUpdateTimeoutId = 0
|
||||
}
|
||||
|
||||
let i;
|
||||
@ -412,10 +356,7 @@ const Background = new Lang.Class({
|
||||
|
||||
let actor = new Meta.BackgroundActor();
|
||||
actor.content = content;
|
||||
|
||||
// The background pattern is the first actor in
|
||||
// the group, and all images should be above that.
|
||||
this.actor.insert_child_at_index(actor, index + 1);
|
||||
this.actor.add_child(actor);
|
||||
|
||||
this._images[index] = actor;
|
||||
this._watchCacheFile(filename);
|
||||
@ -426,27 +367,27 @@ const Background = new Lang.Class({
|
||||
content.brightness = this._brightness;
|
||||
content.vignette_sharpness = this._vignetteSharpness;
|
||||
|
||||
this._cache.removeImageContent(content);
|
||||
this._images[index].content = content;
|
||||
this._watchCacheFile(filename);
|
||||
},
|
||||
|
||||
_updateAnimationProgress: function() {
|
||||
if (this._images[1])
|
||||
if (this._images[1]) {
|
||||
this._images[1].raise_top();
|
||||
this._images[1].opacity = this._animation.transitionProgress * 255;
|
||||
}
|
||||
|
||||
this._queueUpdateAnimation();
|
||||
this._queueAnimationUpdate();
|
||||
},
|
||||
|
||||
_updateAnimation: function() {
|
||||
this._updateAnimationTimeoutId = 0;
|
||||
this._animationUpdateTimeoutId = 0;
|
||||
|
||||
this._animation.update(this._layoutManager.monitors[this._monitorIndex]);
|
||||
let files = this._animation.keyFrameFiles;
|
||||
let files = this._animation.getKeyFrameFiles(this._layoutManager.monitors[this._monitorIndex]);
|
||||
|
||||
if (files.length == 0) {
|
||||
if (!files) {
|
||||
this._setLoaded();
|
||||
this._queueUpdateAnimation();
|
||||
this._queueAnimationUpdate();
|
||||
return;
|
||||
}
|
||||
|
||||
@ -465,7 +406,7 @@ const Background = new Lang.Class({
|
||||
style: this._style,
|
||||
filename: files[i],
|
||||
cancellable: this._cancellable,
|
||||
onFinished: Lang.bind(this, function(content, i) {
|
||||
onFinished: Lang.bind(this, function(content) {
|
||||
numPendingImages--;
|
||||
|
||||
if (!content) {
|
||||
@ -485,34 +426,27 @@ const Background = new Lang.Class({
|
||||
this._setLoaded();
|
||||
this._updateAnimationProgress();
|
||||
}
|
||||
}, i)
|
||||
})
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
_queueUpdateAnimation: function() {
|
||||
if (this._updateAnimationTimeoutId != 0)
|
||||
_queueAnimationUpdate: function() {
|
||||
if (this._animationUpdateTimeoutId != 0)
|
||||
return;
|
||||
|
||||
if (!this._cancellable || this._cancellable.is_cancelled())
|
||||
return;
|
||||
|
||||
if (!this._animation.transitionDuration)
|
||||
if (!this._animation.duration)
|
||||
return;
|
||||
|
||||
let nSteps = 255 / ANIMATION_OPACITY_STEP_INCREMENT;
|
||||
let timePerStep = (this._animation.transitionDuration * 1000) / nSteps;
|
||||
|
||||
let interval = Math.max(ANIMATION_MIN_WAKEUP_INTERVAL * 1000,
|
||||
timePerStep);
|
||||
|
||||
if (interval > GLib.MAXUINT32)
|
||||
return;
|
||||
|
||||
this._updateAnimationTimeoutId = GLib.timeout_add(GLib.PRIORITY_DEFAULT,
|
||||
ANIMATION_OPACITY_STEP_INCREMENT / this._animation.duration);
|
||||
this._animationUpdateTimeoutId = GLib.timeout_add(GLib.PRIORITY_DEFAULT,
|
||||
interval,
|
||||
Lang.bind(this, function() {
|
||||
this._updateAnimationTimeoutId = 0;
|
||||
this._animationUpdateTimeoutId = 0;
|
||||
this._updateAnimation();
|
||||
return false;
|
||||
}));
|
||||
@ -651,9 +585,9 @@ const Animation = new Lang.Class({
|
||||
params = Params.parse(params, { filename: null });
|
||||
|
||||
this.filename = params.filename;
|
||||
this.keyFrameFiles = [];
|
||||
this._keyFrames = [];
|
||||
this.duration = 0.0;
|
||||
this.transitionProgress = 0.0;
|
||||
this.transitionDuration = 0.0;
|
||||
this.loaded = false;
|
||||
},
|
||||
|
||||
@ -665,31 +599,33 @@ const Animation = new Lang.Class({
|
||||
this._show.load_async(null,
|
||||
Lang.bind(this,
|
||||
function(object, result) {
|
||||
this.duration = this._show.get_total_duration();
|
||||
this.loaded = true;
|
||||
if (callback)
|
||||
callback();
|
||||
}));
|
||||
},
|
||||
|
||||
update: function(monitor) {
|
||||
this.keyFrameFiles = [];
|
||||
|
||||
getKeyFrameFiles: function(monitor) {
|
||||
if (!this._show)
|
||||
return;
|
||||
return null;
|
||||
|
||||
if (this._show.get_num_slides() < 1)
|
||||
return;
|
||||
return null;
|
||||
|
||||
let [progress, duration, isFixed, file1, file2] = this._show.get_current_slide(monitor.width, monitor.height);
|
||||
|
||||
this.transitionDuration = duration;
|
||||
this.transitionProgress = progress;
|
||||
|
||||
let files = [];
|
||||
|
||||
if (file1)
|
||||
this.keyFrameFiles.push(file1);
|
||||
files.push(file1);
|
||||
|
||||
if (file2)
|
||||
this.keyFrameFiles.push(file2);
|
||||
files.push(file2);
|
||||
|
||||
return files;
|
||||
},
|
||||
});
|
||||
Signals.addSignalMethods(Animation.prototype);
|
||||
@ -712,9 +648,17 @@ const BackgroundManager = new Lang.Class({
|
||||
|
||||
this.background = this._createBackground();
|
||||
this._newBackground = null;
|
||||
this._loadedSignalId = 0;
|
||||
this._changedSignalId = 0;
|
||||
},
|
||||
|
||||
destroy: function() {
|
||||
if (this._loadedSignalId)
|
||||
this._newBackground.disconnect(this._loadedSignalId);
|
||||
|
||||
if (this._changedSignalId)
|
||||
this.background.disconnect(this._changedSignalId);
|
||||
|
||||
if (this._newBackground) {
|
||||
this._newBackground.actor.destroy();
|
||||
this._newBackground = null;
|
||||
@ -733,24 +677,22 @@ const BackgroundManager = new Lang.Class({
|
||||
newBackground.saturation = background.saturation;
|
||||
newBackground.visible = background.visible;
|
||||
|
||||
newBackground.loadedSignalId = newBackground.connect('loaded',
|
||||
let signalId = newBackground.connect('loaded',
|
||||
Lang.bind(this, function() {
|
||||
newBackground.disconnect(newBackground.loadedSignalId);
|
||||
newBackground.loadedSignalId = 0;
|
||||
newBackground.disconnect(signalId);
|
||||
Tweener.addTween(background.actor,
|
||||
{ opacity: 0,
|
||||
time: FADE_ANIMATION_TIME,
|
||||
transition: 'easeOutQuad',
|
||||
onComplete: Lang.bind(this, function() {
|
||||
if (this.background == background) {
|
||||
this.background = newBackground;
|
||||
this._newBackground = null;
|
||||
background.actor.destroy();
|
||||
}
|
||||
this.background = newBackground;
|
||||
this._newBackground = null;
|
||||
background.actor.destroy();
|
||||
this.emit('changed');
|
||||
})
|
||||
});
|
||||
}));
|
||||
this._loadedSignalId = signalId;
|
||||
|
||||
this._newBackground = newBackground;
|
||||
},
|
||||
@ -769,19 +711,12 @@ const BackgroundManager = new Lang.Class({
|
||||
background.actor.lower_bottom();
|
||||
}
|
||||
|
||||
background.changeSignalId = background.connect('changed', Lang.bind(this, function() {
|
||||
background.disconnect(background.changeSignalId);
|
||||
background.changeSignalId = 0;
|
||||
let signalId = background.connect('changed', Lang.bind(this, function() {
|
||||
background.disconnect(signalId);
|
||||
this._updateBackground(background, this._monitorIndex);
|
||||
}));
|
||||
|
||||
background.actor.connect('destroy', Lang.bind(this, function() {
|
||||
if (background.changeSignalId)
|
||||
background.disconnect(background.changeSignalId);
|
||||
|
||||
if (background.loadedSignalId)
|
||||
background.disconnect(background.loadedSignalId);
|
||||
}));
|
||||
this._changedSignalId = signalId;
|
||||
|
||||
return background;
|
||||
},
|
||||
|
@ -55,10 +55,4 @@ function addBackgroundMenu(actor) {
|
||||
openMenu();
|
||||
});
|
||||
actor.add_action(clickAction);
|
||||
|
||||
actor.connect('destroy', function() {
|
||||
actor._backgroundMenu.destroy();
|
||||
actor._backgroundMenu = null;
|
||||
actor._backgroundManager = null;
|
||||
});
|
||||
}
|
||||
|
@ -71,7 +71,7 @@ function _formatEventTime(event, clockFormat) {
|
||||
default:
|
||||
/* explicit fall-through */
|
||||
case '12h':
|
||||
/* Translators: Shown in calendar event list, if 12h format,
|
||||
/* Transators: Shown in calendar event list, if 12h format,
|
||||
\u2236 is a ratio character, similar to : and \u2009 is
|
||||
a thin space */
|
||||
ret = event.date.toLocaleFormat(C_("event list time", "%l\u2236%M\u2009%p"));
|
||||
@ -168,12 +168,6 @@ const EmptyEventSource = new Lang.Class({
|
||||
Name: 'EmptyEventSource',
|
||||
|
||||
_init: function() {
|
||||
this.isLoading = false;
|
||||
this.isDummy = true;
|
||||
this.hasCalendars = false;
|
||||
},
|
||||
|
||||
destroy: function() {
|
||||
},
|
||||
|
||||
requestRange: function(begin, end) {
|
||||
@ -197,7 +191,6 @@ const CalendarServerIface = <interface name="org.gnome.Shell.CalendarServer">
|
||||
<arg type="b" direction="in" />
|
||||
<arg type="a(sssbxxa{sv})" direction="out" />
|
||||
</method>
|
||||
<property name="HasCalendars" type="b" access="read" />
|
||||
<signal name="Changed" />
|
||||
</interface>;
|
||||
|
||||
@ -208,7 +201,8 @@ function CalendarServer() {
|
||||
g_interface_name: CalendarServerInfo.name,
|
||||
g_interface_info: CalendarServerInfo,
|
||||
g_name: 'org.gnome.Shell.CalendarServer',
|
||||
g_object_path: '/org/gnome/Shell/CalendarServer' });
|
||||
g_object_path: '/org/gnome/Shell/CalendarServer',
|
||||
g_flags: Gio.DBusProxyFlags.DO_NOT_LOAD_PROPERTIES });
|
||||
}
|
||||
|
||||
function _datesEqual(a, b) {
|
||||
@ -235,8 +229,6 @@ const DBusEventSource = new Lang.Class({
|
||||
|
||||
_init: function() {
|
||||
this._resetCache();
|
||||
this.isLoading = false;
|
||||
this.isDummy = false;
|
||||
|
||||
this._initialized = false;
|
||||
this._dbusProxy = new CalendarServer();
|
||||
@ -257,27 +249,11 @@ const DBusEventSource = new Lang.Class({
|
||||
this._onNameVanished();
|
||||
}));
|
||||
|
||||
this._dbusProxy.connect('g-properties-changed', Lang.bind(this, function() {
|
||||
this.emit('notify::has-calendars');
|
||||
}));
|
||||
|
||||
this._initialized = true;
|
||||
this.emit('notify::has-calendars');
|
||||
this._onNameAppeared();
|
||||
}));
|
||||
},
|
||||
|
||||
destroy: function() {
|
||||
this._dbusProxy.run_dispose();
|
||||
},
|
||||
|
||||
get hasCalendars() {
|
||||
if (this._initialized)
|
||||
return this._dbusProxy.HasCalendars;
|
||||
else
|
||||
return false;
|
||||
},
|
||||
|
||||
_resetCache: function() {
|
||||
this._events = [];
|
||||
this._lastRequestBegin = null;
|
||||
@ -317,7 +293,6 @@ const DBusEventSource = new Lang.Class({
|
||||
}
|
||||
|
||||
this._events = newEvents;
|
||||
this.isLoading = false;
|
||||
this.emit('changed');
|
||||
},
|
||||
|
||||
@ -340,7 +315,6 @@ const DBusEventSource = new Lang.Class({
|
||||
|
||||
requestRange: function(begin, end, forceReload) {
|
||||
if (forceReload || !(_datesEqual(begin, this._lastRequestBegin) && _datesEqual(end, this._lastRequestEnd))) {
|
||||
this.isLoading = true;
|
||||
this._lastRequestBegin = begin;
|
||||
this._lastRequestEnd = end;
|
||||
this._curRequestBegin = begin;
|
||||
@ -415,11 +389,19 @@ const Calendar = new Lang.Class({
|
||||
// @eventSource: is an object implementing the EventSource API, e.g. the
|
||||
// requestRange(), getEvents(), hasEvents() methods and the ::changed signal.
|
||||
setEventSource: function(eventSource) {
|
||||
if (this._eventSource) {
|
||||
this._eventSource.disconnect(this._eventSourceChangedId);
|
||||
this._eventSource = null;
|
||||
}
|
||||
|
||||
this._eventSource = eventSource;
|
||||
this._eventSource.connect('changed', Lang.bind(this, function() {
|
||||
this._update(false);
|
||||
}));
|
||||
this._update(true);
|
||||
|
||||
if (this._eventSource) {
|
||||
this._eventSourceChangedId = this._eventSource.connect('changed', Lang.bind(this, function() {
|
||||
this._update(false);
|
||||
}));
|
||||
this._update(true);
|
||||
}
|
||||
},
|
||||
|
||||
// Sets the calendar to show a specific date
|
||||
@ -556,44 +538,20 @@ const Calendar = new Lang.Class({
|
||||
children[i].destroy();
|
||||
|
||||
// Start at the beginning of the week before the start of the month
|
||||
//
|
||||
// We want to show always 6 weeks (to keep the calendar menu at the same
|
||||
// height if there are no events), so we pad it according to the following
|
||||
// policy:
|
||||
//
|
||||
// 1 - If a month has 6 weeks, we place no padding (example: Dec 2012)
|
||||
// 2 - If a month has 5 weeks and it starts on week start, we pad one week
|
||||
// before it (example: Apr 2012)
|
||||
// 3 - If a month has 5 weeks and it starts on any other day, we pad one week
|
||||
// after it (example: Nov 2012)
|
||||
// 4 - If a month has 4 weeks, we pad one week before and one after it
|
||||
// (example: Feb 2010)
|
||||
//
|
||||
// Actually computing the number of weeks is complex, but we know that the
|
||||
// problematic categories (2 and 4) always start on week start, and that
|
||||
// all months at the end have 6 weeks.
|
||||
|
||||
let beginDate = new Date(this._selectedDate);
|
||||
beginDate.setDate(1);
|
||||
beginDate.setSeconds(0);
|
||||
beginDate.setHours(12);
|
||||
let year = beginDate.getYear();
|
||||
|
||||
let daysToWeekStart = (7 + beginDate.getDay() - this._weekStart) % 7;
|
||||
let startsOnWeekStart = daysToWeekStart == 0;
|
||||
let weekPadding = startsOnWeekStart ? 7 : 0;
|
||||
|
||||
beginDate.setTime(beginDate.getTime() - (weekPadding + daysToWeekStart) * MSECS_IN_DAY);
|
||||
beginDate.setTime(beginDate.getTime() - daysToWeekStart * MSECS_IN_DAY);
|
||||
|
||||
let iter = new Date(beginDate);
|
||||
let row = 2;
|
||||
// nRows here means 6 weeks + one header + one navbar
|
||||
let nRows = 8;
|
||||
while (row < 8) {
|
||||
while (true) {
|
||||
let button = new St.Button({ label: iter.getDate().toString() });
|
||||
let rtl = button.get_text_direction() == Clutter.TextDirection.RTL;
|
||||
|
||||
if (this._eventSource.isDummy)
|
||||
if (!this._eventSource)
|
||||
button.reactive = false;
|
||||
|
||||
let iterStr = iter.toUTCString();
|
||||
@ -602,9 +560,8 @@ const Calendar = new Lang.Class({
|
||||
this.setDate(newlySelectedDate, false);
|
||||
}));
|
||||
|
||||
let hasEvents = this._eventSource.hasEvents(iter);
|
||||
let hasEvents = this._eventSource && this._eventSource.hasEvents(iter);
|
||||
let styleClass = 'calendar-day-base calendar-day';
|
||||
|
||||
if (_isWorkDay(iter))
|
||||
styleClass += ' calendar-work-day'
|
||||
else
|
||||
@ -644,13 +601,17 @@ const Calendar = new Lang.Class({
|
||||
}
|
||||
|
||||
iter.setTime(iter.getTime() + MSECS_IN_DAY);
|
||||
|
||||
if (iter.getDay() == this._weekStart)
|
||||
if (iter.getDay() == this._weekStart) {
|
||||
// We stop on the first "first day of the week" after the month we are displaying
|
||||
if (iter.getMonth() > this._selectedDate.getMonth() || iter.getYear() > this._selectedDate.getYear())
|
||||
break;
|
||||
row++;
|
||||
}
|
||||
}
|
||||
// Signal to the event source that we are interested in events
|
||||
// only from this date range
|
||||
this._eventSource.requestRange(beginDate, iter, forceReload);
|
||||
if (this._eventSource)
|
||||
this._eventSource.requestRange(beginDate, iter, forceReload);
|
||||
}
|
||||
});
|
||||
|
||||
@ -668,8 +629,16 @@ const EventsList = new Lang.Class({
|
||||
},
|
||||
|
||||
setEventSource: function(eventSource) {
|
||||
if (this._eventSource) {
|
||||
this._eventSource.disconnect(this._eventSourceChangedId);
|
||||
this._eventSource = null;
|
||||
}
|
||||
|
||||
this._eventSource = eventSource;
|
||||
this._eventSource.connect('changed', Lang.bind(this, this._update));
|
||||
|
||||
if (this._eventSource) {
|
||||
this._eventSourceChangedId = this._eventSource.connect('changed', Lang.bind(this, this._update));
|
||||
}
|
||||
},
|
||||
|
||||
_addEvent: function(dayNameBox, timeBox, eventTitleBox, includeDayName, day, time, desc) {
|
||||
@ -686,6 +655,9 @@ const EventsList = new Lang.Class({
|
||||
},
|
||||
|
||||
_addPeriod: function(header, begin, end, includeDayName, showNothingScheduled) {
|
||||
if (!this._eventSource)
|
||||
return;
|
||||
|
||||
let events = this._eventSource.getEvents(begin, end);
|
||||
|
||||
let clockFormat = this._desktopSettings.get_string(CLOCK_FORMAT_KEY);;
|
||||
@ -782,9 +754,6 @@ const EventsList = new Lang.Class({
|
||||
},
|
||||
|
||||
_update: function() {
|
||||
if (this._eventSource.isLoading)
|
||||
return;
|
||||
|
||||
let today = new Date();
|
||||
if (_sameDay (this._date, today)) {
|
||||
this._showToday();
|
||||
|
@ -292,7 +292,6 @@ const AutorunResidentSource = new Lang.Class({
|
||||
|
||||
_init: function(manager) {
|
||||
this.parent(_("Removable Devices"), 'media-removable');
|
||||
this.resident = true;
|
||||
|
||||
this._mounts = [];
|
||||
|
||||
|
@ -222,7 +222,7 @@ const KeyringPrompter = new Lang.Class({
|
||||
enable: function() {
|
||||
this._prompter.register(Gio.DBus.session);
|
||||
this._dbusId = Gio.DBus.session.own_name('org.gnome.keyring.SystemPrompter',
|
||||
Gio.BusNameOwnerFlags.ALLOW_REPLACEMENT, null, null);
|
||||
Gio.BusNameOwnerFlags.REPLACE, null, null);
|
||||
},
|
||||
|
||||
disable: function() {
|
||||
|
@ -103,11 +103,6 @@ const CtrlAltTabManager = new Lang.Class({
|
||||
else
|
||||
icon = textureCache.bind_pixbuf_property(windows[i], 'icon');
|
||||
items.push({ name: windows[i].title,
|
||||
proxy: windows[i].get_compositor_private(),
|
||||
focusCallback: Lang.bind(windows[i],
|
||||
function(timestamp) {
|
||||
Main.activateWindow(this, timestamp);
|
||||
}),
|
||||
iconActor: icon,
|
||||
sortGroup: SortGroup.MIDDLE });
|
||||
}
|
||||
|
@ -161,10 +161,8 @@ const DateMenuButton = new Lang.Class({
|
||||
this._openClocksItem.actor.visible = app !== null;
|
||||
},
|
||||
|
||||
_updateEventsVisibility: function() {
|
||||
let visible = this._eventSource.hasCalendars;
|
||||
_setEventsVisibility: function(visible) {
|
||||
this._openCalendarItem.actor.visible = visible;
|
||||
this._openClocksItem.actor.visible = visible;
|
||||
this._separator.visible = visible;
|
||||
if (visible) {
|
||||
let alignment = 0.25;
|
||||
@ -179,16 +177,8 @@ const DateMenuButton = new Lang.Class({
|
||||
},
|
||||
|
||||
_setEventSource: function(eventSource) {
|
||||
if (this._eventSource)
|
||||
this._eventSource.destroy();
|
||||
|
||||
this._calendar.setEventSource(eventSource);
|
||||
this._eventList.setEventSource(eventSource);
|
||||
|
||||
this._eventSource = eventSource;
|
||||
this._eventSource.connect('notify::has-calendars', Lang.bind(this, function() {
|
||||
this._updateEventsVisibility();
|
||||
}));
|
||||
},
|
||||
|
||||
_sessionUpdated: function() {
|
||||
@ -197,10 +187,10 @@ const DateMenuButton = new Lang.Class({
|
||||
if (showEvents) {
|
||||
eventSource = new Calendar.DBusEventSource();
|
||||
} else {
|
||||
eventSource = new Calendar.EmptyEventSource();
|
||||
eventSource = null;
|
||||
}
|
||||
this._setEventSource(eventSource);
|
||||
this._updateEventsVisibility();
|
||||
this._setEventsVisibility(showEvents);
|
||||
|
||||
// This needs to be handled manually, as the code to
|
||||
// autohide separators doesn't work across the vbox
|
||||
@ -221,8 +211,6 @@ const DateMenuButton = new Lang.Class({
|
||||
this.menu.close();
|
||||
|
||||
let app = Gio.AppInfo.get_default_for_type('text/calendar', false);
|
||||
if (app.get_id() == 'evolution')
|
||||
app = Gio.DesktopAppInfo.new('evolution-calendar');
|
||||
app.launch([], global.create_app_launch_context());
|
||||
},
|
||||
|
||||
|
12
js/ui/dnd.js
12
js/ui/dnd.js
@ -85,13 +85,11 @@ const _Draggable = new Lang.Class({
|
||||
|
||||
this.actor.connect('destroy', Lang.bind(this, function() {
|
||||
this._actorDestroyed = true;
|
||||
|
||||
// If the drag actor is destroyed and we were going to fix
|
||||
// up its hover state, fix up the parent hover state instead
|
||||
if (this.actor == this._firstLeaveActor)
|
||||
this._firstLeaveActor = this._dragOrigParent;
|
||||
|
||||
if (this._dragInProgress && this._dragCancellable)
|
||||
if (this._dragInProgress)
|
||||
this._cancelDrag(global.get_current_time());
|
||||
this.disconnectAll();
|
||||
}));
|
||||
@ -104,7 +102,6 @@ const _Draggable = new Lang.Class({
|
||||
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._dragCancellable = true;
|
||||
|
||||
// During the drag, we eat enter/leave events so that actors don't prelight.
|
||||
// But we remember the actors that we first left/last entered so we can
|
||||
@ -442,11 +439,6 @@ const _Draggable = new Lang.Class({
|
||||
}
|
||||
}
|
||||
|
||||
// At this point it is too late to cancel a drag by destroying
|
||||
// the actor, the fate of which is decided by acceptDrop and its
|
||||
// side-effects
|
||||
this._dragCancellable = false;
|
||||
|
||||
while (target) {
|
||||
if (target._delegate && target._delegate.acceptDrop) {
|
||||
let [r, targX, targY] = target.transform_stage_point(dropX, dropY);
|
||||
@ -455,6 +447,8 @@ const _Draggable = new Lang.Class({
|
||||
targX,
|
||||
targY,
|
||||
event.get_time())) {
|
||||
if (this._actorDestroyed)
|
||||
return true;
|
||||
// If it accepted the drop without taking the actor,
|
||||
// handle it ourselves.
|
||||
if (this._dragActor.get_parent() == Main.uiGroup) {
|
||||
|
@ -225,8 +225,7 @@ const EndSessionDialog = new Lang.Class({
|
||||
Extends: ModalDialog.ModalDialog,
|
||||
|
||||
_init: function() {
|
||||
this.parent({ styleClass: 'end-session-dialog',
|
||||
destroyOnClose: false });
|
||||
this.parent({ styleClass: 'end-session-dialog' });
|
||||
|
||||
this._user = AccountsService.UserManager.get_default().get_user(GLib.get_user_name());
|
||||
|
||||
|
@ -248,7 +248,7 @@ const GrabHelper = new Lang.Class({
|
||||
global.set_stage_input_mode(Shell.StageInputMode.FOCUSED);
|
||||
}
|
||||
|
||||
global.screen.focus_default_window(global.display.get_current_time_roundtrip());
|
||||
global.screen.focus_default_window(global.get_current_time());
|
||||
},
|
||||
|
||||
// ignoreRelease:
|
||||
@ -308,8 +308,6 @@ const GrabHelper = new Lang.Class({
|
||||
if (!this.grabbed && this._capturedEventId > 0) {
|
||||
global.stage.disconnect(this._capturedEventId);
|
||||
this._capturedEventId = 0;
|
||||
|
||||
this._ignoreRelease = false;
|
||||
}
|
||||
|
||||
if (hadFocus) {
|
||||
@ -355,7 +353,6 @@ const GrabHelper = new Lang.Class({
|
||||
this._ignoreRelease = true;
|
||||
let i = this._actorInGrabStack(event.get_source()) + 1;
|
||||
this.ungrab({ actor: this._grabStack[i].actor, isUser: true });
|
||||
return true;
|
||||
}
|
||||
|
||||
return this._modalCount > 0;
|
||||
|
521
js/ui/layout.js
521
js/ui/layout.js
@ -18,6 +18,7 @@ const Main = imports.ui.main;
|
||||
const Params = imports.misc.params;
|
||||
const Tweener = imports.ui.tweener;
|
||||
|
||||
const HOT_CORNER_ACTIVATION_TIMEOUT = 0.5;
|
||||
const STARTUP_ANIMATION_TIME = 0.5;
|
||||
const KEYBOARD_ANIMATION_TIME = 0.15;
|
||||
const BACKGROUND_FADE_ANIMATION_TIME = 1.0;
|
||||
@ -28,9 +29,6 @@ const DEFAULT_BACKGROUND_COLOR = Clutter.Color.from_pixel(0x2e3436ff);
|
||||
const MESSAGE_TRAY_PRESSURE_THRESHOLD = 250; // pixels
|
||||
const MESSAGE_TRAY_PRESSURE_TIMEOUT = 1000; // ms
|
||||
|
||||
const HOT_CORNER_PRESSURE_THRESHOLD = 100; // pixels
|
||||
const HOT_CORNER_PRESSURE_TIMEOUT = 1000; // ms
|
||||
|
||||
function isPopupMetaWindow(actor) {
|
||||
switch(actor.meta_window.get_window_type()) {
|
||||
case Meta.WindowType.DROPDOWN_MENU:
|
||||
@ -132,9 +130,9 @@ const LayoutManager = new Lang.Class({
|
||||
this.monitors = [];
|
||||
this.primaryMonitor = null;
|
||||
this.primaryIndex = -1;
|
||||
this.hotCorners = [];
|
||||
|
||||
this._keyboardIndex = -1;
|
||||
this._hotCorners = [];
|
||||
this._leftPanelBarrier = null;
|
||||
this._rightPanelBarrier = null;
|
||||
this._trayBarrier = null;
|
||||
|
||||
@ -142,7 +140,6 @@ const LayoutManager = new Lang.Class({
|
||||
this._updateRegionIdle = 0;
|
||||
|
||||
this._trackedActors = [];
|
||||
this._topActors = [];
|
||||
this._isPopupWindowVisible = false;
|
||||
this._startingUp = true;
|
||||
|
||||
@ -194,7 +191,6 @@ const LayoutManager = new Lang.Class({
|
||||
this.trayBox = new St.Widget({ name: 'trayBox',
|
||||
layout_manager: new Clutter.BinLayout() });
|
||||
this.addChrome(this.trayBox);
|
||||
this._setupTrayPressure();
|
||||
|
||||
this.keyboardBox = new St.BoxLayout({ name: 'keyboardBox',
|
||||
reactive: true,
|
||||
@ -222,8 +218,6 @@ const LayoutManager = new Lang.Class({
|
||||
Lang.bind(this, this._windowsRestacked));
|
||||
global.screen.connect('monitors-changed',
|
||||
Lang.bind(this, this._monitorsChanged));
|
||||
global.screen.connect('in-fullscreen-changed',
|
||||
Lang.bind(this, this._updateFullscreen));
|
||||
this._monitorsChanged();
|
||||
},
|
||||
|
||||
@ -234,8 +228,6 @@ const LayoutManager = new Lang.Class({
|
||||
Main.overview.connect('showing', Lang.bind(this, this._overviewShowing));
|
||||
Main.overview.connect('hidden', Lang.bind(this, this._overviewHidden));
|
||||
Main.sessionMode.connect('updated', Lang.bind(this, this._sessionUpdated));
|
||||
|
||||
this._prepareStartupAnimation();
|
||||
},
|
||||
|
||||
_overviewShowing: function() {
|
||||
@ -283,58 +275,56 @@ const LayoutManager = new Lang.Class({
|
||||
|
||||
_updateHotCorners: function() {
|
||||
// destroy old hot corners
|
||||
for (let i = 0; i < this.hotCorners.length; i++)
|
||||
this.hotCorners[i].destroy();
|
||||
this.hotCorners = [];
|
||||
|
||||
let size = this.panelBox.height;
|
||||
for (let i = 0; i < this._hotCorners.length; i++)
|
||||
this._hotCorners[i].destroy();
|
||||
this._hotCorners = [];
|
||||
|
||||
// build new hot corners
|
||||
for (let i = 0; i < this.monitors.length; i++) {
|
||||
if (i == this.primaryIndex)
|
||||
continue;
|
||||
|
||||
let monitor = this.monitors[i];
|
||||
let cornerX = this._rtl ? monitor.x + monitor.width : monitor.x;
|
||||
let cornerY = monitor.y;
|
||||
|
||||
if (i != this.primaryIndex) {
|
||||
let haveTopLeftCorner = true;
|
||||
let haveTopLeftCorner = true;
|
||||
|
||||
// Check if we have a top left (right for RTL) corner.
|
||||
// I.e. if there is no monitor directly above or to the left(right)
|
||||
let besideX = this._rtl ? monitor.x + 1 : cornerX - 1;
|
||||
let besideY = cornerY;
|
||||
let aboveX = cornerX;
|
||||
let aboveY = cornerY - 1;
|
||||
// Check if we have a top left (right for RTL) corner.
|
||||
// I.e. if there is no monitor directly above or to the left(right)
|
||||
let besideX = this._rtl ? monitor.x + 1 : cornerX - 1;
|
||||
let besideY = cornerY;
|
||||
let aboveX = cornerX;
|
||||
let aboveY = cornerY - 1;
|
||||
|
||||
for (let j = 0; j < this.monitors.length; j++) {
|
||||
if (i == j)
|
||||
continue;
|
||||
let otherMonitor = this.monitors[j];
|
||||
if (besideX >= otherMonitor.x &&
|
||||
besideX < otherMonitor.x + otherMonitor.width &&
|
||||
besideY >= otherMonitor.y &&
|
||||
besideY < otherMonitor.y + otherMonitor.height) {
|
||||
haveTopLeftCorner = false;
|
||||
break;
|
||||
}
|
||||
if (aboveX >= otherMonitor.x &&
|
||||
aboveX < otherMonitor.x + otherMonitor.width &&
|
||||
aboveY >= otherMonitor.y &&
|
||||
aboveY < otherMonitor.y + otherMonitor.height) {
|
||||
haveTopLeftCorner = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!haveTopLeftCorner)
|
||||
for (let j = 0; j < this.monitors.length; j++) {
|
||||
if (i == j)
|
||||
continue;
|
||||
let otherMonitor = this.monitors[j];
|
||||
if (besideX >= otherMonitor.x &&
|
||||
besideX < otherMonitor.x + otherMonitor.width &&
|
||||
besideY >= otherMonitor.y &&
|
||||
besideY < otherMonitor.y + otherMonitor.height) {
|
||||
haveTopLeftCorner = false;
|
||||
break;
|
||||
}
|
||||
if (aboveX >= otherMonitor.x &&
|
||||
aboveX < otherMonitor.x + otherMonitor.width &&
|
||||
aboveY >= otherMonitor.y &&
|
||||
aboveY < otherMonitor.y + otherMonitor.height) {
|
||||
haveTopLeftCorner = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
let corner = new HotCorner(this, monitor, cornerX, cornerY);
|
||||
corner.setBarrierSize(size);
|
||||
this.hotCorners.push(corner);
|
||||
}
|
||||
if (!haveTopLeftCorner)
|
||||
continue;
|
||||
|
||||
this.emit('hot-corners-changed');
|
||||
let corner = new HotCorner(this);
|
||||
this._hotCorners.push(corner);
|
||||
corner.actor.set_position(cornerX, cornerY);
|
||||
this.addChrome(corner.actor);
|
||||
}
|
||||
},
|
||||
|
||||
_createBackground: function(monitorIndex) {
|
||||
@ -404,15 +394,16 @@ const LayoutManager = new Lang.Class({
|
||||
},
|
||||
|
||||
_panelBoxChanged: function() {
|
||||
this._updatePanelBarrier();
|
||||
|
||||
let size = this.panelBox.height;
|
||||
this.hotCorners.forEach(function(corner) {
|
||||
corner.setBarrierSize(size);
|
||||
});
|
||||
this.emit('panel-box-changed');
|
||||
this._updatePanelBarriers();
|
||||
},
|
||||
|
||||
_updatePanelBarrier: function() {
|
||||
_updatePanelBarriers: function() {
|
||||
if (this._leftPanelBarrier) {
|
||||
this._leftPanelBarrier.destroy();
|
||||
this._leftPanelBarrier = null;
|
||||
}
|
||||
|
||||
if (this._rightPanelBarrier) {
|
||||
this._rightPanelBarrier.destroy();
|
||||
this._rightPanelBarrier = null;
|
||||
@ -421,6 +412,10 @@ const LayoutManager = new Lang.Class({
|
||||
if (this.panelBox.height) {
|
||||
let primary = this.primaryMonitor;
|
||||
|
||||
this._leftPanelBarrier = new Meta.Barrier({ display: global.display,
|
||||
x1: primary.x, y1: primary.y,
|
||||
x2: primary.x, y2: primary.y + this.panelBox.height,
|
||||
directions: Meta.BarrierDirection.POSITIVE_X });
|
||||
this._rightPanelBarrier = new Meta.Barrier({ display: global.display,
|
||||
x1: primary.x + primary.width, y1: primary.y,
|
||||
x2: primary.x + primary.width, y2: primary.y + this.panelBox.height,
|
||||
@ -428,44 +423,28 @@ const LayoutManager = new Lang.Class({
|
||||
}
|
||||
},
|
||||
|
||||
_setupTrayPressure: function() {
|
||||
this._trayPressure = new PressureBarrier(MESSAGE_TRAY_PRESSURE_THRESHOLD,
|
||||
MESSAGE_TRAY_PRESSURE_TIMEOUT,
|
||||
Shell.KeyBindingMode.NORMAL |
|
||||
Shell.KeyBindingMode.OVERVIEW);
|
||||
this._trayPressure.setEventFilter(this._trayBarrierEventFilter);
|
||||
this._trayPressure.connect('trigger', function(barrier) {
|
||||
if (Main.layoutManager.bottomMonitor.inFullscreen)
|
||||
return;
|
||||
|
||||
Main.messageTray.openTray();
|
||||
});
|
||||
},
|
||||
|
||||
_updateTrayBarrier: function() {
|
||||
let monitor = this.bottomMonitor;
|
||||
|
||||
if (this._trayBarrier) {
|
||||
this._trayPressure.removeBarrier(this._trayBarrier);
|
||||
this._trayBarrier.destroy();
|
||||
this._trayBarrier = null;
|
||||
}
|
||||
|
||||
if (this._trayPressure) {
|
||||
this._trayPressure.destroy();
|
||||
this._trayPressure = null;
|
||||
}
|
||||
|
||||
this._trayBarrier = new Meta.Barrier({ display: global.display,
|
||||
x1: monitor.x, x2: monitor.x + monitor.width,
|
||||
y1: monitor.y + monitor.height, y2: monitor.y + monitor.height,
|
||||
directions: Meta.BarrierDirection.NEGATIVE_Y });
|
||||
this._trayPressure.addBarrier(this._trayBarrier);
|
||||
},
|
||||
|
||||
_trayBarrierEventFilter: function(event) {
|
||||
// Throw out all events where the pointer was grabbed by another
|
||||
// client, as the client that grabbed the pointer expects to have
|
||||
// complete control over it
|
||||
if (event.grabbed && Main.modalCount == 0)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
this._trayPressure = new PressureBarrier(this._trayBarrier, MESSAGE_TRAY_PRESSURE_THRESHOLD, MESSAGE_TRAY_PRESSURE_TIMEOUT);
|
||||
this._trayPressure.connect('trigger', function(barrier) {
|
||||
Main.messageTray.openTray();
|
||||
});
|
||||
},
|
||||
|
||||
_monitorsChanged: function() {
|
||||
@ -555,7 +534,7 @@ const LayoutManager = new Lang.Class({
|
||||
// MetaBackgroundActor inside global.window_group covers the entirety of the
|
||||
// screen. So, we set no_clear_hint at the end of the animation.
|
||||
|
||||
_prepareStartupAnimation: function() {
|
||||
prepareStartupAnimation: function() {
|
||||
// Set ourselves to FULLSCREEN input mode while the animation is running
|
||||
// so events don't get delivered to X11 windows (which are distorted by the animation)
|
||||
global.stage_input_mode = Shell.StageInputMode.FULLSCREEN;
|
||||
@ -578,7 +557,6 @@ const LayoutManager = new Lang.Class({
|
||||
y / global.screen_height);
|
||||
this.uiGroup.scale_x = this.uiGroup.scale_y = 0.5;
|
||||
this.uiGroup.opacity = 0;
|
||||
global.window_group.set_clip(monitor.x, monitor.y, monitor.width, monitor.height);
|
||||
}
|
||||
|
||||
this._systemBackground = new Background.SystemBackground();
|
||||
@ -594,25 +572,25 @@ const LayoutManager = new Lang.Class({
|
||||
Lang.bind(this, function() {
|
||||
this._systemBackground.disconnect(signalId);
|
||||
this._systemBackground.actor.show();
|
||||
global.stage.show();
|
||||
|
||||
this.emit('startup-prepared');
|
||||
|
||||
// We're mostly prepared for the startup animation
|
||||
// now, but since a lot is going on asynchronously
|
||||
// during startup, let's defer the startup animation
|
||||
// until the event loop is uncontended and idle.
|
||||
// This helps to prevent us from running the animation
|
||||
// when the system is bogged down
|
||||
// during startup, let's defer emission of the
|
||||
// startup-prepared signal until the event loop is
|
||||
// uncontended and idle. This helps to prevent us
|
||||
// from running the animation when the system is
|
||||
// bogged down
|
||||
GLib.idle_add(GLib.PRIORITY_LOW,
|
||||
Lang.bind(this, function() {
|
||||
this._startupAnimation();
|
||||
return false;
|
||||
}));
|
||||
this.emit('startup-prepared');
|
||||
return false;
|
||||
}));
|
||||
|
||||
}));
|
||||
},
|
||||
|
||||
_startupAnimation: function() {
|
||||
startupAnimation: function() {
|
||||
global.stage.show();
|
||||
if (Main.sessionMode.isGreeter)
|
||||
this._startupAnimationGreeter();
|
||||
else
|
||||
@ -655,14 +633,12 @@ const LayoutManager = new Lang.Class({
|
||||
this.trayBox.show();
|
||||
this.keyboardBox.show();
|
||||
|
||||
if (!Main.sessionMode.isGreeter) {
|
||||
if (!Main.sessionMode.isGreeter)
|
||||
this._createSecondaryBackgrounds();
|
||||
global.window_group.remove_clip();
|
||||
}
|
||||
|
||||
this.emit('panel-box-changed');
|
||||
|
||||
this._queueUpdateRegions();
|
||||
|
||||
this.emit('startup-complete');
|
||||
},
|
||||
|
||||
showKeyboard: function () {
|
||||
@ -838,11 +814,6 @@ const LayoutManager = new Lang.Class({
|
||||
},
|
||||
|
||||
_updateVisibility: function() {
|
||||
let windowsVisible = Main.sessionMode.hasWindows && !this._inOverview;
|
||||
|
||||
global.window_group.visible = windowsVisible;
|
||||
global.top_window_group.visible = windowsVisible;
|
||||
|
||||
for (let i = 0; i < this._trackedActors.length; i++) {
|
||||
let actorData = this._trackedActors[i], visible;
|
||||
if (!actorData.trackFullscreen)
|
||||
@ -850,7 +821,7 @@ const LayoutManager = new Lang.Class({
|
||||
if (!actorData.isToplevel)
|
||||
continue;
|
||||
|
||||
if (!windowsVisible)
|
||||
if (this._inOverview || !Main.sessionMode.hasWindows)
|
||||
visible = true;
|
||||
else if (this.findMonitorForActor(actorData.actor).inFullscreen)
|
||||
visible = false;
|
||||
@ -900,25 +871,95 @@ const LayoutManager = new Lang.Class({
|
||||
},
|
||||
|
||||
_updateFullscreen: function() {
|
||||
let windows = this._getWindowActorsForWorkspace(global.screen.get_active_workspace());
|
||||
|
||||
// Reset all monitors to not fullscreen
|
||||
for (let i = 0; i < this.monitors.length; i++)
|
||||
this.monitors[i].inFullscreen = global.screen.get_monitor_in_fullscreen (i);
|
||||
this.monitors[i].inFullscreen = false;
|
||||
|
||||
this._updateVisibility();
|
||||
this._queueUpdateRegions();
|
||||
// Ordinary chrome should be visible unless there is a window
|
||||
// with layer FULLSCREEN, or a window with layer
|
||||
// OVERRIDE_REDIRECT that covers the whole screen.
|
||||
// ('override_redirect' is not actually a layer above all
|
||||
// other windows, but this seems to be how mutter treats it
|
||||
// currently...) If we wanted to be extra clever, we could
|
||||
// figure out when an OVERRIDE_REDIRECT window was trying to
|
||||
// partially overlap us, and then adjust the input region and
|
||||
// our clip region accordingly...
|
||||
|
||||
this.emit('fullscreen-changed');
|
||||
// @windows is sorted bottom to top.
|
||||
|
||||
for (let i = windows.length - 1; i > -1; i--) {
|
||||
let window = windows[i];
|
||||
let metaWindow = window.meta_window;
|
||||
let layer = metaWindow.get_layer();
|
||||
|
||||
// Skip minimized windows
|
||||
if (!metaWindow.showing_on_its_workspace())
|
||||
continue;
|
||||
|
||||
if (layer == Meta.StackLayer.FULLSCREEN ||
|
||||
(layer == Meta.StackLayer.OVERRIDE_REDIRECT && metaWindow.is_monitor_sized())) {
|
||||
if (metaWindow.is_screen_sized()) {
|
||||
for (let i = 0; i < this.monitors.length; i++)
|
||||
this.monitors[i].inFullscreen = true;
|
||||
} else {
|
||||
let monitors = metaWindow.get_all_monitors();
|
||||
for (let i = 0; i < monitors.length; i++) {
|
||||
let index = monitors[i];
|
||||
this.monitors[index].inFullscreen = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
_windowsRestacked: function() {
|
||||
let changed = false;
|
||||
let wasInFullscreen = [];
|
||||
for (let i = 0; i < this.monitors.length; i++)
|
||||
wasInFullscreen[i] = this.monitors[i].inFullscreen;
|
||||
|
||||
if (this._isPopupWindowVisible != global.top_window_group.get_children().some(isPopupMetaWindow))
|
||||
let primaryWasInFullscreen = this.primaryMonitor.inFullscreen;
|
||||
|
||||
this._updateFullscreen();
|
||||
|
||||
let changed = false;
|
||||
for (let i = 0; i < wasInFullscreen.length; i++) {
|
||||
if (wasInFullscreen[i] != this.monitors[i].inFullscreen) {
|
||||
changed = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!changed && (this._isPopupWindowVisible != global.top_window_group.get_children().some(isPopupMetaWindow)))
|
||||
changed = true;
|
||||
|
||||
if (changed) {
|
||||
this._updateVisibility();
|
||||
this._queueUpdateRegions();
|
||||
}
|
||||
|
||||
if (primaryWasInFullscreen != this.primaryMonitor.inFullscreen) {
|
||||
let windows = this._getWindowActorsForWorkspace(global.screen.get_active_workspace());
|
||||
for (let i = 0; i < windows.length; i++) {
|
||||
let window = windows[i];
|
||||
let metaWindow = window.meta_window;
|
||||
|
||||
// Skip minimized windows
|
||||
if (!metaWindow.showing_on_its_workspace())
|
||||
continue;
|
||||
|
||||
// Skip windows that aren't on the primary monitor
|
||||
if (!metaWindow.is_on_primary_monitor())
|
||||
continue;
|
||||
|
||||
// Minimize monitor sized windows that are not focused
|
||||
if (metaWindow.is_monitor_sized() &&
|
||||
!metaWindow.appears_focused)
|
||||
metaWindow.minimize();
|
||||
}
|
||||
this.emit('primary-fullscreen-changed', this.primaryMonitor.inFullscreen);
|
||||
}
|
||||
},
|
||||
|
||||
_updateRegions: function() {
|
||||
@ -1048,25 +1089,54 @@ Signals.addSignalMethods(LayoutManager.prototype);
|
||||
const HotCorner = new Lang.Class({
|
||||
Name: 'HotCorner',
|
||||
|
||||
_init : function(layoutManager, monitor, x, y) {
|
||||
_init : function(layoutManager) {
|
||||
// We use this flag to mark the case where the user has entered the
|
||||
// hot corner and has not left both the hot corner and a surrounding
|
||||
// guard area (the "environs"). This avoids triggering the hot corner
|
||||
// multiple times due to an accidental jitter.
|
||||
this._entered = false;
|
||||
|
||||
this._monitor = monitor;
|
||||
this.actor = new Clutter.Actor({ name: 'hot-corner-environs',
|
||||
width: 3,
|
||||
height: 3,
|
||||
reactive: true });
|
||||
|
||||
this._x = x;
|
||||
this._y = y;
|
||||
this._corner = new Clutter.Rectangle({ name: 'hot-corner',
|
||||
width: 1,
|
||||
height: 1,
|
||||
opacity: 0,
|
||||
reactive: true });
|
||||
this._corner._delegate = this;
|
||||
|
||||
this._setupFallbackCornerIfNeeded(layoutManager);
|
||||
this.actor.add_child(this._corner);
|
||||
|
||||
this._pressureBarrier = new PressureBarrier(HOT_CORNER_PRESSURE_THRESHOLD,
|
||||
HOT_CORNER_PRESSURE_TIMEOUT,
|
||||
Shell.KeyBindingMode.NORMAL |
|
||||
Shell.KeyBindingMode.OVERVIEW);
|
||||
this._pressureBarrier.connect('trigger', Lang.bind(this, this._toggleOverview));
|
||||
if (Clutter.get_default_text_direction() == Clutter.TextDirection.RTL) {
|
||||
this._corner.set_position(this.actor.width - this._corner.width, 0);
|
||||
this.actor.set_anchor_point_from_gravity(Clutter.Gravity.NORTH_EAST);
|
||||
} else {
|
||||
this._corner.set_position(0, 0);
|
||||
}
|
||||
|
||||
this._activationTime = 0;
|
||||
|
||||
this.actor.connect('leave-event',
|
||||
Lang.bind(this, this._onEnvironsLeft));
|
||||
|
||||
// Clicking on the hot corner environs should result in the
|
||||
// same behavior as clicking on the hot corner.
|
||||
this.actor.connect('button-release-event',
|
||||
Lang.bind(this, this._onCornerClicked));
|
||||
|
||||
// In addition to being triggered by the mouse enter event,
|
||||
// the hot corner can be triggered by clicking on it. This is
|
||||
// useful if the user wants to undo the effect of triggering
|
||||
// the hot corner once in the hot corner.
|
||||
this._corner.connect('enter-event',
|
||||
Lang.bind(this, this._onCornerEntered));
|
||||
this._corner.connect('button-release-event',
|
||||
Lang.bind(this, this._onCornerClicked));
|
||||
this._corner.connect('leave-event',
|
||||
Lang.bind(this, this._onCornerLeft));
|
||||
|
||||
// Cache the three ripples instead of dynamically creating and destroying them.
|
||||
this._ripple1 = new St.BoxLayout({ style_class: 'ripple-box', opacity: 0, visible: false });
|
||||
@ -1078,74 +1148,8 @@ const HotCorner = new Lang.Class({
|
||||
layoutManager.uiGroup.add_actor(this._ripple3);
|
||||
},
|
||||
|
||||
setBarrierSize: function(size) {
|
||||
if (this._verticalBarrier) {
|
||||
this._pressureBarrier.removeBarrier(this._verticalBarrier);
|
||||
this._verticalBarrier.destroy();
|
||||
this._verticalBarrier = null;
|
||||
}
|
||||
|
||||
if (this._horizontalBarrier) {
|
||||
this._pressureBarrier.removeBarrier(this._horizontalBarrier);
|
||||
this._horizontalBarrier.destroy();
|
||||
this._horizontalBarrier = null;
|
||||
}
|
||||
|
||||
if (size > 0) {
|
||||
this._verticalBarrier = new Meta.Barrier({ display: global.display,
|
||||
x1: this._x, x2: this._x, y1: this._y, y2: this._y + size,
|
||||
directions: Meta.BarrierDirection.POSITIVE_X });
|
||||
this._horizontalBarrier = new Meta.Barrier({ display: global.display,
|
||||
x1: this._x, x2: this._x + size, y1: this._y, y2: this._y,
|
||||
directions: Meta.BarrierDirection.POSITIVE_Y });
|
||||
|
||||
this._pressureBarrier.addBarrier(this._verticalBarrier);
|
||||
this._pressureBarrier.addBarrier(this._horizontalBarrier);
|
||||
}
|
||||
},
|
||||
|
||||
_setupFallbackCornerIfNeeded: function(layoutManager) {
|
||||
if (!global.display.supports_extended_barriers()) {
|
||||
this.actor = new Clutter.Actor({ name: 'hot-corner-environs',
|
||||
x: this._x, y: this._y,
|
||||
width: 3,
|
||||
height: 3,
|
||||
reactive: true });
|
||||
|
||||
this._corner = new Clutter.Rectangle({ name: 'hot-corner',
|
||||
width: 1,
|
||||
height: 1,
|
||||
opacity: 0,
|
||||
reactive: true });
|
||||
this._corner._delegate = this;
|
||||
|
||||
this.actor.add_child(this._corner);
|
||||
layoutManager.addChrome(this.actor);
|
||||
|
||||
if (Clutter.get_default_text_direction() == Clutter.TextDirection.RTL) {
|
||||
this._corner.set_position(this.actor.width - this._corner.width, 0);
|
||||
this.actor.set_anchor_point_from_gravity(Clutter.Gravity.NORTH_EAST);
|
||||
} else {
|
||||
this._corner.set_position(0, 0);
|
||||
}
|
||||
|
||||
this.actor.connect('leave-event',
|
||||
Lang.bind(this, this._onEnvironsLeft));
|
||||
|
||||
this._corner.connect('enter-event',
|
||||
Lang.bind(this, this._onCornerEntered));
|
||||
this._corner.connect('leave-event',
|
||||
Lang.bind(this, this._onCornerLeft));
|
||||
}
|
||||
},
|
||||
|
||||
destroy: function() {
|
||||
this.setBarrierSize(0);
|
||||
this._pressureBarrier.destroy();
|
||||
this._pressureBarrier = null;
|
||||
|
||||
if (this.actor)
|
||||
this.actor.destroy();
|
||||
this.actor.destroy();
|
||||
},
|
||||
|
||||
_animRipple : function(ripple, delay, time, startScale, startOpacity, finalScale) {
|
||||
@ -1165,8 +1169,9 @@ const HotCorner = new Lang.Class({
|
||||
ripple.opacity = 255 * Math.sqrt(startOpacity);
|
||||
ripple.scale_x = ripple.scale_y = startScale;
|
||||
|
||||
ripple.x = this._x;
|
||||
ripple.y = this._y;
|
||||
let [x, y] = this._corner.get_transformed_position();
|
||||
ripple.x = x;
|
||||
ripple.y = y;
|
||||
|
||||
Tweener.addTween(ripple, { _opacity: 0,
|
||||
scale_x: finalScale,
|
||||
@ -1178,7 +1183,7 @@ const HotCorner = new Lang.Class({
|
||||
onComplete: function() { ripple.visible = false; } });
|
||||
},
|
||||
|
||||
_rippleAnimation: function() {
|
||||
rippleAnimation: function() {
|
||||
// Show three concentric ripples expanding outwards; the exact
|
||||
// parameters were found by trial and error, so don't look
|
||||
// for them to make perfect sense mathematically
|
||||
@ -1189,21 +1194,14 @@ const HotCorner = new Lang.Class({
|
||||
this._animRipple(this._ripple3, 0.35, 1.0, 0.0, 0.3, 1);
|
||||
},
|
||||
|
||||
_toggleOverview: function() {
|
||||
if (this._monitor.inFullscreen)
|
||||
return;
|
||||
|
||||
if (Main.overview.shouldToggleByCornerOrButton()) {
|
||||
this._rippleAnimation();
|
||||
Main.overview.toggle();
|
||||
}
|
||||
},
|
||||
|
||||
handleDragOver: function(source, actor, x, y, time) {
|
||||
if (source != Main.xdndHandler)
|
||||
return DND.DragMotionResult.CONTINUE;
|
||||
|
||||
this._toggleOverview();
|
||||
if (!Main.overview.visible && !Main.overview.animationInProgress) {
|
||||
this.rippleAnimation();
|
||||
Main.overview.showTemporarily();
|
||||
}
|
||||
|
||||
return DND.DragMotionResult.CONTINUE;
|
||||
},
|
||||
@ -1211,11 +1209,22 @@ const HotCorner = new Lang.Class({
|
||||
_onCornerEntered : function() {
|
||||
if (!this._entered) {
|
||||
this._entered = true;
|
||||
this._toggleOverview();
|
||||
if (!Main.overview.animationInProgress) {
|
||||
this._activationTime = Date.now() / 1000;
|
||||
|
||||
this.rippleAnimation();
|
||||
Main.overview.toggle();
|
||||
}
|
||||
}
|
||||
return false;
|
||||
},
|
||||
|
||||
_onCornerClicked : function() {
|
||||
if (this.shouldToggleOverviewOnClick())
|
||||
Main.overview.toggle();
|
||||
return true;
|
||||
},
|
||||
|
||||
_onCornerLeft : function(actor, event) {
|
||||
if (event.get_related() != this.actor)
|
||||
this._entered = false;
|
||||
@ -1227,47 +1236,42 @@ const HotCorner = new Lang.Class({
|
||||
if (event.get_related() != this._corner)
|
||||
this._entered = false;
|
||||
return false;
|
||||
},
|
||||
|
||||
// Checks if the Activities button is currently sensitive to
|
||||
// clicks. The first call to this function within the
|
||||
// HOT_CORNER_ACTIVATION_TIMEOUT time of the hot corner being
|
||||
// triggered will return false. This avoids opening and closing
|
||||
// the overview if the user both triggered the hot corner and
|
||||
// clicked the Activities button.
|
||||
shouldToggleOverviewOnClick: function() {
|
||||
if (Main.overview.animationInProgress)
|
||||
return false;
|
||||
if (this._activationTime == 0 || Date.now() / 1000 - this._activationTime > HOT_CORNER_ACTIVATION_TIMEOUT)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
});
|
||||
|
||||
const PressureBarrier = new Lang.Class({
|
||||
Name: 'PressureBarrier',
|
||||
|
||||
_init: function(threshold, timeout, keybindingMode) {
|
||||
_init: function(barrier, threshold, timeout) {
|
||||
this._barrier = barrier;
|
||||
this._threshold = threshold;
|
||||
this._timeout = timeout;
|
||||
this._keybindingMode = keybindingMode;
|
||||
this._barriers = [];
|
||||
this._eventFilter = null;
|
||||
this._orientation = (barrier.y1 == barrier.y2) ? Clutter.Orientation.HORIZONTAL : Clutter.Orientation.VERTICAL;
|
||||
|
||||
this._isTriggered = false;
|
||||
this._reset();
|
||||
},
|
||||
|
||||
addBarrier: function(barrier) {
|
||||
barrier._pressureHitId = barrier.connect('hit', Lang.bind(this, this._onBarrierHit));
|
||||
barrier._pressureLeftId = barrier.connect('left', Lang.bind(this, this._onBarrierLeft));
|
||||
|
||||
this._barriers.push(barrier);
|
||||
},
|
||||
|
||||
_disconnectBarrier: function(barrier) {
|
||||
barrier.disconnect(barrier._pressureHitId);
|
||||
barrier.disconnect(barrier._pressureLeftId);
|
||||
},
|
||||
|
||||
removeBarrier: function(barrier) {
|
||||
this._disconnectBarrier(barrier);
|
||||
this._barriers.splice(this._barriers.indexOf(barrier), 1);
|
||||
this._barrierHitId = this._barrier.connect('hit', Lang.bind(this, this._onBarrierHit));
|
||||
this._barrierLeftId = this._barrier.connect('left', Lang.bind(this, this._onBarrierLeft));
|
||||
},
|
||||
|
||||
destroy: function() {
|
||||
this._barriers.forEach(Lang.bind(this, this._disconnectBarrier));
|
||||
this._barriers = [];
|
||||
},
|
||||
|
||||
setEventFilter: function(filter) {
|
||||
this._eventFilter = filter;
|
||||
this._barrier.disconnect(this._barrierHitId);
|
||||
this._barrier.disconnect(this._barrierLeftId);
|
||||
this._barrier = null;
|
||||
},
|
||||
|
||||
_reset: function() {
|
||||
@ -1276,34 +1280,33 @@ const PressureBarrier = new Lang.Class({
|
||||
this._lastTime = 0;
|
||||
},
|
||||
|
||||
_isHorizontal: function(barrier) {
|
||||
return barrier.y1 == barrier.y2;
|
||||
},
|
||||
|
||||
_getDistanceAcrossBarrier: function(barrier, event) {
|
||||
if (this._isHorizontal(barrier))
|
||||
_getDistanceAcrossBarrier: function(event) {
|
||||
if (this._orientation == Clutter.Orientation.HORIZONTAL)
|
||||
return Math.abs(event.dy);
|
||||
else
|
||||
return Math.abs(event.dx);
|
||||
},
|
||||
|
||||
_getDistanceAlongBarrier: function(barrier, event) {
|
||||
if (this._isHorizontal(barrier))
|
||||
_getDistanceAlongBarrier: function(event) {
|
||||
if (this._orientation == Clutter.Orientation.HORIZONTAL)
|
||||
return Math.abs(event.dx);
|
||||
else
|
||||
return Math.abs(event.dy);
|
||||
},
|
||||
|
||||
_isBarrierEventTooOld: function(event) {
|
||||
// Ignore all events older than this time
|
||||
let threshold = this._lastTime - this._timeout;
|
||||
return event.time < threshold;
|
||||
},
|
||||
|
||||
_trimBarrierEvents: function() {
|
||||
// Events are guaranteed to be sorted in time order from
|
||||
// oldest to newest, so just look for the first old event,
|
||||
// and then chop events after that off.
|
||||
let i = 0;
|
||||
let threshold = this._lastTime - this._timeout;
|
||||
|
||||
while (i < this._barrierEvents.length) {
|
||||
let [time, distance] = this._barrierEvents[i];
|
||||
if (time >= threshold)
|
||||
if (!this._isBarrierEventTooOld(this._barrierEvents[i]))
|
||||
break;
|
||||
i++;
|
||||
}
|
||||
@ -1311,8 +1314,7 @@ const PressureBarrier = new Lang.Class({
|
||||
let firstNewEvent = i;
|
||||
|
||||
for (i = 0; i < firstNewEvent; i++) {
|
||||
let [time, distance] = this._barrierEvents[i];
|
||||
this._currentPressure -= distance;
|
||||
this._currentPressure -= this._getDistanceAcrossBarrier(this._barrierEvents[i]);
|
||||
}
|
||||
|
||||
this._barrierEvents = this._barrierEvents.slice(firstNewEvent);
|
||||
@ -1320,30 +1322,29 @@ const PressureBarrier = new Lang.Class({
|
||||
|
||||
_onBarrierLeft: function(barrier, event) {
|
||||
this._reset();
|
||||
this._isTriggered = false;
|
||||
},
|
||||
|
||||
_trigger: function() {
|
||||
this._isTriggered = true;
|
||||
this.emit('trigger');
|
||||
this._reset();
|
||||
},
|
||||
|
||||
_onBarrierHit: function(barrier, event) {
|
||||
// If we've triggered the barrier, wait until the pointer has the
|
||||
// left the barrier hitbox until we trigger it again.
|
||||
if (this._isTriggered)
|
||||
// Throw out all events where the pointer was grabbed by another
|
||||
// client, as the client that grabbed the pointer expects to have
|
||||
// complete control over it
|
||||
if (event.grabbed && Main.modalCount == 0)
|
||||
return;
|
||||
|
||||
if (this._eventFilter && this._eventFilter(event))
|
||||
let isOverview = ((Main.keybindingMode & (Shell.KeyBindingMode.OVERVIEW)) != 0);
|
||||
|
||||
// Throw out events where the grab is taken by something that's
|
||||
// not the overview (modal dialogs, etc.)
|
||||
if (event.grabbed && !isOverview)
|
||||
return;
|
||||
|
||||
// Throw out all events not in the proper keybinding mode
|
||||
if (!(this._keybindingMode & Main.keybindingMode))
|
||||
return;
|
||||
|
||||
let slide = this._getDistanceAlongBarrier(barrier, event);
|
||||
let distance = this._getDistanceAcrossBarrier(barrier, event);
|
||||
let slide = this._getDistanceAlongBarrier(event);
|
||||
let distance = this._getDistanceAcrossBarrier(event);
|
||||
|
||||
if (distance >= this._threshold) {
|
||||
this._trigger();
|
||||
@ -1359,10 +1360,8 @@ const PressureBarrier = new Lang.Class({
|
||||
this._lastTime = event.time;
|
||||
|
||||
this._trimBarrierEvents();
|
||||
distance = Math.min(15, distance);
|
||||
|
||||
this._barrierEvents.push([event.time, distance]);
|
||||
this._currentPressure += distance;
|
||||
this._barrierEvents.push(event);
|
||||
this._currentPressure += Math.min(15, distance);
|
||||
|
||||
if (this._currentPressure >= this._threshold)
|
||||
this._trigger();
|
||||
|
@ -24,7 +24,6 @@ const Panel = imports.ui.panel;
|
||||
const Params = imports.misc.params;
|
||||
const RunDialog = imports.ui.runDialog;
|
||||
const Layout = imports.ui.layout;
|
||||
const LoginManager = imports.misc.loginManager;
|
||||
const LookingGlass = imports.ui.lookingGlass;
|
||||
const NotificationDaemon = imports.ui.notificationDaemon;
|
||||
const WindowAttentionHandler = imports.ui.windowAttentionHandler;
|
||||
@ -33,6 +32,7 @@ const Scripting = imports.ui.scripting;
|
||||
const SessionMode = imports.ui.sessionMode;
|
||||
const ShellDBus = imports.ui.shellDBus;
|
||||
const ShellMountOperation = imports.ui.shellMountOperation;
|
||||
const UnlockDialog = imports.ui.unlockDialog;
|
||||
const WindowManager = imports.ui.windowManager;
|
||||
const Magnifier = imports.ui.magnifier;
|
||||
const XdndHandler = imports.ui.xdndHandler;
|
||||
@ -58,7 +58,7 @@ let shellDBusService = null;
|
||||
let shellMountOpDBusService = null;
|
||||
let screenSaverDBus = null;
|
||||
let modalCount = 0;
|
||||
let keybindingMode = Shell.KeyBindingMode.NONE;
|
||||
let keybindingMode = Shell.KeyBindingMode.NORMAL;
|
||||
let modalActorFocusStack = [];
|
||||
let uiGroup = null;
|
||||
let magnifier = null;
|
||||
@ -71,8 +71,6 @@ let _cssStylesheet = null;
|
||||
let _overridesSettings = null;
|
||||
|
||||
function _sessionUpdated() {
|
||||
_loadDefaultStylesheet();
|
||||
|
||||
wm.setCustomKeybindingHandler('panel-main-menu',
|
||||
Shell.KeyBindingMode.NORMAL |
|
||||
Shell.KeyBindingMode.OVERVIEW,
|
||||
@ -84,9 +82,8 @@ function _sessionUpdated() {
|
||||
Shell.KeyBindingMode.NORMAL |
|
||||
Shell.KeyBindingMode.OVERVIEW,
|
||||
sessionMode.hasRunDialog ? openRunDialog : null);
|
||||
|
||||
if (!sessionMode.hasRunDialog && lookingGlass)
|
||||
lookingGlass.close();
|
||||
if (sessionMode.isGreeter)
|
||||
screenShield.showDialog();
|
||||
}
|
||||
|
||||
function start() {
|
||||
@ -94,27 +91,29 @@ function start() {
|
||||
global.logError = window.log;
|
||||
global.log = window.log;
|
||||
|
||||
// Hide the stage until we're ready for it
|
||||
global.stage.hide();
|
||||
|
||||
// Chain up async errors reported from C
|
||||
global.connect('notify-error', function (global, msg, detail) { notifyError(msg, detail); });
|
||||
|
||||
Gio.DesktopAppInfo.set_desktop_env('GNOME');
|
||||
|
||||
sessionMode = new SessionMode.SessionMode();
|
||||
sessionMode.connect('sessions-loaded', _sessionsLoaded);
|
||||
sessionMode.init();
|
||||
|
||||
// start session after we know what mode we're running in
|
||||
let signalId = sessionMode.connect('updated', function() {
|
||||
sessionMode.disconnect(signalId);
|
||||
startSession();
|
||||
});
|
||||
}
|
||||
|
||||
function _sessionsLoaded() {
|
||||
sessionMode.connect('updated', _sessionUpdated);
|
||||
_initializeUI();
|
||||
function startSession() {
|
||||
sessionMode.connect('updated', _loadDefaultStylesheet);
|
||||
|
||||
shellDBusService = new ShellDBus.GnomeShell();
|
||||
shellMountOpDBusService = new ShellMountOperation.GnomeShellMountOpHandler();
|
||||
|
||||
_sessionUpdated();
|
||||
}
|
||||
|
||||
function _initializeUI() {
|
||||
// Ensure ShellWindowTracker and ShellAppUsage are initialized; this will
|
||||
// also initialize ShellAppSystem first. ShellAppSystem
|
||||
// needs to load all the .desktop files, and ShellWindowTracker
|
||||
@ -144,9 +143,13 @@ function _initializeUI() {
|
||||
overview = new Overview.Overview();
|
||||
wm = new WindowManager.WindowManager();
|
||||
magnifier = new Magnifier.Magnifier();
|
||||
if (LoginManager.canLock())
|
||||
if (UnlockDialog.isSupported())
|
||||
screenShield = new ScreenShield.ScreenShield();
|
||||
else
|
||||
screenShield = new ScreenShield.ScreenShieldFallback();
|
||||
|
||||
// The message tray relies on being constructed
|
||||
// after the panel.
|
||||
panel = new Panel.Panel();
|
||||
messageTray = new MessageTray.MessageTray();
|
||||
keyboard = new Keyboard.Keyboard();
|
||||
@ -155,11 +158,14 @@ function _initializeUI() {
|
||||
componentManager = new Components.ComponentManager();
|
||||
|
||||
layoutManager.init();
|
||||
layoutManager.prepareStartupAnimation();
|
||||
overview.init();
|
||||
|
||||
global.screen.override_workspace_layout(Meta.ScreenCorner.TOPLEFT,
|
||||
false, -1, 1);
|
||||
global.display.connect('overlay-key', Lang.bind(overview, overview.toggle));
|
||||
sessionMode.connect('updated', _sessionUpdated);
|
||||
_sessionUpdated();
|
||||
|
||||
// Provide the bus object for gnome-session to
|
||||
// initiate logouts.
|
||||
@ -193,16 +199,8 @@ function _initializeUI() {
|
||||
ExtensionDownloader.init();
|
||||
ExtensionSystem.init();
|
||||
|
||||
if (sessionMode.isGreeter && screenShield) {
|
||||
layoutManager.connect('startup-prepared', function() {
|
||||
screenShield.showDialog();
|
||||
});
|
||||
}
|
||||
|
||||
layoutManager.connect('startup-complete', function() {
|
||||
if (keybindingMode == Shell.KeyBindingMode.NONE) {
|
||||
keybindingMode = Shell.KeyBindingMode.NORMAL;
|
||||
}
|
||||
layoutManager.connect('startup-prepared', function() {
|
||||
layoutManager.startupAnimation();
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -1591,13 +1591,17 @@ const MessageTray = new Lang.Class({
|
||||
global.focus_manager.add_group(this.actor);
|
||||
this._summary = new St.BoxLayout({ style_class: 'message-tray-summary',
|
||||
reactive: true,
|
||||
track_hover: true,
|
||||
x_align: Clutter.ActorAlign.END,
|
||||
x_expand: true,
|
||||
y_align: Clutter.ActorAlign.CENTER,
|
||||
y_expand: true });
|
||||
this._summary.connect('notify::hover', Lang.bind(this, this._onSummaryHoverChanged));
|
||||
this.actor.add_actor(this._summary);
|
||||
this._summary.opacity = 0;
|
||||
|
||||
this._summaryMotionId = 0;
|
||||
this._trayMotionId = 0;
|
||||
|
||||
this._summaryBoxPointer = new BoxPointer.BoxPointer(St.Side.BOTTOM,
|
||||
{ reactive: true,
|
||||
@ -1632,22 +1636,15 @@ const MessageTray = new Lang.Class({
|
||||
Main.layoutManager.connect('keyboard-visible-changed', Lang.bind(this, this._onKeyboardVisibleChanged));
|
||||
|
||||
this._trayState = State.HIDDEN;
|
||||
this._locked = false;
|
||||
this._traySummoned = false;
|
||||
this._useLongerTrayLeftTimeout = false;
|
||||
this._trayLeftTimeoutId = 0;
|
||||
|
||||
// pointerInTray is sort of a misnomer -- it tracks whether
|
||||
// a message tray notification should expand. The value is
|
||||
// partially driven by the hover state of the tray, but has
|
||||
// a lot of complex state related to timeouts and the current
|
||||
// state of the pointer when a notification pops up.
|
||||
this._pointerInTray = false;
|
||||
|
||||
// This tracks this.actor.hover and is used to fizzle
|
||||
// out non-changing hover notifications in onTrayHoverChanged.
|
||||
this._trayHovered = false;
|
||||
|
||||
this._pointerInKeyboard = false;
|
||||
this._keyboardVisible = false;
|
||||
this._summaryState = State.HIDDEN;
|
||||
this._pointerInSummary = false;
|
||||
this._notificationClosed = false;
|
||||
this._notificationState = State.HIDDEN;
|
||||
this._notificationTimeoutId = 0;
|
||||
@ -1669,18 +1666,20 @@ const MessageTray = new Lang.Class({
|
||||
});
|
||||
|
||||
Main.layoutManager.trayBox.add_actor(this.actor);
|
||||
this.actor.y = 0;
|
||||
Main.layoutManager.trackChrome(this.actor);
|
||||
Main.layoutManager.trackChrome(this._notificationWidget);
|
||||
Main.layoutManager.trackChrome(this._closeButton);
|
||||
|
||||
Main.layoutManager.connect('fullscreen-changed', Lang.bind(this, this._updateState));
|
||||
Main.layoutManager.connect('hot-corners-changed', Lang.bind(this, this._hotCornersChanged));
|
||||
Main.layoutManager.connect('primary-fullscreen-changed', Lang.bind(this, this._onFullscreenChanged));
|
||||
|
||||
// If the overview shows or hides while we're in
|
||||
// the message tray, revert back to normal mode.
|
||||
Main.overview.connect('showing', Lang.bind(this, this._escapeTray));
|
||||
Main.overview.connect('hiding', Lang.bind(this, this._escapeTray));
|
||||
|
||||
// Track if we've added the activities button
|
||||
this._activitiesButtonAdded = false;
|
||||
Main.sessionMode.connect('updated', Lang.bind(this, this._sessionUpdated));
|
||||
|
||||
Main.wm.addKeybinding('toggle-message-tray',
|
||||
@ -1704,7 +1703,6 @@ const MessageTray = new Lang.Class({
|
||||
this._trayDwellTimeoutId = 0;
|
||||
this._setupTrayDwellIfNeeded();
|
||||
this._sessionUpdated();
|
||||
this._hotCornersChanged();
|
||||
|
||||
this._noMessages = new St.Label({ text: _("No Messages"),
|
||||
style_class: 'no-messages-label',
|
||||
@ -1745,11 +1743,13 @@ const MessageTray = new Lang.Class({
|
||||
|
||||
_openContextMenu: function () {
|
||||
let [x, y, mask] = global.get_pointer();
|
||||
this._lock();
|
||||
this._contextMenu.setPosition(Math.round(x), Math.round(y));
|
||||
this._grabHelper.grab({ actor: this._contextMenu.actor,
|
||||
grabFocus: true,
|
||||
onUngrab: Lang.bind(this, function () {
|
||||
this._contextMenu.close(BoxPointer.PopupAnimation.FULL);
|
||||
this._unlock();
|
||||
})
|
||||
});
|
||||
this._contextMenu.open(BoxPointer.PopupAnimation.FULL);
|
||||
@ -1775,6 +1775,11 @@ const MessageTray = new Lang.Class({
|
||||
},
|
||||
|
||||
_sessionUpdated: function() {
|
||||
if (!this._activitiesButtonAdded && Main.panel.statusArea.activities) {
|
||||
this._activitiesButtonAdded = true;
|
||||
this._grabHelper.addActor(Main.panel.statusArea.activities.hotCorner.actor);
|
||||
}
|
||||
|
||||
if ((Main.sessionMode.isLocked || Main.sessionMode.isGreeter) && this._inCtrlAltTab) {
|
||||
Main.ctrlAltTabManager.removeGroup(this._summary);
|
||||
this._inCtrlAltTab = false;
|
||||
@ -1823,9 +1828,6 @@ const MessageTray = new Lang.Class({
|
||||
_trayDwellTimeout: function() {
|
||||
this._trayDwellTimeoutId = 0;
|
||||
|
||||
if (Main.layoutManager.bottomMonitor.inFullscreen)
|
||||
return false;
|
||||
|
||||
// We don't want to open the tray when a modal dialog
|
||||
// is up, so we check the modal count for that. When we are in the
|
||||
// overview we have to take the overview's modal push into account
|
||||
@ -1997,6 +1999,18 @@ const MessageTray = new Lang.Class({
|
||||
this._notificationQueue.splice(index, 1);
|
||||
},
|
||||
|
||||
_lock: function() {
|
||||
this._locked = true;
|
||||
},
|
||||
|
||||
_unlock: function() {
|
||||
if (!this._locked)
|
||||
return;
|
||||
this._locked = false;
|
||||
this._pointerInTray = this.actor.hover;
|
||||
this._updateState();
|
||||
},
|
||||
|
||||
openTray: function() {
|
||||
if (Main.overview.animationInProgress)
|
||||
return;
|
||||
@ -2022,6 +2036,7 @@ const MessageTray = new Lang.Class({
|
||||
hide: function() {
|
||||
this._traySummoned = false;
|
||||
this.actor.set_hover(false);
|
||||
this._summary.set_hover(false);
|
||||
this._updateState();
|
||||
},
|
||||
|
||||
@ -2081,19 +2096,13 @@ const MessageTray = new Lang.Class({
|
||||
this._updateState();
|
||||
},
|
||||
|
||||
_hotCornersChanged: function() {
|
||||
let primary = Main.layoutManager.primaryIndex;
|
||||
let corner = Main.layoutManager.hotCorners[primary];
|
||||
if (corner && corner.actor)
|
||||
this._grabHelper.addActor(corner.actor);
|
||||
_onSummaryHoverChanged: function() {
|
||||
this._pointerInSummary = this._summary.hover;
|
||||
this._updateState();
|
||||
},
|
||||
|
||||
_onTrayHoverChanged: function() {
|
||||
if (this.actor.hover == this._trayHovered)
|
||||
return;
|
||||
|
||||
this._trayHovered = this.actor.hover;
|
||||
if (this._trayHovered) {
|
||||
if (this.actor.hover) {
|
||||
// No dwell inside notifications at the bottom of the screen
|
||||
this._cancelTrayDwell();
|
||||
|
||||
@ -2101,6 +2110,13 @@ const MessageTray = new Lang.Class({
|
||||
if (this._trayState == State.HIDDEN && this._notificationState == State.HIDDEN)
|
||||
return;
|
||||
|
||||
// Don't do anything if this._useLongerTrayLeftTimeout is true, meaning the notification originally
|
||||
// popped up under the pointer, but this._trayLeftTimeoutId is 0, meaning the pointer didn't leave
|
||||
// the tray yet. We need to check for this case because sometimes _onTrayHoverChanged() gets called
|
||||
// multiple times while this.actor.hover is true.
|
||||
if (this._useLongerTrayLeftTimeout && !this._trayLeftTimeoutId)
|
||||
return;
|
||||
|
||||
this._useLongerTrayLeftTimeout = false;
|
||||
if (this._trayLeftTimeoutId) {
|
||||
Mainloop.source_remove(this._trayLeftTimeoutId);
|
||||
@ -2149,6 +2165,11 @@ const MessageTray = new Lang.Class({
|
||||
this._updateState();
|
||||
},
|
||||
|
||||
_onFullscreenChanged: function(obj, state) {
|
||||
this._inFullscreen = state;
|
||||
this._updateState();
|
||||
},
|
||||
|
||||
_onStatusChanged: function(status) {
|
||||
if (status == GnomeSession.PresenceStatus.BUSY) {
|
||||
// remove notification and allow the summary to be closed now
|
||||
@ -2180,6 +2201,7 @@ const MessageTray = new Lang.Class({
|
||||
this._trayLeftTimeoutId = 0;
|
||||
this._useLongerTrayLeftTimeout = false;
|
||||
this._pointerInTray = false;
|
||||
this._pointerInSummary = false;
|
||||
this._updateNotificationTimeout(0);
|
||||
this._updateState();
|
||||
}
|
||||
@ -2187,7 +2209,9 @@ const MessageTray = new Lang.Class({
|
||||
},
|
||||
|
||||
_escapeTray: function() {
|
||||
this._unlock();
|
||||
this._pointerInTray = false;
|
||||
this._pointerInSummary = false;
|
||||
this._traySummoned = false;
|
||||
this._setClickedSummaryItem(null);
|
||||
this._updateNotificationTimeout(0);
|
||||
@ -2196,7 +2220,7 @@ const MessageTray = new Lang.Class({
|
||||
|
||||
// All of the logic for what happens when occurs here; the various
|
||||
// event handlers merely update variables such as
|
||||
// 'this._pointerInTray', 'this._traySummoned', etc, and
|
||||
// 'this._pointerInTray', 'this._summaryState', etc, and
|
||||
// _updateState() figures out what (if anything) needs to be done
|
||||
// at the present time.
|
||||
_updateState: function() {
|
||||
@ -2204,22 +2228,25 @@ const MessageTray = new Lang.Class({
|
||||
let notificationQueue = this._notificationQueue;
|
||||
let notificationUrgent = notificationQueue.length > 0 && notificationQueue[0].urgency == Urgency.CRITICAL;
|
||||
let notificationForFeedback = notificationQueue.length > 0 && notificationQueue[0].forFeedback;
|
||||
let notificationsLimited = this._busy || Main.layoutManager.bottomMonitor.inFullscreen;
|
||||
let notificationsLimited = this._busy || this._inFullscreen;
|
||||
let notificationsPending = notificationQueue.length > 0 && (!notificationsLimited || notificationUrgent || notificationForFeedback) && Main.sessionMode.hasNotifications;
|
||||
let nextNotification = notificationQueue.length > 0 ? notificationQueue[0] : null;
|
||||
let notificationPinned = this._pointerInTray && !this._notificationRemoved;
|
||||
let notificationPinned = this._pointerInTray && !this._pointerInSummary && !this._notificationRemoved;
|
||||
let notificationExpanded = this._notification && this._notification.expanded;
|
||||
let notificationExpired = this._notificationTimeoutId == 0 &&
|
||||
!(this._notification && this._notification.urgency == Urgency.CRITICAL) &&
|
||||
!(this._notification && this._notification.focused) &&
|
||||
!this._pointerInTray;
|
||||
!this._pointerInTray &&
|
||||
!this._locked &&
|
||||
!(this._pointerInKeyboard && notificationExpanded);
|
||||
let notificationLockedOut = !Main.sessionMode.hasNotifications && this._notification;
|
||||
let notificationMustClose = this._notificationRemoved || notificationLockedOut || (notificationExpired && this._userActiveWhileNotificationShown) || this._notificationClosed;
|
||||
let canShowNotification = notificationsPending && this._trayState == State.HIDDEN;
|
||||
let canShowNotification = notificationsPending && this._summaryState == State.HIDDEN;
|
||||
|
||||
if (this._notificationState == State.HIDDEN) {
|
||||
if (canShowNotification)
|
||||
if (canShowNotification) {
|
||||
this._showNotification();
|
||||
}
|
||||
} else if (this._notificationState == State.SHOWN) {
|
||||
if (notificationMustClose)
|
||||
this._hideNotification();
|
||||
@ -2229,17 +2256,27 @@ const MessageTray = new Lang.Class({
|
||||
this._ensureNotificationFocused();
|
||||
}
|
||||
|
||||
// Summary
|
||||
let summarySummoned = this._pointerInSummary || this._traySummoned;
|
||||
let summaryPinned = this._pointerInTray || summarySummoned || this._locked;
|
||||
let summaryHovered = this._pointerInTray || this._pointerInSummary;
|
||||
|
||||
let notificationsVisible = this._notificationState != State.HIDDEN;
|
||||
let notificationsDone = !notificationsVisible && !notificationsPending;
|
||||
|
||||
let mustHideTray = ((notificationsPending && notificationUrgent)
|
||||
|| notificationsVisible || !Main.sessionMode.hasNotifications);
|
||||
let mustHideSummary = ((notificationsPending && notificationUrgent)
|
||||
|| notificationsVisible || !Main.sessionMode.hasNotifications);
|
||||
|
||||
if (this._summaryState == State.HIDDEN && !mustHideSummary && summarySummoned)
|
||||
this._showSummary();
|
||||
else if (this._summaryState == State.SHOWN && (!summaryPinned || mustHideSummary))
|
||||
this._hideSummary();
|
||||
|
||||
// Summary notification
|
||||
let haveClickedSummaryItem = this._clickedSummaryItem != null;
|
||||
let summarySourceIsMainNotificationSource = (haveClickedSummaryItem && this._notification &&
|
||||
this._clickedSummaryItem.source == this._notification.source);
|
||||
let canShowSummaryBoxPointer = this._trayState == State.SHOWN;
|
||||
let canShowSummaryBoxPointer = this._summaryState == State.SHOWN;
|
||||
// We only have sources with empty notification stacks for legacy tray icons. Currently, we never attempt
|
||||
// to show notifications for legacy tray icons, but this would be necessary if we did.
|
||||
let requestedNotificationStackIsEmpty = (this._clickedSummaryItemMouseButton == 1 && this._clickedSummaryItem.source.notifications.length == 0);
|
||||
@ -2254,7 +2291,7 @@ const MessageTray = new Lang.Class({
|
||||
if (haveClickedSummaryItem && !summarySourceIsMainNotificationSource && canShowSummaryBoxPointer && !requestedNotificationStackIsEmpty)
|
||||
this._showSummaryBoxPointer();
|
||||
} else if (this._summaryBoxPointerState == State.SHOWN) {
|
||||
if (!haveClickedSummaryItem || !canShowSummaryBoxPointer || wrongSummaryBoxPointer || mustHideTray) {
|
||||
if (!haveClickedSummaryItem || !canShowSummaryBoxPointer || wrongSummaryBoxPointer || mustHideSummary) {
|
||||
this._hideSummaryBoxPointer();
|
||||
if (wrongSummaryBoxPointer)
|
||||
this._showSummaryBoxPointer();
|
||||
@ -2264,7 +2301,9 @@ const MessageTray = new Lang.Class({
|
||||
// Tray itself
|
||||
let trayIsVisible = (this._trayState == State.SHOWING ||
|
||||
this._trayState == State.SHOWN);
|
||||
let trayShouldBeVisible = this._traySummoned && !this._keyboardVisible && !mustHideTray;
|
||||
let trayShouldBeVisible = (this._summaryState == State.SHOWING ||
|
||||
this._summaryState == State.SHOWN) &&
|
||||
!this._keyboardVisible;
|
||||
if (!trayIsVisible && trayShouldBeVisible)
|
||||
trayShouldBeVisible = this._showTray();
|
||||
else if (trayIsVisible && !trayShouldBeVisible)
|
||||
@ -2402,7 +2441,7 @@ const MessageTray = new Lang.Class({
|
||||
_showNotification: function() {
|
||||
this._notification = this._notificationQueue.shift();
|
||||
|
||||
this._userActiveWhileNotificationShown = this.idleMonitor.get_idletime() <= IDLE_TIME;
|
||||
this._userActiveWhileNotificationShown = this.idleMonitor.get_idletime() > IDLE_TIME;
|
||||
if (!this._userActiveWhileNotificationShown) {
|
||||
// If the user isn't active, set up a watch to let us know
|
||||
// when the user becomes active.
|
||||
@ -2537,14 +2576,6 @@ const MessageTray = new Lang.Class({
|
||||
this._notificationUnfocusedId = 0;
|
||||
}
|
||||
|
||||
this._useLongerTrayLeftTimeout = false;
|
||||
if (this._trayLeftTimeoutId) {
|
||||
Mainloop.source_remove(this._trayLeftTimeoutId);
|
||||
this._trayLeftTimeoutId = 0;
|
||||
this._trayLeftMouseX = -1;
|
||||
this._trayLeftMouseY = -1;
|
||||
}
|
||||
|
||||
if (this._notificationRemoved) {
|
||||
Tweener.removeTweens(this._notificationWidget);
|
||||
this._notificationWidget.y = this.actor.height;
|
||||
@ -2575,11 +2606,7 @@ const MessageTray = new Lang.Class({
|
||||
this._notificationRemoved = false;
|
||||
this._closeButton.hide();
|
||||
this._pointerInTray = false;
|
||||
|
||||
// Clutter will send a leave-event the next time the mouse
|
||||
// moves, but we need to set this here now to update the
|
||||
// state machine.
|
||||
this.actor.hover = false;
|
||||
this.actor.hover = false; // Clutter doesn't emit notify::hover when actors move
|
||||
this._notificationBin.child = null;
|
||||
this._notificationWidget.hide();
|
||||
},
|
||||
@ -2592,9 +2619,10 @@ const MessageTray = new Lang.Class({
|
||||
},
|
||||
|
||||
_expandNotification: function(autoExpanding) {
|
||||
// Don't focus notifications that are auto-expanding.
|
||||
// Don't grab focus in notifications that are auto-expanded.
|
||||
if (!autoExpanding)
|
||||
this._ensureNotificationFocused();
|
||||
this._grabHelper.grab({ actor: this._notification.actor,
|
||||
grabFocus: true });
|
||||
|
||||
if (!this._notificationExpandedId)
|
||||
this._notificationExpandedId =
|
||||
@ -2624,11 +2652,30 @@ const MessageTray = new Lang.Class({
|
||||
}
|
||||
},
|
||||
|
||||
// We use this function to grab focus when the user moves the pointer
|
||||
// to a notification with CRITICAL urgency that was already auto-expanded.
|
||||
_ensureNotificationFocused: function() {
|
||||
this._grabHelper.grab({ actor: this._notification.actor,
|
||||
grabFocus: true });
|
||||
},
|
||||
|
||||
_showSummary: function() {
|
||||
this._summary.opacity = 0;
|
||||
this._tween(this._summary, '_summaryState', State.SHOWN,
|
||||
{ opacity: 255,
|
||||
time: ANIMATION_TIME,
|
||||
transition: 'easeOutQuad',
|
||||
});
|
||||
},
|
||||
|
||||
_hideSummary: function() {
|
||||
this._tween(this._summary, '_summaryState', State.HIDDEN,
|
||||
{ opacity: 0,
|
||||
time: ANIMATION_TIME,
|
||||
transition: 'easeOutQuad',
|
||||
});
|
||||
},
|
||||
|
||||
_onSourceDoneDisplayingContent: function(source, closeTray) {
|
||||
if (closeTray) {
|
||||
this._escapeTray();
|
||||
@ -2672,6 +2719,7 @@ const MessageTray = new Lang.Class({
|
||||
this._grabHelper.grab({ actor: this._summaryBoxPointer.bin.child,
|
||||
grabFocus: true,
|
||||
onUngrab: Lang.bind(this, this._onSummaryBoxPointerUngrabbed) });
|
||||
this._lock();
|
||||
|
||||
this._summaryBoxPointer.actor.opacity = 0;
|
||||
this._summaryBoxPointer.actor.show();
|
||||
@ -2706,8 +2754,10 @@ const MessageTray = new Lang.Class({
|
||||
this._clickedSummaryItem.actor.remove_style_pseudo_class('selected');
|
||||
this._clickedSummaryItem.actor.disconnect(this._clickedSummaryItemAllocationChangedId);
|
||||
this._summary.disconnect(this._summaryMotionId);
|
||||
Main.layoutManager.trayBox.disconnect(this._trayMotionId);
|
||||
this._clickedSummaryItemAllocationChangedId = 0;
|
||||
this._summaryMotionId = 0;
|
||||
this._trayMotionId = 0;
|
||||
}
|
||||
|
||||
this._clickedSummaryItem = item;
|
||||
@ -2722,6 +2772,8 @@ const MessageTray = new Lang.Class({
|
||||
// _clickedSummaryItem.actor can change absolute position without changing allocation
|
||||
this._summaryMotionId = this._summary.connect('allocation-changed',
|
||||
Lang.bind(this, this._adjustSummaryBoxPointerPosition));
|
||||
this._trayMotionId = Main.layoutManager.trayBox.connect('notify::anchor-y',
|
||||
Lang.bind(this, this._adjustSummaryBoxPointerPosition));
|
||||
}
|
||||
|
||||
return true;
|
||||
@ -2758,6 +2810,8 @@ const MessageTray = new Lang.Class({
|
||||
this._sourceDoneDisplayingId = 0;
|
||||
}
|
||||
|
||||
this._unlock();
|
||||
|
||||
if (this._summaryBoxPointerItem.source.notifications.length == 0) {
|
||||
this._summaryBoxPointer.actor.hide();
|
||||
this._hideSummaryBoxPointerCompleted();
|
||||
|
@ -38,15 +38,13 @@ const ModalDialog = new Lang.Class({
|
||||
styleClass: null,
|
||||
parentActor: Main.uiGroup,
|
||||
keybindingMode: Shell.KeyBindingMode.SYSTEM_MODAL,
|
||||
shouldFadeIn: true,
|
||||
destroyOnClose: true });
|
||||
shouldFadeIn: true });
|
||||
|
||||
this.state = State.CLOSED;
|
||||
this._hasModal = false;
|
||||
this._keybindingMode = params.keybindingMode;
|
||||
this._shellReactive = params.shellReactive;
|
||||
this._shouldFadeIn = params.shouldFadeIn;
|
||||
this._destroyOnClose = params.destroyOnClose;
|
||||
|
||||
this._group = new St.Widget({ visible: false,
|
||||
x: 0,
|
||||
@ -279,9 +277,6 @@ const ModalDialog = new Lang.Class({
|
||||
this.state = State.CLOSED;
|
||||
this._group.hide();
|
||||
this.emit('closed');
|
||||
|
||||
if (this._destroyOnClose)
|
||||
this.destroy();
|
||||
})
|
||||
});
|
||||
},
|
||||
|
@ -244,7 +244,7 @@ const NotificationDaemon = new Lang.Class({
|
||||
Main.overview.connect('hidden',
|
||||
Lang.bind(this, this._onFocusAppChanged));
|
||||
|
||||
this._trayManager.manage_screen(global.screen, Main.messageTray.actor);
|
||||
this._trayManager.manage_stage(global.stage, Main.messageTray.actor);
|
||||
},
|
||||
|
||||
_imageForNotificationData: function(hints) {
|
||||
|
@ -164,12 +164,12 @@ const OsdWindow = new Lang.Class({
|
||||
},
|
||||
|
||||
_monitorsChanged: function() {
|
||||
/* assume 110x110 on a 640x480 display and scale from there */
|
||||
/* assume 130x130 on a 640x480 display and scale from there */
|
||||
let monitor = Main.layoutManager.primaryMonitor;
|
||||
let scalew = monitor.width / 640.0;
|
||||
let scaleh = monitor.height / 480.0;
|
||||
let scale = Math.min(scalew, scaleh);
|
||||
let size = 110 * Math.max(1, scale);
|
||||
let size = 130 * Math.max(1, scale);
|
||||
|
||||
this._box.set_size(size, size);
|
||||
this._box.translation_y = monitor.height / 4;
|
||||
|
@ -33,8 +33,6 @@ const SHADE_ANIMATION_TIME = .20;
|
||||
|
||||
const DND_WINDOW_SWITCH_TIMEOUT = 1250;
|
||||
|
||||
const OVERVIEW_ACTIVATION_TIMEOUT = 0.5;
|
||||
|
||||
const ShellInfo = new Lang.Class({
|
||||
Name: 'ShellInfo',
|
||||
|
||||
@ -95,7 +93,9 @@ const Overview = new Lang.Class({
|
||||
_init: function() {
|
||||
this._overviewCreated = false;
|
||||
this._initCalled = false;
|
||||
this._controlPressed = false;
|
||||
|
||||
global.stage.connect('captured-event', Lang.bind(this, this._capturedEvent));
|
||||
Main.sessionMode.connect('updated', Lang.bind(this, this._sessionUpdated));
|
||||
this._sessionUpdated();
|
||||
},
|
||||
@ -146,10 +146,9 @@ const Overview = new Lang.Class({
|
||||
this._backgroundGroup.hide();
|
||||
this._bgManagers = [];
|
||||
|
||||
this._activationTime = 0;
|
||||
|
||||
this.visible = false; // animating to overview, in overview, animating out
|
||||
this._shown = false; // show() and not hide()
|
||||
this._shownTemporarily = false; // showTemporarily() and not hideTemporarily()
|
||||
this._modal = false; // have a modal grab
|
||||
this.animationInProgress = false;
|
||||
this.visibleTarget = false;
|
||||
@ -239,6 +238,20 @@ const Overview = new Lang.Class({
|
||||
}
|
||||
},
|
||||
|
||||
_capturedEvent: function(actor, event) {
|
||||
let type = event.type();
|
||||
if (type != Clutter.EventType.KEY_PRESS &&
|
||||
type != Clutter.EventType.KEY_RELEASE)
|
||||
return false;
|
||||
|
||||
let symbol = event.get_key_symbol();
|
||||
if (symbol == Clutter.KEY_Control_L ||
|
||||
symbol == Clutter.KEY_Control_R)
|
||||
this._controlPressed = type == Clutter.EventType.KEY_PRESS;
|
||||
|
||||
return false;
|
||||
},
|
||||
|
||||
_sessionUpdated: function() {
|
||||
this.isDummy = !Main.sessionMode.hasOverview;
|
||||
this._createOverview();
|
||||
@ -333,22 +346,18 @@ const Overview = new Lang.Class({
|
||||
},
|
||||
|
||||
_onDragBegin: function() {
|
||||
this._inXdndDrag = true;
|
||||
|
||||
DND.addDragMonitor(this._dragMonitor);
|
||||
// Remember the workspace we started from
|
||||
this._lastActiveWorkspaceIndex = global.screen.get_active_workspace_index();
|
||||
},
|
||||
|
||||
_onDragEnd: function(time) {
|
||||
this._inXdndDrag = false;
|
||||
|
||||
// In case the drag was canceled while in the overview
|
||||
// we have to go back to where we started and hide
|
||||
// the overview
|
||||
if (this._shown) {
|
||||
if (this._shownTemporarily) {
|
||||
global.screen.get_workspace_by_index(this._lastActiveWorkspaceIndex).activate(time);
|
||||
this.hide();
|
||||
this.hideTemporarily();
|
||||
}
|
||||
this._resetWindowSwitchTimeout();
|
||||
this._lastHoveredWindow = null;
|
||||
@ -396,7 +405,7 @@ const Overview = new Lang.Class({
|
||||
this._needsFakePointerEvent = true;
|
||||
Main.activateWindow(dragEvent.targetActor._delegate.metaWindow,
|
||||
this._windowSwitchTimestamp);
|
||||
this.hide();
|
||||
this.hideTemporarily();
|
||||
this._lastHoveredWindow = null;
|
||||
}));
|
||||
}
|
||||
@ -492,10 +501,9 @@ const Overview = new Lang.Class({
|
||||
if (this._shown)
|
||||
return;
|
||||
this._shown = true;
|
||||
|
||||
if (!this._syncInputMode())
|
||||
this._syncInputMode();
|
||||
if (!this._modal)
|
||||
return;
|
||||
|
||||
this._animateVisible();
|
||||
},
|
||||
|
||||
@ -528,7 +536,6 @@ const Overview = new Lang.Class({
|
||||
this.visible = true;
|
||||
this.animationInProgress = true;
|
||||
this.visibleTarget = true;
|
||||
this._activationTime = Date.now() / 1000;
|
||||
|
||||
// All the the actors in the window group are completely obscured,
|
||||
// hiding the group holding them while the Overview is displayed greatly
|
||||
@ -540,6 +547,8 @@ const Overview = new Lang.Class({
|
||||
//
|
||||
// Disable unredirection while in the overview
|
||||
Meta.disable_unredirect_for_screen(global.screen);
|
||||
global.window_group.hide();
|
||||
global.top_window_group.hide();
|
||||
this._stack.show();
|
||||
this._backgroundGroup.show();
|
||||
this._viewSelector.show();
|
||||
@ -559,6 +568,24 @@ const Overview = new Lang.Class({
|
||||
this.emit('showing');
|
||||
},
|
||||
|
||||
// showTemporarily:
|
||||
//
|
||||
// Animates the overview visible without grabbing mouse and keyboard input;
|
||||
// if show() has already been called, this has no immediate effect, but
|
||||
// will result in the overview not being hidden until hideTemporarily() is
|
||||
// called.
|
||||
showTemporarily: function() {
|
||||
if (this.isDummy)
|
||||
return;
|
||||
|
||||
if (this._shownTemporarily)
|
||||
return;
|
||||
|
||||
this._syncInputMode();
|
||||
this._animateVisible();
|
||||
this._shownTemporarily = true;
|
||||
},
|
||||
|
||||
// hide:
|
||||
//
|
||||
// Reverses the effect of show()
|
||||
@ -569,22 +596,33 @@ const Overview = new Lang.Class({
|
||||
if (!this._shown)
|
||||
return;
|
||||
|
||||
let event = Clutter.get_current_event();
|
||||
if (event) {
|
||||
let type = event.type();
|
||||
let button = (type == Clutter.EventType.BUTTON_PRESS ||
|
||||
type == Clutter.EventType.BUTTON_RELEASE);
|
||||
let ctrl = (event.get_state() & Clutter.ModifierType.CONTROL_MASK) != 0;
|
||||
if (button && ctrl)
|
||||
return;
|
||||
}
|
||||
if (this._controlPressed)
|
||||
return;
|
||||
|
||||
this._animateNotVisible();
|
||||
if (!this._shownTemporarily)
|
||||
this._animateNotVisible();
|
||||
|
||||
this._shown = false;
|
||||
this._syncInputMode();
|
||||
},
|
||||
|
||||
// hideTemporarily:
|
||||
//
|
||||
// Reverses the effect of showTemporarily()
|
||||
hideTemporarily: function() {
|
||||
if (this.isDummy)
|
||||
return;
|
||||
|
||||
if (!this._shownTemporarily)
|
||||
return;
|
||||
|
||||
if (!this._shown)
|
||||
this._animateNotVisible();
|
||||
|
||||
this._shownTemporarily = false;
|
||||
this._syncInputMode();
|
||||
},
|
||||
|
||||
toggle: function() {
|
||||
if (this.isDummy)
|
||||
return;
|
||||
@ -595,20 +633,6 @@ const Overview = new Lang.Class({
|
||||
this.show();
|
||||
},
|
||||
|
||||
// Checks if the Activities button is currently sensitive to
|
||||
// clicks. The first call to this function within the
|
||||
// OVERVIEW_ACTIVATION_TIMEOUT time of the hot corner being
|
||||
// triggered will return false. This avoids opening and closing
|
||||
// the overview if the user both triggered the hot corner and
|
||||
// clicked the Activities button.
|
||||
shouldToggleByCornerOrButton: function() {
|
||||
if (this.animationInProgress)
|
||||
return false;
|
||||
if (this._activationTime == 0 || Date.now() / 1000 - this._activationTime > OVERVIEW_ACTIVATION_TIMEOUT)
|
||||
return true;
|
||||
return false;
|
||||
},
|
||||
|
||||
//// Private methods ////
|
||||
|
||||
_syncInputMode: function() {
|
||||
@ -616,23 +640,22 @@ const Overview = new Lang.Class({
|
||||
// overview we don't have a problem with the release of a press/release
|
||||
// going to an application.
|
||||
if (this.animationInProgress)
|
||||
return true;
|
||||
return;
|
||||
|
||||
if (this._shown) {
|
||||
let shouldBeModal = !this._inXdndDrag;
|
||||
if (shouldBeModal) {
|
||||
if (!this._modal) {
|
||||
if (Main.pushModal(this._overview,
|
||||
{ keybindingMode: Shell.KeyBindingMode.OVERVIEW })) {
|
||||
this._modal = true;
|
||||
} else {
|
||||
this.hide();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
global.stage_input_mode = Shell.StageInputMode.FULLSCREEN;
|
||||
if (!this._modal) {
|
||||
if (Main.pushModal(this._overview,
|
||||
{ keybindingMode: Shell.KeyBindingMode.OVERVIEW }))
|
||||
this._modal = true;
|
||||
else
|
||||
this.hide();
|
||||
}
|
||||
} else if (this._shownTemporarily) {
|
||||
if (this._modal) {
|
||||
Main.popModal(this._overview);
|
||||
this._modal = false;
|
||||
}
|
||||
global.stage_input_mode = Shell.StageInputMode.FULLSCREEN;
|
||||
} else {
|
||||
if (this._modal) {
|
||||
Main.popModal(this._overview);
|
||||
@ -641,7 +664,6 @@ const Overview = new Lang.Class({
|
||||
else if (global.stage_input_mode == Shell.StageInputMode.FULLSCREEN)
|
||||
global.stage_input_mode = Shell.StageInputMode.NORMAL;
|
||||
}
|
||||
return true;
|
||||
},
|
||||
|
||||
_animateNotVisible: function() {
|
||||
@ -675,7 +697,7 @@ const Overview = new Lang.Class({
|
||||
|
||||
this.emit('shown');
|
||||
// Handle any calls to hide* while we were showing
|
||||
if (!this._shown)
|
||||
if (!this._shown && !this._shownTemporarily)
|
||||
this._animateNotVisible();
|
||||
|
||||
this._syncInputMode();
|
||||
@ -686,6 +708,9 @@ const Overview = new Lang.Class({
|
||||
// Re-enable unredirection
|
||||
Meta.enable_unredirect_for_screen(global.screen);
|
||||
|
||||
global.window_group.show();
|
||||
global.top_window_group.show();
|
||||
|
||||
this._viewSelector.hide();
|
||||
this._desktopFade.hide();
|
||||
this._backgroundGroup.hide();
|
||||
@ -698,7 +723,7 @@ const Overview = new Lang.Class({
|
||||
|
||||
this.emit('hidden');
|
||||
// Handle any calls to show* while we were hiding
|
||||
if (this._shown)
|
||||
if (this._shown || this._shownTemporarily)
|
||||
this._animateVisible();
|
||||
|
||||
this._syncInputMode();
|
||||
|
@ -452,11 +452,9 @@ const MessagesIndicator = new Lang.Class({
|
||||
|
||||
_updateCount: function() {
|
||||
let count = 0;
|
||||
let hasChats = false;
|
||||
this._sources.forEach(Lang.bind(this,
|
||||
function(source) {
|
||||
count += source.indicatorCount;
|
||||
hasChats |= source.isChat;
|
||||
}));
|
||||
|
||||
this._count = count;
|
||||
@ -464,7 +462,6 @@ const MessagesIndicator = new Lang.Class({
|
||||
"%d new messages",
|
||||
count).format(count);
|
||||
|
||||
this._icon.visible = hasChats;
|
||||
this._updateVisibility();
|
||||
},
|
||||
|
||||
|
@ -18,6 +18,7 @@ const Atk = imports.gi.Atk;
|
||||
const Config = imports.misc.config;
|
||||
const CtrlAltTab = imports.ui.ctrlAltTab;
|
||||
const DND = imports.ui.dnd;
|
||||
const Layout = imports.ui.layout;
|
||||
const Overview = imports.ui.overview;
|
||||
const PopupMenu = imports.ui.popupMenu;
|
||||
const PanelMenu = imports.ui.panelMenu;
|
||||
@ -629,15 +630,23 @@ const ActivitiesButton = new Lang.Class({
|
||||
this.parent(0.0, null, true);
|
||||
this.actor.accessible_role = Atk.Role.TOGGLE_BUTTON;
|
||||
|
||||
let container = new Shell.GenericContainer();
|
||||
container.connect('get-preferred-width', Lang.bind(this, this._containerGetPreferredWidth));
|
||||
container.connect('get-preferred-height', Lang.bind(this, this._containerGetPreferredHeight));
|
||||
container.connect('allocate', Lang.bind(this, this._containerAllocate));
|
||||
this.actor.add_actor(container);
|
||||
this.actor.name = 'panelActivities';
|
||||
|
||||
/* Translators: If there is no suitable word for "Activities"
|
||||
in your language, you can use the word for "Overview". */
|
||||
this._label = new St.Label({ text: _("Activities") });
|
||||
this.actor.add_actor(this._label);
|
||||
container.add_actor(this._label);
|
||||
|
||||
this.actor.label_actor = this._label;
|
||||
|
||||
this.hotCorner = new Layout.HotCorner(Main.layoutManager);
|
||||
container.add_actor(this.hotCorner.actor);
|
||||
|
||||
this.actor.connect('captured-event', Lang.bind(this, this._onCapturedEvent));
|
||||
this.actor.connect_after('button-release-event', Lang.bind(this, this._onButtonRelease));
|
||||
this.actor.connect_after('key-release-event', Lang.bind(this, this._onKeyRelease));
|
||||
@ -652,6 +661,44 @@ const ActivitiesButton = new Lang.Class({
|
||||
}));
|
||||
|
||||
this._xdndTimeOut = 0;
|
||||
|
||||
// Since the hot corner uses stage coordinates, Clutter won't
|
||||
// queue relayouts for us when the panel moves. Queue a relayout
|
||||
// when that happens.
|
||||
Main.layoutManager.connect('panel-box-changed', Lang.bind(this, function() {
|
||||
container.queue_relayout();
|
||||
}));
|
||||
},
|
||||
|
||||
_containerGetPreferredWidth: function(actor, forHeight, alloc) {
|
||||
[alloc.min_size, alloc.natural_size] = this._label.get_preferred_width(forHeight);
|
||||
},
|
||||
|
||||
_containerGetPreferredHeight: function(actor, forWidth, alloc) {
|
||||
[alloc.min_size, alloc.natural_size] = this._label.get_preferred_height(forWidth);
|
||||
},
|
||||
|
||||
_containerAllocate: function(actor, box, flags) {
|
||||
this._label.allocate(box, flags);
|
||||
|
||||
// The hot corner needs to be outside any padding/alignment
|
||||
// that has been imposed on us
|
||||
let primary = Main.layoutManager.primaryMonitor;
|
||||
let hotBox = new Clutter.ActorBox();
|
||||
let ok, x, y;
|
||||
if (actor.get_text_direction() == Clutter.TextDirection.LTR) {
|
||||
[ok, x, y] = actor.transform_stage_point(primary.x, primary.y)
|
||||
} else {
|
||||
[ok, x, y] = actor.transform_stage_point(primary.x + primary.width, primary.y);
|
||||
// hotCorner.actor has northeast gravity, so we don't need
|
||||
// to adjust x for its width
|
||||
}
|
||||
|
||||
hotBox.x1 = Math.round(x);
|
||||
hotBox.x2 = hotBox.x1 + this.hotCorner.actor.width;
|
||||
hotBox.y1 = Math.round(y);
|
||||
hotBox.y2 = hotBox.y1 + this.hotCorner.actor.height;
|
||||
this.hotCorner.actor.allocate(hotBox, flags);
|
||||
},
|
||||
|
||||
handleDragOver: function(source, actor, x, y, time) {
|
||||
@ -661,14 +708,14 @@ const ActivitiesButton = new Lang.Class({
|
||||
if (this._xdndTimeOut != 0)
|
||||
Mainloop.source_remove(this._xdndTimeOut);
|
||||
this._xdndTimeOut = Mainloop.timeout_add(BUTTON_DND_ACTIVATION_TIMEOUT,
|
||||
Lang.bind(this, this._xdndToggleOverview, actor));
|
||||
Lang.bind(this, this._xdndShowOverview, actor));
|
||||
|
||||
return DND.DragMotionResult.CONTINUE;
|
||||
},
|
||||
|
||||
_onCapturedEvent: function(actor, event) {
|
||||
if (event.type() == Clutter.EventType.BUTTON_PRESS) {
|
||||
if (!Main.overview.shouldToggleByCornerOrButton())
|
||||
if (!this.hotCorner.shouldToggleOverviewOnClick())
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
@ -685,12 +732,15 @@ const ActivitiesButton = new Lang.Class({
|
||||
}
|
||||
},
|
||||
|
||||
_xdndToggleOverview: function(actor) {
|
||||
_xdndShowOverview: function(actor) {
|
||||
let [x, y, mask] = global.get_pointer();
|
||||
let pickedActor = global.stage.get_actor_at_pos(Clutter.PickMode.REACTIVE, x, y);
|
||||
|
||||
if (pickedActor == this.actor && Main.overview.shouldToggleByCornerOrButton())
|
||||
Main.overview.toggle();
|
||||
if (pickedActor == this.actor) {
|
||||
if (!Main.overview.visible && !Main.overview.animationInProgress) {
|
||||
Main.overview.showTemporarily();
|
||||
}
|
||||
}
|
||||
|
||||
Mainloop.source_remove(this._xdndTimeOut);
|
||||
this._xdndTimeOut = 0;
|
||||
|
@ -2086,7 +2086,7 @@ const PopupMenuManager = new Lang.Class({
|
||||
},
|
||||
|
||||
removeMenu: function(menu) {
|
||||
if (menu == this.activeMenu)
|
||||
if (menu == this._activeMenu)
|
||||
this._closeMenu(menu);
|
||||
|
||||
let position = this._findMenu(menu);
|
||||
@ -2110,9 +2110,9 @@ const PopupMenuManager = new Lang.Class({
|
||||
},
|
||||
|
||||
get activeMenu() {
|
||||
let firstGrab = this._grabHelper.grabStack[0];
|
||||
if (firstGrab)
|
||||
return firstGrab.actor._delegate;
|
||||
let actor = this._grabHelper.currentGrab.actor;
|
||||
if (actor)
|
||||
return actor._delegate;
|
||||
else
|
||||
return null;
|
||||
},
|
||||
|
@ -127,6 +127,8 @@ function remoteProvidersLoaded(loadState) {
|
||||
// Special case gnome-control-center to be always active and always first
|
||||
sortOrder.unshift('gnome-control-center.desktop');
|
||||
|
||||
let numSorted = sortOrder.length;
|
||||
|
||||
loadState.loadedProviders.sort(
|
||||
function(providerA, providerB) {
|
||||
let idxA, idxB;
|
||||
@ -146,6 +148,15 @@ function remoteProvidersLoaded(loadState) {
|
||||
return GLib.utf8_collate(nameA, nameB);
|
||||
}
|
||||
|
||||
if (numSorted > 1) {
|
||||
// if providerA is the last, it goes after everything
|
||||
if ((idxA + 1) == numSorted)
|
||||
return 1;
|
||||
// if providerB is the last, it goes after everything
|
||||
else if ((idxB + 1) == numSorted)
|
||||
return -1;
|
||||
}
|
||||
|
||||
// if providerA isn't found, it's sorted after providerB
|
||||
if (idxA == -1)
|
||||
return 1;
|
||||
|
@ -30,6 +30,138 @@ const EXEC_ARG_KEY = 'exec-arg';
|
||||
|
||||
const DIALOG_GROW_TIME = 0.1;
|
||||
|
||||
const CommandCompleter = new Lang.Class({
|
||||
Name: 'CommandCompleter',
|
||||
|
||||
_init : function() {
|
||||
this._changedCount = 0;
|
||||
this._paths = GLib.getenv('PATH').split(':');
|
||||
this._paths.push(GLib.get_home_dir());
|
||||
this._valid = false;
|
||||
this._updateInProgress = false;
|
||||
this._childs = new Array(this._paths.length);
|
||||
this._monitors = new Array(this._paths.length);
|
||||
for (let i = 0; i < this._paths.length; i++) {
|
||||
this._childs[i] = [];
|
||||
let file = Gio.file_new_for_path(this._paths[i]);
|
||||
let info;
|
||||
try {
|
||||
info = file.query_info(Gio.FILE_ATTRIBUTE_STANDARD_TYPE, Gio.FileQueryInfoFlags.NONE, null);
|
||||
} catch (e) {
|
||||
// FIXME catchall
|
||||
this._paths[i] = null;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (info.get_attribute_uint32(Gio.FILE_ATTRIBUTE_STANDARD_TYPE) != Gio.FileType.DIRECTORY)
|
||||
continue;
|
||||
|
||||
this._paths[i] = file.get_path();
|
||||
this._monitors[i] = file.monitor_directory(Gio.FileMonitorFlags.NONE, null);
|
||||
if (this._monitors[i] != null) {
|
||||
this._monitors[i].connect('changed', Lang.bind(this, this._onChanged));
|
||||
}
|
||||
}
|
||||
this._paths = this._paths.filter(function(a) {
|
||||
return a != null;
|
||||
});
|
||||
this._update(0);
|
||||
},
|
||||
|
||||
update : function() {
|
||||
if (this._valid)
|
||||
return;
|
||||
this._update(0);
|
||||
},
|
||||
|
||||
_update : function(i) {
|
||||
if (i == 0 && this._updateInProgress)
|
||||
return;
|
||||
this._updateInProgress = true;
|
||||
this._changedCount = 0;
|
||||
this._i = i;
|
||||
if (i >= this._paths.length) {
|
||||
this._valid = true;
|
||||
this._updateInProgress = false;
|
||||
return;
|
||||
}
|
||||
let file = Gio.file_new_for_path(this._paths[i]);
|
||||
this._childs[this._i] = [];
|
||||
FileUtils.listDirAsync(file, Lang.bind(this, function (files) {
|
||||
for (let i = 0; i < files.length; i++) {
|
||||
this._childs[this._i].push(files[i].get_name());
|
||||
}
|
||||
this._update(this._i + 1);
|
||||
}));
|
||||
},
|
||||
|
||||
_onChanged : function(m, f, of, type) {
|
||||
if (!this._valid)
|
||||
return;
|
||||
let path = f.get_parent().get_path();
|
||||
let k = undefined;
|
||||
for (let i = 0; i < this._paths.length; i++) {
|
||||
if (this._paths[i] == path)
|
||||
k = i;
|
||||
}
|
||||
if (k === undefined) {
|
||||
return;
|
||||
}
|
||||
if (type == Gio.FileMonitorEvent.CREATED) {
|
||||
this._childs[k].push(f.get_basename());
|
||||
}
|
||||
if (type == Gio.FileMonitorEvent.DELETED) {
|
||||
this._changedCount++;
|
||||
if (this._changedCount > MAX_FILE_DELETED_BEFORE_INVALID) {
|
||||
this._valid = false;
|
||||
}
|
||||
let name = f.get_basename();
|
||||
this._childs[k] = this._childs[k].filter(function(e) {
|
||||
return e != name;
|
||||
});
|
||||
}
|
||||
if (type == Gio.FileMonitorEvent.UNMOUNTED) {
|
||||
this._childs[k] = [];
|
||||
}
|
||||
},
|
||||
|
||||
getCompletion: function(text) {
|
||||
let common = '';
|
||||
let notInit = true;
|
||||
if (!this._valid) {
|
||||
this._update(0);
|
||||
return common;
|
||||
}
|
||||
function _getCommon(s1, s2) {
|
||||
let k = 0;
|
||||
for (; k < s1.length && k < s2.length; k++) {
|
||||
if (s1[k] != s2[k])
|
||||
break;
|
||||
}
|
||||
if (k == 0)
|
||||
return '';
|
||||
return s1.substr(0, k);
|
||||
}
|
||||
function _hasPrefix(s1, prefix) {
|
||||
return s1.indexOf(prefix) == 0;
|
||||
}
|
||||
for (let i = 0; i < this._childs.length; i++) {
|
||||
for (let k = 0; k < this._childs[i].length; k++) {
|
||||
if (!_hasPrefix(this._childs[i][k], text))
|
||||
continue;
|
||||
if (notInit) {
|
||||
common = this._childs[i][k];
|
||||
notInit = false;
|
||||
}
|
||||
common = _getCommon(common, this._childs[i][k]);
|
||||
}
|
||||
}
|
||||
if (common.length)
|
||||
return common.substr(text.length);
|
||||
return common;
|
||||
}
|
||||
});
|
||||
|
||||
const RunDialog = new Lang.Class({
|
||||
Name: 'RunDialog',
|
||||
Extends: ModalDialog.ModalDialog,
|
||||
@ -110,6 +242,8 @@ const RunDialog = new Lang.Class({
|
||||
key: Clutter.Escape }]);
|
||||
|
||||
this._pathCompleter = new Gio.FilenameCompleter();
|
||||
this._commandCompleter = new CommandCompleter();
|
||||
this._group.connect('notify::visible', Lang.bind(this._commandCompleter, this._commandCompleter.update));
|
||||
|
||||
this._history = new History.HistoryManager({ gsettingsKey: HISTORY_KEY,
|
||||
entry: this._entryText });
|
||||
@ -125,6 +259,18 @@ const RunDialog = new Lang.Class({
|
||||
|
||||
return true;
|
||||
}
|
||||
if (symbol == Clutter.slash) {
|
||||
// Need preload data before get completion. GFilenameCompleter load content of parent directory.
|
||||
// Parent directory for /usr/include/ is /usr/. So need to add fake name('a').
|
||||
let text = o.get_text().concat('/a');
|
||||
let prefix;
|
||||
if (text.lastIndexOf(' ') == -1)
|
||||
prefix = text;
|
||||
else
|
||||
prefix = text.substr(text.lastIndexOf(' ') + 1);
|
||||
this._getCompletion(prefix);
|
||||
return false;
|
||||
}
|
||||
if (symbol == Clutter.Tab) {
|
||||
let text = o.get_text();
|
||||
let prefix;
|
||||
@ -136,6 +282,8 @@ const RunDialog = new Lang.Class({
|
||||
if (postfix != null && postfix.length > 0) {
|
||||
o.insert_text(postfix, -1);
|
||||
o.set_cursor_position(text.length + postfix.length);
|
||||
if (postfix[postfix.length - 1] == '/')
|
||||
this._getCompletion(text + postfix + 'a');
|
||||
}
|
||||
return true;
|
||||
}
|
||||
@ -143,53 +291,11 @@ const RunDialog = new Lang.Class({
|
||||
}));
|
||||
},
|
||||
|
||||
_getCommandCompletion: function(text) {
|
||||
function _getCommon(s1, s2) {
|
||||
if (s1 == null)
|
||||
return s2;
|
||||
|
||||
let k = 0;
|
||||
for (; k < s1.length && k < s2.length; k++) {
|
||||
if (s1[k] != s2[k])
|
||||
break;
|
||||
}
|
||||
if (k == 0)
|
||||
return '';
|
||||
return s1.substr(0, k);
|
||||
}
|
||||
|
||||
let paths = GLib.getenv('PATH').split(':');
|
||||
paths.push(GLib.get_home_dir());
|
||||
let someResults = paths.map(function(path) {
|
||||
let results = [];
|
||||
try {
|
||||
let file = Gio.File.new_for_path(path);
|
||||
let fileEnum = file.enumerate_children('standard::name', Gio.FileQueryInfoFlags.NONE, null);
|
||||
let info;
|
||||
while ((info = fileEnum.next_file(null))) {
|
||||
let name = info.get_name();
|
||||
if (name.slice(0, text.length) == text)
|
||||
results.push(name);
|
||||
}
|
||||
} catch (e if (!e.matches(Gio.IOErrorEnum, Gio.IOErrorEnum.NOT_FOUND) &&
|
||||
!e.matches(Gio.IOErrorEnum, Gio.IOErrorEnum.NOT_DIRECTORY))) {
|
||||
log(e);
|
||||
} finally {
|
||||
return results;
|
||||
}
|
||||
});
|
||||
let results = someResults.reduce(function(a, b) {
|
||||
return a.concat(b);
|
||||
}, []);
|
||||
let common = results.reduce(_getCommon, null);
|
||||
return common.substr(text.length);
|
||||
},
|
||||
|
||||
_getCompletion : function(text) {
|
||||
if (text.indexOf('/') != -1) {
|
||||
return this._pathCompleter.get_completion_suffix(text);
|
||||
} else {
|
||||
return this._getCommandCompletion(text);
|
||||
return this._commandCompleter.getCompletion(text);
|
||||
}
|
||||
},
|
||||
|
||||
|
@ -38,7 +38,11 @@ const ARROW_DRAG_THRESHOLD = 0.1;
|
||||
const N_ARROWS = 3;
|
||||
const ARROW_ANIMATION_TIME = 0.6;
|
||||
const ARROW_ANIMATION_PEAK_OPACITY = 0.4;
|
||||
const ARROW_IDLE_TIME = 30000; // ms
|
||||
|
||||
// The distance in px that the lock screen will move to when pressing
|
||||
// a key that has no effect in the lock screen (bumping it)
|
||||
const BUMP_SIZE = 25;
|
||||
const BUMP_TIME = 0.3;
|
||||
|
||||
const SUMMARY_ICON_SIZE = 48;
|
||||
|
||||
@ -50,7 +54,7 @@ const SUMMARY_ICON_SIZE = 48;
|
||||
// - CURTAIN_SLIDE_TIME is used when raising the shield before unlocking
|
||||
// - INITIAL_FADE_IN_TIME is used for the initial fade in at startup
|
||||
const STANDARD_FADE_TIME = 10;
|
||||
const MANUAL_FADE_TIME = 0.3;
|
||||
const MANUAL_FADE_TIME = 0.8;
|
||||
const BACKGROUND_FADE_TIME = 1.0;
|
||||
const CURTAIN_SLIDE_TIME = 0.3;
|
||||
const INITIAL_FADE_IN_TIME = 0.25;
|
||||
@ -431,8 +435,8 @@ const ScreenShield = new Lang.Class({
|
||||
name: 'lockScreenGroup',
|
||||
visible: false,
|
||||
});
|
||||
this._lockScreenGroup.connect('key-press-event',
|
||||
Lang.bind(this, this._onLockScreenKeyPress));
|
||||
this._lockScreenGroup.connect('key-release-event',
|
||||
Lang.bind(this, this._onLockScreenKeyRelease));
|
||||
this._lockScreenGroup.connect('scroll-event',
|
||||
Lang.bind(this, this._onLockScreenScroll));
|
||||
Main.ctrlAltTabManager.addGroup(this._lockScreenGroup, _("Lock"), 'changes-prevent-symbolic');
|
||||
@ -452,9 +456,6 @@ const ScreenShield = new Lang.Class({
|
||||
this._updateBackgrounds();
|
||||
Main.layoutManager.connect('monitors-changed', Lang.bind(this, this._updateBackgrounds));
|
||||
|
||||
this._arrowAnimationId = 0;
|
||||
this._arrowWatchId = 0;
|
||||
this._arrowActiveWatchId = 0;
|
||||
this._arrowContainer = new St.BoxLayout({ style_class: 'screen-shield-arrows',
|
||||
vertical: true,
|
||||
x_align: Clutter.ActorAlign.CENTER,
|
||||
@ -506,18 +507,14 @@ const ScreenShield = new Lang.Class({
|
||||
this._screenSaverDBus = new ShellDBus.ScreenSaverDBus(this);
|
||||
|
||||
this._inhibitor = null;
|
||||
this._aboutToSuspend = false;
|
||||
this._loginManager = LoginManager.getLoginManager();
|
||||
this._loginManager.connect('prepare-for-sleep',
|
||||
Lang.bind(this, this._prepareForSleep));
|
||||
this._inhibitSuspend();
|
||||
|
||||
this._loginManager.getCurrentSessionProxy(Lang.bind(this,
|
||||
function(sessionProxy) {
|
||||
this._loginSession = sessionProxy;
|
||||
this._loginSession.connectSignal('Lock', Lang.bind(this, function() { this.lock(false); }));
|
||||
this._loginSession.connectSignal('Unlock', Lang.bind(this, function() { this.deactivate(false); }));
|
||||
}));
|
||||
this._loginSession = this._loginManager.getCurrentSessionProxy();
|
||||
this._loginSession.connectSignal('Lock', Lang.bind(this, function() { this.lock(false); }));
|
||||
this._loginSession.connectSignal('Unlock', Lang.bind(this, function() { this.deactivate(false); }));
|
||||
|
||||
this._settings = new Gio.Settings({ schema: SCREENSAVER_SCHEMA });
|
||||
|
||||
@ -550,7 +547,9 @@ const ScreenShield = new Lang.Class({
|
||||
|
||||
let bgManager = new Background.BackgroundManager({ container: widget,
|
||||
monitorIndex: monitorIndex,
|
||||
effects: Meta.BackgroundEffects.BLUR | Meta.BackgroundEffects.DESATURATE,
|
||||
controlPosition: false });
|
||||
bgManager.background.saturation = 0.6;
|
||||
|
||||
this._bgManagers.push(bgManager);
|
||||
|
||||
@ -591,28 +590,28 @@ const ScreenShield = new Lang.Class({
|
||||
return this._isModal;
|
||||
},
|
||||
|
||||
_onLockScreenKeyPress: function(actor, event) {
|
||||
_onLockScreenKeyRelease: function(actor, event) {
|
||||
let symbol = event.get_key_symbol();
|
||||
let unichar = event.get_key_unicode();
|
||||
|
||||
// Do nothing if the lock screen is not fully shown.
|
||||
// This avoids reusing the previous (and stale) unlock
|
||||
// dialog if esc is pressed while the curtain is going
|
||||
// down after cancel.
|
||||
// Similarly, don't bump if the lock screen is not showing or is
|
||||
// animating, as the bump overrides the animation and would
|
||||
// remove any onComplete handler.
|
||||
|
||||
if (this._lockScreenState != MessageTray.State.SHOWN)
|
||||
return false;
|
||||
|
||||
let isEnter = (symbol == Clutter.KEY_Return || symbol == Clutter.KEY_KP_Enter);
|
||||
if (!isEnter && !(GLib.unichar_isprint(unichar) || symbol == Clutter.KEY_Escape))
|
||||
return false;
|
||||
if (symbol == Clutter.KEY_Escape ||
|
||||
symbol == Clutter.KEY_Return ||
|
||||
symbol == Clutter.KEY_KP_Enter) {
|
||||
this._liftShield(false, 0);
|
||||
return true;
|
||||
}
|
||||
|
||||
this._ensureUnlockDialog(true, true);
|
||||
|
||||
if (GLib.unichar_isgraph(unichar))
|
||||
this._dialog.addCharacter(unichar);
|
||||
|
||||
this._liftShield(true, 0);
|
||||
this._bumpLockScreen();
|
||||
return true;
|
||||
},
|
||||
|
||||
@ -650,8 +649,6 @@ const ScreenShield = new Lang.Class({
|
||||
},
|
||||
|
||||
_prepareForSleep: function(loginManager, aboutToSuspend) {
|
||||
this._aboutToSuspend = aboutToSuspend;
|
||||
|
||||
if (aboutToSuspend) {
|
||||
if (!this._settings.get_boolean(LOCK_ENABLED_KEY)) {
|
||||
this._uninhibitSuspend();
|
||||
@ -852,6 +849,21 @@ const ScreenShield = new Lang.Class({
|
||||
this._hideLockScreen(false, 0);
|
||||
},
|
||||
|
||||
_bumpLockScreen: function() {
|
||||
Tweener.removeTweens(this._lockScreenGroup);
|
||||
Tweener.addTween(this._lockScreenGroup,
|
||||
{ y: -BUMP_SIZE,
|
||||
time: BUMP_TIME / 2,
|
||||
transition: 'easeOutQuad',
|
||||
onComplete: function() {
|
||||
Tweener.addTween(this,
|
||||
{ y: 0,
|
||||
time: BUMP_TIME / 2,
|
||||
transition: 'easeInQuad' });
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
_hideLockScreenComplete: function() {
|
||||
if (Main.sessionMode.currentMode == 'lock-screen')
|
||||
Main.sessionMode.popMode('lock-screen');
|
||||
@ -905,12 +917,14 @@ const ScreenShield = new Lang.Class({
|
||||
|
||||
|
||||
let time = global.get_current_time();
|
||||
if (!this._dialog.open(time, onPrimary)) {
|
||||
// This is kind of an impossible error: we're already modal
|
||||
// by the time we reach this...
|
||||
log('Could not open login dialog: failed to acquire grab');
|
||||
this.deactivate(true);
|
||||
}
|
||||
this._dialog.connect('loaded', Lang.bind(this, function() {
|
||||
if (!this._dialog.open(time, onPrimary)) {
|
||||
// This is kind of an impossible error: we're already modal
|
||||
// by the time we reach this...
|
||||
log('Could not open login dialog: failed to acquire grab');
|
||||
this.deactivate(true);
|
||||
}
|
||||
}));
|
||||
|
||||
this._dialog.connect('failed', Lang.bind(this, this._onUnlockFailed));
|
||||
this._dialog.connect('unlocked', Lang.bind(this, this._onUnlockSucceded));
|
||||
@ -976,60 +990,16 @@ const ScreenShield = new Lang.Class({
|
||||
Main.sessionMode.pushMode('lock-screen');
|
||||
},
|
||||
|
||||
_startArrowAnimation: function() {
|
||||
this._arrowActiveWatchId = 0;
|
||||
|
||||
if (!this._arrowAnimationId) {
|
||||
this._arrowAnimationId = Mainloop.timeout_add(6000, Lang.bind(this, this._animateArrows));
|
||||
this._animateArrows();
|
||||
}
|
||||
|
||||
if (!this._arrowWatchId)
|
||||
this._arrowWatchId = this.idleMonitor.add_idle_watch(ARROW_IDLE_TIME,
|
||||
Lang.bind(this, this._pauseArrowAnimation));
|
||||
},
|
||||
|
||||
_pauseArrowAnimation: function() {
|
||||
if (this._arrowAnimationId) {
|
||||
Mainloop.source_remove(this._arrowAnimationId);
|
||||
this._arrowAnimationId = 0;
|
||||
}
|
||||
|
||||
if (!this._arrowActiveWatchId)
|
||||
this._arrowActiveWatchId = this.idleMonitor.add_user_active_watch(Lang.bind(this, this._startArrowAnimation));
|
||||
},
|
||||
|
||||
_stopArrowAnimation: function() {
|
||||
if (this._arrowAnimationId) {
|
||||
Mainloop.source_remove(this._arrowAnimationId);
|
||||
this._arrowAnimationId = 0;
|
||||
}
|
||||
if (this._arrowActiveWatchId) {
|
||||
this.idleMonitor.remove_watch(this._arrowActiveWatchId);
|
||||
this._arrowActiveWatchId = 0;
|
||||
}
|
||||
if (this._arrowWatchId) {
|
||||
this.idleMonitor.remove_watch(this._arrowWatchId);
|
||||
this._arrowWatchId = 0;
|
||||
}
|
||||
},
|
||||
|
||||
_checkArrowAnimation: function() {
|
||||
let idleTime = this.idleMonitor.get_idletime();
|
||||
|
||||
if (idleTime < ARROW_IDLE_TIME)
|
||||
this._startArrowAnimation();
|
||||
else
|
||||
this._pauseArrowAnimation();
|
||||
},
|
||||
|
||||
_lockScreenShown: function() {
|
||||
if (this._dialog && !this._isGreeter) {
|
||||
this._dialog.destroy();
|
||||
this._dialog = null;
|
||||
}
|
||||
|
||||
this._checkArrowAnimation();
|
||||
if (this._arrowAnimationId)
|
||||
Mainloop.source_remove(this._arrowAnimationId);
|
||||
this._arrowAnimationId = Mainloop.timeout_add(6000, Lang.bind(this, this._animateArrows));
|
||||
this._animateArrows();
|
||||
|
||||
let motionId = global.stage.connect('captured-event', function(stage, event) {
|
||||
if (event.type() == Clutter.EventType.MOTION) {
|
||||
@ -1051,8 +1021,7 @@ const ScreenShield = new Lang.Class({
|
||||
if (prevIsActive != this._isActive)
|
||||
this.emit('active-changed');
|
||||
|
||||
if (this._aboutToSuspend)
|
||||
this._uninhibitSuspend();
|
||||
this._uninhibitSuspend();
|
||||
|
||||
this.emit('lock-screen-shown');
|
||||
},
|
||||
@ -1092,10 +1061,13 @@ const ScreenShield = new Lang.Class({
|
||||
this._notificationsBox = null;
|
||||
}
|
||||
|
||||
this._stopArrowAnimation();
|
||||
|
||||
this._lockScreenContentsBox.destroy();
|
||||
|
||||
if (this._arrowAnimationId) {
|
||||
Mainloop.source_remove(this._arrowAnimationId);
|
||||
this._arrowAnimationId = 0;
|
||||
}
|
||||
|
||||
this._hasLockScreen = false;
|
||||
},
|
||||
|
||||
@ -1206,3 +1178,62 @@ const ScreenShield = new Lang.Class({
|
||||
},
|
||||
});
|
||||
Signals.addSignalMethods(ScreenShield.prototype);
|
||||
|
||||
/* Fallback code to handle session locking using gnome-screensaver,
|
||||
in case the required GDM dependency is not there
|
||||
*/
|
||||
const ScreenShieldFallback = new Lang.Class({
|
||||
Name: 'ScreenShieldFallback',
|
||||
|
||||
_init: function() {
|
||||
Util.spawn(['gnome-screensaver']);
|
||||
|
||||
this._proxy = new Gio.DBusProxy({ g_connection: Gio.DBus.session,
|
||||
g_name: 'org.gnome.ScreenSaver',
|
||||
g_object_path: '/org/gnome/ScreenSaver',
|
||||
g_interface_name: 'org.gnome.ScreenSaver',
|
||||
g_flags: (Gio.DBusProxyFlags.DO_NOT_AUTO_START |
|
||||
Gio.DBusProxyFlags.DO_NOT_LOAD_PROPERTIES),
|
||||
});
|
||||
this._proxy.init(null);
|
||||
|
||||
this._proxy.connect('g-signal', Lang.bind(this, this._onSignal));
|
||||
this._proxy.connect('notify::g-name-owner', Lang.bind(this, this._onNameOwnerChanged));
|
||||
},
|
||||
|
||||
_onNameOwnerChanged: function(object, pspec) {
|
||||
if (this._proxy.g_name_owner)
|
||||
[this._locked] = this._proxy.call_sync('GetActive', null,
|
||||
Gio.DBusCallFlags.NONE, -1, null).deep_unpack();
|
||||
else
|
||||
this._locked = false;
|
||||
|
||||
this.emit('active-changed', this._locked);
|
||||
},
|
||||
|
||||
_onSignal: function(proxy, senderName, signalName, params) {
|
||||
if (signalName == 'ActiveChanged') {
|
||||
[this._locked] = params.deep_unpack();
|
||||
this.emit('active-changed', this._locked);
|
||||
}
|
||||
},
|
||||
|
||||
get locked() {
|
||||
return this._locked;
|
||||
},
|
||||
|
||||
lock: function() {
|
||||
this._proxy.call('Lock', null, Gio.DBusCallFlags.NONE, -1, null,
|
||||
Lang.bind(this, function(proxy, result) {
|
||||
proxy.call_finish(result);
|
||||
|
||||
this.emit('lock-screen-shown');
|
||||
}));
|
||||
},
|
||||
|
||||
unlock: function() {
|
||||
this._proxy.call('SetActive', GLib.Variant.new('(b)', false),
|
||||
Gio.DBusCallFlags.NONE, -1, null, null);
|
||||
},
|
||||
});
|
||||
Signals.addSignalMethods(ScreenShieldFallback.prototype);
|
||||
|
@ -4,7 +4,6 @@ const Clutter = imports.gi.Clutter;
|
||||
const Lang = imports.lang;
|
||||
const Gtk = imports.gi.Gtk;
|
||||
const Meta = imports.gi.Meta;
|
||||
const Signals = imports.signals;
|
||||
const St = imports.gi.St;
|
||||
const Atk = imports.gi.Atk;
|
||||
|
||||
@ -14,7 +13,6 @@ const Main = imports.ui.main;
|
||||
const Overview = imports.ui.overview;
|
||||
const Separator = imports.ui.separator;
|
||||
const Search = imports.ui.search;
|
||||
const Util = imports.misc.util;
|
||||
|
||||
const MAX_LIST_SEARCH_RESULTS_ROWS = 3;
|
||||
const MAX_GRID_SEARCH_RESULTS_ROWS = 1;
|
||||
@ -104,7 +102,6 @@ const ListSearchResult = new Lang.Class({
|
||||
y_fill: false,
|
||||
x_align: St.Align.START,
|
||||
y_align: St.Align.START });
|
||||
this.actor.label_actor = title;
|
||||
|
||||
if (this.metaInfo['description']) {
|
||||
let description = new St.Label({ style_class: 'list-search-result-description' });
|
||||
@ -142,7 +139,6 @@ const GridSearchResult = new Lang.Class({
|
||||
}
|
||||
|
||||
this.actor.set_child(content);
|
||||
this.actor.label_actor = content.label_actor;
|
||||
|
||||
let draggable = DND.makeDraggable(this.actor);
|
||||
draggable.connect('drag-begin',
|
||||
@ -231,14 +227,9 @@ const ListSearchResults = new Lang.Class({
|
||||
this._pendingClear = true;
|
||||
},
|
||||
|
||||
_keyFocusIn: function(icon) {
|
||||
this.emit('key-focus-in', icon);
|
||||
},
|
||||
|
||||
renderResults: function(metas) {
|
||||
for (let i = 0; i < metas.length; i++) {
|
||||
let display = new ListSearchResult(this.provider, metas[i], this._terms);
|
||||
display.actor.connect('key-focus-in', Lang.bind(this, this._keyFocusIn));
|
||||
this._content.add_actor(display.actor);
|
||||
}
|
||||
},
|
||||
@ -255,7 +246,6 @@ const ListSearchResults = new Lang.Class({
|
||||
return null;
|
||||
}
|
||||
});
|
||||
Signals.addSignalMethods(ListSearchResults.prototype);
|
||||
|
||||
const GridSearchResults = new Lang.Class({
|
||||
Name: 'GridSearchResults',
|
||||
@ -298,14 +288,9 @@ const GridSearchResults = new Lang.Class({
|
||||
this._pendingClear = true;
|
||||
},
|
||||
|
||||
_keyFocusIn: function(icon) {
|
||||
this.emit('key-focus-in', icon);
|
||||
},
|
||||
|
||||
renderResults: function(metas) {
|
||||
for (let i = 0; i < metas.length; i++) {
|
||||
let display = new GridSearchResult(this.provider, metas[i], this._terms);
|
||||
display.actor.connect('key-focus-in', Lang.bind(this, this._keyFocusIn));
|
||||
this._grid.addItem(display.actor);
|
||||
}
|
||||
},
|
||||
@ -322,7 +307,6 @@ const GridSearchResults = new Lang.Class({
|
||||
return null;
|
||||
}
|
||||
});
|
||||
Signals.addSignalMethods(GridSearchResults.prototype);
|
||||
|
||||
const SearchResults = new Lang.Class({
|
||||
Name: 'SearchResults',
|
||||
@ -382,10 +366,6 @@ const SearchResults = new Lang.Class({
|
||||
return false;
|
||||
},
|
||||
|
||||
_keyFocusIn: function(provider, icon) {
|
||||
Util.ensureActorVisibleInScrollView(this._scrollView, icon);
|
||||
},
|
||||
|
||||
createProviderMeta: function(provider) {
|
||||
let providerBox = new St.BoxLayout({ style_class: 'search-section',
|
||||
vertical: true });
|
||||
@ -399,8 +379,6 @@ const SearchResults = new Lang.Class({
|
||||
resultDisplay = new GridSearchResults(provider);
|
||||
}
|
||||
|
||||
resultDisplay.connect('key-focus-in', Lang.bind(this, this._keyFocusIn));
|
||||
|
||||
let resultDisplayBin = new St.Bin({ child: resultDisplay.actor,
|
||||
x_fill: true,
|
||||
y_fill: true });
|
||||
@ -579,7 +557,6 @@ const ProviderIcon = new Lang.Class({
|
||||
this.parent({ style_class: 'search-provider-icon',
|
||||
reactive: true,
|
||||
can_focus: true,
|
||||
accessible_name: provider.appInfo.get_name(),
|
||||
track_hover: true });
|
||||
|
||||
this._content = new St.Widget({ layout_manager: new Clutter.BinLayout() });
|
||||
|
@ -79,13 +79,12 @@ const _modes = {
|
||||
},
|
||||
|
||||
'initial-setup': {
|
||||
hasWindows: true,
|
||||
isPrimary: true,
|
||||
components: ['keyring'],
|
||||
panel: {
|
||||
left: [],
|
||||
center: ['dateMenu'],
|
||||
right: ['a11yGreeter', 'keyboard', 'volume', 'battery']
|
||||
right: ['a11yGreeter', 'keyboard', 'volume']
|
||||
}
|
||||
},
|
||||
|
||||
@ -159,7 +158,12 @@ function listModes() {
|
||||
const SessionMode = new Lang.Class({
|
||||
Name: 'SessionMode',
|
||||
|
||||
init: function() {
|
||||
_init: function() {
|
||||
global.connect('notify::session-mode', Lang.bind(this, this._sync));
|
||||
this._modes = _modes;
|
||||
this._modeStack = [DEFAULT_MODE];
|
||||
this._sync();
|
||||
|
||||
_getModes(Lang.bind(this, function(modes) {
|
||||
this._modes = modes;
|
||||
let primary = modes[global.session_mode] &&
|
||||
@ -167,8 +171,6 @@ const SessionMode = new Lang.Class({
|
||||
let mode = primary ? global.session_mode : 'user';
|
||||
this._modeStack = [mode];
|
||||
this._sync();
|
||||
|
||||
this.emit('sessions-loaded');
|
||||
}));
|
||||
},
|
||||
|
||||
|
@ -397,7 +397,7 @@ const ScreenSaverDBus = new Lang.Class({
|
||||
if (active)
|
||||
this._screenShield.activate(true);
|
||||
else
|
||||
this._screenShield.deactivate(false);
|
||||
this._screenShield.unlock(false);
|
||||
},
|
||||
|
||||
GetActive: function() {
|
||||
|
@ -171,10 +171,4 @@ function addContextMenu(entry, params) {
|
||||
entry.connect('button-press-event', Lang.bind(null, _onButtonPressEvent, entry));
|
||||
|
||||
entry.connect('popup-menu', Lang.bind(null, _onPopup, entry));
|
||||
|
||||
entry.connect('destroy', function() {
|
||||
entry.menu.destroy();
|
||||
entry.menu = null;
|
||||
entry._menuManager = null;
|
||||
});
|
||||
}
|
||||
|
@ -33,36 +33,6 @@ const KEY_INPUT_SOURCES = 'sources';
|
||||
const INPUT_SOURCE_TYPE_XKB = 'xkb';
|
||||
const INPUT_SOURCE_TYPE_IBUS = 'ibus';
|
||||
|
||||
// This is longest we'll keep the keyboard frozen until an input
|
||||
// source is active.
|
||||
const MAX_INPUT_SOURCE_ACTIVATION_TIME = 2000; // ms
|
||||
|
||||
const BUS_NAME = 'org.gnome.SettingsDaemon.Keyboard';
|
||||
const OBJECT_PATH = '/org/gnome/SettingsDaemon/Keyboard';
|
||||
|
||||
const KeyboardManagerInterface =
|
||||
<interface name="org.gnome.SettingsDaemon.Keyboard">
|
||||
<method name="SetInputSource">
|
||||
<arg type="u" direction="in" />
|
||||
</method>
|
||||
</interface>;
|
||||
|
||||
const KeyboardManagerProxy = Gio.DBusProxy.makeProxyWrapper(KeyboardManagerInterface);
|
||||
|
||||
function releaseKeyboard() {
|
||||
if (Main.modalCount > 0)
|
||||
global.display.unfreeze_keyboard(global.get_current_time());
|
||||
else
|
||||
global.display.ungrab_keyboard(global.get_current_time());
|
||||
}
|
||||
|
||||
function holdKeyboard() {
|
||||
if (Main.modalCount > 0)
|
||||
global.display.freeze_keyboard(global.get_current_time());
|
||||
else
|
||||
global.display.grab_keyboard(global.get_current_time());
|
||||
}
|
||||
|
||||
const IBusManager = new Lang.Class({
|
||||
Name: 'IBusManager',
|
||||
|
||||
@ -260,7 +230,6 @@ const InputSource = new Lang.Class({
|
||||
},
|
||||
|
||||
activate: function() {
|
||||
holdKeyboard();
|
||||
this.emit('activate');
|
||||
},
|
||||
});
|
||||
@ -293,11 +262,11 @@ const InputSourcePopup = new Lang.Class({
|
||||
this._select(this._selectedIndex);
|
||||
},
|
||||
|
||||
_keyPressHandler: function(keysym, _ignored, action) {
|
||||
_keyPressHandler: function(keysym, backwards, action) {
|
||||
if (action == this._action)
|
||||
this._select(this._next());
|
||||
this._select(backwards ? this._previous() : this._next());
|
||||
else if (action == this._actionBackward)
|
||||
this._select(this._previous());
|
||||
this._select(backwards ? this._next() : this._previous());
|
||||
else if (keysym == Clutter.Left)
|
||||
this._select(this._previous());
|
||||
else if (keysym == Clutter.Right)
|
||||
@ -367,13 +336,14 @@ const InputSourceIndicator = new Lang.Class({
|
||||
this._keybindingAction =
|
||||
Main.wm.addKeybinding('switch-input-source',
|
||||
new Gio.Settings({ schema: "org.gnome.desktop.wm.keybindings" }),
|
||||
Meta.KeyBindingFlags.NONE,
|
||||
Meta.KeyBindingFlags.REVERSES,
|
||||
Shell.KeyBindingMode.ALL,
|
||||
Lang.bind(this, this._switchInputSource));
|
||||
this._keybindingActionBackward =
|
||||
Main.wm.addKeybinding('switch-input-source-backward',
|
||||
new Gio.Settings({ schema: "org.gnome.desktop.wm.keybindings" }),
|
||||
Meta.KeyBindingFlags.NONE,
|
||||
Meta.KeyBindingFlags.REVERSES |
|
||||
Meta.KeyBindingFlags.REVERSED,
|
||||
Shell.KeyBindingMode.ALL,
|
||||
Lang.bind(this, this._switchInputSource));
|
||||
this._settings = new Gio.Settings({ schema: DESKTOP_INPUT_SOURCES_SCHEMA });
|
||||
@ -394,13 +364,6 @@ const InputSourceIndicator = new Lang.Class({
|
||||
this._ibusManager.connect('property-updated', Lang.bind(this, this._ibusPropertyUpdated));
|
||||
this._inputSourcesChanged();
|
||||
|
||||
this._keyboardManager = new KeyboardManagerProxy(Gio.DBus.session, BUS_NAME, OBJECT_PATH,
|
||||
function(proxy, error) {
|
||||
if (error)
|
||||
log(error.message);
|
||||
});
|
||||
global.display.connect('modifiers-accelerator-activated', Lang.bind(this, this._modifiersSwitcher));
|
||||
|
||||
this.menu.addMenuItem(new PopupMenu.PopupSeparatorMenuItem());
|
||||
this._showLayoutItem = this.menu.addAction(_("Show Keyboard Layout"), Lang.bind(this, this._showLayout));
|
||||
|
||||
@ -434,44 +397,13 @@ const InputSourceIndicator = new Lang.Class({
|
||||
this._inputSourcesChanged();
|
||||
},
|
||||
|
||||
_modifiersSwitcher: function() {
|
||||
let sourceIndexes = Object.keys(this._inputSources);
|
||||
if (sourceIndexes.length == 0) {
|
||||
releaseKeyboard();
|
||||
return;
|
||||
}
|
||||
|
||||
let is = this._currentSource;
|
||||
if (!is)
|
||||
is = this._inputSources[sourceIndexes[0]];
|
||||
|
||||
let nextIndex = is.index + 1;
|
||||
if (nextIndex > sourceIndexes[sourceIndexes.length - 1])
|
||||
nextIndex = 0;
|
||||
|
||||
while (!(is = this._inputSources[nextIndex]))
|
||||
nextIndex += 1;
|
||||
|
||||
is.activate();
|
||||
},
|
||||
|
||||
_switchInputSource: function(display, screen, window, binding) {
|
||||
if (this._mruSources.length < 2)
|
||||
return;
|
||||
|
||||
// HACK: Fall back on simple input source switching since we
|
||||
// can't show a popup switcher while the message tray is up
|
||||
// without considerable work to consolidate the usage of
|
||||
// pushModal/popModal and grabHelper. See
|
||||
// https://bugzilla.gnome.org/show_bug.cgi?id=695143 .
|
||||
if (Main.keybindingMode == Shell.KeyBindingMode.MESSAGE_TRAY) {
|
||||
this._modifiersSwitcher();
|
||||
return;
|
||||
}
|
||||
|
||||
let popup = new InputSourcePopup(this._mruSources, this._keybindingAction, this._keybindingActionBackward);
|
||||
let modifiers = binding.get_modifiers();
|
||||
let backwards = false; // Not using this
|
||||
let backwards = modifiers & Meta.VirtualModifier.SHIFT_MASK;
|
||||
if (!popup.show(backwards, binding.get_name(), binding.get_mask()))
|
||||
popup.destroy();
|
||||
},
|
||||
@ -484,11 +416,6 @@ const InputSourceIndicator = new Lang.Class({
|
||||
let oldSource;
|
||||
[oldSource, this._currentSource] = [this._currentSource, newSource];
|
||||
|
||||
if (oldSource) {
|
||||
oldSource.menuItem.setShowDot(false);
|
||||
oldSource.indicatorLabel.hide();
|
||||
}
|
||||
|
||||
if (!newSource || (nVisibleSources < 2 && !newSource.properties)) {
|
||||
// This source index might be invalid if we weren't able
|
||||
// to build a menu item for it, so we hide ourselves since
|
||||
@ -503,6 +430,11 @@ const InputSourceIndicator = new Lang.Class({
|
||||
|
||||
this.actor.show();
|
||||
|
||||
if (oldSource) {
|
||||
oldSource.menuItem.setShowDot(false);
|
||||
oldSource.indicatorLabel.hide();
|
||||
}
|
||||
|
||||
newSource.menuItem.setShowDot(true);
|
||||
newSource.indicatorLabel.show();
|
||||
|
||||
@ -555,10 +487,10 @@ const InputSourceIndicator = new Lang.Class({
|
||||
let is = new InputSource(type, id, displayName, shortName, i);
|
||||
|
||||
is.connect('activate', Lang.bind(this, function() {
|
||||
let inVariant = new GLib.Variant('(u)', [is.index]);
|
||||
this._keyboardManager.call('SetInputSource', inVariant, 0,
|
||||
MAX_INPUT_SOURCE_ACTIVATION_TIME,
|
||||
null, releaseKeyboard);
|
||||
if (this._currentSource.index == is.index)
|
||||
return;
|
||||
this._settings.set_value(KEY_CURRENT_INPUT_SOURCE,
|
||||
GLib.Variant.new_uint32(is.index));
|
||||
}));
|
||||
|
||||
if (!(is.shortName in inputSourcesByShortName))
|
||||
@ -771,7 +703,7 @@ const InputSourceIndicator = new Lang.Class({
|
||||
item.prop = prop;
|
||||
item.connect('activate', Lang.bind(this, function() {
|
||||
this._ibusManager.activateProperty(item.prop.get_key(),
|
||||
item.prop.get_state());
|
||||
IBus.PropState.CHECKED);
|
||||
}));
|
||||
break;
|
||||
|
||||
|
@ -27,6 +27,35 @@ const LoginDialog = imports.gdm.loginDialog;
|
||||
// The timeout before going back automatically to the lock screen (in seconds)
|
||||
const IDLE_TIMEOUT = 2 * 60;
|
||||
|
||||
function versionCompare(required, reference) {
|
||||
required = required.split('.');
|
||||
reference = reference.split('.');
|
||||
|
||||
for (let i = 0; i < required.length; i++) {
|
||||
if (required[i] != reference[i])
|
||||
return required[i] < reference[i];
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
function isSupported() {
|
||||
try {
|
||||
let params = GLib.Variant.new('(ss)', ['org.gnome.DisplayManager.Manager', 'Version']);
|
||||
let result = Gio.DBus.system.call_sync('org.gnome.DisplayManager',
|
||||
'/org/gnome/DisplayManager/Manager',
|
||||
'org.freedesktop.DBus.Properties',
|
||||
'Get', params, null,
|
||||
Gio.DBusCallFlags.NONE,
|
||||
-1, null);
|
||||
|
||||
let version = result.deep_unpack()[0].deep_unpack();
|
||||
return versionCompare('3.5.91', version);
|
||||
} catch(e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
const UnlockDialog = new Lang.Class({
|
||||
Name: 'UnlockDialog',
|
||||
Extends: ModalDialog.ModalDialog,
|
||||
@ -47,7 +76,6 @@ const UnlockDialog = new Lang.Class({
|
||||
|
||||
this._greeterClient = new Gdm.Client();
|
||||
this._userVerifier = new GdmUtil.ShellUserVerifier(this._greeterClient, { reauthenticationOnly: true });
|
||||
this._userVerified = false;
|
||||
|
||||
this._userVerifier.connect('ask-question', Lang.bind(this, this._onAskQuestion));
|
||||
this._userVerifier.connect('show-message', Lang.bind(this, this._showMessage));
|
||||
@ -70,7 +98,6 @@ const UnlockDialog = new Lang.Class({
|
||||
|
||||
this._promptEntry = new St.Entry({ style_class: 'login-dialog-prompt-entry',
|
||||
can_focus: true });
|
||||
this._promptEntry.clutter_text.connect('activate', Lang.bind(this, this._doUnlock));
|
||||
this._promptEntry.clutter_text.set_password_char('\u25cf');
|
||||
ShellEntry.addContextMenu(this._promptEntry, { isPassword: true });
|
||||
this.setInitialKeyFocus(this._promptEntry);
|
||||
@ -142,6 +169,11 @@ const UnlockDialog = new Lang.Class({
|
||||
let batch = new Batch.Hold();
|
||||
this._userVerifier.begin(this._userName, batch);
|
||||
|
||||
GLib.idle_add(GLib.PRIORITY_DEFAULT, Lang.bind(this, function() {
|
||||
this.emit('loaded');
|
||||
return false;
|
||||
}));
|
||||
|
||||
Main.ctrlAltTabManager.addGroup(this.dialogLayout, _("Unlock Window"), 'dialog-password-symbolic');
|
||||
|
||||
this._idleMonitor = new GnomeDesktop.IdleMonitor();
|
||||
@ -250,35 +282,18 @@ const UnlockDialog = new Lang.Class({
|
||||
this._userVerifier.answerQuery(query, this._promptEntry.text);
|
||||
},
|
||||
|
||||
_finishUnlock: function() {
|
||||
_onVerificationComplete: function() {
|
||||
this._userVerifier.clear();
|
||||
this.emit('unlocked');
|
||||
},
|
||||
|
||||
_onVerificationComplete: function() {
|
||||
this._userVerified = true;
|
||||
if (!this._userVerifier.hasPendingMessages) {
|
||||
this._finishUnlock();
|
||||
} else {
|
||||
let signalId = this._userVerifier.connect('no-more-messages',
|
||||
Lang.bind(this, function() {
|
||||
this._userVerifier.disconnect(signalId);
|
||||
this._finishUnlock();
|
||||
}));
|
||||
}
|
||||
},
|
||||
|
||||
_onReset: function() {
|
||||
if (!this._userVerified) {
|
||||
this._userVerifier.clear();
|
||||
this.emit('failed');
|
||||
}
|
||||
this.emit('failed');
|
||||
},
|
||||
|
||||
_onVerificationFailed: function() {
|
||||
this._currentQuery = null;
|
||||
this._firstQuestion = true;
|
||||
this._userVerified = false;
|
||||
|
||||
this._promptEntry.text = '';
|
||||
this._promptEntry.clutter_text.set_password_char('\u25cf');
|
||||
@ -318,8 +333,4 @@ const UnlockDialog = new Lang.Class({
|
||||
|
||||
this.destroy();
|
||||
},
|
||||
|
||||
addCharacter: function(unichar) {
|
||||
this._promptEntry.clutter_text.insert_unichar(unichar);
|
||||
},
|
||||
});
|
||||
|
@ -600,8 +600,7 @@ const UserMenuButton = new Lang.Class({
|
||||
Lang.bind(this, this._updateHaveShutdown));
|
||||
|
||||
Main.sessionMode.connect('updated', Lang.bind(this, this._sessionUpdated));
|
||||
if (Main.screenShield)
|
||||
Main.screenShield.connect('locked-changed', Lang.bind(this, this._updatePresenceIcon));
|
||||
Main.screenShield.connect('locked-changed', Lang.bind(this, this._updatePresenceIcon));
|
||||
this._sessionUpdated();
|
||||
},
|
||||
|
||||
@ -657,7 +656,7 @@ const UserMenuButton = new Lang.Class({
|
||||
|
||||
_updateLockScreen: function() {
|
||||
let allowLockScreen = !this._lockdownSettings.get_boolean(DISABLE_LOCK_SCREEN_KEY);
|
||||
this._lockScreenItem.actor.visible = allowLockScreen && LoginManager.canLock();
|
||||
this._lockScreenItem.actor.visible = allowLockScreen;
|
||||
},
|
||||
|
||||
_updateInstallUpdates: function() {
|
||||
@ -865,8 +864,7 @@ const UserMenuButton = new Lang.Class({
|
||||
_onLoginScreenActivate: function() {
|
||||
this.menu.close(BoxPointer.PopupAnimation.NONE);
|
||||
Main.overview.hide();
|
||||
if (Main.screenShield)
|
||||
Main.screenShield.lock(false);
|
||||
Main.screenShield.lock(false);
|
||||
Gdm.goto_login_session_sync(null);
|
||||
},
|
||||
|
||||
@ -917,10 +915,8 @@ const UserMenuButton = new Lang.Class({
|
||||
session.user.get_real_name() : session.username;
|
||||
|
||||
if (session.info.remote)
|
||||
/* Translators: Remote here refers to a remote session, like a ssh login */
|
||||
userLabelText = _("%s (remote)").format(userName);
|
||||
else if (session.info.type == "tty")
|
||||
/* Translators: Console here refers to a tty like a VT console */
|
||||
userLabelText = _("%s (console)").format(userName);
|
||||
else
|
||||
userLabelText = userName;
|
||||
|
@ -11,14 +11,12 @@ const Layout = imports.ui.layout;
|
||||
const Main = imports.ui.main;
|
||||
const Panel = imports.ui.panel;
|
||||
|
||||
// we could make these gsettings
|
||||
const FISH_NAME = 'wanda';
|
||||
const FISH_FILENAME = 'wanda.png';
|
||||
const FISH_SPEED = 300;
|
||||
const FISH_COMMAND = 'fortune';
|
||||
// The size of an individual frame in the animation
|
||||
const FISH_HEIGHT = 22;
|
||||
const FISH_WIDTH = 36;
|
||||
|
||||
const GNOME_PANEL_PIXMAPDIR = '../gnome-panel/fish';
|
||||
const FISH_GROUP = 'Fish Animation';
|
||||
|
||||
const MAGIC_FISH_KEY = 'free the fish';
|
||||
@ -28,16 +26,33 @@ const WandaIcon = new Lang.Class({
|
||||
Extends: IconGrid.BaseIcon,
|
||||
|
||||
_init : function(fish, label, params) {
|
||||
this.parent(label, params);
|
||||
|
||||
this._fish = fish;
|
||||
this._imageFile = GLib.build_filenamev([global.datadir, fish + '.png']);
|
||||
let file = GLib.build_filenamev([global.datadir, GNOME_PANEL_PIXMAPDIR, fish + '.fish']);
|
||||
|
||||
this._imgHeight = FISH_HEIGHT;
|
||||
this._imgWidth = FISH_WIDTH;
|
||||
if (GLib.file_test(file, GLib.FileTest.EXISTS)) {
|
||||
this._keyfile = new GLib.KeyFile();
|
||||
this._keyfile.load_from_file(file, GLib.KeyFileFlags.NONE);
|
||||
|
||||
this._imageFile = GLib.build_filenamev([global.datadir, GNOME_PANEL_PIXMAPDIR,
|
||||
this._keyfile.get_string(FISH_GROUP, 'image')]);
|
||||
|
||||
let tmpPixbuf = GdkPixbuf.Pixbuf.new_from_file(this._imageFile);
|
||||
|
||||
this._imgHeight = tmpPixbuf.height;
|
||||
this._imgWidth = tmpPixbuf.width / this._keyfile.get_integer(FISH_GROUP, 'frames');
|
||||
} else {
|
||||
this._imageFile = null;
|
||||
}
|
||||
|
||||
this.parent(label, params);
|
||||
},
|
||||
|
||||
createIcon: function(iconSize) {
|
||||
if (!this._imageFile) {
|
||||
return new St.Icon({ icon_name: 'face-smile',
|
||||
icon_size: iconSize });
|
||||
}
|
||||
|
||||
this._animations = new Panel.Animation(this._imageFile, this._imgWidth, this._imgHeight, FISH_SPEED);
|
||||
this._animations.play();
|
||||
return this._animations.actor;
|
||||
|
@ -174,15 +174,6 @@ const WindowManager = new Lang.Class({
|
||||
Meta.KeyBindingFlags.NONE,
|
||||
Shell.KeyBindingMode.NORMAL,
|
||||
Lang.bind(this, this._openAppMenu));
|
||||
|
||||
Main.overview.connect('showing', Lang.bind(this, function() {
|
||||
for (let i = 0; i < this._dimmedWindows.length; i++)
|
||||
this._undimWindow(this._dimmedWindows[i]);
|
||||
}));
|
||||
Main.overview.connect('hiding', Lang.bind(this, function() {
|
||||
for (let i = 0; i < this._dimmedWindows.length; i++)
|
||||
this._dimWindow(this._dimmedWindows[i]);
|
||||
}));
|
||||
},
|
||||
|
||||
setCustomKeybindingHandler: function(name, modes, handler) {
|
||||
@ -342,15 +333,13 @@ const WindowManager = new Lang.Class({
|
||||
if (shouldDim && !window._dimmed) {
|
||||
window._dimmed = true;
|
||||
this._dimmedWindows.push(window);
|
||||
if (!Main.overview.visible)
|
||||
this._dimWindow(window);
|
||||
this._dimWindow(window);
|
||||
} else if (!shouldDim && window._dimmed) {
|
||||
window._dimmed = false;
|
||||
this._dimmedWindows = this._dimmedWindows.filter(function(win) {
|
||||
return win != window;
|
||||
});
|
||||
if (!Main.overview.visible)
|
||||
this._undimWindow(window);
|
||||
this._undimWindow(window);
|
||||
}
|
||||
},
|
||||
|
||||
|
@ -15,6 +15,7 @@ const Main = imports.ui.main;
|
||||
const Overview = imports.ui.overview;
|
||||
const Panel = imports.ui.panel;
|
||||
const Tweener = imports.ui.tweener;
|
||||
const WindowManager = imports.ui.windowManager;
|
||||
|
||||
const FOCUS_ANIMATION_TIME = 0.15;
|
||||
|
||||
@ -41,6 +42,68 @@ function _interpolate(start, end, step) {
|
||||
return start + (end - start) * step;
|
||||
}
|
||||
|
||||
const WindowCloneLayout = new Lang.Class({
|
||||
Name: 'WindowCloneLayout',
|
||||
Extends: Clutter.LayoutManager,
|
||||
|
||||
_init: function(boundingBox) {
|
||||
this.parent();
|
||||
|
||||
this._boundingBox = boundingBox;
|
||||
},
|
||||
|
||||
get boundingBox() {
|
||||
return this._boundingBox;
|
||||
},
|
||||
|
||||
set boundingBox(b) {
|
||||
this._boundingBox = b;
|
||||
this.layout_changed();
|
||||
},
|
||||
|
||||
_makeBoxForWindow: function(window) {
|
||||
// We need to adjust the position of the actor because of the
|
||||
// consequences of invisible borders -- in reality, the texture
|
||||
// has an extra set of "padding" around it that we need to trim
|
||||
// down.
|
||||
|
||||
// The outer rect (from which we compute the bounding box)
|
||||
// paradoxically is the smaller rectangle, containing the positions
|
||||
// of the visible frame. The input rect contains everything,
|
||||
// including the invisible border padding.
|
||||
let inputRect = window.get_input_rect();
|
||||
|
||||
let box = new Clutter.ActorBox();
|
||||
|
||||
box.set_origin(inputRect.x - this._boundingBox.x,
|
||||
inputRect.y - this._boundingBox.y);
|
||||
box.set_size(inputRect.width, inputRect.height);
|
||||
|
||||
return box;
|
||||
},
|
||||
|
||||
vfunc_get_preferred_height: function(container, forWidth) {
|
||||
return [this._boundingBox.height, this._boundingBox.height];
|
||||
},
|
||||
|
||||
vfunc_get_preferred_width: function(container, forHeight) {
|
||||
return [this._boundingBox.width, this._boundingBox.width];
|
||||
},
|
||||
|
||||
vfunc_allocate: function(container, box, flags) {
|
||||
let clone = container.get_children().forEach(function (child) {
|
||||
let realWindow;
|
||||
if (child == container._delegate._windowClone)
|
||||
realWindow = container._delegate.realWindow;
|
||||
else
|
||||
realWindow = child.source;
|
||||
|
||||
child.allocate(this._makeBoxForWindow(realWindow.meta_window),
|
||||
flags);
|
||||
}, this);
|
||||
},
|
||||
});
|
||||
|
||||
const WindowClone = new Lang.Class({
|
||||
Name: 'WindowClone',
|
||||
|
||||
@ -50,10 +113,7 @@ const WindowClone = new Lang.Class({
|
||||
this.metaWindow._delegate = this;
|
||||
this._workspace = workspace;
|
||||
|
||||
let [borderX, borderY] = this._getInvisibleBorderPadding();
|
||||
this._windowClone = new Clutter.Clone({ source: realWindow.get_texture(),
|
||||
x: -borderX,
|
||||
y: -borderY });
|
||||
this._windowClone = new Clutter.Clone({ source: realWindow.get_texture() });
|
||||
// We expect this.actor to be used for all interaction rather than
|
||||
// this._windowClone; as the former is reactive and the latter
|
||||
// is not, this just works for most cases. However, for DND all
|
||||
@ -61,20 +121,15 @@ const WindowClone = new Lang.Class({
|
||||
// To avoid this, we hide it from pick.
|
||||
Shell.util_set_hidden_from_pick(this._windowClone, true);
|
||||
|
||||
this.origX = realWindow.x + borderX;
|
||||
this.origY = realWindow.y + borderY;
|
||||
|
||||
let outerRect = realWindow.meta_window.get_outer_rect();
|
||||
|
||||
// The MetaShapedTexture that we clone has a size that includes
|
||||
// the invisible border; this is inconvenient; rather than trying
|
||||
// to compensate all over the place we insert a ClutterActor into
|
||||
// to compensate all over the place we insert a custom container into
|
||||
// the hierarchy that is sized to only the visible portion.
|
||||
// As usual, we cannot use a ShellGenericContainer or StWidget here,
|
||||
// because Workspace plays dirty tricks with reparenting to do DNDs
|
||||
// and scroll-to-zoom.
|
||||
this.actor = new Clutter.Actor({ reactive: true,
|
||||
x: this.origX,
|
||||
y: this.origY,
|
||||
width: outerRect.width,
|
||||
height: outerRect.height });
|
||||
layout_manager: new WindowCloneLayout() });
|
||||
|
||||
this.actor.add_child(this._windowClone);
|
||||
|
||||
@ -84,10 +139,19 @@ const WindowClone = new Lang.Class({
|
||||
this._dragSlot = [0, 0, 0, 0];
|
||||
this._stackAbove = null;
|
||||
|
||||
this._sizeChangedId = this.realWindow.connect('size-changed',
|
||||
this._windowClone._updateId = this.realWindow.connect('size-changed',
|
||||
Lang.bind(this, this._onRealWindowSizeChanged));
|
||||
this._realWindowDestroyId = this.realWindow.connect('destroy',
|
||||
Lang.bind(this, this._disconnectRealWindowSignals));
|
||||
this._windowClone._destroyId = this.realWindow.connect('destroy', Lang.bind(this, function() {
|
||||
// First destroy the clone and then destroy everything
|
||||
// This will ensure that we never see it in the _disconnectSignals loop
|
||||
this._windowClone.destroy();
|
||||
this.destroy();
|
||||
}));
|
||||
|
||||
this._updateAttachedDialogs();
|
||||
this._computeBoundingBox();
|
||||
this.actor.x = this._boundingBox.x;
|
||||
this.actor.y = this._boundingBox.y;
|
||||
|
||||
let clickAction = new Clutter.ClickAction();
|
||||
clickAction.connect('clicked', Lang.bind(this, this._onClicked));
|
||||
@ -121,20 +185,95 @@ const WindowClone = new Lang.Class({
|
||||
return this._slot;
|
||||
},
|
||||
|
||||
// Find the actor just below us, respecting reparenting done
|
||||
// by DND code
|
||||
getActualStackAbove: function() {
|
||||
if (this._stackAbove == null)
|
||||
return null;
|
||||
deleteAll: function() {
|
||||
// Delete all windows, starting from the bottom-most (most-modal) one
|
||||
|
||||
if (this.inDrag || this._zooming) {
|
||||
if (this._stackAbove._delegate)
|
||||
return this._stackAbove._delegate.getActualStackAbove();
|
||||
else
|
||||
return null;
|
||||
} else {
|
||||
return this._stackAbove;
|
||||
let windows = this.actor.get_children();
|
||||
for (let i = windows.length - 1; i >= 1; i--) {
|
||||
let realWindow = windows[i].source;
|
||||
let metaWindow = realWindow.meta_window;
|
||||
|
||||
metaWindow.delete(global.get_current_time());
|
||||
}
|
||||
|
||||
this.metaWindow.delete(global.get_current_time());
|
||||
},
|
||||
|
||||
addAttachedDialog: function(win) {
|
||||
this._doAddAttachedDialog(win, win.get_compositor_private());
|
||||
this._computeBoundingBox();
|
||||
this._updateDimmer();
|
||||
this.emit('size-changed');
|
||||
},
|
||||
|
||||
_doAddAttachedDialog: function(metaWin, realWin) {
|
||||
let clone = new Clutter.Clone({ source: realWin });
|
||||
clone._updateId = realWin.connect('size-changed', Lang.bind(this, function() {
|
||||
this._computeBoundingBox();
|
||||
this.emit('size-changed');
|
||||
}));
|
||||
clone._destroyId = realWin.connect('destroy', Lang.bind(this, function() {
|
||||
clone.destroy();
|
||||
|
||||
this._computeBoundingBox();
|
||||
this._updateDimmer();
|
||||
this.emit('size-changed');
|
||||
}));
|
||||
this.actor.add_child(clone);
|
||||
},
|
||||
|
||||
_updateAttachedDialogs: function() {
|
||||
let iter = Lang.bind(this, function(win) {
|
||||
let actor = win.get_compositor_private();
|
||||
|
||||
if (!actor)
|
||||
return false;
|
||||
if (!win.is_attached_dialog())
|
||||
return false;
|
||||
|
||||
this._doAddAttachedDialog(win, actor);
|
||||
win.foreach_transient(iter);
|
||||
return true;
|
||||
});
|
||||
this.metaWindow.foreach_transient(iter);
|
||||
|
||||
this._dimmer = new WindowManager.WindowDimmer(this._windowClone);
|
||||
this._updateDimmer();
|
||||
},
|
||||
|
||||
_updateDimmer: function() {
|
||||
if (this.actor.get_n_children() > 1) {
|
||||
this._dimmer.setEnabled(true);
|
||||
this._dimmer.dimFactor = 1.0;
|
||||
} else {
|
||||
this._dimmer.setEnabled(false);
|
||||
}
|
||||
},
|
||||
|
||||
get boundingBox() {
|
||||
return this._boundingBox;
|
||||
},
|
||||
|
||||
getOriginalPosition: function() {
|
||||
return [this._boundingBox.x, this._boundingBox.y];
|
||||
},
|
||||
|
||||
_computeBoundingBox: function() {
|
||||
let rect = this.metaWindow.get_outer_rect();
|
||||
|
||||
this.actor.get_children().forEach(function (child) {
|
||||
let realWindow;
|
||||
if (child == this._windowClone)
|
||||
realWindow = this.realWindow;
|
||||
else
|
||||
realWindow = child.source;
|
||||
|
||||
let metaWindow = realWindow.meta_window;
|
||||
rect = rect.union(metaWindow.get_outer_rect());
|
||||
}, this);
|
||||
|
||||
this._boundingBox = rect;
|
||||
this.actor.layout_manager.boundingBox = rect;
|
||||
},
|
||||
|
||||
setStackAbove: function (actor) {
|
||||
@ -142,56 +281,36 @@ const WindowClone = new Lang.Class({
|
||||
if (this.inDrag)
|
||||
// We'll fix up the stack after the drag
|
||||
return;
|
||||
|
||||
let actualAbove = this.getActualStackAbove();
|
||||
if (actualAbove == null)
|
||||
if (this._stackAbove == null)
|
||||
this.actor.lower_bottom();
|
||||
else
|
||||
this.actor.raise(actualAbove);
|
||||
this.actor.raise(this._stackAbove);
|
||||
},
|
||||
|
||||
destroy: function () {
|
||||
this.actor.destroy();
|
||||
},
|
||||
|
||||
_disconnectRealWindowSignals: function() {
|
||||
if (this._sizeChangedId > 0)
|
||||
this.realWindow.disconnect(this._sizeChangedId);
|
||||
this._sizeChangedId = 0;
|
||||
_disconnectSignals: function() {
|
||||
this.actor.get_children().forEach(Lang.bind(this, function (child) {
|
||||
let realWindow;
|
||||
if (child == this._windowClone)
|
||||
realWindow = this.realWindow;
|
||||
else
|
||||
realWindow = child.source;
|
||||
|
||||
if (this._realWindowDestroyId > 0)
|
||||
this.realWindow.disconnect(this._realWindowDestroyId);
|
||||
this._realWindowDestroyId = 0;
|
||||
},
|
||||
|
||||
_getInvisibleBorderPadding: function() {
|
||||
// We need to adjust the position of the actor because of the
|
||||
// consequences of invisible borders -- in reality, the texture
|
||||
// has an extra set of "padding" around it that we need to trim
|
||||
// down.
|
||||
|
||||
// The outer rect paradoxically is the smaller rectangle,
|
||||
// containing the positions of the visible frame. The input
|
||||
// rect contains everything, including the invisible border
|
||||
// padding.
|
||||
let outerRect = this.metaWindow.get_outer_rect();
|
||||
let inputRect = this.metaWindow.get_input_rect();
|
||||
let [borderX, borderY] = [outerRect.x - inputRect.x,
|
||||
outerRect.y - inputRect.y];
|
||||
|
||||
return [borderX, borderY];
|
||||
realWindow.disconnect(child._updateId);
|
||||
realWindow.disconnect(child._destroyId);
|
||||
}));
|
||||
},
|
||||
|
||||
_onRealWindowSizeChanged: function() {
|
||||
let [borderX, borderY] = this._getInvisibleBorderPadding();
|
||||
let outerRect = this.metaWindow.get_outer_rect();
|
||||
this.actor.set_size(outerRect.width, outerRect.height);
|
||||
this._windowClone.set_position(-borderX, -borderY);
|
||||
this._computeBoundingBox();
|
||||
this.emit('size-changed');
|
||||
},
|
||||
|
||||
_onDestroy: function() {
|
||||
this._disconnectRealWindowSignals();
|
||||
this._disconnectSignals();
|
||||
|
||||
this.metaWindow._delegate = null;
|
||||
this.actor._delegate = null;
|
||||
@ -450,7 +569,7 @@ const WindowOverlay = new Lang.Class({
|
||||
Lang.bind(this,
|
||||
this._onWindowAdded));
|
||||
|
||||
metaWindow.delete(global.get_current_time());
|
||||
this._windowClone.deleteAll();
|
||||
},
|
||||
|
||||
_onWindowAdded: function(workspace, win) {
|
||||
@ -926,7 +1045,7 @@ const Workspace = new Lang.Class({
|
||||
this._windowOverlays = [];
|
||||
for (let i = 0; i < windows.length; i++) {
|
||||
if (this._isOverviewWindow(windows[i])) {
|
||||
this._addWindowClone(windows[i], true);
|
||||
this._addWindowClone(windows[i]);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1051,23 +1170,11 @@ const Workspace = new Lang.Class({
|
||||
if (clone.inDrag)
|
||||
continue;
|
||||
|
||||
let cloneWidth = clone.actor.width * scale;
|
||||
let cloneHeight = clone.actor.height * scale;
|
||||
clone.slot = [x, y, cloneWidth, cloneHeight];
|
||||
clone.slot = [x, y, clone.actor.width * scale, clone.actor.height * scale];
|
||||
|
||||
if (overlay && (initialPositioning || !clone.positioned))
|
||||
if (overlay && initialPositioning)
|
||||
overlay.hide();
|
||||
|
||||
if (!clone.positioned) {
|
||||
// This window appeared after the overview was already up
|
||||
// Grow the clone from the center of the slot
|
||||
clone.actor.x = x + cloneWidth / 2;
|
||||
clone.actor.y = y + cloneHeight / 2;
|
||||
clone.actor.scale_x = 0;
|
||||
clone.actor.scale_y = 0;
|
||||
clone.positioned = true;
|
||||
}
|
||||
|
||||
if (animate && isOnCurrentWorkspace) {
|
||||
if (!metaWindow.showing_on_its_workspace()) {
|
||||
/* Hidden windows should fade in and grow
|
||||
@ -1250,10 +1357,30 @@ const Workspace = new Lang.Class({
|
||||
if (this._lookupIndex (metaWin) != -1)
|
||||
return;
|
||||
|
||||
if (!this._isMyWindow(win) || !this._isOverviewWindow(win))
|
||||
if (!this._isMyWindow(win))
|
||||
return;
|
||||
|
||||
let [clone, overlay] = this._addWindowClone(win, false);
|
||||
if (!this._isOverviewWindow(win)) {
|
||||
if (metaWin.is_attached_dialog()) {
|
||||
let parent = metaWin.get_transient_for();
|
||||
while (parent.is_attached_dialog())
|
||||
parent = metaWin.get_transient_for();
|
||||
|
||||
let idx = this._lookupIndex (parent);
|
||||
if (idx < 0) {
|
||||
// parent was not created yet, it will take care
|
||||
// of the dialog when created
|
||||
return;
|
||||
}
|
||||
|
||||
let clone = this._windows[idx];
|
||||
clone.addAttachedDialog(metaWin);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
let [clone, overlay] = this._addWindowClone(win);
|
||||
|
||||
if (win._overviewHint) {
|
||||
let x = win._overviewHint.x - this.actor.x;
|
||||
@ -1262,10 +1389,16 @@ const Workspace = new Lang.Class({
|
||||
delete win._overviewHint;
|
||||
|
||||
clone.slot = [x, y, clone.actor.width * scale, clone.actor.height * scale];
|
||||
clone.positioned = true;
|
||||
clone.actor.set_position (x, y);
|
||||
clone.actor.set_scale (scale, scale);
|
||||
clone.overlay.relayout(false);
|
||||
} else {
|
||||
// Position new windows at the top corner of the workspace rather
|
||||
// than where they were placed for real to avoid the window
|
||||
// being clipped to the workspaceView. Its not really more
|
||||
// natural for the window to suddenly appear in the overview
|
||||
// on some seemingly random location anyway.
|
||||
clone.actor.set_position (this._x, this._y);
|
||||
}
|
||||
|
||||
this._currentLayout = null;
|
||||
@ -1345,9 +1478,11 @@ const Workspace = new Lang.Class({
|
||||
overlay.hide();
|
||||
|
||||
if (clone.metaWindow.showing_on_its_workspace()) {
|
||||
let [origX, origY] = clone.getOriginalPosition();
|
||||
|
||||
Tweener.addTween(clone.actor,
|
||||
{ x: clone.origX,
|
||||
y: clone.origY,
|
||||
{ x: origX,
|
||||
y: origY,
|
||||
scale_x: 1.0,
|
||||
scale_y: 1.0,
|
||||
time: Overview.ANIMATION_TIME,
|
||||
@ -1412,11 +1547,10 @@ const Workspace = new Lang.Class({
|
||||
},
|
||||
|
||||
// Create a clone of a (non-desktop) window and add it to the window list
|
||||
_addWindowClone : function(win, positioned) {
|
||||
_addWindowClone : function(win) {
|
||||
let clone = new WindowClone(win, this);
|
||||
let overlay = new WindowOverlay(clone, this._windowOverlaysGroup);
|
||||
clone.overlay = overlay;
|
||||
clone.positioned = positioned;
|
||||
|
||||
clone.connect('selected',
|
||||
Lang.bind(this, this._onCloneSelected));
|
||||
|
@ -13,6 +13,7 @@ const Background = imports.ui.background;
|
||||
const DND = imports.ui.dnd;
|
||||
const Main = imports.ui.main;
|
||||
const Tweener = imports.ui.tweener;
|
||||
const WindowManager = imports.ui.windowManager;
|
||||
const Workspace = imports.ui.workspace;
|
||||
const WorkspacesView = imports.ui.workspacesView;
|
||||
|
||||
@ -31,20 +32,49 @@ const WORKSPACE_KEEP_ALIVE_TIME = 100;
|
||||
|
||||
const OVERRIDE_SCHEMA = 'org.gnome.shell.overrides';
|
||||
|
||||
/* A layout manager that requests size only for primary_actor, but then allocates
|
||||
all using a fixed layout */
|
||||
const PrimaryActorLayout = new Lang.Class({
|
||||
Name: 'PrimaryActorLayout',
|
||||
Extends: Clutter.FixedLayout,
|
||||
|
||||
_init: function(primaryActor) {
|
||||
this.parent();
|
||||
|
||||
this.primaryActor = primaryActor;
|
||||
},
|
||||
|
||||
vfunc_get_preferred_width: function(forHeight) {
|
||||
return this.primaryActor.get_preferred_width(forHeight);
|
||||
},
|
||||
|
||||
vfunc_get_preferred_height: function(forWidth) {
|
||||
return this.primaryActor.get_preferred_height(forWidth);
|
||||
},
|
||||
});
|
||||
|
||||
const WindowClone = new Lang.Class({
|
||||
Name: 'WindowClone',
|
||||
|
||||
_init : function(realWindow) {
|
||||
this.actor = new Clutter.Clone({ source: realWindow.get_texture(),
|
||||
this.clone = new Clutter.Clone({ source: realWindow });
|
||||
|
||||
/* Can't use a Shell.GenericContainer because of DND and reparenting... */
|
||||
this.actor = new Clutter.Actor({ layout_manager: new PrimaryActorLayout(this.clone),
|
||||
reactive: true });
|
||||
this.actor._delegate = this;
|
||||
this.actor.add_child(this.clone);
|
||||
this.realWindow = realWindow;
|
||||
this.metaWindow = realWindow.meta_window;
|
||||
|
||||
this._positionChangedId = this.realWindow.connect('position-changed',
|
||||
Lang.bind(this, this._onPositionChanged));
|
||||
this._realWindowDestroyedId = this.realWindow.connect('destroy',
|
||||
Lang.bind(this, this._disconnectRealWindowSignals));
|
||||
this.clone._updateId = this.realWindow.connect('position-changed',
|
||||
Lang.bind(this, this._onPositionChanged));
|
||||
this.clone._destroyId = this.realWindow.connect('destroy', Lang.bind(this, function() {
|
||||
// First destroy the clone and then destroy everything
|
||||
// This will ensure that we never see it in the _disconnectSignals loop
|
||||
this.clone.destroy();
|
||||
this.destroy();
|
||||
}));
|
||||
this._onPositionChanged();
|
||||
|
||||
this.actor.connect('button-release-event',
|
||||
@ -60,62 +90,89 @@ const WindowClone = new Lang.Class({
|
||||
this._draggable.connect('drag-cancelled', Lang.bind(this, this._onDragCancelled));
|
||||
this._draggable.connect('drag-end', Lang.bind(this, this._onDragEnd));
|
||||
this.inDrag = false;
|
||||
},
|
||||
|
||||
// Find the actor just below us, respecting reparenting done
|
||||
// by DND code
|
||||
getActualStackAbove: function() {
|
||||
if (this._stackAbove == null)
|
||||
return null;
|
||||
let iter = Lang.bind(this, function(win) {
|
||||
let actor = win.get_compositor_private();
|
||||
|
||||
if (this.inDrag) {
|
||||
if (this._stackAbove._delegate)
|
||||
return this._stackAbove._delegate.getActualStackAbove();
|
||||
else
|
||||
return null;
|
||||
} else {
|
||||
return this._stackAbove;
|
||||
}
|
||||
if (!actor)
|
||||
return false;
|
||||
if (!win.is_attached_dialog())
|
||||
return false;
|
||||
|
||||
this._doAddAttachedDialog(win, actor);
|
||||
win.foreach_transient(iter);
|
||||
|
||||
return true;
|
||||
});
|
||||
this.metaWindow.foreach_transient(iter);
|
||||
|
||||
this._dimmer = new WindowManager.WindowDimmer(this.clone);
|
||||
this._updateDimmer();
|
||||
},
|
||||
|
||||
setStackAbove: function (actor) {
|
||||
this._stackAbove = actor;
|
||||
|
||||
// Don't apply the new stacking now, it will be applied
|
||||
// when dragging ends and window are stacked again
|
||||
if (actor.inDrag)
|
||||
return;
|
||||
|
||||
let actualAbove = this.getActualStackAbove();
|
||||
if (actualAbove == null)
|
||||
if (this._stackAbove == null)
|
||||
this.actor.lower_bottom();
|
||||
else
|
||||
this.actor.raise(actualAbove);
|
||||
this.actor.raise(this._stackAbove);
|
||||
},
|
||||
|
||||
destroy: function () {
|
||||
this.actor.destroy();
|
||||
},
|
||||
|
||||
addAttachedDialog: function(win) {
|
||||
this._doAddAttachedDialog(win, win.get_compositor_private());
|
||||
this._updateDimmer();
|
||||
},
|
||||
|
||||
_doAddAttachedDialog: function(metaDialog, realDialog) {
|
||||
let clone = new Clutter.Clone({ source: realDialog });
|
||||
this._updateDialogPosition(realDialog, clone);
|
||||
|
||||
clone._updateId = realDialog.connect('position-changed',
|
||||
Lang.bind(this, this._updateDialogPosition, clone));
|
||||
clone._destroyId = realDialog.connect('destroy', Lang.bind(this, function() {
|
||||
clone.destroy();
|
||||
this._updateDimmer();
|
||||
}));
|
||||
this.actor.add_child(clone);
|
||||
},
|
||||
|
||||
_updateDimmer: function() {
|
||||
if (this.actor.get_n_children() > 1) {
|
||||
this._dimmer.setEnabled(true);
|
||||
this._dimmer.dimFactor = 1.0;
|
||||
} else {
|
||||
this._dimmer.setEnabled(false);
|
||||
}
|
||||
},
|
||||
|
||||
_updateDialogPosition: function(realDialog, cloneDialog) {
|
||||
let metaDialog = realDialog.meta_window;
|
||||
let dialogRect = metaDialog.get_outer_rect();
|
||||
let rect = this.metaWindow.get_outer_rect();
|
||||
|
||||
cloneDialog.set_position(dialogRect.x - rect.x, dialogRect.y - rect.y);
|
||||
},
|
||||
|
||||
_onPositionChanged: function() {
|
||||
let rect = this.metaWindow.get_outer_rect();
|
||||
this.actor.set_position(this.realWindow.x, this.realWindow.y);
|
||||
},
|
||||
|
||||
_disconnectRealWindowSignals: function() {
|
||||
if (this._positionChangedId != 0) {
|
||||
this.realWindow.disconnect(this._positionChangedId);
|
||||
this._positionChangedId = 0;
|
||||
}
|
||||
_disconnectSignals: function() {
|
||||
this.actor.get_children().forEach(function(child) {
|
||||
let realWindow = child.source;
|
||||
|
||||
if (this._realWindowDestroyedId != 0) {
|
||||
this.realWindow.disconnect(this._realWindowDestroyedId);
|
||||
this._realWindowDestroyedId = 0;
|
||||
}
|
||||
realWindow.disconnect(child._updateId);
|
||||
realWindow.disconnect(child._destroyId);
|
||||
});
|
||||
},
|
||||
|
||||
_onDestroy: function() {
|
||||
this._disconnectRealWindowSignals();
|
||||
this._disconnectSignals();
|
||||
|
||||
this.actor._delegate = null;
|
||||
|
||||
@ -343,10 +400,26 @@ const WorkspaceThumbnail = new Lang.Class({
|
||||
if (this._lookupIndex (metaWin) != -1)
|
||||
return;
|
||||
|
||||
if (!this._isMyWindow(win) || !this._isOverviewWindow(win))
|
||||
if (!this._isMyWindow(win))
|
||||
return;
|
||||
|
||||
let clone = this._addWindowClone(win);
|
||||
if (this._isOverviewWindow(win)) {
|
||||
this._addWindowClone(win);
|
||||
} else if (metaWin.is_attached_dialog()) {
|
||||
let parent = metaWin.get_transient_for();
|
||||
while (parent.is_attached_dialog())
|
||||
parent = metaWin.get_transient_for();
|
||||
|
||||
let idx = this._lookupIndex (parent);
|
||||
if (idx < 0) {
|
||||
// parent was not created yet, it will take care
|
||||
// of the dialog when created
|
||||
return;
|
||||
}
|
||||
|
||||
let clone = this._windows[idx];
|
||||
clone.addAttachedDialog(metaWin);
|
||||
}
|
||||
},
|
||||
|
||||
_windowAdded : function(metaWorkspace, metaWin) {
|
||||
@ -384,8 +457,9 @@ const WorkspaceThumbnail = new Lang.Class({
|
||||
},
|
||||
|
||||
destroy : function() {
|
||||
if (this.actor)
|
||||
this.actor.destroy();
|
||||
this.actor.destroy();
|
||||
this._bgManager.destroy();
|
||||
this._bgManager = null;
|
||||
},
|
||||
|
||||
workspaceRemoved : function() {
|
||||
@ -406,11 +480,6 @@ const WorkspaceThumbnail = new Lang.Class({
|
||||
_onDestroy: function(actor) {
|
||||
this.workspaceRemoved();
|
||||
|
||||
if (this._bgManager) {
|
||||
this._bgManager.destroy();
|
||||
this._bgManager = null;
|
||||
}
|
||||
|
||||
this._windows = [];
|
||||
this.actor = null;
|
||||
},
|
||||
@ -562,7 +631,6 @@ const ThumbnailsBox = new Lang.Class({
|
||||
this._dropPlaceholderPos = -1;
|
||||
this._dropPlaceholder = new St.Bin({ style_class: 'placeholder' });
|
||||
this.actor.add_actor(this._dropPlaceholder);
|
||||
this._spliceIndex = -1;
|
||||
|
||||
this._targetScale = 0;
|
||||
this._scale = 0;
|
||||
@ -745,8 +813,6 @@ const ThumbnailsBox = new Lang.Class({
|
||||
return win.get_workspace() >= newWorkspaceIndex;
|
||||
});
|
||||
|
||||
this._spliceIndex = newWorkspaceIndex;
|
||||
|
||||
// ... move them down one.
|
||||
windows.forEach(function(win) {
|
||||
win.meta_window.change_workspace_by_index(win.get_workspace() + 1,
|
||||
@ -768,14 +834,6 @@ const ThumbnailsBox = new Lang.Class({
|
||||
WORKSPACE_KEEP_ALIVE_TIME);
|
||||
}
|
||||
|
||||
// Start the animation on the workspace (which is actually
|
||||
// an old one which just became empty)
|
||||
let thumbnail = this._thumbnails[newWorkspaceIndex];
|
||||
this._setThumbnailState(thumbnail, ThumbnailState.NEW);
|
||||
thumbnail.slidePosition = 1;
|
||||
|
||||
this._queueUpdateStates();
|
||||
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
@ -863,8 +921,7 @@ const ThumbnailsBox = new Lang.Class({
|
||||
this._thumbnails.push(thumbnail);
|
||||
this.actor.add_actor(thumbnail.actor);
|
||||
|
||||
if (start > 0 && this._spliceIndex == -1) {
|
||||
// not the initial fill, and not splicing via DND
|
||||
if (start > 0) { // not the initial fill
|
||||
thumbnail.state = ThumbnailState.NEW;
|
||||
thumbnail.slidePosition = 1; // start slid out
|
||||
this._haveNewThumbnails = true;
|
||||
@ -879,9 +936,6 @@ const ThumbnailsBox = new Lang.Class({
|
||||
|
||||
// The thumbnails indicator actually needs to be on top of the thumbnails
|
||||
this._indicator.raise_top();
|
||||
|
||||
// Clear the splice index, we got the message
|
||||
this._spliceIndex = -1;
|
||||
},
|
||||
|
||||
removeThumbnails: function(start, count) {
|
||||
|
@ -386,15 +386,6 @@ const WorkspacesView = new Lang.Class({
|
||||
let current = Math.round(adj.value);
|
||||
|
||||
if (active != current) {
|
||||
if (!this._workspaces[current]) {
|
||||
// The current workspace was destroyed. This could happen
|
||||
// when you are on the last empty workspace, and consolidate
|
||||
// windows using the thumbnail bar.
|
||||
// In that case, the intended behavior is to stay on the empty
|
||||
// workspace, which is the last one, so pick it.
|
||||
current = this._workspaces.length - 1;
|
||||
}
|
||||
|
||||
let metaWorkspace = this._workspaces[current].metaWorkspace;
|
||||
metaWorkspace.activate(global.get_current_time());
|
||||
}
|
||||
|
@ -60,7 +60,6 @@ sr@latin
|
||||
sv
|
||||
ta
|
||||
te
|
||||
tg
|
||||
th
|
||||
tr
|
||||
ug
|
||||
|
File diff suppressed because it is too large
Load Diff
1164
po/en_GB.po
1164
po/en_GB.po
File diff suppressed because it is too large
Load Diff
275
po/et.po
275
po/et.po
@ -13,8 +13,8 @@ msgstr ""
|
||||
"Project-Id-Version: gnome-shell MASTER\n"
|
||||
"Report-Msgid-Bugs-To: http://bugzilla.gnome.org/enter_bug.cgi?product=gnome-"
|
||||
"shell&keywords=I18N+L10N&component=general\n"
|
||||
"POT-Creation-Date: 2013-03-11 22:02+0000\n"
|
||||
"PO-Revision-Date: 2013-03-12 16:28+0300\n"
|
||||
"POT-Creation-Date: 2012-12-09 13:03+0000\n"
|
||||
"PO-Revision-Date: 2012-12-19 16:47+0300\n"
|
||||
"Last-Translator: Mattias Põldaru <mahfiaz@gmail.com>\n"
|
||||
"Language-Team: Estonian <>\n"
|
||||
"Language: et\n"
|
||||
@ -104,16 +104,6 @@ msgid ""
|
||||
"favorites area."
|
||||
msgstr "Nendele tunnustele vastavaid rakendusi kuvatakse lemmikutes."
|
||||
|
||||
msgid "List of categories that should be displayed as folders"
|
||||
msgstr "Kategooriad, mida tuleb kuvada kaustadena"
|
||||
|
||||
msgid ""
|
||||
"Each category name in this list will be represented as folder in the "
|
||||
"application view, rather than being displayed inline in the main view."
|
||||
msgstr ""
|
||||
"Kõiki selles loetelus olevaid kategooriaid kuvatakse rakenduste vaates "
|
||||
"kaustadena, mitte peavaates teistega koos."
|
||||
|
||||
msgid "History for command (Alt-F2) dialog"
|
||||
msgstr "Käsudialoogi (Alt-F2) ajalugu"
|
||||
|
||||
@ -145,6 +135,12 @@ msgstr ""
|
||||
"See võti keelab automaatse 'Logi välja' menüükirje peitmise, kui arvutis on "
|
||||
"üks kasutaja ning avatud üks seanss."
|
||||
|
||||
msgid "Show full name in the user menu"
|
||||
msgstr "Kasutajamenüüs näidatakse kasutaja tervet nime"
|
||||
|
||||
msgid "Whether the users full name is shown in the user menu or not."
|
||||
msgstr "Kas kasutajamenüüs näidatakse kasutaja kogu nime või mitte."
|
||||
|
||||
msgid ""
|
||||
"Whether to remember password for mounting encrypted or remote filesystems"
|
||||
msgstr ""
|
||||
@ -303,8 +299,12 @@ msgstr "Laiendus"
|
||||
msgid "Select an extension to configure using the combobox above."
|
||||
msgstr "Vali seadistatav laiendus kasutades ülemist valikukasti."
|
||||
|
||||
msgid "Session…"
|
||||
msgstr "Seanss…"
|
||||
msgid "Session..."
|
||||
msgstr "Seanss..."
|
||||
|
||||
msgctxt "title"
|
||||
msgid "Sign In"
|
||||
msgstr "Sisselogimine"
|
||||
|
||||
#. translators: this message is shown below the user list on the
|
||||
#. login screen. It can be activated to reveal an entry for
|
||||
@ -368,12 +368,16 @@ msgstr "Käsku pole võimalik analüüsida:"
|
||||
msgid "Execution of '%s' failed:"
|
||||
msgstr "'%s' käivitamine nurjus:"
|
||||
|
||||
msgid "Frequent"
|
||||
msgstr "Sage"
|
||||
|
||||
#. Translators: Filter to display all applications
|
||||
msgid "All"
|
||||
msgstr "Kõik"
|
||||
|
||||
msgid "APPLICATIONS"
|
||||
msgstr "RAKENDUSED"
|
||||
|
||||
msgid "SETTINGS"
|
||||
msgstr "SEADED"
|
||||
|
||||
msgid "New Window"
|
||||
msgstr "Uus aken"
|
||||
|
||||
@ -391,12 +395,6 @@ msgstr "%s lisati lemmikutesse."
|
||||
msgid "%s has been removed from your favorites."
|
||||
msgstr "%s eemaldati lemmikutest."
|
||||
|
||||
msgid "Settings"
|
||||
msgstr "Sätted"
|
||||
|
||||
msgid "Change Background…"
|
||||
msgstr "Muuda tausta…"
|
||||
|
||||
#. Translators: Shown in calendar event list for all day events
|
||||
#. * Keep it short, best if you can use less then 10 characters
|
||||
#.
|
||||
@ -404,18 +402,15 @@ msgctxt "event list time"
|
||||
msgid "All Day"
|
||||
msgstr "Kogu päev"
|
||||
|
||||
#. Translators: Shown in calendar event list, if 24h format,
|
||||
#. \u2236 is a ratio character, similar to :
|
||||
#. Translators: Shown in calendar event list, if 24h format
|
||||
msgctxt "event list time"
|
||||
msgid "%H\\u2236%M"
|
||||
msgstr "%H\\u2236%M"
|
||||
msgid "%H:%M"
|
||||
msgstr "%H:%M"
|
||||
|
||||
#. Transators: Shown in calendar event list, if 12h format,
|
||||
#. \u2236 is a ratio character, similar to : and \u2009 is
|
||||
#. a thin space
|
||||
#. Transators: Shown in calendar event list, if 12h format
|
||||
msgctxt "event list time"
|
||||
msgid "%l\\u2236%M\\u2009%p"
|
||||
msgstr "%l\\u2236%M\\u2009%p"
|
||||
msgid "%l:%M %p"
|
||||
msgstr "%l:%M %p"
|
||||
|
||||
#. Translators: Calendar grid abbreviation for Sunday.
|
||||
#. *
|
||||
@ -522,12 +517,6 @@ msgstr "Käesolev nädal"
|
||||
msgid "Next week"
|
||||
msgstr "Järgmine nädal"
|
||||
|
||||
msgid "External drive connected"
|
||||
msgstr "Väline ketas ühendati"
|
||||
|
||||
msgid "External drive disconnected"
|
||||
msgstr "Väline ketas eemaldati"
|
||||
|
||||
msgid "Removable Devices"
|
||||
msgstr "Eemaldatavad seadmed"
|
||||
|
||||
@ -812,20 +801,12 @@ msgstr "Aknad"
|
||||
msgid "Show Applications"
|
||||
msgstr "Rakenduste kuvamine"
|
||||
|
||||
#. Translators: this is the name of the dock/favorites area on
|
||||
#. the left of the overview
|
||||
msgid "Dash"
|
||||
msgstr "Dokk"
|
||||
msgid "Date and Time Settings"
|
||||
msgstr "Kuupäeva ja kellaaja sätted"
|
||||
|
||||
msgid "Open Calendar"
|
||||
msgstr "Ava kalender"
|
||||
|
||||
msgid "Open Clocks"
|
||||
msgstr "Ava kell"
|
||||
|
||||
msgid "Date & Time Settings"
|
||||
msgstr "Kuupäeva ja kella sätted"
|
||||
|
||||
#. 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").
|
||||
#.
|
||||
@ -916,6 +897,9 @@ msgstr "Paigalda"
|
||||
msgid "Download and install '%s' from extensions.gnome.org?"
|
||||
msgstr "Kas laadida alla ja paigaldada '%s' aadressilt extensions.gnome.org?"
|
||||
|
||||
msgid "tray"
|
||||
msgstr "salv"
|
||||
|
||||
msgid "Keyboard"
|
||||
msgstr "Klaviatuur"
|
||||
|
||||
@ -936,8 +920,6 @@ msgstr "Näita vigu"
|
||||
msgid "Enabled"
|
||||
msgstr "Lubatud"
|
||||
|
||||
#. translators:
|
||||
#. * The device has been disabled
|
||||
msgid "Disabled"
|
||||
msgstr "Keelatud"
|
||||
|
||||
@ -962,12 +944,6 @@ msgstr "Ava"
|
||||
msgid "Remove"
|
||||
msgstr "Eemalda"
|
||||
|
||||
msgid "Clear Messages"
|
||||
msgstr "Kustuta teated"
|
||||
|
||||
msgid "Notification Settings"
|
||||
msgstr "Märguannete sätted"
|
||||
|
||||
msgid "No Messages"
|
||||
msgstr "Teateid pole"
|
||||
|
||||
@ -981,12 +957,6 @@ msgctxt "program"
|
||||
msgid "Unknown"
|
||||
msgstr "Tundmatu"
|
||||
|
||||
#, c-format
|
||||
msgid "%d new message"
|
||||
msgid_plural "%d new messages"
|
||||
msgstr[0] "%d uus sõnum"
|
||||
msgstr[1] "%d uut sõnumit"
|
||||
|
||||
msgid "Undo"
|
||||
msgstr "Võta tagasi"
|
||||
|
||||
@ -997,8 +967,13 @@ msgstr "Ülevaade"
|
||||
#. in the search entry when no search is
|
||||
#. active; it should not exceed ~30
|
||||
#. characters.
|
||||
msgid "Type to search…"
|
||||
msgstr "Otsing…"
|
||||
msgid "Type to search..."
|
||||
msgstr "Otsing..."
|
||||
|
||||
#. Translators: this is the name of the dock/favorites area on
|
||||
#. the left of the overview
|
||||
msgid "Dash"
|
||||
msgstr "Dokk"
|
||||
|
||||
msgid "Quit"
|
||||
msgstr "Sulge"
|
||||
@ -1030,6 +1005,12 @@ msgstr "Sulge"
|
||||
msgid "%A, %B %d"
|
||||
msgstr "%A, %d. %B"
|
||||
|
||||
#, c-format
|
||||
msgid "%d new message"
|
||||
msgid_plural "%d new messages"
|
||||
msgstr[0] "%d uus sõnum"
|
||||
msgstr[1] "%d uut sõnumit"
|
||||
|
||||
#, c-format
|
||||
msgid "%d new notification"
|
||||
msgid_plural "%d new notifications"
|
||||
@ -1039,24 +1020,8 @@ msgstr[1] "%d uut märguannet"
|
||||
msgid "Lock"
|
||||
msgstr "Lukusta"
|
||||
|
||||
msgid "GNOME needs to lock the screen"
|
||||
msgstr "GNOME peab ekraani lukustama"
|
||||
|
||||
#. We could not become modal, so we can't activate the
|
||||
#. screenshield. The user is probably very upset at this
|
||||
#. point, but any application using global grabs is broken
|
||||
#. Just tell him to stop using this app
|
||||
#.
|
||||
#. XXX: another option is to kick the user into the gdm login
|
||||
#. screen, where we're not affected by grabs
|
||||
msgid "Unable to lock"
|
||||
msgstr "Pole võimalik lukustada"
|
||||
|
||||
msgid "Lock was blocked by an application"
|
||||
msgstr "Rakendus blokeeris lukustamise"
|
||||
|
||||
msgid "Searching…"
|
||||
msgstr "Otsing…"
|
||||
msgid "Searching..."
|
||||
msgstr "Otsimine..."
|
||||
|
||||
msgid "No results."
|
||||
msgstr "Tulemused puuduvad."
|
||||
@ -1124,11 +1089,11 @@ msgstr "Bluetooth"
|
||||
msgid "Visibility"
|
||||
msgstr "Nähtavus"
|
||||
|
||||
msgid "Send Files to Device…"
|
||||
msgstr "Failide saatmine seadmesse…"
|
||||
msgid "Send Files to Device..."
|
||||
msgstr "Failide saatmine seadmesse..."
|
||||
|
||||
msgid "Set Up a New Device…"
|
||||
msgstr "Uue seadme häälestamine…"
|
||||
msgid "Set up a New Device..."
|
||||
msgstr "Uue seadme häälestamine..."
|
||||
|
||||
msgid "Bluetooth Settings"
|
||||
msgstr "Bluetoothi sätted"
|
||||
@ -1146,8 +1111,8 @@ msgstr "ühenduse katkestamine..."
|
||||
msgid "connecting..."
|
||||
msgstr "ühendumine..."
|
||||
|
||||
msgid "Send Files…"
|
||||
msgstr "Failide saatmine…"
|
||||
msgid "Send Files..."
|
||||
msgstr "Failide saatmine..."
|
||||
|
||||
msgid "Keyboard Settings"
|
||||
msgstr "Klaviatuurisätted"
|
||||
@ -1208,7 +1173,7 @@ msgstr "Olgu"
|
||||
msgid "Show Keyboard Layout"
|
||||
msgstr "Klaviatuuripaigutuse kuvamine"
|
||||
|
||||
msgid "Region & Language Settings"
|
||||
msgid "Region and Language Settings"
|
||||
msgstr "Asukoha ja keele sätted"
|
||||
|
||||
msgid "Volume, network, battery"
|
||||
@ -1247,23 +1212,17 @@ msgstr "pole saadaval"
|
||||
msgid "connection failed"
|
||||
msgstr "ühendumine nurjus"
|
||||
|
||||
msgid "More…"
|
||||
msgstr "Veel…"
|
||||
msgid "More..."
|
||||
msgstr "Veel..."
|
||||
|
||||
#. TRANSLATORS: this is the indication that a connection for another logged in user is active,
|
||||
#. and we cannot access its settings (including the name)
|
||||
msgid "Connected (private)"
|
||||
msgstr "Ühendatud (privaatne)"
|
||||
|
||||
msgid "Wired"
|
||||
msgstr "Juhtmega"
|
||||
|
||||
msgid "Auto Ethernet"
|
||||
msgstr "Automaatne ethernet"
|
||||
|
||||
msgid "Mobile broadband"
|
||||
msgstr "Mobiiliühendus"
|
||||
|
||||
msgid "Auto broadband"
|
||||
msgstr "Automaatne lairibaühendus"
|
||||
|
||||
@ -1310,8 +1269,8 @@ msgstr "Toitesätted..."
|
||||
|
||||
#. 0 is reported when UPower does not have enough data
|
||||
#. to estimate battery life
|
||||
msgid "Estimating…"
|
||||
msgstr "Andmete kogumine…"
|
||||
msgid "Estimating..."
|
||||
msgstr "Andmete kogumine..."
|
||||
|
||||
#, c-format
|
||||
msgid "%d hour remaining"
|
||||
@ -1345,10 +1304,10 @@ msgctxt "percent of battery remaining"
|
||||
msgid "%d%%"
|
||||
msgstr "%d%%"
|
||||
|
||||
msgid "AC Adapter"
|
||||
msgstr "Laadija"
|
||||
msgid "AC adapter"
|
||||
msgstr "Võrgutoite adapter"
|
||||
|
||||
msgid "Laptop Battery"
|
||||
msgid "Laptop battery"
|
||||
msgstr "Sülearvuti aku"
|
||||
|
||||
msgid "UPS"
|
||||
@ -1363,10 +1322,10 @@ msgstr "Hiir"
|
||||
msgid "PDA"
|
||||
msgstr "Elektronmärkmik"
|
||||
|
||||
msgid "Cell Phone"
|
||||
msgid "Cell phone"
|
||||
msgstr "Mobiiltelefon"
|
||||
|
||||
msgid "Media Player"
|
||||
msgid "Media player"
|
||||
msgstr "Meediaesitaja"
|
||||
|
||||
msgid "Tablet"
|
||||
@ -1379,9 +1338,6 @@ msgctxt "device"
|
||||
msgid "Unknown"
|
||||
msgstr "Tundmatu"
|
||||
|
||||
msgid "Volume changed"
|
||||
msgstr "Helivaljus muutus"
|
||||
|
||||
#. Translators: This is the label for audio volume
|
||||
msgid "Volume"
|
||||
msgstr "Helivaljus"
|
||||
@ -1416,6 +1372,9 @@ msgstr "Ühendamata"
|
||||
msgid "Notifications"
|
||||
msgstr "Märguanded"
|
||||
|
||||
msgid "Settings"
|
||||
msgstr "Sätted"
|
||||
|
||||
msgid "Switch User"
|
||||
msgstr "Vaheta kasutajat"
|
||||
|
||||
@ -1435,22 +1394,6 @@ msgstr ""
|
||||
"Märguanded on nüüd keelatud, sealhulgas vestlusteated. Sinu netiolekut "
|
||||
"muudeti, et teised teaksid, et sa ei pruugi nende teateid näha."
|
||||
|
||||
msgid "Other users are logged in."
|
||||
msgstr "Teised kasutajad on sisse logitud."
|
||||
|
||||
msgid "Shutting down might cause them to lose unsaved work."
|
||||
msgstr "Väljalülitamine võib põhjustada salvestamata töö kaotsimineku."
|
||||
|
||||
#. Translators: Remote here refers to a remote session, like a ssh login
|
||||
#, c-format
|
||||
msgid "%s (remote)"
|
||||
msgstr "%s (kaugühendus)"
|
||||
|
||||
#. Translators: Console here refers to a tty like a VT console
|
||||
#, c-format
|
||||
msgid "%s (console)"
|
||||
msgstr "%s (konsool)"
|
||||
|
||||
msgid "Applications"
|
||||
msgstr "Rakendused"
|
||||
|
||||
@ -1469,6 +1412,9 @@ msgstr ""
|
||||
msgid "%s the Oracle says"
|
||||
msgstr "Oraakel %s ütleb"
|
||||
|
||||
msgid "Your favorite Easter Egg"
|
||||
msgstr "Sinu lemmiküllatusmuna"
|
||||
|
||||
#, c-format
|
||||
msgid "'%s' is ready"
|
||||
msgstr "'%s' on valmis"
|
||||
@ -1476,25 +1422,6 @@ msgstr "'%s' on valmis"
|
||||
msgid "Evolution Calendar"
|
||||
msgstr "Evolutioni kalender"
|
||||
|
||||
#. translators:
|
||||
#. * The number of sound outputs on a particular device
|
||||
#, c-format
|
||||
msgid "%u Output"
|
||||
msgid_plural "%u Outputs"
|
||||
msgstr[0] "%u väljund"
|
||||
msgstr[1] "%u väljundit"
|
||||
|
||||
#. translators:
|
||||
#. * The number of sound inputs on a particular device
|
||||
#, c-format
|
||||
msgid "%u Input"
|
||||
msgid_plural "%u Inputs"
|
||||
msgstr[0] "%u sisend"
|
||||
msgstr[1] "%u sisendit"
|
||||
|
||||
msgid "System Sounds"
|
||||
msgstr "Süsteemi helid"
|
||||
|
||||
msgid "Print version"
|
||||
msgstr "Printimise versioon"
|
||||
|
||||
@ -1517,48 +1444,15 @@ msgstr "Paroolid ei kattu."
|
||||
msgid "Password cannot be blank"
|
||||
msgstr "Parool ei saa olla tühi"
|
||||
|
||||
msgid "United Kingdom"
|
||||
msgstr "Suurbritannia"
|
||||
|
||||
msgid "Default"
|
||||
msgstr "Vaikimisi"
|
||||
|
||||
msgid "Authentication dialog was dismissed by the user"
|
||||
msgstr "Kasutaja katkestas autentimisdialoogi"
|
||||
|
||||
#~ msgid "Show full name in the user menu"
|
||||
#~ msgstr "Kasutajamenüüs näidatakse kasutaja tervet nime"
|
||||
|
||||
#~ msgid "Whether the users full name is shown in the user menu or not."
|
||||
#~ msgstr "Kas kasutajamenüüs näidatakse kasutaja kogu nime või mitte."
|
||||
|
||||
#~ msgctxt "title"
|
||||
#~ msgid "Sign In"
|
||||
#~ msgstr "Sisselogimine"
|
||||
|
||||
#~ msgid "APPLICATIONS"
|
||||
#~ msgstr "RAKENDUSED"
|
||||
|
||||
#~ msgid "SETTINGS"
|
||||
#~ msgstr "SEADED"
|
||||
|
||||
#~ msgctxt "event list time"
|
||||
#~ msgid "%H:%M"
|
||||
#~ msgstr "%H:%M"
|
||||
|
||||
#~ msgctxt "event list time"
|
||||
#~ msgid "%l:%M %p"
|
||||
#~ msgstr "%l:%M %p"
|
||||
|
||||
#~ msgid "tray"
|
||||
#~ msgstr "salv"
|
||||
|
||||
#~ msgid "More..."
|
||||
#~ msgstr "Veel..."
|
||||
|
||||
#~ msgid "Your favorite Easter Egg"
|
||||
#~ msgstr "Sinu lemmiküllatusmuna"
|
||||
|
||||
#~ msgid "United Kingdom"
|
||||
#~ msgstr "Suurbritannia"
|
||||
|
||||
#~ msgid "Default"
|
||||
#~ msgstr "Vaikimisi"
|
||||
|
||||
#~ msgid "Subscription request"
|
||||
#~ msgstr "Tellimuse päring"
|
||||
|
||||
@ -1577,9 +1471,28 @@ msgstr "Kasutaja katkestas autentimisdialoogi"
|
||||
#~ msgid "Reconnect"
|
||||
#~ msgstr "Ühendu uuesti"
|
||||
|
||||
#~ msgid "Wired"
|
||||
#~ msgstr "Juhtmega"
|
||||
|
||||
#~ msgid "Wireless"
|
||||
#~ msgstr "Juhtmeta"
|
||||
|
||||
#~ msgid "Mobile broadband"
|
||||
#~ msgstr "Mobiiliühendus"
|
||||
|
||||
#~ msgid "%u Output"
|
||||
#~ msgid_plural "%u Outputs"
|
||||
#~ msgstr[0] "%u väljund"
|
||||
#~ msgstr[1] "%u väljundit"
|
||||
|
||||
#~ msgid "%u Input"
|
||||
#~ msgid_plural "%u Inputs"
|
||||
#~ msgstr[0] "%u sisend"
|
||||
#~ msgstr[1] "%u sisendit"
|
||||
|
||||
#~ msgid "System Sounds"
|
||||
#~ msgstr "Süsteemi helid"
|
||||
|
||||
#~ msgid "disabled OpenSearch providers"
|
||||
#~ msgstr "keelatud OpenSearch pakkujad"
|
||||
|
||||
|
157
po/nb.po
157
po/nb.po
@ -6,10 +6,10 @@
|
||||
# Torstein Adolf Winterseth <kvikende@fsfe.org>, 2010.
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: gnome-shell 3.8.x\n"
|
||||
"Project-Id-Version: gnome-shell 3.7.x\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2013-04-03 13:31+0200\n"
|
||||
"PO-Revision-Date: 2013-04-03 13:31+0200\n"
|
||||
"POT-Creation-Date: 2013-03-04 14:14+0100\n"
|
||||
"PO-Revision-Date: 2013-03-04 14:15+0100\n"
|
||||
"Last-Translator: Kjartan Maraas <kmaraas@gnome.org>\n"
|
||||
"Language-Team: Norwegian bokmål <i18n-nb@lister.ping.uio.no>\n"
|
||||
"Language: \n"
|
||||
@ -295,8 +295,7 @@ msgstr "Fest modal dialog til opphavsvinduet"
|
||||
#: ../data/org.gnome.shell.gschema.xml.in.in.h:43
|
||||
msgid ""
|
||||
"This key overrides the key in org.gnome.mutter when running GNOME Shell."
|
||||
msgstr ""
|
||||
"Denne nøkkelen overstyrer nøkkelen i org.gnome.mutter når GNOME Shell kjøres."
|
||||
msgstr "Denne nøkkelen overstyrer nøkkelen i org.gnome.mutter når GNOME Shell kjøres."
|
||||
|
||||
#: ../data/org.gnome.shell.gschema.xml.in.in.h:44
|
||||
msgid "Arrangement of buttons on the titlebar"
|
||||
@ -306,9 +305,7 @@ msgstr "Plassering av knappene på tittellinjen"
|
||||
msgid ""
|
||||
"This key overrides the key in org.gnome.desktop.wm.preferences when running "
|
||||
"GNOME Shell."
|
||||
msgstr ""
|
||||
"Denne nøkkelen overstyrer nøkkelen i org.gnome.desktop.wm.preferences når "
|
||||
"GNOME Shell kjøres."
|
||||
msgstr "Denne nøkkelen overstyrer nøkkelen i org.gnome.desktop.wm.preferences når GNOME Shell kjøres."
|
||||
|
||||
#: ../data/org.gnome.shell.gschema.xml.in.in.h:46
|
||||
msgid "Enable edge tiling when dropping windows on screen edges"
|
||||
@ -342,36 +339,36 @@ msgstr "Økt …"
|
||||
#. translators: this message is shown below the user list on the
|
||||
#. login screen. It can be activated to reveal an entry for
|
||||
#. manually entering the username.
|
||||
#: ../js/gdm/loginDialog.js:630
|
||||
#: ../js/gdm/loginDialog.js:629
|
||||
msgid "Not listed?"
|
||||
msgstr "Ikke listet?"
|
||||
|
||||
#: ../js/gdm/loginDialog.js:786 ../js/ui/components/networkAgent.js:137
|
||||
#: ../js/gdm/loginDialog.js:783 ../js/ui/components/networkAgent.js:137
|
||||
#: ../js/ui/components/polkitAgent.js:162 ../js/ui/endSessionDialog.js:375
|
||||
#: ../js/ui/extensionDownloader.js:195 ../js/ui/shellMountOperation.js:399
|
||||
#: ../js/ui/status/bluetooth.js:415 ../js/ui/unlockDialog.js:99
|
||||
#: ../js/ui/userMenu.js:938
|
||||
#: ../js/ui/status/bluetooth.js:415 ../js/ui/unlockDialog.js:126
|
||||
#: ../js/ui/userMenu.js:934
|
||||
msgid "Cancel"
|
||||
msgstr "Avbryt"
|
||||
|
||||
#: ../js/gdm/loginDialog.js:802
|
||||
#: ../js/gdm/loginDialog.js:799
|
||||
msgctxt "button"
|
||||
msgid "Sign In"
|
||||
msgstr "Logg inn"
|
||||
|
||||
#: ../js/gdm/loginDialog.js:802
|
||||
#: ../js/gdm/loginDialog.js:799
|
||||
msgid "Next"
|
||||
msgstr "Neste"
|
||||
|
||||
#. TTLS and PEAP are actually much more complicated, but this complication
|
||||
#. is not visible here since we only care about phase2 authentication
|
||||
#. (and don't even care of which one)
|
||||
#: ../js/gdm/loginDialog.js:917 ../js/ui/components/networkAgent.js:260
|
||||
#: ../js/gdm/loginDialog.js:904 ../js/ui/components/networkAgent.js:260
|
||||
#: ../js/ui/components/networkAgent.js:278
|
||||
msgid "Username: "
|
||||
msgstr "Brukernavn: "
|
||||
|
||||
#: ../js/gdm/loginDialog.js:1173
|
||||
#: ../js/gdm/loginDialog.js:1157
|
||||
msgid "Login Window"
|
||||
msgstr "Innloggingsvindu"
|
||||
|
||||
@ -380,8 +377,8 @@ msgstr "Innloggingsvindu"
|
||||
msgid "Power"
|
||||
msgstr "Strøm"
|
||||
|
||||
#: ../js/gdm/powerMenu.js:93 ../js/ui/userMenu.js:696 ../js/ui/userMenu.js:700
|
||||
#: ../js/ui/userMenu.js:816
|
||||
#: ../js/gdm/powerMenu.js:93 ../js/ui/userMenu.js:695 ../js/ui/userMenu.js:699
|
||||
#: ../js/ui/userMenu.js:815
|
||||
msgid "Suspend"
|
||||
msgstr "Hvilemodus"
|
||||
|
||||
@ -389,58 +386,58 @@ msgstr "Hvilemodus"
|
||||
msgid "Restart"
|
||||
msgstr "Start på nytt"
|
||||
|
||||
#: ../js/gdm/powerMenu.js:103 ../js/ui/userMenu.js:698
|
||||
#: ../js/ui/userMenu.js:700 ../js/ui/userMenu.js:815 ../js/ui/userMenu.js:942
|
||||
#: ../js/gdm/powerMenu.js:103 ../js/ui/userMenu.js:697
|
||||
#: ../js/ui/userMenu.js:699 ../js/ui/userMenu.js:814 ../js/ui/userMenu.js:938
|
||||
msgid "Power Off"
|
||||
msgstr "Slå av"
|
||||
|
||||
#: ../js/gdm/util.js:249
|
||||
#: ../js/gdm/util.js:182
|
||||
msgid "Authentication error"
|
||||
msgstr "Autentiseringsfeil"
|
||||
|
||||
#. Translators: this message is shown below the password entry field
|
||||
#. to indicate the user can swipe their finger instead
|
||||
#: ../js/gdm/util.js:366
|
||||
#: ../js/gdm/util.js:299
|
||||
msgid "(or swipe finger)"
|
||||
msgstr "(eller dra finger)"
|
||||
|
||||
#: ../js/gdm/util.js:391
|
||||
#: ../js/gdm/util.js:324
|
||||
#, c-format
|
||||
msgid "(e.g., user or %s)"
|
||||
msgstr "(f.eks. bruker eller %s)"
|
||||
|
||||
#: ../js/misc/util.js:97
|
||||
#: ../js/misc/util.js:94
|
||||
msgid "Command not found"
|
||||
msgstr "Kommando ikke funnet"
|
||||
|
||||
#. Replace "Error invoking GLib.shell_parse_argv: " with
|
||||
#. something nicer
|
||||
#: ../js/misc/util.js:130
|
||||
#: ../js/misc/util.js:127
|
||||
msgid "Could not parse command:"
|
||||
msgstr "Klarte ikke å lese kommando:"
|
||||
|
||||
#: ../js/misc/util.js:138
|
||||
#: ../js/misc/util.js:135
|
||||
#, c-format
|
||||
msgid "Execution of '%s' failed:"
|
||||
msgstr "Kjøring av «%s» feilet:"
|
||||
|
||||
#: ../js/ui/appDisplay.js:349
|
||||
#: ../js/ui/appDisplay.js:348
|
||||
msgid "Frequent"
|
||||
msgstr "Ofte"
|
||||
|
||||
#: ../js/ui/appDisplay.js:356
|
||||
#: ../js/ui/appDisplay.js:355
|
||||
msgid "All"
|
||||
msgstr "Alle"
|
||||
|
||||
#: ../js/ui/appDisplay.js:914
|
||||
#: ../js/ui/appDisplay.js:913
|
||||
msgid "New Window"
|
||||
msgstr "Nytt vindu"
|
||||
|
||||
#: ../js/ui/appDisplay.js:917 ../js/ui/dash.js:284
|
||||
#: ../js/ui/appDisplay.js:916 ../js/ui/dash.js:284
|
||||
msgid "Remove from Favorites"
|
||||
msgstr "Fjern fra favoritter"
|
||||
|
||||
#: ../js/ui/appDisplay.js:918
|
||||
#: ../js/ui/appDisplay.js:917
|
||||
msgid "Add to Favorites"
|
||||
msgstr "Legg til i favoritter"
|
||||
|
||||
@ -454,7 +451,7 @@ msgstr "%s ble lagt til i dine favoritter."
|
||||
msgid "%s has been removed from your favorites."
|
||||
msgstr "%s ble fjernet fra dine favoritter."
|
||||
|
||||
#: ../js/ui/backgroundMenu.js:19 ../js/ui/userMenu.js:789
|
||||
#: ../js/ui/backgroundMenu.js:19 ../js/ui/userMenu.js:788
|
||||
msgid "Settings"
|
||||
msgstr "Innstillinger"
|
||||
|
||||
@ -477,7 +474,7 @@ msgctxt "event list time"
|
||||
msgid "%H\\u2236%M"
|
||||
msgstr "%H\\u2336%M"
|
||||
|
||||
#. Translators: Shown in calendar event list, if 12h format,
|
||||
#. Transators: Shown in calendar event list, if 12h format,
|
||||
#. \u2236 is a ratio character, similar to : and \u2009 is
|
||||
#. a thin space
|
||||
#: ../js/ui/calendar.js:77
|
||||
@ -579,35 +576,35 @@ msgid "S"
|
||||
msgstr "Lø"
|
||||
|
||||
#. Translators: Text to show if there are no events
|
||||
#: ../js/ui/calendar.js:720
|
||||
#: ../js/ui/calendar.js:692
|
||||
msgid "Nothing Scheduled"
|
||||
msgstr "Ingenting planlagt"
|
||||
|
||||
#. Translators: Shown on calendar heading when selected day occurs on current year
|
||||
#: ../js/ui/calendar.js:736
|
||||
#: ../js/ui/calendar.js:708
|
||||
msgctxt "calendar heading"
|
||||
msgid "%A, %B %d"
|
||||
msgstr "%A %B %d"
|
||||
|
||||
#. Translators: Shown on calendar heading when selected day occurs on different year
|
||||
#: ../js/ui/calendar.js:739
|
||||
#: ../js/ui/calendar.js:711
|
||||
msgctxt "calendar heading"
|
||||
msgid "%A, %B %d, %Y"
|
||||
msgstr "%A %B %d, %Y"
|
||||
|
||||
#: ../js/ui/calendar.js:749
|
||||
#: ../js/ui/calendar.js:721
|
||||
msgid "Today"
|
||||
msgstr "I dag"
|
||||
|
||||
#: ../js/ui/calendar.js:753
|
||||
#: ../js/ui/calendar.js:725
|
||||
msgid "Tomorrow"
|
||||
msgstr "I morgen"
|
||||
|
||||
#: ../js/ui/calendar.js:764
|
||||
#: ../js/ui/calendar.js:736
|
||||
msgid "This week"
|
||||
msgstr "Denne uken"
|
||||
|
||||
#: ../js/ui/calendar.js:772
|
||||
#: ../js/ui/calendar.js:744
|
||||
msgid "Next week"
|
||||
msgstr "Neste uke"
|
||||
|
||||
@ -623,12 +620,12 @@ msgstr "Ekstern stasjon koblet fra"
|
||||
msgid "Removable Devices"
|
||||
msgstr "Avtagbare enheter"
|
||||
|
||||
#: ../js/ui/components/autorunManager.js:594
|
||||
#: ../js/ui/components/autorunManager.js:593
|
||||
#, c-format
|
||||
msgid "Open with %s"
|
||||
msgstr "Åpne med %s"
|
||||
|
||||
#: ../js/ui/components/autorunManager.js:620
|
||||
#: ../js/ui/components/autorunManager.js:619
|
||||
msgid "Eject"
|
||||
msgstr "Løs ut"
|
||||
|
||||
@ -1010,7 +1007,7 @@ msgstr "Innstillinger for dato og klokkeslett"
|
||||
#. 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").
|
||||
#.
|
||||
#: ../js/ui/dateMenu.js:215
|
||||
#: ../js/ui/dateMenu.js:205
|
||||
msgid "%A %B %e, %Y"
|
||||
msgstr "%a %e %B, %Y"
|
||||
|
||||
@ -1184,15 +1181,15 @@ msgstr "Tøm meldinger"
|
||||
msgid "Notification Settings"
|
||||
msgstr "Innstillinger for varsling"
|
||||
|
||||
#: ../js/ui/messageTray.js:1709
|
||||
#: ../js/ui/messageTray.js:1707
|
||||
msgid "No Messages"
|
||||
msgstr "Ingen meldinger"
|
||||
|
||||
#: ../js/ui/messageTray.js:1782
|
||||
#: ../js/ui/messageTray.js:1787
|
||||
msgid "Message Tray"
|
||||
msgstr "Meldingstrau"
|
||||
|
||||
#: ../js/ui/messageTray.js:2810
|
||||
#: ../js/ui/messageTray.js:2864
|
||||
msgid "System Information"
|
||||
msgstr "Systeminformasjon"
|
||||
|
||||
@ -1201,14 +1198,14 @@ msgctxt "program"
|
||||
msgid "Unknown"
|
||||
msgstr "Ukjent"
|
||||
|
||||
#: ../js/ui/overviewControls.js:463 ../js/ui/screenShield.js:149
|
||||
#: ../js/ui/overviewControls.js:460 ../js/ui/screenShield.js:153
|
||||
#, c-format
|
||||
msgid "%d new message"
|
||||
msgid_plural "%d new messages"
|
||||
msgstr[0] "%d ny melding"
|
||||
msgstr[1] "%d nye meldinger"
|
||||
|
||||
#: ../js/ui/overview.js:84
|
||||
#: ../js/ui/overview.js:82
|
||||
msgid "Undo"
|
||||
msgstr "Angre"
|
||||
|
||||
@ -1220,21 +1217,21 @@ msgstr "Oversikt"
|
||||
#. in the search entry when no search is
|
||||
#. active; it should not exceed ~30
|
||||
#. characters.
|
||||
#: ../js/ui/overview.js:271
|
||||
#: ../js/ui/overview.js:284
|
||||
msgid "Type to search…"
|
||||
msgstr "Skriv for å søke …"
|
||||
|
||||
#: ../js/ui/panel.js:612
|
||||
#: ../js/ui/panel.js:613
|
||||
msgid "Quit"
|
||||
msgstr "Avslutt"
|
||||
|
||||
#. Translators: If there is no suitable word for "Activities"
|
||||
#. in your language, you can use the word for "Overview".
|
||||
#: ../js/ui/panel.js:636
|
||||
#: ../js/ui/panel.js:642
|
||||
msgid "Activities"
|
||||
msgstr "Aktiviteter"
|
||||
|
||||
#: ../js/ui/panel.js:933
|
||||
#: ../js/ui/panel.js:983
|
||||
msgid "Top Bar"
|
||||
msgstr "Topp-panel"
|
||||
|
||||
@ -1247,32 +1244,32 @@ msgstr "Topp-panel"
|
||||
msgid "toggle-switch-us"
|
||||
msgstr "toggle-switch-intl"
|
||||
|
||||
#: ../js/ui/runDialog.js:73
|
||||
#: ../js/ui/runDialog.js:205
|
||||
msgid "Enter a Command"
|
||||
msgstr "Oppgi en kommando"
|
||||
|
||||
#: ../js/ui/runDialog.js:109
|
||||
#: ../js/ui/runDialog.js:241
|
||||
msgid "Close"
|
||||
msgstr "Lukk"
|
||||
|
||||
#. Translators: This is a time format for a date in
|
||||
#. long format
|
||||
#: ../js/ui/screenShield.js:86
|
||||
#: ../js/ui/screenShield.js:90
|
||||
msgid "%A, %B %d"
|
||||
msgstr "%A, %B %d"
|
||||
|
||||
#: ../js/ui/screenShield.js:151
|
||||
#: ../js/ui/screenShield.js:155
|
||||
#, c-format
|
||||
msgid "%d new notification"
|
||||
msgid_plural "%d new notifications"
|
||||
msgstr[0] "%d ny varsling"
|
||||
msgstr[1] "%d nye varslinger"
|
||||
|
||||
#: ../js/ui/screenShield.js:438 ../js/ui/userMenu.js:807
|
||||
#: ../js/ui/screenShield.js:442 ../js/ui/userMenu.js:806
|
||||
msgid "Lock"
|
||||
msgstr "Lås"
|
||||
|
||||
#: ../js/ui/screenShield.js:640
|
||||
#: ../js/ui/screenShield.js:639
|
||||
msgid "GNOME needs to lock the screen"
|
||||
msgstr "GNOME må låse skjermen"
|
||||
|
||||
@ -1283,19 +1280,19 @@ msgstr "GNOME må låse skjermen"
|
||||
#.
|
||||
#. XXX: another option is to kick the user into the gdm login
|
||||
#. screen, where we're not affected by grabs
|
||||
#: ../js/ui/screenShield.js:761 ../js/ui/screenShield.js:1197
|
||||
#: ../js/ui/screenShield.js:758 ../js/ui/screenShield.js:1169
|
||||
msgid "Unable to lock"
|
||||
msgstr "Kan ikke låse"
|
||||
|
||||
#: ../js/ui/screenShield.js:762 ../js/ui/screenShield.js:1198
|
||||
#: ../js/ui/screenShield.js:759 ../js/ui/screenShield.js:1170
|
||||
msgid "Lock was blocked by an application"
|
||||
msgstr "Låsing ble stoppet av et program"
|
||||
|
||||
#: ../js/ui/searchDisplay.js:453
|
||||
#: ../js/ui/searchDisplay.js:431
|
||||
msgid "Searching…"
|
||||
msgstr "Søker …"
|
||||
|
||||
#: ../js/ui/searchDisplay.js:497
|
||||
#: ../js/ui/searchDisplay.js:475
|
||||
msgid "No results."
|
||||
msgstr "Ingen resultater."
|
||||
|
||||
@ -1307,11 +1304,11 @@ msgstr "Kopier"
|
||||
msgid "Paste"
|
||||
msgstr "Lim inn"
|
||||
|
||||
#: ../js/ui/shellEntry.js:106
|
||||
#: ../js/ui/shellEntry.js:105
|
||||
msgid "Show Text"
|
||||
msgstr "Vis tekst"
|
||||
|
||||
#: ../js/ui/shellEntry.js:108
|
||||
#: ../js/ui/shellEntry.js:107
|
||||
msgid "Hide Text"
|
||||
msgstr "Skjul tekst"
|
||||
|
||||
@ -1323,7 +1320,7 @@ msgstr "Passord"
|
||||
msgid "Remember Password"
|
||||
msgstr "Husk passord"
|
||||
|
||||
#: ../js/ui/shellMountOperation.js:403 ../js/ui/unlockDialog.js:113
|
||||
#: ../js/ui/shellMountOperation.js:403 ../js/ui/unlockDialog.js:140
|
||||
msgid "Unlock"
|
||||
msgstr "Lås opp"
|
||||
|
||||
@ -1728,11 +1725,11 @@ msgstr "Volum"
|
||||
msgid "Microphone"
|
||||
msgstr "Mikrofon"
|
||||
|
||||
#: ../js/ui/unlockDialog.js:124
|
||||
#: ../js/ui/unlockDialog.js:151
|
||||
msgid "Log in as another user"
|
||||
msgstr "Logg inn som en annen bruker"
|
||||
|
||||
#: ../js/ui/unlockDialog.js:145
|
||||
#: ../js/ui/unlockDialog.js:177
|
||||
msgid "Unlock Window"
|
||||
msgstr "Lås opp vindu"
|
||||
|
||||
@ -1760,27 +1757,27 @@ msgstr "Ledig"
|
||||
msgid "Offline"
|
||||
msgstr "Frakoblet"
|
||||
|
||||
#: ../js/ui/userMenu.js:781
|
||||
#: ../js/ui/userMenu.js:780
|
||||
msgid "Notifications"
|
||||
msgstr "Varslinger"
|
||||
|
||||
#: ../js/ui/userMenu.js:797
|
||||
#: ../js/ui/userMenu.js:796
|
||||
msgid "Switch User"
|
||||
msgstr "Bytt bruker"
|
||||
|
||||
#: ../js/ui/userMenu.js:802
|
||||
#: ../js/ui/userMenu.js:801
|
||||
msgid "Log Out"
|
||||
msgstr "Logg ut"
|
||||
|
||||
#: ../js/ui/userMenu.js:822
|
||||
#: ../js/ui/userMenu.js:821
|
||||
msgid "Install Updates & Restart"
|
||||
msgstr "Installer oppdateringer og start på nytt"
|
||||
|
||||
#: ../js/ui/userMenu.js:840
|
||||
#: ../js/ui/userMenu.js:839
|
||||
msgid "Your chat status will be set to busy"
|
||||
msgstr "Din pratestatus vil bli satt til opptatt"
|
||||
|
||||
#: ../js/ui/userMenu.js:841
|
||||
#: ../js/ui/userMenu.js:840
|
||||
msgid ""
|
||||
"Notifications are now disabled, including chat messages. Your online status "
|
||||
"has been adjusted to let others know that you might not see their messages."
|
||||
@ -1789,24 +1786,22 @@ msgstr ""
|
||||
"tilkoblingsstatus er justert for å la andre vite at du kanskje ikke ser "
|
||||
"deres meldinger."
|
||||
|
||||
#: ../js/ui/userMenu.js:888
|
||||
#: ../js/ui/userMenu.js:886
|
||||
msgid "Other users are logged in."
|
||||
msgstr "Andre brukere er logget inn."
|
||||
|
||||
#: ../js/ui/userMenu.js:893
|
||||
#: ../js/ui/userMenu.js:891
|
||||
msgid "Shutting down might cause them to lose unsaved work."
|
||||
msgstr ""
|
||||
"Hvis du slår av vil dette kunne medføre at de mister arbeid som ikke er "
|
||||
"lagret."
|
||||
|
||||
#. Translators: Remote here refers to a remote session, like a ssh login
|
||||
#: ../js/ui/userMenu.js:921
|
||||
#: ../js/ui/userMenu.js:918
|
||||
#, c-format
|
||||
msgid "%s (remote)"
|
||||
msgstr "%s (ekstern)"
|
||||
|
||||
#. Translators: Console here refers to a tty like a VT console
|
||||
#: ../js/ui/userMenu.js:924
|
||||
#: ../js/ui/userMenu.js:920
|
||||
#, c-format
|
||||
msgid "%s (console)"
|
||||
msgstr "%s (konsoll)"
|
||||
@ -1819,7 +1814,7 @@ msgstr "Programmer"
|
||||
msgid "Search"
|
||||
msgstr "Søk"
|
||||
|
||||
#: ../js/ui/wanda.js:77
|
||||
#: ../js/ui/wanda.js:92
|
||||
#, c-format
|
||||
msgid ""
|
||||
"Sorry, no wisdom for you today:\n"
|
||||
@ -1828,7 +1823,7 @@ msgstr ""
|
||||
"Beklager, ingen visdom til deg i dag:\n"
|
||||
"%s"
|
||||
|
||||
#: ../js/ui/wanda.js:81
|
||||
#: ../js/ui/wanda.js:96
|
||||
#, c-format
|
||||
msgid "%s the Oracle says"
|
||||
msgstr "Orakelet sier %s"
|
||||
|
307
po/pl.po
307
po/pl.po
@ -6,15 +6,14 @@
|
||||
# -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
|
||||
# Piotr Drąg <piotrdrag@gmail.com>, 2009-2013.
|
||||
# Tomasz Dominikowski <dominikowski@gmail.com>, 2009.
|
||||
# Wojciech Szczęsny <wszczesny@aviary.pl>, 2013.
|
||||
# Aviary.pl <gnomepl@aviary.pl>, 2009-2013.
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: gnome-shell\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2013-04-02 15:54+0200\n"
|
||||
"PO-Revision-Date: 2013-04-02 15:55+0200\n"
|
||||
"Last-Translator: Wojciech Szczęsny <wszczesny@aviary.pl>\n"
|
||||
"POT-Creation-Date: 2013-02-24 01:52+0100\n"
|
||||
"PO-Revision-Date: 2013-02-24 01:53+0100\n"
|
||||
"Last-Translator: Piotr Drąg <piotrdrag@gmail.com>\n"
|
||||
"Language-Team: Polish <gnomepl@aviary.pl>\n"
|
||||
"Language: pl\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
@ -62,7 +61,7 @@ msgid "Window management and application launching"
|
||||
msgstr "Zarządzanie oknami i uruchamianiem programów"
|
||||
|
||||
#: ../data/gnome-shell-extension-prefs.desktop.in.in.h:1
|
||||
#: ../js/extensionPrefs/main.js:153
|
||||
#: ../js/extensionPrefs/main.js:152
|
||||
msgid "GNOME Shell Extension Preferences"
|
||||
msgstr "Preferencje rozszerzenia powłoki GNOME"
|
||||
|
||||
@ -81,7 +80,7 @@ msgid ""
|
||||
"Allows access to internal debugging and monitoring tools using the Alt-F2 "
|
||||
"dialog."
|
||||
msgstr ""
|
||||
"Umożliwia dostęp do wewnętrznych narzędzi debugowania i monitorowania, "
|
||||
"Umożliwia dostęp do wewnętrznych narzędzi debugowania i monitorowania "
|
||||
"używając okna dialogowego Alt-F2."
|
||||
|
||||
#: ../data/org.gnome.shell.gschema.xml.in.in.h:3
|
||||
@ -97,9 +96,9 @@ msgid ""
|
||||
msgstr ""
|
||||
"Rozszerzenia powłoki GNOME posiadają własność UUID; ten klucz zawiera "
|
||||
"rozszerzenia, które powinny zostać wczytane. Każde rozszerzenie, które ma "
|
||||
"zostać wczytane, musi znajdować się na tej liście. Można także manipulować "
|
||||
"tą listą za pomocą metod EnableExtension i DisableExtension usługi D-Bus na "
|
||||
"org.gnome.Shell."
|
||||
"zostać wczytane musi znajdować się na tej liście. Można także manipulować tą "
|
||||
"listą za pomocą metod EnableExtension i DisableExtension usługi D-Bus na org."
|
||||
"gnome.Shell."
|
||||
|
||||
#: ../data/org.gnome.shell.gschema.xml.in.in.h:5
|
||||
msgid "Whether to collect stats about applications usage"
|
||||
@ -113,7 +112,7 @@ msgid ""
|
||||
"remove already saved data."
|
||||
msgstr ""
|
||||
"Powłoka zwykle monitoruje aktywne programy, aby przedstawiać najczęściej "
|
||||
"używane (np. aktywatory programów). Mimo że te dane nie są publiczne, można "
|
||||
"używane (np. aktywatory programów). Mimo, że te dane nie są publiczne, można "
|
||||
"wyłączyć je z powodu prywatności. Proszę zauważyć, że wyłączenie nie "
|
||||
"spowoduje usunięcia już zapisanych danych."
|
||||
|
||||
@ -139,7 +138,7 @@ msgid ""
|
||||
"application view, rather than being displayed inline in the main view."
|
||||
msgstr ""
|
||||
"Każda nazwa kategorii na tej liście będzie przedstawiana jako katalog w "
|
||||
"widoku programów, zamiast wyświetlania jej bezpośrednio w głównym widoku."
|
||||
"widoku programów, zamiast wyświetlać ją bezpośrednio w głównym widoku."
|
||||
|
||||
#: ../data/org.gnome.shell.gschema.xml.in.in.h:11
|
||||
msgid "History for command (Alt-F2) dialog"
|
||||
@ -287,7 +286,7 @@ msgstr ""
|
||||
"Ustawia potok biblioteki GStreamer używany do zakodowania nagrań. Używa "
|
||||
"składni programu gst-launch. Potok powinien posiadać niepołączony odpływ, "
|
||||
"gdzie jest nagrywane. Zwykle taki posiada, a wyjście będzie zapisywane do "
|
||||
"pliku wyjściowego. Mimo że potok może sam zająć się swoim wyjściem, można "
|
||||
"pliku wyjściowego. Mimo, że potok może sam zająć się swoim wyjściem, można "
|
||||
"także wysłać wyjście do serwera icecast przez polecenie shout2send lub "
|
||||
"podobne. Jeśli nie zostanie ustawione lub ustawione na pustą wartość, to "
|
||||
"zostanie użyty domyślny potok. Jest nim obecnie \"vp8enc min_quantizer=13 "
|
||||
@ -360,20 +359,20 @@ msgstr "Dynamiczne zarządzanie obszarami roboczymi"
|
||||
msgid "Workspaces only on primary monitor"
|
||||
msgstr "Obszary robocze tylko na pierwszym monitorze"
|
||||
|
||||
#: ../js/extensionPrefs/main.js:125
|
||||
#: ../js/extensionPrefs/main.js:124
|
||||
#, c-format
|
||||
msgid "There was an error loading the preferences dialog for %s:"
|
||||
msgstr ""
|
||||
"Wystąpił błąd podczas wczytywania okna preferencji dla rozszerzenia %s:"
|
||||
|
||||
#: ../js/extensionPrefs/main.js:165
|
||||
#: ../js/extensionPrefs/main.js:164
|
||||
msgid "Extension"
|
||||
msgstr "Rozszerzenie"
|
||||
|
||||
#: ../js/extensionPrefs/main.js:189
|
||||
#: ../js/extensionPrefs/main.js:188
|
||||
msgid "Select an extension to configure using the combobox above."
|
||||
msgstr ""
|
||||
"Proszę wybrać rozszerzenie do skonfigurowania, używając powyższego pola "
|
||||
"Proszę wybrać rozszerzenie do skonfigurowania używając powyższego pola "
|
||||
"wyboru."
|
||||
|
||||
#: ../js/gdm/loginDialog.js:405
|
||||
@ -383,36 +382,36 @@ msgstr "Sesja…"
|
||||
#. translators: this message is shown below the user list on the
|
||||
#. login screen. It can be activated to reveal an entry for
|
||||
#. manually entering the username.
|
||||
#: ../js/gdm/loginDialog.js:630
|
||||
#: ../js/gdm/loginDialog.js:629
|
||||
msgid "Not listed?"
|
||||
msgstr "Inny użytkownik?"
|
||||
|
||||
#: ../js/gdm/loginDialog.js:786 ../js/ui/components/networkAgent.js:137
|
||||
#: ../js/gdm/loginDialog.js:783 ../js/ui/components/networkAgent.js:137
|
||||
#: ../js/ui/components/polkitAgent.js:162 ../js/ui/endSessionDialog.js:375
|
||||
#: ../js/ui/extensionDownloader.js:195 ../js/ui/shellMountOperation.js:399
|
||||
#: ../js/ui/status/bluetooth.js:415 ../js/ui/unlockDialog.js:99
|
||||
#: ../js/ui/userMenu.js:938
|
||||
#: ../js/ui/status/bluetooth.js:415 ../js/ui/unlockDialog.js:126
|
||||
#: ../js/ui/userMenu.js:932
|
||||
msgid "Cancel"
|
||||
msgstr "Anuluj"
|
||||
|
||||
#: ../js/gdm/loginDialog.js:802
|
||||
#: ../js/gdm/loginDialog.js:799
|
||||
msgctxt "button"
|
||||
msgid "Sign In"
|
||||
msgstr "Zaloguj"
|
||||
|
||||
#: ../js/gdm/loginDialog.js:802
|
||||
#: ../js/gdm/loginDialog.js:799
|
||||
msgid "Next"
|
||||
msgstr "Dalej"
|
||||
|
||||
#. TTLS and PEAP are actually much more complicated, but this complication
|
||||
#. is not visible here since we only care about phase2 authentication
|
||||
#. (and don't even care of which one)
|
||||
#: ../js/gdm/loginDialog.js:917 ../js/ui/components/networkAgent.js:260
|
||||
#: ../js/gdm/loginDialog.js:904 ../js/ui/components/networkAgent.js:260
|
||||
#: ../js/ui/components/networkAgent.js:278
|
||||
msgid "Username: "
|
||||
msgstr "Nazwa użytkownika: "
|
||||
|
||||
#: ../js/gdm/loginDialog.js:1173
|
||||
#: ../js/gdm/loginDialog.js:1157
|
||||
msgid "Login Window"
|
||||
msgstr "Okno logowania"
|
||||
|
||||
@ -421,8 +420,8 @@ msgstr "Okno logowania"
|
||||
msgid "Power"
|
||||
msgstr "Zasilanie"
|
||||
|
||||
#: ../js/gdm/powerMenu.js:93 ../js/ui/userMenu.js:696 ../js/ui/userMenu.js:700
|
||||
#: ../js/ui/userMenu.js:816
|
||||
#: ../js/gdm/powerMenu.js:93 ../js/ui/userMenu.js:694 ../js/ui/userMenu.js:698
|
||||
#: ../js/ui/userMenu.js:814
|
||||
msgid "Suspend"
|
||||
msgstr "Uśpij"
|
||||
|
||||
@ -430,58 +429,58 @@ msgstr "Uśpij"
|
||||
msgid "Restart"
|
||||
msgstr "Uruchom ponownie"
|
||||
|
||||
#: ../js/gdm/powerMenu.js:103 ../js/ui/userMenu.js:698
|
||||
#: ../js/ui/userMenu.js:700 ../js/ui/userMenu.js:815 ../js/ui/userMenu.js:942
|
||||
#: ../js/gdm/powerMenu.js:103 ../js/ui/userMenu.js:696
|
||||
#: ../js/ui/userMenu.js:698 ../js/ui/userMenu.js:813 ../js/ui/userMenu.js:936
|
||||
msgid "Power Off"
|
||||
msgstr "Wyłącz komputer"
|
||||
|
||||
#: ../js/gdm/util.js:249
|
||||
#: ../js/gdm/util.js:182
|
||||
msgid "Authentication error"
|
||||
msgstr "Błąd uwierzytelniania"
|
||||
|
||||
#. Translators: this message is shown below the password entry field
|
||||
#. to indicate the user can swipe their finger instead
|
||||
#: ../js/gdm/util.js:366
|
||||
#: ../js/gdm/util.js:299
|
||||
msgid "(or swipe finger)"
|
||||
msgstr "(lub przeciągnięcie palca)"
|
||||
|
||||
#: ../js/gdm/util.js:391
|
||||
#: ../js/gdm/util.js:324
|
||||
#, c-format
|
||||
msgid "(e.g., user or %s)"
|
||||
msgstr "(np. użytkownik lub %s)"
|
||||
|
||||
#: ../js/misc/util.js:97
|
||||
#: ../js/misc/util.js:94
|
||||
msgid "Command not found"
|
||||
msgstr "Nie odnaleziono polecenia"
|
||||
|
||||
#. Replace "Error invoking GLib.shell_parse_argv: " with
|
||||
#. something nicer
|
||||
#: ../js/misc/util.js:130
|
||||
#: ../js/misc/util.js:127
|
||||
msgid "Could not parse command:"
|
||||
msgstr "Nie można przetworzyć polecenia:"
|
||||
|
||||
#: ../js/misc/util.js:138
|
||||
#: ../js/misc/util.js:135
|
||||
#, c-format
|
||||
msgid "Execution of '%s' failed:"
|
||||
msgstr "Wykonanie polecenia \"%s\" się nie powiodło:"
|
||||
|
||||
#: ../js/ui/appDisplay.js:349
|
||||
#: ../js/ui/appDisplay.js:348
|
||||
msgid "Frequent"
|
||||
msgstr "Często używane"
|
||||
|
||||
#: ../js/ui/appDisplay.js:356
|
||||
#: ../js/ui/appDisplay.js:355
|
||||
msgid "All"
|
||||
msgstr "Wszystkie"
|
||||
|
||||
#: ../js/ui/appDisplay.js:914
|
||||
#: ../js/ui/appDisplay.js:913
|
||||
msgid "New Window"
|
||||
msgstr "Nowe okno"
|
||||
|
||||
#: ../js/ui/appDisplay.js:917 ../js/ui/dash.js:284
|
||||
#: ../js/ui/appDisplay.js:916 ../js/ui/dash.js:284
|
||||
msgid "Remove from Favorites"
|
||||
msgstr "Usuń z ulubionych"
|
||||
|
||||
#: ../js/ui/appDisplay.js:918
|
||||
#: ../js/ui/appDisplay.js:917
|
||||
msgid "Add to Favorites"
|
||||
msgstr "Dodaj do ulubionych"
|
||||
|
||||
@ -495,7 +494,7 @@ msgstr "Program %s został dodany do ulubionych."
|
||||
msgid "%s has been removed from your favorites."
|
||||
msgstr "Program %s został usunięty z ulubionych."
|
||||
|
||||
#: ../js/ui/backgroundMenu.js:19 ../js/ui/userMenu.js:789
|
||||
#: ../js/ui/backgroundMenu.js:19 ../js/ui/userMenu.js:787
|
||||
msgid "Settings"
|
||||
msgstr "Ustawienia"
|
||||
|
||||
@ -518,7 +517,7 @@ msgctxt "event list time"
|
||||
msgid "%H\\u2236%M"
|
||||
msgstr "%H\\u2236%M"
|
||||
|
||||
#. Translators: Shown in calendar event list, if 12h format,
|
||||
#. Transators: Shown in calendar event list, if 12h format,
|
||||
#. \u2236 is a ratio character, similar to : and \u2009 is
|
||||
#. a thin space
|
||||
#: ../js/ui/calendar.js:77
|
||||
@ -620,35 +619,35 @@ msgid "S"
|
||||
msgstr "S"
|
||||
|
||||
#. Translators: Text to show if there are no events
|
||||
#: ../js/ui/calendar.js:720
|
||||
#: ../js/ui/calendar.js:692
|
||||
msgid "Nothing Scheduled"
|
||||
msgstr "Nic nie zaplanowano"
|
||||
|
||||
#. Translators: Shown on calendar heading when selected day occurs on current year
|
||||
#: ../js/ui/calendar.js:736
|
||||
#: ../js/ui/calendar.js:708
|
||||
msgctxt "calendar heading"
|
||||
msgid "%A, %B %d"
|
||||
msgstr "%A, %e %B"
|
||||
|
||||
#. Translators: Shown on calendar heading when selected day occurs on different year
|
||||
#: ../js/ui/calendar.js:739
|
||||
#: ../js/ui/calendar.js:711
|
||||
msgctxt "calendar heading"
|
||||
msgid "%A, %B %d, %Y"
|
||||
msgstr "%A, %e %B %Y"
|
||||
|
||||
#: ../js/ui/calendar.js:749
|
||||
#: ../js/ui/calendar.js:721
|
||||
msgid "Today"
|
||||
msgstr "Dzisiaj"
|
||||
|
||||
#: ../js/ui/calendar.js:753
|
||||
#: ../js/ui/calendar.js:725
|
||||
msgid "Tomorrow"
|
||||
msgstr "Jutro"
|
||||
|
||||
#: ../js/ui/calendar.js:764
|
||||
#: ../js/ui/calendar.js:736
|
||||
msgid "This week"
|
||||
msgstr "Ten tydzień"
|
||||
|
||||
#: ../js/ui/calendar.js:772
|
||||
#: ../js/ui/calendar.js:744
|
||||
msgid "Next week"
|
||||
msgstr "Następny tydzień"
|
||||
|
||||
@ -664,12 +663,12 @@ msgstr "Odłączono dysk zewnętrzny"
|
||||
msgid "Removable Devices"
|
||||
msgstr "Urządzenia wymienne"
|
||||
|
||||
#: ../js/ui/components/autorunManager.js:594
|
||||
#: ../js/ui/components/autorunManager.js:593
|
||||
#, c-format
|
||||
msgid "Open with %s"
|
||||
msgstr "Otwórz za pomocą %s"
|
||||
|
||||
#: ../js/ui/components/autorunManager.js:620
|
||||
#: ../js/ui/components/autorunManager.js:619
|
||||
msgid "Eject"
|
||||
msgstr "Wysuń"
|
||||
|
||||
@ -812,39 +811,39 @@ msgid "Mute"
|
||||
msgstr "Wycisz"
|
||||
|
||||
#. Translators: this is the word "Yesterday" followed by a time string. i.e. "Yesterday, 14:30"
|
||||
#: ../js/ui/components/telepathyClient.js:942
|
||||
#: ../js/ui/components/telepathyClient.js:938
|
||||
#, no-c-format
|
||||
msgid "<b>Yesterday</b>, <b>%H:%M</b>"
|
||||
msgstr "<b>Wczoraj</b> o <b>%H:%M</b>"
|
||||
|
||||
#. Translators: this is the week day name followed by a time string. i.e. "Monday, 14:30
|
||||
#: ../js/ui/components/telepathyClient.js:948
|
||||
#: ../js/ui/components/telepathyClient.js:944
|
||||
#, no-c-format
|
||||
msgid "<b>%A</b>, <b>%H:%M</b>"
|
||||
msgstr "<b>%A</b> o <b>%H:%M</b>"
|
||||
|
||||
#. Translators: this is the month name and day number followed by a time string. i.e. "May 25, 14:30"
|
||||
#: ../js/ui/components/telepathyClient.js:953
|
||||
#: ../js/ui/components/telepathyClient.js:949
|
||||
#, no-c-format
|
||||
msgid "<b>%B</b> <b>%d</b>, <b>%H:%M</b>"
|
||||
msgstr "<b>%d</b> <b>%B</b>, <b>%H:%M</b>"
|
||||
|
||||
#. Translators: this is the month name, day number, year number followed by a time string. i.e. "May 25 2012, 14:30"
|
||||
#: ../js/ui/components/telepathyClient.js:957
|
||||
#: ../js/ui/components/telepathyClient.js:953
|
||||
#, no-c-format
|
||||
msgid "<b>%B</b> <b>%d</b> <b>%Y</b>, <b>%H:%M</b> "
|
||||
msgstr "<b>%d</b> <b>%B</b> <b>%Y</b>, <b>%H:%M</b> "
|
||||
|
||||
#. Translators: this is the other person changing their old IM name to their new
|
||||
#. IM name.
|
||||
#: ../js/ui/components/telepathyClient.js:985
|
||||
#: ../js/ui/components/telepathyClient.js:981
|
||||
#, c-format
|
||||
msgid "%s is now known as %s"
|
||||
msgstr "Użytkownik %s jest teraz znany jako %s"
|
||||
|
||||
#. translators: argument is a room name like
|
||||
#. * room@jabber.org for example.
|
||||
#: ../js/ui/components/telepathyClient.js:1088
|
||||
#: ../js/ui/components/telepathyClient.js:1084
|
||||
#, c-format
|
||||
msgid "Invitation to %s"
|
||||
msgstr "Zaproszenie do pokoju %s"
|
||||
@ -852,38 +851,38 @@ msgstr "Zaproszenie do pokoju %s"
|
||||
#. translators: first argument is the name of a contact and the second
|
||||
#. * one the name of a room. "Alice is inviting you to join room@jabber.org
|
||||
#. * for example.
|
||||
#: ../js/ui/components/telepathyClient.js:1096
|
||||
#: ../js/ui/components/telepathyClient.js:1092
|
||||
#, c-format
|
||||
msgid "%s is inviting you to join %s"
|
||||
msgstr "Użytkownik %s zaprasza do dołączenia do pokoju %s"
|
||||
|
||||
#: ../js/ui/components/telepathyClient.js:1098
|
||||
#: ../js/ui/components/telepathyClient.js:1137
|
||||
#: ../js/ui/components/telepathyClient.js:1177
|
||||
#: ../js/ui/components/telepathyClient.js:1240
|
||||
#: ../js/ui/components/telepathyClient.js:1094
|
||||
#: ../js/ui/components/telepathyClient.js:1133
|
||||
#: ../js/ui/components/telepathyClient.js:1173
|
||||
#: ../js/ui/components/telepathyClient.js:1236
|
||||
msgid "Decline"
|
||||
msgstr "Odmów"
|
||||
|
||||
#: ../js/ui/components/telepathyClient.js:1099
|
||||
#: ../js/ui/components/telepathyClient.js:1178
|
||||
#: ../js/ui/components/telepathyClient.js:1241
|
||||
#: ../js/ui/components/telepathyClient.js:1095
|
||||
#: ../js/ui/components/telepathyClient.js:1174
|
||||
#: ../js/ui/components/telepathyClient.js:1237
|
||||
msgid "Accept"
|
||||
msgstr "Zaakceptuj"
|
||||
|
||||
#. translators: argument is a contact name like Alice for example.
|
||||
#: ../js/ui/components/telepathyClient.js:1129
|
||||
#: ../js/ui/components/telepathyClient.js:1125
|
||||
#, c-format
|
||||
msgid "Video call from %s"
|
||||
msgstr "Wideorozmowa z użytkownikiem %s"
|
||||
|
||||
#. translators: argument is a contact name like Alice for example.
|
||||
#: ../js/ui/components/telepathyClient.js:1132
|
||||
#: ../js/ui/components/telepathyClient.js:1128
|
||||
#, c-format
|
||||
msgid "Call from %s"
|
||||
msgstr "Rozmowa z użytkownikiem %s"
|
||||
|
||||
#. translators: this is a button label (verb), not a noun
|
||||
#: ../js/ui/components/telepathyClient.js:1139
|
||||
#: ../js/ui/components/telepathyClient.js:1135
|
||||
msgid "Answer"
|
||||
msgstr "Odbierz"
|
||||
|
||||
@ -892,111 +891,111 @@ msgstr "Odbierz"
|
||||
#. * file name. The string will be something
|
||||
#. * like: "Alice is sending you test.ogg"
|
||||
#.
|
||||
#: ../js/ui/components/telepathyClient.js:1171
|
||||
#: ../js/ui/components/telepathyClient.js:1167
|
||||
#, c-format
|
||||
msgid "%s is sending you %s"
|
||||
msgstr "Użytkownik %s przysyła plik %s"
|
||||
|
||||
#. To translators: The parameter is the contact's alias
|
||||
#: ../js/ui/components/telepathyClient.js:1206
|
||||
#: ../js/ui/components/telepathyClient.js:1202
|
||||
#, c-format
|
||||
msgid "%s would like permission to see when you are online"
|
||||
msgstr "Użytkownik %s prosi o uprawnienie do wyświetlania stanu"
|
||||
|
||||
#: ../js/ui/components/telepathyClient.js:1298
|
||||
#: ../js/ui/components/telepathyClient.js:1294
|
||||
msgid "Network error"
|
||||
msgstr "Błąd sieci"
|
||||
|
||||
#: ../js/ui/components/telepathyClient.js:1300
|
||||
#: ../js/ui/components/telepathyClient.js:1296
|
||||
msgid "Authentication failed"
|
||||
msgstr "Uwierzytelnienie się nie powiodło"
|
||||
|
||||
#: ../js/ui/components/telepathyClient.js:1302
|
||||
#: ../js/ui/components/telepathyClient.js:1298
|
||||
msgid "Encryption error"
|
||||
msgstr "Błąd szyfrowania"
|
||||
|
||||
#: ../js/ui/components/telepathyClient.js:1304
|
||||
#: ../js/ui/components/telepathyClient.js:1300
|
||||
msgid "Certificate not provided"
|
||||
msgstr "Nie podano certyfikatu"
|
||||
|
||||
#: ../js/ui/components/telepathyClient.js:1306
|
||||
#: ../js/ui/components/telepathyClient.js:1302
|
||||
msgid "Certificate untrusted"
|
||||
msgstr "Certyfikat jest niezaufany"
|
||||
|
||||
#: ../js/ui/components/telepathyClient.js:1308
|
||||
#: ../js/ui/components/telepathyClient.js:1304
|
||||
msgid "Certificate expired"
|
||||
msgstr "Certyfikat wygasł"
|
||||
|
||||
#: ../js/ui/components/telepathyClient.js:1310
|
||||
#: ../js/ui/components/telepathyClient.js:1306
|
||||
msgid "Certificate not activated"
|
||||
msgstr "Certyfikat nie został aktywowany"
|
||||
|
||||
#: ../js/ui/components/telepathyClient.js:1312
|
||||
#: ../js/ui/components/telepathyClient.js:1308
|
||||
msgid "Certificate hostname mismatch"
|
||||
msgstr "Nazwa komputera certyfikatu się nie zgadza"
|
||||
|
||||
#: ../js/ui/components/telepathyClient.js:1314
|
||||
#: ../js/ui/components/telepathyClient.js:1310
|
||||
msgid "Certificate fingerprint mismatch"
|
||||
msgstr "Odcisk palca certyfikatu się nie zgadza"
|
||||
|
||||
#: ../js/ui/components/telepathyClient.js:1316
|
||||
#: ../js/ui/components/telepathyClient.js:1312
|
||||
msgid "Certificate self-signed"
|
||||
msgstr "Certyfikat został samodzielnie podpisany"
|
||||
|
||||
#: ../js/ui/components/telepathyClient.js:1318
|
||||
#: ../js/ui/components/telepathyClient.js:1314
|
||||
msgid "Status is set to offline"
|
||||
msgstr "Stan jest ustawiony na offline"
|
||||
|
||||
#: ../js/ui/components/telepathyClient.js:1320
|
||||
#: ../js/ui/components/telepathyClient.js:1316
|
||||
msgid "Encryption is not available"
|
||||
msgstr "Szyfrowanie jest niedostępne"
|
||||
|
||||
#: ../js/ui/components/telepathyClient.js:1322
|
||||
#: ../js/ui/components/telepathyClient.js:1318
|
||||
msgid "Certificate is invalid"
|
||||
msgstr "Certyfikat jest nieprawidłowy"
|
||||
|
||||
#: ../js/ui/components/telepathyClient.js:1324
|
||||
#: ../js/ui/components/telepathyClient.js:1320
|
||||
msgid "Connection has been refused"
|
||||
msgstr "Odrzucono połączenie"
|
||||
|
||||
#: ../js/ui/components/telepathyClient.js:1326
|
||||
#: ../js/ui/components/telepathyClient.js:1322
|
||||
msgid "Connection can't be established"
|
||||
msgstr "Nie można nawiązać połączenia"
|
||||
|
||||
#: ../js/ui/components/telepathyClient.js:1328
|
||||
#: ../js/ui/components/telepathyClient.js:1324
|
||||
msgid "Connection has been lost"
|
||||
msgstr "Utracono połączenie"
|
||||
|
||||
#: ../js/ui/components/telepathyClient.js:1330
|
||||
#: ../js/ui/components/telepathyClient.js:1326
|
||||
msgid "This account is already connected to the server"
|
||||
msgstr "To konto jest już połączone z serwerem"
|
||||
|
||||
#: ../js/ui/components/telepathyClient.js:1332
|
||||
#: ../js/ui/components/telepathyClient.js:1328
|
||||
msgid ""
|
||||
"Connection has been replaced by a new connection using the same resource"
|
||||
msgstr ""
|
||||
"Połączenie zostało zastąpione nowym z wykorzystaniem tego samego zasobu"
|
||||
|
||||
#: ../js/ui/components/telepathyClient.js:1334
|
||||
#: ../js/ui/components/telepathyClient.js:1330
|
||||
msgid "The account already exists on the server"
|
||||
msgstr "Konto już istnieje na serwerze"
|
||||
|
||||
#: ../js/ui/components/telepathyClient.js:1336
|
||||
#: ../js/ui/components/telepathyClient.js:1332
|
||||
msgid "Server is currently too busy to handle the connection"
|
||||
msgstr "Serwer jest obecnie zbyt zajęty, aby obsłużyć połączenie"
|
||||
|
||||
#: ../js/ui/components/telepathyClient.js:1338
|
||||
#: ../js/ui/components/telepathyClient.js:1334
|
||||
msgid "Certificate has been revoked"
|
||||
msgstr "Certyfikat został unieważniony"
|
||||
|
||||
#: ../js/ui/components/telepathyClient.js:1340
|
||||
#: ../js/ui/components/telepathyClient.js:1336
|
||||
msgid ""
|
||||
"Certificate uses an insecure cipher algorithm or is cryptographically weak"
|
||||
msgstr ""
|
||||
"Certyfikat używa niezabezpieczonego algorytmu szyfrowania lub jest "
|
||||
"kryptograficznie słaby"
|
||||
|
||||
#: ../js/ui/components/telepathyClient.js:1342
|
||||
#: ../js/ui/components/telepathyClient.js:1338
|
||||
msgid ""
|
||||
"The length of the server certificate, or the depth of the server certificate "
|
||||
"chain, exceed the limits imposed by the cryptography library"
|
||||
@ -1004,26 +1003,26 @@ msgstr ""
|
||||
"Długość certyfikatu serwera lub głębokość jego łańcucha przekracza "
|
||||
"ograniczenia nałożone przez bibliotekę kryptograficzną"
|
||||
|
||||
#: ../js/ui/components/telepathyClient.js:1344
|
||||
#: ../js/ui/components/telepathyClient.js:1340
|
||||
msgid "Internal error"
|
||||
msgstr "Błąd wewnętrzny"
|
||||
|
||||
#. translators: argument is the account name, like
|
||||
#. * name@jabber.org for example.
|
||||
#: ../js/ui/components/telepathyClient.js:1354
|
||||
#: ../js/ui/components/telepathyClient.js:1350
|
||||
#, c-format
|
||||
msgid "Unable to connect to %s"
|
||||
msgstr "Nie można połączyć się z kontem %s"
|
||||
|
||||
#: ../js/ui/components/telepathyClient.js:1359
|
||||
#: ../js/ui/components/telepathyClient.js:1355
|
||||
msgid "View account"
|
||||
msgstr "Wyświetl konto"
|
||||
|
||||
#: ../js/ui/components/telepathyClient.js:1398
|
||||
#: ../js/ui/components/telepathyClient.js:1394
|
||||
msgid "Unknown reason"
|
||||
msgstr "Nieznana przyczyna"
|
||||
|
||||
#: ../js/ui/ctrlAltTab.js:29 ../js/ui/viewSelector.js:96
|
||||
#: ../js/ui/ctrlAltTab.js:29 ../js/ui/viewSelector.js:97
|
||||
msgid "Windows"
|
||||
msgstr "Okna"
|
||||
|
||||
@ -1052,7 +1051,7 @@ msgstr "Ustawienia daty i czasu"
|
||||
#. 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").
|
||||
#.
|
||||
#: ../js/ui/dateMenu.js:215
|
||||
#: ../js/ui/dateMenu.js:205
|
||||
msgid "%A %B %e, %Y"
|
||||
msgstr "%A, %e %B %Y"
|
||||
|
||||
@ -1213,23 +1212,23 @@ msgstr "Wyświetl źródło"
|
||||
msgid "Web Page"
|
||||
msgstr "Strona WWW"
|
||||
|
||||
#: ../js/ui/messageTray.js:1182
|
||||
#: ../js/ui/messageTray.js:1177
|
||||
msgid "Open"
|
||||
msgstr "Otwórz"
|
||||
|
||||
#: ../js/ui/messageTray.js:1189
|
||||
#: ../js/ui/messageTray.js:1184
|
||||
msgid "Remove"
|
||||
msgstr "Usuń"
|
||||
|
||||
#: ../js/ui/messageTray.js:1501
|
||||
#: ../js/ui/messageTray.js:1496
|
||||
msgid "Clear Messages"
|
||||
msgstr "Wyczyść wiadomości"
|
||||
|
||||
#: ../js/ui/messageTray.js:1528
|
||||
#: ../js/ui/messageTray.js:1523
|
||||
msgid "Notification Settings"
|
||||
msgstr "Ustawienia powiadomień"
|
||||
|
||||
#: ../js/ui/messageTray.js:1709
|
||||
#: ../js/ui/messageTray.js:1702
|
||||
msgid "No Messages"
|
||||
msgstr "Brak wiadomości"
|
||||
|
||||
@ -1237,7 +1236,7 @@ msgstr "Brak wiadomości"
|
||||
msgid "Message Tray"
|
||||
msgstr "Obszar powiadamiania"
|
||||
|
||||
#: ../js/ui/messageTray.js:2810
|
||||
#: ../js/ui/messageTray.js:2857
|
||||
msgid "System Information"
|
||||
msgstr "Informacje systemowe"
|
||||
|
||||
@ -1246,19 +1245,11 @@ msgctxt "program"
|
||||
msgid "Unknown"
|
||||
msgstr "Nieznany"
|
||||
|
||||
#: ../js/ui/overviewControls.js:463 ../js/ui/screenShield.js:149
|
||||
#, c-format
|
||||
msgid "%d new message"
|
||||
msgid_plural "%d new messages"
|
||||
msgstr[0] "%d nowa wiadomość"
|
||||
msgstr[1] "%d nowe wiadomości"
|
||||
msgstr[2] "%d nowych wiadomości"
|
||||
|
||||
#: ../js/ui/overview.js:84
|
||||
#: ../js/ui/overview.js:81
|
||||
msgid "Undo"
|
||||
msgstr "Cofnij"
|
||||
|
||||
#: ../js/ui/overview.js:129
|
||||
#: ../js/ui/overview.js:124
|
||||
msgid "Overview"
|
||||
msgstr "Podgląd"
|
||||
|
||||
@ -1266,21 +1257,21 @@ msgstr "Podgląd"
|
||||
#. in the search entry when no search is
|
||||
#. active; it should not exceed ~30
|
||||
#. characters.
|
||||
#: ../js/ui/overview.js:271
|
||||
#: ../js/ui/overview.js:272
|
||||
msgid "Type to search…"
|
||||
msgstr "Wyszukiwanie…"
|
||||
|
||||
#: ../js/ui/panel.js:612
|
||||
#: ../js/ui/panel.js:613
|
||||
msgid "Quit"
|
||||
msgstr "Zakończ"
|
||||
|
||||
#. Translators: If there is no suitable word for "Activities"
|
||||
#. in your language, you can use the word for "Overview".
|
||||
#: ../js/ui/panel.js:636
|
||||
#: ../js/ui/panel.js:642
|
||||
msgid "Activities"
|
||||
msgstr "Podgląd"
|
||||
|
||||
#: ../js/ui/panel.js:933
|
||||
#: ../js/ui/panel.js:983
|
||||
msgid "Top Bar"
|
||||
msgstr "Górny pasek"
|
||||
|
||||
@ -1293,21 +1284,29 @@ msgstr "Górny pasek"
|
||||
msgid "toggle-switch-us"
|
||||
msgstr "toggle-switch-intl"
|
||||
|
||||
#: ../js/ui/runDialog.js:73
|
||||
#: ../js/ui/runDialog.js:205
|
||||
msgid "Enter a Command"
|
||||
msgstr "Proszę wprowadzić polecenie"
|
||||
|
||||
#: ../js/ui/runDialog.js:109
|
||||
#: ../js/ui/runDialog.js:241
|
||||
msgid "Close"
|
||||
msgstr "Zamknij"
|
||||
|
||||
#. Translators: This is a time format for a date in
|
||||
#. long format
|
||||
#: ../js/ui/screenShield.js:86
|
||||
#: ../js/ui/screenShield.js:90
|
||||
msgid "%A, %B %d"
|
||||
msgstr "%A, %e %B"
|
||||
|
||||
#: ../js/ui/screenShield.js:151
|
||||
#: ../js/ui/screenShield.js:153
|
||||
#, c-format
|
||||
msgid "%d new message"
|
||||
msgid_plural "%d new messages"
|
||||
msgstr[0] "%d nowa wiadomość"
|
||||
msgstr[1] "%d nowe wiadomości"
|
||||
msgstr[2] "%d nowych wiadomości"
|
||||
|
||||
#: ../js/ui/screenShield.js:155
|
||||
#, c-format
|
||||
msgid "%d new notification"
|
||||
msgid_plural "%d new notifications"
|
||||
@ -1315,11 +1314,11 @@ msgstr[0] "%d nowe powiadomienie"
|
||||
msgstr[1] "%d nowe powiadomienia"
|
||||
msgstr[2] "%d nowych powiadomień"
|
||||
|
||||
#: ../js/ui/screenShield.js:438 ../js/ui/userMenu.js:807
|
||||
#: ../js/ui/screenShield.js:442 ../js/ui/userMenu.js:805
|
||||
msgid "Lock"
|
||||
msgstr "Zablokuj ekran"
|
||||
|
||||
#: ../js/ui/screenShield.js:640
|
||||
#: ../js/ui/screenShield.js:638
|
||||
msgid "GNOME needs to lock the screen"
|
||||
msgstr "Środowisko GNOME musi zablokować ekran"
|
||||
|
||||
@ -1330,19 +1329,19 @@ msgstr "Środowisko GNOME musi zablokować ekran"
|
||||
#.
|
||||
#. XXX: another option is to kick the user into the gdm login
|
||||
#. screen, where we're not affected by grabs
|
||||
#: ../js/ui/screenShield.js:761 ../js/ui/screenShield.js:1197
|
||||
#: ../js/ui/screenShield.js:757 ../js/ui/screenShield.js:1168
|
||||
msgid "Unable to lock"
|
||||
msgstr "Nie można zablokować"
|
||||
|
||||
#: ../js/ui/screenShield.js:762 ../js/ui/screenShield.js:1198
|
||||
#: ../js/ui/screenShield.js:758 ../js/ui/screenShield.js:1169
|
||||
msgid "Lock was blocked by an application"
|
||||
msgstr "Blokowanie zostało zablokowane przez program"
|
||||
|
||||
#: ../js/ui/searchDisplay.js:453
|
||||
#: ../js/ui/searchDisplay.js:431
|
||||
msgid "Searching…"
|
||||
msgstr "Wyszukiwanie…"
|
||||
|
||||
#: ../js/ui/searchDisplay.js:497
|
||||
#: ../js/ui/searchDisplay.js:475
|
||||
msgid "No results."
|
||||
msgstr "Brak wyników."
|
||||
|
||||
@ -1354,11 +1353,11 @@ msgstr "Skopiuj"
|
||||
msgid "Paste"
|
||||
msgstr "Wklej"
|
||||
|
||||
#: ../js/ui/shellEntry.js:106
|
||||
#: ../js/ui/shellEntry.js:105
|
||||
msgid "Show Text"
|
||||
msgstr "Wyświetl tekst"
|
||||
|
||||
#: ../js/ui/shellEntry.js:108
|
||||
#: ../js/ui/shellEntry.js:107
|
||||
msgid "Hide Text"
|
||||
msgstr "Ukryj tekst"
|
||||
|
||||
@ -1370,7 +1369,7 @@ msgstr "Hasło"
|
||||
msgid "Remember Password"
|
||||
msgstr "Zapamiętanie hasła"
|
||||
|
||||
#: ../js/ui/shellMountOperation.js:403 ../js/ui/unlockDialog.js:113
|
||||
#: ../js/ui/shellMountOperation.js:403 ../js/ui/unlockDialog.js:140
|
||||
msgid "Unlock"
|
||||
msgstr "Odblokuj"
|
||||
|
||||
@ -1779,59 +1778,59 @@ msgstr "Głośność"
|
||||
msgid "Microphone"
|
||||
msgstr "Mikrofon"
|
||||
|
||||
#: ../js/ui/unlockDialog.js:124
|
||||
#: ../js/ui/unlockDialog.js:151
|
||||
msgid "Log in as another user"
|
||||
msgstr "Zaloguj jako inny użytkownik"
|
||||
|
||||
#: ../js/ui/unlockDialog.js:145
|
||||
#: ../js/ui/unlockDialog.js:177
|
||||
msgid "Unlock Window"
|
||||
msgstr "Okno odblokowania"
|
||||
|
||||
#: ../js/ui/userMenu.js:193
|
||||
#: ../js/ui/userMenu.js:192
|
||||
msgid "Available"
|
||||
msgstr "Dostępny"
|
||||
|
||||
#: ../js/ui/userMenu.js:196
|
||||
#: ../js/ui/userMenu.js:195
|
||||
msgid "Busy"
|
||||
msgstr "Zajęty"
|
||||
|
||||
#: ../js/ui/userMenu.js:199
|
||||
#: ../js/ui/userMenu.js:198
|
||||
msgid "Invisible"
|
||||
msgstr "Niewidoczny"
|
||||
|
||||
#: ../js/ui/userMenu.js:202
|
||||
#: ../js/ui/userMenu.js:201
|
||||
msgid "Away"
|
||||
msgstr "Nieobecny"
|
||||
|
||||
#: ../js/ui/userMenu.js:205
|
||||
#: ../js/ui/userMenu.js:204
|
||||
msgid "Idle"
|
||||
msgstr "Bezczynny"
|
||||
|
||||
#: ../js/ui/userMenu.js:208
|
||||
#: ../js/ui/userMenu.js:207
|
||||
msgid "Offline"
|
||||
msgstr "Offline"
|
||||
|
||||
#: ../js/ui/userMenu.js:781
|
||||
#: ../js/ui/userMenu.js:779
|
||||
msgid "Notifications"
|
||||
msgstr "Powiadomienia"
|
||||
|
||||
#: ../js/ui/userMenu.js:797
|
||||
#: ../js/ui/userMenu.js:795
|
||||
msgid "Switch User"
|
||||
msgstr "Przełącz użytkownika"
|
||||
|
||||
#: ../js/ui/userMenu.js:802
|
||||
#: ../js/ui/userMenu.js:800
|
||||
msgid "Log Out"
|
||||
msgstr "Wyloguj się"
|
||||
|
||||
#: ../js/ui/userMenu.js:822
|
||||
#: ../js/ui/userMenu.js:820
|
||||
msgid "Install Updates & Restart"
|
||||
msgstr "Zaktualizuj i uruchom ponownie"
|
||||
|
||||
#: ../js/ui/userMenu.js:840
|
||||
#: ../js/ui/userMenu.js:838
|
||||
msgid "Your chat status will be set to busy"
|
||||
msgstr "Stan komunikatora zostanie ustawiony na \"zajęty\""
|
||||
|
||||
#: ../js/ui/userMenu.js:841
|
||||
#: ../js/ui/userMenu.js:839
|
||||
msgid ""
|
||||
"Notifications are now disabled, including chat messages. Your online status "
|
||||
"has been adjusted to let others know that you might not see their messages."
|
||||
@ -1841,35 +1840,33 @@ msgstr ""
|
||||
"użytkownik tego komputera może nie zobaczyć przychodzących od nich "
|
||||
"wiadomości."
|
||||
|
||||
#: ../js/ui/userMenu.js:888
|
||||
#: ../js/ui/userMenu.js:885
|
||||
msgid "Other users are logged in."
|
||||
msgstr "Inni użytkownicy są zalogowani."
|
||||
|
||||
#: ../js/ui/userMenu.js:893
|
||||
#: ../js/ui/userMenu.js:890
|
||||
msgid "Shutting down might cause them to lose unsaved work."
|
||||
msgstr "Wyłączenie komputera może spowodować utratę danych."
|
||||
|
||||
#. Translators: Remote here refers to a remote session, like a ssh login
|
||||
#: ../js/ui/userMenu.js:921
|
||||
#: ../js/ui/userMenu.js:916
|
||||
#, c-format
|
||||
msgid "%s (remote)"
|
||||
msgstr "%s (zdalnie)"
|
||||
|
||||
#. Translators: Console here refers to a tty like a VT console
|
||||
#: ../js/ui/userMenu.js:924
|
||||
#: ../js/ui/userMenu.js:918
|
||||
#, c-format
|
||||
msgid "%s (console)"
|
||||
msgstr "%s (konsola)"
|
||||
|
||||
#: ../js/ui/viewSelector.js:100
|
||||
#: ../js/ui/viewSelector.js:101
|
||||
msgid "Applications"
|
||||
msgstr "Programy"
|
||||
|
||||
#: ../js/ui/viewSelector.js:104
|
||||
#: ../js/ui/viewSelector.js:105
|
||||
msgid "Search"
|
||||
msgstr "Wyszukiwanie"
|
||||
|
||||
#: ../js/ui/wanda.js:77
|
||||
#: ../js/ui/wanda.js:92
|
||||
#, c-format
|
||||
msgid ""
|
||||
"Sorry, no wisdom for you today:\n"
|
||||
@ -1878,7 +1875,7 @@ msgstr ""
|
||||
"Nic mądrego na dzisiaj:\n"
|
||||
"%s"
|
||||
|
||||
#: ../js/ui/wanda.js:81
|
||||
#: ../js/ui/wanda.js:96
|
||||
#, c-format
|
||||
msgid "%s the Oracle says"
|
||||
msgstr "Wyrocznia %s przemawia"
|
||||
|
193
po/ru.po
193
po/ru.po
@ -15,8 +15,8 @@ msgstr ""
|
||||
"Project-Id-Version: gnome-shell\n"
|
||||
"Report-Msgid-Bugs-To: http://bugzilla.gnome.org/enter_bug.cgi?product=gnome-"
|
||||
"shell&keywords=I18N+L10N&component=general\n"
|
||||
"POT-Creation-Date: 2013-03-14 18:11+0000\n"
|
||||
"PO-Revision-Date: 2013-03-22 21:02+0400\n"
|
||||
"POT-Creation-Date: 2013-03-03 12:52+0000\n"
|
||||
"PO-Revision-Date: 2013-03-03 23:21+0400\n"
|
||||
"Last-Translator: Yuri Myasoedov <omerta13@yandex.ru>\n"
|
||||
"Language-Team: русский <gnome-cyr@gnome.org>\n"
|
||||
"Language: ru\n"
|
||||
@ -142,11 +142,11 @@ msgstr ""
|
||||
|
||||
#: ../data/org.gnome.shell.gschema.xml.in.in.h:11
|
||||
msgid "History for command (Alt-F2) dialog"
|
||||
msgstr "История команд диалогового окна (Alt-F2)"
|
||||
msgstr "История команд диалога (Alt-F2)"
|
||||
|
||||
#: ../data/org.gnome.shell.gschema.xml.in.in.h:12
|
||||
msgid "History for the looking glass dialog"
|
||||
msgstr "История просмотра прозрачного диалогового окна"
|
||||
msgstr "История просмотра прозрачного диалога"
|
||||
|
||||
#: ../data/org.gnome.shell.gschema.xml.in.in.h:13
|
||||
msgid ""
|
||||
@ -223,11 +223,11 @@ msgstr "Комбинация клавиш для перехода в режим
|
||||
|
||||
#: ../data/org.gnome.shell.gschema.xml.in.in.h:25
|
||||
msgid "Keybinding to toggle the visibility of the message tray"
|
||||
msgstr "Комбинация клавиш для отображения или скрытия панели сообщений"
|
||||
msgstr "Комбинация клавиш для показа и скрытия панели сообщений"
|
||||
|
||||
#: ../data/org.gnome.shell.gschema.xml.in.in.h:26
|
||||
msgid "Keybinding to toggle the visibility of the message tray."
|
||||
msgstr "Комбинация клавиш для отображения или скрытия панели сообщений."
|
||||
msgstr "Комбинация клавиш для показа и скрытия панели сообщений."
|
||||
|
||||
#: ../data/org.gnome.shell.gschema.xml.in.in.h:27
|
||||
msgid "Keybinding to focus the active notification"
|
||||
@ -239,13 +239,12 @@ msgstr "Комбинация клавиш для перевода фокуса
|
||||
|
||||
#: ../data/org.gnome.shell.gschema.xml.in.in.h:29
|
||||
msgid "Keybinding to toggle the screen recorder"
|
||||
msgstr "Комбинация клавиш для включения или выключения средства записи экрана"
|
||||
msgstr "Комбинация клавиш для включения и выключения средства записи экрана"
|
||||
|
||||
#: ../data/org.gnome.shell.gschema.xml.in.in.h:30
|
||||
msgid "Keybinding to start/stop the builtin screen recorder."
|
||||
msgstr ""
|
||||
"Комбинация клавиш для запуска или остановки встроенного средства записи "
|
||||
"экрана."
|
||||
"Комбинация клавиш для запуска и останова встроенного средства записи экрана."
|
||||
|
||||
#: ../data/org.gnome.shell.gschema.xml.in.in.h:31
|
||||
msgid "Which keyboard to use"
|
||||
@ -264,8 +263,8 @@ msgid ""
|
||||
"The framerate of the resulting screencast recordered by GNOME Shell's "
|
||||
"screencast recorder in frames-per-second."
|
||||
msgstr ""
|
||||
"Частота смены кадров (кадров/сек) скринкаста, записанного с помощью GNOME "
|
||||
"Shell."
|
||||
"Частота смены кадров в скринкасте, записанном с помощью GNOME Shell (кадров/"
|
||||
"сек)."
|
||||
|
||||
#: ../data/org.gnome.shell.gschema.xml.in.in.h:35
|
||||
msgid "The gstreamer pipeline used to encode the screencast"
|
||||
@ -300,7 +299,7 @@ msgstr ""
|
||||
|
||||
#: ../data/org.gnome.shell.gschema.xml.in.in.h:38
|
||||
msgid "File extension used for storing the screencast"
|
||||
msgstr "Расширение файла, используемое при сохранении скринкастов"
|
||||
msgstr "Расширение файла, использующееся для хранения скринкастов"
|
||||
|
||||
#: ../data/org.gnome.shell.gschema.xml.in.in.h:39
|
||||
msgid ""
|
||||
@ -308,9 +307,9 @@ msgid ""
|
||||
"current date, and use this extension. It should be changed when recording to "
|
||||
"a different container format."
|
||||
msgstr ""
|
||||
"Имя файла записанного скринкаста будет уникальным, основанным на текущей "
|
||||
"дате и используемом расширении. Оно должно быть изменено, если запись "
|
||||
"выполняется в другой формат контейнера."
|
||||
"Имя файла записанного скринкаста будет уникальным именем, основанным на "
|
||||
"текущей дате, и использует это расширение. Оно должно быть изменено, если "
|
||||
"запись выполняется в другой контейнерный формат."
|
||||
|
||||
#: ../data/org.gnome.shell.gschema.xml.in.in.h:40
|
||||
msgid "The application icon mode."
|
||||
@ -365,7 +364,7 @@ msgstr "Рабочие места только на основном монит
|
||||
#: ../js/extensionPrefs/main.js:125
|
||||
#, c-format
|
||||
msgid "There was an error loading the preferences dialog for %s:"
|
||||
msgstr "При загрузке диалогового окна параметров для %s произошла ошибка:"
|
||||
msgstr "При загрузке диалога параметров для %s произошла ошибка:"
|
||||
|
||||
#: ../js/extensionPrefs/main.js:165
|
||||
msgid "Extension"
|
||||
@ -382,46 +381,46 @@ msgstr "Сеанс…"
|
||||
#. translators: this message is shown below the user list on the
|
||||
#. login screen. It can be activated to reveal an entry for
|
||||
#. manually entering the username.
|
||||
#: ../js/gdm/loginDialog.js:630
|
||||
#: ../js/gdm/loginDialog.js:629
|
||||
msgid "Not listed?"
|
||||
msgstr "Нет в списке?"
|
||||
|
||||
#: ../js/gdm/loginDialog.js:784 ../js/ui/components/networkAgent.js:137
|
||||
#: ../js/gdm/loginDialog.js:783 ../js/ui/components/networkAgent.js:137
|
||||
#: ../js/ui/components/polkitAgent.js:162 ../js/ui/endSessionDialog.js:375
|
||||
#: ../js/ui/extensionDownloader.js:195 ../js/ui/shellMountOperation.js:399
|
||||
#: ../js/ui/status/bluetooth.js:415 ../js/ui/unlockDialog.js:98
|
||||
#: ../js/ui/userMenu.js:938
|
||||
#: ../js/ui/status/bluetooth.js:415 ../js/ui/unlockDialog.js:126
|
||||
#: ../js/ui/userMenu.js:934
|
||||
msgid "Cancel"
|
||||
msgstr "Отмена"
|
||||
|
||||
#: ../js/gdm/loginDialog.js:800
|
||||
#: ../js/gdm/loginDialog.js:799
|
||||
msgctxt "button"
|
||||
msgid "Sign In"
|
||||
msgstr "Войти"
|
||||
|
||||
#: ../js/gdm/loginDialog.js:800
|
||||
#: ../js/gdm/loginDialog.js:799
|
||||
msgid "Next"
|
||||
msgstr "Далее"
|
||||
msgstr "Следующий"
|
||||
|
||||
#. TTLS and PEAP are actually much more complicated, but this complication
|
||||
#. is not visible here since we only care about phase2 authentication
|
||||
#. (and don't even care of which one)
|
||||
#: ../js/gdm/loginDialog.js:915 ../js/ui/components/networkAgent.js:260
|
||||
#: ../js/gdm/loginDialog.js:904 ../js/ui/components/networkAgent.js:260
|
||||
#: ../js/ui/components/networkAgent.js:278
|
||||
msgid "Username: "
|
||||
msgstr "Имя пользователя: "
|
||||
|
||||
#: ../js/gdm/loginDialog.js:1159
|
||||
#: ../js/gdm/loginDialog.js:1157
|
||||
msgid "Login Window"
|
||||
msgstr "Окно входа в систему"
|
||||
|
||||
#. Translators: accessible name of the power menu in the login screen
|
||||
#: ../js/gdm/powerMenu.js:36
|
||||
msgid "Power"
|
||||
msgstr "Электропитание"
|
||||
msgstr "Питание"
|
||||
|
||||
#: ../js/gdm/powerMenu.js:93 ../js/ui/userMenu.js:696 ../js/ui/userMenu.js:700
|
||||
#: ../js/ui/userMenu.js:816
|
||||
#: ../js/gdm/powerMenu.js:93 ../js/ui/userMenu.js:695 ../js/ui/userMenu.js:699
|
||||
#: ../js/ui/userMenu.js:815
|
||||
msgid "Suspend"
|
||||
msgstr "Ждущий режим"
|
||||
|
||||
@ -429,14 +428,14 @@ msgstr "Ждущий режим"
|
||||
msgid "Restart"
|
||||
msgstr "Перезапустить"
|
||||
|
||||
#: ../js/gdm/powerMenu.js:103 ../js/ui/userMenu.js:698
|
||||
#: ../js/ui/userMenu.js:700 ../js/ui/userMenu.js:815 ../js/ui/userMenu.js:942
|
||||
#: ../js/gdm/powerMenu.js:103 ../js/ui/userMenu.js:697
|
||||
#: ../js/ui/userMenu.js:699 ../js/ui/userMenu.js:814 ../js/ui/userMenu.js:938
|
||||
msgid "Power Off"
|
||||
msgstr "Выключить"
|
||||
|
||||
#: ../js/gdm/util.js:182
|
||||
msgid "Authentication error"
|
||||
msgstr "Ошибка проверки подлинности"
|
||||
msgstr "Ошибка подтверждения подлинности"
|
||||
|
||||
#. Translators: this message is shown below the password entry field
|
||||
#. to indicate the user can swipe their finger instead
|
||||
@ -449,38 +448,38 @@ msgstr "(или проведите пальцем по считывающему
|
||||
msgid "(e.g., user or %s)"
|
||||
msgstr "(например, пользователь или %s)"
|
||||
|
||||
#: ../js/misc/util.js:97
|
||||
#: ../js/misc/util.js:94
|
||||
msgid "Command not found"
|
||||
msgstr "Команда не найдена"
|
||||
|
||||
#. Replace "Error invoking GLib.shell_parse_argv: " with
|
||||
#. something nicer
|
||||
#: ../js/misc/util.js:130
|
||||
#: ../js/misc/util.js:127
|
||||
msgid "Could not parse command:"
|
||||
msgstr "Не удалось разобрать команду:"
|
||||
|
||||
#: ../js/misc/util.js:138
|
||||
#: ../js/misc/util.js:135
|
||||
#, c-format
|
||||
msgid "Execution of '%s' failed:"
|
||||
msgstr "Не удалось выполнить «%s»:"
|
||||
|
||||
#: ../js/ui/appDisplay.js:325
|
||||
#: ../js/ui/appDisplay.js:348
|
||||
msgid "Frequent"
|
||||
msgstr "Популярные"
|
||||
msgstr "Часто используемые"
|
||||
|
||||
#: ../js/ui/appDisplay.js:332
|
||||
#: ../js/ui/appDisplay.js:355
|
||||
msgid "All"
|
||||
msgstr "Все"
|
||||
|
||||
#: ../js/ui/appDisplay.js:890
|
||||
#: ../js/ui/appDisplay.js:913
|
||||
msgid "New Window"
|
||||
msgstr "Новое окно"
|
||||
|
||||
#: ../js/ui/appDisplay.js:893 ../js/ui/dash.js:284
|
||||
#: ../js/ui/appDisplay.js:916 ../js/ui/dash.js:284
|
||||
msgid "Remove from Favorites"
|
||||
msgstr "Удалить из избранного"
|
||||
|
||||
#: ../js/ui/appDisplay.js:894
|
||||
#: ../js/ui/appDisplay.js:917
|
||||
msgid "Add to Favorites"
|
||||
msgstr "Добавить в избранное"
|
||||
|
||||
@ -494,7 +493,7 @@ msgstr "Приложение %s добавлено в избранное."
|
||||
msgid "%s has been removed from your favorites."
|
||||
msgstr "Приложение %s удалено из избранного."
|
||||
|
||||
#: ../js/ui/backgroundMenu.js:19 ../js/ui/userMenu.js:789
|
||||
#: ../js/ui/backgroundMenu.js:19 ../js/ui/userMenu.js:788
|
||||
msgid "Settings"
|
||||
msgstr "Параметры"
|
||||
|
||||
@ -619,35 +618,35 @@ msgid "S"
|
||||
msgstr "Сб"
|
||||
|
||||
#. Translators: Text to show if there are no events
|
||||
#: ../js/ui/calendar.js:720
|
||||
#: ../js/ui/calendar.js:692
|
||||
msgid "Nothing Scheduled"
|
||||
msgstr "Нет событий"
|
||||
|
||||
#. Translators: Shown on calendar heading when selected day occurs on current year
|
||||
#: ../js/ui/calendar.js:736
|
||||
#: ../js/ui/calendar.js:708
|
||||
msgctxt "calendar heading"
|
||||
msgid "%A, %B %d"
|
||||
msgstr "%A, %B %d"
|
||||
|
||||
#. Translators: Shown on calendar heading when selected day occurs on different year
|
||||
#: ../js/ui/calendar.js:739
|
||||
#: ../js/ui/calendar.js:711
|
||||
msgctxt "calendar heading"
|
||||
msgid "%A, %B %d, %Y"
|
||||
msgstr "%A, %B %d, %Y"
|
||||
|
||||
#: ../js/ui/calendar.js:749
|
||||
#: ../js/ui/calendar.js:721
|
||||
msgid "Today"
|
||||
msgstr "Сегодня"
|
||||
|
||||
#: ../js/ui/calendar.js:753
|
||||
#: ../js/ui/calendar.js:725
|
||||
msgid "Tomorrow"
|
||||
msgstr "Завтра"
|
||||
|
||||
#: ../js/ui/calendar.js:764
|
||||
#: ../js/ui/calendar.js:736
|
||||
msgid "This week"
|
||||
msgstr "Эта неделя"
|
||||
|
||||
#: ../js/ui/calendar.js:772
|
||||
#: ../js/ui/calendar.js:744
|
||||
msgid "Next week"
|
||||
msgstr "Следующая неделя"
|
||||
|
||||
@ -744,7 +743,7 @@ msgstr "Для широкополосного мобильного устрой
|
||||
|
||||
#: ../js/ui/components/networkAgent.js:330
|
||||
msgid "PIN: "
|
||||
msgstr "PIN-код: "
|
||||
msgstr "PIN: "
|
||||
|
||||
#: ../js/ui/components/networkAgent.js:336
|
||||
msgid "Mobile broadband network password"
|
||||
@ -773,7 +772,7 @@ msgstr "Подтвердить"
|
||||
#. * for instance.
|
||||
#: ../js/ui/components/polkitAgent.js:256 ../js/ui/shellMountOperation.js:383
|
||||
msgid "Sorry, that didn't work. Please try again."
|
||||
msgstr "Не удалось подтвердить подлинность. Попробуйте снова."
|
||||
msgstr "Извините, это не сработало. Попробуйте снова."
|
||||
|
||||
#. Translators: this is a filename used for screencast recording
|
||||
#: ../js/ui/components/recorder.js:48
|
||||
@ -1021,7 +1020,7 @@ msgstr "Показать учётную запись"
|
||||
msgid "Unknown reason"
|
||||
msgstr "Неизвестная причина"
|
||||
|
||||
#: ../js/ui/ctrlAltTab.js:29 ../js/ui/viewSelector.js:96
|
||||
#: ../js/ui/ctrlAltTab.js:29 ../js/ui/viewSelector.js:97
|
||||
msgid "Windows"
|
||||
msgstr "Окна"
|
||||
|
||||
@ -1050,7 +1049,7 @@ msgstr "Настроить дату и время"
|
||||
#. 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").
|
||||
#.
|
||||
#: ../js/ui/dateMenu.js:215
|
||||
#: ../js/ui/dateMenu.js:205
|
||||
msgid "%A %B %e, %Y"
|
||||
msgstr "%A, %e %B, %Y"
|
||||
|
||||
@ -1058,7 +1057,7 @@ msgstr "%A, %e %B, %Y"
|
||||
#, c-format
|
||||
msgctxt "title"
|
||||
msgid "Log Out %s"
|
||||
msgstr "Завершение сеанса пользователя %s"
|
||||
msgstr "Завершить сеанс пользователя %s"
|
||||
|
||||
#: ../js/ui/endSessionDialog.js:64
|
||||
msgctxt "title"
|
||||
@ -1229,15 +1228,15 @@ msgstr "Очистить список сообщений"
|
||||
msgid "Notification Settings"
|
||||
msgstr "Параметры уведомлений"
|
||||
|
||||
#: ../js/ui/messageTray.js:1711
|
||||
#: ../js/ui/messageTray.js:1707
|
||||
msgid "No Messages"
|
||||
msgstr "Нет сообщений"
|
||||
|
||||
#: ../js/ui/messageTray.js:1784
|
||||
#: ../js/ui/messageTray.js:1787
|
||||
msgid "Message Tray"
|
||||
msgstr "Панель сообщений"
|
||||
|
||||
#: ../js/ui/messageTray.js:2816
|
||||
#: ../js/ui/messageTray.js:2864
|
||||
msgid "System Information"
|
||||
msgstr "Системная информация"
|
||||
|
||||
@ -1246,7 +1245,7 @@ msgctxt "program"
|
||||
msgid "Unknown"
|
||||
msgstr "Неизвестно"
|
||||
|
||||
#: ../js/ui/overviewControls.js:463 ../js/ui/screenShield.js:148
|
||||
#: ../js/ui/overviewControls.js:460 ../js/ui/screenShield.js:153
|
||||
#, c-format
|
||||
msgid "%d new message"
|
||||
msgid_plural "%d new messages"
|
||||
@ -1254,7 +1253,7 @@ msgstr[0] "%d новое сообщение"
|
||||
msgstr[1] "%d новых сообщения"
|
||||
msgstr[2] "%d новых сообщений"
|
||||
|
||||
#: ../js/ui/overview.js:84
|
||||
#: ../js/ui/overview.js:82
|
||||
msgid "Undo"
|
||||
msgstr "Отменить"
|
||||
|
||||
@ -1266,21 +1265,21 @@ msgstr "Обзор"
|
||||
#. in the search entry when no search is
|
||||
#. active; it should not exceed ~30
|
||||
#. characters.
|
||||
#: ../js/ui/overview.js:271
|
||||
#: ../js/ui/overview.js:284
|
||||
msgid "Type to search…"
|
||||
msgstr "Найти…"
|
||||
|
||||
#: ../js/ui/panel.js:612
|
||||
#: ../js/ui/panel.js:613
|
||||
msgid "Quit"
|
||||
msgstr "Закрыть"
|
||||
|
||||
#. Translators: If there is no suitable word for "Activities"
|
||||
#. in your language, you can use the word for "Overview".
|
||||
#: ../js/ui/panel.js:636
|
||||
#: ../js/ui/panel.js:642
|
||||
msgid "Activities"
|
||||
msgstr "Обзор"
|
||||
|
||||
#: ../js/ui/panel.js:933
|
||||
#: ../js/ui/panel.js:983
|
||||
msgid "Top Bar"
|
||||
msgstr "Верхняя панель"
|
||||
|
||||
@ -1293,33 +1292,33 @@ msgstr "Верхняя панель"
|
||||
msgid "toggle-switch-us"
|
||||
msgstr "toggle-switch-intl"
|
||||
|
||||
#: ../js/ui/runDialog.js:73
|
||||
#: ../js/ui/runDialog.js:205
|
||||
msgid "Enter a Command"
|
||||
msgstr "Введите команду"
|
||||
|
||||
#: ../js/ui/runDialog.js:109
|
||||
#: ../js/ui/runDialog.js:241
|
||||
msgid "Close"
|
||||
msgstr "Закрыть"
|
||||
|
||||
#. Translators: This is a time format for a date in
|
||||
#. long format
|
||||
#: ../js/ui/screenShield.js:85
|
||||
#: ../js/ui/screenShield.js:90
|
||||
msgid "%A, %B %d"
|
||||
msgstr "%d %B, %A"
|
||||
|
||||
#: ../js/ui/screenShield.js:150
|
||||
#: ../js/ui/screenShield.js:155
|
||||
#, c-format
|
||||
msgid "%d new notification"
|
||||
msgid_plural "%d new notifications"
|
||||
msgstr[0] "%d новое уведомление"
|
||||
msgstr[1] "%d новых уведомления"
|
||||
msgstr[0] "%d новые уведомление"
|
||||
msgstr[1] "%d новых уведомленя"
|
||||
msgstr[2] "%d новых уведомлений"
|
||||
|
||||
#: ../js/ui/screenShield.js:437 ../js/ui/userMenu.js:807
|
||||
#: ../js/ui/screenShield.js:442 ../js/ui/userMenu.js:806
|
||||
msgid "Lock"
|
||||
msgstr "Заблокировать"
|
||||
|
||||
#: ../js/ui/screenShield.js:635
|
||||
#: ../js/ui/screenShield.js:639
|
||||
msgid "GNOME needs to lock the screen"
|
||||
msgstr "GNOME необходимо заблокировать экран"
|
||||
|
||||
@ -1330,19 +1329,19 @@ msgstr "GNOME необходимо заблокировать экран"
|
||||
#.
|
||||
#. XXX: another option is to kick the user into the gdm login
|
||||
#. screen, where we're not affected by grabs
|
||||
#: ../js/ui/screenShield.js:756 ../js/ui/screenShield.js:1151
|
||||
#: ../js/ui/screenShield.js:758 ../js/ui/screenShield.js:1169
|
||||
msgid "Unable to lock"
|
||||
msgstr "Не удалось заблокировать"
|
||||
|
||||
#: ../js/ui/screenShield.js:757 ../js/ui/screenShield.js:1152
|
||||
#: ../js/ui/screenShield.js:759 ../js/ui/screenShield.js:1170
|
||||
msgid "Lock was blocked by an application"
|
||||
msgstr "Блокировке помешало приложение"
|
||||
msgstr "Блокировано помешало приложение"
|
||||
|
||||
#: ../js/ui/searchDisplay.js:451
|
||||
#: ../js/ui/searchDisplay.js:431
|
||||
msgid "Searching…"
|
||||
msgstr "Поиск…"
|
||||
|
||||
#: ../js/ui/searchDisplay.js:495
|
||||
#: ../js/ui/searchDisplay.js:475
|
||||
msgid "No results."
|
||||
msgstr "Нет результатов."
|
||||
|
||||
@ -1354,11 +1353,11 @@ msgstr "Копировать"
|
||||
msgid "Paste"
|
||||
msgstr "Вставить"
|
||||
|
||||
#: ../js/ui/shellEntry.js:106
|
||||
#: ../js/ui/shellEntry.js:105
|
||||
msgid "Show Text"
|
||||
msgstr "Показать текст"
|
||||
|
||||
#: ../js/ui/shellEntry.js:108
|
||||
#: ../js/ui/shellEntry.js:107
|
||||
msgid "Hide Text"
|
||||
msgstr "Скрыть текст"
|
||||
|
||||
@ -1370,7 +1369,7 @@ msgstr "Пароль"
|
||||
msgid "Remember Password"
|
||||
msgstr "Запомнить пароль"
|
||||
|
||||
#: ../js/ui/shellMountOperation.js:403 ../js/ui/unlockDialog.js:112
|
||||
#: ../js/ui/shellMountOperation.js:403 ../js/ui/unlockDialog.js:140
|
||||
msgid "Unlock"
|
||||
msgstr "Разблокировать"
|
||||
|
||||
@ -1671,7 +1670,7 @@ msgstr "Батарея"
|
||||
|
||||
#: ../js/ui/status/power.js:81
|
||||
msgid "Power Settings"
|
||||
msgstr "Параметры электропитания"
|
||||
msgstr "Параметры питания"
|
||||
|
||||
#. 0 is reported when UPower does not have enough data
|
||||
#. to estimate battery life
|
||||
@ -1779,11 +1778,11 @@ msgstr "Громкость"
|
||||
msgid "Microphone"
|
||||
msgstr "Микрофон"
|
||||
|
||||
#: ../js/ui/unlockDialog.js:123
|
||||
#: ../js/ui/unlockDialog.js:151
|
||||
msgid "Log in as another user"
|
||||
msgstr "Войти от имени другого пользователя"
|
||||
|
||||
#: ../js/ui/unlockDialog.js:144
|
||||
#: ../js/ui/unlockDialog.js:177
|
||||
msgid "Unlock Window"
|
||||
msgstr "Разблокировать окно"
|
||||
|
||||
@ -1811,27 +1810,27 @@ msgstr "Бездействует"
|
||||
msgid "Offline"
|
||||
msgstr "Не в сети"
|
||||
|
||||
#: ../js/ui/userMenu.js:781
|
||||
#: ../js/ui/userMenu.js:780
|
||||
msgid "Notifications"
|
||||
msgstr "Уведомления"
|
||||
|
||||
#: ../js/ui/userMenu.js:797
|
||||
#: ../js/ui/userMenu.js:796
|
||||
msgid "Switch User"
|
||||
msgstr "Сменить пользователя"
|
||||
|
||||
#: ../js/ui/userMenu.js:802
|
||||
#: ../js/ui/userMenu.js:801
|
||||
msgid "Log Out"
|
||||
msgstr "Выйти из системы"
|
||||
|
||||
#: ../js/ui/userMenu.js:822
|
||||
#: ../js/ui/userMenu.js:821
|
||||
msgid "Install Updates & Restart"
|
||||
msgstr "Установить обновления и выполнить перезагрузку"
|
||||
|
||||
#: ../js/ui/userMenu.js:840
|
||||
#: ../js/ui/userMenu.js:839
|
||||
msgid "Your chat status will be set to busy"
|
||||
msgstr "Будет установлен статус «не беспокоить»"
|
||||
|
||||
#: ../js/ui/userMenu.js:841
|
||||
#: ../js/ui/userMenu.js:840
|
||||
msgid ""
|
||||
"Notifications are now disabled, including chat messages. Your online status "
|
||||
"has been adjusted to let others know that you might not see their messages."
|
||||
@ -1839,35 +1838,33 @@ msgstr ""
|
||||
"Уведомления отключены, включая сообщения в чате. Ваш статус доступности "
|
||||
"изменён, чтобы другие знали, что вы возможно не видите их сообщения."
|
||||
|
||||
#: ../js/ui/userMenu.js:888
|
||||
#: ../js/ui/userMenu.js:886
|
||||
msgid "Other users are logged in."
|
||||
msgstr "В системе имеются открытые сеансы других пользователей."
|
||||
msgstr "В системе имеются сеансы других пользователей."
|
||||
|
||||
#: ../js/ui/userMenu.js:893
|
||||
#: ../js/ui/userMenu.js:891
|
||||
msgid "Shutting down might cause them to lose unsaved work."
|
||||
msgstr "Завершение работы может привести к потере несохранённых изменений."
|
||||
|
||||
#. Translators: Remote here refers to a remote session, like a ssh login
|
||||
#: ../js/ui/userMenu.js:921
|
||||
#: ../js/ui/userMenu.js:918
|
||||
#, c-format
|
||||
msgid "%s (remote)"
|
||||
msgstr "%s (удалённый)"
|
||||
|
||||
#. Translators: Console here refers to a tty like a VT console
|
||||
#: ../js/ui/userMenu.js:924
|
||||
#: ../js/ui/userMenu.js:920
|
||||
#, c-format
|
||||
msgid "%s (console)"
|
||||
msgstr "%s (консоль)"
|
||||
|
||||
#: ../js/ui/viewSelector.js:100
|
||||
#: ../js/ui/viewSelector.js:101
|
||||
msgid "Applications"
|
||||
msgstr "Приложения"
|
||||
|
||||
#: ../js/ui/viewSelector.js:104
|
||||
#: ../js/ui/viewSelector.js:105
|
||||
msgid "Search"
|
||||
msgstr "Поиск"
|
||||
|
||||
#: ../js/ui/wanda.js:77
|
||||
#: ../js/ui/wanda.js:92
|
||||
#, c-format
|
||||
msgid ""
|
||||
"Sorry, no wisdom for you today:\n"
|
||||
@ -1876,7 +1873,7 @@ msgstr ""
|
||||
"Извините, на сегодня нет никаких советов:\n"
|
||||
"%s"
|
||||
|
||||
#: ../js/ui/wanda.js:81
|
||||
#: ../js/ui/wanda.js:96
|
||||
#, c-format
|
||||
msgid "%s the Oracle says"
|
||||
msgstr "Оракул говорит: «%s»"
|
||||
|
590
po/sr@latin.po
590
po/sr@latin.po
File diff suppressed because it is too large
Load Diff
77
po/ug.po
77
po/ug.po
@ -11,8 +11,8 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: gnome-shell\n"
|
||||
"Report-Msgid-Bugs-To: http://bugzilla.gnome.org/enter_bug.cgi?product=gnome-shell&keywords=I18N+L10N&component=general\n"
|
||||
"POT-Creation-Date: 2013-03-04 08:38+0000\n"
|
||||
"PO-Revision-Date: 2013-03-07 21:01+0900\n"
|
||||
"POT-Creation-Date: 2013-03-02 23:02+0000\n"
|
||||
"PO-Revision-Date: 2013-03-03 15:57+0900\n"
|
||||
"Last-Translator: Gheyret Kenji <gheyret@gmail.com>\n"
|
||||
"Language-Team: Uyghur Computer Science Association <UKIJ@yahoogroups.com>\n"
|
||||
"Language: \n"
|
||||
@ -112,13 +112,13 @@ msgstr "مۇناسىپ پروگرامما بەلگىسى يىغقۇچ رايون
|
||||
|
||||
#: ../data/org.gnome.shell.gschema.xml.in.in.h:9
|
||||
msgid "List of categories that should be displayed as folders"
|
||||
msgstr "قىسقۇچ سۈپىتىدە كۆرسىتىلىدىغان كاتېگورىيەلەرنىڭ تىزىمى"
|
||||
msgstr ""
|
||||
|
||||
#: ../data/org.gnome.shell.gschema.xml.in.in.h:10
|
||||
msgid ""
|
||||
"Each category name in this list will be represented as folder in the "
|
||||
"application view, rather than being displayed inline in the main view."
|
||||
msgstr "پروگرامما كۆرۈنۈشىدە ھەر بىر كاتېگورىيە ئاتى قىسقۇچ سۈپىتىدە ئىپادىلىنىدۇ، ئاساسىي كۆرۈنۈشتە كۆرسىتىلمەيدۇ."
|
||||
msgstr ""
|
||||
|
||||
#: ../data/org.gnome.shell.gschema.xml.in.in.h:11
|
||||
msgid "History for command (Alt-F2) dialog"
|
||||
@ -316,6 +316,7 @@ msgid "Select an extension to configure using the combobox above."
|
||||
msgstr "يۇقىرىدىكى combobox دىن سەپلەيدىغان كېڭەيتىلمىنى تاللاڭ."
|
||||
|
||||
#: ../js/gdm/loginDialog.js:405
|
||||
#| msgid "Session..."
|
||||
msgid "Session…"
|
||||
msgstr "ئەڭگىمە…"
|
||||
|
||||
@ -330,7 +331,7 @@ msgstr "تىزىمدا يوقمۇ؟"
|
||||
#: ../js/ui/components/polkitAgent.js:162 ../js/ui/endSessionDialog.js:375
|
||||
#: ../js/ui/extensionDownloader.js:195 ../js/ui/shellMountOperation.js:399
|
||||
#: ../js/ui/status/bluetooth.js:415 ../js/ui/unlockDialog.js:126
|
||||
#: ../js/ui/userMenu.js:934
|
||||
#: ../js/ui/userMenu.js:932
|
||||
msgid "Cancel"
|
||||
msgstr "ئەمەلدىن قالدۇر"
|
||||
|
||||
@ -360,8 +361,8 @@ msgstr "كىرىش كۆزنىكى"
|
||||
msgid "Power"
|
||||
msgstr "توك مەنبە"
|
||||
|
||||
#: ../js/gdm/powerMenu.js:93 ../js/ui/userMenu.js:695 ../js/ui/userMenu.js:699
|
||||
#: ../js/ui/userMenu.js:815
|
||||
#: ../js/gdm/powerMenu.js:93 ../js/ui/userMenu.js:694 ../js/ui/userMenu.js:698
|
||||
#: ../js/ui/userMenu.js:814
|
||||
msgid "Suspend"
|
||||
msgstr "توڭلات"
|
||||
|
||||
@ -369,14 +370,14 @@ msgstr "توڭلات"
|
||||
msgid "Restart"
|
||||
msgstr "قايتا قوزغات"
|
||||
|
||||
#: ../js/gdm/powerMenu.js:103 ../js/ui/userMenu.js:697
|
||||
#: ../js/ui/userMenu.js:699 ../js/ui/userMenu.js:814 ../js/ui/userMenu.js:938
|
||||
#: ../js/gdm/powerMenu.js:103 ../js/ui/userMenu.js:696
|
||||
#: ../js/ui/userMenu.js:698 ../js/ui/userMenu.js:813 ../js/ui/userMenu.js:936
|
||||
msgid "Power Off"
|
||||
msgstr "توكنى ئۈز"
|
||||
|
||||
#: ../js/gdm/util.js:182
|
||||
msgid "Authentication error"
|
||||
msgstr "كىملىك دەلىللەش خاتالىقى"
|
||||
msgstr "سالاھىيەت دەلىللەش خاتالىقى"
|
||||
|
||||
#. Translators: this message is shown below the password entry field
|
||||
#. to indicate the user can swipe their finger instead
|
||||
@ -434,7 +435,7 @@ msgstr "%s يىغقۇچىڭىزغا قوشۇلدى."
|
||||
msgid "%s has been removed from your favorites."
|
||||
msgstr "%s يىغقۇچىڭىزدىن چىقىرىۋېتىلىدۇ."
|
||||
|
||||
#: ../js/ui/backgroundMenu.js:19 ../js/ui/userMenu.js:788
|
||||
#: ../js/ui/backgroundMenu.js:19 ../js/ui/userMenu.js:787
|
||||
msgid "Settings"
|
||||
msgstr "تەڭشەكلەر"
|
||||
|
||||
@ -696,7 +697,7 @@ msgstr "‹%s› كە باغلىنىش ئۈچۈن بىر ئىمغا ئېھتىي
|
||||
|
||||
#: ../js/ui/components/polkitAgent.js:55
|
||||
msgid "Authentication Required"
|
||||
msgstr "كىملىك دەلىللەش زۆرۈر"
|
||||
msgstr "سالاھىيەت دەلىللەش زۆرۈر"
|
||||
|
||||
#: ../js/ui/components/polkitAgent.js:93
|
||||
msgid "Administrator"
|
||||
@ -846,7 +847,7 @@ msgstr "تور خاتالىقى"
|
||||
|
||||
#: ../js/ui/components/telepathyClient.js:1300
|
||||
msgid "Authentication failed"
|
||||
msgstr "كىملىك دەلىللەش مەغلۇپ بولدى"
|
||||
msgstr "سالاھىيەت دەلىللەش مەغلۇپ بولدى"
|
||||
|
||||
#: ../js/ui/components/telepathyClient.js:1302
|
||||
msgid "Encryption error"
|
||||
@ -955,7 +956,7 @@ msgstr "ھېساباتنى كۆرۈش"
|
||||
msgid "Unknown reason"
|
||||
msgstr "نامەلۇم سەۋەب"
|
||||
|
||||
#: ../js/ui/ctrlAltTab.js:29 ../js/ui/viewSelector.js:96
|
||||
#: ../js/ui/ctrlAltTab.js:29 ../js/ui/viewSelector.js:97
|
||||
msgid "Windows"
|
||||
msgstr "كۆزنەكلەر"
|
||||
|
||||
@ -1143,6 +1144,7 @@ msgid "Remove"
|
||||
msgstr "چىقىرىۋەت"
|
||||
|
||||
#: ../js/ui/messageTray.js:1501
|
||||
#| msgid "No Messages"
|
||||
msgid "Clear Messages"
|
||||
msgstr "ئۇچۇرنى تازىلا"
|
||||
|
||||
@ -1186,6 +1188,7 @@ msgstr "قىسقىچە بايان"
|
||||
#. active; it should not exceed ~30
|
||||
#. characters.
|
||||
#: ../js/ui/overview.js:284
|
||||
#| msgid "Type to search..."
|
||||
msgid "Type to search…"
|
||||
msgstr "ئىزدەيدىغاننى كىرگۈزۈڭ.…"
|
||||
|
||||
@ -1232,7 +1235,7 @@ msgid "%d new notification"
|
||||
msgid_plural "%d new notifications"
|
||||
msgstr[0] "%d دانە ئۇقتۇرۇش"
|
||||
|
||||
#: ../js/ui/screenShield.js:442 ../js/ui/userMenu.js:806
|
||||
#: ../js/ui/screenShield.js:442 ../js/ui/userMenu.js:805
|
||||
msgid "Lock"
|
||||
msgstr "قۇلۇپلا"
|
||||
|
||||
@ -1248,6 +1251,7 @@ msgstr "گىنوم ئېكراننى قۇلۇپلىشى زۆرۈر"
|
||||
#. XXX: another option is to kick the user into the gdm login
|
||||
#. screen, where we're not affected by grabs
|
||||
#: ../js/ui/screenShield.js:758 ../js/ui/screenShield.js:1169
|
||||
#| msgid "Unable to connect to %s"
|
||||
msgid "Unable to lock"
|
||||
msgstr "قۇلۇپلىغىلى بولمىدى"
|
||||
|
||||
@ -1256,6 +1260,7 @@ msgid "Lock was blocked by an application"
|
||||
msgstr "بىر پروگرامما قۇلۇپلاشنى توسۇپ قويغان"
|
||||
|
||||
#: ../js/ui/searchDisplay.js:431
|
||||
#| msgid "Searching..."
|
||||
msgid "Searching…"
|
||||
msgstr "ئىزدەۋاتىدۇ…"
|
||||
|
||||
@ -1351,10 +1356,12 @@ msgid "Visibility"
|
||||
msgstr "كۆرۈشچانلىقى"
|
||||
|
||||
#: ../js/ui/status/bluetooth.js:59
|
||||
#| msgid "Send Files to Device..."
|
||||
msgid "Send Files to Device…"
|
||||
msgstr "ھۆججەتلەرنى ئۈسكۈنىگە ئەۋەتىش…"
|
||||
|
||||
#: ../js/ui/status/bluetooth.js:60
|
||||
#| msgid "Set Up a New Device..."
|
||||
msgid "Set Up a New Device…"
|
||||
msgstr "يېڭى ئۈسكۈنە ئورنىتىش…"
|
||||
|
||||
@ -1381,6 +1388,7 @@ msgid "connecting..."
|
||||
msgstr "باغلىنىۋاتىدۇ…"
|
||||
|
||||
#: ../js/ui/status/bluetooth.js:239
|
||||
#| msgid "Send Files..."
|
||||
msgid "Send Files…"
|
||||
msgstr "ھۆججەت يوللاش…"
|
||||
|
||||
@ -1486,7 +1494,7 @@ msgstr "باشقۇرۇلمىغان"
|
||||
#. Translators: this is for network connections that require some kind of key or password
|
||||
#: ../js/ui/status/network.js:469 ../js/ui/status/network.js:1549
|
||||
msgid "authentication required"
|
||||
msgstr "كىملىك دەلىللەش زۆرۈر"
|
||||
msgstr "سالاھىيەت دەلىللەش زۆرۈر"
|
||||
|
||||
#. Translators: this is for devices that require some kind of firmware or kernel
|
||||
#. module, which is missing
|
||||
@ -1593,6 +1601,7 @@ msgstr "توك مەنبە تەڭشىكى"
|
||||
#. 0 is reported when UPower does not have enough data
|
||||
#. to estimate battery life
|
||||
#: ../js/ui/status/power.js:99
|
||||
#| msgid "Estimating..."
|
||||
msgid "Estimating…"
|
||||
msgstr "مۆلچەرلەۋاتىدۇ…"
|
||||
|
||||
@ -1696,79 +1705,79 @@ msgstr "باشقا ئىشلەتكۈچى سۈپىتىدە كىر"
|
||||
msgid "Unlock Window"
|
||||
msgstr "كۆزنەكنى قۇلۇپلا"
|
||||
|
||||
#: ../js/ui/userMenu.js:193
|
||||
#: ../js/ui/userMenu.js:192
|
||||
msgid "Available"
|
||||
msgstr "ئىشلەتكىلى بولىدۇ"
|
||||
|
||||
#: ../js/ui/userMenu.js:196
|
||||
#: ../js/ui/userMenu.js:195
|
||||
msgid "Busy"
|
||||
msgstr "ئالدىراش"
|
||||
|
||||
#: ../js/ui/userMenu.js:199
|
||||
#: ../js/ui/userMenu.js:198
|
||||
msgid "Invisible"
|
||||
msgstr "يوشۇرۇن"
|
||||
|
||||
#: ../js/ui/userMenu.js:202
|
||||
#: ../js/ui/userMenu.js:201
|
||||
msgid "Away"
|
||||
msgstr "يوق"
|
||||
|
||||
#: ../js/ui/userMenu.js:205
|
||||
#: ../js/ui/userMenu.js:204
|
||||
msgid "Idle"
|
||||
msgstr "بىكار"
|
||||
|
||||
#: ../js/ui/userMenu.js:208
|
||||
#: ../js/ui/userMenu.js:207
|
||||
msgid "Offline"
|
||||
msgstr "توردا يوق"
|
||||
|
||||
#: ../js/ui/userMenu.js:780
|
||||
#: ../js/ui/userMenu.js:779
|
||||
msgid "Notifications"
|
||||
msgstr "ئۇقتۇرۇشلار"
|
||||
|
||||
#: ../js/ui/userMenu.js:796
|
||||
#: ../js/ui/userMenu.js:795
|
||||
msgid "Switch User"
|
||||
msgstr "ئىشلەتكۈچى ئالماشتۇرۇش"
|
||||
|
||||
#: ../js/ui/userMenu.js:801
|
||||
#: ../js/ui/userMenu.js:800
|
||||
msgid "Log Out"
|
||||
msgstr "تىزىمدىن چىقىش"
|
||||
|
||||
#: ../js/ui/userMenu.js:821
|
||||
#: ../js/ui/userMenu.js:820
|
||||
msgid "Install Updates & Restart"
|
||||
msgstr "يېڭىلانمىلارنى ئورنىتىپ قايتا قوزغات"
|
||||
|
||||
#: ../js/ui/userMenu.js:839
|
||||
#: ../js/ui/userMenu.js:838
|
||||
msgid "Your chat status will be set to busy"
|
||||
msgstr "سىزنىڭ سۆھبەت ھالىتىڭىز ئالدىراش قىلىنىدۇ"
|
||||
|
||||
#: ../js/ui/userMenu.js:840
|
||||
#: ../js/ui/userMenu.js:839
|
||||
msgid ""
|
||||
"Notifications are now disabled, including chat messages. Your online status "
|
||||
"has been adjusted to let others know that you might not see their messages."
|
||||
msgstr ""
|
||||
|
||||
#: ../js/ui/userMenu.js:886
|
||||
#: ../js/ui/userMenu.js:885
|
||||
msgid "Other users are logged in."
|
||||
msgstr "باشقا ئىشلەتكۈچىلەر كىردى:"
|
||||
|
||||
#: ../js/ui/userMenu.js:891
|
||||
#: ../js/ui/userMenu.js:890
|
||||
msgid "Shutting down might cause them to lose unsaved work."
|
||||
msgstr "تاقالسا ساقلانمىغان خىزمەتلەر يوقىلىشى مۇمكىن."
|
||||
|
||||
#: ../js/ui/userMenu.js:918
|
||||
#: ../js/ui/userMenu.js:916
|
||||
#, c-format
|
||||
msgid "%s (remote)"
|
||||
msgstr "%s (يىراق)"
|
||||
|
||||
#: ../js/ui/userMenu.js:920
|
||||
#: ../js/ui/userMenu.js:918
|
||||
#, c-format
|
||||
msgid "%s (console)"
|
||||
msgstr "%s (تىزگىن كۆزنەك)"
|
||||
|
||||
#: ../js/ui/viewSelector.js:100
|
||||
#: ../js/ui/viewSelector.js:101
|
||||
msgid "Applications"
|
||||
msgstr "پروگراممىلار"
|
||||
|
||||
#: ../js/ui/viewSelector.js:104
|
||||
#: ../js/ui/viewSelector.js:105
|
||||
msgid "Search"
|
||||
msgstr "ئىزدە"
|
||||
|
||||
|
877
po/zh_CN.po
877
po/zh_CN.po
File diff suppressed because it is too large
Load Diff
583
po/zh_HK.po
583
po/zh_HK.po
File diff suppressed because it is too large
Load Diff
585
po/zh_TW.po
585
po/zh_TW.po
File diff suppressed because it is too large
Load Diff
@ -287,7 +287,7 @@ libgnome_shell_la_LIBADD = \
|
||||
libgnome_shell_la_CPPFLAGS = $(gnome_shell_cflags)
|
||||
|
||||
Shell-0.1.gir: libgnome-shell.la St-1.0.gir
|
||||
Shell_0_1_gir_INCLUDES = Clutter-1.0 ClutterX11-1.0 Meta-3.0 TelepathyGLib-0.12 Soup-2.4 GMenu-3.0 NetworkManager-1.0 NMClient-1.0
|
||||
Shell_0_1_gir_INCLUDES = Clutter-1.0 ClutterX11-1.0 Meta-3.0 TelepathyGLib-0.12 TelepathyLogger-0.2 Soup-2.4 GMenu-3.0 NetworkManager-1.0 NMClient-1.0
|
||||
Shell_0_1_gir_CFLAGS = $(libgnome_shell_la_CPPFLAGS) -I $(srcdir)
|
||||
Shell_0_1_gir_LIBS = libgnome-shell.la
|
||||
Shell_0_1_gir_FILES = $(libgnome_shell_la_gir_sources)
|
||||
|
@ -490,17 +490,6 @@ calendar_sources_registry_source_removed_cb (ESourceRegistry *registry,
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
ensure_appointment_sources (CalendarSources *sources)
|
||||
{
|
||||
if (!sources->priv->appointment_sources.loaded)
|
||||
{
|
||||
calendar_sources_load_esource_list (sources->priv->registry,
|
||||
&sources->priv->appointment_sources);
|
||||
sources->priv->appointment_sources.loaded = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
GList *
|
||||
calendar_sources_get_appointment_clients (CalendarSources *sources)
|
||||
{
|
||||
@ -508,7 +497,12 @@ calendar_sources_get_appointment_clients (CalendarSources *sources)
|
||||
|
||||
g_return_val_if_fail (CALENDAR_IS_SOURCES (sources), NULL);
|
||||
|
||||
ensure_appointment_sources (sources);
|
||||
if (!sources->priv->appointment_sources.loaded)
|
||||
{
|
||||
calendar_sources_load_esource_list (sources->priv->registry,
|
||||
&sources->priv->appointment_sources);
|
||||
sources->priv->appointment_sources.loaded = TRUE;
|
||||
}
|
||||
|
||||
list = g_hash_table_get_values (sources->priv->appointment_sources.clients);
|
||||
|
||||
@ -518,17 +512,6 @@ calendar_sources_get_appointment_clients (CalendarSources *sources)
|
||||
return list;
|
||||
}
|
||||
|
||||
static void
|
||||
ensure_task_sources (CalendarSources *sources)
|
||||
{
|
||||
if (!sources->priv->task_sources.loaded)
|
||||
{
|
||||
calendar_sources_load_esource_list (sources->priv->registry,
|
||||
&sources->priv->task_sources);
|
||||
sources->priv->task_sources.loaded = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
GList *
|
||||
calendar_sources_get_task_clients (CalendarSources *sources)
|
||||
{
|
||||
@ -536,7 +519,12 @@ calendar_sources_get_task_clients (CalendarSources *sources)
|
||||
|
||||
g_return_val_if_fail (CALENDAR_IS_SOURCES (sources), NULL);
|
||||
|
||||
ensure_task_sources (sources);
|
||||
if (!sources->priv->task_sources.loaded)
|
||||
{
|
||||
calendar_sources_load_esource_list (sources->priv->registry,
|
||||
&sources->priv->task_sources);
|
||||
sources->priv->task_sources.loaded = TRUE;
|
||||
}
|
||||
|
||||
list = g_hash_table_get_values (sources->priv->task_sources.clients);
|
||||
|
||||
@ -545,15 +533,3 @@ calendar_sources_get_task_clients (CalendarSources *sources)
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
gboolean
|
||||
calendar_sources_has_sources (CalendarSources *sources)
|
||||
{
|
||||
g_return_val_if_fail (CALENDAR_IS_SOURCES (sources), FALSE);
|
||||
|
||||
ensure_appointment_sources (sources);
|
||||
ensure_task_sources (sources);
|
||||
|
||||
return g_hash_table_size (sources->priv->appointment_sources.clients) > 0 ||
|
||||
g_hash_table_size (sources->priv->task_sources.clients) > 0;
|
||||
}
|
||||
|
@ -61,8 +61,6 @@ CalendarSources *calendar_sources_get (void);
|
||||
GList *calendar_sources_get_appointment_clients (CalendarSources *sources);
|
||||
GList *calendar_sources_get_task_clients (CalendarSources *sources);
|
||||
|
||||
gboolean calendar_sources_has_sources (CalendarSources *sources);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __CALENDAR_SOURCES_H__ */
|
||||
|
@ -57,7 +57,6 @@ static const gchar introspection_xml[] =
|
||||
" <signal name='Changed'/>"
|
||||
" <property name='Since' type='x' access='read'/>"
|
||||
" <property name='Until' type='x' access='read'/>"
|
||||
" <property name='HasCalendars' type='b' access='read'/>"
|
||||
" </interface>"
|
||||
"</node>";
|
||||
static GDBusNodeInfo *introspection_data = NULL;
|
||||
@ -727,12 +726,6 @@ app_load_events (App *app)
|
||||
app->cache_invalid = FALSE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
app_has_calendars (App *app)
|
||||
{
|
||||
return calendar_sources_has_sources (app->sources);
|
||||
}
|
||||
|
||||
static void
|
||||
on_appointment_sources_changed (CalendarSources *sources,
|
||||
gpointer user_data)
|
||||
@ -741,26 +734,6 @@ on_appointment_sources_changed (CalendarSources *sources,
|
||||
|
||||
print_debug ("Sources changed\n");
|
||||
app_load_events (app);
|
||||
|
||||
/* Notify the HasCalendars property */
|
||||
{
|
||||
GVariantBuilder dict_builder;
|
||||
|
||||
g_variant_builder_init (&dict_builder, G_VARIANT_TYPE ("a{sv}"));
|
||||
g_variant_builder_add (&dict_builder, "{sv}", "HasCalendars",
|
||||
g_variant_new_boolean (app_has_calendars (app)));
|
||||
|
||||
g_dbus_connection_emit_signal (g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, NULL),
|
||||
NULL,
|
||||
"/org/gnome/Shell/CalendarServer",
|
||||
"org.freedesktop.DBus.Properties",
|
||||
"PropertiesChanged",
|
||||
g_variant_new ("(sa{sv}as)",
|
||||
"org.gnome.Shell.CalendarServer",
|
||||
&dict_builder,
|
||||
NULL),
|
||||
NULL);
|
||||
}
|
||||
}
|
||||
|
||||
static App *
|
||||
@ -960,10 +933,6 @@ handle_get_property (GDBusConnection *connection,
|
||||
{
|
||||
ret = g_variant_new_int64 (app->until);
|
||||
}
|
||||
else if (g_strcmp0 (property_name, "HasCalendars") == 0)
|
||||
{
|
||||
ret = g_variant_new_boolean (app_has_calendars (app));
|
||||
}
|
||||
else
|
||||
{
|
||||
g_assert_not_reached ();
|
||||
|
@ -8,7 +8,9 @@
|
||||
#include "shell-embedded-window-private.h"
|
||||
|
||||
/* This type is a subclass of GtkWindow that ties the window to a
|
||||
* ShellGtkEmbed; the resizing logic is bound to the clutter logic.
|
||||
* ShellGtkEmbed; the window is reparented into the stage
|
||||
* window for the actor and the resizing logic is bound to the clutter
|
||||
* logic.
|
||||
*
|
||||
* The typical usage we might expect is
|
||||
*
|
||||
@ -26,13 +28,16 @@
|
||||
G_DEFINE_TYPE (ShellEmbeddedWindow, shell_embedded_window, GTK_TYPE_WINDOW);
|
||||
|
||||
enum {
|
||||
PROP_0
|
||||
PROP_0,
|
||||
|
||||
PROP_STAGE
|
||||
};
|
||||
|
||||
struct _ShellEmbeddedWindowPrivate {
|
||||
ShellGtkEmbed *actor;
|
||||
|
||||
GdkRectangle position;
|
||||
Window stage_xwindow;
|
||||
};
|
||||
|
||||
/*
|
||||
@ -75,6 +80,27 @@ shell_embedded_window_hide (GtkWidget *widget)
|
||||
GTK_WIDGET_CLASS (shell_embedded_window_parent_class)->hide (widget);
|
||||
}
|
||||
|
||||
static void
|
||||
shell_embedded_window_realize (GtkWidget *widget)
|
||||
{
|
||||
ShellEmbeddedWindow *window = SHELL_EMBEDDED_WINDOW (widget);
|
||||
|
||||
GTK_WIDGET_CLASS (shell_embedded_window_parent_class)->realize (widget);
|
||||
|
||||
|
||||
/* Using XReparentWindow() is simpler than using gdk_window_reparent(),
|
||||
* since it avoids maybe having to create a new foreign GDK window for
|
||||
* the stage. However, GDK will be left thinking that the parent of
|
||||
* window->window is the root window - it's not immediately clear
|
||||
* to me whether that is more or less likely to cause problems than
|
||||
* modifying the GDK hierarchy.
|
||||
*/
|
||||
XReparentWindow (GDK_DISPLAY_XDISPLAY (gtk_widget_get_display (widget)),
|
||||
gdk_x11_window_get_xid (gtk_widget_get_window (widget)),
|
||||
window->priv->stage_xwindow,
|
||||
window->priv->position.x, window->priv->position.y);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
shell_embedded_window_configure_event (GtkWidget *widget,
|
||||
GdkEventConfigure *event)
|
||||
@ -101,6 +127,27 @@ shell_embedded_window_check_resize (GtkContainer *container)
|
||||
clutter_actor_queue_relayout (CLUTTER_ACTOR (window->priv->actor));
|
||||
}
|
||||
|
||||
static void
|
||||
shell_embedded_window_set_property (GObject *object,
|
||||
guint prop_id,
|
||||
const GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
ShellEmbeddedWindow *window = SHELL_EMBEDDED_WINDOW (object);
|
||||
|
||||
switch (prop_id)
|
||||
{
|
||||
case PROP_STAGE:
|
||||
window->priv->stage_xwindow =
|
||||
clutter_x11_get_stage_window (g_value_get_object (value));
|
||||
break;
|
||||
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static GObject *
|
||||
shell_embedded_window_constructor (GType gtype,
|
||||
guint n_properties,
|
||||
@ -135,13 +182,23 @@ shell_embedded_window_class_init (ShellEmbeddedWindowClass *klass)
|
||||
|
||||
g_type_class_add_private (klass, sizeof (ShellEmbeddedWindowPrivate));
|
||||
|
||||
object_class->set_property = shell_embedded_window_set_property;
|
||||
object_class->constructor = shell_embedded_window_constructor;
|
||||
|
||||
widget_class->show = shell_embedded_window_show;
|
||||
widget_class->hide = shell_embedded_window_hide;
|
||||
widget_class->realize = shell_embedded_window_realize;
|
||||
widget_class->configure_event = shell_embedded_window_configure_event;
|
||||
|
||||
container_class->check_resize = shell_embedded_window_check_resize;
|
||||
|
||||
g_object_class_install_property (object_class,
|
||||
PROP_STAGE,
|
||||
g_param_spec_object ("stage",
|
||||
"Stage",
|
||||
"ClutterStage to embed on",
|
||||
CLUTTER_TYPE_STAGE,
|
||||
G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY));
|
||||
}
|
||||
|
||||
static void
|
||||
@ -225,8 +282,9 @@ _shell_embedded_window_unmap (ShellEmbeddedWindow *window)
|
||||
* Public API
|
||||
*/
|
||||
GtkWidget *
|
||||
shell_embedded_window_new (void)
|
||||
shell_embedded_window_new (ClutterStage *stage)
|
||||
{
|
||||
return g_object_new (SHELL_TYPE_EMBEDDED_WINDOW,
|
||||
"stage", stage,
|
||||
NULL);
|
||||
}
|
||||
|
@ -30,6 +30,6 @@ struct _ShellEmbeddedWindowClass
|
||||
};
|
||||
|
||||
GType shell_embedded_window_get_type (void) G_GNUC_CONST;
|
||||
GtkWidget *shell_embedded_window_new (void);
|
||||
GtkWidget *shell_embedded_window_new (ClutterStage *stage);
|
||||
|
||||
#endif /* __SHELL_EMBEDDED_WINDOW_H__ */
|
||||
|
@ -3,11 +3,8 @@
|
||||
#include "config.h"
|
||||
|
||||
#include "shell-embedded-window-private.h"
|
||||
#include "shell-global.h"
|
||||
|
||||
#include <gdk/gdkx.h>
|
||||
#include <meta/display.h>
|
||||
#include <meta/window.h>
|
||||
|
||||
enum {
|
||||
PROP_0,
|
||||
@ -18,14 +15,9 @@ enum {
|
||||
struct _ShellGtkEmbedPrivate
|
||||
{
|
||||
ShellEmbeddedWindow *window;
|
||||
|
||||
ClutterActor *window_actor;
|
||||
guint window_actor_destroyed_handler;
|
||||
|
||||
guint window_created_handler;
|
||||
};
|
||||
|
||||
G_DEFINE_TYPE (ShellGtkEmbed, shell_gtk_embed, CLUTTER_TYPE_CLONE);
|
||||
G_DEFINE_TYPE (ShellGtkEmbed, shell_gtk_embed, CLUTTER_X11_TYPE_TEXTURE_PIXMAP);
|
||||
|
||||
static void shell_gtk_embed_set_window (ShellGtkEmbed *embed,
|
||||
ShellEmbeddedWindow *window);
|
||||
@ -38,106 +30,39 @@ shell_gtk_embed_on_window_destroy (GtkWidget *object,
|
||||
}
|
||||
|
||||
static void
|
||||
shell_gtk_embed_remove_window_actor (ShellGtkEmbed *embed)
|
||||
{
|
||||
ShellGtkEmbedPrivate *priv = embed->priv;
|
||||
|
||||
if (priv->window_actor)
|
||||
{
|
||||
g_signal_handler_disconnect (priv->window_actor,
|
||||
priv->window_actor_destroyed_handler);
|
||||
priv->window_actor_destroyed_handler = 0;
|
||||
|
||||
g_object_unref (priv->window_actor);
|
||||
priv->window_actor = NULL;
|
||||
}
|
||||
|
||||
clutter_clone_set_source (CLUTTER_CLONE (embed), NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
shell_gtk_embed_window_created_cb (MetaDisplay *display,
|
||||
MetaWindow *window,
|
||||
shell_gtk_embed_on_window_realize (GtkWidget *widget,
|
||||
ShellGtkEmbed *embed)
|
||||
{
|
||||
ShellGtkEmbedPrivate *priv = embed->priv;
|
||||
Window xwindow = meta_window_get_xwindow (window);
|
||||
GdkWindow *gdk_window = gtk_widget_get_window (GTK_WIDGET (priv->window));
|
||||
|
||||
if (xwindow == gdk_x11_window_get_xid (gdk_window))
|
||||
{
|
||||
ClutterActor *window_actor =
|
||||
CLUTTER_ACTOR (meta_window_get_compositor_private (window));
|
||||
MetaDisplay *display = shell_global_get_display (shell_global_get ());
|
||||
GCallback remove_cb = G_CALLBACK (shell_gtk_embed_remove_window_actor);
|
||||
cairo_region_t *empty_region;
|
||||
|
||||
clutter_clone_set_source (CLUTTER_CLONE (embed), window_actor);
|
||||
|
||||
/* We want to explicitly clear the clone source when the window
|
||||
actor is destroyed because otherwise we might end up keeping
|
||||
it alive after it has been disposed. Otherwise this can cause
|
||||
a crash if there is a paint after mutter notices that the top
|
||||
level window has been destroyed, which causes it to dispose
|
||||
the window, and before the tray manager notices that the
|
||||
window is gone which would otherwise reset the window and
|
||||
unref the clone */
|
||||
priv->window_actor = g_object_ref (window_actor);
|
||||
priv->window_actor_destroyed_handler =
|
||||
g_signal_connect_swapped (window_actor,
|
||||
"destroy",
|
||||
remove_cb,
|
||||
embed);
|
||||
|
||||
/* Hide the original actor otherwise it will appear in the scene
|
||||
as a normal window */
|
||||
clutter_actor_set_opacity (window_actor, 0);
|
||||
|
||||
/* Set an empty input shape on the window so that it can't get
|
||||
any input. This probably isn't the ideal way to acheive this.
|
||||
It would probably be better to force the window to go behind
|
||||
Mutter's guard window, but this is quite difficult to do as
|
||||
Mutter doesn't manage the stacking for override redirect
|
||||
windows and the guard window is repeatedly lowered to the
|
||||
bottom of the stack. */
|
||||
empty_region = cairo_region_create ();
|
||||
gdk_window_input_shape_combine_region (gdk_window,
|
||||
empty_region,
|
||||
0, 0 /* offset x/y */);
|
||||
cairo_region_destroy (empty_region);
|
||||
|
||||
/* Now that we've found the window we don't need to listen for
|
||||
new windows anymore */
|
||||
g_signal_handler_disconnect (display,
|
||||
priv->window_created_handler);
|
||||
priv->window_created_handler = 0;
|
||||
}
|
||||
/* Here automatic=FALSE means to use CompositeRedirectManual.
|
||||
* That is, the X server shouldn't draw the window onto the
|
||||
* screen.
|
||||
*/
|
||||
clutter_x11_texture_pixmap_set_window (CLUTTER_X11_TEXTURE_PIXMAP (embed),
|
||||
gdk_x11_window_get_xid (gtk_widget_get_window (widget)),
|
||||
FALSE);
|
||||
}
|
||||
|
||||
static void
|
||||
shell_gtk_embed_set_window (ShellGtkEmbed *embed,
|
||||
ShellEmbeddedWindow *window)
|
||||
{
|
||||
MetaDisplay *display = shell_global_get_display (shell_global_get ());
|
||||
|
||||
if (embed->priv->window)
|
||||
{
|
||||
if (embed->priv->window_created_handler)
|
||||
{
|
||||
g_signal_handler_disconnect (display,
|
||||
embed->priv->window_created_handler);
|
||||
embed->priv->window_created_handler = 0;
|
||||
}
|
||||
|
||||
shell_gtk_embed_remove_window_actor (embed);
|
||||
|
||||
_shell_embedded_window_set_actor (embed->priv->window, NULL);
|
||||
|
||||
g_object_unref (embed->priv->window);
|
||||
|
||||
clutter_x11_texture_pixmap_set_window (CLUTTER_X11_TEXTURE_PIXMAP (embed),
|
||||
None,
|
||||
FALSE);
|
||||
|
||||
g_signal_handlers_disconnect_by_func (embed->priv->window,
|
||||
(gpointer)shell_gtk_embed_on_window_destroy,
|
||||
embed);
|
||||
g_signal_handlers_disconnect_by_func (embed->priv->window,
|
||||
(gpointer)shell_gtk_embed_on_window_realize,
|
||||
embed);
|
||||
}
|
||||
|
||||
embed->priv->window = window;
|
||||
@ -150,14 +75,11 @@ shell_gtk_embed_set_window (ShellGtkEmbed *embed,
|
||||
|
||||
g_signal_connect (embed->priv->window, "destroy",
|
||||
G_CALLBACK (shell_gtk_embed_on_window_destroy), embed);
|
||||
g_signal_connect (embed->priv->window, "realize",
|
||||
G_CALLBACK (shell_gtk_embed_on_window_realize), embed);
|
||||
|
||||
/* Listen for new windows so we can detect when Mutter has
|
||||
created a MutterWindow for this window */
|
||||
embed->priv->window_created_handler =
|
||||
g_signal_connect (display,
|
||||
"window-created",
|
||||
G_CALLBACK (shell_gtk_embed_window_created_cb),
|
||||
embed);
|
||||
if (gtk_widget_get_realized (GTK_WIDGET (window)))
|
||||
shell_gtk_embed_on_window_realize (GTK_WIDGET (embed->priv->window), embed);
|
||||
}
|
||||
|
||||
clutter_actor_queue_relayout (CLUTTER_ACTOR (embed));
|
||||
@ -338,6 +260,11 @@ shell_gtk_embed_init (ShellGtkEmbed *embed)
|
||||
{
|
||||
embed->priv = G_TYPE_INSTANCE_GET_PRIVATE (embed, SHELL_TYPE_GTK_EMBED,
|
||||
ShellGtkEmbedPrivate);
|
||||
|
||||
/* automatic here means whether ClutterX11TexturePixmap should
|
||||
* process damage update and refresh the pixmap itself.
|
||||
*/
|
||||
clutter_x11_texture_pixmap_set_automatic (CLUTTER_X11_TEXTURE_PIXMAP (embed), TRUE);
|
||||
}
|
||||
|
||||
/*
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user