Compare commits

..

46 Commits

Author SHA1 Message Date
Carlos Garcia Campos
a8c769e0ff browser-plugin: The NPObject returned by NPP_GetValue should be retained
The Mozilla documentation says: "And as always when working with
reference counted NPObjects, the caller is responsible for calling
NPN_ReleaseObject on the NPObject to drop the reference."

Browsers assume that the plugin does the right thing and always call
NPN_ReleaseObject. At some point the object is released and deallocated
and both the plugin and browser still have references to the object
thinking that it's still alive. That's why the crash is sometimes in the
plugin when it tries to use the np object, and sometimes in the browser.

https://bugzilla.gnome.org/post_bug.cgi
2016-10-29 14:57:30 -04:00
gogo
efd8b2d3a6 Add Croatian translation 2016-10-09 19:26:44 +00:00
Piotr Drąg
2b8d16e685 Updated Polish translation 2016-07-12 21:25:13 +02:00
Florian Müllner
598cf48973 Bump version to 3.18.5
Update NEWS.
2016-04-21 12:04:11 +02:00
Florian Müllner
ce811ec063 st: Don't assert when corner texture creation fails 2016-04-20 19:32:32 +02:00
Florian Müllner
535fb0e2a0 Do not skip CoglError parameters
While CoglError is a define to GError, it doesn't follow the convention
of ignoring errors when NULL is passed, but rather treats the error as
fatal :-(
That's clearly unwanted for a compositor, so make sure to always pass
an error parameter where a runtime error is possible

https://bugzilla.gnome.org/show_bug.cgi?id=765061
2016-04-20 19:32:32 +02:00
Florian Müllner
281101d942 st: Do not try to unref NULL CoglObjects
https://bugzilla.gnome.org/show_bug.cgi?id=765061
2016-04-20 19:32:31 +02:00
Aaron Plattner
045e1f01af st: Fix offscreen leak if cogl_framebuffer_allocate fails
If cogl_framebuffer_allocate fails in _st_create_shadow_pipeline_from_actor, the
CoglOffscreen* that was allocated earlier in the function is leaked.

https://bugzilla.gnome.org/show_bug.cgi?id=735705

Signed-off-by: Aaron Plattner <aplattner@nvidia.com>
2016-04-03 11:56:39 +02:00
Marek Černocký
db252a65f8 Updated Czech translation 2016-03-30 08:29:07 +02:00
Christophe Fergeau
358ee88e1c NetworkAgent: Fix double-unref in get_secrets_keyring_cb()
In get_secrets_keyring_cb, we own a ref on the 'attributes' hash table
from secret_item_get_attributes), and a ref on the 'secret' object (from
secret_item_get_secret(), but in the SHELL_KEYRING_SK_TAG case, we unref
these once before breaking out of the loop, and the second time after
breaking out of the loop.

https://bugzilla.gnome.org/show_bug.cgi?id=759708

Note: This is needed to avoid crashes with libsecret 0.18.4 -- Michael
2016-03-21 17:56:15 -05:00
Florian Müllner
cdc9652f5b telepathyClient: Acknowledge messages before closing
While a channel has pending messages, it will pop up again when
dismissed. That is clearly not what users expect, so clear them
out first before closing a channel.

https://bugzilla.gnome.org/show_bug.cgi?id=747991
2016-03-16 17:45:52 -05:00
Matej Urbančič
fcfa752fbd Updated Slovenian translation 2016-03-05 20:44:53 +01:00
Florian Müllner
4651b7adcc Bump version to 3.18.4
Update NEWS.
2016-02-22 16:45:15 +01:00
Lubomir Rintel
4562a431ad NetworkAgent: correctly identify the VPN secret requests
The non-interactive requests for 'vpn' settings are forwarded to the UI because
it is able to talk to the auth helpers. However, the VPN requests are identified
by the connection type instead of setting type. That is incorrect and the UI
is not prepared to handle such requests; tries to construct a dialog and fails
miserably:

  Gjs-Message: JS LOG: Invalid connection type: vpn

  (gnome-shell:13133): Gjs-WARNING **: JS ERROR: Error: No property 'text' in property list (or its value was undefined)
  NetworkSecretDialog<._init@resource:///org/gnome/shell/ui/components/networkAgent.js:60
  wrapper@resource:///org/gnome/gjs/modules/lang.js:169
  _Base.prototype._construct@resource:///org/gnome/gjs/modules/lang.js:110
  Class.prototype._construct/newClass@resource:///org/gnome/gjs/modules/lang.js:204
  NetworkAgent<._handleRequest@resource:///org/gnome/shell/ui/components/networkAgent.js:724
  wrapper@resource:///org/gnome/gjs/modules/lang.js:169
  NetworkAgent<._newRequest@resource:///org/gnome/shell/ui/components/networkAgent.js:715
  wrapper@resource:///org/gnome/gjs/modules/lang.js:169

https://bugzilla.gnome.org/show_bug.cgi?id=760999
2016-01-27 13:42:05 +01:00
Michael Catanzaro
f5d9d188a7 authPrompt: Do not allow bypassing disabled Sign In button
The Next and Sign In buttons are disabled when the username/password
field is empty. However, the user can still bypass this button by
pressing the enter key, leading to some odd glitches with the log in
for 'Not Listed?' users.

This is easy to fix by simply not progressing to the next screen when
the button is disabled.

https://bugzilla.gnome.org/show_bug.cgi?id=746180
2016-01-07 17:19:24 -06:00
Andika Triwidada
cca01e3f02 Updated Indonesian translation 2016-01-02 12:12:44 +00:00
Daniel Korostil
1874f3605d Updated Ukrainian translation 2015-12-05 17:00:22 +02:00
Michael Catanzaro
3001f3376c loginDialog: Reconsider user for user list when user changes
Generally a user-changed operation will be uninteresting, but if the
user is currently in the user list and the account changes to locked, we
want to remove it from the list, or if the user is not in the list and
the account changed to unlocked, we want to add it to the list. This
fixes the case where a new user account created in gnome-control-center
does not appear in the user list. The password mode is set in the new
account immediately after it is created, but the operations are not
atomic, so the login dialog considers the new user account when it is
still locked and rejects it from being displayed, then immediately
afterwards the account is unlocked. This commit causes the login dialog
to show the account when this occurs.

The containsUser() check here is not strictly necessary, but reduces
spurious calls to addUser() and removeUser(), since there's no easy way
to check if the locked status of the account has changed (as it's much
easier to connect to one signal on the UserManager than to
notify::locked on each User object).

https://bugzilla.gnome.org/show_bug.cgi?id=758568
2015-12-02 18:25:25 +01:00
Florian Müllner
491e511a96 altTab: Fix window-switcher on HiDPI displays
We need to take the scale factor into account to avoid tiny window
previews on HiDPI.

https://bugzilla.gnome.org/show_bug.cgi?id=758676
2015-12-02 10:35:52 +01:00
Michael Catanzaro
293bc98394 loginDialog: Fix TypeError when user is deleted
LoginDialog has a private _user, but UserListItem has a public user.
Easy to get wrong since _user would be the right thing to type in 90% of
this file.
2015-11-23 17:48:18 -06:00
Kristjan SCHMIDT
2ed3482d54 Updated Esperanto translation 2015-11-23 00:40:00 +01:00
Florian Müllner
4e4414a84d Bump version to 3.18.3
Update NEWS.
2015-11-17 22:25:33 +01:00
Carlos Garcia Campos
934a08f28f browser-plugin: Do not create a new object every time NPPVpluginScriptableNPObject is requested
Merge PluginData and PluginObject structs into a single one and create
the scriptable object associated to the plugin instance in NPP_New. Then,
when NPPVpluginScriptableNPObject is requested we just return the
scriptable object associated to the given instance. This caused the
crashes in NPN_InvokeDefault with WebKit, since we had multiple
scriptable objects for the same instance, but only one of those objects
had the onchange listener installed. Firefox seems to cache the
scriptable object for the instance and therefore NPPVpluginScriptableNPObject
is requested only once.

https://bugzilla.gnome.org/show_bug.cgi?id=737932
2015-11-17 13:18:05 -06:00
Carlos Garcia Campos
732ea2a91e browser-plugin: Set windowless mode and don't claim to need XEmbed
NPAPI plugins are windowed by default, so we need to set
NPPVpluginWindowBool value to FALSE on startup. This way the browser
will not create a GtkSocket for a GtkPlug that we are not going to
create. It doesn't make sense to claim that we need XEmbed either.

https://bugzilla.gnome.org/show_bug.cgi?id=757940
2015-11-17 11:35:53 -06:00
Michael Catanzaro
aae6a3cbbd Revert "browser-plugin: Set windowless mode and don't claim to need XEmbed"
This reverts commit a52c91e9e5.

https://bugzilla.gnome.org/show_bug.cgi?id=758035
2015-11-16 10:57:56 -06:00
Florian Müllner
f67a6589bd Bump version to 3.18.2
Update NEWS.
2015-11-12 13:08:29 +01:00
Carlos Garcia Campos
88c1fa8a3e browser-plugin: Set windowless mode and don't claim to need XEmbed
NPAPI plugins are windowed by default, so we need to set
NPPVpluginWindowBool value to FALSE on startup. This way the browser
will not create a GtkSocket for a GtkPlug that we are not going to
create. It doesn't make sense to claim that we need XEmbed either.

https://bugzilla.gnome.org/show_bug.cgi?id=757940
2015-11-12 12:12:29 +01:00
Florian Müllner
012443bffa st: Fix Gaussian kernel calculation
The result of subtracting unsigned operands is unsigned, which throws
off our calculation in case it should be negative.

This partly reverts 18b6f13395.

https://bugzilla.gnome.org/show_bug.cgi?id=757779
2015-11-12 01:03:01 +01:00
Anthony Fok
61b14c7f04 Updated Chinese (Taiwan) translation 2015-11-11 00:36:06 +00:00
Aron Xu
13dff7d5eb Stable backport for zh_CN translation from master 2015-11-11 00:21:32 +08:00
Carlos Garcia Campos
55087d03e4 browser-plugin: link with -Wl,-z,nodelete
This ensures that the module will not be unloaded, since GObject types
registered statically can't be reloaded. This should fix crashes with
browsers that correctly unload the plugins.

https://bugzilla.gnome.org/show_bug.cgi?id=737932
2015-11-10 15:25:40 +01:00
Owen W. Taylor
e7528bf2fa st_theme_node_prerender_shadow: guard against failure to allocate a texture
If we are trying to render a shadow at a size that is very large in one
direction, but small in the other direction (so that we don't 9-slice
the texture), then allocating the backing texture for the offscreen
buffer may fail due to texture-size limits. Don't crash in that case.

https://bugzilla.gnome.org/show_bug.cgi?id=757150
2015-10-27 15:54:00 -04:00
Daniel Șerbănescu
9e64a1e3d6 Updated Romanian translation 2015-10-24 17:02:18 +00:00
Rui Matos
007ac93cd6 ActivitiesButton: fix overview being toggled while still animating
Adds the missing checks for whether we should toggle the overview, on
button and key release.

https://bugzilla.gnome.org/show_bug.cgi?id=756925
2015-10-23 13:44:49 +02:00
Owen W. Taylor
d8336efddc Defend against failure of cairo_pattern_get_surface()
There are quite a few crashes in retrace.fedoraproject.org that are a result of
of cairo_pattern_get_surface() failing, then a subsequent call to
cairo_image_surface_get_width() crashing because no surface was returned to the
out parameter. Knowing what causes these is hard - my best guess is widgets getting
allocated at ridiculous sizes - but avoiding the crash makes sense in any case.

See https://bugzilla.redhat.com/show_bug.cgi?id=1206754

https://bugzilla.gnome.org/show_bug.cgi?id=756983
2015-10-22 15:15:54 -04:00
Ray Strode
a83f822512 animation: do spinner animation with low priority
It's very unexpected that a spinner animation would
preempt idles from running.

This commit runs the spinner animation with a low
priority to ensure it doesn't take over the main
loop.

https://bugzilla.gnome.org/show_bug.cgi?id=754814
2015-10-21 08:54:55 -04:00
Ray Strode
f64d64035a animation: Run every 16ms not ever 14ms
Right now the spinner animation updates every 14ms.
60 frames per second would be one frame per 16.667ms,
so we're waking up more frequently than we need to.

This commit changes the wakeup to happen after 16ms.

https://bugzilla.gnome.org/show_bug.cgi?id=754814
2015-10-21 08:54:31 -04:00
Ray Strode
5583f881df gdm: don't emit start-session-when-ready from idle function
There's no point in delaying the emission.  We should do it
right away.

https://bugzilla.gnome.org/show_bug.cgi?id=754814
2015-10-21 08:54:24 -04:00
Balázs Meskó
10e4382a7d Updated Hungarian translation 2015-10-21 06:08:43 +00:00
Sveinn í Felli
9f0ee0dc9f Updated Icelandic translation 2015-10-20 14:25:09 +00:00
Owen W. Taylor
2f82f783f2 Fix text-scaling-factor under wayland.
The text-scaling-factor GSetting was not being properly propagated
to clutter and the Pango font map; under X this is done by Clutter,
which listens to XSETTINGS directly.

https://bugzilla.gnome.org/show_bug.cgi?id=756447
2015-10-20 09:37:57 -04:00
Rui Matos
4d066e3916 windowMenu: Ensure the source actor isn't sized 0x0
If the source actor is sized 0x0, the grabHelper will close the menu
on button release if the menu ends up flipped because in that case the
release event happens when the pointer is neither over the source
actor (since it's 0x0) or over the menu actor. A zero sized source
actor works for the non-flipped menu case because the menu's actor
itself ends up underneath the pointer.

https://bugzilla.gnome.org/show_bug.cgi?id=756605
2015-10-20 15:11:31 +02:00
Khaled Hosny
342fbd16d3 Add RLM as appropriate 2015-10-18 17:23:22 +04:00
Cosimo Cecchi
8ae0c69ccf windowManager: fix fullscreen clone being left around
If we get another effect on the same actor, we should make sure to
remove the clone through the "overwrite" methods provided by Tweener, or
there will be a race that might end up with a stray clone being left
around.

https://bugzilla.gnome.org/show_bug.cgi?id=756714
2015-10-16 14:11:10 -07:00
Kjartan Maraas
bed660bdf4 Fix some issues reported by Bjørn Lie in bug 740906. 2015-10-16 18:12:28 +02:00
Florian Müllner
ab2ca17b76 windowManager: Fix fullscreen animations on dualscreen
The translation should describe the difference between the fullscreened
and unfullscreened position of the window - however we are currently
assuming a fullscreen position of (0, 0) instead of the monitor's origin,
which causes glitches on dualscreen setups.

https://bugzilla.gnome.org/show_bug.cgi?id=756697
2015-10-16 15:52:07 +02:00
237 changed files with 26715 additions and 31810 deletions

10
.gitignore vendored
View File

@@ -16,8 +16,11 @@ config.log
config.status
config
configure
data/org.gnome.Shell.desktop
data/org.gnome.Shell.desktop.in
data/50-gnome-shell-*.xml
data/gnome-shell.desktop
data/gnome-shell.desktop.in
data/gnome-shell-wayland.desktop
data/gnome-shell-wayland.desktop.in
data/gnome-shell-extension-prefs.desktop
data/gnome-shell-extension-prefs.desktop.in
data/gnome-shell-theme.gresource
@@ -25,6 +28,8 @@ data/gschemas.compiled
data/perf-background.xml
data/org.gnome.shell.gschema.xml
data/org.gnome.shell.gschema.valid
data/org.gnome.shell.evolution.calendar.gschema.xml
data/org.gnome.shell.evolution.calendar.gschema.valid
data/org.gnome.Shell.PortalHelper.desktop
data/org.gnome.Shell.PortalHelper.service
data/theme/.sass-cache
@@ -71,6 +76,7 @@ src/*-marshal.[ch]
src/Makefile
src/Makefile.in
src/calendar-server/evolution-calendar.desktop
src/calendar-server/evolution-calendar.desktop.in
src/calendar-server/org.gnome.Shell.CalendarServer.service
src/gnome-shell
src/gnome-shell-calendar-server

264
NEWS
View File

@@ -1,268 +1,54 @@
3.22.0
3.18.5
======
* Misc. bug fixes [Florian, Rui; #771391, #771536] #771656]
Contributors:
Rui Matos, Florian Müllner
Translations:
Ask Hjorth Larsen [da], GNOME Translation Robot [gd], Alexandre Franke [fr],
Daniel Korostil [uk], Jordi Mas [ca], Khaled Hosny [ar], David King [en_GB]
3.21.92
=======
* Adjust screen capture to work with multiple stage views [Jonas; #770128]
* Improve handling of cycle shortcuts [Florian; #771063]
* Fix windows not getting undimmed in some cases [Rui; #770163, #752524]
* Disable extension version check by default [Florian; #770887]
* Misc. bug fixes [Rui, Florian, Michael; #770382, #770888, #770328]
Contributors:
Jonas Ådahl, Michael Catanzaro, Fran Dieguez, Olivier Fourdan, Rui Matos,
Florian Müllner
Translations:
Changwoo Ryu [ko], Baurzhan Muftakhidinov [kk], Aurimas Černius [lt],
Muhammet Kara [tr], Trần Ngọc Quân [vi], A S Alam [pa], Yosef Or Boczko [he],
Anders Jonsson [sv], Tiago Santos [pt], Hannie Dumoleyn [nl],
Rūdolfs Mazurs [lv], Claude Paroz [fr], Arash Mousavi [fa],
Fran Dieguez [gl], Stas Solovey [ru], Tom Tryfonidis [el]
3.21.91
=======
Translations:
Mario Blättermann [de], Jiri Grönroos [fi], Dušan Kazik [sk],
Andika Triwidada [id], Daniel Mustieles [es], Fabio Tomat [fur],
Enrico Nicoletto [pt_BR], Matej Urbančič [sl], Мирослав Николић [sr, sr@latin]
3.21.90.1
=========
Contributors:
Piotr Drąg
Translations:
Marek Černocký [cs], Balázs Úr [hu]
3.21.90
=======
* Improve on-screen keyboard on wayland [Carlos; #765009]
* Misc. bug fixes [Florian; #769156, #769216, #769074]
Contributors:
Carlos Garnacho, Florian Müllner
Translations:
Fabio Tomat [fur], Tiago Santos [pt], Daniel Mustieles [es],
Bernd Homuth [de], Aurimas Černius [lt], Balázs Úr [hu],
Yosef Or Boczko [he], Jiri Grönroos [fi], Marek Cernocky [cs],
Muhammet Kara [tr], Enrico Nicoletto [pt_BR], Andika Triwidada [id]
3.21.4
======
* overview: Fix switching workspaces when scrolling on non-primary monitors
[Florian; #766883, #768316]
* Fix crash when using screen recorder under wayland [Rui; #767001]
* Update theme on video memory purge errors [Rui; #739178]
* Free old backgrounds immediately [Hyungwon; #766353]
* Add support for system upgrades to end session dialog [Kalev; #763611]
* Fix maximized windows flickering to the wrong size on restart [Owen; #761566]
* Hide ignored events in calendar as well [Florian; #768538]
* calendar: Only hide dismissed occurrence of recurring event [Florian; #748226]
* Provide org.freedesktop.impl.portal.access implementation [Florian; #768669]
* Misc. bug fixes and cleanups [Rui, Florian, Marinus, Jonas; #767954, #768317,
#746867, #762206, #768956, #768979]
Contributors:
Jonas Ådahl, Piotr Drąg, Hyungwon Hwang, Kalev Lember, Rui Matos,
Florian Müllner, Marinus Schraal, Owen W. Taylor
Translations:
Andika Triwidada [id], Daniel Mustieles [es], Bruce Cowan [en_GB],
Dušan Kazik [sk], Piotr Drąg [pl], Chao-Hsiung Liao [zh_HK]
3.21.3
======
* Do not disable suspend action when locked [Florian; #725960]
* Remember input sources MRU list [Cosimo; #766826]
* networkAgent: Handle VPN service aliases [David; #658484]
* Plug a memory leak [Hans; #710230]
Contributors:
Cosimo Cecchi, Florian Müllner, Hans Petter Jansson, David Woodhouse
Translations:
Tiago Santos [pt], Cédric Valmary [oc], Muhammet Kara [tr],
Daniel Mustieles [es], Rafael Fontenelle [pt_BR]
3.21.2
======
* Fix sorting of hidden apps in app switcher [Florian; #766238]
* Set logind's LockedHint property when locked [Victor; #764773]
* Allocate framebuffers early to fix a crash on NVIDIA [Martin; #764898]
* Fix cycle-windows/cycle-group keybindings [Florian; #730739]
* Switch to shared desktop schema for calendar settings [Iain; #766318]
* Misc. bug fixes [Florian, Cosimo, Michele; #766325, #758471, #757556,
#757019, #766598]
Contributors:
Cosimo Cecchi, Michele Gaio, Iain Lane, Florian Müllner, Martin Szulecki,
Victor Toso
Translations:
Tiago Santos [pt], Kjartan Maraas [nb], Jiro Matsuzawa [ja],
Cédric Valmary [oc], Sveinn í Felli [is]
3.21.1
======
* Save screencasts in HOME if XDG_VIDEO_DIR doesn't exist [Florian; #765015]
* Don't show orientation lock when g-s-d won't rotate [Florian; #765267]
* Misc. bug fixes [Heiher, Florian, Marek, Rui; #722752, #765061, #763068,
#765607, #757676, #760439]
Contributors:
Heiher, Marek Chalupa, Rui Matos, Florian Müllner
Translations:
Arash Mousavi [fa], Kristjan SCHMIDT [eo], GNOME Translation Robot [gd]
3.20.1
======
* Plug a memory leak [Aaron; #735705]
Contributors:
Aaron Plattner
Translations:
Daniel Korostil [uk], Matej Urbančič [sl], Inaki Larranaga Murgoitio [eu],
Cheng-Chia Tseng [zh_TW], Fabio Tomat [fur], Trần Ngọc Quân [vi],
YunQiang Su [zh_CN], Marek Černocký [cs], Arash Mousavi [fa],
Alexander Shopov [bg], Khaled Hosny [ar]
3.20.0
======
Translations:
Changwoo Ryu [ko], Baurzhan Muftakhidinov [kk], Milo Casagrande [it],
Anders Jonsson [sv], Muhammet Kara [tr], Alexandre Franke [fr],
Rūdolfs Mazurs [lv], Ask Hjorth Larsen [da], Jiro Matsuzawa [ja]
3.19.92
=======
* Update location dialog according to latest mockups [Zeeshan; #762480]
* Fix deleting chat notifications in calendar [Florian; #747991]
* Fix recount issue in network agent component [Christophe; #759708]
* Plug a memory leak [Aaron; #735705]
* Do not assert on non-fatal runtime errors [Florian; #765061]
Contributors:
Zeeshan Ali (Khattak), Florian Müllner
Christophe Fergeau, Florian Müllner, Aaron Plattner
Translations:
Rūdolfs Mazurs [lv], Changwoo Ryu [ko], Matej Urbančič [sl],
Justin van Steijn [nl], Fabio Tomat [fur], Kris Thomsen [da],
Marek Černocký [cs], Piotr Drąg [pl], Dušan Kazik [sk],
Мирослав Николић [sr, sr@latin], Balázs Úr [hu], Yosef Or Boczko [he],
Daniel Mustieles [es], Fran Dieguez [gl], Bernd Homuth [de],
Tom Tryfonidis [el], Jiri Grönroos [fi], Gil Forcada [ca],
Artur Morais [pt_BR], Aurimas Černius [lt], Stas Solovey [ru]
Matej Urbančič [sl], Marek Černocký [cs]
3.19.91
=======
* location: Ask user only once [Zeeshan; #762559]
* Fix jiggling when auto-hiding legacy tray [Florian; #747957]
* Misc. bug fixes [Florian, Michael, Ting-Wei; #762475, #762507, #755659]
Contributors:
Zeeshan Ali (Khattak), Michael Catanzaro, Ting-Wei Lan, Florian Müllner
Translations:
Мирослав Николић [sr, sr@latin], Piotr Drąg [pl], A S Alam [pa],
Artur de Aquino Morais [pt_BR], Daniel Mustieles [es],
Chao-Hsiung Liao [zh_TW], Daniel Korostil [uk], Fran Dieguez [gl],
Tom Tryfonidis [el], Bernd Homuth [de], Sebastian Rasmussen [sv],
Jordi Mas [ca], Piotr Drąg [ga], Cédric Valmary [oc], Gábor Kelemen [hu],
Baurzhan Muftakhidinov [kk], Friedel Wolff [af], Marek Černocký [cs],
Mingye Wang (Arthur2e5) [zh_CN], Aron Xu [zh_CN], Khaled Hosny [ar],
Aurimas Černius [lt], Stas Solovey [ru], Yosef Or Boczko [he]
3.19.90
=======
* Correctly identify VPN secret requests [Lubomir; #760999]
* Improve week number presentation [Jakub; #683245]
* Add audio device selection dialog [Florian; #760284]
* Add media controls to the time and date drop down [Florian; #756491]
* Fix IBus candidate popup position under wayland [Rui; #753476]
* Ask user to grant applications access to location [Zeeshan; #762119]
* Misc. bug fixes [Mario, Jakub, Florian; #761208, #761772, #762270]
Contributors:
Zeeshan Ali (Khattak), Michael Catanzaro, Rui Matos, Florian Müllner,
Lubomir Rintel, Mario Sanchez Prada, Jakub Steiner
Translations:
Alexander Shopov [bg], Balázs Meskó [hu], Fabio Tomat [fur],
Dušan Kazik [sk], Piotr Drąg [pl], Alexandre Franke [fr],
Mario Blättermann [de], Milo Casagrande [it], Jordi Mas [ca]
3.19.4
======
* gdm: Do not allow bypassing disabled Sign In button [Michael; #746180]
* Style week numbers in calendar [Jakub; #683245]
* Misc. bug fixes [Christophe, Jakub, Rui; #759708, #760577, #760945]
Contributors:
Michael Catanzaro, Marek Černocký, Christophe Fergeau, Rui Matos,
Jakub Steiner
Translations:
Aurimas Černius [lt], Enrico Nicoletto [pt_BR], Andika Triwidada [id],
Mario Blättermann [de], Marek Černocký [cs], Kjartan Maraas [nb],
Muhammet Kara [tr], Stas Solovey [ru]
3.19.3
3.18.4
======
* Fix thumbnail scaling in window switcher on HiDPI [Florian; #758676]
* Update animated backgrounds on timezone changes [Florian; #758939]
* loginDialog: Update user list on user changes [Michael; #758568]
* Fix touch interaction on wayland [Carlos; #756748]
* gdm: Do not allow bypassing disabled Sign In button [Michael; #746180]
* Correctly identify VPN secret requests [Lubomir; #760999]
Contributors:
Michael Catanzaro, Carlos Garnacho, Kalev Lember, Florian Müllner
Michael Catanzaro, Florian Müllner, Lubomir Rintel
Translations:
Daniel Korostil [uk], Muhammet Kara [tr], Dušan Kazik [sk],
Baurzhan Muftakhidinov [kk], Marek Černocký [cs]
Kristjan SCHMIDT [eo], Daniel Korostil [uk], Andika Triwidada [id]
3.19.2
3.18.3
======
* Make gnome-shell DBus activatable [Ray; #741666]
* Fix browser plugin crash in Firefox [Carlos; #737932, #757940]
* Optionally show battery percentage in system status area [Bastien; #735771]
* Misc. bug fixes [Kalev, Florian, Bastien; #757418, #757668, #757779, #757816,
#745626, #758220]
Contributors:
Michael Biebl, Michael Catanzaro, Piotr Drąg, Carlos Garcia Campos,
Kalev Lember, Florian Müllner, Bastien Nocera, Ray Strode
Carlos Garcia Campos
Translations:
Pedro Albuquerque [pt], liushuyu [zh_CN], Yosef Or Boczko [he],
Jiri Grönroos [fi], Kjartan Maraas [nb], GNOME Translation Robot [gd],
Daniel Mustieles [es], Marek Černocký [cs], Kristjan SCHMIDT [eo],
Stas Solovey [ru]
3.19.1
3.18.2
======
* Fix fullscreen animation glitches [Florian, Cosimo; #756697, #756714]
* Fix window menu being closed immediately in top orientation [Rui; #756605]
* Respect text-scaling factor under wayland [Owen; #756447]
* Show the Bluetooth submenu when there were setup devices [Bastien; #723848]
* Misc. bug fixes [Florian, Cosimo, Rui, Ray, Owen, Jakub, Bastien;
#756697, #756714, #756605, #754814, #738942, #756983, #756925,
#757011, #673235, #757150]
* Fix login screen getting stuck after authentification [Ray; #754814]
* Fix overview being toggled while still animating [Rui; #756925]
* Improve robustness of browser plugin [Carlos; #737932, #757940]
* Misc. bug fixes [Owen, Florian; #756983, #757150, #757779]
Contributors:
Cosimo Cecchi, Rui Matos, Florian Müllner, Bastien Nocera, Jakub Steiner,
Ray Strode, Owen W. Taylor
Cosimo Cecchi, Carlos Garcia Campos, Rui Matos, Florian Müllner, Ray Strode,
Owen W. Taylor
Translations:
Kjartan Maraas [nb], Khaled Hosny [ar], Balázs Meskó [hu],
Daniel Șerbănescu [ro], Marek Černocký [cs]
Kjartan Maraas [nb], Khaled Hosny [ar], Sveinn í Felli [is],
Balázs Meskó [hu], Daniel Șerbănescu [ro], Aron Xu [zh_CN],
Anthony Fok [zh_TW]
3.18.1
======

View File

@@ -33,11 +33,11 @@
#include <json-glib/json-glib.h>
#define ORIGIN "extensions.gnome.org"
#define PLUGIN_NAME "GNOME Shell Integration"
#define PLUGIN_DESCRIPTION "This plugin provides integration with GNOME Shell " \
#define PLUGIN_NAME "Gnome Shell Integration"
#define PLUGIN_DESCRIPTION "This plugin provides integration with Gnome Shell " \
"for live extension enabling and disabling. " \
"It can be used only by extensions.gnome.org"
#define PLUGIN_MIME_STRING "application/x-gnome-shell-integration::GNOME Shell Integration Dummy Content-Type";
#define PLUGIN_MIME_STRING "application/x-gnome-shell-integration::Gnome Shell Integration Dummy Content-Type";
#define PLUGIN_API_VERSION 5
@@ -163,6 +163,14 @@ on_shell_signal (GDBusProxy *proxy,
{
PluginObject *obj = user_data;
/* FIXME: We have half a dozen bug reports in which this function crashes in
* WebKit due to a null NPObject. This should never happen, but since it is
* happening, let's turn the crash into a critical.
*
* https://bugzilla.gnome.org/show_bug.cgi?id=737932
*/
g_return_if_fail (obj->instance);
if (strcmp (signal_name, "ExtensionStatusChanged") == 0)
{
gchar *uuid;
@@ -193,6 +201,12 @@ on_shell_appeared (GDBusConnection *connection,
{
PluginObject *obj = (PluginObject*) user_data;
/* FIXME: Not sure if this is ever hit or not, but let's play it safe.
*
* https://bugzilla.gnome.org/show_bug.cgi?id=737932
*/
g_return_if_fail (obj->instance);
if (obj->restart_listener)
{
NPVariant result = { NPVariantType_Void };
@@ -1029,6 +1043,7 @@ NPP_GetValue(NPP instance,
if (!instance->pdata)
return NPERR_INVALID_INSTANCE_ERROR;
funcs.retainobject (instance->pdata);
*(NPObject**)value = instance->pdata;
break;

View File

@@ -1,5 +1,5 @@
AC_PREREQ(2.63)
AC_INIT([gnome-shell],[3.22.0],[https://bugzilla.gnome.org/enter_bug.cgi?product=gnome-shell],[gnome-shell])
AC_INIT([gnome-shell],[3.18.5],[https://bugzilla.gnome.org/enter_bug.cgi?product=gnome-shell],[gnome-shell])
AX_IS_RELEASE([git-directory])
AC_CONFIG_HEADERS([config.h])
@@ -24,14 +24,13 @@ LT_PREREQ([2.2.6])
LT_INIT([disable-static])
# i18n
IT_PROG_INTLTOOL([0.40])
GETTEXT_PACKAGE=gnome-shell
AC_SUBST(GETTEXT_PACKAGE)
AC_DEFINE_UNQUOTED(GETTEXT_PACKAGE, "$GETTEXT_PACKAGE",
[The prefix for our gettext translation domains.])
AM_GNU_GETTEXT_VERSION([0.19.6])
AM_GNU_GETTEXT([external])
PKG_PROG_PKG_CONFIG([0.22])
AC_PATH_PROG([XSLTPROC], [xsltproc])
@@ -53,7 +52,7 @@ if $PKG_CONFIG --exists gstreamer-1.0 '>=' $GSTREAMER_MIN_VERSION ; then
AC_MSG_RESULT(yes)
build_recorder=true
recorder_modules="gstreamer-1.0 gstreamer-base-1.0 x11 gtk+-3.0"
PKG_CHECK_MODULES(TEST_SHELL_RECORDER, $recorder_modules mutter-clutter-1.0)
PKG_CHECK_MODULES(TEST_SHELL_RECORDER, $recorder_modules clutter-1.0)
else
AC_MSG_RESULT(no)
fi
@@ -76,9 +75,9 @@ AS_IF([test x$enable_systemd != xno], [
AC_MSG_RESULT($enable_systemd)
CLUTTER_MIN_VERSION=1.21.5
GOBJECT_INTROSPECTION_MIN_VERSION=1.49.1
GOBJECT_INTROSPECTION_MIN_VERSION=1.45.4
GJS_MIN_VERSION=1.39.0
MUTTER_MIN_VERSION=3.22.0
MUTTER_MIN_VERSION=3.18.1
GTK_MIN_VERSION=3.15.0
GIO_MIN_VERSION=2.45.3
LIBECAL_MIN_VERSION=3.5.3
@@ -99,8 +98,8 @@ SHARED_PCS="gio-unix-2.0 >= $GIO_MIN_VERSION
gjs-internals-1.0 >= $GJS_MIN_VERSION
$recorder_modules
gdk-x11-3.0 libsoup-2.4
mutter-clutter-1.0 >= $CLUTTER_MIN_VERSION
mutter-cogl-pango-1.0
clutter-x11-1.0 >= $CLUTTER_MIN_VERSION
clutter-glx-1.0 >= $CLUTTER_MIN_VERSION
libstartup-notification-1.0 >= $STARTUP_NOTIFICATION_MIN_VERSION
gobject-introspection-1.0 >= $GOBJECT_INTROSPECTION_MIN_VERSION
libcanberra libcanberra-gtk3
@@ -115,12 +114,12 @@ PKG_CHECK_MODULES(GNOME_SHELL, $SHARED_PCS)
PKG_CHECK_MODULES(MUTTER, libmutter >= $MUTTER_MIN_VERSION)
PKG_CHECK_MODULES(GNOME_SHELL_JS, gio-2.0 gjs-internals-1.0 >= $GJS_MIN_VERSION)
PKG_CHECK_MODULES(ST, mutter-clutter-1.0 gtk+-3.0 libcroco-0.6 >= 0.6.8 x11)
PKG_CHECK_MODULES(ST, clutter-1.0 gtk+-3.0 libcroco-0.6 >= 0.6.8 x11)
PKG_CHECK_MODULES(SHELL_PERF_HELPER, gtk+-3.0 gio-2.0)
PKG_CHECK_MODULES(SHELL_HOTPLUG_SNIFFER, gio-2.0 gdk-pixbuf-2.0)
PKG_CHECK_MODULES(TRAY, mutter-clutter-1.0 gtk+-3.0)
PKG_CHECK_MODULES(TRAY, gtk+-3.0)
PKG_CHECK_MODULES(GVC, libpulse >= $PULSE_MIN_VERS libpulse-mainloop-glib gobject-2.0)
PKG_CHECK_MODULES(DESKTOP_SCHEMAS, gsettings-desktop-schemas >= 3.21.3)
PKG_CHECK_MODULES(DESKTOP_SCHEMAS, gsettings-desktop-schemas >= 3.13.1)
AC_ARG_ENABLE(browser-plugin,
[AS_HELP_STRING([--enable-browser-plugin],
@@ -255,6 +254,7 @@ AC_CONFIG_FILES([
docs/reference/st/Makefile
docs/reference/st/st-docs.sgml
js/Makefile
src/calendar-server/evolution-calendar.desktop.in
src/Makefile
src/gvc/Makefile
browser-plugin/Makefile

View File

@@ -1,24 +1,24 @@
<?xml version="1.0" encoding="UTF-8" ?>
<KeyListEntries schema="org.gnome.shell.keybindings"
group="system"
name="System"
_name="System"
wm_name="GNOME Shell"
package="gnome-shell">
<KeyListEntry name="toggle-message-tray"
description="Show the notification list"/>
_description="Show the notification list"/>
<KeyListEntry name="focus-active-notification"
description="Focus the active notification"/>
_description="Focus the active notification"/>
<KeyListEntry name="toggle-overview"
description="Show the overview"/>
_description="Show the overview"/>
<KeyListEntry name="toggle-application-view"
description="Show all applications"/>
_description="Show all applications"/>
<KeyListEntry name="open-application-menu"
description="Open the application menu"/>
_description="Open the application menu"/>
</KeyListEntries>

View File

@@ -2,21 +2,17 @@ CLEANFILES =
NULL =
desktopdir=$(datadir)/applications
desktop_DATA = org.gnome.Shell.desktop gnome-shell-extension-prefs.desktop
desktop_DATA = gnome-shell.desktop gnome-shell-wayland.desktop gnome-shell-extension-prefs.desktop
if HAVE_NETWORKMANAGER
desktop_DATA += org.gnome.Shell.PortalHelper.desktop
portaldir = $(datadir)/xdg-desktop-portal/portals
portal_DATA = gnome-shell.portal
servicedir = $(datadir)/dbus-1/services
service_DATA = org.gnome.Shell.PortalHelper.service
CLEANFILES += \
org.gnome.Shell.PortalHelper.service \
org.gnome.Shell.PortalHelper.desktop \
org.gnome.Shell.PortalHelper.desktop.in \
org.gnome.Shell.PortalHelper.service \
org.gnome.Shell.PortalHelper.desktop \
$(NULL)
endif
@@ -32,9 +28,7 @@ endif
-e "s|@VERSION[@]|$(VERSION)|" \
$< > $@ || rm $@
%.desktop:%.desktop.in
$(AM_V_GEN) $(MSGFMT) --desktop --template $(builddir)/$< \
-d $(top_srcdir)/po -o $@
@INTLTOOL_DESKTOP_RULE@
introspectiondir = $(datadir)/dbus-1/interfaces
introspection_DATA = \
@@ -86,11 +80,14 @@ perf-background.xml: perf-background.xml.in
$< > $@ || rm $@
keysdir = @GNOME_KEYBINDINGS_KEYSDIR@
keys_DATA = 50-gnome-shell-system.xml
keys_in_files = 50-gnome-shell-system.xml.in
keys_DATA = $(keys_in_files:.xml.in=.xml)
gsettings_SCHEMAS = org.gnome.shell.gschema.xml
%.gschema.xml: %.gschema.xml.in Makefile
@INTLTOOL_XML_NOMERGE_RULE@
%.gschema.xml.in: %.gschema.xml.in.in Makefile
$(AM_V_GEN) sed -e 's|@GETTEXT_PACKAGE[@]|$(GETTEXT_PACKAGE)|g' \
$< > $@ || rm $@
@@ -107,29 +104,32 @@ convertdir = $(datadir)/GConf/gsettings
convert_DATA = gnome-shell-overrides.convert
EXTRA_DIST = \
org.gnome.Shell.desktop.in.in \
gnome-shell.desktop.in.in \
gnome-shell-wayland.desktop.in.in \
gnome-shell-extension-prefs.desktop.in.in \
$(portal_DATA) \
$(introspection_DATA) \
$(menu_DATA) \
$(convert_DATA) \
$(keys_DATA) \
$(keys_in_files) \
$(dist_theme_files) \
perf-background.xml.in \
org.gnome.Shell.PortalHelper.desktop.in.in \
org.gnome.Shell.PortalHelper.desktop.in \
org.gnome.Shell.PortalHelper.service.in \
org.gnome.shell.gschema.xml.in \
org.gnome.shell.gschema.xml.in.in \
gnome-shell-theme.gresource.xml \
$(resource_files) \
$(NULL)
CLEANFILES += \
org.gnome.Shell.desktop.in \
gnome-shell.desktop.in \
gnome-shell-wayland.desktop.in \
gnome-shell-extension-prefs.in \
$(desktop_DATA) \
$(keys_DATA) \
$(gsettings_SCHEMAS) \
perf-background.xml \
gschemas.compiled \
org.gnome.shell.gschema.valid \
org.gnome.shell.gschema.xml.in \
gnome-shell-theme.gresource \
$(NULL)

View File

@@ -1,7 +1,7 @@
[Desktop Entry]
Type=Application
Name=GNOME Shell Extension Preferences
Comment=Configure GNOME Shell Extensions
_Name=GNOME Shell Extension Preferences
_Comment=Configure GNOME Shell Extensions
Exec=@bindir@/gnome-shell-extension-prefs %u
X-GNOME-Bugzilla-Bugzilla=GNOME
X-GNOME-Bugzilla-Product=gnome-shell

View File

@@ -0,0 +1,15 @@
[Desktop Entry]
Type=Application
_Name=GNOME Shell (wayland compositor)
_Comment=Window management and application launching
Exec=@bindir@/gnome-shell --wayland --display-server
X-GNOME-Bugzilla-Bugzilla=GNOME
X-GNOME-Bugzilla-Product=gnome-shell
X-GNOME-Bugzilla-Component=general
X-GNOME-Bugzilla-Version=@VERSION@
Categories=GNOME;GTK;Core;
OnlyShowIn=GNOME;
NoDisplay=true
X-GNOME-Autostart-Phase=DisplayServer
X-GNOME-Autostart-Notify=true
X-GNOME-AutoRestart=false

View File

@@ -1,7 +1,7 @@
[Desktop Entry]
Type=Application
Name=GNOME Shell
Comment=Window management and application launching
_Name=GNOME Shell
_Comment=Window management and application launching
Exec=@bindir@/gnome-shell
X-GNOME-Bugzilla-Bugzilla=GNOME
X-GNOME-Bugzilla-Product=gnome-shell
@@ -10,7 +10,7 @@ X-GNOME-Bugzilla-Version=@VERSION@
Categories=GNOME;GTK;Core;
OnlyShowIn=GNOME;
NoDisplay=true
X-GNOME-Autostart-Phase=DisplayServer
X-GNOME-Autostart-Phase=WindowManager
X-GNOME-Provides=panel;windowmanager;
X-GNOME-Autostart-Notify=true
X-GNOME-AutoRestart=false

View File

@@ -1,4 +0,0 @@
[portal]
DBusName=org.freedesktop.impl.portal.desktop.gnome
Interfaces=org.freedesktop.impl.portal.Access
UseIn=gnome

View File

@@ -1,10 +1,9 @@
[Desktop Entry]
Name=Network Login
_Name=Network Login
Type=Application
Exec=gapplication launch org.gnome.Shell.PortalHelper
DBusActivatable=true
NoDisplay=true
# Translators: Do NOT translate or transliterate this text (this is an icon file name)!
Icon=network-workgroup
StartupNotify=true
OnlyShowIn=GNOME;

View File

@@ -3,131 +3,133 @@
gettext-domain="@GETTEXT_PACKAGE@">
<key name="development-tools" type="b">
<default>true</default>
<summary>
<_summary>
Enable internal tools useful for developers and testers from Alt-F2
</summary>
<description>
</_summary>
<_description>
Allows access to internal debugging and monitoring tools
using the Alt-F2 dialog.
</description>
</_description>
</key>
<key name="enabled-extensions" type="as">
<default>[]</default>
<summary>UUIDs of extensions to enable</summary>
<description>
<_summary>UUIDs of extensions to enable</_summary>
<_description>
GNOME Shell extensions have a UUID property; this key lists extensions
which should be loaded. Any extension that wants to be loaded needs
to be in this list. You can also manipulate this list with the
EnableExtension and DisableExtension D-Bus methods on org.gnome.Shell.
</description>
</_description>
</key>
<key name="disable-extension-version-validation" type="b">
<default>true</default>
<summary>Disables the validation of extension version compatibility</summary>
<description>
<default>false</default>
<_summary>Disables the validation of extension version compatibility</_summary>
<_description>
GNOME Shell will only load extensions that claim to support the current
running version. Enabling this option will disable this check and try to
load all extensions regardless of the versions they claim to support.
</description>
</_description>
</key>
<key name="favorite-apps" type="as">
<default>[ 'epiphany.desktop', 'evolution.desktop', 'rhythmbox.desktop', 'shotwell.desktop', 'org.gnome.Nautilus.desktop', 'org.gnome.Software.desktop' ]</default>
<summary>List of desktop file IDs for favorite applications</summary>
<description>
<_summary>List of desktop file IDs for favorite applications</_summary>
<_description>
The applications corresponding to these identifiers
will be displayed in the favorites area.
</description>
</_description>
</key>
<key name="app-picker-view" type="u">
<default>0</default>
<summary>App Picker View</summary>
<description>
<_summary>App Picker View</_summary>
<_description>
Index of the currently selected view in the application picker.
</description>
</_description>
</key>
<key name="command-history" type="as">
<default>[]</default>
<summary>History for command (Alt-F2) dialog</summary>
<_summary>History for command (Alt-F2) dialog</_summary>
</key>
<key name="looking-glass-history" type="as">
<default>[]</default>
<!-- Translators: looking glass is a debugger and inspector tool, see https://wiki.gnome.org/Projects/GnomeShell/LookingGlass -->
<summary>History for the looking glass dialog</summary>
<!-- Translators: looking glass is a debugger and inspector tool, see https://live.gnome.org/GnomeShell/LookingGlass -->
<_summary>History for the looking glass dialog</_summary>
</key>
<key name="always-show-log-out" type="b">
<default>false</default>
<summary>Always show the 'Log out' menu item in the user menu.</summary>
<description>
<_summary>Always show the 'Log out' menu item in the user menu.</_summary>
<_description>
This key overrides the automatic hiding of the 'Log out'
menu item in single-user, single-session situations.
</description>
</_description>
</key>
<key name="remember-mount-password" type="b">
<default>false</default>
<summary>Whether to remember password for mounting encrypted or remote filesystems</summary>
<description>
<_summary>Whether to remember password for mounting encrypted or remote filesystems</_summary>
<_description>
The shell will request a password when an encrypted device or a
remote filesystem is mounted. If the password can be saved for
future use a 'Remember Password' checkbox will be present.
This key sets the default state of the checkbox.
</description>
</key>
<key name="had-bluetooth-devices-setup" type="b">
<default>false</default>
<summary>Whether the default Bluetooth adapter had set up devices associated to it</summary>
<description>
The shell will only show a Bluetooth menu item if a Bluetooth
adapter is powered, or if there were devices set up associated
with the default adapter. This will be reset if the default
adapter is ever seen not to have devices associated to it.
</description>
</_description>
</key>
<child name="calendar" schema="org.gnome.shell.calendar"/>
<child name="keybindings" schema="org.gnome.shell.keybindings"/>
<child name="keyboard" schema="org.gnome.shell.keyboard"/>
</schema>
<schema id="org.gnome.shell.calendar" path="/org/gnome/shell/calendar/"
gettext-domain="@GETTEXT_PACKAGE@">
<key name="show-weekdate" type="b">
<default>false</default>
<_summary>Show the week date in the calendar</_summary>
<_description>
If true, display the ISO week date in the calendar.
</_description>
</key>
</schema>
<schema id="org.gnome.shell.keybindings" path="/org/gnome/shell/keybindings/"
gettext-domain="@GETTEXT_PACKAGE@">
<key name="open-application-menu" type="as">
<default>["&lt;Super&gt;F10"]</default>
<summary>Keybinding to open the application menu</summary>
<description>
<_summary>Keybinding to open the application menu</_summary>
<_description>
Keybinding to open the application menu.
</description>
</_description>
</key>
<key name="toggle-application-view" type="as">
<default>["&lt;Super&gt;a"]</default>
<summary>Keybinding to open the "Show Applications" view</summary>
<description>
<_summary>Keybinding to open the "Show Applications" view</_summary>
<_description>
Keybinding to open the "Show Applications" view of the Activities
Overview.
</description>
</_description>
</key>
<key name="toggle-overview" type="as">
<default>["&lt;Super&gt;s"]</default>
<summary>Keybinding to open the overview</summary>
<description>
<_summary>Keybinding to open the overview</_summary>
<_description>
Keybinding to open the Activities Overview.
</description>
</_description>
</key>
<key name="toggle-message-tray" type="as">
<default>["&lt;Super&gt;v","&lt;Super&gt;m"]</default>
<summary>Keybinding to toggle the visibility of the notification list</summary>
<description>
<_summary>Keybinding to toggle the visibility of the notification list</_summary>
<_description>
Keybinding to toggle the visibility of the notification list.
</description>
</_description>
</key>
<key name="focus-active-notification" type="as">
<default>["&lt;Super&gt;n"]</default>
<summary>Keybinding to focus the active notification</summary>
<description>
<_summary>Keybinding to focus the active notification</_summary>
<_description>
Keybinding to focus the active notification.
</description>
</_description>
</key>
<key name="pause-resume-tweens" type="as">
<default>[]</default>
<summary>Keybinding that pauses and resumes all running tweens, for debugging purposes</summary>
<description></description>
<_summary>Keybinding that pauses and resumes all running tweens, for debugging purposes</_summary>
<_description></_description>
</key>
</schema>
@@ -135,10 +137,10 @@
gettext-domain="@GETTEXT_PACKAGE@">
<key name="keyboard-type" type="s">
<default>'touch'</default>
<summary>Which keyboard to use</summary>
<description>
<_summary>Which keyboard to use</_summary>
<_description>
The type of keyboard to use.
</description>
</_description>
</key>
</schema>
@@ -147,11 +149,11 @@
gettext-domain="@GETTEXT_PACKAGE@">
<key type="b" name="current-workspace-only">
<default>false</default>
<summary>Limit switcher to current workspace.</summary>
<description>
<_summary>Limit switcher to current workspace.</_summary>
<_description>
If true, only applications that have windows on the current workspace are shown in the switcher.
Otherwise, all applications are included.
</description>
</_description>
</key>
</schema>
@@ -165,20 +167,20 @@
gettext-domain="@GETTEXT_PACKAGE@">
<key name="app-icon-mode" enum="org.gnome.shell.window-switcher.AppIconMode">
<default>'both'</default>
<summary>The application icon mode.</summary>
<description>
<_summary>The application icon mode.</_summary>
<_description>
Configures how the windows are shown in the switcher. Valid possibilities
are 'thumbnail-only' (shows a thumbnail of the window), 'app-icon-only'
(shows only the application icon) or 'both'.
</description>
</_description>
</key>
<key type="b" name="current-workspace-only">
<default>true</default>
<summary>Limit switcher to current workspace.</summary>
<description>
<_summary>Limit switcher to current workspace.</_summary>
<_description>
If true, only windows from the current workspace are shown in the switcher.
Otherwise, all windows are included.
</description>
</_description>
</key>
</schema>
@@ -186,43 +188,43 @@
gettext-domain="@GETTEXT_PACKAGE@">
<key name="attach-modal-dialogs" type="b">
<default>true</default>
<summary>Attach modal dialog to the parent window</summary>
<description>
<_summary>Attach modal dialog to the parent window</_summary>
<_description>
This key overrides the key in org.gnome.mutter when running
GNOME Shell.
</description>
</_description>
</key>
<key name="edge-tiling" type="b">
<default>true</default>
<summary>Enable edge tiling when dropping windows on screen edges</summary>
<description>
<_summary>Enable edge tiling when dropping windows on screen edges</_summary>
<_description>
This key overrides the key in org.gnome.mutter when running GNOME Shell.
</description>
</_description>
</key>
<key name="dynamic-workspaces" type="b">
<default>true</default>
<summary>Workspaces are managed dynamically</summary>
<description>
<_summary>Workspaces are managed dynamically</_summary>
<_description>
This key overrides the key in org.gnome.mutter when running GNOME Shell.
</description>
</_description>
</key>
<key name="workspaces-only-on-primary" type="b">
<default>true</default>
<summary>Workspaces only on primary monitor</summary>
<description>
<_summary>Workspaces only on primary monitor</_summary>
<_description>
This key overrides the key in org.gnome.mutter when running GNOME Shell.
</description>
</_description>
</key>
<key name="focus-change-on-pointer-rest" type="b">
<default>true</default>
<summary>Delay focus changes in mouse mode until the pointer stops moving</summary>
<description>
<_summary>Delay focus changes in mouse mode until the pointer stops moving</_summary>
<_description>
This key overrides the key in org.gnome.mutter when running GNOME Shell.
</description>
</_description>
</key>
</schema>
</schemalist>

View File

@@ -41,9 +41,9 @@ stage {
icon-shadow: 0 1px black;
box-shadow: inset 0px 0px 0px 1px #215d9c; }
.button:insensitive {
color: gray;
color: #7f7f7f;
border-color: rgba(0, 0, 0, 0.7);
background-color: rgba(62, 67, 69, 0.7);
background-color: rgba(62, 67, 68, 0.7);
box-shadow: none;
text-shadow: none;
icon-shadow: none; }
@@ -65,9 +65,9 @@ stage {
icon-shadow: 0 1px black;
padding: 12px; }
.modal-dialog-linked-button:insensitive {
color: gray;
color: #7f7f7f;
border-color: rgba(0, 0, 0, 0.7);
background-color: rgba(62, 67, 69, 0.7);
background-color: rgba(62, 67, 68, 0.7);
box-shadow: none;
text-shadow: none;
icon-shadow: none; }
@@ -107,8 +107,8 @@ StEntry {
box-shadow: inset 0 2px 4px rgba(0, 0, 0, 0.4);
border-color: rgba(166, 166, 166, 0.5); }
StEntry:insensitive {
color: gray;
border-color: #0e0e0e;
color: #7f7f7f;
border-color: #0d0d0d;
box-shadow: none; }
StEntry StIcon.capslock-warning {
icon-size: 16px;
@@ -142,7 +142,7 @@ StScrollBar {
.slider {
height: 1em;
-slider-height: 0.3em;
-slider-background-color: #0e0e0e;
-slider-background-color: #0d0d0d;
-slider-border-color: black;
-slider-active-background-color: #215d9c;
-slider-active-border-color: #184472;
@@ -199,7 +199,7 @@ StScrollBar {
border-radius: 9px;
color: #eeeeec;
background-color: rgba(23, 25, 26, 0.95);
border: 1px solid rgba(238, 238, 236, 0.2); }
border: 3px solid rgba(238, 238, 236, 0.5); }
.modal-dialog .modal-dialog-content-box {
padding: 24px; }
.modal-dialog .run-dialog-entry {
@@ -224,7 +224,7 @@ StScrollBar {
/* End Session Dialog */
.end-session-dialog {
spacing: 42px;
border: 1px solid rgba(238, 238, 236, 0.2); }
border: 3px solid rgba(238, 238, 236, 0.2); }
.end-session-dialog-list {
padding-top: 20px; }
@@ -399,77 +399,6 @@ StScrollBar {
width: 48px;
height: 48px; }
/* Audio selection dialog */
.audio-device-selection-dialog {
spacing: 30px; }
.audio-selection-content {
spacing: 20px;
padding: 24px; }
.audio-selection-title {
font-weight: bold;
text-align: center; }
.audio-selection-box {
spacing: 20px; }
.audio-selection-device {
border: 1px solid rgba(238, 238, 236, 0.2);
border-radius: 12px; }
.audio-selection-device:active, .audio-selection-device:hover, .audio-selection-device:focus {
background-color: #215d9c; }
.audio-selection-device-box {
padding: 20px;
spacing: 20px; }
.audio-selection-device-icon {
icon-size: 64px; }
/* Access Dialog */
.access-dialog {
spacing: 30px; }
.access-dialog-main-layout {
padding: 12px 20px 0;
spacing: 12px; }
.access-dialog-content {
max-width: 28em;
spacing: 20px; }
.access-dialog-icon {
min-width: 48px;
icon-size: 48px; }
.access-dialog-title {
font-weight: bold; }
.access-dialog-subtitle {
color: #999999;
font-weight: bold; }
/* Geolocation Dialog */
.geolocation-dialog {
spacing: 30px; }
.geolocation-dialog-main-layout {
spacing: 12px; }
.geolocation-dialog-content {
spacing: 20px; }
.geolocation-dialog-icon {
icon-size: 48px; }
.geolocation-dialog-title {
font-weight: bold; }
.geolocation-dialog-reason {
color: #999999;
font-weight: bold; }
/* Network Agent Dialog */
.network-dialog-secret-table {
spacing-rows: 15px;
@@ -558,9 +487,6 @@ StScrollBar {
border-radius: 0.3em;
background-color: rgba(11, 12, 13, 0.5);
color: #eeeeec; }
.osd-window .level-bar {
background-color: #eeeeec;
border-radius: 0.3em; }
/* App Switcher */
.switcher-popup {
@@ -604,10 +530,6 @@ StScrollBar {
width: 96px;
height: 96px; }
/* Window Cycler */
.cycler-highlight {
border: 5px solid #215d9c; }
/* Workspace Switcher */
.workspace-switcher-group {
padding: 12px; }
@@ -703,8 +625,6 @@ StScrollBar {
#panel .panel-status-indicators-box,
#panel .panel-status-menu-box {
spacing: 2px; }
#panel .power-status.panel-status-indicators-box {
spacing: 0; }
#panel .screencast-indicator {
color: #f57900; }
@@ -796,7 +716,7 @@ StScrollBar {
border-radius: 1.4em; }
.calendar-day-base:hover, .calendar-day-base:focus {
background-color: #0d0d0d; }
.calendar-day-base:active, .calendar-day-base:selected {
.calendar-day-base:active {
color: white;
background-color: #215d9c;
border-color: transparent; }
@@ -815,7 +735,7 @@ StScrollBar {
border-left-width: 1px; }
.calendar-nonwork-day {
color: gray; }
color: #7f7f7f; }
.calendar-today {
font-weight: bold;
@@ -830,17 +750,6 @@ StScrollBar {
color: rgba(255, 255, 255, 0.15);
opacity: 0.5; }
.calendar-week-number {
font-size: 70%;
font-weight: bold;
width: 2.3em;
height: 1.8em;
border-radius: 2px;
padding: 0.5em 0 0;
margin: 6px;
background-color: rgba(255, 255, 255, 0.3);
color: #000; }
/* Message list */
.message-list {
width: 31.5em; }
@@ -899,23 +808,6 @@ StScrollBar {
padding: 8px;
font-size: .9em; }
.message-media-control {
padding: 6px; }
.message-media-control:last-child:ltr {
padding-right: 18px; }
.message-media-control:last-child:rtl {
padding-left: 18px; }
.media-message-cover-icon {
icon-size: 32px; }
.media-message-cover-icon.fallback {
color: #1a1a1a;
background-color: #000;
border: 2px solid #000;
border-radius: 2px;
icon-size: 16px;
padding: 8px; }
.system-switch-user-submenu-icon.user-icon {
icon-size: 20px;
padding: 0 2px; }
@@ -1068,14 +960,10 @@ StScrollBar {
.search-entry {
width: 320px;
padding: 7px 9px;
border-radius: 6px;
border-color: #747467;
color: #eeeeec;
background-color: #2e3436; }
border-radius: 6px; }
.search-entry:focus {
padding: 6px 8px;
border-width: 2px;
border-color: #215d9c; }
border-width: 2px; }
.search-entry .search-entry-icon {
icon-size: 1em;
padding: 0 4px;
@@ -1603,9 +1491,9 @@ StScrollBar {
text-shadow: none;
icon-shadow: none; }
.login-dialog .modal-dialog-button:default:insensitive {
color: gray;
color: #7f7f7f;
border-color: rgba(0, 0, 0, 0.7);
background-color: rgba(62, 67, 69, 0.7);
background-color: rgba(62, 67, 68, 0.7);
box-shadow: none;
text-shadow: none;
icon-shadow: none; }

View File

@@ -41,9 +41,9 @@ stage {
icon-shadow: 0 1px black;
box-shadow: inset 0px 0px 0px 1px #215d9c; }
.button:insensitive {
color: #949796;
color: #939695;
border-color: rgba(0, 0, 0, 0.7);
background-color: rgba(66, 72, 73, 0.7);
background-color: rgba(66, 71, 73, 0.7);
box-shadow: none;
text-shadow: none;
icon-shadow: none; }
@@ -65,9 +65,9 @@ stage {
icon-shadow: 0 1px black;
padding: 12px; }
.modal-dialog-linked-button:insensitive {
color: #949796;
color: #939695;
border-color: rgba(0, 0, 0, 0.7);
background-color: rgba(66, 72, 73, 0.7);
background-color: rgba(66, 71, 73, 0.7);
box-shadow: none;
text-shadow: none;
icon-shadow: none; }
@@ -107,8 +107,8 @@ StEntry {
box-shadow: inset 0 2px 4px rgba(0, 0, 0, 0.4);
border-color: rgba(154, 154, 142, 0.5); }
StEntry:insensitive {
color: #949796;
border-color: #333636;
color: #939695;
border-color: #323636;
box-shadow: none; }
StEntry StIcon.capslock-warning {
icon-size: 16px;
@@ -131,10 +131,10 @@ StScrollBar {
background-color: transparent; }
StScrollBar StButton#vhandle, StScrollBar StButton#hhandle {
border-radius: 8px;
background-color: #a6a8a7;
background-color: #a5a8a6;
margin: 3px; }
StScrollBar StButton#vhandle:hover, StScrollBar StButton#hhandle:hover {
background-color: #cacbc9; }
background-color: #c9cbc9; }
StScrollBar StButton#vhandle:active, StScrollBar StButton#hhandle:active {
background-color: #215d9c; }
@@ -142,7 +142,7 @@ StScrollBar {
.slider {
height: 1em;
-slider-height: 0.3em;
-slider-background-color: #333636;
-slider-background-color: #323636;
-slider-border-color: #1c1f1f;
-slider-active-background-color: #215d9c;
-slider-active-border-color: #184472;
@@ -199,7 +199,7 @@ StScrollBar {
border-radius: 9px;
color: #eeeeec;
background-color: rgba(23, 25, 26, 0.95);
border: 1px solid rgba(238, 238, 236, 0.2); }
border: 3px solid rgba(238, 238, 236, 0.5); }
.modal-dialog .modal-dialog-content-box {
padding: 24px; }
.modal-dialog .run-dialog-entry {
@@ -224,7 +224,7 @@ StScrollBar {
/* End Session Dialog */
.end-session-dialog {
spacing: 42px;
border: 1px solid rgba(238, 238, 236, 0.2); }
border: 3px solid rgba(238, 238, 236, 0.2); }
.end-session-dialog-list {
padding-top: 20px; }
@@ -399,77 +399,6 @@ StScrollBar {
width: 48px;
height: 48px; }
/* Audio selection dialog */
.audio-device-selection-dialog {
spacing: 30px; }
.audio-selection-content {
spacing: 20px;
padding: 24px; }
.audio-selection-title {
font-weight: bold;
text-align: center; }
.audio-selection-box {
spacing: 20px; }
.audio-selection-device {
border: 1px solid rgba(238, 238, 236, 0.2);
border-radius: 12px; }
.audio-selection-device:active, .audio-selection-device:hover, .audio-selection-device:focus {
background-color: #215d9c; }
.audio-selection-device-box {
padding: 20px;
spacing: 20px; }
.audio-selection-device-icon {
icon-size: 64px; }
/* Access Dialog */
.access-dialog {
spacing: 30px; }
.access-dialog-main-layout {
padding: 12px 20px 0;
spacing: 12px; }
.access-dialog-content {
max-width: 28em;
spacing: 20px; }
.access-dialog-icon {
min-width: 48px;
icon-size: 48px; }
.access-dialog-title {
font-weight: bold; }
.access-dialog-subtitle {
color: #8e8e80;
font-weight: bold; }
/* Geolocation Dialog */
.geolocation-dialog {
spacing: 30px; }
.geolocation-dialog-main-layout {
spacing: 12px; }
.geolocation-dialog-content {
spacing: 20px; }
.geolocation-dialog-icon {
icon-size: 48px; }
.geolocation-dialog-title {
font-weight: bold; }
.geolocation-dialog-reason {
color: #8e8e80;
font-weight: bold; }
/* Network Agent Dialog */
.network-dialog-secret-table {
spacing-rows: 15px;
@@ -558,9 +487,6 @@ StScrollBar {
border-radius: 0.3em;
background-color: rgba(11, 12, 13, 0.5);
color: #eeeeec; }
.osd-window .level-bar {
background-color: #eeeeec;
border-radius: 0.3em; }
/* App Switcher */
.switcher-popup {
@@ -604,10 +530,6 @@ StScrollBar {
width: 96px;
height: 96px; }
/* Window Cycler */
.cycler-highlight {
border: 5px solid #215d9c; }
/* Workspace Switcher */
.workspace-switcher-group {
padding: 12px; }
@@ -703,8 +625,6 @@ StScrollBar {
#panel .panel-status-indicators-box,
#panel .panel-status-menu-box {
spacing: 2px; }
#panel .power-status.panel-status-indicators-box {
spacing: 0; }
#panel .screencast-indicator {
color: #f57900; }
@@ -796,7 +716,7 @@ StScrollBar {
border-radius: 1.4em; }
.calendar-day-base:hover, .calendar-day-base:focus {
background-color: #454c4c; }
.calendar-day-base:active, .calendar-day-base:selected {
.calendar-day-base:active {
color: white;
background-color: #215d9c;
border-color: transparent; }
@@ -815,7 +735,7 @@ StScrollBar {
border-left-width: 1px; }
.calendar-nonwork-day {
color: #949796; }
color: #939695; }
.calendar-today {
font-weight: bold;
@@ -830,17 +750,6 @@ StScrollBar {
color: rgba(238, 238, 236, 0.15);
opacity: 0.5; }
.calendar-week-number {
font-size: 70%;
font-weight: bold;
width: 2.3em;
height: 1.8em;
border-radius: 2px;
padding: 0.5em 0 0;
margin: 6px;
background-color: rgba(238, 238, 236, 0.3);
color: #393f3f; }
/* Message list */
.message-list {
width: 31.5em; }
@@ -899,23 +808,6 @@ StScrollBar {
padding: 8px;
font-size: .9em; }
.message-media-control {
padding: 6px; }
.message-media-control:last-child:ltr {
padding-right: 18px; }
.message-media-control:last-child:rtl {
padding-left: 18px; }
.media-message-cover-icon {
icon-size: 32px; }
.media-message-cover-icon.fallback {
color: #515a5a;
background-color: #393f3f;
border: 2px solid #393f3f;
border-radius: 2px;
icon-size: 16px;
padding: 8px; }
.system-switch-user-submenu-icon.user-icon {
icon-size: 20px;
padding: 0 2px; }
@@ -1068,14 +960,10 @@ StScrollBar {
.search-entry {
width: 320px;
padding: 7px 9px;
border-radius: 6px;
border-color: #747467;
color: #eeeeec;
background-color: #2e3436; }
border-radius: 6px; }
.search-entry:focus {
padding: 6px 8px;
border-width: 2px;
border-color: #215d9c; }
border-width: 2px; }
.search-entry .search-entry-icon {
icon-size: 1em;
padding: 0 4px;
@@ -1603,9 +1491,9 @@ StScrollBar {
text-shadow: none;
icon-shadow: none; }
.login-dialog .modal-dialog-button:default:insensitive {
color: #949796;
color: #939695;
border-color: rgba(0, 0, 0, 0.7);
background-color: rgba(66, 72, 73, 0.7);
background-color: rgba(66, 71, 73, 0.7);
box-shadow: none;
text-shadow: none;
icon-shadow: none; }

View File

@@ -113,7 +113,7 @@ expand_content_files=
# e.g. GTKDOC_CFLAGS=-I$(top_srcdir) -I$(top_builddir) $(GTK_DEBUG_FLAGS)
# e.g. GTKDOC_LIBS=$(top_builddir)/gtk/$(gtktargetlib)
GTKDOC_CFLAGS=$(GNOME_SHELL_CFLAGS)
GTKDOC_LIBS=$(GNOME_SHELL_LIBS) $(top_builddir)/src/libgnome-shell-menu.la $(top_builddir)/src/libgnome-shell-base.la $(top_builddir)/src/libgnome-shell.la -rpath $(MUTTER_TYPELIB_DIR)
GTKDOC_LIBS=$(GNOME_SHELL_LIBS) $(top_builddir)/src/libgnome-shell-menu.la $(top_builddir)/src/libgnome-shell-base.la $(top_builddir)/src/libgnome-shell.la
# This includes the standard gtk-doc make rules, copied by gtkdocize.
include $(top_srcdir)/gtk-doc.make

View File

@@ -78,7 +78,7 @@ expand_content_files=
# e.g. GTKDOC_CFLAGS=-I$(top_srcdir) -I$(top_builddir) $(GTK_DEBUG_FLAGS)
# e.g. GTKDOC_LIBS=$(top_builddir)/gtk/$(gtktargetlib)
GTKDOC_CFLAGS=
GTKDOC_LIBS=$(top_builddir)/src/libst-1.0.la -rpath $(MUTTER_TYPELIB_DIR)
GTKDOC_LIBS=$(top_builddir)/src/libst-1.0.la
# This includes the standard gtk-doc make rules, copied by gtkdocize.
include $(top_srcdir)/gtk-doc.make

View File

@@ -23,6 +23,11 @@ const GnomeShellIface = '<node> \
</interface> \
</node>';
const customCss = '.prefs-button { \
padding: 8px; \
border-radius: 20px; \
}';
const GnomeShellProxy = Gio.DBusProxy.makeProxyWrapper(GnomeShellIface);
function stripPrefix(string, prefix) {
@@ -152,7 +157,6 @@ const Application = new Lang.Class({
let scroll = new Gtk.ScrolledWindow({ hscrollbar_policy: Gtk.PolicyType.NEVER,
shadow_type: Gtk.ShadowType.IN,
halign: Gtk.Align.CENTER,
propagate_natural_width: true,
margin: 18 });
this._window.add(scroll);
@@ -172,6 +176,21 @@ const Application = new Lang.Class({
this._window.show_all();
},
_addCustomStyle: function() {
let provider = new Gtk.CssProvider();
try {
provider.load_from_data(customCss, -1);
} catch(e) {
log('Failed to add application style');
return;
}
let screen = this._window.window.get_screen();
let priority = Gtk.STYLE_PROVIDER_PRIORITY_APPLICATION;
Gtk.StyleContext.add_provider_for_screen(screen, provider, priority);
},
_sortList: function(row1, row2) {
let name1 = ExtensionUtils.extensions[row1.uuid].metadata.name;
let name2 = ExtensionUtils.extensions[row2.uuid].metadata.name;
@@ -220,6 +239,7 @@ const Application = new Lang.Class({
_onStartup: function(app) {
this._buildUI(app);
this._addCustomStyle();
this._scanExtensions();
},
@@ -296,7 +316,7 @@ const ExtensionRow = new Lang.Class({
button.add(new Gtk.Image({ icon_name: 'emblem-system-symbolic',
icon_size: Gtk.IconSize.BUTTON,
visible: true }));
button.get_style_context().add_class('circular');
button.get_style_context().add_class('prefs-button');
hbox.add(button);
this.prefsButton = button;

View File

@@ -804,11 +804,6 @@ const LoginDialog = new Lang.Class({
this._user = null;
if (this._nextSignalId) {
this._authPrompt.disconnect(this._nextSignalId);
this._nextSignalId = 0;
}
if (beginRequest == AuthPrompt.BeginRequestType.PROVIDE_USERNAME) {
if (!this._disableUserList)
this._showUserList();

View File

@@ -31,12 +31,10 @@
<file>portalHelper/main.js</file>
<file>ui/accessDialog.js</file>
<file>ui/altTab.js</file>
<file>ui/animation.js</file>
<file>ui/appDisplay.js</file>
<file>ui/appFavorites.js</file>
<file>ui/audioDeviceSelection.js</file>
<file>ui/backgroundMenu.js</file>
<file>ui/background.js</file>
<file>ui/boxpointer.js</file>
@@ -64,9 +62,7 @@
<file>ui/magnifierDBus.js</file>
<file>ui/main.js</file>
<file>ui/messageTray.js</file>
<file>ui/messageList.js</file>
<file>ui/modalDialog.js</file>
<file>ui/mpris.js</file>
<file>ui/notificationDaemon.js</file>
<file>ui/osdWindow.js</file>
<file>ui/osdMonitorLabeler.js</file>

View File

@@ -6,7 +6,9 @@
const Lang = imports.lang;
const Signals = imports.signals;
const GLib = imports.gi.GLib;
const Gio = imports.gi.Gio;
const ShellJS = imports.gi.ShellJS;
const Config = imports.misc.config;
const FileUtils = imports.misc.fileUtils;
@@ -138,11 +140,12 @@ function createExtensionObject(uuid, dir, type) {
return extension;
}
var _extension = null;
function installImporter(extension) {
let oldSearchPath = imports.searchPath.slice(); // make a copy
imports.searchPath = [extension.path];
extension.imports = imports['.']; // "subdir" creates a new importer object
imports.searchPath = oldSearchPath;
_extension = extension;
ShellJS.add_extension_importer('imports.misc.extensionUtils._extension', 'imports', extension.path);
_extension = null;
}
const ExtensionFinder = new Lang.Class({

View File

@@ -40,9 +40,6 @@ const SystemdLoginSessionIface = '<node> \
<signal name="Lock" /> \
<signal name="Unlock" /> \
<property name="Active" type="b" access="read" /> \
<method name="SetLockedHint"> \
<arg type="b" direction="in"/> \
</method> \
</interface> \
</node>';
@@ -134,13 +131,10 @@ const LoginManagerSystemd = new Lang.Class({
canSuspend: function(asyncCallback) {
this._proxy.CanSuspendRemote(function(result, error) {
if (error) {
asyncCallback(false, false);
} else {
let needsAuth = result[0] == 'challenge';
let canSuspend = needsAuth || result[0] == 'yes';
asyncCallback(canSuspend, needsAuth);
}
if (error)
asyncCallback(false);
else
asyncCallback(result[0] != 'no' && result[0] != 'na');
});
},
@@ -193,7 +187,7 @@ const LoginManagerDummy = new Lang.Class({
},
canSuspend: function(asyncCallback) {
asyncCallback(false, false);
asyncCallback(false);
},
listSessions: function(asyncCallback) {

View File

@@ -1,202 +0,0 @@
const Clutter = imports.gi.Clutter;
const Gio = imports.gi.Gio;
const GLib = imports.gi.GLib;
const Lang = imports.lang;
const Pango = imports.gi.Pango;
const Shell = imports.gi.Shell;
const St = imports.gi.St;
const CheckBox = imports.ui.checkBox;
const ModalDialog = imports.ui.modalDialog;
const RequestIface = '<node> \
<interface name="org.freedesktop.impl.portal.Request"> \
<method name="Close"/> \
</interface> \
</node>';
const AccessIface = '<node> \
<interface name="org.freedesktop.impl.portal.Access"> \
<method name="AccessDialog"> \
<arg type="o" name="handle" direction="in"/> \
<arg type="s" name="app_id" direction="in"/> \
<arg type="s" name="parent_window" direction="in"/> \
<arg type="s" name="title" direction="in"/> \
<arg type="s" name="subtitle" direction="in"/> \
<arg type="s" name="body" direction="in"/> \
<arg type="a{sv}" name="options" direction="in"/> \
<arg type="u" name="response" direction="out"/> \
<arg type="a{sv}" name="results" direction="out"/> \
</method> \
</interface> \
</node>';
const DialogResponse = {
OK: 0,
CANCEL: 1,
CLOSED: 2
};
const AccessDialog = new Lang.Class({
Name: 'AccessDialog',
Extends: ModalDialog.ModalDialog,
_init: function(invocation, handle, title, subtitle, body, options) {
this.parent({ styleClass: 'access-dialog' });
this._invocation = invocation;
this._handle = handle;
this._requestExported = false;
this._request = Gio.DBusExportedObject.wrapJSObject(RequestIface, this);
for (let option in options)
options[option] = options[option].deep_unpack();
this._buildLayout(title, subtitle, body, options);
},
_buildLayout: function(title, subtitle, body, options) {
// No support for non-modal system dialogs, so ignore the option
//let modal = options['modal'] || true;
let denyLabel = options['deny_label'] || _("Deny Access");
let grantLabel = options['grant_label'] || _("Grant Access");
let iconName = options['icon'] || null;
let choices = options['choices'] || [];
let mainContentBox = new St.BoxLayout();
mainContentBox.style_class = 'access-dialog-main-layout';
this.contentLayout.add_actor(mainContentBox);
let icon = new St.Icon({ style_class: 'access-dialog-icon',
icon_name: iconName,
y_align: Clutter.ActorAlign.START });
mainContentBox.add_actor(icon);
let messageBox = new St.BoxLayout({ vertical: true });
messageBox.style_class = 'access-dialog-content',
mainContentBox.add_actor(messageBox);
let label;
label = new St.Label({ style_class: 'access-dialog-title headline',
text: title });
messageBox.add_actor(label);
label = new St.Label({ style_class: 'access-dialog-subtitle',
text: subtitle });
label.clutter_text.ellipsize = Pango.EllipsizeMode.NONE;
label.clutter_text.line_wrap = true;
messageBox.add_actor(label);
this._choices = new Map();
for (let i = 0; i < choices.length; i++) {
let [id, name, opts, selected] = choices[i];
if (opts.length > 0)
continue; // radio buttons, not implemented
let check = new CheckBox.CheckBox();
check.getLabelActor().text = name;
check.actor.checked = selected == "true";
messageBox.add_actor(check.actor);
this._choices.set(id, check);
}
label = new St.Label({ text: body });
label.clutter_text.ellipsize = Pango.EllipsizeMode.NONE;
label.clutter_text.line_wrap = true;
messageBox.add_actor(label);
this.addButton({ label: denyLabel,
action: () => {
this._sendResponse(DialogResponse.CANCEL);
},
key: Clutter.KEY_Escape });
this.addButton({ label: grantLabel,
action: () => {
this._sendResponse(DialogResponse.OK);
}});
},
open: function() {
this.parent();
let connection = this._invocation.get_connection();
this._requestExported = this._request.export(connection, this._handle);
},
CloseAsync: function(invocation, params) {
if (this._invocation.get_sender() != invocation.get_sender()) {
invocation.return_error_literal(Gio.DBusError,
Gio.DBusError.ACCESS_DENIED,
'');
return;
}
this._sendResponse(DialogResponse.CLOSED);
},
_sendResponse: function(response) {
if (this._requestExported)
this._request.unexport();
this._requestExported = false;
let results = {};
if (response == DialogResponse.OK) {
for (let [id, check] of this._choices) {
let checked = check.actor.checked ? 'true' : 'false';
results[id] = new GLib.Variant('s', checked);
}
}
// Delay actual response until the end of the close animation (if any)
this.connect('closed', () => {
this._invocation.return_value(new GLib.Variant('(ua{sv})',
[response, results]));
});
this.close();
}
});
const AccessDialogDBus = new Lang.Class({
Name: 'AccessDialogDBus',
_init: function() {
this._accessDialog = null;
this._windowTracker = Shell.WindowTracker.get_default();
this._dbusImpl = Gio.DBusExportedObject.wrapJSObject(AccessIface, this);
this._dbusImpl.export(Gio.DBus.session, '/org/freedesktop/portal/desktop');
Gio.DBus.session.own_name('org.freedesktop.impl.portal.desktop.gnome', Gio.BusNameOwnerFlags.REPLACE, null, null);
},
AccessDialogAsync: function(params, invocation) {
if (this._accessDialog) {
invocation.return_error_literal(Gio.DBusError,
Gio.DBusError.LIMITS_EXCEEDED,
'Already showing a system access dialog');
return;
}
let [handle, appId, parentWindow, title, subtitle, body, options] = params;
// We probably want to use parentWindow and global.display.focus_window
// for this check in the future
if (appId && appId + '.desktop' != this._windowTracker.focus_app.id) {
invocation.return_error_literal(Gio.DBusError,
Gio.DBusError.ACCESS_DENIED,
'Only the focused app is allowed to show a system access dialog');
return;
}
let dialog = new AccessDialog(invocation, handle, title,
subtitle, body, options);
dialog.open();
dialog.connect('closed', () => { this._accessDialog = null; });
this._accessDialog = dialog;
}
});

View File

@@ -354,149 +354,6 @@ const AppSwitcherPopup = new Lang.Class({
}
});
const CyclerHighlight = new Lang.Class({
Name: 'CyclerHighlight',
_init: function() {
this._window = null;
this.actor = new St.Widget({ layout_manager: new Clutter.BinLayout() });
this._clone = new Clutter.Clone();
this.actor.add_actor(this._clone);
this._highlight = new St.Widget({ style_class: 'cycler-highlight' });
this.actor.add_actor(this._highlight);
let coordinate = Clutter.BindCoordinate.ALL;
let constraint = new Clutter.BindConstraint({ coordinate: coordinate });
this._clone.bind_property('source', constraint, 'source', 0);
this.actor.add_constraint(constraint);
this.actor.connect('notify::allocation',
Lang.bind(this, this._onAllocationChanged));
this.actor.connect('destroy', Lang.bind(this, this._onDestroy));
},
set window(w) {
if (this._window == w)
return;
this._window = w;
if (this._clone.source)
this._clone.source.sync_visibility();
let windowActor = this._window ? this._window.get_compositor_private()
: null;
if (windowActor)
windowActor.hide();
this._clone.source = windowActor;
},
_onAllocationChanged: function() {
if (!this._window) {
this._highlight.set_size(0, 0);
this._highlight.hide();
} else {
let [x, y] = this.actor.allocation.get_origin();
let rect = this._window.get_frame_rect();
this._highlight.set_size(rect.width, rect.height);
this._highlight.set_position(rect.x - x, rect.y - y);
this._highlight.show();
}
},
_onDestroy: function() {
this.window = null;
}
});
const CyclerPopup = new Lang.Class({
Name: 'CyclerPopup',
Extends: SwitcherPopup.SwitcherPopup,
Abstract: true,
_init : function() {
this.parent();
this._items = this._getWindows();
if (this._items.length == 0)
return;
this._highlight = new CyclerHighlight();
global.window_group.add_actor(this._highlight.actor);
// We don't show an actual popup, so just provide what SwitcherPopup
// expects instead of inheriting from SwitcherList
this._switcherList = { actor: new St.Widget(),
highlight: Lang.bind(this, this._highlightItem),
connect: function() {} };
},
_highlightItem: function(index, justOutline) {
this._highlight.window = this._items[index];
global.window_group.set_child_above_sibling(this._highlight.actor, null);
},
_finish: function() {
let window = this._items[this._selectedIndex];
let ws = window.get_workspace();
let activeWs = global.screen.get_active_workspace();
if (window.minimized) {
Main.wm.skipNextEffect(window.get_compositor_private());
window.unminimize();
}
if (activeWs == ws) {
Main.activateWindow(window);
} else {
// If the selected window is on a different workspace, we don't
// want it to disappear, then slide in with the workspace; instead,
// always activate it on the active workspace ...
activeWs.activate_with_focus(window, global.get_current_time());
// ... then slide it over to the original workspace if necessary
Main.wm.actionMoveWindow(window, ws);
}
this.parent();
},
_onDestroy: function() {
this._highlight.actor.destroy();
this.parent();
}
});
const GroupCyclerPopup = new Lang.Class({
Name: 'GroupCyclerPopup',
Extends: CyclerPopup,
_getWindows: function() {
let app = Shell.WindowTracker.get_default().focus_app;
return app ? app.get_windows() : [];
},
_keyPressHandler: function(keysym, action) {
if (action == Meta.KeyBindingAction.CYCLE_GROUP)
this._select(this._next());
else if (action == Meta.KeyBindingAction.CYCLE_GROUP_BACKWARD)
this._select(this._previous());
else
return Clutter.EVENT_PROPAGATE;
return Clutter.EVENT_STOP;
}
});
const WindowSwitcherPopup = new Lang.Class({
Name: 'WindowSwitcherPopup',
Extends: SwitcherPopup.SwitcherPopup,
@@ -544,32 +401,6 @@ const WindowSwitcherPopup = new Lang.Class({
}
});
const WindowCyclerPopup = new Lang.Class({
Name: 'WindowCyclerPopup',
Extends: CyclerPopup,
_init: function() {
this._settings = new Gio.Settings({ schema_id: 'org.gnome.shell.window-switcher' });
this.parent();
},
_getWindows: function() {
let workspace = this._settings.get_boolean('current-workspace-only') ? global.screen.get_active_workspace() : null;
return global.display.get_tab_list(Meta.TabList.NORMAL, workspace);
},
_keyPressHandler: function(keysym, action) {
if (action == Meta.KeyBindingAction.CYCLE_WINDOWS)
this._select(this._next());
else if (action == Meta.KeyBindingAction.CYCLE_WINDOWS_BACKWARD)
this._select(this._previous());
else
return Clutter.EVENT_PROPAGATE;
return Clutter.EVENT_STOP;
}
});
const AppIcon = new Lang.Class({
Name: 'AppIcon',

View File

@@ -1814,7 +1814,7 @@ const AppIconMenu = new Lang.Class({
if (!source.actor.mapped)
this.close();
}));
source.actor.connect('destroy', Lang.bind(this, this.destroy));
source.actor.connect('destroy', Lang.bind(this, function () { this.actor.destroy(); }));
Main.uiGroup.add_actor(this.actor);
},

View File

@@ -16,18 +16,16 @@ const RENAMED_DESKTOP_IDS = {
'glchess.desktop': 'gnome-chess.desktop',
'glines.desktop': 'five-or-more.desktop',
'gnect.desktop': 'four-in-a-row.desktop',
'gnibbles.desktop': 'org.gnome.Nibbles.desktop',
'gnibbles.desktop': 'gnome-nibbles.desktop',
'gnobots2.desktop': 'gnome-robots.desktop',
'gnome-boxes.desktop': 'org.gnome.Boxes.desktop',
'gnome-clocks.desktop': 'org.gnome.clocks.desktop',
'gnome-contacts.desktop': 'org.gnome.Contacts.desktop',
'gnome-documents.desktop': 'org.gnome.Documents.desktop',
'gnome-font-viewer.desktop': 'org.gnome.font-viewer.desktop',
'gnome-nibbles.desktop': 'org.gnome.Nibbles.desktop',
'gnome-photos.desktop': 'org.gnome.Photos.desktop',
'gnome-screenshot.desktop': 'org.gnome.Screenshot.desktop',
'gnome-software.desktop': 'org.gnome.Software.desktop',
'gnome-terminal.desktop': 'org.gnome.Terminal.desktop',
'gnome-weather.desktop': 'org.gnome.Weather.Application.desktop',
'gnomine.desktop': 'gnome-mines.desktop',
'gnotravex.desktop': 'gnome-tetravex.desktop',

View File

@@ -1,216 +0,0 @@
const Clutter = imports.gi.Clutter;
const Gio = imports.gi.Gio;
const GLib = imports.gi.GLib;
const Lang = imports.lang;
const Meta = imports.gi.Meta;
const Shell = imports.gi.Shell;
const St = imports.gi.St;
const Main = imports.ui.main;
const ModalDialog = imports.ui.modalDialog;
const AudioDevice = {
HEADPHONES: 1 << 0,
HEADSET: 1 << 1,
MICROPHONE: 1 << 2
};
const AudioDeviceSelectionIface = '<node> \
<interface name="org.gnome.Shell.AudioDeviceSelection"> \
<method name="Open"> \
<arg name="devices" direction="in" type="as" /> \
</method> \
<method name="Close"> \
</method> \
<signal name="DeviceSelected"> \
<arg name="device" type="s" /> \
</signal> \
</interface> \
</node>';
const AudioDeviceSelectionDialog = new Lang.Class({
Name: 'AudioDeviceSelectionDialog',
Extends: ModalDialog.ModalDialog,
_init: function(devices) {
this.parent({ styleClass: 'audio-device-selection-dialog' });
this._deviceItems = {};
this._buildLayout();
if (devices & AudioDevice.HEADPHONES)
this._addDevice(AudioDevice.HEADPHONES);
if (devices & AudioDevice.HEADSET)
this._addDevice(AudioDevice.HEADSET);
if (devices & AudioDevice.MICROPHONE)
this._addDevice(AudioDevice.MICROPHONE);
if (this._selectionBox.get_n_children() < 2)
throw new Error('Too few devices for a selection');
},
destroy: function() {
this.parent();
},
_buildLayout: function(devices) {
let title = new St.Label({ style_class: 'audio-selection-title',
text: _("Select Audio Device"),
x_align: Clutter.ActorAlign.CENTER });
this.contentLayout.style_class = 'audio-selection-content';
this.contentLayout.add(title);
this._selectionBox = new St.BoxLayout({ style_class: 'audio-selection-box' });
this.contentLayout.add(this._selectionBox, { expand: true });
this.addButton({ action: Lang.bind(this, this._openSettings),
label: _("Sound Settings") });
this.addButton({ action: Lang.bind(this, this.close),
label: _("Cancel"),
key: Clutter.Escape });
},
_getDeviceLabel: function(device) {
switch(device) {
case AudioDevice.HEADPHONES:
return _("Headphones");
case AudioDevice.HEADSET:
return _("Headset");
case AudioDevice.MICROPHONE:
return _("Microphone");
default:
return null;
}
},
_getDeviceIcon: function(device) {
switch(device) {
case AudioDevice.HEADPHONES:
return 'audio-headphones-symbolic';
case AudioDevice.HEADSET:
return 'audio-headset-symbolic';
case AudioDevice.MICROPHONE:
return 'audio-input-microphone-symbolic';
default:
return null;
}
},
_addDevice: function(device) {
let box = new St.BoxLayout({ style_class: 'audio-selection-device-box',
vertical: true });
box.connect('notify::height',
function() {
Meta.later_add(Meta.LaterType.BEFORE_REDRAW,
function() {
box.width = box.height;
});
});
let icon = new St.Icon({ style_class: 'audio-selection-device-icon',
icon_name: this._getDeviceIcon(device) });
box.add(icon);
let label = new St.Label({ style_class: 'audio-selection-device-label',
text: this._getDeviceLabel(device),
x_align: Clutter.ActorAlign.CENTER });
box.add(label);
let button = new St.Button({ style_class: 'audio-selection-device',
can_focus: true,
child: box });
this._selectionBox.add(button);
button.connect('clicked', Lang.bind(this,
function() {
this.emit('device-selected', device);
this.close();
Main.overview.hide();
}));
},
_openSettings: function() {
let desktopFile = 'gnome-sound-panel.desktop'
let app = Shell.AppSystem.get_default().lookup_app(desktopFile);
if (!app) {
log('Settings panel for desktop file ' + desktopFile + ' could not be loaded!');
return;
}
this.close();
Main.overview.hide();
app.activate();
}
});
const AudioDeviceSelectionDBus = new Lang.Class({
Name: 'AudioDeviceSelectionDBus',
_init: function() {
this._audioSelectionDialog = null;
this._dbusImpl = Gio.DBusExportedObject.wrapJSObject(AudioDeviceSelectionIface, this);
this._dbusImpl.export(Gio.DBus.session, '/org/gnome/Shell/AudioDeviceSelection');
Gio.DBus.session.own_name('org.gnome.Shell.AudioDeviceSelection', Gio.BusNameOwnerFlags.REPLACE, null, null);
},
_onDialogClosed: function() {
this._audioSelectionDialog = null;
},
_onDeviceSelected: function(dialog, device) {
let connection = this._dbusImpl.get_connection();
let info = this._dbusImpl.get_info();
let deviceName = Object.keys(AudioDevice).filter(
function(dev) {
return AudioDevice[dev] == device;
})[0].toLowerCase();
connection.emit_signal(this._audioSelectionDialog._sender,
this._dbusImpl.get_object_path(),
info ? info.name : null,
'DeviceSelected',
GLib.Variant.new('(s)', [deviceName]));
},
OpenAsync: function(params, invocation) {
if (this._audioSelectionDialog) {
invocation.return_value(null);
return;
}
let [deviceNames] = params;
let devices = 0;
deviceNames.forEach(function(n) {
devices |= AudioDevice[n.toUpperCase()];
});
let dialog;
try {
dialog = new AudioDeviceSelectionDialog(devices);
} catch(e) {
invocation.return_value(null);
return;
}
dialog._sender = invocation.get_sender();
dialog.connect('closed', Lang.bind(this, this._onDialogClosed));
dialog.connect('device-selected',
Lang.bind(this, this._onDeviceSelected));
dialog.open();
this._audioSelectionDialog = dialog;
invocation.return_value(null);
},
CloseAsync: function(params, invocation) {
if (this._audioSelectionDialog &&
this._audioSelectionDialog._sender == invocation.get_sender())
this._audioSelectionDialog.close();
invocation.return_value(null);
}
});

View File

@@ -247,13 +247,6 @@ const Background = new Lang.Class({
this._cancellable = new Gio.Cancellable();
this.isLoaded = false;
this._clock = new GnomeDesktop.WallClock();
this._timezoneChangedId = this._clock.connect('notify::timezone',
Lang.bind(this, function() {
if (this._animation)
this._loadAnimation(this._animation.file);
}));
this._settingsChangedSignalId = this._settings.connect('changed', Lang.bind(this, function() {
this.emit('changed');
}));
@@ -272,10 +265,6 @@ const Background = new Lang.Class({
}
this._fileWatches = null;
if (this._timezoneChangedId != 0)
this._clock.disconnect(this._timezoneChangedId);
this._timezoneChangedId = 0;
if (this._settingsChangedSignalId != 0)
this._settings.disconnect(this._settingsChangedSignalId);
this._settingsChangedSignalId = 0;
@@ -696,7 +685,6 @@ const BackgroundManager = new Lang.Class({
time: FADE_ANIMATION_TIME,
transition: 'easeOutQuad',
onComplete: function() {
oldBackgroundActor.background.run_dispose();
oldBackgroundActor.destroy();
}
});

File diff suppressed because it is too large Load Diff

View File

@@ -313,10 +313,6 @@ const AutorunSource = new Lang.Class({
getIcon: function() {
return this.mount.get_icon();
},
_createPolicy: function() {
return new MessageTray.NotificationApplicationPolicy('org.gnome.Nautilus');
}
});

View File

@@ -796,18 +796,10 @@ const NetworkAgent = new Lang.Class({
path = GLib.build_filenamev([Config.LIBEXECDIR, path]);
}
if (GLib.file_test(path, GLib.FileTest.IS_EXECUTABLE)) {
if (GLib.file_test(path, GLib.FileTest.IS_EXECUTABLE))
this._vpnBinaries[service] = { fileName: path, externalUIMode: externalUIMode, supportsHints: hints };
try {
let aliases = keyfile.get_string_list('VPN Connection', 'aliases');
for (let alias of aliases) {
this._vpnBinaries[alias] = { fileName: path, externalUIMode: externalUIMode, supportsHints: hints };
}
} catch(e) { } // ignore errors if key does not exist
} else {
else
throw new Error('VPN plugin at %s is not executable'.format(path));
}
} catch(e) {
log('Error \'%s\' while processing VPN keyfile \'%s\''.
format(e.message, dir.get_child(name).get_path()));

View File

@@ -12,9 +12,9 @@ const St = imports.gi.St;
const Tpl = imports.gi.TelepathyLogger;
const Tp = imports.gi.TelepathyGLib;
const Calendar = imports.ui.calendar;
const History = imports.misc.history;
const Main = imports.ui.main;
const MessageList = imports.ui.messageList;
const MessageTray = imports.ui.messageTray;
const Params = imports.misc.params;
const PopupMenu = imports.ui.popupMenu;
@@ -475,11 +475,6 @@ const ChatSource = new Lang.Class({
this._channel.close_async(function(channel, result) {
channel.close_finish(result);
});
} else {
// Don't indicate any unread messages when the notification
// that represents them has been destroyed.
this._pendingMessages = [];
this.countUpdated();
}
// Keep source alive while the channel is open
@@ -872,7 +867,7 @@ const ChatNotificationBanner = new Lang.Class({
},
_addMessage: function(message) {
let highlighter = new MessageList.URLHighlighter(message.body, true, true);
let highlighter = new Calendar.URLHighlighter(message.body, true, true);
let body = highlighter.actor;
let styles = message.styles;

View File

@@ -259,7 +259,7 @@ const ShowAppsIcon = new Lang.Class({
},
_createIcon: function(size) {
this._iconActor = new St.Icon({ icon_name: 'view-app-grid-symbolic',
this._iconActor = new St.Icon({ icon_name: 'view-grid-symbolic',
icon_size: size,
style_class: 'show-apps-icon',
track_hover: true });

View File

@@ -360,7 +360,7 @@ const DateMenuButton = new Lang.Class({
}));
// Fill up the first column
this._messageList = new Calendar.CalendarMessageList();
this._messageList = new Calendar.MessageList();
hbox.add(this._messageList.actor, { expand: true, y_fill: false, y_align: St.Align.START });
// Fill up the second column

View File

@@ -79,12 +79,9 @@ const _Draggable = new Lang.Class({
dragActorOpacity: undefined });
this.actor = actor;
if (!params.manualMode) {
if (!params.manualMode)
this.actor.connect('button-press-event',
Lang.bind(this, this._onButtonPress));
this.actor.connect('touch-event',
Lang.bind(this, this._onTouchEvent));
}
this.actor.connect('destroy', Lang.bind(this, function() {
this._actorDestroyed = true;
@@ -124,50 +121,8 @@ const _Draggable = new Lang.Class({
return Clutter.EVENT_PROPAGATE;
},
_onTouchEvent: function (actor, event) {
if (event.type() != Clutter.EventType.TOUCH_BEGIN ||
!global.display.is_pointer_emulating_sequence(event.get_event_sequence()))
return Clutter.EVENT_PROPAGATE;
if (Tweener.getTweenCount(actor))
return Clutter.EVENT_PROPAGATE;
this._touchSequence = event.get_event_sequence();
this._buttonDown = true;
this._grabActor();
let [stageX, stageY] = event.get_coords();
this._dragStartX = stageX;
this._dragStartY = stageY;
return Clutter.EVENT_PROPAGATE;
},
_grabDevice: function(actor) {
let manager = Clutter.DeviceManager.get_default();
let pointer = manager.get_core_device(Clutter.InputDeviceType.POINTER_DEVICE);
if (pointer && this._touchSequence)
pointer.sequence_grab(this._touchSequence, actor);
else if (pointer)
pointer.grab (actor);
this._grabbedDevice = pointer;
},
_ungrabDevice: function() {
if (this._touchSequence)
this._grabbedDevice.sequence_ungrab (this._touchSequence);
else
this._grabbedDevice.ungrab();
this._touchSequence = null;
this._grabbedDevice = null;
},
_grabActor: function() {
this._grabDevice(this.actor);
Clutter.grab_pointer(this.actor);
this._onEventId = this.actor.connect('event',
Lang.bind(this, this._onEvent));
},
@@ -176,7 +131,7 @@ const _Draggable = new Lang.Class({
if (!this._onEventId)
return;
this._ungrabDevice();
Clutter.ungrab_pointer();
this.actor.disconnect(this._onEventId);
this._onEventId = null;
},
@@ -185,13 +140,13 @@ const _Draggable = new Lang.Class({
if (!this._eventsGrabbed) {
this._eventsGrabbed = Main.pushModal(_getEventHandlerActor());
if (this._eventsGrabbed)
this._grabDevice(_getEventHandlerActor());
Clutter.grab_pointer(_getEventHandlerActor());
}
},
_ungrabEvents: function() {
if (this._eventsGrabbed) {
this._ungrabDevice();
Clutter.ungrab_pointer();
Main.popModal(_getEventHandlerActor());
this._eventsGrabbed = false;
}
@@ -202,9 +157,7 @@ const _Draggable = new Lang.Class({
// didn't start the drag, to drop the draggable in case the drag was in progress, and
// to complete the drag and ensure that whatever happens to be under the pointer does
// not get triggered if the drag was cancelled with Esc.
if (event.type() == Clutter.EventType.BUTTON_RELEASE ||
(event.type() == Clutter.EventType.TOUCH_END &&
global.display.is_pointer_emulating_sequence(event.get_event_sequence()))) {
if (event.type() == Clutter.EventType.BUTTON_RELEASE) {
this._buttonDown = false;
if (this._dragInProgress) {
return this._dragActorDropped(event);
@@ -219,9 +172,7 @@ const _Draggable = new Lang.Class({
}
// We intercept MOTION event to figure out if the drag has started and to draw
// this._dragActor under the pointer when dragging is in progress
} else if (event.type() == Clutter.EventType.MOTION ||
(event.type() == Clutter.EventType.TOUCH_UPDATE &&
global.display.is_pointer_emulating_sequence(event.get_event_sequence()))) {
} else if (event.type() == Clutter.EventType.MOTION) {
if (this._dragInProgress) {
return this._updateDragPosition(event);
} else if (this._dragActor == null) {
@@ -263,7 +214,7 @@ const _Draggable = new Lang.Class({
* This function is useful to call if you've specified manualMode
* for the draggable.
*/
startDrag: function (stageX, stageY, time, sequence) {
startDrag: function (stageX, stageY, time) {
currentDraggable = this;
this._dragInProgress = true;
@@ -277,8 +228,6 @@ const _Draggable = new Lang.Class({
this.emit('drag-begin', time);
if (this._onEventId)
this._ungrabActor();
this._touchSequence = sequence;
this._grabEvents();
global.screen.set_cursor(Meta.Cursor.DND_IN_DRAG);
@@ -389,8 +338,8 @@ const _Draggable = new Lang.Class({
let threshold = Gtk.Settings.get_default().gtk_dnd_drag_threshold;
if ((Math.abs(stageX - this._dragStartX) > threshold ||
Math.abs(stageY - this._dragStartY) > threshold)) {
this.startDrag(stageX, stageY, event.get_time(), this._touchSequence);
this._updateDragPosition(event);
this.startDrag(stageX, stageY, event.get_time());
this._updateDragPosition(event);
}
return true;
@@ -571,13 +520,20 @@ const _Draggable = new Lang.Class({
return;
}
this._animateDragEnd(eventTime,
{ x: snapBackX,
y: snapBackY,
scale_x: snapBackScale,
scale_y: snapBackScale,
time: SNAP_BACK_ANIMATION_TIME,
});
this._animationInProgress = true;
// No target, so snap back
Tweener.addTween(this._dragActor,
{ x: snapBackX,
y: snapBackY,
scale_x: snapBackScale,
scale_y: snapBackScale,
opacity: this._dragOrigOpacity,
time: SNAP_BACK_ANIMATION_TIME,
transition: 'easeOutQuad',
onComplete: this._onAnimationComplete,
onCompleteScope: this,
onCompleteParams: [this._dragActor, eventTime]
});
},
_restoreDragActor: function(eventTime) {
@@ -589,44 +545,18 @@ const _Draggable = new Lang.Class({
this._dragActor.set_scale(restoreScale, restoreScale);
this._dragActor.opacity = 0;
this._animateDragEnd(eventTime,
{ time: REVERT_ANIMATION_TIME });
},
_animateDragEnd: function (eventTime, params) {
this._animationInProgress = true;
// finish animation if the actor gets destroyed
// during it
this._dragActorDestroyId =
this._dragActor.connect('destroy',
Lang.bind(this, this._finishAnimation));
params['opacity'] = this._dragOrigOpacity;
params['transition'] = 'easeOutQuad';
params['onComplete'] = this._onAnimationComplete;
params['onCompleteScope'] = this;
params['onCompleteParams'] = [this._dragActor, eventTime];
// start the animation
Tweener.addTween(this._dragActor, params)
},
_finishAnimation : function () {
if (!this._animationInProgress)
return
this._animationInProgress = false;
if (!this._buttonDown)
this._dragComplete();
global.screen.set_cursor(Meta.Cursor.DEFAULT);
Tweener.addTween(this._dragActor,
{ opacity: this._dragOrigOpacity,
time: REVERT_ANIMATION_TIME,
transition: 'easeOutQuad',
onComplete: this._onAnimationComplete,
onCompleteScope: this,
onCompleteParams: [this._dragActor, eventTime]
});
},
_onAnimationComplete : function (dragActor, eventTime) {
dragActor.disconnect(this._dragActorDestroyId);
this._dragActorDestroyId = 0;
if (this._dragOrigParent) {
Main.uiGroup.remove_child(this._dragActor);
this._dragOrigParent.add_actor(this._dragActor);
@@ -635,9 +565,12 @@ const _Draggable = new Lang.Class({
} else {
dragActor.destroy();
}
global.screen.set_cursor(Meta.Cursor.DEFAULT);
this.emit('drag-end', eventTime, false);
this._finishAnimation();
this._animationInProgress = false;
if (!this._buttonDown)
this._dragComplete();
},
_dragComplete: function() {

View File

@@ -1,6 +1,6 @@
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
/*
* Copyright 2010-2016 Red Hat, Inc
* Copyright 2010 Red Hat, Inc
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -114,7 +114,7 @@ const restartDialogContent = {
showOtherSessions: true,
};
const restartUpdateDialogContent = {
const restartInstallDialogContent = {
subject: C_("title", "Restart & Install Updates"),
description: function(seconds) {
@@ -132,38 +132,18 @@ const restartUpdateDialogContent = {
showOtherSessions: true,
};
const restartUpgradeDialogContent = {
subject: C_("title", "Restart & Install Upgrade"),
upgradeDescription: function(distroName, distroVersion) {
/* Translators: This is the text displayed for system upgrades in the
shut down dialog. First %s gets replaced with the distro name and
second %s with the distro version to upgrade to */
return _("%s %s will be installed after restart. Upgrade installation can take a long time: ensure that you have backed up and that the computer is plugged in.").format(distroName, distroVersion);
},
disableTimer: true,
showBatteryWarning: false,
confirmButtons: [{ signal: 'ConfirmedReboot',
label: C_("button", "Restart &amp; Install") }],
iconName: 'view-refresh-symbolic',
iconStyleClass: 'end-session-dialog-shutdown-icon',
showOtherSessions: true,
};
const DialogType = {
LOGOUT: 0 /* GSM_SHELL_END_SESSION_DIALOG_TYPE_LOGOUT */,
SHUTDOWN: 1 /* GSM_SHELL_END_SESSION_DIALOG_TYPE_SHUTDOWN */,
RESTART: 2 /* GSM_SHELL_END_SESSION_DIALOG_TYPE_RESTART */,
UPDATE_RESTART: 3,
UPGRADE_RESTART: 4
UPDATE_RESTART: 3
};
const DialogContent = {
0 /* DialogType.LOGOUT */: logoutDialogContent,
1 /* DialogType.SHUTDOWN */: shutdownDialogContent,
2 /* DialogType.RESTART */: restartDialogContent,
3 /* DialogType.UPDATE_RESTART */: restartUpdateDialogContent,
4 /* DialogType.UPGRADE_RESTART */: restartUpgradeDialogContent
3 /* DialogType.UPDATE_RESTART */: restartInstallDialogContent
};
const MAX_USERS_IN_SESSION_DIALOG = 5;
@@ -183,10 +163,7 @@ const LogindSession = Gio.DBusProxy.makeProxyWrapper(LogindSessionIface);
const PkOfflineIface = '<node> \
<interface name="org.freedesktop.PackageKit.Offline"> \
<property name="UpdatePrepared" type="b" access="read"/> \
<property name="UpdateTriggered" type="b" access="read"/> \
<property name="UpgradePrepared" type="b" access="read"/> \
<property name="UpgradeTriggered" type="b" access="read"/> \
<property name="PreparedUpgrade" type="a{sv}" access="read"/> \
<property name="TriggerAction" type="s" access="read"/> \
<method name="Trigger"> \
<arg type="s" name="action" direction="in"/> \
</method> \
@@ -438,19 +415,11 @@ const EndSessionDialog = new Lang.Class({
if (dialogContent.descriptionWithUser)
description = dialogContent.descriptionWithUser(realName, displayTime);
else
description = dialogContent.description(displayTime);
}
}
// Use a different description when we are installing a system upgrade
if (dialogContent.upgradeDescription) {
let name = this._pkOfflineProxy.PreparedUpgrade['name'].deep_unpack();
let version = this._pkOfflineProxy.PreparedUpgrade['version'].deep_unpack();
if (name != null && version != null)
description = dialogContent.upgradeDescription(name, version);
}
// Fall back to regular description
if (!description)
description = dialogContent.description(displayTime);
@@ -729,12 +698,9 @@ const EndSessionDialog = new Lang.Class({
this._totalSecondsToStayOpen = totalSecondsToStayOpen;
this._type = type;
if (this._type == DialogType.RESTART) {
if (this._pkOfflineProxy.UpdateTriggered)
this._type = DialogType.UPDATE_RESTART;
else if (this._pkOfflineProxy.UpgradeTriggered)
this._type = DialogType.UPGRADE_RESTART;
}
if (this._type == DialogType.RESTART &&
this._pkOfflineProxy.TriggerAction == 'reboot')
this._type = DialogType.UPDATE_RESTART;
this._applications = [];
this._applicationList.destroy_all_children();
@@ -761,19 +727,19 @@ const EndSessionDialog = new Lang.Class({
if (dialogContent.showOtherSessions)
this._loadSessions();
let updateTriggered = this._pkOfflineProxy.UpdateTriggered;
let updateAlreadyTriggered = this._pkOfflineProxy.TriggerAction == 'power-off' || this._pkOfflineProxy.TriggerAction == 'reboot';
let updatePrepared = this._pkOfflineProxy.UpdatePrepared;
let updatesAllowed = this._updatesPermission && this._updatesPermission.allowed;
_setCheckBoxLabel(this._checkBox, dialogContent.checkBoxText);
this._checkBox.actor.visible = (dialogContent.checkBoxText && updatePrepared && updatesAllowed);
this._checkBox.actor.checked = (updatePrepared && updateTriggered);
this._checkBox.actor.checked = (updatePrepared && updateAlreadyTriggered);
// We show the warning either together with the checkbox, or when
// updates have already been triggered, but the user doesn't have
// enough permissions to cancel them.
this._batteryWarning.visible = (dialogContent.showBatteryWarning &&
(this._checkBox.actor.visible || updatePrepared && updateTriggered && !updatesAllowed));
(this._checkBox.actor.visible || updatePrepared && updateAlreadyTriggered && !updatesAllowed));
this._updateButtons();
@@ -783,9 +749,7 @@ const EndSessionDialog = new Lang.Class({
return;
}
if (!dialogContent.disableTimer)
this._startTimer();
this._startTimer();
this._sync();
let signalId = this.connect('opened',

View File

@@ -334,7 +334,7 @@ function _sessionUpdated() {
// from allowExtensions in the future
if (Main.sessionMode.allowExtensions) {
if (initted)
enabledExtensions = getEnabledExtensions();
onEnabledExtensionsChanged();
enableAllExtensions();
} else {
disableAllExtensions();

View File

@@ -158,22 +158,10 @@ const CandidatePopup = new Lang.Class({
panelService.connect('set-cursor-location',
Lang.bind(this, function(ps, x, y, w, h) {
this._setDummyCursorGeometry(x, y, w, h);
Main.layoutManager.setDummyCursorGeometry(x, y, w, h);
if (this._boxPointer.actor.visible)
this._boxPointer.setPosition(Main.layoutManager.dummyCursor, 0);
}));
try {
panelService.connect('set-cursor-location-relative',
Lang.bind(this, function(ps, x, y, w, h) {
if (!global.display.focus_window)
return;
let window = global.display.focus_window.get_compositor_private();
this._setDummyCursorGeometry(window.x + x, window.y + y, w, h);
}));
} catch(e) {
// Only recent IBus versions have support for this signal
// which is used for wayland clients. In order to work
// with older IBus versions we can silently ignore the
// signal's absence.
}
panelService.connect('update-preedit-text',
Lang.bind(this, function(ps, text, cursorPosition, visible) {
this._preeditText.visible = visible;
@@ -258,12 +246,6 @@ const CandidatePopup = new Lang.Class({
}));
},
_setDummyCursorGeometry: function(x, y, w, h) {
Main.layoutManager.setDummyCursorGeometry(x, y, w, h);
if (this._boxPointer.actor.visible)
this._boxPointer.setPosition(Main.layoutManager.dummyCursor, 0);
},
_updateVisibility: function() {
let isVisible = (this._preeditText.visible ||
this._auxText.visible ||

View File

@@ -10,7 +10,6 @@ const Meta = imports.gi.Meta;
const Shell = imports.gi.Shell;
const Signals = imports.signals;
const St = imports.gi.St;
const InputSourceManager = imports.ui.status.keyboard;
const BoxPointer = imports.ui.boxpointer;
const Layout = imports.ui.layout;
@@ -758,48 +757,19 @@ const ShellWaylandAdapter = new Lang.Class({
Name: 'ShellWaylandAdapter',
Extends: Caribou.XAdapter,
_init: function () {
this.parent();
let deviceManager = Clutter.DeviceManager.get_default();
this._virtualDevice = deviceManager.create_virtual_device(Clutter.InputDeviceType.KEYBOARD_DEVICE);
this._inputSourceManager = InputSourceManager.getInputSourceManager();
this._sourceChangedId = this._inputSourceManager.connect('current-source-changed',
Lang.bind(this, this._onSourceChanged));
this._sourcesModifiedId = this._inputSourceManager.connect ('sources-changed',
Lang.bind(this, this._onSourcesModified));
},
_onSourcesModified: function () {
this.emit('config-changed');
},
_onSourceChanged: function (inputSourceManager, oldSource) {
let source = inputSourceManager.currentSource;
this.emit('group-changed', source.index, source.id, '');
},
vfunc_get_groups: function () {
let inputSources = this._inputSourceManager.inputSources;
let groups = []
let variants = [];
for (let i in inputSources) {
let is = inputSources[i];
groups[is.index] = is.id;
variants[is.index] = '';
}
return [groups, groups.length, variants, variants.length];
},
vfunc_keyval_press: function(keyval) {
this._virtualDevice.notify_keyval(Clutter.get_current_event_time(),
keyval, Clutter.KeyState.PRESSED);
let focus = global.stage.get_key_focus();
if (focus instanceof Clutter.Text)
Shell.util_text_insert_keyval(focus, keyval);
else
this.parent(keyval);
},
vfunc_keyval_release: function(keyval) {
this._virtualDevice.notify_keyval(Clutter.get_current_event_time(),
keyval, Clutter.KeyState.RELEASED);
let focus = global.stage.get_key_focus();
if (focus instanceof Clutter.Text)
return; // do nothing
else
this.parent(keyval);
},
});

View File

@@ -220,8 +220,7 @@ const LayoutManager = new Lang.Class({
global.stage.add_child(this.uiGroup);
this.overviewGroup = new St.Widget({ name: 'overviewGroup',
visible: false,
reactive: true });
visible: false });
this.addChrome(this.overviewGroup);
this.screenShieldGroup = new St.Widget({ name: 'screenShieldGroup',
@@ -592,10 +591,7 @@ const LayoutManager = new Lang.Class({
this.addChrome(this._coverPane);
if (Meta.is_restart()) {
// On restart, we don't do an animation. Force an update of the
// regions immediately so that maximized windows restore to the
// right size taking struts into account.
this._updateRegions();
// On restart, we don't do an animation
} else if (Main.sessionMode.isGreeter) {
this.panelBox.translation_y = -this.panelBox.height;
} else {
@@ -942,11 +938,6 @@ const LayoutManager = new Lang.Class({
if (Main.modalCount > 0)
return GLib.SOURCE_REMOVE;
// Bug workaround - get_transformed_position()/get_transformed_size() don't work after
// a change in stage size until the first pick or paint.
// https://bugzilla.gnome.org/show_bug.cgi?id=761565
global.stage.get_actor_at_pos(Clutter.PickMode.ALL, 0, 0);
let rects = [], struts = [], i;
let isPopupMenuVisible = global.top_window_group.get_children().some(isPopupMetaWindow);
let wantsInputRegion = !isPopupMenuVisible;

View File

@@ -50,14 +50,15 @@ const LegacyTray = new Lang.Class({
this._slideLayout.translationX = 0;
this._slideLayout.slideDirection = OverviewControls.SlideDirection.LEFT;
this._slider = new St.Widget({ x_expand: true, y_expand: true,
this._slider = new St.Widget({ style_class: 'legacy-tray',
x_expand: true, y_expand: true,
x_align: Clutter.ActorAlign.START,
y_align: Clutter.ActorAlign.END,
layout_manager: this._slideLayout });
this.actor.add_actor(this._slider);
this._slider.connect('notify::allocation', Lang.bind(this, this._syncBarrier));
this._box = new St.BoxLayout({ style_class: 'legacy-tray' });
this._box = new St.BoxLayout();
this._slider.add_actor(this._box);
this._concealHandle = new St.Button({ style_class: 'legacy-tray-handle',

View File

@@ -11,8 +11,6 @@ const Meta = imports.gi.Meta;
const Shell = imports.gi.Shell;
const St = imports.gi.St;
const AccessDialog = imports.ui.accessDialog;
const AudioDeviceSelection = imports.ui.audioDeviceSelection;
const Components = imports.ui.components;
const CtrlAltTab = imports.ui.ctrlAltTab;
const EndSessionDialog = imports.ui.endSessionDialog;
@@ -64,8 +62,6 @@ let ctrlAltTabManager = null;
let osdWindowManager = null;
let osdMonitorLabeler = null;
let sessionMode = null;
let shellAccessDialogDBusService = null;
let shellAudioSelectionDBusService = null;
let shellDBusService = null;
let shellMountOpDBusService = null;
let screenSaverDBus = null;
@@ -82,7 +78,6 @@ let _startDate;
let _defaultCssStylesheet = null;
let _cssStylesheet = null;
let _a11ySettings = null;
let _themeResource = null;
function _sessionUpdated() {
if (sessionMode.isPrimary)
@@ -124,8 +119,6 @@ function start() {
_loadDefaultStylesheet);
_initializeUI();
shellAccessDialogDBusService = new AccessDialog.AccessDialogDBus();
shellAudioSelectionDBusService = new AudioDeviceSelection.AudioDeviceSelectionDBus();
shellDBusService = new ShellDBus.GnomeShell();
shellMountOpDBusService = new ShellMountOperation.GnomeShellMountOpHandler();
@@ -144,7 +137,9 @@ function _initializeUI() {
Shell.WindowTracker.get_default();
Shell.AppUsage.get_default();
reloadThemeResource();
let resource = Gio.Resource.load(global.datadir + '/gnome-shell-theme.gresource');
resource._register();
_loadDefaultStylesheet();
// Setup the stage hierarchy early
@@ -194,8 +189,6 @@ function _initializeUI() {
return true;
});
global.display.connect('gl-video-memory-purged', loadTheme);
// Provide the bus object for gnome-session to
// initiate logouts.
EndSessionDialog.init();
@@ -297,14 +290,6 @@ function setThemeStylesheet(cssStylesheet) {
_cssStylesheet = cssStylesheet ? Gio.File.new_for_path(cssStylesheet) : null;
}
function reloadThemeResource() {
if (_themeResource)
_themeResource._unregister();
_themeResource = Gio.Resource.load(global.datadir + '/gnome-shell-theme.gresource');
_themeResource._register();
}
/**
* loadTheme:
*

View File

@@ -1,726 +0,0 @@
const Atk = imports.gi.Atk;
const Clutter = imports.gi.Clutter;
const Gio = imports.gi.Gio;
const GLib = imports.gi.GLib;
const GObject = imports.gi.GObject;
const Lang = imports.lang;
const Main = imports.ui.main;
const MessageTray = imports.ui.messageTray;
const Meta = imports.gi.Meta;
const Pango = imports.gi.Pango;
const Signals = imports.signals;
const St = imports.gi.St;
const Calendar = imports.ui.calendar;
const Tweener = imports.ui.tweener;
const Util = imports.misc.util;
const MESSAGE_ANIMATION_TIME = 0.1;
const DEFAULT_EXPAND_LINES = 6;
function _fixMarkup(text, allowMarkup) {
if (allowMarkup) {
// Support &amp;, &quot;, &apos;, &lt; and &gt;, escape all other
// occurrences of '&'.
let _text = text.replace(/&(?!amp;|quot;|apos;|lt;|gt;)/g, '&amp;');
// Support <b>, <i>, and <u>, escape anything else
// so it displays as raw markup.
_text = _text.replace(/<(?!\/?[biu]>)/g, '&lt;');
try {
Pango.parse_markup(_text, -1, '');
return _text;
} catch (e) {}
}
// !allowMarkup, or invalid markup
return GLib.markup_escape_text(text, -1);
}
const URLHighlighter = new Lang.Class({
Name: 'URLHighlighter',
_init: function(text, lineWrap, allowMarkup) {
if (!text)
text = '';
this.actor = new St.Label({ reactive: true, style_class: 'url-highlighter',
x_expand: true, x_align: Clutter.ActorAlign.START });
this._linkColor = '#ccccff';
this.actor.connect('style-changed', Lang.bind(this, function() {
let [hasColor, color] = this.actor.get_theme_node().lookup_color('link-color', false);
if (hasColor) {
let linkColor = color.to_string().substr(0, 7);
if (linkColor != this._linkColor) {
this._linkColor = linkColor;
this._highlightUrls();
}
}
}));
this.actor.clutter_text.line_wrap = lineWrap;
this.actor.clutter_text.line_wrap_mode = Pango.WrapMode.WORD_CHAR;
this.setMarkup(text, allowMarkup);
this.actor.connect('button-press-event', Lang.bind(this, function(actor, event) {
// Don't try to URL highlight when invisible.
// The MessageTray doesn't actually hide us, so
// we need to check for paint opacities as well.
if (!actor.visible || actor.get_paint_opacity() == 0)
return Clutter.EVENT_PROPAGATE;
// Keep Notification.actor from seeing this and taking
// a pointer grab, which would block our button-release-event
// handler, if an URL is clicked
return this._findUrlAtPos(event) != -1;
}));
this.actor.connect('button-release-event', Lang.bind(this, function (actor, event) {
if (!actor.visible || actor.get_paint_opacity() == 0)
return Clutter.EVENT_PROPAGATE;
let urlId = this._findUrlAtPos(event);
if (urlId != -1) {
let url = this._urls[urlId].url;
if (url.indexOf(':') == -1)
url = 'http://' + url;
Gio.app_info_launch_default_for_uri(url, global.create_app_launch_context(0, -1));
return Clutter.EVENT_STOP;
}
return Clutter.EVENT_PROPAGATE;
}));
this.actor.connect('motion-event', Lang.bind(this, function(actor, event) {
if (!actor.visible || actor.get_paint_opacity() == 0)
return Clutter.EVENT_PROPAGATE;
let urlId = this._findUrlAtPos(event);
if (urlId != -1 && !this._cursorChanged) {
global.screen.set_cursor(Meta.Cursor.POINTING_HAND);
this._cursorChanged = true;
} else if (urlId == -1) {
global.screen.set_cursor(Meta.Cursor.DEFAULT);
this._cursorChanged = false;
}
return Clutter.EVENT_PROPAGATE;
}));
this.actor.connect('leave-event', Lang.bind(this, function() {
if (!this.actor.visible || this.actor.get_paint_opacity() == 0)
return Clutter.EVENT_PROPAGATE;
if (this._cursorChanged) {
this._cursorChanged = false;
global.screen.set_cursor(Meta.Cursor.DEFAULT);
}
return Clutter.EVENT_PROPAGATE;
}));
},
setMarkup: function(text, allowMarkup) {
text = text ? _fixMarkup(text, allowMarkup) : '';
this._text = text;
this.actor.clutter_text.set_markup(text);
/* clutter_text.text contain text without markup */
this._urls = Util.findUrls(this.actor.clutter_text.text);
this._highlightUrls();
},
_highlightUrls: function() {
// text here contain markup
let urls = Util.findUrls(this._text);
let markup = '';
let pos = 0;
for (let i = 0; i < urls.length; i++) {
let url = urls[i];
let str = this._text.substr(pos, url.pos - pos);
markup += str + '<span foreground="' + this._linkColor + '"><u>' + url.url + '</u></span>';
pos = url.pos + url.url.length;
}
markup += this._text.substr(pos);
this.actor.clutter_text.set_markup(markup);
},
_findUrlAtPos: function(event) {
let success;
let [x, y] = event.get_coords();
[success, x, y] = this.actor.transform_stage_point(x, y);
let find_pos = -1;
for (let i = 0; i < this.actor.clutter_text.text.length; i++) {
let [success, px, py, line_height] = this.actor.clutter_text.position_to_coords(i);
if (py > y || py + line_height < y || x < px)
continue;
find_pos = i;
}
if (find_pos != -1) {
for (let i = 0; i < this._urls.length; i++)
if (find_pos >= this._urls[i].pos &&
this._urls[i].pos + this._urls[i].url.length > find_pos)
return i;
}
return -1;
}
});
const ScaleLayout = new Lang.Class({
Name: 'ScaleLayout',
Extends: Clutter.BinLayout,
_connectContainer: function(container) {
if (this._container == container)
return;
if (this._container)
for (let id of this._signals)
this._container.disconnect(id);
this._container = container;
this._signals = [];
if (this._container)
for (let signal of ['notify::scale-x', 'notify::scale-y']) {
let id = this._container.connect(signal, Lang.bind(this,
function() {
this.layout_changed();
}));
this._signals.push(id);
}
},
vfunc_get_preferred_width: function(container, forHeight) {
this._connectContainer(container);
let [min, nat] = this.parent(container, forHeight);
return [Math.floor(min * container.scale_x),
Math.floor(nat * container.scale_x)];
},
vfunc_get_preferred_height: function(container, forWidth) {
this._connectContainer(container);
let [min, nat] = this.parent(container, forWidth);
return [Math.floor(min * container.scale_y),
Math.floor(nat * container.scale_y)];
}
});
const LabelExpanderLayout = new Lang.Class({
Name: 'LabelExpanderLayout',
Extends: Clutter.LayoutManager,
Properties: { 'expansion': GObject.ParamSpec.double('expansion',
'Expansion',
'Expansion of the layout, between 0 (collapsed) ' +
'and 1 (fully expanded',
GObject.ParamFlags.READABLE | GObject.ParamFlags.WRITABLE,
0, 1, 0)},
_init: function(params) {
this._expansion = 0;
this._expandLines = DEFAULT_EXPAND_LINES;
this.parent(params);
},
get expansion() {
return this._expansion;
},
set expansion(v) {
if (v == this._expansion)
return;
this._expansion = v;
this.notify('expansion');
let visibleIndex = this._expansion > 0 ? 1 : 0;
for (let i = 0; this._container && i < this._container.get_n_children(); i++)
this._container.get_child_at_index(i).visible = (i == visibleIndex);
this.layout_changed();
},
set expandLines(v) {
if (v == this._expandLines)
return;
this._expandLines = v;
if (this._expansion > 0)
this.layout_changed();
},
vfunc_set_container: function(container) {
this._container = container;
},
vfunc_get_preferred_width: function(container, forHeight) {
let [min, nat] = [0, 0];
for (let i = 0; i < container.get_n_children(); i++) {
if (i > 1)
break; // we support one unexpanded + one expanded child
let child = container.get_child_at_index(i);
let [childMin, childNat] = child.get_preferred_width(forHeight);
[min, nat] = [Math.max(min, childMin), Math.max(nat, childNat)];
}
return [min, nat];
},
vfunc_get_preferred_height: function(container, forWidth) {
let [min, nat] = [0, 0];
let children = container.get_children();
if (children[0])
[min, nat] = children[0].get_preferred_height(forWidth);
if (children[1]) {
let [min2, nat2] = children[1].get_preferred_height(forWidth);
let [expMin, expNat] = [Math.min(min2, min * this._expandLines),
Math.min(nat2, nat * this._expandLines)];
[min, nat] = [min + this._expansion * (expMin - min),
nat + this._expansion * (expNat - nat)];
}
return [min, nat];
},
vfunc_allocate: function(container, box, flags) {
for (let i = 0; i < container.get_n_children(); i++) {
let child = container.get_child_at_index(i);
if (child.visible)
child.allocate(box, flags);
}
}
});
const Message = new Lang.Class({
Name: 'Message',
_init: function(title, body) {
this.expanded = false;
this.actor = new St.Button({ style_class: 'message',
accessible_role: Atk.Role.NOTIFICATION,
can_focus: true,
x_expand: true, x_fill: true });
this.actor.connect('key-press-event',
Lang.bind(this, this._onKeyPressed));
let vbox = new St.BoxLayout({ vertical: true });
this.actor.set_child(vbox);
let hbox = new St.BoxLayout();
vbox.add_actor(hbox);
this._actionBin = new St.Widget({ layout_manager: new ScaleLayout(),
visible: false });
vbox.add_actor(this._actionBin);
this._iconBin = new St.Bin({ style_class: 'message-icon-bin',
y_expand: true,
visible: false });
hbox.add_actor(this._iconBin);
let contentBox = new St.BoxLayout({ style_class: 'message-content',
vertical: true, x_expand: true });
hbox.add_actor(contentBox);
this._mediaControls = new St.BoxLayout();
hbox.add_actor(this._mediaControls);
let titleBox = new St.BoxLayout();
contentBox.add_actor(titleBox);
this.titleLabel = new St.Label({ style_class: 'message-title',
x_expand: true,
x_align: Clutter.ActorAlign.START });
this.setTitle(title);
titleBox.add_actor(this.titleLabel);
this._secondaryBin = new St.Bin({ style_class: 'message-secondary-bin' });
titleBox.add_actor(this._secondaryBin);
let closeIcon = new St.Icon({ icon_name: 'window-close-symbolic',
icon_size: 16 });
this._closeButton = new St.Button({ child: closeIcon, visible: false });
titleBox.add_actor(this._closeButton);
this._bodyStack = new St.Widget({ x_expand: true });
this._bodyStack.layout_manager = new LabelExpanderLayout();
contentBox.add_actor(this._bodyStack);
this.bodyLabel = new URLHighlighter('', false, this._useBodyMarkup);
this.bodyLabel.actor.add_style_class_name('message-body');
this._bodyStack.add_actor(this.bodyLabel.actor);
this.setBody(body);
this._closeButton.connect('clicked', Lang.bind(this, this.close));
this.actor.connect('notify::hover', Lang.bind(this, this._sync));
this.actor.connect('clicked', Lang.bind(this, this._onClicked));
this.actor.connect('destroy', Lang.bind(this, this._onDestroy));
this._sync();
},
close: function() {
this.emit('close');
},
setIcon: function(actor) {
this._iconBin.child = actor;
this._iconBin.visible = (actor != null);
},
setSecondaryActor: function(actor) {
this._secondaryBin.child = actor;
},
setTitle: function(text) {
let title = text ? _fixMarkup(text.replace(/\n/g, ' '), false) : '';
this.titleLabel.clutter_text.set_markup(title);
},
setBody: function(text) {
this._bodyText = text;
this.bodyLabel.setMarkup(text ? text.replace(/\n/g, ' ') : '',
this._useBodyMarkup);
if (this._expandedLabel)
this._expandedLabel.setMarkup(text, this._useBodyMarkup);
},
setUseBodyMarkup: function(enable) {
if (this._useBodyMarkup === enable)
return;
this._useBodyMarkup = enable;
if (this.bodyLabel)
this.setBody(this._bodyText);
},
setActionArea: function(actor) {
if (actor == null) {
if (this._actionBin.get_n_children() > 0)
this._actionBin.get_child_at_index(0).destroy();
return;
}
if (this._actionBin.get_n_children() > 0)
throw new Error('Message already has an action area');
this._actionBin.add_actor(actor);
this._actionBin.visible = this.expanded;
},
addMediaControl: function(iconName, callback) {
let icon = new St.Icon({ icon_name: iconName, icon_size: 16 });
let button = new St.Button({ style_class: 'message-media-control',
child: icon });
button.connect('clicked', callback);
this._mediaControls.add_actor(button);
return button;
},
setExpandedBody: function(actor) {
if (actor == null) {
if (this._bodyStack.get_n_children() > 1)
this._bodyStack.get_child_at_index(1).destroy();
return;
}
if (this._bodyStack.get_n_children() > 1)
throw new Error('Message already has an expanded body actor');
this._bodyStack.insert_child_at_index(actor, 1);
},
setExpandedLines: function(nLines) {
this._bodyStack.layout_manager.expandLines = nLines;
},
expand: function(animate) {
this.expanded = true;
this._actionBin.visible = (this._actionBin.get_n_children() > 0);
if (this._bodyStack.get_n_children() < 2) {
this._expandedLabel = new URLHighlighter(this._bodyText,
true, this._useBodyMarkup);
this.setExpandedBody(this._expandedLabel.actor);
}
if (animate) {
Tweener.addTween(this._bodyStack.layout_manager,
{ expansion: 1,
time: MessageTray.ANIMATION_TIME,
transition: 'easeOutQuad' });
this._actionBin.scale_y = 0;
Tweener.addTween(this._actionBin,
{ scale_y: 1,
time: MessageTray.ANIMATION_TIME,
transition: 'easeOutQuad' });
} else {
this._bodyStack.layout_manager.expansion = 1;
this._actionBin.scale_y = 1;
}
this.emit('expanded');
},
unexpand: function(animate) {
if (animate) {
Tweener.addTween(this._bodyStack.layout_manager,
{ expansion: 0,
time: MessageTray.ANIMATION_TIME,
transition: 'easeOutQuad' });
Tweener.addTween(this._actionBin,
{ scale_y: 0,
time: MessageTray.ANIMATION_TIME,
transition: 'easeOutQuad',
onCompleteScope: this,
onComplete: function() {
this._actionBin.hide();
this.expanded = false;
}});
} else {
this._bodyStack.layout_manager.expansion = 0;
this._actionBin.scale_y = 0;
this.expanded = false;
}
this.emit('unexpanded');
},
canClose: function() {
return this._mediaControls.get_n_children() == 0;
},
_sync: function() {
let hovered = this.actor.hover;
this._closeButton.visible = hovered && this.canClose();
this._secondaryBin.visible = !hovered;
},
_onClicked: function() {
},
_onDestroy: function() {
},
_onKeyPressed: function(a, event) {
let keysym = event.get_key_symbol();
if (keysym == Clutter.KEY_Delete ||
keysym == Clutter.KEY_KP_Delete) {
this.close();
return Clutter.EVENT_STOP;
}
return Clutter.EVENT_PROPAGATE;
}
});
Signals.addSignalMethods(Message.prototype);
const MessageListSection = new Lang.Class({
Name: 'MessageListSection',
_init: function(title) {
this.actor = new St.BoxLayout({ style_class: 'message-list-section',
clip_to_allocation: true,
x_expand: true, vertical: true });
let titleBox = new St.BoxLayout({ style_class: 'message-list-section-title-box' });
this.actor.add_actor(titleBox);
this._title = new St.Button({ style_class: 'message-list-section-title',
label: title,
can_focus: true,
x_expand: true,
x_align: St.Align.START });
titleBox.add_actor(this._title);
this._title.connect('clicked', Lang.bind(this, this._onTitleClicked));
this._title.connect('key-focus-in', Lang.bind(this, this._onKeyFocusIn));
let closeIcon = new St.Icon({ icon_name: 'window-close-symbolic' });
this._closeButton = new St.Button({ style_class: 'message-list-section-close',
child: closeIcon,
accessible_name: _("Clear section"),
can_focus: true });
this._closeButton.set_x_align(Clutter.ActorAlign.END);
titleBox.add_actor(this._closeButton);
this._closeButton.connect('clicked', Lang.bind(this, this.clear));
this._list = new St.BoxLayout({ style_class: 'message-list-section-list',
vertical: true });
this.actor.add_actor(this._list);
this._list.connect('actor-added', Lang.bind(this, this._sync));
this._list.connect('actor-removed', Lang.bind(this, this._sync));
let id = Main.sessionMode.connect('updated',
Lang.bind(this, this._sync));
this.actor.connect('destroy', function() {
Main.sessionMode.disconnect(id);
});
this._messages = new Map();
this._date = new Date();
this.empty = true;
this._sync();
},
_onTitleClicked: function() {
Main.overview.hide();
Main.panel.closeCalendar();
},
_onKeyFocusIn: function(actor) {
this.emit('key-focus-in', actor);
},
get allowed() {
return true;
},
setDate: function(date) {
if (Calendar.sameDay(date, this._date))
return;
this._date = date;
this._sync();
},
addMessage: function(message, animate) {
this.addMessageAtIndex(message, -1, animate);
},
addMessageAtIndex: function(message, index, animate) {
let obj = {
container: null,
destroyId: 0,
keyFocusId: 0,
closeId: 0
};
let pivot = new Clutter.Point({ x: .5, y: .5 });
let scale = animate ? 0 : 1;
obj.container = new St.Widget({ layout_manager: new ScaleLayout(),
pivot_point: pivot,
scale_x: scale, scale_y: scale });
obj.keyFocusId = message.actor.connect('key-focus-in',
Lang.bind(this, this._onKeyFocusIn));
obj.destroyId = message.actor.connect('destroy',
Lang.bind(this, function() {
this.removeMessage(message, false);
}));
obj.closeId = message.connect('close',
Lang.bind(this, function() {
this.removeMessage(message, true);
}));
this._messages.set(message, obj);
obj.container.add_actor(message.actor);
this._list.insert_child_at_index(obj.container, index);
if (animate)
Tweener.addTween(obj.container, { scale_x: 1,
scale_y: 1,
time: MESSAGE_ANIMATION_TIME,
transition: 'easeOutQuad' });
},
moveMessage: function(message, index, animate) {
let obj = this._messages.get(message);
if (!animate) {
this._list.set_child_at_index(obj.container, index);
return;
}
let onComplete = Lang.bind(this, function() {
this._list.set_child_at_index(obj.container, index);
Tweener.addTween(obj.container, { scale_x: 1,
scale_y: 1,
time: MESSAGE_ANIMATION_TIME,
transition: 'easeOutQuad' });
});
Tweener.addTween(obj.container, { scale_x: 0,
scale_y: 0,
time: MESSAGE_ANIMATION_TIME,
transition: 'easeOutQuad',
onComplete: onComplete });
},
removeMessage: function(message, animate) {
let obj = this._messages.get(message);
message.actor.disconnect(obj.destroyId);
message.actor.disconnect(obj.keyFocusId);
message.disconnect(obj.closeId);
this._messages.delete(message);
if (animate) {
Tweener.addTween(obj.container, { scale_x: 0, scale_y: 0,
time: MESSAGE_ANIMATION_TIME,
transition: 'easeOutQuad',
onComplete: function() {
obj.container.destroy();
global.sync_pointer();
}});
} else {
obj.container.destroy();
global.sync_pointer();
}
},
clear: function() {
let messages = [...this._messages.keys()].filter(function(message) {
return message.canClose();
});
// If there are few messages, letting them all zoom out looks OK
if (messages.length < 2) {
messages.forEach(function(message) {
message.close();
});
} else {
// Otherwise we slide them out one by one, and then zoom them
// out "off-screen" in the end to smoothly shrink the parent
let delay = MESSAGE_ANIMATION_TIME / Math.max(messages.length, 5);
for (let i = 0; i < messages.length; i++) {
let message = messages[i];
let obj = this._messages.get(message);
Tweener.addTween(obj.container,
{ anchor_x: this._list.width,
opacity: 0,
time: MESSAGE_ANIMATION_TIME,
delay: i * delay,
transition: 'easeOutQuad',
onComplete: function() {
message.close();
}});
}
}
},
_canClear: function() {
for (let message of this._messages.keys())
if (message.canClose())
return true;
return false;
},
_shouldShow: function() {
return !this.empty;
},
_sync: function() {
let empty = this._list.get_n_children() == 0;
let changed = this.empty !== empty;
this.empty = empty;
if (changed)
this.emit('empty-changed');
this._closeButton.visible = this._canClear();
this.actor.visible = this.allowed && this._shouldShow();
}
});
Signals.addSignalMethods(MessageListSection.prototype);

View File

@@ -259,7 +259,7 @@ const ModalDialog = new Lang.Class({
if (this.state == State.OPENED || this.state == State.OPENING)
return true;
if (!this.pushModal(timestamp))
if (!this.pushModal({ timestamp: timestamp }))
return false;
this._fadeOpen(onPrimary);
@@ -318,11 +318,8 @@ const ModalDialog = new Lang.Class({
pushModal: function (timestamp) {
if (this._hasModal)
return true;
let params = { actionMode: this._actionMode };
if (timestamp)
params['timestamp'] = timestamp;
if (!Main.pushModal(this._group, params))
if (!Main.pushModal(this._group, { timestamp: timestamp,
actionMode: this._actionMode }))
return false;
this._hasModal = true;

View File

@@ -1,270 +0,0 @@
const Gio = imports.gi.Gio;
const Lang = imports.lang;
const Signals = imports.signals;
const Shell = imports.gi.Shell;
const St = imports.gi.St;
const Calendar = imports.ui.calendar;
const Main = imports.ui.main;
const MessageList = imports.ui.messageList;
const DBusIface = '<node> \
<interface name="org.freedesktop.DBus"> \
<method name="ListNames"> \
<arg type="as" direction="out" name="names" /> \
</method> \
<signal name="NameOwnerChanged"> \
<arg type="s" direction="out" name="name" /> \
<arg type="s" direction="out" name="oldOwner" /> \
<arg type="s" direction="out" name="newOwner" /> \
</signal> \
</interface> \
</node>';
const DBusProxy = Gio.DBusProxy.makeProxyWrapper(DBusIface);
const MprisIface = '<node> \
<interface name="org.mpris.MediaPlayer2"> \
<method name="Raise" /> \
<property name="CanRaise" type="b" access="read" /> \
<property name="DesktopEntry" type="s" access="read" /> \
</interface> \
</node>';
const MprisProxy = Gio.DBusProxy.makeProxyWrapper(MprisIface);
const MprisPlayerIface = '<node> \
<interface name="org.mpris.MediaPlayer2.Player"> \
<method name="PlayPause" /> \
<method name="Next" /> \
<method name="Previous" /> \
<property name="CanPlay" type="b" access="read" /> \
<property name="Metadata" type="a{sv}" access="read" /> \
<property name="PlaybackStatus" type="s" access="read" /> \
</interface> \
</node>';
const MprisPlayerProxy = Gio.DBusProxy.makeProxyWrapper(MprisPlayerIface);
const MPRIS_PLAYER_PREFIX = 'org.mpris.MediaPlayer2.';
const MediaMessage = new Lang.Class({
Name: 'MediaMessage',
Extends: MessageList.Message,
_init: function(player) {
this._player = player;
this.parent('', '');
this._icon = new St.Icon({ style_class: 'media-message-cover-icon' });
this.setIcon(this._icon);
this.addMediaControl('media-skip-backward-symbolic',
Lang.bind(this, function() {
this._player.previous();
}));
this._playPauseButton = this.addMediaControl(null,
Lang.bind(this, function() {
this._player.playPause();
}));
this.addMediaControl('media-skip-forward-symbolic',
Lang.bind(this, function() {
this._player.next();
}));
this._player.connect('changed', Lang.bind(this, this._update));
this._player.connect('closed', Lang.bind(this, this.close));
this._update();
},
_onClicked: function() {
this._player.raise();
Main.panel.closeCalendar();
},
_update: function() {
this.setTitle(this._player.trackArtists.join(', '));
this.setBody(this._player.trackTitle);
if (this._player.trackCoverUrl) {
let file = Gio.File.new_for_uri(this._player.trackCoverUrl);
this._icon.gicon = new Gio.FileIcon({ file: file });
this._icon.remove_style_class_name('fallback');
} else {
this._icon.icon_name = 'audio-x-generic-symbolic';
this._icon.add_style_class_name('fallback');
}
let isPlaying = this._player.status == 'Playing';
let iconName = isPlaying ? 'media-playback-pause-symbolic'
: 'media-playback-start-symbolic';
this._playPauseButton.child.icon_name = iconName;
}
});
const MprisPlayer = new Lang.Class({
Name: 'MprisPlayer',
_init: function(busName) {
this._mprisProxy = new MprisProxy(Gio.DBus.session, busName,
'/org/mpris/MediaPlayer2',
Lang.bind(this, this._onMprisProxyReady));
this._playerProxy = new MprisPlayerProxy(Gio.DBus.session, busName,
'/org/mpris/MediaPlayer2',
Lang.bind(this, this._onPlayerProxyReady));
this._visible = false;
this._trackArtists = [];
this._trackTitle = '';
this._trackCoverUrl = '';
},
get status() {
return this._playerProxy.PlaybackStatus;
},
get trackArtists() {
return this._trackArtists;
},
get trackTitle() {
return this._trackTitle;
},
get trackCoverUrl() {
return this._trackCoverUrl;
},
playPause: function() {
this._playerProxy.PlayPauseRemote();
},
next: function() {
this._playerProxy.NextRemote();
},
previous: function() {
this._playerProxy.PreviousRemote();
},
raise: function() {
// The remote Raise() method may run into focus stealing prevention,
// so prefer activating the app via .desktop file if possible
let app = null;
if (this._mprisProxy.DesktopEntry) {
let desktopId = this._mprisProxy.DesktopEntry + '.desktop';
app = Shell.AppSystem.get_default().lookup_app(desktopId);
}
if (app)
app.activate();
else if (this._mprisProxy.CanRaise)
this._mprisProxy.RaiseRemote();
},
_close: function() {
this._mprisProxy.disconnect(this._ownerNotifyId);
this._mprisProxy = null;
this._playerProxy.disconnect(this._propsChangedId);
this._playerProxy = null;
this.emit('closed');
},
_onMprisProxyReady: function() {
this._ownerNotifyId = this._mprisProxy.connect('notify::g-name-owner',
Lang.bind(this, function() {
if (!this._mprisProxy.g_name_owner)
this._close();
}));
},
_onPlayerProxyReady: function() {
this._propsChangedId = this._playerProxy.connect('g-properties-changed',
Lang.bind(this, this._updateState));
this._updateState();
},
_updateState: function() {
let metadata = {};
for (let prop in this._playerProxy.Metadata)
metadata[prop] = this._playerProxy.Metadata[prop].deep_unpack();
this._trackArtists = metadata['xesam:artist'] || [_("Unknown artist")];
this._trackTitle = metadata['xesam:title'] || _("Unknown title");
this._trackCoverUrl = metadata['mpris:artUrl'] || '';
this.emit('changed');
let visible = this._playerProxy.CanPlay;
if (this._visible != visible) {
this._visible = visible;
if (visible)
this.emit('show');
else
this._close();
}
}
});
Signals.addSignalMethods(MprisPlayer.prototype);
const MediaSection = new Lang.Class({
Name: 'MediaSection',
Extends: MessageList.MessageListSection,
_init: function() {
this.parent(_("Media"));
this._players = new Map();
this._proxy = new DBusProxy(Gio.DBus.session,
'org.freedesktop.DBus',
'/org/freedesktop/DBus',
Lang.bind(this, this._onProxyReady));
},
_shouldShow: function() {
return !this.empty && Calendar.isToday(this._date);
},
_addPlayer: function(busName) {
if (this._players.get(busName))
return;
let player = new MprisPlayer(busName);
player.connect('closed', Lang.bind(this,
function() {
this._players.delete(busName);
}));
player.connect('show', Lang.bind(this,
function() {
let message = new MediaMessage(player);
this.addMessage(message, true);
}));
this._players.set(busName, player);
},
_onProxyReady: function() {
this._proxy.ListNamesRemote(Lang.bind(this,
function([names]) {
names.forEach(Lang.bind(this,
function(name) {
if (!name.startsWith(MPRIS_PLAYER_PREFIX))
return;
this._addPlayer(name);
}));
}));
this._proxy.connectSignal('NameOwnerChanged',
Lang.bind(this, this._onNameOwnerChanged));
},
_onNameOwnerChanged: function(proxy, sender, [name, oldOwner, newOwner]) {
if (!name.startsWith(MPRIS_PLAYER_PREFIX))
return;
if (newOwner && !oldOwner)
this._addPlayer(name);
}
});

View File

@@ -22,13 +22,11 @@ const LevelBar = new Lang.Class({
this._level = 0;
this.actor = new St.Bin({ style_class: 'level',
x_align: St.Align.START,
y_fill: true });
this._bar = new St.Widget({ style_class: 'level-bar' });
x_fill: true, y_fill: true });
this._bar = new St.DrawingArea();
this._bar.connect('repaint', Lang.bind(this, this._repaint));
this.actor.set_child(this._bar);
this.actor.connect('notify::width', () => { this.level = this.level; });
},
get level() {
@@ -36,44 +34,39 @@ const LevelBar = new Lang.Class({
},
set level(value) {
this._level = Math.max(0, Math.min(value, 100));
let alloc = this.actor.get_allocation_box();
let newWidth = Math.round((alloc.x2 - alloc.x1) * this._level / 100);
if (newWidth != this._bar.width)
this._bar.width = newWidth;
}
});
const OsdWindowConstraint = new Lang.Class({
Name: 'OsdWindowConstraint',
Extends: Clutter.Constraint,
_init: function(props) {
this._minSize = 0;
this.parent(props);
let newValue = Math.max(0, Math.min(value, 100));
if (newValue == this._level)
return;
this._level = newValue;
this._bar.queue_repaint();
},
set minSize(v) {
this._minSize = v;
if (this.actor)
this.actor.queue_relayout();
},
_repaint: function() {
let cr = this._bar.get_context();
vfunc_update_allocation: function(actor, actorBox) {
// Clutter will adjust the allocation for margins,
// so add it to our minimum size
let minSize = this._minSize + actor.margin_top + actor.margin_bottom;
let [width, height] = actorBox.get_size();
let node = this.actor.get_theme_node();
let radius = node.get_border_radius(0); // assume same radius for all corners
Clutter.cairo_set_source_color(cr, node.get_foreground_color());
// Enforce a ratio of 1
let size = Math.ceil(Math.max(minSize, height));
actorBox.set_size(size, size);
let [w, h] = this._bar.get_surface_size();
w *= (this._level / 100.);
// Recenter
let [x, y] = actorBox.get_origin();
actorBox.set_origin(Math.floor(x + width / 2 - size / 2),
Math.floor(y + height / 2 - size / 2));
if (w == 0)
return;
cr.moveTo(radius, 0);
if (w >= radius)
cr.arc(w - radius, radius, radius, 1.5 * Math.PI, 2. * Math.PI);
else
cr.lineTo(w, 0);
if (w >= radius)
cr.arc(w - radius, h - radius, radius, 0, 0.5 * Math.PI);
else
cr.lineTo(w, h);
cr.arc(radius, h - radius, radius, 0.5 * Math.PI, Math.PI);
cr.arc(radius, radius, radius, Math.PI, 1.5 * Math.PI);
cr.fill();
cr.$dispose();
}
});
@@ -81,6 +74,7 @@ const OsdWindow = new Lang.Class({
Name: 'OsdWindow',
_init: function(monitorIndex) {
this._popupSize = 0;
this.actor = new St.Widget({ x_expand: true,
y_expand: true,
x_align: Clutter.ActorAlign.CENTER,
@@ -90,12 +84,19 @@ const OsdWindow = new Lang.Class({
let constraint = new Layout.MonitorConstraint({ index: monitorIndex });
this.actor.add_constraint(constraint);
this._boxConstraint = new OsdWindowConstraint();
this._box = new St.BoxLayout({ style_class: 'osd-window',
vertical: true });
this._box.add_constraint(this._boxConstraint);
this.actor.add_actor(this._box);
this._box.connect('style-changed', Lang.bind(this, this._onStyleChanged));
this._box.connect('notify::height', Lang.bind(this,
function() {
Meta.later_add(Meta.LaterType.BEFORE_REDRAW, Lang.bind(this,
function() {
this._box.width = this._box.height;
}));
}));
this._icon = new St.Icon();
this._box.add(this._icon, { expand: true });
@@ -197,12 +198,30 @@ const OsdWindow = new Lang.Class({
let scalew = monitor.width / 640.0;
let scaleh = monitor.height / 480.0;
let scale = Math.min(scalew, scaleh);
let popupSize = 110 * Math.max(1, scale);
this._popupSize = 110 * Math.max(1, scale);
let scaleFactor = St.ThemeContext.get_for_stage(global.stage).scale_factor;
this._icon.icon_size = popupSize / (2 * scaleFactor);
this._icon.icon_size = this._popupSize / (2 * scaleFactor);
this._box.translation_y = monitor.height / 4;
this._boxConstraint.minSize = popupSize;
this._box.style_changed();
},
_onStyleChanged: function() {
let themeNode = this._box.get_theme_node();
let horizontalPadding = themeNode.get_horizontal_padding();
let verticalPadding = themeNode.get_vertical_padding();
let topBorder = themeNode.get_border_width(St.Side.TOP);
let bottomBorder = themeNode.get_border_width(St.Side.BOTTOM);
let leftBorder = themeNode.get_border_width(St.Side.LEFT);
let rightBorder = themeNode.get_border_width(St.Side.RIGHT);
let minWidth = this._popupSize - verticalPadding - leftBorder - rightBorder;
let minHeight = this._popupSize - horizontalPadding - topBorder - bottomBorder;
// minWidth/minHeight here are in real pixels,
// but the theme takes measures in unscaled dimensions
let scaleFactor = St.ThemeContext.get_for_stage(global.stage).scale_factor;
this._box.style = 'min-height: %dpx;'.format(Math.max(minWidth, minHeight) / scaleFactor);
}
});

View File

@@ -107,12 +107,18 @@ const Overview = new Lang.Class({
this._overviewCreated = true;
let layout = new Clutter.BinLayout();
this._stack = new Clutter.Actor({ layout_manager: layout });
this._stack.add_constraint(new LayoutManager.MonitorConstraint({ primary: true }));
/* Translators: This is the main view to select
activities. See also note for "Activities" string. */
this._overview = new St.BoxLayout({ name: 'overview',
accessible_name: _("Overview"),
vertical: true });
this._overview.add_constraint(new LayoutManager.MonitorConstraint({ primary: true }));
reactive: true,
vertical: true,
x_expand: true,
y_expand: true });
this._overview._delegate = this;
// The main Background actors are inside global.window_group which are
@@ -120,7 +126,7 @@ const Overview = new Lang.Class({
// one. Instances of this class share a single CoglTexture behind the
// scenes which allows us to show the background with different
// rendering options without duplicating the texture data.
this._backgroundGroup = new Meta.BackgroundGroup({ reactive: true });
this._backgroundGroup = new Meta.BackgroundGroup();
Main.layoutManager.overviewGroup.add_child(this._backgroundGroup);
this._bgManagers = [];
@@ -143,7 +149,8 @@ const Overview = new Lang.Class({
Main.layoutManager.overviewGroup.add_child(this._coverPane);
this._coverPane.connect('event', Lang.bind(this, function (actor, event) { return Clutter.EVENT_STOP; }));
Main.layoutManager.overviewGroup.add_child(this._overview);
this._stack.add_actor(this._overview);
Main.layoutManager.overviewGroup.add_child(this._stack);
this._coverPane.hide();
@@ -152,9 +159,6 @@ const Overview = new Lang.Class({
dragMotion: Lang.bind(this, this._onDragMotion)
};
Main.layoutManager.overviewGroup.connect('scroll-event',
Lang.bind(this, this._onScrollEvent));
Main.xdndHandler.connect('drag-begin', Lang.bind(this, this._onDragBegin));
Main.xdndHandler.connect('drag-end', Lang.bind(this, this._onDragEnd));
@@ -251,6 +255,7 @@ const Overview = new Lang.Class({
// Add our same-line elements after the search entry
this._overview.add(this._controls.actor, { y_fill: true, expand: true });
this._controls.actor.connect('scroll-event', Lang.bind(this, this._onScrollEvent));
// TODO - recalculate everything when desktop size changes
this.dashIconSize = this._dash.iconSize;
@@ -367,7 +372,7 @@ const Overview = new Lang.Class({
if (this.isDummy)
return;
this._backgroundGroup.add_action(action);
this._overview.add_action(action);
},
_getDesktopClone: function() {
@@ -547,8 +552,8 @@ const Overview = new Lang.Class({
Meta.disable_unredirect_for_screen(global.screen);
this.viewSelector.show();
this._overview.opacity = 0;
Tweener.addTween(this._overview,
this._stack.opacity = 0;
Tweener.addTween(this._stack,
{ opacity: 255,
transition: 'easeOutQuad',
time: ANIMATION_TIME,
@@ -613,7 +618,7 @@ const Overview = new Lang.Class({
this.viewSelector.animateFromOverview();
// Make other elements fade out.
Tweener.addTween(this._overview,
Tweener.addTween(this._stack,
{ opacity: 0,
transition: 'easeOutQuad',
time: ANIMATION_TIME,

View File

@@ -421,6 +421,7 @@ const ControlsManager = new Lang.Class({
let layout = new ControlsLayout();
this.actor = new St.Widget({ layout_manager: layout,
reactive: true,
x_expand: true, y_expand: true,
clip_to_allocation: true });
this._group = new St.BoxLayout({ name: 'overview-group',

View File

@@ -1146,16 +1146,6 @@ const PopupSubMenuMenuItem = new Lang.Class({
this.actor.remove_style_pseudo_class ('active');
this._setOpenState(!this._getOpenState());
return Clutter.EVENT_PROPAGATE;
},
_onTouchEvent: function(actor, event) {
if (event.type() == Clutter.EventType.TOUCH_END) {
// Since we override the parent, we need to manage what the parent does
// with the active style class
this.actor.remove_style_pseudo_class ('active');
this._setOpenState(!this._getOpenState());
}
return Clutter.EVENT_PROPAGATE;
}
});

View File

@@ -61,7 +61,6 @@ const RunDialog = new Lang.Class({
// rt is short for "reload theme"
'rt': Lang.bind(this, function() {
Main.reloadThemeResource();
Main.loadTheme();
})
};

View File

@@ -349,6 +349,7 @@ const Arrow = new Lang.Class({
_init: function(params) {
this.parent(params);
this.x_fill = this.y_fill = true;
this.set_offscreen_redirect(Clutter.OffscreenRedirect.ALWAYS);
this._drawingArea = new St.DrawingArea();
this._drawingArea.connect('repaint', Lang.bind(this, this._drawArrow));
@@ -376,22 +377,6 @@ const Arrow = new Lang.Class({
cr.$dispose();
},
vfunc_get_paint_volume: function(volume) {
if (!this.parent(volume))
return false;
if (!this._shadow)
return true;
let shadow_box = new Clutter.ActorBox();
this._shadow.get_box(this._drawingArea.get_allocation_box(), shadow_box);
volume.set_width(Math.max(shadow_box.x2 - shadow_box.x1, volume.get_width()));
volume.set_height(Math.max(shadow_box.y2 - shadow_box.y1, volume.get_height()));
return true;
},
vfunc_style_changed: function() {
let node = this.get_theme_node();
this._shadow = node.get_shadow('-arrow-shadow');
@@ -399,8 +384,6 @@ const Arrow = new Lang.Class({
this._shadowHelper = St.ShadowHelper.new(this._shadow);
else
this._shadowHelper = null;
this.parent();
},
vfunc_paint: function() {
@@ -576,9 +559,6 @@ const ScreenShield = new Lang.Class({
if (prevIsActive != this._isActive)
this.emit('active-changed');
if (this._loginSession)
this._loginSession.SetLockedHintRemote(active);
this._syncInhibitor();
},
@@ -728,7 +708,7 @@ const ScreenShield = new Lang.Class({
let unitaryDelay = ARROW_ANIMATION_TIME / (arrows.length + 1);
let maxOpacity = 255 * ARROW_ANIMATION_PEAK_OPACITY;
for (let i = 0; i < arrows.length; i++) {
arrows[i].opacity = 0;
arrows.opacity = 0;
Tweener.addTween(arrows[i],
{ opacity: 0,
delay: unitaryDelay * (N_ARROWS - (i + 1)),

View File

@@ -137,10 +137,6 @@ const Slider = new Lang.Class({
this._motionId = this.actor.connect('motion-event', Lang.bind(this, this._motionEvent));
}
// We need to emit 'drag-begin' before moving the handle to make
// sure that no 'value-changed' signal is emitted before this one.
this.emit('drag-begin');
let absX, absY;
[absX, absY] = event.get_coords();
this._moveHandle(absX, absY);
@@ -228,7 +224,6 @@ const Slider = new Lang.Class({
let delta = key == Clutter.KEY_Right ? 0.1 : -0.1;
this._value = Math.max(0, Math.min(this._value + delta, 1));
this.actor.queue_repaint();
this.emit('drag-begin');
this.emit('value-changed', this._value);
this.emit('drag-end');
return Clutter.EVENT_STOP;

View File

@@ -1,8 +1,11 @@
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
const Clutter = imports.gi.Clutter;
const GLib = imports.gi.GLib;
const Gio = imports.gi.Gio;
const GnomeBluetooth = imports.gi.GnomeBluetooth;
const Lang = imports.lang;
const St = imports.gi.St;
const Main = imports.ui.main;
const PanelMenu = imports.ui.panelMenu;
@@ -20,8 +23,6 @@ const RfkillManagerInterface = '<node> \
const RfkillManagerProxy = Gio.DBusProxy.makeProxyWrapper(RfkillManagerInterface);
const HAD_BLUETOOTH_DEVICES_SETUP = 'had-bluetooth-devices-setup';
const Indicator = new Lang.Class({
Name: 'BTIndicator',
Extends: PanelMenu.SystemIndicator,
@@ -31,7 +32,6 @@ const Indicator = new Lang.Class({
this._indicator = this._addIndicator();
this._indicator.icon_name = 'bluetooth-active-symbolic';
this._hadSetupDevices = global.settings.get_boolean(HAD_BLUETOOTH_DEVICES_SETUP);
this._proxy = new RfkillManagerProxy(Gio.DBus.session, BUS_NAME, OBJECT_PATH,
Lang.bind(this, function(proxy, error) {
@@ -44,15 +44,13 @@ const Indicator = new Lang.Class({
}));
this._proxy.connect('g-properties-changed', Lang.bind(this, this._sync));
this._item = new PopupMenu.PopupSubMenuMenuItem(_("Bluetooth"), true);
// The Bluetooth menu only appears when Bluetooth is in use,
// so just statically build it with a "Turn Off" menu item.
this._item = new PopupMenu.PopupSubMenuMenuItem('', true);
this._item.icon.icon_name = 'bluetooth-active-symbolic';
this._toggleItem = new PopupMenu.PopupMenuItem('');
this._toggleItem.connect('activate', Lang.bind(this, function() {
this._proxy.BluetoothAirplaneMode = !this._proxy.BluetoothAirplaneMode;
this._item.menu.addAction(_("Turn Off"), Lang.bind(this, function() {
this._proxy.BluetoothAirplaneMode = true;
}));
this._item.menu.addMenuItem(this._toggleItem);
this._item.menu.addSettingsAction(_("Bluetooth Settings"), 'gnome-bluetooth-panel.desktop');
this.menu.addMenuItem(this._item);
@@ -70,75 +68,42 @@ const Indicator = new Lang.Class({
while (ret) {
let isDefault = this._model.get_value(iter,
GnomeBluetooth.Column.DEFAULT);
let isPowered = this._model.get_value(iter,
GnomeBluetooth.Column.POWERED);
if (isDefault && isPowered)
if (isDefault)
return iter;
ret = this._model.iter_next(iter);
}
return null;
},
// nDevices is the number of devices setup for the current default
// adapter if one exists and is powered. If unpowered or unavailable,
// nDevice is "1" if it had setup devices associated to it the last
// time it was seen, and "-1" if not.
//
// nConnectedDevices is the number of devices connected to the default
// adapter if one exists and is powered, or -1 if it's not available.
_getNDevices: function() {
_getNConnectedDevices: function() {
let adapter = this._getDefaultAdapter();
if (!adapter)
return [ this._hadSetupDevices ? 1 : -1, -1 ];
return 0;
let nConnectedDevices = 0;
let nDevices = 0;
let [ret, iter] = this._model.iter_children(adapter);
while (ret) {
let isConnected = this._model.get_value(iter,
GnomeBluetooth.Column.CONNECTED);
if (isConnected)
nConnectedDevices++;
let isPaired = this._model.get_value(iter,
GnomeBluetooth.Column.PAIRED);
let isTrusted = this._model.get_value(iter,
GnomeBluetooth.Column.TRUSTED);
if (isPaired || isTrusted)
nDevices++;
ret = this._model.iter_next(iter);
}
if (this._hadSetupDevices != (nDevices > 0)) {
this._hadSetupDevices = !this._hadSetupDevices;
global.settings.set_boolean(HAD_BLUETOOTH_DEVICES_SETUP, this._hadSetupDevices);
}
return [ nDevices, nConnectedDevices];
return nDevices;
},
_sync: function() {
let [ nDevices, nConnectedDevices ] = this._getNDevices();
let nDevices = this._getNConnectedDevices();
let sensitive = !Main.sessionMode.isLocked && !Main.sessionMode.isGreeter;
this.menu.setSensitive(sensitive);
this._indicator.visible = nConnectedDevices > 0;
this._indicator.visible = nDevices > 0;
this._item.actor.visible = this._proxy.BluetoothHasAirplaneMode && !this._proxy.BluetoothAirplaneMode;
// Remember if there were setup devices and show the menu
// if we've seen setup devices and we're not hard blocked
if (nDevices > 0)
this._item.actor.visible = !this._proxy.BluetoothHardwareAirplaneMode;
else
this._item.actor.visible = this._proxy.BluetoothHasAirplaneMode && !this._proxy.BluetoothAirplaneMode;
if (nConnectedDevices > 0)
/* Translators: this is the number of connected bluetooth devices */
this._item.label.text = ngettext("%d Connected", "%d Connected", nConnectedDevices).format(nConnectedDevices);
else if (nConnectedDevices == -1)
this._item.label.text = _("Off");
this._item.label.text = ngettext("%d Connected", "%d Connected", nDevices).format(nDevices);
else
this._item.label.text = _("Not In Use");
this._toggleItem.label.text = this._proxy.BluetoothAirplaneMode ? _("Turn On") : _("Turn Off");
},
});

View File

@@ -61,8 +61,8 @@ const InputSource = new Lang.Class({
this.emit('changed');
},
activate: function(interactive) {
this.emit('activate', !!interactive);
activate: function() {
this.emit('activate');
},
_getXkbId: function() {
@@ -109,7 +109,7 @@ const InputSourcePopup = new Lang.Class({
_finish : function() {
this.parent();
this._items[this._selectedIndex].activate(true);
this._items[this._selectedIndex].activate();
},
});
@@ -159,14 +159,6 @@ const InputSourceSettings = new Lang.Class({
return [];
},
get mruSources() {
return [];
},
set mruSources(sourcesList) {
// do nothing
},
get keyboardOptions() {
return [];
},
@@ -259,7 +251,6 @@ const InputSourceSessionSettings = new Lang.Class({
_DESKTOP_INPUT_SOURCES_SCHEMA: 'org.gnome.desktop.input-sources',
_KEY_INPUT_SOURCES: 'sources',
_KEY_MRU_SOURCES: 'mru-sources',
_KEY_KEYBOARD_OPTIONS: 'xkb-options',
_KEY_PER_WINDOW: 'per-window',
@@ -270,9 +261,9 @@ const InputSourceSessionSettings = new Lang.Class({
this._settings.connect('changed::' + this._KEY_PER_WINDOW, Lang.bind(this, this._emitPerWindowChanged));
},
_getSourcesList: function(key) {
get inputSources() {
let sourcesList = [];
let sources = this._settings.get_value(key);
let sources = this._settings.get_value(this._KEY_INPUT_SOURCES);
let nSources = sources.n_children();
for (let i = 0; i < nSources; i++) {
@@ -282,19 +273,6 @@ const InputSourceSessionSettings = new Lang.Class({
return sourcesList;
},
get inputSources() {
return this._getSourcesList(this._KEY_INPUT_SOURCES);
},
get mruSources() {
return this._getSourcesList(this._KEY_MRU_SOURCES);
},
set mruSources(sourcesList) {
let sources = GLib.Variant.new('a(ss)', sourcesList);
this._settings.set_value(this._KEY_MRU_SOURCES, sources);
},
get keyboardOptions() {
return this._settings.get_strv(this._KEY_KEYBOARD_OPTIONS);
},
@@ -394,7 +372,7 @@ const InputSourceManager = new Lang.Class({
while (!(is = this._inputSources[nextIndex]))
nextIndex += 1;
is.activate(true);
is.activate();
return true;
},
@@ -422,25 +400,6 @@ const InputSourceManager = new Lang.Class({
this._keyboardManager.reapply();
},
_updateMruSettings: function() {
// If IBus is not ready we don't have a full picture of all
// the available sources, so don't update the setting
if (!this._ibusReady)
return;
// If IBus is temporarily disabled, don't update the setting
if (this._disableIBus)
return;
let sourcesList = [];
for (let i = 0; i < this._mruSources.length; ++i) {
let source = this._mruSources[i];
sourcesList.push([source.type, source.id]);
}
this._settings.mruSources = sourcesList;
},
_currentInputSourceChanged: function(newSource) {
let oldSource;
[oldSource, this._currentSource] = [this._currentSource, newSource];
@@ -457,7 +416,7 @@ const InputSourceManager = new Lang.Class({
this._changePerWindowSource();
},
_activateInputSource: function(is, interactive) {
_activateInputSource: function(is) {
KeyboardManager.holdKeyboard();
this._keyboardManager.apply(is.xkbId);
@@ -475,54 +434,6 @@ const InputSourceManager = new Lang.Class({
this._ibusManager.setEngine(engine, KeyboardManager.releaseKeyboard);
this._currentInputSourceChanged(is);
if (interactive)
this._updateMruSettings();
},
_updateMruSources: function() {
let sourcesList = [];
for (let i in this._inputSources)
sourcesList.push(this._inputSources[i]);
this._keyboardManager.setUserLayouts(sourcesList.map(function(x) { return x.xkbId; }));
if (!this._disableIBus && this._mruSourcesBackup) {
this._mruSources = this._mruSourcesBackup;
this._mruSourcesBackup = null;
}
// Initialize from settings when we have no MRU sources list
if (this._mruSources.length == 0) {
let mruSettings = this._settings.mruSources;
for (let i = 0; i < mruSettings.length; i++) {
let mruSettingSource = mruSettings[i];
let mruSource = null;
for (let j = 0; j < sourcesList.length; j++) {
let source = sourcesList[j];
if (source.type == mruSettingSource.type &&
source.id == mruSettingSource.id) {
mruSource = source;
break;
}
}
if (mruSource)
this._mruSources.push(mruSource);
}
}
let mruSources = [];
for (let i = 0; i < this._mruSources.length; i++) {
for (let j = 0; j < sourcesList.length; j++)
if (this._mruSources[i].type == sourcesList[j].type &&
this._mruSources[i].id == sourcesList[j].id) {
mruSources = mruSources.concat(sourcesList.splice(j, 1));
break;
}
}
this._mruSources = mruSources.concat(sourcesList);
},
_inputSourcesChanged: function() {
@@ -599,10 +510,30 @@ const InputSourceManager = new Lang.Class({
this.emit('sources-changed');
this._updateMruSources();
let sourcesList = [];
for (let i in this._inputSources)
sourcesList.push(this._inputSources[i]);
this._keyboardManager.setUserLayouts(sourcesList.map(function(x) { return x.xkbId; }));
if (!this._disableIBus && this._mruSourcesBackup) {
this._mruSources = this._mruSourcesBackup;
this._mruSourcesBackup = null;
}
let mruSources = [];
for (let i = 0; i < this._mruSources.length; i++) {
for (let j = 0; j < sourcesList.length; j++)
if (this._mruSources[i].type == sourcesList[j].type &&
this._mruSources[i].id == sourcesList[j].id) {
mruSources = mruSources.concat(sourcesList.splice(j, 1));
break;
}
}
this._mruSources = mruSources.concat(sourcesList);
if (this._mruSources.length > 0)
this._mruSources[0].activate(false);
this._mruSources[0].activate();
// All ibus engines are preloaded here to reduce the launching time
// when users switch the input sources.
@@ -711,7 +642,7 @@ const InputSourceManager = new Lang.Class({
}
if (window._currentSource)
window._currentSource.activate(false);
window._currentSource.activate();
},
_sourcesPerWindowChanged: function() {
@@ -832,10 +763,7 @@ const InputSourceIndicator = new Lang.Class({
let is = this._inputSourceManager.inputSources[i];
let menuItem = new LayoutMenuItem(is.displayName, is.shortName);
menuItem.connect('activate', function() {
is.activate(true);
});
menuItem.connect('activate', Lang.bind(is, is.activate));
let indicatorLabel = new St.Label({ text: is.shortName,
visible: false });

View File

@@ -1,6 +1,5 @@
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
const Clutter = imports.gi.Clutter;
const GLib = imports.gi.GLib;
const Gio = imports.gi.Gio;
const Lang = imports.lang;
@@ -8,18 +7,12 @@ const Lang = imports.lang;
const Main = imports.ui.main;
const PanelMenu = imports.ui.panelMenu;
const PopupMenu = imports.ui.popupMenu;
const ModalDialog = imports.ui.modalDialog;
const Shell = imports.gi.Shell;
const Signals = imports.signals;
const St = imports.gi.St;
const LOCATION_SCHEMA = 'org.gnome.system.location';
const MAX_ACCURACY_LEVEL = 'max-accuracy-level';
const ENABLED = 'enabled';
const APP_PERMISSIONS_TABLE = 'gnome';
const APP_PERMISSIONS_ID = 'geolocation';
const GeoclueAccuracyLevel = {
NONE: 0,
COUNTRY: 1,
@@ -29,15 +22,6 @@ const GeoclueAccuracyLevel = {
EXACT: 8
};
function accuracyLevelToString(accuracyLevel) {
for (let key in GeoclueAccuracyLevel) {
if (GeoclueAccuracyLevel[key] == accuracyLevel)
return key;
}
return 'NONE';
}
var GeoclueIface = '<node> \
<interface name="org.freedesktop.GeoClue2.Manager"> \
<property name="InUse" type="b" access="read"/> \
@@ -62,26 +46,6 @@ var AgentIface = '<node> \
</interface> \
</node>';
var PermissionStoreIface = '<node> \
<interface name="org.freedesktop.impl.portal.PermissionStore"> \
<method name="Lookup"> \
<arg name="table" type="s" direction="in"/> \
<arg name="id" type="s" direction="in"/> \
<arg name="permissions" type="a{sas}" direction="out"/> \
<arg name="data" type="v" direction="out"/> \
</method> \
<method name="Set"> \
<arg name="table" type="s" direction="in"/> \
<arg name="create" type="b" direction="in"/> \
<arg name="id" type="s" direction="in"/> \
<arg name="app_permissions" type="a{sas}" direction="in"/> \
<arg name="data" type="v" direction="in"/> \
</method> \
</interface> \
</node>';
const PermissionStore = Gio.DBusProxy.makeProxyWrapper(PermissionStoreIface);
const Indicator = new Lang.Class({
Name: 'LocationIndicator',
Extends: PanelMenu.SystemIndicator,
@@ -119,66 +83,64 @@ const Indicator = new Lang.Class({
this._onSessionUpdated();
this._onMaxAccuracyLevelChanged();
this._connectToGeoclue();
this._connectToPermissionStore();
},
get MaxAccuracyLevel() {
return this._getMaxAccuracyLevel();
},
AuthorizeAppAsync: function(params, invocation) {
let [desktopId, reqAccuracyLevel] = params;
// We (and geoclue) have currently no way to reliably identifying apps so
// for now, lets just authorize all apps as long as they provide a valid
// desktop ID. We also ensure they don't get more accuracy than global max.
AuthorizeApp: function(desktop_id, reqAccuracyLevel) {
var appSystem = Shell.AppSystem.get_default();
var app = appSystem.lookup_app(desktop_id + ".desktop");
if (app == null) {
return [false, 0];
}
let authorizer = new AppAuthorizer(desktopId,
reqAccuracyLevel,
this._permStoreProxy,
this._getMaxAccuracyLevel());
authorizer.authorize(Lang.bind(this, function(accuracyLevel) {
let ret = (accuracyLevel != GeoclueAccuracyLevel.NONE);
invocation.return_value(GLib.Variant.new('(bu)',
[ret, accuracyLevel]));
}));
let allowedAccuracyLevel = clamp(reqAccuracyLevel, 0, this._getMaxAccuracyLevel());
return [true, allowedAccuracyLevel];
},
_syncIndicator: function() {
if (this._managerProxy == null) {
if (this._proxy == null) {
this._indicator.visible = false;
this._item.actor.visible = false;
return;
}
this._indicator.visible = this._managerProxy.InUse;
this._indicator.visible = this._proxy.InUse;
this._item.actor.visible = this._indicator.visible;
this._updateMenuLabels();
},
_connectToGeoclue: function() {
if (this._managerProxy != null || this._connecting)
if (this._proxy != null || this._connecting)
return false;
this._connecting = true;
new GeoclueManager(Gio.DBus.system,
'org.freedesktop.GeoClue2',
'/org/freedesktop/GeoClue2/Manager',
Lang.bind(this, this._onManagerProxyReady));
Lang.bind(this, this._onProxyReady));
return true;
},
_onManagerProxyReady: function(proxy, error) {
_onProxyReady: function(proxy, error) {
if (error != null) {
log(error.message);
this._connecting = false;
return;
}
this._managerProxy = proxy;
this._propertiesChangedId = this._managerProxy.connect('g-properties-changed',
this._proxy = proxy;
this._propertiesChangedId = this._proxy.connect('g-properties-changed',
Lang.bind(this, this._onGeocluePropsChanged));
this._syncIndicator();
this._managerProxy.AddAgentRemote('gnome-shell', Lang.bind(this, this._onAgentRegistered));
this._proxy.AddAgentRemote('gnome-shell', Lang.bind(this, this._onAgentRegistered));
},
_onAgentRegistered: function(result, error) {
@@ -191,10 +153,10 @@ const Indicator = new Lang.Class({
_onGeoclueVanished: function() {
if (this._propertiesChangedId) {
this._managerProxy.disconnect(this._propertiesChangedId);
this._proxy.disconnect(this._propertiesChangedId);
this._propertiesChangedId = 0;
}
this._managerProxy = null;
this._proxy = null;
this._syncIndicator();
},
@@ -249,206 +211,9 @@ const Indicator = new Lang.Class({
let unpacked = properties.deep_unpack();
if ("InUse" in unpacked)
this._syncIndicator();
},
_connectToPermissionStore: function() {
this._permStoreProxy = null;
new PermissionStore(Gio.DBus.session,
'org.freedesktop.impl.portal.PermissionStore',
'/org/freedesktop/impl/portal/PermissionStore',
Lang.bind(this, this._onPermStoreProxyReady));
},
_onPermStoreProxyReady: function(proxy, error) {
if (error != null) {
log(error.message);
return;
}
this._permStoreProxy = proxy;
},
}
});
function clamp(value, min, max) {
return Math.max(min, Math.min(max, value));
}
const AppAuthorizer = new Lang.Class({
Name: 'LocationAppAuthorizer',
_init: function(desktopId,
reqAccuracyLevel,
permStoreProxy,
maxAccuracyLevel) {
this.desktopId = desktopId;
this.reqAccuracyLevel = reqAccuracyLevel;
this._permStoreProxy = permStoreProxy;
this._maxAccuracyLevel = maxAccuracyLevel;
this._accuracyLevel = GeoclueAccuracyLevel.NONE;
},
authorize: function(onAuthDone) {
this._onAuthDone = onAuthDone;
let appSystem = Shell.AppSystem.get_default();
this._app = appSystem.lookup_app(this.desktopId + ".desktop");
if (this._app == null || this._permStoreProxy == null) {
this._completeAuth();
return;
}
this._permStoreProxy.LookupRemote(APP_PERMISSIONS_TABLE,
APP_PERMISSIONS_ID,
Lang.bind(this,
this._onPermLookupDone));
},
_onPermLookupDone: function(result, error) {
if (error != null) {
if (error.domain == Gio.DBusError) {
// Likely no xdg-app installed, just authorize the app
this._accuracyLevel = this.reqAccuracyLevel;
this._permStoreProxy = null;
this._completeAuth();
} else {
// Currently xdg-app throws an error if we lookup for
// unknown ID (which would be the case first time this code
// runs) so we continue with user authorization as normal
// and ID is added to the store if user says "yes".
log(error.message);
this._permissions = {};
this._userAuthorizeApp();
}
return;
}
[this._permissions] = result;
let permission = this._permissions[this.desktopId];
if (permission == null) {
this._userAuthorizeApp();
} else {
let [levelStr] = permission || ['NONE'];
this._accuracyLevel = GeoclueAccuracyLevel[levelStr] ||
GeoclueAccuracyLevel.NONE;
this._completeAuth();
}
},
_userAuthorizeApp: function() {
let name = this._app.get_name();
let appInfo = this._app.get_app_info();
let reason = appInfo.get_string("X-Geoclue-Reason");
this._showAppAuthDialog(name, reason);
},
_showAppAuthDialog: function(name, reason) {
this._dialog = new GeolocationDialog(name,
reason,
this.reqAccuracyLevel);
let responseId = this._dialog.connect('response', Lang.bind(this,
function(dialog, level) {
this._dialog.disconnect(responseId);
this._accuracyLevel = level;
this._completeAuth();
}));
this._dialog.open();
},
_completeAuth: function() {
if (this._accuracyLevel != GeoclueAccuracyLevel.NONE) {
this._accuracyLevel = clamp(this._accuracyLevel,
0,
this._maxAccuracyLevel);
}
this._saveToPermissionStore();
this._onAuthDone(this._accuracyLevel);
},
_saveToPermissionStore: function() {
if (this._permStoreProxy == null)
return;
let levelStr = accuracyLevelToString(this._accuracyLevel);
let dateStr = Math.round(Date.now() / 1000).toString();
this._permissions[this.desktopId] = [levelStr, dateStr];
let data = GLib.Variant.new('av', {});
this._permStoreProxy.SetRemote(APP_PERMISSIONS_TABLE,
true,
APP_PERMISSIONS_ID,
this._permissions,
data,
function (result, error) {
if (error != null)
log(error.message);
});
},
});
const GeolocationDialog = new Lang.Class({
Name: 'GeolocationDialog',
Extends: ModalDialog.ModalDialog,
_init: function(name, reason, reqAccuracyLevel) {
this.parent({ styleClass: 'geolocation-dialog' });
this.reqAccuracyLevel = reqAccuracyLevel;
let mainContentBox = new St.BoxLayout({ style_class: 'geolocation-dialog-main-layout' });
this.contentLayout.add_actor(mainContentBox);
let icon = new St.Icon({ style_class: 'geolocation-dialog-icon',
icon_name: 'find-location-symbolic',
y_align: Clutter.ActorAlign.START });
mainContentBox.add_actor(icon);
let messageBox = new St.BoxLayout({ style_class: 'geolocation-dialog-content',
vertical: true });
mainContentBox.add_actor(messageBox);
this._title = new St.Label({ style_class: 'geolocation-dialog-title headline' });
messageBox.add_actor(this._title);
this._reason = new St.Label({ style_class: 'geolocation-dialog-reason' });
messageBox.add_actor(this._reason);
this._privacyNote = new St.Label();
messageBox.add_actor(this._privacyNote);
let button = this.addButton({ label: _("Deny Access"),
action: Lang.bind(this, this._onDenyClicked),
key: Clutter.KEY_Escape });
this.addButton({ label: _("Grant Access"),
action: Lang.bind(this, this._onGrantClicked) });
this.setInitialKeyFocus(button);
/* Translators: %s is an application name */
this._title.text = _("Give %s access to your location?").format(name);
this._privacyNote.text = _("Location access can be changed at any time from the privacy settings.");
if (reason)
this._reason.text = reason;
this._reason.visible = (reason != null);
},
_onGrantClicked: function() {
this.emit('response', this.reqAccuracyLevel);
this.close();
},
_onDenyClicked: function() {
this.emit('response', GeoclueAccuracyLevel.NONE);
this.close();
}
});
Signals.addSignalMethods(GeolocationDialog.prototype);

View File

@@ -621,7 +621,7 @@ const NMDeviceBluetooth = new Lang.Class({
_init: function(client, device, settings) {
this.parent(client, device, settings);
this.item.menu.addMenuItem(createSettingsAction(_("Bluetooth Settings"), device));
this.item.menu.addMenuItem(createSettingsAction(_("Mobile Broadband Settings"), device));
},
_getDescription: function() {
@@ -629,7 +629,7 @@ const NMDeviceBluetooth = new Lang.Class({
},
getConnectLabel: function() {
return _("Connect to Internet");
return _("Use as Internet connection");
},
getIndicatorIcon: function() {
@@ -1632,8 +1632,6 @@ const NMApplet = new Lang.Class({
this._readConnections();
this._readDevices();
this._syncNMState();
this._syncMainConnection();
this._syncVPNConnections();
this._client.connect('notify::manager-running', Lang.bind(this, this._syncNMState));
this._client.connect('notify::networking-enabled', Lang.bind(this, this._syncNMState));

View File

@@ -1,8 +1,6 @@
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
const Gio = imports.gi.Gio;
const Clutter = imports.gi.Clutter;
const St = imports.gi.St;
const Lang = imports.lang;
const UPower = imports.gi.UPowerGlib;
@@ -27,8 +25,6 @@ const DisplayDeviceInterface = '<node> \
const PowerManagerProxy = Gio.DBusProxy.makeProxyWrapper(DisplayDeviceInterface);
const SHOW_BATTERY_PERCENTAGE = 'show-battery-percentage';
const Indicator = new Lang.Class({
Name: 'PowerIndicator',
Extends: PanelMenu.SystemIndicator,
@@ -36,15 +32,7 @@ const Indicator = new Lang.Class({
_init: function() {
this.parent();
this._desktopSettings = new Gio.Settings({ schema_id: 'org.gnome.desktop.interface' });
this._desktopSettings.connect('changed::' + SHOW_BATTERY_PERCENTAGE,
Lang.bind(this, this._sync));
this._indicator = this._addIndicator();
this._percentageLabel = new St.Label({ y_expand: true,
y_align: Clutter.ActorAlign.CENTER });
this.indicators.add(this._percentageLabel, { expand: true, y_fill: true });
this.indicators.add_style_class_name('power-status');
this._proxy = new PowerManagerProxy(Gio.DBus.system, BUS_NAME, OBJECT_PATH,
Lang.bind(this, function(proxy, error) {
@@ -95,12 +83,12 @@ const Indicator = new Lang.Class({
if (this._proxy.State == UPower.DeviceState.DISCHARGING) {
// Translators: this is <hours>:<minutes> Remaining (<percentage>)
return _("%d\u2236%02d Remaining (%d\u2009%%)").format(hours, minutes, this._proxy.Percentage);
return _("%d\u2236%02d Remaining (%d%%)").format(hours, minutes, this._proxy.Percentage);
}
if (this._proxy.State == UPower.DeviceState.CHARGING) {
// Translators: this is <hours>:<minutes> Until Full (<percentage>)
return _("%d\u2236%02d Until Full (%d\u2009%%)").format(hours, minutes, this._proxy.Percentage);
return _("%d\u2236%02d Until Full (%d%%)").format(hours, minutes, this._proxy.Percentage);
}
return null;
@@ -111,12 +99,10 @@ const Indicator = new Lang.Class({
let visible = this._proxy.IsPresent;
if (visible) {
this._item.actor.show();
this._percentageLabel.visible = this._desktopSettings.get_boolean(SHOW_BATTERY_PERCENTAGE);
} else {
// If there's no battery, then we use the power icon.
this._item.actor.hide();
this._indicator.icon_name = 'system-shutdown-symbolic';
this._percentageLabel.hide();
return;
}
@@ -125,14 +111,6 @@ const Indicator = new Lang.Class({
this._indicator.icon_name = icon;
this._item.icon.icon_name = icon;
// The icon label
let label
if (this._proxy.State == UPower.DeviceState.FULLY_CHARGED)
label = _("%d\u2009%%").format(100);
else
label = _("%d\u2009%%").format(this._proxy.Percentage);
this._percentageLabel.clutter_text.set_markup('<span size="smaller">' + label + '</span>');
// The status label
this._item.label.text = this._getStatus();
},

View File

@@ -6,7 +6,6 @@ const Gdm = imports.gi.Gdm;
const Gio = imports.gi.Gio;
const GLib = imports.gi.GLib;
const Lang = imports.lang;
const Meta = imports.gi.Meta;
const Shell = imports.gi.Shell;
const St = imports.gi.St;
@@ -111,7 +110,6 @@ const Indicator = new Lang.Class({
this._session = new GnomeSession.SessionManager();
this._loginManager = LoginManager.getLoginManager();
this._monitorManager = Meta.MonitorManager.get();
this._haveShutdown = true;
this._haveSuspend = true;
@@ -157,8 +155,6 @@ const Indicator = new Lang.Class({
this._orientationSettings.connect('changed::orientation-lock',
Lang.bind(this, this._updateOrientationLock));
Main.layoutManager.connect('monitors-changed',
Lang.bind(this, this._updateOrientationLock));
Gio.DBus.system.watch_name(SENSOR_BUS_NAME,
Gio.BusNameWatcherFlags.NONE,
Lang.bind(this, this._sensorProxyAppeared),
@@ -268,8 +264,7 @@ const Indicator = new Lang.Class({
_updateOrientationLock: function() {
if (this._sensorProxy)
this._orientationLockAction.visible = this._sensorProxy.HasAccelerometer &&
this._monitorManager.get_is_builtin_display_on();
this._orientationLockAction.visible = this._sensorProxy.HasAccelerometer;
else
this._orientationLockAction.visible = false;
@@ -306,17 +301,14 @@ const Indicator = new Lang.Class({
},
_updateHaveSuspend: function() {
this._loginManager.canSuspend(Lang.bind(this,
function(canSuspend, needsAuth) {
this._haveSuspend = canSuspend;
this._suspendNeedsAuth = needsAuth;
this._updateSuspend();
}));
this._loginManager.canSuspend(Lang.bind(this, function(result) {
this._haveSuspend = result;
this._updateSuspend();
}));
},
_updateSuspend: function() {
let disabled = (Main.sessionMode.isLocked &&
this._suspendNeedsAuth) ||
let disabled = Main.sessionMode.isLocked ||
(Main.sessionMode.isGreeter &&
this._loginScreenSettings.get_boolean(DISABLE_RESTART_KEY));
this._suspendAction.visible = this._haveSuspend && !disabled;

View File

@@ -156,7 +156,7 @@ const ViewSelector = new Lang.Class({
this.appDisplay = new AppDisplay.AppDisplay();
this._appsPage = this._addPage(this.appDisplay.actor,
_("Applications"), 'view-app-grid-symbolic');
_("Applications"), 'view-grid-symbolic');
this._searchResults = new Search.SearchResults();
this._searchPage = this._addPage(this._searchResults.actor,

View File

@@ -683,8 +683,6 @@ const WindowManager = new Lang.Class({
this._dimmedWindows = [];
this._skippedActors = [];
this._allowedKeybindings = {};
this._isWorkspacePrepended = false;
@@ -852,34 +850,22 @@ const WindowManager = new Lang.Class({
Lang.bind(this, this._showWorkspaceSwitcher));
this.setCustomKeybindingHandler('switch-applications',
Shell.ActionMode.NORMAL,
Lang.bind(this, this._startSwitcher));
Lang.bind(this, this._startAppSwitcher));
this.setCustomKeybindingHandler('switch-group',
Shell.ActionMode.NORMAL,
Lang.bind(this, this._startSwitcher));
Lang.bind(this, this._startAppSwitcher));
this.setCustomKeybindingHandler('switch-applications-backward',
Shell.ActionMode.NORMAL,
Lang.bind(this, this._startSwitcher));
Lang.bind(this, this._startAppSwitcher));
this.setCustomKeybindingHandler('switch-group-backward',
Shell.ActionMode.NORMAL,
Lang.bind(this, this._startSwitcher));
Lang.bind(this, this._startAppSwitcher));
this.setCustomKeybindingHandler('switch-windows',
Shell.ActionMode.NORMAL,
Lang.bind(this, this._startSwitcher));
Lang.bind(this, this._startWindowSwitcher));
this.setCustomKeybindingHandler('switch-windows-backward',
Shell.ActionMode.NORMAL,
Lang.bind(this, this._startSwitcher));
this.setCustomKeybindingHandler('cycle-windows',
Shell.ActionMode.NORMAL,
Lang.bind(this, this._startSwitcher));
this.setCustomKeybindingHandler('cycle-windows-backward',
Shell.ActionMode.NORMAL,
Lang.bind(this, this._startSwitcher));
this.setCustomKeybindingHandler('cycle-group',
Shell.ActionMode.NORMAL,
Lang.bind(this, this._startSwitcher));
this.setCustomKeybindingHandler('cycle-group-backward',
Shell.ActionMode.NORMAL,
Lang.bind(this, this._startSwitcher));
Lang.bind(this, this._startWindowSwitcher));
this.setCustomKeybindingHandler('switch-panels',
Shell.ActionMode.NORMAL |
Shell.ActionMode.OVERVIEW |
@@ -1037,10 +1023,6 @@ const WindowManager = new Lang.Class({
this._workspaceTracker.keepWorkspaceAlive(workspace, duration);
},
skipNextEffect: function(actor) {
this._skippedActors.push(actor);
},
setCustomKeybindingHandler: function(name, modes, handler) {
if (Meta.keybindings_set_custom_handler(name, handler))
this.allowKeybinding(name, modes);
@@ -1067,9 +1049,6 @@ const WindowManager = new Lang.Class({
},
_shouldAnimateActor: function(actor, types) {
if (this._removeEffect(this._skippedActors, actor))
return false;
if (!this._shouldAnimate())
return false;
@@ -1358,13 +1337,9 @@ const WindowManager = new Lang.Class({
_hasAttachedDialogs: function(window, ignoreWindow) {
var count = 0;
window.foreach_transient(function(win) {
if (win != ignoreWindow &&
win.is_attached_dialog() &&
win.get_transient_for() == window) {
if (win != ignoreWindow && win.is_attached_dialog())
count++;
return false;
}
return true;
return false;
});
return count != 0;
},
@@ -1392,14 +1367,11 @@ const WindowManager = new Lang.Class({
let dimmer = getWindowDimmer(actor);
if (!dimmer)
return;
if (this._shouldAnimate())
Tweener.addTween(dimmer,
{ dimFactor: 1.0,
time: DIM_TIME,
transition: 'linear'
});
else
dimmer.dimFactor = 1.0;
Tweener.addTween(dimmer,
{ dimFactor: 1.0,
time: DIM_TIME,
transition: 'linear'
});
},
_undimWindow: function(window) {
@@ -1409,13 +1381,10 @@ const WindowManager = new Lang.Class({
let dimmer = getWindowDimmer(actor);
if (!dimmer)
return;
if (this._shouldAnimate())
Tweener.addTween(dimmer,
{ dimFactor: 0.0,
time: UNDIM_TIME,
transition: 'linear' });
else
dimmer.dimFactor = 0.0;
Tweener.addTween(dimmer,
{ dimFactor: 0.0,
time: UNDIM_TIME,
transition: 'linear' });
},
_mapWindow : function(shellwm, actor) {
@@ -1433,14 +1402,6 @@ const WindowManager = new Lang.Class({
actor._windowType = type;
}));
actor.meta_window.connect('unmanaged', Lang.bind(this, function(window) {
let parent = window.get_transient_for();
if (parent)
this._checkDimming(parent);
}));
if (actor.meta_window.is_attached_dialog())
this._checkDimming(actor.get_meta_window().get_transient_for());
let types = [Meta.WindowType.NORMAL,
Meta.WindowType.DIALOG,
@@ -1450,6 +1411,9 @@ const WindowManager = new Lang.Class({
return;
}
if (actor.meta_window.is_attached_dialog())
this._checkDimming(actor.get_meta_window().get_transient_for());
switch (actor._windowType) {
case Meta.WindowType.NORMAL:
actor.set_pivot_point(0.5, 1.0);
@@ -1532,9 +1496,6 @@ const WindowManager = new Lang.Class({
});
}
if (window.is_attached_dialog())
this._checkDimming(window.get_transient_for(), window);
let types = [Meta.WindowType.NORMAL,
Meta.WindowType.DIALOG,
Meta.WindowType.MODAL_DIALOG];
@@ -1569,6 +1530,7 @@ const WindowManager = new Lang.Class({
if (window.is_attached_dialog()) {
let parent = window.get_transient_for();
this._checkDimming(parent, window);
actor._parentDestroyId = parent.connect('unmanaged', Lang.bind(this, function () {
Tweener.removeTweens(actor);
this._destroyWindowDone(shellwm, actor);
@@ -1774,37 +1736,23 @@ const WindowManager = new Lang.Class({
this._windowMenuManager.showWindowMenuForWindow(window, menu, rect);
},
_startSwitcher: function(display, screen, window, binding) {
let constructor = null;
switch (binding.get_name()) {
case 'switch-applications':
case 'switch-applications-backward':
case 'switch-group':
case 'switch-group-backward':
constructor = AltTab.AppSwitcherPopup;
break;
case 'switch-windows':
case 'switch-windows-backward':
constructor = AltTab.WindowSwitcherPopup;
break;
case 'cycle-windows':
case 'cycle-windows-backward':
constructor = AltTab.WindowCyclerPopup;
break;
case 'cycle-group':
case 'cycle-group-backward':
constructor = AltTab.GroupCyclerPopup;
break;
}
if (!constructor)
return;
_startAppSwitcher : function(display, screen, window, binding) {
/* prevent a corner case where both popups show up at once */
if (this._workspaceSwitcherPopup != null)
this._workspaceSwitcherPopup.destroy();
let tabPopup = new constructor();
let tabPopup = new AltTab.AppSwitcherPopup();
if (!tabPopup.show(binding.is_reversed(), binding.get_name(), binding.get_mask()))
tabPopup.destroy();
},
_startWindowSwitcher : function(display, screen, window, binding) {
/* prevent a corner case where both popups show up at once */
if (this._workspaceSwitcherPopup != null)
this._workspaceSwitcherPopup.destroy();
let tabPopup = new AltTab.WindowSwitcherPopup();
if (!tabPopup.show(binding.is_reversed(), binding.get_name(), binding.get_mask()))
tabPopup.destroy();

View File

@@ -361,9 +361,6 @@ const WindowClone = new Lang.Class({
// a long-press canceled when the pointer movement
// exceeds dnd-drag-threshold to manually start the drag
if (state == Clutter.LongPressState.CANCEL) {
let event = Clutter.get_current_event();
this._dragTouchSequence = event.get_event_sequence();
// A click cancels a long-press before any click handler is
// run - make sure to not start a drag in that case
Meta.later_add(Meta.LaterType.BEFORE_REDRAW, Lang.bind(this,
@@ -372,7 +369,7 @@ const WindowClone = new Lang.Class({
return;
let [x, y] = action.get_coords();
action.release();
this._draggable.startDrag(x, y, global.get_current_time(), this._dragTouchSequence);
this._draggable.startDrag(x, y, global.get_current_time());
}));
}
return true;

View File

@@ -19,7 +19,8 @@ const WorkspaceSwitcherPopup = new Lang.Class({
Name: 'WorkspaceSwitcherPopup',
_init : function() {
this.actor = new St.Widget({ x: 0,
this.actor = new St.Widget({ reactive: true,
x: 0,
y: 0,
width: global.screen_width,
height: global.screen_height,

View File

@@ -45,11 +45,11 @@ const PrimaryActorLayout = new Lang.Class({
this.primaryActor = primaryActor;
},
vfunc_get_preferred_width: function(container, forHeight) {
vfunc_get_preferred_width: function(forHeight) {
return this.primaryActor.get_preferred_width(forHeight);
},
vfunc_get_preferred_height: function(container, forWidth) {
vfunc_get_preferred_height: function(forWidth) {
return this.primaryActor.get_preferred_height(forWidth);
},
});
@@ -80,8 +80,6 @@ const WindowClone = new Lang.Class({
this.actor.connect('button-release-event',
Lang.bind(this, this._onButtonRelease));
this.actor.connect('touch-event',
Lang.bind(this, this._onTouchEvent));
this.actor.connect('destroy', Lang.bind(this, this._onDestroy));
@@ -202,15 +200,6 @@ const WindowClone = new Lang.Class({
return Clutter.EVENT_STOP;
},
_onTouchEvent : function (actor, event) {
if (event.type() != Clutter.EventType.TOUCH_END ||
!global.display.is_pointer_emulating_sequence(event.get_event_sequence()))
return Clutter.EVENT_PROPAGATE;
this.emit('selected', event.get_time());
return Clutter.EVENT_STOP;
},
_onDragBegin : function (draggable, time) {
this.inDrag = true;
this.emit('drag-begin');
@@ -653,7 +642,6 @@ const ThumbnailsBox = new Lang.Class({
this.actor.connect('button-press-event', function() { return Clutter.EVENT_STOP; });
this.actor.connect('button-release-event', Lang.bind(this, this._onButtonRelease));
this.actor.connect('touch-event', Lang.bind(this, this._onTouchEvent));
Main.overview.connect('showing',
Lang.bind(this, this._createThumbnails));
@@ -684,31 +672,18 @@ const ThumbnailsBox = new Lang.Class({
global.screen.n_workspaces > 1;
},
_activateThumbnailAtPoint: function (stageX, stageY, time) {
_onButtonRelease: function(actor, event) {
let [stageX, stageY] = event.get_coords();
let [r, x, y] = this.actor.transform_stage_point(stageX, stageY);
for (let i = 0; i < this._thumbnails.length; i++) {
let thumbnail = this._thumbnails[i]
let [w, h] = thumbnail.actor.get_transformed_size();
if (y >= thumbnail.actor.y && y <= thumbnail.actor.y + h) {
thumbnail.activate(time);
thumbnail.activate(event.get_time());
break;
}
}
},
_onButtonRelease: function(actor, event) {
let [stageX, stageY] = event.get_coords();
this._activateThumbnailAtPoint(stageX, stageY, event.get_time());
return Clutter.EVENT_STOP;
},
_onTouchEvent: function (actor, event) {
if (event.type() == Clutter.EventType.TOUCH_END &&
global.display.is_pointer_emulating_sequence(event.get_event_sequence())) {
let [stageX, stageY] = event.get_coords();
this._activateThumbnailAtPoint(stageX, stageY, event.get_time());
}
return Clutter.EVENT_STOP;
},

View File

@@ -103,7 +103,7 @@ const WorkspacesView = new Lang.Class({
page_increment: 1,
page_size: 1,
step_increment: 0,
upper: global.screen.n_workspaces });
upper: 0 });
this.scrollAdjustment.connect('notify::value',
Lang.bind(this, this._onScroll));
@@ -374,10 +374,6 @@ const ExtraWorkspaceView = new Lang.Class({
this._workspace.setActualGeometry(this._actualGeometry);
},
getActiveWorkspace: function() {
return this._workspace;
},
animateToOverview: function(animationType) {
if (animationType == AnimationType.ZOOM)
this._workspace.zoomToOverview();
@@ -425,10 +421,8 @@ const WorkspacesDisplay = new Lang.Class({
// Only switch to the workspace when there's no application
// windows open. The problem is that it's too easy to miss
// an app window and get the wrong one focused.
let event = Clutter.get_current_event();
let index = this._getMonitorIndexForEvent(event);
if ((action.get_button() == 1 || action.get_button() == 0) &&
this._workspacesViews[index].getActiveWorkspace().isEmpty())
if (action.get_button() == 1 &&
this._getPrimaryView().getActiveWorkspace().isEmpty())
Main.overview.hide();
}));
Main.overview.addAction(clickAction);
@@ -437,18 +431,11 @@ const WorkspacesDisplay = new Lang.Class({
let panAction = new Clutter.PanAction({ threshold_trigger_edge: Clutter.GestureTriggerEdge.AFTER });
panAction.connect('pan', Lang.bind(this, this._onPan));
panAction.connect('gesture-begin', Lang.bind(this, function() {
if (this._workspacesOnlyOnPrimary) {
let event = Clutter.get_current_event();
if (this._getMonitorIndexForEvent(event) != this._primaryIndex)
return false;
}
for (let i = 0; i < this._workspacesViews.length; i++)
this._workspacesViews[i].startSwipeScroll();
return true;
}));
panAction.connect('gesture-cancel', Lang.bind(this, function() {
clickAction.release();
for (let i = 0; i < this._workspacesViews.length; i++)
this._workspacesViews[i].endSwipeScroll();
}));
@@ -594,12 +581,6 @@ const WorkspacesDisplay = new Lang.Class({
}
},
_getMonitorIndexForEvent: function(event) {
let [x, y] = event.get_coords();
let rect = new Meta.Rectangle({ x: x, y: y, width: 1, height: 1 });
return global.screen.get_monitor_index_for_rect(rect);
},
_getPrimaryView: function() {
if (!this._workspacesViews.length)
return null;
@@ -680,11 +661,6 @@ const WorkspacesDisplay = new Lang.Class({
_onScrollEvent: function(actor, event) {
if (!this.actor.mapped)
return Clutter.EVENT_PROPAGATE;
if (this._workspacesOnlyOnPrimary &&
this._getMonitorIndexForEvent(event) != this._primaryIndex)
return Clutter.EVENT_PROPAGATE;
let activeWs = global.screen.get_active_workspace();
let ws;
switch (event.get_scroll_direction()) {

View File

@@ -140,7 +140,7 @@
<para>
<filename>/usr/share/gnome-session/sessions/gnome.session</filename>,
<filename>/usr/share/applications/org.gnome.Shell.desktop</filename>.</para>
<filename>/usr/share/applications/gnome-shell.desktop</filename>.</para>
</refsect1>
<refsect1>

View File

@@ -24,11 +24,11 @@ fi
fr
fur
ga
gd
gl
gu
he
hi
hr
hu
ia
id

View File

@@ -1,68 +0,0 @@
# Makefile variables for PO directory in any package using GNU gettext.
# Usually the message domain is the same as the package name.
DOMAIN = $(PACKAGE)
# These two variables depend on the location of this directory.
subdir = po
top_builddir = ..
# These options get passed to xgettext.
XGETTEXT_OPTIONS = --from-code=UTF-8 --keyword=_ --keyword=N_ \
--keyword=C_:1c,2 --keyword=NC_:1c,2 \
--keyword=g_dngettext:2,3 --add-comments \
--flag=g_dngettext:2:pass-c-format \
--flag=g_strdup_printf:1:c-format \
--flag=g_string_printf:2:c-format \
--flag=g_string_append_printf:2:c-format \
--flag=g_error_new:3:c-format \
--flag=g_set_error:4:c-format \
--flag=g_markup_printf_escaped:1:c-format \
--flag=g_log:3:c-format \
--flag=g_print:1:c-format \
--flag=g_printerr:1:c-format \
--flag=g_printf:1:c-format \
--flag=g_fprintf:2:c-format \
--flag=g_sprintf:2:c-format \
--flag=g_snprintf:3:c-format
# This is the copyright holder that gets inserted into the header of the
# $(DOMAIN).pot file. Set this to the copyright holder of the surrounding
# package. (Note that the msgstr strings, extracted from the package's
# sources, belong to the copyright holder of the package.) Translators are
# expected to transfer the copyright for their translations to this person
# or entity, or to disclaim their copyright. The empty string stands for
# the public domain; in this case the translators are expected to disclaim
# their copyright.
COPYRIGHT_HOLDER = Translation copyright holder
# This is the email address or URL to which the translators shall report
# bugs in the untranslated strings:
# - Strings which are not entire sentences, see the maintainer guidelines
# in the GNU gettext documentation, section 'Preparing Strings'.
# - Strings which use unclear terms or require additional context to be
# understood.
# - Strings which make invalid assumptions about notation of date, time or
# money.
# - Pluralisation problems.
# - Incorrect English spelling.
# - Incorrect formatting.
# It can be your email address, or a mailing list address where translators
# can write to without being subscribed, or the URL of a web page through
# which the translators can contact you.
MSGID_BUGS_ADDRESS = http://bugzilla.gnome.org/enter_bug.cgi?product=gnome-shell&keywords=I18N+L10N&component=general
# This is the list of locale categories, beyond LC_MESSAGES, for which the
# message catalogs shall be used. It is usually empty.
EXTRA_LOCALE_CATEGORIES =
# Ignore the timestamp of the .pot file, as git clones do not have
# deterministic timestamps, and .po files are updated by translators
# (only) in GNOME projects.
PO_DEPENDS_ON_POT = no
# This tells whether or not to forcibly update $(DOMAIN).pot and
# regenerate PO files on "make dist". Possible values are "yes" and
# "no". Set this to no if the POT file and PO files are maintained
# externally.
DIST_DEPENDS_ON_UPDATE_PO = no

View File

@@ -1,20 +1,20 @@
# List of source files containing translatable strings.
# Please keep this file sorted alphabetically.
data/50-gnome-shell-system.xml
[encoding: UTF-8]
data/50-gnome-shell-system.xml.in
data/gnome-shell.desktop.in.in
data/gnome-shell-extension-prefs.desktop.in.in
data/org.gnome.Shell.desktop.in.in
data/org.gnome.shell.gschema.xml.in
data/org.gnome.Shell.PortalHelper.desktop.in.in
data/gnome-shell-wayland.desktop.in.in
data/org.gnome.shell.gschema.xml.in.in
data/org.gnome.Shell.PortalHelper.desktop.in
js/extensionPrefs/main.js
js/gdm/authPrompt.js
js/gdm/loginDialog.js
js/gdm/util.js
js/misc/util.js
js/portalHelper/main.js
js/ui/accessDialog.js
js/ui/appDisplay.js
js/ui/appFavorites.js
js/ui/audioDeviceSelection.js
js/ui/backgroundMenu.js
js/ui/calendar.js
js/ui/components/automountManager.js
@@ -33,9 +33,7 @@ js/ui/keyboard.js
js/ui/legacyTray.js
js/ui/lookingGlass.js
js/ui/main.js
js/ui/messageList.js
js/ui/messageTray.js
js/ui/mpris.js
js/ui/notificationDaemon.js
js/ui/overviewControls.js
js/ui/overview.js
@@ -61,7 +59,7 @@ js/ui/viewSelector.js
js/ui/windowAttentionHandler.js
js/ui/windowManager.js
js/ui/windowMenu.js
src/calendar-server/evolution-calendar.desktop.in
src/calendar-server/evolution-calendar.desktop.in.in
# Please do not remove this file from POTFILES.in. Run "git submodule init && git submodule update" to get it.
src/gvc/gvc-mixer-control.c
src/main.c

4
po/POTFILES.skip Normal file
View File

@@ -0,0 +1,4 @@
data/org.gnome.shell.evolution.calendar.gschema.xml.in
src/calendar-server/evolution-calendar.desktop.in
# Meh, autofools :-(
sub/src/calendar-server/evolution-calendar.desktop.in

1403
po/af.po

File diff suppressed because it is too large Load Diff

907
po/ar.po

File diff suppressed because it is too large Load Diff

View File

@@ -13,7 +13,7 @@ msgstr ""
"PO-Revision-Date: 2014-09-15 14:59+0530\n"
"Last-Translator: Nilamdyuti Goswami <ngoswami@redhat.com>\n"
"Language-Team: Assamese <kde-i18n-doc@kde.org>\n"
"Language: as\n"
"Language: as_IN\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"

719
po/bg.po

File diff suppressed because it is too large Load Diff

View File

@@ -7,7 +7,6 @@ msgstr ""
"PO-Revision-Date: 2011-04-04 11:04+0600\n"
"Last-Translator: Israt Jahan <israt@ankur.org.bd>\n"
"Language-Team: Bengali <ankur-bd-l10n@googlegroups.com>\n"
"Language: bn\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"

View File

@@ -11,7 +11,7 @@ msgstr ""
"PO-Revision-Date: 2014-12-30 16:45+0000\n"
"Last-Translator: \n"
"Language-Team: American English <kde-i18n-doc@kde.org>\n"
"Language: bn_IN\n"
"Language: en_US\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"

925
po/ca.po

File diff suppressed because it is too large Load Diff

View File

@@ -14,7 +14,7 @@ msgstr ""
"PO-Revision-Date: 2014-09-14 23:32+0200\n"
"Last-Translator: Gil Forcada <gilforcada@guifi.net>\n"
"Language-Team: Catalan <tradgnome@softcatala.org>\n"
"Language: ca@valencia\n"
"Language: ca-XV\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bits\n"

928
po/cs.po

File diff suppressed because it is too large Load Diff

912
po/da.po

File diff suppressed because it is too large Load Diff

1316
po/de.po

File diff suppressed because it is too large Load Diff

927
po/el.po

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

435
po/eo.po

File diff suppressed because it is too large Load Diff

946
po/es.po

File diff suppressed because it is too large Load Diff

915
po/eu.po

File diff suppressed because it is too large Load Diff

1254
po/fa.po

File diff suppressed because it is too large Load Diff

928
po/fi.po

File diff suppressed because it is too large Load Diff

890
po/fr.po

File diff suppressed because it is too large Load Diff

2089
po/fur.po

File diff suppressed because it is too large Load Diff

View File

@@ -715,7 +715,7 @@ msgstr "Tá brón orm, theip sé sin. Bain triail eile as, le do thoil."
#. Translators: this is the other person changing their old IM name to their new
#. IM name.
#: ../js/ui/components/telepathyClient.js:759
#, fuzzy, javascript-format
#, javascript-format
msgid "%s is now known as %s"
msgstr "Tugtar %2$s ar %1$s anois"

915
po/gl.po

File diff suppressed because it is too large Load Diff

View File

@@ -13,7 +13,7 @@ msgstr ""
"PO-Revision-Date: 2014-10-01 15:51+0530\n"
"Last-Translator: \n"
"Language-Team: American English <kde-i18n-doc@kde.org>\n"
"Language: gu\n"
"Language: \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"

952
po/he.po

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

1199
po/hu.po

File diff suppressed because it is too large Load Diff

892
po/id.po

File diff suppressed because it is too large Load Diff

429
po/is.po
View File

@@ -1,14 +1,14 @@
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
# This file is distributed under the same license as the PACKAGE package.
#
# Sveinn í Felli <sv1@fellsnet.is>, 2015, 2016.
# Sveinn í Felli <sv1@fellsnet.is>, 2015.
msgid ""
msgstr ""
"Project-Id-Version: \n"
"Report-Msgid-Bugs-To: http://bugzilla.gnome.org/enter_bug.cgi?product=gnome-"
"shell&keywords=I18N+L10N&component=general\n"
"POT-Creation-Date: 2016-05-05 09:55+0000\n"
"PO-Revision-Date: 2016-05-14 21:09+0000\n"
"POT-Creation-Date: 2015-10-19 08:43+0000\n"
"PO-Revision-Date: 2015-10-20 14:23+0000\n"
"Last-Translator: Sveinn í Felli <sv1@fellsnet.is>\n"
"Language-Team: Icelandic <translation-team-is@lists.sourceforge.net>\n"
"Language: is\n"
@@ -42,6 +42,15 @@ msgstr "Birta öll forrit"
msgid "Open the application menu"
msgstr "Birta forritavalmynd"
#: ../data/gnome-shell.desktop.in.in.h:1
msgid "GNOME Shell"
msgstr "GNOME skel"
#: ../data/gnome-shell.desktop.in.in.h:2
#: ../data/gnome-shell-wayland.desktop.in.in.h:2
msgid "Window management and application launching"
msgstr "Gluggastjórnun og forritaræsing"
#: ../data/gnome-shell-extension-prefs.desktop.in.in.h:1
msgid "GNOME Shell Extension Preferences"
msgstr "Kjörstillingar GNOME Shell Extension skeljarviðbóta"
@@ -50,13 +59,9 @@ msgstr "Kjörstillingar GNOME Shell Extension skeljarviðbóta"
msgid "Configure GNOME Shell Extensions"
msgstr "Stilla GNOME Shell Extension skeljarviðbætur"
#: ../data/org.gnome.Shell.desktop.in.in.h:1
msgid "GNOME Shell"
msgstr "GNOME skel"
#: ../data/org.gnome.Shell.desktop.in.in.h:2
msgid "Window management and application launching"
msgstr "Gluggastjórnun og forritaræsing"
#: ../data/gnome-shell-wayland.desktop.in.in.h:1
msgid "GNOME Shell (wayland compositor)"
msgstr "GNOME skel (wayland skjásamsetning)"
#: ../data/org.gnome.shell.gschema.xml.in.in.h:1
msgid "Enable internal tools useful for developers and testers from Alt-F2"
@@ -142,139 +147,117 @@ msgid ""
msgstr ""
#: ../data/org.gnome.shell.gschema.xml.in.in.h:18
msgid ""
"Whether the default Bluetooth adapter had set up devices associated to it"
msgstr ""
#: ../data/org.gnome.shell.gschema.xml.in.in.h:19
msgid ""
"The shell will only show a Bluetooth menu item if a Bluetooth adapter is "
"powered, or if there were devices set up associated with the default "
"adapter. This will be reset if the default adapter is ever seen not to have "
"devices associated to it."
msgstr ""
#: ../data/org.gnome.shell.gschema.xml.in.in.h:20
msgid "Show the week date in the calendar"
msgstr "Sýna vikudag í dagatali"
#: ../data/org.gnome.shell.gschema.xml.in.in.h:21
#: ../data/org.gnome.shell.gschema.xml.in.in.h:19
msgid "If true, display the ISO week date in the calendar."
msgstr ""
"Ef merkt er við þetta sem satt þá mun ISO-vikunúmer vera sýnt í dagatalinu."
#: ../data/org.gnome.shell.gschema.xml.in.in.h:22
#: ../data/org.gnome.shell.gschema.xml.in.in.h:20
msgid "Keybinding to open the application menu"
msgstr "Lyklasamsetning til að opna forritavalmyndina"
msgstr ""
#: ../data/org.gnome.shell.gschema.xml.in.in.h:21
msgid "Keybinding to open the application menu."
msgstr ""
#: ../data/org.gnome.shell.gschema.xml.in.in.h:22
msgid "Keybinding to open the \"Show Applications\" view"
msgstr ""
#: ../data/org.gnome.shell.gschema.xml.in.in.h:23
msgid "Keybinding to open the application menu."
msgstr "Lyklasamsetning til að opna forritavalmyndina."
#: ../data/org.gnome.shell.gschema.xml.in.in.h:24
msgid "Keybinding to open the \"Show Applications\" view"
msgstr "Lyklasamsetning til að opna \"Birta forrit\" sýnina"
#: ../data/org.gnome.shell.gschema.xml.in.in.h:25
msgid ""
"Keybinding to open the \"Show Applications\" view of the Activities Overview."
msgstr ""
"Lyklasamsetning til að opna \"Birta forrit\" sýnina í virkniyfirlitinu."
#: ../data/org.gnome.shell.gschema.xml.in.in.h:24
msgid "Keybinding to open the overview"
msgstr ""
#: ../data/org.gnome.shell.gschema.xml.in.in.h:25
msgid "Keybinding to open the Activities Overview."
msgstr ""
#: ../data/org.gnome.shell.gschema.xml.in.in.h:26
msgid "Keybinding to open the overview"
msgstr "Lyklasamsetning til að opna yfirlitið"
msgid "Keybinding to toggle the visibility of the notification list"
msgstr ""
#: ../data/org.gnome.shell.gschema.xml.in.in.h:27
msgid "Keybinding to open the Activities Overview."
msgstr "Lyklasamsetning til að opna virkniyfirlitið."
msgid "Keybinding to toggle the visibility of the notification list."
msgstr ""
#: ../data/org.gnome.shell.gschema.xml.in.in.h:28
msgid "Keybinding to toggle the visibility of the notification list"
msgstr "Lyklasamsetning til að víxla sýnileika tilkynningalistans"
msgid "Keybinding to focus the active notification"
msgstr ""
#: ../data/org.gnome.shell.gschema.xml.in.in.h:29
msgid "Keybinding to toggle the visibility of the notification list."
msgstr "Lyklasamsetning til að víxla sýnileika tilkynningalistans."
msgid "Keybinding to focus the active notification."
msgstr ""
#: ../data/org.gnome.shell.gschema.xml.in.in.h:30
msgid "Keybinding to focus the active notification"
msgstr "Lyklasamsetning til að setja virkni á virka tilkynningu"
#: ../data/org.gnome.shell.gschema.xml.in.in.h:31
msgid "Keybinding to focus the active notification."
msgstr "Lyklasamsetning til að setja virkni á virka tilkynningu."
#: ../data/org.gnome.shell.gschema.xml.in.in.h:32
msgid ""
"Keybinding that pauses and resumes all running tweens, for debugging purposes"
msgstr ""
#: ../data/org.gnome.shell.gschema.xml.in.in.h:33
#: ../data/org.gnome.shell.gschema.xml.in.in.h:31
msgid "Which keyboard to use"
msgstr "Hvaða lyklaborð á að nota"
#: ../data/org.gnome.shell.gschema.xml.in.in.h:34
#: ../data/org.gnome.shell.gschema.xml.in.in.h:32
msgid "The type of keyboard to use."
msgstr "Tegund lyklaborðs sem á að nota."
#: ../data/org.gnome.shell.gschema.xml.in.in.h:35
#: ../data/org.gnome.shell.gschema.xml.in.in.h:33
msgid "Limit switcher to current workspace."
msgstr "Takmarka fletti við núverandi vinnusvæði."
msgstr ""
#: ../data/org.gnome.shell.gschema.xml.in.in.h:36
#: ../data/org.gnome.shell.gschema.xml.in.in.h:34
msgid ""
"If true, only applications that have windows on the current workspace are "
"shown in the switcher. Otherwise, all applications are included."
msgstr ""
"Ef þetta er satt, verða eingöngu birt forrit sem eru með glugga á núverandi "
"vinnusvæði í flettinum."
"Annars eru öll forrit höfð með."
#: ../data/org.gnome.shell.gschema.xml.in.in.h:37
#: ../data/org.gnome.shell.gschema.xml.in.in.h:35
msgid "The application icon mode."
msgstr "Táknmyndinahamur forrits."
msgstr ""
#: ../data/org.gnome.shell.gschema.xml.in.in.h:38
#: ../data/org.gnome.shell.gschema.xml.in.in.h:36
msgid ""
"Configures how the windows are shown in the switcher. Valid possibilities "
"are 'thumbnail-only' (shows a thumbnail of the window), 'app-icon-"
"only' (shows only the application icon) or 'both'."
msgstr ""
#: ../data/org.gnome.shell.gschema.xml.in.in.h:39
#: ../data/org.gnome.shell.gschema.xml.in.in.h:37
msgid ""
"If true, only windows from the current workspace are shown in the switcher. "
"Otherwise, all windows are included."
msgstr ""
"Ef þetta er satt, verða eingöngu birtir gluggar frá núverandi vinnusvæði í "
"flettinum."
"Annars eru allir gluggar hafðir með."
#: ../data/org.gnome.shell.gschema.xml.in.in.h:40
#: ../data/org.gnome.shell.gschema.xml.in.in.h:38
msgid "Attach modal dialog to the parent window"
msgstr "Festa kvaðningarglugga við yfirglugga"
msgstr ""
#: ../data/org.gnome.shell.gschema.xml.in.in.h:41
#: ../data/org.gnome.shell.gschema.xml.in.in.h:39
msgid ""
"This key overrides the key in org.gnome.mutter when running GNOME Shell."
msgstr ""
"Þetta hefur forgang fram yfir lykilinn í kjörstillingum org.gnome.mutter "
"þegar GNOME-skelin er keyrð."
#: ../data/org.gnome.shell.gschema.xml.in.in.h:40
msgid "Enable edge tiling when dropping windows on screen edges"
msgstr ""
#: ../data/org.gnome.shell.gschema.xml.in.in.h:41
msgid "Workspaces are managed dynamically"
msgstr ""
#: ../data/org.gnome.shell.gschema.xml.in.in.h:42
msgid "Enable edge tiling when dropping windows on screen edges"
msgstr "Virkja flísalögn við jaðra þegar gluggum er sleppt á skjájaðra"
#: ../data/org.gnome.shell.gschema.xml.in.in.h:43
msgid "Workspaces are managed dynamically"
msgstr "Vinnusvæðum er stýrt eftir þörfum"
#: ../data/org.gnome.shell.gschema.xml.in.in.h:44
msgid "Workspaces only on primary monitor"
msgstr "Vinnusvæði einungis á aðalskjá"
#: ../data/org.gnome.shell.gschema.xml.in.in.h:45
#: ../data/org.gnome.shell.gschema.xml.in.in.h:43
msgid "Delay focus changes in mouse mode until the pointer stops moving"
msgstr ""
@@ -282,52 +265,51 @@ msgstr ""
msgid "Network Login"
msgstr "Innskráning á neti"
#: ../js/extensionPrefs/main.js:117
#: ../js/extensionPrefs/main.js:122
#, javascript-format
msgid "There was an error loading the preferences dialog for %s:"
msgstr "Villa kom upp við ræsingu kjörstillingaglugga fyrir %s:"
#: ../js/extensionPrefs/main.js:149
#: ../js/extensionPrefs/main.js:154
msgid "GNOME Shell Extensions"
msgstr "GNOME Shell Extension skeljarviðbætur"
#: ../js/gdm/authPrompt.js:147 ../js/ui/audioDeviceSelection.js:71
#: ../js/ui/components/networkAgent.js:145
#: ../js/gdm/authPrompt.js:147 ../js/ui/components/networkAgent.js:145
#: ../js/ui/components/polkitAgent.js:179 ../js/ui/endSessionDialog.js:452
#: ../js/ui/extensionDownloader.js:195 ../js/ui/shellMountOperation.js:399
#: ../js/ui/status/network.js:916
msgid "Cancel"
msgstr "Hætta við"
#: ../js/gdm/authPrompt.js:169 ../js/gdm/authPrompt.js:216
#: ../js/gdm/authPrompt.js:448
#: ../js/gdm/authPrompt.js:169 ../js/gdm/authPrompt.js:215
#: ../js/gdm/authPrompt.js:447
msgid "Next"
msgstr "Næsta"
#: ../js/gdm/authPrompt.js:212 ../js/ui/shellMountOperation.js:403
#: ../js/gdm/authPrompt.js:211 ../js/ui/shellMountOperation.js:403
#: ../js/ui/unlockDialog.js:59
msgid "Unlock"
msgstr "Aflæsa"
#: ../js/gdm/authPrompt.js:214
#: ../js/gdm/authPrompt.js:213
msgctxt "button"
msgid "Sign In"
msgstr "Skrá inn"
#: ../js/gdm/loginDialog.js:285
#: ../js/gdm/loginDialog.js:281
msgid "Choose Session"
msgstr "Veldu setu"
#. 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:435
#: ../js/gdm/loginDialog.js:431
msgid "Not listed?"
msgstr "Ekki á listanum?"
#. Translators: this message is shown below the username entry field
#. to clue the user in on how to login to the local network realm
#: ../js/gdm/loginDialog.js:854
#: ../js/gdm/loginDialog.js:850
#, javascript-format
msgid "(e.g., user or %s)"
msgstr "(t.d., notandi eða %s)"
@@ -335,12 +317,12 @@ msgstr "(t.d., notandi eða %s)"
#. 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:859 ../js/ui/components/networkAgent.js:271
#: ../js/gdm/loginDialog.js:855 ../js/ui/components/networkAgent.js:271
#: ../js/ui/components/networkAgent.js:289
msgid "Username: "
msgstr "Notandanafn:"
#: ../js/gdm/loginDialog.js:1196
#: ../js/gdm/loginDialog.js:1184
msgid "Login Window"
msgstr "Innskráningargluggi"
@@ -476,37 +458,16 @@ msgstr "Bæta í Eftirlæti"
msgid "Show Details"
msgstr "Sýna ítarlegri upplýsingar"
#: ../js/ui/appFavorites.js:134
#: ../js/ui/appFavorites.js:132
#, javascript-format
msgid "%s has been added to your favorites."
msgstr "%s var bætt við sem eftirlætisforrit."
#: ../js/ui/appFavorites.js:168
#: ../js/ui/appFavorites.js:166
#, javascript-format
msgid "%s has been removed from your favorites."
msgstr "%s var fjarlægt úr eftirlætisforritum."
#: ../js/ui/audioDeviceSelection.js:59
msgid "Select Audio Device"
msgstr "Veldu hljóðtæki"
#: ../js/ui/audioDeviceSelection.js:69
#| msgid "Settings"
msgid "Sound Settings"
msgstr "Hljóðstillingar"
#: ../js/ui/audioDeviceSelection.js:78
msgid "Headphones"
msgstr "Heyrnartól"
#: ../js/ui/audioDeviceSelection.js:80
msgid "Headset"
msgstr "Heyrnartól með hljóðnema"
#: ../js/ui/audioDeviceSelection.js:82 ../js/ui/status/volume.js:213
msgid "Microphone"
msgstr "Hljóðnemi"
#: ../js/ui/backgroundMenu.js:19
msgid "Change Background…"
msgstr "Breyta _bakgrunni skjáborðs…"
@@ -515,12 +476,12 @@ msgstr "Breyta _bakgrunni skjáborðs…"
msgid "Display Settings"
msgstr "Birtingarstillingar"
#: ../js/ui/backgroundMenu.js:22 ../js/ui/status/system.js:371
#: ../js/ui/backgroundMenu.js:22 ../js/ui/status/system.js:366
msgid "Settings"
msgstr "Stillingar"
#. Translators: Enter 0-6 (Sunday-Saturday) for non-work days. Examples: "0" (Sunday) "6" (Saturday) "06" (Sunday and Saturday).
#: ../js/ui/calendar.js:47
#: ../js/ui/calendar.js:55
msgctxt "calendar-no-work"
msgid "06"
msgstr "06"
@@ -530,96 +491,94 @@ msgstr "06"
#. * NOTE: These grid abbreviations are always shown together
#. * and in order, e.g. "S M T W T F S".
#.
#: ../js/ui/calendar.js:76
#: ../js/ui/calendar.js:84
msgctxt "grid sunday"
msgid "S"
msgstr "Su"
#. Translators: Calendar grid abbreviation for Monday
#: ../js/ui/calendar.js:78
#: ../js/ui/calendar.js:86
msgctxt "grid monday"
msgid "M"
msgstr "Má"
#. Translators: Calendar grid abbreviation for Tuesday
#: ../js/ui/calendar.js:80
#: ../js/ui/calendar.js:88
msgctxt "grid tuesday"
msgid "T"
msgstr "Þr"
#. Translators: Calendar grid abbreviation for Wednesday
#: ../js/ui/calendar.js:82
#: ../js/ui/calendar.js:90
msgctxt "grid wednesday"
msgid "W"
msgstr "Mi"
#. Translators: Calendar grid abbreviation for Thursday
#: ../js/ui/calendar.js:84
#: ../js/ui/calendar.js:92
msgctxt "grid thursday"
msgid "T"
msgstr "Fi"
#. Translators: Calendar grid abbreviation for Friday
#: ../js/ui/calendar.js:86
#: ../js/ui/calendar.js:94
msgctxt "grid friday"
msgid "F"
msgstr "Fö"
#. Translators: Calendar grid abbreviation for Saturday
#: ../js/ui/calendar.js:88
#: ../js/ui/calendar.js:96
msgctxt "grid saturday"
msgid "S"
msgstr "La"
#: ../js/ui/calendar.js:416
#: ../js/ui/calendar.js:566
msgid "Previous month"
msgstr "Fyrri mánuður"
#: ../js/ui/calendar.js:426
#: ../js/ui/calendar.js:576
msgid "Next month"
msgstr "Næsti mánuður"
#: ../js/ui/calendar.js:579
#, no-javascript-format
msgctxt "date day number format"
msgid "%d"
msgstr "%d"
#: ../js/ui/calendar.js:634
#: ../js/ui/calendar.js:783
msgid "Week %V"
msgstr "Vika %V"
#. Translators: Shown in calendar event list for all day events
#. * Keep it short, best if you can use less then 10 characters
#.
#: ../js/ui/calendar.js:695
#: ../js/ui/calendar.js:1188
msgctxt "event list time"
msgid "All Day"
msgstr "Allan daginn"
#: ../js/ui/calendar.js:821
#: ../js/ui/calendar.js:1295
msgid "Clear section"
msgstr "Hreinsa kafla"
#: ../js/ui/calendar.js:1522
msgid "Events"
msgstr "Atburðir"
#: ../js/ui/calendar.js:830
#: ../js/ui/calendar.js:1531
msgctxt "calendar heading"
msgid "%A, %B %d"
msgstr "%A, %B %d"
#: ../js/ui/calendar.js:834
#: ../js/ui/calendar.js:1535
msgctxt "calendar heading"
msgid "%A, %B %d, %Y"
msgstr "%A, %B %d, %Y"
#: ../js/ui/calendar.js:919
#: ../js/ui/calendar.js:1620
msgid "Notifications"
msgstr "Tilkynningar"
#: ../js/ui/calendar.js:1070
#: ../js/ui/calendar.js:1771
msgid "No Notifications"
msgstr "Engar tilkynningar"
#: ../js/ui/calendar.js:1073
#: ../js/ui/calendar.js:1774
msgid "No Events"
msgstr "Engir atburðir"
@@ -631,7 +590,7 @@ msgstr "Utanáliggjandi drif tengt"
msgid "External drive disconnected"
msgstr "Utanáliggjandi drif aftengt"
#: ../js/ui/components/autorunManager.js:355
#: ../js/ui/components/autorunManager.js:351
#, javascript-format
msgid "Open with %s"
msgstr "Opna með %s"
@@ -758,7 +717,7 @@ msgstr "Æ, þetta virkaði ekki. Endilega reyndu aftur."
#. Translators: this is the other person changing their old IM name to their new
#. IM name.
#: ../js/ui/components/telepathyClient.js:760
#: ../js/ui/components/telepathyClient.js:759
#, javascript-format
msgid "%s is now known as %s"
msgstr "%s er nú þekkt(ur) sem %s"
@@ -944,11 +903,11 @@ msgid "Keyboard"
msgstr "Lyklaborð"
#. translators: 'Hide' is a verb
#: ../js/ui/legacyTray.js:65
#: ../js/ui/legacyTray.js:66
msgid "Hide tray"
msgstr "Fela kerfisbakka"
#: ../js/ui/legacyTray.js:106
#: ../js/ui/legacyTray.js:107
msgid "Status Icons"
msgstr "Táknmyndir fyrir stöðu"
@@ -976,7 +935,7 @@ msgstr "Virkt"
#. translators:
#. * The device has been disabled
#: ../js/ui/lookingGlass.js:719 ../src/gvc/gvc-mixer-control.c:1866
#: ../js/ui/lookingGlass.js:719 ../src/gvc/gvc-mixer-control.c:1828
msgid "Disabled"
msgstr "Óvirkt"
@@ -1000,29 +959,10 @@ msgstr "Skoða frumtexta"
msgid "Web Page"
msgstr "Vefsíða"
#: ../js/ui/messageList.js:543
msgid "Clear section"
msgstr "Hreinsa kafla"
#: ../js/ui/messageTray.js:1486
msgid "System Information"
msgstr "Kerfisupplýsingar"
#: ../js/ui/mpris.js:194
#| msgid "Unknown reason"
msgid "Unknown artist"
msgstr "Óþekktur flytjandi"
#: ../js/ui/mpris.js:195
#| msgctxt "program"
#| msgid "Unknown"
msgid "Unknown title"
msgstr "Óþekktur titill"
#: ../js/ui/mpris.js:217
msgid "Media"
msgstr "Gagnamiðill"
#: ../js/ui/overview.js:84
msgid "Undo"
msgstr "Afturkalla"
@@ -1049,13 +989,13 @@ msgstr "Hætta"
msgid "Activities"
msgstr "Virkni"
#: ../js/ui/panel.js:695
#: ../js/ui/panel.js:693
#| msgid "System"
msgctxt "System menu in the top bar"
msgid "System"
msgstr "Kerfið"
msgstr "Kerfi"
#: ../js/ui/panel.js:807
#: ../js/ui/panel.js:805
msgid "Top Bar"
msgstr "Toppstika"
@@ -1068,15 +1008,15 @@ msgstr "Toppstika"
msgid "toggle-switch-us"
msgstr "toggle-switch-intl"
#: ../js/ui/runDialog.js:71
#: ../js/ui/runDialog.js:70
msgid "Enter a Command"
msgstr "Settu inn skipun"
#: ../js/ui/runDialog.js:111 ../js/ui/windowMenu.js:162
#: ../js/ui/runDialog.js:110 ../js/ui/windowMenu.js:162
msgid "Close"
msgstr "Loka"
#: ../js/ui/runDialog.js:282
#: ../js/ui/runDialog.js:281
msgid "Restarting…"
msgstr "Endurræsi…"
@@ -1100,7 +1040,7 @@ msgid_plural "%d new notifications"
msgstr[0] "%d ný skilaboð"
msgstr[1] "%d ný skilaboð"
#: ../js/ui/screenShield.js:432 ../js/ui/status/system.js:379
#: ../js/ui/screenShield.js:432 ../js/ui/status/system.js:374
msgid "Lock"
msgstr "Læsa"
@@ -1199,43 +1139,31 @@ msgstr "Mikil birtuskil"
msgid "Large Text"
msgstr "Stór texti"
#: ../js/ui/status/bluetooth.js:47
msgid "Bluetooth"
msgstr "Bluetooth"
#: ../js/ui/status/bluetooth.js:56
msgid "Bluetooth Settings"
msgstr "Stillingar Bluetooth"
#. Translators: this is the number of connected bluetooth devices
#: ../js/ui/status/bluetooth.js:136
#, javascript-format
#| msgid "Connected"
msgid "%d Connected"
msgid_plural "%d Connected"
msgstr[0] "%d tengt"
msgstr[1] "%d tengt"
#: ../js/ui/status/bluetooth.js:138
msgid "Off"
msgstr "Slökkt"
#: ../js/ui/status/bluetooth.js:140
#| msgid "In Use"
msgid "Not In Use"
msgstr "Ekki í notkun"
#: ../js/ui/status/bluetooth.js:142 ../js/ui/status/network.js:1279
msgid "Turn On"
msgstr "Kveikja á"
#: ../js/ui/status/bluetooth.js:142 ../js/ui/status/network.js:178
#: ../js/ui/status/bluetooth.js:51 ../js/ui/status/network.js:178
#: ../js/ui/status/network.js:353 ../js/ui/status/network.js:1279
#: ../js/ui/status/network.js:1394 ../js/ui/status/rfkill.js:90
#: ../js/ui/status/rfkill.js:117
msgid "Turn Off"
msgstr "Slökkva"
#: ../js/ui/status/bluetooth.js:54
msgid "Bluetooth Settings"
msgstr "Stillingar Bluetooth"
#. Translators: this is the number of connected bluetooth devices
#: ../js/ui/status/bluetooth.js:105
#, javascript-format
#| msgid "Connected"
msgid "%d Connected"
msgid_plural "%d Connected"
msgstr[0] "%d tengt"
msgstr[1] "%d tengd"
#: ../js/ui/status/bluetooth.js:107
#| msgid "In Use"
msgid "Not In Use"
msgstr "Ekki í notkun"
#: ../js/ui/status/brightness.js:44
msgid "Brightness"
msgstr "Birtustig"
@@ -1244,51 +1172,33 @@ msgstr "Birtustig"
msgid "Show Keyboard Layout"
msgstr "Birta lyklaborðsuppsetningu"
#: ../js/ui/status/location.js:107 ../js/ui/status/location.js:215
#: ../js/ui/status/location.js:71 ../js/ui/status/location.js:177
#| msgid "Location"
msgid "Location Enabled"
msgstr "Staðsetning virk"
#: ../js/ui/status/location.js:108 ../js/ui/status/location.js:216
#: ../js/ui/status/location.js:72 ../js/ui/status/location.js:178
msgid "Disable"
msgstr "Gera óvirkt"
#: ../js/ui/status/location.js:109
#: ../js/ui/status/location.js:73
msgid "Privacy Settings"
msgstr "Stillingar á friðhelgi"
#: ../js/ui/status/location.js:214
#: ../js/ui/status/location.js:176
#| msgid "Location"
msgid "Location In Use"
msgstr "Staðsetning í notkun"
#: ../js/ui/status/location.js:218
#: ../js/ui/status/location.js:180
#| msgid "Connection failed"
msgid "Location Disabled"
msgstr "Staðsetning óvirk"
#: ../js/ui/status/location.js:219
#: ../js/ui/status/location.js:181
msgid "Enable"
msgstr "Virkja"
#: ../js/ui/status/location.js:426
msgid "Deny Access"
msgstr "Hafna aðgangi"
#: ../js/ui/status/location.js:429
msgid "Grant Access"
msgstr "Veita aðgang"
#. Translators: %s is an application name
#: ../js/ui/status/location.js:435
#, javascript-format
msgid "Give %s access to your location?"
msgstr "Á að gefa %s aðgang að staðsetningunni þinni?"
#: ../js/ui/status/location.js:437
msgid "Location access can be changed at any time from the privacy settings."
msgstr ""
#: ../js/ui/status/network.js:101
msgid "<unknown>"
msgstr "<óþekkt>"
@@ -1434,6 +1344,10 @@ msgstr "Veldu netkerfi"
msgid "Wi-Fi Settings"
msgstr "Stillingar þráðlauss netkerfis"
#: ../js/ui/status/network.js:1279
msgid "Turn On"
msgstr "Kveikja á"
#. Translators: %s is a network identifier
#: ../js/ui/status/network.js:1296
#, javascript-format
@@ -1486,38 +1400,31 @@ msgstr "Tenging mistókst"
msgid "Activation of network connection failed"
msgstr "Mistókst að virkja nettengingu"
#: ../js/ui/status/power.js:61
#: ../js/ui/status/power.js:49
msgid "Power Settings"
msgstr "Orkustillingar"
#: ../js/ui/status/power.js:77
#: ../js/ui/status/power.js:65
msgid "Fully Charged"
msgstr "Full hleðsla"
#. 0 is reported when UPower does not have enough data
#. to estimate battery life
#: ../js/ui/status/power.js:84 ../js/ui/status/power.js:90
#: ../js/ui/status/power.js:72 ../js/ui/status/power.js:78
msgid "Estimating…"
msgstr "Reikna…"
#. Translators: this is <hours>:<minutes> Remaining (<percentage>)
#: ../js/ui/status/power.js:98
#: ../js/ui/status/power.js:86
#, javascript-format
#| msgid "%d%02d Remaining (%d%%)"
msgid "%d%02d Remaining (%d%%)"
msgid "%d%02d Remaining (%d%%)"
msgstr "%d%02d eftir (%d%%)"
#. Translators: this is <hours>:<minutes> Until Full (<percentage>)
#: ../js/ui/status/power.js:103
#: ../js/ui/status/power.js:91
#, javascript-format
#| msgid "%d%02d Until Full (%d%%)"
msgid "%d%02d Until Full (%d%%)"
msgstr "%d%02d þar til fullhlaðið (%d%%)"
#: ../js/ui/status/power.js:131 ../js/ui/status/power.js:133
#, javascript-format
msgid "%d%%"
msgstr "%d%%"
msgid "%d%02d Until Full (%d%%)"
msgstr "%d%02d þar til fullhlaðin (%d%%)"
#. The menu only appears when airplane mode is on, so just
#. statically build it as if it was on, rather than dynamically
@@ -1527,28 +1434,28 @@ msgstr "%d%%"
msgid "Airplane Mode On"
msgstr "Flugvélahamur virkur"
#: ../js/ui/status/system.js:348
#: ../js/ui/status/system.js:343
msgid "Switch User"
msgstr "Skipta um notanda"
#: ../js/ui/status/system.js:353
#: ../js/ui/status/system.js:348
msgid "Log Out"
msgstr "Skrá út"
#: ../js/ui/status/system.js:358
#: ../js/ui/status/system.js:353
#| msgid "Power Settings"
msgid "Account Settings"
msgstr "Stillingar aðgangs"
#: ../js/ui/status/system.js:375
#: ../js/ui/status/system.js:370
msgid "Orientation Lock"
msgstr "Stefnulás"
#: ../js/ui/status/system.js:383
#: ../js/ui/status/system.js:378
msgid "Suspend"
msgstr "Hvíla"
#: ../js/ui/status/system.js:386
#: ../js/ui/status/system.js:381
msgid "Power Off"
msgstr "Slökkva"
@@ -1560,6 +1467,10 @@ msgstr "Hljóðstyrkur breyttist"
msgid "Volume"
msgstr "Hljóðstyrkur"
#: ../js/ui/status/volume.js:213
msgid "Microphone"
msgstr "Hljóðnemi"
#: ../js/ui/unlockDialog.js:67
msgid "Log in as another user"
msgstr "Skrá inn sem annar notandi"
@@ -1682,7 +1593,7 @@ msgstr "Evolution dagatal"
#. translators:
#. * The number of sound outputs on a particular device
#: ../src/gvc/gvc-mixer-control.c:1873
#: ../src/gvc/gvc-mixer-control.c:1835
#, c-format
msgid "%u Output"
msgid_plural "%u Outputs"
@@ -1691,14 +1602,14 @@ msgstr[1] "%u úttök"
#. translators:
#. * The number of sound inputs on a particular device
#: ../src/gvc/gvc-mixer-control.c:1883
#: ../src/gvc/gvc-mixer-control.c:1845
#, c-format
msgid "%u Input"
msgid_plural "%u Inputs"
msgstr[0] "%u inntak"
msgstr[1] "%u inntök"
#: ../src/gvc/gvc-mixer-control.c:2738
#: ../src/gvc/gvc-mixer-control.c:2371
msgid "System Sounds"
msgstr "Kerfishljóð"
@@ -1728,26 +1639,29 @@ msgstr "Óþekkt"
msgid "Failed to launch “%s”"
msgstr "Mistókst að ræsa \"“%s”"
#: ../src/shell-keyring-prompt.c:730
#: ../src/shell-keyring-prompt.c:742
msgid "Passwords do not match."
msgstr "Lykilorðin stemma ekki"
#: ../src/shell-keyring-prompt.c:738
#: ../src/shell-keyring-prompt.c:750
msgid "Password cannot be blank"
msgstr "Lykilorðið getur ekki verið autt"
#: ../src/shell-polkit-authentication-agent.c:353
#: ../src/shell-polkit-authentication-agent.c:346
msgid "Authentication dialog was dismissed by the user"
msgstr "Notandi hafnaði auðkenningarglugga"
#~ msgid "GNOME Shell (wayland compositor)"
#~ msgstr "GNOME skel (wayland skjásamsetning)"
#~ msgid "Bluetooth"
#~ msgstr "Bluetooth"
#~ msgid "%d Connected Device"
#~ msgid_plural "%d Connected Devices"
#~ msgstr[0] "%d tengt tæki"
#~ msgstr[1] "%d tengd tæki"
#~ msgid "Off"
#~ msgstr "Slökkt"
#~ msgid "Authentication required"
#~ msgstr "Auðkenningar krafist"
@@ -1938,6 +1852,9 @@ msgstr "Notandi hafnaði auðkenningarglugga"
#~ msgid "View account"
#~ msgstr "Skoða aðgang"
#~ msgid "Unknown reason"
#~ msgstr "Óþekkt ástæða"
#~ msgid "Open Calendar"
#~ msgstr "Opna dagatal"

903
po/it.po

File diff suppressed because it is too large Load Diff

655
po/ja.po

File diff suppressed because it is too large Load Diff

923
po/kk.po

File diff suppressed because it is too large Load Diff

Some files were not shown because too many files have changed in this diff Show More