Compare commits
415 Commits
wip/screen
...
3.5.4
Author | SHA1 | Date | |
---|---|---|---|
edb96cde70 | |||
e06ecb8f0c | |||
2791d948e9 | |||
360e6e790a | |||
d0807c8276 | |||
75d0362cd8 | |||
4f7c554d8d | |||
8b81f23caf | |||
0098c2b7f7 | |||
f0e03b5e82 | |||
be2f1001a5 | |||
cf08b4d56a | |||
04074f883f | |||
14d3235f1a | |||
e00c1cbd20 | |||
3df3f0d9dc | |||
985db40547 | |||
c9fa0fdff0 | |||
fe69ea305b | |||
ff9088e42b | |||
f556cdf0ca | |||
c671ff74c6 | |||
04570ac783 | |||
6ab25cd791 | |||
a04350f7ce | |||
b7018de7e0 | |||
d212d57466 | |||
c4e7d8ed8c | |||
464813ecbb | |||
9812771dcd | |||
6f605598de | |||
85bc8ccccc | |||
e756c2dbce | |||
e82fe14f00 | |||
de65739c01 | |||
e1ec89a133 | |||
bdb3410d9d | |||
168e0b5a42 | |||
f906cfe5f6 | |||
9faac81a37 | |||
b90e7eb95c | |||
1e286e43ad | |||
539993b4f4 | |||
1363d30f79 | |||
3a48daaa64 | |||
d2b4a65e65 | |||
1ead290c23 | |||
6658660355 | |||
85ab019987 | |||
460cda2aa1 | |||
2d913578e1 | |||
34831796f6 | |||
8754b2767c | |||
04fb688f7d | |||
58dbd285fc | |||
cf6f149888 | |||
8d017ceaf1 | |||
02428019fa | |||
b4464929cb | |||
3ea22f8b0e | |||
9745e97e14 | |||
6c6e182ecc | |||
7973dd45b7 | |||
a1837dde68 | |||
4448b65a18 | |||
2231c23c4d | |||
f17fc43d6e | |||
f9dbe56785 | |||
8845a2170c | |||
a4b1ebd8c3 | |||
66adeef9bd | |||
20769f68a7 | |||
e92719b98d | |||
59246babea | |||
23e86d7dd5 | |||
c99e8eb29d | |||
7949397958 | |||
1d1359b58f | |||
8915bb4892 | |||
6a117ac12f | |||
67689f1a6d | |||
48b83f1ffd | |||
7da0f398a5 | |||
7e277fdd4a | |||
5d10d8566b | |||
a10295f584 | |||
46cf9faa11 | |||
971341bb53 | |||
2b2a235a49 | |||
970b9deeaa | |||
fd256b624c | |||
698fb64be9 | |||
9561f77b17 | |||
c3d3d346d4 | |||
e43fe98263 | |||
04dbf15d9b | |||
de72065a4a | |||
a1bb0ec738 | |||
1a33cd9584 | |||
00279dbd04 | |||
eb759cf22f | |||
ae16da4e81 | |||
965287e724 | |||
3d5312e8d2 | |||
bc91b7dcae | |||
4d77eb94ff | |||
1b8d03f945 | |||
de2dcfeb99 | |||
c7196a519f | |||
0d82ce5210 | |||
3ce9ad05b3 | |||
ab75faac74 | |||
9e25e13218 | |||
69e1503c6d | |||
7eaf231e56 | |||
a347a72091 | |||
560daec913 | |||
d9e968d863 | |||
556d5d181e | |||
4e4092f9e8 | |||
fd62aba71c | |||
ef0aa65774 | |||
6b5f9a647a | |||
01c07fbea1 | |||
81929c2a92 | |||
d9ff8e3122 | |||
0c4692ae58 | |||
df56ff4f09 | |||
96cdc9c4eb | |||
3b4ad5cd7d | |||
317c6b77f3 | |||
e5f5a2adaa | |||
594c3174ab | |||
5b7e4bb4a7 | |||
f7c0f826d4 | |||
66af7de6d6 | |||
d1815a36d0 | |||
61de3de909 | |||
36888a34d6 | |||
646435ee3e | |||
cbb8d5b0dc | |||
ebee01b355 | |||
0e3795b2f3 | |||
de73128d47 | |||
281b0a3e63 | |||
c414f9ac9d | |||
77242cfec0 | |||
8ebbba6eb8 | |||
0804cefbee | |||
2404d2935d | |||
e6f5e21b5d | |||
c303c6b5c1 | |||
f58e8f2a35 | |||
ededba0c6d | |||
e112fa92fe | |||
7524210d1f | |||
201dc05416 | |||
2b34978993 | |||
447246da74 | |||
1cf2bb6646 | |||
de1eafb564 | |||
22f0099a5d | |||
300eb87016 | |||
aa38b16368 | |||
266bfdf739 | |||
19ef6b0421 | |||
75570b7995 | |||
3290bfae68 | |||
0805d7a35f | |||
11278a0814 | |||
86de6f5861 | |||
498b023989 | |||
5265884af9 | |||
cdbe0bbf38 | |||
feef35a8ca | |||
3ff51da529 | |||
496e9f7b16 | |||
0b30dc29a5 | |||
15b4d29e70 | |||
9eee4b7687 | |||
196f6c241a | |||
c9296191a8 | |||
c7b4022283 | |||
a7ecc4cdd6 | |||
df5298d59c | |||
b79d17332e | |||
675572a41a | |||
0078fe9349 | |||
dc004f6eb7 | |||
07f1a05ab4 | |||
54292a99af | |||
f5933c8cb8 | |||
6700f86145 | |||
b31d22488e | |||
6382eeb8fd | |||
b07345a55c | |||
06febdce22 | |||
c31d9d5e3d | |||
cda8a545f1 | |||
f850e92524 | |||
cc9d53e038 | |||
7b048fc092 | |||
4ba4a501fd | |||
2b2cce6896 | |||
c1f51a7bf3 | |||
465556f0d8 | |||
db7ac5208a | |||
cfcd1bc014 | |||
e63f7e8779 | |||
7911154bad | |||
ec0730f3e5 | |||
76005f5adf | |||
94493cde35 | |||
a1f68720e5 | |||
022376dd56 | |||
934e5aacab | |||
35b142f23f | |||
41c3795a7b | |||
95d7099133 | |||
33dc9abb9b | |||
5e4edac14d | |||
cb5ae92986 | |||
ebbd295ebe | |||
65d23fb9a3 | |||
ad6d986172 | |||
985641cc2e | |||
de0a714081 | |||
3f942302d1 | |||
96396163cf | |||
0c736c4561 | |||
33ad9d1035 | |||
d57658d059 | |||
031206cf1f | |||
12c7cc278d | |||
9d3750b9b8 | |||
ba4b9f229e | |||
850fe98cbb | |||
8a9e3e0df2 | |||
a277569d31 | |||
7ed9516884 | |||
ecff2fa2b7 | |||
e49b94658c | |||
e4f1572a3a | |||
b5b13322d8 | |||
c25e7f3c41 | |||
f6a2c92bfa | |||
ed17418101 | |||
5264f39209 | |||
de69c719fb | |||
ab3173487d | |||
a3fcb8c284 | |||
ba92cfa064 | |||
6bee51ed33 | |||
122bca49ea | |||
19318a1eeb | |||
a7a46bbe1c | |||
3d26224180 | |||
940ddb104c | |||
5617f91281 | |||
a9a863aab4 | |||
ca26347dea | |||
41a14e808e | |||
6452501275 | |||
b61ada72cc | |||
ace42d845c | |||
850b6f28e5 | |||
3c81e9f0e7 | |||
e20ea19f34 | |||
ce041a3190 | |||
3a01aaf7fb | |||
ec4a2aae95 | |||
de8a66d4ce | |||
dc3d3acb3b | |||
48d6eb168f | |||
6190d6c962 | |||
76616dc98c | |||
82c2f5221d | |||
a3bbb7be14 | |||
9e1a2cfeac | |||
c6fabe504a | |||
61a17d7fab | |||
865cfa5211 | |||
e2b857adae | |||
f3924ccd91 | |||
86e3e59530 | |||
02e4726ba6 | |||
66e470e073 | |||
afaa5c24d6 | |||
518282e169 | |||
d955adbbad | |||
83d3225e57 | |||
6fa45975bf | |||
e6087efb40 | |||
4ce2f80a2f | |||
0862d1c804 | |||
333e380340 | |||
58f77a19ed | |||
f2d883dab2 | |||
7ba8c7c2b5 | |||
0bf6c93faa | |||
b9f0158278 | |||
25ee41f344 | |||
5436634829 | |||
915524e1ab | |||
d579cd1605 | |||
cb5941ec55 | |||
a5ac183d86 | |||
a36de92bb9 | |||
01f9d551f1 | |||
399df66b18 | |||
723a1c843a | |||
e333263fd6 | |||
507df9eea1 | |||
a9a3687ea0 | |||
f05c649c61 | |||
a2dfba1842 | |||
c199da4dfa | |||
ee9033e12f | |||
54788d750e | |||
78e894c6f2 | |||
32107ba8b5 | |||
6122f65e7a | |||
43fd29f9bf | |||
54c624b356 | |||
8c33adfd29 | |||
2e8881b77c | |||
64aa729edd | |||
ccf95b738d | |||
b2847fedd3 | |||
8befcb9bba | |||
988fc52303 | |||
7293ddb22c | |||
f23c118e81 | |||
f68b3be35a | |||
3d95e7bb11 | |||
337c484f01 | |||
5d98e2bf04 | |||
6f300d0cc6 | |||
3422e1dca7 | |||
963c6ae567 | |||
6304169926 | |||
221afde55e | |||
0ae87270ad | |||
9d33baec70 | |||
0f37b22cdb | |||
47afd87e84 | |||
700c06023e | |||
4fea5b5ca3 | |||
521bddc1cc | |||
bdfff20ec2 | |||
bdd05aba3b | |||
89c2538ff1 | |||
7680819108 | |||
d79e8b84c9 | |||
731317230a | |||
5046938913 | |||
0e8fd45559 | |||
6099a5dbc3 | |||
2daa98a694 | |||
5d2c6496fa | |||
817dbbe73f | |||
29c89c82f8 | |||
0b714bd479 | |||
8c94a5afb9 | |||
aeb117c9d1 | |||
a2d4f133b7 | |||
b833aff3c8 | |||
6601e4ddba | |||
815da2d0ec | |||
ddd35b3653 | |||
8a32894c83 | |||
49d8e6da40 | |||
8089f24c81 | |||
b6aab53d10 | |||
55a4517cd1 | |||
b095319a16 | |||
5ea5806730 | |||
bfbf812148 | |||
168e9eeac1 | |||
dd79c1a79a | |||
fe3402589b | |||
74dcaff21c | |||
0a7968a2e5 | |||
00091a2acb | |||
c5aa834b6a | |||
b1bde46694 | |||
49e4fa494e | |||
4622c52b71 | |||
e9ac5dd5f4 | |||
7570c43d11 | |||
4332e7ec49 | |||
9f26f1e225 | |||
0c0319c415 | |||
c16dbd7607 | |||
7b1f10a5fe | |||
dce74749b7 | |||
1ba88b8c42 | |||
9c50b57d46 | |||
900bd3ee97 | |||
b4affe00a7 | |||
ca49c84bc1 | |||
2cddf60226 | |||
d9c3951f02 | |||
aa5997d975 | |||
c51acf7c2a | |||
348044bc8a | |||
7dbdf2aa07 | |||
c933731ead | |||
e7da715994 | |||
6d82aefad4 | |||
8a11ab7d96 | |||
f465086405 | |||
70313a8b79 | |||
71679c38be | |||
addd943074 |
6
.gitignore
vendored
6
.gitignore
vendored
@ -23,6 +23,8 @@ data/gnome-shell-extension-prefs.desktop.in
|
|||||||
data/gschemas.compiled
|
data/gschemas.compiled
|
||||||
data/org.gnome.shell.gschema.xml
|
data/org.gnome.shell.gschema.xml
|
||||||
data/org.gnome.shell.gschema.valid
|
data/org.gnome.shell.gschema.valid
|
||||||
|
data/org.gnome.shell.evolution.calendar.gschema.xml
|
||||||
|
data/org.gnome.shell.evolution.calendar.gschema.valid
|
||||||
docs/reference/*/*.args
|
docs/reference/*/*.args
|
||||||
docs/reference/*/*.bak
|
docs/reference/*/*.bak
|
||||||
docs/reference/*/*.hierarchy
|
docs/reference/*/*.hierarchy
|
||||||
@ -48,6 +50,7 @@ po/gnome-shell.pot
|
|||||||
po/*.header
|
po/*.header
|
||||||
po/*.sed
|
po/*.sed
|
||||||
po/*.sin
|
po/*.sin
|
||||||
|
po/.intltool-merge-cache
|
||||||
po/Makefile.in.in
|
po/Makefile.in.in
|
||||||
po/Makevars.template
|
po/Makevars.template
|
||||||
po/POTFILES
|
po/POTFILES
|
||||||
@ -60,6 +63,8 @@ src/*-enum-types.[ch]
|
|||||||
src/*-marshal.[ch]
|
src/*-marshal.[ch]
|
||||||
src/Makefile
|
src/Makefile
|
||||||
src/Makefile.in
|
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/calendar-server/org.gnome.Shell.CalendarServer.service
|
||||||
src/gnome-shell
|
src/gnome-shell
|
||||||
src/gnome-shell-calendar-server
|
src/gnome-shell-calendar-server
|
||||||
@ -68,6 +73,7 @@ src/gnome-shell-extension-prefs
|
|||||||
src/gnome-shell-hotplug-sniffer
|
src/gnome-shell-hotplug-sniffer
|
||||||
src/gnome-shell-jhbuild
|
src/gnome-shell-jhbuild
|
||||||
src/gnome-shell-perf-helper
|
src/gnome-shell-perf-helper
|
||||||
|
src/gnome-shell-perf-tool
|
||||||
src/gnome-shell-real
|
src/gnome-shell-real
|
||||||
src/hotplug-sniffer/org.gnome.Shell.HotplugSniffer.service
|
src/hotplug-sniffer/org.gnome.Shell.HotplugSniffer.service
|
||||||
src/run-js-test
|
src/run-js-test
|
||||||
|
223
NEWS
223
NEWS
@ -1,3 +1,214 @@
|
|||||||
|
3.5.4
|
||||||
|
=====
|
||||||
|
* Fix wrong result handling of remote calls [Florian; #678852]
|
||||||
|
* dateMenu: Fix regression that caused no date to be displayed [Colin]
|
||||||
|
* WindowTracker: Fix refcounting bug in get_app_for_window() [Giovanni; #678992]
|
||||||
|
* Show the workspace switcher for move-to-workspace keybinding
|
||||||
|
[Giovanni, Jasper; #674104, #660839, #679005]
|
||||||
|
* userMenu: Move "Power off" item to the bottom [Florian; #678887]
|
||||||
|
* Remove contacts search provider [Florian, Rui; #677442]
|
||||||
|
* network: don't ask for always-ask secrets when interaction isn't allowed
|
||||||
|
[Dan; #679091]
|
||||||
|
* PolkitAgent: Look for the right password prompt [Matthias; #675300]
|
||||||
|
* Implement extension updates [Jasper; #679099]
|
||||||
|
* userMenu: Don't disconnect account signals when disabled [Guillaume; #669112]
|
||||||
|
* Fix startup notification when opening calendar [Florian; #677907]
|
||||||
|
* networkAgent: use absolute path if configured [Clemens; #679212]
|
||||||
|
* recorder: Port to GStreamer-1.0 API [Florian; #679445]
|
||||||
|
* telepathyClient: don't add log messages on presence changes [Ana; #669508]
|
||||||
|
* lookingGlass: Don't use a signal callback on 'paint' to draw the border
|
||||||
|
[Jasper; #679464]
|
||||||
|
* Add support for inhibiting automount [Hans; #678597]
|
||||||
|
* Implemented banner support for the login screen [Matthias, Marius; #665346]
|
||||||
|
* boxpointer: Flip side if we would end outside the monitor [Rui; #678164]
|
||||||
|
* boxpointer: Change 'animate' parameter on show/hide to a bitmask
|
||||||
|
[Rui; #678337]
|
||||||
|
* Add a grayscale effect [Matthias, Jasper, Florian: #676782, #674499]
|
||||||
|
* UserMenu: show "Install Updates & Restart" when appropriate
|
||||||
|
[Giovanni; #677394, #680080]
|
||||||
|
* messageTray: don't show the message tray when a new notification is shown
|
||||||
|
[Ana; #677210]
|
||||||
|
* panel: don't break when indicator has no menu [Jean-Philippe; #678694]
|
||||||
|
* appMenu: Disable app menu during startup animations [Florian; #672322]
|
||||||
|
* autorun: Add a notification when unmounting drives [Cosimo; #676125]
|
||||||
|
* st-icon: Fix potential crash involving shadows [Jasper; #679776]
|
||||||
|
* Remove manual garbage collection on tweeners end [Cosimo; #679832]
|
||||||
|
* dash: hide tooltips when overview begins hiding [Stefano; #674241]
|
||||||
|
* Update modal dialog animation for new centered position [Florian; #674499]
|
||||||
|
* calendar: Fix grid lines in RTL locales [Florian; #679879]
|
||||||
|
* Integrate IBus with keyboard indicator [Rui; #641531]
|
||||||
|
* Move ibus status icon under keyboard [Matthias]
|
||||||
|
* gdm: port from libgdmgreeter to libgdm [Ray; #676401]
|
||||||
|
* Misc bug fixes and cleanups [Antoine, Cosimo, Giovanni, Jasper, Rico;
|
||||||
|
#678978, #672790, #679847, #679944]
|
||||||
|
|
||||||
|
Contributors:
|
||||||
|
Jean-Philippe Braun, Clemens Buchacher, Giovanni Campagna, Cosimo Cecchi,
|
||||||
|
Matthias Clasen, Hans de Goede, Guillaume Desmottes, Stefano Facchini,
|
||||||
|
Antoine Jacoutot, Rui Matos, Florian Müllner, Marius Rieder, Ana Risteska,
|
||||||
|
Jasper St. Pierre, Rico Tzschichholz, Colin Walters, Dan Williams
|
||||||
|
|
||||||
|
Translations:
|
||||||
|
Matej Urbančič [sl], Khaled Hosny [ar], Nguyễn Thái Ngọc Duy [vi],
|
||||||
|
Nilamdyuti Goswami [as], Alexander Shopov [bg], Ivaylo Valkov [bg],
|
||||||
|
Daniel Mustieles [es], Kjartan Maraas [nb,nn], Yaron Shahrabani [he],
|
||||||
|
Nilamdyuti Goswami [as], Chao-Hsiung Liao [zh_HK, zh_TW], Ihar Hrachyshka [be],
|
||||||
|
Praveen Illa [te]
|
||||||
|
|
||||||
|
3.5.3
|
||||||
|
=====
|
||||||
|
* calendar: Adapt to Evolution-Data-Server API changes [Matthew; #677402]
|
||||||
|
* messageTray: Don't show non urgent notifications while in fullscreen
|
||||||
|
[Adel; #677590]
|
||||||
|
* modalDialog: show dialogs on monitor with the mouse pointer [Tim; #642591]
|
||||||
|
* extensionSystem: Prepare for extension updating system [Jasper; #677586]
|
||||||
|
* appDisplay: Don't show apps in NoDisplay categories in the All view
|
||||||
|
[Jasper; #658176]
|
||||||
|
* st: Trigger theme updates on resolution changes [Florian; #677975]
|
||||||
|
* Always enable a11y [Bastien; #678095]
|
||||||
|
* telepathyClient: ignore invalidated channels [Guillaume; #677457]
|
||||||
|
* shell-app: Update app menu if necessary [Florian; #676238]
|
||||||
|
* Enable the Screen Reader menu item [Matthias; #663256]
|
||||||
|
* Disable unredirection when a modal operation is active [Giovanni]
|
||||||
|
* Make folks optional [Colin]
|
||||||
|
* Improve mount-operation support [Cosimo]
|
||||||
|
- Fix exception when showing password entry [#678428]
|
||||||
|
- Close the password entry on operation abort [#673787]
|
||||||
|
- autorun: Don't allow autorun for things we mount on startup [#660595]
|
||||||
|
- Turn passphrase prompt into a dialog [#674962]
|
||||||
|
- Implement org.Gtk.MountOperationHandler [#678516]
|
||||||
|
* Network menu improvements
|
||||||
|
- Sort Wifi networks by strength [Giovanni; #658946]
|
||||||
|
- Prefer wifi/3g over VPN in the panel [Cosimo; #672591]
|
||||||
|
* clock: Switch to using GnomeWallClock [Colin; #657074]
|
||||||
|
* remoteSearch: Allow to reference .desktop file for Title/Icon
|
||||||
|
[Florian; #678816]
|
||||||
|
* Fix memory leaks [Jasper, Pavel; #678079, #678406, #678737]
|
||||||
|
* Misc fixes [Florian, Giovanni, Guillaume, Jasper, Kjartan, Piotr, Rui;
|
||||||
|
#658955, #677497, #678396, #678502]
|
||||||
|
* Misc cleanups [Bastien, Florian, Jasper; #677426, #677515, #678096, #678416]
|
||||||
|
|
||||||
|
Contributors:
|
||||||
|
Matthew Barnes, Giovanni Campagna, Cosimo Cecchi, Matthias Clasen,
|
||||||
|
Guillaume Desmottes, Piotr Drąg, Adel Gadllah, Tim L, Kjartan Maraas,
|
||||||
|
Rui Matos, Florian Müllner, Bastien Nocera, Jasper St. Pierre, Colin Walters
|
||||||
|
|
||||||
|
Translations:
|
||||||
|
Matej Urbančič [sl], Yuri Kozlov [ru], Tom Tryfonidis [el],
|
||||||
|
Kjartan Maraas [nb], Žygimantas Beručka [lt], Luca Ferretti [it],
|
||||||
|
Khaled Hosny [ar], Daniel Mustieles [es], Fran Diéguez [gl], A S Alam [pa]
|
||||||
|
|
||||||
|
3.5.2
|
||||||
|
=====
|
||||||
|
* main: Move 'toggle-recording' binding into the shell [Florian; #674377]
|
||||||
|
* popupMenu: make sure to break the grab when the slider is not visible
|
||||||
|
[Stefano; #672713]
|
||||||
|
* st-theme-node-drawing: Don't use GL types [Neil; #672711]
|
||||||
|
* Mirror Evolution calendar settings into our own schema [Owen; #674424]
|
||||||
|
* shell-network-agent: don't crash if a request isn't found [Dan; #674961]
|
||||||
|
* notificationDaemon: Match app based on WM_CLASS [Jasper; #673761]
|
||||||
|
* NetworkMenu: use network-offline while loading [Giovanni; #674426]
|
||||||
|
* lookingGlass: Remove the Errors tab [Jasper; #675104]
|
||||||
|
* searchDisplay: Reset keyboard focus after displaying async results
|
||||||
|
[Rui; #675078]
|
||||||
|
* gdm: don't fail if fprintd is unavailable [Ray; #675006]
|
||||||
|
* messageTray: Fix scrolling up [Jasper; #661615]
|
||||||
|
* main: Close the recorder instead of pausing it [Rui; #675128]
|
||||||
|
* Accessibility [Alejandro]
|
||||||
|
- Use the proper label_actor for date menu on top panel [#675307]
|
||||||
|
- Set the proper role/label_actor for SearchResult.content [#672242]
|
||||||
|
- do not expose a label text if 'hidden' style class is used [#675341]
|
||||||
|
* Magnifier: Add brightness and contrast functionality [Joseph; #639851]
|
||||||
|
* theme: use a smaller border-radius for top bar [Jakub; #672430]
|
||||||
|
* placeDisplay: use new bookmark file location [Matthias; #675443]
|
||||||
|
* port all synchronous search providers to the async API [Jasper, Rui; #675328]
|
||||||
|
* NetworkAgent: disallow multiple requests for the same connection/setting
|
||||||
|
[Giovanni; #674961]
|
||||||
|
* userMenu: Update to latest mockups [Florian; #675802]
|
||||||
|
* util: Don't double-fork when spawning from Alt-F2 [Colin; #675789]
|
||||||
|
* messageTray: Make Source usable without subclassing [Jasper; #661236]
|
||||||
|
* panel: Check for appMenu button's reactivity before opening [Florian; #676316]
|
||||||
|
* Fix formatting of bluetooth passkey [Florian; #651251]
|
||||||
|
* notificationDaemon: Filter out file-transfer notifications [Jasper; #676175]
|
||||||
|
* Don't use global.log() [Jasper; #675790]
|
||||||
|
* Fix broken extension loading in some distributions [Owen, Alexandre; #670477]
|
||||||
|
* shell-app: Raise windows in reverse order to preserve the stacking
|
||||||
|
[Rui; #676371]
|
||||||
|
* Generalize gdm-mode [Florian; #676156]
|
||||||
|
* Switch string formatting to the one inside gjs [Jasper; #675479]
|
||||||
|
* extensionUtils: Support subdirectories in getCurrentExtension
|
||||||
|
[Jasper; #677001]
|
||||||
|
* panel: Refuse to add (legacy) status icons not part of the session mode
|
||||||
|
[Florian; #677058]
|
||||||
|
* Add an initial-setup mode [Matthias; #676697]
|
||||||
|
* status/keyboard: Port to the new input sources settings [Rui; #641531]
|
||||||
|
* NetworkMenu: show notifications for failed VPN connections [Giovanni; #676330]
|
||||||
|
* userMenu: Indicate progress on status changes [Florian; #659067]
|
||||||
|
* recorder: Honor "disable-save-to-disk" lockdown key [Rūdolfs; #673630]
|
||||||
|
* searchDisplay: Use the rowLimit we pass to the IconGrid [Christian; #675527]
|
||||||
|
* endSessionDialog: Factor out _updateDescription from _updateContent
|
||||||
|
[Alejandro; #674210]
|
||||||
|
* Fix empathy's appMenu freezing the shell [Alban; #676447]
|
||||||
|
* Code cleanups [Florian, Giovanni, Jasper; #672807, #672413, #676837, #676850,
|
||||||
|
#672272]
|
||||||
|
* Misc bug fixes [Alban, Florian, Giovanni, Guillaume, Jasper, Piotr, Rico,
|
||||||
|
Ron, Rui, Stefano; #659968, #672192, #673177, #673198, #674323, #675301,
|
||||||
|
#675370, #676347, #676806, #677097]
|
||||||
|
|
||||||
|
Contributors:
|
||||||
|
Alban Browaeys, Giovanni Campagna, Matthias Clasen, Guillaume Desmottes,
|
||||||
|
Piotr Drąg, Stefano Facchini, Rui Matos, Rūdolfs Mazurs, Florian Müllner,
|
||||||
|
Alejandro Piñeiro, Neil Roberts, Alexandre Rostovtsev, Joseph Scheuhammer,
|
||||||
|
Jakub Steiner, Jasper St. Pierre, Ray Strode, Owen Taylor, Rico Tzschichholz,
|
||||||
|
Colin Walters, Dan Winship, Ron Yorston
|
||||||
|
|
||||||
|
Translations:
|
||||||
|
OKANO Takayoshi [ja], Daniel Mustieles [es], Changwoo Ryu [ko],
|
||||||
|
Yaron Shahrabani [he], Fran Diéguez [gl], Jonh Wendell [pt_BR],
|
||||||
|
Kjartan Maraas [nb], Luca Ferretti [it], Tom Tryfonidis [el],
|
||||||
|
Sandeep Sheshrao Shedmake [mr], Takanori MATSUURA [ja], Dirgita [id],
|
||||||
|
Mantas Kriaučiūnas [lt], Matej Urbančič [sl], Jiro Matsuzawa [ja]
|
||||||
|
|
||||||
|
3.4.1
|
||||||
|
=====
|
||||||
|
* Fix crash that occurred when an icon theme change caused unexpected
|
||||||
|
reentrancy in the icon loading code [Jasper; #673512]
|
||||||
|
* Don't show system and other disabled users in the GDM user list
|
||||||
|
[Adel; #673784]
|
||||||
|
* Make gnome-shell-calendar-server initialize GTK+ so it can display
|
||||||
|
password prompts if needed [#673608; Owen, Rico]
|
||||||
|
* Adapt to Mutter API change for keybinding addition [Florian; #673014]
|
||||||
|
* Fix crash when an extension was installed as both a user extension
|
||||||
|
and a system extension [#673613; Jasper]
|
||||||
|
* Fix bug where chat entry could end up partially offscreen [Joost, 661944]
|
||||||
|
* Fix problem where icons weren't updating when theme was changed
|
||||||
|
[#672941; Florian]
|
||||||
|
* Look for Evolution calendar settings in GSettings, not GConf [#673610; Owen]
|
||||||
|
* Add <super>F10 for the application menu [#672909; Florian]
|
||||||
|
* Fix %Id format characters to work in translations [#673106; Cosimo]
|
||||||
|
(were already used in fa translation)
|
||||||
|
* Fix error when NetworkManager restarts [#673043; Giovanni]
|
||||||
|
* Improve efficiency of overview redraws by working around Clutter issue
|
||||||
|
[Stefano; #670636]
|
||||||
|
* Misc bug fixes [Florian, Giovanni, Jasper, Rui, Stefano;
|
||||||
|
#672592, #672641, #672719, #673187, #673233, #673656]
|
||||||
|
|
||||||
|
Contributors:
|
||||||
|
Giovanni Campagna, Cosimo Cecchi, Stefano Facchini, Adel Gadllah, Rui Matos,
|
||||||
|
Florian Müllner, Jasper St. Pierre, Owen Taylor, Rico Tzschichholz,
|
||||||
|
Joost Verdoorn
|
||||||
|
|
||||||
|
Translations:
|
||||||
|
Khaled Hosny [ar], Ihar Hrachyshka [be], Alexander Shopov [bg], Gil Forcada,
|
||||||
|
Jordi Serratosa [ca], Petr Kovar [cs], Bruce Cowan [en_GB],
|
||||||
|
Carles Ferrando [ca@valencia], Wolfgang Stöggl [de], Daniel Mustieles [es],
|
||||||
|
Arash Mousavi [fa], Bruno Brouard [fr], Fran Diéguez [gl],
|
||||||
|
Sweta Kothari [gu], Yaron Shahrabani [he], Gabor Kelemen [hu],
|
||||||
|
Shankar Prasad [kn], Žygimantas Beručka [lt], Rudolfs Mazurs [lv],
|
||||||
|
Sandeep Sheshrao Shedmake [mr], Kjartan Maraas [nb], Piotr Drąg [pl],
|
||||||
|
Yuri Myasoedov [ru], Daniel Nylander [se], Matej Urbančič [sl],
|
||||||
|
Miroslav Nikolić [sr], Sasi Bhushan, Praveen Illa [te], Yinghua Wang [zh_CN]
|
||||||
|
|
||||||
3.4.0
|
3.4.0
|
||||||
=====
|
=====
|
||||||
* Don't crash when taking screenshots [Jasper; #672775]
|
* Don't crash when taking screenshots [Jasper; #672775]
|
||||||
@ -8,10 +219,10 @@ Contributors:
|
|||||||
|
|
||||||
Translations:
|
Translations:
|
||||||
Khaled Hosny, Abderrahim Kitouni [ar], Ihar Hrachyshka [be],
|
Khaled Hosny, Abderrahim Kitouni [ar], Ihar Hrachyshka [be],
|
||||||
Alexander Shopov [bg], Marek Černocký [cz], Jiri Grönroos, Timo Jyrinki [fi],
|
Alexander Shopov [bg], Marek Černocký [cs], Jiri Grönroos, Timo Jyrinki [fi],
|
||||||
Bruno Brouard [fr], Fran Diéguez [gl], Yaron Shahrabani [he],
|
Bruno Brouard [fr], Fran Diéguez [gl], Yaron Shahrabani [he],
|
||||||
Gabor Kelemen [hu], Jiro Matsuzawa [ja], Kenneth Nielsen [dk],
|
Gabor Kelemen [hu], Jiro Matsuzawa [ja], Kenneth Nielsen [dk],
|
||||||
Mattias Põldaru [et], Changwoo Ryu [kr], Rudolfs Mazurs [lv],
|
Mattias Põldaru [et], Changwoo Ryu [ko], Rudolfs Mazurs [lv],
|
||||||
Jonh Wendell [pt_BR], Yuri Myasoedov[ru], Daniel Korostil [uk],
|
Jonh Wendell [pt_BR], Yuri Myasoedov[ru], Daniel Korostil [uk],
|
||||||
Nguyễn Thái Ngọc Duy [vi], Chao-Hsiung Liao [zh_HK, zh_TW]
|
Nguyễn Thái Ngọc Duy [vi], Chao-Hsiung Liao [zh_HK, zh_TW]
|
||||||
|
|
||||||
@ -80,7 +291,7 @@ Contributors:
|
|||||||
|
|
||||||
Translations:
|
Translations:
|
||||||
Nilamdyuti Goswami [as], Ihar Hrachyshka, Kasia Bondarava [be],
|
Nilamdyuti Goswami [as], Ihar Hrachyshka, Kasia Bondarava [be],
|
||||||
Alexander Shopov, Ivaylo Valkov [bg], Gil Forcada [ca], Marek Černocký [cz],
|
Alexander Shopov, Ivaylo Valkov [bg], Gil Forcada [ca], Marek Černocký [cs],
|
||||||
Mario Blättermann [de], Kris Thomsen [dk], Bruce Cowan [en_GB],
|
Mario Blättermann [de], Kris Thomsen [dk], Bruce Cowan [en_GB],
|
||||||
Kristjan Schmidt [eo], Daniel Mustieles [es], Mattias Põldaru [et],
|
Kristjan Schmidt [eo], Daniel Mustieles [es], Mattias Põldaru [et],
|
||||||
Inaki Larranaga Murgoitio [eu], Arash Mousavi [fa], Timo Jyrinki [fi],
|
Inaki Larranaga Murgoitio [eu], Arash Mousavi [fa], Timo Jyrinki [fi],
|
||||||
@ -129,7 +340,7 @@ Contributors:
|
|||||||
Will Thompson, Stef Walter
|
Will Thompson, Stef Walter
|
||||||
|
|
||||||
Translations:
|
Translations:
|
||||||
Ihar Hrachyshka [be], Marek Černocký, Adam Matoušek [cz],
|
Ihar Hrachyshka [be], Marek Černocký, Adam Matoušek [cs],
|
||||||
Kenneth Nielsen [dk], Daniel Mustieles [es], Mattias Põldaru [et],
|
Kenneth Nielsen [dk], Daniel Mustieles [es], Mattias Põldaru [et],
|
||||||
Fran Diéguez [gl], Yaron Shahrabani [he], Luca Ferretti [it],
|
Fran Diéguez [gl], Yaron Shahrabani [he], Luca Ferretti [it],
|
||||||
Baurzhan Muftakhidinov [kk], Aurimas Černius [lt], Kjartan Maraas [nb],
|
Baurzhan Muftakhidinov [kk], Aurimas Černius [lt], Kjartan Maraas [nb],
|
||||||
@ -260,7 +471,7 @@ Contributors:
|
|||||||
Marina Zhurakhinskaya
|
Marina Zhurakhinskaya
|
||||||
|
|
||||||
Translations:
|
Translations:
|
||||||
Petr Kovar [cz], Kris Thomsen [dk], Daniel Mustieles [es],
|
Petr Kovar [cs], Kris Thomsen [dk], Daniel Mustieles [es],
|
||||||
Ville-Pekka Vainio [fi], Yaron Shahrabani [he], Luca Ferretti [it],
|
Ville-Pekka Vainio [fi], Yaron Shahrabani [he], Luca Ferretti [it],
|
||||||
Hideki Yamane [ja], Žygimantas Beručka [lt], Jovan Naumovski [mk],
|
Hideki Yamane [ja], Žygimantas Beručka [lt], Jovan Naumovski [mk],
|
||||||
Kjartan Maraas [nb], "Andreas N" [nn], Lucian Adrian Grijincu [ro],
|
Kjartan Maraas [nb], "Andreas N" [nn], Lucian Adrian Grijincu [ro],
|
||||||
@ -423,7 +634,7 @@ Contributors:
|
|||||||
Translations:
|
Translations:
|
||||||
Friedel Wolff [af], Nilamdyuti Goswami [as], Ihar Hrachyshka [be],
|
Friedel Wolff [af], Nilamdyuti Goswami [as], Ihar Hrachyshka [be],
|
||||||
Ivaylo Valkov [bg], Gil Forcada [ca], Carles Ferrando [ca@valencia],
|
Ivaylo Valkov [bg], Gil Forcada [ca], Carles Ferrando [ca@valencia],
|
||||||
Petr Kovar [cz], Mario Blättermann [de], Kris Thomsen [dk],
|
Petr Kovar [cs], Mario Blättermann [de], Kris Thomsen [dk],
|
||||||
Tiffany Antopolski, Kristjan Schmidt [eo], Daniel Mustieles [es],
|
Tiffany Antopolski, Kristjan Schmidt [eo], Daniel Mustieles [es],
|
||||||
Inaki Larranaga Murgoitio [eu], Tommi Vainikainen [fi], Bruno Brouard [fr],
|
Inaki Larranaga Murgoitio [eu], Tommi Vainikainen [fi], Bruno Brouard [fr],
|
||||||
Fran Dieguez [gl], Yaron Shahrabani [he], Gabor Kelemen [hu],
|
Fran Dieguez [gl], Yaron Shahrabani [he], Gabor Kelemen [hu],
|
||||||
|
@ -41,7 +41,7 @@
|
|||||||
"It can be used only by extensions.gnome.org"
|
"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 3
|
#define PLUGIN_API_VERSION 5
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
GDBusProxy *proxy;
|
GDBusProxy *proxy;
|
||||||
@ -163,6 +163,7 @@ NP_Initialize(NPNetscapeFuncs *pfuncs, NPPluginFuncs *plugin)
|
|||||||
plugin->newp = NPP_New;
|
plugin->newp = NPP_New;
|
||||||
plugin->destroy = NPP_Destroy;
|
plugin->destroy = NPP_Destroy;
|
||||||
plugin->getvalue = NPP_GetValue;
|
plugin->getvalue = NPP_GetValue;
|
||||||
|
plugin->setwindow = NPP_SetWindow;
|
||||||
|
|
||||||
return NPERR_NO_ERROR;
|
return NPERR_NO_ERROR;
|
||||||
}
|
}
|
||||||
@ -224,7 +225,7 @@ NPP_New(NPMIMEType mimetype,
|
|||||||
NULL, /* interface info */
|
NULL, /* interface info */
|
||||||
"org.gnome.Shell",
|
"org.gnome.Shell",
|
||||||
"/org/gnome/Shell",
|
"/org/gnome/Shell",
|
||||||
"org.gnome.Shell",
|
"org.gnome.Shell.Extensions",
|
||||||
NULL, /* GCancellable */
|
NULL, /* GCancellable */
|
||||||
&error);
|
&error);
|
||||||
if (!data->proxy)
|
if (!data->proxy)
|
||||||
@ -267,6 +268,7 @@ typedef struct {
|
|||||||
NPObject parent;
|
NPObject parent;
|
||||||
NPP instance;
|
NPP instance;
|
||||||
GDBusProxy *proxy;
|
GDBusProxy *proxy;
|
||||||
|
GSettings *settings;
|
||||||
NPObject *listener;
|
NPObject *listener;
|
||||||
NPObject *restart_listener;
|
NPObject *restart_listener;
|
||||||
gint signal_id;
|
gint signal_id;
|
||||||
@ -323,6 +325,9 @@ on_shell_appeared (GDBusConnection *connection,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define SHELL_SCHEMA "org.gnome.shell"
|
||||||
|
#define ENABLED_EXTENSIONS_KEY "enabled-extensions"
|
||||||
|
|
||||||
static NPObject *
|
static NPObject *
|
||||||
plugin_object_allocate (NPP instance,
|
plugin_object_allocate (NPP instance,
|
||||||
NPClass *klass)
|
NPClass *klass)
|
||||||
@ -332,6 +337,7 @@ plugin_object_allocate (NPP instance,
|
|||||||
|
|
||||||
obj->instance = instance;
|
obj->instance = instance;
|
||||||
obj->proxy = g_object_ref (data->proxy);
|
obj->proxy = g_object_ref (data->proxy);
|
||||||
|
obj->settings = g_settings_new (SHELL_SCHEMA);
|
||||||
obj->signal_id = g_signal_connect (obj->proxy, "g-signal",
|
obj->signal_id = g_signal_connect (obj->proxy, "g-signal",
|
||||||
G_CALLBACK (on_shell_signal), obj);
|
G_CALLBACK (on_shell_signal), obj);
|
||||||
|
|
||||||
@ -367,39 +373,14 @@ plugin_object_deallocate (NPObject *npobj)
|
|||||||
g_slice_free (PluginObject, obj);
|
g_slice_free (PluginObject, obj);
|
||||||
}
|
}
|
||||||
|
|
||||||
static NPIdentifier api_version_id;
|
|
||||||
static NPIdentifier shell_version_id;
|
|
||||||
static NPIdentifier get_info_id;
|
|
||||||
static NPIdentifier list_extensions_id;
|
|
||||||
static NPIdentifier enable_extension_id;
|
|
||||||
static NPIdentifier install_extension_id;
|
|
||||||
static NPIdentifier uninstall_extension_id;
|
|
||||||
static NPIdentifier onextension_changed_id;
|
|
||||||
static NPIdentifier onrestart_id;
|
|
||||||
static NPIdentifier get_errors_id;
|
|
||||||
static NPIdentifier launch_extension_prefs_id;
|
|
||||||
|
|
||||||
static bool
|
|
||||||
plugin_object_has_method (NPObject *npobj,
|
|
||||||
NPIdentifier name)
|
|
||||||
{
|
|
||||||
return (name == get_info_id ||
|
|
||||||
name == list_extensions_id ||
|
|
||||||
name == enable_extension_id ||
|
|
||||||
name == install_extension_id ||
|
|
||||||
name == uninstall_extension_id ||
|
|
||||||
name == get_errors_id ||
|
|
||||||
name == launch_extension_prefs_id);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline gboolean
|
static inline gboolean
|
||||||
uuid_is_valid (const gchar *uuid)
|
uuid_is_valid (NPString string)
|
||||||
{
|
{
|
||||||
gsize i;
|
gsize i;
|
||||||
|
|
||||||
for (i = 0; uuid[i]; i ++)
|
for (i = 0; i < string.UTF8Length; i++)
|
||||||
{
|
{
|
||||||
gchar c = uuid[i];
|
gchar c = string.UTF8Characters[i];
|
||||||
if (c < 32 || c >= 127)
|
if (c < 32 || c >= 127)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
@ -462,8 +443,73 @@ jsonify_variant (GVariant *variant,
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
parse_args (const gchar *format_str,
|
||||||
|
uint32_t argc,
|
||||||
|
const NPVariant *argv,
|
||||||
|
...)
|
||||||
|
{
|
||||||
|
va_list args;
|
||||||
|
gsize i;
|
||||||
|
gboolean ret = FALSE;
|
||||||
|
|
||||||
|
if (strlen (format_str) != argc)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
va_start (args, argv);
|
||||||
|
|
||||||
|
for (i = 0; format_str[i]; i++)
|
||||||
|
{
|
||||||
|
gpointer arg_location;
|
||||||
|
const NPVariant arg = argv[i];
|
||||||
|
|
||||||
|
arg_location = va_arg (args, gpointer);
|
||||||
|
|
||||||
|
switch (format_str[i])
|
||||||
|
{
|
||||||
|
case 'u':
|
||||||
|
{
|
||||||
|
NPString string;
|
||||||
|
|
||||||
|
if (!NPVARIANT_IS_STRING (arg))
|
||||||
|
goto out;
|
||||||
|
|
||||||
|
string = NPVARIANT_TO_STRING (arg);
|
||||||
|
|
||||||
|
if (!uuid_is_valid (string))
|
||||||
|
goto out;
|
||||||
|
|
||||||
|
*(gchar **) arg_location = g_strndup (string.UTF8Characters, string.UTF8Length);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'b':
|
||||||
|
if (!NPVARIANT_IS_BOOLEAN (arg))
|
||||||
|
goto out;
|
||||||
|
|
||||||
|
*(gboolean *) arg_location = NPVARIANT_TO_BOOLEAN (arg);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'o':
|
||||||
|
if (!NPVARIANT_IS_OBJECT (arg))
|
||||||
|
goto out;
|
||||||
|
|
||||||
|
*(NPObject **) arg_location = NPVARIANT_TO_OBJECT (arg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = TRUE;
|
||||||
|
|
||||||
|
out:
|
||||||
|
va_end (args);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
plugin_list_extensions (PluginObject *obj,
|
plugin_list_extensions (PluginObject *obj,
|
||||||
|
uint32_t argc,
|
||||||
|
const NPVariant *args,
|
||||||
NPVariant *result)
|
NPVariant *result)
|
||||||
{
|
{
|
||||||
GError *error = NULL;
|
GError *error = NULL;
|
||||||
@ -489,90 +535,158 @@ plugin_list_extensions (PluginObject *obj,
|
|||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
plugin_enable_extension (PluginObject *obj,
|
plugin_enable_extension (PluginObject *obj,
|
||||||
NPString uuid,
|
uint32_t argc,
|
||||||
gboolean enabled)
|
const NPVariant *argv,
|
||||||
|
NPVariant *result)
|
||||||
{
|
{
|
||||||
gchar *uuid_str = g_strndup (uuid.UTF8Characters, uuid.UTF8Length);
|
gboolean ret;
|
||||||
if (!uuid_is_valid (uuid_str))
|
gchar *uuid;
|
||||||
{
|
gboolean enabled;
|
||||||
g_free (uuid_str);
|
gsize length;
|
||||||
|
gchar **uuids;
|
||||||
|
const gchar **new_uuids;
|
||||||
|
|
||||||
|
if (!parse_args ("ub", argc, argv, &uuid, &enabled))
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
|
uuids = g_settings_get_strv (obj->settings, ENABLED_EXTENSIONS_KEY);
|
||||||
|
length = g_strv_length (uuids);
|
||||||
|
|
||||||
|
if (enabled)
|
||||||
|
{
|
||||||
|
new_uuids = g_new (const gchar *, length + 2); /* New key, NULL */
|
||||||
|
memcpy (new_uuids, uuids, length * sizeof (*new_uuids));
|
||||||
|
new_uuids[length] = uuid;
|
||||||
|
new_uuids[length + 1] = NULL;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
gsize i = 0, j = 0;
|
||||||
|
new_uuids = g_new (const gchar *, length);
|
||||||
|
for (i = 0; i < length; i ++)
|
||||||
|
{
|
||||||
|
if (g_str_equal (uuids[i], uuid))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
new_uuids[j] = uuids[i];
|
||||||
|
j++;
|
||||||
}
|
}
|
||||||
|
|
||||||
g_dbus_proxy_call (obj->proxy,
|
new_uuids[j] = NULL;
|
||||||
(enabled ? "EnableExtension" : "DisableExtension"),
|
}
|
||||||
g_variant_new ("(s)", uuid_str),
|
|
||||||
G_DBUS_CALL_FLAGS_NONE,
|
|
||||||
-1, /* timeout */
|
|
||||||
NULL, /* cancellable */
|
|
||||||
NULL, /* callback */
|
|
||||||
NULL /* user_data */);
|
|
||||||
|
|
||||||
g_free (uuid_str);
|
ret = g_settings_set_strv (obj->settings,
|
||||||
|
ENABLED_EXTENSIONS_KEY,
|
||||||
|
new_uuids);
|
||||||
|
|
||||||
return TRUE;
|
g_strfreev (uuids);
|
||||||
|
g_free (new_uuids);
|
||||||
|
g_free (uuid);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
typedef struct _AsyncClosure AsyncClosure;
|
||||||
|
|
||||||
|
struct _AsyncClosure {
|
||||||
|
PluginObject *obj;
|
||||||
|
NPObject *callback;
|
||||||
|
NPObject *errback;
|
||||||
|
};
|
||||||
|
|
||||||
|
static void
|
||||||
|
install_extension_cb (GObject *proxy,
|
||||||
|
GAsyncResult *async_res,
|
||||||
|
gpointer user_data)
|
||||||
|
{
|
||||||
|
AsyncClosure *async_closure = (AsyncClosure *) user_data;
|
||||||
|
GError *error = NULL;
|
||||||
|
GVariant *res;
|
||||||
|
NPVariant args[1];
|
||||||
|
NPVariant result = { NPVariantType_Void };
|
||||||
|
NPObject *callback;
|
||||||
|
|
||||||
|
res = g_dbus_proxy_call_finish (G_DBUS_PROXY (proxy), async_res, &error);
|
||||||
|
|
||||||
|
if (res == NULL)
|
||||||
|
{
|
||||||
|
if (g_dbus_error_is_remote_error (error))
|
||||||
|
g_dbus_error_strip_remote_error (error);
|
||||||
|
STRINGZ_TO_NPVARIANT (error->message, args[0]);
|
||||||
|
callback = async_closure->errback;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
char *string_result;
|
||||||
|
g_variant_get (res, "(&s)", &string_result);
|
||||||
|
STRINGZ_TO_NPVARIANT (string_result, args[0]);
|
||||||
|
callback = async_closure->callback;
|
||||||
|
}
|
||||||
|
|
||||||
|
funcs.invokeDefault (async_closure->obj->instance,
|
||||||
|
callback, args, 1, &result);
|
||||||
|
|
||||||
|
funcs.releasevariantvalue (&result);
|
||||||
|
|
||||||
|
funcs.releaseobject (async_closure->callback);
|
||||||
|
funcs.releaseobject (async_closure->errback);
|
||||||
|
g_slice_free (AsyncClosure, async_closure);
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
plugin_install_extension (PluginObject *obj,
|
plugin_install_extension (PluginObject *obj,
|
||||||
NPString uuid,
|
uint32_t argc,
|
||||||
NPString version_tag)
|
const NPVariant *argv,
|
||||||
|
NPVariant *result)
|
||||||
{
|
{
|
||||||
gchar *uuid_str = g_strndup (uuid.UTF8Characters, uuid.UTF8Length);
|
gchar *uuid;
|
||||||
gchar *version_tag_str;
|
NPObject *callback, *errback;
|
||||||
|
AsyncClosure *async_closure;
|
||||||
|
|
||||||
if (!uuid_is_valid (uuid_str))
|
if (!parse_args ("uoo", argc, argv, &uuid, &callback, &errback))
|
||||||
{
|
|
||||||
g_free (uuid_str);
|
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
|
||||||
|
|
||||||
version_tag_str = g_strndup (version_tag.UTF8Characters,
|
async_closure = g_slice_new (AsyncClosure);
|
||||||
version_tag.UTF8Length);
|
async_closure->obj = obj;
|
||||||
|
async_closure->callback = funcs.retainobject (callback);
|
||||||
|
async_closure->errback = funcs.retainobject (errback);
|
||||||
|
|
||||||
g_dbus_proxy_call (obj->proxy,
|
g_dbus_proxy_call (obj->proxy,
|
||||||
"InstallRemoteExtension",
|
"InstallRemoteExtension",
|
||||||
g_variant_new ("(ss)",
|
g_variant_new ("(s)", uuid),
|
||||||
uuid_str,
|
|
||||||
version_tag_str),
|
|
||||||
G_DBUS_CALL_FLAGS_NONE,
|
G_DBUS_CALL_FLAGS_NONE,
|
||||||
-1, /* timeout */
|
-1, /* timeout */
|
||||||
NULL, /* cancellable */
|
NULL, /* cancellable */
|
||||||
NULL, /* callback */
|
install_extension_cb,
|
||||||
NULL /* user_data */);
|
async_closure);
|
||||||
|
|
||||||
g_free (uuid_str);
|
g_free (uuid);
|
||||||
g_free (version_tag_str);
|
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
plugin_uninstall_extension (PluginObject *obj,
|
plugin_uninstall_extension (PluginObject *obj,
|
||||||
NPString uuid,
|
uint32_t argc,
|
||||||
|
const NPVariant *argv,
|
||||||
NPVariant *result)
|
NPVariant *result)
|
||||||
{
|
{
|
||||||
GError *error = NULL;
|
GError *error = NULL;
|
||||||
GVariant *res;
|
GVariant *res;
|
||||||
gchar *uuid_str;
|
gchar *uuid;
|
||||||
|
|
||||||
uuid_str = g_strndup (uuid.UTF8Characters, uuid.UTF8Length);
|
if (!parse_args ("u", argc, argv, &uuid))
|
||||||
if (!uuid_is_valid (uuid_str))
|
|
||||||
{
|
|
||||||
g_free (uuid_str);
|
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
|
||||||
|
|
||||||
res = g_dbus_proxy_call_sync (obj->proxy,
|
res = g_dbus_proxy_call_sync (obj->proxy,
|
||||||
"UninstallExtension",
|
"UninstallExtension",
|
||||||
g_variant_new ("(s)",
|
g_variant_new ("(s)", uuid),
|
||||||
uuid_str),
|
|
||||||
G_DBUS_CALL_FLAGS_NONE,
|
G_DBUS_CALL_FLAGS_NONE,
|
||||||
-1, /* timeout */
|
-1, /* timeout */
|
||||||
NULL, /* cancellable */
|
NULL, /* cancellable */
|
||||||
&error);
|
&error);
|
||||||
|
|
||||||
g_free (uuid_str);
|
g_free (uuid);
|
||||||
|
|
||||||
if (!res)
|
if (!res)
|
||||||
{
|
{
|
||||||
@ -586,29 +700,26 @@ plugin_uninstall_extension (PluginObject *obj,
|
|||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
plugin_get_info (PluginObject *obj,
|
plugin_get_info (PluginObject *obj,
|
||||||
NPString uuid,
|
uint32_t argc,
|
||||||
|
const NPVariant *argv,
|
||||||
NPVariant *result)
|
NPVariant *result)
|
||||||
{
|
{
|
||||||
GError *error = NULL;
|
GError *error = NULL;
|
||||||
GVariant *res;
|
GVariant *res;
|
||||||
gchar *uuid_str;
|
gchar *uuid;
|
||||||
|
|
||||||
uuid_str = g_strndup (uuid.UTF8Characters, uuid.UTF8Length);
|
if (!parse_args ("u", argc, argv, &uuid))
|
||||||
if (!uuid_is_valid (uuid_str))
|
|
||||||
{
|
|
||||||
g_free (uuid_str);
|
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
|
||||||
|
|
||||||
res = g_dbus_proxy_call_sync (obj->proxy,
|
res = g_dbus_proxy_call_sync (obj->proxy,
|
||||||
"GetExtensionInfo",
|
"GetExtensionInfo",
|
||||||
g_variant_new ("(s)", uuid_str),
|
g_variant_new ("(s)", uuid),
|
||||||
G_DBUS_CALL_FLAGS_NONE,
|
G_DBUS_CALL_FLAGS_NONE,
|
||||||
-1, /* timeout */
|
-1, /* timeout */
|
||||||
NULL, /* cancellable */
|
NULL, /* cancellable */
|
||||||
&error);
|
&error);
|
||||||
|
|
||||||
g_free (uuid_str);
|
g_free (uuid);
|
||||||
|
|
||||||
if (!res)
|
if (!res)
|
||||||
{
|
{
|
||||||
@ -622,30 +733,25 @@ plugin_get_info (PluginObject *obj,
|
|||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
plugin_get_errors (PluginObject *obj,
|
plugin_get_errors (PluginObject *obj,
|
||||||
NPString uuid,
|
uint32_t argc,
|
||||||
|
const NPVariant *argv,
|
||||||
NPVariant *result)
|
NPVariant *result)
|
||||||
{
|
{
|
||||||
GError *error = NULL;
|
GError *error = NULL;
|
||||||
GVariant *res;
|
GVariant *res;
|
||||||
gchar *uuid_str;
|
gchar *uuid;
|
||||||
|
|
||||||
uuid_str = g_strndup (uuid.UTF8Characters, uuid.UTF8Length);
|
if (!parse_args ("u", argc, argv, &uuid))
|
||||||
if (!uuid_is_valid (uuid_str))
|
|
||||||
{
|
|
||||||
g_free (uuid_str);
|
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
|
||||||
|
|
||||||
res = g_dbus_proxy_call_sync (obj->proxy,
|
res = g_dbus_proxy_call_sync (obj->proxy,
|
||||||
"GetExtensionErrors",
|
"GetExtensionErrors",
|
||||||
g_variant_new ("(s)", uuid_str),
|
g_variant_new ("(s)", uuid),
|
||||||
G_DBUS_CALL_FLAGS_NONE,
|
G_DBUS_CALL_FLAGS_NONE,
|
||||||
-1, /* timeout */
|
-1, /* timeout */
|
||||||
NULL, /* cancellable */
|
NULL, /* cancellable */
|
||||||
&error);
|
&error);
|
||||||
|
|
||||||
g_free (uuid_str);
|
|
||||||
|
|
||||||
if (!res)
|
if (!res)
|
||||||
{
|
{
|
||||||
g_warning ("Failed to retrieve errors: %s", error->message);
|
g_warning ("Failed to retrieve errors: %s", error->message);
|
||||||
@ -658,28 +764,24 @@ plugin_get_errors (PluginObject *obj,
|
|||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
plugin_launch_extension_prefs (PluginObject *obj,
|
plugin_launch_extension_prefs (PluginObject *obj,
|
||||||
NPString uuid,
|
uint32_t argc,
|
||||||
|
const NPVariant *argv,
|
||||||
NPVariant *result)
|
NPVariant *result)
|
||||||
{
|
{
|
||||||
gchar *uuid_str;
|
gchar *uuid;
|
||||||
|
|
||||||
uuid_str = g_strndup (uuid.UTF8Characters, uuid.UTF8Length);
|
if (!parse_args ("u", argc, argv, &uuid))
|
||||||
if (!uuid_is_valid (uuid_str))
|
|
||||||
{
|
|
||||||
g_free (uuid_str);
|
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
|
||||||
|
|
||||||
g_dbus_proxy_call (obj->proxy,
|
g_dbus_proxy_call (obj->proxy,
|
||||||
"LaunchExtensionPrefs",
|
"LaunchExtensionPrefs",
|
||||||
g_variant_new ("(s)", uuid_str),
|
g_variant_new ("(s)", uuid),
|
||||||
G_DBUS_CALL_FLAGS_NONE,
|
G_DBUS_CALL_FLAGS_NONE,
|
||||||
-1, /* timeout */
|
-1, /* timeout */
|
||||||
NULL, /* cancellable */
|
NULL, /* cancellable */
|
||||||
NULL, /* callback */
|
NULL, /* callback */
|
||||||
NULL /* user_data */);
|
NULL /* user_data */);
|
||||||
|
|
||||||
g_free (uuid_str);
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -733,10 +835,40 @@ plugin_get_shell_version (PluginObject *obj,
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define METHODS \
|
||||||
|
METHOD (list_extensions) \
|
||||||
|
METHOD (get_info) \
|
||||||
|
METHOD (enable_extension) \
|
||||||
|
METHOD (install_extension) \
|
||||||
|
METHOD (uninstall_extension) \
|
||||||
|
METHOD (get_errors) \
|
||||||
|
METHOD (launch_extension_prefs) \
|
||||||
|
/* */
|
||||||
|
|
||||||
|
#define METHOD(x) \
|
||||||
|
static NPIdentifier x##_id;
|
||||||
|
METHODS
|
||||||
|
#undef METHOD
|
||||||
|
|
||||||
|
static NPIdentifier api_version_id;
|
||||||
|
static NPIdentifier shell_version_id;
|
||||||
|
static NPIdentifier onextension_changed_id;
|
||||||
|
static NPIdentifier onrestart_id;
|
||||||
|
|
||||||
|
static bool
|
||||||
|
plugin_object_has_method (NPObject *npobj,
|
||||||
|
NPIdentifier name)
|
||||||
|
{
|
||||||
|
#define METHOD(x) (name == (x##_id)) ||
|
||||||
|
/* expands to (name == list_extensions_id) || FALSE; */
|
||||||
|
return METHODS FALSE;
|
||||||
|
#undef METHOD
|
||||||
|
}
|
||||||
|
|
||||||
static bool
|
static bool
|
||||||
plugin_object_invoke (NPObject *npobj,
|
plugin_object_invoke (NPObject *npobj,
|
||||||
NPIdentifier name,
|
NPIdentifier name,
|
||||||
const NPVariant *args,
|
const NPVariant *argv,
|
||||||
uint32_t argc,
|
uint32_t argc,
|
||||||
NPVariant *result)
|
NPVariant *result)
|
||||||
{
|
{
|
||||||
@ -748,61 +880,13 @@ plugin_object_invoke (NPObject *npobj,
|
|||||||
|
|
||||||
VOID_TO_NPVARIANT (*result);
|
VOID_TO_NPVARIANT (*result);
|
||||||
|
|
||||||
if (!plugin_object_has_method (npobj, name))
|
#define METHOD(x) \
|
||||||
|
if (name == x##_id) \
|
||||||
|
return plugin_##x (obj, argc, argv, result);
|
||||||
|
METHODS
|
||||||
|
#undef METHOD
|
||||||
|
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
if (name == list_extensions_id)
|
|
||||||
return plugin_list_extensions (obj, result);
|
|
||||||
else if (name == get_info_id)
|
|
||||||
{
|
|
||||||
if (!NPVARIANT_IS_STRING(args[0])) return FALSE;
|
|
||||||
|
|
||||||
return plugin_get_info (obj, NPVARIANT_TO_STRING(args[0]), result);
|
|
||||||
}
|
|
||||||
else if (name == enable_extension_id)
|
|
||||||
{
|
|
||||||
if (!NPVARIANT_IS_STRING(args[0])) return FALSE;
|
|
||||||
if (!NPVARIANT_IS_BOOLEAN(args[1])) return FALSE;
|
|
||||||
|
|
||||||
return plugin_enable_extension (obj,
|
|
||||||
NPVARIANT_TO_STRING(args[0]),
|
|
||||||
NPVARIANT_TO_BOOLEAN(args[1]));
|
|
||||||
}
|
|
||||||
else if (name == install_extension_id)
|
|
||||||
{
|
|
||||||
if (!NPVARIANT_IS_STRING(args[0])) return FALSE;
|
|
||||||
if (!NPVARIANT_IS_STRING(args[1])) return FALSE;
|
|
||||||
|
|
||||||
return plugin_install_extension (obj,
|
|
||||||
NPVARIANT_TO_STRING(args[0]),
|
|
||||||
NPVARIANT_TO_STRING(args[1]));
|
|
||||||
}
|
|
||||||
else if (name == uninstall_extension_id)
|
|
||||||
{
|
|
||||||
if (!NPVARIANT_IS_STRING(args[0])) return FALSE;
|
|
||||||
|
|
||||||
return plugin_uninstall_extension (obj,
|
|
||||||
NPVARIANT_TO_STRING(args[0]),
|
|
||||||
result);
|
|
||||||
}
|
|
||||||
else if (name == get_errors_id)
|
|
||||||
{
|
|
||||||
if (!NPVARIANT_IS_STRING(args[0])) return FALSE;
|
|
||||||
|
|
||||||
return plugin_get_errors (obj,
|
|
||||||
NPVARIANT_TO_STRING(args[0]),
|
|
||||||
result);
|
|
||||||
}
|
|
||||||
else if (name == launch_extension_prefs_id)
|
|
||||||
{
|
|
||||||
if (!NPVARIANT_IS_STRING(args[0])) return FALSE;
|
|
||||||
|
|
||||||
return plugin_launch_extension_prefs (obj,
|
|
||||||
NPVARIANT_TO_STRING(args[0]),
|
|
||||||
result);
|
|
||||||
}
|
|
||||||
|
|
||||||
return TRUE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool
|
static bool
|
||||||
@ -946,3 +1030,12 @@ NPP_GetValue(NPP instance,
|
|||||||
|
|
||||||
return NPERR_NO_ERROR;
|
return NPERR_NO_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Opera tries to call NPP_SetWindow without checking the
|
||||||
|
* NULL pointer beforehand. */
|
||||||
|
NPError
|
||||||
|
NPP_SetWindow(NPP instance,
|
||||||
|
NPWindow *window)
|
||||||
|
{
|
||||||
|
return NPERR_NO_ERROR;
|
||||||
|
}
|
||||||
|
63
configure.ac
63
configure.ac
@ -1,5 +1,5 @@
|
|||||||
AC_PREREQ(2.63)
|
AC_PREREQ(2.63)
|
||||||
AC_INIT([gnome-shell],[3.4.0],[https://bugzilla.gnome.org/enter_bug.cgi?product=gnome-shell],[gnome-shell])
|
AC_INIT([gnome-shell],[3.5.4],[https://bugzilla.gnome.org/enter_bug.cgi?product=gnome-shell],[gnome-shell])
|
||||||
|
|
||||||
AC_CONFIG_HEADERS([config.h])
|
AC_CONFIG_HEADERS([config.h])
|
||||||
AC_CONFIG_SRCDIR([src/shell-global.c])
|
AC_CONFIG_SRCDIR([src/shell-global.c])
|
||||||
@ -44,15 +44,15 @@ AC_SUBST(PYTHON)
|
|||||||
|
|
||||||
# We need at least this, since gst_plugin_register_static() was added
|
# We need at least this, since gst_plugin_register_static() was added
|
||||||
# in 0.10.16, but nothing older than 0.10.21 has been tested.
|
# in 0.10.16, but nothing older than 0.10.21 has been tested.
|
||||||
GSTREAMER_MIN_VERSION=0.10.16
|
GSTREAMER_MIN_VERSION=0.11.92
|
||||||
|
|
||||||
recorder_modules=
|
recorder_modules=
|
||||||
build_recorder=false
|
build_recorder=false
|
||||||
AC_MSG_CHECKING([for GStreamer (needed for recording functionality)])
|
AC_MSG_CHECKING([for GStreamer (needed for recording functionality)])
|
||||||
if $PKG_CONFIG --exists gstreamer-0.10 '>=' $GSTREAMER_MIN_VERSION ; then
|
if $PKG_CONFIG --exists gstreamer-1.0 '>=' $GSTREAMER_MIN_VERSION ; then
|
||||||
AC_MSG_RESULT(yes)
|
AC_MSG_RESULT(yes)
|
||||||
build_recorder=true
|
build_recorder=true
|
||||||
recorder_modules="gstreamer-0.10 gstreamer-base-0.10 x11"
|
recorder_modules="gstreamer-1.0 gstreamer-base-1.0 x11"
|
||||||
PKG_CHECK_MODULES(TEST_SHELL_RECORDER, $recorder_modules clutter-1.0 xfixes gl)
|
PKG_CHECK_MODULES(TEST_SHELL_RECORDER, $recorder_modules clutter-1.0 xfixes gl)
|
||||||
else
|
else
|
||||||
AC_MSG_RESULT(no)
|
AC_MSG_RESULT(no)
|
||||||
@ -62,28 +62,30 @@ AM_CONDITIONAL(BUILD_RECORDER, $build_recorder)
|
|||||||
|
|
||||||
CLUTTER_MIN_VERSION=1.9.16
|
CLUTTER_MIN_VERSION=1.9.16
|
||||||
GOBJECT_INTROSPECTION_MIN_VERSION=0.10.1
|
GOBJECT_INTROSPECTION_MIN_VERSION=0.10.1
|
||||||
GJS_MIN_VERSION=1.29.18
|
GJS_MIN_VERSION=1.33.2
|
||||||
MUTTER_MIN_VERSION=3.3.92
|
MUTTER_MIN_VERSION=3.5.4
|
||||||
FOLKS_MIN_VERSION=0.5.2
|
|
||||||
GTK_MIN_VERSION=3.3.9
|
GTK_MIN_VERSION=3.3.9
|
||||||
GIO_MIN_VERSION=2.31.6
|
GIO_MIN_VERSION=2.31.6
|
||||||
LIBECAL_MIN_VERSION=2.32.0
|
LIBECAL_MIN_VERSION=3.5.3
|
||||||
LIBEDATASERVER_MIN_VERSION=1.2.0
|
LIBEDATASERVER_MIN_VERSION=3.5.3
|
||||||
LIBEDATASERVERUI_MIN_VERSION=2.91.6
|
LIBEDATASERVERUI_MIN_VERSION=3.5.3
|
||||||
TELEPATHY_GLIB_MIN_VERSION=0.17.5
|
TELEPATHY_GLIB_MIN_VERSION=0.17.5
|
||||||
TELEPATHY_LOGGER_MIN_VERSION=0.2.4
|
TELEPATHY_LOGGER_MIN_VERSION=0.2.4
|
||||||
POLKIT_MIN_VERSION=0.100
|
POLKIT_MIN_VERSION=0.100
|
||||||
STARTUP_NOTIFICATION_MIN_VERSION=0.11
|
STARTUP_NOTIFICATION_MIN_VERSION=0.11
|
||||||
GCR_MIN_VERSION=3.3.90
|
GCR_MIN_VERSION=3.3.90
|
||||||
|
GNOME_DESKTOP_REQUIRED_VERSION=3.5.1
|
||||||
|
GNOME_MENUS_REQUIRED_VERSION=3.5.3
|
||||||
|
|
||||||
# Collect more than 20 libraries for a prize!
|
# Collect more than 20 libraries for a prize!
|
||||||
PKG_CHECK_MODULES(GNOME_SHELL, gio-unix-2.0 >= $GIO_MIN_VERSION
|
PKG_CHECK_MODULES(GNOME_SHELL, gio-unix-2.0 >= $GIO_MIN_VERSION
|
||||||
libxml-2.0
|
libxml-2.0
|
||||||
gtk+-3.0 >= $GTK_MIN_VERSION
|
gtk+-3.0 >= $GTK_MIN_VERSION
|
||||||
folks >= $FOLKS_MIN_VERSION
|
atk-bridge-2.0
|
||||||
libmutter >= $MUTTER_MIN_VERSION
|
libmutter >= $MUTTER_MIN_VERSION
|
||||||
gjs-internals-1.0 >= $GJS_MIN_VERSION
|
gjs-internals-1.0 >= $GJS_MIN_VERSION
|
||||||
libgnome-menu-3.0 $recorder_modules
|
libgnome-menu-3.0 >= $GNOME_MENUS_REQUIRED_VERSION
|
||||||
|
$recorder_modules
|
||||||
gdk-x11-3.0 libsoup-2.4
|
gdk-x11-3.0 libsoup-2.4
|
||||||
gl
|
gl
|
||||||
clutter-x11-1.0 >= $CLUTTER_MIN_VERSION
|
clutter-x11-1.0 >= $CLUTTER_MIN_VERSION
|
||||||
@ -95,7 +97,8 @@ PKG_CHECK_MODULES(GNOME_SHELL, gio-unix-2.0 >= $GIO_MIN_VERSION
|
|||||||
telepathy-logger-0.2 >= $TELEPATHY_LOGGER_MIN_VERSION
|
telepathy-logger-0.2 >= $TELEPATHY_LOGGER_MIN_VERSION
|
||||||
polkit-agent-1 >= $POLKIT_MIN_VERSION xfixes
|
polkit-agent-1 >= $POLKIT_MIN_VERSION xfixes
|
||||||
libnm-glib libnm-util gnome-keyring-1
|
libnm-glib libnm-util gnome-keyring-1
|
||||||
gcr-3 >= $GCR_MIN_VERSION)
|
gcr-3 >= $GCR_MIN_VERSION
|
||||||
|
gnome-desktop-3.0 >= $GNOME_DESKTOP_REQUIRED_VERSION)
|
||||||
|
|
||||||
PKG_CHECK_MODULES(SHELL_PERF_HELPER, gtk+-3.0 gio-2.0)
|
PKG_CHECK_MODULES(SHELL_PERF_HELPER, gtk+-3.0 gio-2.0)
|
||||||
|
|
||||||
@ -103,13 +106,7 @@ PKG_CHECK_MODULES(SHELL_HOTPLUG_SNIFFER, gio-2.0 gdk-pixbuf-2.0)
|
|||||||
|
|
||||||
PKG_CHECK_MODULES(BROWSER_PLUGIN, gio-2.0 >= $GIO_MIN_VERSION json-glib-1.0 >= 0.13.2)
|
PKG_CHECK_MODULES(BROWSER_PLUGIN, gio-2.0 >= $GIO_MIN_VERSION json-glib-1.0 >= 0.13.2)
|
||||||
|
|
||||||
GJS_VERSION=`$PKG_CONFIG --modversion gjs-internals-1.0`
|
|
||||||
AC_DEFINE_UNQUOTED([GJS_VERSION], ["$GJS_VERSION"], [The version of GJS we're linking to])
|
|
||||||
AC_SUBST([GJS_VERSION], ["$GJS_VERSION"])
|
|
||||||
|
|
||||||
GOBJECT_INTROSPECTION_CHECK([$GOBJECT_INTROSPECTION_MIN_VERSION])
|
GOBJECT_INTROSPECTION_CHECK([$GOBJECT_INTROSPECTION_MIN_VERSION])
|
||||||
JHBUILD_TYPELIBDIR="$INTROSPECTION_TYPELIBDIR"
|
|
||||||
AC_SUBST(JHBUILD_TYPELIBDIR)
|
|
||||||
|
|
||||||
saved_CFLAGS=$CFLAGS
|
saved_CFLAGS=$CFLAGS
|
||||||
saved_LIBS=$LIBS
|
saved_LIBS=$LIBS
|
||||||
@ -123,7 +120,7 @@ PKG_CHECK_MODULES(GNOME_SHELL_JS, gio-2.0 gjs-internals-1.0 >= $GJS_MIN_VERSION)
|
|||||||
PKG_CHECK_MODULES(ST, clutter-1.0 gtk+-3.0 libcroco-0.6 >= 0.6.2 x11)
|
PKG_CHECK_MODULES(ST, clutter-1.0 gtk+-3.0 libcroco-0.6 >= 0.6.2 x11)
|
||||||
PKG_CHECK_MODULES(TRAY, gtk+-3.0)
|
PKG_CHECK_MODULES(TRAY, gtk+-3.0)
|
||||||
PKG_CHECK_MODULES(GVC, libpulse libpulse-mainloop-glib gobject-2.0)
|
PKG_CHECK_MODULES(GVC, libpulse libpulse-mainloop-glib gobject-2.0)
|
||||||
PKG_CHECK_MODULES(DESKTOP_SCHEMAS, gsettings-desktop-schemas >= 0.1.7)
|
PKG_CHECK_MODULES(DESKTOP_SCHEMAS, gsettings-desktop-schemas >= 3.5.1)
|
||||||
|
|
||||||
AC_MSG_CHECKING([for bluetooth support])
|
AC_MSG_CHECKING([for bluetooth support])
|
||||||
PKG_CHECK_EXISTS([gnome-bluetooth-1.0 >= 3.1.0],
|
PKG_CHECK_EXISTS([gnome-bluetooth-1.0 >= 3.1.0],
|
||||||
@ -239,31 +236,6 @@ AC_ARG_ENABLE(jhbuild-wrapper-script,
|
|||||||
AS_HELP_STRING([--enable-jhbuild-wrapper-script],[Make "gnome-shell" script work for jhbuild]),,enable_jhbuild_wrapper_script=no)
|
AS_HELP_STRING([--enable-jhbuild-wrapper-script],[Make "gnome-shell" script work for jhbuild]),,enable_jhbuild_wrapper_script=no)
|
||||||
AM_CONDITIONAL(USE_JHBUILD_WRAPPER_SCRIPT, test "x$enable_jhbuild_wrapper_script" = xyes)
|
AM_CONDITIONAL(USE_JHBUILD_WRAPPER_SCRIPT, test "x$enable_jhbuild_wrapper_script" = xyes)
|
||||||
|
|
||||||
AC_MSG_CHECKING([location of system Certificate Authority list])
|
|
||||||
AC_ARG_WITH(ca-certificates,
|
|
||||||
[AC_HELP_STRING([--with-ca-certificates=@<:@path@:>@],
|
|
||||||
[path to system Certificate Authority list])])
|
|
||||||
|
|
||||||
if test "$with_ca_certificates" = "no"; then
|
|
||||||
AC_MSG_RESULT([disabled])
|
|
||||||
else
|
|
||||||
if test -z "$with_ca_certificates"; then
|
|
||||||
for f in /etc/pki/tls/certs/ca-bundle.crt \
|
|
||||||
/etc/ssl/certs/ca-certificates.crt; do
|
|
||||||
if test -f "$f"; then
|
|
||||||
with_ca_certificates="$f"
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
if test -z "$with_ca_certificates"; then
|
|
||||||
AC_MSG_ERROR([could not find. Use --with-ca-certificates=path to set, or --without-ca-certificates to disable])
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
|
|
||||||
AC_MSG_RESULT($with_ca_certificates)
|
|
||||||
AC_DEFINE_UNQUOTED(SHELL_SYSTEM_CA_FILE, ["$with_ca_certificates"], [The system TLS CA list])
|
|
||||||
fi
|
|
||||||
AC_SUBST(SHELL_SYSTEM_CA_FILE,["$with_ca_certificates"])
|
|
||||||
|
|
||||||
BROWSER_PLUGIN_DIR="${BROWSER_PLUGIN_DIR:-"\${libdir}/mozilla/plugins"}"
|
BROWSER_PLUGIN_DIR="${BROWSER_PLUGIN_DIR:-"\${libdir}/mozilla/plugins"}"
|
||||||
AC_ARG_VAR([BROWSER_PLUGIN_DIR],[Where to install the plugin to])
|
AC_ARG_VAR([BROWSER_PLUGIN_DIR],[Where to install the plugin to])
|
||||||
|
|
||||||
@ -277,6 +249,7 @@ AC_CONFIG_FILES([
|
|||||||
docs/reference/st/Makefile
|
docs/reference/st/Makefile
|
||||||
docs/reference/st/st-docs.sgml
|
docs/reference/st/st-docs.sgml
|
||||||
js/Makefile
|
js/Makefile
|
||||||
|
src/calendar-server/evolution-calendar.desktop.in
|
||||||
src/Makefile
|
src/Makefile
|
||||||
browser-plugin/Makefile
|
browser-plugin/Makefile
|
||||||
tests/Makefile
|
tests/Makefile
|
||||||
|
@ -56,6 +56,11 @@ dist_theme_DATA = \
|
|||||||
gsettings_SCHEMAS = org.gnome.shell.gschema.xml
|
gsettings_SCHEMAS = org.gnome.shell.gschema.xml
|
||||||
|
|
||||||
@INTLTOOL_XML_NOMERGE_RULE@
|
@INTLTOOL_XML_NOMERGE_RULE@
|
||||||
|
|
||||||
|
%.gschema.xml.in: %.gschema.xml.in.in Makefile
|
||||||
|
$(AM_V_GEN) sed -e 's|@GETTEXT_PACKAGE[@]|$(GETTEXT_PACKAGE)|g' \
|
||||||
|
$< > $@ || rm $@
|
||||||
|
|
||||||
@GSETTINGS_RULES@
|
@GSETTINGS_RULES@
|
||||||
|
|
||||||
# We need to compile schemas at make time
|
# We need to compile schemas at make time
|
||||||
@ -68,24 +73,19 @@ all-local: gschemas.compiled
|
|||||||
convertdir = $(datadir)/GConf/gsettings
|
convertdir = $(datadir)/GConf/gsettings
|
||||||
convert_DATA = gnome-shell-overrides.convert
|
convert_DATA = gnome-shell-overrides.convert
|
||||||
|
|
||||||
shadersdir = $(pkgdatadir)/shaders
|
|
||||||
shaders_DATA = \
|
|
||||||
shaders/dim-window.glsl
|
|
||||||
|
|
||||||
|
|
||||||
EXTRA_DIST = \
|
EXTRA_DIST = \
|
||||||
gnome-shell.desktop.in.in \
|
gnome-shell.desktop.in.in \
|
||||||
gnome-shell-extension-prefs.desktop.in.in \
|
gnome-shell-extension-prefs.desktop.in.in \
|
||||||
$(introspection_DATA) \
|
$(introspection_DATA) \
|
||||||
$(menu_DATA) \
|
$(menu_DATA) \
|
||||||
$(shaders_DATA) \
|
|
||||||
$(convert_DATA) \
|
$(convert_DATA) \
|
||||||
org.gnome.shell.gschema.xml.in
|
org.gnome.shell.gschema.xml.in.in
|
||||||
|
|
||||||
CLEANFILES = \
|
CLEANFILES = \
|
||||||
gnome-shell.desktop.in \
|
gnome-shell.desktop.in \
|
||||||
gnome-shell-extension-prefs.in \
|
gnome-shell-extension-prefs.in \
|
||||||
$(desktop_DATA) \
|
$(desktop_DATA) \
|
||||||
$(gsettings_SCHEMAS) \
|
$(gsettings_SCHEMAS) \
|
||||||
gschemas.compiled
|
gschemas.compiled \
|
||||||
|
org.gnome.shell.gschema.valid \
|
||||||
|
org.gnome.shell.gschema.xml.in
|
||||||
|
@ -61,9 +61,9 @@ value here is from the TpConnectionPresenceType enumeration.</_summary>
|
|||||||
<_summary>Internally used to store the last session presence status for the user. The
|
<_summary>Internally used to store the last session presence status for the user. The
|
||||||
value here is from the GsmPresenceStatus enumeration.</_summary>
|
value here is from the GsmPresenceStatus enumeration.</_summary>
|
||||||
</key>
|
</key>
|
||||||
<child name="clock" schema="org.gnome.shell.clock"/>
|
|
||||||
<child name="calendar" schema="org.gnome.shell.calendar"/>
|
<child name="calendar" schema="org.gnome.shell.calendar"/>
|
||||||
<child name="recorder" schema="org.gnome.shell.recorder"/>
|
<child name="recorder" schema="org.gnome.shell.recorder"/>
|
||||||
|
<child name="keybindings" schema="org.gnome.shell.keybindings"/>
|
||||||
<child name="keyboard" schema="org.gnome.shell.keyboard"/>
|
<child name="keyboard" schema="org.gnome.shell.keyboard"/>
|
||||||
</schema>
|
</schema>
|
||||||
|
|
||||||
@ -78,6 +78,24 @@ value here is from the GsmPresenceStatus enumeration.</_summary>
|
|||||||
</key>
|
</key>
|
||||||
</schema>
|
</schema>
|
||||||
|
|
||||||
|
<schema id="org.gnome.shell.keybindings" path="/org/gnome/shell/keybindings/"
|
||||||
|
gettext-domain="@GETTEXT_PACKAGE@">
|
||||||
|
<key name="open-application-menu" type="as">
|
||||||
|
<default>["<Super>F10"]</default>
|
||||||
|
<_summary>Keybinding to open the application menu</_summary>
|
||||||
|
<_description>
|
||||||
|
Keybinding to open the application menu.
|
||||||
|
</_description>
|
||||||
|
</key>
|
||||||
|
<key name="toggle-recording" type="as">
|
||||||
|
<default><![CDATA[['<Control><Shift><Alt>r']]]></default>
|
||||||
|
<_summary>Keybinding to toggle the screen recorder</_summary>
|
||||||
|
<_description>
|
||||||
|
Keybinding to start/stop the builtin screen recorder.
|
||||||
|
</_description>
|
||||||
|
</key>
|
||||||
|
</schema>
|
||||||
|
|
||||||
<schema id="org.gnome.shell.keyboard" path="/org/gnome/shell/keyboard/"
|
<schema id="org.gnome.shell.keyboard" path="/org/gnome/shell/keyboard/"
|
||||||
gettext-domain="@GETTEXT_PACKAGE@">
|
gettext-domain="@GETTEXT_PACKAGE@">
|
||||||
<key name="keyboard-type" type="s">
|
<key name="keyboard-type" type="s">
|
||||||
@ -89,24 +107,6 @@ value here is from the GsmPresenceStatus enumeration.</_summary>
|
|||||||
</key>
|
</key>
|
||||||
</schema>
|
</schema>
|
||||||
|
|
||||||
<schema id="org.gnome.shell.clock" path="/org/gnome/shell/clock/"
|
|
||||||
gettext-domain="@GETTEXT_PACKAGE@">
|
|
||||||
<key name="show-seconds" type="b">
|
|
||||||
<default>false</default>
|
|
||||||
<_summary>Show time with seconds</_summary>
|
|
||||||
<_description>
|
|
||||||
If true, display seconds in time.
|
|
||||||
</_description>
|
|
||||||
</key>
|
|
||||||
<key name="show-date" type="b">
|
|
||||||
<default>false</default>
|
|
||||||
<_summary>Show date in clock</_summary>
|
|
||||||
<_description>
|
|
||||||
If true, display date in the clock, in addition to time.
|
|
||||||
</_description>
|
|
||||||
</key>
|
|
||||||
</schema>
|
|
||||||
|
|
||||||
<schema id="org.gnome.shell.recorder" path="/org/gnome/shell/recorder/"
|
<schema id="org.gnome.shell.recorder" path="/org/gnome/shell/recorder/"
|
||||||
gettext-domain="@GETTEXT_PACKAGE@">
|
gettext-domain="@GETTEXT_PACKAGE@">
|
||||||
<key name="framerate" type="i">
|
<key name="framerate" type="i">
|
@ -1,27 +0,0 @@
|
|||||||
#version 110
|
|
||||||
uniform sampler2D tex;
|
|
||||||
uniform float fraction;
|
|
||||||
uniform float height;
|
|
||||||
const float c = -0.2;
|
|
||||||
const float border_max_height = 60.0;
|
|
||||||
|
|
||||||
mat4 contrast = mat4 (1.0 + c, 0.0, 0.0, 0.0,
|
|
||||||
0.0, 1.0 + c, 0.0, 0.0,
|
|
||||||
0.0, 0.0, 1.0 + c, 0.0,
|
|
||||||
0.0, 0.0, 0.0, 1.0);
|
|
||||||
vec4 off = vec4(0.633, 0.633, 0.633, 0);
|
|
||||||
void main()
|
|
||||||
{
|
|
||||||
vec4 color = texture2D(tex, cogl_tex_coord_in[0].xy);
|
|
||||||
float y = height * cogl_tex_coord_in[0].y;
|
|
||||||
|
|
||||||
// To reduce contrast, blend with a mid gray
|
|
||||||
cogl_color_out = color * contrast - off * c * color.a;
|
|
||||||
|
|
||||||
// We only fully dim at a distance of BORDER_MAX_HEIGHT from the top and
|
|
||||||
// when the fraction is 1.0. For other locations and fractions we linearly
|
|
||||||
// interpolate back to the original undimmed color, so the top of the window
|
|
||||||
// is at full color.
|
|
||||||
cogl_color_out = color + (cogl_color_out - color) * max(min(y / border_max_height, 1.0), 0.0);
|
|
||||||
cogl_color_out = color + (cogl_color_out - color) * fraction;
|
|
||||||
}
|
|
@ -16,6 +16,14 @@
|
|||||||
|
|
||||||
/* Login Dialog */
|
/* Login Dialog */
|
||||||
|
|
||||||
|
.login-dialog-banner {
|
||||||
|
font-size: 10pt;
|
||||||
|
font-weight: bold;
|
||||||
|
text-align: center;
|
||||||
|
color: #666666;
|
||||||
|
padding-bottom: 1em;
|
||||||
|
}
|
||||||
|
|
||||||
.login-dialog-title {
|
.login-dialog-title {
|
||||||
font-size: 14pt;
|
font-size: 14pt;
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
|
@ -328,6 +328,11 @@ StScrollBar StButton#vhandle:hover
|
|||||||
background-gradient-end: rgba(255, 255, 255, 0.2);
|
background-gradient-end: rgba(255, 255, 255, 0.2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.notification-icon-button:insensitive,
|
||||||
|
.notification-button:insensitive {
|
||||||
|
color: #9f9f9f;
|
||||||
|
}
|
||||||
|
|
||||||
/* Panel */
|
/* Panel */
|
||||||
|
|
||||||
#panel {
|
#panel {
|
||||||
@ -357,7 +362,7 @@ StScrollBar StButton#vhandle:hover
|
|||||||
}
|
}
|
||||||
|
|
||||||
.panel-corner {
|
.panel-corner {
|
||||||
-panel-corner-radius: 10px;
|
-panel-corner-radius: 6px;
|
||||||
-panel-corner-background-color: black;
|
-panel-corner-background-color: black;
|
||||||
-panel-corner-border-width: 2px;
|
-panel-corner-border-width: 2px;
|
||||||
-panel-corner-border-color: transparent;
|
-panel-corner-border-color: transparent;
|
||||||
@ -409,7 +414,7 @@ StScrollBar StButton#vhandle:hover
|
|||||||
.panel-button:active,
|
.panel-button:active,
|
||||||
.panel-button:overview,
|
.panel-button:overview,
|
||||||
.panel-button:focus {
|
.panel-button:focus {
|
||||||
border-image: url("panel-button-border.svg") 10 10 0 2;
|
border-image: url("panel-button-border.svg") 6 10 0 2;
|
||||||
background-image: url("panel-button-highlight-wide.svg");
|
background-image: url("panel-button-highlight-wide.svg");
|
||||||
color: white;
|
color: white;
|
||||||
text-shadow: black 0px 2px 2px;
|
text-shadow: black 0px 2px 2px;
|
||||||
@ -431,6 +436,10 @@ StScrollBar StButton#vhandle:hover
|
|||||||
-boxpointer-gap: 4px
|
-boxpointer-gap: 4px
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#networkMenu {
|
||||||
|
spacing: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
/* User Menu */
|
/* User Menu */
|
||||||
|
|
||||||
#panelUserMenu {
|
#panelUserMenu {
|
||||||
@ -794,58 +803,8 @@ StScrollBar StButton#vhandle:hover
|
|||||||
transition-duration: 100;
|
transition-duration: 100;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Contacts */
|
|
||||||
|
|
||||||
.contact-grid {
|
|
||||||
spacing: 36px;
|
|
||||||
-shell-grid-horizontal-item-size: 272px; /* 2 * -shell-grid-horizontal-item-size + spacing */
|
|
||||||
-shell-grid-vertical-item-size: 118px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.contact {
|
|
||||||
width: 272px; /* Same width as two normal results + spacing */
|
|
||||||
height: 118px; /* Aspect ratio = 1.75. Normal US business card ratio */
|
|
||||||
border-radius: 4px;
|
|
||||||
padding: 3px;
|
|
||||||
border: 1px rgba(0,0,0,0);
|
|
||||||
transition-duration: 100;
|
|
||||||
}
|
|
||||||
|
|
||||||
.contact-content {
|
|
||||||
border-radius: 7px;
|
|
||||||
padding: 8px;
|
|
||||||
width: 232px;
|
|
||||||
height: 84px;
|
|
||||||
background-color: rgba(0.0, 0.0, 0.0, 0.5);
|
|
||||||
color: white;
|
|
||||||
}
|
|
||||||
|
|
||||||
.contact-icon {
|
|
||||||
border-radius: 4px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.contact-details {
|
|
||||||
padding: 0px 6px 22px 10px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.contact-details-alias {
|
|
||||||
font-size: 18px;
|
|
||||||
padding-bottom: 8px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.contact-details-status-icon {
|
|
||||||
padding-right: 4px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.contact:hover {
|
|
||||||
background-color: rgba(255,255,255,0.1);
|
|
||||||
transition-duration: 100;
|
|
||||||
}
|
|
||||||
|
|
||||||
.contact:focus,
|
|
||||||
.app-well-app:focus > .overview-icon,
|
.app-well-app:focus > .overview-icon,
|
||||||
.search-result-content:focus > .overview-icon,
|
.search-result-content:focus > .overview-icon,
|
||||||
.contact:selected,
|
|
||||||
.app-well-app:selected > .overview-icon,
|
.app-well-app:selected > .overview-icon,
|
||||||
.search-result-content:selected > .overview-icon {
|
.search-result-content:selected > .overview-icon {
|
||||||
background-color: rgba(255,255,255,0.33);
|
background-color: rgba(255,255,255,0.33);
|
||||||
@ -1057,6 +1016,7 @@ StScrollBar StButton#vhandle:hover
|
|||||||
padding: .4em 1.75em;
|
padding: .4em 1.75em;
|
||||||
color: #cccccc;
|
color: #cccccc;
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
|
text-align: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
.calendar-day-base {
|
.calendar-day-base {
|
||||||
@ -1203,7 +1163,8 @@ StScrollBar StButton#vhandle:hover
|
|||||||
height: 36px;
|
height: 36px;
|
||||||
}
|
}
|
||||||
|
|
||||||
#notification {
|
.notification {
|
||||||
|
font-size: 11pt;
|
||||||
border-radius: 10px 10px 0px 0px;
|
border-radius: 10px 10px 0px 0px;
|
||||||
background: rgba(0,0,0,0.8);
|
background: rgba(0,0,0,0.8);
|
||||||
padding: 8px 8px 4px 8px;
|
padding: 8px 8px 4px 8px;
|
||||||
@ -1212,7 +1173,7 @@ StScrollBar StButton#vhandle:hover
|
|||||||
width: 34em;
|
width: 34em;
|
||||||
}
|
}
|
||||||
|
|
||||||
#notification.multi-line-notification {
|
.notification.multi-line-notification {
|
||||||
padding-bottom: 8px;
|
padding-bottom: 8px;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1234,7 +1195,7 @@ StScrollBar StButton#vhandle:hover
|
|||||||
color: white;
|
color: white;
|
||||||
}
|
}
|
||||||
|
|
||||||
.summary-boxpointer #notification {
|
.summary-boxpointer .notification {
|
||||||
border-radius: 9px;
|
border-radius: 9px;
|
||||||
background: rgba(0,0,0,0) !important;
|
background: rgba(0,0,0,0) !important;
|
||||||
padding-bottom: 12px;
|
padding-bottom: 12px;
|
||||||
@ -1251,10 +1212,6 @@ StScrollBar StButton#vhandle:hover
|
|||||||
padding-bottom: 6px;
|
padding-bottom: 6px;
|
||||||
}
|
}
|
||||||
|
|
||||||
#summary-notification-stack-scrollview > .top-shadow, #summary-notification-stack-scrollview > .bottom-shadow {
|
|
||||||
height: 1em;
|
|
||||||
}
|
|
||||||
|
|
||||||
#summary-notification-stack-scrollview:ltr {
|
#summary-notification-stack-scrollview:ltr {
|
||||||
padding-right: 8px;
|
padding-right: 8px;
|
||||||
}
|
}
|
||||||
@ -1263,28 +1220,24 @@ StScrollBar StButton#vhandle:hover
|
|||||||
padding-left: 8px;
|
padding-left: 8px;
|
||||||
}
|
}
|
||||||
|
|
||||||
#notification-scrollview {
|
.notification-scrollview {
|
||||||
max-height: 10em;
|
max-height: 10em;
|
||||||
-st-vfade-offset: 24px;
|
-st-vfade-offset: 24px;
|
||||||
}
|
}
|
||||||
|
|
||||||
#notification-scrollview > .top-shadow, #notification-scrollview > .bottom-shadow {
|
.notification-scrollview:ltr > StScrollBar {
|
||||||
height: 1em;
|
|
||||||
}
|
|
||||||
|
|
||||||
#notification-scrollview:ltr > StScrollBar {
|
|
||||||
padding-left: 6px;
|
padding-left: 6px;
|
||||||
}
|
}
|
||||||
|
|
||||||
#notification-scrollview:rtl > StScrollBar {
|
.notification-scrollview:rtl > StScrollBar {
|
||||||
padding-right: 6px;
|
padding-right: 6px;
|
||||||
}
|
}
|
||||||
|
|
||||||
#notification-body {
|
.notification-body {
|
||||||
spacing: 5px;
|
spacing: 5px;
|
||||||
}
|
}
|
||||||
|
|
||||||
#notification-actions {
|
.notification-actions {
|
||||||
spacing: 10px;
|
spacing: 10px;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1311,6 +1264,10 @@ StScrollBar StButton#vhandle:hover
|
|||||||
padding: 8px;
|
padding: 8px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.secondary-icon {
|
||||||
|
icon-size: 1.09em;
|
||||||
|
}
|
||||||
|
|
||||||
.hotplug-transient-box {
|
.hotplug-transient-box {
|
||||||
spacing: 6px;
|
spacing: 6px;
|
||||||
padding: 2px 72px 2px 12px;
|
padding: 2px 72px 2px 12px;
|
||||||
@ -1411,7 +1368,7 @@ StScrollBar StButton#vhandle:hover
|
|||||||
font-style: italic;
|
font-style: italic;
|
||||||
}
|
}
|
||||||
|
|
||||||
#notification StEntry {
|
.notification StEntry {
|
||||||
padding: 4px;
|
padding: 4px;
|
||||||
border-radius: 4px;
|
border-radius: 4px;
|
||||||
color: #a8a8a8;
|
color: #a8a8a8;
|
||||||
@ -1427,7 +1384,7 @@ StScrollBar StButton#vhandle:hover
|
|||||||
caret-size: 1px;
|
caret-size: 1px;
|
||||||
}
|
}
|
||||||
|
|
||||||
#notification StEntry:focus {
|
.notification StEntry:focus {
|
||||||
border: 1px solid #8b8b8b;
|
border: 1px solid #8b8b8b;
|
||||||
color: #333333;
|
color: #333333;
|
||||||
background-gradient-direction: vertical;
|
background-gradient-direction: vertical;
|
||||||
@ -1717,7 +1674,7 @@ StScrollBar StButton#vhandle:hover
|
|||||||
}
|
}
|
||||||
|
|
||||||
.lightbox {
|
.lightbox {
|
||||||
background-color: black;
|
background-color: rgba(0, 0, 0, 0.4);
|
||||||
}
|
}
|
||||||
|
|
||||||
.flashspot {
|
.flashspot {
|
||||||
@ -1950,10 +1907,12 @@ StScrollBar StButton#vhandle:hover
|
|||||||
padding-bottom: 8px;
|
padding-bottom: 8px;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* intentionally left transparent to avoid dialog changing size */
|
.hidden {
|
||||||
|
color: rgba(0,0,0,0);
|
||||||
|
}
|
||||||
|
|
||||||
.prompt-dialog-null-label {
|
.prompt-dialog-null-label {
|
||||||
font-size: 10pt;
|
font-size: 10pt;
|
||||||
color: rgba(0,0,0,0);
|
|
||||||
padding-bottom: 8px;
|
padding-bottom: 8px;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2047,3 +2006,17 @@ StScrollBar StButton#vhandle:hover
|
|||||||
-arrow-rise: 10px;
|
-arrow-rise: 10px;
|
||||||
-boxpointer-gap: 5px;
|
-boxpointer-gap: 5px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* IBus Candidate Popup */
|
||||||
|
.candidate-index {
|
||||||
|
padding: 0.5em 0.5em 0.5em 0.5em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.candidate-label {
|
||||||
|
padding: 0.5em 0.5em 0.5em 0.5em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.candidate-label:selected {
|
||||||
|
border-radius: 4px;
|
||||||
|
background-color: rgba(255,255,255,0.33);
|
||||||
|
}
|
||||||
|
@ -9,7 +9,7 @@
|
|||||||
xmlns="http://www.w3.org/2000/svg"
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||||
width="21"
|
width="17"
|
||||||
height="10"
|
height="10"
|
||||||
id="svg2"
|
id="svg2"
|
||||||
version="1.1"
|
version="1.1"
|
||||||
@ -66,9 +66,9 @@
|
|||||||
<rect
|
<rect
|
||||||
style="opacity:0.8;fill:#ffffff;fill-opacity:1;stroke-width:0.43599999;stroke-miterlimit:4;stroke-dasharray:none"
|
style="opacity:0.8;fill:#ffffff;fill-opacity:1;stroke-width:0.43599999;stroke-miterlimit:4;stroke-dasharray:none"
|
||||||
id="rect3796"
|
id="rect3796"
|
||||||
width="3"
|
width="7"
|
||||||
height="2"
|
height="2"
|
||||||
x="9"
|
x="5"
|
||||||
y="8" />
|
y="8" />
|
||||||
</g>
|
</g>
|
||||||
</svg>
|
</svg>
|
||||||
|
Before Width: | Height: | Size: 2.0 KiB After Width: | Height: | Size: 2.0 KiB |
@ -9,7 +9,7 @@
|
|||||||
xmlns="http://www.w3.org/2000/svg"
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||||
width="64"
|
width="65"
|
||||||
height="22"
|
height="22"
|
||||||
id="svg3273"
|
id="svg3273"
|
||||||
version="1.1"
|
version="1.1"
|
||||||
|
Before Width: | Height: | Size: 4.7 KiB After Width: | Height: | Size: 4.7 KiB |
@ -9,7 +9,7 @@
|
|||||||
xmlns="http://www.w3.org/2000/svg"
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||||
width="64"
|
width="65"
|
||||||
height="22"
|
height="22"
|
||||||
id="svg3012"
|
id="svg3012"
|
||||||
version="1.1"
|
version="1.1"
|
||||||
|
Before Width: | Height: | Size: 7.2 KiB After Width: | Height: | Size: 7.2 KiB |
@ -68,6 +68,10 @@ IGNORE_HFILES= \
|
|||||||
gactionobserver.h \
|
gactionobserver.h \
|
||||||
shell-recorder-src.h
|
shell-recorder-src.h
|
||||||
|
|
||||||
|
if !BUILD_RECORDER
|
||||||
|
IGNORE_HFILES += shell-recorder.h
|
||||||
|
endif
|
||||||
|
|
||||||
# Images to copy into HTML directory.
|
# Images to copy into HTML directory.
|
||||||
# e.g. HTML_IMAGES=$(top_srcdir)/gtk/stock-icons/stock_about_24.png
|
# e.g. HTML_IMAGES=$(top_srcdir)/gtk/stock-icons/stock_about_24.png
|
||||||
HTML_IMAGES=
|
HTML_IMAGES=
|
||||||
|
@ -66,4 +66,11 @@ its dependencies to build from tarballs.</description>
|
|||||||
<gnome:userid>marinaz</gnome:userid>
|
<gnome:userid>marinaz</gnome:userid>
|
||||||
</foaf:Person>
|
</foaf:Person>
|
||||||
</maintainer>
|
</maintainer>
|
||||||
|
<maintainer>
|
||||||
|
<foaf:Person>
|
||||||
|
<foaf:name>Florian Müllner</foaf:name>
|
||||||
|
<foaf:mbox rdf:resource="mailto:fmuellner@gnome.org" />
|
||||||
|
<gnome:userid>fmuellner</gnome:userid>
|
||||||
|
</foaf:Person>
|
||||||
|
</maintainer>
|
||||||
</Project>
|
</Project>
|
||||||
|
@ -6,9 +6,7 @@ misc/config.js: misc/config.js.in Makefile
|
|||||||
[ -d $(@D) ] || $(mkdir_p) $(@D) ; \
|
[ -d $(@D) ] || $(mkdir_p) $(@D) ; \
|
||||||
sed -e "s|[@]PACKAGE_NAME@|$(PACKAGE_NAME)|g" \
|
sed -e "s|[@]PACKAGE_NAME@|$(PACKAGE_NAME)|g" \
|
||||||
-e "s|[@]PACKAGE_VERSION@|$(PACKAGE_VERSION)|g" \
|
-e "s|[@]PACKAGE_VERSION@|$(PACKAGE_VERSION)|g" \
|
||||||
-e "s|[@]GJS_VERSION@|$(GJS_VERSION)|g" \
|
|
||||||
-e "s|[@]HAVE_BLUETOOTH@|$(HAVE_BLUETOOTH)|g" \
|
-e "s|[@]HAVE_BLUETOOTH@|$(HAVE_BLUETOOTH)|g" \
|
||||||
-e "s|[@]SHELL_SYSTEM_CA_FILE@|$(SHELL_SYSTEM_CA_FILE)|g" \
|
|
||||||
-e "s|[@]GETTEXT_PACKAGE@|$(GETTEXT_PACKAGE)|g" \
|
-e "s|[@]GETTEXT_PACKAGE@|$(GETTEXT_PACKAGE)|g" \
|
||||||
-e "s|[@]datadir@|$(datadir)|g" \
|
-e "s|[@]datadir@|$(datadir)|g" \
|
||||||
-e "s|[@]libexecdir@|$(libexecdir)|g" \
|
-e "s|[@]libexecdir@|$(libexecdir)|g" \
|
||||||
@ -28,7 +26,6 @@ nobase_dist_js_DATA = \
|
|||||||
misc/config.js \
|
misc/config.js \
|
||||||
misc/extensionUtils.js \
|
misc/extensionUtils.js \
|
||||||
misc/fileUtils.js \
|
misc/fileUtils.js \
|
||||||
misc/format.js \
|
|
||||||
misc/gnomeSession.js \
|
misc/gnomeSession.js \
|
||||||
misc/history.js \
|
misc/history.js \
|
||||||
misc/jsParse.js \
|
misc/jsParse.js \
|
||||||
@ -45,7 +42,6 @@ nobase_dist_js_DATA = \
|
|||||||
ui/boxpointer.js \
|
ui/boxpointer.js \
|
||||||
ui/calendar.js \
|
ui/calendar.js \
|
||||||
ui/checkBox.js \
|
ui/checkBox.js \
|
||||||
ui/contactDisplay.js \
|
|
||||||
ui/ctrlAltTab.js \
|
ui/ctrlAltTab.js \
|
||||||
ui/dash.js \
|
ui/dash.js \
|
||||||
ui/dateMenu.js \
|
ui/dateMenu.js \
|
||||||
@ -53,13 +49,14 @@ nobase_dist_js_DATA = \
|
|||||||
ui/endSessionDialog.js \
|
ui/endSessionDialog.js \
|
||||||
ui/environment.js \
|
ui/environment.js \
|
||||||
ui/extensionSystem.js \
|
ui/extensionSystem.js \
|
||||||
|
ui/extensionDownloader.js \
|
||||||
ui/flashspot.js \
|
ui/flashspot.js \
|
||||||
|
ui/ibusCandidatePopup.js\
|
||||||
ui/iconGrid.js \
|
ui/iconGrid.js \
|
||||||
ui/keyboard.js \
|
ui/keyboard.js \
|
||||||
ui/keyringPrompt.js \
|
ui/keyringPrompt.js \
|
||||||
ui/layout.js \
|
ui/layout.js \
|
||||||
ui/lightbox.js \
|
ui/lightbox.js \
|
||||||
ui/link.js \
|
|
||||||
ui/lookingGlass.js \
|
ui/lookingGlass.js \
|
||||||
ui/magnifier.js \
|
ui/magnifier.js \
|
||||||
ui/magnifierDBus.js \
|
ui/magnifierDBus.js \
|
||||||
@ -67,6 +64,7 @@ nobase_dist_js_DATA = \
|
|||||||
ui/messageTray.js \
|
ui/messageTray.js \
|
||||||
ui/modalDialog.js \
|
ui/modalDialog.js \
|
||||||
ui/networkAgent.js \
|
ui/networkAgent.js \
|
||||||
|
ui/sessionMode.js \
|
||||||
ui/shellEntry.js \
|
ui/shellEntry.js \
|
||||||
ui/shellMountOperation.js \
|
ui/shellMountOperation.js \
|
||||||
ui/notificationDaemon.js \
|
ui/notificationDaemon.js \
|
||||||
@ -78,7 +76,6 @@ nobase_dist_js_DATA = \
|
|||||||
ui/popupMenu.js \
|
ui/popupMenu.js \
|
||||||
ui/remoteSearch.js \
|
ui/remoteSearch.js \
|
||||||
ui/runDialog.js \
|
ui/runDialog.js \
|
||||||
ui/screenShield.js \
|
|
||||||
ui/scripting.js \
|
ui/scripting.js \
|
||||||
ui/search.js \
|
ui/search.js \
|
||||||
ui/searchDisplay.js \
|
ui/searchDisplay.js \
|
||||||
|
@ -6,11 +6,11 @@ const GObject = imports.gi.GObject;
|
|||||||
const Gio = imports.gi.Gio;
|
const Gio = imports.gi.Gio;
|
||||||
const Gtk = imports.gi.Gtk;
|
const Gtk = imports.gi.Gtk;
|
||||||
const Pango = imports.gi.Pango;
|
const Pango = imports.gi.Pango;
|
||||||
|
const Format = imports.format;
|
||||||
|
|
||||||
const _ = Gettext.gettext;
|
const _ = Gettext.gettext;
|
||||||
|
|
||||||
const Config = imports.misc.config;
|
const Config = imports.misc.config;
|
||||||
const Format = imports.misc.format;
|
|
||||||
const ExtensionUtils = imports.misc.extensionUtils;
|
const ExtensionUtils = imports.misc.extensionUtils;
|
||||||
|
|
||||||
|
|
||||||
@ -202,24 +202,18 @@ const Application = new Lang.Class({
|
|||||||
},
|
},
|
||||||
|
|
||||||
_scanExtensions: function() {
|
_scanExtensions: function() {
|
||||||
ExtensionUtils.scanExtensions(Lang.bind(this, function(uuid, dir, type) {
|
let finder = new ExtensionUtils.ExtensionFinder();
|
||||||
if (ExtensionUtils.extensions[uuid] !== undefined)
|
finder.connect('extension-found', Lang.bind(this, this._extensionFound));
|
||||||
return;
|
finder.scanExtensions();
|
||||||
|
|
||||||
let extension;
|
|
||||||
try {
|
|
||||||
extension = ExtensionUtils.createExtensionObject(uuid, dir, type);
|
|
||||||
} catch(e) {
|
|
||||||
global.logError('' + e);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
let iter = this._model.append();
|
|
||||||
this._model.set(iter, [0, 1], [uuid, extension.metadata.name]);
|
|
||||||
this._extensionIters[uuid] = iter;
|
|
||||||
}));
|
|
||||||
},
|
},
|
||||||
|
|
||||||
|
_extensionFound: function(signals, extension) {
|
||||||
|
let iter = this._model.append();
|
||||||
|
this._model.set(iter, [0, 1], [extension.uuid, extension.metadata.name]);
|
||||||
|
this._extensionIters[uuid] = iter;
|
||||||
|
},
|
||||||
|
|
||||||
|
|
||||||
_onActivate: function() {
|
_onActivate: function() {
|
||||||
this._window.present();
|
this._window.present();
|
||||||
},
|
},
|
||||||
@ -257,7 +251,7 @@ function initEnvironment() {
|
|||||||
},
|
},
|
||||||
|
|
||||||
logError: function(s) {
|
logError: function(s) {
|
||||||
global.log('ERROR: ' + s);
|
log('ERROR: ' + s);
|
||||||
},
|
},
|
||||||
|
|
||||||
userdatadir: GLib.build_filenamev([GLib.get_user_data_dir(), 'gnome-shell'])
|
userdatadir: GLib.build_filenamev([GLib.get_user_data_dir(), 'gnome-shell'])
|
||||||
@ -268,7 +262,6 @@ function initEnvironment() {
|
|||||||
|
|
||||||
function main(argv) {
|
function main(argv) {
|
||||||
initEnvironment();
|
initEnvironment();
|
||||||
ExtensionUtils.init();
|
|
||||||
|
|
||||||
Gettext.bindtextdomain(Config.GETTEXT_PACKAGE, Config.LOCALEDIR);
|
Gettext.bindtextdomain(Config.GETTEXT_PACKAGE, Config.LOCALEDIR);
|
||||||
Gettext.textdomain(Config.GETTEXT_PACKAGE);
|
Gettext.textdomain(Config.GETTEXT_PACKAGE);
|
||||||
|
@ -11,10 +11,17 @@ const FprintManagerIface = <interface name='net.reactivated.Fprint.Manager'>
|
|||||||
</method>
|
</method>
|
||||||
</interface>;
|
</interface>;
|
||||||
|
|
||||||
const FprintManagerProxy = Gio.DBusProxy.makeProxyWrapper(FprintManagerIface);
|
const FprintManagerInfo = Gio.DBusInterfaceInfo.new_for_xml(FprintManagerIface);
|
||||||
|
|
||||||
function FprintManager() {
|
function FprintManager() {
|
||||||
return new FprintManagerProxy(Gio.DBus.system,
|
var self = new Gio.DBusProxy({ g_connection: Gio.DBus.system,
|
||||||
'net.reactivated.Fprint',
|
g_interface_name: FprintManagerInfo.name,
|
||||||
'/net/reactivated/Fprint/Manager');
|
g_interface_info: FprintManagerInfo,
|
||||||
};
|
g_name: 'net.reactivated.Fprint',
|
||||||
|
g_object_path: '/net/reactivated/Fprint/Manager',
|
||||||
|
g_flags: (Gio.DBusProxyFlags.DO_NOT_AUTO_START |
|
||||||
|
Gio.DBusProxyFlags.DO_NOT_LOAD_PROPERTIES) });
|
||||||
|
|
||||||
|
self.init(null);
|
||||||
|
return self;
|
||||||
|
}
|
||||||
|
@ -30,7 +30,7 @@ const Pango = imports.gi.Pango;
|
|||||||
const Signals = imports.signals;
|
const Signals = imports.signals;
|
||||||
const Shell = imports.gi.Shell;
|
const Shell = imports.gi.Shell;
|
||||||
const St = imports.gi.St;
|
const St = imports.gi.St;
|
||||||
const GdmGreeter = imports.gi.GdmGreeter;
|
const Gdm = imports.gi.Gdm;
|
||||||
|
|
||||||
const Batch = imports.gdm.batch;
|
const Batch = imports.gdm.batch;
|
||||||
const Fprint = imports.gdm.fingerprint;
|
const Fprint = imports.gdm.fingerprint;
|
||||||
@ -49,6 +49,8 @@ const _LOGO_ICON_NAME_SIZE = 48;
|
|||||||
|
|
||||||
const _LOGIN_SCREEN_SCHEMA = 'org.gnome.login-screen';
|
const _LOGIN_SCREEN_SCHEMA = 'org.gnome.login-screen';
|
||||||
const _FINGERPRINT_AUTHENTICATION_KEY = 'enable-fingerprint-authentication';
|
const _FINGERPRINT_AUTHENTICATION_KEY = 'enable-fingerprint-authentication';
|
||||||
|
const _BANNER_MESSAGE_KEY = 'banner-message-enable';
|
||||||
|
const _BANNER_MESSAGE_TEXT_KEY = 'banner-message-text';
|
||||||
|
|
||||||
const _LOGO_KEY = 'logo';
|
const _LOGO_KEY = 'logo';
|
||||||
|
|
||||||
@ -488,6 +490,9 @@ const UserList = new Lang.Class({
|
|||||||
if (user.is_system_account())
|
if (user.is_system_account())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
if (user.locked)
|
||||||
|
return;
|
||||||
|
|
||||||
let userName = user.get_user_name();
|
let userName = user.get_user_name();
|
||||||
|
|
||||||
if (!userName)
|
if (!userName)
|
||||||
@ -698,7 +703,7 @@ const SessionList = new Lang.Class({
|
|||||||
this._activeSessionId = null;
|
this._activeSessionId = null;
|
||||||
this._items = {};
|
this._items = {};
|
||||||
|
|
||||||
let ids = GdmGreeter.get_session_ids();
|
let ids = Gdm.get_session_ids();
|
||||||
ids.sort();
|
ids.sort();
|
||||||
|
|
||||||
if (ids.length <= 1) {
|
if (ids.length <= 1) {
|
||||||
@ -710,7 +715,7 @@ const SessionList = new Lang.Class({
|
|||||||
}
|
}
|
||||||
|
|
||||||
for (let i = 0; i < ids.length; i++) {
|
for (let i = 0; i < ids.length; i++) {
|
||||||
let [sessionName, sessionDescription] = GdmGreeter.get_session_name_and_description(ids[i]);
|
let [sessionName, sessionDescription] = Gdm.get_session_name_and_description(ids[i]);
|
||||||
|
|
||||||
let item = new SessionListItem(ids[i], sessionName);
|
let item = new SessionListItem(ids[i], sessionName);
|
||||||
this._itemList.add_actor(item.actor,
|
this._itemList.add_actor(item.actor,
|
||||||
@ -744,44 +749,38 @@ const LoginDialog = new Lang.Class({
|
|||||||
Lang.bind(this, this._onOpened));
|
Lang.bind(this, this._onOpened));
|
||||||
|
|
||||||
this._userManager = AccountsService.UserManager.get_default()
|
this._userManager = AccountsService.UserManager.get_default()
|
||||||
this._greeterClient = new GdmGreeter.Client();
|
this._greeterClient = new Gdm.Client();
|
||||||
|
|
||||||
this._greeterClient.open_connection();
|
this._greeter = this._greeterClient.get_greeter_sync(null);
|
||||||
|
|
||||||
this._greeterClient.call_start_conversation(_PASSWORD_SERVICE_NAME);
|
this._greeter.connect('default-session-name-changed',
|
||||||
|
|
||||||
this._greeterClient.connect('reset',
|
|
||||||
Lang.bind(this, this._onReset));
|
|
||||||
this._greeterClient.connect('default-session-changed',
|
|
||||||
Lang.bind(this, this._onDefaultSessionChanged));
|
Lang.bind(this, this._onDefaultSessionChanged));
|
||||||
this._greeterClient.connect('info',
|
|
||||||
Lang.bind(this, this._onInfo));
|
this._greeter.connect('session-opened',
|
||||||
this._greeterClient.connect('problem',
|
|
||||||
Lang.bind(this, this._onProblem));
|
|
||||||
this._greeterClient.connect('info-query',
|
|
||||||
Lang.bind(this, this._onInfoQuery));
|
|
||||||
this._greeterClient.connect('secret-info-query',
|
|
||||||
Lang.bind(this, this._onSecretInfoQuery));
|
|
||||||
this._greeterClient.connect('session-opened',
|
|
||||||
Lang.bind(this, this._onSessionOpened));
|
Lang.bind(this, this._onSessionOpened));
|
||||||
this._greeterClient.connect('timed-login-requested',
|
this._greeter.connect('timed-login-requested',
|
||||||
Lang.bind(this, this._onTimedLoginRequested));
|
Lang.bind(this, this._onTimedLoginRequested));
|
||||||
this._greeterClient.connect('authentication-failed',
|
|
||||||
Lang.bind(this, this._onAuthenticationFailed));
|
|
||||||
this._greeterClient.connect('conversation-stopped',
|
|
||||||
Lang.bind(this, this._onConversationStopped));
|
|
||||||
|
|
||||||
this._settings = new Gio.Settings({ schema: _LOGIN_SCREEN_SCHEMA });
|
this._settings = new Gio.Settings({ schema: _LOGIN_SCREEN_SCHEMA });
|
||||||
|
|
||||||
this._fprintManager = new Fprint.FprintManager();
|
this._fprintManager = new Fprint.FprintManager();
|
||||||
this._startFingerprintConversationIfNeeded();
|
this._checkForFingerprintReader();
|
||||||
this._settings.connect('changed::' + _LOGO_KEY,
|
this._settings.connect('changed::' + _LOGO_KEY,
|
||||||
Lang.bind(this, this._updateLogo));
|
Lang.bind(this, this._updateLogo));
|
||||||
|
this._settings.connect('changed::' + _BANNER_MESSAGE_KEY,
|
||||||
|
Lang.bind(this, this._updateBanner));
|
||||||
|
this._settings.connect('changed::' + _BANNER_MESSAGE_TEXT_KEY,
|
||||||
|
Lang.bind(this, this._updateBanner));
|
||||||
|
|
||||||
this._logoBox = new St.Bin({ style_class: 'login-dialog-logo-box' });
|
this._logoBox = new St.Bin({ style_class: 'login-dialog-logo-box' });
|
||||||
this.contentLayout.add(this._logoBox);
|
this.contentLayout.add(this._logoBox);
|
||||||
this._updateLogo();
|
this._updateLogo();
|
||||||
|
|
||||||
|
this._bannerLabel = new St.Label({ style_class: 'login-dialog-banner',
|
||||||
|
text: '' });
|
||||||
|
this.contentLayout.add(this._bannerLabel);
|
||||||
|
this._updateBanner();
|
||||||
|
|
||||||
this._titleLabel = new St.Label({ style_class: 'login-dialog-title',
|
this._titleLabel = new St.Label({ style_class: 'login-dialog-title',
|
||||||
text: C_("title", "Sign In") });
|
text: C_("title", "Sign In") });
|
||||||
|
|
||||||
@ -836,7 +835,7 @@ const LoginDialog = new Lang.Class({
|
|||||||
this._sessionList = new SessionList();
|
this._sessionList = new SessionList();
|
||||||
this._sessionList.connect('session-activated',
|
this._sessionList.connect('session-activated',
|
||||||
Lang.bind(this, function(list, sessionId) {
|
Lang.bind(this, function(list, sessionId) {
|
||||||
this._greeterClient.call_select_session (sessionId);
|
this._greeter.call_select_session_sync (sessionId, null);
|
||||||
}));
|
}));
|
||||||
|
|
||||||
this._promptBox.add(this._sessionList.actor,
|
this._promptBox.add(this._sessionList.actor,
|
||||||
@ -884,7 +883,7 @@ const LoginDialog = new Lang.Class({
|
|||||||
|
|
||||||
},
|
},
|
||||||
|
|
||||||
_startFingerprintConversationIfNeeded: function() {
|
_checkForFingerprintReader: function() {
|
||||||
this._haveFingerprintReader = false;
|
this._haveFingerprintReader = false;
|
||||||
|
|
||||||
if (!this._settings.get_boolean(_FINGERPRINT_AUTHENTICATION_KEY))
|
if (!this._settings.get_boolean(_FINGERPRINT_AUTHENTICATION_KEY))
|
||||||
@ -894,9 +893,6 @@ const LoginDialog = new Lang.Class({
|
|||||||
function(device, error) {
|
function(device, error) {
|
||||||
if (!error && device)
|
if (!error && device)
|
||||||
this._haveFingerprintReader = true;
|
this._haveFingerprintReader = true;
|
||||||
|
|
||||||
if (this._haveFingerprintReader)
|
|
||||||
this._greeterClient.call_start_conversation(_FINGERPRINT_SERVICE_NAME);
|
|
||||||
}));
|
}));
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -914,9 +910,22 @@ const LoginDialog = new Lang.Class({
|
|||||||
|
|
||||||
},
|
},
|
||||||
|
|
||||||
|
_updateBanner: function() {
|
||||||
|
let enabled = this._settings.get_boolean(_BANNER_MESSAGE_KEY);
|
||||||
|
let text = this._settings.get_string(_BANNER_MESSAGE_TEXT_KEY);
|
||||||
|
|
||||||
|
if (enabled && text) {
|
||||||
|
this._bannerLabel.set_text(text);
|
||||||
|
this._fadeInBanner();
|
||||||
|
} else {
|
||||||
|
this._fadeOutBanner();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
_onReset: function(client, serviceName) {
|
_onReset: function(client, serviceName) {
|
||||||
this._greeterClient.call_start_conversation(_PASSWORD_SERVICE_NAME);
|
this._userVerifier = null;
|
||||||
this._startFingerprintConversationIfNeeded();
|
|
||||||
|
this._checkForFingerprintReader();
|
||||||
|
|
||||||
let tasks = [this._hidePrompt,
|
let tasks = [this._hidePrompt,
|
||||||
|
|
||||||
@ -974,7 +983,7 @@ const LoginDialog = new Lang.Class({
|
|||||||
},
|
},
|
||||||
|
|
||||||
_onCancel: function(client) {
|
_onCancel: function(client) {
|
||||||
this._greeterClient.call_cancel();
|
this._userVerifier.call_cancel_sync(null);
|
||||||
},
|
},
|
||||||
|
|
||||||
_fadeInPrompt: function() {
|
_fadeInPrompt: function() {
|
||||||
@ -1081,7 +1090,7 @@ const LoginDialog = new Lang.Class({
|
|||||||
let _text = this._promptEntry.get_text();
|
let _text = this._promptEntry.get_text();
|
||||||
this._promptEntry.reactive = false;
|
this._promptEntry.reactive = false;
|
||||||
this._promptEntry.add_style_pseudo_class('insensitive');
|
this._promptEntry.add_style_pseudo_class('insensitive');
|
||||||
this._greeterClient.call_answer_query(serviceName, _text);
|
this._userVerifier.call_answer_query_sync(serviceName, _text, null);
|
||||||
}];
|
}];
|
||||||
|
|
||||||
let batch = new Batch.ConsecutiveBatch(this, tasks);
|
let batch = new Batch.ConsecutiveBatch(this, tasks);
|
||||||
@ -1108,7 +1117,7 @@ const LoginDialog = new Lang.Class({
|
|||||||
},
|
},
|
||||||
|
|
||||||
_onSessionOpened: function(client, serviceName) {
|
_onSessionOpened: function(client, serviceName) {
|
||||||
this._greeterClient.call_start_session_when_ready(serviceName, true);
|
this._greeter.call_start_session_when_ready_sync(serviceName, true, null);
|
||||||
},
|
},
|
||||||
|
|
||||||
_waitForItemForUser: function(userName) {
|
_waitForItemForUser: function(userName) {
|
||||||
@ -1190,7 +1199,7 @@ const LoginDialog = new Lang.Class({
|
|||||||
|
|
||||||
function() {
|
function() {
|
||||||
this._timedLoginBatch = null;
|
this._timedLoginBatch = null;
|
||||||
this._greeterClient.call_begin_auto_login(userName);
|
this._greeter.call_begin_auto_login_sync(userName, null);
|
||||||
}];
|
}];
|
||||||
|
|
||||||
this._timedLoginBatch = new Batch.ConsecutiveBatch(this, tasks);
|
this._timedLoginBatch = new Batch.ConsecutiveBatch(this, tasks);
|
||||||
@ -1233,16 +1242,12 @@ const LoginDialog = new Lang.Class({
|
|||||||
}));
|
}));
|
||||||
},
|
},
|
||||||
|
|
||||||
_onAuthenticationFailed: function(client) {
|
|
||||||
this._greeterClient.call_cancel();
|
|
||||||
},
|
|
||||||
|
|
||||||
_onConversationStopped: function(client, serviceName) {
|
_onConversationStopped: function(client, serviceName) {
|
||||||
// if the password service fails, then cancel everything.
|
// if the password service fails, then cancel everything.
|
||||||
// But if, e.g., fingerprint fails, still give
|
// But if, e.g., fingerprint fails, still give
|
||||||
// password authentication a chance to succeed
|
// password authentication a chance to succeed
|
||||||
if (serviceName == _PASSWORD_SERVICE_NAME) {
|
if (serviceName == _PASSWORD_SERVICE_NAME) {
|
||||||
this._greeterClient.call_cancel();
|
this._userVerifier.call_cancel_sync(null);
|
||||||
} else if (serviceName == _FINGERPRINT_SERVICE_NAME) {
|
} else if (serviceName == _FINGERPRINT_SERVICE_NAME) {
|
||||||
_fadeOutActor(this._promptFingerprintMessage);
|
_fadeOutActor(this._promptFingerprintMessage);
|
||||||
}
|
}
|
||||||
@ -1266,7 +1271,16 @@ const LoginDialog = new Lang.Class({
|
|||||||
this._fadeOutLogo]),
|
this._fadeOutLogo]),
|
||||||
|
|
||||||
function() {
|
function() {
|
||||||
this._greeterClient.call_begin_verification(_PASSWORD_SERVICE_NAME);
|
let hold = new Batch.Hold();
|
||||||
|
|
||||||
|
this._userVerifier.call_begin_verification(_PASSWORD_SERVICE_NAME,
|
||||||
|
null,
|
||||||
|
Lang.bind(this, function (userVerifier, result) {
|
||||||
|
this._userVerifier.call_begin_verification_finish (result);
|
||||||
|
hold.release();
|
||||||
|
}));
|
||||||
|
|
||||||
|
return hold;
|
||||||
}];
|
}];
|
||||||
|
|
||||||
let batch = new Batch.ConsecutiveBatch(this, tasks);
|
let batch = new Batch.ConsecutiveBatch(this, tasks);
|
||||||
@ -1281,6 +1295,14 @@ const LoginDialog = new Lang.Class({
|
|||||||
return _fadeOutActor(this._logoBox);
|
return _fadeOutActor(this._logoBox);
|
||||||
},
|
},
|
||||||
|
|
||||||
|
_fadeInBanner: function() {
|
||||||
|
return _fadeInActor(this._bannerLabel);
|
||||||
|
},
|
||||||
|
|
||||||
|
_fadeOutBanner: function() {
|
||||||
|
return _fadeOutActor(this._bannerLabel);
|
||||||
|
},
|
||||||
|
|
||||||
_fadeInTitleLabel: function() {
|
_fadeInTitleLabel: function() {
|
||||||
return _fadeInActor(this._titleLabel);
|
return _fadeInActor(this._titleLabel);
|
||||||
},
|
},
|
||||||
@ -1297,7 +1319,101 @@ const LoginDialog = new Lang.Class({
|
|||||||
return _fadeOutActor(this._notListedButton);
|
return _fadeOutActor(this._notListedButton);
|
||||||
},
|
},
|
||||||
|
|
||||||
|
_getUserVerifier: function(userName) {
|
||||||
|
let hold = new Batch.Hold();
|
||||||
|
|
||||||
|
this._userVerifier = null;
|
||||||
|
|
||||||
|
// If possible, reauthenticate an already running session,
|
||||||
|
// so any session specific credentials get updated appropriately
|
||||||
|
this._greeterClient.open_reauthentication_channel(userName,
|
||||||
|
null,
|
||||||
|
Lang.bind(this, function(client, result) {
|
||||||
|
try {
|
||||||
|
this._userVerifier = this._greeterClient.open_reauthentication_channel_finish(result);
|
||||||
|
hold.release();
|
||||||
|
} catch (e) {
|
||||||
|
// If there's no session running, or it otherwise fails, then fall back
|
||||||
|
// to performing verification from this login session
|
||||||
|
this._greeterClient.get_user_verifier(null,
|
||||||
|
Lang.bind(this, function(client, result) {
|
||||||
|
this._userVerifier = this._greeterClient.get_user_verifier_finish(result);
|
||||||
|
hold.release();
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
}));
|
||||||
|
|
||||||
|
hold.connect('release', Lang.bind(this, function() {
|
||||||
|
if (this._userVerifier) {
|
||||||
|
let ids = [];
|
||||||
|
let id;
|
||||||
|
|
||||||
|
id = this._userVerifier.connect('info',
|
||||||
|
Lang.bind(this, this._onInfo));
|
||||||
|
ids.push(id);
|
||||||
|
id = this._userVerifier.connect('problem',
|
||||||
|
Lang.bind(this, this._onProblem));
|
||||||
|
ids.push(id);
|
||||||
|
id = this._userVerifier.connect('info-query',
|
||||||
|
Lang.bind(this, this._onInfoQuery));
|
||||||
|
ids.push(id);
|
||||||
|
id = this._userVerifier.connect('secret-info-query',
|
||||||
|
Lang.bind(this, this._onSecretInfoQuery));
|
||||||
|
ids.push(id);
|
||||||
|
id = this._userVerifier.connect('conversation-stopped',
|
||||||
|
Lang.bind(this, this._onConversationStopped));
|
||||||
|
ids.push(id);
|
||||||
|
id = this._userVerifier.connect('reset',
|
||||||
|
Lang.bind(this, function() {
|
||||||
|
for (let i = 0; i < ids.length; i++)
|
||||||
|
this._userVerifier.disconnect(ids[i]);
|
||||||
|
|
||||||
|
this._onReset();
|
||||||
|
}));
|
||||||
|
ids.push(id);
|
||||||
|
}
|
||||||
|
}));
|
||||||
|
|
||||||
|
return hold;
|
||||||
|
},
|
||||||
|
|
||||||
|
_beginVerificationForUser: function(userName) {
|
||||||
|
let tasks = [function() {
|
||||||
|
let hold = new Batch.Hold();
|
||||||
|
this._userVerifier.call_begin_verification_for_user (_PASSWORD_SERVICE_NAME,
|
||||||
|
userName, null,
|
||||||
|
Lang.bind(this, function(userVerifier, result) {
|
||||||
|
this._userVerifier.call_begin_verification_for_user_finish (result);
|
||||||
|
hold.release();
|
||||||
|
}));
|
||||||
|
return hold;
|
||||||
|
},
|
||||||
|
|
||||||
|
function() {
|
||||||
|
let hold = new Batch.Hold();
|
||||||
|
if (this._haveFingerprintReader) {
|
||||||
|
this._userVerifier.call_begin_verification_for_user (_FINGERPRINT_SERVICE_NAME,
|
||||||
|
userName, null,
|
||||||
|
Lang.bind(this, function(userVerifier, result) {
|
||||||
|
this._userVerifier.call_begin_verification_for_user_finish (result);
|
||||||
|
hold.release();
|
||||||
|
}));
|
||||||
|
} else {
|
||||||
|
hold.release();
|
||||||
|
}
|
||||||
|
|
||||||
|
return hold;
|
||||||
|
}];
|
||||||
|
|
||||||
|
let batch = new Batch.ConsecutiveBatch(this, [this._getUserVerifier(userName),
|
||||||
|
new Batch.ConcurrentBatch(this, tasks)]);
|
||||||
|
|
||||||
|
return batch.run();
|
||||||
|
},
|
||||||
|
|
||||||
_onUserListActivated: function(activatedItem) {
|
_onUserListActivated: function(activatedItem) {
|
||||||
|
let userName;
|
||||||
|
|
||||||
let tasks = [function() {
|
let tasks = [function() {
|
||||||
this._userList.actor.reactive = false;
|
this._userList.actor.reactive = false;
|
||||||
return this._userList.pinInPlace();
|
return this._userList.pinInPlace();
|
||||||
@ -1324,12 +1440,9 @@ const LoginDialog = new Lang.Class({
|
|||||||
},
|
},
|
||||||
|
|
||||||
function() {
|
function() {
|
||||||
let userName = activatedItem.user.get_user_name();
|
userName = activatedItem.user.get_user_name();
|
||||||
this._greeterClient.call_begin_verification_for_user(_PASSWORD_SERVICE_NAME,
|
|
||||||
userName);
|
|
||||||
|
|
||||||
if (this._haveFingerprintReader)
|
return this._beginVerificationForUser(userName);
|
||||||
this._greeterClient.call_begin_verification_for_user(_FINGERPRINT_SERVICE_NAME, userName);
|
|
||||||
}];
|
}];
|
||||||
|
|
||||||
this._user = activatedItem.user;
|
this._user = activatedItem.user;
|
||||||
|
@ -60,10 +60,8 @@ const PowerMenuButton = new Lang.Class({
|
|||||||
},
|
},
|
||||||
|
|
||||||
_updateVisibility: function() {
|
_updateVisibility: function() {
|
||||||
if (!this._haveSuspend && !this._haveShutdown && !this._haveRestart)
|
let shouldBeVisible = (this._haveSuspend || this._haveShutdown || this._haveRestart);
|
||||||
this.actor.hide();
|
this.actor.visible = shouldBeVisible;
|
||||||
else
|
|
||||||
this.actor.show();
|
|
||||||
},
|
},
|
||||||
|
|
||||||
_updateHaveShutdown: function() {
|
_updateHaveShutdown: function() {
|
||||||
@ -72,31 +70,22 @@ const PowerMenuButton = new Lang.Class({
|
|||||||
this._systemdLoginManager.CanPowerOffRemote(Lang.bind(this,
|
this._systemdLoginManager.CanPowerOffRemote(Lang.bind(this,
|
||||||
function(result, error) {
|
function(result, error) {
|
||||||
if (!error)
|
if (!error)
|
||||||
this._haveShutdown = result != 'no';
|
this._haveShutdown = result[0] != 'no';
|
||||||
else
|
else
|
||||||
this._haveShutdown = false;
|
this._haveShutdown = false;
|
||||||
|
|
||||||
if (this._haveShutdown)
|
this._powerOffItem.actor.visible = this._haveShutdown;
|
||||||
this._powerOffItem.actor.show();
|
|
||||||
else
|
|
||||||
this._powerOffItem.actor.hide();
|
|
||||||
|
|
||||||
this._updateVisibility();
|
this._updateVisibility();
|
||||||
}));
|
}));
|
||||||
} else {
|
} else {
|
||||||
this._consoleKitManager.CanStopRemote(Lang.bind(this,
|
this._consoleKitManager.CanStopRemote(Lang.bind(this,
|
||||||
function(result, error) {
|
function(result, error) {
|
||||||
if (!error)
|
if (!error)
|
||||||
this._haveShutdown = result;
|
this._haveShutdown = result[0];
|
||||||
else
|
else
|
||||||
this._haveShutdown = false;
|
this._haveShutdown = false;
|
||||||
|
|
||||||
if (this._haveShutdown) {
|
this._powerOffItem.actor.visible = this._haveShutdown;
|
||||||
this._powerOffItem.actor.show();
|
|
||||||
} else {
|
|
||||||
this._powerOffItem.actor.hide();
|
|
||||||
}
|
|
||||||
|
|
||||||
this._updateVisibility();
|
this._updateVisibility();
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
@ -108,31 +97,22 @@ const PowerMenuButton = new Lang.Class({
|
|||||||
this._systemdLoginManager.CanRebootRemote(Lang.bind(this,
|
this._systemdLoginManager.CanRebootRemote(Lang.bind(this,
|
||||||
function(result, error) {
|
function(result, error) {
|
||||||
if (!error)
|
if (!error)
|
||||||
this._haveRestart = result != 'no';
|
this._haveRestart = result[0] != 'no';
|
||||||
else
|
else
|
||||||
this._haveRestart = false;
|
this._haveRestart = false;
|
||||||
|
|
||||||
if (this._haveRestart)
|
this._restartItem.actor.visible = this._haveRestart;
|
||||||
this._restartItem.actor.show();
|
|
||||||
else
|
|
||||||
this._restartItem.actor.hide();
|
|
||||||
|
|
||||||
this._updateVisibility();
|
this._updateVisibility();
|
||||||
}));
|
}));
|
||||||
} else {
|
} else {
|
||||||
this._consoleKitManager.CanRestartRemote(Lang.bind(this,
|
this._consoleKitManager.CanRestartRemote(Lang.bind(this,
|
||||||
function(result, error) {
|
function(result, error) {
|
||||||
if (!error)
|
if (!error)
|
||||||
this._haveRestart = result;
|
this._haveRestart = result[0];
|
||||||
else
|
else
|
||||||
this._haveRestart = false;
|
this._haveRestart = false;
|
||||||
|
|
||||||
if (this._haveRestart) {
|
this._restartItem.actor.visible = this._haveRestart;
|
||||||
this._restartItem.actor.show();
|
|
||||||
} else {
|
|
||||||
this._restartItem.actor.hide();
|
|
||||||
}
|
|
||||||
|
|
||||||
this._updateVisibility();
|
this._updateVisibility();
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
@ -140,12 +120,7 @@ const PowerMenuButton = new Lang.Class({
|
|||||||
|
|
||||||
_updateHaveSuspend: function() {
|
_updateHaveSuspend: function() {
|
||||||
this._haveSuspend = this._upClient.get_can_suspend();
|
this._haveSuspend = this._upClient.get_can_suspend();
|
||||||
|
this._suspendItem.actor.visible = this._haveSuspend;
|
||||||
if (this._haveSuspend)
|
|
||||||
this._suspendItem.actor.show();
|
|
||||||
else
|
|
||||||
this._suspendItem.actor.hide();
|
|
||||||
|
|
||||||
this._updateVisibility();
|
this._updateVisibility();
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -4,12 +4,8 @@
|
|||||||
const PACKAGE_NAME = '@PACKAGE_NAME@';
|
const PACKAGE_NAME = '@PACKAGE_NAME@';
|
||||||
/* The version of this package */
|
/* The version of this package */
|
||||||
const PACKAGE_VERSION = '@PACKAGE_VERSION@';
|
const PACKAGE_VERSION = '@PACKAGE_VERSION@';
|
||||||
/* The version of GJS we're linking to */
|
|
||||||
const GJS_VERSION = '@GJS_VERSION@';
|
|
||||||
/* 1 if gnome-bluetooth is available, 0 otherwise */
|
/* 1 if gnome-bluetooth is available, 0 otherwise */
|
||||||
const HAVE_BLUETOOTH = @HAVE_BLUETOOTH@;
|
const HAVE_BLUETOOTH = @HAVE_BLUETOOTH@;
|
||||||
/* The system TLS CA list */
|
|
||||||
const SHELL_SYSTEM_CA_FILE = '@SHELL_SYSTEM_CA_FILE@';
|
|
||||||
/* gettext package */
|
/* gettext package */
|
||||||
const GETTEXT_PACKAGE = '@GETTEXT_PACKAGE@';
|
const GETTEXT_PACKAGE = '@GETTEXT_PACKAGE@';
|
||||||
/* locale dir */
|
/* locale dir */
|
||||||
|
@ -3,6 +3,9 @@
|
|||||||
// Common utils for the extension system and the extension
|
// Common utils for the extension system and the extension
|
||||||
// preferences tool
|
// preferences tool
|
||||||
|
|
||||||
|
const Lang = imports.lang;
|
||||||
|
const Signals = imports.signals;
|
||||||
|
|
||||||
const GLib = imports.gi.GLib;
|
const GLib = imports.gi.GLib;
|
||||||
const Gio = imports.gi.Gio;
|
const Gio = imports.gi.Gio;
|
||||||
const ShellJS = imports.gi.ShellJS;
|
const ShellJS = imports.gi.ShellJS;
|
||||||
@ -14,9 +17,6 @@ const ExtensionType = {
|
|||||||
PER_USER: 2
|
PER_USER: 2
|
||||||
};
|
};
|
||||||
|
|
||||||
// GFile for user extensions
|
|
||||||
var userExtensionsDir = null;
|
|
||||||
|
|
||||||
// Maps uuid -> metadata object
|
// Maps uuid -> metadata object
|
||||||
const extensions = {};
|
const extensions = {};
|
||||||
|
|
||||||
@ -40,13 +40,18 @@ function getCurrentExtension() {
|
|||||||
throw new Error('Could not find current extension');
|
throw new Error('Could not find current extension');
|
||||||
|
|
||||||
let path = match[1];
|
let path = match[1];
|
||||||
let uuid = GLib.path_get_basename(GLib.path_get_dirname(path));
|
let file = Gio.File.new_for_path(path);
|
||||||
|
|
||||||
let extension = extensions[uuid];
|
|
||||||
if (extension === undefined)
|
|
||||||
throw new Error('Could not find current extension');
|
|
||||||
|
|
||||||
|
// Walk up the directory tree, looking for an extesion with
|
||||||
|
// the same UUID as a directory name.
|
||||||
|
while (file != null) {
|
||||||
|
let extension = extensions[file.get_basename()];
|
||||||
|
if (extension !== undefined)
|
||||||
return extension;
|
return extension;
|
||||||
|
file = file.get_parent();
|
||||||
|
}
|
||||||
|
|
||||||
|
throw new Error('Could not find current extension');
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -83,9 +88,6 @@ function isOutOfDate(extension) {
|
|||||||
if (!versionCheck(extension.metadata['shell-version'], Config.PACKAGE_VERSION))
|
if (!versionCheck(extension.metadata['shell-version'], Config.PACKAGE_VERSION))
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
if (extension.metadata['js-version'] && !versionCheck(extension.metadata['js-version'], Config.GJS_VERSION))
|
|
||||||
return true;
|
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -120,7 +122,7 @@ function createExtensionObject(uuid, dir, type) {
|
|||||||
|
|
||||||
// Encourage people to add this
|
// Encourage people to add this
|
||||||
if (!meta.url) {
|
if (!meta.url) {
|
||||||
global.log('Warning: Missing "url" property in metadata.json');
|
log('Warning: Missing "url" property in %s/metadata.json'.format(uuid));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (uuid != meta.uuid) {
|
if (uuid != meta.uuid) {
|
||||||
@ -150,24 +152,16 @@ function installImporter(extension) {
|
|||||||
_extension = null;
|
_extension = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
function init() {
|
const ExtensionFinder = new Lang.Class({
|
||||||
let userExtensionsPath = GLib.build_filenamev([global.userdatadir, 'extensions']);
|
Name: 'ExtensionFinder',
|
||||||
userExtensionsDir = Gio.file_new_for_path(userExtensionsPath);
|
|
||||||
try {
|
|
||||||
if (!userExtensionsDir.query_exists(null))
|
|
||||||
userExtensionsDir.make_directory_with_parents(null);
|
|
||||||
} catch (e) {
|
|
||||||
global.logError('' + e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function scanExtensionsInDirectory(callback, dir, type) {
|
_scanExtensionsInDirectory: function(dir, type) {
|
||||||
let fileEnum;
|
let fileEnum;
|
||||||
let file, info;
|
let file, info;
|
||||||
try {
|
try {
|
||||||
fileEnum = dir.enumerate_children('standard::*', Gio.FileQueryInfoFlags.NONE, null);
|
fileEnum = dir.enumerate_children('standard::*', Gio.FileQueryInfoFlags.NONE, null);
|
||||||
} catch(e) {
|
} catch(e) {
|
||||||
global.logError('' + e);
|
logError(e, 'Could not enumerate extensions directory');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -177,18 +171,36 @@ function scanExtensionsInDirectory(callback, dir, type) {
|
|||||||
continue;
|
continue;
|
||||||
let uuid = info.get_name();
|
let uuid = info.get_name();
|
||||||
let extensionDir = dir.get_child(uuid);
|
let extensionDir = dir.get_child(uuid);
|
||||||
callback(uuid, extensionDir, type);
|
|
||||||
}
|
let existing = extensions[uuid];
|
||||||
fileEnum.close(null);
|
if (existing) {
|
||||||
|
log('Extension %s already installed in %s. %s will not be loaded'.format(uuid, existing.path, extensionDir.get_path()));
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
function scanExtensions(callback) {
|
let extension;
|
||||||
|
try {
|
||||||
|
extension = createExtensionObject(uuid, extensionDir, type);
|
||||||
|
} catch(e) {
|
||||||
|
logError(e, 'Could not load extension %s'.format(uuid));
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
this.emit('extension-found', extension);
|
||||||
|
}
|
||||||
|
fileEnum.close(null);
|
||||||
|
},
|
||||||
|
|
||||||
|
scanExtensions: function() {
|
||||||
|
let userExtensionsDir = Gio.File.new_for_path(GLib.build_filenamev([global.userdatadir, 'extensions']));
|
||||||
|
this._scanExtensionsInDirectory(userExtensionsDir, ExtensionType.PER_USER);
|
||||||
|
|
||||||
let systemDataDirs = GLib.get_system_data_dirs();
|
let systemDataDirs = GLib.get_system_data_dirs();
|
||||||
for (let i = 0; i < systemDataDirs.length; i++) {
|
for (let i = 0; i < systemDataDirs.length; i++) {
|
||||||
let dirPath = GLib.build_filenamev([systemDataDirs[i], 'gnome-shell', 'extensions']);
|
let dirPath = GLib.build_filenamev([systemDataDirs[i], 'gnome-shell', 'extensions']);
|
||||||
let dir = Gio.file_new_for_path(dirPath);
|
let dir = Gio.file_new_for_path(dirPath);
|
||||||
if (dir.query_exists(null))
|
if (dir.query_exists(null))
|
||||||
scanExtensionsInDirectory(callback, dir, ExtensionType.SYSTEM);
|
this._scanExtensionsInDirectory(dir, ExtensionType.SYSTEM);
|
||||||
}
|
}
|
||||||
scanExtensionsInDirectory(callback, userExtensionsDir, ExtensionType.PER_USER);
|
|
||||||
}
|
}
|
||||||
|
});
|
||||||
|
Signals.addSignalMethods(ExtensionFinder.prototype);
|
||||||
|
@ -28,7 +28,7 @@ function deleteGFile(file) {
|
|||||||
return file['delete'](null);
|
return file['delete'](null);
|
||||||
}
|
}
|
||||||
|
|
||||||
function recursivelyDeleteDir(dir) {
|
function recursivelyDeleteDir(dir, deleteParent) {
|
||||||
let children = dir.enumerate_children('standard::name,standard::type',
|
let children = dir.enumerate_children('standard::name,standard::type',
|
||||||
Gio.FileQueryInfoFlags.NONE, null);
|
Gio.FileQueryInfoFlags.NONE, null);
|
||||||
|
|
||||||
@ -39,8 +39,29 @@ function recursivelyDeleteDir(dir) {
|
|||||||
if (type == Gio.FileType.REGULAR)
|
if (type == Gio.FileType.REGULAR)
|
||||||
deleteGFile(child);
|
deleteGFile(child);
|
||||||
else if (type == Gio.FileType.DIRECTORY)
|
else if (type == Gio.FileType.DIRECTORY)
|
||||||
recursivelyDeleteDir(child);
|
recursivelyDeleteDir(child, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (deleteParent)
|
||||||
deleteGFile(dir);
|
deleteGFile(dir);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function recursivelyMoveDir(srcDir, destDir) {
|
||||||
|
let children = srcDir.enumerate_children('standard::name,standard::type',
|
||||||
|
Gio.FileQueryInfoFlags.NONE, null);
|
||||||
|
|
||||||
|
if (!destDir.query_exists(null))
|
||||||
|
destDir.make_directory_with_parents(null);
|
||||||
|
|
||||||
|
let info, child;
|
||||||
|
while ((info = children.next_file(null)) != null) {
|
||||||
|
let type = info.get_file_type();
|
||||||
|
let srcChild = srcDir.get_child(info.get_name());
|
||||||
|
let destChild = destDir.get_child(info.get_name());
|
||||||
|
log([srcChild.get_path(), destChild.get_path()]);
|
||||||
|
if (type == Gio.FileType.REGULAR)
|
||||||
|
srcChild.move(destChild, Gio.FileCopyFlags.NONE, null, null);
|
||||||
|
else if (type == Gio.FileType.DIRECTORY)
|
||||||
|
recursivelyMoveDir(srcChild, destChild);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -1,60 +0,0 @@
|
|||||||
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
|
|
||||||
|
|
||||||
/*
|
|
||||||
* This function is intended to extend the String object and provide
|
|
||||||
* an String.format API for string formatting.
|
|
||||||
* It has to be set up using String.prototype.format = Format.format;
|
|
||||||
* Usage:
|
|
||||||
* "somestring %s %d".format('hello', 5);
|
|
||||||
* It supports %s, %d, %x and %f, for %f it also support precisions like
|
|
||||||
* "%.2f".format(1.526). All specifiers can be prefixed with a minimum
|
|
||||||
* field width, e.g. "%5s".format("foo"). Unless the width is prefixed
|
|
||||||
* with '0', the formatted string will be padded with spaces.
|
|
||||||
*/
|
|
||||||
|
|
||||||
function format() {
|
|
||||||
let str = this;
|
|
||||||
let i = 0;
|
|
||||||
let args = arguments;
|
|
||||||
|
|
||||||
return str.replace(/%([0-9]+)?(?:\.([0-9]+))?(.)/g, function (str, widthGroup, precisionGroup, genericGroup) {
|
|
||||||
|
|
||||||
if (precisionGroup != '' && genericGroup != 'f')
|
|
||||||
throw new Error("Precision can only be specified for 'f'");
|
|
||||||
|
|
||||||
let fillChar = (widthGroup[0] == '0') ? '0' : ' ';
|
|
||||||
let width = parseInt(widthGroup, 10) || 0;
|
|
||||||
|
|
||||||
function fillWidth(s, c, w) {
|
|
||||||
let fill = '';
|
|
||||||
for (let i = 0; i < w; i++)
|
|
||||||
fill += c;
|
|
||||||
return fill.substr(s.length) + s;
|
|
||||||
}
|
|
||||||
|
|
||||||
let s = '';
|
|
||||||
switch (genericGroup) {
|
|
||||||
case '%':
|
|
||||||
return '%';
|
|
||||||
break;
|
|
||||||
case 's':
|
|
||||||
s = args[i++].toString();
|
|
||||||
break;
|
|
||||||
case 'd':
|
|
||||||
s = parseInt(args[i++]).toString();
|
|
||||||
break;
|
|
||||||
case 'x':
|
|
||||||
s = parseInt(args[i++]).toString(16);
|
|
||||||
break;
|
|
||||||
case 'f':
|
|
||||||
if (precisionGroup == '')
|
|
||||||
s = parseFloat(args[i++]).toString();
|
|
||||||
else
|
|
||||||
s = parseFloat(args[i++]).toFixed(parseInt(precisionGroup));
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
throw new Error('Unsupported conversion character %' + genericGroup);
|
|
||||||
}
|
|
||||||
return fillWidth(s, fillChar, width);
|
|
||||||
});
|
|
||||||
}
|
|
@ -50,9 +50,20 @@ const SessionManagerIface = <interface name="org.gnome.SessionManager">
|
|||||||
<arg type="u" direction="in" />
|
<arg type="u" direction="in" />
|
||||||
</method>
|
</method>
|
||||||
<method name="Shutdown" />
|
<method name="Shutdown" />
|
||||||
|
<method name="Reboot" />
|
||||||
<method name="CanShutdown">
|
<method name="CanShutdown">
|
||||||
<arg type="b" direction="out" />
|
<arg type="b" direction="out" />
|
||||||
</method>
|
</method>
|
||||||
|
<method name="IsInhibited">
|
||||||
|
<arg type="u" direction="in" />
|
||||||
|
<arg type="b" direction="out" />
|
||||||
|
</method>
|
||||||
|
<signal name="InhibitorAdded">
|
||||||
|
<arg type="o" direction="out"/>
|
||||||
|
</signal>
|
||||||
|
<signal name="InhibitorRemoved">
|
||||||
|
<arg type="o" direction="out"/>
|
||||||
|
</signal>
|
||||||
</interface>;
|
</interface>;
|
||||||
|
|
||||||
var SessionManagerProxy = Gio.DBusProxy.makeProxyWrapper(SessionManagerIface);
|
var SessionManagerProxy = Gio.DBusProxy.makeProxyWrapper(SessionManagerIface);
|
||||||
|
@ -83,25 +83,34 @@ function spawnCommandLine(command_line) {
|
|||||||
// this will throw an error.
|
// this will throw an error.
|
||||||
function trySpawn(argv)
|
function trySpawn(argv)
|
||||||
{
|
{
|
||||||
|
var success, pid;
|
||||||
try {
|
try {
|
||||||
GLib.spawn_async(null, argv, null,
|
[success, pid] = GLib.spawn_async(null, argv, null,
|
||||||
GLib.SpawnFlags.SEARCH_PATH,
|
GLib.SpawnFlags.SEARCH_PATH | GLib.SpawnFlags.DO_NOT_REAP_CHILD,
|
||||||
null, null);
|
null, null);
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
if (err.code == GLib.SpawnError.G_SPAWN_ERROR_NOENT) {
|
/* Rewrite the error in case of ENOENT */
|
||||||
err.message = _("Command not found");
|
if (err.matches(GLib.SpawnError, GLib.SpawnError.NOENT)) {
|
||||||
} else {
|
throw new GLib.SpawnError({ code: GLib.SpawnError.NOENT,
|
||||||
|
message: _("Command not found") });
|
||||||
|
} else if (err instanceof GLib.Error) {
|
||||||
// The exception from gjs contains an error string like:
|
// The exception from gjs contains an error string like:
|
||||||
// Error invoking GLib.spawn_command_line_async: Failed to
|
// Error invoking GLib.spawn_command_line_async: Failed to
|
||||||
// execute child process "foo" (No such file or directory)
|
// execute child process "foo" (No such file or directory)
|
||||||
// We are only interested in the part in the parentheses. (And
|
// We are only interested in the part in the parentheses. (And
|
||||||
// we can't pattern match the text, since it gets localized.)
|
// we can't pattern match the text, since it gets localized.)
|
||||||
err.message = err.message.replace(/.*\((.+)\)/, '$1');
|
let message = err.message.replace(/.*\((.+)\)/, '$1');
|
||||||
}
|
throw new (err.constructor)({ code: err.code,
|
||||||
|
message: message });
|
||||||
|
} else {
|
||||||
throw err;
|
throw err;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// Dummy child watch; we don't want to double-fork internally
|
||||||
|
// because then we lose the parent-child relationship, which
|
||||||
|
// can break polkit. See https://bugzilla.redhat.com//show_bug.cgi?id=819275
|
||||||
|
GLib.child_watch_add(GLib.PRIORITY_DEFAULT, pid, function () {}, null);
|
||||||
|
}
|
||||||
|
|
||||||
// trySpawnCommandLine:
|
// trySpawnCommandLine:
|
||||||
// @command_line: a command line
|
// @command_line: a command line
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
|
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
|
||||||
|
|
||||||
|
const System = imports.system;
|
||||||
|
|
||||||
const Main = imports.ui.main;
|
const Main = imports.ui.main;
|
||||||
const Scripting = imports.ui.scripting;
|
const Scripting = imports.ui.scripting;
|
||||||
|
|
||||||
@ -99,7 +101,7 @@ function run() {
|
|||||||
Main.overview.hide();
|
Main.overview.hide();
|
||||||
yield Scripting.waitLeisure();
|
yield Scripting.waitLeisure();
|
||||||
|
|
||||||
global.gc();
|
System.gc();
|
||||||
yield Scripting.sleep(1000);
|
yield Scripting.sleep(1000);
|
||||||
Scripting.collectStatistics();
|
Scripting.collectStatistics();
|
||||||
Scripting.scriptEvent('afterShowHide');
|
Scripting.scriptEvent('afterShowHide');
|
||||||
|
@ -22,6 +22,7 @@ const Search = imports.ui.search;
|
|||||||
const Tweener = imports.ui.tweener;
|
const Tweener = imports.ui.tweener;
|
||||||
const Workspace = imports.ui.workspace;
|
const Workspace = imports.ui.workspace;
|
||||||
const Params = imports.misc.params;
|
const Params = imports.misc.params;
|
||||||
|
const Util = imports.misc.util;
|
||||||
|
|
||||||
const MAX_APPLICATION_WORK_MILLIS = 75;
|
const MAX_APPLICATION_WORK_MILLIS = 75;
|
||||||
const MENU_POPUP_TIMEOUT = 600;
|
const MENU_POPUP_TIMEOUT = 600;
|
||||||
@ -36,6 +37,7 @@ const AlphabeticalView = new Lang.Class({
|
|||||||
|
|
||||||
this._pendingAppLaterId = 0;
|
this._pendingAppLaterId = 0;
|
||||||
this._appIcons = {}; // desktop file id
|
this._appIcons = {}; // desktop file id
|
||||||
|
this._allApps = [];
|
||||||
|
|
||||||
let box = new St.BoxLayout({ vertical: true });
|
let box = new St.BoxLayout({ vertical: true });
|
||||||
box.add(this._grid.actor, { y_align: St.Align.START, expand: true });
|
box.add(this._grid.actor, { y_align: St.Align.START, expand: true });
|
||||||
@ -60,16 +62,22 @@ const AlphabeticalView = new Lang.Class({
|
|||||||
}));
|
}));
|
||||||
},
|
},
|
||||||
|
|
||||||
_removeAll: function() {
|
removeAll: function() {
|
||||||
this._grid.removeAll();
|
this._grid.removeAll();
|
||||||
this._appIcons = {};
|
this._appIcons = {};
|
||||||
|
this._allApps = [];
|
||||||
},
|
},
|
||||||
|
|
||||||
_addApp: function(app) {
|
addApp: function(app) {
|
||||||
var id = app.get_id();
|
var id = app.get_id();
|
||||||
let appIcon = new AppWellIcon(app);
|
if (this._appIcons[id] !== undefined)
|
||||||
|
return;
|
||||||
|
|
||||||
this._grid.addItem(appIcon.actor);
|
let appIcon = new AppWellIcon(app);
|
||||||
|
let pos = Util.insertSorted(this._allApps, app, function(a, b) {
|
||||||
|
return a.compare_by_name(b);
|
||||||
|
});
|
||||||
|
this._grid.addItem(appIcon.actor, pos);
|
||||||
appIcon.actor.connect('key-focus-in', Lang.bind(this, this._ensureIconVisible));
|
appIcon.actor.connect('key-focus-in', Lang.bind(this, this._ensureIconVisible));
|
||||||
|
|
||||||
this._appIcons[id] = appIcon;
|
this._appIcons[id] = appIcon;
|
||||||
@ -120,14 +128,6 @@ const AlphabeticalView = new Lang.Class({
|
|||||||
icon.actor.visible = true;
|
icon.actor.visible = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
|
||||||
|
|
||||||
setAppList: function(apps) {
|
|
||||||
this._removeAll();
|
|
||||||
for (var i = 0; i < apps.length; i++) {
|
|
||||||
var app = apps[i];
|
|
||||||
this._addApp(app);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -147,7 +147,6 @@ const ViewByCategories = new Lang.Class({
|
|||||||
// (used only before the actor is mapped the first time)
|
// (used only before the actor is mapped the first time)
|
||||||
this._currentCategory = -2;
|
this._currentCategory = -2;
|
||||||
this._categories = [];
|
this._categories = [];
|
||||||
this._apps = null;
|
|
||||||
|
|
||||||
this._categoryBox = new St.BoxLayout({ vertical: true,
|
this._categoryBox = new St.BoxLayout({ vertical: true,
|
||||||
reactive: true,
|
reactive: true,
|
||||||
@ -204,16 +203,19 @@ const ViewByCategories = new Lang.Class({
|
|||||||
if (nextType == GMenu.TreeItemType.ENTRY) {
|
if (nextType == GMenu.TreeItemType.ENTRY) {
|
||||||
var entry = iter.get_entry();
|
var entry = iter.get_entry();
|
||||||
var app = this._appSystem.lookup_app_by_tree_entry(entry);
|
var app = this._appSystem.lookup_app_by_tree_entry(entry);
|
||||||
if (!entry.get_app_info().get_nodisplay())
|
if (!entry.get_app_info().get_nodisplay()) {
|
||||||
|
this._view.addApp(app);
|
||||||
appList.push(app);
|
appList.push(app);
|
||||||
|
}
|
||||||
} else if (nextType == GMenu.TreeItemType.DIRECTORY) {
|
} else if (nextType == GMenu.TreeItemType.DIRECTORY) {
|
||||||
if (!dir.get_is_nodisplay())
|
var itemDir = iter.get_directory();
|
||||||
this._loadCategory(iter.get_directory(), appList);
|
if (!itemDir.get_is_nodisplay())
|
||||||
|
this._loadCategory(itemDir, appList);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
_addCategory: function(name, index, dir, allApps) {
|
_addCategory: function(name, index, dir) {
|
||||||
let button = new St.Button({ label: GLib.markup_escape_text (name, -1),
|
let button = new St.Button({ label: GLib.markup_escape_text (name, -1),
|
||||||
style_class: 'app-filter',
|
style_class: 'app-filter',
|
||||||
x_align: St.Align.START,
|
x_align: St.Align.START,
|
||||||
@ -225,7 +227,6 @@ const ViewByCategories = new Lang.Class({
|
|||||||
|
|
||||||
var apps;
|
var apps;
|
||||||
if (dir == null) {
|
if (dir == null) {
|
||||||
apps = allApps;
|
|
||||||
this._allCategoryButton = button;
|
this._allCategoryButton = button;
|
||||||
} else {
|
} else {
|
||||||
apps = [];
|
apps = [];
|
||||||
@ -239,6 +240,7 @@ const ViewByCategories = new Lang.Class({
|
|||||||
},
|
},
|
||||||
|
|
||||||
_removeAll: function() {
|
_removeAll: function() {
|
||||||
|
this._view.removeAll();
|
||||||
this._categories = [];
|
this._categories = [];
|
||||||
this._categoryBox.destroy_all_children();
|
this._categoryBox.destroy_all_children();
|
||||||
},
|
},
|
||||||
@ -246,13 +248,8 @@ const ViewByCategories = new Lang.Class({
|
|||||||
refresh: function() {
|
refresh: function() {
|
||||||
this._removeAll();
|
this._removeAll();
|
||||||
|
|
||||||
var allApps = Shell.AppSystem.get_default().get_all();
|
|
||||||
allApps.sort(function(a, b) {
|
|
||||||
return a.compare_by_name(b);
|
|
||||||
});
|
|
||||||
|
|
||||||
/* Translators: Filter to display all applications */
|
/* Translators: Filter to display all applications */
|
||||||
this._addCategory(_("All"), -1, null, allApps);
|
this._addCategory(_("All"), -1, null);
|
||||||
|
|
||||||
var tree = this._appSystem.get_tree();
|
var tree = this._appSystem.get_tree();
|
||||||
var root = tree.get_root_directory();
|
var root = tree.get_root_directory();
|
||||||
@ -270,7 +267,6 @@ const ViewByCategories = new Lang.Class({
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
this._view.setAppList(allApps);
|
|
||||||
this._selectCategory(-1);
|
this._selectCategory(-1);
|
||||||
|
|
||||||
if (this._focusDummy) {
|
if (this._focusDummy) {
|
||||||
@ -312,11 +308,10 @@ const AppSearchProvider = new Lang.Class({
|
|||||||
|
|
||||||
_init: function() {
|
_init: function() {
|
||||||
this.parent(_("APPLICATIONS"));
|
this.parent(_("APPLICATIONS"));
|
||||||
|
|
||||||
this._appSys = Shell.AppSystem.get_default();
|
this._appSys = Shell.AppSystem.get_default();
|
||||||
},
|
},
|
||||||
|
|
||||||
getResultMetas: function(apps) {
|
getResultMetas: function(apps, callback) {
|
||||||
let metas = [];
|
let metas = [];
|
||||||
for (let i = 0; i < apps.length; i++) {
|
for (let i = 0; i < apps.length; i++) {
|
||||||
let app = apps[i];
|
let app = apps[i];
|
||||||
@ -327,15 +322,15 @@ const AppSearchProvider = new Lang.Class({
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
return metas;
|
callback(metas);
|
||||||
},
|
},
|
||||||
|
|
||||||
getInitialResultSet: function(terms) {
|
getInitialResultSet: function(terms) {
|
||||||
return this._appSys.initial_search(terms);
|
this.searchSystem.pushResults(this, this._appSys.initial_search(terms));
|
||||||
},
|
},
|
||||||
|
|
||||||
getSubsearchResultSet: function(previousResults, terms) {
|
getSubsearchResultSet: function(previousResults, terms) {
|
||||||
return this._appSys.subsearch(previousResults, terms);
|
this.searchSystem.pushResults(this, this._appSys.subsearch(previousResults, terms));
|
||||||
},
|
},
|
||||||
|
|
||||||
activateResult: function(app, params) {
|
activateResult: function(app, params) {
|
||||||
@ -378,7 +373,7 @@ const SettingsSearchProvider = new Lang.Class({
|
|||||||
this._gnomecc = this._appSys.lookup_app('gnome-control-center.desktop');
|
this._gnomecc = this._appSys.lookup_app('gnome-control-center.desktop');
|
||||||
},
|
},
|
||||||
|
|
||||||
getResultMetas: function(prefs) {
|
getResultMetas: function(prefs, callback) {
|
||||||
let metas = [];
|
let metas = [];
|
||||||
for (let i = 0; i < prefs.length; i++) {
|
for (let i = 0; i < prefs.length; i++) {
|
||||||
let pref = prefs[i];
|
let pref = prefs[i];
|
||||||
@ -389,15 +384,15 @@ const SettingsSearchProvider = new Lang.Class({
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
return metas;
|
callback(metas);
|
||||||
},
|
},
|
||||||
|
|
||||||
getInitialResultSet: function(terms) {
|
getInitialResultSet: function(terms) {
|
||||||
return this._appSys.search_settings(terms);
|
this.searchSystem.pushResults(this, this._appSys.search_settings(terms));
|
||||||
},
|
},
|
||||||
|
|
||||||
getSubsearchResultSet: function(previousResults, terms) {
|
getSubsearchResultSet: function(previousResults, terms) {
|
||||||
return this._appSys.search_settings(terms);
|
this.searchSystem.pushResults(this, this._appSys.search_settings(terms));
|
||||||
},
|
},
|
||||||
|
|
||||||
activateResult: function(pref, params) {
|
activateResult: function(pref, params) {
|
||||||
|
@ -10,6 +10,9 @@ const Shell = imports.gi.Shell;
|
|||||||
const Main = imports.ui.main;
|
const Main = imports.ui.main;
|
||||||
const ShellMountOperation = imports.ui.shellMountOperation;
|
const ShellMountOperation = imports.ui.shellMountOperation;
|
||||||
const ScreenSaver = imports.misc.screenSaver;
|
const ScreenSaver = imports.misc.screenSaver;
|
||||||
|
const GnomeSession = imports.misc.gnomeSession;
|
||||||
|
|
||||||
|
const GNOME_SESSION_AUTOMOUNT_INHIBIT = 16;
|
||||||
|
|
||||||
// GSettings keys
|
// GSettings keys
|
||||||
const SETTINGS_SCHEMA = 'org.gnome.desktop.media-handling';
|
const SETTINGS_SCHEMA = 'org.gnome.desktop.media-handling';
|
||||||
@ -79,6 +82,12 @@ const AutomountManager = new Lang.Class({
|
|||||||
_init: function() {
|
_init: function() {
|
||||||
this._settings = new Gio.Settings({ schema: SETTINGS_SCHEMA });
|
this._settings = new Gio.Settings({ schema: SETTINGS_SCHEMA });
|
||||||
this._volumeQueue = [];
|
this._volumeQueue = [];
|
||||||
|
this._session = new GnomeSession.SessionManager();
|
||||||
|
this._session.connectSignal('InhibitorAdded',
|
||||||
|
Lang.bind(this, this._InhibitorsChanged));
|
||||||
|
this._session.connectSignal('InhibitorRemoved',
|
||||||
|
Lang.bind(this, this._InhibitorsChanged));
|
||||||
|
this._inhibited = false;
|
||||||
|
|
||||||
if (!haveSystemd())
|
if (!haveSystemd())
|
||||||
this.ckListener = new ConsoleKitManager();
|
this.ckListener = new ConsoleKitManager();
|
||||||
@ -108,6 +117,16 @@ const AutomountManager = new Lang.Class({
|
|||||||
Mainloop.idle_add(Lang.bind(this, this._startupMountAll));
|
Mainloop.idle_add(Lang.bind(this, this._startupMountAll));
|
||||||
},
|
},
|
||||||
|
|
||||||
|
_InhibitorsChanged: function(object, senderName, [inhibtor]) {
|
||||||
|
this._session.IsInhibitedRemote(GNOME_SESSION_AUTOMOUNT_INHIBIT,
|
||||||
|
Lang.bind(this,
|
||||||
|
function(result, error) {
|
||||||
|
if (!error) {
|
||||||
|
this._inhibited = result[0];
|
||||||
|
}
|
||||||
|
}));
|
||||||
|
},
|
||||||
|
|
||||||
_screenSaverActiveChanged: function(object, senderName, [isActive]) {
|
_screenSaverActiveChanged: function(object, senderName, [isActive]) {
|
||||||
if (!isActive) {
|
if (!isActive) {
|
||||||
this._volumeQueue.forEach(Lang.bind(this, function(volume) {
|
this._volumeQueue.forEach(Lang.bind(this, function(volume) {
|
||||||
@ -123,7 +142,8 @@ const AutomountManager = new Lang.Class({
|
|||||||
let volumes = this._volumeMonitor.get_volumes();
|
let volumes = this._volumeMonitor.get_volumes();
|
||||||
volumes.forEach(Lang.bind(this, function(volume) {
|
volumes.forEach(Lang.bind(this, function(volume) {
|
||||||
this._checkAndMountVolume(volume, { checkSession: false,
|
this._checkAndMountVolume(volume, { checkSession: false,
|
||||||
useMountOp: false });
|
useMountOp: false,
|
||||||
|
allowAutorun: false });
|
||||||
}));
|
}));
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
@ -201,7 +221,8 @@ const AutomountManager = new Lang.Class({
|
|||||||
|
|
||||||
_checkAndMountVolume: function(volume, params) {
|
_checkAndMountVolume: function(volume, params) {
|
||||||
params = Params.parse(params, { checkSession: true,
|
params = Params.parse(params, { checkSession: true,
|
||||||
useMountOp: true });
|
useMountOp: true,
|
||||||
|
allowAutorun: true });
|
||||||
|
|
||||||
if (params.checkSession) {
|
if (params.checkSession) {
|
||||||
// if we're not in the current ConsoleKit session,
|
// if we're not in the current ConsoleKit session,
|
||||||
@ -217,6 +238,9 @@ const AutomountManager = new Lang.Class({
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (this._inhibited)
|
||||||
|
return;
|
||||||
|
|
||||||
// Volume is already mounted, don't bother.
|
// Volume is already mounted, don't bother.
|
||||||
if (volume.get_mount())
|
if (volume.get_mount())
|
||||||
return;
|
return;
|
||||||
@ -236,15 +260,20 @@ const AutomountManager = new Lang.Class({
|
|||||||
|
|
||||||
if (params.useMountOp) {
|
if (params.useMountOp) {
|
||||||
let operation = new ShellMountOperation.ShellMountOperation(volume);
|
let operation = new ShellMountOperation.ShellMountOperation(volume);
|
||||||
this._mountVolume(volume, operation.mountOp);
|
this._mountVolume(volume, operation, params.allowAutorun);
|
||||||
} else {
|
} else {
|
||||||
this._mountVolume(volume, null);
|
this._mountVolume(volume, null, params.allowAutorun);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
_mountVolume: function(volume, operation) {
|
_mountVolume: function(volume, operation, allowAutorun) {
|
||||||
|
if (allowAutorun)
|
||||||
this._allowAutorun(volume);
|
this._allowAutorun(volume);
|
||||||
volume.mount(0, operation, null,
|
|
||||||
|
let mountOp = operation ? operation.mountOp : null;
|
||||||
|
volume._operation = operation;
|
||||||
|
|
||||||
|
volume.mount(0, mountOp, null,
|
||||||
Lang.bind(this, this._onVolumeMounted));
|
Lang.bind(this, this._onVolumeMounted));
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -253,15 +282,19 @@ const AutomountManager = new Lang.Class({
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
volume.mount_finish(res);
|
volume.mount_finish(res);
|
||||||
|
this._closeOperation(volume);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
let string = e.toString();
|
// FIXME: we will always get G_IO_ERROR_FAILED from the gvfs udisks
|
||||||
|
// backend in this case, see
|
||||||
// FIXME: needs proper error code handling instead of this
|
// https://bugs.freedesktop.org/show_bug.cgi?id=51271
|
||||||
// See https://bugzilla.gnome.org/show_bug.cgi?id=591480
|
if (e.message.indexOf('No key available with this passphrase') != -1) {
|
||||||
if (string.indexOf('No key available with this passphrase') != -1)
|
|
||||||
this._reaskPassword(volume);
|
this._reaskPassword(volume);
|
||||||
else
|
} else {
|
||||||
log('Unable to mount volume ' + volume.get_name() + ': ' + string);
|
if (!e.matches(Gio.IOErrorEnum, Gio.IOErrorEnum.FAILED_HANDLED))
|
||||||
|
log('Unable to mount volume ' + volume.get_name() + ': ' + e.toString());
|
||||||
|
|
||||||
|
this._closeOperation(volume);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -273,8 +306,16 @@ const AutomountManager = new Lang.Class({
|
|||||||
},
|
},
|
||||||
|
|
||||||
_reaskPassword: function(volume) {
|
_reaskPassword: function(volume) {
|
||||||
let operation = new ShellMountOperation.ShellMountOperation(volume, { reaskPassword: true });
|
let existingDialog = volume._operation ? volume._operation.borrowDialog() : null;
|
||||||
this._mountVolume(volume, operation.mountOp);
|
let operation =
|
||||||
|
new ShellMountOperation.ShellMountOperation(volume,
|
||||||
|
{ existingDialog: existingDialog });
|
||||||
|
this._mountVolume(volume, operation);
|
||||||
|
},
|
||||||
|
|
||||||
|
_closeOperation: function(volume) {
|
||||||
|
if (volume._operation)
|
||||||
|
volume._operation.close();
|
||||||
},
|
},
|
||||||
|
|
||||||
_allowAutorun: function(volume) {
|
_allowAutorun: function(volume) {
|
||||||
|
@ -23,12 +23,14 @@ const AutorunSetting = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// misc utils
|
// misc utils
|
||||||
function ignoreAutorunForMount(mount) {
|
function shouldAutorunMount(mount, forTransient) {
|
||||||
let root = mount.get_root();
|
let root = mount.get_root();
|
||||||
let volume = mount.get_volume();
|
let volume = mount.get_volume();
|
||||||
|
|
||||||
if ((root.is_native() && !isMountRootHidden(root)) ||
|
if (!volume || (!volume.allowAutorun && forTransient))
|
||||||
(volume && volume.allowAutorun && volume.should_automount()))
|
return false;
|
||||||
|
|
||||||
|
if (!root.is_native() || isMountRootHidden(root))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
@ -224,9 +226,7 @@ const AutorunManager = new Lang.Class({
|
|||||||
try {
|
try {
|
||||||
mount.unmount_with_operation_finish(res);
|
mount.unmount_with_operation_finish(res);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
// FIXME: we need to ignore G_IO_ERROR_FAILED_HANDLED errors here
|
if (!e.matches(Gio.IOErrorEnum, Gio.IOErrorEnum.FAILED_HANDLED))
|
||||||
// but we can't access the error code from JS.
|
|
||||||
// See https://bugzilla.gnome.org/show_bug.cgi?id=591480
|
|
||||||
log('Unable to eject the mount ' + mount.get_name()
|
log('Unable to eject the mount ' + mount.get_name()
|
||||||
+ ': ' + e.toString());
|
+ ': ' + e.toString());
|
||||||
}
|
}
|
||||||
@ -236,9 +236,7 @@ const AutorunManager = new Lang.Class({
|
|||||||
try {
|
try {
|
||||||
source.eject_with_operation_finish(res);
|
source.eject_with_operation_finish(res);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
// FIXME: we need to ignore G_IO_ERROR_FAILED_HANDLED errors here
|
if (!e.matches(Gio.IOErrorEnum, Gio.IOErrorEnum.FAILED_HANDLED))
|
||||||
// but we can't access the error code from JS.
|
|
||||||
// See https://bugzilla.gnome.org/show_bug.cgi?id=591480
|
|
||||||
log('Unable to eject the drive ' + source.get_name()
|
log('Unable to eject the drive ' + source.get_name()
|
||||||
+ ': ' + e.toString());
|
+ ': ' + e.toString());
|
||||||
}
|
}
|
||||||
@ -248,9 +246,7 @@ const AutorunManager = new Lang.Class({
|
|||||||
try {
|
try {
|
||||||
drive.stop_finish(res);
|
drive.stop_finish(res);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
// FIXME: we need to ignore G_IO_ERROR_FAILED_HANDLED errors here
|
if (!e.matches(Gio.IOErrorEnum, Gio.IOErrorEnum.FAILED_HANDLED))
|
||||||
// but we can't access the error code from JS.
|
|
||||||
// See https://bugzilla.gnome.org/show_bug.cgi?id=591480
|
|
||||||
log('Unable to stop the drive ' + drive.get_name()
|
log('Unable to stop the drive ' + drive.get_name()
|
||||||
+ ': ' + e.toString());
|
+ ': ' + e.toString());
|
||||||
}
|
}
|
||||||
@ -262,16 +258,15 @@ const AutorunResidentSource = new Lang.Class({
|
|||||||
Extends: MessageTray.Source,
|
Extends: MessageTray.Source,
|
||||||
|
|
||||||
_init: function() {
|
_init: function() {
|
||||||
this.parent(_("Removable Devices"));
|
this.parent(_("Removable Devices"), 'media-removable', St.IconType.FULLCOLOR);
|
||||||
|
|
||||||
this._mounts = [];
|
this._mounts = [];
|
||||||
|
|
||||||
this._notification = new AutorunResidentNotification(this);
|
this._notification = new AutorunResidentNotification(this);
|
||||||
this._setSummaryIcon(this.createNotificationIcon());
|
|
||||||
},
|
},
|
||||||
|
|
||||||
addMount: function(mount, apps) {
|
addMount: function(mount, apps) {
|
||||||
if (ignoreAutorunForMount(mount))
|
if (!shouldAutorunMount(mount, false))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
let filtered = this._mounts.filter(function (element) {
|
let filtered = this._mounts.filter(function (element) {
|
||||||
@ -310,12 +305,6 @@ const AutorunResidentSource = new Lang.Class({
|
|||||||
Main.messageTray.add(this);
|
Main.messageTray.add(this);
|
||||||
this.pushNotification(this._notification);
|
this.pushNotification(this._notification);
|
||||||
}
|
}
|
||||||
},
|
|
||||||
|
|
||||||
createNotificationIcon: function() {
|
|
||||||
return new St.Icon ({ icon_name: 'media-removable',
|
|
||||||
icon_type: St.IconType.FULLCOLOR,
|
|
||||||
icon_size: this.ICON_SIZE });
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -455,7 +444,7 @@ const AutorunTransientDispatcher = new Lang.Class({
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
// if the mount doesn't want to be autorun, return
|
// if the mount doesn't want to be autorun, return
|
||||||
if (ignoreAutorunForMount(mount))
|
if (!shouldAutorunMount(mount, true))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
let setting = this._getAutorunSettingForType(contentTypes[0]);
|
let setting = this._getAutorunSettingForType(contentTypes[0]);
|
||||||
@ -500,11 +489,11 @@ const AutorunTransientSource = new Lang.Class({
|
|||||||
Extends: MessageTray.Source,
|
Extends: MessageTray.Source,
|
||||||
|
|
||||||
_init: function(mount, apps) {
|
_init: function(mount, apps) {
|
||||||
this.parent(mount.get_name());
|
|
||||||
|
|
||||||
this.mount = mount;
|
this.mount = mount;
|
||||||
this.apps = apps;
|
this.apps = apps;
|
||||||
|
|
||||||
|
this.parent(mount.get_name());
|
||||||
|
|
||||||
this._notification = new AutorunTransientNotification(this);
|
this._notification = new AutorunTransientNotification(this);
|
||||||
this._setSummaryIcon(this.createNotificationIcon());
|
this._setSummaryIcon(this.createNotificationIcon());
|
||||||
|
|
||||||
|
@ -9,6 +9,13 @@ const Shell = imports.gi.Shell;
|
|||||||
const Main = imports.ui.main;
|
const Main = imports.ui.main;
|
||||||
const Tweener = imports.ui.tweener;
|
const Tweener = imports.ui.tweener;
|
||||||
|
|
||||||
|
const PopupAnimation = {
|
||||||
|
NONE: 0,
|
||||||
|
SLIDE: 1 << 0,
|
||||||
|
FADE: 1 << 1,
|
||||||
|
FULL: ~0,
|
||||||
|
};
|
||||||
|
|
||||||
const POPUP_ANIMATION_TIME = 0.15;
|
const POPUP_ANIMATION_TIME = 0.15;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -18,7 +25,10 @@ const POPUP_ANIMATION_TIME = 0.15;
|
|||||||
*
|
*
|
||||||
* An actor which displays a triangle "arrow" pointing to a given
|
* An actor which displays a triangle "arrow" pointing to a given
|
||||||
* side. The .bin property is a container in which content can be
|
* side. The .bin property is a container in which content can be
|
||||||
* placed. The arrow position may be controlled via setArrowOrigin().
|
* placed. The arrow position may be controlled via
|
||||||
|
* setArrowOrigin(). The arrow side might be temporarily flipped
|
||||||
|
* depending on the box size and source position to keep the box
|
||||||
|
* totally inside the monitor if possible.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
const BoxPointer = new Lang.Class({
|
const BoxPointer = new Lang.Class({
|
||||||
@ -26,6 +36,7 @@ const BoxPointer = new Lang.Class({
|
|||||||
|
|
||||||
_init: function(arrowSide, binProperties) {
|
_init: function(arrowSide, binProperties) {
|
||||||
this._arrowSide = arrowSide;
|
this._arrowSide = arrowSide;
|
||||||
|
this._userArrowSide = arrowSide;
|
||||||
this._arrowOrigin = 0;
|
this._arrowOrigin = 0;
|
||||||
this.actor = new St.Bin({ x_fill: true,
|
this.actor = new St.Bin({ x_fill: true,
|
||||||
y_fill: true });
|
y_fill: true });
|
||||||
@ -65,11 +76,16 @@ const BoxPointer = new Lang.Class({
|
|||||||
show: function(animate, onComplete) {
|
show: function(animate, onComplete) {
|
||||||
let themeNode = this.actor.get_theme_node();
|
let themeNode = this.actor.get_theme_node();
|
||||||
let rise = themeNode.get_length('-arrow-rise');
|
let rise = themeNode.get_length('-arrow-rise');
|
||||||
|
let animationTime = (animate & PopupAnimation.FULL) ? POPUP_ANIMATION_TIME : 0;
|
||||||
|
|
||||||
|
if (animate & PopupAnimation.FADE)
|
||||||
this.opacity = 0;
|
this.opacity = 0;
|
||||||
|
else
|
||||||
|
this.opacity = 255;
|
||||||
|
|
||||||
this.actor.show();
|
this.actor.show();
|
||||||
|
|
||||||
if (animate) {
|
if (animate & PopupAnimation.SLIDE) {
|
||||||
switch (this._arrowSide) {
|
switch (this._arrowSide) {
|
||||||
case St.Side.TOP:
|
case St.Side.TOP:
|
||||||
this.yOffset = -rise;
|
this.yOffset = -rise;
|
||||||
@ -95,7 +111,7 @@ const BoxPointer = new Lang.Class({
|
|||||||
if (onComplete)
|
if (onComplete)
|
||||||
onComplete();
|
onComplete();
|
||||||
}),
|
}),
|
||||||
time: POPUP_ANIMATION_TIME });
|
time: animationTime });
|
||||||
},
|
},
|
||||||
|
|
||||||
hide: function(animate, onComplete) {
|
hide: function(animate, onComplete) {
|
||||||
@ -103,8 +119,10 @@ const BoxPointer = new Lang.Class({
|
|||||||
let yOffset = 0;
|
let yOffset = 0;
|
||||||
let themeNode = this.actor.get_theme_node();
|
let themeNode = this.actor.get_theme_node();
|
||||||
let rise = themeNode.get_length('-arrow-rise');
|
let rise = themeNode.get_length('-arrow-rise');
|
||||||
|
let fade = (animate & PopupAnimation.FADE);
|
||||||
|
let animationTime = (animate & PopupAnimation.FULL) ? POPUP_ANIMATION_TIME : 0;
|
||||||
|
|
||||||
if (animate) {
|
if (animate & PopupAnimation.SLIDE) {
|
||||||
switch (this._arrowSide) {
|
switch (this._arrowSide) {
|
||||||
case St.Side.TOP:
|
case St.Side.TOP:
|
||||||
yOffset = rise;
|
yOffset = rise;
|
||||||
@ -123,13 +141,14 @@ const BoxPointer = new Lang.Class({
|
|||||||
|
|
||||||
this._muteInput();
|
this._muteInput();
|
||||||
|
|
||||||
Tweener.addTween(this, { opacity: 0,
|
Tweener.addTween(this, { opacity: fade ? 0 : 255,
|
||||||
xOffset: xOffset,
|
xOffset: xOffset,
|
||||||
yOffset: yOffset,
|
yOffset: yOffset,
|
||||||
transition: 'linear',
|
transition: 'linear',
|
||||||
time: POPUP_ANIMATION_TIME,
|
time: animationTime,
|
||||||
onComplete: Lang.bind(this, function () {
|
onComplete: Lang.bind(this, function () {
|
||||||
this.actor.hide();
|
this.actor.hide();
|
||||||
|
this.opacity = 0;
|
||||||
this.xOffset = 0;
|
this.xOffset = 0;
|
||||||
this.yOffset = 0;
|
this.yOffset = 0;
|
||||||
if (onComplete)
|
if (onComplete)
|
||||||
@ -199,8 +218,27 @@ const BoxPointer = new Lang.Class({
|
|||||||
}
|
}
|
||||||
this.bin.allocate(childBox, flags);
|
this.bin.allocate(childBox, flags);
|
||||||
|
|
||||||
if (this._sourceActor && this._sourceActor.mapped)
|
if (this._sourceActor && this._sourceActor.mapped) {
|
||||||
this._reposition(this._sourceActor, this._arrowAlignment);
|
this._reposition(this._sourceActor, this._arrowAlignment);
|
||||||
|
|
||||||
|
if (this._shouldFlip()) {
|
||||||
|
switch (this._arrowSide) {
|
||||||
|
case St.Side.TOP:
|
||||||
|
this._arrowSide = St.Side.BOTTOM;
|
||||||
|
break;
|
||||||
|
case St.Side.BOTTOM:
|
||||||
|
this._arrowSide = St.Side.TOP;
|
||||||
|
break;
|
||||||
|
case St.Side.LEFT:
|
||||||
|
this._arrowSide = St.Side.RIGHT;
|
||||||
|
break;
|
||||||
|
case St.Side.RIGHT:
|
||||||
|
this._arrowSide = St.Side.LEFT;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
this._reposition(this._sourceActor, this._arrowAlignment);
|
||||||
|
}
|
||||||
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
_drawBorder: function(area) {
|
_drawBorder: function(area) {
|
||||||
@ -327,6 +365,8 @@ const BoxPointer = new Lang.Class({
|
|||||||
},
|
},
|
||||||
|
|
||||||
setPosition: function(sourceActor, alignment) {
|
setPosition: function(sourceActor, alignment) {
|
||||||
|
this._arrowSide = this._userArrowSide;
|
||||||
|
|
||||||
// We need to show it now to force an allocation,
|
// We need to show it now to force an allocation,
|
||||||
// so that we can query the correct size.
|
// so that we can query the correct size.
|
||||||
this.actor.show();
|
this.actor.show();
|
||||||
@ -343,11 +383,7 @@ const BoxPointer = new Lang.Class({
|
|||||||
if (!this._sourceActor)
|
if (!this._sourceActor)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// We need to show it now to force an allocation,
|
this.setPosition(this._sourceActor, this._arrowAlignment);
|
||||||
// so that we can query the correct size.
|
|
||||||
this.actor.show();
|
|
||||||
|
|
||||||
this._reposition(this._sourceActor, this._arrowAlignment);
|
|
||||||
},
|
},
|
||||||
|
|
||||||
_reposition: function(sourceActor, alignment) {
|
_reposition: function(sourceActor, alignment) {
|
||||||
@ -446,6 +482,39 @@ const BoxPointer = new Lang.Class({
|
|||||||
-(this._yPosition + this._yOffset));
|
-(this._yPosition + this._yOffset));
|
||||||
},
|
},
|
||||||
|
|
||||||
|
_shouldFlip: function() {
|
||||||
|
let sourceAllocation = Shell.util_get_transformed_allocation(this._sourceActor);
|
||||||
|
let boxAllocation = Shell.util_get_transformed_allocation(this.actor);
|
||||||
|
let boxWidth = boxAllocation.x2 - boxAllocation.x1;
|
||||||
|
let boxHeight = boxAllocation.y2 - boxAllocation.y1;
|
||||||
|
let monitor = Main.layoutManager.findMonitorForActor(this.actor);
|
||||||
|
|
||||||
|
switch (this._arrowSide) {
|
||||||
|
case St.Side.TOP:
|
||||||
|
if (boxAllocation.y2 > monitor.y + monitor.height &&
|
||||||
|
boxHeight < sourceAllocation.y1 - monitor.y)
|
||||||
|
return true;
|
||||||
|
break;
|
||||||
|
case St.Side.BOTTOM:
|
||||||
|
if (boxAllocation.y1 < monitor.y &&
|
||||||
|
boxHeight < monitor.y + monitor.height - sourceAllocation.y2)
|
||||||
|
return true;
|
||||||
|
break;
|
||||||
|
case St.Side.LEFT:
|
||||||
|
if (boxAllocation.x2 > monitor.x + monitor.width &&
|
||||||
|
boxWidth < sourceAllocation.x1 - monitor.x)
|
||||||
|
return true;
|
||||||
|
break;
|
||||||
|
case St.Side.RIGHT:
|
||||||
|
if (boxAllocation.x1 < monitor.x &&
|
||||||
|
boxWidth < monitor.x + monitor.width - sourceAllocation.x2)
|
||||||
|
return true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
},
|
||||||
|
|
||||||
set xOffset(offset) {
|
set xOffset(offset) {
|
||||||
this._xOffset = offset;
|
this._xOffset = offset;
|
||||||
this._shiftActor();
|
this._shiftActor();
|
||||||
|
@ -448,7 +448,7 @@ const Calendar = new Lang.Class({
|
|||||||
}
|
}
|
||||||
|
|
||||||
// All the children after this are days, and get removed when we update the calendar
|
// All the children after this are days, and get removed when we update the calendar
|
||||||
this._firstDayIndex = this.actor.get_children().length;
|
this._firstDayIndex = this.actor.get_n_children();
|
||||||
},
|
},
|
||||||
|
|
||||||
_onStyleChange: function(actor, event) {
|
_onStyleChange: function(actor, event) {
|
||||||
@ -551,6 +551,7 @@ const Calendar = new Lang.Class({
|
|||||||
let row = 2;
|
let row = 2;
|
||||||
while (true) {
|
while (true) {
|
||||||
let button = new St.Button({ label: iter.getDate().toString() });
|
let button = new St.Button({ label: iter.getDate().toString() });
|
||||||
|
let rtl = button.get_text_direction() == Clutter.TextDirection.RTL;
|
||||||
|
|
||||||
if (!this._eventSource)
|
if (!this._eventSource)
|
||||||
button.reactive = false;
|
button.reactive = false;
|
||||||
@ -571,7 +572,10 @@ const Calendar = new Lang.Class({
|
|||||||
// Hack used in lieu of border-collapse - see gnome-shell.css
|
// Hack used in lieu of border-collapse - see gnome-shell.css
|
||||||
if (row == 2)
|
if (row == 2)
|
||||||
styleClass = 'calendar-day-top ' + styleClass;
|
styleClass = 'calendar-day-top ' + styleClass;
|
||||||
if (iter.getDay() == this._weekStart)
|
|
||||||
|
let leftMost = rtl ? iter.getDay() == (this._weekStart + 6) % 7
|
||||||
|
: iter.getDay() == this._weekStart;
|
||||||
|
if (leftMost)
|
||||||
styleClass = 'calendar-day-left ' + styleClass;
|
styleClass = 'calendar-day-left ' + styleClass;
|
||||||
|
|
||||||
if (_sameDay(now, iter))
|
if (_sameDay(now, iter))
|
||||||
|
@ -1,196 +0,0 @@
|
|||||||
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
|
|
||||||
|
|
||||||
const Folks = imports.gi.Folks
|
|
||||||
const Lang = imports.lang;
|
|
||||||
const Meta = imports.gi.Meta;
|
|
||||||
const Shell = imports.gi.Shell;
|
|
||||||
const St = imports.gi.St;
|
|
||||||
const Atk = imports.gi.Atk;
|
|
||||||
|
|
||||||
const Util = imports.misc.util;
|
|
||||||
const IconGrid = imports.ui.iconGrid;
|
|
||||||
const Search = imports.ui.search;
|
|
||||||
const SearchDisplay = imports.ui.searchDisplay;
|
|
||||||
|
|
||||||
const MAX_SEARCH_RESULTS_ROWS = 1;
|
|
||||||
const ICON_SIZE = 81;
|
|
||||||
|
|
||||||
function launchContact(id) {
|
|
||||||
Util.spawn(['gnome-contacts', '-i', id]);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* This class represents a shown contact search result in the overview */
|
|
||||||
const Contact = new Lang.Class({
|
|
||||||
Name: 'Contact',
|
|
||||||
|
|
||||||
_init: function(id) {
|
|
||||||
this._contactSys = Shell.ContactSystem.get_default();
|
|
||||||
this.individual = this._contactSys.get_individual(id);
|
|
||||||
|
|
||||||
this.actor = new St.Bin({ style_class: 'contact',
|
|
||||||
reactive: true,
|
|
||||||
can_focus: true,
|
|
||||||
track_hover: true,
|
|
||||||
accessible_role: Atk.Role.PUSH_BUTTON });
|
|
||||||
|
|
||||||
let content = new St.BoxLayout( { style_class: 'contact-content',
|
|
||||||
vertical: false });
|
|
||||||
this.actor.set_child(content);
|
|
||||||
|
|
||||||
let icon = new St.Icon({ icon_type: St.IconType.FULLCOLOR,
|
|
||||||
icon_size: ICON_SIZE,
|
|
||||||
style_class: 'contact-icon' });
|
|
||||||
if (this.individual.avatar != null)
|
|
||||||
icon.gicon = this.individual.avatar;
|
|
||||||
else
|
|
||||||
icon.icon_name = 'avatar-default';
|
|
||||||
|
|
||||||
content.add(icon, { x_fill: true,
|
|
||||||
y_fill: false,
|
|
||||||
x_align: St.Align.START,
|
|
||||||
y_align: St.Align.MIDDLE });
|
|
||||||
|
|
||||||
let details = new St.BoxLayout({ style_class: 'contact-details',
|
|
||||||
vertical: true });
|
|
||||||
content.add(details, { x_fill: true,
|
|
||||||
y_fill: false,
|
|
||||||
x_align: St.Align.START,
|
|
||||||
y_align: St.Align.MIDDLE });
|
|
||||||
|
|
||||||
let email = this._contactSys.get_email_for_display(this.individual);
|
|
||||||
let aliasText = this.individual.alias ||
|
|
||||||
this.individual.full_name ||
|
|
||||||
this.individual.nickname ||
|
|
||||||
email ||
|
|
||||||
_("Unknown");
|
|
||||||
let aliasLabel = new St.Label({ text: aliasText,
|
|
||||||
style_class: 'contact-details-alias' });
|
|
||||||
details.add(aliasLabel, { x_fill: true,
|
|
||||||
y_fill: false,
|
|
||||||
x_align: St.Align.START,
|
|
||||||
y_align: St.Align.START });
|
|
||||||
|
|
||||||
this.actor.label_actor = aliasLabel;
|
|
||||||
|
|
||||||
let presence = this._createPresence(this.individual.presence_type);
|
|
||||||
details.add(presence, { x_fill: false,
|
|
||||||
y_fill: true,
|
|
||||||
x_align: St.Align.START,
|
|
||||||
y_align: St.Align.END });
|
|
||||||
},
|
|
||||||
|
|
||||||
_createPresence: function(presence) {
|
|
||||||
let text;
|
|
||||||
let iconName;
|
|
||||||
|
|
||||||
switch(presence) {
|
|
||||||
case Folks.PresenceType.AVAILABLE:
|
|
||||||
text = _("Available");
|
|
||||||
iconName = 'user-available';
|
|
||||||
break;
|
|
||||||
case Folks.PresenceType.AWAY:
|
|
||||||
case Folks.PresenceType.EXTENDED_AWAY:
|
|
||||||
text = _("Away");
|
|
||||||
iconName = 'user-away';
|
|
||||||
break;
|
|
||||||
case Folks.PresenceType.BUSY:
|
|
||||||
text = _("Busy");
|
|
||||||
iconName = 'user-busy';
|
|
||||||
break;
|
|
||||||
case Folks.PresenceType.OFFLINE:
|
|
||||||
text = _("Offline");
|
|
||||||
iconName = 'user-offline';
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
text = '';
|
|
||||||
iconName = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
let box = new St.BoxLayout({ vertical: false,
|
|
||||||
style_class: 'contact-details-status' });
|
|
||||||
|
|
||||||
if (iconName) {
|
|
||||||
let icon = new St.Icon({ icon_name: iconName,
|
|
||||||
icon_type: St.IconType.FULLCOLOR,
|
|
||||||
icon_size: 16,
|
|
||||||
style_class: 'contact-details-status-icon' });
|
|
||||||
box.add(icon, { x_fill: true,
|
|
||||||
y_fill: false,
|
|
||||||
x_align: St.Align.START,
|
|
||||||
y_align: St.Align.START });
|
|
||||||
}
|
|
||||||
|
|
||||||
let label = new St.Label({ text: text });
|
|
||||||
|
|
||||||
box.add(label, { x_fill: true,
|
|
||||||
y_fill: false,
|
|
||||||
x_align: St.Align.END,
|
|
||||||
y_align: St.Align.START });
|
|
||||||
|
|
||||||
return box;
|
|
||||||
},
|
|
||||||
|
|
||||||
createIcon: function(size) {
|
|
||||||
let tc = St.TextureCache.get_default();
|
|
||||||
let icon = this.individual.avatar;
|
|
||||||
|
|
||||||
if (icon != null) {
|
|
||||||
return tc.load_gicon(null, icon, size);
|
|
||||||
} else {
|
|
||||||
return tc.load_icon_name(null, 'avatar-default', St.IconType.FULLCOLOR, size);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
|
|
||||||
/* Searches for and returns contacts */
|
|
||||||
const ContactSearchProvider = new Lang.Class({
|
|
||||||
Name: 'ContactSearchProvider',
|
|
||||||
Extends: Search.SearchProvider,
|
|
||||||
|
|
||||||
_init: function() {
|
|
||||||
this.parent(_("CONTACTS"));
|
|
||||||
this._contactSys = Shell.ContactSystem.get_default();
|
|
||||||
},
|
|
||||||
|
|
||||||
getResultMetas: function(ids) {
|
|
||||||
let metas = [];
|
|
||||||
for (let i = 0; i < ids.length; i++) {
|
|
||||||
let contact = new Contact(ids[i]);
|
|
||||||
metas.push({ 'id': ids[i],
|
|
||||||
'name': contact.alias,
|
|
||||||
'createIcon': function(size) {
|
|
||||||
return contact.createIcon(size);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
return metas;
|
|
||||||
},
|
|
||||||
|
|
||||||
getInitialResultSet: function(terms) {
|
|
||||||
return this._contactSys.initial_search(terms);
|
|
||||||
},
|
|
||||||
|
|
||||||
getSubsearchResultSet: function(previousResults, terms) {
|
|
||||||
return this._contactSys.subsearch(previousResults, terms);
|
|
||||||
},
|
|
||||||
|
|
||||||
createResultActor: function(resultMeta, terms) {
|
|
||||||
let contact = new Contact(resultMeta.id);
|
|
||||||
return contact.actor;
|
|
||||||
},
|
|
||||||
|
|
||||||
createResultContainerActor: function() {
|
|
||||||
let grid = new IconGrid.IconGrid({ rowLimit: MAX_SEARCH_RESULTS_ROWS,
|
|
||||||
xAlign: St.Align.START });
|
|
||||||
grid.actor.style_class = 'contact-grid';
|
|
||||||
|
|
||||||
let actor = new SearchDisplay.GridSearchResults(this, grid);
|
|
||||||
return actor;
|
|
||||||
},
|
|
||||||
|
|
||||||
activateResult: function(id, params) {
|
|
||||||
launchContact(id);
|
|
||||||
}
|
|
||||||
});
|
|
@ -133,7 +133,6 @@ const DashItemContainer = new Lang.Class({
|
|||||||
},
|
},
|
||||||
|
|
||||||
hideLabel: function () {
|
hideLabel: function () {
|
||||||
this.label.opacity = 255;
|
|
||||||
Tweener.addTween(this.label,
|
Tweener.addTween(this.label,
|
||||||
{ opacity: 0,
|
{ opacity: 0,
|
||||||
time: DASH_ITEM_LABEL_HIDE_TIME,
|
time: DASH_ITEM_LABEL_HIDE_TIME,
|
||||||
@ -168,7 +167,17 @@ const DashItemContainer = new Lang.Class({
|
|||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
|
destroy: function() {
|
||||||
|
if (this.label)
|
||||||
|
this.label.destroy();
|
||||||
|
|
||||||
|
this.actor.destroy();
|
||||||
|
},
|
||||||
|
|
||||||
animateOutAndDestroy: function() {
|
animateOutAndDestroy: function() {
|
||||||
|
if (this.label)
|
||||||
|
this.label.destroy();
|
||||||
|
|
||||||
if (this.child == null) {
|
if (this.child == null) {
|
||||||
this.actor.destroy();
|
this.actor.destroy();
|
||||||
return;
|
return;
|
||||||
@ -449,6 +458,13 @@ const Dash = new Lang.Class({
|
|||||||
Lang.bind(this, function() {
|
Lang.bind(this, function() {
|
||||||
this._onHover(item, display)
|
this._onHover(item, display)
|
||||||
}));
|
}));
|
||||||
|
|
||||||
|
Main.overview.connect('hiding',
|
||||||
|
Lang.bind(this, function() {
|
||||||
|
this._labelShowing = false;
|
||||||
|
item.hideLabel();
|
||||||
|
}));
|
||||||
|
|
||||||
return item;
|
return item;
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -691,7 +707,7 @@ const Dash = new Lang.Class({
|
|||||||
if (Main.overview.visible)
|
if (Main.overview.visible)
|
||||||
item.animateOutAndDestroy();
|
item.animateOutAndDestroy();
|
||||||
else
|
else
|
||||||
item.actor.destroy();
|
item.destroy();
|
||||||
}
|
}
|
||||||
|
|
||||||
this._adjustIconSize();
|
this._adjustIconSize();
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
const GLib = imports.gi.GLib;
|
const GLib = imports.gi.GLib;
|
||||||
const Gio = imports.gi.Gio;
|
const Gio = imports.gi.Gio;
|
||||||
|
const GnomeDesktop = imports.gi.GnomeDesktop;
|
||||||
const Lang = imports.lang;
|
const Lang = imports.lang;
|
||||||
const Mainloop = imports.mainloop;
|
const Mainloop = imports.mainloop;
|
||||||
const Cairo = imports.cairo;
|
const Cairo = imports.cairo;
|
||||||
@ -16,14 +17,6 @@ const Main = imports.ui.main;
|
|||||||
const PanelMenu = imports.ui.panelMenu;
|
const PanelMenu = imports.ui.panelMenu;
|
||||||
const PopupMenu = imports.ui.popupMenu;
|
const PopupMenu = imports.ui.popupMenu;
|
||||||
const Calendar = imports.ui.calendar;
|
const Calendar = imports.ui.calendar;
|
||||||
const UPowerGlib = imports.gi.UPowerGlib;
|
|
||||||
|
|
||||||
// in org.gnome.desktop.interface
|
|
||||||
const CLOCK_FORMAT_KEY = 'clock-format';
|
|
||||||
|
|
||||||
// in org.gnome.shell.clock
|
|
||||||
const CLOCK_SHOW_DATE_KEY = 'show-date';
|
|
||||||
const CLOCK_SHOW_SECONDS_KEY = 'show-seconds';
|
|
||||||
|
|
||||||
function _onVertSepRepaint (area)
|
function _onVertSepRepaint (area)
|
||||||
{
|
{
|
||||||
@ -45,9 +38,7 @@ const DateMenuButton = new Lang.Class({
|
|||||||
Name: 'DateMenuButton',
|
Name: 'DateMenuButton',
|
||||||
Extends: PanelMenu.Button,
|
Extends: PanelMenu.Button,
|
||||||
|
|
||||||
_init: function(params) {
|
_init: function() {
|
||||||
params = Params.parse(params, { showEvents: true });
|
|
||||||
|
|
||||||
let item;
|
let item;
|
||||||
let hbox;
|
let hbox;
|
||||||
let vbox;
|
let vbox;
|
||||||
@ -62,8 +53,8 @@ const DateMenuButton = new Lang.Class({
|
|||||||
// role ATK_ROLE_MENU like other elements of the panel.
|
// role ATK_ROLE_MENU like other elements of the panel.
|
||||||
this.actor.accessible_role = Atk.Role.LABEL;
|
this.actor.accessible_role = Atk.Role.LABEL;
|
||||||
|
|
||||||
this._clock = new St.Label();
|
this._clockDisplay = new St.Label();
|
||||||
this.actor.add_actor(this._clock);
|
this.actor.add_actor(this._clockDisplay);
|
||||||
|
|
||||||
hbox = new St.BoxLayout({name: 'calendarArea' });
|
hbox = new St.BoxLayout({name: 'calendarArea' });
|
||||||
this.menu.addActor(hbox);
|
this.menu.addActor(hbox);
|
||||||
@ -75,11 +66,11 @@ const DateMenuButton = new Lang.Class({
|
|||||||
|
|
||||||
// Date
|
// Date
|
||||||
this._date = new St.Label();
|
this._date = new St.Label();
|
||||||
this.actor.label_actor = this._date;
|
this.actor.label_actor = this._clockDisplay;
|
||||||
this._date.style_class = 'datemenu-date-label';
|
this._date.style_class = 'datemenu-date-label';
|
||||||
vbox.add(this._date);
|
vbox.add(this._date);
|
||||||
|
|
||||||
if (params.showEvents) {
|
if (Main.sessionMode.showCalendarEvents) {
|
||||||
this._eventSource = new Calendar.DBusEventSource();
|
this._eventSource = new Calendar.DBusEventSource();
|
||||||
this._eventList = new Calendar.EventsList(this._eventSource);
|
this._eventList = new Calendar.EventsList(this._eventSource);
|
||||||
} else {
|
} else {
|
||||||
@ -110,7 +101,7 @@ const DateMenuButton = new Lang.Class({
|
|||||||
item.actor.reparent(vbox);
|
item.actor.reparent(vbox);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (params.showEvents) {
|
if (Main.sessionMode.showCalendarEvents) {
|
||||||
// Add vertical separator
|
// Add vertical separator
|
||||||
|
|
||||||
item = new St.DrawingArea({ style_class: 'calendar-vertical-separator',
|
item = new St.DrawingArea({ style_class: 'calendar-vertical-separator',
|
||||||
@ -157,77 +148,29 @@ const DateMenuButton = new Lang.Class({
|
|||||||
|
|
||||||
// Done with hbox for calendar and event list
|
// Done with hbox for calendar and event list
|
||||||
|
|
||||||
// Track changes to clock settings
|
this._clock = new GnomeDesktop.WallClock();
|
||||||
this._desktopSettings = new Gio.Settings({ schema: 'org.gnome.desktop.interface' });
|
this._clock.connect('notify::clock', Lang.bind(this, this._updateClockAndDate));
|
||||||
this._clockSettings = new Gio.Settings({ schema: 'org.gnome.shell.clock' });
|
|
||||||
this._desktopSettings.connect('changed', Lang.bind(this, this._updateClockAndDate));
|
|
||||||
this._clockSettings.connect('changed', Lang.bind(this, this._updateClockAndDate));
|
|
||||||
|
|
||||||
// https://bugzilla.gnome.org/show_bug.cgi?id=655129
|
|
||||||
this._upClient = new UPowerGlib.Client();
|
|
||||||
this._upClient.connect('notify-resume', Lang.bind(this, this._updateClockAndDate));
|
|
||||||
|
|
||||||
// Start the clock
|
|
||||||
this._updateClockAndDate();
|
this._updateClockAndDate();
|
||||||
},
|
},
|
||||||
|
|
||||||
_updateClockAndDate: function() {
|
_updateClockAndDate: function() {
|
||||||
let format = this._desktopSettings.get_string(CLOCK_FORMAT_KEY);
|
this._clockDisplay.set_text(this._clock.clock);
|
||||||
let showDate = this._clockSettings.get_boolean(CLOCK_SHOW_DATE_KEY);
|
|
||||||
let showSeconds = this._clockSettings.get_boolean(CLOCK_SHOW_SECONDS_KEY);
|
|
||||||
|
|
||||||
let clockFormat;
|
|
||||||
let dateFormat;
|
|
||||||
|
|
||||||
switch (format) {
|
|
||||||
case '24h':
|
|
||||||
if (showDate)
|
|
||||||
/* Translators: This is the time format with date used
|
|
||||||
in 24-hour mode. */
|
|
||||||
clockFormat = showSeconds ? _("%a %b %e, %R:%S")
|
|
||||||
: _("%a %b %e, %R");
|
|
||||||
else
|
|
||||||
/* Translators: This is the time format without date used
|
|
||||||
in 24-hour mode. */
|
|
||||||
clockFormat = showSeconds ? _("%a %R:%S")
|
|
||||||
: _("%a %R");
|
|
||||||
break;
|
|
||||||
case '12h':
|
|
||||||
default:
|
|
||||||
if (showDate)
|
|
||||||
/* Translators: This is a time format with date used
|
|
||||||
for AM/PM. */
|
|
||||||
clockFormat = showSeconds ? _("%a %b %e, %l:%M:%S %p")
|
|
||||||
: _("%a %b %e, %l:%M %p");
|
|
||||||
else
|
|
||||||
/* Translators: This is a time format without date used
|
|
||||||
for AM/PM. */
|
|
||||||
clockFormat = showSeconds ? _("%a %l:%M:%S %p")
|
|
||||||
: _("%a %l:%M %p");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
let displayDate = new Date();
|
|
||||||
|
|
||||||
this._clock.set_text(displayDate.toLocaleFormat(clockFormat));
|
|
||||||
|
|
||||||
/* Translators: This is the date format to use when the calendar popup is
|
/* Translators: This is the date format to use when the calendar popup is
|
||||||
* shown - it is shown just below the time in the shell (e.g. "Tue 9:29 AM").
|
* shown - it is shown just below the time in the shell (e.g. "Tue 9:29 AM").
|
||||||
*/
|
*/
|
||||||
dateFormat = _("%A %B %e, %Y");
|
let dateFormat = _("%A %B %e, %Y");
|
||||||
|
let displayDate = new Date();
|
||||||
this._date.set_text(displayDate.toLocaleFormat(dateFormat));
|
this._date.set_text(displayDate.toLocaleFormat(dateFormat));
|
||||||
|
|
||||||
Mainloop.timeout_add_seconds(1, Lang.bind(this, this._updateClockAndDate));
|
|
||||||
return false;
|
|
||||||
},
|
},
|
||||||
|
|
||||||
_onOpenCalendarActivate: function() {
|
_onOpenCalendarActivate: function() {
|
||||||
this.menu.close();
|
this.menu.close();
|
||||||
let calendarSettings = new Gio.Settings({ schema: 'org.gnome.desktop.default-applications.office.calendar' });
|
let calendarSettings = new Gio.Settings({ schema: 'org.gnome.desktop.default-applications.office.calendar' });
|
||||||
let tool = calendarSettings.get_string('exec');
|
let tool = calendarSettings.get_string('exec');
|
||||||
if (tool.length == 0 || tool == 'evolution') {
|
if (tool.length == 0 || tool.substr(0, 9) == 'evolution') {
|
||||||
// TODO: pass the selected day
|
// TODO: pass the selected day
|
||||||
Util.spawn(['evolution', '-c', 'calendar']);
|
let app = Shell.AppSystem.get_default().lookup_app('evolution-calendar.desktop');
|
||||||
|
app.activate();
|
||||||
} else {
|
} else {
|
||||||
let needTerm = calendarSettings.get_boolean('needs-term');
|
let needTerm = calendarSettings.get_boolean('needs-term');
|
||||||
if (needTerm) {
|
if (needTerm) {
|
||||||
|
@ -31,7 +31,6 @@ const St = imports.gi.St;
|
|||||||
const Shell = imports.gi.Shell;
|
const Shell = imports.gi.Shell;
|
||||||
|
|
||||||
const GnomeSession = imports.misc.gnomeSession;
|
const GnomeSession = imports.misc.gnomeSession;
|
||||||
const Lightbox = imports.ui.lightbox;
|
|
||||||
const Main = imports.ui.main;
|
const Main = imports.ui.main;
|
||||||
const ModalDialog = imports.ui.modalDialog;
|
const ModalDialog = imports.ui.modalDialog;
|
||||||
const Tweener = imports.ui.tweener;
|
const Tweener = imports.ui.tweener;
|
||||||
@ -288,13 +287,13 @@ const EndSessionDialog = new Lang.Class({
|
|||||||
|
|
||||||
this._applicationList.connect('actor-added',
|
this._applicationList.connect('actor-added',
|
||||||
Lang.bind(this, function() {
|
Lang.bind(this, function() {
|
||||||
if (this._applicationList.get_children().length == 1)
|
if (this._applicationList.get_n_children() == 1)
|
||||||
scrollView.show();
|
scrollView.show();
|
||||||
}));
|
}));
|
||||||
|
|
||||||
this._applicationList.connect('actor-removed',
|
this._applicationList.connect('actor-removed',
|
||||||
Lang.bind(this, function() {
|
Lang.bind(this, function() {
|
||||||
if (this._applicationList.get_children().length == 0)
|
if (this._applicationList.get_n_children() == 0)
|
||||||
scrollView.hide();
|
scrollView.hide();
|
||||||
}));
|
}));
|
||||||
|
|
||||||
@ -342,7 +341,7 @@ const EndSessionDialog = new Lang.Class({
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
_updateContent: function() {
|
_updateDescription: function() {
|
||||||
if (this.state != ModalDialog.State.OPENING &&
|
if (this.state != ModalDialog.State.OPENING &&
|
||||||
this.state != ModalDialog.State.OPENED)
|
this.state != ModalDialog.State.OPENED)
|
||||||
return;
|
return;
|
||||||
@ -352,17 +351,6 @@ const EndSessionDialog = new Lang.Class({
|
|||||||
let subject = dialogContent.subject;
|
let subject = dialogContent.subject;
|
||||||
let description;
|
let description;
|
||||||
|
|
||||||
if (this._user.is_loaded && !dialogContent.iconName) {
|
|
||||||
let iconFile = this._user.get_icon_file();
|
|
||||||
if (GLib.file_test(iconFile, GLib.FileTest.EXISTS))
|
|
||||||
this._setIconFromFile(iconFile, dialogContent.iconStyleClass);
|
|
||||||
else
|
|
||||||
this._setIconFromName('avatar-default', dialogContent.iconStyleClass);
|
|
||||||
} else if (dialogContent.iconName) {
|
|
||||||
this._setIconFromName(dialogContent.iconName,
|
|
||||||
dialogContent.iconStyleClass);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this._inhibitors.length > 0) {
|
if (this._inhibitors.length > 0) {
|
||||||
this._stopTimer();
|
this._stopTimer();
|
||||||
description = dialogContent.inhibitedDescription;
|
description = dialogContent.inhibitedDescription;
|
||||||
@ -395,6 +383,27 @@ const EndSessionDialog = new Lang.Class({
|
|||||||
_setLabelText(this._descriptionLabel, description);
|
_setLabelText(this._descriptionLabel, description);
|
||||||
},
|
},
|
||||||
|
|
||||||
|
_updateContent: function() {
|
||||||
|
if (this.state != ModalDialog.State.OPENING &&
|
||||||
|
this.state != ModalDialog.State.OPENED)
|
||||||
|
return;
|
||||||
|
|
||||||
|
let dialogContent = DialogContent[this._type];
|
||||||
|
|
||||||
|
if (this._user.is_loaded && !dialogContent.iconName) {
|
||||||
|
let iconFile = this._user.get_icon_file();
|
||||||
|
if (GLib.file_test(iconFile, GLib.FileTest.EXISTS))
|
||||||
|
this._setIconFromFile(iconFile, dialogContent.iconStyleClass);
|
||||||
|
else
|
||||||
|
this._setIconFromName('avatar-default', dialogContent.iconStyleClass);
|
||||||
|
} else if (dialogContent.iconName) {
|
||||||
|
this._setIconFromName(dialogContent.iconName,
|
||||||
|
dialogContent.iconStyleClass);
|
||||||
|
}
|
||||||
|
|
||||||
|
this._updateDescription();
|
||||||
|
},
|
||||||
|
|
||||||
_updateButtons: function() {
|
_updateButtons: function() {
|
||||||
let dialogContent = DialogContent[this._type];
|
let dialogContent = DialogContent[this._type];
|
||||||
let buttons = [{ action: Lang.bind(this, this.cancel),
|
let buttons = [{ action: Lang.bind(this, this.cancel),
|
||||||
@ -441,7 +450,7 @@ const EndSessionDialog = new Lang.Class({
|
|||||||
{ _secondsLeft: 0,
|
{ _secondsLeft: 0,
|
||||||
time: this._secondsLeft,
|
time: this._secondsLeft,
|
||||||
transition: 'linear',
|
transition: 'linear',
|
||||||
onUpdate: Lang.bind(this, this._updateContent),
|
onUpdate: Lang.bind(this, this._updateDescription),
|
||||||
onComplete: Lang.bind(this, function() {
|
onComplete: Lang.bind(this, function() {
|
||||||
let dialogContent = DialogContent[this._type];
|
let dialogContent = DialogContent[this._type];
|
||||||
let button = dialogContent.confirmButtons[dialogContent.confirmButtons.length - 1];
|
let button = dialogContent.confirmButtons[dialogContent.confirmButtons.length - 1];
|
||||||
|
@ -39,11 +39,19 @@ function _patchContainerClass(containerClass) {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function _makeLoggingFunc(func) {
|
||||||
|
return function() {
|
||||||
|
return func([].join.call(arguments, ', '));
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
function init() {
|
function init() {
|
||||||
// Add some bindings to the global JS namespace; (gjs keeps the web
|
// Add some bindings to the global JS namespace; (gjs keeps the web
|
||||||
// browser convention of having that namespace be called 'window'.)
|
// browser convention of having that namespace be called 'window'.)
|
||||||
window.global = Shell.Global.get();
|
window.global = Shell.Global.get();
|
||||||
|
|
||||||
|
window.log = _makeLoggingFunc(window.log);
|
||||||
|
|
||||||
window._ = Gettext.gettext;
|
window._ = Gettext.gettext;
|
||||||
window.C_ = Gettext.pgettext;
|
window.C_ = Gettext.pgettext;
|
||||||
window.ngettext = Gettext.ngettext;
|
window.ngettext = Gettext.ngettext;
|
||||||
@ -82,7 +90,7 @@ function init() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// OK, now things are initialized enough that we can import shell JS
|
// OK, now things are initialized enough that we can import shell JS
|
||||||
const Format = imports.misc.format;
|
const Format = imports.format;
|
||||||
const Tweener = imports.ui.tweener;
|
const Tweener = imports.ui.tweener;
|
||||||
|
|
||||||
Tweener.init();
|
Tweener.init();
|
||||||
|
269
js/ui/extensionDownloader.js
Normal file
269
js/ui/extensionDownloader.js
Normal file
@ -0,0 +1,269 @@
|
|||||||
|
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
|
||||||
|
|
||||||
|
const Lang = imports.lang;
|
||||||
|
|
||||||
|
const Clutter = imports.gi.Clutter;
|
||||||
|
const GLib = imports.gi.GLib;
|
||||||
|
const Gio = imports.gi.Gio;
|
||||||
|
const Soup = imports.gi.Soup;
|
||||||
|
const St = imports.gi.St;
|
||||||
|
const Shell = imports.gi.Shell;
|
||||||
|
|
||||||
|
const Config = imports.misc.config;
|
||||||
|
const ExtensionUtils = imports.misc.extensionUtils;
|
||||||
|
const ExtensionSystem = imports.ui.extensionSystem;
|
||||||
|
const FileUtils = imports.misc.fileUtils;
|
||||||
|
const ModalDialog = imports.ui.modalDialog;
|
||||||
|
|
||||||
|
const _signals = ExtensionSystem._signals;
|
||||||
|
|
||||||
|
const REPOSITORY_URL_BASE = 'https://extensions.gnome.org';
|
||||||
|
const REPOSITORY_URL_DOWNLOAD = REPOSITORY_URL_BASE + '/download-extension/%s.shell-extension.zip';
|
||||||
|
const REPOSITORY_URL_INFO = REPOSITORY_URL_BASE + '/extension-info/';
|
||||||
|
const REPOSITORY_URL_UPDATE = REPOSITORY_URL_BASE + '/update-info/';
|
||||||
|
|
||||||
|
let _httpSession;
|
||||||
|
|
||||||
|
function installExtension(uuid, invocation) {
|
||||||
|
let params = { uuid: uuid,
|
||||||
|
shell_version: Config.PACKAGE_VERSION };
|
||||||
|
|
||||||
|
let message = Soup.form_request_new_from_hash('GET', REPOSITORY_URL_INFO, params);
|
||||||
|
|
||||||
|
_httpSession.queue_message(message, function(session, message) {
|
||||||
|
if (message.status_code != Soup.KnownStatusCode.OK) {
|
||||||
|
ExtensionSystem.logExtensionError(uuid, 'downloading info: ' + message.status_code);
|
||||||
|
invocation.return_dbus_error('org.gnome.Shell.DownloadInfoError', message.status_code.toString());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
let info;
|
||||||
|
try {
|
||||||
|
info = JSON.parse(message.response_body.data);
|
||||||
|
} catch (e) {
|
||||||
|
ExtensionSystem.logExtensionError(uuid, 'parsing info: ' + e);
|
||||||
|
invocation.return_dbus_error('org.gnome.Shell.ParseInfoError', e.toString());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
let dialog = new InstallExtensionDialog(uuid, info, invocation);
|
||||||
|
dialog.open(global.get_current_time());
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function uninstallExtension(uuid) {
|
||||||
|
let extension = ExtensionUtils.extensions[uuid];
|
||||||
|
if (!extension)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// Don't try to uninstall system extensions
|
||||||
|
if (extension.type != ExtensionUtils.ExtensionType.PER_USER)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (!ExtensionSystem.unloadExtension(uuid))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
FileUtils.recursivelyDeleteDir(extension.dir, true);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
function gotExtensionZipFile(session, message, uuid, dir, callback, errback) {
|
||||||
|
if (message.status_code != Soup.KnownStatusCode.OK) {
|
||||||
|
errback('DownloadExtensionError', message.status_code);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
if (!dir.query_exists(null))
|
||||||
|
dir.make_directory_with_parents(null);
|
||||||
|
} catch (e) {
|
||||||
|
errback('CreateExtensionDirectoryError', e);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
let [file, stream] = Gio.File.new_tmp('XXXXXX.shell-extension.zip');
|
||||||
|
let contents = message.response_body.flatten().as_bytes();
|
||||||
|
stream.output_stream.write_bytes(contents, null);
|
||||||
|
stream.close(null);
|
||||||
|
let [success, pid] = GLib.spawn_async(null,
|
||||||
|
['unzip', '-uod', dir.get_path(), '--', file.get_path()],
|
||||||
|
null,
|
||||||
|
GLib.SpawnFlags.SEARCH_PATH | GLib.SpawnFlags.DO_NOT_REAP_CHILD,
|
||||||
|
null);
|
||||||
|
|
||||||
|
if (!success) {
|
||||||
|
errback('ExtractExtensionError');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
GLib.child_watch_add(GLib.PRIORITY_DEFAULT, pid, function(pid, status) {
|
||||||
|
GLib.spawn_close_pid(pid);
|
||||||
|
|
||||||
|
if (status != 0)
|
||||||
|
errback('ExtractExtensionError');
|
||||||
|
else
|
||||||
|
callback();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function updateExtension(uuid) {
|
||||||
|
// This gets a bit tricky. We want the update to be seamless -
|
||||||
|
// if we have any error during downloading or extracting, we
|
||||||
|
// want to not unload the current version.
|
||||||
|
|
||||||
|
let oldExtensionTmpDir = GLib.Dir.make_tmp('XXXXXX-shell-extension');
|
||||||
|
let newExtensionTmpDir = GLib.Dir.make_tmp('XXXXXX-shell-extension');
|
||||||
|
|
||||||
|
let params = { shell_version: Config.PACKAGE_VERSION };
|
||||||
|
|
||||||
|
let url = REPOSITORY_URL_DOWNLOAD.format(uuid);
|
||||||
|
let message = Soup.form_request_new_from_hash('GET', url, params);
|
||||||
|
|
||||||
|
_httpSession.queue_message(message, Lang.bind(this, function(session, message) {
|
||||||
|
gotExtensionZipFile(session, message, uuid, newExtensionTmpDir, function() {
|
||||||
|
let oldExtension = ExtensionUtils.extensions[uuid];
|
||||||
|
let extensionDir = oldExtension.dir;
|
||||||
|
|
||||||
|
if (!ExtensionSystem.unloadExtension(uuid))
|
||||||
|
return;
|
||||||
|
|
||||||
|
FileUtils.recursivelyMoveDir(extensionDir, oldExtensionTmpDir);
|
||||||
|
FileUtils.recursivelyMoveDir(newExtensionTmpDir, extensionDir);
|
||||||
|
|
||||||
|
let extension = ExtensionUtils.createExtensionObject(uuid, extensionDir, ExtensionUtils.ExtensionType.PER_USER);
|
||||||
|
|
||||||
|
try {
|
||||||
|
ExtensionSystem.loadExtension(extension);
|
||||||
|
} catch(e) {
|
||||||
|
ExtensionSystem.unloadExtension(uuid);
|
||||||
|
|
||||||
|
logError(e, 'Error loading extension %s'.format(uuid));
|
||||||
|
|
||||||
|
FileUtils.recursivelyDeleteDir(extensionDir, false);
|
||||||
|
FileUtils.recursivelyMoveDir(oldExtensionTmpDir, extensionDir);
|
||||||
|
|
||||||
|
// Restore what was there before. We can't do much if we
|
||||||
|
// fail here.
|
||||||
|
ExtensionSystem.loadExtension(oldExtension);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
FileUtils.recursivelyDeleteDir(oldExtensionTmpDir, true);
|
||||||
|
}, function(code, message) {
|
||||||
|
log('Error while updating extension %s: %s (%s)'.format(uuid, code, message ? message : ''));
|
||||||
|
});
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
|
function checkForUpdates() {
|
||||||
|
let metadatas = {};
|
||||||
|
for (let uuid in ExtensionUtils.extensions) {
|
||||||
|
metadatas[uuid] = ExtensionUtils.extensions[uuid].metadata;
|
||||||
|
}
|
||||||
|
|
||||||
|
let params = { shell_version: Config.PACKAGE_VERSION,
|
||||||
|
installed: JSON.stringify(metadatas) };
|
||||||
|
|
||||||
|
let url = REPOSITORY_URL_UPDATE;
|
||||||
|
let message = Soup.form_request_new_from_hash('GET', url, params);
|
||||||
|
_httpSession.queue_message(message, function(session, message) {
|
||||||
|
if (message.status_code != Soup.KnownStatusCode.OK)
|
||||||
|
return;
|
||||||
|
|
||||||
|
let operations = JSON.parse(message.response_body.data);
|
||||||
|
for (let uuid in operations) {
|
||||||
|
let operation = operations[uuid];
|
||||||
|
if (operation == 'blacklist')
|
||||||
|
uninstallExtension(uuid);
|
||||||
|
else if (operation == 'upgrade' || operation == 'downgrade')
|
||||||
|
updateExtension(uuid);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
const InstallExtensionDialog = new Lang.Class({
|
||||||
|
Name: 'InstallExtensionDialog',
|
||||||
|
Extends: ModalDialog.ModalDialog,
|
||||||
|
|
||||||
|
_init: function(uuid, info, invocation) {
|
||||||
|
this.parent({ styleClass: 'extension-dialog' });
|
||||||
|
|
||||||
|
this._uuid = uuid;
|
||||||
|
this._info = info;
|
||||||
|
this._invocation = invocation;
|
||||||
|
|
||||||
|
this.setButtons([{ label: _("Cancel"),
|
||||||
|
action: Lang.bind(this, this._onCancelButtonPressed),
|
||||||
|
key: Clutter.Escape
|
||||||
|
},
|
||||||
|
{ label: _("Install"),
|
||||||
|
action: Lang.bind(this, this._onInstallButtonPressed)
|
||||||
|
}]);
|
||||||
|
|
||||||
|
let message = _("Download and install '%s' from extensions.gnome.org?").format(info.name);
|
||||||
|
|
||||||
|
let box = new St.BoxLayout();
|
||||||
|
this.contentLayout.add(box);
|
||||||
|
|
||||||
|
let gicon = new Gio.FileIcon({ file: Gio.File.new_for_uri(REPOSITORY_URL_BASE + info.icon) })
|
||||||
|
let icon = new St.Icon({ gicon: gicon });
|
||||||
|
box.add(icon);
|
||||||
|
|
||||||
|
let label = new St.Label({ text: message });
|
||||||
|
box.add(label);
|
||||||
|
},
|
||||||
|
|
||||||
|
_onCancelButtonPressed: function(button, event) {
|
||||||
|
this.close(global.get_current_time());
|
||||||
|
this._invocation.return_value(GLib.Variant.new('(s)', ['cancelled']));
|
||||||
|
},
|
||||||
|
|
||||||
|
_onInstallButtonPressed: function(button, event) {
|
||||||
|
let params = { shell_version: Config.PACKAGE_VERSION };
|
||||||
|
|
||||||
|
let url = REPOSITORY_URL_DOWNLOAD.format(this._uuid);
|
||||||
|
let message = Soup.form_request_new_from_hash('GET', url, params);
|
||||||
|
|
||||||
|
let uuid = this._uuid;
|
||||||
|
let dir = Gio.File.new_for_path(GLib.build_filenamev([global.userdatadir, 'extensions', uuid]));
|
||||||
|
let invocation = this._invocation;
|
||||||
|
function errback(code, message) {
|
||||||
|
invocation.return_dbus_error('org.gnome.Shell.' + code, message ? message.toString() : '');
|
||||||
|
}
|
||||||
|
|
||||||
|
function callback() {
|
||||||
|
// Add extension to 'enabled-extensions' for the user, always...
|
||||||
|
let enabledExtensions = global.settings.get_strv(ExtensionSystem.ENABLED_EXTENSIONS_KEY);
|
||||||
|
if (enabledExtensions.indexOf(uuid) == -1) {
|
||||||
|
enabledExtensions.push(uuid);
|
||||||
|
global.settings.set_strv(ExtensionSystem.ENABLED_EXTENSIONS_KEY, enabledExtensions);
|
||||||
|
}
|
||||||
|
|
||||||
|
let extension = ExtensionUtils.createExtensionObject(uuid, dir, ExtensionUtils.ExtensionType.PER_USER);
|
||||||
|
|
||||||
|
try {
|
||||||
|
ExtensionSystem.loadExtension(extension);
|
||||||
|
} catch(e) {
|
||||||
|
uninstallExtension(uuid);
|
||||||
|
errback('LoadExtensionError', e);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
invocation.return_value(GLib.Variant.new('(s)', 'successful'));
|
||||||
|
}
|
||||||
|
|
||||||
|
_httpSession.queue_message(message, Lang.bind(this, function(session, message) {
|
||||||
|
gotExtensionZipFile(session, message, uuid, dir, callback, errback);
|
||||||
|
}));
|
||||||
|
|
||||||
|
this.close(global.get_current_time());
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
function init() {
|
||||||
|
_httpSession = new Soup.SessionAsync({ ssl_use_system_ca_file: true });
|
||||||
|
|
||||||
|
// See: https://bugzilla.gnome.org/show_bug.cgi?id=655189 for context.
|
||||||
|
// _httpSession.add_feature(new Soup.ProxyResolverDefault());
|
||||||
|
Soup.Session.prototype.add_feature.call(_httpSession, new Soup.ProxyResolverDefault());
|
||||||
|
}
|
@ -3,19 +3,11 @@
|
|||||||
const Lang = imports.lang;
|
const Lang = imports.lang;
|
||||||
const Signals = imports.signals;
|
const Signals = imports.signals;
|
||||||
|
|
||||||
const Clutter = imports.gi.Clutter;
|
|
||||||
const GLib = imports.gi.GLib;
|
const GLib = imports.gi.GLib;
|
||||||
const Gio = imports.gi.Gio;
|
const Gio = imports.gi.Gio;
|
||||||
const St = imports.gi.St;
|
const St = imports.gi.St;
|
||||||
const Shell = imports.gi.Shell;
|
|
||||||
const Soup = imports.gi.Soup;
|
|
||||||
|
|
||||||
const Config = imports.misc.config;
|
|
||||||
const ExtensionUtils = imports.misc.extensionUtils;
|
const ExtensionUtils = imports.misc.extensionUtils;
|
||||||
const FileUtils = imports.misc.fileUtils;
|
|
||||||
const ModalDialog = imports.ui.modalDialog;
|
|
||||||
|
|
||||||
const API_VERSION = 1;
|
|
||||||
|
|
||||||
const ExtensionState = {
|
const ExtensionState = {
|
||||||
ENABLED: 1,
|
ENABLED: 1,
|
||||||
@ -30,29 +22,6 @@ const ExtensionState = {
|
|||||||
UNINSTALLED: 99
|
UNINSTALLED: 99
|
||||||
};
|
};
|
||||||
|
|
||||||
const REPOSITORY_URL_BASE = 'https://extensions.gnome.org';
|
|
||||||
const REPOSITORY_URL_DOWNLOAD = REPOSITORY_URL_BASE + '/download-extension/%s.shell-extension.zip';
|
|
||||||
const REPOSITORY_URL_INFO = REPOSITORY_URL_BASE + '/extension-info/';
|
|
||||||
|
|
||||||
const _httpSession = new Soup.SessionAsync();
|
|
||||||
|
|
||||||
// The unfortunate state of gjs, gobject-introspection and libsoup
|
|
||||||
// means that I have to do a hack to add a feature.
|
|
||||||
// See: https://bugzilla.gnome.org/show_bug.cgi?id=655189 for context.
|
|
||||||
|
|
||||||
if (Soup.Session.prototype.add_feature != null)
|
|
||||||
Soup.Session.prototype.add_feature.call(_httpSession, new Soup.ProxyResolverDefault());
|
|
||||||
|
|
||||||
function _getCertFile() {
|
|
||||||
let localCert = GLib.build_filenamev([global.userdatadir, 'extensions.gnome.org.crt']);
|
|
||||||
if (GLib.file_test(localCert, GLib.FileTest.EXISTS))
|
|
||||||
return localCert;
|
|
||||||
else
|
|
||||||
return Config.SHELL_SYSTEM_CA_FILE;
|
|
||||||
}
|
|
||||||
|
|
||||||
_httpSession.ssl_ca_file = _getCertFile();
|
|
||||||
|
|
||||||
// Arrays of uuids
|
// Arrays of uuids
|
||||||
var enabledExtensions;
|
var enabledExtensions;
|
||||||
// Contains the order that extensions were enabled in.
|
// Contains the order that extensions were enabled in.
|
||||||
@ -69,90 +38,6 @@ const disconnect = Lang.bind(_signals, _signals.disconnect);
|
|||||||
|
|
||||||
const ENABLED_EXTENSIONS_KEY = 'enabled-extensions';
|
const ENABLED_EXTENSIONS_KEY = 'enabled-extensions';
|
||||||
|
|
||||||
function installExtensionFromUUID(uuid, version_tag) {
|
|
||||||
let params = { uuid: uuid,
|
|
||||||
version_tag: version_tag,
|
|
||||||
shell_version: Config.PACKAGE_VERSION,
|
|
||||||
api_version: API_VERSION.toString() };
|
|
||||||
|
|
||||||
let message = Soup.form_request_new_from_hash('GET', REPOSITORY_URL_INFO, params);
|
|
||||||
|
|
||||||
_httpSession.queue_message(message,
|
|
||||||
function(session, message) {
|
|
||||||
let info = JSON.parse(message.response_body.data);
|
|
||||||
let dialog = new InstallExtensionDialog(uuid, version_tag, info.name);
|
|
||||||
dialog.open(global.get_current_time());
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function uninstallExtensionFromUUID(uuid) {
|
|
||||||
let extension = ExtensionUtils.extensions[uuid];
|
|
||||||
if (!extension)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
// Try to disable it -- if it's ERROR'd, we can't guarantee that,
|
|
||||||
// but it will be removed on next reboot, and hopefully nothing
|
|
||||||
// broke too much.
|
|
||||||
disableExtension(uuid);
|
|
||||||
|
|
||||||
// Don't try to uninstall system extensions
|
|
||||||
if (extension.type != ExtensionUtils.ExtensionType.PER_USER)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
extension.state = ExtensionState.UNINSTALLED;
|
|
||||||
_signals.emit('extension-state-changed', extension);
|
|
||||||
|
|
||||||
delete ExtensionUtils.extensions[uuid];
|
|
||||||
|
|
||||||
FileUtils.recursivelyDeleteDir(Gio.file_new_for_path(extension.path));
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
function gotExtensionZipFile(session, message, uuid) {
|
|
||||||
if (message.status_code != Soup.KnownStatusCode.OK) {
|
|
||||||
logExtensionError(uuid, 'downloading extension: ' + message.status_code);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// FIXME: use a GFile mkstemp-type method once one exists
|
|
||||||
let fd, tmpzip;
|
|
||||||
try {
|
|
||||||
[fd, tmpzip] = GLib.file_open_tmp('XXXXXX.shell-extension.zip');
|
|
||||||
} catch (e) {
|
|
||||||
logExtensionError(uuid, 'tempfile: ' + e.toString());
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
let stream = new Gio.UnixOutputStream({ fd: fd });
|
|
||||||
let dir = ExtensionUtils.userExtensionsDir.get_child(uuid);
|
|
||||||
Shell.write_soup_message_to_stream(stream, message);
|
|
||||||
stream.close(null);
|
|
||||||
let [success, pid] = GLib.spawn_async(null,
|
|
||||||
['unzip', '-uod', dir.get_path(), '--', tmpzip],
|
|
||||||
null,
|
|
||||||
GLib.SpawnFlags.SEARCH_PATH | GLib.SpawnFlags.DO_NOT_REAP_CHILD,
|
|
||||||
null);
|
|
||||||
|
|
||||||
if (!success) {
|
|
||||||
logExtensionError(uuid, 'extract: could not extract');
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
GLib.child_watch_add(GLib.PRIORITY_DEFAULT, pid, function(pid, status) {
|
|
||||||
GLib.spawn_close_pid(pid);
|
|
||||||
|
|
||||||
// Add extension to 'enabled-extensions' for the user, always...
|
|
||||||
let enabledExtensions = global.settings.get_strv(ENABLED_EXTENSIONS_KEY);
|
|
||||||
if (enabledExtensions.indexOf(uuid) == -1) {
|
|
||||||
enabledExtensions.push(uuid);
|
|
||||||
global.settings.set_strv(ENABLED_EXTENSIONS_KEY, enabledExtensions);
|
|
||||||
}
|
|
||||||
|
|
||||||
loadExtension(dir, ExtensionUtils.ExtensionType.PER_USER, true);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function disableExtension(uuid) {
|
function disableExtension(uuid) {
|
||||||
let extension = ExtensionUtils.extensions[uuid];
|
let extension = ExtensionUtils.extensions[uuid];
|
||||||
if (!extension)
|
if (!extension)
|
||||||
@ -178,23 +63,23 @@ function disableExtension(uuid) {
|
|||||||
try {
|
try {
|
||||||
ExtensionUtils.extensions[uuid].stateObj.disable();
|
ExtensionUtils.extensions[uuid].stateObj.disable();
|
||||||
} catch(e) {
|
} catch(e) {
|
||||||
logExtensionError(uuid, e.toString());
|
logExtensionError(uuid, e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
if (extension.stylesheet) {
|
||||||
extension.stateObj.disable();
|
let theme = St.ThemeContext.get_for_stage(global.stage).get_theme();
|
||||||
} catch(e) {
|
theme.unload_stylesheet(extension.stylesheet.get_path());
|
||||||
logExtensionError(uuid, e.toString());
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
extension.stateObj.disable();
|
||||||
|
|
||||||
for (let i = 0; i < order.length; i++) {
|
for (let i = 0; i < order.length; i++) {
|
||||||
let uuid = order[i];
|
let uuid = order[i];
|
||||||
try {
|
try {
|
||||||
ExtensionUtils.extensions[uuid].stateObj.enable();
|
ExtensionUtils.extensions[uuid].stateObj.enable();
|
||||||
} catch(e) {
|
} catch(e) {
|
||||||
logExtensionError(uuid, e.toString());
|
logExtensionError(uuid, e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -217,67 +102,77 @@ function enableExtension(uuid) {
|
|||||||
|
|
||||||
extensionOrder.push(uuid);
|
extensionOrder.push(uuid);
|
||||||
|
|
||||||
try {
|
|
||||||
extension.stateObj.enable();
|
extension.stateObj.enable();
|
||||||
} catch(e) {
|
|
||||||
logExtensionError(uuid, e.toString());
|
let stylesheetFile = extension.dir.get_child('stylesheet.css');
|
||||||
return;
|
if (stylesheetFile.query_exists(null)) {
|
||||||
|
let theme = St.ThemeContext.get_for_stage(global.stage).get_theme();
|
||||||
|
theme.load_stylesheet(stylesheetFile.get_path());
|
||||||
|
extension.stylesheet = stylesheetFile;
|
||||||
}
|
}
|
||||||
|
|
||||||
extension.state = ExtensionState.ENABLED;
|
extension.state = ExtensionState.ENABLED;
|
||||||
_signals.emit('extension-state-changed', extension);
|
_signals.emit('extension-state-changed', extension);
|
||||||
}
|
}
|
||||||
|
|
||||||
function logExtensionError(uuid, message, state) {
|
function logExtensionError(uuid, error) {
|
||||||
let extension = ExtensionUtils.extensions[uuid];
|
let extension = ExtensionUtils.extensions[uuid];
|
||||||
if (!extension)
|
if (!extension)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
let message = '' + error;
|
||||||
|
|
||||||
|
if (error.state)
|
||||||
|
extension.state = error.state;
|
||||||
|
else
|
||||||
|
extension.state = ExtensionState.ERROR;
|
||||||
|
|
||||||
if (!extension.errors)
|
if (!extension.errors)
|
||||||
extension.errors = [];
|
extension.errors = [];
|
||||||
|
|
||||||
extension.errors.push(message);
|
log('Extension "%s" had error: %s'.format(uuid, message));
|
||||||
global.logError('Extension "%s" had error: %s'.format(uuid, message));
|
|
||||||
state = state || ExtensionState.ERROR;
|
|
||||||
_signals.emit('extension-state-changed', { uuid: uuid,
|
_signals.emit('extension-state-changed', { uuid: uuid,
|
||||||
error: message,
|
error: message,
|
||||||
state: state });
|
state: extension.state });
|
||||||
}
|
|
||||||
|
|
||||||
function loadExtension(dir, type, enabled) {
|
|
||||||
let uuid = dir.get_basename();
|
|
||||||
let extension;
|
|
||||||
|
|
||||||
if (ExtensionUtils.extensions[uuid] != undefined) {
|
|
||||||
throw new Error('extension already loaded');
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
extension = ExtensionUtils.createExtensionObject(uuid, dir, type);
|
|
||||||
} catch(e) {
|
|
||||||
logExtensionError(uuid, e.message);
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function loadExtension(extension) {
|
||||||
// Default to error, we set success as the last step
|
// Default to error, we set success as the last step
|
||||||
extension.state = ExtensionState.ERROR;
|
extension.state = ExtensionState.ERROR;
|
||||||
|
|
||||||
if (ExtensionUtils.isOutOfDate(extension)) {
|
if (ExtensionUtils.isOutOfDate(extension)) {
|
||||||
logExtensionError(uuid, 'extension is not compatible with current GNOME Shell and/or GJS version', ExtensionState.OUT_OF_DATE);
|
let error = new Error('extension is not compatible with current GNOME Shell and/or GJS version');
|
||||||
extension.state = ExtensionState.OUT_OF_DATE;
|
error.state = ExtensionState.OUT_OF_DATE;
|
||||||
return;
|
throw error;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let enabled = enabledExtensions.indexOf(extension.uuid) != -1;
|
||||||
if (enabled) {
|
if (enabled) {
|
||||||
initExtension(uuid);
|
initExtension(extension.uuid);
|
||||||
if (extension.state == ExtensionState.DISABLED)
|
if (extension.state == ExtensionState.DISABLED)
|
||||||
enableExtension(uuid);
|
enableExtension(extension.uuid);
|
||||||
} else {
|
} else {
|
||||||
extension.state = ExtensionState.INITIALIZED;
|
extension.state = ExtensionState.INITIALIZED;
|
||||||
}
|
}
|
||||||
|
|
||||||
_signals.emit('extension-state-changed', extension);
|
_signals.emit('extension-state-changed', extension);
|
||||||
global.log('Loaded extension ' + uuid);
|
}
|
||||||
|
|
||||||
|
function unloadExtension(uuid) {
|
||||||
|
let extension = ExtensionUtils.extensions[uuid];
|
||||||
|
if (!extension)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// Try to disable it -- if it's ERROR'd, we can't guarantee that,
|
||||||
|
// but it will be removed on next reboot, and hopefully nothing
|
||||||
|
// broke too much.
|
||||||
|
disableExtension(uuid);
|
||||||
|
|
||||||
|
extension.state = ExtensionState.UNINSTALLED;
|
||||||
|
_signals.emit('extension-state-changed', extension);
|
||||||
|
|
||||||
|
delete ExtensionUtils.extensions[uuid];
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
function initExtension(uuid) {
|
function initExtension(uuid) {
|
||||||
@ -288,64 +183,24 @@ function initExtension(uuid) {
|
|||||||
throw new Error("Extension was not properly created. Call loadExtension first");
|
throw new Error("Extension was not properly created. Call loadExtension first");
|
||||||
|
|
||||||
let extensionJs = dir.get_child('extension.js');
|
let extensionJs = dir.get_child('extension.js');
|
||||||
if (!extensionJs.query_exists(null)) {
|
if (!extensionJs.query_exists(null))
|
||||||
logExtensionError(uuid, 'Missing extension.js');
|
throw new Error('Missing extension.js');
|
||||||
return;
|
|
||||||
}
|
|
||||||
let stylesheetPath = null;
|
|
||||||
let themeContext = St.ThemeContext.get_for_stage(global.stage);
|
|
||||||
let theme = themeContext.get_theme();
|
|
||||||
let stylesheetFile = dir.get_child('stylesheet.css');
|
|
||||||
if (stylesheetFile.query_exists(null)) {
|
|
||||||
try {
|
|
||||||
theme.load_stylesheet(stylesheetFile.get_path());
|
|
||||||
} catch (e) {
|
|
||||||
logExtensionError(uuid, 'Stylesheet parse error: ' + e);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
let extensionModule;
|
let extensionModule;
|
||||||
let extensionState = null;
|
let extensionState = null;
|
||||||
try {
|
|
||||||
ExtensionUtils.installImporter(extension);
|
ExtensionUtils.installImporter(extension);
|
||||||
extensionModule = extension.imports.extension;
|
extensionModule = extension.imports.extension;
|
||||||
} catch (e) {
|
|
||||||
if (stylesheetPath != null)
|
|
||||||
theme.unload_stylesheet(stylesheetPath);
|
|
||||||
logExtensionError(uuid, '' + e);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!extensionModule.init) {
|
if (extensionModule.init) {
|
||||||
logExtensionError(uuid, 'missing \'init\' function');
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
extensionState = extensionModule.init(extension);
|
extensionState = extensionModule.init(extension);
|
||||||
} catch (e) {
|
|
||||||
if (stylesheetPath != null)
|
|
||||||
theme.unload_stylesheet(stylesheetPath);
|
|
||||||
logExtensionError(uuid, 'Failed to evaluate init function:' + e);
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!extensionState)
|
if (!extensionState)
|
||||||
extensionState = extensionModule;
|
extensionState = extensionModule;
|
||||||
extension.stateObj = extensionState;
|
extension.stateObj = extensionState;
|
||||||
|
|
||||||
if (!extensionState.enable) {
|
|
||||||
logExtensionError(uuid, 'missing \'enable\' function');
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (!extensionState.disable) {
|
|
||||||
logExtensionError(uuid, 'missing \'disable\' function');
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
extension.state = ExtensionState.DISABLED;
|
extension.state = ExtensionState.DISABLED;
|
||||||
|
|
||||||
_signals.emit('extension-loaded', uuid);
|
_signals.emit('extension-loaded', uuid);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -357,7 +212,11 @@ function onEnabledExtensionsChanged() {
|
|||||||
newEnabledExtensions.filter(function(uuid) {
|
newEnabledExtensions.filter(function(uuid) {
|
||||||
return enabledExtensions.indexOf(uuid) == -1;
|
return enabledExtensions.indexOf(uuid) == -1;
|
||||||
}).forEach(function(uuid) {
|
}).forEach(function(uuid) {
|
||||||
|
try {
|
||||||
enableExtension(uuid);
|
enableExtension(uuid);
|
||||||
|
} catch(e) {
|
||||||
|
logExtensionError(uuid, e);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// Find and disable all the newly disabled extensions: UUIDs found in the
|
// Find and disable all the newly disabled extensions: UUIDs found in the
|
||||||
@ -365,87 +224,27 @@ function onEnabledExtensionsChanged() {
|
|||||||
enabledExtensions.filter(function(item) {
|
enabledExtensions.filter(function(item) {
|
||||||
return newEnabledExtensions.indexOf(item) == -1;
|
return newEnabledExtensions.indexOf(item) == -1;
|
||||||
}).forEach(function(uuid) {
|
}).forEach(function(uuid) {
|
||||||
|
try {
|
||||||
disableExtension(uuid);
|
disableExtension(uuid);
|
||||||
|
} catch(e) {
|
||||||
|
logExtensionError(uuid, e);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
enabledExtensions = newEnabledExtensions;
|
enabledExtensions = newEnabledExtensions;
|
||||||
}
|
}
|
||||||
|
|
||||||
function init() {
|
function loadExtensions() {
|
||||||
ExtensionUtils.init();
|
|
||||||
|
|
||||||
global.settings.connect('changed::' + ENABLED_EXTENSIONS_KEY, onEnabledExtensionsChanged);
|
global.settings.connect('changed::' + ENABLED_EXTENSIONS_KEY, onEnabledExtensionsChanged);
|
||||||
enabledExtensions = global.settings.get_strv(ENABLED_EXTENSIONS_KEY);
|
enabledExtensions = global.settings.get_strv(ENABLED_EXTENSIONS_KEY);
|
||||||
}
|
|
||||||
|
|
||||||
function loadExtensions() {
|
let finder = new ExtensionUtils.ExtensionFinder();
|
||||||
ExtensionUtils.scanExtensions(function(uuid, dir, type) {
|
finder.connect('extension-found', function(signals, extension) {
|
||||||
let enabled = enabledExtensions.indexOf(uuid) != -1;
|
try {
|
||||||
loadExtension(dir, type, enabled);
|
loadExtension(extension);
|
||||||
});
|
} catch(e) {
|
||||||
}
|
logExtensionError(extension.uuid, e);
|
||||||
|
|
||||||
const InstallExtensionDialog = new Lang.Class({
|
|
||||||
Name: 'InstallExtensionDialog',
|
|
||||||
Extends: ModalDialog.ModalDialog,
|
|
||||||
|
|
||||||
_init: function(uuid, version_tag, name) {
|
|
||||||
this.parent({ styleClass: 'extension-dialog' });
|
|
||||||
|
|
||||||
this._uuid = uuid;
|
|
||||||
this._version_tag = version_tag;
|
|
||||||
this._name = name;
|
|
||||||
|
|
||||||
this.setButtons([{ label: _("Cancel"),
|
|
||||||
action: Lang.bind(this, this._onCancelButtonPressed),
|
|
||||||
key: Clutter.Escape
|
|
||||||
},
|
|
||||||
{ label: _("Install"),
|
|
||||||
action: Lang.bind(this, this._onInstallButtonPressed)
|
|
||||||
}]);
|
|
||||||
|
|
||||||
let message = _("Download and install '%s' from extensions.gnome.org?").format(name);
|
|
||||||
|
|
||||||
this._descriptionLabel = new St.Label({ text: message });
|
|
||||||
|
|
||||||
this.contentLayout.add(this._descriptionLabel,
|
|
||||||
{ y_fill: true,
|
|
||||||
y_align: St.Align.START });
|
|
||||||
},
|
|
||||||
|
|
||||||
_onCancelButtonPressed: function(button, event) {
|
|
||||||
this.close(global.get_current_time());
|
|
||||||
|
|
||||||
// Even though the extension is already "uninstalled", send through
|
|
||||||
// a state-changed signal for any users who want to know if the install
|
|
||||||
// went through correctly -- using proper async DBus would block more
|
|
||||||
// traditional clients like the plugin
|
|
||||||
let meta = { uuid: this._uuid,
|
|
||||||
state: ExtensionState.UNINSTALLED,
|
|
||||||
error: '' };
|
|
||||||
|
|
||||||
_signals.emit('extension-state-changed', meta);
|
|
||||||
},
|
|
||||||
|
|
||||||
_onInstallButtonPressed: function(button, event) {
|
|
||||||
let state = { uuid: this._uuid,
|
|
||||||
state: ExtensionState.DOWNLOADING,
|
|
||||||
error: '' };
|
|
||||||
|
|
||||||
_signals.emit('extension-state-changed', state);
|
|
||||||
|
|
||||||
let params = { version_tag: this._version_tag,
|
|
||||||
shell_version: Config.PACKAGE_VERSION,
|
|
||||||
api_version: API_VERSION.toString() };
|
|
||||||
|
|
||||||
let url = REPOSITORY_URL_DOWNLOAD.format(this._uuid);
|
|
||||||
let message = Soup.form_request_new_from_hash('GET', url, params);
|
|
||||||
|
|
||||||
_httpSession.queue_message(message,
|
|
||||||
Lang.bind(this, function(session, message) {
|
|
||||||
gotExtensionZipFile(session, message, this._uuid);
|
|
||||||
}));
|
|
||||||
|
|
||||||
this.close(global.get_current_time());
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
finder.scanExtensions();
|
||||||
|
}
|
||||||
|
228
js/ui/ibusCandidatePopup.js
Normal file
228
js/ui/ibusCandidatePopup.js
Normal file
@ -0,0 +1,228 @@
|
|||||||
|
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
|
||||||
|
|
||||||
|
const Clutter = imports.gi.Clutter;
|
||||||
|
const IBus = imports.gi.IBus;
|
||||||
|
const Lang = imports.lang;
|
||||||
|
const St = imports.gi.St;
|
||||||
|
|
||||||
|
const BoxPointer = imports.ui.boxpointer;
|
||||||
|
const Main = imports.ui.main;
|
||||||
|
const PopupMenu = imports.ui.popupMenu;
|
||||||
|
|
||||||
|
const MAX_CANDIDATES_PER_PAGE = 16;
|
||||||
|
|
||||||
|
const CandidateArea = new Lang.Class({
|
||||||
|
Name: 'CandidateArea',
|
||||||
|
Extends: PopupMenu.PopupBaseMenuItem,
|
||||||
|
|
||||||
|
_init: function() {
|
||||||
|
this.parent({ reactive: false });
|
||||||
|
|
||||||
|
// St.Table exhibits some sizing problems so let's go with a
|
||||||
|
// clutter layout manager for now.
|
||||||
|
this._table = new Clutter.Actor();
|
||||||
|
this.addActor(this._table);
|
||||||
|
|
||||||
|
this._tableLayout = new Clutter.TableLayout();
|
||||||
|
this._table.set_layout_manager(this._tableLayout);
|
||||||
|
|
||||||
|
this._indexLabels = [];
|
||||||
|
this._candidateLabels = [];
|
||||||
|
for (let i = 0; i < MAX_CANDIDATES_PER_PAGE; ++i) {
|
||||||
|
this._indexLabels.push(new St.Label({ style_class: 'candidate-index' }));
|
||||||
|
this._candidateLabels.push(new St.Label({ style_class: 'candidate-label' }));
|
||||||
|
}
|
||||||
|
|
||||||
|
this._orientation = -1;
|
||||||
|
this._cursorPosition = 0;
|
||||||
|
},
|
||||||
|
|
||||||
|
_setOrientation: function(orientation) {
|
||||||
|
if (this._orientation == orientation)
|
||||||
|
return;
|
||||||
|
|
||||||
|
this._orientation = orientation;
|
||||||
|
|
||||||
|
this._table.remove_all_children();
|
||||||
|
|
||||||
|
if (this._orientation == IBus.Orientation.HORIZONTAL)
|
||||||
|
for (let i = 0; i < MAX_CANDIDATES_PER_PAGE; ++i) {
|
||||||
|
this._tableLayout.pack(this._indexLabels[i], i*2, 0);
|
||||||
|
this._tableLayout.pack(this._candidateLabels[i], i*2 + 1, 0);
|
||||||
|
}
|
||||||
|
else // VERTICAL || SYSTEM
|
||||||
|
for (let i = 0; i < MAX_CANDIDATES_PER_PAGE; ++i) {
|
||||||
|
this._tableLayout.pack(this._indexLabels[i], 0, i);
|
||||||
|
this._tableLayout.pack(this._candidateLabels[i], 1, i);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
setCandidates: function(indexes, candidates, orientation, cursorPosition, cursorVisible) {
|
||||||
|
this._setOrientation(orientation);
|
||||||
|
|
||||||
|
for (let i = 0; i < MAX_CANDIDATES_PER_PAGE; ++i) {
|
||||||
|
let visible = i < candidates.length;
|
||||||
|
this._indexLabels[i].visible = visible;
|
||||||
|
this._candidateLabels[i].visible = visible;
|
||||||
|
|
||||||
|
if (!visible)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
this._indexLabels[i].text = ((indexes && indexes[i]) ? indexes[i] : '%x.'.format(i + 1));
|
||||||
|
this._candidateLabels[i].text = candidates[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
this._candidateLabels[this._cursorPosition].remove_style_pseudo_class('selected');
|
||||||
|
this._cursorPosition = cursorPosition;
|
||||||
|
if (cursorVisible)
|
||||||
|
this._candidateLabels[cursorPosition].add_style_pseudo_class('selected');
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
const CandidatePopup = new Lang.Class({
|
||||||
|
Name: 'CandidatePopup',
|
||||||
|
Extends: PopupMenu.PopupMenu,
|
||||||
|
|
||||||
|
_init: function() {
|
||||||
|
this._cursor = new St.Bin({ opacity: 0 });
|
||||||
|
Main.uiGroup.add_actor(this._cursor);
|
||||||
|
|
||||||
|
this.parent(this._cursor, 0, St.Side.TOP);
|
||||||
|
this.actor.hide();
|
||||||
|
Main.uiGroup.add_actor(this.actor);
|
||||||
|
|
||||||
|
this._preeditTextItem = new PopupMenu.PopupMenuItem('', { reactive: false });
|
||||||
|
this._preeditTextItem.actor.hide();
|
||||||
|
this.addMenuItem(this._preeditTextItem);
|
||||||
|
|
||||||
|
this._auxTextItem = new PopupMenu.PopupMenuItem('', { reactive: false });
|
||||||
|
this._auxTextItem.actor.hide();
|
||||||
|
this.addMenuItem(this._auxTextItem);
|
||||||
|
|
||||||
|
this.addMenuItem(new PopupMenu.PopupSeparatorMenuItem());
|
||||||
|
|
||||||
|
this._lookupTableItem = new CandidateArea();
|
||||||
|
this._lookupTableItem.actor.hide();
|
||||||
|
this.addMenuItem(this._lookupTableItem);
|
||||||
|
|
||||||
|
this._panelService = null;
|
||||||
|
},
|
||||||
|
|
||||||
|
setPanelService: function(panelService) {
|
||||||
|
this._panelService = panelService;
|
||||||
|
if (!panelService)
|
||||||
|
return;
|
||||||
|
|
||||||
|
panelService.connect('set-cursor-location',
|
||||||
|
Lang.bind(this, function(ps, x, y, w, h) {
|
||||||
|
this._cursor.set_position(x, y);
|
||||||
|
this._cursor.set_size(w, h);
|
||||||
|
}));
|
||||||
|
panelService.connect('update-preedit-text',
|
||||||
|
Lang.bind(this, function(ps, text, cursorPosition, visible) {
|
||||||
|
if (visible)
|
||||||
|
this._preeditTextItem.actor.show();
|
||||||
|
else
|
||||||
|
this._preeditTextItem.actor.hide();
|
||||||
|
this._updateVisibility();
|
||||||
|
|
||||||
|
this._preeditTextItem.actor.label_actor.text = text.get_text();
|
||||||
|
|
||||||
|
let attrs = text.get_attributes();
|
||||||
|
if (attrs)
|
||||||
|
this._setTextAttributes(this._preeditTextItem.actor.label_actor.clutter_text,
|
||||||
|
attrs);
|
||||||
|
}));
|
||||||
|
panelService.connect('show-preedit-text',
|
||||||
|
Lang.bind(this, function(ps) {
|
||||||
|
this._preeditTextItem.actor.show();
|
||||||
|
this._updateVisibility();
|
||||||
|
}));
|
||||||
|
panelService.connect('hide-preedit-text',
|
||||||
|
Lang.bind(this, function(ps) {
|
||||||
|
this._preeditTextItem.actor.hide();
|
||||||
|
this._updateVisibility();
|
||||||
|
}));
|
||||||
|
panelService.connect('update-auxiliary-text',
|
||||||
|
Lang.bind(this, function(ps, text, visible) {
|
||||||
|
if (visible)
|
||||||
|
this._auxTextItem.actor.show();
|
||||||
|
else
|
||||||
|
this._auxTextItem.actor.hide();
|
||||||
|
this._updateVisibility();
|
||||||
|
|
||||||
|
this._auxTextItem.actor.label_actor.text = text.get_text();
|
||||||
|
}));
|
||||||
|
panelService.connect('show-auxiliary-text',
|
||||||
|
Lang.bind(this, function(ps) {
|
||||||
|
this._auxTextItem.actor.show();
|
||||||
|
this._updateVisibility();
|
||||||
|
}));
|
||||||
|
panelService.connect('hide-auxiliary-text',
|
||||||
|
Lang.bind(this, function(ps) {
|
||||||
|
this._auxTextItem.actor.hide();
|
||||||
|
this._updateVisibility();
|
||||||
|
}));
|
||||||
|
panelService.connect('update-lookup-table',
|
||||||
|
Lang.bind(this, function(ps, lookupTable, visible) {
|
||||||
|
if (visible)
|
||||||
|
this._lookupTableItem.actor.show();
|
||||||
|
else
|
||||||
|
this._lookupTableItem.actor.hide();
|
||||||
|
this._updateVisibility();
|
||||||
|
|
||||||
|
let cursorPos = lookupTable.get_cursor_pos();
|
||||||
|
let pageSize = lookupTable.get_page_size();
|
||||||
|
let page = ((cursorPos == 0) ? 0 : Math.floor(cursorPos / pageSize));
|
||||||
|
let startIndex = page * pageSize;
|
||||||
|
let endIndex = Math.min((page + 1) * pageSize,
|
||||||
|
lookupTable.get_number_of_candidates());
|
||||||
|
let indexes = [];
|
||||||
|
let indexLabel;
|
||||||
|
for (let i = 0; indexLabel = lookupTable.get_label(i); ++i)
|
||||||
|
indexes.push(indexLabel.get_text());
|
||||||
|
|
||||||
|
let candidates = [];
|
||||||
|
for (let i = startIndex; i < endIndex; ++i)
|
||||||
|
candidates.push(lookupTable.get_candidate(i).get_text());
|
||||||
|
|
||||||
|
this._lookupTableItem.setCandidates(indexes,
|
||||||
|
candidates,
|
||||||
|
lookupTable.get_orientation(),
|
||||||
|
cursorPos % pageSize,
|
||||||
|
lookupTable.is_cursor_visible());
|
||||||
|
}));
|
||||||
|
panelService.connect('show-lookup-table',
|
||||||
|
Lang.bind(this, function(ps) {
|
||||||
|
this._lookupTableItem.actor.show();
|
||||||
|
this._updateVisibility();
|
||||||
|
}));
|
||||||
|
panelService.connect('hide-lookup-table',
|
||||||
|
Lang.bind(this, function(ps) {
|
||||||
|
this._lookupTableItem.actor.hide();
|
||||||
|
this._updateVisibility();
|
||||||
|
}));
|
||||||
|
panelService.connect('focus-out',
|
||||||
|
Lang.bind(this, function(ps) {
|
||||||
|
this.close(BoxPointer.PopupAnimation.NONE);
|
||||||
|
}));
|
||||||
|
},
|
||||||
|
|
||||||
|
_updateVisibility: function() {
|
||||||
|
let isVisible = (this._preeditTextItem.actor.visible ||
|
||||||
|
this._auxTextItem.actor.visible ||
|
||||||
|
this._lookupTableItem.actor.visible);
|
||||||
|
|
||||||
|
if (isVisible)
|
||||||
|
this.open(BoxPointer.PopupAnimation.NONE);
|
||||||
|
else
|
||||||
|
this.close(BoxPointer.PopupAnimation.NONE);
|
||||||
|
},
|
||||||
|
|
||||||
|
_setTextAttributes: function(clutterText, ibusAttrList) {
|
||||||
|
let attr;
|
||||||
|
for (let i = 0; attr = ibusAttrList.get(i); ++i)
|
||||||
|
if (attr.get_attr_type() == IBus.AttrType.BACKGROUND)
|
||||||
|
clutterText.set_selection(attr.get_start_index(), attr.get_end_index());
|
||||||
|
}
|
||||||
|
});
|
@ -146,11 +146,6 @@ const BaseIcon = new Lang.Class({
|
|||||||
size = found ? len : ICON_SIZE;
|
size = found ? len : ICON_SIZE;
|
||||||
}
|
}
|
||||||
|
|
||||||
// don't create icons unnecessarily
|
|
||||||
if (size == this.iconSize &&
|
|
||||||
this._iconBin.child)
|
|
||||||
return;
|
|
||||||
|
|
||||||
this._createIconTexture(size);
|
this._createIconTexture(size);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@ -287,6 +282,10 @@ const IconGrid = new Lang.Class({
|
|||||||
return this._computeLayout(rowWidth)[0];
|
return this._computeLayout(rowWidth)[0];
|
||||||
},
|
},
|
||||||
|
|
||||||
|
getRowLimit: function() {
|
||||||
|
return this._rowLimit;
|
||||||
|
},
|
||||||
|
|
||||||
_computeLayout: function (forWidth) {
|
_computeLayout: function (forWidth) {
|
||||||
let nColumns = 0;
|
let nColumns = 0;
|
||||||
let usedWidth = 0;
|
let usedWidth = 0;
|
||||||
@ -311,20 +310,21 @@ const IconGrid = new Lang.Class({
|
|||||||
},
|
},
|
||||||
|
|
||||||
removeAll: function() {
|
removeAll: function() {
|
||||||
this._grid.get_children().forEach(Lang.bind(this, function (child) {
|
this._grid.destroy_all_children();
|
||||||
child.destroy();
|
|
||||||
}));
|
|
||||||
},
|
},
|
||||||
|
|
||||||
addItem: function(actor) {
|
addItem: function(actor, index) {
|
||||||
|
if (index !== undefined)
|
||||||
|
this._grid.insert_child_at_index(actor, index);
|
||||||
|
else
|
||||||
this._grid.add_actor(actor);
|
this._grid.add_actor(actor);
|
||||||
},
|
},
|
||||||
|
|
||||||
getItemAtIndex: function(index) {
|
getItemAtIndex: function(index) {
|
||||||
return this._grid.get_children()[index];
|
return this._grid.get_child_at_index(index);
|
||||||
},
|
},
|
||||||
|
|
||||||
visibleItemsCount: function() {
|
visibleItemsCount: function() {
|
||||||
return this._grid.get_children().length - this._grid.get_n_skip_paint();
|
return this._grid.get_n_children() - this._grid.get_n_skip_paint();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -175,7 +175,7 @@ const Key = new Lang.Class({
|
|||||||
this.actor.fake_release();
|
this.actor.fake_release();
|
||||||
this._boxPointer.actor.raise_top();
|
this._boxPointer.actor.raise_top();
|
||||||
this._boxPointer.setPosition(this.actor, 0.5);
|
this._boxPointer.setPosition(this.actor, 0.5);
|
||||||
this._boxPointer.show(true);
|
this._boxPointer.show(BoxPointer.PopupAnimation.FULL);
|
||||||
this.actor.set_hover(false);
|
this.actor.set_hover(false);
|
||||||
if (!this._grabbed) {
|
if (!this._grabbed) {
|
||||||
Main.pushModal(this.actor);
|
Main.pushModal(this.actor);
|
||||||
@ -186,7 +186,7 @@ const Key = new Lang.Class({
|
|||||||
} else {
|
} else {
|
||||||
if (this._grabbed)
|
if (this._grabbed)
|
||||||
this._ungrab();
|
this._ungrab();
|
||||||
this._boxPointer.hide(true);
|
this._boxPointer.hide(BoxPointer.PopupAnimation.FULL);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@ -541,16 +541,8 @@ const KeyboardSource = new Lang.Class({
|
|||||||
Extends: MessageTray.Source,
|
Extends: MessageTray.Source,
|
||||||
|
|
||||||
_init: function(keyboard) {
|
_init: function(keyboard) {
|
||||||
this.parent(_("Keyboard"));
|
|
||||||
this._keyboard = keyboard;
|
this._keyboard = keyboard;
|
||||||
|
this.parent(_("Keyboard"), 'input-keyboard', St.IconType.SYMBOLIC);
|
||||||
this._setSummaryIcon(this.createNotificationIcon());
|
|
||||||
},
|
|
||||||
|
|
||||||
createNotificationIcon: function() {
|
|
||||||
return new St.Icon({ icon_name: 'input-keyboard',
|
|
||||||
icon_type: St.IconType.SYMBOLIC,
|
|
||||||
icon_size: this.ICON_SIZE });
|
|
||||||
},
|
},
|
||||||
|
|
||||||
handleSummaryClick: function() {
|
handleSummaryClick: function() {
|
||||||
|
@ -53,6 +53,10 @@ const LayoutManager = new Lang.Class({
|
|||||||
global.screen.connect('monitors-changed',
|
global.screen.connect('monitors-changed',
|
||||||
Lang.bind(this, this._monitorsChanged));
|
Lang.bind(this, this._monitorsChanged));
|
||||||
this._monitorsChanged();
|
this._monitorsChanged();
|
||||||
|
|
||||||
|
this._chrome.connect('primary-fullscreen-changed', Lang.bind(this, function(chrome, state) {
|
||||||
|
this.emit('primary-fullscreen-changed', state);
|
||||||
|
}));
|
||||||
},
|
},
|
||||||
|
|
||||||
// This is called by Main after everything else is constructed;
|
// This is called by Main after everything else is constructed;
|
||||||
@ -224,26 +228,9 @@ const LayoutManager = new Lang.Class({
|
|||||||
return false;
|
return false;
|
||||||
},
|
},
|
||||||
|
|
||||||
get focusIndex() {
|
get currentMonitor() {
|
||||||
let focusWindow = global.display.focus_window;
|
let index = global.screen.get_current_monitor();
|
||||||
|
return Main.layoutManager.monitors[index];
|
||||||
if (focusWindow) {
|
|
||||||
let wrect = focusWindow.get_outer_rect();
|
|
||||||
for (let i = 0; i < this.monitors.length; i++) {
|
|
||||||
let monitor = this.monitors[i];
|
|
||||||
|
|
||||||
if (monitor.x <= wrect.x && monitor.y <= wrect.y &&
|
|
||||||
monitor.x + monitor.width > wrect.x &&
|
|
||||||
monitor.y + monitor.height > wrect.y)
|
|
||||||
return i;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return this.primaryIndex;
|
|
||||||
},
|
|
||||||
|
|
||||||
get focusMonitor() {
|
|
||||||
return this.monitors[this.focusIndex];
|
|
||||||
},
|
},
|
||||||
|
|
||||||
_startupAnimation: function() {
|
_startupAnimation: function() {
|
||||||
@ -852,6 +839,8 @@ const Chrome = new Lang.Class({
|
|||||||
for (let i = 0; i < this._monitors.length; i++)
|
for (let i = 0; i < this._monitors.length; i++)
|
||||||
wasInFullscreen[i] = this._monitors[i].inFullscreen;
|
wasInFullscreen[i] = this._monitors[i].inFullscreen;
|
||||||
|
|
||||||
|
let primaryWasInFullscreen = this._primaryMonitor.inFullscreen;
|
||||||
|
|
||||||
this._updateFullscreen();
|
this._updateFullscreen();
|
||||||
|
|
||||||
let changed = false;
|
let changed = false;
|
||||||
@ -861,10 +850,15 @@ const Chrome = new Lang.Class({
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (changed) {
|
if (changed) {
|
||||||
this._updateVisibility();
|
this._updateVisibility();
|
||||||
this._queueUpdateRegions();
|
this._queueUpdateRegions();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (primaryWasInFullscreen != this._primaryMonitor.inFullscreen) {
|
||||||
|
this.emit('primary-fullscreen-changed', this._primaryMonitor.inFullscreen);
|
||||||
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
updateRegions: function() {
|
updateRegions: function() {
|
||||||
@ -979,3 +973,5 @@ const Chrome = new Lang.Class({
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
Signals.addSignalMethods(Chrome.prototype);
|
||||||
|
@ -8,8 +8,6 @@ const St = imports.gi.St;
|
|||||||
const Params = imports.misc.params;
|
const Params = imports.misc.params;
|
||||||
const Tweener = imports.ui.tweener;
|
const Tweener = imports.ui.tweener;
|
||||||
|
|
||||||
const DEFAULT_FADE_FACTOR = 0.4;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Lightbox:
|
* Lightbox:
|
||||||
* @container: parent Clutter.Container
|
* @container: parent Clutter.Container
|
||||||
@ -17,8 +15,7 @@ const DEFAULT_FADE_FACTOR = 0.4;
|
|||||||
* - inhibitEvents: whether to inhibit events for @container
|
* - inhibitEvents: whether to inhibit events for @container
|
||||||
* - width: shade actor width
|
* - width: shade actor width
|
||||||
* - height: shade actor height
|
* - height: shade actor height
|
||||||
* - fadeInTime: seconds used to fade in
|
* - fadeTime: seconds used to fade in/out
|
||||||
* - fadeOutTime: seconds used to fade out
|
|
||||||
*
|
*
|
||||||
* Lightbox creates a dark translucent "shade" actor to hide the
|
* Lightbox creates a dark translucent "shade" actor to hide the
|
||||||
* contents of @container, and allows you to specify particular actors
|
* contents of @container, and allows you to specify particular actors
|
||||||
@ -41,16 +38,12 @@ const Lightbox = new Lang.Class({
|
|||||||
params = Params.parse(params, { inhibitEvents: false,
|
params = Params.parse(params, { inhibitEvents: false,
|
||||||
width: null,
|
width: null,
|
||||||
height: null,
|
height: null,
|
||||||
fadeInTime: null,
|
fadeTime: null
|
||||||
fadeOutTime: null,
|
|
||||||
fadeFactor: DEFAULT_FADE_FACTOR
|
|
||||||
});
|
});
|
||||||
|
|
||||||
this._container = container;
|
this._container = container;
|
||||||
this._children = container.get_children();
|
this._children = container.get_children();
|
||||||
this._fadeInTime = params.fadeInTime;
|
this._fadeTime = params.fadeTime;
|
||||||
this._fadeOutTime = params.fadeOutTime;
|
|
||||||
this._fadeFactor = params.fadeFactor;
|
|
||||||
this.actor = new St.Bin({ x: 0,
|
this.actor = new St.Bin({ x: 0,
|
||||||
y: 0,
|
y: 0,
|
||||||
style_class: 'lightbox',
|
style_class: 'lightbox',
|
||||||
@ -59,7 +52,6 @@ const Lightbox = new Lang.Class({
|
|||||||
container.add_actor(this.actor);
|
container.add_actor(this.actor);
|
||||||
this.actor.raise_top();
|
this.actor.raise_top();
|
||||||
this.actor.hide();
|
this.actor.hide();
|
||||||
this.shown = false;
|
|
||||||
|
|
||||||
this.actor.connect('destroy', Lang.bind(this, this._onDestroy));
|
this.actor.connect('destroy', Lang.bind(this, this._onDestroy));
|
||||||
|
|
||||||
@ -101,30 +93,24 @@ const Lightbox = new Lang.Class({
|
|||||||
},
|
},
|
||||||
|
|
||||||
show: function() {
|
show: function() {
|
||||||
if (this._fadeInTime) {
|
if (this._fadeTime) {
|
||||||
this.shown = false;
|
|
||||||
this.actor.opacity = 0;
|
this.actor.opacity = 0;
|
||||||
Tweener.addTween(this.actor,
|
Tweener.addTween(this.actor,
|
||||||
{ opacity: 255 * this._fadeFactor,
|
{ opacity: 255,
|
||||||
time: this._fadeInTime,
|
time: this._fadeTime,
|
||||||
transition: 'easeOutQuad',
|
transition: 'easeOutQuad'
|
||||||
onComplete: Lang.bind(this, function() {
|
|
||||||
this.shown = true;
|
|
||||||
})
|
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
this.actor.opacity = 255 * this._fadeFactor;
|
this.actor.opacity = 255;
|
||||||
this.shown = true;
|
|
||||||
}
|
}
|
||||||
this.actor.show();
|
this.actor.show();
|
||||||
},
|
},
|
||||||
|
|
||||||
hide: function() {
|
hide: function() {
|
||||||
this.shown = false;
|
if (this._fadeTime) {
|
||||||
if (this._fadeOutTime) {
|
|
||||||
Tweener.addTween(this.actor,
|
Tweener.addTween(this.actor,
|
||||||
{ opacity: 0,
|
{ opacity: 0,
|
||||||
time: this._fadeOutTime,
|
time: this._fadeTime,
|
||||||
transition: 'easeOutQuad',
|
transition: 'easeOutQuad',
|
||||||
onComplete: Lang.bind(this, function() {
|
onComplete: Lang.bind(this, function() {
|
||||||
this.actor.hide();
|
this.actor.hide();
|
||||||
|
@ -1,21 +0,0 @@
|
|||||||
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
|
|
||||||
|
|
||||||
const Lang = imports.lang;
|
|
||||||
const Signals = imports.signals;
|
|
||||||
const St = imports.gi.St;
|
|
||||||
|
|
||||||
const Link = new Lang.Class({
|
|
||||||
Name: 'Link',
|
|
||||||
|
|
||||||
_init : function(props) {
|
|
||||||
let realProps = { reactive: true,
|
|
||||||
track_hover: true,
|
|
||||||
style_class: 'shell-link' };
|
|
||||||
// The user can pass in reactive: false to override the above and get
|
|
||||||
// a non-reactive link (a link to the current page, perhaps)
|
|
||||||
Lang.copyProperties(props, realProps);
|
|
||||||
|
|
||||||
this.actor = new St.Button(realProps);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
Signals.addSignalMethods(Link.prototype);
|
|
@ -12,16 +12,18 @@ const Shell = imports.gi.Shell;
|
|||||||
const Signals = imports.signals;
|
const Signals = imports.signals;
|
||||||
const Lang = imports.lang;
|
const Lang = imports.lang;
|
||||||
const Mainloop = imports.mainloop;
|
const Mainloop = imports.mainloop;
|
||||||
|
const System = imports.system;
|
||||||
|
|
||||||
const History = imports.misc.history;
|
const History = imports.misc.history;
|
||||||
const ExtensionSystem = imports.ui.extensionSystem;
|
const ExtensionSystem = imports.ui.extensionSystem;
|
||||||
const ExtensionUtils = imports.misc.extensionUtils;
|
const ExtensionUtils = imports.misc.extensionUtils;
|
||||||
const Link = imports.ui.link;
|
|
||||||
const ShellEntry = imports.ui.shellEntry;
|
const ShellEntry = imports.ui.shellEntry;
|
||||||
const Tweener = imports.ui.tweener;
|
const Tweener = imports.ui.tweener;
|
||||||
const Main = imports.ui.main;
|
const Main = imports.ui.main;
|
||||||
const JsParse = imports.misc.jsParse;
|
const JsParse = imports.misc.jsParse;
|
||||||
|
|
||||||
|
const CHEVRON = '>>> ';
|
||||||
|
|
||||||
/* Imports...feel free to add here as needed */
|
/* Imports...feel free to add here as needed */
|
||||||
var commandHeader = 'const Clutter = imports.gi.Clutter; ' +
|
var commandHeader = 'const Clutter = imports.gi.Clutter; ' +
|
||||||
'const GLib = imports.gi.GLib; ' +
|
'const GLib = imports.gi.GLib; ' +
|
||||||
@ -261,9 +263,8 @@ function objectToString(o) {
|
|||||||
|
|
||||||
const ObjLink = new Lang.Class({
|
const ObjLink = new Lang.Class({
|
||||||
Name: 'ObjLink',
|
Name: 'ObjLink',
|
||||||
Extends: Link.Link,
|
|
||||||
|
|
||||||
_init: function(o, title) {
|
_init: function(lookingGlass, o, title) {
|
||||||
let text;
|
let text;
|
||||||
if (title)
|
if (title)
|
||||||
text = title;
|
text = title;
|
||||||
@ -272,24 +273,30 @@ const ObjLink = new Lang.Class({
|
|||||||
text = GLib.markup_escape_text(text, -1);
|
text = GLib.markup_escape_text(text, -1);
|
||||||
this._obj = o;
|
this._obj = o;
|
||||||
|
|
||||||
this.parent({ label: text });
|
this.actor = new St.Button({ reactive: true,
|
||||||
|
track_hover: true,
|
||||||
|
style_class: 'shell-link',
|
||||||
|
label: text });
|
||||||
this.actor.get_child().single_line_mode = true;
|
this.actor.get_child().single_line_mode = true;
|
||||||
this.actor.connect('clicked', Lang.bind(this, this._onClicked));
|
this.actor.connect('clicked', Lang.bind(this, this._onClicked));
|
||||||
|
|
||||||
|
this._lookingGlass = lookingGlass;
|
||||||
},
|
},
|
||||||
|
|
||||||
_onClicked: function (link) {
|
_onClicked: function (link) {
|
||||||
Main.lookingGlass.inspectObject(this._obj, this.actor);
|
this._lookingGlass.inspectObject(this._obj, this.actor);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
const Result = new Lang.Class({
|
const Result = new Lang.Class({
|
||||||
Name: 'Result',
|
Name: 'Result',
|
||||||
|
|
||||||
_init : function(command, o, index) {
|
_init: function(lookingGlass, command, o, index) {
|
||||||
this.index = index;
|
this.index = index;
|
||||||
this.o = o;
|
this.o = o;
|
||||||
|
|
||||||
this.actor = new St.BoxLayout({ vertical: true });
|
this.actor = new St.BoxLayout({ vertical: true });
|
||||||
|
this._lookingGlass = lookingGlass;
|
||||||
|
|
||||||
let cmdTxt = new St.Label({ text: command });
|
let cmdTxt = new St.Label({ text: command });
|
||||||
cmdTxt.clutter_text.ellipsize = Pango.EllipsizeMode.END;
|
cmdTxt.clutter_text.ellipsize = Pango.EllipsizeMode.END;
|
||||||
@ -299,7 +306,7 @@ const Result = new Lang.Class({
|
|||||||
let resultTxt = new St.Label({ text: 'r(' + index + ') = ' });
|
let resultTxt = new St.Label({ text: 'r(' + index + ') = ' });
|
||||||
resultTxt.clutter_text.ellipsize = Pango.EllipsizeMode.END;
|
resultTxt.clutter_text.ellipsize = Pango.EllipsizeMode.END;
|
||||||
box.add(resultTxt);
|
box.add(resultTxt);
|
||||||
let objLink = new ObjLink(o);
|
let objLink = new ObjLink(this._lookingGlass, o);
|
||||||
box.add(objLink.actor);
|
box.add(objLink.actor);
|
||||||
let line = new Clutter.Rectangle({ name: 'Separator' });
|
let line = new Clutter.Rectangle({ name: 'Separator' });
|
||||||
let padBin = new St.Bin({ name: 'Separator', x_fill: true, y_fill: true });
|
let padBin = new St.Bin({ name: 'Separator', x_fill: true, y_fill: true });
|
||||||
@ -311,16 +318,18 @@ const Result = new Lang.Class({
|
|||||||
const WindowList = new Lang.Class({
|
const WindowList = new Lang.Class({
|
||||||
Name: 'WindowList',
|
Name: 'WindowList',
|
||||||
|
|
||||||
_init : function () {
|
_init: function(lookingGlass) {
|
||||||
this.actor = new St.BoxLayout({ name: 'Windows', vertical: true, style: 'spacing: 8px' });
|
this.actor = new St.BoxLayout({ name: 'Windows', vertical: true, style: 'spacing: 8px' });
|
||||||
let tracker = Shell.WindowTracker.get_default();
|
let tracker = Shell.WindowTracker.get_default();
|
||||||
this._updateId = Main.initializeDeferredWork(this.actor, Lang.bind(this, this._updateWindowList));
|
this._updateId = Main.initializeDeferredWork(this.actor, Lang.bind(this, this._updateWindowList));
|
||||||
global.display.connect('window-created', Lang.bind(this, this._updateWindowList));
|
global.display.connect('window-created', Lang.bind(this, this._updateWindowList));
|
||||||
tracker.connect('tracked-windows-changed', Lang.bind(this, this._updateWindowList));
|
tracker.connect('tracked-windows-changed', Lang.bind(this, this._updateWindowList));
|
||||||
|
|
||||||
|
this._lookingGlass = lookingGlass;
|
||||||
},
|
},
|
||||||
|
|
||||||
_updateWindowList: function() {
|
_updateWindowList: function() {
|
||||||
this.actor.get_children().forEach(function (actor) { actor.destroy(); });
|
this.actor.destroy_all_children();
|
||||||
let windows = global.get_window_actors();
|
let windows = global.get_window_actors();
|
||||||
let tracker = Shell.WindowTracker.get_default();
|
let tracker = Shell.WindowTracker.get_default();
|
||||||
for (let i = 0; i < windows.length; i++) {
|
for (let i = 0; i < windows.length; i++) {
|
||||||
@ -332,7 +341,7 @@ const WindowList = new Lang.Class({
|
|||||||
}
|
}
|
||||||
let box = new St.BoxLayout({ vertical: true });
|
let box = new St.BoxLayout({ vertical: true });
|
||||||
this.actor.add(box);
|
this.actor.add(box);
|
||||||
let windowLink = new ObjLink(metaWindow, metaWindow.title);
|
let windowLink = new ObjLink(this._lookingGlass, metaWindow, metaWindow.title);
|
||||||
box.add(windowLink.actor, { x_align: St.Align.START, x_fill: false });
|
box.add(windowLink.actor, { x_align: St.Align.START, x_fill: false });
|
||||||
let propsBox = new St.BoxLayout({ vertical: true, style: 'padding-left: 6px;' });
|
let propsBox = new St.BoxLayout({ vertical: true, style: 'padding-left: 6px;' });
|
||||||
box.add(propsBox);
|
box.add(propsBox);
|
||||||
@ -343,7 +352,7 @@ const WindowList = new Lang.Class({
|
|||||||
let propBox = new St.BoxLayout({ style: 'spacing: 6px; ' });
|
let propBox = new St.BoxLayout({ style: 'spacing: 6px; ' });
|
||||||
propsBox.add(propBox);
|
propsBox.add(propBox);
|
||||||
propBox.add(new St.Label({ text: 'app: ' }), { y_fill: false });
|
propBox.add(new St.Label({ text: 'app: ' }), { y_fill: false });
|
||||||
let appLink = new ObjLink(app, app.get_id());
|
let appLink = new ObjLink(this._lookingGlass, app, app.get_id());
|
||||||
propBox.add(appLink.actor, { y_fill: false });
|
propBox.add(appLink.actor, { y_fill: false });
|
||||||
propBox.add(icon, { y_fill: false });
|
propBox.add(icon, { y_fill: false });
|
||||||
} else {
|
} else {
|
||||||
@ -357,7 +366,7 @@ Signals.addSignalMethods(WindowList.prototype);
|
|||||||
const ObjInspector = new Lang.Class({
|
const ObjInspector = new Lang.Class({
|
||||||
Name: 'ObjInspector',
|
Name: 'ObjInspector',
|
||||||
|
|
||||||
_init : function () {
|
_init: function(lookingGlass) {
|
||||||
this._obj = null;
|
this._obj = null;
|
||||||
this._previousObj = null;
|
this._previousObj = null;
|
||||||
|
|
||||||
@ -369,6 +378,8 @@ const ObjInspector = new Lang.Class({
|
|||||||
style_class: 'lg-dialog',
|
style_class: 'lg-dialog',
|
||||||
vertical: true });
|
vertical: true });
|
||||||
this.actor.add_actor(this._container);
|
this.actor.add_actor(this._container);
|
||||||
|
|
||||||
|
this._lookingGlass = lookingGlass;
|
||||||
},
|
},
|
||||||
|
|
||||||
selectObject: function(obj, skipPrevious) {
|
selectObject: function(obj, skipPrevious) {
|
||||||
@ -378,7 +389,7 @@ const ObjInspector = new Lang.Class({
|
|||||||
this._previousObj = null;
|
this._previousObj = null;
|
||||||
this._obj = obj;
|
this._obj = obj;
|
||||||
|
|
||||||
this._container.get_children().forEach(function (child) { child.destroy(); });
|
this._container.destroy_all_children();
|
||||||
|
|
||||||
let hbox = new St.BoxLayout({ style_class: 'lg-obj-inspector-title' });
|
let hbox = new St.BoxLayout({ style_class: 'lg-obj-inspector-title' });
|
||||||
this._container.add_actor(hbox);
|
this._container.add_actor(hbox);
|
||||||
@ -400,12 +411,19 @@ const ObjInspector = new Lang.Class({
|
|||||||
button.connect('clicked', Lang.bind(this, this.close));
|
button.connect('clicked', Lang.bind(this, this.close));
|
||||||
hbox.add(button);
|
hbox.add(button);
|
||||||
if (typeof(obj) == typeof({})) {
|
if (typeof(obj) == typeof({})) {
|
||||||
|
let properties = [];
|
||||||
for (let propName in obj) {
|
for (let propName in obj) {
|
||||||
|
properties.push(propName);
|
||||||
|
}
|
||||||
|
properties.sort();
|
||||||
|
|
||||||
|
for (let i = 0; i < properties.length; i++) {
|
||||||
|
let propName = properties[i];
|
||||||
let valueStr;
|
let valueStr;
|
||||||
let link;
|
let link;
|
||||||
try {
|
try {
|
||||||
let prop = obj[propName];
|
let prop = obj[propName];
|
||||||
link = new ObjLink(prop).actor;
|
link = new ObjLink(this._lookingGlass, prop).actor;
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
link = new St.Label({ text: '<error>' });
|
link = new St.Label({ text: '<error>' });
|
||||||
}
|
}
|
||||||
@ -450,7 +468,7 @@ const ObjInspector = new Lang.Class({
|
|||||||
_onInsert: function() {
|
_onInsert: function() {
|
||||||
let obj = this._obj;
|
let obj = this._obj;
|
||||||
this.close();
|
this.close();
|
||||||
Main.lookingGlass.insertObject(obj);
|
this._lookingGlass.insertObject(obj);
|
||||||
},
|
},
|
||||||
|
|
||||||
_onBack: function() {
|
_onBack: function() {
|
||||||
@ -458,9 +476,14 @@ const ObjInspector = new Lang.Class({
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
function addBorderPaintHook(actor) {
|
const RedBorderEffect = new Lang.Class({
|
||||||
let signalId = actor.connect_after('paint',
|
Name: 'RedBorderEffect',
|
||||||
function () {
|
Extends: Clutter.Effect,
|
||||||
|
|
||||||
|
vfunc_paint: function() {
|
||||||
|
let actor = this.get_actor();
|
||||||
|
actor.continue_paint();
|
||||||
|
|
||||||
let color = new Cogl.Color();
|
let color = new Cogl.Color();
|
||||||
color.init_from_4ub(0xff, 0, 0, 0xc4);
|
color.init_from_4ub(0xff, 0, 0, 0xc4);
|
||||||
Cogl.set_source_color(color);
|
Cogl.set_source_color(color);
|
||||||
@ -476,16 +499,13 @@ function addBorderPaintHook(actor) {
|
|||||||
geom.width - width, geom.height - width);
|
geom.width - width, geom.height - width);
|
||||||
Cogl.rectangle(0, geom.height - width,
|
Cogl.rectangle(0, geom.height - width,
|
||||||
width, width);
|
width, width);
|
||||||
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
actor.queue_redraw();
|
|
||||||
return signalId;
|
|
||||||
}
|
|
||||||
|
|
||||||
const Inspector = new Lang.Class({
|
const Inspector = new Lang.Class({
|
||||||
Name: 'Inspector',
|
Name: 'Inspector',
|
||||||
|
|
||||||
_init: function() {
|
_init: function(lookingGlass) {
|
||||||
let container = new Shell.GenericContainer({ width: 0,
|
let container = new Shell.GenericContainer({ width: 0,
|
||||||
height: 0 });
|
height: 0 });
|
||||||
container.connect('allocate', Lang.bind(this, this._allocate));
|
container.connect('allocate', Lang.bind(this, this._allocate));
|
||||||
@ -499,9 +519,6 @@ const Inspector = new Lang.Class({
|
|||||||
this._displayText = new St.Label();
|
this._displayText = new St.Label();
|
||||||
eventHandler.add(this._displayText, { expand: true });
|
eventHandler.add(this._displayText, { expand: true });
|
||||||
|
|
||||||
this._borderPaintTarget = null;
|
|
||||||
this._borderPaintId = null;
|
|
||||||
eventHandler.connect('destroy', Lang.bind(this, this._onDestroy));
|
|
||||||
eventHandler.connect('key-press-event', Lang.bind(this, this._onKeyPressEvent));
|
eventHandler.connect('key-press-event', Lang.bind(this, this._onKeyPressEvent));
|
||||||
eventHandler.connect('button-press-event', Lang.bind(this, this._onButtonPressEvent));
|
eventHandler.connect('button-press-event', Lang.bind(this, this._onButtonPressEvent));
|
||||||
eventHandler.connect('scroll-event', Lang.bind(this, this._onScrollEvent));
|
eventHandler.connect('scroll-event', Lang.bind(this, this._onScrollEvent));
|
||||||
@ -516,6 +533,8 @@ const Inspector = new Lang.Class({
|
|||||||
// out, or move the pointer outside of _pointerTarget.
|
// out, or move the pointer outside of _pointerTarget.
|
||||||
this._target = null;
|
this._target = null;
|
||||||
this._pointerTarget = null;
|
this._pointerTarget = null;
|
||||||
|
|
||||||
|
this._lookingGlass = lookingGlass;
|
||||||
},
|
},
|
||||||
|
|
||||||
_allocate: function(actor, box, flags) {
|
_allocate: function(actor, box, flags) {
|
||||||
@ -543,11 +562,6 @@ const Inspector = new Lang.Class({
|
|||||||
this.emit('closed');
|
this.emit('closed');
|
||||||
},
|
},
|
||||||
|
|
||||||
_onDestroy: function() {
|
|
||||||
if (this._borderPaintTarget != null)
|
|
||||||
this._borderPaintTarget.disconnect(this._borderPaintId);
|
|
||||||
},
|
|
||||||
|
|
||||||
_onKeyPressEvent: function (actor, event) {
|
_onKeyPressEvent: function (actor, event) {
|
||||||
if (event.get_key_symbol() == Clutter.Escape)
|
if (event.get_key_symbol() == Clutter.Escape)
|
||||||
this._close();
|
this._close();
|
||||||
@ -616,56 +630,12 @@ const Inspector = new Lang.Class({
|
|||||||
this._displayText.text = '';
|
this._displayText.text = '';
|
||||||
this._displayText.text = position + ' ' + this._target;
|
this._displayText.text = position + ' ' + this._target;
|
||||||
|
|
||||||
if (this._borderPaintTarget != this._target) {
|
this._lookingGlass.setBorderPaintTarget(this._target);
|
||||||
if (this._borderPaintTarget != null)
|
|
||||||
this._borderPaintTarget.disconnect(this._borderPaintId);
|
|
||||||
this._borderPaintTarget = this._target;
|
|
||||||
this._borderPaintId = addBorderPaintHook(this._target);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
Signals.addSignalMethods(Inspector.prototype);
|
Signals.addSignalMethods(Inspector.prototype);
|
||||||
|
|
||||||
const ErrorLog = new Lang.Class({
|
|
||||||
Name: 'ErrorLog',
|
|
||||||
|
|
||||||
_init: function() {
|
|
||||||
this.actor = new St.BoxLayout();
|
|
||||||
this.text = new St.Label();
|
|
||||||
this.actor.add(this.text);
|
|
||||||
// We need to override StLabel's default ellipsization when
|
|
||||||
// using line_wrap; otherwise ClutterText's layout is going
|
|
||||||
// to constrain both the width and height, which prevents
|
|
||||||
// scrolling.
|
|
||||||
this.text.clutter_text.ellipsize = Pango.EllipsizeMode.NONE;
|
|
||||||
this.text.clutter_text.line_wrap = true;
|
|
||||||
this.actor.connect('notify::mapped', Lang.bind(this, this._renderText));
|
|
||||||
},
|
|
||||||
|
|
||||||
_formatTime: function(d){
|
|
||||||
function pad(n) { return n < 10 ? '0' + n : n; }
|
|
||||||
return d.getUTCFullYear()+'-'
|
|
||||||
+ pad(d.getUTCMonth()+1)+'-'
|
|
||||||
+ pad(d.getUTCDate())+'T'
|
|
||||||
+ pad(d.getUTCHours())+':'
|
|
||||||
+ pad(d.getUTCMinutes())+':'
|
|
||||||
+ pad(d.getUTCSeconds())+'Z';
|
|
||||||
},
|
|
||||||
|
|
||||||
_renderText: function() {
|
|
||||||
if (!this.actor.mapped)
|
|
||||||
return;
|
|
||||||
let text = this.text.text;
|
|
||||||
let stack = Main._getAndClearErrorStack();
|
|
||||||
for (let i = 0; i < stack.length; i++) {
|
|
||||||
let logItem = stack[i];
|
|
||||||
text += logItem.category + ' t=' + this._formatTime(new Date(logItem.timestamp)) + ' ' + logItem.message + '\n';
|
|
||||||
}
|
|
||||||
this.text.text = text;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
const Memory = new Lang.Class({
|
const Memory = new Lang.Class({
|
||||||
Name: 'Memory',
|
Name: 'Memory',
|
||||||
|
|
||||||
@ -694,7 +664,7 @@ const Memory = new Lang.Class({
|
|||||||
|
|
||||||
this._gcbutton = new St.Button({ label: 'Full GC',
|
this._gcbutton = new St.Button({ label: 'Full GC',
|
||||||
style_class: 'lg-obj-inspector-button' });
|
style_class: 'lg-obj-inspector-button' });
|
||||||
this._gcbutton.connect('clicked', Lang.bind(this, function () { global.gc(); this._renderText(); }));
|
this._gcbutton.connect('clicked', Lang.bind(this, function () { System.gc(); this._renderText(); }));
|
||||||
this.actor.add(this._gcbutton, { x_align: St.Align.START,
|
this.actor.add(this._gcbutton, { x_align: St.Align.START,
|
||||||
x_fill: false });
|
x_fill: false });
|
||||||
|
|
||||||
@ -755,13 +725,13 @@ const Extensions = new Lang.Class({
|
|||||||
let extension = actor._extension;
|
let extension = actor._extension;
|
||||||
let uri = extension.dir.get_uri();
|
let uri = extension.dir.get_uri();
|
||||||
Gio.app_info_launch_default_for_uri(uri, global.create_app_launch_context());
|
Gio.app_info_launch_default_for_uri(uri, global.create_app_launch_context());
|
||||||
Main.lookingGlass.close();
|
this._lookingGlass.close();
|
||||||
},
|
},
|
||||||
|
|
||||||
_onWebPage: function (actor) {
|
_onWebPage: function (actor) {
|
||||||
let extension = actor._extension;
|
let extension = actor._extension;
|
||||||
Gio.app_info_launch_default_for_uri(extension.metadata.url, global.create_app_launch_context());
|
Gio.app_info_launch_default_for_uri(extension.metadata.url, global.create_app_launch_context());
|
||||||
Main.lookingGlass.close();
|
this._lookingGlass.close();
|
||||||
},
|
},
|
||||||
|
|
||||||
_onViewErrors: function (actor) {
|
_onViewErrors: function (actor) {
|
||||||
@ -825,24 +795,33 @@ const Extensions = new Lang.Class({
|
|||||||
text: this._stateToString(extension.state) });
|
text: this._stateToString(extension.state) });
|
||||||
metaBox.add(state);
|
metaBox.add(state);
|
||||||
|
|
||||||
let viewsource = new Link.Link({ label: _("View Source") });
|
let viewsource = new St.Button({ reactive: true,
|
||||||
viewsource.actor._extension = extension;
|
track_hover: true,
|
||||||
viewsource.actor.connect('clicked', Lang.bind(this, this._onViewSource));
|
style_class: 'shell-link',
|
||||||
metaBox.add(viewsource.actor);
|
label: _("View Source") });
|
||||||
|
viewsource._extension = extension;
|
||||||
|
viewsource.connect('clicked', Lang.bind(this, this._onViewSource));
|
||||||
|
metaBox.add(viewsource);
|
||||||
|
|
||||||
if (extension.metadata.url) {
|
if (extension.metadata.url) {
|
||||||
let webpage = new Link.Link({ label: _("Web Page") });
|
let webpage = new St.Button({ reactive: true,
|
||||||
webpage.actor._extension = extension;
|
track_hover: true,
|
||||||
webpage.actor.connect('clicked', Lang.bind(this, this._onWebPage));
|
style_class: 'shell-link',
|
||||||
metaBox.add(webpage.actor);
|
label: _("Web Page") });
|
||||||
|
webpage._extension = extension;
|
||||||
|
webpage.connect('clicked', Lang.bind(this, this._onWebPage));
|
||||||
|
metaBox.add(webpage);
|
||||||
}
|
}
|
||||||
|
|
||||||
let viewerrors = new Link.Link({ label: _("Show Errors") });
|
let viewerrors = new St.Button({ reactive: true,
|
||||||
viewerrors.actor._extension = extension;
|
track_hover: true,
|
||||||
viewerrors.actor._parentBox = box;
|
style_class: 'shell-link',
|
||||||
viewerrors.actor._isShowing = false;
|
label: _("Show Errors") });
|
||||||
viewerrors.actor.connect('clicked', Lang.bind(this, this._onViewErrors));
|
viewerrors._extension = extension;
|
||||||
metaBox.add(viewerrors.actor);
|
viewerrors._parentBox = box;
|
||||||
|
viewerrors._isShowing = false;
|
||||||
|
viewerrors.connect('clicked', Lang.bind(this, this._onViewErrors));
|
||||||
|
metaBox.add(viewerrors);
|
||||||
|
|
||||||
return box;
|
return box;
|
||||||
}
|
}
|
||||||
@ -853,8 +832,7 @@ const LookingGlass = new Lang.Class({
|
|||||||
|
|
||||||
_init : function() {
|
_init : function() {
|
||||||
this._borderPaintTarget = null;
|
this._borderPaintTarget = null;
|
||||||
this._borderPaintId = 0;
|
this._redBorderEffect = new RedBorderEffect();
|
||||||
this._borderDestroyId = 0;
|
|
||||||
|
|
||||||
this._open = false;
|
this._open = false;
|
||||||
|
|
||||||
@ -884,7 +862,7 @@ const LookingGlass = new Lang.Class({
|
|||||||
Main.layoutManager.keyboardBox.connect('allocation-changed',
|
Main.layoutManager.keyboardBox.connect('allocation-changed',
|
||||||
Lang.bind(this, this._queueResize));
|
Lang.bind(this, this._queueResize));
|
||||||
|
|
||||||
this._objInspector = new ObjInspector();
|
this._objInspector = new ObjInspector(this);
|
||||||
Main.uiGroup.add_actor(this._objInspector.actor);
|
Main.uiGroup.add_actor(this._objInspector.actor);
|
||||||
this._objInspector.actor.hide();
|
this._objInspector.actor.hide();
|
||||||
|
|
||||||
@ -896,7 +874,7 @@ const LookingGlass = new Lang.Class({
|
|||||||
toolbar.add_actor(inspectIcon);
|
toolbar.add_actor(inspectIcon);
|
||||||
inspectIcon.reactive = true;
|
inspectIcon.reactive = true;
|
||||||
inspectIcon.connect('button-press-event', Lang.bind(this, function () {
|
inspectIcon.connect('button-press-event', Lang.bind(this, function () {
|
||||||
let inspector = new Inspector();
|
let inspector = new Inspector(this);
|
||||||
inspector.connect('target', Lang.bind(this, function(i, target, stageX, stageY) {
|
inspector.connect('target', Lang.bind(this, function(i, target, stageX, stageY) {
|
||||||
this._pushResult('<inspect x:' + stageX + ' y:' + stageY + '>',
|
this._pushResult('<inspect x:' + stageX + ' y:' + stageY + '>',
|
||||||
target);
|
target);
|
||||||
@ -926,23 +904,16 @@ const LookingGlass = new Lang.Class({
|
|||||||
this._entryArea = new St.BoxLayout({ name: 'EntryArea' });
|
this._entryArea = new St.BoxLayout({ name: 'EntryArea' });
|
||||||
this._evalBox.add_actor(this._entryArea);
|
this._evalBox.add_actor(this._entryArea);
|
||||||
|
|
||||||
let label = new St.Label({ text: 'js>>> ' });
|
let label = new St.Label({ text: CHEVRON });
|
||||||
this._entryArea.add(label);
|
this._entryArea.add(label);
|
||||||
|
|
||||||
this._entry = new St.Entry({ can_focus: true });
|
this._entry = new St.Entry({ can_focus: true });
|
||||||
ShellEntry.addContextMenu(this._entry);
|
ShellEntry.addContextMenu(this._entry);
|
||||||
this._entryArea.add(this._entry, { expand: true });
|
this._entryArea.add(this._entry, { expand: true });
|
||||||
|
|
||||||
this._windowList = new WindowList();
|
this._windowList = new WindowList(this);
|
||||||
this._windowList.connect('selected', Lang.bind(this, function(list, window) {
|
|
||||||
notebook.selectIndex(0);
|
|
||||||
this._pushResult('<window selection>', window);
|
|
||||||
}));
|
|
||||||
notebook.appendPage('Windows', this._windowList.actor);
|
notebook.appendPage('Windows', this._windowList.actor);
|
||||||
|
|
||||||
this._errorLog = new ErrorLog();
|
|
||||||
notebook.appendPage('Errors', this._errorLog.actor);
|
|
||||||
|
|
||||||
this._memory = new Memory();
|
this._memory = new Memory();
|
||||||
notebook.appendPage('Memory', this._memory.actor);
|
notebook.appendPage('Memory', this._memory.actor);
|
||||||
|
|
||||||
@ -994,23 +965,22 @@ const LookingGlass = new Lang.Class({
|
|||||||
+ 'font-family: "' + fontDesc.get_family() + '";';
|
+ 'font-family: "' + fontDesc.get_family() + '";';
|
||||||
},
|
},
|
||||||
|
|
||||||
|
setBorderPaintTarget: function(obj) {
|
||||||
|
if (this._borderPaintTarget != null)
|
||||||
|
this._borderPaintTarget.remove_effect(this._redBorderEffect);
|
||||||
|
this._borderPaintTarget = obj;
|
||||||
|
if (this._borderPaintTarget != null)
|
||||||
|
this._borderPaintTarget.add_effect(this._redBorderEffect);
|
||||||
|
},
|
||||||
|
|
||||||
_pushResult: function(command, obj) {
|
_pushResult: function(command, obj) {
|
||||||
let index = this._results.length + this._offset;
|
let index = this._results.length + this._offset;
|
||||||
let result = new Result('>>> ' + command, obj, index);
|
let result = new Result(this, CHEVRON + command, obj, index);
|
||||||
this._results.push(result);
|
this._results.push(result);
|
||||||
this._resultsArea.add(result.actor);
|
this._resultsArea.add(result.actor);
|
||||||
if (this._borderPaintTarget != null) {
|
if (obj instanceof Clutter.Actor)
|
||||||
this._borderPaintTarget.disconnect(this._borderPaintId);
|
this.setBorderPaintTarget(obj);
|
||||||
this._borderPaintTarget = null;
|
|
||||||
}
|
|
||||||
if (obj instanceof Clutter.Actor) {
|
|
||||||
this._borderPaintTarget = obj;
|
|
||||||
this._borderPaintId = addBorderPaintHook(obj);
|
|
||||||
this._borderDestroyId = obj.connect('destroy', Lang.bind(this, function () {
|
|
||||||
this._borderDestroyId = 0;
|
|
||||||
this._borderPaintTarget = null;
|
|
||||||
}));
|
|
||||||
}
|
|
||||||
let children = this._resultsArea.get_children();
|
let children = this._resultsArea.get_children();
|
||||||
if (children.length > this._maxItems) {
|
if (children.length > this._maxItems) {
|
||||||
this._results.shift();
|
this._results.shift();
|
||||||
@ -1191,11 +1161,7 @@ const LookingGlass = new Lang.Class({
|
|||||||
this._open = false;
|
this._open = false;
|
||||||
Tweener.removeTweens(this.actor);
|
Tweener.removeTweens(this.actor);
|
||||||
|
|
||||||
if (this._borderPaintTarget != null) {
|
this.setBorderPaintTarget(null);
|
||||||
this._borderPaintTarget.disconnect(this._borderPaintId);
|
|
||||||
this._borderPaintTarget.disconnect(this._borderDestroyId);
|
|
||||||
this._borderPaintTarget = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
Main.popModal(this._entry);
|
Main.popModal(this._entry);
|
||||||
|
|
||||||
|
@ -16,6 +16,7 @@ const Params = imports.misc.params;
|
|||||||
|
|
||||||
const MOUSE_POLL_FREQUENCY = 50;
|
const MOUSE_POLL_FREQUENCY = 50;
|
||||||
const CROSSHAIRS_CLIP_SIZE = [100, 100];
|
const CROSSHAIRS_CLIP_SIZE = [100, 100];
|
||||||
|
const NO_CHANGE = 0.0;
|
||||||
|
|
||||||
// Settings
|
// Settings
|
||||||
const APPLICATIONS_SCHEMA = 'org.gnome.desktop.a11y.applications';
|
const APPLICATIONS_SCHEMA = 'org.gnome.desktop.a11y.applications';
|
||||||
@ -24,6 +25,14 @@ const SHOW_KEY = 'screen-magnifier-enabled';
|
|||||||
const MAGNIFIER_SCHEMA = 'org.gnome.desktop.a11y.magnifier';
|
const MAGNIFIER_SCHEMA = 'org.gnome.desktop.a11y.magnifier';
|
||||||
const SCREEN_POSITION_KEY = 'screen-position';
|
const SCREEN_POSITION_KEY = 'screen-position';
|
||||||
const MAG_FACTOR_KEY = 'mag-factor';
|
const MAG_FACTOR_KEY = 'mag-factor';
|
||||||
|
const INVERT_LIGHTNESS_KEY = 'invert-lightness';
|
||||||
|
const COLOR_SATURATION_KEY = 'color-saturation';
|
||||||
|
const BRIGHT_RED_KEY = 'brightness-red';
|
||||||
|
const BRIGHT_GREEN_KEY = 'brightness-green';
|
||||||
|
const BRIGHT_BLUE_KEY = 'brightness-blue';
|
||||||
|
const CONTRAST_RED_KEY = 'contrast-red';
|
||||||
|
const CONTRAST_GREEN_KEY = 'contrast-green';
|
||||||
|
const CONTRAST_BLUE_KEY = 'contrast-blue';
|
||||||
const LENS_MODE_KEY = 'lens-mode';
|
const LENS_MODE_KEY = 'lens-mode';
|
||||||
const CLAMP_MODE_KEY = 'scroll-at-edges';
|
const CLAMP_MODE_KEY = 'scroll-at-edges';
|
||||||
const MOUSE_TRACKING_KEY = 'mouse-tracking';
|
const MOUSE_TRACKING_KEY = 'mouse-tracking';
|
||||||
@ -443,6 +452,25 @@ const Magnifier = new Lang.Class({
|
|||||||
aPref = this._settings.get_enum(MOUSE_TRACKING_KEY);
|
aPref = this._settings.get_enum(MOUSE_TRACKING_KEY);
|
||||||
if (aPref)
|
if (aPref)
|
||||||
zoomRegion.setMouseTrackingMode(aPref);
|
zoomRegion.setMouseTrackingMode(aPref);
|
||||||
|
|
||||||
|
aPref = this._settings.get_boolean(INVERT_LIGHTNESS_KEY);
|
||||||
|
if (aPref)
|
||||||
|
zoomRegion.setInvertLightness(aPref);
|
||||||
|
|
||||||
|
aPref = this._settings.get_double(COLOR_SATURATION_KEY);
|
||||||
|
if (aPref)
|
||||||
|
zoomRegion.setColorSaturation(aPref);
|
||||||
|
|
||||||
|
let bc = {};
|
||||||
|
bc.r = this._settings.get_double(BRIGHT_RED_KEY);
|
||||||
|
bc.g = this._settings.get_double(BRIGHT_GREEN_KEY);
|
||||||
|
bc.b = this._settings.get_double(BRIGHT_BLUE_KEY);
|
||||||
|
zoomRegion.setBrightness(bc);
|
||||||
|
|
||||||
|
bc.r = this._settings.get_double(CONTRAST_RED_KEY);
|
||||||
|
bc.g = this._settings.get_double(CONTRAST_GREEN_KEY);
|
||||||
|
bc.b = this._settings.get_double(CONTRAST_BLUE_KEY);
|
||||||
|
zoomRegion.setContrast(bc);
|
||||||
}
|
}
|
||||||
|
|
||||||
let showCrosshairs = this._settings.get_boolean(SHOW_CROSS_HAIRS_KEY);
|
let showCrosshairs = this._settings.get_boolean(SHOW_CROSS_HAIRS_KEY);
|
||||||
@ -465,6 +493,25 @@ const Magnifier = new Lang.Class({
|
|||||||
this._settings.connect('changed::' + MOUSE_TRACKING_KEY,
|
this._settings.connect('changed::' + MOUSE_TRACKING_KEY,
|
||||||
Lang.bind(this, this._updateMouseTrackingMode));
|
Lang.bind(this, this._updateMouseTrackingMode));
|
||||||
|
|
||||||
|
this._settings.connect('changed::' + INVERT_LIGHTNESS_KEY,
|
||||||
|
Lang.bind(this, this._updateInvertLightness));
|
||||||
|
this._settings.connect('changed::' + COLOR_SATURATION_KEY,
|
||||||
|
Lang.bind(this, this._updateColorSaturation));
|
||||||
|
|
||||||
|
this._settings.connect('changed::' + BRIGHT_RED_KEY,
|
||||||
|
Lang.bind(this, this._updateBrightness));
|
||||||
|
this._settings.connect('changed::' + BRIGHT_GREEN_KEY,
|
||||||
|
Lang.bind(this, this._updateBrightness));
|
||||||
|
this._settings.connect('changed::' + BRIGHT_BLUE_KEY,
|
||||||
|
Lang.bind(this, this._updateBrightness));
|
||||||
|
|
||||||
|
this._settings.connect('changed::' + CONTRAST_RED_KEY,
|
||||||
|
Lang.bind(this, this._updateContrast));
|
||||||
|
this._settings.connect('changed::' + CONTRAST_GREEN_KEY,
|
||||||
|
Lang.bind(this, this._updateContrast));
|
||||||
|
this._settings.connect('changed::' + CONTRAST_BLUE_KEY,
|
||||||
|
Lang.bind(this, this._updateContrast));
|
||||||
|
|
||||||
this._settings.connect('changed::' + SHOW_CROSS_HAIRS_KEY,
|
this._settings.connect('changed::' + SHOW_CROSS_HAIRS_KEY,
|
||||||
Lang.bind(this, function() {
|
Lang.bind(this, function() {
|
||||||
this.setCrosshairsVisible(this._settings.get_boolean(SHOW_CROSS_HAIRS_KEY));
|
this.setCrosshairsVisible(this._settings.get_boolean(SHOW_CROSS_HAIRS_KEY));
|
||||||
@ -540,7 +587,47 @@ const Magnifier = new Lang.Class({
|
|||||||
this._settings.get_enum(MOUSE_TRACKING_KEY)
|
this._settings.get_enum(MOUSE_TRACKING_KEY)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
_updateInvertLightness: function() {
|
||||||
|
// Applies only to the first zoom region.
|
||||||
|
if (this._zoomRegions.length) {
|
||||||
|
this._zoomRegions[0].setInvertLightness(
|
||||||
|
this._settings.get_boolean(INVERT_LIGHTNESS_KEY)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
_updateColorSaturation: function() {
|
||||||
|
// Applies only to the first zoom region.
|
||||||
|
if (this._zoomRegions.length) {
|
||||||
|
this._zoomRegions[0].setColorSaturation(
|
||||||
|
this._settings.get_boolean(COLOR_SATURATION_KEY)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
_updateBrightness: function() {
|
||||||
|
// Applies only to the first zoom region.
|
||||||
|
if (this._zoomRegions.length) {
|
||||||
|
let brightness = {};
|
||||||
|
brightness.r = this._settings.get_double(BRIGHT_RED_KEY);
|
||||||
|
brightness.g = this._settings.get_double(BRIGHT_GREEN_KEY);
|
||||||
|
brightness.b = this._settings.get_double(BRIGHT_BLUE_KEY);
|
||||||
|
this._zoomRegions[0].setBrightness(brightness);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
_updateContrast: function() {
|
||||||
|
// Applies only to the first zoom region.
|
||||||
|
if (this._zoomRegions.length) {
|
||||||
|
let contrast = {};
|
||||||
|
contrast.r = this._settings.get_double(CONTRAST_RED_KEY);
|
||||||
|
contrast.g = this._settings.get_double(CONTRAST_GREEN_KEY);
|
||||||
|
contrast.b = this._settings.get_double(CONTRAST_BLUE_KEY);
|
||||||
|
this._zoomRegions[0].setContrast(contrast);
|
||||||
|
}
|
||||||
|
},
|
||||||
});
|
});
|
||||||
Signals.addSignalMethods(Magnifier.prototype);
|
Signals.addSignalMethods(Magnifier.prototype);
|
||||||
|
|
||||||
@ -554,6 +641,10 @@ const ZoomRegion = new Lang.Class({
|
|||||||
this._clampScrollingAtEdges = false;
|
this._clampScrollingAtEdges = false;
|
||||||
this._lensMode = false;
|
this._lensMode = false;
|
||||||
this._screenPosition = GDesktopEnums.MagnifierScreenPosition.FULL_SCREEN;
|
this._screenPosition = GDesktopEnums.MagnifierScreenPosition.FULL_SCREEN;
|
||||||
|
this._invertLightness = false;
|
||||||
|
this._colorSaturation = 1.0;
|
||||||
|
this._brightness = { r: NO_CHANGE, g: NO_CHANGE, b: NO_CHANGE };
|
||||||
|
this._contrast = { r: NO_CHANGE, g: NO_CHANGE, b: NO_CHANGE };
|
||||||
|
|
||||||
this._magView = null;
|
this._magView = null;
|
||||||
this._background = null;
|
this._background = null;
|
||||||
@ -879,6 +970,107 @@ const ZoomRegion = new Lang.Class({
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* setInvertLightness:
|
||||||
|
* Set whether to invert the lightness of the magnified view.
|
||||||
|
* @flag Boolean to either invert brightness (true), or not (false).
|
||||||
|
*/
|
||||||
|
setInvertLightness: function(flag) {
|
||||||
|
this._invertLightness = flag;
|
||||||
|
if (this._magShaderEffects)
|
||||||
|
this._magShaderEffects.setInvertLightness(this._invertLightness);
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* getInvertLightness:
|
||||||
|
* Retrieve whether the lightness is inverted.
|
||||||
|
* @return Boolean indicating inversion (true), or not (false).
|
||||||
|
*/
|
||||||
|
getInvertLightness: function() {
|
||||||
|
return this._invertLightness;
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* setColorSaturation:
|
||||||
|
* Set the color saturation of the magnified view.
|
||||||
|
* @sauration A value from 0.0 to 1.0 that defines the color
|
||||||
|
* saturation, with 0.0 defining no color (grayscale),
|
||||||
|
* and 1.0 defining full color.
|
||||||
|
*/
|
||||||
|
setColorSaturation: function(saturation) {
|
||||||
|
this._colorSaturation = saturation;
|
||||||
|
if (this._magShaderEffects)
|
||||||
|
this._magShaderEffects.setColorSaturation(this._colorSaturation);
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* getColorSaturation:
|
||||||
|
* Retrieve the color saturation of the magnified view.
|
||||||
|
*/
|
||||||
|
getColorSaturation: function() {
|
||||||
|
return this._colorSaturation;
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* setBrightness:
|
||||||
|
* Alter the brightness of the magnified view.
|
||||||
|
* @brightness Object containing the contrast for the red, green,
|
||||||
|
* and blue channels. Values of 0.0 represent "standard"
|
||||||
|
* brightness (no change), whereas values less or greater than
|
||||||
|
* 0.0 indicate decreased or incresaed brightness, respectively.
|
||||||
|
*/
|
||||||
|
setBrightness: function(brightness) {
|
||||||
|
this._brightness.r = brightness.r;
|
||||||
|
this._brightness.g = brightness.g;
|
||||||
|
this._brightness.b = brightness.b;
|
||||||
|
if (this._magShaderEffects)
|
||||||
|
this._magShaderEffects.setBrightness(this._brightness);
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* getBrightness:
|
||||||
|
* Retrive the current brightness of the Zoom Region.
|
||||||
|
* @return Object containing the brightness change for the red, green,
|
||||||
|
* and blue channels.
|
||||||
|
*/
|
||||||
|
getBrightness: function() {
|
||||||
|
let brightness = {};
|
||||||
|
brightness.r = this._brightness.r;
|
||||||
|
brightness.g = this._brightness.g;
|
||||||
|
brightness.b = this._brightness.b;
|
||||||
|
return brightness;
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* setContrast:
|
||||||
|
* Alter the contrast of the magnified view.
|
||||||
|
* @contrast Object containing the contrast for the red, green,
|
||||||
|
* and blue channels. Values of 0.0 represent "standard"
|
||||||
|
* contrast (no change), whereas values less or greater than
|
||||||
|
* 0.0 indicate decreased or incresaed contrast, respectively.
|
||||||
|
*/
|
||||||
|
setContrast: function(contrast) {
|
||||||
|
this._contrast.r = contrast.r;
|
||||||
|
this._contrast.g = contrast.g;
|
||||||
|
this._contrast.b = contrast.b;
|
||||||
|
if (this._magShaderEffects)
|
||||||
|
this._magShaderEffects.setContrast(this._contrast);
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* getContrast:
|
||||||
|
* Retreive the contrast of the magnified view.
|
||||||
|
* @return Object containing the contrast for the red, green,
|
||||||
|
* and blue channels.
|
||||||
|
*/
|
||||||
|
getContrast: function() {
|
||||||
|
let contrast = {};
|
||||||
|
contrast.r = this._contrast.r;
|
||||||
|
contrast.g = this._contrast.g;
|
||||||
|
contrast.b = this._contrast.b;
|
||||||
|
return contrast;
|
||||||
|
},
|
||||||
|
|
||||||
//// Private methods ////
|
//// Private methods ////
|
||||||
|
|
||||||
_createActors: function() {
|
_createActors: function() {
|
||||||
@ -917,6 +1109,13 @@ const ZoomRegion = new Lang.Class({
|
|||||||
this._crossHairsActor = this._crossHairs.addToZoomRegion(this, this._mouseActor);
|
this._crossHairsActor = this._crossHairs.addToZoomRegion(this, this._mouseActor);
|
||||||
else
|
else
|
||||||
this._crossHairsActor = null;
|
this._crossHairsActor = null;
|
||||||
|
|
||||||
|
// Contrast and brightness effects.
|
||||||
|
this._magShaderEffects = new MagShaderEffects(this._uiGroupClone);
|
||||||
|
this._magShaderEffects.setColorSaturation(this._colorSaturation);
|
||||||
|
this._magShaderEffects.setInvertLightness(this._invertLightness);
|
||||||
|
this._magShaderEffects.setBrightness(this._brightness);
|
||||||
|
this._magShaderEffects.setContrast(this._contrast);
|
||||||
},
|
},
|
||||||
|
|
||||||
_destroyActors: function() {
|
_destroyActors: function() {
|
||||||
@ -925,6 +1124,8 @@ const ZoomRegion = new Lang.Class({
|
|||||||
if (this._crossHairs)
|
if (this._crossHairs)
|
||||||
this._crossHairs.removeFromParent(this._crossHairsActor);
|
this._crossHairs.removeFromParent(this._crossHairsActor);
|
||||||
|
|
||||||
|
this._magShaderEffects.destroyEffects();
|
||||||
|
this._magShaderEffects = null;
|
||||||
this._magView.destroy();
|
this._magView.destroy();
|
||||||
this._magView = null;
|
this._magView = null;
|
||||||
this._background = null;
|
this._background = null;
|
||||||
@ -1228,10 +1429,7 @@ const Crosshairs = new Lang.Class({
|
|||||||
crosshairsActor = new Clutter.Clone({ source: this._actor });
|
crosshairsActor = new Clutter.Clone({ source: this._actor });
|
||||||
this._clones.push(crosshairsActor);
|
this._clones.push(crosshairsActor);
|
||||||
}
|
}
|
||||||
if (this._actor.visible)
|
crosshairsActor.visible = this._actor.visible;
|
||||||
crosshairsActor.show();
|
|
||||||
else
|
|
||||||
crosshairsActor.hide();
|
|
||||||
|
|
||||||
container.add_actor(crosshairsActor);
|
container.add_actor(crosshairsActor);
|
||||||
container.raise_child(magnifiedMouse, crosshairsActor);
|
container.raise_child(magnifiedMouse, crosshairsActor);
|
||||||
@ -1436,3 +1634,144 @@ const Crosshairs = new Lang.Class({
|
|||||||
this._vertBottomHair.set_position((groupWidth - thickness) / 2, bottom);
|
this._vertBottomHair.set_position((groupWidth - thickness) / 2, bottom);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const MagShaderEffects = new Lang.Class({
|
||||||
|
Name: 'MagShaderEffects',
|
||||||
|
|
||||||
|
_init: function(uiGroupClone) {
|
||||||
|
this._inverse = new Shell.InvertLightnessEffect();
|
||||||
|
this._brightnessContrast = new Clutter.BrightnessContrastEffect();
|
||||||
|
this._colorSaturation = new Clutter.DesaturateEffect();
|
||||||
|
this._inverse.set_enabled(false);
|
||||||
|
this._brightnessContrast.set_enabled(false);
|
||||||
|
|
||||||
|
this._magView = uiGroupClone;
|
||||||
|
this._magView.add_effect(this._inverse);
|
||||||
|
this._magView.add_effect(this._brightnessContrast);
|
||||||
|
this._magView.add_effect(this._colorSaturation);
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* destroyEffects:
|
||||||
|
* Remove contrast and brightness effects from the magnified view, and
|
||||||
|
* lose the reference to the actor they were applied to. Don't use this
|
||||||
|
* object after calling this.
|
||||||
|
*/
|
||||||
|
destroyEffects: function() {
|
||||||
|
this._magView.clear_effects();
|
||||||
|
this._colorSaturation = null;
|
||||||
|
this._brightnessContrast = null;
|
||||||
|
this._inverse = null;
|
||||||
|
this._magView = null;
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* setInvertLightness:
|
||||||
|
* Enable/disable invert lightness effect.
|
||||||
|
* @invertFlag: Enabled flag.
|
||||||
|
*/
|
||||||
|
setInvertLightness: function(invertFlag) {
|
||||||
|
this._inverse.set_enabled(invertFlag);
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* getInvertLightness:
|
||||||
|
* Report whether the inversion effect is enabled.
|
||||||
|
* @return: Boolean.
|
||||||
|
*/
|
||||||
|
getInvertLightness: function() {
|
||||||
|
return this._inverse.get_enabled();
|
||||||
|
},
|
||||||
|
|
||||||
|
setColorSaturation: function(factor) {
|
||||||
|
this._colorSaturation.set_factor(factor);
|
||||||
|
},
|
||||||
|
|
||||||
|
getColorSaturation: function() {
|
||||||
|
return this._colorSaturation.get_factor();
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* setBrightness:
|
||||||
|
* Set the brightness of the magnified view.
|
||||||
|
* @brightness: Object containing the brightness for the red, green,
|
||||||
|
* and blue channels. Values of 0.0 represent "standard"
|
||||||
|
* brightness (no change), whereas values less or greater than
|
||||||
|
* 0.0 indicate decreased or incresaed brightness,
|
||||||
|
* respectively.
|
||||||
|
*/
|
||||||
|
setBrightness: function(brightness) {
|
||||||
|
let bRed = brightness.r;
|
||||||
|
let bGreen = brightness.g;
|
||||||
|
let bBlue = brightness.b;
|
||||||
|
this._brightnessContrast.set_brightness_full(bRed, bGreen, bBlue);
|
||||||
|
|
||||||
|
// Enable the effect if the brightness OR contrast change are such that
|
||||||
|
// it modifies the brightness and/or contrast.
|
||||||
|
let [cRed, cGreen, cBlue] = this._brightnessContrast.get_contrast();
|
||||||
|
this._brightnessContrast.set_enabled(
|
||||||
|
(bRed != NO_CHANGE || bGreen != NO_CHANGE || bBlue != NO_CHANGE ||
|
||||||
|
cRed != NO_CHANGE || cGreen != NO_CHANGE || cBlue != NO_CHANGE)
|
||||||
|
);
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* getBrightness:
|
||||||
|
* Retrieve current brightness of the magnified view.
|
||||||
|
* @return: Object containing the brightness for the red, green,
|
||||||
|
* and blue channels. Values of 0.0 represent "standard"
|
||||||
|
* brightness (no change), whereas values less or greater than
|
||||||
|
* 0.0 indicate decreased or incresaed brightness, respectively.
|
||||||
|
*/
|
||||||
|
getBrightness: function() {
|
||||||
|
let result = {};
|
||||||
|
let [bRed, bGreen, bBlue] = this._brightnessContrast.get_brightness();
|
||||||
|
result.r = bRed;
|
||||||
|
result.g = bGreen;
|
||||||
|
result.b = bBlue;
|
||||||
|
|
||||||
|
return result;
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the contrast of the magnified view.
|
||||||
|
* @contrast: Object containing the contrast for the red, green,
|
||||||
|
* and blue channels. Values of 0.0 represent "standard"
|
||||||
|
* contrast (no change), whereas values less or greater than
|
||||||
|
* 0.0 indicate decreased or incresaed contrast, respectively.
|
||||||
|
*/
|
||||||
|
setContrast: function(contrast) {
|
||||||
|
let cRed = contrast.r;
|
||||||
|
let cGreen = contrast.g;
|
||||||
|
let cBlue = contrast.b;
|
||||||
|
|
||||||
|
this._brightnessContrast.set_contrast_full(cRed, cGreen, cBlue);
|
||||||
|
|
||||||
|
// Enable the effect if the contrast OR brightness change are such that
|
||||||
|
// it modifies the brightness and/or contrast.
|
||||||
|
// should be able to use Clutter.color_equal(), but that complains of
|
||||||
|
// a null first argument.
|
||||||
|
let [bRed, bGreen, bBlue] = this._brightnessContrast.get_brightness();
|
||||||
|
this._brightnessContrast.set_enabled(
|
||||||
|
cRed != NO_CHANGE || cGreen != NO_CHANGE || cBlue != NO_CHANGE ||
|
||||||
|
bRed != NO_CHANGE || bGreen != NO_CHANGE || bBlue != NO_CHANGE
|
||||||
|
);
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieve current contrast of the magnified view.
|
||||||
|
* @return: Object containing the contrast for the red, green,
|
||||||
|
* and blue channels. Values of 0.0 represent "standard"
|
||||||
|
* contrast (no change), whereas values less or greater than
|
||||||
|
* 0.0 indicate decreased or incresaed contrast, respectively.
|
||||||
|
*/
|
||||||
|
getContrast: function() {
|
||||||
|
let resutl = {};
|
||||||
|
let [cRed, cGreen, cBlue] = this._brightnessContrast.get_contrast();
|
||||||
|
result.r = cRed;
|
||||||
|
result.g = cGreen;
|
||||||
|
result.b = cBlue;
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
210
js/ui/main.js
210
js/ui/main.js
@ -18,6 +18,7 @@ const PolkitAuthenticationAgent = imports.ui.polkitAuthenticationAgent;
|
|||||||
const KeyringPrompt = imports.ui.keyringPrompt;
|
const KeyringPrompt = imports.ui.keyringPrompt;
|
||||||
const Environment = imports.ui.environment;
|
const Environment = imports.ui.environment;
|
||||||
const ExtensionSystem = imports.ui.extensionSystem;
|
const ExtensionSystem = imports.ui.extensionSystem;
|
||||||
|
const ExtensionDownloader = imports.ui.extensionDownloader;
|
||||||
const Keyboard = imports.ui.keyboard;
|
const Keyboard = imports.ui.keyboard;
|
||||||
const MessageTray = imports.ui.messageTray;
|
const MessageTray = imports.ui.messageTray;
|
||||||
const Overview = imports.ui.overview;
|
const Overview = imports.ui.overview;
|
||||||
@ -29,9 +30,10 @@ const LookingGlass = imports.ui.lookingGlass;
|
|||||||
const NetworkAgent = imports.ui.networkAgent;
|
const NetworkAgent = imports.ui.networkAgent;
|
||||||
const NotificationDaemon = imports.ui.notificationDaemon;
|
const NotificationDaemon = imports.ui.notificationDaemon;
|
||||||
const WindowAttentionHandler = imports.ui.windowAttentionHandler;
|
const WindowAttentionHandler = imports.ui.windowAttentionHandler;
|
||||||
const ScreenShield = imports.ui.screenShield;
|
|
||||||
const Scripting = imports.ui.scripting;
|
const Scripting = imports.ui.scripting;
|
||||||
|
const SessionMode = imports.ui.sessionMode;
|
||||||
const ShellDBus = imports.ui.shellDBus;
|
const ShellDBus = imports.ui.shellDBus;
|
||||||
|
const ShellMountOperation = imports.ui.shellMountOperation;
|
||||||
const TelepathyClient = imports.ui.telepathyClient;
|
const TelepathyClient = imports.ui.telepathyClient;
|
||||||
const WindowManager = imports.ui.windowManager;
|
const WindowManager = imports.ui.windowManager;
|
||||||
const Magnifier = imports.ui.magnifier;
|
const Magnifier = imports.ui.magnifier;
|
||||||
@ -47,19 +49,19 @@ let automountManager = null;
|
|||||||
let autorunManager = null;
|
let autorunManager = null;
|
||||||
let panel = null;
|
let panel = null;
|
||||||
let hotCorners = [];
|
let hotCorners = [];
|
||||||
let placesManager = null;
|
|
||||||
let overview = null;
|
let overview = null;
|
||||||
let runDialog = null;
|
let runDialog = null;
|
||||||
let lookingGlass = null;
|
let lookingGlass = null;
|
||||||
let wm = null;
|
let wm = null;
|
||||||
let messageTray = null;
|
let messageTray = null;
|
||||||
let screenShield = null;
|
|
||||||
let notificationDaemon = null;
|
let notificationDaemon = null;
|
||||||
let windowAttentionHandler = null;
|
let windowAttentionHandler = null;
|
||||||
let telepathyClient = null;
|
let telepathyClient = null;
|
||||||
let ctrlAltTabManager = null;
|
let ctrlAltTabManager = null;
|
||||||
let recorder = null;
|
let recorder = null;
|
||||||
|
let sessionMode = null;
|
||||||
let shellDBusService = null;
|
let shellDBusService = null;
|
||||||
|
let shellMountOpDBusService = null;
|
||||||
let modalCount = 0;
|
let modalCount = 0;
|
||||||
let modalActorFocusStack = [];
|
let modalActorFocusStack = [];
|
||||||
let uiGroup = null;
|
let uiGroup = null;
|
||||||
@ -69,28 +71,27 @@ let statusIconDispatcher = null;
|
|||||||
let keyboard = null;
|
let keyboard = null;
|
||||||
let layoutManager = null;
|
let layoutManager = null;
|
||||||
let networkAgent = null;
|
let networkAgent = null;
|
||||||
let _errorLogStack = [];
|
|
||||||
let _startDate;
|
let _startDate;
|
||||||
let _defaultCssStylesheet = null;
|
let _defaultCssStylesheet = null;
|
||||||
let _cssStylesheet = null;
|
let _cssStylesheet = null;
|
||||||
let _gdmCssStylesheet = null;
|
|
||||||
let _overridesSettings = null;
|
let _overridesSettings = null;
|
||||||
|
|
||||||
let background = null;
|
let background = null;
|
||||||
|
|
||||||
function _createUserSession() {
|
function createUserSession() {
|
||||||
// Load the calendar server. Note that we are careful about
|
// Load the calendar server. Note that we are careful about
|
||||||
// not loading any events until the user presses the clock
|
// not loading any events until the user presses the clock
|
||||||
global.launch_calendar_server();
|
global.launch_calendar_server();
|
||||||
|
|
||||||
placesManager = new PlaceDisplay.PlacesManager();
|
|
||||||
telepathyClient = new TelepathyClient.Client();
|
telepathyClient = new TelepathyClient.Client();
|
||||||
automountManager = new AutomountManager.AutomountManager();
|
automountManager = new AutomountManager.AutomountManager();
|
||||||
autorunManager = new AutorunManager.AutorunManager();
|
autorunManager = new AutorunManager.AutorunManager();
|
||||||
networkAgent = new NetworkAgent.NetworkAgent();
|
networkAgent = new NetworkAgent.NetworkAgent();
|
||||||
|
|
||||||
|
_initRecorder();
|
||||||
}
|
}
|
||||||
|
|
||||||
function _createGDMSession() {
|
function createGDMSession() {
|
||||||
// We do this this here instead of at the top to prevent GDM
|
// We do this this here instead of at the top to prevent GDM
|
||||||
// related code from getting loaded in normal user sessions
|
// related code from getting loaded in normal user sessions
|
||||||
const LoginDialog = imports.gdm.loginDialog;
|
const LoginDialog = imports.gdm.loginDialog;
|
||||||
@ -101,18 +102,26 @@ function _createGDMSession() {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function createInitialSetupSession() {
|
||||||
|
networkAgent = new NetworkAgent.NetworkAgent();
|
||||||
|
}
|
||||||
|
|
||||||
function _initRecorder() {
|
function _initRecorder() {
|
||||||
let recorderSettings = new Gio.Settings({ schema: 'org.gnome.shell.recorder' });
|
let recorderSettings = new Gio.Settings({ schema: 'org.gnome.shell.recorder' });
|
||||||
|
let desktopLockdownSettings = new Gio.Settings({ schema: 'org.gnome.desktop.lockdown' });
|
||||||
|
let bindingSettings = new Gio.Settings({ schema: 'org.gnome.shell.keybindings' });
|
||||||
|
|
||||||
global.screen.connect('toggle-recording', function() {
|
global.display.add_keybinding('toggle-recording',
|
||||||
|
bindingSettings,
|
||||||
|
Meta.KeyBindingFlags.NONE, function() {
|
||||||
if (recorder == null) {
|
if (recorder == null) {
|
||||||
recorder = new Shell.Recorder({ stage: global.stage });
|
recorder = new Shell.Recorder({ stage: global.stage });
|
||||||
}
|
}
|
||||||
|
|
||||||
if (recorder.is_recording()) {
|
if (recorder.is_recording()) {
|
||||||
recorder.pause();
|
recorder.close();
|
||||||
Meta.enable_unredirect_for_screen(global.screen);
|
Meta.enable_unredirect_for_screen(global.screen);
|
||||||
} else {
|
} else if (!desktopLockdownSettings.get_boolean('disable-save-to-disk')) {
|
||||||
// read the parameters from GSettings always in case they have changed
|
// read the parameters from GSettings always in case they have changed
|
||||||
recorder.set_framerate(recorderSettings.get_int('framerate'));
|
recorder.set_framerate(recorderSettings.get_int('framerate'));
|
||||||
/* Translators: this is a filename used for screencast recording */
|
/* Translators: this is a filename used for screencast recording */
|
||||||
@ -131,39 +140,19 @@ function _initRecorder() {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function _initUserSession() {
|
|
||||||
_initRecorder();
|
|
||||||
|
|
||||||
global.screen.override_workspace_layout(Meta.ScreenCorner.TOPLEFT, false, -1, 1);
|
|
||||||
|
|
||||||
ExtensionSystem.init();
|
|
||||||
ExtensionSystem.loadExtensions();
|
|
||||||
|
|
||||||
Meta.keybindings_set_custom_handler('panel-run-dialog', function() {
|
|
||||||
getRunDialog().open();
|
|
||||||
});
|
|
||||||
|
|
||||||
Meta.keybindings_set_custom_handler('panel-main-menu', function () {
|
|
||||||
overview.toggle();
|
|
||||||
});
|
|
||||||
|
|
||||||
global.display.connect('overlay-key', Lang.bind(overview, overview.toggle));
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
function start() {
|
function start() {
|
||||||
// Monkey patch utility functions into the global proxy;
|
// These are here so we don't break compatibility.
|
||||||
// This is easier and faster than indirecting down into global
|
global.logError = window.log;
|
||||||
// if we want to call back up into JS.
|
global.log = window.log;
|
||||||
global.logError = _logError;
|
|
||||||
global.log = _logDebug;
|
|
||||||
|
|
||||||
// Chain up async errors reported from C
|
// Chain up async errors reported from C
|
||||||
global.connect('notify-error', function (global, msg, detail) { notifyError(msg, detail); });
|
global.connect('notify-error', function (global, msg, detail) { notifyError(msg, detail); });
|
||||||
|
|
||||||
Gio.DesktopAppInfo.set_desktop_env('GNOME');
|
Gio.DesktopAppInfo.set_desktop_env('GNOME');
|
||||||
|
|
||||||
|
sessionMode = new SessionMode.SessionMode();
|
||||||
shellDBusService = new ShellDBus.GnomeShell();
|
shellDBusService = new ShellDBus.GnomeShell();
|
||||||
|
shellMountOpDBusService = new ShellMountOperation.GnomeShellMountOpHandler();
|
||||||
|
|
||||||
// Ensure ShellWindowTracker and ShellAppUsage are initialized; this will
|
// Ensure ShellWindowTracker and ShellAppUsage are initialized; this will
|
||||||
// also initialize ShellAppSystem first. ShellAppSystem
|
// also initialize ShellAppSystem first. ShellAppSystem
|
||||||
@ -185,7 +174,6 @@ function start() {
|
|||||||
global.stage.no_clear_hint = true;
|
global.stage.no_clear_hint = true;
|
||||||
|
|
||||||
_defaultCssStylesheet = global.datadir + '/theme/gnome-shell.css';
|
_defaultCssStylesheet = global.datadir + '/theme/gnome-shell.css';
|
||||||
_gdmCssStylesheet = global.datadir + '/theme/gdm.css';
|
|
||||||
loadTheme();
|
loadTheme();
|
||||||
|
|
||||||
// Set up stage hierarchy to group all UI actors under one container.
|
// Set up stage hierarchy to group all UI actors under one container.
|
||||||
@ -196,9 +184,16 @@ function start() {
|
|||||||
for (let i = 0; i < children.length; i++)
|
for (let i = 0; i < children.length; i++)
|
||||||
children[i].allocate_preferred_size(flags);
|
children[i].allocate_preferred_size(flags);
|
||||||
});
|
});
|
||||||
let constraint = new Clutter.BindConstraint({ source: global.stage,
|
uiGroup.connect('get-preferred-width',
|
||||||
coordinate: Clutter.BindCoordinate.SIZE });
|
function(actor, forHeight, alloc) {
|
||||||
uiGroup.add_constraint(constraint);
|
let width = global.stage.width;
|
||||||
|
[alloc.min_size, alloc.natural_size] = [width, width];
|
||||||
|
});
|
||||||
|
uiGroup.connect('get-preferred-height',
|
||||||
|
function(actor, forWidth, alloc) {
|
||||||
|
let height = global.stage.height;
|
||||||
|
[alloc.min_size, alloc.natural_size] = [height, height];
|
||||||
|
});
|
||||||
global.window_group.reparent(uiGroup);
|
global.window_group.reparent(uiGroup);
|
||||||
global.overlay_group.reparent(uiGroup);
|
global.overlay_group.reparent(uiGroup);
|
||||||
global.stage.add_actor(uiGroup);
|
global.stage.add_actor(uiGroup);
|
||||||
@ -206,22 +201,17 @@ function start() {
|
|||||||
layoutManager = new Layout.LayoutManager();
|
layoutManager = new Layout.LayoutManager();
|
||||||
xdndHandler = new XdndHandler.XdndHandler();
|
xdndHandler = new XdndHandler.XdndHandler();
|
||||||
ctrlAltTabManager = new CtrlAltTab.CtrlAltTabManager();
|
ctrlAltTabManager = new CtrlAltTab.CtrlAltTabManager();
|
||||||
// This overview object is just a stub for non-user sessions
|
overview = new Overview.Overview();
|
||||||
overview = new Overview.Overview({ isDummy: global.session_type != Shell.SessionType.USER });
|
|
||||||
magnifier = new Magnifier.Magnifier();
|
magnifier = new Magnifier.Magnifier();
|
||||||
statusIconDispatcher = new StatusIconDispatcher.StatusIconDispatcher();
|
statusIconDispatcher = new StatusIconDispatcher.StatusIconDispatcher();
|
||||||
panel = new Panel.Panel();
|
panel = new Panel.Panel();
|
||||||
wm = new WindowManager.WindowManager();
|
wm = new WindowManager.WindowManager();
|
||||||
messageTray = new MessageTray.MessageTray();
|
messageTray = new MessageTray.MessageTray();
|
||||||
screenShield = new ScreenShield.ScreenShield();
|
|
||||||
keyboard = new Keyboard.Keyboard();
|
keyboard = new Keyboard.Keyboard();
|
||||||
notificationDaemon = new NotificationDaemon.NotificationDaemon();
|
notificationDaemon = new NotificationDaemon.NotificationDaemon();
|
||||||
windowAttentionHandler = new WindowAttentionHandler.WindowAttentionHandler();
|
windowAttentionHandler = new WindowAttentionHandler.WindowAttentionHandler();
|
||||||
|
|
||||||
if (global.session_type == Shell.SessionType.USER)
|
sessionMode.createSession();
|
||||||
_createUserSession();
|
|
||||||
else if (global.session_type == Shell.SessionType.GDM)
|
|
||||||
_createGDMSession();
|
|
||||||
|
|
||||||
panel.startStatusArea();
|
panel.startStatusArea();
|
||||||
|
|
||||||
@ -229,8 +219,30 @@ function start() {
|
|||||||
keyboard.init();
|
keyboard.init();
|
||||||
overview.init();
|
overview.init();
|
||||||
|
|
||||||
if (global.session_type == Shell.SessionType.USER)
|
if (sessionMode.hasWorkspaces)
|
||||||
_initUserSession();
|
global.screen.override_workspace_layout(Meta.ScreenCorner.TOPLEFT,
|
||||||
|
false, -1, 1);
|
||||||
|
|
||||||
|
if (sessionMode.allowExtensions) {
|
||||||
|
ExtensionDownloader.init();
|
||||||
|
ExtensionSystem.loadExtensions();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (sessionMode.hasRunDialog) {
|
||||||
|
Meta.keybindings_set_custom_handler('panel-run-dialog', function() {
|
||||||
|
getRunDialog().open();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (sessionMode.hasOverview) {
|
||||||
|
Meta.keybindings_set_custom_handler('panel-main-menu', function () {
|
||||||
|
overview.toggle();
|
||||||
|
});
|
||||||
|
|
||||||
|
global.display.connect('overlay-key',
|
||||||
|
Lang.bind(overview, overview.toggle));
|
||||||
|
}
|
||||||
|
|
||||||
statusIconDispatcher.start(messageTray.actor);
|
statusIconDispatcher.start(messageTray.actor);
|
||||||
|
|
||||||
// Provide the bus object for gnome-session to
|
// Provide the bus object for gnome-session to
|
||||||
@ -247,7 +259,6 @@ function start() {
|
|||||||
|
|
||||||
global.stage.connect('captured-event', _globalKeyPressHandler);
|
global.stage.connect('captured-event', _globalKeyPressHandler);
|
||||||
|
|
||||||
_log('info', 'loaded at ' + _startDate);
|
|
||||||
log('GNOME Shell started at ' + _startDate);
|
log('GNOME Shell started at ' + _startDate);
|
||||||
|
|
||||||
let perfModuleName = GLib.getenv("SHELL_PERF_MODULE");
|
let perfModuleName = GLib.getenv("SHELL_PERF_MODULE");
|
||||||
@ -490,8 +501,8 @@ function loadTheme() {
|
|||||||
|
|
||||||
let theme = new St.Theme ({ application_stylesheet: cssStylesheet });
|
let theme = new St.Theme ({ application_stylesheet: cssStylesheet });
|
||||||
|
|
||||||
if (global.session_type == Shell.SessionType.GDM)
|
if (sessionMode.extraStylesheet)
|
||||||
theme.load_stylesheet(_gdmCssStylesheet);
|
theme.load_stylesheet(sessionMode.extraStylesheet);
|
||||||
|
|
||||||
if (previousTheme) {
|
if (previousTheme) {
|
||||||
let customStylesheets = previousTheme.get_custom_stylesheets();
|
let customStylesheets = previousTheme.get_custom_stylesheets();
|
||||||
@ -533,59 +544,6 @@ function notifyError(msg, details) {
|
|||||||
notify(msg, details);
|
notify(msg, details);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* _log:
|
|
||||||
* @category: string message type ('info', 'error')
|
|
||||||
* @msg: A message string
|
|
||||||
* ...: Any further arguments are converted into JSON notation,
|
|
||||||
* and appended to the log message, separated by spaces.
|
|
||||||
*
|
|
||||||
* Log a message into the LookingGlass error
|
|
||||||
* stream. This is primarily intended for use by the
|
|
||||||
* extension system as well as debugging.
|
|
||||||
*/
|
|
||||||
function _log(category, msg) {
|
|
||||||
let text = msg;
|
|
||||||
if (arguments.length > 2) {
|
|
||||||
text += ': ';
|
|
||||||
for (let i = 2; i < arguments.length; i++) {
|
|
||||||
text += JSON.stringify(arguments[i]);
|
|
||||||
if (i < arguments.length - 1)
|
|
||||||
text += ' ';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
_errorLogStack.push({timestamp: new Date().getTime(),
|
|
||||||
category: category,
|
|
||||||
message: text });
|
|
||||||
}
|
|
||||||
|
|
||||||
function _logError(msg) {
|
|
||||||
return _log('error', msg);
|
|
||||||
}
|
|
||||||
|
|
||||||
function _logDebug(msg) {
|
|
||||||
return _log('debug', msg);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Used by the error display in lookingGlass.js
|
|
||||||
function _getAndClearErrorStack() {
|
|
||||||
let errors = _errorLogStack;
|
|
||||||
_errorLogStack = [];
|
|
||||||
return errors;
|
|
||||||
}
|
|
||||||
|
|
||||||
function logStackTrace(msg) {
|
|
||||||
try {
|
|
||||||
throw new Error();
|
|
||||||
} catch (e) {
|
|
||||||
// e.stack must have at least two lines, with the first being
|
|
||||||
// logStackTrace() (which we strip off), and the second being
|
|
||||||
// our caller.
|
|
||||||
let trace = e.stack.substr(e.stack.indexOf('\n') + 1);
|
|
||||||
log(msg ? (msg + '\n' + trace) : trace);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function isWindowActorDisplayedOnWorkspace(win, workspaceIndex) {
|
function isWindowActorDisplayedOnWorkspace(win, workspaceIndex) {
|
||||||
return win.get_workspace() == workspaceIndex ||
|
return win.get_workspace() == workspaceIndex ||
|
||||||
(win.get_meta_window() && win.get_meta_window().is_on_all_workspaces());
|
(win.get_meta_window() && win.get_meta_window().is_on_all_workspaces());
|
||||||
@ -608,6 +566,11 @@ function _globalKeyPressHandler(actor, event) {
|
|||||||
if (event.type() != Clutter.EventType.KEY_PRESS)
|
if (event.type() != Clutter.EventType.KEY_PRESS)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
if (!sessionMode.allowKeybindingsWhenModal) {
|
||||||
|
if (modalCount > (overview.visible ? 1 : 0))
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
let symbol = event.get_key_symbol();
|
let symbol = event.get_key_symbol();
|
||||||
let keyCode = event.get_key_code();
|
let keyCode = event.get_key_code();
|
||||||
let ignoredModifiers = global.display.get_ignored_modifier_mask();
|
let ignoredModifiers = global.display.get_ignored_modifier_mask();
|
||||||
@ -616,11 +579,6 @@ function _globalKeyPressHandler(actor, event) {
|
|||||||
// This relies on the fact that Clutter.ModifierType is the same as Gdk.ModifierType
|
// This relies on the fact that Clutter.ModifierType is the same as Gdk.ModifierType
|
||||||
let action = global.display.get_keybinding_action(keyCode, modifierState);
|
let action = global.display.get_keybinding_action(keyCode, modifierState);
|
||||||
|
|
||||||
// Other bindings are only available to the user session when the overview is up and
|
|
||||||
// no modal dialog is present.
|
|
||||||
if (global.session_type == Shell.SessionType.USER && (!overview.visible || modalCount > 1))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
// This isn't a Meta.KeyBindingAction yet
|
// This isn't a Meta.KeyBindingAction yet
|
||||||
if (symbol == Clutter.Super_L || symbol == Clutter.Super_R) {
|
if (symbol == Clutter.Super_L || symbol == Clutter.Super_R) {
|
||||||
overview.hide();
|
overview.hide();
|
||||||
@ -633,28 +591,39 @@ function _globalKeyPressHandler(actor, event) {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// None of the other bindings are relevant outside of the user's session
|
|
||||||
if (global.session_type != Shell.SessionType.USER)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
switch (action) {
|
switch (action) {
|
||||||
// left/right would effectively act as synonyms for up/down if we enabled them;
|
// left/right would effectively act as synonyms for up/down if we enabled them;
|
||||||
// but that could be considered confusing; we also disable them in the main view.
|
// but that could be considered confusing; we also disable them in the main view.
|
||||||
//
|
//
|
||||||
// case Meta.KeyBindingAction.WORKSPACE_LEFT:
|
// case Meta.KeyBindingAction.WORKSPACE_LEFT:
|
||||||
|
// if (!sessionMode.hasWorkspaces)
|
||||||
|
// return false;
|
||||||
|
//
|
||||||
// wm.actionMoveWorkspaceLeft();
|
// wm.actionMoveWorkspaceLeft();
|
||||||
// return true;
|
// return true;
|
||||||
// case Meta.KeyBindingAction.WORKSPACE_RIGHT:
|
// case Meta.KeyBindingAction.WORKSPACE_RIGHT:
|
||||||
|
// if (!sessionMode.hasWorkspaces)
|
||||||
|
// return false;
|
||||||
|
//
|
||||||
// wm.actionMoveWorkspaceRight();
|
// wm.actionMoveWorkspaceRight();
|
||||||
// return true;
|
// return true;
|
||||||
case Meta.KeyBindingAction.WORKSPACE_UP:
|
case Meta.KeyBindingAction.WORKSPACE_UP:
|
||||||
wm.actionMoveWorkspaceUp();
|
if (!sessionMode.hasWorkspaces)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
wm.actionMoveWorkspace(Meta.MotionDirection.UP);
|
||||||
return true;
|
return true;
|
||||||
case Meta.KeyBindingAction.WORKSPACE_DOWN:
|
case Meta.KeyBindingAction.WORKSPACE_DOWN:
|
||||||
wm.actionMoveWorkspaceDown();
|
if (!sessionMode.hasWorkspaces)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
wm.actionMoveWorkspace(Meta.MotionDirection.DOWN);
|
||||||
return true;
|
return true;
|
||||||
case Meta.KeyBindingAction.PANEL_RUN_DIALOG:
|
case Meta.KeyBindingAction.PANEL_RUN_DIALOG:
|
||||||
case Meta.KeyBindingAction.COMMAND_2:
|
case Meta.KeyBindingAction.COMMAND_2:
|
||||||
|
if (!sessionMode.hasRunDialog)
|
||||||
|
return false;
|
||||||
|
|
||||||
getRunDialog().open();
|
getRunDialog().open();
|
||||||
return true;
|
return true;
|
||||||
case Meta.KeyBindingAction.PANEL_MAIN_MENU:
|
case Meta.KeyBindingAction.PANEL_MAIN_MENU:
|
||||||
@ -673,10 +642,6 @@ function _findModal(actor) {
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
function isInModalStack(actor) {
|
|
||||||
return _findModal(actor) != -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* pushModal:
|
* pushModal:
|
||||||
* @actor: #ClutterActor which will be given keyboard focus
|
* @actor: #ClutterActor which will be given keyboard focus
|
||||||
@ -709,6 +674,7 @@ function pushModal(actor, timestamp, options) {
|
|||||||
log('pushModal: invocation of begin_modal failed');
|
log('pushModal: invocation of begin_modal failed');
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
Meta.disable_unredirect_for_screen(global.screen);
|
||||||
}
|
}
|
||||||
|
|
||||||
global.set_stage_input_mode(Shell.StageInputMode.FULLSCREEN);
|
global.set_stage_input_mode(Shell.StageInputMode.FULLSCREEN);
|
||||||
@ -789,6 +755,7 @@ function popModal(actor, timestamp) {
|
|||||||
|
|
||||||
global.end_modal(timestamp);
|
global.end_modal(timestamp);
|
||||||
global.set_stage_input_mode(Shell.StageInputMode.NORMAL);
|
global.set_stage_input_mode(Shell.StageInputMode.NORMAL);
|
||||||
|
Meta.enable_unredirect_for_screen(global.screen);
|
||||||
}
|
}
|
||||||
|
|
||||||
function createLookingGlass() {
|
function createLookingGlass() {
|
||||||
@ -931,7 +898,8 @@ function initializeDeferredWork(actor, callback, props) {
|
|||||||
function queueDeferredWork(workId) {
|
function queueDeferredWork(workId) {
|
||||||
let data = _deferredWorkData[workId];
|
let data = _deferredWorkData[workId];
|
||||||
if (!data) {
|
if (!data) {
|
||||||
global.logError('invalid work id ', workId);
|
let message = 'Invalid work id %d'.format(workId);
|
||||||
|
logError(new Error(message), message);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (_deferredWorkQueue.indexOf(workId) < 0)
|
if (_deferredWorkQueue.indexOf(workId) < 0)
|
||||||
|
@ -441,7 +441,7 @@ const Notification = new Lang.Class({
|
|||||||
this.actor.connect('clicked', Lang.bind(this, this._onClicked));
|
this.actor.connect('clicked', Lang.bind(this, this._onClicked));
|
||||||
this.actor.connect('destroy', Lang.bind(this, this._onDestroy));
|
this.actor.connect('destroy', Lang.bind(this, this._onDestroy));
|
||||||
|
|
||||||
this._table = new St.Table({ name: 'notification',
|
this._table = new St.Table({ style_class: 'notification',
|
||||||
reactive: true });
|
reactive: true });
|
||||||
this._table.connect('style-changed', Lang.bind(this, this._styleChanged));
|
this._table.connect('style-changed', Lang.bind(this, this._styleChanged));
|
||||||
this.actor.set_child(this._table);
|
this.actor.set_child(this._table);
|
||||||
@ -493,6 +493,7 @@ const Notification = new Lang.Class({
|
|||||||
params = Params.parse(params, { customContent: false,
|
params = Params.parse(params, { customContent: false,
|
||||||
body: null,
|
body: null,
|
||||||
icon: null,
|
icon: null,
|
||||||
|
secondaryIcon: null,
|
||||||
titleMarkup: false,
|
titleMarkup: false,
|
||||||
bannerMarkup: false,
|
bannerMarkup: false,
|
||||||
bodyMarkup: false,
|
bodyMarkup: false,
|
||||||
@ -507,6 +508,11 @@ const Notification = new Lang.Class({
|
|||||||
this._icon = null;
|
this._icon = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (this._secondaryIcon && (params.secondaryIcon || params.clear)) {
|
||||||
|
this._secondaryIcon.destroy();
|
||||||
|
this._secondaryIcon = null;
|
||||||
|
}
|
||||||
|
|
||||||
// We always clear the content area if we don't have custom
|
// We always clear the content area if we don't have custom
|
||||||
// content because it might contain the @banner that didn't
|
// content because it might contain the @banner that didn't
|
||||||
// fit in the banner mode.
|
// fit in the banner mode.
|
||||||
@ -542,6 +548,13 @@ const Notification = new Lang.Class({
|
|||||||
y_align: St.Align.START });
|
y_align: St.Align.START });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!this._secondaryIcon) {
|
||||||
|
this._secondaryIcon = params.secondaryIcon;
|
||||||
|
|
||||||
|
if (this._secondaryIcon)
|
||||||
|
this._bannerBox.add_actor(this._secondaryIcon);
|
||||||
|
}
|
||||||
|
|
||||||
this.title = title;
|
this.title = title;
|
||||||
title = title ? _fixMarkup(title.replace(/\n/g, ' '), params.titleMarkup) : '';
|
title = title ? _fixMarkup(title.replace(/\n/g, ' '), params.titleMarkup) : '';
|
||||||
this._titleLabel.clutter_text.set_markup('<b>' + title + '</b>');
|
this._titleLabel.clutter_text.set_markup('<b>' + title + '</b>');
|
||||||
@ -577,7 +590,7 @@ const Notification = new Lang.Class({
|
|||||||
|
|
||||||
if (params.body)
|
if (params.body)
|
||||||
this.addBody(params.body, params.bodyMarkup);
|
this.addBody(params.body, params.bodyMarkup);
|
||||||
this._updated();
|
this.updated();
|
||||||
},
|
},
|
||||||
|
|
||||||
setIconVisible: function(visible) {
|
setIconVisible: function(visible) {
|
||||||
@ -586,19 +599,21 @@ const Notification = new Lang.Class({
|
|||||||
|
|
||||||
enableScrolling: function(enableScrolling) {
|
enableScrolling: function(enableScrolling) {
|
||||||
this._scrollPolicy = enableScrolling ? Gtk.PolicyType.AUTOMATIC : Gtk.PolicyType.NEVER;
|
this._scrollPolicy = enableScrolling ? Gtk.PolicyType.AUTOMATIC : Gtk.PolicyType.NEVER;
|
||||||
if (this._scrollArea)
|
if (this._scrollArea) {
|
||||||
this._scrollArea.vscrollbar_policy = this._scrollPolicy;
|
this._scrollArea.vscrollbar_policy = this._scrollPolicy;
|
||||||
|
this._scrollArea.enable_mouse_scrolling = enableScrolling;
|
||||||
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
_createScrollArea: function() {
|
_createScrollArea: function() {
|
||||||
this._table.add_style_class_name('multi-line-notification');
|
this._table.add_style_class_name('multi-line-notification');
|
||||||
this._scrollArea = new St.ScrollView({ name: 'notification-scrollview',
|
this._scrollArea = new St.ScrollView({ style_class: 'notification-scrollview',
|
||||||
vscrollbar_policy: this._scrollPolicy,
|
vscrollbar_policy: this._scrollPolicy,
|
||||||
hscrollbar_policy: Gtk.PolicyType.NEVER });
|
hscrollbar_policy: Gtk.PolicyType.NEVER });
|
||||||
this._table.add(this._scrollArea, { row: 1,
|
this._table.add(this._scrollArea, { row: 1,
|
||||||
col: 2 });
|
col: 2 });
|
||||||
this._updateLastColumnSettings();
|
this._updateLastColumnSettings();
|
||||||
this._contentArea = new St.BoxLayout({ name: 'notification-body',
|
this._contentArea = new St.BoxLayout({ style_class: 'notification-body',
|
||||||
vertical: true });
|
vertical: true });
|
||||||
this._scrollArea.add_actor(this._contentArea);
|
this._scrollArea.add_actor(this._contentArea);
|
||||||
// If we know the notification will be expandable, we need to add
|
// If we know the notification will be expandable, we need to add
|
||||||
@ -616,7 +631,7 @@ const Notification = new Lang.Class({
|
|||||||
}
|
}
|
||||||
|
|
||||||
this._contentArea.add(actor, style ? style : {});
|
this._contentArea.add(actor, style ? style : {});
|
||||||
this._updated();
|
this.updated();
|
||||||
},
|
},
|
||||||
|
|
||||||
// addBody:
|
// addBody:
|
||||||
@ -679,7 +694,7 @@ const Notification = new Lang.Class({
|
|||||||
this._table.add_style_class_name('multi-line-notification');
|
this._table.add_style_class_name('multi-line-notification');
|
||||||
this._table.add(this._actionArea, props);
|
this._table.add(this._actionArea, props);
|
||||||
this._updateLastColumnSettings();
|
this._updateLastColumnSettings();
|
||||||
this._updated();
|
this.updated();
|
||||||
},
|
},
|
||||||
|
|
||||||
_updateLastColumnSettings: function() {
|
_updateLastColumnSettings: function() {
|
||||||
@ -734,7 +749,7 @@ const Notification = new Lang.Class({
|
|||||||
addButton: function(id, label) {
|
addButton: function(id, label) {
|
||||||
if (!this._buttonBox) {
|
if (!this._buttonBox) {
|
||||||
|
|
||||||
let box = new St.BoxLayout({ name: 'notification-actions' });
|
let box = new St.BoxLayout({ style_class: 'notification-actions' });
|
||||||
this.setActionArea(box, { x_expand: false,
|
this.setActionArea(box, { x_expand: false,
|
||||||
y_expand: false,
|
y_expand: false,
|
||||||
x_fill: false,
|
x_fill: false,
|
||||||
@ -744,6 +759,7 @@ const Notification = new Lang.Class({
|
|||||||
}
|
}
|
||||||
|
|
||||||
let button = new St.Button({ can_focus: true });
|
let button = new St.Button({ can_focus: true });
|
||||||
|
button._actionId = id;
|
||||||
|
|
||||||
if (this._useActionIcons && Gtk.IconTheme.get_default().has_icon(id)) {
|
if (this._useActionIcons && Gtk.IconTheme.get_default().has_icon(id)) {
|
||||||
button.add_style_class_name('notification-icon-button');
|
button.add_style_class_name('notification-icon-button');
|
||||||
@ -753,14 +769,39 @@ const Notification = new Lang.Class({
|
|||||||
button.label = label;
|
button.label = label;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this._buttonBox.get_children().length > 0)
|
if (this._buttonBox.get_n_children() > 0)
|
||||||
this._buttonFocusManager.remove_group(this._buttonBox);
|
this._buttonFocusManager.remove_group(this._buttonBox);
|
||||||
|
|
||||||
this._buttonBox.add(button);
|
this._buttonBox.add(button);
|
||||||
this._buttonFocusManager.add_group(this._buttonBox);
|
this._buttonFocusManager.add_group(this._buttonBox);
|
||||||
button.connect('clicked', Lang.bind(this, this._onActionInvoked, id));
|
button.connect('clicked', Lang.bind(this, this._onActionInvoked, id));
|
||||||
|
|
||||||
this._updated();
|
this.updated();
|
||||||
|
},
|
||||||
|
|
||||||
|
// setButtonSensitive:
|
||||||
|
// @id: the action ID
|
||||||
|
// @sensitive: whether the button should be sensitive
|
||||||
|
//
|
||||||
|
// If the notification contains a button with action ID @id,
|
||||||
|
// its sensitivity will be set to @sensitive. Insensitive
|
||||||
|
// buttons cannot be clicked.
|
||||||
|
setButtonSensitive: function(id, sensitive) {
|
||||||
|
if (!this._buttonBox)
|
||||||
|
return;
|
||||||
|
|
||||||
|
let button = this._buttonBox.get_children().filter(function(b) {
|
||||||
|
return b._actionId == id;
|
||||||
|
})[0];
|
||||||
|
|
||||||
|
if (!button || button.reactive == sensitive)
|
||||||
|
return;
|
||||||
|
|
||||||
|
button.reactive = sensitive;
|
||||||
|
if (sensitive)
|
||||||
|
button.remove_style_pseudo_class('insensitive');
|
||||||
|
else
|
||||||
|
button.add_style_pseudo_class('insensitive');
|
||||||
},
|
},
|
||||||
|
|
||||||
setUrgency: function(urgency) {
|
setUrgency: function(urgency) {
|
||||||
@ -787,8 +828,15 @@ const Notification = new Lang.Class({
|
|||||||
let [titleMin, titleNat] = this._titleLabel.get_preferred_width(forHeight);
|
let [titleMin, titleNat] = this._titleLabel.get_preferred_width(forHeight);
|
||||||
let [bannerMin, bannerNat] = this._bannerLabel.get_preferred_width(forHeight);
|
let [bannerMin, bannerNat] = this._bannerLabel.get_preferred_width(forHeight);
|
||||||
|
|
||||||
|
if (this._secondaryIcon) {
|
||||||
|
let [secondaryIconMin, secondaryIconNat] = this._secondaryIcon.get_preferred_width(forHeight);
|
||||||
|
|
||||||
|
alloc.min_size = secondaryIconMin + this._spacing + titleMin;
|
||||||
|
alloc.natural_size = secondaryIconNat + this._spacing + titleNat + this._spacing + bannerNat;
|
||||||
|
} else {
|
||||||
alloc.min_size = titleMin;
|
alloc.min_size = titleMin;
|
||||||
alloc.natural_size = titleNat + this._spacing + bannerNat;
|
alloc.natural_size = titleNat + this._spacing + bannerNat;
|
||||||
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
_bannerBoxGetPreferredHeight: function(actor, forWidth, alloc) {
|
_bannerBoxGetPreferredHeight: function(actor, forWidth, alloc) {
|
||||||
@ -803,14 +851,42 @@ const Notification = new Lang.Class({
|
|||||||
let [titleMinH, titleNatH] = this._titleLabel.get_preferred_height(availWidth);
|
let [titleMinH, titleNatH] = this._titleLabel.get_preferred_height(availWidth);
|
||||||
let [bannerMinW, bannerNatW] = this._bannerLabel.get_preferred_width(availWidth);
|
let [bannerMinW, bannerNatW] = this._bannerLabel.get_preferred_width(availWidth);
|
||||||
|
|
||||||
|
let rtl = (this._titleDirection == Clutter.TextDirection.RTL);
|
||||||
|
let x = rtl ? availWidth : 0;
|
||||||
|
|
||||||
|
if (this._secondaryIcon) {
|
||||||
|
let [iconMinW, iconNatW] = this._secondaryIcon.get_preferred_width(-1);
|
||||||
|
let [iconMinH, iconNatH] = this._secondaryIcon.get_preferred_height(availWidth);
|
||||||
|
|
||||||
|
let secondaryIconBox = new Clutter.ActorBox();
|
||||||
|
let secondaryIconBoxW = Math.min(iconNatW, availWidth);
|
||||||
|
|
||||||
|
// allocate secondary icon box
|
||||||
|
if (rtl) {
|
||||||
|
secondaryIconBox.x1 = x - secondaryIconBoxW;
|
||||||
|
secondaryIconBox.x2 = x;
|
||||||
|
x = x - (secondaryIconBoxW + this._spacing);
|
||||||
|
} else {
|
||||||
|
secondaryIconBox.x1 = x;
|
||||||
|
secondaryIconBox.x2 = x + secondaryIconBoxW;
|
||||||
|
x = x + secondaryIconBoxW + this._spacing;
|
||||||
|
}
|
||||||
|
secondaryIconBox.y1 = 0;
|
||||||
|
// Using titleNatH ensures that the secondary icon is centered vertically
|
||||||
|
secondaryIconBox.y2 = titleNatH;
|
||||||
|
|
||||||
|
availWidth = availWidth - (secondaryIconBoxW + this._spacing);
|
||||||
|
this._secondaryIcon.allocate(secondaryIconBox, flags);
|
||||||
|
}
|
||||||
|
|
||||||
let titleBox = new Clutter.ActorBox();
|
let titleBox = new Clutter.ActorBox();
|
||||||
let titleBoxW = Math.min(titleNatW, availWidth);
|
let titleBoxW = Math.min(titleNatW, availWidth);
|
||||||
if (this._titleDirection == Clutter.TextDirection.RTL) {
|
if (rtl) {
|
||||||
titleBox.x1 = availWidth - titleBoxW;
|
titleBox.x1 = availWidth - titleBoxW;
|
||||||
titleBox.x2 = availWidth;
|
titleBox.x2 = availWidth;
|
||||||
} else {
|
} else {
|
||||||
titleBox.x1 = 0;
|
titleBox.x1 = x;
|
||||||
titleBox.x2 = titleBoxW;
|
titleBox.x2 = titleBox.x1 + titleBoxW;
|
||||||
}
|
}
|
||||||
titleBox.y1 = 0;
|
titleBox.y1 = 0;
|
||||||
titleBox.y2 = titleNatH;
|
titleBox.y2 = titleNatH;
|
||||||
@ -824,7 +900,7 @@ const Notification = new Lang.Class({
|
|||||||
} else {
|
} else {
|
||||||
let bannerBox = new Clutter.ActorBox();
|
let bannerBox = new Clutter.ActorBox();
|
||||||
|
|
||||||
if (this._titleDirection == Clutter.TextDirection.RTL) {
|
if (rtl) {
|
||||||
bannerBox.x1 = 0;
|
bannerBox.x1 = 0;
|
||||||
bannerBox.x2 = titleBox.x1 - this._spacing;
|
bannerBox.x2 = titleBox.x1 - this._spacing;
|
||||||
|
|
||||||
@ -856,7 +932,7 @@ const Notification = new Lang.Class({
|
|||||||
if (this._canExpandContent()) {
|
if (this._canExpandContent()) {
|
||||||
this._addBannerBody();
|
this._addBannerBody();
|
||||||
this._table.add_style_class_name('multi-line-notification');
|
this._table.add_style_class_name('multi-line-notification');
|
||||||
this._updated();
|
this.updated();
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}));
|
}));
|
||||||
@ -867,7 +943,7 @@ const Notification = new Lang.Class({
|
|||||||
(!this._titleFitsInBannerMode && !this._table.has_style_class_name('multi-line-notification'));
|
(!this._titleFitsInBannerMode && !this._table.has_style_class_name('multi-line-notification'));
|
||||||
},
|
},
|
||||||
|
|
||||||
_updated: function() {
|
updated: function() {
|
||||||
if (this.expanded)
|
if (this.expanded)
|
||||||
this.expand(false);
|
this.expand(false);
|
||||||
},
|
},
|
||||||
@ -958,8 +1034,10 @@ const Source = new Lang.Class({
|
|||||||
|
|
||||||
ICON_SIZE: 24,
|
ICON_SIZE: 24,
|
||||||
|
|
||||||
_init: function(title) {
|
_init: function(title, iconName, iconType) {
|
||||||
this.title = title;
|
this.title = title;
|
||||||
|
this.iconName = iconName;
|
||||||
|
this.iconType = iconType;
|
||||||
|
|
||||||
this.actor = new Shell.GenericContainer();
|
this.actor = new Shell.GenericContainer();
|
||||||
this.actor.connect('get-preferred-width', Lang.bind(this, this._getPreferredWidth));
|
this.actor.connect('get-preferred-width', Lang.bind(this, this._getPreferredWidth));
|
||||||
@ -989,6 +1067,8 @@ const Source = new Lang.Class({
|
|||||||
this.isMuted = false;
|
this.isMuted = false;
|
||||||
|
|
||||||
this.notifications = [];
|
this.notifications = [];
|
||||||
|
|
||||||
|
this._setSummaryIcon(this.createNotificationIcon());
|
||||||
},
|
},
|
||||||
|
|
||||||
_getPreferredWidth: function (actor, forHeight, alloc) {
|
_getPreferredWidth: function (actor, forHeight, alloc) {
|
||||||
@ -1059,10 +1139,12 @@ const Source = new Lang.Class({
|
|||||||
},
|
},
|
||||||
|
|
||||||
// Called to create a new icon actor (of size this.ICON_SIZE).
|
// Called to create a new icon actor (of size this.ICON_SIZE).
|
||||||
// Must be overridden by the subclass if you do not pass icons
|
// Provides a sane default implementation, override if you need
|
||||||
// explicitly to the Notification() constructor.
|
// something more fancy.
|
||||||
createNotificationIcon: function() {
|
createNotificationIcon: function() {
|
||||||
throw new Error('no implementation of createNotificationIcon in ' + this);
|
return new St.Icon({ icon_name: this.iconName,
|
||||||
|
icon_type: this.iconType,
|
||||||
|
icon_size: this.ICON_SIZE });
|
||||||
},
|
},
|
||||||
|
|
||||||
// Unlike createNotificationIcon, this always returns the same actor;
|
// Unlike createNotificationIcon, this always returns the same actor;
|
||||||
@ -1113,16 +1195,14 @@ const Source = new Lang.Class({
|
|||||||
},
|
},
|
||||||
|
|
||||||
//// Protected methods ////
|
//// Protected methods ////
|
||||||
|
|
||||||
// The subclass must call this at least once to set the summary icon.
|
|
||||||
_setSummaryIcon: function(icon) {
|
_setSummaryIcon: function(icon) {
|
||||||
if (this._iconBin.child)
|
if (this._iconBin.child)
|
||||||
this._iconBin.child.destroy();
|
this._iconBin.child.destroy();
|
||||||
this._iconBin.child = icon;
|
this._iconBin.child = icon;
|
||||||
},
|
},
|
||||||
|
|
||||||
// Default implementation is to do nothing, but subclasses can override
|
|
||||||
open: function(notification) {
|
open: function(notification) {
|
||||||
|
this.emit('opened', notification);
|
||||||
},
|
},
|
||||||
|
|
||||||
destroyNonResidentNotifications: function() {
|
destroyNonResidentNotifications: function() {
|
||||||
@ -1252,7 +1332,7 @@ const SummaryItem = new Lang.Class({
|
|||||||
},
|
},
|
||||||
|
|
||||||
prepareNotificationStackForShowing: function() {
|
prepareNotificationStackForShowing: function() {
|
||||||
if (this.notificationStack.get_children().length > 0)
|
if (this.notificationStack.get_n_children() > 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
for (let i = 0; i < this.source.notifications.length; i++) {
|
for (let i = 0; i < this.source.notifications.length; i++) {
|
||||||
@ -1261,7 +1341,6 @@ const SummaryItem = new Lang.Class({
|
|||||||
},
|
},
|
||||||
|
|
||||||
doneShowingNotificationStack: function() {
|
doneShowingNotificationStack: function() {
|
||||||
let notificationActors = this.notificationStack.get_children();
|
|
||||||
for (let i = 0; i < this._stackedNotifications.length; i++) {
|
for (let i = 0; i < this._stackedNotifications.length; i++) {
|
||||||
let stackedNotification = this._stackedNotifications[i];
|
let stackedNotification = this._stackedNotifications[i];
|
||||||
let notification = stackedNotification.notification;
|
let notification = stackedNotification.notification;
|
||||||
@ -1291,7 +1370,7 @@ const SummaryItem = new Lang.Class({
|
|||||||
this._stackedNotifications.push(stackedNotification);
|
this._stackedNotifications.push(stackedNotification);
|
||||||
if (!this.source.isChat)
|
if (!this.source.isChat)
|
||||||
notification.enableScrolling(false);
|
notification.enableScrolling(false);
|
||||||
if (this.notificationStack.get_children().length > 0)
|
if (this.notificationStack.get_n_children() > 0)
|
||||||
notification.setIconVisible(false);
|
notification.setIconVisible(false);
|
||||||
this.notificationStack.add(notification.actor);
|
this.notificationStack.add(notification.actor);
|
||||||
notification.expand(false);
|
notification.expand(false);
|
||||||
@ -1437,6 +1516,7 @@ const MessageTray = new Lang.Class({
|
|||||||
this._overviewVisible = Main.overview.visible;
|
this._overviewVisible = Main.overview.visible;
|
||||||
this._notificationRemoved = false;
|
this._notificationRemoved = false;
|
||||||
this._reNotifyAfterHideNotification = null;
|
this._reNotifyAfterHideNotification = null;
|
||||||
|
this._inFullscreen = false;
|
||||||
|
|
||||||
this._corner = new Clutter.Rectangle({ width: 1,
|
this._corner = new Clutter.Rectangle({ width: 1,
|
||||||
height: 1,
|
height: 1,
|
||||||
@ -1447,11 +1527,12 @@ const MessageTray = new Lang.Class({
|
|||||||
Main.layoutManager.trackChrome(this._corner);
|
Main.layoutManager.trackChrome(this._corner);
|
||||||
|
|
||||||
Main.layoutManager.trayBox.add_actor(this.actor);
|
Main.layoutManager.trayBox.add_actor(this.actor);
|
||||||
this.actor.y = this.actor.height;
|
this.actor.y = 0;
|
||||||
Main.layoutManager.trackChrome(this.actor);
|
Main.layoutManager.trackChrome(this.actor);
|
||||||
Main.layoutManager.trackChrome(this._notificationBin);
|
Main.layoutManager.trackChrome(this._notificationBin);
|
||||||
|
|
||||||
Main.layoutManager.connect('monitors-changed', Lang.bind(this, this._setSizePosition));
|
Main.layoutManager.connect('monitors-changed', Lang.bind(this, this._setSizePosition));
|
||||||
|
Main.layoutManager.connect('primary-fullscreen-changed', Lang.bind(this, this._onFullscreenChanged));
|
||||||
|
|
||||||
this._setSizePosition();
|
this._setSizePosition();
|
||||||
|
|
||||||
@ -1854,7 +1935,7 @@ const MessageTray = new Lang.Class({
|
|||||||
_onTrayHoverChanged: function() {
|
_onTrayHoverChanged: function() {
|
||||||
if (this.actor.hover) {
|
if (this.actor.hover) {
|
||||||
// Don't do anything if the one pixel area at the bottom is hovered over while the tray is hidden.
|
// Don't do anything if the one pixel area at the bottom is hovered over while the tray is hidden.
|
||||||
if (this._trayState == State.HIDDEN)
|
if (this._trayState == State.HIDDEN && this._notificationState == State.HIDDEN)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// Don't do anything if this._useLongerTrayLeftTimeout is true, meaning the notification originally
|
// Don't do anything if this._useLongerTrayLeftTimeout is true, meaning the notification originally
|
||||||
@ -1925,6 +2006,11 @@ const MessageTray = new Lang.Class({
|
|||||||
this._updateState();
|
this._updateState();
|
||||||
},
|
},
|
||||||
|
|
||||||
|
_onFullscreenChanged: function(obj, state) {
|
||||||
|
this._inFullscreen = state;
|
||||||
|
this._updateState();
|
||||||
|
},
|
||||||
|
|
||||||
_onStatusChanged: function(status) {
|
_onStatusChanged: function(status) {
|
||||||
if (status == GnomeSession.PresenceStatus.BUSY) {
|
if (status == GnomeSession.PresenceStatus.BUSY) {
|
||||||
// remove notification and allow the summary to be closed now
|
// remove notification and allow the summary to be closed now
|
||||||
@ -1982,9 +2068,9 @@ const MessageTray = new Lang.Class({
|
|||||||
_updateState: function() {
|
_updateState: function() {
|
||||||
// Notifications
|
// Notifications
|
||||||
let notificationUrgent = this._notificationQueue.length > 0 && this._notificationQueue[0].urgency == Urgency.CRITICAL;
|
let notificationUrgent = this._notificationQueue.length > 0 && this._notificationQueue[0].urgency == Urgency.CRITICAL;
|
||||||
let notificationsPending = this._notificationQueue.length > 0 && (!this._busy || notificationUrgent);
|
let notificationsPending = this._notificationQueue.length > 0 && ((!this._busy && !this._inFullscreen) || notificationUrgent);
|
||||||
let notificationPinned = this._pointerInTray && !this._pointerInSummary && !this._notificationRemoved;
|
let notificationPinned = this._pointerInTray && !this._pointerInSummary && !this._notificationRemoved;
|
||||||
let notificationExpanded = this._notificationBin.y < 0;
|
let notificationExpanded = this._notificationBin.y < - this.actor.height;
|
||||||
let notificationExpired = (this._notificationTimeoutId == 0 && !(this._notification && this._notification.urgency == Urgency.CRITICAL) && !this._pointerInTray && !this._locked && !(this._pointerInKeyboard && notificationExpanded)) || this._notificationRemoved;
|
let notificationExpired = (this._notificationTimeoutId == 0 && !(this._notification && this._notification.urgency == Urgency.CRITICAL) && !this._pointerInTray && !this._locked && !(this._pointerInKeyboard && notificationExpanded)) || this._notificationRemoved;
|
||||||
let canShowNotification = notificationsPending && this._summaryState == State.HIDDEN;
|
let canShowNotification = notificationsPending && this._summaryState == State.HIDDEN;
|
||||||
|
|
||||||
@ -2018,7 +2104,7 @@ const MessageTray = new Lang.Class({
|
|||||||
if (this._summaryState == State.HIDDEN && !mustHideSummary) {
|
if (this._summaryState == State.HIDDEN && !mustHideSummary) {
|
||||||
if (summarySummoned) {
|
if (summarySummoned) {
|
||||||
this._showSummary(0);
|
this._showSummary(0);
|
||||||
} else if (notificationsDone && !this._busy) {
|
} else if (notificationsDone && !this._busy && !this._inFullscreen) {
|
||||||
if (this._backFromAway && this._unseenNotifications.length > 0)
|
if (this._backFromAway && this._unseenNotifications.length > 0)
|
||||||
this._showSummary(LONGER_SUMMARY_TIMEOUT);
|
this._showSummary(LONGER_SUMMARY_TIMEOUT);
|
||||||
else if (this._newSummaryItems.length > 0)
|
else if (this._newSummaryItems.length > 0)
|
||||||
@ -2064,8 +2150,7 @@ const MessageTray = new Lang.Class({
|
|||||||
// Tray itself
|
// Tray itself
|
||||||
let trayIsVisible = (this._trayState == State.SHOWING ||
|
let trayIsVisible = (this._trayState == State.SHOWING ||
|
||||||
this._trayState == State.SHOWN);
|
this._trayState == State.SHOWN);
|
||||||
let trayShouldBeVisible = (!notificationsDone ||
|
let trayShouldBeVisible = (this._summaryState == State.SHOWING ||
|
||||||
this._summaryState == State.SHOWING ||
|
|
||||||
this._summaryState == State.SHOWN);
|
this._summaryState == State.SHOWN);
|
||||||
if (!trayIsVisible && trayShouldBeVisible)
|
if (!trayIsVisible && trayShouldBeVisible)
|
||||||
this._showTray();
|
this._showTray();
|
||||||
@ -2105,7 +2190,7 @@ const MessageTray = new Lang.Class({
|
|||||||
|
|
||||||
_hideTray: function() {
|
_hideTray: function() {
|
||||||
this._tween(this.actor, '_trayState', State.HIDDEN,
|
this._tween(this.actor, '_trayState', State.HIDDEN,
|
||||||
{ y: this.actor.height,
|
{ y: 0,
|
||||||
time: ANIMATION_TIME,
|
time: ANIMATION_TIME,
|
||||||
transition: 'easeOutQuad'
|
transition: 'easeOutQuad'
|
||||||
});
|
});
|
||||||
@ -2142,7 +2227,7 @@ const MessageTray = new Lang.Class({
|
|||||||
this._notificationBin.child = this._notification.actor;
|
this._notificationBin.child = this._notification.actor;
|
||||||
|
|
||||||
this._notificationBin.opacity = 0;
|
this._notificationBin.opacity = 0;
|
||||||
this._notificationBin.y = this.actor.height;
|
this._notificationBin.y = 0;
|
||||||
this._notificationBin.show();
|
this._notificationBin.show();
|
||||||
|
|
||||||
this._updateShowingNotification();
|
this._updateShowingNotification();
|
||||||
@ -2177,7 +2262,8 @@ const MessageTray = new Lang.Class({
|
|||||||
// We tween all notifications to full opacity. This ensures that both new notifications and
|
// We tween all notifications to full opacity. This ensures that both new notifications and
|
||||||
// notifications that might have been in the process of hiding get full opacity.
|
// notifications that might have been in the process of hiding get full opacity.
|
||||||
//
|
//
|
||||||
// We tween any notification showing in the banner mode to banner height (this._notificationBin.y = 0).
|
// We tween any notification showing in the banner mode to banner height
|
||||||
|
// (this._notificationBin.y = -this.actor.height).
|
||||||
// This ensures that both new notifications and notifications in the banner mode that might
|
// This ensures that both new notifications and notifications in the banner mode that might
|
||||||
// have been in the process of hiding are shown with the banner height.
|
// have been in the process of hiding are shown with the banner height.
|
||||||
//
|
//
|
||||||
@ -2194,7 +2280,7 @@ const MessageTray = new Lang.Class({
|
|||||||
onCompleteScope: this
|
onCompleteScope: this
|
||||||
};
|
};
|
||||||
if (!this._notification.expanded)
|
if (!this._notification.expanded)
|
||||||
tweenParams.y = 0;
|
tweenParams.y = - this.actor.height;
|
||||||
|
|
||||||
this._tween(this._notificationBin, '_notificationState', State.SHOWN, tweenParams);
|
this._tween(this._notificationBin, '_notificationState', State.SHOWN, tweenParams);
|
||||||
},
|
},
|
||||||
@ -2283,7 +2369,7 @@ const MessageTray = new Lang.Class({
|
|||||||
},
|
},
|
||||||
|
|
||||||
_onNotificationExpanded: function() {
|
_onNotificationExpanded: function() {
|
||||||
let expandedY = this.actor.height - this._notificationBin.height;
|
let expandedY = - this._notificationBin.height;
|
||||||
|
|
||||||
// Don't animate the notification to its new position if it has shrunk:
|
// Don't animate the notification to its new position if it has shrunk:
|
||||||
// there will be a very visible "gap" that breaks the illusion.
|
// there will be a very visible "gap" that breaks the illusion.
|
||||||
@ -2391,24 +2477,23 @@ const MessageTray = new Lang.Class({
|
|||||||
|
|
||||||
this._summaryBoxPointerState = State.SHOWING;
|
this._summaryBoxPointerState = State.SHOWING;
|
||||||
this._clickedSummaryItem.actor.add_style_pseudo_class('selected');
|
this._clickedSummaryItem.actor.add_style_pseudo_class('selected');
|
||||||
this._summaryBoxPointer.show(true, Lang.bind(this, function() {
|
this._summaryBoxPointer.show(BoxPointer.PopupAnimation.FULL, Lang.bind(this, function() {
|
||||||
this._summaryBoxPointerState = State.SHOWN;
|
this._summaryBoxPointerState = State.SHOWN;
|
||||||
}));
|
}));
|
||||||
},
|
},
|
||||||
|
|
||||||
_onSummaryBoxPointerContentUpdated: function() {
|
_onSummaryBoxPointerContentUpdated: function() {
|
||||||
if (this._summaryBoxPointerItem.notificationStack.get_children().length == 0)
|
if (this._summaryBoxPointerItem.notificationStack.get_n_children() == 0)
|
||||||
this._hideSummaryBoxPointer();
|
this._hideSummaryBoxPointer();
|
||||||
this._adjustSummaryBoxPointerPosition();
|
this._adjustSummaryBoxPointerPosition();
|
||||||
|
|
||||||
},
|
},
|
||||||
|
|
||||||
_adjustSummaryBoxPointerPosition: function() {
|
_adjustSummaryBoxPointerPosition: function() {
|
||||||
// The position of the arrow origin should be the same as center of this._clickedSummaryItem.actor
|
|
||||||
if (!this._clickedSummaryItem)
|
if (!this._clickedSummaryItem)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
this._summaryBoxPointer.setPosition(this._clickedSummaryItem.actor, 0, 0.5);
|
this._summaryBoxPointer.setPosition(this._clickedSummaryItem.actor, 0);
|
||||||
},
|
},
|
||||||
|
|
||||||
_unsetClickedSummaryItem: function() {
|
_unsetClickedSummaryItem: function() {
|
||||||
@ -2431,7 +2516,7 @@ const MessageTray = new Lang.Class({
|
|||||||
// We should be sure to hide the box pointer if all notifications in it are destroyed while
|
// We should be sure to hide the box pointer if all notifications in it are destroyed while
|
||||||
// it is hiding, so that we don't show an an animation of an empty blob being hidden.
|
// it is hiding, so that we don't show an an animation of an empty blob being hidden.
|
||||||
if (this._summaryBoxPointerState == State.HIDING &&
|
if (this._summaryBoxPointerState == State.HIDING &&
|
||||||
this._summaryBoxPointerItem.notificationStack.get_children().length == 0) {
|
this._summaryBoxPointerItem.notificationStack.get_n_children() == 0) {
|
||||||
this._summaryBoxPointer.actor.hide();
|
this._summaryBoxPointer.actor.hide();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -2446,7 +2531,7 @@ const MessageTray = new Lang.Class({
|
|||||||
this._summaryBoxPointer.actor.hide();
|
this._summaryBoxPointer.actor.hide();
|
||||||
this._hideSummaryBoxPointerCompleted();
|
this._hideSummaryBoxPointerCompleted();
|
||||||
} else {
|
} else {
|
||||||
this._summaryBoxPointer.hide(true, Lang.bind(this, this._hideSummaryBoxPointerCompleted));
|
this._summaryBoxPointer.hide(BoxPointer.PopupAnimation.FULL, Lang.bind(this, this._hideSummaryBoxPointerCompleted));
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -2487,15 +2572,7 @@ const SystemNotificationSource = new Lang.Class({
|
|||||||
Extends: Source,
|
Extends: Source,
|
||||||
|
|
||||||
_init: function() {
|
_init: function() {
|
||||||
this.parent(_("System Information"));
|
this.parent(_("System Information"), 'dialog-information', St.IconType.SYMBOLIC);
|
||||||
|
|
||||||
this._setSummaryIcon(this.createNotificationIcon());
|
|
||||||
},
|
|
||||||
|
|
||||||
createNotificationIcon: function() {
|
|
||||||
return new St.Icon({ icon_name: 'dialog-information',
|
|
||||||
icon_type: St.IconType.SYMBOLIC,
|
|
||||||
icon_size: this.ICON_SIZE });
|
|
||||||
},
|
},
|
||||||
|
|
||||||
open: function() {
|
open: function() {
|
||||||
|
@ -180,7 +180,7 @@ const ModalDialog = new Lang.Class({
|
|||||||
},
|
},
|
||||||
|
|
||||||
_fadeOpen: function() {
|
_fadeOpen: function() {
|
||||||
let monitor = Main.layoutManager.focusMonitor;
|
let monitor = Main.layoutManager.currentMonitor;
|
||||||
|
|
||||||
this._backgroundBin.set_position(monitor.x, monitor.y);
|
this._backgroundBin.set_position(monitor.x, monitor.y);
|
||||||
this._backgroundBin.set_size(monitor.width, monitor.height);
|
this._backgroundBin.set_size(monitor.width, monitor.height);
|
||||||
|
@ -683,7 +683,10 @@ const NetworkAgent = new Lang.Class({
|
|||||||
try {
|
try {
|
||||||
externalUIMode = keyfile.get_boolean('GNOME', 'supports-external-ui-mode');
|
externalUIMode = keyfile.get_boolean('GNOME', 'supports-external-ui-mode');
|
||||||
} catch(e) { } // ignore errors if key does not exist
|
} catch(e) { } // ignore errors if key does not exist
|
||||||
let path = GLib.build_filenamev([Config.LIBEXECDIR, binary]);
|
let path = binary;
|
||||||
|
if (!GLib.path_is_absolute(path)) {
|
||||||
|
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 };
|
this._vpnBinaries[service] = { fileName: path, externalUIMode: externalUIMode };
|
||||||
|
@ -221,12 +221,19 @@ const NotificationDaemon = new Lang.Class({
|
|||||||
let [appName, replacesId, icon, summary, body, actions, hints, timeout] = params;
|
let [appName, replacesId, icon, summary, body, actions, hints, timeout] = params;
|
||||||
let id;
|
let id;
|
||||||
|
|
||||||
|
for (let hint in hints) {
|
||||||
|
// unpack the variants
|
||||||
|
hints[hint] = hints[hint].deep_unpack();
|
||||||
|
}
|
||||||
|
|
||||||
|
hints = Params.parse(hints, { urgency: Urgency.NORMAL }, true);
|
||||||
|
|
||||||
// Filter out chat, presence, calls and invitation notifications from
|
// Filter out chat, presence, calls and invitation notifications from
|
||||||
// Empathy, since we handle that information from telepathyClient.js
|
// Empathy, since we handle that information from telepathyClient.js
|
||||||
if (appName == 'Empathy' && (hints['category'] == 'im.received' ||
|
if (appName == 'Empathy' && (hints['category'] == 'im.received' ||
|
||||||
hints['category'] == 'x-empathy.im.room-invitation' ||
|
hints['category'] == 'x-empathy.im.room-invitation' ||
|
||||||
hints['category'] == 'x-empathy.call.incoming' ||
|
hints['category'] == 'x-empathy.call.incoming' ||
|
||||||
hints['category'] == 'x-empathy.call.incoming"' ||
|
hints['category'] == 'x-empathy.transfer.incoming' ||
|
||||||
hints['category'] == 'x-empathy.im.subscription-request' ||
|
hints['category'] == 'x-empathy.im.subscription-request' ||
|
||||||
hints['category'] == 'presence.online' ||
|
hints['category'] == 'presence.online' ||
|
||||||
hints['category'] == 'presence.offline')) {
|
hints['category'] == 'presence.offline')) {
|
||||||
@ -249,13 +256,6 @@ const NotificationDaemon = new Lang.Class({
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (let hint in hints) {
|
|
||||||
// unpack the variants
|
|
||||||
hints[hint] = hints[hint].deep_unpack();
|
|
||||||
}
|
|
||||||
|
|
||||||
hints = Params.parse(hints, { urgency: Urgency.NORMAL }, true);
|
|
||||||
|
|
||||||
// Be compatible with the various hints for image data and image path
|
// Be compatible with the various hints for image data and image path
|
||||||
// 'image-data' and 'image-path' are the latest name of these hints, introduced in 1.2
|
// 'image-data' and 'image-path' are the latest name of these hints, introduced in 1.2
|
||||||
|
|
||||||
@ -483,7 +483,7 @@ const NotificationDaemon = new Lang.Class({
|
|||||||
},
|
},
|
||||||
|
|
||||||
_onTrayIconAdded: function(o, icon) {
|
_onTrayIconAdded: function(o, icon) {
|
||||||
let source = this._getSource(icon.title || icon.wm_class || _("Unknown"), icon.pid, null, null, icon);
|
let source = this._getSource(icon.title || icon.wm_class || C_("program", "Unknown"), icon.pid, null, null, icon);
|
||||||
},
|
},
|
||||||
|
|
||||||
_onTrayIconRemoved: function(o, icon) {
|
_onTrayIconRemoved: function(o, icon) {
|
||||||
@ -578,11 +578,27 @@ const Source = new Lang.Class({
|
|||||||
return true;
|
return true;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
_getApp: function() {
|
||||||
|
let app;
|
||||||
|
|
||||||
|
app = Shell.WindowTracker.get_default().get_app_from_pid(this.pid);
|
||||||
|
if (app != null)
|
||||||
|
return app;
|
||||||
|
|
||||||
|
if (this.trayIcon) {
|
||||||
|
app = Shell.AppSystem.get_default().lookup_wmclass(this.trayIcon.wmclass);
|
||||||
|
if (app != null)
|
||||||
|
return app;
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
},
|
||||||
|
|
||||||
_setApp: function() {
|
_setApp: function() {
|
||||||
if (this.app)
|
if (this.app)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
this.app = Shell.WindowTracker.get_default().get_app_from_pid(this.pid);
|
this.app = this._getApp();
|
||||||
if (!this.app)
|
if (!this.app)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@ -622,5 +638,10 @@ const Source = new Lang.Class({
|
|||||||
}
|
}
|
||||||
|
|
||||||
this.parent();
|
this.parent();
|
||||||
|
},
|
||||||
|
|
||||||
|
createNotificationIcon: function() {
|
||||||
|
// We set the summary icon ourselves.
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -11,10 +11,8 @@ const Shell = imports.gi.Shell;
|
|||||||
const Gdk = imports.gi.Gdk;
|
const Gdk = imports.gi.Gdk;
|
||||||
|
|
||||||
const AppDisplay = imports.ui.appDisplay;
|
const AppDisplay = imports.ui.appDisplay;
|
||||||
const ContactDisplay = imports.ui.contactDisplay;
|
|
||||||
const Dash = imports.ui.dash;
|
const Dash = imports.ui.dash;
|
||||||
const DND = imports.ui.dnd;
|
const DND = imports.ui.dnd;
|
||||||
const Lightbox = imports.ui.lightbox;
|
|
||||||
const Main = imports.ui.main;
|
const Main = imports.ui.main;
|
||||||
const MessageTray = imports.ui.messageTray;
|
const MessageTray = imports.ui.messageTray;
|
||||||
const Panel = imports.ui.panel;
|
const Panel = imports.ui.panel;
|
||||||
@ -99,10 +97,8 @@ const ShellInfo = new Lang.Class({
|
|||||||
const Overview = new Lang.Class({
|
const Overview = new Lang.Class({
|
||||||
Name: 'Overview',
|
Name: 'Overview',
|
||||||
|
|
||||||
_init : function(params) {
|
_init : function() {
|
||||||
params = Params.parse(params, { isDummy: false });
|
this.isDummy = !Main.sessionMode.hasOverview;
|
||||||
|
|
||||||
this.isDummy = params.isDummy;
|
|
||||||
|
|
||||||
// We only have an overview in user sessions, so
|
// We only have an overview in user sessions, so
|
||||||
// create a dummy overview in other cases
|
// create a dummy overview in other cases
|
||||||
@ -210,7 +206,6 @@ const Overview = new Lang.Class({
|
|||||||
this.addSearchProvider(new AppDisplay.AppSearchProvider());
|
this.addSearchProvider(new AppDisplay.AppSearchProvider());
|
||||||
this.addSearchProvider(new AppDisplay.SettingsSearchProvider());
|
this.addSearchProvider(new AppDisplay.SettingsSearchProvider());
|
||||||
this.addSearchProvider(new PlaceDisplay.PlaceSearchProvider());
|
this.addSearchProvider(new PlaceDisplay.PlaceSearchProvider());
|
||||||
this.addSearchProvider(new ContactDisplay.ContactSearchProvider());
|
|
||||||
|
|
||||||
// Load remote search providers provided by applications
|
// Load remote search providers provided by applications
|
||||||
RemoteSearch.loadRemoteSearchProviders(Lang.bind(this, this.addSearchProvider));
|
RemoteSearch.loadRemoteSearchProviders(Lang.bind(this, this.addSearchProvider));
|
||||||
|
@ -4,6 +4,7 @@ const Cairo = imports.cairo;
|
|||||||
const Clutter = imports.gi.Clutter;
|
const Clutter = imports.gi.Clutter;
|
||||||
const Gio = imports.gi.Gio;
|
const Gio = imports.gi.Gio;
|
||||||
const GLib = imports.gi.GLib;
|
const GLib = imports.gi.GLib;
|
||||||
|
const Gtk = imports.gi.Gtk;
|
||||||
const Lang = imports.lang;
|
const Lang = imports.lang;
|
||||||
const Mainloop = imports.mainloop;
|
const Mainloop = imports.mainloop;
|
||||||
const Meta = imports.gi.Meta;
|
const Meta = imports.gi.Meta;
|
||||||
@ -13,7 +14,6 @@ const St = imports.gi.St;
|
|||||||
const Signals = imports.signals;
|
const Signals = imports.signals;
|
||||||
const Atk = imports.gi.Atk;
|
const Atk = imports.gi.Atk;
|
||||||
|
|
||||||
const Config = imports.misc.config;
|
|
||||||
const CtrlAltTab = imports.ui.ctrlAltTab;
|
const CtrlAltTab = imports.ui.ctrlAltTab;
|
||||||
const DND = imports.ui.dnd;
|
const DND = imports.ui.dnd;
|
||||||
const Layout = imports.ui.layout;
|
const Layout = imports.ui.layout;
|
||||||
@ -31,33 +31,6 @@ const BUTTON_DND_ACTIVATION_TIMEOUT = 250;
|
|||||||
const ANIMATED_ICON_UPDATE_TIMEOUT = 100;
|
const ANIMATED_ICON_UPDATE_TIMEOUT = 100;
|
||||||
const SPINNER_ANIMATION_TIME = 0.2;
|
const SPINNER_ANIMATION_TIME = 0.2;
|
||||||
|
|
||||||
const STANDARD_STATUS_AREA_ORDER = ['a11y', 'keyboard', 'volume', 'bluetooth', 'network', 'battery', 'userMenu'];
|
|
||||||
const STANDARD_STATUS_AREA_SHELL_IMPLEMENTATION = {
|
|
||||||
'a11y': imports.ui.status.accessibility.ATIndicator,
|
|
||||||
'volume': imports.ui.status.volume.Indicator,
|
|
||||||
'battery': imports.ui.status.power.Indicator,
|
|
||||||
'keyboard': imports.ui.status.keyboard.XKBIndicator,
|
|
||||||
'userMenu': imports.ui.userMenu.UserMenuButton
|
|
||||||
};
|
|
||||||
|
|
||||||
if (Config.HAVE_BLUETOOTH)
|
|
||||||
STANDARD_STATUS_AREA_SHELL_IMPLEMENTATION['bluetooth'] = imports.ui.status.bluetooth.Indicator;
|
|
||||||
|
|
||||||
try {
|
|
||||||
STANDARD_STATUS_AREA_SHELL_IMPLEMENTATION['network'] = imports.ui.status.network.NMApplet;
|
|
||||||
} catch(e) {
|
|
||||||
log('NMApplet is not supported. It is possible that your NetworkManager version is too old');
|
|
||||||
}
|
|
||||||
|
|
||||||
const GDM_STATUS_AREA_ORDER = ['a11y', 'display', 'keyboard', 'volume', 'battery', 'powerMenu'];
|
|
||||||
const GDM_STATUS_AREA_SHELL_IMPLEMENTATION = {
|
|
||||||
'a11y': imports.ui.status.accessibility.ATIndicator,
|
|
||||||
'volume': imports.ui.status.volume.Indicator,
|
|
||||||
'battery': imports.ui.status.power.Indicator,
|
|
||||||
'keyboard': imports.ui.status.keyboard.XKBIndicator,
|
|
||||||
'powerMenu': imports.gdm.powerMenu.PowerMenuButton
|
|
||||||
};
|
|
||||||
|
|
||||||
// To make sure the panel corners blend nicely with the panel,
|
// To make sure the panel corners blend nicely with the panel,
|
||||||
// we draw background and borders the same way, e.g. drawing
|
// we draw background and borders the same way, e.g. drawing
|
||||||
// them as filled shapes from the outside inwards instead of
|
// them as filled shapes from the outside inwards instead of
|
||||||
@ -373,6 +346,7 @@ const AppMenuButton = new Lang.Class({
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
this._stop = true;
|
this._stop = true;
|
||||||
|
this.actor.reactive = true;
|
||||||
Tweener.addTween(this._spinner.actor,
|
Tweener.addTween(this._spinner.actor,
|
||||||
{ opacity: 0,
|
{ opacity: 0,
|
||||||
time: SPINNER_ANIMATION_TIME,
|
time: SPINNER_ANIMATION_TIME,
|
||||||
@ -387,6 +361,7 @@ const AppMenuButton = new Lang.Class({
|
|||||||
|
|
||||||
startAnimation: function() {
|
startAnimation: function() {
|
||||||
this._stop = false;
|
this._stop = false;
|
||||||
|
this.actor.reactive = false;
|
||||||
this._spinner.actor.show();
|
this._spinner.actor.show();
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -961,7 +936,7 @@ const Panel = new Lang.Class({
|
|||||||
this.actor.connect('button-press-event', Lang.bind(this, this._onButtonPress));
|
this.actor.connect('button-press-event', Lang.bind(this, this._onButtonPress));
|
||||||
|
|
||||||
/* Button on the left side of the panel. */
|
/* Button on the left side of the panel. */
|
||||||
if (global.session_type == Shell.SessionType.USER) {
|
if (Main.sessionMode.hasOverview) {
|
||||||
this._activitiesButton = new ActivitiesButton();
|
this._activitiesButton = new ActivitiesButton();
|
||||||
this._activities = this._activitiesButton.actor;
|
this._activities = this._activitiesButton.actor;
|
||||||
this._leftBox.add(this._activities);
|
this._leftBox.add(this._activities);
|
||||||
@ -969,28 +944,19 @@ const Panel = new Lang.Class({
|
|||||||
// The activities button has a pretend menu, so as to integrate
|
// The activities button has a pretend menu, so as to integrate
|
||||||
// more cleanly with the rest of the panel
|
// more cleanly with the rest of the panel
|
||||||
this._menus.addMenu(this._activitiesButton.menu);
|
this._menus.addMenu(this._activitiesButton.menu);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Main.sessionMode.hasAppMenu) {
|
||||||
this._appMenu = new AppMenuButton(this._menus);
|
this._appMenu = new AppMenuButton(this._menus);
|
||||||
this._leftBox.add(this._appMenu.actor);
|
this._leftBox.add(this._appMenu.actor);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* center */
|
/* center */
|
||||||
if (global.session_type == Shell.SessionType.USER)
|
this._dateMenu = new DateMenu.DateMenuButton();
|
||||||
this._dateMenu = new DateMenu.DateMenuButton({ showEvents: true });
|
|
||||||
else
|
|
||||||
this._dateMenu = new DateMenu.DateMenuButton({ showEvents: false });
|
|
||||||
this._centerBox.add(this._dateMenu.actor, { y_fill: true });
|
this._centerBox.add(this._dateMenu.actor, { y_fill: true });
|
||||||
this._menus.addMenu(this._dateMenu.menu);
|
this._menus.addMenu(this._dateMenu.menu);
|
||||||
|
|
||||||
/* right */
|
/* right */
|
||||||
if (global.session_type == Shell.SessionType.GDM) {
|
|
||||||
this._status_area_order = GDM_STATUS_AREA_ORDER;
|
|
||||||
this._status_area_shell_implementation = GDM_STATUS_AREA_SHELL_IMPLEMENTATION;
|
|
||||||
} else {
|
|
||||||
this._status_area_order = STANDARD_STATUS_AREA_ORDER;
|
|
||||||
this._status_area_shell_implementation = STANDARD_STATUS_AREA_SHELL_IMPLEMENTATION;
|
|
||||||
}
|
|
||||||
|
|
||||||
Main.statusIconDispatcher.connect('status-icon-added', Lang.bind(this, this._onTrayIconAdded));
|
Main.statusIconDispatcher.connect('status-icon-added', Lang.bind(this, this._onTrayIconAdded));
|
||||||
Main.statusIconDispatcher.connect('status-icon-removed', Lang.bind(this, this._onTrayIconRemoved));
|
Main.statusIconDispatcher.connect('status-icon-removed', Lang.bind(this, this._onTrayIconRemoved));
|
||||||
|
|
||||||
@ -1112,10 +1078,19 @@ const Panel = new Lang.Class({
|
|||||||
return true;
|
return true;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
openAppMenu: function() {
|
||||||
|
let menu = this._appMenu.menu;
|
||||||
|
if (!this._appMenu.actor.reactive || menu.isOpen)
|
||||||
|
return;
|
||||||
|
|
||||||
|
menu.open();
|
||||||
|
menu.actor.navigate_focus(null, Gtk.DirectionType.TAB_FORWARD, false);
|
||||||
|
},
|
||||||
|
|
||||||
startStatusArea: function() {
|
startStatusArea: function() {
|
||||||
for (let i = 0; i < this._status_area_order.length; i++) {
|
for (let i = 0; i < Main.sessionMode.statusArea.order.length; i++) {
|
||||||
let role = this._status_area_order[i];
|
let role = Main.sessionMode.statusArea.order[i];
|
||||||
let constructor = this._status_area_shell_implementation[role];
|
let constructor = Main.sessionMode.statusArea.implementation[role];
|
||||||
if (!constructor) {
|
if (!constructor) {
|
||||||
// This icon is not implemented (this is a bug)
|
// This icon is not implemented (this is a bug)
|
||||||
continue;
|
continue;
|
||||||
@ -1153,6 +1128,7 @@ const Panel = new Lang.Class({
|
|||||||
if (!position)
|
if (!position)
|
||||||
position = 0;
|
position = 0;
|
||||||
this._insertStatusItem(indicator.actor, position);
|
this._insertStatusItem(indicator.actor, position);
|
||||||
|
if (indicator.menu)
|
||||||
this._menus.addMenu(indicator.menu);
|
this._menus.addMenu(indicator.menu);
|
||||||
|
|
||||||
this._statusArea[role] = indicator;
|
this._statusArea[role] = indicator;
|
||||||
@ -1165,18 +1141,21 @@ const Panel = new Lang.Class({
|
|||||||
},
|
},
|
||||||
|
|
||||||
_onTrayIconAdded: function(o, icon, role) {
|
_onTrayIconAdded: function(o, icon, role) {
|
||||||
if (this._status_area_shell_implementation[role]) {
|
if (Main.sessionMode.statusArea.implementation[role]) {
|
||||||
// This icon is legacy, and replaced by a Shell version
|
// This icon is legacy, and replaced by a Shell version
|
||||||
// Hide it
|
// Hide it
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (Main.sessionMode.statusArea.order.indexOf(role) == -1)
|
||||||
|
return;
|
||||||
|
|
||||||
icon.height = PANEL_ICON_SIZE;
|
icon.height = PANEL_ICON_SIZE;
|
||||||
let buttonBox = new PanelMenu.ButtonBox();
|
let buttonBox = new PanelMenu.ButtonBox();
|
||||||
let box = buttonBox.actor;
|
let box = buttonBox.actor;
|
||||||
box.add_actor(icon);
|
box.add_actor(icon);
|
||||||
|
|
||||||
this._insertStatusItem(box, this._status_area_order.indexOf(role));
|
this._insertStatusItem(box, Main.sessionMode.statusArea.order.indexOf(role));
|
||||||
},
|
},
|
||||||
|
|
||||||
_onTrayIconRemoved: function(o, icon) {
|
_onTrayIconRemoved: function(o, icon) {
|
||||||
|
@ -189,7 +189,7 @@ const PlacesManager = new Lang.Class({
|
|||||||
this._volumeMonitor.connect('drive-changed', Lang.bind(this, this._updateDevices));
|
this._volumeMonitor.connect('drive-changed', Lang.bind(this, this._updateDevices));
|
||||||
this._updateDevices();
|
this._updateDevices();
|
||||||
|
|
||||||
this._bookmarksPath = GLib.build_filenamev([GLib.get_home_dir(), '.gtk-bookmarks']);
|
this._bookmarksPath = GLib.build_filenamev([GLib.get_user_config_dir(), 'gtk-3.0', 'bookmarks']);
|
||||||
this._bookmarksFile = Gio.file_new_for_path(this._bookmarksPath);
|
this._bookmarksFile = Gio.file_new_for_path(this._bookmarksPath);
|
||||||
this._monitor = this._bookmarksFile.monitor_file(Gio.FileMonitorFlags.NONE, null);
|
this._monitor = this._bookmarksFile.monitor_file(Gio.FileMonitorFlags.NONE, null);
|
||||||
this._bookmarkTimeoutId = 0;
|
this._bookmarkTimeoutId = 0;
|
||||||
@ -365,12 +365,13 @@ const PlaceSearchProvider = new Lang.Class({
|
|||||||
|
|
||||||
_init: function() {
|
_init: function() {
|
||||||
this.parent(_("PLACES & DEVICES"));
|
this.parent(_("PLACES & DEVICES"));
|
||||||
|
this.placesManager = new PlacesManager();
|
||||||
},
|
},
|
||||||
|
|
||||||
getResultMetas: function(resultIds) {
|
getResultMetas: function(resultIds, callback) {
|
||||||
let metas = [];
|
let metas = [];
|
||||||
for (let i = 0; i < resultIds.length; i++) {
|
for (let i = 0; i < resultIds.length; i++) {
|
||||||
let placeInfo = Main.placesManager.lookupPlaceById(resultIds[i]);
|
let placeInfo = this.placesManager.lookupPlaceById(resultIds[i]);
|
||||||
if (!placeInfo)
|
if (!placeInfo)
|
||||||
metas.push(null);
|
metas.push(null);
|
||||||
else
|
else
|
||||||
@ -381,24 +382,22 @@ const PlaceSearchProvider = new Lang.Class({
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
return metas;
|
callback(metas);
|
||||||
},
|
},
|
||||||
|
|
||||||
activateResult: function(id, params) {
|
activateResult: function(id, params) {
|
||||||
let placeInfo = Main.placesManager.lookupPlaceById(id);
|
let placeInfo = this.placesManager.lookupPlaceById(id);
|
||||||
placeInfo.launch(params);
|
placeInfo.launch(params);
|
||||||
},
|
},
|
||||||
|
|
||||||
_compareResultMeta: function (idA, idB) {
|
_compareResultMeta: function (idA, idB) {
|
||||||
let infoA = Main.placesManager.lookupPlaceById(idA);
|
let infoA = this.placesManager.lookupPlaceById(idA);
|
||||||
let infoB = Main.placesManager.lookupPlaceById(idB);
|
let infoB = this.placesManager.lookupPlaceById(idB);
|
||||||
return infoA.name.localeCompare(infoB.name);
|
return infoA.name.localeCompare(infoB.name);
|
||||||
},
|
},
|
||||||
|
|
||||||
_searchPlaces: function(places, terms) {
|
_searchPlaces: function(places, terms) {
|
||||||
let multiplePrefixResults = [];
|
|
||||||
let prefixResults = [];
|
let prefixResults = [];
|
||||||
let multipleSubstringResults = [];
|
|
||||||
let substringResults = [];
|
let substringResults = [];
|
||||||
|
|
||||||
terms = terms.map(String.toLowerCase);
|
terms = terms.map(String.toLowerCase);
|
||||||
@ -406,29 +405,26 @@ const PlaceSearchProvider = new Lang.Class({
|
|||||||
for (let i = 0; i < places.length; i++) {
|
for (let i = 0; i < places.length; i++) {
|
||||||
let place = places[i];
|
let place = places[i];
|
||||||
let mtype = place.matchTerms(terms);
|
let mtype = place.matchTerms(terms);
|
||||||
if (mtype == Search.MatchType.MULTIPLE_PREFIX)
|
if (mtype == Search.MatchType.PREFIX)
|
||||||
multiplePrefixResults.push(place.id);
|
|
||||||
else if (mtype == Search.MatchType.PREFIX)
|
|
||||||
prefixResults.push(place.id);
|
prefixResults.push(place.id);
|
||||||
else if (mtype == Search.MatchType.MULTIPLE_SUBSTRING)
|
|
||||||
multipleSubstringResults.push(place.id);
|
|
||||||
else if (mtype == Search.MatchType.SUBSTRING)
|
else if (mtype == Search.MatchType.SUBSTRING)
|
||||||
substringResults.push(place.id);
|
substringResults.push(place.id);
|
||||||
}
|
}
|
||||||
multiplePrefixResults.sort(this._compareResultMeta);
|
prefixResults.sort(Lang.bind(this, this._compareResultMeta));
|
||||||
prefixResults.sort(this._compareResultMeta);
|
substringResults.sort(Lang.bind(this, this._compareResultMeta));
|
||||||
multipleSubstringResults.sort(this._compareResultMeta);
|
|
||||||
substringResults.sort(this._compareResultMeta);
|
this.searchSystem.pushResults(this, prefixResults.concat(substringResults));
|
||||||
return multiplePrefixResults.concat(prefixResults.concat(multipleSubstringResults.concat(substringResults)));
|
|
||||||
},
|
},
|
||||||
|
|
||||||
getInitialResultSet: function(terms) {
|
getInitialResultSet: function(terms) {
|
||||||
let places = Main.placesManager.getAllPlaces();
|
let places = this.placesManager.getAllPlaces();
|
||||||
return this._searchPlaces(places, terms);
|
this._searchPlaces(places, terms);
|
||||||
},
|
},
|
||||||
|
|
||||||
getSubsearchResultSet: function(previousResults, terms) {
|
getSubsearchResultSet: function(previousResults, terms) {
|
||||||
let places = previousResults.map(function (id) { return Main.placesManager.lookupPlaceById(id); });
|
let places = previousResults.map(Lang.bind(this, function(id) {
|
||||||
return this._searchPlaces(places, terms);
|
return this.placesManager.lookupPlaceById(id);
|
||||||
|
}));
|
||||||
|
this._searchPlaces(places, terms);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -167,6 +167,7 @@ const AuthenticationDialog = new Lang.Class({
|
|||||||
*/
|
*/
|
||||||
this._nullMessageLabel = new St.Label({ style_class: 'prompt-dialog-null-label',
|
this._nullMessageLabel = new St.Label({ style_class: 'prompt-dialog-null-label',
|
||||||
text: 'abc'});
|
text: 'abc'});
|
||||||
|
this._nullMessageLabel.add_style_class_name('hidden');
|
||||||
this._nullMessageLabel.clutter_text.ellipsize = Pango.EllipsizeMode.NONE;
|
this._nullMessageLabel.clutter_text.ellipsize = Pango.EllipsizeMode.NONE;
|
||||||
this._nullMessageLabel.clutter_text.line_wrap = true;
|
this._nullMessageLabel.clutter_text.line_wrap = true;
|
||||||
messageBox.add(this._nullMessageLabel);
|
messageBox.add(this._nullMessageLabel);
|
||||||
@ -268,7 +269,7 @@ const AuthenticationDialog = new Lang.Class({
|
|||||||
|
|
||||||
_onSessionRequest: function(session, request, echo_on) {
|
_onSessionRequest: function(session, request, echo_on) {
|
||||||
// Cheap localization trick
|
// Cheap localization trick
|
||||||
if (request == 'Password:')
|
if (request == 'Password:' || request == 'Password: ')
|
||||||
this._passwordLabel.set_text(_("Password:"));
|
this._passwordLabel.set_text(_("Password:"));
|
||||||
else
|
else
|
||||||
this._passwordLabel.set_text(request);
|
this._passwordLabel.set_text(request);
|
||||||
|
@ -546,6 +546,10 @@ const PopupSliderMenuItem = new Lang.Class({
|
|||||||
this._slider.connect('repaint', Lang.bind(this, this._sliderRepaint));
|
this._slider.connect('repaint', Lang.bind(this, this._sliderRepaint));
|
||||||
this.actor.connect('button-press-event', Lang.bind(this, this._startDragging));
|
this.actor.connect('button-press-event', Lang.bind(this, this._startDragging));
|
||||||
this.actor.connect('scroll-event', Lang.bind(this, this._onScrollEvent));
|
this.actor.connect('scroll-event', Lang.bind(this, this._onScrollEvent));
|
||||||
|
this.actor.connect('notify::mapped', Lang.bind(this, function() {
|
||||||
|
if (!this.actor.mapped)
|
||||||
|
this._endDragging();
|
||||||
|
}));
|
||||||
|
|
||||||
this._releaseId = this._motionId = 0;
|
this._releaseId = this._motionId = 0;
|
||||||
this._dragging = false;
|
this._dragging = false;
|
||||||
@ -884,8 +888,7 @@ const PopupMenuBase = new Lang.Class({
|
|||||||
},
|
},
|
||||||
|
|
||||||
addSettingsAction: function(title, desktopFile) {
|
addSettingsAction: function(title, desktopFile) {
|
||||||
// Don't allow user settings to get edited unless we're in a user session
|
if (!Main.sessionMode.allowSettings)
|
||||||
if (global.session_type != Shell.SessionType.USER)
|
|
||||||
return null;
|
return null;
|
||||||
|
|
||||||
let menuItem = this.addAction(title, function() {
|
let menuItem = this.addAction(title, function() {
|
||||||
@ -903,7 +906,7 @@ const PopupMenuBase = new Lang.Class({
|
|||||||
},
|
},
|
||||||
|
|
||||||
isEmpty: function() {
|
isEmpty: function() {
|
||||||
return this.box.get_children().length == 0;
|
return this.box.get_n_children() == 0;
|
||||||
},
|
},
|
||||||
|
|
||||||
isChildMenu: function(menu) {
|
isChildMenu: function(menu) {
|
||||||
@ -939,7 +942,7 @@ const PopupMenuBase = new Lang.Class({
|
|||||||
_connectSubMenuSignals: function(object, menu) {
|
_connectSubMenuSignals: function(object, menu) {
|
||||||
object._subMenuActivateId = menu.connect('activate', Lang.bind(this, function() {
|
object._subMenuActivateId = menu.connect('activate', Lang.bind(this, function() {
|
||||||
this.emit('activate');
|
this.emit('activate');
|
||||||
this.close(true);
|
this.close(BoxPointer.PopupAnimation.FULL);
|
||||||
}));
|
}));
|
||||||
object._subMenuActiveChangeId = menu.connect('active-changed', Lang.bind(this, function(submenu, submenuItem) {
|
object._subMenuActiveChangeId = menu.connect('active-changed', Lang.bind(this, function(submenu, submenuItem) {
|
||||||
if (this._activeMenuItem && this._activeMenuItem != submenuItem)
|
if (this._activeMenuItem && this._activeMenuItem != submenuItem)
|
||||||
@ -974,7 +977,7 @@ const PopupMenuBase = new Lang.Class({
|
|||||||
}));
|
}));
|
||||||
menuItem._activateId = menuItem.connect('activate', Lang.bind(this, function (menuItem, event) {
|
menuItem._activateId = menuItem.connect('activate', Lang.bind(this, function (menuItem, event) {
|
||||||
this.emit('activate', menuItem);
|
this.emit('activate', menuItem);
|
||||||
this.close(true);
|
this.close(BoxPointer.PopupAnimation.FULL);
|
||||||
}));
|
}));
|
||||||
// the weird name is to avoid a conflict with some random property
|
// the weird name is to avoid a conflict with some random property
|
||||||
// the menuItem may have, called destroyId
|
// the menuItem may have, called destroyId
|
||||||
@ -1047,7 +1050,7 @@ const PopupMenuBase = new Lang.Class({
|
|||||||
menuItem._closingId = this.connect('open-state-changed',
|
menuItem._closingId = this.connect('open-state-changed',
|
||||||
function(self, open) {
|
function(self, open) {
|
||||||
if (!open)
|
if (!open)
|
||||||
menuItem.close(false);
|
menuItem.close(BoxPointer.PopupAnimation.FADE);
|
||||||
});
|
});
|
||||||
menuItem.connect('destroy', Lang.bind(this, function() {
|
menuItem.connect('destroy', Lang.bind(this, function() {
|
||||||
menuItem.disconnect(menuItem._subMenuActivateId);
|
menuItem.disconnect(menuItem._subMenuActivateId);
|
||||||
@ -1064,7 +1067,7 @@ const PopupMenuBase = new Lang.Class({
|
|||||||
this._connectItemSignals(menuItem);
|
this._connectItemSignals(menuItem);
|
||||||
menuItem._closingId = this.connect('open-state-changed', function(self, open) {
|
menuItem._closingId = this.connect('open-state-changed', function(self, open) {
|
||||||
if (!open)
|
if (!open)
|
||||||
menuItem.menu.close(false);
|
menuItem.menu.close(BoxPointer.PopupAnimation.FADE);
|
||||||
});
|
});
|
||||||
} else if (menuItem instanceof PopupSeparatorMenuItem) {
|
} else if (menuItem instanceof PopupSeparatorMenuItem) {
|
||||||
this._connectItemSignals(menuItem);
|
this._connectItemSignals(menuItem);
|
||||||
@ -1151,9 +1154,9 @@ const PopupMenuBase = new Lang.Class({
|
|||||||
|
|
||||||
toggle: function() {
|
toggle: function() {
|
||||||
if (this.isOpen)
|
if (this.isOpen)
|
||||||
this.close(true);
|
this.close(BoxPointer.PopupAnimation.FULL);
|
||||||
else
|
else
|
||||||
this.open(true);
|
this.open(BoxPointer.PopupAnimation.FULL);
|
||||||
},
|
},
|
||||||
|
|
||||||
destroy: function() {
|
destroy: function() {
|
||||||
@ -1214,7 +1217,7 @@ const PopupMenu = new Lang.Class({
|
|||||||
|
|
||||||
_onKeyPressEvent: function(actor, event) {
|
_onKeyPressEvent: function(actor, event) {
|
||||||
if (event.get_key_symbol() == Clutter.Escape) {
|
if (event.get_key_symbol() == Clutter.Escape) {
|
||||||
this.close(true);
|
this.close(BoxPointer.PopupAnimation.FULL);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1416,7 +1419,7 @@ const PopupSubMenu = new Lang.Class({
|
|||||||
// Move focus back to parent menu if the user types Left.
|
// Move focus back to parent menu if the user types Left.
|
||||||
|
|
||||||
if (this.isOpen && event.get_key_symbol() == Clutter.KEY_Left) {
|
if (this.isOpen && event.get_key_symbol() == Clutter.KEY_Left) {
|
||||||
this.close(true);
|
this.close(BoxPointer.PopupAnimation.FULL);
|
||||||
this.sourceActor._delegate.setActive(true);
|
this.sourceActor._delegate.setActive(true);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -1498,7 +1501,7 @@ const PopupSubMenuMenuItem = new Lang.Class({
|
|||||||
let symbol = event.get_key_symbol();
|
let symbol = event.get_key_symbol();
|
||||||
|
|
||||||
if (symbol == Clutter.KEY_Right) {
|
if (symbol == Clutter.KEY_Right) {
|
||||||
this.menu.open(true);
|
this.menu.open(BoxPointer.PopupAnimation.FULL);
|
||||||
this.menu.actor.navigate_focus(null, Gtk.DirectionType.DOWN, false);
|
this.menu.actor.navigate_focus(null, Gtk.DirectionType.DOWN, false);
|
||||||
return true;
|
return true;
|
||||||
} else if (symbol == Clutter.KEY_Left && this.menu.isOpen) {
|
} else if (symbol == Clutter.KEY_Left && this.menu.isOpen) {
|
||||||
@ -1510,7 +1513,7 @@ const PopupSubMenuMenuItem = new Lang.Class({
|
|||||||
},
|
},
|
||||||
|
|
||||||
activate: function(event) {
|
activate: function(event) {
|
||||||
this.menu.open(true);
|
this.menu.open(BoxPointer.PopupAnimation.FULL);
|
||||||
},
|
},
|
||||||
|
|
||||||
_onButtonReleaseEvent: function(actor) {
|
_onButtonReleaseEvent: function(actor) {
|
||||||
@ -1537,7 +1540,7 @@ const PopupComboMenu = new Lang.Class({
|
|||||||
|
|
||||||
_onKeyPressEvent: function(actor, event) {
|
_onKeyPressEvent: function(actor, event) {
|
||||||
if (event.get_key_symbol() == Clutter.Escape) {
|
if (event.get_key_symbol() == Clutter.Escape) {
|
||||||
this.close(true);
|
this.close(BoxPointer.PopupAnimation.FULL);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1917,7 +1920,7 @@ const RemoteMenu = new Lang.Class({
|
|||||||
while (k0 < currentItems.length && currentItems[k0]._ignored)
|
while (k0 < currentItems.length && currentItems[k0]._ignored)
|
||||||
k0++;
|
k0++;
|
||||||
// find the right menu item matching the model item
|
// find the right menu item matching the model item
|
||||||
for (j0 = 0; j0 < position; j0++, k0++) {
|
for (j0 = 0; k0 < currentItems.length && j0 < position; j0++, k0++) {
|
||||||
if (currentItems[k0]._ignored)
|
if (currentItems[k0]._ignored)
|
||||||
k0++;
|
k0++;
|
||||||
}
|
}
|
||||||
@ -1927,7 +1930,7 @@ const RemoteMenu = new Lang.Class({
|
|||||||
for (k = k0; k < currentItems.length; k++)
|
for (k = k0; k < currentItems.length; k++)
|
||||||
currentItems[k].destroy();
|
currentItems[k].destroy();
|
||||||
} else {
|
} else {
|
||||||
for (j = j0, k = k0; j < j0 + removed; j++, k++) {
|
for (j = j0, k = k0; k < currentItems.length && j < j0 + removed; j++, k++) {
|
||||||
currentItems[k].destroy();
|
currentItems[k].destroy();
|
||||||
|
|
||||||
if (currentItems[k]._ignored)
|
if (currentItems[k]._ignored)
|
||||||
@ -1958,8 +1961,9 @@ const RemoteMenu = new Lang.Class({
|
|||||||
k++;
|
k++;
|
||||||
}
|
}
|
||||||
} else if (changeSignal) {
|
} else if (changeSignal) {
|
||||||
let signalId = this.actionGroup.connect(changeSignal, Lang.bind(this, function() {
|
let signalId = this.actionGroup.connect(changeSignal, Lang.bind(this, function(actionGroup, actionName) {
|
||||||
this.actionGroup.disconnect(signalId);
|
actionGroup.disconnect(signalId);
|
||||||
|
if (this._actions[actionName]) return;
|
||||||
|
|
||||||
// force a full update
|
// force a full update
|
||||||
this._modelChanged(model, 0, -1, model.get_n_items(), target);
|
this._modelChanged(model, 0, -1, model.get_n_items(), target);
|
||||||
@ -2190,11 +2194,11 @@ const PopupMenuManager = new Lang.Class({
|
|||||||
let oldMenu = this._activeMenu;
|
let oldMenu = this._activeMenu;
|
||||||
this._activeMenu = null;
|
this._activeMenu = null;
|
||||||
for (let i = this._menuStack.length - 1; i >= 0; i--)
|
for (let i = this._menuStack.length - 1; i >= 0; i--)
|
||||||
this._menuStack[i].close(false);
|
this._menuStack[i].close(BoxPointer.PopupAnimation.FADE);
|
||||||
oldMenu.close(false);
|
oldMenu.close(BoxPointer.PopupAnimation.FADE);
|
||||||
newMenu.open(false);
|
newMenu.open(BoxPointer.PopupAnimation.FADE);
|
||||||
} else
|
} else
|
||||||
newMenu.open(true);
|
newMenu.open(BoxPointer.PopupAnimation.FULL);
|
||||||
},
|
},
|
||||||
|
|
||||||
_onMenuSourceEnter: function(menu) {
|
_onMenuSourceEnter: function(menu) {
|
||||||
@ -2309,6 +2313,6 @@ const PopupMenuManager = new Lang.Class({
|
|||||||
|
|
||||||
_closeMenu: function() {
|
_closeMenu: function() {
|
||||||
if (this._activeMenu != null)
|
if (this._activeMenu != null)
|
||||||
this._activeMenu.close(true);
|
this._activeMenu.close(BoxPointer.PopupAnimation.FULL);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -62,10 +62,25 @@ function loadRemoteSearchProvidersFromDir(dir, addProviderCallback) {
|
|||||||
let remoteProvider, title;
|
let remoteProvider, title;
|
||||||
try {
|
try {
|
||||||
let group = KEY_FILE_GROUP;
|
let group = KEY_FILE_GROUP;
|
||||||
let icon = keyfile.get_string(group, 'Icon');
|
|
||||||
let busName = keyfile.get_string(group, 'BusName');
|
let busName = keyfile.get_string(group, 'BusName');
|
||||||
let objectPath = keyfile.get_string(group, 'ObjectPath');
|
let objectPath = keyfile.get_string(group, 'ObjectPath');
|
||||||
|
|
||||||
|
let appInfo = null;
|
||||||
|
try {
|
||||||
|
let desktopId = keyfile.get_string(group, 'DesktopId');
|
||||||
|
appInfo = Gio.DesktopAppInfo.new(desktopId);
|
||||||
|
} catch (e) {
|
||||||
|
}
|
||||||
|
|
||||||
|
let icon;
|
||||||
|
if (appInfo) {
|
||||||
|
icon = appInfo.get_icon();
|
||||||
|
title = appInfo.get_name();
|
||||||
|
} else {
|
||||||
|
let iconName = keyfile.get_string(group, 'Icon');
|
||||||
|
icon = new Gio.ThemedIcon({ name: iconName });
|
||||||
title = keyfile.get_locale_string(group, 'Title', null);
|
title = keyfile.get_locale_string(group, 'Title', null);
|
||||||
|
}
|
||||||
|
|
||||||
remoteProvider = new RemoteSearchProvider(title,
|
remoteProvider = new RemoteSearchProvider(title,
|
||||||
icon,
|
icon,
|
||||||
@ -91,7 +106,6 @@ const RemoteSearchProvider = new Lang.Class({
|
|||||||
dbusName, dbusPath);
|
dbusName, dbusPath);
|
||||||
|
|
||||||
this.parent(title.toUpperCase());
|
this.parent(title.toUpperCase());
|
||||||
this.async = true;
|
|
||||||
this._cancellable = new Gio.Cancellable();
|
this._cancellable = new Gio.Cancellable();
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -120,7 +134,7 @@ const RemoteSearchProvider = new Lang.Class({
|
|||||||
this.searchSystem.pushResults(this, results[0]);
|
this.searchSystem.pushResults(this, results[0]);
|
||||||
},
|
},
|
||||||
|
|
||||||
getInitialResultSetAsync: function(terms) {
|
getInitialResultSet: function(terms) {
|
||||||
this._cancellable.cancel();
|
this._cancellable.cancel();
|
||||||
this._cancellable.reset();
|
this._cancellable.reset();
|
||||||
try {
|
try {
|
||||||
@ -133,7 +147,7 @@ const RemoteSearchProvider = new Lang.Class({
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
getSubsearchResultSetAsync: function(previousResults, newTerms) {
|
getSubsearchResultSet: function(previousResults, newTerms) {
|
||||||
this._cancellable.cancel();
|
this._cancellable.cancel();
|
||||||
this._cancellable.reset();
|
this._cancellable.reset();
|
||||||
try {
|
try {
|
||||||
@ -164,7 +178,7 @@ const RemoteSearchProvider = new Lang.Class({
|
|||||||
callback(resultMetas);
|
callback(resultMetas);
|
||||||
},
|
},
|
||||||
|
|
||||||
getResultMetasAsync: function(ids, callback) {
|
getResultMetas: function(ids, callback) {
|
||||||
this._cancellable.cancel();
|
this._cancellable.cancel();
|
||||||
this._cancellable.reset();
|
this._cancellable.reset();
|
||||||
try {
|
try {
|
||||||
|
@ -1,91 +0,0 @@
|
|||||||
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
|
|
||||||
|
|
||||||
const Clutter = imports.gi.Clutter;
|
|
||||||
const Gio = imports.gi.Gio;
|
|
||||||
const Lang = imports.lang;
|
|
||||||
const Meta = imports.gi.Meta;
|
|
||||||
const St = imports.gi.St;
|
|
||||||
|
|
||||||
const GnomeSession = imports.misc.gnomeSession;
|
|
||||||
const Lightbox = imports.ui.lightbox;
|
|
||||||
const LoginDialog = imports.gdm.loginDialog;
|
|
||||||
const Main = imports.ui.main;
|
|
||||||
|
|
||||||
const SCREENSAVER_SCHEMA = 'org.gnome.desktop.screensaver';
|
|
||||||
const LOCK_ENABLED_KEY = 'lock-enabled';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* To test screen shield, make sure to kill gnome-screensaver.
|
|
||||||
*
|
|
||||||
* If you are setting org.gnome.desktop.session.idle-delay directly in dconf,
|
|
||||||
* rather than through System Settings, you also need to set
|
|
||||||
* org.gnome.settings-daemon.plugins.power.sleep-display-ac and
|
|
||||||
* org.gnome.settings-daemon.plugins.power.sleep-display-battery to the same value.
|
|
||||||
* This will ensure that the screen blanks at the right time when it fades out.
|
|
||||||
* https://bugzilla.gnome.org/show_bug.cgi?id=668703 explains the dependance.
|
|
||||||
*/
|
|
||||||
const ScreenShield = new Lang.Class({
|
|
||||||
Name: 'ScreenShield',
|
|
||||||
|
|
||||||
_init: function() {
|
|
||||||
this._presence = new GnomeSession.Presence(Lang.bind(this, function(proxy, error) {
|
|
||||||
this._onStatusChanged(proxy.status);
|
|
||||||
}));
|
|
||||||
this._presence.connectSignal('StatusChanged', Lang.bind(this, function(proxy, senderName, [status]) {
|
|
||||||
this._onStatusChanged(status);
|
|
||||||
}));
|
|
||||||
|
|
||||||
this._settings = new Gio.Settings({ schema: SCREENSAVER_SCHEMA });
|
|
||||||
|
|
||||||
this._group = new St.Widget({ x: 0,
|
|
||||||
y: 0 });
|
|
||||||
Main.uiGroup.add_actor(this._group);
|
|
||||||
let constraint = new Clutter.BindConstraint({ source: global.stage,
|
|
||||||
coordinate: Clutter.BindCoordinate.POSITION | Clutter.BindCoordinate.SIZE });
|
|
||||||
this._group.add_constraint(constraint);
|
|
||||||
this._group.connect('key-press-event', Lang.bind(this, this._onKeyPressEvent));
|
|
||||||
this._group.connect('button-press-event', Lang.bind(this, this._onButtonPressEvent));
|
|
||||||
this._lightbox = new Lightbox.Lightbox(this._group,
|
|
||||||
{ inhibitEvents: true, fadeInTime: 10, fadeFactor: 1 });
|
|
||||||
this._background = Meta.BackgroundActor.new_for_screen(global.screen);
|
|
||||||
this._background.hide();
|
|
||||||
Main.uiGroup.add_actor(this._background);
|
|
||||||
},
|
|
||||||
|
|
||||||
_onStatusChanged: function(status) {
|
|
||||||
log ("in _onStatusChanged");
|
|
||||||
if (status == GnomeSession.PresenceStatus.IDLE) {
|
|
||||||
log("session gone idle");
|
|
||||||
this._group.reactive = true;
|
|
||||||
Main.pushModal(this._group);
|
|
||||||
this._lightbox.show();
|
|
||||||
} else {
|
|
||||||
let lightboxWasShown = this._lightbox.shown;
|
|
||||||
log("this._lightbox.shown " + this._lightbox.shown);
|
|
||||||
this._lightbox.hide();
|
|
||||||
if (lightboxWasShown && this._settings.get_boolean(LOCK_ENABLED_KEY)) {
|
|
||||||
this._background.show();
|
|
||||||
this._background.raise_top();
|
|
||||||
} else {
|
|
||||||
this._popModal();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
_popModal: function() {
|
|
||||||
this._group.reactive = false;
|
|
||||||
if (Main.isInModalStack(this._group))
|
|
||||||
Main.popModal(this._group);
|
|
||||||
this._background.hide();
|
|
||||||
},
|
|
||||||
|
|
||||||
_onKeyPressEvent: function(object, keyPressEvent) {
|
|
||||||
log("in _onKeyPressEvent - lock is enabled: " + this._settings.get_boolean(LOCK_ENABLED_KEY));
|
|
||||||
this._popModal();
|
|
||||||
},
|
|
||||||
|
|
||||||
_onButtonPressEvent: function(object, buttonPressEvent) {
|
|
||||||
log("in _onButtonPressEvent - lock is enabled: " + this._settings.get_boolean(LOCK_ENABLED_KEY));
|
|
||||||
this._popModal();
|
|
||||||
},
|
|
||||||
});
|
|
104
js/ui/search.js
104
js/ui/search.js
@ -18,9 +18,7 @@ const DISABLED_OPEN_SEARCH_PROVIDERS_KEY = 'disabled-open-search-providers';
|
|||||||
const MatchType = {
|
const MatchType = {
|
||||||
NONE: 0,
|
NONE: 0,
|
||||||
SUBSTRING: 1,
|
SUBSTRING: 1,
|
||||||
MULTIPLE_SUBSTRING: 2,
|
PREFIX: 2
|
||||||
PREFIX: 3,
|
|
||||||
MULTIPLE_PREFIX: 4
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const SearchResultDisplay = new Lang.Class({
|
const SearchResultDisplay = new Lang.Class({
|
||||||
@ -53,7 +51,7 @@ const SearchResultDisplay = new Lang.Class({
|
|||||||
* Remove all results from this display.
|
* Remove all results from this display.
|
||||||
*/
|
*/
|
||||||
clear: function() {
|
clear: function() {
|
||||||
this.actor.get_children().forEach(function (actor) { actor.destroy(); });
|
this.actor.destroy_all_children();
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -72,11 +70,8 @@ const SearchResultDisplay = new Lang.Class({
|
|||||||
* Subclass this object to add a new result type
|
* Subclass this object to add a new result type
|
||||||
* to the search system, then call registerProvider()
|
* to the search system, then call registerProvider()
|
||||||
* in SearchSystem with an instance.
|
* in SearchSystem with an instance.
|
||||||
* By default, search is synchronous and uses the
|
* Search is asynchronous and uses the
|
||||||
* getInitialResultSet()/getSubsearchResultSet() methods.
|
* getInitialResultSet()/getSubsearchResultSet() methods.
|
||||||
* For asynchronous search, set the async property to true
|
|
||||||
* and implement getInitialResultSetAsync()/getSubsearchResultSetAsync()
|
|
||||||
* instead.
|
|
||||||
*/
|
*/
|
||||||
const SearchProvider = new Lang.Class({
|
const SearchProvider = new Lang.Class({
|
||||||
Name: 'SearchProvider',
|
Name: 'SearchProvider',
|
||||||
@ -84,7 +79,6 @@ const SearchProvider = new Lang.Class({
|
|||||||
_init: function(title) {
|
_init: function(title) {
|
||||||
this.title = title;
|
this.title = title;
|
||||||
this.searchSystem = null;
|
this.searchSystem = null;
|
||||||
this.async = false;
|
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -95,7 +89,7 @@ const SearchProvider = new Lang.Class({
|
|||||||
* therefore a single term of length one or two), or when
|
* therefore a single term of length one or two), or when
|
||||||
* a new term is added.
|
* a new term is added.
|
||||||
*
|
*
|
||||||
* Should return an array of result identifier strings representing
|
* Should "return" an array of result identifier strings representing
|
||||||
* items which match the given search terms. This
|
* items which match the given search terms. This
|
||||||
* is expected to be a substring match on the metadata for a given
|
* is expected to be a substring match on the metadata for a given
|
||||||
* item. Ordering of returned results is up to the discretion of the provider,
|
* item. Ordering of returned results is up to the discretion of the provider,
|
||||||
@ -105,6 +99,9 @@ const SearchProvider = new Lang.Class({
|
|||||||
* description) before single matches
|
* description) before single matches
|
||||||
* * Put items which match on a prefix before non-prefix substring matches
|
* * Put items which match on a prefix before non-prefix substring matches
|
||||||
*
|
*
|
||||||
|
* We say "return" above, but in order to make the query asynchronous, use
|
||||||
|
* this.searchSystem.pushResults();. The return value should be ignored.
|
||||||
|
*
|
||||||
* This function should be fast; do not perform unindexed full-text searches
|
* This function should be fast; do not perform unindexed full-text searches
|
||||||
* or network queries.
|
* or network queries.
|
||||||
*/
|
*/
|
||||||
@ -112,18 +109,6 @@ const SearchProvider = new Lang.Class({
|
|||||||
throw new Error('Not implemented');
|
throw new Error('Not implemented');
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
|
||||||
* getInitialResultSetAsync:
|
|
||||||
* @terms: Array of search terms, treated as logical AND
|
|
||||||
*
|
|
||||||
* Like getInitialResultSet(), but the method should return immediately
|
|
||||||
* without a return value - use SearchSystem.pushResults() when the
|
|
||||||
* corresponding results are ready.
|
|
||||||
*/
|
|
||||||
getInitialResultSetAsync: function(terms) {
|
|
||||||
throw new Error('Not implemented');
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* getSubsearchResultSet:
|
* getSubsearchResultSet:
|
||||||
* @previousResults: Array of item identifiers
|
* @previousResults: Array of item identifiers
|
||||||
@ -136,62 +121,26 @@ const SearchProvider = new Lang.Class({
|
|||||||
*
|
*
|
||||||
* This allows search providers to only search through the previous
|
* This allows search providers to only search through the previous
|
||||||
* result set, rather than possibly performing a full re-query.
|
* result set, rather than possibly performing a full re-query.
|
||||||
|
*
|
||||||
|
* Similar to getInitialResultSet, the return value for this will
|
||||||
|
* be ignored; use this.searchSystem.pushResults();.
|
||||||
*/
|
*/
|
||||||
getSubsearchResultSet: function(previousResults, newTerms) {
|
getSubsearchResultSet: function(previousResults, newTerms) {
|
||||||
throw new Error('Not implemented');
|
throw new Error('Not implemented');
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
|
||||||
* getSubsearchResultSetAsync:
|
|
||||||
* @previousResults: Array of item identifiers
|
|
||||||
* @newTerms: Updated search terms
|
|
||||||
*
|
|
||||||
* Like getSubsearchResultSet(), but the method should return immediately
|
|
||||||
* without a return value - use SearchSystem.pushResults() when the
|
|
||||||
* corresponding results are ready.
|
|
||||||
*/
|
|
||||||
getSubsearchResultSetAsync: function(previousResults, newTerms) {
|
|
||||||
throw new Error('Not implemented');
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* getResultMetas:
|
* getResultMetas:
|
||||||
* @ids: Result identifier strings
|
* @ids: Result identifier strings
|
||||||
*
|
*
|
||||||
* Return an array of objects with 'id', 'name', (both strings) and
|
* Call callback with array of objects with 'id', 'name', (both strings) and
|
||||||
* 'createIcon' (function(size) returning a Clutter.Texture) properties
|
* 'createIcon' (function(size) returning a Clutter.Texture) properties
|
||||||
* with the same number of members as @ids
|
* with the same number of members as @ids
|
||||||
*/
|
*/
|
||||||
getResultMetas: function(ids) {
|
getResultMetas: function(ids, callback) {
|
||||||
throw new Error('Not implemented');
|
throw new Error('Not implemented');
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
|
||||||
* getResultMetasAsync:
|
|
||||||
* @ids: Result identifier strings
|
|
||||||
* @callback: callback to pass the results to when ready
|
|
||||||
*
|
|
||||||
* Like getResultMetas(), but the method should return immediately
|
|
||||||
* without a return value - pass the results to the provided @callback
|
|
||||||
* when ready.
|
|
||||||
*/
|
|
||||||
getResultMetasAsync: function(ids, callback) {
|
|
||||||
throw new Error('Not implemented');
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* createResultContainer:
|
|
||||||
*
|
|
||||||
* Search providers may optionally override this to render their
|
|
||||||
* results in a custom fashion. The default implementation
|
|
||||||
* will create a vertical list.
|
|
||||||
*
|
|
||||||
* Returns: An instance of SearchResultDisplay.
|
|
||||||
*/
|
|
||||||
createResultContainerActor: function() {
|
|
||||||
return null;
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* createResultActor:
|
* createResultActor:
|
||||||
* @resultMeta: Object with result metadata
|
* @resultMeta: Object with result metadata
|
||||||
@ -379,42 +328,33 @@ const SearchSystem = new Lang.Class({
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let previousResultsArr = this._previousResults;
|
||||||
|
|
||||||
let results = [];
|
let results = [];
|
||||||
|
this._previousTerms = terms;
|
||||||
|
this._previousResults = results;
|
||||||
|
|
||||||
if (isSubSearch) {
|
if (isSubSearch) {
|
||||||
for (let i = 0; i < this._providers.length; i++) {
|
for (let i = 0; i < this._providers.length; i++) {
|
||||||
let [provider, previousResults] = this._previousResults[i];
|
let [provider, previousResults] = previousResultsArr[i];
|
||||||
try {
|
try {
|
||||||
if (provider.async) {
|
|
||||||
provider.getSubsearchResultSetAsync(previousResults, terms);
|
|
||||||
results.push([provider, []]);
|
results.push([provider, []]);
|
||||||
} else {
|
provider.getSubsearchResultSet(previousResults, terms);
|
||||||
let providerResults = provider.getSubsearchResultSet(previousResults, terms);
|
|
||||||
results.push([provider, providerResults]);
|
|
||||||
}
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
global.log ('A ' + error.name + ' has occured in ' + provider.title + ': ' + error.message);
|
log('A ' + error.name + ' has occured in ' + provider.title + ': ' + error.message);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
for (let i = 0; i < this._providers.length; i++) {
|
for (let i = 0; i < this._providers.length; i++) {
|
||||||
let provider = this._providers[i];
|
let provider = this._providers[i];
|
||||||
try {
|
try {
|
||||||
if (provider.async) {
|
|
||||||
provider.getInitialResultSetAsync(terms);
|
|
||||||
results.push([provider, []]);
|
results.push([provider, []]);
|
||||||
} else {
|
provider.getInitialResultSet(terms);
|
||||||
let providerResults = provider.getInitialResultSet(terms);
|
|
||||||
results.push([provider, providerResults]);
|
|
||||||
}
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
global.log ('A ' + error.name + ' has occured in ' + provider.title + ': ' + error.message);
|
log('A ' + error.name + ' has occured in ' + provider.title + ': ' + error.message);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
this._previousTerms = terms;
|
|
||||||
this._previousResults = results;
|
|
||||||
this.emit('search-completed', results);
|
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
Signals.addSignalMethods(SearchSystem.prototype);
|
Signals.addSignalMethods(SearchSystem.prototype);
|
||||||
|
@ -5,6 +5,7 @@ const Lang = imports.lang;
|
|||||||
const Gtk = imports.gi.Gtk;
|
const Gtk = imports.gi.Gtk;
|
||||||
const Meta = imports.gi.Meta;
|
const Meta = imports.gi.Meta;
|
||||||
const St = imports.gi.St;
|
const St = imports.gi.St;
|
||||||
|
const Atk = imports.gi.Atk;
|
||||||
|
|
||||||
const DND = imports.ui.dnd;
|
const DND = imports.ui.dnd;
|
||||||
const IconGrid = imports.ui.iconGrid;
|
const IconGrid = imports.ui.iconGrid;
|
||||||
@ -33,12 +34,13 @@ const SearchResult = new Lang.Class({
|
|||||||
content = new St.Bin({ style_class: 'search-result-content',
|
content = new St.Bin({ style_class: 'search-result-content',
|
||||||
reactive: true,
|
reactive: true,
|
||||||
can_focus: true,
|
can_focus: true,
|
||||||
track_hover: true });
|
track_hover: true,
|
||||||
|
accessible_role: Atk.Role.PUSH_BUTTON });
|
||||||
let icon = new IconGrid.BaseIcon(this.metaInfo['name'],
|
let icon = new IconGrid.BaseIcon(this.metaInfo['name'],
|
||||||
{ createIcon: this.metaInfo['createIcon'] });
|
{ createIcon: this.metaInfo['createIcon'] });
|
||||||
content.set_child(icon.actor);
|
content.set_child(icon.actor);
|
||||||
this._dragActorSource = icon.icon;
|
this._dragActorSource = icon.icon;
|
||||||
this.actor.label_actor = icon.label;
|
content.label_actor = icon.label;
|
||||||
} else {
|
} else {
|
||||||
if (content._delegate && content._delegate.getDragActorSource)
|
if (content._delegate && content._delegate.getDragActorSource)
|
||||||
this._dragActorSource = content._delegate.getDragActorSource();
|
this._dragActorSource = content._delegate.getDragActorSource();
|
||||||
@ -119,13 +121,7 @@ const GridSearchResults = new Lang.Class({
|
|||||||
if (results.length == 0)
|
if (results.length == 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (provider.async) {
|
provider.getResultMetas(results, Lang.bind(this, this.renderResults));
|
||||||
provider.getResultMetasAsync(results,
|
|
||||||
Lang.bind(this, this.renderResults));
|
|
||||||
} else {
|
|
||||||
let metas = provider.getResultMetas(results);
|
|
||||||
this.renderResults(metas);
|
|
||||||
}
|
|
||||||
}));
|
}));
|
||||||
}));
|
}));
|
||||||
this._notDisplayedResult = [];
|
this._notDisplayedResult = [];
|
||||||
@ -135,7 +131,7 @@ const GridSearchResults = new Lang.Class({
|
|||||||
|
|
||||||
getResultsForDisplay: function() {
|
getResultsForDisplay: function() {
|
||||||
let alreadyVisible = this._pendingClear ? 0 : this._grid.visibleItemsCount();
|
let alreadyVisible = this._pendingClear ? 0 : this._grid.visibleItemsCount();
|
||||||
let canDisplay = this._grid.childrenInRow(this._width) * MAX_SEARCH_RESULTS_ROWS
|
let canDisplay = this._grid.childrenInRow(this._width) * this._grid.getRowLimit()
|
||||||
- alreadyVisible;
|
- alreadyVisible;
|
||||||
|
|
||||||
let numResults = Math.min(this._notDisplayedResult.length, canDisplay);
|
let numResults = Math.min(this._notDisplayedResult.length, canDisplay);
|
||||||
@ -179,8 +175,7 @@ const SearchResults = new Lang.Class({
|
|||||||
|
|
||||||
_init: function(searchSystem, openSearchSystem) {
|
_init: function(searchSystem, openSearchSystem) {
|
||||||
this._searchSystem = searchSystem;
|
this._searchSystem = searchSystem;
|
||||||
this._searchSystem.connect('search-updated', Lang.bind(this, this._updateCurrentResults));
|
this._searchSystem.connect('search-updated', Lang.bind(this, this._updateResults));
|
||||||
this._searchSystem.connect('search-completed', Lang.bind(this, this._updateResults));
|
|
||||||
this._openSearchSystem = openSearchSystem;
|
this._openSearchSystem = openSearchSystem;
|
||||||
|
|
||||||
this.actor = new St.BoxLayout({ name: 'searchResults',
|
this.actor = new St.BoxLayout({ name: 'searchResults',
|
||||||
@ -214,10 +209,8 @@ const SearchResults = new Lang.Class({
|
|||||||
this._content.add(this._statusText);
|
this._content.add(this._statusText);
|
||||||
this._providers = this._searchSystem.getProviders();
|
this._providers = this._searchSystem.getProviders();
|
||||||
this._providerMeta = [];
|
this._providerMeta = [];
|
||||||
this._providerMetaResults = {};
|
|
||||||
for (let i = 0; i < this._providers.length; i++) {
|
for (let i = 0; i < this._providers.length; i++) {
|
||||||
this.createProviderMeta(this._providers[i]);
|
this.createProviderMeta(this._providers[i]);
|
||||||
this._providerMetaResults[this.providers[i].title] = [];
|
|
||||||
}
|
}
|
||||||
this._searchProvidersBox = new St.BoxLayout({ style_class: 'search-providers-box' });
|
this._searchProvidersBox = new St.BoxLayout({ style_class: 'search-providers-box' });
|
||||||
this.actor.add(this._searchProvidersBox);
|
this.actor.add(this._searchProvidersBox);
|
||||||
@ -282,16 +275,12 @@ const SearchResults = new Lang.Class({
|
|||||||
x_fill: true,
|
x_fill: true,
|
||||||
y_fill: true });
|
y_fill: true });
|
||||||
providerBox.add(resultDisplayBin, { expand: true });
|
providerBox.add(resultDisplayBin, { expand: true });
|
||||||
let resultDisplay = provider.createResultContainerActor();
|
let resultDisplay = new GridSearchResults(provider);
|
||||||
if (resultDisplay == null) {
|
|
||||||
resultDisplay = new GridSearchResults(provider);
|
|
||||||
}
|
|
||||||
resultDisplayBin.set_child(resultDisplay.actor);
|
resultDisplayBin.set_child(resultDisplay.actor);
|
||||||
|
|
||||||
this._providerMeta.push({ provider: provider,
|
this._providerMeta.push({ provider: provider,
|
||||||
actor: providerBox,
|
actor: providerBox,
|
||||||
resultDisplay: resultDisplay,
|
resultDisplay: resultDisplay });
|
||||||
hasPendingResults: false });
|
|
||||||
this._content.add(providerBox);
|
this._content.add(providerBox);
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -307,7 +296,6 @@ const SearchResults = new Lang.Class({
|
|||||||
},
|
},
|
||||||
|
|
||||||
_clearDisplay: function() {
|
_clearDisplay: function() {
|
||||||
this._visibleResultsCount = 0;
|
|
||||||
for (let i = 0; i < this._providerMeta.length; i++) {
|
for (let i = 0; i < this._providerMeta.length; i++) {
|
||||||
let meta = this._providerMeta[i];
|
let meta = this._providerMeta[i];
|
||||||
meta.resultDisplay.clear();
|
meta.resultDisplay.clear();
|
||||||
@ -335,6 +323,8 @@ const SearchResults = new Lang.Class({
|
|||||||
|
|
||||||
doSearch: function (searchString) {
|
doSearch: function (searchString) {
|
||||||
this._searchSystem.updateSearch(searchString);
|
this._searchSystem.updateSearch(searchString);
|
||||||
|
let terms = this._searchSystem.getTerms();
|
||||||
|
this._openSearchSystem.setSearchTerms(terms);
|
||||||
},
|
},
|
||||||
|
|
||||||
_metaForProvider: function(provider) {
|
_metaForProvider: function(provider) {
|
||||||
@ -346,8 +336,6 @@ const SearchResults = new Lang.Class({
|
|||||||
|
|
||||||
for (let i = 0; i < this._providerMeta.length; i++) {
|
for (let i = 0; i < this._providerMeta.length; i++) {
|
||||||
let meta = this._providerMeta[i];
|
let meta = this._providerMeta[i];
|
||||||
if (meta.hasPendingResults)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (!meta.actor.visible)
|
if (!meta.actor.visible)
|
||||||
continue;
|
continue;
|
||||||
@ -372,71 +360,57 @@ const SearchResults = new Lang.Class({
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
_updateCurrentResults: function(searchSystem, results) {
|
_updateStatusText: function () {
|
||||||
let terms = searchSystem.getTerms();
|
let haveResults = false;
|
||||||
let [provider, providerResults] = results;
|
|
||||||
let meta = this._metaForProvider(provider);
|
|
||||||
meta.hasPendingResults = false;
|
|
||||||
this._updateProviderResults(provider, providerResults, terms);
|
|
||||||
},
|
|
||||||
|
|
||||||
_updateProviderResults: function(provider, providerResults, terms) {
|
for (let i = 0; i < this._providerMeta.length; ++i)
|
||||||
let meta = this._metaForProvider(provider);
|
if (this._providerMeta[i].resultDisplay.getFirstResult()) {
|
||||||
if (providerResults.length == 0) {
|
haveResults = true;
|
||||||
this._clearDisplayForProvider(provider);
|
break;
|
||||||
meta.resultDisplay.setResults([], []);
|
|
||||||
} else {
|
|
||||||
this._providerMetaResults[provider.title] = providerResults;
|
|
||||||
meta.resultDisplay.setResults(providerResults, terms);
|
|
||||||
let results = meta.resultDisplay.getResultsForDisplay();
|
|
||||||
|
|
||||||
if (provider.async) {
|
|
||||||
provider.getResultMetasAsync(results, Lang.bind(this,
|
|
||||||
function(metas) {
|
|
||||||
this._clearDisplayForProvider(provider);
|
|
||||||
meta.actor.show();
|
|
||||||
this._content.hide();
|
|
||||||
meta.resultDisplay.renderResults(metas);
|
|
||||||
this._maybeSetInitialSelection();
|
|
||||||
this._content.show();
|
|
||||||
}));
|
|
||||||
} else {
|
|
||||||
let metas = provider.getResultMetas(results);
|
|
||||||
this._clearDisplayForProvider(provider);
|
|
||||||
meta.actor.show();
|
|
||||||
meta.resultDisplay.renderResults(metas);
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
_updateResults: function(searchSystem, results) {
|
if (!haveResults) {
|
||||||
if (results.length == 0) {
|
|
||||||
this._statusText.set_text(_("No matching results."));
|
this._statusText.set_text(_("No matching results."));
|
||||||
this._statusText.show();
|
this._statusText.show();
|
||||||
} else {
|
} else {
|
||||||
this._statusText.hide();
|
this._statusText.hide();
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
_updateResults: function(searchSystem, results) {
|
||||||
let terms = searchSystem.getTerms();
|
let terms = searchSystem.getTerms();
|
||||||
this._openSearchSystem.setSearchTerms(terms);
|
let [provider, providerResults] = results;
|
||||||
|
let meta = this._metaForProvider(provider);
|
||||||
|
|
||||||
// To avoid CSS transitions causing flickering when the first search
|
if (providerResults.length == 0) {
|
||||||
// result stays the same, we hide the content while filling in the
|
this._clearDisplayForProvider(provider);
|
||||||
// results.
|
meta.resultDisplay.setResults([], []);
|
||||||
|
this._maybeSetInitialSelection();
|
||||||
|
this._updateStatusText();
|
||||||
|
} else {
|
||||||
|
meta.resultDisplay.setResults(providerResults, terms);
|
||||||
|
let results = meta.resultDisplay.getResultsForDisplay();
|
||||||
|
|
||||||
|
provider.getResultMetas(results, Lang.bind(this, function(metas) {
|
||||||
|
this._clearDisplayForProvider(provider);
|
||||||
|
meta.actor.show();
|
||||||
|
|
||||||
|
// Hiding drops the key focus if we have it
|
||||||
|
let focus = global.stage.get_key_focus();
|
||||||
|
// To avoid CSS transitions causing flickering when
|
||||||
|
// the first search result stays the same, we hide the
|
||||||
|
// content while filling in the results.
|
||||||
this._content.hide();
|
this._content.hide();
|
||||||
|
|
||||||
for (let i = 0; i < results.length; i++) {
|
meta.resultDisplay.renderResults(metas);
|
||||||
let [provider, providerResults] = results[i];
|
|
||||||
let meta = this._metaForProvider(provider);
|
|
||||||
meta.hasPendingResults = provider.async;
|
|
||||||
if (!meta.hasPendingResults)
|
|
||||||
this._updateProviderResults(provider, providerResults, terms);
|
|
||||||
}
|
|
||||||
|
|
||||||
this._maybeSetInitialSelection();
|
this._maybeSetInitialSelection();
|
||||||
this._content.show();
|
this._updateStatusText();
|
||||||
|
|
||||||
return true;
|
this._content.show();
|
||||||
|
if (this._content.contains(focus))
|
||||||
|
global.stage.set_key_focus(focus);
|
||||||
|
}));
|
||||||
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
activateDefault: function() {
|
activateDefault: function() {
|
||||||
|
124
js/ui/sessionMode.js
Normal file
124
js/ui/sessionMode.js
Normal file
@ -0,0 +1,124 @@
|
|||||||
|
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
|
||||||
|
|
||||||
|
const Lang = imports.lang;
|
||||||
|
|
||||||
|
const Config = imports.misc.config;
|
||||||
|
const Main = imports.ui.main;
|
||||||
|
const Params = imports.misc.params;
|
||||||
|
|
||||||
|
|
||||||
|
const STANDARD_STATUS_AREA_SHELL_IMPLEMENTATION = {
|
||||||
|
'a11y': imports.ui.status.accessibility.ATIndicator,
|
||||||
|
'volume': imports.ui.status.volume.Indicator,
|
||||||
|
'battery': imports.ui.status.power.Indicator,
|
||||||
|
'keyboard': imports.ui.status.keyboard.InputSourceIndicator,
|
||||||
|
'userMenu': imports.ui.userMenu.UserMenuButton
|
||||||
|
};
|
||||||
|
|
||||||
|
if (Config.HAVE_BLUETOOTH)
|
||||||
|
STANDARD_STATUS_AREA_SHELL_IMPLEMENTATION['bluetooth'] =
|
||||||
|
imports.ui.status.bluetooth.Indicator;
|
||||||
|
|
||||||
|
try {
|
||||||
|
STANDARD_STATUS_AREA_SHELL_IMPLEMENTATION['network'] =
|
||||||
|
imports.ui.status.network.NMApplet;
|
||||||
|
} catch(e) {
|
||||||
|
log('NMApplet is not supported. It is possible that your NetworkManager version is too old');
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const DEFAULT_MODE = 'user';
|
||||||
|
|
||||||
|
const _modes = {
|
||||||
|
'gdm': { hasOverview: false,
|
||||||
|
hasAppMenu: false,
|
||||||
|
showCalendarEvents: false,
|
||||||
|
allowSettings: false,
|
||||||
|
allowExtensions: false,
|
||||||
|
allowKeybindingsWhenModal: true,
|
||||||
|
hasRunDialog: false,
|
||||||
|
hasWorkspaces: false,
|
||||||
|
createSession: Main.createGDMSession,
|
||||||
|
extraStylesheet: global.datadir + '/theme/gdm.css',
|
||||||
|
statusArea: {
|
||||||
|
order: [
|
||||||
|
'a11y', 'display', 'keyboard',
|
||||||
|
'volume', 'battery', 'powerMenu'
|
||||||
|
],
|
||||||
|
implementation: {
|
||||||
|
'a11y': imports.ui.status.accessibility.ATIndicator,
|
||||||
|
'volume': imports.ui.status.volume.Indicator,
|
||||||
|
'battery': imports.ui.status.power.Indicator,
|
||||||
|
'keyboard': imports.ui.status.keyboard.InputSourceIndicator,
|
||||||
|
'powerMenu': imports.gdm.powerMenu.PowerMenuButton
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
'initial-setup': { hasOverview: false,
|
||||||
|
hasAppMenu: false,
|
||||||
|
showCalendarEvents: false,
|
||||||
|
allowSettings: false,
|
||||||
|
allowExtensions: false,
|
||||||
|
allowKeybindingsWhenModal: false,
|
||||||
|
hasRunDialog: false,
|
||||||
|
hasWorkspaces: false,
|
||||||
|
createSession: Main.createInitialSetupSession,
|
||||||
|
extraStylesheet: null,
|
||||||
|
statusArea: {
|
||||||
|
order: [
|
||||||
|
'a11y', 'keyboard', 'volume'
|
||||||
|
],
|
||||||
|
implementation: {
|
||||||
|
'a11y': imports.ui.status.accessibility.ATIndicator,
|
||||||
|
'keyboard': imports.ui.status.keyboard.XKBIndicator,
|
||||||
|
'volume': imports.ui.status.volume.Indicator
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
'user': { hasOverview: true,
|
||||||
|
hasAppMenu: true,
|
||||||
|
showCalendarEvents: true,
|
||||||
|
allowSettings: true,
|
||||||
|
allowExtensions: true,
|
||||||
|
allowKeybindingsWhenModal: false,
|
||||||
|
hasRunDialog: true,
|
||||||
|
hasWorkspaces: true,
|
||||||
|
createSession: Main.createUserSession,
|
||||||
|
extraStylesheet: null,
|
||||||
|
statusArea: {
|
||||||
|
order: [
|
||||||
|
'input-method', 'a11y', 'keyboard', 'volume', 'bluetooth',
|
||||||
|
'network', 'battery', 'userMenu'
|
||||||
|
],
|
||||||
|
implementation: STANDARD_STATUS_AREA_SHELL_IMPLEMENTATION
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
function listModes() {
|
||||||
|
let modes = Object.getOwnPropertyNames(_modes);
|
||||||
|
for (let i = 0; i < modes.length; i++)
|
||||||
|
print(modes[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
const SessionMode = new Lang.Class({
|
||||||
|
Name: 'SessionMode',
|
||||||
|
|
||||||
|
_init: function() {
|
||||||
|
let params = _modes[global.session_mode];
|
||||||
|
|
||||||
|
params = Params.parse(params, _modes[DEFAULT_MODE]);
|
||||||
|
|
||||||
|
this._createSession = params.createSession;
|
||||||
|
delete params.createSession;
|
||||||
|
|
||||||
|
Lang.copyProperties(params, this);
|
||||||
|
},
|
||||||
|
|
||||||
|
createSession: function() {
|
||||||
|
if (this._createSession)
|
||||||
|
this._createSession();
|
||||||
|
}
|
||||||
|
});
|
@ -7,6 +7,7 @@ const Shell = imports.gi.Shell;
|
|||||||
|
|
||||||
const Config = imports.misc.config;
|
const Config = imports.misc.config;
|
||||||
const ExtensionSystem = imports.ui.extensionSystem;
|
const ExtensionSystem = imports.ui.extensionSystem;
|
||||||
|
const ExtensionDownloader = imports.ui.extensionDownloader;
|
||||||
const ExtensionUtils = imports.misc.extensionUtils;
|
const ExtensionUtils = imports.misc.extensionUtils;
|
||||||
const Flashspot = imports.ui.flashspot;
|
const Flashspot = imports.ui.flashspot;
|
||||||
const Main = imports.ui.main;
|
const Main = imports.ui.main;
|
||||||
@ -17,17 +18,6 @@ const GnomeShellIface = <interface name="org.gnome.Shell">
|
|||||||
<arg type="b" direction="out" name="success" />
|
<arg type="b" direction="out" name="success" />
|
||||||
<arg type="s" direction="out" name="result" />
|
<arg type="s" direction="out" name="result" />
|
||||||
</method>
|
</method>
|
||||||
<method name="ListExtensions">
|
|
||||||
<arg type="a{sa{sv}}" direction="out" name="extensions" />
|
|
||||||
</method>
|
|
||||||
<method name="GetExtensionInfo">
|
|
||||||
<arg type="s" direction="in" name="extension" />
|
|
||||||
<arg type="a{sv}" direction="out" name="info" />
|
|
||||||
</method>
|
|
||||||
<method name="GetExtensionErrors">
|
|
||||||
<arg type="s" direction="in" name="extension" />
|
|
||||||
<arg type="as" direction="out" name="errors" />
|
|
||||||
</method>
|
|
||||||
<method name="ScreenshotArea">
|
<method name="ScreenshotArea">
|
||||||
<arg type="i" direction="in" name="x"/>
|
<arg type="i" direction="in" name="x"/>
|
||||||
<arg type="i" direction="in" name="y"/>
|
<arg type="i" direction="in" name="y"/>
|
||||||
@ -56,31 +46,8 @@ const GnomeShellIface = <interface name="org.gnome.Shell">
|
|||||||
<arg type="i" direction="in" name="width"/>
|
<arg type="i" direction="in" name="width"/>
|
||||||
<arg type="i" direction="in" name="height"/>
|
<arg type="i" direction="in" name="height"/>
|
||||||
</method>
|
</method>
|
||||||
<method name="EnableExtension">
|
|
||||||
<arg type="s" direction="in" name="uuid"/>
|
|
||||||
</method>
|
|
||||||
<method name="DisableExtension">
|
|
||||||
<arg type="s" direction="in" name="uuid"/>
|
|
||||||
</method>
|
|
||||||
<method name="InstallRemoteExtension">
|
|
||||||
<arg type="s" direction="in" name="uuid"/>
|
|
||||||
<arg type="s" direction="in" name="version"/>
|
|
||||||
</method>
|
|
||||||
<method name="UninstallExtension">
|
|
||||||
<arg type="s" direction="in" name="uuid"/>
|
|
||||||
<arg type="b" direction="out" name="success"/>
|
|
||||||
</method>
|
|
||||||
<method name="LaunchExtensionPrefs">
|
|
||||||
<arg type="s" direction="in" name="uuid"/>
|
|
||||||
</method>
|
|
||||||
<property name="OverviewActive" type="b" access="readwrite" />
|
<property name="OverviewActive" type="b" access="readwrite" />
|
||||||
<property name="ApiVersion" type="i" access="read" />
|
|
||||||
<property name="ShellVersion" type="s" access="read" />
|
<property name="ShellVersion" type="s" access="read" />
|
||||||
<signal name="ExtensionStatusChanged">
|
|
||||||
<arg type="s" name="uuid"/>
|
|
||||||
<arg type="i" name="state"/>
|
|
||||||
<arg type="s" name="error"/>
|
|
||||||
</signal>
|
|
||||||
</interface>;
|
</interface>;
|
||||||
|
|
||||||
const GnomeShell = new Lang.Class({
|
const GnomeShell = new Lang.Class({
|
||||||
@ -89,8 +56,8 @@ const GnomeShell = new Lang.Class({
|
|||||||
_init: function() {
|
_init: function() {
|
||||||
this._dbusImpl = Gio.DBusExportedObject.wrapJSObject(GnomeShellIface, this);
|
this._dbusImpl = Gio.DBusExportedObject.wrapJSObject(GnomeShellIface, this);
|
||||||
this._dbusImpl.export(Gio.DBus.session, '/org/gnome/Shell');
|
this._dbusImpl.export(Gio.DBus.session, '/org/gnome/Shell');
|
||||||
ExtensionSystem.connect('extension-state-changed',
|
|
||||||
Lang.bind(this, this._extensionStateChanged));
|
this._extensionsSerivce = new GnomeShellExtensions();
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -202,6 +169,67 @@ const GnomeShell = new Lang.Class({
|
|||||||
flashspot.fire();
|
flashspot.fire();
|
||||||
},
|
},
|
||||||
|
|
||||||
|
get OverviewActive() {
|
||||||
|
return Main.overview.visible;
|
||||||
|
},
|
||||||
|
|
||||||
|
set OverviewActive(visible) {
|
||||||
|
if (visible)
|
||||||
|
Main.overview.show();
|
||||||
|
else
|
||||||
|
Main.overview.hide();
|
||||||
|
},
|
||||||
|
|
||||||
|
ShellVersion: Config.PACKAGE_VERSION
|
||||||
|
});
|
||||||
|
|
||||||
|
const GnomeShellExtensionsIface = <interface name="org.gnome.Shell.Extensions">
|
||||||
|
<method name="ListExtensions">
|
||||||
|
<arg type="a{sa{sv}}" direction="out" name="extensions" />
|
||||||
|
</method>
|
||||||
|
<method name="GetExtensionInfo">
|
||||||
|
<arg type="s" direction="in" name="extension" />
|
||||||
|
<arg type="a{sv}" direction="out" name="info" />
|
||||||
|
</method>
|
||||||
|
<method name="GetExtensionErrors">
|
||||||
|
<arg type="s" direction="in" name="extension" />
|
||||||
|
<arg type="as" direction="out" name="errors" />
|
||||||
|
</method>
|
||||||
|
<signal name="ExtensionStatusChanged">
|
||||||
|
<arg type="s" name="uuid"/>
|
||||||
|
<arg type="i" name="state"/>
|
||||||
|
<arg type="s" name="error"/>
|
||||||
|
</signal>
|
||||||
|
<method name="InstallRemoteExtension">
|
||||||
|
<arg type="s" direction="in" name="uuid"/>
|
||||||
|
<arg type="s" direction="out" name="result"/>
|
||||||
|
</method>
|
||||||
|
<method name="UninstallExtension">
|
||||||
|
<arg type="s" direction="in" name="uuid"/>
|
||||||
|
<arg type="b" direction="out" name="success"/>
|
||||||
|
</method>
|
||||||
|
<method name="LaunchExtensionPrefs">
|
||||||
|
<arg type="s" direction="in" name="uuid"/>
|
||||||
|
</method>
|
||||||
|
<method name="ReloadExtension">
|
||||||
|
<arg type="s" direction="in" name="uuid"/>
|
||||||
|
</method>
|
||||||
|
<method name="CheckForUpdates">
|
||||||
|
</method>
|
||||||
|
<property name="ShellVersion" type="s" access="read" />
|
||||||
|
</interface>;
|
||||||
|
|
||||||
|
const GnomeShellExtensions = new Lang.Class({
|
||||||
|
Name: 'GnomeShellExtensionsDBus',
|
||||||
|
|
||||||
|
_init: function() {
|
||||||
|
this._dbusImpl = Gio.DBusExportedObject.wrapJSObject(GnomeShellExtensionsIface, this);
|
||||||
|
this._dbusImpl.export(Gio.DBus.session, '/org/gnome/Shell');
|
||||||
|
ExtensionSystem.connect('extension-state-changed',
|
||||||
|
Lang.bind(this, this._extensionStateChanged));
|
||||||
|
},
|
||||||
|
|
||||||
|
|
||||||
ListExtensions: function() {
|
ListExtensions: function() {
|
||||||
let out = {};
|
let out = {};
|
||||||
for (let uuid in ExtensionUtils.extensions) {
|
for (let uuid in ExtensionUtils.extensions) {
|
||||||
@ -260,26 +288,12 @@ const GnomeShell = new Lang.Class({
|
|||||||
return extension.errors;
|
return extension.errors;
|
||||||
},
|
},
|
||||||
|
|
||||||
EnableExtension: function(uuid) {
|
InstallRemoteExtensionAsync: function([uuid], invocation) {
|
||||||
let enabledExtensions = global.settings.get_strv(ExtensionSystem.ENABLED_EXTENSIONS_KEY);
|
return ExtensionDownloader.installExtension(uuid, invocation);
|
||||||
if (enabledExtensions.indexOf(uuid) == -1)
|
|
||||||
enabledExtensions.push(uuid);
|
|
||||||
global.settings.set_strv(ExtensionSystem.ENABLED_EXTENSIONS_KEY, enabledExtensions);
|
|
||||||
},
|
|
||||||
|
|
||||||
DisableExtension: function(uuid) {
|
|
||||||
let enabledExtensions = global.settings.get_strv(ExtensionSystem.ENABLED_EXTENSIONS_KEY);
|
|
||||||
while (enabledExtensions.indexOf(uuid) != -1)
|
|
||||||
enabledExtensions.splice(enabledExtensions.indexOf(uuid), 1);
|
|
||||||
global.settings.set_strv(ExtensionSystem.ENABLED_EXTENSIONS_KEY, enabledExtensions);
|
|
||||||
},
|
|
||||||
|
|
||||||
InstallRemoteExtension: function(uuid, version_tag) {
|
|
||||||
ExtensionSystem.installExtensionFromUUID(uuid, version_tag);
|
|
||||||
},
|
},
|
||||||
|
|
||||||
UninstallExtension: function(uuid) {
|
UninstallExtension: function(uuid) {
|
||||||
return ExtensionSystem.uninstallExtensionFromUUID(uuid);
|
return ExtensionDownloader.uninstallExtension(uuid);
|
||||||
},
|
},
|
||||||
|
|
||||||
LaunchExtensionPrefs: function(uuid) {
|
LaunchExtensionPrefs: function(uuid) {
|
||||||
@ -289,19 +303,15 @@ const GnomeShell = new Lang.Class({
|
|||||||
['extension:///' + uuid], -1, null);
|
['extension:///' + uuid], -1, null);
|
||||||
},
|
},
|
||||||
|
|
||||||
get OverviewActive() {
|
ReloadExtension: function(uuid) {
|
||||||
return Main.overview.visible;
|
ExtensionSystem.unloadExtension(uuid);
|
||||||
|
ExtensionSystem.loadExtension(uuid);
|
||||||
},
|
},
|
||||||
|
|
||||||
set OverviewActive(visible) {
|
CheckForUpdates: function() {
|
||||||
if (visible)
|
ExtensionDownloader.checkForUpdates();
|
||||||
Main.overview.show();
|
|
||||||
else
|
|
||||||
Main.overview.hide();
|
|
||||||
},
|
},
|
||||||
|
|
||||||
ApiVersion: ExtensionSystem.API_VERSION,
|
|
||||||
|
|
||||||
ShellVersion: Config.PACKAGE_VERSION,
|
ShellVersion: Config.PACKAGE_VERSION,
|
||||||
|
|
||||||
_extensionStateChanged: function(_, newState) {
|
_extensionStateChanged: function(_, newState) {
|
||||||
|
@ -1,17 +1,21 @@
|
|||||||
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
|
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
|
||||||
|
|
||||||
|
const Clutter = imports.gi.Clutter;
|
||||||
const Lang = imports.lang;
|
const Lang = imports.lang;
|
||||||
const Signals = imports.signals;
|
const Signals = imports.signals;
|
||||||
const Gio = imports.gi.Gio;
|
const Gio = imports.gi.Gio;
|
||||||
|
const GLib = imports.gi.GLib;
|
||||||
const Gtk = imports.gi.Gtk;
|
const Gtk = imports.gi.Gtk;
|
||||||
const Pango = imports.gi.Pango;
|
const Pango = imports.gi.Pango;
|
||||||
const St = imports.gi.St;
|
const St = imports.gi.St;
|
||||||
const Shell = imports.gi.Shell;
|
const Shell = imports.gi.Shell;
|
||||||
|
|
||||||
|
const CheckBox = imports.ui.checkBox;
|
||||||
const Main = imports.ui.main;
|
const Main = imports.ui.main;
|
||||||
const MessageTray = imports.ui.messageTray;
|
const MessageTray = imports.ui.messageTray;
|
||||||
const ModalDialog = imports.ui.modalDialog;
|
const ModalDialog = imports.ui.modalDialog;
|
||||||
const Params = imports.misc.params;
|
const Params = imports.misc.params;
|
||||||
|
const ShellEntry = imports.ui.shellEntry;
|
||||||
|
|
||||||
const LIST_ITEM_ICON_SIZE = 48;
|
const LIST_ITEM_ICON_SIZE = 48;
|
||||||
|
|
||||||
@ -48,6 +52,11 @@ function _setLabelsForMessage(dialog, message) {
|
|||||||
_setLabelText(dialog.descriptionLabel, labels[1]);
|
_setLabelText(dialog.descriptionLabel, labels[1]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function _createIcon(gicon) {
|
||||||
|
return new St.Icon({ gicon: gicon,
|
||||||
|
style_class: 'shell-mount-operation-icon' })
|
||||||
|
}
|
||||||
|
|
||||||
/* -------------------------------------------------------- */
|
/* -------------------------------------------------------- */
|
||||||
|
|
||||||
const ListItem = new Lang.Class({
|
const ListItem = new Lang.Class({
|
||||||
@ -91,11 +100,11 @@ const ShellMountOperation = new Lang.Class({
|
|||||||
Name: 'ShellMountOperation',
|
Name: 'ShellMountOperation',
|
||||||
|
|
||||||
_init: function(source, params) {
|
_init: function(source, params) {
|
||||||
params = Params.parse(params, { reaskPassword: false });
|
params = Params.parse(params, { existingDialog: null });
|
||||||
|
|
||||||
this._reaskPassword = params.reaskPassword;
|
|
||||||
|
|
||||||
this._dialog = null;
|
this._dialog = null;
|
||||||
|
this._dialogId = 0;
|
||||||
|
this._existingDialog = params.existingDialog;
|
||||||
this._processesDialog = null;
|
this._processesDialog = null;
|
||||||
|
|
||||||
this.mountOp = new Shell.MountOperation();
|
this.mountOp = new Shell.MountOperation();
|
||||||
@ -107,70 +116,90 @@ const ShellMountOperation = new Lang.Class({
|
|||||||
this.mountOp.connect('show-processes-2',
|
this.mountOp.connect('show-processes-2',
|
||||||
Lang.bind(this, this._onShowProcesses2));
|
Lang.bind(this, this._onShowProcesses2));
|
||||||
this.mountOp.connect('aborted',
|
this.mountOp.connect('aborted',
|
||||||
Lang.bind(this, this._onAborted));
|
Lang.bind(this, this.close));
|
||||||
|
this.mountOp.connect('show-unmount-progress',
|
||||||
|
Lang.bind(this, this._onShowUnmountProgress));
|
||||||
|
|
||||||
this._icon = new St.Icon({ gicon: source.get_icon(),
|
this._gicon = source.get_icon();
|
||||||
style_class: 'shell-mount-operation-icon' });
|
},
|
||||||
|
|
||||||
|
_closeExistingDialog: function() {
|
||||||
|
if (!this._existingDialog)
|
||||||
|
return;
|
||||||
|
|
||||||
|
this._existingDialog.close();
|
||||||
|
this._existingDialog = null;
|
||||||
},
|
},
|
||||||
|
|
||||||
_onAskQuestion: function(op, message, choices) {
|
_onAskQuestion: function(op, message, choices) {
|
||||||
this._dialog = new ShellMountQuestionDialog(this._icon);
|
this._closeExistingDialog();
|
||||||
|
this._dialog = new ShellMountQuestionDialog(this._gicon);
|
||||||
|
|
||||||
this._dialog.connect('response',
|
this._dialogId = this._dialog.connect('response', Lang.bind(this,
|
||||||
Lang.bind(this, function(object, choice) {
|
function(object, choice) {
|
||||||
this.mountOp.set_choice(choice);
|
this.mountOp.set_choice(choice);
|
||||||
this.mountOp.reply(Gio.MountOperationResult.HANDLED);
|
this.mountOp.reply(Gio.MountOperationResult.HANDLED);
|
||||||
|
|
||||||
this._dialog.close(global.get_current_time());
|
this.close();
|
||||||
this._dialog = null;
|
|
||||||
}));
|
}));
|
||||||
|
|
||||||
this._dialog.update(message, choices);
|
this._dialog.update(message, choices);
|
||||||
this._dialog.open(global.get_current_time());
|
this._dialog.open();
|
||||||
},
|
},
|
||||||
|
|
||||||
_onAskPassword: function(op, message) {
|
_onAskPassword: function(op, message, defaultUser, defaultDomain, flags) {
|
||||||
this._notificationShowing = true;
|
if (this._existingDialog) {
|
||||||
this._source = new ShellMountPasswordSource(message, this._icon, this._reaskPassword);
|
this._dialog = this._existingDialog;
|
||||||
|
this._dialog.reaskPassword();
|
||||||
|
} else {
|
||||||
|
this._dialog = new ShellMountPasswordDialog(message, this._gicon, flags);
|
||||||
|
}
|
||||||
|
|
||||||
|
this._dialogId = this._dialog.connect('response', Lang.bind(this,
|
||||||
|
function(object, choice, password, remember) {
|
||||||
|
if (choice == -1) {
|
||||||
|
this.mountOp.reply(Gio.MountOperationResult.ABORTED);
|
||||||
|
} else {
|
||||||
|
if (remember)
|
||||||
|
this.mountOp.set_password_save(Gio.PasswordSave.PERMANENTLY);
|
||||||
|
else
|
||||||
|
this.mountOp.set_password_save(Gio.PasswordSave.NEVER);
|
||||||
|
|
||||||
this._source.connect('password-ready',
|
|
||||||
Lang.bind(this, function(source, password) {
|
|
||||||
this.mountOp.set_password(password);
|
this.mountOp.set_password(password);
|
||||||
this.mountOp.reply(Gio.MountOperationResult.HANDLED);
|
this.mountOp.reply(Gio.MountOperationResult.HANDLED);
|
||||||
|
}
|
||||||
this._notificationShowing = false;
|
|
||||||
this._source.destroy();
|
|
||||||
}));
|
|
||||||
|
|
||||||
this._source.connect('destroy',
|
|
||||||
Lang.bind(this, function() {
|
|
||||||
if (!this._notificationShowing)
|
|
||||||
return;
|
|
||||||
|
|
||||||
this._notificationShowing = false;
|
|
||||||
this.mountOp.reply(Gio.MountOperationResult.ABORTED);
|
|
||||||
}));
|
}));
|
||||||
|
this._dialog.open();
|
||||||
},
|
},
|
||||||
|
|
||||||
_onAborted: function(op) {
|
close: function(op) {
|
||||||
if (!this._dialog)
|
this._closeExistingDialog();
|
||||||
return;
|
this._processesDialog = null;
|
||||||
|
|
||||||
this._dialog.close(global.get_current_time());
|
if (this._dialog) {
|
||||||
|
this._dialog.close();
|
||||||
this._dialog = null;
|
this._dialog = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this._notifier) {
|
||||||
|
this._notifier.done();
|
||||||
|
this._notifier = null;
|
||||||
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
_onShowProcesses2: function(op) {
|
_onShowProcesses2: function(op) {
|
||||||
|
this._closeExistingDialog();
|
||||||
|
|
||||||
let processes = op.get_show_processes_pids();
|
let processes = op.get_show_processes_pids();
|
||||||
let choices = op.get_show_processes_choices();
|
let choices = op.get_show_processes_choices();
|
||||||
let message = op.get_show_processes_message();
|
let message = op.get_show_processes_message();
|
||||||
|
|
||||||
if (!this._processesDialog) {
|
if (!this._processesDialog) {
|
||||||
this._processesDialog = new ShellProcessesDialog(this._icon);
|
this._processesDialog = new ShellProcessesDialog(this._gicon);
|
||||||
this._dialog = this._processesDialog;
|
this._dialog = this._processesDialog;
|
||||||
|
|
||||||
this._processesDialog.connect('response',
|
this._dialogId = this._processesDialog.connect('response', Lang.bind(this,
|
||||||
Lang.bind(this, function(object, choice) {
|
function(object, choice) {
|
||||||
if (choice == -1) {
|
if (choice == -1) {
|
||||||
this.mountOp.reply(Gio.MountOperationResult.ABORTED);
|
this.mountOp.reply(Gio.MountOperationResult.ABORTED);
|
||||||
} else {
|
} else {
|
||||||
@ -178,28 +207,86 @@ const ShellMountOperation = new Lang.Class({
|
|||||||
this.mountOp.reply(Gio.MountOperationResult.HANDLED);
|
this.mountOp.reply(Gio.MountOperationResult.HANDLED);
|
||||||
}
|
}
|
||||||
|
|
||||||
this._processesDialog.close(global.get_current_time());
|
this.close();
|
||||||
this._dialog = null;
|
|
||||||
}));
|
}));
|
||||||
this._processesDialog.open(global.get_current_time());
|
this._processesDialog.open();
|
||||||
}
|
}
|
||||||
|
|
||||||
this._processesDialog.update(message, processes, choices);
|
this._processesDialog.update(message, processes, choices);
|
||||||
},
|
},
|
||||||
|
|
||||||
|
_onShowUnmountProgress: function(op, message, timeLeft, bytesLeft) {
|
||||||
|
if (!this._notifier)
|
||||||
|
this._notifier = new ShellUnmountNotifier();
|
||||||
|
|
||||||
|
if (bytesLeft == 0)
|
||||||
|
this._notifier.done(message);
|
||||||
|
else
|
||||||
|
this._notifier.show(message);
|
||||||
|
},
|
||||||
|
|
||||||
|
borrowDialog: function() {
|
||||||
|
if (this._dialogId != 0) {
|
||||||
|
this._dialog.disconnect(this._dialogId);
|
||||||
|
this._dialogId = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return this._dialog;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
const ShellUnmountNotifier = new Lang.Class({
|
||||||
|
Name: 'ShellUnmountNotifier',
|
||||||
|
Extends: MessageTray.Source,
|
||||||
|
|
||||||
|
_init: function() {
|
||||||
|
this.parent('', 'media-removable', St.IconType.FULLCOLOR);
|
||||||
|
|
||||||
|
this._notification = null;
|
||||||
|
Main.messageTray.add(this);
|
||||||
|
},
|
||||||
|
|
||||||
|
show: function(message) {
|
||||||
|
let [header, text] = message.split('\n', 2);
|
||||||
|
|
||||||
|
if (!this._notification) {
|
||||||
|
this._notification = new MessageTray.Notification(this, header, text);
|
||||||
|
this._notification.setTransient(true);
|
||||||
|
this._notification.setUrgency(MessageTray.Urgency.CRITICAL);
|
||||||
|
} else {
|
||||||
|
this._notification.update(header, text);
|
||||||
|
}
|
||||||
|
|
||||||
|
this.notify(this._notification);
|
||||||
|
},
|
||||||
|
|
||||||
|
done: function(message) {
|
||||||
|
if (this._notification) {
|
||||||
|
this._notification.destroy();
|
||||||
|
this._notification = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (message) {
|
||||||
|
let notification = new MessageTray.Notification(this, message, null);
|
||||||
|
notification.setTransient(true);
|
||||||
|
|
||||||
|
this.notify(notification);
|
||||||
|
}
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
const ShellMountQuestionDialog = new Lang.Class({
|
const ShellMountQuestionDialog = new Lang.Class({
|
||||||
Name: 'ShellMountQuestionDialog',
|
Name: 'ShellMountQuestionDialog',
|
||||||
Extends: ModalDialog.ModalDialog,
|
Extends: ModalDialog.ModalDialog,
|
||||||
|
|
||||||
_init: function(icon) {
|
_init: function(gicon) {
|
||||||
this.parent({ styleClass: 'mount-question-dialog' });
|
this.parent({ styleClass: 'mount-question-dialog' });
|
||||||
|
|
||||||
let mainContentLayout = new St.BoxLayout();
|
let mainContentLayout = new St.BoxLayout();
|
||||||
this.contentLayout.add(mainContentLayout, { x_fill: true,
|
this.contentLayout.add(mainContentLayout, { x_fill: true,
|
||||||
y_fill: false });
|
y_fill: false });
|
||||||
|
|
||||||
this._iconBin = new St.Bin({ child: icon });
|
this._iconBin = new St.Bin({ child: _createIcon(gicon) });
|
||||||
mainContentLayout.add(this._iconBin,
|
mainContentLayout.add(this._iconBin,
|
||||||
{ x_fill: true,
|
{ x_fill: true,
|
||||||
y_fill: false,
|
y_fill: false,
|
||||||
@ -234,62 +321,107 @@ const ShellMountQuestionDialog = new Lang.Class({
|
|||||||
});
|
});
|
||||||
Signals.addSignalMethods(ShellMountQuestionDialog.prototype);
|
Signals.addSignalMethods(ShellMountQuestionDialog.prototype);
|
||||||
|
|
||||||
const ShellMountPasswordSource = new Lang.Class({
|
const ShellMountPasswordDialog = new Lang.Class({
|
||||||
Name: 'ShellMountPasswordSource',
|
Name: 'ShellMountPasswordDialog',
|
||||||
Extends: MessageTray.Source,
|
Extends: ModalDialog.ModalDialog,
|
||||||
|
|
||||||
_init: function(message, icon, reaskPassword) {
|
_init: function(message, gicon, flags) {
|
||||||
let strings = message.split('\n');
|
let strings = message.split('\n');
|
||||||
this.parent(strings[0]);
|
this.parent({ styleClass: 'prompt-dialog' });
|
||||||
|
|
||||||
this._notification = new ShellMountPasswordNotification(this, strings, icon, reaskPassword);
|
let mainContentBox = new St.BoxLayout({ style_class: 'prompt-dialog-main-layout',
|
||||||
|
vertical: false });
|
||||||
|
this.contentLayout.add(mainContentBox);
|
||||||
|
|
||||||
// add ourselves as a source, and popup the notification
|
let icon = _createIcon(gicon);
|
||||||
Main.messageTray.add(this);
|
mainContentBox.add(icon,
|
||||||
this.notify(this._notification);
|
{ x_fill: true,
|
||||||
},
|
y_fill: false,
|
||||||
});
|
x_align: St.Align.END,
|
||||||
Signals.addSignalMethods(ShellMountPasswordSource.prototype);
|
y_align: St.Align.START });
|
||||||
|
|
||||||
const ShellMountPasswordNotification = new Lang.Class({
|
this._messageBox = new St.BoxLayout({ style_class: 'prompt-dialog-message-layout',
|
||||||
Name: 'ShellMountPasswordNotification',
|
vertical: true });
|
||||||
Extends: MessageTray.Notification,
|
mainContentBox.add(this._messageBox,
|
||||||
|
{ y_align: St.Align.START, expand: true, x_fill: true, y_fill: true });
|
||||||
|
|
||||||
_init: function(source, strings, icon, reaskPassword) {
|
let subject = new St.Label({ style_class: 'prompt-dialog-headline' });
|
||||||
this.parent(source, strings[0], null, { customContent: true, icon: icon });
|
this._messageBox.add(subject,
|
||||||
|
{ y_fill: false,
|
||||||
// set the notification to transient and urgent, so that it
|
y_align: St.Align.START });
|
||||||
// expands out
|
if (strings[0])
|
||||||
this.setTransient(true);
|
subject.set_text(strings[0]);
|
||||||
this.setUrgency(MessageTray.Urgency.CRITICAL);
|
|
||||||
|
|
||||||
|
let description = new St.Label({ style_class: 'prompt-dialog-description' });
|
||||||
|
description.clutter_text.ellipsize = Pango.EllipsizeMode.NONE;
|
||||||
|
description.clutter_text.line_wrap = true;
|
||||||
|
this._messageBox.add(description,
|
||||||
|
{ y_fill: true,
|
||||||
|
y_align: St.Align.START });
|
||||||
if (strings[1])
|
if (strings[1])
|
||||||
this.addBody(strings[1]);
|
description.set_text(strings[1]);
|
||||||
|
|
||||||
if (reaskPassword) {
|
this._passwordBox = new St.BoxLayout({ vertical: false });
|
||||||
let label = new St.Label({ style_class: 'mount-password-reask',
|
this._messageBox.add(this._passwordBox);
|
||||||
text: _("Wrong password, please try again") });
|
|
||||||
|
|
||||||
this.addActor(label);
|
this._passwordLabel = new St.Label(({ style_class: 'prompt-dialog-password-label',
|
||||||
|
text: _("Passphrase") }));
|
||||||
|
this._passwordBox.add(this._passwordLabel);
|
||||||
|
|
||||||
|
this._passwordEntry = new St.Entry({ style_class: 'prompt-dialog-password-entry',
|
||||||
|
text: "",
|
||||||
|
can_focus: true});
|
||||||
|
ShellEntry.addContextMenu(this._passwordEntry, { isPassword: true });
|
||||||
|
this._passwordEntry.clutter_text.connect('activate', Lang.bind(this, this._onEntryActivate));
|
||||||
|
this._passwordEntry.clutter_text.set_password_char('\u25cf'); // ● U+25CF BLACK CIRCLE
|
||||||
|
this._passwordBox.add(this._passwordEntry, {expand: true });
|
||||||
|
this.setInitialKeyFocus(this._passwordEntry);
|
||||||
|
|
||||||
|
this._errorMessageLabel = new St.Label({ style_class: 'prompt-dialog-error-label',
|
||||||
|
text: _("Sorry, that didn\'t work. Please try again.") });
|
||||||
|
this._errorMessageLabel.clutter_text.ellipsize = Pango.EllipsizeMode.NONE;
|
||||||
|
this._errorMessageLabel.clutter_text.line_wrap = true;
|
||||||
|
this._errorMessageLabel.hide();
|
||||||
|
this._messageBox.add(this._errorMessageLabel);
|
||||||
|
|
||||||
|
if (flags & Gio.AskPasswordFlags.SAVING_SUPPORTED) {
|
||||||
|
this._rememberChoice = new CheckBox.CheckBox();
|
||||||
|
this._rememberChoice.getLabelActor().text = _("Remember Passphrase");
|
||||||
|
this._rememberChoice.actor.checked = true;
|
||||||
|
this._messageBox.add(this._rememberChoice.actor);
|
||||||
|
} else {
|
||||||
|
this._rememberChoice = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
this._responseEntry = new St.Entry({ style_class: 'mount-password-entry',
|
let buttons = [{ label: _("Cancel"),
|
||||||
can_focus: true });
|
action: Lang.bind(this, this._onCancelButton),
|
||||||
this.setActionArea(this._responseEntry);
|
key: Clutter.Escape
|
||||||
|
},
|
||||||
|
{ label: _("Unlock"),
|
||||||
|
action: Lang.bind(this, this._onUnlockButton)
|
||||||
|
}];
|
||||||
|
|
||||||
this._responseEntry.clutter_text.connect('activate',
|
this.setButtons(buttons);
|
||||||
Lang.bind(this, this._onEntryActivated));
|
|
||||||
this._responseEntry.clutter_text.set_password_char('\u25cf'); // ● U+25CF BLACK CIRCLE
|
|
||||||
|
|
||||||
this._responseEntry.grab_key_focus();
|
|
||||||
},
|
},
|
||||||
|
|
||||||
_onEntryActivated: function() {
|
reaskPassword: function() {
|
||||||
let text = this._responseEntry.get_text();
|
this._passwordEntry.set_text('');
|
||||||
if (text == '')
|
this._errorMessageLabel.show();
|
||||||
return;
|
},
|
||||||
|
|
||||||
this.source.emit('password-ready', text);
|
_onCancelButton: function() {
|
||||||
|
this.emit('response', -1, '', false);
|
||||||
|
},
|
||||||
|
|
||||||
|
_onUnlockButton: function() {
|
||||||
|
this._onEntryActivate();
|
||||||
|
},
|
||||||
|
|
||||||
|
_onEntryActivate: function() {
|
||||||
|
this.emit('response', 1,
|
||||||
|
this._passwordEntry.get_text(),
|
||||||
|
this._rememberChoice &&
|
||||||
|
this._rememberChoice.actor.checked);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -297,14 +429,14 @@ const ShellProcessesDialog = new Lang.Class({
|
|||||||
Name: 'ShellProcessesDialog',
|
Name: 'ShellProcessesDialog',
|
||||||
Extends: ModalDialog.ModalDialog,
|
Extends: ModalDialog.ModalDialog,
|
||||||
|
|
||||||
_init: function(icon) {
|
_init: function(gicon) {
|
||||||
this.parent({ styleClass: 'show-processes-dialog' });
|
this.parent({ styleClass: 'show-processes-dialog' });
|
||||||
|
|
||||||
let mainContentLayout = new St.BoxLayout();
|
let mainContentLayout = new St.BoxLayout();
|
||||||
this.contentLayout.add(mainContentLayout, { x_fill: true,
|
this.contentLayout.add(mainContentLayout, { x_fill: true,
|
||||||
y_fill: false });
|
y_fill: false });
|
||||||
|
|
||||||
this._iconBin = new St.Bin({ child: icon });
|
this._iconBin = new St.Bin({ child: _createIcon(gicon) });
|
||||||
mainContentLayout.add(this._iconBin,
|
mainContentLayout.add(this._iconBin,
|
||||||
{ x_fill: true,
|
{ x_fill: true,
|
||||||
y_fill: false,
|
y_fill: false,
|
||||||
@ -346,13 +478,13 @@ const ShellProcessesDialog = new Lang.Class({
|
|||||||
|
|
||||||
this._applicationList.connect('actor-added',
|
this._applicationList.connect('actor-added',
|
||||||
Lang.bind(this, function() {
|
Lang.bind(this, function() {
|
||||||
if (this._applicationList.get_children().length == 1)
|
if (this._applicationList.get_n_children() == 1)
|
||||||
scrollView.show();
|
scrollView.show();
|
||||||
}));
|
}));
|
||||||
|
|
||||||
this._applicationList.connect('actor-removed',
|
this._applicationList.connect('actor-removed',
|
||||||
Lang.bind(this, function() {
|
Lang.bind(this, function() {
|
||||||
if (this._applicationList.get_children().length == 0)
|
if (this._applicationList.get_n_children() == 0)
|
||||||
scrollView.hide();
|
scrollView.hide();
|
||||||
}));
|
}));
|
||||||
},
|
},
|
||||||
@ -386,3 +518,253 @@ const ShellProcessesDialog = new Lang.Class({
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
Signals.addSignalMethods(ShellProcessesDialog.prototype);
|
Signals.addSignalMethods(ShellProcessesDialog.prototype);
|
||||||
|
|
||||||
|
const GnomeShellMountOpIface = <interface name="org.Gtk.MountOperationHandler">
|
||||||
|
<method name="AskPassword">
|
||||||
|
<arg type="s" direction="in" name="object_id"/>
|
||||||
|
<arg type="s" direction="in" name="message"/>
|
||||||
|
<arg type="s" direction="in" name="icon_name"/>
|
||||||
|
<arg type="s" direction="in" name="default_user"/>
|
||||||
|
<arg type="s" direction="in" name="default_domain"/>
|
||||||
|
<arg type="u" direction="in" name="flags"/>
|
||||||
|
<arg type="u" direction="out" name="response"/>
|
||||||
|
<arg type="a{sv}" direction="out" name="response_details"/>
|
||||||
|
</method>
|
||||||
|
<method name="AskQuestion">
|
||||||
|
<arg type="s" direction="in" name="object_id"/>
|
||||||
|
<arg type="s" direction="in" name="message"/>
|
||||||
|
<arg type="s" direction="in" name="icon_name"/>
|
||||||
|
<arg type="as" direction="in" name="choices"/>
|
||||||
|
<arg type="u" direction="out" name="response"/>
|
||||||
|
<arg type="a{sv}" direction="out" name="response_details"/>
|
||||||
|
</method>
|
||||||
|
<method name="ShowProcesses">
|
||||||
|
<arg type="s" direction="in" name="object_id"/>
|
||||||
|
<arg type="s" direction="in" name="message"/>
|
||||||
|
<arg type="s" direction="in" name="icon_name"/>
|
||||||
|
<arg type="ai" direction="in" name="application_pids"/>
|
||||||
|
<arg type="as" direction="in" name="choices"/>
|
||||||
|
<arg type="u" direction="out" name="response"/>
|
||||||
|
<arg type="a{sv}" direction="out" name="response_details"/>
|
||||||
|
</method>
|
||||||
|
<method name="Close"/>
|
||||||
|
</interface>;
|
||||||
|
|
||||||
|
const ShellMountOperationType = {
|
||||||
|
NONE: 0,
|
||||||
|
ASK_PASSWORD: 1,
|
||||||
|
ASK_QUESTION: 2,
|
||||||
|
SHOW_PROCESSES: 3
|
||||||
|
};
|
||||||
|
|
||||||
|
const GnomeShellMountOpHandler = new Lang.Class({
|
||||||
|
Name: 'GnomeShellMountOpHandler',
|
||||||
|
|
||||||
|
_init: function() {
|
||||||
|
this._dbusImpl = Gio.DBusExportedObject.wrapJSObject(GnomeShellMountOpIface, this);
|
||||||
|
this._dbusImpl.export(Gio.DBus.session, '/org/gtk/MountOperationHandler');
|
||||||
|
Gio.bus_own_name_on_connection(Gio.DBus.session, 'org.gtk.MountOperationHandler',
|
||||||
|
Gio.BusNameOwnerFlags.REPLACE, null, null);
|
||||||
|
|
||||||
|
this._dialog = null;
|
||||||
|
this._volumeMonitor = Gio.VolumeMonitor.get();
|
||||||
|
|
||||||
|
this._ensureEmptyRequest();
|
||||||
|
},
|
||||||
|
|
||||||
|
_ensureEmptyRequest: function() {
|
||||||
|
this._currentId = null;
|
||||||
|
this._currentInvocation = null;
|
||||||
|
this._currentType = ShellMountOperationType.NONE;
|
||||||
|
},
|
||||||
|
|
||||||
|
_clearCurrentRequest: function(response, details) {
|
||||||
|
if (this._currentInvocation) {
|
||||||
|
this._currentInvocation.return_value(
|
||||||
|
GLib.Variant.new('(ua{sv})', [response, details]));
|
||||||
|
}
|
||||||
|
|
||||||
|
this._ensureEmptyRequest();
|
||||||
|
},
|
||||||
|
|
||||||
|
_setCurrentRequest: function(invocation, id, type) {
|
||||||
|
let oldId = this._currentId;
|
||||||
|
let oldType = this._currentType;
|
||||||
|
let requestId = id + '@' + invocation.get_sender();
|
||||||
|
|
||||||
|
this._clearCurrentRequest(Gio.MountOperationResult.UNHANDLED, {});
|
||||||
|
|
||||||
|
this._currentInvocation = invocation;
|
||||||
|
this._currentId = requestId;
|
||||||
|
this._currentType = type;
|
||||||
|
|
||||||
|
if (this._dialog && (oldId == requestId) && (oldType == type))
|
||||||
|
return true;
|
||||||
|
|
||||||
|
return false;
|
||||||
|
},
|
||||||
|
|
||||||
|
_closeDialog: function() {
|
||||||
|
if (this._dialog) {
|
||||||
|
this._dialog.close();
|
||||||
|
this._dialog = null;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
_createGIcon: function(iconName) {
|
||||||
|
let realIconName = iconName ? iconName : 'drive-harddisk';
|
||||||
|
return new Gio.ThemedIcon({ name: realIconName,
|
||||||
|
use_default_fallbacks: true });
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* AskPassword:
|
||||||
|
* @id: an opaque ID identifying the object for which the operation is requested
|
||||||
|
* The ID must be unique in the context of the calling process.
|
||||||
|
* @message: the message to display
|
||||||
|
* @icon_name: the name of an icon to display
|
||||||
|
* @default_user: the default username for display
|
||||||
|
* @default_domain: the default domain for display
|
||||||
|
* @flags: a set of GAskPasswordFlags
|
||||||
|
* @response: a GMountOperationResult
|
||||||
|
* @response_details: a dictionary containing the response details as
|
||||||
|
* entered by the user. The dictionary MAY contain the following properties:
|
||||||
|
* - "password" -> (s): a password to be used to complete the mount operation
|
||||||
|
* - "password_save" -> (u): a GPasswordSave
|
||||||
|
*
|
||||||
|
* The dialog will stay visible until clients call the Close() method, or
|
||||||
|
* another dialog becomes visible.
|
||||||
|
* Calling AskPassword again for the same id will have the effect to clear
|
||||||
|
* the existing dialog and update it with a message indicating the previous
|
||||||
|
* attempt went wrong.
|
||||||
|
*/
|
||||||
|
AskPasswordAsync: function(params, invocation) {
|
||||||
|
let [id, message, iconName, defaultUser, defaultDomain, flags] = params;
|
||||||
|
|
||||||
|
if (this._setCurrentRequest(invocation, id, ShellMountOperationType.ASK_PASSWORD)) {
|
||||||
|
this._dialog.reaskPassword();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
this._closeDialog();
|
||||||
|
|
||||||
|
this._dialog = new ShellMountPasswordDialog(message, this._createGIcon(iconName), flags);
|
||||||
|
this._dialog.connect('response', Lang.bind(this,
|
||||||
|
function(object, choice, password, remember) {
|
||||||
|
let details = {};
|
||||||
|
let response;
|
||||||
|
|
||||||
|
if (choice == -1) {
|
||||||
|
response = Gio.MountOperationResult.ABORTED;
|
||||||
|
} else {
|
||||||
|
response = Gio.MountOperationResult.HANDLED;
|
||||||
|
|
||||||
|
let passSave = remember ? Gio.PasswordSave.PERMANENTLY : Gio.PasswordSave.NEVER;
|
||||||
|
details['password_save'] = GLib.Variant.new('u', passSave);
|
||||||
|
details['password'] = GLib.Variant.new('s', password);
|
||||||
|
}
|
||||||
|
|
||||||
|
this._clearCurrentRequest(response, details);
|
||||||
|
}));
|
||||||
|
this._dialog.open();
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* AskQuestion:
|
||||||
|
* @id: an opaque ID identifying the object for which the operation is requested
|
||||||
|
* The ID must be unique in the context of the calling process.
|
||||||
|
* @message: the message to display
|
||||||
|
* @icon_name: the name of an icon to display
|
||||||
|
* @choices: an array of choice strings
|
||||||
|
* GetResponse:
|
||||||
|
* @response: a GMountOperationResult
|
||||||
|
* @response_details: a dictionary containing the response details as
|
||||||
|
* entered by the user. The dictionary MAY contain the following properties:
|
||||||
|
* - "choice" -> (i): the chosen answer among the array of strings passed in
|
||||||
|
*
|
||||||
|
* The dialog will stay visible until clients call the Close() method, or
|
||||||
|
* another dialog becomes visible.
|
||||||
|
* Calling AskQuestion again for the same id will have the effect to clear
|
||||||
|
* update the dialog with the new question.
|
||||||
|
*/
|
||||||
|
AskQuestionAsync: function(params, invocation) {
|
||||||
|
let [id, message, iconName, choices] = params;
|
||||||
|
|
||||||
|
if (this._setCurrentRequest(invocation, id, ShellMountOperationType.ASK_QUESTION)) {
|
||||||
|
this._dialog.update(message, choices);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
this._closeDialog();
|
||||||
|
|
||||||
|
this._dialog = new ShellMountQuestionDialog(this._createGIcon(iconName), message);
|
||||||
|
this._dialog.connect('response', Lang.bind(this,
|
||||||
|
function(object, choice) {
|
||||||
|
this._clearCurrentRequest(Gio.MountOperationResult.HANDLED,
|
||||||
|
{ choice: GLib.Variant.new('i', choice) });
|
||||||
|
}));
|
||||||
|
|
||||||
|
this._dialog.update(message, choices);
|
||||||
|
this._dialog.open();
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ShowProcesses:
|
||||||
|
* @id: an opaque ID identifying the object for which the operation is requested
|
||||||
|
* The ID must be unique in the context of the calling process.
|
||||||
|
* @message: the message to display
|
||||||
|
* @icon_name: the name of an icon to display
|
||||||
|
* @application_pids: the PIDs of the applications to display
|
||||||
|
* @choices: an array of choice strings
|
||||||
|
* @response: a GMountOperationResult
|
||||||
|
* @response_details: a dictionary containing the response details as
|
||||||
|
* entered by the user. The dictionary MAY contain the following properties:
|
||||||
|
* - "choice" -> (i): the chosen answer among the array of strings passed in
|
||||||
|
*
|
||||||
|
* The dialog will stay visible until clients call the Close() method, or
|
||||||
|
* another dialog becomes visible.
|
||||||
|
* Calling ShowProcesses again for the same id will have the effect to clear
|
||||||
|
* the existing dialog and update it with the new message and the new list
|
||||||
|
* of processes.
|
||||||
|
*/
|
||||||
|
ShowProcessesAsync: function(params, invocation) {
|
||||||
|
let [id, message, iconName, applicationPids, choices] = params;
|
||||||
|
|
||||||
|
if (this._setCurrentRequest(invocation, id, ShellMountOperationType.SHOW_PROCESSES)) {
|
||||||
|
this._dialog.update(message, applicationPids, choices);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
this._closeDialog();
|
||||||
|
|
||||||
|
this._dialog = new ShellProcessesDialog(this._createGIcon(iconName));
|
||||||
|
this._dialog.connect('response', Lang.bind(this,
|
||||||
|
function(object, choice) {
|
||||||
|
let response;
|
||||||
|
let details = {};
|
||||||
|
|
||||||
|
if (choice == -1) {
|
||||||
|
response = Gio.MountOperationResult.ABORTED;
|
||||||
|
} else {
|
||||||
|
response = Gio.MountOperationResult.HANDLED;
|
||||||
|
details['choice'] = GLib.Variant.new('i', choice);
|
||||||
|
}
|
||||||
|
|
||||||
|
this._clearCurrentRequest(response, details);
|
||||||
|
}));
|
||||||
|
|
||||||
|
this._dialog.update(message, applicationPids, choices);
|
||||||
|
this._dialog.open();
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Close:
|
||||||
|
*
|
||||||
|
* Closes a dialog previously opened by AskPassword, AskQuestion or ShowProcesses.
|
||||||
|
* If no dialog is open, does nothing.
|
||||||
|
*/
|
||||||
|
Close: function(params, invocation) {
|
||||||
|
this._clearCurrentRequest(Gio.MountOperationResult.UNHANDLED, {});
|
||||||
|
this._closeDialog();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
@ -56,9 +56,9 @@ const ATIndicator = new Lang.Class({
|
|||||||
let textZoom = this._buildFontItem();
|
let textZoom = this._buildFontItem();
|
||||||
this.menu.addMenuItem(textZoom);
|
this.menu.addMenuItem(textZoom);
|
||||||
|
|
||||||
// let screenReader = this._buildItem(_("Screen Reader"), APPLICATIONS_SCHEMA,
|
let screenReader = this._buildItem(_("Screen Reader"), APPLICATIONS_SCHEMA,
|
||||||
// 'screen-reader-enabled');
|
'screen-reader-enabled');
|
||||||
// this.menu.addMenuItem(screenReader);
|
this.menu.addMenuItem(screenReader);
|
||||||
|
|
||||||
let screenKeyboard = this._buildItem(_("Screen Keyboard"), APPLICATIONS_SCHEMA,
|
let screenKeyboard = this._buildItem(_("Screen Keyboard"), APPLICATIONS_SCHEMA,
|
||||||
'screen-keyboard-enabled');
|
'screen-keyboard-enabled');
|
||||||
|
@ -106,10 +106,7 @@ const Indicator = new Lang.Class({
|
|||||||
/* TRANSLATORS: this means that bluetooth was disabled by hardware rfkill */
|
/* TRANSLATORS: this means that bluetooth was disabled by hardware rfkill */
|
||||||
this._killswitch.setStatus(_("hardware disabled"));
|
this._killswitch.setStatus(_("hardware disabled"));
|
||||||
|
|
||||||
if (has_adapter)
|
this.actor.visible = has_adapter;
|
||||||
this.actor.show();
|
|
||||||
else
|
|
||||||
this.actor.hide();
|
|
||||||
|
|
||||||
if (on) {
|
if (on) {
|
||||||
this._discoverable.actor.show();
|
this._discoverable.actor.show();
|
||||||
@ -308,7 +305,7 @@ const Indicator = new Lang.Class({
|
|||||||
|
|
||||||
_ensureSource: function() {
|
_ensureSource: function() {
|
||||||
if (!this._source) {
|
if (!this._source) {
|
||||||
this._source = new Source();
|
this._source = new MessageTray.Source(_("Bluetooth"), 'bluetooth-active', St.IconType.SYMBOLIC);
|
||||||
Main.messageTray.add(this._source);
|
Main.messageTray.add(this._source);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -333,35 +330,6 @@ const Indicator = new Lang.Class({
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
const Source = new Lang.Class({
|
|
||||||
Name: 'BluetoothSource',
|
|
||||||
Extends: MessageTray.Source,
|
|
||||||
|
|
||||||
_init: function() {
|
|
||||||
this.parent(_("Bluetooth"));
|
|
||||||
|
|
||||||
this._setSummaryIcon(this.createNotificationIcon());
|
|
||||||
},
|
|
||||||
|
|
||||||
notify: function(notification) {
|
|
||||||
this._private_destroyId = notification.connect('destroy', Lang.bind(this, function(notification) {
|
|
||||||
if (this.notification == notification) {
|
|
||||||
// the destroyed notification is the last for this source
|
|
||||||
this.notification.disconnect(this._private_destroyId);
|
|
||||||
this.destroy();
|
|
||||||
}
|
|
||||||
}));
|
|
||||||
|
|
||||||
this.parent(notification);
|
|
||||||
},
|
|
||||||
|
|
||||||
createNotificationIcon: function() {
|
|
||||||
return new St.Icon({ icon_name: 'bluetooth-active',
|
|
||||||
icon_type: St.IconType.SYMBOLIC,
|
|
||||||
icon_size: this.ICON_SIZE });
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
const AuthNotification = new Lang.Class({
|
const AuthNotification = new Lang.Class({
|
||||||
Name: 'AuthNotification',
|
Name: 'AuthNotification',
|
||||||
Extends: MessageTray.Notification,
|
Extends: MessageTray.Notification,
|
||||||
@ -412,7 +380,7 @@ const ConfirmNotification = new Lang.Class({
|
|||||||
this._applet = applet;
|
this._applet = applet;
|
||||||
this._devicePath = device_path;
|
this._devicePath = device_path;
|
||||||
this.addBody(_("Device %s wants to pair with this computer").format(long_name));
|
this.addBody(_("Device %s wants to pair with this computer").format(long_name));
|
||||||
this.addBody(_("Please confirm whether the PIN '%s' matches the one on the device.").format(pin));
|
this.addBody(_("Please confirm whether the PIN '%06d' matches the one on the device.").format(pin));
|
||||||
|
|
||||||
this.addButton('matches', _("Matches"));
|
this.addButton('matches', _("Matches"));
|
||||||
this.addButton('does-not-match', _("Does not match"));
|
this.addButton('does-not-match', _("Does not match"));
|
||||||
@ -448,6 +416,7 @@ const PinNotification = new Lang.Class({
|
|||||||
this._entry.connect('key-release-event', Lang.bind(this, function(entry, event) {
|
this._entry.connect('key-release-event', Lang.bind(this, function(entry, event) {
|
||||||
let key = event.get_key_symbol();
|
let key = event.get_key_symbol();
|
||||||
if (key == Clutter.KEY_Return) {
|
if (key == Clutter.KEY_Return) {
|
||||||
|
if (this._canActivateOkButton())
|
||||||
this.emit('action-invoked', 'ok');
|
this.emit('action-invoked', 'ok');
|
||||||
return true;
|
return true;
|
||||||
} else if (key == Clutter.KEY_Escape) {
|
} else if (key == Clutter.KEY_Escape) {
|
||||||
@ -461,6 +430,12 @@ const PinNotification = new Lang.Class({
|
|||||||
this.addButton('ok', _("OK"));
|
this.addButton('ok', _("OK"));
|
||||||
this.addButton('cancel', _("Cancel"));
|
this.addButton('cancel', _("Cancel"));
|
||||||
|
|
||||||
|
this.setButtonSensitive('ok', this._canActivateOkButton());
|
||||||
|
this._entry.clutter_text.connect('text-changed', Lang.bind(this,
|
||||||
|
function() {
|
||||||
|
this.setButtonSensitive('ok', this._canActivateOkButton());
|
||||||
|
}));
|
||||||
|
|
||||||
this.connect('action-invoked', Lang.bind(this, function(self, action) {
|
this.connect('action-invoked', Lang.bind(this, function(self, action) {
|
||||||
if (action == 'ok') {
|
if (action == 'ok') {
|
||||||
if (this._numeric) {
|
if (this._numeric) {
|
||||||
@ -483,6 +458,11 @@ const PinNotification = new Lang.Class({
|
|||||||
}));
|
}));
|
||||||
},
|
},
|
||||||
|
|
||||||
|
_canActivateOkButton: function() {
|
||||||
|
// PINs have a fixed length of 6
|
||||||
|
return this._entry.clutter_text.text.length == 6;
|
||||||
|
},
|
||||||
|
|
||||||
grabFocus: function(lockTray) {
|
grabFocus: function(lockTray) {
|
||||||
this.parent(lockTray);
|
this.parent(lockTray);
|
||||||
global.stage.set_key_focus(this._entry);
|
global.stage.set_key_focus(this._entry);
|
||||||
|
@ -2,46 +2,151 @@
|
|||||||
|
|
||||||
const Clutter = imports.gi.Clutter;
|
const Clutter = imports.gi.Clutter;
|
||||||
const GdkPixbuf = imports.gi.GdkPixbuf;
|
const GdkPixbuf = imports.gi.GdkPixbuf;
|
||||||
const Gkbd = imports.gi.Gkbd;
|
|
||||||
const Gio = imports.gi.Gio;
|
const Gio = imports.gi.Gio;
|
||||||
const GLib = imports.gi.GLib;
|
const GLib = imports.gi.GLib;
|
||||||
|
const GnomeDesktop = imports.gi.GnomeDesktop;
|
||||||
const Lang = imports.lang;
|
const Lang = imports.lang;
|
||||||
|
const Mainloop = imports.mainloop;
|
||||||
const Shell = imports.gi.Shell;
|
const Shell = imports.gi.Shell;
|
||||||
const St = imports.gi.St;
|
const St = imports.gi.St;
|
||||||
|
|
||||||
|
try {
|
||||||
|
var IBus = imports.gi.IBus;
|
||||||
|
if (!('new_async' in IBus.Bus))
|
||||||
|
throw "IBus version is too old";
|
||||||
|
const IBusCandidatePopup = imports.ui.ibusCandidatePopup;
|
||||||
|
} catch (e) {
|
||||||
|
var IBus = null;
|
||||||
|
log(e);
|
||||||
|
}
|
||||||
|
|
||||||
const Main = imports.ui.main;
|
const Main = imports.ui.main;
|
||||||
const PopupMenu = imports.ui.popupMenu;
|
const PopupMenu = imports.ui.popupMenu;
|
||||||
const PanelMenu = imports.ui.panelMenu;
|
const PanelMenu = imports.ui.panelMenu;
|
||||||
const Util = imports.misc.util;
|
const Util = imports.misc.util;
|
||||||
|
|
||||||
|
const DESKTOP_INPUT_SOURCES_SCHEMA = 'org.gnome.desktop.input-sources';
|
||||||
|
const KEY_CURRENT_INPUT_SOURCE = 'current';
|
||||||
|
const KEY_INPUT_SOURCES = 'sources';
|
||||||
|
|
||||||
|
const INPUT_SOURCE_TYPE_XKB = 'xkb';
|
||||||
|
const INPUT_SOURCE_TYPE_IBUS = 'ibus';
|
||||||
|
|
||||||
|
const IBusManager = new Lang.Class({
|
||||||
|
Name: 'IBusManager',
|
||||||
|
|
||||||
|
_init: function(readyCallback) {
|
||||||
|
if (!IBus)
|
||||||
|
return;
|
||||||
|
|
||||||
|
IBus.init();
|
||||||
|
|
||||||
|
this._readyCallback = readyCallback;
|
||||||
|
this._candidatePopup = new IBusCandidatePopup.CandidatePopup();
|
||||||
|
|
||||||
|
this._ibus = null;
|
||||||
|
this._panelService = null;
|
||||||
|
this._engines = {};
|
||||||
|
this._ready = false;
|
||||||
|
|
||||||
|
this._nameWatcherId = Gio.DBus.session.watch_name(IBus.SERVICE_IBUS,
|
||||||
|
Gio.BusNameWatcherFlags.NONE,
|
||||||
|
Lang.bind(this, this._onNameAppeared),
|
||||||
|
Lang.bind(this, this._clear));
|
||||||
|
},
|
||||||
|
|
||||||
|
_clear: function() {
|
||||||
|
if (this._panelService)
|
||||||
|
this._panelService.destroy();
|
||||||
|
if (this._ibus)
|
||||||
|
this._ibus.destroy();
|
||||||
|
|
||||||
|
this._ibus = null;
|
||||||
|
this._panelService = null;
|
||||||
|
this._candidatePopup.setPanelService(null);
|
||||||
|
this._engines = {};
|
||||||
|
this._ready = false;
|
||||||
|
},
|
||||||
|
|
||||||
|
_onNameAppeared: function() {
|
||||||
|
this._ibus = IBus.Bus.new_async();
|
||||||
|
this._ibus.connect('connected', Lang.bind(this, this._onConnected));
|
||||||
|
},
|
||||||
|
|
||||||
|
_onConnected: function() {
|
||||||
|
this._ibus.list_engines_async(-1, null, Lang.bind(this, this._initEngines));
|
||||||
|
this._ibus.request_name_async(IBus.SERVICE_PANEL,
|
||||||
|
IBus.BusNameFlag.REPLACE_EXISTING,
|
||||||
|
-1, null,
|
||||||
|
Lang.bind(this, this._initPanelService));
|
||||||
|
this._ibus.connect('disconnected', Lang.bind(this, this._clear));
|
||||||
|
},
|
||||||
|
|
||||||
|
_initEngines: function(ibus, result) {
|
||||||
|
let enginesList = this._ibus.list_engines_async_finish(result);
|
||||||
|
if (enginesList) {
|
||||||
|
for (let i = 0; i < enginesList.length; ++i) {
|
||||||
|
let name = enginesList[i].get_name();
|
||||||
|
this._engines[name] = enginesList[i];
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
this._clear();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
this._updateReadiness();
|
||||||
|
},
|
||||||
|
|
||||||
|
_initPanelService: function(ibus, result) {
|
||||||
|
let success = this._ibus.request_name_async_finish(result);
|
||||||
|
if (success) {
|
||||||
|
this._panelService = new IBus.PanelService({ connection: this._ibus.get_connection(),
|
||||||
|
object_path: IBus.PATH_PANEL });
|
||||||
|
this._candidatePopup.setPanelService(this._panelService);
|
||||||
|
} else {
|
||||||
|
this._clear();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
this._updateReadiness();
|
||||||
|
},
|
||||||
|
|
||||||
|
_updateReadiness: function() {
|
||||||
|
this._ready = (Object.keys(this._engines).length > 0 &&
|
||||||
|
this._panelService != null);
|
||||||
|
|
||||||
|
if (this._ready && this._readyCallback)
|
||||||
|
this._readyCallback();
|
||||||
|
},
|
||||||
|
|
||||||
|
getEngineDesc: function(id) {
|
||||||
|
if (!IBus || !this._ready)
|
||||||
|
return null;
|
||||||
|
|
||||||
|
return this._engines[id];
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
const LayoutMenuItem = new Lang.Class({
|
const LayoutMenuItem = new Lang.Class({
|
||||||
Name: 'LayoutMenuItem',
|
Name: 'LayoutMenuItem',
|
||||||
Extends: PopupMenu.PopupBaseMenuItem,
|
Extends: PopupMenu.PopupBaseMenuItem,
|
||||||
|
|
||||||
_init: function(config, id, indicator, long_name) {
|
_init: function(displayName, shortName) {
|
||||||
this.parent();
|
this.parent();
|
||||||
|
|
||||||
this._config = config;
|
this.label = new St.Label({ text: displayName });
|
||||||
this._id = id;
|
this.indicator = new St.Label({ text: shortName });
|
||||||
this.label = new St.Label({ text: long_name });
|
|
||||||
this.indicator = indicator;
|
|
||||||
this.addActor(this.label);
|
this.addActor(this.label);
|
||||||
this.addActor(this.indicator);
|
this.addActor(this.indicator);
|
||||||
},
|
|
||||||
|
|
||||||
activate: function(event) {
|
|
||||||
this.parent(event);
|
|
||||||
|
|
||||||
this._config.lock_group(this._id);
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
const XKBIndicator = new Lang.Class({
|
const InputSourceIndicator = new Lang.Class({
|
||||||
Name: 'XKBIndicator',
|
Name: 'InputSourceIndicator',
|
||||||
Extends: PanelMenu.Button,
|
Extends: PanelMenu.Button,
|
||||||
|
|
||||||
_init: function() {
|
_init: function() {
|
||||||
this.parent(0.0);
|
this.parent(0.0, _("Keyboard"));
|
||||||
|
|
||||||
this._container = new Shell.GenericContainer();
|
this._container = new Shell.GenericContainer();
|
||||||
this._container.connect('get-preferred-width', Lang.bind(this, this._containerGetPreferredWidth));
|
this._container.connect('get-preferred-width', Lang.bind(this, this._containerGetPreferredWidth));
|
||||||
@ -50,122 +155,164 @@ const XKBIndicator = new Lang.Class({
|
|||||||
this.actor.add_actor(this._container);
|
this.actor.add_actor(this._container);
|
||||||
this.actor.add_style_class_name('panel-status-button');
|
this.actor.add_style_class_name('panel-status-button');
|
||||||
|
|
||||||
this._iconActor = new St.Icon({ icon_name: 'keyboard', icon_type: St.IconType.SYMBOLIC, style_class: 'system-status-icon' });
|
this._labelActors = {};
|
||||||
this._container.add_actor(this._iconActor);
|
this._layoutItems = {};
|
||||||
this._labelActors = [ ];
|
|
||||||
this._layoutItems = [ ];
|
|
||||||
|
|
||||||
this._showFlags = false;
|
this._settings = new Gio.Settings({ schema: DESKTOP_INPUT_SOURCES_SCHEMA });
|
||||||
this._config = Gkbd.Configuration.get();
|
this._settings.connect('changed::' + KEY_CURRENT_INPUT_SOURCE, Lang.bind(this, this._currentInputSourceChanged));
|
||||||
this._config.connect('changed', Lang.bind(this, this._syncConfig));
|
this._settings.connect('changed::' + KEY_INPUT_SOURCES, Lang.bind(this, this._inputSourcesChanged));
|
||||||
this._config.connect('group-changed', Lang.bind(this, this._syncGroup));
|
|
||||||
this._config.start_listen();
|
|
||||||
|
|
||||||
this._syncConfig();
|
this._currentSourceIndex = this._settings.get_uint(KEY_CURRENT_INPUT_SOURCE);
|
||||||
|
this._xkbInfo = new GnomeDesktop.XkbInfo();
|
||||||
|
|
||||||
if (global.session_type == Shell.SessionType.USER) {
|
this._ibusManager = new IBusManager(Lang.bind(this, this._inputSourcesChanged));
|
||||||
|
|
||||||
|
this._inputSourcesChanged();
|
||||||
|
|
||||||
|
// re-using "allowSettings" for the keyboard layout is a bit shady,
|
||||||
|
// but at least for now it is used as "allow popping up windows
|
||||||
|
// from shell menus"; we can always add a separate sessionMode
|
||||||
|
// option if need arises.
|
||||||
|
if (Main.sessionMode.allowSettings) {
|
||||||
this.menu.addMenuItem(new PopupMenu.PopupSeparatorMenuItem());
|
this.menu.addMenuItem(new PopupMenu.PopupSeparatorMenuItem());
|
||||||
this.menu.addAction(_("Show Keyboard Layout"), Lang.bind(this, function() {
|
this.menu.addAction(_("Show Keyboard Layout"), Lang.bind(this, this._showLayout));
|
||||||
Main.overview.hide();
|
|
||||||
Util.spawn(['gkbd-keyboard-display', '-g', String(this._config.get_current_group() + 1)]);
|
|
||||||
}));
|
|
||||||
}
|
}
|
||||||
this.menu.addSettingsAction(_("Region and Language Settings"), 'gnome-region-panel.desktop');
|
this.menu.addSettingsAction(_("Region and Language Settings"), 'gnome-region-panel.desktop');
|
||||||
},
|
},
|
||||||
|
|
||||||
_adjustGroupNames: function(names) {
|
_currentInputSourceChanged: function() {
|
||||||
// Disambiguate duplicate names with a subscript
|
let nVisibleSources = Object.keys(this._layoutItems).length;
|
||||||
// This is O(N^2) to avoid sorting names
|
if (nVisibleSources < 2)
|
||||||
// but N <= 4 so who cares?
|
return;
|
||||||
|
|
||||||
for (let i = 0; i < names.length; i++) {
|
let nSources = this._settings.get_value(KEY_INPUT_SOURCES).n_children();
|
||||||
let name = names[i];
|
let newCurrentSourceIndex = this._settings.get_uint(KEY_CURRENT_INPUT_SOURCE);
|
||||||
let cnt = 0;
|
if (newCurrentSourceIndex >= nSources)
|
||||||
for (let j = i + 1; j < names.length; j++) {
|
return;
|
||||||
if (names[j] == name) {
|
|
||||||
cnt++;
|
if (!this._layoutItems[newCurrentSourceIndex]) {
|
||||||
// U+2081 SUBSCRIPT ONE
|
// This source index is invalid as we weren't able to
|
||||||
names[j] = name + String.fromCharCode(0x2081 + cnt);
|
// build a menu item for it, so we hide ourselves since we
|
||||||
}
|
// can't fix it here. *shrug*
|
||||||
}
|
this.menu.close();
|
||||||
if (cnt != 0)
|
this.actor.hide();
|
||||||
names[i] = name + '\u2081';
|
return;
|
||||||
|
} else {
|
||||||
|
this.actor.show();
|
||||||
}
|
}
|
||||||
|
|
||||||
return names;
|
if (this._layoutItems[this._currentSourceIndex]) {
|
||||||
|
this._layoutItems[this._currentSourceIndex].setShowDot(false);
|
||||||
|
this._container.set_skip_paint(this._labelActors[this._currentSourceIndex], true);
|
||||||
|
}
|
||||||
|
|
||||||
|
this._layoutItems[newCurrentSourceIndex].setShowDot(true);
|
||||||
|
this._container.set_skip_paint(this._labelActors[newCurrentSourceIndex], false);
|
||||||
|
|
||||||
|
this._currentSourceIndex = newCurrentSourceIndex;
|
||||||
},
|
},
|
||||||
|
|
||||||
_syncConfig: function() {
|
_inputSourcesChanged: function() {
|
||||||
this._showFlags = this._config.if_flags_shown();
|
let sources = this._settings.get_value(KEY_INPUT_SOURCES);
|
||||||
if (this._showFlags) {
|
let nSources = sources.n_children();
|
||||||
this._container.set_skip_paint(this._iconActor, false);
|
|
||||||
} else {
|
for (let i in this._layoutItems)
|
||||||
this._container.set_skip_paint(this._iconActor, true);
|
this._layoutItems[i].destroy();
|
||||||
|
|
||||||
|
for (let i in this._labelActors)
|
||||||
|
this._labelActors[i].destroy();
|
||||||
|
|
||||||
|
this._layoutItems = {};
|
||||||
|
this._labelActors = {};
|
||||||
|
|
||||||
|
let infos = [];
|
||||||
|
let infosByShortName = {};
|
||||||
|
|
||||||
|
for (let i = 0; i < nSources; i++) {
|
||||||
|
let info = { exists: false };
|
||||||
|
let [type, id] = sources.get_child_value(i).deep_unpack();
|
||||||
|
|
||||||
|
if (type == INPUT_SOURCE_TYPE_XKB) {
|
||||||
|
[info.exists, info.displayName, info.shortName, , ] =
|
||||||
|
this._xkbInfo.get_layout_info(id);
|
||||||
|
} else if (type == INPUT_SOURCE_TYPE_IBUS) {
|
||||||
|
let engineDesc = this._ibusManager.getEngineDesc(id);
|
||||||
|
if (engineDesc) {
|
||||||
|
info.exists = true;
|
||||||
|
info.displayName = engineDesc.get_longname();
|
||||||
|
info.shortName = engineDesc.get_symbol();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let groups = this._config.get_group_names();
|
if (!info.exists)
|
||||||
if (groups.length > 1) {
|
continue;
|
||||||
|
|
||||||
|
info.sourceIndex = i;
|
||||||
|
|
||||||
|
if (!(info.shortName in infosByShortName))
|
||||||
|
infosByShortName[info.shortName] = [];
|
||||||
|
infosByShortName[info.shortName].push(info);
|
||||||
|
infos.push(info);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (infos.length > 1) {
|
||||||
this.actor.show();
|
this.actor.show();
|
||||||
} else {
|
} else {
|
||||||
this.menu.close();
|
this.menu.close();
|
||||||
this.actor.hide();
|
this.actor.hide();
|
||||||
}
|
}
|
||||||
|
|
||||||
for (let i = 0; i < this._layoutItems.length; i++)
|
for (let i = 0; i < infos.length; i++) {
|
||||||
this._layoutItems[i].destroy();
|
let info = infos[i];
|
||||||
|
if (infosByShortName[info.shortName].length > 1) {
|
||||||
|
let sub = infosByShortName[info.shortName].indexOf(info) + 1;
|
||||||
|
info.shortName += String.fromCharCode(0x2080 + sub);
|
||||||
|
}
|
||||||
|
|
||||||
for (let i = 0; i < this._labelActors.length; i++)
|
let item = new LayoutMenuItem(info.displayName, info.shortName);
|
||||||
this._labelActors[i].destroy();
|
this._layoutItems[info.sourceIndex] = item;
|
||||||
|
|
||||||
let short_names = this._adjustGroupNames(this._config.get_short_group_names());
|
|
||||||
|
|
||||||
this._selectedLayout = null;
|
|
||||||
this._layoutItems = [ ];
|
|
||||||
this._selectedLabel = null;
|
|
||||||
this._labelActors = [ ];
|
|
||||||
for (let i = 0; i < groups.length; i++) {
|
|
||||||
let icon_name = this._config.get_group_name(i);
|
|
||||||
let actor;
|
|
||||||
if (this._showFlags)
|
|
||||||
actor = new St.Icon({ icon_name: icon_name, icon_type: St.IconType.SYMBOLIC, style_class: 'popup-menu-icon' });
|
|
||||||
else
|
|
||||||
actor = new St.Label({ text: short_names[i] });
|
|
||||||
let item = new LayoutMenuItem(this._config, i, actor, groups[i]);
|
|
||||||
item._short_group_name = short_names[i];
|
|
||||||
item._icon_name = icon_name;
|
|
||||||
this._layoutItems.push(item);
|
|
||||||
this.menu.addMenuItem(item, i);
|
this.menu.addMenuItem(item, i);
|
||||||
|
item.connect('activate', Lang.bind(this, function() {
|
||||||
|
this._settings.set_value(KEY_CURRENT_INPUT_SOURCE,
|
||||||
|
GLib.Variant.new_uint32(info.sourceIndex));
|
||||||
|
}));
|
||||||
|
|
||||||
let shortLabel = new St.Label({ text: short_names[i] });
|
let shortLabel = new St.Label({ text: info.shortName });
|
||||||
this._labelActors.push(shortLabel);
|
this._labelActors[info.sourceIndex] = shortLabel;
|
||||||
this._container.add_actor(shortLabel);
|
this._container.add_actor(shortLabel);
|
||||||
this._container.set_skip_paint(shortLabel, true);
|
this._container.set_skip_paint(shortLabel, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
this._syncGroup();
|
this._currentInputSourceChanged();
|
||||||
},
|
},
|
||||||
|
|
||||||
_syncGroup: function() {
|
_showLayout: function() {
|
||||||
let selected = this._config.get_current_group();
|
Main.overview.hide();
|
||||||
|
|
||||||
if (this._selectedLayout) {
|
let sources = this._settings.get_value(KEY_INPUT_SOURCES);
|
||||||
this._selectedLayout.setShowDot(false);
|
let current = this._settings.get_uint(KEY_CURRENT_INPUT_SOURCE);
|
||||||
this._selectedLayout = null;
|
let [type, id] = sources.get_child_value(current).deep_unpack();
|
||||||
|
let xkbLayout = '';
|
||||||
|
let xkbVariant = '';
|
||||||
|
|
||||||
|
if (type == INPUT_SOURCE_TYPE_XKB) {
|
||||||
|
[, , , xkbLayout, xkbVariant] = this._xkbInfo.get_layout_info(id);
|
||||||
|
} else if (type == INPUT_SOURCE_TYPE_IBUS) {
|
||||||
|
let engineDesc = this._ibusManager.getEngineDesc(id);
|
||||||
|
if (engineDesc) {
|
||||||
|
xkbLayout = engineDesc.get_layout();
|
||||||
|
xkbVariant = '';
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this._selectedLabel) {
|
if (!xkbLayout || xkbLayout.length == 0)
|
||||||
this._container.set_skip_paint(this._selectedLabel, true);
|
return;
|
||||||
this._selectedLabel = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
let item = this._layoutItems[selected];
|
let description = xkbLayout;
|
||||||
item.setShowDot(true);
|
if (xkbVariant.length > 0)
|
||||||
|
description = description + '\t' + xkbVariant;
|
||||||
|
|
||||||
this._iconActor.icon_name = item._icon_name;
|
Util.spawn(['gkbd-keyboard-display', '-l', description]);
|
||||||
this._selectedLabel = this._labelActors[selected];
|
|
||||||
this._container.set_skip_paint(this._selectedLabel, this._showFlags);
|
|
||||||
|
|
||||||
this._selectedLayout = item;
|
|
||||||
},
|
},
|
||||||
|
|
||||||
_containerGetPreferredWidth: function(container, for_height, alloc) {
|
_containerGetPreferredWidth: function(container, for_height, alloc) {
|
||||||
@ -173,16 +320,12 @@ const XKBIndicator = new Lang.Class({
|
|||||||
// for the height of all children, but we ignore the results
|
// for the height of all children, but we ignore the results
|
||||||
// for those we don't actually display.
|
// for those we don't actually display.
|
||||||
let max_min_width = 0, max_natural_width = 0;
|
let max_min_width = 0, max_natural_width = 0;
|
||||||
if (this._showFlags)
|
|
||||||
[max_min_width, max_natural_width] = this._iconActor.get_preferred_width(for_height);
|
|
||||||
|
|
||||||
for (let i = 0; i < this._labelActors.length; i++) {
|
for (let i in this._labelActors) {
|
||||||
let [min_width, natural_width] = this._labelActors[i].get_preferred_width(for_height);
|
let [min_width, natural_width] = this._labelActors[i].get_preferred_width(for_height);
|
||||||
if (!this._showFlags) {
|
|
||||||
max_min_width = Math.max(max_min_width, min_width);
|
max_min_width = Math.max(max_min_width, min_width);
|
||||||
max_natural_width = Math.max(max_natural_width, natural_width);
|
max_natural_width = Math.max(max_natural_width, natural_width);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
alloc.min_size = max_min_width;
|
alloc.min_size = max_min_width;
|
||||||
alloc.natural_size = max_natural_width;
|
alloc.natural_size = max_natural_width;
|
||||||
@ -190,16 +333,12 @@ const XKBIndicator = new Lang.Class({
|
|||||||
|
|
||||||
_containerGetPreferredHeight: function(container, for_width, alloc) {
|
_containerGetPreferredHeight: function(container, for_width, alloc) {
|
||||||
let max_min_height = 0, max_natural_height = 0;
|
let max_min_height = 0, max_natural_height = 0;
|
||||||
if (this._showFlags)
|
|
||||||
[max_min_height, max_natural_height] = this._iconActor.get_preferred_height(for_width);
|
|
||||||
|
|
||||||
for (let i = 0; i < this._labelActors.length; i++) {
|
for (let i in this._labelActors) {
|
||||||
let [min_height, natural_height] = this._labelActors[i].get_preferred_height(for_width);
|
let [min_height, natural_height] = this._labelActors[i].get_preferred_height(for_width);
|
||||||
if (!this._showFlags) {
|
|
||||||
max_min_height = Math.max(max_min_height, min_height);
|
max_min_height = Math.max(max_min_height, min_height);
|
||||||
max_natural_height = Math.max(max_natural_height, natural_height);
|
max_natural_height = Math.max(max_natural_height, natural_height);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
alloc.min_size = max_min_height;
|
alloc.min_size = max_min_height;
|
||||||
alloc.natural_size = max_natural_height;
|
alloc.natural_size = max_natural_height;
|
||||||
@ -212,8 +351,7 @@ const XKBIndicator = new Lang.Class({
|
|||||||
box.y2 -= box.y1;
|
box.y2 -= box.y1;
|
||||||
box.y1 = 0;
|
box.y1 = 0;
|
||||||
|
|
||||||
this._iconActor.allocate_align_fill(box, 0.5, 0, false, false, flags);
|
for (let i in this._labelActors)
|
||||||
for (let i = 0; i < this._labelActors.length; i++)
|
|
||||||
this._labelActors[i].allocate_align_fill(box, 0.5, 0, false, false, flags);
|
this._labelActors[i].allocate_align_fill(box, 0.5, 0, false, false, flags);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -101,11 +101,10 @@ const NMNetworkMenuItem = new Lang.Class({
|
|||||||
Name: 'NMNetworkMenuItem',
|
Name: 'NMNetworkMenuItem',
|
||||||
Extends: PopupMenu.PopupBaseMenuItem,
|
Extends: PopupMenu.PopupBaseMenuItem,
|
||||||
|
|
||||||
_init: function(accessPoints, title, params) {
|
_init: function(bestAP, title, params) {
|
||||||
this.parent(params);
|
this.parent(params);
|
||||||
|
|
||||||
accessPoints = sortAccessPoints(accessPoints);
|
this.bestAP = bestAP;
|
||||||
this.bestAP = accessPoints[0];
|
|
||||||
|
|
||||||
if (!title) {
|
if (!title) {
|
||||||
let ssid = this.bestAP.get_ssid();
|
let ssid = this.bestAP.get_ssid();
|
||||||
@ -127,24 +126,10 @@ const NMNetworkMenuItem = new Lang.Class({
|
|||||||
this.bestAP._secType != NMAccessPointSecurity.NONE)
|
this.bestAP._secType != NMAccessPointSecurity.NONE)
|
||||||
this._secureIcon.icon_name = 'network-wireless-encrypted';
|
this._secureIcon.icon_name = 'network-wireless-encrypted';
|
||||||
this._icons.add_actor(this._secureIcon);
|
this._icons.add_actor(this._secureIcon);
|
||||||
|
|
||||||
this._accessPoints = [ ];
|
|
||||||
for (let i = 0; i < accessPoints.length; i++) {
|
|
||||||
let ap = accessPoints[i];
|
|
||||||
// need a wrapper object here, because the access points can be shared
|
|
||||||
// between many NMNetworkMenuItems
|
|
||||||
let apObj = {
|
|
||||||
ap: ap,
|
|
||||||
updateId: ap.connect('notify::strength', Lang.bind(this, this._updated))
|
|
||||||
};
|
|
||||||
this._accessPoints.push(apObj);
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
|
|
||||||
_updated: function(ap) {
|
updateBestAP: function(ap) {
|
||||||
if (ap.strength > this.bestAP.strength)
|
|
||||||
this.bestAP = ap;
|
this.bestAP = ap;
|
||||||
|
|
||||||
this._signalIcon.icon_name = this._getIcon();
|
this._signalIcon.icon_name = this._getIcon();
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -153,36 +138,6 @@ const NMNetworkMenuItem = new Lang.Class({
|
|||||||
return 'network-workgroup';
|
return 'network-workgroup';
|
||||||
else
|
else
|
||||||
return 'network-wireless-signal-' + signalToIcon(this.bestAP.strength);
|
return 'network-wireless-signal-' + signalToIcon(this.bestAP.strength);
|
||||||
},
|
|
||||||
|
|
||||||
updateAccessPoints: function(accessPoints) {
|
|
||||||
for (let i = 0; i < this._accessPoints.length; i++) {
|
|
||||||
let apObj = this._accessPoints[i];
|
|
||||||
apObj.ap.disconnect(apObj.updateId);
|
|
||||||
apObj.updateId = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
accessPoints = sortAccessPoints(accessPoints);
|
|
||||||
this.bestAP = accessPoints[0];
|
|
||||||
this._accessPoints = [ ];
|
|
||||||
for (let i = 0; i < accessPoints; i++) {
|
|
||||||
let ap = accessPoints[i];
|
|
||||||
let apObj = {
|
|
||||||
ap: ap,
|
|
||||||
updateId: ap.connect('notify::strength', Lang.bind(this, this._updated))
|
|
||||||
};
|
|
||||||
this._accessPoints.push(apObj);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
destroy: function() {
|
|
||||||
for (let i = 0; i < this._accessPoints.length; i++) {
|
|
||||||
let apObj = this._accessPoints[i];
|
|
||||||
apObj.ap.disconnect(apObj.updateId);
|
|
||||||
apObj.updateId = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
this.parent();
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -297,16 +252,17 @@ const NMDevice = new Lang.Class({
|
|||||||
this._client = client;
|
this._client = client;
|
||||||
this._connections = [ ];
|
this._connections = [ ];
|
||||||
for (let i = 0; i < connections.length; i++) {
|
for (let i = 0; i < connections.length; i++) {
|
||||||
if (!connections[i]._uuid)
|
if (!connections[i].get_uuid())
|
||||||
continue;
|
continue;
|
||||||
if (!this.connectionValid(connections[i]))
|
if (!this.connectionValid(connections[i]))
|
||||||
continue;
|
continue;
|
||||||
// record the connection
|
// record the connection
|
||||||
let obj = {
|
let obj = {
|
||||||
connection: connections[i],
|
connection: connections[i],
|
||||||
name: connections[i]._name,
|
name: connections[i].get_id(),
|
||||||
uuid: connections[i]._uuid,
|
uuid: connections[i].get_uuid(),
|
||||||
timestamp: connections[i]._timestamp,
|
timestamp: connections[i]._timestamp,
|
||||||
|
item: null,
|
||||||
};
|
};
|
||||||
this._connections.push(obj);
|
this._connections.push(obj);
|
||||||
}
|
}
|
||||||
@ -401,48 +357,46 @@ const NMDevice = new Lang.Class({
|
|||||||
},
|
},
|
||||||
|
|
||||||
checkConnection: function(connection) {
|
checkConnection: function(connection) {
|
||||||
let pos = this._findConnection(connection._uuid);
|
let pos = this._findConnection(connection.get_uuid());
|
||||||
let exists = pos != -1;
|
let exists = pos != -1;
|
||||||
let valid = this.connectionValid(connection);
|
let valid = this.connectionValid(connection);
|
||||||
|
let similar = false;
|
||||||
|
if (exists) {
|
||||||
|
let existing = this._connections[pos];
|
||||||
|
|
||||||
if (exists && !valid)
|
// Check if connection changed name or id
|
||||||
|
similar = existing.name == connection.get_id() &&
|
||||||
|
existing.timestamp == connection._timestamp;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (exists && valid && similar) {
|
||||||
|
// Nothing to do
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (exists)
|
||||||
this.removeConnection(connection);
|
this.removeConnection(connection);
|
||||||
else if (!exists && valid)
|
if (valid)
|
||||||
this.addConnection(connection);
|
this.addConnection(connection);
|
||||||
else if (exists && valid) {
|
|
||||||
// propagate changes and update the UI
|
|
||||||
|
|
||||||
if (this._connections[pos].timestamp != connection._timestamp) {
|
|
||||||
this._connections[pos].timestamp = connection._timestamp;
|
|
||||||
this._connections.sort(this._connectionSortFunction);
|
|
||||||
|
|
||||||
this._clearSection();
|
|
||||||
this._queueCreateSection();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
|
|
||||||
addConnection: function(connection) {
|
addConnection: function(connection) {
|
||||||
// record the connection
|
// record the connection
|
||||||
let obj = {
|
let obj = {
|
||||||
connection: connection,
|
connection: connection,
|
||||||
name: connection._name,
|
name: connection.get_id(),
|
||||||
uuid: connection._uuid,
|
uuid: connection.get_uuid(),
|
||||||
timestamp: connection._timestamp,
|
timestamp: connection._timestamp,
|
||||||
|
item: null,
|
||||||
};
|
};
|
||||||
this._connections.push(obj);
|
Util.insertSorted(this._connections, obj, this._connectionSortFunction);
|
||||||
this._connections.sort(this._connectionSortFunction);
|
|
||||||
|
|
||||||
this._clearSection();
|
this._clearSection();
|
||||||
this._queueCreateSection();
|
this._queueCreateSection();
|
||||||
},
|
},
|
||||||
|
|
||||||
removeConnection: function(connection) {
|
removeConnection: function(connection) {
|
||||||
if (!connection._uuid) {
|
let pos = this._findConnection(connection.get_uuid());
|
||||||
log('Cannot remove a connection without an UUID');
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
let pos = this._findConnection(connection._uuid);
|
|
||||||
if (pos == -1) {
|
if (pos == -1) {
|
||||||
// this connection was never added, nothing to do here
|
// this connection was never added, nothing to do here
|
||||||
return;
|
return;
|
||||||
@ -614,7 +568,7 @@ const NMDevice = new Lang.Class({
|
|||||||
let title;
|
let title;
|
||||||
let active = this._activeConnection._connection;
|
let active = this._activeConnection._connection;
|
||||||
if (active) {
|
if (active) {
|
||||||
title = active._name;
|
title = active.get_id();
|
||||||
} else {
|
} else {
|
||||||
/* TRANSLATORS: this is the indication that a connection for another logged in user is active,
|
/* TRANSLATORS: this is the indication that a connection for another logged in user is active,
|
||||||
and we cannot access its settings (including the name) */
|
and we cannot access its settings (including the name) */
|
||||||
@ -707,18 +661,15 @@ const NMDeviceWired = new Lang.Class({
|
|||||||
// the device
|
// the device
|
||||||
// we can do it here because addConnection and removeConnection
|
// we can do it here because addConnection and removeConnection
|
||||||
// both call _createSection at some point
|
// both call _createSection at some point
|
||||||
if (this._connections.length <= 1)
|
this.section.actor.visible = this._connections.length > 1;
|
||||||
this.section.actor.hide();
|
|
||||||
else
|
|
||||||
this.section.actor.show();
|
|
||||||
},
|
},
|
||||||
|
|
||||||
_createAutomaticConnection: function() {
|
_createAutomaticConnection: function() {
|
||||||
let connection = new NetworkManager.Connection();
|
let connection = new NetworkManager.Connection();
|
||||||
connection._uuid = NetworkManager.utils_uuid_generate();
|
let uuid = NetworkManager.utils_uuid_generate();
|
||||||
connection.add_setting(new NetworkManager.SettingWired());
|
connection.add_setting(new NetworkManager.SettingWired());
|
||||||
connection.add_setting(new NetworkManager.SettingConnection({
|
connection.add_setting(new NetworkManager.SettingConnection({
|
||||||
uuid: connection._uuid,
|
uuid: uuid,
|
||||||
id: this._autoConnectionName,
|
id: this._autoConnectionName,
|
||||||
type: NetworkManager.SETTING_WIRED_SETTING_NAME,
|
type: NetworkManager.SETTING_WIRED_SETTING_NAME,
|
||||||
autoconnect: true
|
autoconnect: true
|
||||||
@ -862,10 +813,10 @@ const NMDeviceBluetooth = new Lang.Class({
|
|||||||
|
|
||||||
_createAutomaticConnection: function() {
|
_createAutomaticConnection: function() {
|
||||||
let connection = new NetworkManager.Connection;
|
let connection = new NetworkManager.Connection;
|
||||||
connection._uuid = NetworkManager.utils_uuid_generate();
|
let uuid = NetworkManager.utils_uuid_generate();
|
||||||
connection.add_setting(new NetworkManager.SettingBluetooth);
|
connection.add_setting(new NetworkManager.SettingBluetooth);
|
||||||
connection.add_setting(new NetworkManager.SettingConnection({
|
connection.add_setting(new NetworkManager.SettingConnection({
|
||||||
uuid: connection._uuid,
|
uuid: uuid,
|
||||||
id: this._autoConnectionName,
|
id: this._autoConnectionName,
|
||||||
type: NetworkManager.SETTING_BLUETOOTH_SETTING_NAME,
|
type: NetworkManager.SETTING_BLUETOOTH_SETTING_NAME,
|
||||||
autoconnect: false
|
autoconnect: false
|
||||||
@ -900,12 +851,12 @@ const NMDeviceVPN = new Lang.Class({
|
|||||||
Name: 'NMDeviceVPN',
|
Name: 'NMDeviceVPN',
|
||||||
Extends: NMDevice,
|
Extends: NMDevice,
|
||||||
|
|
||||||
_init: function(client) {
|
_init: function(client, device, connections) {
|
||||||
// Disable autoconnections
|
// Disable autoconnections
|
||||||
this._autoConnectionName = null;
|
this._autoConnectionName = null;
|
||||||
this.category = NMConnectionCategory.VPN;
|
this.category = NMConnectionCategory.VPN;
|
||||||
|
|
||||||
this.parent(client, null, [ ]);
|
this.parent(client, null, connections);
|
||||||
},
|
},
|
||||||
|
|
||||||
connectionValid: function(connection) {
|
connectionValid: function(connection) {
|
||||||
@ -917,13 +868,24 @@ const NMDeviceVPN = new Lang.Class({
|
|||||||
},
|
},
|
||||||
|
|
||||||
get connected() {
|
get connected() {
|
||||||
return !!this._activeConnection;
|
if (!this._activeConnection)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return this._activeConnection.vpn_state == NetworkManager.VPNConnectionState.ACTIVATED;
|
||||||
},
|
},
|
||||||
|
|
||||||
setActiveConnection: function(activeConnection) {
|
setActiveConnection: function(activeConnection) {
|
||||||
|
if (this._stateChangeId)
|
||||||
|
this._activeConnection.disconnect(this._stateChangeId);
|
||||||
|
this._stateChangeId = 0;
|
||||||
|
|
||||||
this.parent(activeConnection);
|
this.parent(activeConnection);
|
||||||
|
|
||||||
this.emit('active-connection-changed');
|
if (this._activeConnection)
|
||||||
|
this._stateChangeId = this._activeConnection.connect('vpn-state-changed',
|
||||||
|
Lang.bind(this, this._connectionStateChanged));
|
||||||
|
|
||||||
|
this.emit('state-changed');
|
||||||
},
|
},
|
||||||
|
|
||||||
_shouldShowConnectionList: function() {
|
_shouldShowConnectionList: function() {
|
||||||
@ -936,7 +898,39 @@ const NMDeviceVPN = new Lang.Class({
|
|||||||
},
|
},
|
||||||
|
|
||||||
getStatusLabel: function() {
|
getStatusLabel: function() {
|
||||||
|
if (!this._activeConnection) // Same as DISCONNECTED
|
||||||
return null;
|
return null;
|
||||||
|
|
||||||
|
switch(this._activeConnection.vpn_state) {
|
||||||
|
case NetworkManager.VPNConnectionState.DISCONNECTED:
|
||||||
|
case NetworkManager.VPNConnectionState.ACTIVATED:
|
||||||
|
return null;
|
||||||
|
case NetworkManager.VPNConnectionState.PREPARE:
|
||||||
|
case NetworkManager.VPNConnectionState.CONNECT:
|
||||||
|
case NetworkManager.VPNConnectionState.IP_CONFIG_GET:
|
||||||
|
return _("connecting...");
|
||||||
|
case NetworkManager.VPNConnectionState.NEED_AUTH:
|
||||||
|
/* Translators: this is for network connections that require some kind of key or password */
|
||||||
|
return _("authentication required");
|
||||||
|
case NetworkManager.VPNConnectionState.FAILED:
|
||||||
|
return _("connection failed");
|
||||||
|
default:
|
||||||
|
log('VPN connection state invalid, is %d'.format(this.device.state));
|
||||||
|
return 'invalid';
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
_connectionStateChanged: function(connection, newstate, reason) {
|
||||||
|
if (newstate == NetworkManager.VPNConnectionState.FAILED) {
|
||||||
|
// FIXME: if we ever want to show something based on reason,
|
||||||
|
// we need to convert from NetworkManager.VPNConnectionStateReason
|
||||||
|
// to NetworkManager.DeviceStateReason
|
||||||
|
this.emit('activation-failed', reason);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Differently from real NMDevices, there is no need to queue
|
||||||
|
// an update of the menu section, contents wouldn't change anyway
|
||||||
|
this.emit('state-changed');
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -987,6 +981,7 @@ const NMDeviceWireless = new Lang.Class({
|
|||||||
obj.ssidText = ssidToLabel(obj.ssid);
|
obj.ssidText = ssidToLabel(obj.ssid);
|
||||||
this._networks.push(obj);
|
this._networks.push(obj);
|
||||||
}
|
}
|
||||||
|
ap._updateId = ap.connect('notify::strength', Lang.bind(this, this._onApStrengthChanged));
|
||||||
|
|
||||||
// Check if some connection is valid for this AP
|
// Check if some connection is valid for this AP
|
||||||
for (let j = 0; j < validConnections.length; j++) {
|
for (let j = 0; j < validConnections.length; j++) {
|
||||||
@ -998,6 +993,10 @@ const NMDeviceWireless = new Lang.Class({
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Sort APs within each network by strength
|
||||||
|
for (let i = 0; i < this._networks.length; i++)
|
||||||
|
sortAccessPoints(this._networks[i].accessPoints);
|
||||||
|
|
||||||
if (this.device.active_access_point) {
|
if (this.device.active_access_point) {
|
||||||
let networkPos = this._findNetwork(this.device.active_access_point);
|
let networkPos = this._findNetwork(this.device.active_access_point);
|
||||||
|
|
||||||
@ -1038,13 +1037,8 @@ const NMDeviceWireless = new Lang.Class({
|
|||||||
},
|
},
|
||||||
|
|
||||||
setEnabled: function(enabled) {
|
setEnabled: function(enabled) {
|
||||||
if (enabled) {
|
this.statusItem.actor.visible = enabled;
|
||||||
this.statusItem.actor.show();
|
this.section.actor.visible = enabled;
|
||||||
this.section.actor.show();
|
|
||||||
} else {
|
|
||||||
this.statusItem.actor.hide();
|
|
||||||
this.section.actor.hide();
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
|
|
||||||
activate: function() {
|
activate: function() {
|
||||||
@ -1085,7 +1079,7 @@ const NMDeviceWireless = new Lang.Class({
|
|||||||
// the user toggles the switch and has more than one wireless device)
|
// the user toggles the switch and has more than one wireless device)
|
||||||
if (this._networks.length > 0) {
|
if (this._networks.length > 0) {
|
||||||
let connection = this._createAutomaticConnection(this._networks[0]);
|
let connection = this._createAutomaticConnection(this._networks[0]);
|
||||||
let accessPoints = sortAccessPoints(this._networks[0].accessPoints);
|
let accessPoints = this._networks[0].accessPoints;
|
||||||
this._client.add_and_activate_connection(connection, this.device, accessPoints[0].dbus_path, null);
|
this._client.add_and_activate_connection(connection, this.device, accessPoints[0].dbus_path, null);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -1155,6 +1149,13 @@ const NMDeviceWireless = new Lang.Class({
|
|||||||
else if (!oneHasConnection && twoHasConnection)
|
else if (!oneHasConnection && twoHasConnection)
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
|
let oneStrength = one.accessPoints[0].strength;
|
||||||
|
let twoStrength = two.accessPoints[0].strength;
|
||||||
|
|
||||||
|
// place stronger connections first
|
||||||
|
if (oneStrength != twoStrength)
|
||||||
|
return oneStrength < twoStrength ? 1 : -1;
|
||||||
|
|
||||||
let oneHasSecurity = one.security != NMAccessPointSecurity.NONE;
|
let oneHasSecurity = one.security != NMAccessPointSecurity.NONE;
|
||||||
let twoHasSecurity = two.security != NMAccessPointSecurity.NONE;
|
let twoHasSecurity = two.security != NMAccessPointSecurity.NONE;
|
||||||
|
|
||||||
@ -1204,6 +1205,28 @@ const NMDeviceWireless = new Lang.Class({
|
|||||||
return -1;
|
return -1;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
_onApStrengthChanged: function(ap) {
|
||||||
|
let res = this._findExistingNetwork(ap);
|
||||||
|
if (res == null) {
|
||||||
|
// Uhm... stale signal?
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
let network = this._networks[res.network];
|
||||||
|
network.accessPoints.splice(res.ap, 1);
|
||||||
|
Util.insertSorted(network.accessPoints, ap, function(one, two) {
|
||||||
|
return two.strength - one.strength;
|
||||||
|
});
|
||||||
|
|
||||||
|
this._networks.splice(res.network, 1);
|
||||||
|
let newPos = Util.insertSorted(this._networks, network, Lang.bind(this, this._networkSortFunction));
|
||||||
|
|
||||||
|
if (newPos != res.network) {
|
||||||
|
this._clearSection();
|
||||||
|
this._queueCreateSection();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
_accessPointAdded: function(device, accessPoint) {
|
_accessPointAdded: function(device, accessPoint) {
|
||||||
if (accessPoint.get_ssid() == null) {
|
if (accessPoint.get_ssid() == null) {
|
||||||
// This access point is not visible yet
|
// This access point is not visible yet
|
||||||
@ -1223,9 +1246,11 @@ const NMDeviceWireless = new Lang.Class({
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
apObj.accessPoints.push(accessPoint);
|
Util.insertSorted(apObj.accessPoints, accessPoint, function(one, two) {
|
||||||
|
return two.strength - one.strength;
|
||||||
|
});
|
||||||
if (apObj.item)
|
if (apObj.item)
|
||||||
apObj.item.updateAccessPoints(apObj.accessPoints);
|
apObj.item.updateBestAP(apObj.accessPoints[0]);
|
||||||
} else {
|
} else {
|
||||||
apObj = { ssid: accessPoint.get_ssid(),
|
apObj = { ssid: accessPoint.get_ssid(),
|
||||||
mode: accessPoint.mode,
|
mode: accessPoint.mode,
|
||||||
@ -1236,6 +1261,7 @@ const NMDeviceWireless = new Lang.Class({
|
|||||||
};
|
};
|
||||||
apObj.ssidText = ssidToLabel(apObj.ssid);
|
apObj.ssidText = ssidToLabel(apObj.ssid);
|
||||||
}
|
}
|
||||||
|
accessPoint._updateId = accessPoint.connect('notify::strength', Lang.bind(this, this._onApStrengthChanged));
|
||||||
|
|
||||||
// check if this enables new connections for this group
|
// check if this enables new connections for this group
|
||||||
for (let i = 0; i < this._connections.length; i++) {
|
for (let i = 0; i < this._connections.length; i++) {
|
||||||
@ -1243,23 +1269,26 @@ const NMDeviceWireless = new Lang.Class({
|
|||||||
if (accessPoint.connection_valid(connection) &&
|
if (accessPoint.connection_valid(connection) &&
|
||||||
apObj.connections.indexOf(connection) == -1) {
|
apObj.connections.indexOf(connection) == -1) {
|
||||||
apObj.connections.push(connection);
|
apObj.connections.push(connection);
|
||||||
|
|
||||||
// this potentially changes the order
|
|
||||||
needsupdate = true;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pos == -1 || needsupdate) {
|
|
||||||
if (pos != -1)
|
if (pos != -1)
|
||||||
this._networks.splice(pos, 1);
|
this._networks.splice(pos, 1);
|
||||||
pos = Util.insertSorted(this._networks, apObj, this._networkSortFunction);
|
let newPos = Util.insertSorted(this._networks, apObj, this._networkSortFunction);
|
||||||
|
|
||||||
|
// Queue an update of the UI if we changed the order
|
||||||
|
if (newPos != pos) {
|
||||||
this._clearSection();
|
this._clearSection();
|
||||||
this._queueCreateSection();
|
this._queueCreateSection();
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
_accessPointRemoved: function(device, accessPoint) {
|
_accessPointRemoved: function(device, accessPoint) {
|
||||||
|
if (accessPoint._updateId) {
|
||||||
|
accessPoint.disconnect(accessPoint._updateId);
|
||||||
|
accessPoint._updateId = 0;
|
||||||
|
}
|
||||||
|
|
||||||
let res = this._findExistingNetwork(accessPoint);
|
let res = this._findExistingNetwork(accessPoint);
|
||||||
|
|
||||||
if (res == null) {
|
if (res == null) {
|
||||||
@ -1301,17 +1330,30 @@ const NMDeviceWireless = new Lang.Class({
|
|||||||
this._overflowItem = null;
|
this._overflowItem = null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
this._networks.splice(res.network, 1);
|
|
||||||
|
|
||||||
} else if (apObj.item)
|
this._networks.splice(res.network, 1);
|
||||||
apObj.item.updateAccessPoints(apObj.accessPoints);
|
} else {
|
||||||
|
let okPrev = true, okNext = true;
|
||||||
|
|
||||||
|
if (res.network > 0)
|
||||||
|
okPrev = this._networkSortFunction(this._networks[res.network - 1], apObj) >= 0;
|
||||||
|
if (res.network < this._networks.length-1)
|
||||||
|
okNext = this._networkSortFunction(this._networks[res.network + 1], apObj) <= 0;
|
||||||
|
|
||||||
|
if (!okPrev || !okNext) {
|
||||||
|
this._clearSection();
|
||||||
|
this._queueCreateSection();
|
||||||
|
} else if (apObj.item) {
|
||||||
|
apObj.item.updateBestAP(apObj.accessPoints[0]);
|
||||||
|
}
|
||||||
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
_createAPItem: function(connection, accessPointObj, useConnectionName) {
|
_createAPItem: function(connection, accessPointObj, useConnectionName) {
|
||||||
let item = new NMNetworkMenuItem(accessPointObj.accessPoints, useConnectionName ? connection._name : undefined);
|
let item = new NMNetworkMenuItem(accessPointObj.accessPoints[0], useConnectionName ? connection.get_id() : undefined);
|
||||||
item._connection = connection;
|
item._connection = connection;
|
||||||
item.connect('activate', Lang.bind(this, function() {
|
item.connect('activate', Lang.bind(this, function() {
|
||||||
let accessPoints = sortAccessPoints(accessPointObj.accessPoints);
|
let accessPoints = accessPointObj.accessPoints;
|
||||||
for (let i = 0; i < accessPoints.length; i++) {
|
for (let i = 0; i < accessPoints.length; i++) {
|
||||||
if (accessPoints[i].connection_valid(connection)) {
|
if (accessPoints[i].connection_valid(connection)) {
|
||||||
this._client.activate_connection(connection, this.device, accessPoints[i].dbus_path, null);
|
this._client.activate_connection(connection, this.device, accessPoints[i].dbus_path, null);
|
||||||
@ -1331,9 +1373,7 @@ const NMDeviceWireless = new Lang.Class({
|
|||||||
},
|
},
|
||||||
|
|
||||||
removeConnection: function(connection) {
|
removeConnection: function(connection) {
|
||||||
if (!connection._uuid)
|
let pos = this._findConnection(connection.get_uuid());
|
||||||
return;
|
|
||||||
let pos = this._findConnection(connection._uuid);
|
|
||||||
if (pos == -1) {
|
if (pos == -1) {
|
||||||
// removing connection that was never added
|
// removing connection that was never added
|
||||||
return;
|
return;
|
||||||
@ -1347,7 +1387,7 @@ const NMDeviceWireless = new Lang.Class({
|
|||||||
let apObj = this._networks[i];
|
let apObj = this._networks[i];
|
||||||
let connections = apObj.connections;
|
let connections = apObj.connections;
|
||||||
for (let k = 0; k < connections.length; k++) {
|
for (let k = 0; k < connections.length; k++) {
|
||||||
if (connections[k]._uuid == connection._uuid) {
|
if (connections[k].get_uuid() == connection.get_uuid()) {
|
||||||
// remove the connection from the access point group
|
// remove the connection from the access point group
|
||||||
connections.splice(k);
|
connections.splice(k);
|
||||||
forceupdate = forceupdate || connections.length == 0;
|
forceupdate = forceupdate || connections.length == 0;
|
||||||
@ -1363,7 +1403,7 @@ const NMDeviceWireless = new Lang.Class({
|
|||||||
forceupdate = true;
|
forceupdate = true;
|
||||||
} else {
|
} else {
|
||||||
for (let j = 0; j < items.length; j++) {
|
for (let j = 0; j < items.length; j++) {
|
||||||
if (items[j]._connection._uuid == connection._uuid) {
|
if (items[j]._connection.get_uuid() == connection.get_uuid()) {
|
||||||
items[j].destroy();
|
items[j].destroy();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -1390,8 +1430,8 @@ const NMDeviceWireless = new Lang.Class({
|
|||||||
// record the connection
|
// record the connection
|
||||||
let obj = {
|
let obj = {
|
||||||
connection: connection,
|
connection: connection,
|
||||||
name: connection._name,
|
name: connection.get_id(),
|
||||||
uuid: connection._uuid,
|
uuid: connection.get_uuid(),
|
||||||
};
|
};
|
||||||
this._connections.push(obj);
|
this._connections.push(obj);
|
||||||
|
|
||||||
@ -1420,27 +1460,19 @@ const NMDeviceWireless = new Lang.Class({
|
|||||||
},
|
},
|
||||||
|
|
||||||
_createActiveConnectionItem: function() {
|
_createActiveConnectionItem: function() {
|
||||||
let icon, title;
|
let title;
|
||||||
if (this._activeConnection && this._activeConnection._connection) {
|
if (this._activeConnection && this._activeConnection._connection)
|
||||||
let connection = this._activeConnection._connection;
|
title = this._activeConnection._connection.get_id();
|
||||||
|
else
|
||||||
|
title = _("Connected (private)");
|
||||||
|
|
||||||
if (this._activeNetwork)
|
if (this._activeNetwork)
|
||||||
this._activeConnectionItem = new NMNetworkMenuItem(this._activeNetwork.accessPoints, undefined,
|
this._activeConnectionItem = new NMNetworkMenuItem(this.device.active_access_point, undefined,
|
||||||
{ reactive: false });
|
{ reactive: false });
|
||||||
else
|
else
|
||||||
this._activeConnectionItem = new PopupMenu.PopupImageMenuItem(connection._name,
|
this._activeConnectionItem = new PopupMenu.PopupImageMenuItem(title,
|
||||||
'network-wireless-connected',
|
'network-wireless-connected',
|
||||||
{ reactive: false });
|
{ reactive: false });
|
||||||
} else {
|
|
||||||
// We cannot read the connection (due to ACL, or API incompatibility), but we still show signal if we have it
|
|
||||||
let menuItem;
|
|
||||||
if (this._activeNetwork)
|
|
||||||
this._activeConnectionItem = new NMNetworkMenuItem(this._activeNetwork.accessPoints, undefined,
|
|
||||||
{ reactive: false });
|
|
||||||
else
|
|
||||||
this._activeConnectionItem = new PopupMenu.PopupImageMenuItem(_("Connected (private)"),
|
|
||||||
'network-wireless-connected',
|
|
||||||
{ reactive: false });
|
|
||||||
}
|
|
||||||
this._activeConnectionItem.setShowDot(true);
|
this._activeConnectionItem.setShowDot(true);
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -1480,9 +1512,9 @@ const NMDeviceWireless = new Lang.Class({
|
|||||||
apObj.item.menu.addMenuItem(this._createAPItem(apObj.connections[i], apObj, true));
|
apObj.item.menu.addMenuItem(this._createAPItem(apObj.connections[i], apObj, true));
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
apObj.item = new NMNetworkMenuItem(apObj.accessPoints);
|
apObj.item = new NMNetworkMenuItem(apObj.accessPoints[0]);
|
||||||
apObj.item.connect('activate', Lang.bind(this, function() {
|
apObj.item.connect('activate', Lang.bind(this, function() {
|
||||||
let accessPoints = sortAccessPoints(apObj.accessPoints);
|
let accessPoints = apObj.accessPoints;
|
||||||
if ( (accessPoints[0]._secType == NMAccessPointSecurity.WPA2_ENT)
|
if ( (accessPoints[0]._secType == NMAccessPointSecurity.WPA2_ENT)
|
||||||
|| (accessPoints[0]._secType == NMAccessPointSecurity.WPA_ENT)) {
|
|| (accessPoints[0]._secType == NMAccessPointSecurity.WPA_ENT)) {
|
||||||
// 802.1x-enabled APs require further configuration, so they're
|
// 802.1x-enabled APs require further configuration, so they're
|
||||||
@ -1535,10 +1567,25 @@ const NMDeviceWireless = new Lang.Class({
|
|||||||
|
|
||||||
const NMApplet = new Lang.Class({
|
const NMApplet = new Lang.Class({
|
||||||
Name: 'NMApplet',
|
Name: 'NMApplet',
|
||||||
Extends: PanelMenu.SystemStatusButton,
|
Extends: PanelMenu.Button,
|
||||||
|
|
||||||
_init: function() {
|
_init: function() {
|
||||||
this.parent('network-error', _("Network"));
|
this.parent(0.0, _('Network'));
|
||||||
|
|
||||||
|
this._box = new St.BoxLayout({ name: 'networkMenu' });
|
||||||
|
this.actor.add_actor (this._box);
|
||||||
|
this.actor.add_style_class_name('panel-status-button');
|
||||||
|
|
||||||
|
this._primaryIcon = new St.Icon({ icon_name: 'network-offline',
|
||||||
|
icon_type: St.IconType.SYMBOLIC,
|
||||||
|
style_class: 'system-status-icon' });
|
||||||
|
this._box.add_actor(this._primaryIcon);
|
||||||
|
|
||||||
|
this._secondaryIcon = new St.Icon({ icon_name: 'network-vpn',
|
||||||
|
icon_type: St.IconType.SYMBOLIC,
|
||||||
|
style_class: 'system-status-icon',
|
||||||
|
visible: false });
|
||||||
|
this._box.add_actor(this._secondaryIcon);
|
||||||
|
|
||||||
this._client = NMClient.Client.new();
|
this._client = NMClient.Client.new();
|
||||||
|
|
||||||
@ -1552,6 +1599,16 @@ const NMApplet = new Lang.Class({
|
|||||||
this.menu.addMenuItem(this._statusSection);
|
this.menu.addMenuItem(this._statusSection);
|
||||||
this.menu.addMenuItem(new PopupMenu.PopupSeparatorMenuItem());
|
this.menu.addMenuItem(new PopupMenu.PopupSeparatorMenuItem());
|
||||||
|
|
||||||
|
this._activeConnections = [ ];
|
||||||
|
this._connections = [ ];
|
||||||
|
|
||||||
|
this._mainConnection = null;
|
||||||
|
this._vpnConnection = null;
|
||||||
|
this._activeAccessPointUpdateId = 0;
|
||||||
|
this._activeAccessPoint = null;
|
||||||
|
this._mobileUpdateId = 0;
|
||||||
|
this._mobileUpdateDevice = null;
|
||||||
|
|
||||||
this._devices = { };
|
this._devices = { };
|
||||||
|
|
||||||
this._devices.wired = {
|
this._devices.wired = {
|
||||||
@ -1587,13 +1644,9 @@ const NMApplet = new Lang.Class({
|
|||||||
|
|
||||||
this._devices.vpn = {
|
this._devices.vpn = {
|
||||||
section: new PopupMenu.PopupMenuSection(),
|
section: new PopupMenu.PopupMenuSection(),
|
||||||
device: new NMDeviceVPN(this._client),
|
device: this._makeWrapperDevice(NMDeviceVPN, null),
|
||||||
item: new NMWiredSectionTitleMenuItem(_("VPN Connections"))
|
item: new NMWiredSectionTitleMenuItem(_("VPN Connections"))
|
||||||
};
|
};
|
||||||
this._devices.vpn.device.connect('active-connection-changed', Lang.bind(this, function() {
|
|
||||||
this._devices.vpn.item.updateForDevice(this._devices.vpn.device);
|
|
||||||
}));
|
|
||||||
this._devices.vpn.item.updateForDevice(this._devices.vpn.device);
|
|
||||||
this._devices.vpn.section.addMenuItem(this._devices.vpn.item);
|
this._devices.vpn.section.addMenuItem(this._devices.vpn.item);
|
||||||
this._devices.vpn.section.addMenuItem(this._devices.vpn.device.section);
|
this._devices.vpn.section.addMenuItem(this._devices.vpn.device.section);
|
||||||
this._devices.vpn.section.actor.hide();
|
this._devices.vpn.section.actor.hide();
|
||||||
@ -1601,15 +1654,6 @@ const NMApplet = new Lang.Class({
|
|||||||
this.menu.addMenuItem(new PopupMenu.PopupSeparatorMenuItem());
|
this.menu.addMenuItem(new PopupMenu.PopupSeparatorMenuItem());
|
||||||
this.menu.addSettingsAction(_("Network Settings"), 'gnome-network-panel.desktop');
|
this.menu.addSettingsAction(_("Network Settings"), 'gnome-network-panel.desktop');
|
||||||
|
|
||||||
this._activeConnections = [ ];
|
|
||||||
this._connections = [ ];
|
|
||||||
|
|
||||||
this._mainConnection = null;
|
|
||||||
this._activeAccessPointUpdateId = 0;
|
|
||||||
this._activeAccessPoint = null;
|
|
||||||
this._mobileUpdateId = 0;
|
|
||||||
this._mobileUpdateDevice = null;
|
|
||||||
|
|
||||||
// Device types
|
// Device types
|
||||||
this._dtypes = { };
|
this._dtypes = { };
|
||||||
this._dtypes[NetworkManager.DeviceType.ETHERNET] = NMDeviceWired;
|
this._dtypes[NetworkManager.DeviceType.ETHERNET] = NMDeviceWired;
|
||||||
@ -1650,9 +1694,16 @@ const NMApplet = new Lang.Class({
|
|||||||
}));
|
}));
|
||||||
},
|
},
|
||||||
|
|
||||||
|
setIcon: function(iconName) {
|
||||||
|
this._primaryIcon.icon_name = iconName;
|
||||||
|
},
|
||||||
|
|
||||||
_ensureSource: function() {
|
_ensureSource: function() {
|
||||||
if (!this._source) {
|
if (!this._source) {
|
||||||
this._source = new NMMessageTraySource();
|
this._source = new MessageTray.Source(_("Network Manager"),
|
||||||
|
'network-transmit-receive',
|
||||||
|
St.IconType.SYMBOLIC);
|
||||||
|
|
||||||
this._source.connect('destroy', Lang.bind(this, function() {
|
this._source.connect('destroy', Lang.bind(this, function() {
|
||||||
this._source = null;
|
this._source = null;
|
||||||
}));
|
}));
|
||||||
@ -1673,6 +1724,18 @@ const NMApplet = new Lang.Class({
|
|||||||
},
|
},
|
||||||
|
|
||||||
_syncSectionTitle: function(category) {
|
_syncSectionTitle: function(category) {
|
||||||
|
if (category == NMConnectionCategory.VPN) {
|
||||||
|
// Special case VPN: it's only one device (and a fake one
|
||||||
|
// actually), and we don't show it if empty
|
||||||
|
let device = this._devices.vpn.device;
|
||||||
|
let section = this._devices.vpn.section;
|
||||||
|
let item = this._devices.vpn.item;
|
||||||
|
|
||||||
|
section.actor.visible = !device.empty;
|
||||||
|
item.updateForDevice(device);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
let devices = this._devices[category].devices;
|
let devices = this._devices[category].devices;
|
||||||
let item = this._devices[category].item;
|
let item = this._devices[category].item;
|
||||||
let section = this._devices[category].section;
|
let section = this._devices[category].section;
|
||||||
@ -1723,13 +1786,7 @@ const NMApplet = new Lang.Class({
|
|||||||
this._source.notify(device._notification);
|
this._source.notify(device._notification);
|
||||||
},
|
},
|
||||||
|
|
||||||
_deviceAdded: function(client, device) {
|
_makeWrapperDevice: function(wrapperClass, device) {
|
||||||
if (device._delegate) {
|
|
||||||
// already seen, not adding again
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
let wrapperClass = this._dtypes[device.get_device_type()];
|
|
||||||
if (wrapperClass) {
|
|
||||||
let wrapper = new wrapperClass(this._client, device, this._connections);
|
let wrapper = new wrapperClass(this._client, device, this._connections);
|
||||||
|
|
||||||
wrapper._activationFailedId = wrapper.connect('activation-failed', Lang.bind(this, function(device, reason) {
|
wrapper._activationFailedId = wrapper.connect('activation-failed', Lang.bind(this, function(device, reason) {
|
||||||
@ -1748,6 +1805,19 @@ const NMApplet = new Lang.Class({
|
|||||||
wrapper.disconnect(wrapper._deviceStateChangedId);
|
wrapper.disconnect(wrapper._deviceStateChangedId);
|
||||||
wrapper.disconnect(wrapper._destroyId);
|
wrapper.disconnect(wrapper._destroyId);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
return wrapper;
|
||||||
|
},
|
||||||
|
|
||||||
|
_deviceAdded: function(client, device) {
|
||||||
|
if (device._delegate) {
|
||||||
|
// already seen, not adding again
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
let wrapperClass = this._dtypes[device.get_device_type()];
|
||||||
|
if (wrapperClass) {
|
||||||
|
let wrapper = this._makeWrapperDevice(wrapperClass, device);
|
||||||
|
|
||||||
let section = this._devices[wrapper.category].section;
|
let section = this._devices[wrapper.category].section;
|
||||||
let devices = this._devices[wrapper.category].devices;
|
let devices = this._devices[wrapper.category].devices;
|
||||||
|
|
||||||
@ -1801,6 +1871,8 @@ const NMApplet = new Lang.Class({
|
|||||||
|
|
||||||
this._activeConnections = newActiveConnections;
|
this._activeConnections = newActiveConnections;
|
||||||
this._mainConnection = null;
|
this._mainConnection = null;
|
||||||
|
this._vpnConnection = null;
|
||||||
|
|
||||||
let activating = null;
|
let activating = null;
|
||||||
let default_ip4 = null;
|
let default_ip4 = null;
|
||||||
let default_ip6 = null;
|
let default_ip6 = null;
|
||||||
@ -1834,17 +1906,17 @@ const NMApplet = new Lang.Class({
|
|||||||
default_ip4 = a;
|
default_ip4 = a;
|
||||||
if (a.default6)
|
if (a.default6)
|
||||||
default_ip6 = a;
|
default_ip6 = a;
|
||||||
|
|
||||||
if (a._type == 'vpn')
|
if (a._type == 'vpn')
|
||||||
active_vpn = a;
|
active_vpn = a;
|
||||||
|
else if (a.state == NetworkManager.ActiveConnectionState.ACTIVATING)
|
||||||
if (a.state == NetworkManager.ActiveConnectionState.ACTIVATING)
|
|
||||||
activating = a;
|
activating = a;
|
||||||
|
|
||||||
if (!a._primaryDevice) {
|
if (!a._primaryDevice) {
|
||||||
if (a._type != NetworkManager.SETTING_VPN_SETTING_NAME) {
|
if (a._type != NetworkManager.SETTING_VPN_SETTING_NAME) {
|
||||||
// find a good device to be considered primary
|
// find a good device to be considered primary
|
||||||
a._primaryDevice = null;
|
a._primaryDevice = null;
|
||||||
let devices = a.get_devices();
|
let devices = a.get_devices() || [];
|
||||||
for (let j = 0; j < devices.length; j++) {
|
for (let j = 0; j < devices.length; j++) {
|
||||||
let d = devices[j];
|
let d = devices[j];
|
||||||
if (d._delegate) {
|
if (d._delegate) {
|
||||||
@ -1866,7 +1938,8 @@ const NMApplet = new Lang.Class({
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
this._mainConnection = activating || active_vpn || default_ip4 || default_ip6 || this._activeConnections[0] || null;
|
this._mainConnection = activating || default_ip4 || default_ip6 || this._activeConnections[0] || null;
|
||||||
|
this._vpnConnection = active_vpn;
|
||||||
},
|
},
|
||||||
|
|
||||||
_notifyActivated: function(activeConnection) {
|
_notifyActivated: function(activeConnection) {
|
||||||
@ -1883,7 +1956,7 @@ const NMApplet = new Lang.Class({
|
|||||||
let connections = this._settings.list_connections();
|
let connections = this._settings.list_connections();
|
||||||
for (let i = 0; i < connections.length; i++) {
|
for (let i = 0; i < connections.length; i++) {
|
||||||
let connection = connections[i];
|
let connection = connections[i];
|
||||||
if (connection._uuid) {
|
if (connection._updatedId) {
|
||||||
// connection was already seen (for example because NetworkManager was restarted)
|
// connection was already seen (for example because NetworkManager was restarted)
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@ -1896,7 +1969,7 @@ const NMApplet = new Lang.Class({
|
|||||||
},
|
},
|
||||||
|
|
||||||
_newConnection: function(settings, connection) {
|
_newConnection: function(settings, connection) {
|
||||||
if (connection._uuid) {
|
if (connection._updatedId) {
|
||||||
// connection was already seen
|
// connection was already seen
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -1919,35 +1992,31 @@ const NMApplet = new Lang.Class({
|
|||||||
|
|
||||||
if (section == NMConnectionCategory.VPN) {
|
if (section == NMConnectionCategory.VPN) {
|
||||||
this._devices.vpn.device.removeConnection(connection);
|
this._devices.vpn.device.removeConnection(connection);
|
||||||
if (this._devices.vpn.device.empty)
|
this._syncSectionTitle(section);
|
||||||
this._devices.vpn.section.actor.hide();
|
|
||||||
} else if (section != NMConnectionCategory.INVALID) {
|
} else if (section != NMConnectionCategory.INVALID) {
|
||||||
let devices = this._devices[section].devices;
|
let devices = this._devices[section].devices;
|
||||||
for (let i = 0; i < devices.length; i++)
|
for (let i = 0; i < devices.length; i++)
|
||||||
devices[i].removeConnection(connection);
|
devices[i].removeConnection(connection);
|
||||||
}
|
}
|
||||||
|
|
||||||
connection._uuid = null;
|
|
||||||
connection.disconnect(connection._removedId);
|
connection.disconnect(connection._removedId);
|
||||||
connection.disconnect(connection._updatedId);
|
connection.disconnect(connection._updatedId);
|
||||||
|
connection._removedId = connection._updatedId = 0;
|
||||||
},
|
},
|
||||||
|
|
||||||
_updateConnection: function(connection) {
|
_updateConnection: function(connection) {
|
||||||
let connectionSettings = connection.get_setting_by_name(NetworkManager.SETTING_CONNECTION_SETTING_NAME);
|
let connectionSettings = connection.get_setting_by_name(NetworkManager.SETTING_CONNECTION_SETTING_NAME);
|
||||||
connection._type = connectionSettings.type;
|
connection._type = connectionSettings.type;
|
||||||
|
|
||||||
connection._section = this._ctypes[connection._type] || NMConnectionCategory.INVALID;
|
connection._section = this._ctypes[connection._type] || NMConnectionCategory.INVALID;
|
||||||
connection._name = connectionSettings.id;
|
|
||||||
connection._uuid = connectionSettings.uuid;
|
|
||||||
connection._timestamp = connectionSettings.timestamp;
|
connection._timestamp = connectionSettings.timestamp;
|
||||||
|
|
||||||
let section = connection._section;
|
let section = connection._section;
|
||||||
|
|
||||||
if (connection._section == NMConnectionCategory.INVALID)
|
if (section == NMConnectionCategory.INVALID)
|
||||||
return;
|
return;
|
||||||
if (section == NMConnectionCategory.VPN) {
|
if (section == NMConnectionCategory.VPN) {
|
||||||
this._devices.vpn.device.checkConnection(connection);
|
this._devices.vpn.device.checkConnection(connection);
|
||||||
this._devices.vpn.section.actor.show();
|
this._syncSectionTitle(section);
|
||||||
} else {
|
} else {
|
||||||
let devices = this._devices[section].devices;
|
let devices = this._devices[section].devices;
|
||||||
for (let i = 0; i < devices.length; i++) {
|
for (let i = 0; i < devices.length; i++) {
|
||||||
@ -1970,12 +2039,10 @@ const NMApplet = new Lang.Class({
|
|||||||
|
|
||||||
this._statusSection.actor.hide();
|
this._statusSection.actor.hide();
|
||||||
|
|
||||||
this._syncSectionTitle('wired');
|
this._syncSectionTitle(NMConnectionCategory.WIRED);
|
||||||
this._syncSectionTitle('wireless');
|
this._syncSectionTitle(NMConnectionCategory.WIRELESS);
|
||||||
this._syncSectionTitle('wwan');
|
this._syncSectionTitle(NMConnectionCategory.WWAN);
|
||||||
|
this._syncSectionTitle(NMConnectionCategory.VPN);
|
||||||
if (!this._devices.vpn.device.empty)
|
|
||||||
this._devices.vpn.section.actor.show();
|
|
||||||
},
|
},
|
||||||
|
|
||||||
_syncNMState: function() {
|
_syncNMState: function() {
|
||||||
@ -2018,9 +2085,6 @@ const NMApplet = new Lang.Class({
|
|||||||
case NMConnectionCategory.WIRED:
|
case NMConnectionCategory.WIRED:
|
||||||
this.setIcon('network-wired-acquiring');
|
this.setIcon('network-wired-acquiring');
|
||||||
break;
|
break;
|
||||||
case NMConnectionCategory.VPN:
|
|
||||||
this.setIcon('network-vpn-acquiring');
|
|
||||||
break;
|
|
||||||
default:
|
default:
|
||||||
// fallback to a generic connected icon
|
// fallback to a generic connected icon
|
||||||
// (it could be a private connection of some other user)
|
// (it could be a private connection of some other user)
|
||||||
@ -2083,9 +2147,6 @@ const NMApplet = new Lang.Class({
|
|||||||
this.setIcon('network-cellular-signal-' + signalToIcon(dev.mobileDevice.signal_quality));
|
this.setIcon('network-cellular-signal-' + signalToIcon(dev.mobileDevice.signal_quality));
|
||||||
hasMobileIcon = true;
|
hasMobileIcon = true;
|
||||||
break;
|
break;
|
||||||
case NMConnectionCategory.VPN:
|
|
||||||
this.setIcon('network-vpn');
|
|
||||||
break;
|
|
||||||
default:
|
default:
|
||||||
// fallback to a generic connected icon
|
// fallback to a generic connected icon
|
||||||
// (it could be a private connection of some other user)
|
// (it could be a private connection of some other user)
|
||||||
@ -2094,6 +2155,25 @@ const NMApplet = new Lang.Class({
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// update VPN indicator
|
||||||
|
if (this._vpnConnection) {
|
||||||
|
let vpnIconName = 'network-vpn';
|
||||||
|
if (this._vpnConnection.state == NetworkManager.ActiveConnectionState.ACTIVATING)
|
||||||
|
vpnIconName = 'network-vpn-acquiring';
|
||||||
|
|
||||||
|
// only show a separate icon when we're using a wireless/3g connection
|
||||||
|
if (mc._section == NMConnectionCategory.WIRELESS ||
|
||||||
|
mc._section == NMConnectionCategory.WWAN) {
|
||||||
|
this._secondaryIcon.icon_name = vpnIconName;
|
||||||
|
this._secondaryIcon.visible = true;
|
||||||
|
} else {
|
||||||
|
this.setIcon(vpnIconName);
|
||||||
|
this._secondaryIcon.visible = false;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
this._secondaryIcon.visible = false;
|
||||||
|
}
|
||||||
|
|
||||||
// cleanup stale signal connections
|
// cleanup stale signal connections
|
||||||
|
|
||||||
if (!hasApIcon && this._activeAccessPointUpdateId) {
|
if (!hasApIcon && this._activeAccessPointUpdateId) {
|
||||||
@ -2108,18 +2188,3 @@ const NMApplet = new Lang.Class({
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
const NMMessageTraySource = new Lang.Class({
|
|
||||||
Name: 'NMMessageTraySource',
|
|
||||||
Extends: MessageTray.Source,
|
|
||||||
|
|
||||||
_init: function() {
|
|
||||||
this.parent(_("Network Manager"));
|
|
||||||
|
|
||||||
let icon = new St.Icon({ icon_name: 'network-transmit-receive',
|
|
||||||
icon_type: St.IconType.SYMBOLIC,
|
|
||||||
icon_size: this.ICON_SIZE
|
|
||||||
});
|
|
||||||
this._setSummaryIcon(icon);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
@ -212,7 +212,7 @@ const DeviceItem = new Lang.Class({
|
|||||||
case UPDeviceType.COMPUTER:
|
case UPDeviceType.COMPUTER:
|
||||||
return _("Computer");
|
return _("Computer");
|
||||||
default:
|
default:
|
||||||
return _("Unknown");
|
return C_("device", "Unknown");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -149,13 +149,9 @@ const Indicator = new Lang.Class({
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (showInput) {
|
|
||||||
this._inputTitle.actor.show();
|
this._inputTitle.actor.visible = showInput;
|
||||||
this._inputSlider.actor.show();
|
this._inputSlider.actor.visible = showInput;
|
||||||
} else {
|
|
||||||
this._inputTitle.actor.hide();
|
|
||||||
this._inputSlider.actor.hide();
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
|
|
||||||
_volumeToIcon: function(volume) {
|
_volumeToIcon: function(volume) {
|
||||||
|
@ -20,7 +20,7 @@ const STANDARD_TRAY_ICON_IMPLEMENTATIONS = {
|
|||||||
'kbd-scrolllock': 'keyboard',
|
'kbd-scrolllock': 'keyboard',
|
||||||
'kbd-numlock': 'keyboard',
|
'kbd-numlock': 'keyboard',
|
||||||
'kbd-capslock': 'keyboard',
|
'kbd-capslock': 'keyboard',
|
||||||
'ibus-ui-gtk': 'input-method'
|
'ibus-ui-gtk': 'keyboard'
|
||||||
};
|
};
|
||||||
|
|
||||||
const StatusIconDispatcher = new Lang.Class({
|
const StatusIconDispatcher = new Lang.Class({
|
||||||
|
@ -132,6 +132,9 @@ const Client = new Lang.Class({
|
|||||||
let channel = channels[i];
|
let channel = channels[i];
|
||||||
let [targetHandle, targetHandleType] = channel.get_handle();
|
let [targetHandle, targetHandleType] = channel.get_handle();
|
||||||
|
|
||||||
|
if (Shell.is_channel_invalidated(channel))
|
||||||
|
continue;
|
||||||
|
|
||||||
/* Only observe contact text channels */
|
/* Only observe contact text channels */
|
||||||
if ((!(channel instanceof Tp.TextChannel)) ||
|
if ((!(channel instanceof Tp.TextChannel)) ||
|
||||||
targetHandleType != Tp.HandleType.CONTACT)
|
targetHandleType != Tp.HandleType.CONTACT)
|
||||||
@ -181,6 +184,9 @@ const Client = new Lang.Class({
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (Shell.is_channel_invalidated(channel))
|
||||||
|
continue;
|
||||||
|
|
||||||
// 'notify' will be true when coming from an actual HandleChannels
|
// 'notify' will be true when coming from an actual HandleChannels
|
||||||
// call, and not when from a successful Claim call. The point is
|
// call, and not when from a successful Claim call. The point is
|
||||||
// we don't want to notify for a channel we just claimed which
|
// we don't want to notify for a channel we just claimed which
|
||||||
@ -231,12 +237,19 @@ const Client = new Lang.Class({
|
|||||||
let channel = channels[0];
|
let channel = channels[0];
|
||||||
let chanType = channel.get_channel_type();
|
let chanType = channel.get_channel_type();
|
||||||
|
|
||||||
|
if (Shell.is_channel_invalidated(channel)) {
|
||||||
|
Shell.decline_dispatch_op(context, 'Channel is invalidated');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (chanType == Tp.IFACE_CHANNEL_TYPE_TEXT)
|
if (chanType == Tp.IFACE_CHANNEL_TYPE_TEXT)
|
||||||
this._approveTextChannel(account, conn, channel, dispatchOp, context);
|
this._approveTextChannel(account, conn, channel, dispatchOp, context);
|
||||||
else if (chanType == Tp.IFACE_CHANNEL_TYPE_CALL)
|
else if (chanType == Tp.IFACE_CHANNEL_TYPE_CALL)
|
||||||
this._approveCall(account, conn, channel, dispatchOp, context);
|
this._approveCall(account, conn, channel, dispatchOp, context);
|
||||||
else if (chanType == Tp.IFACE_CHANNEL_TYPE_FILE_TRANSFER)
|
else if (chanType == Tp.IFACE_CHANNEL_TYPE_FILE_TRANSFER)
|
||||||
this._approveFileTransfer(account, conn, channel, dispatchOp, context);
|
this._approveFileTransfer(account, conn, channel, dispatchOp, context);
|
||||||
|
else
|
||||||
|
Shell.decline_dispatch_op(context, 'Unsupported channel type');
|
||||||
},
|
},
|
||||||
|
|
||||||
_approveTextChannel: function(account, conn, channel, dispatchOp, context) {
|
_approveTextChannel: function(account, conn, channel, dispatchOp, context) {
|
||||||
@ -365,8 +378,9 @@ const Client = new Lang.Class({
|
|||||||
|
|
||||||
_ensureSubscriptionSource: function() {
|
_ensureSubscriptionSource: function() {
|
||||||
if (this._subscriptionSource == null) {
|
if (this._subscriptionSource == null) {
|
||||||
this._subscriptionSource = new MultiNotificationSource(
|
this._subscriptionSource = new MessageTray.Source(_("Subscription request"),
|
||||||
_("Subscription request"), 'gtk-dialog-question');
|
'gtk-dialog-question',
|
||||||
|
St.IconType.FULLCOLOR);
|
||||||
Main.messageTray.add(this._subscriptionSource);
|
Main.messageTray.add(this._subscriptionSource);
|
||||||
this._subscriptionSource.connect('destroy', Lang.bind(this, function () {
|
this._subscriptionSource.connect('destroy', Lang.bind(this, function () {
|
||||||
this._subscriptionSource = null;
|
this._subscriptionSource = null;
|
||||||
@ -401,8 +415,9 @@ const Client = new Lang.Class({
|
|||||||
|
|
||||||
_ensureAccountSource: function() {
|
_ensureAccountSource: function() {
|
||||||
if (this._accountSource == null) {
|
if (this._accountSource == null) {
|
||||||
this._accountSource = new MultiNotificationSource(
|
this._accountSource = new MessageTray.Source(_("Connection error"),
|
||||||
_("Connection error"), 'gtk-dialog-error');
|
'gtk-dialog-error',
|
||||||
|
St.IconType.FULLCOLOR);
|
||||||
Main.messageTray.add(this._accountSource);
|
Main.messageTray.add(this._accountSource);
|
||||||
this._accountSource.connect('destroy', Lang.bind(this, function () {
|
this._accountSource.connect('destroy', Lang.bind(this, function () {
|
||||||
this._accountSource = null;
|
this._accountSource = null;
|
||||||
@ -418,14 +433,13 @@ const ChatSource = new Lang.Class({
|
|||||||
Extends: MessageTray.Source,
|
Extends: MessageTray.Source,
|
||||||
|
|
||||||
_init: function(account, conn, channel, contact, client) {
|
_init: function(account, conn, channel, contact, client) {
|
||||||
this.parent(contact.get_alias());
|
|
||||||
|
|
||||||
this.isChat = true;
|
|
||||||
|
|
||||||
this._account = account;
|
this._account = account;
|
||||||
this._contact = contact;
|
this._contact = contact;
|
||||||
this._client = client;
|
this._client = client;
|
||||||
|
|
||||||
|
this.parent(contact.get_alias());
|
||||||
|
|
||||||
|
this.isChat = true;
|
||||||
this._pendingMessages = [];
|
this._pendingMessages = [];
|
||||||
|
|
||||||
this._conn = conn;
|
this._conn = conn;
|
||||||
@ -446,8 +460,6 @@ const ChatSource = new Lang.Class({
|
|||||||
this._receivedId = this._channel.connect('message-received', Lang.bind(this, this._messageReceived));
|
this._receivedId = this._channel.connect('message-received', Lang.bind(this, this._messageReceived));
|
||||||
this._pendingId = this._channel.connect('pending-message-removed', Lang.bind(this, this._pendingRemoved));
|
this._pendingId = this._channel.connect('pending-message-removed', Lang.bind(this, this._pendingRemoved));
|
||||||
|
|
||||||
this._setSummaryIcon(this.createNotificationIcon());
|
|
||||||
|
|
||||||
this._notifyAliasId = this._contact.connect('notify::alias', Lang.bind(this, this._updateAlias));
|
this._notifyAliasId = this._contact.connect('notify::alias', Lang.bind(this, this._updateAlias));
|
||||||
this._notifyAvatarId = this._contact.connect('notify::avatar-file', Lang.bind(this, this._updateAvatarIcon));
|
this._notifyAvatarId = this._contact.connect('notify::avatar-file', Lang.bind(this, this._updateAvatarIcon));
|
||||||
this._presenceChangedId = this._contact.connect('presence-changed', Lang.bind(this, this._presenceChanged));
|
this._presenceChangedId = this._contact.connect('presence-changed', Lang.bind(this, this._presenceChanged));
|
||||||
@ -488,6 +500,37 @@ const ChatSource = new Lang.Class({
|
|||||||
return this._iconBox;
|
return this._iconBox;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
createSecondaryIcon: function() {
|
||||||
|
let iconBox = new St.Bin();
|
||||||
|
iconBox.child = new St.Icon({ style_class: 'secondary-icon',
|
||||||
|
icon_type: St.IconType.FULLCOLOR });
|
||||||
|
let presenceType = this._contact.get_presence_type();
|
||||||
|
|
||||||
|
switch (presenceType) {
|
||||||
|
case Tp.ConnectionPresenceType.AVAILABLE:
|
||||||
|
iconBox.child.icon_name = 'user-available';
|
||||||
|
break;
|
||||||
|
case Tp.ConnectionPresenceType.BUSY:
|
||||||
|
iconBox.child.icon_name = 'user-busy';
|
||||||
|
break;
|
||||||
|
case Tp.ConnectionPresenceType.OFFLINE:
|
||||||
|
iconBox.child.icon_name = 'user-offline';
|
||||||
|
break;
|
||||||
|
case Tp.ConnectionPresenceType.HIDDEN:
|
||||||
|
iconBox.child.icon_name = 'user-invisible';
|
||||||
|
break;
|
||||||
|
case Tp.ConnectionPresenceType.AWAY:
|
||||||
|
iconBox.child.icon_name = 'user-away';
|
||||||
|
break;
|
||||||
|
case Tp.ConnectionPresenceType.EXTENDED_AWAY:
|
||||||
|
iconBox.child.icon_name = 'user-idle';
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
iconBox.child.icon_name = 'user-offline';
|
||||||
|
}
|
||||||
|
return iconBox;
|
||||||
|
},
|
||||||
|
|
||||||
_updateAvatarIcon: function() {
|
_updateAvatarIcon: function() {
|
||||||
this._setSummaryIcon(this.createNotificationIcon());
|
this._setSummaryIcon(this.createNotificationIcon());
|
||||||
this._notification.update(this._notification.title, null, { customContent: true, icon: this.createNotificationIcon() });
|
this._notification.update(this._notification.title, null, { customContent: true, icon: this.createNotificationIcon() });
|
||||||
@ -510,10 +553,10 @@ const ChatSource = new Lang.Class({
|
|||||||
_getLogMessages: function() {
|
_getLogMessages: function() {
|
||||||
let logManager = Tpl.LogManager.dup_singleton();
|
let logManager = Tpl.LogManager.dup_singleton();
|
||||||
let entity = Tpl.Entity.new_from_tp_contact(this._contact, Tpl.EntityType.CONTACT);
|
let entity = Tpl.Entity.new_from_tp_contact(this._contact, Tpl.EntityType.CONTACT);
|
||||||
Shell.get_contact_events(logManager,
|
|
||||||
this._account, entity,
|
logManager.get_filtered_events_async(this._account, entity,
|
||||||
SCROLLBACK_HISTORY_LINES,
|
Tpl.EventTypeMask.TEXT, SCROLLBACK_HISTORY_LINES,
|
||||||
Lang.bind(this, this._displayPendingMessages));
|
null, Lang.bind(this, this._displayPendingMessages));
|
||||||
},
|
},
|
||||||
|
|
||||||
_displayPendingMessages: function(logManager, result) {
|
_displayPendingMessages: function(logManager, result) {
|
||||||
@ -652,38 +695,14 @@ const ChatSource = new Lang.Class({
|
|||||||
},
|
},
|
||||||
|
|
||||||
_presenceChanged: function (contact, presence, status, message) {
|
_presenceChanged: function (contact, presence, status, message) {
|
||||||
let msg, shouldNotify, title;
|
let msg, title;
|
||||||
|
|
||||||
if (this._presence == presence)
|
|
||||||
return;
|
|
||||||
|
|
||||||
title = GLib.markup_escape_text(this.title, -1);
|
title = GLib.markup_escape_text(this.title, -1);
|
||||||
|
|
||||||
if (presence == Tp.ConnectionPresenceType.AVAILABLE) {
|
this._notification.update(this._notification.title, null, { customContent: true, secondaryIcon: this.createSecondaryIcon() });
|
||||||
msg = _("%s is online.").format(title);
|
|
||||||
shouldNotify = (this._presence == Tp.ConnectionPresenceType.OFFLINE);
|
|
||||||
} else if (presence == Tp.ConnectionPresenceType.OFFLINE) {
|
|
||||||
presence = Tp.ConnectionPresenceType.OFFLINE;
|
|
||||||
msg = _("%s is offline.").format(title);
|
|
||||||
shouldNotify = (this._presence != Tp.ConnectionPresenceType.OFFLINE);
|
|
||||||
} else if (presence == Tp.ConnectionPresenceType.AWAY ||
|
|
||||||
presence == Tp.ConnectionPresenceType.EXTENDED_AWAY) {
|
|
||||||
msg = _("%s is away.").format(title);
|
|
||||||
shouldNotify = false;
|
|
||||||
} else if (presence == Tp.ConnectionPresenceType.BUSY) {
|
|
||||||
msg = _("%s is busy.").format(title);
|
|
||||||
shouldNotify = false;
|
|
||||||
} else
|
|
||||||
return;
|
|
||||||
|
|
||||||
this._presence = presence;
|
|
||||||
|
|
||||||
if (message)
|
if (message)
|
||||||
msg += ' <i>(' + GLib.markup_escape_text(message, -1) + ')</i>';
|
msg += ' <i>(' + GLib.markup_escape_text(message, -1) + ')</i>';
|
||||||
|
|
||||||
this._notification.appendPresence(msg, shouldNotify);
|
|
||||||
if (shouldNotify)
|
|
||||||
this.notify();
|
|
||||||
},
|
},
|
||||||
|
|
||||||
_pendingRemoved: function(channel, message) {
|
_pendingRemoved: function(channel, message) {
|
||||||
@ -710,7 +729,7 @@ const ChatNotification = new Lang.Class({
|
|||||||
Extends: MessageTray.Notification,
|
Extends: MessageTray.Notification,
|
||||||
|
|
||||||
_init: function(source) {
|
_init: function(source) {
|
||||||
this.parent(source, source.title, null, { customContent: true });
|
this.parent(source, source.title, null, { customContent: true, secondaryIcon: source.createSecondaryIcon() });
|
||||||
this.setResident(true);
|
this.setResident(true);
|
||||||
|
|
||||||
this._responseEntry = new St.Entry({ style_class: 'chat-response',
|
this._responseEntry = new St.Entry({ style_class: 'chat-response',
|
||||||
@ -803,7 +822,7 @@ const ChatNotification = new Lang.Class({
|
|||||||
let groups = this._contentArea.get_children();
|
let groups = this._contentArea.get_children();
|
||||||
for (let i = 0; i < groups.length; i++) {
|
for (let i = 0; i < groups.length; i++) {
|
||||||
let group = groups[i];
|
let group = groups[i];
|
||||||
if (group.get_children().length == 0)
|
if (group.get_n_children() == 0)
|
||||||
group.destroy();
|
group.destroy();
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -853,6 +872,8 @@ const ChatNotification = new Lang.Class({
|
|||||||
|
|
||||||
this._lastGroupActor.add(body, props.childProps);
|
this._lastGroupActor.add(body, props.childProps);
|
||||||
|
|
||||||
|
this.updated();
|
||||||
|
|
||||||
let timestamp = props.timestamp;
|
let timestamp = props.timestamp;
|
||||||
this._history.unshift({ actor: body, time: timestamp,
|
this._history.unshift({ actor: body, time: timestamp,
|
||||||
realMessage: group != 'meta' });
|
realMessage: group != 'meta' });
|
||||||
@ -918,19 +939,6 @@ const ChatNotification = new Lang.Class({
|
|||||||
return false;
|
return false;
|
||||||
},
|
},
|
||||||
|
|
||||||
appendPresence: function(text, asTitle) {
|
|
||||||
if (asTitle)
|
|
||||||
this.update(text, null, { customContent: true, titleMarkup: true });
|
|
||||||
else
|
|
||||||
this.update(this.source.title, null, { customContent: true });
|
|
||||||
|
|
||||||
let label = this._append({ body: text,
|
|
||||||
group: 'meta',
|
|
||||||
styles: ['chat-meta-message'] });
|
|
||||||
|
|
||||||
this._filterMessages();
|
|
||||||
},
|
|
||||||
|
|
||||||
appendAliasChange: function(oldAlias, newAlias) {
|
appendAliasChange: function(oldAlias, newAlias) {
|
||||||
oldAlias = GLib.markup_escape_text(oldAlias, -1);
|
oldAlias = GLib.markup_escape_text(oldAlias, -1);
|
||||||
newAlias = GLib.markup_escape_text(newAlias, -1);
|
newAlias = GLib.markup_escape_text(newAlias, -1);
|
||||||
@ -1000,10 +1008,9 @@ const ApproverSource = new Lang.Class({
|
|||||||
Extends: MessageTray.Source,
|
Extends: MessageTray.Source,
|
||||||
|
|
||||||
_init: function(dispatchOp, text, gicon) {
|
_init: function(dispatchOp, text, gicon) {
|
||||||
this.parent(text);
|
|
||||||
|
|
||||||
this._gicon = gicon;
|
this._gicon = gicon;
|
||||||
this._setSummaryIcon(this.createNotificationIcon());
|
|
||||||
|
this.parent(text);
|
||||||
|
|
||||||
this._dispatchOp = dispatchOp;
|
this._dispatchOp = dispatchOp;
|
||||||
|
|
||||||
@ -1026,7 +1033,6 @@ const ApproverSource = new Lang.Class({
|
|||||||
|
|
||||||
createNotificationIcon: function() {
|
createNotificationIcon: function() {
|
||||||
return new St.Icon({ gicon: this._gicon,
|
return new St.Icon({ gicon: this._gicon,
|
||||||
icon_type: St.IconType.FULLCOLOR,
|
|
||||||
icon_size: this.ICON_SIZE });
|
icon_size: this.ICON_SIZE });
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@ -1149,40 +1155,6 @@ const FileTransferNotification = new Lang.Class({
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// A notification source that can embed multiple notifications
|
|
||||||
const MultiNotificationSource = new Lang.Class({
|
|
||||||
Name: 'MultiNotificationSource',
|
|
||||||
Extends: MessageTray.Source,
|
|
||||||
|
|
||||||
_init: function(title, icon) {
|
|
||||||
this.parent(title);
|
|
||||||
|
|
||||||
this._icon = icon;
|
|
||||||
this._setSummaryIcon(this.createNotificationIcon());
|
|
||||||
this._nbNotifications = 0;
|
|
||||||
},
|
|
||||||
|
|
||||||
notify: function(notification) {
|
|
||||||
this.parent(notification);
|
|
||||||
|
|
||||||
this._nbNotifications += 1;
|
|
||||||
|
|
||||||
// Display the source while there is at least one notification
|
|
||||||
notification.connect('destroy', Lang.bind(this, function () {
|
|
||||||
this._nbNotifications -= 1;
|
|
||||||
|
|
||||||
if (this._nbNotifications == 0)
|
|
||||||
this.destroy();
|
|
||||||
}));
|
|
||||||
},
|
|
||||||
|
|
||||||
createNotificationIcon: function() {
|
|
||||||
return new St.Icon({ gicon: Gio.icon_new_for_string(this._icon),
|
|
||||||
icon_type: St.IconType.FULLCOLOR,
|
|
||||||
icon_size: this.ICON_SIZE });
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// Subscription request
|
// Subscription request
|
||||||
const SubscriptionRequestNotification = new Lang.Class({
|
const SubscriptionRequestNotification = new Lang.Class({
|
||||||
Name: 'SubscriptionRequestNotification',
|
Name: 'SubscriptionRequestNotification',
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
|
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
|
||||||
|
|
||||||
const AccountsService = imports.gi.AccountsService;
|
const AccountsService = imports.gi.AccountsService;
|
||||||
|
const Gdm = imports.gi.Gdm;
|
||||||
const Gio = imports.gi.Gio;
|
const Gio = imports.gi.Gio;
|
||||||
const GLib = imports.gi.GLib;
|
const GLib = imports.gi.GLib;
|
||||||
const Lang = imports.lang;
|
const Lang = imports.lang;
|
||||||
@ -132,7 +133,7 @@ const IMStatusChooserItem = new Lang.Class({
|
|||||||
item = new IMStatusItem(_("Busy"), 'user-busy');
|
item = new IMStatusItem(_("Busy"), 'user-busy');
|
||||||
this._combo.addMenuItem(item, IMStatus.BUSY);
|
this._combo.addMenuItem(item, IMStatus.BUSY);
|
||||||
|
|
||||||
item = new IMStatusItem(_("Hidden"), 'user-invisible');
|
item = new IMStatusItem(_("Invisible"), 'user-invisible');
|
||||||
this._combo.addMenuItem(item, IMStatus.HIDDEN);
|
this._combo.addMenuItem(item, IMStatus.HIDDEN);
|
||||||
|
|
||||||
item = new IMStatusItem(_("Away"), 'user-away');
|
item = new IMStatusItem(_("Away"), 'user-away');
|
||||||
@ -473,13 +474,20 @@ const UserMenuButton = new Lang.Class({
|
|||||||
style_class: 'popup-menu-icon' });
|
style_class: 'popup-menu-icon' });
|
||||||
this._idleIcon = new St.Icon({ icon_name: 'user-idle',
|
this._idleIcon = new St.Icon({ icon_name: 'user-idle',
|
||||||
style_class: 'popup-menu-icon' });
|
style_class: 'popup-menu-icon' });
|
||||||
|
this._pendingIcon = new St.Icon({ icon_name: 'user-status-pending',
|
||||||
|
style_class: 'popup-menu-icon' });
|
||||||
|
|
||||||
this._accountMgr.connect('most-available-presence-changed',
|
this._accountMgr.connect('most-available-presence-changed',
|
||||||
Lang.bind(this, this._updatePresenceIcon));
|
Lang.bind(this, this._updatePresenceIcon));
|
||||||
|
this._accountMgr.connect('account-enabled',
|
||||||
|
Lang.bind(this, this._onAccountEnabled));
|
||||||
|
this._accountMgr.connect('account-removed',
|
||||||
|
Lang.bind(this, this._onAccountRemoved));
|
||||||
this._accountMgr.prepare_async(null, Lang.bind(this,
|
this._accountMgr.prepare_async(null, Lang.bind(this,
|
||||||
function(mgr) {
|
function(mgr) {
|
||||||
let [presence, s, msg] = mgr.get_most_available_presence();
|
let [presence, s, msg] = mgr.get_most_available_presence();
|
||||||
this._updatePresenceIcon(mgr, presence, s, msg);
|
this._updatePresenceIcon(mgr, presence, s, msg);
|
||||||
|
this._setupAccounts();
|
||||||
}));
|
}));
|
||||||
|
|
||||||
this._name = new St.Label();
|
this._name = new St.Label();
|
||||||
@ -497,13 +505,13 @@ const UserMenuButton = new Lang.Class({
|
|||||||
}));
|
}));
|
||||||
|
|
||||||
this._userManager.connect('notify::is-loaded',
|
this._userManager.connect('notify::is-loaded',
|
||||||
Lang.bind(this, this._updateSwitchUser));
|
Lang.bind(this, this._updateMultiUser));
|
||||||
this._userManager.connect('notify::has-multiple-users',
|
this._userManager.connect('notify::has-multiple-users',
|
||||||
Lang.bind(this, this._updateSwitchUser));
|
Lang.bind(this, this._updateMultiUser));
|
||||||
this._userManager.connect('user-added',
|
this._userManager.connect('user-added',
|
||||||
Lang.bind(this, this._updateSwitchUser));
|
Lang.bind(this, this._updateMultiUser));
|
||||||
this._userManager.connect('user-removed',
|
this._userManager.connect('user-removed',
|
||||||
Lang.bind(this, this._updateSwitchUser));
|
Lang.bind(this, this._updateMultiUser));
|
||||||
this._lockdownSettings.connect('changed::' + DISABLE_USER_SWITCH_KEY,
|
this._lockdownSettings.connect('changed::' + DISABLE_USER_SWITCH_KEY,
|
||||||
Lang.bind(this, this._updateSwitchUser));
|
Lang.bind(this, this._updateSwitchUser));
|
||||||
this._lockdownSettings.connect('changed::' + DISABLE_LOG_OUT_KEY,
|
this._lockdownSettings.connect('changed::' + DISABLE_LOG_OUT_KEY,
|
||||||
@ -515,6 +523,10 @@ const UserMenuButton = new Lang.Class({
|
|||||||
this._updateLogout();
|
this._updateLogout();
|
||||||
this._updateLockScreen();
|
this._updateLockScreen();
|
||||||
|
|
||||||
|
this._updatesFile = Gio.File.new_for_path('/var/lib/PackageKit/prepared-update');
|
||||||
|
this._updatesMonitor = this._updatesFile.monitor(Gio.FileMonitorFlags.NONE, null);
|
||||||
|
this._updatesMonitor.connect('changed', Lang.bind(this, this._updateInstallUpdates));
|
||||||
|
|
||||||
// Whether shutdown is available or not depends on both lockdown
|
// Whether shutdown is available or not depends on both lockdown
|
||||||
// settings (disable-log-out) and Polkit policy - the latter doesn't
|
// settings (disable-log-out) and Polkit policy - the latter doesn't
|
||||||
// notify, so we update the menu item each time the menu opens or
|
// notify, so we update the menu item each time the menu opens or
|
||||||
@ -542,37 +554,45 @@ const UserMenuButton = new Lang.Class({
|
|||||||
this._name.set_text("");
|
this._name.set_text("");
|
||||||
},
|
},
|
||||||
|
|
||||||
|
_updateMultiUser: function() {
|
||||||
|
this._updateSwitchUser();
|
||||||
|
this._updateLogout();
|
||||||
|
},
|
||||||
|
|
||||||
_updateSwitchUser: function() {
|
_updateSwitchUser: function() {
|
||||||
let allowSwitch = !this._lockdownSettings.get_boolean(DISABLE_USER_SWITCH_KEY);
|
let allowSwitch = !this._lockdownSettings.get_boolean(DISABLE_USER_SWITCH_KEY);
|
||||||
if (allowSwitch &&
|
let multiUser = this._userManager.can_switch() && this._userManager.has_multiple_users;
|
||||||
this._userManager.can_switch() &&
|
let multiSession = Gdm.get_session_ids().length > 1;
|
||||||
this._userManager.has_multiple_users)
|
|
||||||
this._loginScreenItem.actor.show();
|
this._loginScreenItem.label.set_text(multiUser ? _("Switch User")
|
||||||
else
|
: _("Switch Session"));
|
||||||
this._loginScreenItem.actor.hide();
|
this._loginScreenItem.actor.visible = allowSwitch && (multiUser || multiSession);
|
||||||
},
|
},
|
||||||
|
|
||||||
_updateLogout: function() {
|
_updateLogout: function() {
|
||||||
let allowLogout = !this._lockdownSettings.get_boolean(DISABLE_LOG_OUT_KEY);
|
let allowLogout = !this._lockdownSettings.get_boolean(DISABLE_LOG_OUT_KEY);
|
||||||
if (allowLogout)
|
let multiUser = this._userManager.has_multiple_users;
|
||||||
this._logoutItem.actor.show();
|
let multiSession = Gdm.get_session_ids().length > 1;
|
||||||
else
|
|
||||||
this._logoutItem.actor.hide();
|
this._logoutItem.actor.visible = allowLogout && (multiUser || multiSession);
|
||||||
},
|
},
|
||||||
|
|
||||||
_updateLockScreen: function() {
|
_updateLockScreen: function() {
|
||||||
let allowLockScreen = !this._lockdownSettings.get_boolean(DISABLE_LOCK_SCREEN_KEY);
|
let allowLockScreen = !this._lockdownSettings.get_boolean(DISABLE_LOCK_SCREEN_KEY);
|
||||||
if (allowLockScreen)
|
this._lockScreenItem.actor.visible = allowLockScreen;
|
||||||
this._lockScreenItem.actor.show();
|
},
|
||||||
else
|
|
||||||
this._lockScreenItem.actor.hide();
|
_updateInstallUpdates: function() {
|
||||||
|
let haveUpdates = this._updatesFile.query_exists(null);
|
||||||
|
this._installUpdatesItem.actor.visible = haveUpdates && this._haveShutdown;
|
||||||
},
|
},
|
||||||
|
|
||||||
_updateHaveShutdown: function() {
|
_updateHaveShutdown: function() {
|
||||||
this._session.CanShutdownRemote(Lang.bind(this,
|
this._session.CanShutdownRemote(Lang.bind(this,
|
||||||
function(result, error) {
|
function(result, error) {
|
||||||
if (!error) {
|
if (!error) {
|
||||||
this._haveShutdown = result;
|
this._haveShutdown = result[0];
|
||||||
|
this._updateInstallUpdates();
|
||||||
this._updateSuspendOrPowerOff();
|
this._updateSuspendOrPowerOff();
|
||||||
}
|
}
|
||||||
}));
|
}));
|
||||||
@ -584,19 +604,16 @@ const UserMenuButton = new Lang.Class({
|
|||||||
if (!this._suspendOrPowerOffItem)
|
if (!this._suspendOrPowerOffItem)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (!this._haveShutdown && !this._haveSuspend)
|
this._suspendOrPowerOffItem.actor.visible = this._haveShutdown || this._haveSuspend;
|
||||||
this._suspendOrPowerOffItem.actor.hide();
|
|
||||||
else
|
|
||||||
this._suspendOrPowerOffItem.actor.show();
|
|
||||||
|
|
||||||
// If we can't suspend show Power Off... instead
|
// If we can't power off show Suspend instead
|
||||||
// and disable the alt key
|
// and disable the alt key
|
||||||
if (!this._haveSuspend) {
|
if (!this._haveShutdown) {
|
||||||
this._suspendOrPowerOffItem.updateText(_("Power Off..."), null);
|
|
||||||
} else if (!this._haveShutdown) {
|
|
||||||
this._suspendOrPowerOffItem.updateText(_("Suspend"), null);
|
this._suspendOrPowerOffItem.updateText(_("Suspend"), null);
|
||||||
|
} else if (!this._haveSuspend) {
|
||||||
|
this._suspendOrPowerOffItem.updateText(_("Power Off"), null);
|
||||||
} else {
|
} else {
|
||||||
this._suspendOrPowerOffItem.updateText(_("Suspend"), _("Power Off..."));
|
this._suspendOrPowerOffItem.updateText(_("Power Off"), _("Suspend"));
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -620,10 +637,51 @@ const UserMenuButton = new Lang.Class({
|
|||||||
this._iconBox.child = this._offlineIcon;
|
this._iconBox.child = this._offlineIcon;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
_setupAccounts: function() {
|
||||||
|
let accounts = this._accountMgr.get_valid_accounts();
|
||||||
|
for (let i = 0; i < accounts.length; i++) {
|
||||||
|
accounts[i]._changingId = accounts[i].connect('notify::connection-status',
|
||||||
|
Lang.bind(this, this._updateChangingPresence));
|
||||||
|
}
|
||||||
|
this._updateChangingPresence();
|
||||||
|
},
|
||||||
|
|
||||||
|
_onAccountEnabled: function(accountMgr, account) {
|
||||||
|
if (!account._changingId)
|
||||||
|
account._changingId = account.connect('notify::connection-status',
|
||||||
|
Lang.bind(this, this._updateChangingPresence));
|
||||||
|
this._updateChangingPresence();
|
||||||
|
},
|
||||||
|
|
||||||
|
_onAccountRemoved: function(accountMgr, account) {
|
||||||
|
account.disconnect(account._changingId);
|
||||||
|
account._changingId = 0;
|
||||||
|
this._updateChangingPresence();
|
||||||
|
},
|
||||||
|
|
||||||
|
_updateChangingPresence: function() {
|
||||||
|
let accounts = this._accountMgr.get_valid_accounts();
|
||||||
|
let changing = false;
|
||||||
|
for (let i = 0; i < accounts.length; i++) {
|
||||||
|
if (accounts[i].connection_status == Tp.ConnectionStatus.CONNECTING) {
|
||||||
|
changing = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (changing) {
|
||||||
|
this._iconBox.child = this._pendingIcon;
|
||||||
|
} else {
|
||||||
|
let [presence, s, msg] = this._accountMgr.get_most_available_presence();
|
||||||
|
this._updatePresenceIcon(this._accountMgr, presence, s, msg);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
_createSubMenu: function() {
|
_createSubMenu: function() {
|
||||||
let item;
|
let item;
|
||||||
|
|
||||||
item = new IMStatusChooserItem();
|
item = new IMStatusChooserItem();
|
||||||
|
if (Main.sessionMode.allowSettings)
|
||||||
item.connect('activate', Lang.bind(this, this._onMyAccountActivate));
|
item.connect('activate', Lang.bind(this, this._onMyAccountActivate));
|
||||||
this.menu.addMenuItem(item);
|
this.menu.addMenuItem(item);
|
||||||
this._statusChooser = item;
|
this._statusChooser = item;
|
||||||
@ -636,41 +694,44 @@ const UserMenuButton = new Lang.Class({
|
|||||||
item = new PopupMenu.PopupSeparatorMenuItem();
|
item = new PopupMenu.PopupSeparatorMenuItem();
|
||||||
this.menu.addMenuItem(item);
|
this.menu.addMenuItem(item);
|
||||||
|
|
||||||
item = new PopupMenu.PopupMenuItem(_("Online Accounts"));
|
if (Main.sessionMode.allowSettings) {
|
||||||
item.connect('activate', Lang.bind(this, this._onOnlineAccountsActivate));
|
|
||||||
this.menu.addMenuItem(item);
|
|
||||||
|
|
||||||
item = new PopupMenu.PopupMenuItem(_("System Settings"));
|
item = new PopupMenu.PopupMenuItem(_("System Settings"));
|
||||||
item.connect('activate', Lang.bind(this, this._onPreferencesActivate));
|
item.connect('activate', Lang.bind(this, this._onPreferencesActivate));
|
||||||
this.menu.addMenuItem(item);
|
this.menu.addMenuItem(item);
|
||||||
|
}
|
||||||
|
|
||||||
item = new PopupMenu.PopupSeparatorMenuItem();
|
item = new PopupMenu.PopupSeparatorMenuItem();
|
||||||
this.menu.addMenuItem(item);
|
this.menu.addMenuItem(item);
|
||||||
|
|
||||||
item = new PopupMenu.PopupMenuItem(_("Lock Screen"));
|
|
||||||
item.connect('activate', Lang.bind(this, this._onLockScreenActivate));
|
|
||||||
this.menu.addMenuItem(item);
|
|
||||||
this._lockScreenItem = item;
|
|
||||||
|
|
||||||
item = new PopupMenu.PopupMenuItem(_("Switch User"));
|
item = new PopupMenu.PopupMenuItem(_("Switch User"));
|
||||||
item.connect('activate', Lang.bind(this, this._onLoginScreenActivate));
|
item.connect('activate', Lang.bind(this, this._onLoginScreenActivate));
|
||||||
this.menu.addMenuItem(item);
|
this.menu.addMenuItem(item);
|
||||||
this._loginScreenItem = item;
|
this._loginScreenItem = item;
|
||||||
|
|
||||||
item = new PopupMenu.PopupMenuItem(_("Log Out..."));
|
item = new PopupMenu.PopupMenuItem(_("Log Out"));
|
||||||
item.connect('activate', Lang.bind(this, this._onQuitSessionActivate));
|
item.connect('activate', Lang.bind(this, this._onQuitSessionActivate));
|
||||||
this.menu.addMenuItem(item);
|
this.menu.addMenuItem(item);
|
||||||
this._logoutItem = item;
|
this._logoutItem = item;
|
||||||
|
|
||||||
|
item = new PopupMenu.PopupMenuItem(_("Lock"));
|
||||||
|
item.connect('activate', Lang.bind(this, this._onLockScreenActivate));
|
||||||
|
this.menu.addMenuItem(item);
|
||||||
|
this._lockScreenItem = item;
|
||||||
|
|
||||||
item = new PopupMenu.PopupSeparatorMenuItem();
|
item = new PopupMenu.PopupSeparatorMenuItem();
|
||||||
this.menu.addMenuItem(item);
|
this.menu.addMenuItem(item);
|
||||||
|
|
||||||
item = new PopupMenu.PopupAlternatingMenuItem(_("Suspend"),
|
item = new PopupMenu.PopupAlternatingMenuItem(_("Power Off"),
|
||||||
_("Power Off..."));
|
_("Suspend"));
|
||||||
this.menu.addMenuItem(item);
|
this.menu.addMenuItem(item);
|
||||||
this._suspendOrPowerOffItem = item;
|
|
||||||
item.connect('activate', Lang.bind(this, this._onSuspendOrPowerOffActivate));
|
item.connect('activate', Lang.bind(this, this._onSuspendOrPowerOffActivate));
|
||||||
|
this._suspendOrPowerOffItem = item;
|
||||||
this._updateSuspendOrPowerOff();
|
this._updateSuspendOrPowerOff();
|
||||||
|
|
||||||
|
item = new PopupMenu.PopupMenuItem(_("Install Updates & Restart"));
|
||||||
|
item.connect('activate', Lang.bind(this, this._onInstallUpdatesActivate));
|
||||||
|
this.menu.addMenuItem(item);
|
||||||
|
this._installUpdatesItem = item;
|
||||||
},
|
},
|
||||||
|
|
||||||
_updatePresenceStatus: function(item, event) {
|
_updatePresenceStatus: function(item, event) {
|
||||||
@ -698,12 +759,6 @@ const UserMenuButton = new Lang.Class({
|
|||||||
app.activate();
|
app.activate();
|
||||||
},
|
},
|
||||||
|
|
||||||
_onOnlineAccountsActivate: function() {
|
|
||||||
Main.overview.hide();
|
|
||||||
let app = Shell.AppSystem.get_default().lookup_setting('gnome-online-accounts-panel.desktop');
|
|
||||||
app.activate(-1);
|
|
||||||
},
|
|
||||||
|
|
||||||
_onPreferencesActivate: function() {
|
_onPreferencesActivate: function() {
|
||||||
Main.overview.hide();
|
Main.overview.hide();
|
||||||
let app = Shell.AppSystem.get_default().lookup_app('gnome-control-center.desktop');
|
let app = Shell.AppSystem.get_default().lookup_app('gnome-control-center.desktop');
|
||||||
@ -729,17 +784,24 @@ const UserMenuButton = new Lang.Class({
|
|||||||
this._session.LogoutRemote(0);
|
this._session.LogoutRemote(0);
|
||||||
},
|
},
|
||||||
|
|
||||||
|
_onInstallUpdatesActivate: function() {
|
||||||
|
Main.overview.hide();
|
||||||
|
Util.spawn(['pkexec', '/usr/libexec/pk-trigger-offline-update']);
|
||||||
|
|
||||||
|
this._session.RebootRemote();
|
||||||
|
},
|
||||||
|
|
||||||
_onSuspendOrPowerOffActivate: function() {
|
_onSuspendOrPowerOffActivate: function() {
|
||||||
Main.overview.hide();
|
Main.overview.hide();
|
||||||
|
|
||||||
if (this._haveSuspend &&
|
if (this._haveShutdown &&
|
||||||
this._suspendOrPowerOffItem.state == PopupMenu.PopupAlternatingMenuItemState.DEFAULT) {
|
this._suspendOrPowerOffItem.state == PopupMenu.PopupAlternatingMenuItemState.DEFAULT) {
|
||||||
|
this._session.ShutdownRemote();
|
||||||
|
} else {
|
||||||
// Ensure we only suspend after locking the screen
|
// Ensure we only suspend after locking the screen
|
||||||
this._screenSaverProxy.LockRemote(Lang.bind(this, function() {
|
this._screenSaverProxy.LockRemote(Lang.bind(this, function() {
|
||||||
this._upClient.suspend_sync(null);
|
this._upClient.suspend_sync(null);
|
||||||
}));
|
}));
|
||||||
} else {
|
|
||||||
this._session.ShutdownRemote();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -168,8 +168,8 @@ const WandaSearchProvider = new Lang.Class({
|
|||||||
this.parent(_("Your favorite Easter Egg"));
|
this.parent(_("Your favorite Easter Egg"));
|
||||||
},
|
},
|
||||||
|
|
||||||
getResultMetas: function(fish) {
|
getResultMetas: function(fish, callback) {
|
||||||
return [{ 'id': fish[0], // there may be many fish in the sea, but
|
callback([{ 'id': fish[0], // there may be many fish in the sea, but
|
||||||
// only one which speaks the truth!
|
// only one which speaks the truth!
|
||||||
'name': capitalize(fish[0]),
|
'name': capitalize(fish[0]),
|
||||||
'createIcon': function(iconSize) {
|
'createIcon': function(iconSize) {
|
||||||
@ -184,18 +184,19 @@ const WandaSearchProvider = new Lang.Class({
|
|||||||
St.IconType.FULLCOLOR,
|
St.IconType.FULLCOLOR,
|
||||||
iconSize);
|
iconSize);
|
||||||
}
|
}
|
||||||
}];
|
}]);
|
||||||
},
|
},
|
||||||
|
|
||||||
getInitialResultSet: function(terms) {
|
getInitialResultSet: function(terms) {
|
||||||
if (terms.join(' ') == MAGIC_FISH_KEY) {
|
if (terms.join(' ') == MAGIC_FISH_KEY) {
|
||||||
return [ FISH_NAME ];
|
this.searchSystem.pushResults(this, [ FISH_NAME ]);
|
||||||
|
} else {
|
||||||
|
this.searchSystem.pushResults(this, []);
|
||||||
}
|
}
|
||||||
return [];
|
|
||||||
},
|
},
|
||||||
|
|
||||||
getSubsearchResultSet: function(previousResults, terms) {
|
getSubsearchResultSet: function(previousResults, terms) {
|
||||||
return this.getInitialResultSet(terms);
|
this.getInitialResultSet(terms);
|
||||||
},
|
},
|
||||||
|
|
||||||
activateResult: function(fish, params) {
|
activateResult: function(fish, params) {
|
||||||
|
@ -53,10 +53,10 @@ const Source = new Lang.Class({
|
|||||||
Extends: MessageTray.Source,
|
Extends: MessageTray.Source,
|
||||||
|
|
||||||
_init: function(app, window) {
|
_init: function(app, window) {
|
||||||
this.parent(app.get_name());
|
|
||||||
this._window = window;
|
this._window = window;
|
||||||
this._app = app;
|
this._app = app;
|
||||||
this._setSummaryIcon(this.createNotificationIcon());
|
|
||||||
|
this.parent(app.get_name());
|
||||||
|
|
||||||
this.signalIDs = [];
|
this.signalIDs = [];
|
||||||
this.signalIDs.push(this._window.connect('notify::demands-attention', Lang.bind(this, function() { this.destroy(); })));
|
this.signalIDs.push(this._window.connect('notify::demands-attention', Lang.bind(this, function() { this.destroy(); })));
|
||||||
|
@ -13,66 +13,40 @@ const WorkspaceSwitcherPopup = imports.ui.workspaceSwitcherPopup;
|
|||||||
const Main = imports.ui.main;
|
const Main = imports.ui.main;
|
||||||
const Tweener = imports.ui.tweener;
|
const Tweener = imports.ui.tweener;
|
||||||
|
|
||||||
|
const SHELL_KEYBINDINGS_SCHEMA = 'org.gnome.shell.keybindings';
|
||||||
const WINDOW_ANIMATION_TIME = 0.25;
|
const WINDOW_ANIMATION_TIME = 0.25;
|
||||||
|
const DIM_DESATURATION = 0.6;
|
||||||
|
const DIM_BRIGHTNESS = -0.1;
|
||||||
const DIM_TIME = 0.500;
|
const DIM_TIME = 0.500;
|
||||||
const UNDIM_TIME = 0.250;
|
const UNDIM_TIME = 0.250;
|
||||||
|
|
||||||
var dimShader = undefined;
|
|
||||||
|
|
||||||
function getDimShaderSource() {
|
|
||||||
if (!dimShader)
|
|
||||||
dimShader = Shell.get_file_contents_utf8_sync(global.datadir + '/shaders/dim-window.glsl');
|
|
||||||
return dimShader;
|
|
||||||
}
|
|
||||||
|
|
||||||
function getTopInvisibleBorder(metaWindow) {
|
|
||||||
let outerRect = metaWindow.get_outer_rect();
|
|
||||||
let inputRect = metaWindow.get_input_rect();
|
|
||||||
return outerRect.y - inputRect.y;
|
|
||||||
}
|
|
||||||
|
|
||||||
const WindowDimmer = new Lang.Class({
|
const WindowDimmer = new Lang.Class({
|
||||||
Name: 'WindowDimmer',
|
Name: 'WindowDimmer',
|
||||||
|
|
||||||
_init: function(actor) {
|
_init: function(actor) {
|
||||||
if (Clutter.feature_available(Clutter.FeatureFlags.SHADERS_GLSL)) {
|
this._desaturateEffect = new Clutter.DesaturateEffect();
|
||||||
this._effect = new Clutter.ShaderEffect({ shader_type: Clutter.ShaderType.FRAGMENT_SHADER });
|
this._brightnessEffect = new Clutter.BrightnessContrastEffect();
|
||||||
this._effect.set_shader_source(getDimShaderSource());
|
actor.add_effect(this._desaturateEffect);
|
||||||
} else {
|
actor.add_effect(this._brightnessEffect);
|
||||||
this._effect = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
this.actor = actor;
|
this.actor = actor;
|
||||||
|
this._dimFactor = 0.0;
|
||||||
},
|
},
|
||||||
|
|
||||||
set dimFraction(fraction) {
|
setEnabled: function(enabled) {
|
||||||
this._dimFraction = fraction;
|
this._desaturateEffect.enabled = enabled;
|
||||||
|
this._brightnessEffect.enabled = enabled;
|
||||||
|
},
|
||||||
|
|
||||||
if (this._effect == null)
|
set dimFactor(factor) {
|
||||||
return;
|
this._dimFactor = factor;
|
||||||
|
this._desaturateEffect.set_factor(factor * DIM_DESATURATION);
|
||||||
|
this._brightnessEffect.set_brightness(factor * DIM_BRIGHTNESS);
|
||||||
|
},
|
||||||
|
|
||||||
if (!Meta.prefs_get_attach_modal_dialogs()) {
|
get dimFactor() {
|
||||||
this._effect.enabled = false;
|
return this._dimFactor;
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fraction > 0.01) {
|
|
||||||
Shell.shader_effect_set_double_uniform(this._effect, 'height', this.actor.get_height());
|
|
||||||
Shell.shader_effect_set_double_uniform(this._effect, 'fraction', fraction);
|
|
||||||
|
|
||||||
if (!this._effect.actor)
|
|
||||||
this.actor.add_effect(this._effect);
|
|
||||||
} else {
|
|
||||||
if (this._effect.actor)
|
|
||||||
this.actor.remove_effect(this._effect);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
get dimFraction() {
|
|
||||||
return this._dimFraction;
|
|
||||||
},
|
|
||||||
|
|
||||||
_dimFraction: 0.0
|
|
||||||
});
|
});
|
||||||
|
|
||||||
function getWindowDimmer(actor) {
|
function getWindowDimmer(actor) {
|
||||||
@ -93,6 +67,7 @@ const WindowManager = new Lang.Class({
|
|||||||
this._unmaximizing = [];
|
this._unmaximizing = [];
|
||||||
this._mapping = [];
|
this._mapping = [];
|
||||||
this._destroying = [];
|
this._destroying = [];
|
||||||
|
this._movingWindow = null;
|
||||||
|
|
||||||
this._dimmedWindows = [];
|
this._dimmedWindows = [];
|
||||||
|
|
||||||
@ -124,6 +99,14 @@ const WindowManager = new Lang.Class({
|
|||||||
Lang.bind(this, this._showWorkspaceSwitcher));
|
Lang.bind(this, this._showWorkspaceSwitcher));
|
||||||
Meta.keybindings_set_custom_handler('switch-to-workspace-down',
|
Meta.keybindings_set_custom_handler('switch-to-workspace-down',
|
||||||
Lang.bind(this, this._showWorkspaceSwitcher));
|
Lang.bind(this, this._showWorkspaceSwitcher));
|
||||||
|
Meta.keybindings_set_custom_handler('move-to-workspace-left',
|
||||||
|
Lang.bind(this, this._showWorkspaceSwitcher));
|
||||||
|
Meta.keybindings_set_custom_handler('move-to-workspace-right',
|
||||||
|
Lang.bind(this, this._showWorkspaceSwitcher));
|
||||||
|
Meta.keybindings_set_custom_handler('move-to-workspace-up',
|
||||||
|
Lang.bind(this, this._showWorkspaceSwitcher));
|
||||||
|
Meta.keybindings_set_custom_handler('move-to-workspace-down',
|
||||||
|
Lang.bind(this, this._showWorkspaceSwitcher));
|
||||||
Meta.keybindings_set_custom_handler('switch-windows',
|
Meta.keybindings_set_custom_handler('switch-windows',
|
||||||
Lang.bind(this, this._startAppSwitcher));
|
Lang.bind(this, this._startAppSwitcher));
|
||||||
Meta.keybindings_set_custom_handler('switch-group',
|
Meta.keybindings_set_custom_handler('switch-group',
|
||||||
@ -134,14 +117,18 @@ const WindowManager = new Lang.Class({
|
|||||||
Lang.bind(this, this._startAppSwitcher));
|
Lang.bind(this, this._startAppSwitcher));
|
||||||
Meta.keybindings_set_custom_handler('switch-panels',
|
Meta.keybindings_set_custom_handler('switch-panels',
|
||||||
Lang.bind(this, this._startA11ySwitcher));
|
Lang.bind(this, this._startA11ySwitcher));
|
||||||
|
global.display.add_keybinding('open-application-menu',
|
||||||
|
new Gio.Settings({ schema: SHELL_KEYBINDINGS_SCHEMA }),
|
||||||
|
Meta.KeyBindingFlags.NONE,
|
||||||
|
Lang.bind(this, this._openAppMenu));
|
||||||
|
|
||||||
Main.overview.connect('showing', Lang.bind(this, function() {
|
Main.overview.connect('showing', Lang.bind(this, function() {
|
||||||
for (let i = 0; i < this._dimmedWindows.length; i++)
|
for (let i = 0; i < this._dimmedWindows.length; i++)
|
||||||
this._undimWindow(this._dimmedWindows[i], true);
|
this._undimWindow(this._dimmedWindows[i]);
|
||||||
}));
|
}));
|
||||||
Main.overview.connect('hiding', Lang.bind(this, function() {
|
Main.overview.connect('hiding', Lang.bind(this, function() {
|
||||||
for (let i = 0; i < this._dimmedWindows.length; i++)
|
for (let i = 0; i < this._dimmedWindows.length; i++)
|
||||||
this._dimWindow(this._dimmedWindows[i], true);
|
this._dimWindow(this._dimmedWindows[i]);
|
||||||
}));
|
}));
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -153,12 +140,14 @@ const WindowManager = new Lang.Class({
|
|||||||
this._animationBlockCount = Math.max(0, this._animationBlockCount - 1);
|
this._animationBlockCount = Math.max(0, this._animationBlockCount - 1);
|
||||||
},
|
},
|
||||||
|
|
||||||
_shouldAnimate : function(actor) {
|
_shouldAnimate: function() {
|
||||||
if (Main.overview.visible || this._animationBlockCount > 0)
|
return !(Main.overview.visible || this._animationBlockCount > 0);
|
||||||
|
},
|
||||||
|
|
||||||
|
_shouldAnimateActor: function(actor) {
|
||||||
|
if (!this._shouldAnimate())
|
||||||
return false;
|
return false;
|
||||||
if (actor && (actor.meta_window.get_window_type() != Meta.WindowType.NORMAL))
|
return actor.meta_window.get_window_type() == Meta.WindowType.NORMAL;
|
||||||
return false;
|
|
||||||
return true;
|
|
||||||
},
|
},
|
||||||
|
|
||||||
_removeEffect : function(list, actor) {
|
_removeEffect : function(list, actor) {
|
||||||
@ -171,7 +160,7 @@ const WindowManager = new Lang.Class({
|
|||||||
},
|
},
|
||||||
|
|
||||||
_minimizeWindow : function(shellwm, actor) {
|
_minimizeWindow : function(shellwm, actor) {
|
||||||
if (!this._shouldAnimate(actor)) {
|
if (!this._shouldAnimateActor(actor)) {
|
||||||
shellwm.completed_minimize(actor);
|
shellwm.completed_minimize(actor);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -255,43 +244,47 @@ const WindowManager = new Lang.Class({
|
|||||||
window._dimmed = true;
|
window._dimmed = true;
|
||||||
this._dimmedWindows.push(window);
|
this._dimmedWindows.push(window);
|
||||||
if (!Main.overview.visible)
|
if (!Main.overview.visible)
|
||||||
this._dimWindow(window, true);
|
this._dimWindow(window);
|
||||||
} else if (!shouldDim && window._dimmed) {
|
} else if (!shouldDim && window._dimmed) {
|
||||||
window._dimmed = false;
|
window._dimmed = false;
|
||||||
this._dimmedWindows = this._dimmedWindows.filter(function(win) {
|
this._dimmedWindows = this._dimmedWindows.filter(function(win) {
|
||||||
return win != window;
|
return win != window;
|
||||||
});
|
});
|
||||||
if (!Main.overview.visible)
|
if (!Main.overview.visible)
|
||||||
this._undimWindow(window, true);
|
this._undimWindow(window);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
_dimWindow: function(window, animate) {
|
_dimWindow: function(window) {
|
||||||
let actor = window.get_compositor_private();
|
let actor = window.get_compositor_private();
|
||||||
if (!actor)
|
if (!actor)
|
||||||
return;
|
return;
|
||||||
if (animate)
|
let dimmer = getWindowDimmer(actor);
|
||||||
Tweener.addTween(getWindowDimmer(actor),
|
let enabled = Meta.prefs_get_attach_modal_dialogs();
|
||||||
{ dimFraction: 1.0,
|
dimmer.setEnabled(enabled);
|
||||||
|
if (!enabled)
|
||||||
|
return;
|
||||||
|
Tweener.addTween(dimmer,
|
||||||
|
{ dimFactor: 1.0,
|
||||||
time: DIM_TIME,
|
time: DIM_TIME,
|
||||||
transition: 'linear'
|
transition: 'linear'
|
||||||
});
|
});
|
||||||
else
|
|
||||||
getWindowDimmer(actor).dimFraction = 1.0;
|
|
||||||
},
|
},
|
||||||
|
|
||||||
_undimWindow: function(window, animate) {
|
_undimWindow: function(window) {
|
||||||
let actor = window.get_compositor_private();
|
let actor = window.get_compositor_private();
|
||||||
if (!actor)
|
if (!actor)
|
||||||
return;
|
return;
|
||||||
if (animate)
|
let dimmer = getWindowDimmer(actor);
|
||||||
Tweener.addTween(getWindowDimmer(actor),
|
let enabled = Meta.prefs_get_attach_modal_dialogs();
|
||||||
{ dimFraction: 0.0,
|
dimmer.setEnabled(enabled);
|
||||||
|
if (!enabled)
|
||||||
|
return;
|
||||||
|
Tweener.addTween(dimmer,
|
||||||
|
{ dimFactor: 0.0,
|
||||||
time: UNDIM_TIME,
|
time: UNDIM_TIME,
|
||||||
transition: 'linear'
|
transition: 'linear'
|
||||||
});
|
});
|
||||||
else
|
|
||||||
getWindowDimmer(actor).dimFraction = 0.0;
|
|
||||||
},
|
},
|
||||||
|
|
||||||
_mapWindow : function(shellwm, actor) {
|
_mapWindow : function(shellwm, actor) {
|
||||||
@ -311,28 +304,12 @@ const WindowManager = new Lang.Class({
|
|||||||
}));
|
}));
|
||||||
if (actor.meta_window.is_attached_dialog()) {
|
if (actor.meta_window.is_attached_dialog()) {
|
||||||
this._checkDimming(actor.get_meta_window().get_transient_for());
|
this._checkDimming(actor.get_meta_window().get_transient_for());
|
||||||
if (this._shouldAnimate()) {
|
|
||||||
actor.set_scale(1.0, 0.0);
|
|
||||||
actor.show();
|
|
||||||
this._mapping.push(actor);
|
|
||||||
|
|
||||||
Tweener.addTween(actor,
|
if (!this._shouldAnimate()) {
|
||||||
{ scale_y: 1,
|
|
||||||
time: WINDOW_ANIMATION_TIME,
|
|
||||||
transition: "easeOutQuad",
|
|
||||||
onComplete: this._mapWindowDone,
|
|
||||||
onCompleteScope: this,
|
|
||||||
onCompleteParams: [shellwm, actor],
|
|
||||||
onOverwrite: this._mapWindowOverwrite,
|
|
||||||
onOverwriteScope: this,
|
|
||||||
onOverwriteParams: [shellwm, actor]
|
|
||||||
});
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
shellwm.completed_map(actor);
|
shellwm.completed_map(actor);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (!this._shouldAnimate(actor)) {
|
} else if (!this._shouldAnimateActor(actor)) {
|
||||||
shellwm.completed_map(actor);
|
shellwm.completed_map(actor);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -388,7 +365,7 @@ const WindowManager = new Lang.Class({
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
actor.set_scale(1.0, 1.0);
|
actor.opacity = 255;
|
||||||
actor.show();
|
actor.show();
|
||||||
this._destroying.push(actor);
|
this._destroying.push(actor);
|
||||||
|
|
||||||
@ -398,7 +375,7 @@ const WindowManager = new Lang.Class({
|
|||||||
}));
|
}));
|
||||||
|
|
||||||
Tweener.addTween(actor,
|
Tweener.addTween(actor,
|
||||||
{ scale_y: 0,
|
{ opacity: 0,
|
||||||
time: WINDOW_ANIMATION_TIME,
|
time: WINDOW_ANIMATION_TIME,
|
||||||
transition: "easeOutQuad",
|
transition: "easeOutQuad",
|
||||||
onComplete: this._destroyWindowDone,
|
onComplete: this._destroyWindowDone,
|
||||||
@ -460,11 +437,13 @@ const WindowManager = new Lang.Class({
|
|||||||
this._switchData = switchData;
|
this._switchData = switchData;
|
||||||
switchData.inGroup = new Clutter.Group();
|
switchData.inGroup = new Clutter.Group();
|
||||||
switchData.outGroup = new Clutter.Group();
|
switchData.outGroup = new Clutter.Group();
|
||||||
|
switchData.movingWindowBin = new Clutter.Group();
|
||||||
switchData.windows = [];
|
switchData.windows = [];
|
||||||
|
|
||||||
let wgroup = global.window_group;
|
let wgroup = global.window_group;
|
||||||
wgroup.add_actor(switchData.inGroup);
|
wgroup.add_actor(switchData.inGroup);
|
||||||
wgroup.add_actor(switchData.outGroup);
|
wgroup.add_actor(switchData.outGroup);
|
||||||
|
wgroup.add_actor(switchData.movingWindowBin);
|
||||||
|
|
||||||
for (let i = 0; i < windows.length; i++) {
|
for (let i = 0; i < windows.length; i++) {
|
||||||
let window = windows[i];
|
let window = windows[i];
|
||||||
@ -472,7 +451,12 @@ const WindowManager = new Lang.Class({
|
|||||||
if (!window.meta_window.showing_on_its_workspace())
|
if (!window.meta_window.showing_on_its_workspace())
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (window.get_workspace() == from) {
|
if (this._movingWindow && window.meta_window == this._movingWindow) {
|
||||||
|
switchData.movingWindow = { window: window,
|
||||||
|
parent: window.get_parent() };
|
||||||
|
switchData.windows.push(switchData.movingWindow);
|
||||||
|
window.reparent(switchData.movingWindowBin);
|
||||||
|
} else if (window.get_workspace() == from) {
|
||||||
switchData.windows.push({ window: window,
|
switchData.windows.push({ window: window,
|
||||||
parent: window.get_parent() });
|
parent: window.get_parent() });
|
||||||
window.reparent(switchData.outGroup);
|
window.reparent(switchData.outGroup);
|
||||||
@ -487,6 +471,8 @@ const WindowManager = new Lang.Class({
|
|||||||
switchData.inGroup.set_position(-xDest, -yDest);
|
switchData.inGroup.set_position(-xDest, -yDest);
|
||||||
switchData.inGroup.raise_top();
|
switchData.inGroup.raise_top();
|
||||||
|
|
||||||
|
switchData.movingWindowBin.raise_top();
|
||||||
|
|
||||||
Tweener.addTween(switchData.outGroup,
|
Tweener.addTween(switchData.outGroup,
|
||||||
{ x: xDest,
|
{ x: xDest,
|
||||||
y: yDest,
|
y: yDest,
|
||||||
@ -524,6 +510,10 @@ const WindowManager = new Lang.Class({
|
|||||||
Tweener.removeTweens(switchData.outGroup);
|
Tweener.removeTweens(switchData.outGroup);
|
||||||
switchData.inGroup.destroy();
|
switchData.inGroup.destroy();
|
||||||
switchData.outGroup.destroy();
|
switchData.outGroup.destroy();
|
||||||
|
switchData.movingWindowBin.destroy();
|
||||||
|
|
||||||
|
if (this._movingWindow)
|
||||||
|
this._movingWindow = null;
|
||||||
|
|
||||||
shellwm.completed_switch_workspace();
|
shellwm.completed_switch_workspace();
|
||||||
},
|
},
|
||||||
@ -531,7 +521,7 @@ const WindowManager = new Lang.Class({
|
|||||||
_startAppSwitcher : function(display, screen, window, binding) {
|
_startAppSwitcher : function(display, screen, window, binding) {
|
||||||
/* prevent a corner case where both popups show up at once */
|
/* prevent a corner case where both popups show up at once */
|
||||||
if (this._workspaceSwitcherPopup != null)
|
if (this._workspaceSwitcherPopup != null)
|
||||||
this._workspaceSwitcherPopup.actor.hide();
|
this._workspaceSwitcherPopup.destroy();
|
||||||
|
|
||||||
let tabPopup = new AltTab.AltTabPopup();
|
let tabPopup = new AltTab.AltTabPopup();
|
||||||
|
|
||||||
@ -547,80 +537,64 @@ const WindowManager = new Lang.Class({
|
|||||||
Main.ctrlAltTabManager.popup(backwards, binding.get_mask());
|
Main.ctrlAltTabManager.popup(backwards, binding.get_mask());
|
||||||
},
|
},
|
||||||
|
|
||||||
|
_openAppMenu : function(display, screen, window, event, binding) {
|
||||||
|
Main.panel.openAppMenu();
|
||||||
|
},
|
||||||
|
|
||||||
_showWorkspaceSwitcher : function(display, screen, window, binding) {
|
_showWorkspaceSwitcher : function(display, screen, window, binding) {
|
||||||
if (screen.n_workspaces == 1)
|
if (screen.n_workspaces == 1)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (this._workspaceSwitcherPopup == null)
|
let [action,,,direction] = binding.get_name().split('-');
|
||||||
|
let direction = Meta.MotionDirection[direction.toUpperCase()];
|
||||||
|
let newWs;
|
||||||
|
|
||||||
|
|
||||||
|
if (direction != Meta.MotionDirection.UP &&
|
||||||
|
direction != Meta.MotionDirection.DOWN)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (action == 'switch')
|
||||||
|
newWs = this.actionMoveWorkspace(direction);
|
||||||
|
else
|
||||||
|
newWs = this.actionMoveWindow(window, direction);
|
||||||
|
|
||||||
|
if (!Main.overview.visible) {
|
||||||
|
if (this._workspaceSwitcherPopup == null) {
|
||||||
this._workspaceSwitcherPopup = new WorkspaceSwitcherPopup.WorkspaceSwitcherPopup();
|
this._workspaceSwitcherPopup = new WorkspaceSwitcherPopup.WorkspaceSwitcherPopup();
|
||||||
|
this._workspaceSwitcherPopup.connect('destroy', Lang.bind(this, function() {
|
||||||
if (binding.get_name() == 'switch-to-workspace-up')
|
this._workspaceSwitcherPopup = null;
|
||||||
this.actionMoveWorkspaceUp();
|
}));
|
||||||
else if (binding.get_name() == 'switch-to-workspace-down')
|
|
||||||
this.actionMoveWorkspaceDown();
|
|
||||||
// left/right would effectively act as synonyms for up/down if we enabled them;
|
|
||||||
// but that could be considered confusing.
|
|
||||||
// else if (binding.get_name() == 'switch-to-workspace-left')
|
|
||||||
// this.actionMoveWorkspaceLeft();
|
|
||||||
// else if (binding.get_name() == 'switch-to-workspace-right')
|
|
||||||
// this.actionMoveWorkspaceRight();
|
|
||||||
},
|
|
||||||
|
|
||||||
actionMoveWorkspaceLeft: function() {
|
|
||||||
let rtl = (Clutter.get_default_text_direction() == Clutter.TextDirection.RTL);
|
|
||||||
let activeWorkspaceIndex = global.screen.get_active_workspace_index();
|
|
||||||
let indexToActivate = activeWorkspaceIndex;
|
|
||||||
if (rtl && activeWorkspaceIndex < global.screen.n_workspaces - 1)
|
|
||||||
indexToActivate++;
|
|
||||||
else if (!rtl && activeWorkspaceIndex > 0)
|
|
||||||
indexToActivate--;
|
|
||||||
|
|
||||||
if (indexToActivate != activeWorkspaceIndex)
|
|
||||||
global.screen.get_workspace_by_index(indexToActivate).activate(global.get_current_time());
|
|
||||||
|
|
||||||
if (!Main.overview.visible)
|
|
||||||
this._workspaceSwitcherPopup.display(WorkspaceSwitcherPopup.UP, indexToActivate);
|
|
||||||
},
|
|
||||||
|
|
||||||
actionMoveWorkspaceRight: function() {
|
|
||||||
let rtl = (Clutter.get_default_text_direction() == Clutter.TextDirection.RTL);
|
|
||||||
let activeWorkspaceIndex = global.screen.get_active_workspace_index();
|
|
||||||
let indexToActivate = activeWorkspaceIndex;
|
|
||||||
if (rtl && activeWorkspaceIndex > 0)
|
|
||||||
indexToActivate--;
|
|
||||||
else if (!rtl && activeWorkspaceIndex < global.screen.n_workspaces - 1)
|
|
||||||
indexToActivate++;
|
|
||||||
|
|
||||||
if (indexToActivate != activeWorkspaceIndex)
|
|
||||||
global.screen.get_workspace_by_index(indexToActivate).activate(global.get_current_time());
|
|
||||||
|
|
||||||
if (!Main.overview.visible)
|
|
||||||
this._workspaceSwitcherPopup.display(WorkspaceSwitcherPopup.DOWN, indexToActivate);
|
|
||||||
},
|
|
||||||
|
|
||||||
actionMoveWorkspaceUp: function() {
|
|
||||||
let activeWorkspaceIndex = global.screen.get_active_workspace_index();
|
|
||||||
let indexToActivate = activeWorkspaceIndex;
|
|
||||||
if (activeWorkspaceIndex > 0)
|
|
||||||
indexToActivate--;
|
|
||||||
|
|
||||||
if (indexToActivate != activeWorkspaceIndex)
|
|
||||||
global.screen.get_workspace_by_index(indexToActivate).activate(global.get_current_time());
|
|
||||||
|
|
||||||
if (!Main.overview.visible)
|
|
||||||
this._workspaceSwitcherPopup.display(WorkspaceSwitcherPopup.UP, indexToActivate);
|
|
||||||
},
|
|
||||||
|
|
||||||
actionMoveWorkspaceDown: function() {
|
|
||||||
let activeWorkspaceIndex = global.screen.get_active_workspace_index();
|
|
||||||
let indexToActivate = activeWorkspaceIndex;
|
|
||||||
if (activeWorkspaceIndex < global.screen.n_workspaces - 1)
|
|
||||||
indexToActivate++;
|
|
||||||
|
|
||||||
if (indexToActivate != activeWorkspaceIndex)
|
|
||||||
global.screen.get_workspace_by_index(indexToActivate).activate(global.get_current_time());
|
|
||||||
|
|
||||||
if (!Main.overview.visible)
|
|
||||||
this._workspaceSwitcherPopup.display(WorkspaceSwitcherPopup.DOWN, indexToActivate);
|
|
||||||
}
|
}
|
||||||
|
this._workspaceSwitcherPopup.display(direction, newWs.index());
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
actionMoveWorkspace: function(direction) {
|
||||||
|
let activeWorkspace = global.screen.get_active_workspace();
|
||||||
|
let toActivate = activeWorkspace.get_neighbor(direction);
|
||||||
|
|
||||||
|
if (activeWorkspace != toActivate)
|
||||||
|
toActivate.activate(global.get_current_time());
|
||||||
|
|
||||||
|
return toActivate;
|
||||||
|
},
|
||||||
|
|
||||||
|
actionMoveWindow: function(window, direction) {
|
||||||
|
let activeWorkspace = global.screen.get_active_workspace();
|
||||||
|
let toActivate = activeWorkspace.get_neighbor(direction);
|
||||||
|
|
||||||
|
if (activeWorkspace != toActivate) {
|
||||||
|
// This won't have any effect for "always sticky" windows
|
||||||
|
// (like desktop windows or docks)
|
||||||
|
|
||||||
|
this._movingWindow = window;
|
||||||
|
window.change_workspace(toActivate);
|
||||||
|
|
||||||
|
global.display.clear_mouse_mode();
|
||||||
|
toActivate.activate_with_focus (window, global.get_current_time());
|
||||||
|
}
|
||||||
|
|
||||||
|
return toActivate;
|
||||||
|
},
|
||||||
});
|
});
|
||||||
|
@ -301,8 +301,7 @@ const WindowClone = new Lang.Class({
|
|||||||
|
|
||||||
if (!this._zoomLightbox)
|
if (!this._zoomLightbox)
|
||||||
this._zoomLightbox = new Lightbox.Lightbox(Main.uiGroup,
|
this._zoomLightbox = new Lightbox.Lightbox(Main.uiGroup,
|
||||||
{ fadeInTime: LIGHTBOX_FADE_TIME,
|
{ fadeTime: LIGHTBOX_FADE_TIME });
|
||||||
fadeOutTime: LIGHTBOX_FADE_TIME });
|
|
||||||
this._zoomLightbox.show();
|
this._zoomLightbox.show();
|
||||||
|
|
||||||
this._zoomLocalOrig = new ScaledPoint(this.actor.x, this.actor.y, this.actor.scale_x, this.actor.scale_y);
|
this._zoomLocalOrig = new ScaledPoint(this.actor.x, this.actor.y, this.actor.scale_x, this.actor.scale_y);
|
||||||
@ -1122,26 +1121,6 @@ const Workspace = new Lang.Class({
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
_showAllOverlays: function() {
|
|
||||||
let currentWorkspace = global.screen.get_active_workspace();
|
|
||||||
for (let i = 0; i < this._windows.length; i++) {
|
|
||||||
let clone = this._windows[i];
|
|
||||||
let overlay = this._windowOverlays[i];
|
|
||||||
this._showWindowOverlay(clone, overlay,
|
|
||||||
this.metaWorkspace == null || this.metaWorkspace == currentWorkspace);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
_hideAllOverlays: function() {
|
|
||||||
for (let i = 0; i < this._windows.length; i++) {
|
|
||||||
let clone = this._windows[i];
|
|
||||||
Tweener.removeTweens(clone.actor);
|
|
||||||
let overlay = this._windowOverlays[i];
|
|
||||||
if (overlay)
|
|
||||||
overlay.hide();
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
_delayedWindowRepositioning: function() {
|
_delayedWindowRepositioning: function() {
|
||||||
if (this._windowIsZooming)
|
if (this._windowIsZooming)
|
||||||
return true;
|
return true;
|
||||||
@ -1253,7 +1232,7 @@ const Workspace = new Lang.Class({
|
|||||||
if (!this._isMyWindow(win) || !this._isOverviewWindow(win))
|
if (!this._isMyWindow(win) || !this._isOverviewWindow(win))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
let clone = this._addWindowClone(win);
|
let [clone, overlay] = this._addWindowClone(win);
|
||||||
|
|
||||||
if (win._overviewHint) {
|
if (win._overviewHint) {
|
||||||
let x = win._overviewHint.x - this.actor.x;
|
let x = win._overviewHint.x - this.actor.x;
|
||||||
@ -1263,6 +1242,7 @@ const Workspace = new Lang.Class({
|
|||||||
|
|
||||||
clone.actor.set_position (x, y);
|
clone.actor.set_position (x, y);
|
||||||
clone.actor.set_scale (scale, scale);
|
clone.actor.set_scale (scale, scale);
|
||||||
|
this._updateWindowOverlayPositions(clone, overlay, x, y, scale, false);
|
||||||
} else {
|
} else {
|
||||||
// Position new windows at the top corner of the workspace rather
|
// Position new windows at the top corner of the workspace rather
|
||||||
// than where they were placed for real to avoid the window
|
// than where they were placed for real to avoid the window
|
||||||
@ -1322,7 +1302,10 @@ const Workspace = new Lang.Class({
|
|||||||
|
|
||||||
this.leavingOverview = true;
|
this.leavingOverview = true;
|
||||||
|
|
||||||
this._hideAllOverlays();
|
for (let i = 0; i < this._windows.length; i++) {
|
||||||
|
let clone = this._windows[i];
|
||||||
|
Tweener.removeTweens(clone.actor);
|
||||||
|
}
|
||||||
|
|
||||||
if (this._repositionWindowsId > 0) {
|
if (this._repositionWindowsId > 0) {
|
||||||
Mainloop.source_remove(this._repositionWindowsId);
|
Mainloop.source_remove(this._repositionWindowsId);
|
||||||
@ -1337,6 +1320,10 @@ const Workspace = new Lang.Class({
|
|||||||
// Position and scale the windows.
|
// Position and scale the windows.
|
||||||
for (let i = 0; i < this._windows.length; i++) {
|
for (let i = 0; i < this._windows.length; i++) {
|
||||||
let clone = this._windows[i];
|
let clone = this._windows[i];
|
||||||
|
let overlay = this._windowOverlays[i];
|
||||||
|
|
||||||
|
if (overlay)
|
||||||
|
overlay.hide();
|
||||||
|
|
||||||
clone.zoomFromOverview();
|
clone.zoomFromOverview();
|
||||||
|
|
||||||
@ -1361,7 +1348,6 @@ const Workspace = new Lang.Class({
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
},
|
},
|
||||||
|
|
||||||
destroy : function() {
|
destroy : function() {
|
||||||
@ -1452,7 +1438,7 @@ const Workspace = new Lang.Class({
|
|||||||
this._windows.push(clone);
|
this._windows.push(clone);
|
||||||
this._windowOverlays.push(overlay);
|
this._windowOverlays.push(overlay);
|
||||||
|
|
||||||
return clone;
|
return [clone, overlay];
|
||||||
},
|
},
|
||||||
|
|
||||||
_onShowOverlayClose: function (windowOverlay) {
|
_onShowOverlayClose: function (windowOverlay) {
|
||||||
|
@ -3,18 +3,17 @@
|
|||||||
const Clutter = imports.gi.Clutter;
|
const Clutter = imports.gi.Clutter;
|
||||||
const Lang = imports.lang;
|
const Lang = imports.lang;
|
||||||
const Mainloop = imports.mainloop;
|
const Mainloop = imports.mainloop;
|
||||||
|
const Meta = imports.gi.Meta;
|
||||||
const Shell = imports.gi.Shell;
|
const Shell = imports.gi.Shell;
|
||||||
|
const Signals = imports.signals;
|
||||||
const St = imports.gi.St;
|
const St = imports.gi.St;
|
||||||
const Main = imports.ui.main;
|
|
||||||
|
|
||||||
|
const Main = imports.ui.main;
|
||||||
const Tweener = imports.ui.tweener;
|
const Tweener = imports.ui.tweener;
|
||||||
|
|
||||||
const ANIMATION_TIME = 0.1;
|
const ANIMATION_TIME = 0.1;
|
||||||
const DISPLAY_TIMEOUT = 600;
|
const DISPLAY_TIMEOUT = 600;
|
||||||
|
|
||||||
const UP = -1;
|
|
||||||
const DOWN = 1;
|
|
||||||
|
|
||||||
const WorkspaceSwitcherPopup = new Lang.Class({
|
const WorkspaceSwitcherPopup = new Lang.Class({
|
||||||
Name: 'WorkspaceSwitcherPopup',
|
Name: 'WorkspaceSwitcherPopup',
|
||||||
|
|
||||||
@ -43,12 +42,14 @@ const WorkspaceSwitcherPopup = new Lang.Class({
|
|||||||
|
|
||||||
this.actor.add_actor(this._container);
|
this.actor.add_actor(this._container);
|
||||||
|
|
||||||
this._redraw();
|
this._redisplay();
|
||||||
|
|
||||||
this._position();
|
|
||||||
|
|
||||||
this.actor.hide();
|
this.actor.hide();
|
||||||
|
|
||||||
|
this._globalSignals = [];
|
||||||
|
this._globalSignals.push(global.screen.connect('workspace-added', Lang.bind(this, this._redisplay)));
|
||||||
|
this._globalSignals.push(global.screen.connect('workspace-removed', Lang.bind(this, this._redisplay)));
|
||||||
|
|
||||||
this._timeoutId = Mainloop.timeout_add(DISPLAY_TIMEOUT, Lang.bind(this, this._onTimeout));
|
this._timeoutId = Mainloop.timeout_add(DISPLAY_TIMEOUT, Lang.bind(this, this._onTimeout));
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -104,15 +105,15 @@ const WorkspaceSwitcherPopup = new Lang.Class({
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
_redraw : function(direction, activeWorkspaceIndex) {
|
_redisplay: function() {
|
||||||
this._list.destroy_all_children();
|
this._list.destroy_all_children();
|
||||||
|
|
||||||
for (let i = 0; i < global.screen.n_workspaces; i++) {
|
for (let i = 0; i < global.screen.n_workspaces; i++) {
|
||||||
let indicator = null;
|
let indicator = null;
|
||||||
|
|
||||||
if (i == activeWorkspaceIndex && direction == UP)
|
if (i == this._activeWorkspaceIndex && this._direction == Meta.MotionDirection.UP)
|
||||||
indicator = new St.Bin({ style_class: 'ws-switcher-active-up' });
|
indicator = new St.Bin({ style_class: 'ws-switcher-active-up' });
|
||||||
else if(i == activeWorkspaceIndex && direction == DOWN)
|
else if(i == this._activeWorkspaceIndex && this._direction == Meta.MotionDirection.DOWN)
|
||||||
indicator = new St.Bin({ style_class: 'ws-switcher-active-down' });
|
indicator = new St.Bin({ style_class: 'ws-switcher-active-down' });
|
||||||
else
|
else
|
||||||
indicator = new St.Bin({ style_class: 'ws-switcher-box' });
|
indicator = new St.Bin({ style_class: 'ws-switcher-box' });
|
||||||
@ -120,13 +121,13 @@ const WorkspaceSwitcherPopup = new Lang.Class({
|
|||||||
this._list.add_actor(indicator);
|
this._list.add_actor(indicator);
|
||||||
|
|
||||||
}
|
}
|
||||||
},
|
|
||||||
|
|
||||||
_position: function() {
|
|
||||||
let primary = Main.layoutManager.primaryMonitor;
|
let primary = Main.layoutManager.primaryMonitor;
|
||||||
this._container.x = primary.x + Math.floor((primary.width - this._container.width) / 2);
|
let [containerMinHeight, containerNatHeight] = this._container.get_preferred_height(global.screen_width);
|
||||||
|
let [containerMinWidth, containerNatWidth] = this._container.get_preferred_width(containerNatHeight);
|
||||||
|
this._container.x = primary.x + Math.floor((primary.width - containerNatWidth) / 2);
|
||||||
this._container.y = primary.y + Main.panel.actor.height +
|
this._container.y = primary.y + Main.panel.actor.height +
|
||||||
Math.floor(((primary.height - Main.panel.actor.height) - this._container.height) / 2);
|
Math.floor(((primary.height - Main.panel.actor.height) - containerNatHeight) / 2);
|
||||||
},
|
},
|
||||||
|
|
||||||
_show : function() {
|
_show : function() {
|
||||||
@ -134,12 +135,14 @@ const WorkspaceSwitcherPopup = new Lang.Class({
|
|||||||
time: ANIMATION_TIME,
|
time: ANIMATION_TIME,
|
||||||
transition: 'easeOutQuad'
|
transition: 'easeOutQuad'
|
||||||
});
|
});
|
||||||
this._position();
|
|
||||||
this.actor.show();
|
this.actor.show();
|
||||||
},
|
},
|
||||||
|
|
||||||
display : function(direction, activeWorkspaceIndex) {
|
display : function(direction, activeWorkspaceIndex) {
|
||||||
this._redraw(direction, activeWorkspaceIndex);
|
this._direction = direction;
|
||||||
|
this._activeWorkspaceIndex = activeWorkspaceIndex;
|
||||||
|
|
||||||
|
this._redisplay();
|
||||||
if (this._timeoutId != 0)
|
if (this._timeoutId != 0)
|
||||||
Mainloop.source_remove(this._timeoutId);
|
Mainloop.source_remove(this._timeoutId);
|
||||||
this._timeoutId = Mainloop.timeout_add(DISPLAY_TIMEOUT, Lang.bind(this, this._onTimeout));
|
this._timeoutId = Mainloop.timeout_add(DISPLAY_TIMEOUT, Lang.bind(this, this._onTimeout));
|
||||||
@ -152,8 +155,22 @@ const WorkspaceSwitcherPopup = new Lang.Class({
|
|||||||
Tweener.addTween(this._container, { opacity: 0.0,
|
Tweener.addTween(this._container, { opacity: 0.0,
|
||||||
time: ANIMATION_TIME,
|
time: ANIMATION_TIME,
|
||||||
transition: 'easeOutQuad',
|
transition: 'easeOutQuad',
|
||||||
onComplete: function() { this.actor.hide(); },
|
onComplete: function() { this.destroy(); },
|
||||||
onCompleteScope: this
|
onCompleteScope: this
|
||||||
});
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
destroy: function() {
|
||||||
|
if (this._timeoutId)
|
||||||
|
Mainloop.source_remove(this._timeoutId);
|
||||||
|
this._timeoutId = 0;
|
||||||
|
|
||||||
|
for (let i = 0; i < this._globalSignals.length; i++)
|
||||||
|
global.screen.disconnect(this._globalSignals[i]);
|
||||||
|
|
||||||
|
this.actor.destroy();
|
||||||
|
|
||||||
|
this.emit('destroy');
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
Signals.addSignalMethods(WorkspaceSwitcherPopup.prototype);
|
||||||
|
@ -667,7 +667,7 @@ const ThumbnailsBox = new Lang.Class({
|
|||||||
if (this._dropWorkspace != -1)
|
if (this._dropWorkspace != -1)
|
||||||
return this._thumbnails[this._dropWorkspace].handleDragOverInternal(source, time);
|
return this._thumbnails[this._dropWorkspace].handleDragOverInternal(source, time);
|
||||||
else if (this._dropPlaceholderPos != -1)
|
else if (this._dropPlaceholderPos != -1)
|
||||||
return DND.DragMotionResult.MOVE_DROP;
|
return source.realWindow ? DND.DragMotionResult.MOVE_DROP : DND.DragMotionResult.COPY_DROP;
|
||||||
else
|
else
|
||||||
return DND.DragMotionResult.CONTINUE;
|
return DND.DragMotionResult.CONTINUE;
|
||||||
},
|
},
|
||||||
|
@ -529,9 +529,11 @@ const WorkspacesDisplay = new Lang.Class({
|
|||||||
this._updateAlwaysZoom();
|
this._updateAlwaysZoom();
|
||||||
}));
|
}));
|
||||||
|
|
||||||
|
global.screen.connect('notify::n-workspaces',
|
||||||
|
Lang.bind(this, this._workspacesChanged));
|
||||||
|
|
||||||
this._switchWorkspaceNotifyId = 0;
|
this._switchWorkspaceNotifyId = 0;
|
||||||
|
|
||||||
this._nWorkspacesChangedId = 0;
|
|
||||||
this._itemDragBeginId = 0;
|
this._itemDragBeginId = 0;
|
||||||
this._itemDragCancelledId = 0;
|
this._itemDragCancelledId = 0;
|
||||||
this._itemDragEndId = 0;
|
this._itemDragEndId = 0;
|
||||||
@ -570,9 +572,6 @@ const WorkspacesDisplay = new Lang.Class({
|
|||||||
global.screen.connect('restacked',
|
global.screen.connect('restacked',
|
||||||
Lang.bind(this, this._onRestacked));
|
Lang.bind(this, this._onRestacked));
|
||||||
|
|
||||||
if (this._nWorkspacesChangedId == 0)
|
|
||||||
this._nWorkspacesChangedId = global.screen.connect('notify::n-workspaces',
|
|
||||||
Lang.bind(this, this._workspacesChanged));
|
|
||||||
if (this._itemDragBeginId == 0)
|
if (this._itemDragBeginId == 0)
|
||||||
this._itemDragBeginId = Main.overview.connect('item-drag-begin',
|
this._itemDragBeginId = Main.overview.connect('item-drag-begin',
|
||||||
Lang.bind(this, this._dragBegin));
|
Lang.bind(this, this._dragBegin));
|
||||||
@ -844,10 +843,7 @@ const WorkspacesDisplay = new Lang.Class({
|
|||||||
if (!primaryView)
|
if (!primaryView)
|
||||||
return;
|
return;
|
||||||
primaryView.actor.opacity = opacity;
|
primaryView.actor.opacity = opacity;
|
||||||
if (opacity == 0)
|
primaryView.actor.visible = opacity != 0;
|
||||||
primaryView.actor.hide();
|
|
||||||
else
|
|
||||||
primaryView.actor.show();
|
|
||||||
}));
|
}));
|
||||||
}));
|
}));
|
||||||
},
|
},
|
||||||
@ -928,19 +924,16 @@ const WorkspacesDisplay = new Lang.Class({
|
|||||||
},
|
},
|
||||||
|
|
||||||
_workspacesChanged: function() {
|
_workspacesChanged: function() {
|
||||||
let oldNumWorkspaces = this._workspaces[0].length;
|
|
||||||
let newNumWorkspaces = global.screen.n_workspaces;
|
|
||||||
let active = global.screen.get_active_workspace_index();
|
|
||||||
|
|
||||||
if (oldNumWorkspaces == newNumWorkspaces)
|
|
||||||
return;
|
|
||||||
|
|
||||||
this._updateAlwaysZoom();
|
this._updateAlwaysZoom();
|
||||||
this._updateZoom();
|
this._updateZoom();
|
||||||
|
|
||||||
if (this._workspacesViews == null)
|
if (this._workspacesViews == null)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
let oldNumWorkspaces = this._workspaces[0].length;
|
||||||
|
let newNumWorkspaces = global.screen.n_workspaces;
|
||||||
|
let active = global.screen.get_active_workspace_index();
|
||||||
|
|
||||||
let lostWorkspaces = [];
|
let lostWorkspaces = [];
|
||||||
if (newNumWorkspaces > oldNumWorkspaces) {
|
if (newNumWorkspaces > oldNumWorkspaces) {
|
||||||
let monitors = Main.layoutManager.monitors;
|
let monitors = Main.layoutManager.monitors;
|
||||||
@ -1055,10 +1048,10 @@ const WorkspacesDisplay = new Lang.Class({
|
|||||||
_onScrollEvent: function (actor, event) {
|
_onScrollEvent: function (actor, event) {
|
||||||
switch ( event.get_scroll_direction() ) {
|
switch ( event.get_scroll_direction() ) {
|
||||||
case Clutter.ScrollDirection.UP:
|
case Clutter.ScrollDirection.UP:
|
||||||
Main.wm.actionMoveWorkspaceUp();
|
Main.wm.actionMoveWorkspace(Meta.MotionDirection.UP);
|
||||||
break;
|
break;
|
||||||
case Clutter.ScrollDirection.DOWN:
|
case Clutter.ScrollDirection.DOWN:
|
||||||
Main.wm.actionMoveWorkspaceDown();
|
Main.wm.actionMoveWorkspace(Meta.MotionDirection.DOWN);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
data/gnome-shell.desktop.in.in
|
data/gnome-shell.desktop.in.in
|
||||||
data/gnome-shell-extension-prefs.desktop.in.in
|
data/gnome-shell-extension-prefs.desktop.in.in
|
||||||
data/org.gnome.shell.gschema.xml.in
|
data/org.gnome.shell.gschema.xml.in.in
|
||||||
js/extensionPrefs/main.js
|
js/extensionPrefs/main.js
|
||||||
js/gdm/loginDialog.js
|
js/gdm/loginDialog.js
|
||||||
js/gdm/powerMenu.js
|
js/gdm/powerMenu.js
|
||||||
@ -9,10 +9,10 @@ js/ui/appDisplay.js
|
|||||||
js/ui/appFavorites.js
|
js/ui/appFavorites.js
|
||||||
js/ui/autorunManager.js
|
js/ui/autorunManager.js
|
||||||
js/ui/calendar.js
|
js/ui/calendar.js
|
||||||
js/ui/contactDisplay.js
|
|
||||||
js/ui/dash.js
|
js/ui/dash.js
|
||||||
js/ui/dateMenu.js
|
js/ui/dateMenu.js
|
||||||
js/ui/endSessionDialog.js
|
js/ui/endSessionDialog.js
|
||||||
|
js/ui/extensionDownloader.js
|
||||||
js/ui/extensionSystem.js
|
js/ui/extensionSystem.js
|
||||||
js/ui/keyboard.js
|
js/ui/keyboard.js
|
||||||
js/ui/keyringPrompt.js
|
js/ui/keyringPrompt.js
|
||||||
@ -41,6 +41,7 @@ js/ui/userMenu.js
|
|||||||
js/ui/viewSelector.js
|
js/ui/viewSelector.js
|
||||||
js/ui/wanda.js
|
js/ui/wanda.js
|
||||||
js/ui/windowAttentionHandler.js
|
js/ui/windowAttentionHandler.js
|
||||||
|
src/calendar-server/evolution-calendar.desktop.in.in
|
||||||
src/gvc/gvc-mixer-control.c
|
src/gvc/gvc-mixer-control.c
|
||||||
src/main.c
|
src/main.c
|
||||||
src/shell-app.c
|
src/shell-app.c
|
||||||
|
@ -1,2 +1,4 @@
|
|||||||
data/gnome-shell.desktop.in
|
data/gnome-shell.desktop.in
|
||||||
data/gnome-shell-extension-prefs.desktop.in
|
data/gnome-shell-extension-prefs.desktop.in
|
||||||
|
data/org.gnome.shell.evolution.calendar.gschema.xml.in
|
||||||
|
src/calendar-server/evolution-calendar.desktop.in
|
||||||
|
132
po/ca.po
132
po/ca.po
@ -3,19 +3,21 @@
|
|||||||
# This file is distributed under the same license as the gnome-shell package.
|
# This file is distributed under the same license as the gnome-shell package.
|
||||||
# Siegfried-Angel Gevatter Pujals <rainct@ubuntu.com>, 2009.
|
# Siegfried-Angel Gevatter Pujals <rainct@ubuntu.com>, 2009.
|
||||||
# Gil Forcada <gilforcada@guifi.net>, 2010, 2011, 2012.
|
# Gil Forcada <gilforcada@guifi.net>, 2010, 2011, 2012.
|
||||||
|
# Jordi Serratosa <jordis@softcatala.cat>, 2012.
|
||||||
#
|
#
|
||||||
msgid ""
|
msgid ""
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Project-Id-Version: HEAD\n"
|
"Project-Id-Version: HEAD\n"
|
||||||
"Report-Msgid-Bugs-To: \n"
|
"Report-Msgid-Bugs-To: http://bugzilla.gnome.org/enter_bug.cgi?product=gnome-"
|
||||||
"POT-Creation-Date: 2012-03-19 22:35+0100\n"
|
"shell&keywords=I18N+L10N&component=general\n"
|
||||||
"PO-Revision-Date: 2012-03-19 22:35+0100\n"
|
"POT-Creation-Date: 2012-04-01 22:09+0000\n"
|
||||||
|
"PO-Revision-Date: 2012-04-02 00:08+0200\n"
|
||||||
"Last-Translator: Gil Forcada <gilforcada@guifi.net>\n"
|
"Last-Translator: Gil Forcada <gilforcada@guifi.net>\n"
|
||||||
"Language-Team: català; valencià <tradgnome@softcatala.org>\n"
|
"Language-Team: català; valencià <tradgnome@softcatala.org>\n"
|
||||||
"Language: ca\n"
|
|
||||||
"MIME-Version: 1.0\n"
|
"MIME-Version: 1.0\n"
|
||||||
"Content-Type: text/plain; charset=UTF-8\n"
|
"Content-Type: text/plain; charset=UTF-8\n"
|
||||||
"Content-Transfer-Encoding: 8bits\n"
|
"Content-Transfer-Encoding: 8bits\n"
|
||||||
|
"Language: ca\n"
|
||||||
"Plural-Forms: nplurals=2; plural=n != 1;\n"
|
"Plural-Forms: nplurals=2; plural=n != 1;\n"
|
||||||
|
|
||||||
#: ../data/gnome-shell.desktop.in.in.h:1
|
#: ../data/gnome-shell.desktop.in.in.h:1
|
||||||
@ -134,35 +136,43 @@ msgid "If true, display the ISO week date in the calendar."
|
|||||||
msgstr "Si és «true» (cert) es mostra el número de la setmana en el calendari."
|
msgstr "Si és «true» (cert) es mostra el número de la setmana en el calendari."
|
||||||
|
|
||||||
#: ../data/org.gnome.shell.gschema.xml.in.h:16
|
#: ../data/org.gnome.shell.gschema.xml.in.h:16
|
||||||
|
msgid "Keybinding to open the application menu"
|
||||||
|
msgstr "Vinculació per obrir el menú d'aplicació"
|
||||||
|
|
||||||
|
#: ../data/org.gnome.shell.gschema.xml.in.h:17
|
||||||
|
msgid "Keybinding to open the application menu."
|
||||||
|
msgstr "La vinculació per obrir el menú d'aplicació."
|
||||||
|
|
||||||
|
#: ../data/org.gnome.shell.gschema.xml.in.h:18
|
||||||
msgid "Which keyboard to use"
|
msgid "Which keyboard to use"
|
||||||
msgstr "Quin tipus de teclat s'ha d'utilitzar"
|
msgstr "Quin tipus de teclat s'ha d'utilitzar"
|
||||||
|
|
||||||
#: ../data/org.gnome.shell.gschema.xml.in.h:17
|
#: ../data/org.gnome.shell.gschema.xml.in.h:19
|
||||||
msgid "The type of keyboard to use."
|
msgid "The type of keyboard to use."
|
||||||
msgstr "El tipus de teclat que s'utilitzarà."
|
msgstr "El tipus de teclat que s'utilitzarà."
|
||||||
|
|
||||||
#: ../data/org.gnome.shell.gschema.xml.in.h:18
|
#: ../data/org.gnome.shell.gschema.xml.in.h:20
|
||||||
msgid "Show time with seconds"
|
msgid "Show time with seconds"
|
||||||
msgstr "Mostra l'hora amb segons"
|
msgstr "Mostra l'hora amb segons"
|
||||||
|
|
||||||
#: ../data/org.gnome.shell.gschema.xml.in.h:19
|
#: ../data/org.gnome.shell.gschema.xml.in.h:21
|
||||||
msgid "If true, display seconds in time."
|
msgid "If true, display seconds in time."
|
||||||
msgstr "Si és «true» (cert) es mostren els segons."
|
msgstr "Si és «true» (cert) es mostren els segons."
|
||||||
|
|
||||||
#: ../data/org.gnome.shell.gschema.xml.in.h:20
|
#: ../data/org.gnome.shell.gschema.xml.in.h:22
|
||||||
msgid "Show date in clock"
|
msgid "Show date in clock"
|
||||||
msgstr "Mostra la data en el rellotge"
|
msgstr "Mostra la data en el rellotge"
|
||||||
|
|
||||||
#: ../data/org.gnome.shell.gschema.xml.in.h:21
|
#: ../data/org.gnome.shell.gschema.xml.in.h:23
|
||||||
msgid "If true, display date in the clock, in addition to time."
|
msgid "If true, display date in the clock, in addition to time."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Si és «true» (cert) es mostra la data en el rellotge a més a més de l'hora."
|
"Si és «true» (cert) es mostra la data en el rellotge a més a més de l'hora."
|
||||||
|
|
||||||
#: ../data/org.gnome.shell.gschema.xml.in.h:22
|
#: ../data/org.gnome.shell.gschema.xml.in.h:24
|
||||||
msgid "Framerate used for recording screencasts."
|
msgid "Framerate used for recording screencasts."
|
||||||
msgstr "Imatges per segon per enregistrar els screencasts."
|
msgstr "Imatges per segon per enregistrar els screencasts."
|
||||||
|
|
||||||
#: ../data/org.gnome.shell.gschema.xml.in.h:23
|
#: ../data/org.gnome.shell.gschema.xml.in.h:25
|
||||||
msgid ""
|
msgid ""
|
||||||
"The framerate of the resulting screencast recordered by GNOME Shell's "
|
"The framerate of the resulting screencast recordered by GNOME Shell's "
|
||||||
"screencast recorder in frames-per-second."
|
"screencast recorder in frames-per-second."
|
||||||
@ -170,11 +180,11 @@ msgstr ""
|
|||||||
"Les imatges per segon, en fotogrames per segon, de l'screencast enregistrat "
|
"Les imatges per segon, en fotogrames per segon, de l'screencast enregistrat "
|
||||||
"per l'eina d'enregistrament del GNOME Shell."
|
"per l'eina d'enregistrament del GNOME Shell."
|
||||||
|
|
||||||
#: ../data/org.gnome.shell.gschema.xml.in.h:24
|
#: ../data/org.gnome.shell.gschema.xml.in.h:26
|
||||||
msgid "The gstreamer pipeline used to encode the screencast"
|
msgid "The gstreamer pipeline used to encode the screencast"
|
||||||
msgstr "El conducte GStreamer per enregistrar els screencasts"
|
msgstr "El conducte GStreamer per enregistrar els screencasts"
|
||||||
|
|
||||||
#: ../data/org.gnome.shell.gschema.xml.in.h:26
|
#: ../data/org.gnome.shell.gschema.xml.in.h:28
|
||||||
#, no-c-format
|
#, no-c-format
|
||||||
msgid ""
|
msgid ""
|
||||||
"Sets the GStreamer pipeline used to encode recordings. It follows the syntax "
|
"Sets the GStreamer pipeline used to encode recordings. It follows the syntax "
|
||||||
@ -200,11 +210,11 @@ msgstr ""
|
|||||||
"enregistra amb el format WEBM i utilitza el còdec VP8. El %T és una variable "
|
"enregistra amb el format WEBM i utilitza el còdec VP8. El %T és una variable "
|
||||||
"per estimar el nombre de fils d'execució paral·lels òptims del sistema."
|
"per estimar el nombre de fils d'execució paral·lels òptims del sistema."
|
||||||
|
|
||||||
#: ../data/org.gnome.shell.gschema.xml.in.h:27
|
#: ../data/org.gnome.shell.gschema.xml.in.h:29
|
||||||
msgid "File extension used for storing the screencast"
|
msgid "File extension used for storing the screencast"
|
||||||
msgstr "Extensió de fitxer per desar l'screencast"
|
msgstr "Extensió de fitxer per desar l'screencast"
|
||||||
|
|
||||||
#: ../data/org.gnome.shell.gschema.xml.in.h:28
|
#: ../data/org.gnome.shell.gschema.xml.in.h:30
|
||||||
msgid ""
|
msgid ""
|
||||||
"The filename for recorded screencasts will be a unique filename based on the "
|
"The filename for recorded screencasts will be a unique filename based on the "
|
||||||
"current date, and use this extension. It should be changed when recording to "
|
"current date, and use this extension. It should be changed when recording to "
|
||||||
@ -505,7 +515,7 @@ msgstr "Ocupat"
|
|||||||
|
|
||||||
#: ../js/ui/contactDisplay.js:102
|
#: ../js/ui/contactDisplay.js:102
|
||||||
msgid "Offline"
|
msgid "Offline"
|
||||||
msgstr "Fora de línia"
|
msgstr "Fora de línia"
|
||||||
|
|
||||||
#: ../js/ui/contactDisplay.js:153
|
#: ../js/ui/contactDisplay.js:153
|
||||||
msgid "CONTACTS"
|
msgid "CONTACTS"
|
||||||
@ -684,51 +694,51 @@ msgstr "Contrasenya:"
|
|||||||
msgid "Type again:"
|
msgid "Type again:"
|
||||||
msgstr "Torneu a escriure-la:"
|
msgstr "Torneu a escriure-la:"
|
||||||
|
|
||||||
#: ../js/ui/lookingGlass.js:725
|
#: ../js/ui/lookingGlass.js:732
|
||||||
msgid "No extensions installed"
|
msgid "No extensions installed"
|
||||||
msgstr "No hi ha cap extensió instal·lada"
|
msgstr "No hi ha cap extensió instal·lada"
|
||||||
|
|
||||||
#. Translators: argument is an extension UUID.
|
#. Translators: argument is an extension UUID.
|
||||||
#: ../js/ui/lookingGlass.js:779
|
#: ../js/ui/lookingGlass.js:786
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "%s has not emitted any errors."
|
msgid "%s has not emitted any errors."
|
||||||
msgstr "%s no ha emès cap error."
|
msgstr "%s no ha emès cap error."
|
||||||
|
|
||||||
#: ../js/ui/lookingGlass.js:785
|
#: ../js/ui/lookingGlass.js:792
|
||||||
msgid "Hide Errors"
|
msgid "Hide Errors"
|
||||||
msgstr "Amaga els errors"
|
msgstr "Amaga els errors"
|
||||||
|
|
||||||
#: ../js/ui/lookingGlass.js:789 ../js/ui/lookingGlass.js:840
|
#: ../js/ui/lookingGlass.js:796 ../js/ui/lookingGlass.js:847
|
||||||
msgid "Show Errors"
|
msgid "Show Errors"
|
||||||
msgstr "Mostra els errors"
|
msgstr "Mostra els errors"
|
||||||
|
|
||||||
#: ../js/ui/lookingGlass.js:798
|
#: ../js/ui/lookingGlass.js:805
|
||||||
msgid "Enabled"
|
msgid "Enabled"
|
||||||
msgstr "Habilitat"
|
msgstr "Habilitat"
|
||||||
|
|
||||||
#. translators:
|
#. translators:
|
||||||
#. * The device has been disabled
|
#. * The device has been disabled
|
||||||
#: ../js/ui/lookingGlass.js:801 ../src/gvc/gvc-mixer-control.c:1093
|
#: ../js/ui/lookingGlass.js:808 ../src/gvc/gvc-mixer-control.c:1093
|
||||||
msgid "Disabled"
|
msgid "Disabled"
|
||||||
msgstr "Inhabilitat"
|
msgstr "Inhabilitat"
|
||||||
|
|
||||||
#: ../js/ui/lookingGlass.js:803
|
#: ../js/ui/lookingGlass.js:810
|
||||||
msgid "Error"
|
msgid "Error"
|
||||||
msgstr "Error"
|
msgstr "Error"
|
||||||
|
|
||||||
#: ../js/ui/lookingGlass.js:805
|
#: ../js/ui/lookingGlass.js:812
|
||||||
msgid "Out of date"
|
msgid "Out of date"
|
||||||
msgstr "Fora d'hora"
|
msgstr "Fora d'hora"
|
||||||
|
|
||||||
#: ../js/ui/lookingGlass.js:807
|
#: ../js/ui/lookingGlass.js:814
|
||||||
msgid "Downloading"
|
msgid "Downloading"
|
||||||
msgstr "S'està baixant"
|
msgstr "S'està baixant"
|
||||||
|
|
||||||
#: ../js/ui/lookingGlass.js:828
|
#: ../js/ui/lookingGlass.js:835
|
||||||
msgid "View Source"
|
msgid "View Source"
|
||||||
msgstr "Mostra el codi font"
|
msgstr "Mostra el codi font"
|
||||||
|
|
||||||
#: ../js/ui/lookingGlass.js:834
|
#: ../js/ui/lookingGlass.js:841
|
||||||
msgid "Web Page"
|
msgid "Web Page"
|
||||||
msgstr "Pàgina web"
|
msgstr "Pàgina web"
|
||||||
|
|
||||||
@ -796,15 +806,15 @@ msgstr "La xarxa sense fil requereix autenticació"
|
|||||||
#: ../js/ui/networkAgent.js:330
|
#: ../js/ui/networkAgent.js:330
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid ""
|
msgid ""
|
||||||
"Passwords or encryption keys are required to access the wireless network "
|
"Passwords or encryption keys are required to access the wireless network '%"
|
||||||
"'%s'."
|
"s'."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Per accedir a la xarxa sense fil «%s» calen les contrasenyes o les claus "
|
"Per accedir a la xarxa sense fil «%s» calen les contrasenyes o les claus "
|
||||||
"d'encriptació."
|
"d'encriptació."
|
||||||
|
|
||||||
#: ../js/ui/networkAgent.js:334
|
#: ../js/ui/networkAgent.js:334
|
||||||
msgid "Wired 802.1X authentication"
|
msgid "Wired 802.1X authentication"
|
||||||
msgstr "Autenticació 802.1X amb fil"
|
msgstr "Autenticació 802.1X amb fil"
|
||||||
|
|
||||||
#: ../js/ui/networkAgent.js:336
|
#: ../js/ui/networkAgent.js:336
|
||||||
msgid "Network name: "
|
msgid "Network name: "
|
||||||
@ -812,15 +822,15 @@ msgstr "Nom de la xarxa: "
|
|||||||
|
|
||||||
#: ../js/ui/networkAgent.js:341
|
#: ../js/ui/networkAgent.js:341
|
||||||
msgid "DSL authentication"
|
msgid "DSL authentication"
|
||||||
msgstr "Autenticació DSL"
|
msgstr "Autenticació DSL"
|
||||||
|
|
||||||
#: ../js/ui/networkAgent.js:348
|
#: ../js/ui/networkAgent.js:348
|
||||||
msgid "PIN code required"
|
msgid "PIN code required"
|
||||||
msgstr "Cal que introduïu el codi PIN"
|
msgstr "Cal que introduïu el codi PIN"
|
||||||
|
|
||||||
#: ../js/ui/networkAgent.js:349
|
#: ../js/ui/networkAgent.js:349
|
||||||
msgid "PIN code is needed for the mobile broadband device"
|
msgid "PIN code is needed for the mobile broadband device"
|
||||||
msgstr "Cal que introduïu el codi PIN del dispositiu de banda ampla mòbil"
|
msgstr "Cal que introduïu el codi PIN del dispositiu de banda ampla mòbil"
|
||||||
|
|
||||||
#: ../js/ui/networkAgent.js:350
|
#: ../js/ui/networkAgent.js:350
|
||||||
msgid "PIN: "
|
msgid "PIN: "
|
||||||
@ -828,12 +838,12 @@ msgstr "PIN: "
|
|||||||
|
|
||||||
#: ../js/ui/networkAgent.js:356
|
#: ../js/ui/networkAgent.js:356
|
||||||
msgid "Mobile broadband network password"
|
msgid "Mobile broadband network password"
|
||||||
msgstr "Contrasenya de la xarxa de banda ampla mòbil"
|
msgstr "Contrasenya de la xarxa de banda ampla mòbil"
|
||||||
|
|
||||||
#: ../js/ui/networkAgent.js:357
|
#: ../js/ui/networkAgent.js:357
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "A password is required to connect to '%s'."
|
msgid "A password is required to connect to '%s'."
|
||||||
msgstr "Cal que introduïu una contrasenya per connectar-vos a «%s»."
|
msgstr "Cal que introduïu una contrasenya per connectar-vos a «%s»."
|
||||||
|
|
||||||
#: ../js/ui/overview.js:90
|
#: ../js/ui/overview.js:90
|
||||||
msgid "Undo"
|
msgid "Undo"
|
||||||
@ -857,17 +867,17 @@ msgstr "Aplicacions"
|
|||||||
msgid "Dash"
|
msgid "Dash"
|
||||||
msgstr "Quadre d'aplicacions"
|
msgstr "Quadre d'aplicacions"
|
||||||
|
|
||||||
#: ../js/ui/panel.js:591
|
#: ../js/ui/panel.js:592
|
||||||
msgid "Quit"
|
msgid "Quit"
|
||||||
msgstr "Surt"
|
msgstr "Surt"
|
||||||
|
|
||||||
#. Translators: If there is no suitable word for "Activities"
|
#. Translators: If there is no suitable word for "Activities"
|
||||||
#. in your language, you can use the word for "Overview".
|
#. in your language, you can use the word for "Overview".
|
||||||
#: ../js/ui/panel.js:623
|
#: ../js/ui/panel.js:624
|
||||||
msgid "Activities"
|
msgid "Activities"
|
||||||
msgstr "Activitats"
|
msgstr "Activitats"
|
||||||
|
|
||||||
#: ../js/ui/panel.js:998
|
#: ../js/ui/panel.js:999
|
||||||
msgid "Top Bar"
|
msgid "Top Bar"
|
||||||
msgstr "Barra superior"
|
msgstr "Barra superior"
|
||||||
|
|
||||||
@ -921,11 +931,11 @@ msgstr "toggle-switch-intl"
|
|||||||
msgid "Please enter a command:"
|
msgid "Please enter a command:"
|
||||||
msgstr "Introduïu una ordre:"
|
msgstr "Introduïu una ordre:"
|
||||||
|
|
||||||
#: ../js/ui/searchDisplay.js:331
|
#: ../js/ui/searchDisplay.js:332
|
||||||
msgid "Searching..."
|
msgid "Searching..."
|
||||||
msgstr "S'està cercant..."
|
msgstr "S'està cercant..."
|
||||||
|
|
||||||
#: ../js/ui/searchDisplay.js:413
|
#: ../js/ui/searchDisplay.js:414
|
||||||
msgid "No matching results."
|
msgid "No matching results."
|
||||||
msgstr "No s'ha trobat cap coincidència."
|
msgstr "No s'ha trobat cap coincidència."
|
||||||
|
|
||||||
@ -1068,7 +1078,7 @@ msgstr "Paràmetres de so"
|
|||||||
#: ../js/ui/status/bluetooth.js:372
|
#: ../js/ui/status/bluetooth.js:372
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "Authorization request from %s"
|
msgid "Authorization request from %s"
|
||||||
msgstr "Hi ha una petició d'autorització des de %s"
|
msgstr "Hi ha una sol·licitud d'autorització des de %s"
|
||||||
|
|
||||||
#: ../js/ui/status/bluetooth.js:378
|
#: ../js/ui/status/bluetooth.js:378
|
||||||
#, c-format
|
#, c-format
|
||||||
@ -1238,7 +1248,7 @@ msgstr "Paràmetres de xarxa"
|
|||||||
|
|
||||||
#: ../js/ui/status/network.js:1739
|
#: ../js/ui/status/network.js:1739
|
||||||
msgid "Connection failed"
|
msgid "Connection failed"
|
||||||
msgstr "Ha fallat la connexió"
|
msgstr "Ha fallat la connexió"
|
||||||
|
|
||||||
#: ../js/ui/status/network.js:1740
|
#: ../js/ui/status/network.js:1740
|
||||||
msgid "Activation of network connection failed"
|
msgid "Activation of network connection failed"
|
||||||
@ -1367,11 +1377,11 @@ msgstr "Trucada"
|
|||||||
#. We got the TpContact
|
#. We got the TpContact
|
||||||
#: ../js/ui/telepathyClient.js:287
|
#: ../js/ui/telepathyClient.js:287
|
||||||
msgid "File Transfer"
|
msgid "File Transfer"
|
||||||
msgstr "Transferència de fitxers"
|
msgstr "Transferència de fitxers"
|
||||||
|
|
||||||
#: ../js/ui/telepathyClient.js:369
|
#: ../js/ui/telepathyClient.js:369
|
||||||
msgid "Subscription request"
|
msgid "Subscription request"
|
||||||
msgstr "Teniu una petició de subscripció"
|
msgstr "Teniu una sol·licitud de subscripció"
|
||||||
|
|
||||||
#: ../js/ui/telepathyClient.js:405
|
#: ../js/ui/telepathyClient.js:405
|
||||||
msgid "Connection error"
|
msgid "Connection error"
|
||||||
@ -1482,7 +1492,7 @@ msgstr "En/na %s us envia %s"
|
|||||||
#: ../js/ui/telepathyClient.js:1194
|
#: ../js/ui/telepathyClient.js:1194
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "%s would like permission to see when you are online"
|
msgid "%s would like permission to see when you are online"
|
||||||
msgstr "%s vol poder saber quan esteu en línia"
|
msgstr "%s vol poder saber quan esteu en línia"
|
||||||
|
|
||||||
#: ../js/ui/telepathyClient.js:1287
|
#: ../js/ui/telepathyClient.js:1287
|
||||||
msgid "Network error"
|
msgid "Network error"
|
||||||
@ -1490,7 +1500,7 @@ msgstr "Error de la xarxa"
|
|||||||
|
|
||||||
#: ../js/ui/telepathyClient.js:1289
|
#: ../js/ui/telepathyClient.js:1289
|
||||||
msgid "Authentication failed"
|
msgid "Authentication failed"
|
||||||
msgstr "Ha fallat l'autenticació"
|
msgstr "Ha fallat l'autenticació"
|
||||||
|
|
||||||
#: ../js/ui/telepathyClient.js:1291
|
#: ../js/ui/telepathyClient.js:1291
|
||||||
msgid "Encryption error"
|
msgid "Encryption error"
|
||||||
@ -1502,19 +1512,19 @@ msgstr "No s'ha proporcionat el certificat"
|
|||||||
|
|
||||||
#: ../js/ui/telepathyClient.js:1295
|
#: ../js/ui/telepathyClient.js:1295
|
||||||
msgid "Certificate untrusted"
|
msgid "Certificate untrusted"
|
||||||
msgstr "El certificat no és de confiança"
|
msgstr "El certificat no és de confiança"
|
||||||
|
|
||||||
#: ../js/ui/telepathyClient.js:1297
|
#: ../js/ui/telepathyClient.js:1297
|
||||||
msgid "Certificate expired"
|
msgid "Certificate expired"
|
||||||
msgstr "El certificat ha vençut"
|
msgstr "El certificat ha vençut"
|
||||||
|
|
||||||
#: ../js/ui/telepathyClient.js:1299
|
#: ../js/ui/telepathyClient.js:1299
|
||||||
msgid "Certificate not activated"
|
msgid "Certificate not activated"
|
||||||
msgstr "El certificat no està activat"
|
msgstr "El certificat no està activat"
|
||||||
|
|
||||||
#: ../js/ui/telepathyClient.js:1301
|
#: ../js/ui/telepathyClient.js:1301
|
||||||
msgid "Certificate hostname mismatch"
|
msgid "Certificate hostname mismatch"
|
||||||
msgstr "No coincideix el nom de la màquina del certificat"
|
msgstr "No coincideix el nom de la màquina del certificat"
|
||||||
|
|
||||||
#: ../js/ui/telepathyClient.js:1303
|
#: ../js/ui/telepathyClient.js:1303
|
||||||
msgid "Certificate fingerprint mismatch"
|
msgid "Certificate fingerprint mismatch"
|
||||||
@ -1530,33 +1540,33 @@ msgstr "S'ha establert l'estat a fora de línia"
|
|||||||
|
|
||||||
#: ../js/ui/telepathyClient.js:1309
|
#: ../js/ui/telepathyClient.js:1309
|
||||||
msgid "Encryption is not available"
|
msgid "Encryption is not available"
|
||||||
msgstr "L'encriptació no està disponible"
|
msgstr "L'encriptació no està disponible"
|
||||||
|
|
||||||
#: ../js/ui/telepathyClient.js:1311
|
#: ../js/ui/telepathyClient.js:1311
|
||||||
msgid "Certificate is invalid"
|
msgid "Certificate is invalid"
|
||||||
msgstr "El certificat no és vàlid"
|
msgstr "El certificat no és vàlid"
|
||||||
|
|
||||||
#: ../js/ui/telepathyClient.js:1313
|
#: ../js/ui/telepathyClient.js:1313
|
||||||
msgid "Connection has been refused"
|
msgid "Connection has been refused"
|
||||||
msgstr "S'ha rebutjat la connexió"
|
msgstr "S'ha rebutjat la connexió"
|
||||||
|
|
||||||
#: ../js/ui/telepathyClient.js:1315
|
#: ../js/ui/telepathyClient.js:1315
|
||||||
msgid "Connection can't be established"
|
msgid "Connection can't be established"
|
||||||
msgstr "No es pot establir la connexió"
|
msgstr "No es pot establir la connexió"
|
||||||
|
|
||||||
#: ../js/ui/telepathyClient.js:1317
|
#: ../js/ui/telepathyClient.js:1317
|
||||||
msgid "Connection has been lost"
|
msgid "Connection has been lost"
|
||||||
msgstr "S'ha perdut la connexió"
|
msgstr "S'ha perdut la connexió"
|
||||||
|
|
||||||
#: ../js/ui/telepathyClient.js:1319
|
#: ../js/ui/telepathyClient.js:1319
|
||||||
msgid "This account is already connected to the server"
|
msgid "This account is already connected to the server"
|
||||||
msgstr "Aquest compte ja està connectat al servidor"
|
msgstr "Aquest compte ja està connectat al servidor"
|
||||||
|
|
||||||
#: ../js/ui/telepathyClient.js:1321
|
#: ../js/ui/telepathyClient.js:1321
|
||||||
msgid ""
|
msgid ""
|
||||||
"Connection has been replaced by a new connection using the same resource"
|
"Connection has been replaced by a new connection using the same resource"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"S'ha reemplaçat la connexió per una altra de nova fent servir el mateix "
|
"S'ha reemplaçat la connexió per una altra de nova fent servir el mateix "
|
||||||
"recurs"
|
"recurs"
|
||||||
|
|
||||||
#: ../js/ui/telepathyClient.js:1323
|
#: ../js/ui/telepathyClient.js:1323
|
||||||
@ -1565,7 +1575,7 @@ msgstr "Ja existeix aquest compte al servidor"
|
|||||||
|
|
||||||
#: ../js/ui/telepathyClient.js:1325
|
#: ../js/ui/telepathyClient.js:1325
|
||||||
msgid "Server is currently too busy to handle the connection"
|
msgid "Server is currently too busy to handle the connection"
|
||||||
msgstr "El servidor està massa ocupat per gestionar la connexió"
|
msgstr "El servidor està massa ocupat per gestionar la connexió"
|
||||||
|
|
||||||
#: ../js/ui/telepathyClient.js:1327
|
#: ../js/ui/telepathyClient.js:1327
|
||||||
msgid "Certificate has been revoked"
|
msgid "Certificate has been revoked"
|
||||||
@ -1575,8 +1585,8 @@ msgstr "S'ha revocat el certificat"
|
|||||||
msgid ""
|
msgid ""
|
||||||
"Certificate uses an insecure cipher algorithm or is cryptographically weak"
|
"Certificate uses an insecure cipher algorithm or is cryptographically weak"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"El certificat utilitza un algorisme criptògraf no segur o la seva fortalesa "
|
"El certificat utilitza un algorisme criptògraf no segur o la seva fortalesa "
|
||||||
"criptogràfica és feble"
|
"criptogràfica és feble"
|
||||||
|
|
||||||
#: ../js/ui/telepathyClient.js:1331
|
#: ../js/ui/telepathyClient.js:1331
|
||||||
msgid ""
|
msgid ""
|
||||||
@ -1584,7 +1594,7 @@ msgid ""
|
|||||||
"chain, exceed the limits imposed by the cryptography library"
|
"chain, exceed the limits imposed by the cryptography library"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"La llargada del certificat del servidor o la profunditat de la cadena de "
|
"La llargada del certificat del servidor o la profunditat de la cadena de "
|
||||||
"certificació excedeix els límits de la biblioteca criptogràfica"
|
"certificació excedeix els límits de la biblioteca criptogràfica"
|
||||||
|
|
||||||
#: ../js/ui/telepathyClient.js:1333
|
#: ../js/ui/telepathyClient.js:1333
|
||||||
msgid "Internal error"
|
msgid "Internal error"
|
||||||
|
1148
po/ca@valencia.po
1148
po/ca@valencia.po
File diff suppressed because it is too large
Load Diff
81
po/cs.po
81
po/cs.po
@ -1,27 +1,26 @@
|
|||||||
# Czech translation of gnome-shell.
|
# Czech translation of gnome-shell.
|
||||||
# Copyright (C) 2009, 2010, 2011 the author(s) of gnome-shell.
|
# Copyright (C) 2009, 2010, 2011 the author(s) of gnome-shell.
|
||||||
# This file is distributed under the same license as the gnome-shell package.
|
# This file is distributed under the same license as the gnome-shell package.
|
||||||
#
|
|
||||||
# Andre Klapper <ak-47@gmx.net>, 2009.
|
# Andre Klapper <ak-47@gmx.net>, 2009.
|
||||||
# Petr Kovar <pknbe@volny.cz>, 2009, 2010, 2011.
|
# Petr Kovar <pknbe@volny.cz>, 2009, 2010, 2011, 2012.
|
||||||
# Adam Matoušek <adydas95@gmail.com>, 2012
|
# Adam Matoušek <adydas95@gmail.com>, 2012
|
||||||
# Marek Černocký <marek@manet.cz>, 2012.
|
# Marek Černocký <marek@manet.cz>, 2012.
|
||||||
#
|
|
||||||
msgid ""
|
msgid ""
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Project-Id-Version: gnome-shell\n"
|
"Project-Id-Version: gnome-shell\n"
|
||||||
"Report-Msgid-Bugs-To: http://bugzilla.gnome.org/enter_bug.cgi?product=gnome-"
|
"Report-Msgid-Bugs-To: http://bugzilla.gnome.org/enter_bug.cgi?product=gnome-"
|
||||||
"shell&keywords=I18N+L10N&component=general\n"
|
"shell&keywords=I18N+L10N&component=general\n"
|
||||||
"POT-Creation-Date: 2012-03-19 14:09+0000\n"
|
"POT-Creation-Date: 2012-03-30 17:59+0000\n"
|
||||||
"PO-Revision-Date: 2012-03-22 11:28+0100\n"
|
"PO-Revision-Date: 2012-04-16 15:34+0200\n"
|
||||||
"Last-Translator: Marek Černocký <marek@manet.cz>\n"
|
"Last-Translator: Petr Kovar <pknbe@volny.cz>\n"
|
||||||
"Language-Team: Czech <gnome-cs-list@gnome.org>\n"
|
"Language-Team: Czech <gnome-cs-list@gnome.org>\n"
|
||||||
|
"Language: cs\n"
|
||||||
"MIME-Version: 1.0\n"
|
"MIME-Version: 1.0\n"
|
||||||
"Content-Type: text/plain; charset=UTF-8\n"
|
"Content-Type: text/plain; charset=UTF-8\n"
|
||||||
"Content-Transfer-Encoding: 8bit\n"
|
"Content-Transfer-Encoding: 8bit\n"
|
||||||
"Language: cs\n"
|
|
||||||
"Plural-Forms: nplurals=3; plural=(n==1) ? 0 : (n>=2 && n<=4) ? 1 : 2;\n"
|
"Plural-Forms: nplurals=3; plural=(n==1) ? 0 : (n>=2 && n<=4) ? 1 : 2;\n"
|
||||||
"X-Generator: Lokalize 1.2\n"
|
"X-Generator: Virtaal 0.7.1\n"
|
||||||
|
"X-Project-Style: gnome\n"
|
||||||
|
|
||||||
#: ../data/gnome-shell.desktop.in.in.h:1
|
#: ../data/gnome-shell.desktop.in.in.h:1
|
||||||
msgid "GNOME Shell"
|
msgid "GNOME Shell"
|
||||||
@ -134,34 +133,42 @@ msgid "If true, display the ISO week date in the calendar."
|
|||||||
msgstr "Je-li zapnuto, zobrazovat v kalendáři čísla týdnů dle ISO."
|
msgstr "Je-li zapnuto, zobrazovat v kalendáři čísla týdnů dle ISO."
|
||||||
|
|
||||||
#: ../data/org.gnome.shell.gschema.xml.in.h:16
|
#: ../data/org.gnome.shell.gschema.xml.in.h:16
|
||||||
|
msgid "Keybinding to open the application menu"
|
||||||
|
msgstr "Klávesová zkratka na otevření nabídky aplikace"
|
||||||
|
|
||||||
|
#: ../data/org.gnome.shell.gschema.xml.in.h:17
|
||||||
|
msgid "Keybinding to open the application menu."
|
||||||
|
msgstr "Klávesová zkratka na otevření nabídky aplikace."
|
||||||
|
|
||||||
|
#: ../data/org.gnome.shell.gschema.xml.in.h:18
|
||||||
msgid "Which keyboard to use"
|
msgid "Which keyboard to use"
|
||||||
msgstr "Která klávesnice se má používat"
|
msgstr "Která klávesnice se má používat"
|
||||||
|
|
||||||
#: ../data/org.gnome.shell.gschema.xml.in.h:17
|
#: ../data/org.gnome.shell.gschema.xml.in.h:19
|
||||||
msgid "The type of keyboard to use."
|
msgid "The type of keyboard to use."
|
||||||
msgstr "Typ klávesnice, který se má používat."
|
msgstr "Typ klávesnice, který se má používat."
|
||||||
|
|
||||||
#: ../data/org.gnome.shell.gschema.xml.in.h:18
|
#: ../data/org.gnome.shell.gschema.xml.in.h:20
|
||||||
msgid "Show time with seconds"
|
msgid "Show time with seconds"
|
||||||
msgstr "Zobrazovat čas včetně sekund"
|
msgstr "Zobrazovat čas včetně sekund"
|
||||||
|
|
||||||
#: ../data/org.gnome.shell.gschema.xml.in.h:19
|
#: ../data/org.gnome.shell.gschema.xml.in.h:21
|
||||||
msgid "If true, display seconds in time."
|
msgid "If true, display seconds in time."
|
||||||
msgstr "Je-li zapnuto, zobrazovat čas včetně sekund."
|
msgstr "Je-li zapnuto, zobrazovat čas včetně sekund."
|
||||||
|
|
||||||
#: ../data/org.gnome.shell.gschema.xml.in.h:20
|
#: ../data/org.gnome.shell.gschema.xml.in.h:22
|
||||||
msgid "Show date in clock"
|
msgid "Show date in clock"
|
||||||
msgstr "Zobrazovat v hodinách datum"
|
msgstr "Zobrazovat v hodinách datum"
|
||||||
|
|
||||||
#: ../data/org.gnome.shell.gschema.xml.in.h:21
|
#: ../data/org.gnome.shell.gschema.xml.in.h:23
|
||||||
msgid "If true, display date in the clock, in addition to time."
|
msgid "If true, display date in the clock, in addition to time."
|
||||||
msgstr "Je-li zapnuto, zobrazovat v hodinách kromě času i datum."
|
msgstr "Je-li zapnuto, zobrazovat v hodinách kromě času i datum."
|
||||||
|
|
||||||
#: ../data/org.gnome.shell.gschema.xml.in.h:22
|
#: ../data/org.gnome.shell.gschema.xml.in.h:24
|
||||||
msgid "Framerate used for recording screencasts."
|
msgid "Framerate used for recording screencasts."
|
||||||
msgstr "Frekvence snímků při nahrávání dění na obrazovce."
|
msgstr "Frekvence snímků při nahrávání dění na obrazovce."
|
||||||
|
|
||||||
#: ../data/org.gnome.shell.gschema.xml.in.h:23
|
#: ../data/org.gnome.shell.gschema.xml.in.h:25
|
||||||
msgid ""
|
msgid ""
|
||||||
"The framerate of the resulting screencast recordered by GNOME Shell's "
|
"The framerate of the resulting screencast recordered by GNOME Shell's "
|
||||||
"screencast recorder in frames-per-second."
|
"screencast recorder in frames-per-second."
|
||||||
@ -169,11 +176,11 @@ msgstr ""
|
|||||||
"Frekvence snímků za sekundu výsledné nahrávky dění na obrazovce, která byla "
|
"Frekvence snímků za sekundu výsledné nahrávky dění na obrazovce, která byla "
|
||||||
"nahrána záznamovým programem GNOME Shell."
|
"nahrána záznamovým programem GNOME Shell."
|
||||||
|
|
||||||
#: ../data/org.gnome.shell.gschema.xml.in.h:24
|
#: ../data/org.gnome.shell.gschema.xml.in.h:26
|
||||||
msgid "The gstreamer pipeline used to encode the screencast"
|
msgid "The gstreamer pipeline used to encode the screencast"
|
||||||
msgstr "Roura systému gstreamer určená ke kódování nahrávky dění na obrazovce"
|
msgstr "Roura systému gstreamer určená ke kódování nahrávky dění na obrazovce"
|
||||||
|
|
||||||
#: ../data/org.gnome.shell.gschema.xml.in.h:26
|
#: ../data/org.gnome.shell.gschema.xml.in.h:28
|
||||||
#, no-c-format
|
#, no-c-format
|
||||||
msgid ""
|
msgid ""
|
||||||
"Sets the GStreamer pipeline used to encode recordings. It follows the syntax "
|
"Sets the GStreamer pipeline used to encode recordings. It follows the syntax "
|
||||||
@ -197,11 +204,11 @@ msgstr ""
|
|||||||
"%T ! queue ! webmmux“ s nahráváním do WEBM s kodekem VP8. %T je použito jako "
|
"%T ! queue ! webmmux“ s nahráváním do WEBM s kodekem VP8. %T je použito jako "
|
||||||
"zástupný symbol odhadu nejvhodnějšího počtu vláken na systému."
|
"zástupný symbol odhadu nejvhodnějšího počtu vláken na systému."
|
||||||
|
|
||||||
#: ../data/org.gnome.shell.gschema.xml.in.h:27
|
#: ../data/org.gnome.shell.gschema.xml.in.h:29
|
||||||
msgid "File extension used for storing the screencast"
|
msgid "File extension used for storing the screencast"
|
||||||
msgstr "Přípona souboru s nahrávkou dění na obrazovce"
|
msgstr "Přípona souboru s nahrávkou dění na obrazovce"
|
||||||
|
|
||||||
#: ../data/org.gnome.shell.gschema.xml.in.h:28
|
#: ../data/org.gnome.shell.gschema.xml.in.h:30
|
||||||
msgid ""
|
msgid ""
|
||||||
"The filename for recorded screencasts will be a unique filename based on the "
|
"The filename for recorded screencasts will be a unique filename based on the "
|
||||||
"current date, and use this extension. It should be changed when recording to "
|
"current date, and use this extension. It should be changed when recording to "
|
||||||
@ -697,51 +704,51 @@ msgstr "Heslo:"
|
|||||||
msgid "Type again:"
|
msgid "Type again:"
|
||||||
msgstr "Napište znovu:"
|
msgstr "Napište znovu:"
|
||||||
|
|
||||||
#: ../js/ui/lookingGlass.js:725
|
#: ../js/ui/lookingGlass.js:732
|
||||||
msgid "No extensions installed"
|
msgid "No extensions installed"
|
||||||
msgstr "Nejsou nainstalována žádná rozšíření"
|
msgstr "Nejsou nainstalována žádná rozšíření"
|
||||||
|
|
||||||
#. Translators: argument is an extension UUID.
|
#. Translators: argument is an extension UUID.
|
||||||
#: ../js/ui/lookingGlass.js:779
|
#: ../js/ui/lookingGlass.js:786
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "%s has not emitted any errors."
|
msgid "%s has not emitted any errors."
|
||||||
msgstr "Rozšíření %s nevyvolalo žádné chyby."
|
msgstr "Rozšíření %s nevyvolalo žádné chyby."
|
||||||
|
|
||||||
#: ../js/ui/lookingGlass.js:785
|
#: ../js/ui/lookingGlass.js:792
|
||||||
msgid "Hide Errors"
|
msgid "Hide Errors"
|
||||||
msgstr "Skrývat chyby"
|
msgstr "Skrývat chyby"
|
||||||
|
|
||||||
#: ../js/ui/lookingGlass.js:789 ../js/ui/lookingGlass.js:840
|
#: ../js/ui/lookingGlass.js:796 ../js/ui/lookingGlass.js:847
|
||||||
msgid "Show Errors"
|
msgid "Show Errors"
|
||||||
msgstr "Zobrazovat chyby"
|
msgstr "Zobrazovat chyby"
|
||||||
|
|
||||||
#: ../js/ui/lookingGlass.js:798
|
#: ../js/ui/lookingGlass.js:805
|
||||||
msgid "Enabled"
|
msgid "Enabled"
|
||||||
msgstr "Povoleno"
|
msgstr "Povoleno"
|
||||||
|
|
||||||
#. translators:
|
#. translators:
|
||||||
#. * The device has been disabled
|
#. * The device has been disabled
|
||||||
#: ../js/ui/lookingGlass.js:801 ../src/gvc/gvc-mixer-control.c:1093
|
#: ../js/ui/lookingGlass.js:808 ../src/gvc/gvc-mixer-control.c:1093
|
||||||
msgid "Disabled"
|
msgid "Disabled"
|
||||||
msgstr "Zakázáno"
|
msgstr "Zakázáno"
|
||||||
|
|
||||||
#: ../js/ui/lookingGlass.js:803
|
#: ../js/ui/lookingGlass.js:810
|
||||||
msgid "Error"
|
msgid "Error"
|
||||||
msgstr "Chyba"
|
msgstr "Chyba"
|
||||||
|
|
||||||
#: ../js/ui/lookingGlass.js:805
|
#: ../js/ui/lookingGlass.js:812
|
||||||
msgid "Out of date"
|
msgid "Out of date"
|
||||||
msgstr "Neaktuální"
|
msgstr "Neaktuální"
|
||||||
|
|
||||||
#: ../js/ui/lookingGlass.js:807
|
#: ../js/ui/lookingGlass.js:814
|
||||||
msgid "Downloading"
|
msgid "Downloading"
|
||||||
msgstr "Stahování"
|
msgstr "Stahování"
|
||||||
|
|
||||||
#: ../js/ui/lookingGlass.js:828
|
#: ../js/ui/lookingGlass.js:835
|
||||||
msgid "View Source"
|
msgid "View Source"
|
||||||
msgstr "Zobrazit zdroj"
|
msgstr "Zobrazit zdroj"
|
||||||
|
|
||||||
#: ../js/ui/lookingGlass.js:834
|
#: ../js/ui/lookingGlass.js:841
|
||||||
msgid "Web Page"
|
msgid "Web Page"
|
||||||
msgstr "Webová stránka"
|
msgstr "Webová stránka"
|
||||||
|
|
||||||
@ -809,8 +816,8 @@ msgstr "K bezdrátové síti je vyžadováno ověření"
|
|||||||
#: ../js/ui/networkAgent.js:330
|
#: ../js/ui/networkAgent.js:330
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid ""
|
msgid ""
|
||||||
"Passwords or encryption keys are required to access the wireless network "
|
"Passwords or encryption keys are required to access the wireless network '%"
|
||||||
"'%s'."
|
"s'."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Pro přístup k bezdrátové síti „%s“ jsou vyžadována hesla nebo šifrovací "
|
"Pro přístup k bezdrátové síti „%s“ jsou vyžadována hesla nebo šifrovací "
|
||||||
"klíče."
|
"klíče."
|
||||||
@ -870,17 +877,17 @@ msgstr "Aplikace"
|
|||||||
msgid "Dash"
|
msgid "Dash"
|
||||||
msgstr "Oblíbené"
|
msgstr "Oblíbené"
|
||||||
|
|
||||||
#: ../js/ui/panel.js:591
|
#: ../js/ui/panel.js:592
|
||||||
msgid "Quit"
|
msgid "Quit"
|
||||||
msgstr "Ukončit"
|
msgstr "Ukončit"
|
||||||
|
|
||||||
#. Translators: If there is no suitable word for "Activities"
|
#. Translators: If there is no suitable word for "Activities"
|
||||||
#. in your language, you can use the word for "Overview".
|
#. in your language, you can use the word for "Overview".
|
||||||
#: ../js/ui/panel.js:623
|
#: ../js/ui/panel.js:624
|
||||||
msgid "Activities"
|
msgid "Activities"
|
||||||
msgstr "Činnosti"
|
msgstr "Činnosti"
|
||||||
|
|
||||||
#: ../js/ui/panel.js:998
|
#: ../js/ui/panel.js:999
|
||||||
msgid "Top Bar"
|
msgid "Top Bar"
|
||||||
msgstr "Horní lišta"
|
msgstr "Horní lišta"
|
||||||
|
|
||||||
@ -934,11 +941,11 @@ msgstr "toggle-switch-intl"
|
|||||||
msgid "Please enter a command:"
|
msgid "Please enter a command:"
|
||||||
msgstr "Zadejte prosím příkaz:"
|
msgstr "Zadejte prosím příkaz:"
|
||||||
|
|
||||||
#: ../js/ui/searchDisplay.js:331
|
#: ../js/ui/searchDisplay.js:332
|
||||||
msgid "Searching..."
|
msgid "Searching..."
|
||||||
msgstr "Hledá se…"
|
msgstr "Hledá se…"
|
||||||
|
|
||||||
#: ../js/ui/searchDisplay.js:413
|
#: ../js/ui/searchDisplay.js:414
|
||||||
msgid "No matching results."
|
msgid "No matching results."
|
||||||
msgstr "Neodpovídá ani jeden z výsledků."
|
msgstr "Neodpovídá ani jeden z výsledků."
|
||||||
|
|
||||||
|
116
po/de.po
116
po/de.po
@ -11,15 +11,16 @@
|
|||||||
# Jakob Kramer <jakob.kramer@gmx.de>, 2010.
|
# Jakob Kramer <jakob.kramer@gmx.de>, 2010.
|
||||||
# Paul Seyfert <pseyfert@mathphys.fsk.uni-heidelberg.de>, 2010, 2011.
|
# Paul Seyfert <pseyfert@mathphys.fsk.uni-heidelberg.de>, 2010, 2011.
|
||||||
# Christian Kirbach <Christian.Kirbach@googlemail.com>, 2009, 2010, 2011, 2012.
|
# Christian Kirbach <Christian.Kirbach@googlemail.com>, 2009, 2010, 2011, 2012.
|
||||||
|
# Wolfgang Stöggl <c72578@yahoo.de>, 2012.
|
||||||
#
|
#
|
||||||
msgid ""
|
msgid ""
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Project-Id-Version: gnome-shell master\n"
|
"Project-Id-Version: gnome-shell master\n"
|
||||||
"Report-Msgid-Bugs-To: http://bugzilla.gnome.org/enter_bug.cgi?product=gnome-"
|
"Report-Msgid-Bugs-To: http://bugzilla.gnome.org/enter_bug.cgi?product=gnome-"
|
||||||
"shell&keywords=I18N+L10N&component=general\n"
|
"shell&keywords=I18N+L10N&component=general\n"
|
||||||
"POT-Creation-Date: 2012-03-18 00:40+0000\n"
|
"POT-Creation-Date: 2012-04-13 19:40+0000\n"
|
||||||
"PO-Revision-Date: 2012-03-18 01:04+0100\n"
|
"PO-Revision-Date: 2012-04-14 16:04+0200\n"
|
||||||
"Last-Translator: Christian Kirbach <Christian.Kirbach@googlemail.com>\n"
|
"Last-Translator: Wolfgang Stoeggl <c72578@yahoo.de>\n"
|
||||||
"Language-Team: Deutsch <gnome-de@gnome.org>\n"
|
"Language-Team: Deutsch <gnome-de@gnome.org>\n"
|
||||||
"MIME-Version: 1.0\n"
|
"MIME-Version: 1.0\n"
|
||||||
"Content-Type: text/plain; charset=UTF-8\n"
|
"Content-Type: text/plain; charset=UTF-8\n"
|
||||||
@ -142,34 +143,42 @@ msgstr ""
|
|||||||
"Wenn dieser Wert gesetzt ist, wird der ISO-Wochentag im Kalender angezeigt."
|
"Wenn dieser Wert gesetzt ist, wird der ISO-Wochentag im Kalender angezeigt."
|
||||||
|
|
||||||
#: ../data/org.gnome.shell.gschema.xml.in.h:16
|
#: ../data/org.gnome.shell.gschema.xml.in.h:16
|
||||||
|
msgid "Keybinding to open the application menu"
|
||||||
|
msgstr "Tastenkombination zum Öffnen des Anwendungsmenüs"
|
||||||
|
|
||||||
|
#: ../data/org.gnome.shell.gschema.xml.in.h:17
|
||||||
|
msgid "Keybinding to open the application menu."
|
||||||
|
msgstr "Tastenkombination zum Öffnen des Anwendungsmenüs."
|
||||||
|
|
||||||
|
#: ../data/org.gnome.shell.gschema.xml.in.h:18
|
||||||
msgid "Which keyboard to use"
|
msgid "Which keyboard to use"
|
||||||
msgstr "Zu verwendende Tastatur"
|
msgstr "Zu verwendende Tastatur"
|
||||||
|
|
||||||
#: ../data/org.gnome.shell.gschema.xml.in.h:17
|
#: ../data/org.gnome.shell.gschema.xml.in.h:19
|
||||||
msgid "The type of keyboard to use."
|
msgid "The type of keyboard to use."
|
||||||
msgstr "Der Typ der zu verwendenden Tastatur"
|
msgstr "Der Typ der zu verwendenden Tastatur"
|
||||||
|
|
||||||
#: ../data/org.gnome.shell.gschema.xml.in.h:18
|
#: ../data/org.gnome.shell.gschema.xml.in.h:20
|
||||||
msgid "Show time with seconds"
|
msgid "Show time with seconds"
|
||||||
msgstr "Zeit sekundengenau anzeigen"
|
msgstr "Zeit sekundengenau anzeigen"
|
||||||
|
|
||||||
#: ../data/org.gnome.shell.gschema.xml.in.h:19
|
#: ../data/org.gnome.shell.gschema.xml.in.h:21
|
||||||
msgid "If true, display seconds in time."
|
msgid "If true, display seconds in time."
|
||||||
msgstr "Legt fest, ob in der Uhrzeit Sekunden angezeigt werden."
|
msgstr "Legt fest, ob in der Uhrzeit Sekunden angezeigt werden."
|
||||||
|
|
||||||
#: ../data/org.gnome.shell.gschema.xml.in.h:20
|
#: ../data/org.gnome.shell.gschema.xml.in.h:22
|
||||||
msgid "Show date in clock"
|
msgid "Show date in clock"
|
||||||
msgstr "Datum in der Uhr anzeigen"
|
msgstr "Datum in der Uhr anzeigen"
|
||||||
|
|
||||||
#: ../data/org.gnome.shell.gschema.xml.in.h:21
|
#: ../data/org.gnome.shell.gschema.xml.in.h:23
|
||||||
msgid "If true, display date in the clock, in addition to time."
|
msgid "If true, display date in the clock, in addition to time."
|
||||||
msgstr "Legt fest, ob das Datum zusätzlich zur Uhrzeit angezeigt wird."
|
msgstr "Legt fest, ob das Datum zusätzlich zur Uhrzeit angezeigt wird."
|
||||||
|
|
||||||
#: ../data/org.gnome.shell.gschema.xml.in.h:22
|
#: ../data/org.gnome.shell.gschema.xml.in.h:24
|
||||||
msgid "Framerate used for recording screencasts."
|
msgid "Framerate used for recording screencasts."
|
||||||
msgstr "Bildwiederholungsrate zur Aufnahme von Screencasts"
|
msgstr "Bildwiederholungsrate zur Aufnahme von Screencasts"
|
||||||
|
|
||||||
#: ../data/org.gnome.shell.gschema.xml.in.h:23
|
#: ../data/org.gnome.shell.gschema.xml.in.h:25
|
||||||
msgid ""
|
msgid ""
|
||||||
"The framerate of the resulting screencast recordered by GNOME Shell's "
|
"The framerate of the resulting screencast recordered by GNOME Shell's "
|
||||||
"screencast recorder in frames-per-second."
|
"screencast recorder in frames-per-second."
|
||||||
@ -178,12 +187,12 @@ msgstr ""
|
|||||||
"der GNOME-Shell aufgezeichnet werden soll, in Einzelbildern pro Sekunde."
|
"der GNOME-Shell aufgezeichnet werden soll, in Einzelbildern pro Sekunde."
|
||||||
|
|
||||||
# hmm Enkodieren oder Kodieren?
|
# hmm Enkodieren oder Kodieren?
|
||||||
#: ../data/org.gnome.shell.gschema.xml.in.h:24
|
#: ../data/org.gnome.shell.gschema.xml.in.h:26
|
||||||
msgid "The gstreamer pipeline used to encode the screencast"
|
msgid "The gstreamer pipeline used to encode the screencast"
|
||||||
msgstr "Die GStreamer-Weiterleitung zur Enkodierung des Screencasts"
|
msgstr "Die GStreamer-Weiterleitung zur Enkodierung des Screencasts"
|
||||||
|
|
||||||
# Hier blicke ich überhaupt nicht durch.
|
# Hier blicke ich überhaupt nicht durch.
|
||||||
#: ../data/org.gnome.shell.gschema.xml.in.h:26
|
#: ../data/org.gnome.shell.gschema.xml.in.h:28
|
||||||
#, no-c-format
|
#, no-c-format
|
||||||
msgid ""
|
msgid ""
|
||||||
"Sets the GStreamer pipeline used to encode recordings. It follows the syntax "
|
"Sets the GStreamer pipeline used to encode recordings. It follows the syntax "
|
||||||
@ -210,11 +219,11 @@ msgstr ""
|
|||||||
"mittels des VP8-Codecs aufzeichnet. %T wird als Platzhalter für die "
|
"mittels des VP8-Codecs aufzeichnet. %T wird als Platzhalter für die "
|
||||||
"vermutete optimale Thread-Anzahl auf dem System verwendet."
|
"vermutete optimale Thread-Anzahl auf dem System verwendet."
|
||||||
|
|
||||||
#: ../data/org.gnome.shell.gschema.xml.in.h:27
|
#: ../data/org.gnome.shell.gschema.xml.in.h:29
|
||||||
msgid "File extension used for storing the screencast"
|
msgid "File extension used for storing the screencast"
|
||||||
msgstr "Die Dateiendung zum Speichern des Screencast"
|
msgstr "Die Dateiendung zum Speichern des Screencast"
|
||||||
|
|
||||||
#: ../data/org.gnome.shell.gschema.xml.in.h:28
|
#: ../data/org.gnome.shell.gschema.xml.in.h:30
|
||||||
msgid ""
|
msgid ""
|
||||||
"The filename for recorded screencasts will be a unique filename based on the "
|
"The filename for recorded screencasts will be a unique filename based on the "
|
||||||
"current date, and use this extension. It should be changed when recording to "
|
"current date, and use this extension. It should be changed when recording to "
|
||||||
@ -238,53 +247,53 @@ msgstr "<b>Erweiterung</b>"
|
|||||||
msgid "Select an extension to configure using the combobox above."
|
msgid "Select an extension to configure using the combobox above."
|
||||||
msgstr "Wählen Sie oben eine Erweiterung aus, die Sie konfigurieren wollen."
|
msgstr "Wählen Sie oben eine Erweiterung aus, die Sie konfigurieren wollen."
|
||||||
|
|
||||||
#: ../js/gdm/loginDialog.js:624
|
#: ../js/gdm/loginDialog.js:627
|
||||||
msgid "Session..."
|
msgid "Session..."
|
||||||
msgstr "Sitzung …"
|
msgstr "Sitzung …"
|
||||||
|
|
||||||
#: ../js/gdm/loginDialog.js:786
|
#: ../js/gdm/loginDialog.js:789
|
||||||
msgctxt "title"
|
msgctxt "title"
|
||||||
msgid "Sign In"
|
msgid "Sign In"
|
||||||
msgstr "Anmelden"
|
msgstr "Anmelden"
|
||||||
|
|
||||||
#. Translators: this message is shown below the password entry field
|
#. Translators: this message is shown below the password entry field
|
||||||
#. to indicate the user can swipe their finger instead
|
#. to indicate the user can swipe their finger instead
|
||||||
#: ../js/gdm/loginDialog.js:831
|
#: ../js/gdm/loginDialog.js:834
|
||||||
msgid "(or swipe finger)"
|
msgid "(or swipe finger)"
|
||||||
msgstr "(oder benutzen Sie den Fingerabdruckleser)"
|
msgstr "(oder benutzen Sie den Fingerabdruckleser)"
|
||||||
|
|
||||||
#. translators: this message is shown below the user list on the
|
#. translators: this message is shown below the user list on the
|
||||||
#. login screen. It can be activated to reveal an entry for
|
#. login screen. It can be activated to reveal an entry for
|
||||||
#. manually entering the username.
|
#. manually entering the username.
|
||||||
#: ../js/gdm/loginDialog.js:852
|
#: ../js/gdm/loginDialog.js:855
|
||||||
msgid "Not listed?"
|
msgid "Not listed?"
|
||||||
msgstr "Nicht aufgeführt?"
|
msgstr "Nicht aufgeführt?"
|
||||||
|
|
||||||
#: ../js/gdm/loginDialog.js:1020 ../js/ui/endSessionDialog.js:401
|
#: ../js/gdm/loginDialog.js:1023 ../js/ui/endSessionDialog.js:401
|
||||||
#: ../js/ui/extensionSystem.js:399 ../js/ui/networkAgent.js:153
|
#: ../js/ui/extensionSystem.js:400 ../js/ui/networkAgent.js:153
|
||||||
#: ../js/ui/polkitAuthenticationAgent.js:175 ../js/ui/status/bluetooth.js:462
|
#: ../js/ui/polkitAuthenticationAgent.js:175 ../js/ui/status/bluetooth.js:462
|
||||||
msgid "Cancel"
|
msgid "Cancel"
|
||||||
msgstr "Abbrechen"
|
msgstr "Abbrechen"
|
||||||
|
|
||||||
#: ../js/gdm/loginDialog.js:1025
|
#: ../js/gdm/loginDialog.js:1028
|
||||||
msgctxt "button"
|
msgctxt "button"
|
||||||
msgid "Sign In"
|
msgid "Sign In"
|
||||||
msgstr "Anmelden"
|
msgstr "Anmelden"
|
||||||
|
|
||||||
#: ../js/gdm/loginDialog.js:1377
|
#: ../js/gdm/loginDialog.js:1380
|
||||||
msgid "Login Window"
|
msgid "Login Window"
|
||||||
msgstr "Anmeldefenster"
|
msgstr "Anmeldefenster"
|
||||||
|
|
||||||
#: ../js/gdm/powerMenu.js:152 ../js/ui/userMenu.js:597
|
#: ../js/gdm/powerMenu.js:155 ../js/ui/userMenu.js:597
|
||||||
#: ../js/ui/userMenu.js:599 ../js/ui/userMenu.js:668
|
#: ../js/ui/userMenu.js:599 ../js/ui/userMenu.js:668
|
||||||
msgid "Suspend"
|
msgid "Suspend"
|
||||||
msgstr "Bereitschaft"
|
msgstr "Bereitschaft"
|
||||||
|
|
||||||
#: ../js/gdm/powerMenu.js:157
|
#: ../js/gdm/powerMenu.js:160
|
||||||
msgid "Restart"
|
msgid "Restart"
|
||||||
msgstr "Neu starten"
|
msgstr "Neu starten"
|
||||||
|
|
||||||
#: ../js/gdm/powerMenu.js:162
|
#: ../js/gdm/powerMenu.js:165
|
||||||
msgid "Power Off"
|
msgid "Power Off"
|
||||||
msgstr "Ausschalten"
|
msgstr "Ausschalten"
|
||||||
|
|
||||||
@ -679,11 +688,11 @@ msgstr[1] "Das System wird automatisch in %d Sekunden neu gestartet."
|
|||||||
msgid "Restarting the system."
|
msgid "Restarting the system."
|
||||||
msgstr "Neustart des Systems."
|
msgstr "Neustart des Systems."
|
||||||
|
|
||||||
#: ../js/ui/extensionSystem.js:403
|
#: ../js/ui/extensionSystem.js:404
|
||||||
msgid "Install"
|
msgid "Install"
|
||||||
msgstr "Installieren"
|
msgstr "Installieren"
|
||||||
|
|
||||||
#: ../js/ui/extensionSystem.js:407
|
#: ../js/ui/extensionSystem.js:408
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "Download and install '%s' from extensions.gnome.org?"
|
msgid "Download and install '%s' from extensions.gnome.org?"
|
||||||
msgstr "»%s« von extensions.gnome.org herunterladen und installieren?"
|
msgstr "»%s« von extensions.gnome.org herunterladen und installieren?"
|
||||||
@ -692,7 +701,8 @@ msgstr "»%s« von extensions.gnome.org herunterladen und installieren?"
|
|||||||
msgid "tray"
|
msgid "tray"
|
||||||
msgstr "Benachrichtigungsfeld"
|
msgstr "Benachrichtigungsfeld"
|
||||||
|
|
||||||
#: ../js/ui/keyboard.js:544 ../js/ui/status/power.js:203
|
#: ../js/ui/keyboard.js:544 ../js/ui/status/keyboard.js:44
|
||||||
|
#: ../js/ui/status/power.js:203
|
||||||
msgid "Keyboard"
|
msgid "Keyboard"
|
||||||
msgstr "Tastatur"
|
msgstr "Tastatur"
|
||||||
|
|
||||||
@ -704,51 +714,51 @@ msgstr "Passwort:"
|
|||||||
msgid "Type again:"
|
msgid "Type again:"
|
||||||
msgstr "Erneut eingeben:"
|
msgstr "Erneut eingeben:"
|
||||||
|
|
||||||
#: ../js/ui/lookingGlass.js:725
|
#: ../js/ui/lookingGlass.js:732
|
||||||
msgid "No extensions installed"
|
msgid "No extensions installed"
|
||||||
msgstr "Keine Erweiterungen installiert"
|
msgstr "Keine Erweiterungen installiert"
|
||||||
|
|
||||||
#. Translators: argument is an extension UUID.
|
#. Translators: argument is an extension UUID.
|
||||||
#: ../js/ui/lookingGlass.js:779
|
#: ../js/ui/lookingGlass.js:786
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "%s has not emitted any errors."
|
msgid "%s has not emitted any errors."
|
||||||
msgstr "%s hat keine Fehler ausgegeben."
|
msgstr "%s hat keine Fehler ausgegeben."
|
||||||
|
|
||||||
#: ../js/ui/lookingGlass.js:785
|
#: ../js/ui/lookingGlass.js:792
|
||||||
msgid "Hide Errors"
|
msgid "Hide Errors"
|
||||||
msgstr "Fehler verbergen"
|
msgstr "Fehler verbergen"
|
||||||
|
|
||||||
#: ../js/ui/lookingGlass.js:789 ../js/ui/lookingGlass.js:840
|
#: ../js/ui/lookingGlass.js:796 ../js/ui/lookingGlass.js:847
|
||||||
msgid "Show Errors"
|
msgid "Show Errors"
|
||||||
msgstr "Fehler anzeigen"
|
msgstr "Fehler anzeigen"
|
||||||
|
|
||||||
#: ../js/ui/lookingGlass.js:798
|
#: ../js/ui/lookingGlass.js:805
|
||||||
msgid "Enabled"
|
msgid "Enabled"
|
||||||
msgstr "Aktiviert"
|
msgstr "Aktiviert"
|
||||||
|
|
||||||
#. translators:
|
#. translators:
|
||||||
#. * The device has been disabled
|
#. * The device has been disabled
|
||||||
#: ../js/ui/lookingGlass.js:801 ../src/gvc/gvc-mixer-control.c:1093
|
#: ../js/ui/lookingGlass.js:808 ../src/gvc/gvc-mixer-control.c:1082
|
||||||
msgid "Disabled"
|
msgid "Disabled"
|
||||||
msgstr "Deaktiviert"
|
msgstr "Deaktiviert"
|
||||||
|
|
||||||
#: ../js/ui/lookingGlass.js:803
|
#: ../js/ui/lookingGlass.js:810
|
||||||
msgid "Error"
|
msgid "Error"
|
||||||
msgstr "Fehler"
|
msgstr "Fehler"
|
||||||
|
|
||||||
#: ../js/ui/lookingGlass.js:805
|
#: ../js/ui/lookingGlass.js:812
|
||||||
msgid "Out of date"
|
msgid "Out of date"
|
||||||
msgstr "Veraltet"
|
msgstr "Veraltet"
|
||||||
|
|
||||||
#: ../js/ui/lookingGlass.js:807
|
#: ../js/ui/lookingGlass.js:814
|
||||||
msgid "Downloading"
|
msgid "Downloading"
|
||||||
msgstr "Herunterladen"
|
msgstr "Herunterladen"
|
||||||
|
|
||||||
#: ../js/ui/lookingGlass.js:828
|
#: ../js/ui/lookingGlass.js:835
|
||||||
msgid "View Source"
|
msgid "View Source"
|
||||||
msgstr "Quelle zeigen"
|
msgstr "Quelle zeigen"
|
||||||
|
|
||||||
#: ../js/ui/lookingGlass.js:834
|
#: ../js/ui/lookingGlass.js:841
|
||||||
msgid "Web Page"
|
msgid "Web Page"
|
||||||
msgstr "Webseite"
|
msgstr "Webseite"
|
||||||
|
|
||||||
@ -859,32 +869,36 @@ msgstr "Es wird ein Passwort benötigt, um sich mit »%s« zu verbinden."
|
|||||||
msgid "Undo"
|
msgid "Undo"
|
||||||
msgstr "Rückgängig"
|
msgstr "Rückgängig"
|
||||||
|
|
||||||
#: ../js/ui/overview.js:199
|
#: ../js/ui/overview.js:132
|
||||||
|
msgid "Overview"
|
||||||
|
msgstr "Übersicht"
|
||||||
|
|
||||||
|
#: ../js/ui/overview.js:202
|
||||||
msgid "Windows"
|
msgid "Windows"
|
||||||
msgstr "Fenster"
|
msgstr "Fenster"
|
||||||
|
|
||||||
#: ../js/ui/overview.js:202
|
#: ../js/ui/overview.js:205
|
||||||
msgid "Applications"
|
msgid "Applications"
|
||||||
msgstr "Anwendungen"
|
msgstr "Anwendungen"
|
||||||
|
|
||||||
# Würde ich so übernehmen, oder evtl. »Dock«.
|
# Würde ich so übernehmen, oder evtl. »Dock«.
|
||||||
#. Translators: this is the name of the dock/favorites area on
|
#. Translators: this is the name of the dock/favorites area on
|
||||||
#. the left of the overview
|
#. the left of the overview
|
||||||
#: ../js/ui/overview.js:228
|
#: ../js/ui/overview.js:231
|
||||||
msgid "Dash"
|
msgid "Dash"
|
||||||
msgstr "Dash"
|
msgstr "Dash"
|
||||||
|
|
||||||
#: ../js/ui/panel.js:591
|
#: ../js/ui/panel.js:592
|
||||||
msgid "Quit"
|
msgid "Quit"
|
||||||
msgstr "Beenden"
|
msgstr "Beenden"
|
||||||
|
|
||||||
#. Translators: If there is no suitable word for "Activities"
|
#. Translators: If there is no suitable word for "Activities"
|
||||||
#. in your language, you can use the word for "Overview".
|
#. in your language, you can use the word for "Overview".
|
||||||
#: ../js/ui/panel.js:623
|
#: ../js/ui/panel.js:624
|
||||||
msgid "Activities"
|
msgid "Activities"
|
||||||
msgstr "Aktivitäten"
|
msgstr "Aktivitäten"
|
||||||
|
|
||||||
#: ../js/ui/panel.js:998
|
#: ../js/ui/panel.js:999
|
||||||
msgid "Top Bar"
|
msgid "Top Bar"
|
||||||
msgstr "Obere Leiste"
|
msgstr "Obere Leiste"
|
||||||
|
|
||||||
@ -938,11 +952,11 @@ msgstr "toggle-switch-intl"
|
|||||||
msgid "Please enter a command:"
|
msgid "Please enter a command:"
|
||||||
msgstr "Bitte geben Sie einen Befehl ein:"
|
msgstr "Bitte geben Sie einen Befehl ein:"
|
||||||
|
|
||||||
#: ../js/ui/searchDisplay.js:331
|
#: ../js/ui/searchDisplay.js:332
|
||||||
msgid "Searching..."
|
msgid "Searching..."
|
||||||
msgstr "Suche läuft …"
|
msgstr "Suche läuft …"
|
||||||
|
|
||||||
#: ../js/ui/searchDisplay.js:413
|
#: ../js/ui/searchDisplay.js:415
|
||||||
msgid "No matching results."
|
msgid "No matching results."
|
||||||
msgstr "Keine passenden Ergebnisse."
|
msgstr "Keine passenden Ergebnisse."
|
||||||
|
|
||||||
@ -1193,7 +1207,7 @@ msgstr "Verbindung gescheitert"
|
|||||||
|
|
||||||
#: ../js/ui/status/network.js:585 ../js/ui/status/network.js:1505
|
#: ../js/ui/status/network.js:585 ../js/ui/status/network.js:1505
|
||||||
msgid "More..."
|
msgid "More..."
|
||||||
msgstr "Mehr ..."
|
msgstr "Mehr …"
|
||||||
|
|
||||||
#. TRANSLATORS: this is the indication that a connection for another logged in user is active,
|
#. TRANSLATORS: this is the indication that a connection for another logged in user is active,
|
||||||
#. and we cannot access its settings (including the name)
|
#. and we cannot access its settings (including the name)
|
||||||
@ -1720,7 +1734,7 @@ msgstr "»%s« ist bereit"
|
|||||||
|
|
||||||
#. translators:
|
#. translators:
|
||||||
#. * The number of sound outputs on a particular device
|
#. * The number of sound outputs on a particular device
|
||||||
#: ../src/gvc/gvc-mixer-control.c:1100
|
#: ../src/gvc/gvc-mixer-control.c:1089
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "%u Output"
|
msgid "%u Output"
|
||||||
msgid_plural "%u Outputs"
|
msgid_plural "%u Outputs"
|
||||||
@ -1729,14 +1743,14 @@ msgstr[1] "%u Ausgänge"
|
|||||||
|
|
||||||
#. translators:
|
#. translators:
|
||||||
#. * The number of sound inputs on a particular device
|
#. * The number of sound inputs on a particular device
|
||||||
#: ../src/gvc/gvc-mixer-control.c:1110
|
#: ../src/gvc/gvc-mixer-control.c:1099
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "%u Input"
|
msgid "%u Input"
|
||||||
msgid_plural "%u Inputs"
|
msgid_plural "%u Inputs"
|
||||||
msgstr[0] "%u Eingang"
|
msgstr[0] "%u Eingang"
|
||||||
msgstr[1] "%u Eingänge"
|
msgstr[1] "%u Eingänge"
|
||||||
|
|
||||||
#: ../src/gvc/gvc-mixer-control.c:1408
|
#: ../src/gvc/gvc-mixer-control.c:1397
|
||||||
msgid "System Sounds"
|
msgid "System Sounds"
|
||||||
msgstr "Systemklänge"
|
msgstr "Systemklänge"
|
||||||
|
|
||||||
|
193
po/en_GB.po
193
po/en_GB.po
@ -7,8 +7,8 @@ msgid ""
|
|||||||
msgstr ""
|
msgstr ""
|
||||||
"Project-Id-Version: gnome-shell master\n"
|
"Project-Id-Version: gnome-shell master\n"
|
||||||
"Report-Msgid-Bugs-To: \n"
|
"Report-Msgid-Bugs-To: \n"
|
||||||
"POT-Creation-Date: 2012-03-13 14:03+0000\n"
|
"POT-Creation-Date: 2012-04-13 13:20+0100\n"
|
||||||
"PO-Revision-Date: 2012-03-13 14:06+0100\n"
|
"PO-Revision-Date: 2012-04-13 13:20+0100\n"
|
||||||
"Last-Translator: Bruce Cowan <bruce@bcowan.me.uk>\n"
|
"Last-Translator: Bruce Cowan <bruce@bcowan.me.uk>\n"
|
||||||
"Language-Team: British English <en@li.org>\n"
|
"Language-Team: British English <en@li.org>\n"
|
||||||
"Language: en_GB\n"
|
"Language: en_GB\n"
|
||||||
@ -129,34 +129,42 @@ msgid "If true, display the ISO week date in the calendar."
|
|||||||
msgstr "If true, display the ISO week date in the calendar."
|
msgstr "If true, display the ISO week date in the calendar."
|
||||||
|
|
||||||
#: ../data/org.gnome.shell.gschema.xml.in.h:16
|
#: ../data/org.gnome.shell.gschema.xml.in.h:16
|
||||||
|
msgid "Keybinding to open the application menu"
|
||||||
|
msgstr "Keybinding to open the application menu"
|
||||||
|
|
||||||
|
#: ../data/org.gnome.shell.gschema.xml.in.h:17
|
||||||
|
msgid "Keybinding to open the application menu."
|
||||||
|
msgstr "Keybinding to open the application menu."
|
||||||
|
|
||||||
|
#: ../data/org.gnome.shell.gschema.xml.in.h:18
|
||||||
msgid "Which keyboard to use"
|
msgid "Which keyboard to use"
|
||||||
msgstr "Which keyboard to use"
|
msgstr "Which keyboard to use"
|
||||||
|
|
||||||
#: ../data/org.gnome.shell.gschema.xml.in.h:17
|
#: ../data/org.gnome.shell.gschema.xml.in.h:19
|
||||||
msgid "The type of keyboard to use."
|
msgid "The type of keyboard to use."
|
||||||
msgstr "The type of keyboard to use."
|
msgstr "The type of keyboard to use."
|
||||||
|
|
||||||
#: ../data/org.gnome.shell.gschema.xml.in.h:18
|
#: ../data/org.gnome.shell.gschema.xml.in.h:20
|
||||||
msgid "Show time with seconds"
|
msgid "Show time with seconds"
|
||||||
msgstr "Show time with seconds"
|
msgstr "Show time with seconds"
|
||||||
|
|
||||||
#: ../data/org.gnome.shell.gschema.xml.in.h:19
|
#: ../data/org.gnome.shell.gschema.xml.in.h:21
|
||||||
msgid "If true, display seconds in time."
|
msgid "If true, display seconds in time."
|
||||||
msgstr "If true, display seconds in time."
|
msgstr "If true, display seconds in time."
|
||||||
|
|
||||||
#: ../data/org.gnome.shell.gschema.xml.in.h:20
|
#: ../data/org.gnome.shell.gschema.xml.in.h:22
|
||||||
msgid "Show date in clock"
|
msgid "Show date in clock"
|
||||||
msgstr "Show date in clock"
|
msgstr "Show date in clock"
|
||||||
|
|
||||||
#: ../data/org.gnome.shell.gschema.xml.in.h:21
|
#: ../data/org.gnome.shell.gschema.xml.in.h:23
|
||||||
msgid "If true, display date in the clock, in addition to time."
|
msgid "If true, display date in the clock, in addition to time."
|
||||||
msgstr "If true, display date in the clock, in addition to time."
|
msgstr "If true, display date in the clock, in addition to time."
|
||||||
|
|
||||||
#: ../data/org.gnome.shell.gschema.xml.in.h:22
|
#: ../data/org.gnome.shell.gschema.xml.in.h:24
|
||||||
msgid "Framerate used for recording screencasts."
|
msgid "Framerate used for recording screencasts."
|
||||||
msgstr "Framerate used for recording screencasts."
|
msgstr "Framerate used for recording screencasts."
|
||||||
|
|
||||||
#: ../data/org.gnome.shell.gschema.xml.in.h:23
|
#: ../data/org.gnome.shell.gschema.xml.in.h:25
|
||||||
msgid ""
|
msgid ""
|
||||||
"The framerate of the resulting screencast recordered by GNOME Shell's "
|
"The framerate of the resulting screencast recordered by GNOME Shell's "
|
||||||
"screencast recorder in frames-per-second."
|
"screencast recorder in frames-per-second."
|
||||||
@ -164,11 +172,11 @@ msgstr ""
|
|||||||
"The framerate of the resulting screencast recordered by GNOME Shell's "
|
"The framerate of the resulting screencast recordered by GNOME Shell's "
|
||||||
"screencast recorder in frames per second."
|
"screencast recorder in frames per second."
|
||||||
|
|
||||||
#: ../data/org.gnome.shell.gschema.xml.in.h:24
|
#: ../data/org.gnome.shell.gschema.xml.in.h:26
|
||||||
msgid "The gstreamer pipeline used to encode the screencast"
|
msgid "The gstreamer pipeline used to encode the screencast"
|
||||||
msgstr "The GStreamer pipeline used to encode the screencast"
|
msgstr "The GStreamer pipeline used to encode the screencast"
|
||||||
|
|
||||||
#: ../data/org.gnome.shell.gschema.xml.in.h:26
|
#: ../data/org.gnome.shell.gschema.xml.in.h:28
|
||||||
#, no-c-format
|
#, no-c-format
|
||||||
msgid ""
|
msgid ""
|
||||||
"Sets the GStreamer pipeline used to encode recordings. It follows the syntax "
|
"Sets the GStreamer pipeline used to encode recordings. It follows the syntax "
|
||||||
@ -193,11 +201,11 @@ msgstr ""
|
|||||||
"using the VP8 codec. %T is used as a placeholder for a guess at the optimal "
|
"using the VP8 codec. %T is used as a placeholder for a guess at the optimal "
|
||||||
"thread count on the system."
|
"thread count on the system."
|
||||||
|
|
||||||
#: ../data/org.gnome.shell.gschema.xml.in.h:27
|
#: ../data/org.gnome.shell.gschema.xml.in.h:29
|
||||||
msgid "File extension used for storing the screencast"
|
msgid "File extension used for storing the screencast"
|
||||||
msgstr "File extension used for storing the screencast"
|
msgstr "File extension used for storing the screencast"
|
||||||
|
|
||||||
#: ../data/org.gnome.shell.gschema.xml.in.h:28
|
#: ../data/org.gnome.shell.gschema.xml.in.h:30
|
||||||
msgid ""
|
msgid ""
|
||||||
"The filename for recorded screencasts will be a unique filename based on the "
|
"The filename for recorded screencasts will be a unique filename based on the "
|
||||||
"current date, and use this extension. It should be changed when recording to "
|
"current date, and use this extension. It should be changed when recording to "
|
||||||
@ -220,53 +228,53 @@ msgstr "<b>Extension</b>"
|
|||||||
msgid "Select an extension to configure using the combobox above."
|
msgid "Select an extension to configure using the combobox above."
|
||||||
msgstr "Select an extension to configure using the combobox above."
|
msgstr "Select an extension to configure using the combobox above."
|
||||||
|
|
||||||
#: ../js/gdm/loginDialog.js:624
|
#: ../js/gdm/loginDialog.js:627
|
||||||
msgid "Session..."
|
msgid "Session..."
|
||||||
msgstr "Session…"
|
msgstr "Session…"
|
||||||
|
|
||||||
#: ../js/gdm/loginDialog.js:786
|
#: ../js/gdm/loginDialog.js:789
|
||||||
msgctxt "title"
|
msgctxt "title"
|
||||||
msgid "Sign In"
|
msgid "Sign In"
|
||||||
msgstr "Sign In"
|
msgstr "Sign In"
|
||||||
|
|
||||||
#. Translators: this message is shown below the password entry field
|
#. Translators: this message is shown below the password entry field
|
||||||
#. to indicate the user can swipe their finger instead
|
#. to indicate the user can swipe their finger instead
|
||||||
#: ../js/gdm/loginDialog.js:831
|
#: ../js/gdm/loginDialog.js:834
|
||||||
msgid "(or swipe finger)"
|
msgid "(or swipe finger)"
|
||||||
msgstr "(or swipe finger)"
|
msgstr "(or swipe finger)"
|
||||||
|
|
||||||
#. translators: this message is shown below the user list on the
|
#. translators: this message is shown below the user list on the
|
||||||
#. login screen. It can be activated to reveal an entry for
|
#. login screen. It can be activated to reveal an entry for
|
||||||
#. manually entering the username.
|
#. manually entering the username.
|
||||||
#: ../js/gdm/loginDialog.js:852
|
#: ../js/gdm/loginDialog.js:855
|
||||||
msgid "Not listed?"
|
msgid "Not listed?"
|
||||||
msgstr "Not listed?"
|
msgstr "Not listed?"
|
||||||
|
|
||||||
#: ../js/gdm/loginDialog.js:1020 ../js/ui/endSessionDialog.js:419
|
#: ../js/gdm/loginDialog.js:1023 ../js/ui/endSessionDialog.js:401
|
||||||
#: ../js/ui/extensionSystem.js:399 ../js/ui/networkAgent.js:153
|
#: ../js/ui/extensionSystem.js:400 ../js/ui/networkAgent.js:153
|
||||||
#: ../js/ui/polkitAuthenticationAgent.js:175 ../js/ui/status/bluetooth.js:462
|
#: ../js/ui/polkitAuthenticationAgent.js:175 ../js/ui/status/bluetooth.js:462
|
||||||
msgid "Cancel"
|
msgid "Cancel"
|
||||||
msgstr "Cancel"
|
msgstr "Cancel"
|
||||||
|
|
||||||
#: ../js/gdm/loginDialog.js:1025
|
#: ../js/gdm/loginDialog.js:1028
|
||||||
msgctxt "button"
|
msgctxt "button"
|
||||||
msgid "Sign In"
|
msgid "Sign In"
|
||||||
msgstr "Sign In"
|
msgstr "Sign In"
|
||||||
|
|
||||||
#: ../js/gdm/loginDialog.js:1377
|
#: ../js/gdm/loginDialog.js:1380
|
||||||
msgid "Login Window"
|
msgid "Login Window"
|
||||||
msgstr "Login Window"
|
msgstr "Login Window"
|
||||||
|
|
||||||
#: ../js/gdm/powerMenu.js:152 ../js/ui/userMenu.js:591
|
#: ../js/gdm/powerMenu.js:155 ../js/ui/userMenu.js:597
|
||||||
#: ../js/ui/userMenu.js:593 ../js/ui/userMenu.js:662
|
#: ../js/ui/userMenu.js:599 ../js/ui/userMenu.js:668
|
||||||
msgid "Suspend"
|
msgid "Suspend"
|
||||||
msgstr "Suspend"
|
msgstr "Suspend"
|
||||||
|
|
||||||
#: ../js/gdm/powerMenu.js:157
|
#: ../js/gdm/powerMenu.js:160
|
||||||
msgid "Restart"
|
msgid "Restart"
|
||||||
msgstr "Restart"
|
msgstr "Restart"
|
||||||
|
|
||||||
#: ../js/gdm/powerMenu.js:162
|
#: ../js/gdm/powerMenu.js:165
|
||||||
msgid "Power Off"
|
msgid "Power Off"
|
||||||
msgstr "Power Off"
|
msgstr "Power Off"
|
||||||
|
|
||||||
@ -286,27 +294,27 @@ msgid "Execution of '%s' failed:"
|
|||||||
msgstr "Execution of '%s' failed:"
|
msgstr "Execution of '%s' failed:"
|
||||||
|
|
||||||
#. Translators: Filter to display all applications
|
#. Translators: Filter to display all applications
|
||||||
#: ../js/ui/appDisplay.js:251
|
#: ../js/ui/appDisplay.js:255
|
||||||
msgid "All"
|
msgid "All"
|
||||||
msgstr "All"
|
msgstr "All"
|
||||||
|
|
||||||
#: ../js/ui/appDisplay.js:310
|
#: ../js/ui/appDisplay.js:314
|
||||||
msgid "APPLICATIONS"
|
msgid "APPLICATIONS"
|
||||||
msgstr "APPLICATIONS"
|
msgstr "APPLICATIONS"
|
||||||
|
|
||||||
#: ../js/ui/appDisplay.js:371
|
#: ../js/ui/appDisplay.js:375
|
||||||
msgid "SETTINGS"
|
msgid "SETTINGS"
|
||||||
msgstr "SETTINGS"
|
msgstr "SETTINGS"
|
||||||
|
|
||||||
#: ../js/ui/appDisplay.js:676
|
#: ../js/ui/appDisplay.js:680
|
||||||
msgid "New Window"
|
msgid "New Window"
|
||||||
msgstr "New Window"
|
msgstr "New Window"
|
||||||
|
|
||||||
#: ../js/ui/appDisplay.js:679
|
#: ../js/ui/appDisplay.js:683
|
||||||
msgid "Remove from Favorites"
|
msgid "Remove from Favorites"
|
||||||
msgstr "Remove from Favourites"
|
msgstr "Remove from Favourites"
|
||||||
|
|
||||||
#: ../js/ui/appDisplay.js:680
|
#: ../js/ui/appDisplay.js:684
|
||||||
msgid "Add to Favorites"
|
msgid "Add to Favorites"
|
||||||
msgstr "Add to Favourites"
|
msgstr "Add to Favourites"
|
||||||
|
|
||||||
@ -479,28 +487,28 @@ msgstr "This week"
|
|||||||
msgid "Next week"
|
msgid "Next week"
|
||||||
msgstr "Next week"
|
msgstr "Next week"
|
||||||
|
|
||||||
#: ../js/ui/contactDisplay.js:64 ../js/ui/notificationDaemon.js:486
|
#: ../js/ui/contactDisplay.js:66 ../js/ui/notificationDaemon.js:486
|
||||||
#: ../js/ui/status/power.js:215 ../src/shell-app.c:372
|
#: ../js/ui/status/power.js:215 ../src/shell-app.c:374
|
||||||
msgid "Unknown"
|
msgid "Unknown"
|
||||||
msgstr "Unknown"
|
msgstr "Unknown"
|
||||||
|
|
||||||
#: ../js/ui/contactDisplay.js:85 ../js/ui/userMenu.js:127
|
#: ../js/ui/contactDisplay.js:89 ../js/ui/userMenu.js:129
|
||||||
msgid "Available"
|
msgid "Available"
|
||||||
msgstr "Available"
|
msgstr "Available"
|
||||||
|
|
||||||
#: ../js/ui/contactDisplay.js:90 ../js/ui/userMenu.js:136
|
#: ../js/ui/contactDisplay.js:94 ../js/ui/userMenu.js:138
|
||||||
msgid "Away"
|
msgid "Away"
|
||||||
msgstr "Away"
|
msgstr "Away"
|
||||||
|
|
||||||
#: ../js/ui/contactDisplay.js:94 ../js/ui/userMenu.js:130
|
#: ../js/ui/contactDisplay.js:98 ../js/ui/userMenu.js:132
|
||||||
msgid "Busy"
|
msgid "Busy"
|
||||||
msgstr "Busy"
|
msgstr "Busy"
|
||||||
|
|
||||||
#: ../js/ui/contactDisplay.js:98
|
#: ../js/ui/contactDisplay.js:102
|
||||||
msgid "Offline"
|
msgid "Offline"
|
||||||
msgstr "Offline"
|
msgstr "Offline"
|
||||||
|
|
||||||
#: ../js/ui/contactDisplay.js:149
|
#: ../js/ui/contactDisplay.js:153
|
||||||
msgid "CONTACTS"
|
msgid "CONTACTS"
|
||||||
msgstr "CONTACTS"
|
msgstr "CONTACTS"
|
||||||
|
|
||||||
@ -508,58 +516,58 @@ msgstr "CONTACTS"
|
|||||||
msgid "Remove"
|
msgid "Remove"
|
||||||
msgstr "Remove"
|
msgstr "Remove"
|
||||||
|
|
||||||
#: ../js/ui/dateMenu.js:97
|
#: ../js/ui/dateMenu.js:103
|
||||||
msgid "Date and Time Settings"
|
msgid "Date and Time Settings"
|
||||||
msgstr "Date and Time Settings"
|
msgstr "Date and Time Settings"
|
||||||
|
|
||||||
#: ../js/ui/dateMenu.js:123
|
#: ../js/ui/dateMenu.js:129
|
||||||
msgid "Open Calendar"
|
msgid "Open Calendar"
|
||||||
msgstr "Open Calendar"
|
msgstr "Open Calendar"
|
||||||
|
|
||||||
#. Translators: This is the time format with date used
|
#. Translators: This is the time format with date used
|
||||||
#. in 24-hour mode.
|
#. in 24-hour mode.
|
||||||
#: ../js/ui/dateMenu.js:181
|
#: ../js/ui/dateMenu.js:187
|
||||||
msgid "%a %b %e, %R:%S"
|
msgid "%a %b %e, %R:%S"
|
||||||
msgstr "%a %e %b, %R:%S"
|
msgstr "%a %e %b, %R:%S"
|
||||||
|
|
||||||
#: ../js/ui/dateMenu.js:182
|
#: ../js/ui/dateMenu.js:188
|
||||||
msgid "%a %b %e, %R"
|
msgid "%a %b %e, %R"
|
||||||
msgstr "%a %e %b, %R"
|
msgstr "%a %e %b, %R"
|
||||||
|
|
||||||
#. Translators: This is the time format without date used
|
#. Translators: This is the time format without date used
|
||||||
#. in 24-hour mode.
|
#. in 24-hour mode.
|
||||||
#: ../js/ui/dateMenu.js:186
|
#: ../js/ui/dateMenu.js:192
|
||||||
msgid "%a %R:%S"
|
msgid "%a %R:%S"
|
||||||
msgstr "%a %R:%S"
|
msgstr "%a %R:%S"
|
||||||
|
|
||||||
#: ../js/ui/dateMenu.js:187
|
#: ../js/ui/dateMenu.js:193
|
||||||
msgid "%a %R"
|
msgid "%a %R"
|
||||||
msgstr "%a %R"
|
msgstr "%a %R"
|
||||||
|
|
||||||
#. Translators: This is a time format with date used
|
#. Translators: This is a time format with date used
|
||||||
#. for AM/PM.
|
#. for AM/PM.
|
||||||
#: ../js/ui/dateMenu.js:194
|
#: ../js/ui/dateMenu.js:200
|
||||||
msgid "%a %b %e, %l:%M:%S %p"
|
msgid "%a %b %e, %l:%M:%S %p"
|
||||||
msgstr "%a %e %b, %l:%M:%S %p"
|
msgstr "%a %e %b, %l:%M:%S %p"
|
||||||
|
|
||||||
#: ../js/ui/dateMenu.js:195
|
#: ../js/ui/dateMenu.js:201
|
||||||
msgid "%a %b %e, %l:%M %p"
|
msgid "%a %b %e, %l:%M %p"
|
||||||
msgstr "%a %e %b, %l:%M %p"
|
msgstr "%a %e %b, %l:%M %p"
|
||||||
|
|
||||||
#. Translators: This is a time format without date used
|
#. Translators: This is a time format without date used
|
||||||
#. for AM/PM.
|
#. for AM/PM.
|
||||||
#: ../js/ui/dateMenu.js:199
|
#: ../js/ui/dateMenu.js:205
|
||||||
msgid "%a %l:%M:%S %p"
|
msgid "%a %l:%M:%S %p"
|
||||||
msgstr "%a %l:%M:%S %p"
|
msgstr "%a %l:%M:%S %p"
|
||||||
|
|
||||||
#: ../js/ui/dateMenu.js:200
|
#: ../js/ui/dateMenu.js:206
|
||||||
msgid "%a %l:%M %p"
|
msgid "%a %l:%M %p"
|
||||||
msgstr "%a %l:%M %p"
|
msgstr "%a %l:%M %p"
|
||||||
|
|
||||||
#. Translators: This is the date format to use when the calendar popup is
|
#. Translators: This is the date format to use when the calendar popup is
|
||||||
#. * shown - it is shown just below the time in the shell (e.g. "Tue 9:29 AM").
|
#. * shown - it is shown just below the time in the shell (e.g. "Tue 9:29 AM").
|
||||||
#.
|
#.
|
||||||
#: ../js/ui/dateMenu.js:211
|
#: ../js/ui/dateMenu.js:217
|
||||||
msgid "%A %B %e, %Y"
|
msgid "%A %B %e, %Y"
|
||||||
msgstr "%A %e %B, %Y"
|
msgstr "%A %e %B, %Y"
|
||||||
|
|
||||||
@ -651,20 +659,21 @@ msgstr[1] "The system will restart automatically in %d seconds."
|
|||||||
msgid "Restarting the system."
|
msgid "Restarting the system."
|
||||||
msgstr "Restarting the system."
|
msgstr "Restarting the system."
|
||||||
|
|
||||||
#: ../js/ui/extensionSystem.js:403
|
#: ../js/ui/extensionSystem.js:404
|
||||||
msgid "Install"
|
msgid "Install"
|
||||||
msgstr "Install"
|
msgstr "Install"
|
||||||
|
|
||||||
#: ../js/ui/extensionSystem.js:407
|
#: ../js/ui/extensionSystem.js:408
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "Download and install '%s' from extensions.gnome.org?"
|
msgid "Download and install '%s' from extensions.gnome.org?"
|
||||||
msgstr "Download and install '%s' from extensions.gnome.org?"
|
msgstr "Download and install '%s' from extensions.gnome.org?"
|
||||||
|
|
||||||
#: ../js/ui/keyboard.js:322
|
#: ../js/ui/keyboard.js:327
|
||||||
msgid "tray"
|
msgid "tray"
|
||||||
msgstr "tray"
|
msgstr "tray"
|
||||||
|
|
||||||
#: ../js/ui/keyboard.js:539 ../js/ui/status/power.js:203
|
#: ../js/ui/keyboard.js:544 ../js/ui/status/keyboard.js:44
|
||||||
|
#: ../js/ui/status/power.js:203
|
||||||
msgid "Keyboard"
|
msgid "Keyboard"
|
||||||
msgstr "Keyboard"
|
msgstr "Keyboard"
|
||||||
|
|
||||||
@ -676,51 +685,51 @@ msgstr "Password:"
|
|||||||
msgid "Type again:"
|
msgid "Type again:"
|
||||||
msgstr "Type again:"
|
msgstr "Type again:"
|
||||||
|
|
||||||
#: ../js/ui/lookingGlass.js:725
|
#: ../js/ui/lookingGlass.js:732
|
||||||
msgid "No extensions installed"
|
msgid "No extensions installed"
|
||||||
msgstr "No extensions installed"
|
msgstr "No extensions installed"
|
||||||
|
|
||||||
#. Translators: argument is an extension UUID.
|
#. Translators: argument is an extension UUID.
|
||||||
#: ../js/ui/lookingGlass.js:779
|
#: ../js/ui/lookingGlass.js:786
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "%s has not emitted any errors."
|
msgid "%s has not emitted any errors."
|
||||||
msgstr "%s has not emitted any errors."
|
msgstr "%s has not emitted any errors."
|
||||||
|
|
||||||
#: ../js/ui/lookingGlass.js:785
|
#: ../js/ui/lookingGlass.js:792
|
||||||
msgid "Hide Errors"
|
msgid "Hide Errors"
|
||||||
msgstr "Hide Errors"
|
msgstr "Hide Errors"
|
||||||
|
|
||||||
#: ../js/ui/lookingGlass.js:789 ../js/ui/lookingGlass.js:840
|
#: ../js/ui/lookingGlass.js:796 ../js/ui/lookingGlass.js:847
|
||||||
msgid "Show Errors"
|
msgid "Show Errors"
|
||||||
msgstr "Show Errors"
|
msgstr "Show Errors"
|
||||||
|
|
||||||
#: ../js/ui/lookingGlass.js:798
|
#: ../js/ui/lookingGlass.js:805
|
||||||
msgid "Enabled"
|
msgid "Enabled"
|
||||||
msgstr "Enabled"
|
msgstr "Enabled"
|
||||||
|
|
||||||
#. translators:
|
#. translators:
|
||||||
#. * The device has been disabled
|
#. * The device has been disabled
|
||||||
#: ../js/ui/lookingGlass.js:801 ../src/gvc/gvc-mixer-control.c:1093
|
#: ../js/ui/lookingGlass.js:808 ../src/gvc/gvc-mixer-control.c:1082
|
||||||
msgid "Disabled"
|
msgid "Disabled"
|
||||||
msgstr "Disabled"
|
msgstr "Disabled"
|
||||||
|
|
||||||
#: ../js/ui/lookingGlass.js:803
|
#: ../js/ui/lookingGlass.js:810
|
||||||
msgid "Error"
|
msgid "Error"
|
||||||
msgstr "Error"
|
msgstr "Error"
|
||||||
|
|
||||||
#: ../js/ui/lookingGlass.js:805
|
#: ../js/ui/lookingGlass.js:812
|
||||||
msgid "Out of date"
|
msgid "Out of date"
|
||||||
msgstr "Out of date"
|
msgstr "Out of date"
|
||||||
|
|
||||||
#: ../js/ui/lookingGlass.js:807
|
#: ../js/ui/lookingGlass.js:814
|
||||||
msgid "Downloading"
|
msgid "Downloading"
|
||||||
msgstr "Downloading"
|
msgstr "Downloading"
|
||||||
|
|
||||||
#: ../js/ui/lookingGlass.js:828
|
#: ../js/ui/lookingGlass.js:835
|
||||||
msgid "View Source"
|
msgid "View Source"
|
||||||
msgstr "View Source"
|
msgstr "View Source"
|
||||||
|
|
||||||
#: ../js/ui/lookingGlass.js:834
|
#: ../js/ui/lookingGlass.js:841
|
||||||
msgid "Web Page"
|
msgid "Web Page"
|
||||||
msgstr "Web Page"
|
msgstr "Web Page"
|
||||||
|
|
||||||
@ -742,7 +751,7 @@ msgstr "Unmute"
|
|||||||
msgid "Mute"
|
msgid "Mute"
|
||||||
msgstr "Mute"
|
msgstr "Mute"
|
||||||
|
|
||||||
#: ../js/ui/messageTray.js:2450
|
#: ../js/ui/messageTray.js:2490
|
||||||
msgid "System Information"
|
msgid "System Information"
|
||||||
msgstr "System Information"
|
msgstr "System Information"
|
||||||
|
|
||||||
@ -831,31 +840,35 @@ msgstr "A password is required to connect to '%s'."
|
|||||||
msgid "Undo"
|
msgid "Undo"
|
||||||
msgstr "Undo"
|
msgstr "Undo"
|
||||||
|
|
||||||
#: ../js/ui/overview.js:199
|
#: ../js/ui/overview.js:132
|
||||||
|
msgid "Overview"
|
||||||
|
msgstr "Overview"
|
||||||
|
|
||||||
|
#: ../js/ui/overview.js:202
|
||||||
msgid "Windows"
|
msgid "Windows"
|
||||||
msgstr "Windows"
|
msgstr "Windows"
|
||||||
|
|
||||||
#: ../js/ui/overview.js:202
|
#: ../js/ui/overview.js:205
|
||||||
msgid "Applications"
|
msgid "Applications"
|
||||||
msgstr "Applications"
|
msgstr "Applications"
|
||||||
|
|
||||||
#. Translators: this is the name of the dock/favorites area on
|
#. Translators: this is the name of the dock/favorites area on
|
||||||
#. the left of the overview
|
#. the left of the overview
|
||||||
#: ../js/ui/overview.js:228
|
#: ../js/ui/overview.js:231
|
||||||
msgid "Dash"
|
msgid "Dash"
|
||||||
msgstr "Dash"
|
msgstr "Dash"
|
||||||
|
|
||||||
#: ../js/ui/panel.js:583
|
#: ../js/ui/panel.js:592
|
||||||
msgid "Quit"
|
msgid "Quit"
|
||||||
msgstr "Quit"
|
msgstr "Quit"
|
||||||
|
|
||||||
#. Translators: If there is no suitable word for "Activities"
|
#. Translators: If there is no suitable word for "Activities"
|
||||||
#. in your language, you can use the word for "Overview".
|
#. in your language, you can use the word for "Overview".
|
||||||
#: ../js/ui/panel.js:614
|
#: ../js/ui/panel.js:624
|
||||||
msgid "Activities"
|
msgid "Activities"
|
||||||
msgstr "Activities"
|
msgstr "Activities"
|
||||||
|
|
||||||
#: ../js/ui/panel.js:987
|
#: ../js/ui/panel.js:999
|
||||||
msgid "Top Bar"
|
msgid "Top Bar"
|
||||||
msgstr "Top Bar"
|
msgstr "Top Bar"
|
||||||
|
|
||||||
@ -901,7 +914,7 @@ msgstr "Sorry, that didn't work. Please try again."
|
|||||||
#. "ON" and "OFF") or "toggle-switch-intl" (for toggle
|
#. "ON" and "OFF") or "toggle-switch-intl" (for toggle
|
||||||
#. switches containing "◯" and "|"). Other values will
|
#. switches containing "◯" and "|"). Other values will
|
||||||
#. simply result in invisible toggle switches.
|
#. simply result in invisible toggle switches.
|
||||||
#: ../js/ui/popupMenu.js:720
|
#: ../js/ui/popupMenu.js:724
|
||||||
msgid "toggle-switch-us"
|
msgid "toggle-switch-us"
|
||||||
msgstr "toggle-switch-us"
|
msgstr "toggle-switch-us"
|
||||||
|
|
||||||
@ -909,11 +922,11 @@ msgstr "toggle-switch-us"
|
|||||||
msgid "Please enter a command:"
|
msgid "Please enter a command:"
|
||||||
msgstr "Please enter a command:"
|
msgstr "Please enter a command:"
|
||||||
|
|
||||||
#: ../js/ui/searchDisplay.js:331
|
#: ../js/ui/searchDisplay.js:332
|
||||||
msgid "Searching..."
|
msgid "Searching..."
|
||||||
msgstr "Searching…"
|
msgstr "Searching…"
|
||||||
|
|
||||||
#: ../js/ui/searchDisplay.js:413
|
#: ../js/ui/searchDisplay.js:415
|
||||||
msgid "No matching results."
|
msgid "No matching results."
|
||||||
msgstr "No matching results."
|
msgstr "No matching results."
|
||||||
|
|
||||||
@ -1595,51 +1608,51 @@ msgstr "Edit account"
|
|||||||
msgid "Unknown reason"
|
msgid "Unknown reason"
|
||||||
msgstr "Unknown reason"
|
msgstr "Unknown reason"
|
||||||
|
|
||||||
#: ../js/ui/userMenu.js:133
|
#: ../js/ui/userMenu.js:135
|
||||||
msgid "Hidden"
|
msgid "Hidden"
|
||||||
msgstr "Hidden"
|
msgstr "Hidden"
|
||||||
|
|
||||||
#: ../js/ui/userMenu.js:139
|
#: ../js/ui/userMenu.js:141
|
||||||
msgid "Idle"
|
msgid "Idle"
|
||||||
msgstr "Idle"
|
msgstr "Idle"
|
||||||
|
|
||||||
#: ../js/ui/userMenu.js:142
|
#: ../js/ui/userMenu.js:144
|
||||||
msgid "Unavailable"
|
msgid "Unavailable"
|
||||||
msgstr "Unavailable"
|
msgstr "Unavailable"
|
||||||
|
|
||||||
#: ../js/ui/userMenu.js:589 ../js/ui/userMenu.js:593 ../js/ui/userMenu.js:663
|
#: ../js/ui/userMenu.js:595 ../js/ui/userMenu.js:599 ../js/ui/userMenu.js:669
|
||||||
msgid "Power Off..."
|
msgid "Power Off..."
|
||||||
msgstr "Power Off…"
|
msgstr "Power Off…"
|
||||||
|
|
||||||
#: ../js/ui/userMenu.js:625
|
#: ../js/ui/userMenu.js:631
|
||||||
msgid "Notifications"
|
msgid "Notifications"
|
||||||
msgstr "Notifications"
|
msgstr "Notifications"
|
||||||
|
|
||||||
#: ../js/ui/userMenu.js:633
|
#: ../js/ui/userMenu.js:639
|
||||||
msgid "Online Accounts"
|
msgid "Online Accounts"
|
||||||
msgstr "Online Accounts"
|
msgstr "Online Accounts"
|
||||||
|
|
||||||
#: ../js/ui/userMenu.js:637
|
#: ../js/ui/userMenu.js:643
|
||||||
msgid "System Settings"
|
msgid "System Settings"
|
||||||
msgstr "System Settings"
|
msgstr "System Settings"
|
||||||
|
|
||||||
#: ../js/ui/userMenu.js:644
|
#: ../js/ui/userMenu.js:650
|
||||||
msgid "Lock Screen"
|
msgid "Lock Screen"
|
||||||
msgstr "Lock Screen"
|
msgstr "Lock Screen"
|
||||||
|
|
||||||
#: ../js/ui/userMenu.js:649
|
#: ../js/ui/userMenu.js:655
|
||||||
msgid "Switch User"
|
msgid "Switch User"
|
||||||
msgstr "Switch User"
|
msgstr "Switch User"
|
||||||
|
|
||||||
#: ../js/ui/userMenu.js:654
|
#: ../js/ui/userMenu.js:660
|
||||||
msgid "Log Out..."
|
msgid "Log Out..."
|
||||||
msgstr "Log Out…"
|
msgstr "Log Out…"
|
||||||
|
|
||||||
#: ../js/ui/userMenu.js:682
|
#: ../js/ui/userMenu.js:688
|
||||||
msgid "Your chat status will be set to busy"
|
msgid "Your chat status will be set to busy"
|
||||||
msgstr "Your chat status will be set to busy"
|
msgstr "Your chat status will be set to busy"
|
||||||
|
|
||||||
#: ../js/ui/userMenu.js:683
|
#: ../js/ui/userMenu.js:689
|
||||||
msgid ""
|
msgid ""
|
||||||
"Notifications are now disabled, including chat messages. Your online status "
|
"Notifications are now disabled, including chat messages. Your online status "
|
||||||
"has been adjusted to let others know that you might not see their messages."
|
"has been adjusted to let others know that you might not see their messages."
|
||||||
@ -1684,7 +1697,7 @@ msgstr "'%s' is ready"
|
|||||||
|
|
||||||
#. translators:
|
#. translators:
|
||||||
#. * The number of sound outputs on a particular device
|
#. * The number of sound outputs on a particular device
|
||||||
#: ../src/gvc/gvc-mixer-control.c:1100
|
#: ../src/gvc/gvc-mixer-control.c:1089
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "%u Output"
|
msgid "%u Output"
|
||||||
msgid_plural "%u Outputs"
|
msgid_plural "%u Outputs"
|
||||||
@ -1693,14 +1706,14 @@ msgstr[1] "%u Outputs"
|
|||||||
|
|
||||||
#. translators:
|
#. translators:
|
||||||
#. * The number of sound inputs on a particular device
|
#. * The number of sound inputs on a particular device
|
||||||
#: ../src/gvc/gvc-mixer-control.c:1110
|
#: ../src/gvc/gvc-mixer-control.c:1099
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "%u Input"
|
msgid "%u Input"
|
||||||
msgid_plural "%u Inputs"
|
msgid_plural "%u Inputs"
|
||||||
msgstr[0] "%u Input"
|
msgstr[0] "%u Input"
|
||||||
msgstr[1] "%u Inputs"
|
msgstr[1] "%u Inputs"
|
||||||
|
|
||||||
#: ../src/gvc/gvc-mixer-control.c:1408
|
#: ../src/gvc/gvc-mixer-control.c:1397
|
||||||
msgid "System Sounds"
|
msgid "System Sounds"
|
||||||
msgstr "System Sounds"
|
msgstr "System Sounds"
|
||||||
|
|
||||||
@ -1712,7 +1725,7 @@ msgstr "Print version"
|
|||||||
msgid "Mode used by GDM for login screen"
|
msgid "Mode used by GDM for login screen"
|
||||||
msgstr "Mode used by GDM for login screen"
|
msgstr "Mode used by GDM for login screen"
|
||||||
|
|
||||||
#: ../src/shell-app.c:617
|
#: ../src/shell-app.c:619
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "Failed to launch '%s'"
|
msgid "Failed to launch '%s'"
|
||||||
msgstr "Failed to launch '%s'"
|
msgstr "Failed to launch '%s'"
|
||||||
|
221
po/fa.po
221
po/fa.po
@ -8,8 +8,8 @@ msgid ""
|
|||||||
msgstr ""
|
msgstr ""
|
||||||
"Project-Id-Version: gnome-shell master\n"
|
"Project-Id-Version: gnome-shell master\n"
|
||||||
"Report-Msgid-Bugs-To: http://bugzilla.gnome.org/enter_bug.cgi?product=gnome-shell&keywords=I18N+L10N&component=general\n"
|
"Report-Msgid-Bugs-To: http://bugzilla.gnome.org/enter_bug.cgi?product=gnome-shell&keywords=I18N+L10N&component=general\n"
|
||||||
"POT-Creation-Date: 2012-02-29 22:27+0000\n"
|
"POT-Creation-Date: 2012-03-30 17:59+0000\n"
|
||||||
"PO-Revision-Date: 2012-03-04 20:00+0330\n"
|
"PO-Revision-Date: 2012-03-31 01:45+0330\n"
|
||||||
"Last-Translator: Arash Mousavi <mousavi.arash@gmail.com>\n"
|
"Last-Translator: Arash Mousavi <mousavi.arash@gmail.com>\n"
|
||||||
"Language-Team: Persian\n"
|
"Language-Team: Persian\n"
|
||||||
"MIME-Version: 1.0\n"
|
"MIME-Version: 1.0\n"
|
||||||
@ -99,63 +99,59 @@ msgid "If true, display the ISO week date in the calendar."
|
|||||||
msgstr "در صورت تنظیم بر روی «درست»، تاریخ هفتگی ایزو را در تقویم نشان میدهد."
|
msgstr "در صورت تنظیم بر روی «درست»، تاریخ هفتگی ایزو را در تقویم نشان میدهد."
|
||||||
|
|
||||||
#: ../data/org.gnome.shell.gschema.xml.in.h:16
|
#: ../data/org.gnome.shell.gschema.xml.in.h:16
|
||||||
|
msgid "Keybinding to open the application menu"
|
||||||
|
msgstr "کلید مقید برای باز کردن منو برنامه"
|
||||||
|
|
||||||
|
#: ../data/org.gnome.shell.gschema.xml.in.h:17
|
||||||
|
msgid "Keybinding to open the application menu."
|
||||||
|
msgstr "کلید مقید برای باز کردن منو برنامه."
|
||||||
|
|
||||||
|
#: ../data/org.gnome.shell.gschema.xml.in.h:18
|
||||||
msgid "Which keyboard to use"
|
msgid "Which keyboard to use"
|
||||||
msgstr "استفاده از کدام صفحهکلید"
|
msgstr "استفاده از کدام صفحهکلید"
|
||||||
|
|
||||||
#: ../data/org.gnome.shell.gschema.xml.in.h:17
|
#: ../data/org.gnome.shell.gschema.xml.in.h:19
|
||||||
msgid "The type of keyboard to use."
|
msgid "The type of keyboard to use."
|
||||||
msgstr "نوع صفحهکلید جهت استفاده"
|
msgstr "نوع صفحهکلید جهت استفاده"
|
||||||
|
|
||||||
#: ../data/org.gnome.shell.gschema.xml.in.h:18
|
#: ../data/org.gnome.shell.gschema.xml.in.h:20
|
||||||
msgid "Show time with seconds"
|
msgid "Show time with seconds"
|
||||||
msgstr "نمایش ساعت همراه با ثانیه"
|
msgstr "نمایش ساعت همراه با ثانیه"
|
||||||
|
|
||||||
#: ../data/org.gnome.shell.gschema.xml.in.h:19
|
#: ../data/org.gnome.shell.gschema.xml.in.h:21
|
||||||
msgid "If true, display seconds in time."
|
msgid "If true, display seconds in time."
|
||||||
msgstr "در صورت تنظیم بر روی «درست»، ثانیهها را در ساعت نشان میدهد."
|
msgstr "در صورت تنظیم بر روی «درست»، ثانیهها را در ساعت نشان میدهد."
|
||||||
|
|
||||||
#: ../data/org.gnome.shell.gschema.xml.in.h:20
|
#: ../data/org.gnome.shell.gschema.xml.in.h:22
|
||||||
msgid "Show date in clock"
|
msgid "Show date in clock"
|
||||||
msgstr "نمایش تاریخ در ساعت"
|
msgstr "نمایش تاریخ در ساعت"
|
||||||
|
|
||||||
#: ../data/org.gnome.shell.gschema.xml.in.h:21
|
#: ../data/org.gnome.shell.gschema.xml.in.h:23
|
||||||
msgid "If true, display date in the clock, in addition to time."
|
msgid "If true, display date in the clock, in addition to time."
|
||||||
msgstr "اگر روی «درست» تنظیم شود، تاریخ را در کنار ساعت نشان میدهد."
|
msgstr "اگر روی «درست» تنظیم شود، تاریخ را در کنار ساعت نشان میدهد."
|
||||||
|
|
||||||
#: ../data/org.gnome.shell.gschema.xml.in.h:22
|
#: ../data/org.gnome.shell.gschema.xml.in.h:24
|
||||||
msgid "Framerate used for recording screencasts."
|
msgid "Framerate used for recording screencasts."
|
||||||
msgstr "سرعت فریم استفاده شده در تصویربرداری از صفحهنمایش."
|
msgstr "سرعت فریم استفاده شده در تصویربرداری از صفحهنمایش."
|
||||||
|
|
||||||
#: ../data/org.gnome.shell.gschema.xml.in.h:23
|
#: ../data/org.gnome.shell.gschema.xml.in.h:25
|
||||||
msgid "The framerate of the resulting screencast recordered by GNOME Shell's screencast recorder in frames-per-second."
|
msgid "The framerate of the resulting screencast recordered by GNOME Shell's screencast recorder in frames-per-second."
|
||||||
msgstr "سرعت فریم حاصل از تصویربرداری از صفحه نمایش با استفاده از ضبط کننده نمایشگر پوستهی گنوم بر اساس فریم بر ثانیه"
|
msgstr "سرعت فریم حاصل از تصویربرداری از صفحه نمایش با استفاده از ضبط کننده نمایشگر پوستهی گنوم بر اساس فریم بر ثانیه"
|
||||||
|
|
||||||
#: ../data/org.gnome.shell.gschema.xml.in.h:24
|
#: ../data/org.gnome.shell.gschema.xml.in.h:26
|
||||||
msgid "The gstreamer pipeline used to encode the screencast"
|
msgid "The gstreamer pipeline used to encode the screencast"
|
||||||
msgstr "مجرای ارتباطی gstreamer برای کدگذاری تصویربرداری از صفحه نمایش"
|
msgstr "مجرای ارتباطی gstreamer برای کدگذاری تصویربرداری از صفحه نمایش"
|
||||||
|
|
||||||
#: ../data/org.gnome.shell.gschema.xml.in.h:26
|
#: ../data/org.gnome.shell.gschema.xml.in.h:28
|
||||||
#, no-c-format
|
#, no-c-format
|
||||||
#| msgid ""
|
|
||||||
#| "Sets the GStreamer pipeline used to encode recordings. It follows the "
|
|
||||||
#| "syntax used for gst-launch. The pipeline should have an unconnected sink "
|
|
||||||
#| "pad where the recorded video is recorded. It will normally have a "
|
|
||||||
#| "unconnected source pad; output from that pad will be written into the "
|
|
||||||
#| "output file. However the pipeline can also take care of its own output - "
|
|
||||||
#| "this might be used to send the output to an icecast server via shout2send "
|
|
||||||
#| "or similar. When unset or set to an empty value, the default pipeline "
|
|
||||||
#| "will be used. This is currently 'videorate ! vp8enc quality=10 speed=2 "
|
|
||||||
#| "threads=%T ! queue ! webmmux' and records to WEBM using the VP8 codec. %T "
|
|
||||||
#| "is used as a placeholder for a guess at the optimal thread count on the "
|
|
||||||
#| "system."
|
|
||||||
msgid "Sets the GStreamer pipeline used to encode recordings. It follows the syntax used for gst-launch. The pipeline should have an unconnected sink pad where the recorded video is recorded. It will normally have a unconnected source pad; output from that pad will be written into the output file. However the pipeline can also take care of its own output - this might be used to send the output to an icecast server via shout2send or similar. When unset or set to an empty value, the default pipeline will be used. This is currently 'vp8enc quality=8 speed=6 threads=%T ! queue ! webmmux' and records to WEBM using the VP8 codec. %T is used as a placeholder for a guess at the optimal thread count on the system."
|
msgid "Sets the GStreamer pipeline used to encode recordings. It follows the syntax used for gst-launch. The pipeline should have an unconnected sink pad where the recorded video is recorded. It will normally have a unconnected source pad; output from that pad will be written into the output file. However the pipeline can also take care of its own output - this might be used to send the output to an icecast server via shout2send or similar. When unset or set to an empty value, the default pipeline will be used. This is currently 'vp8enc quality=8 speed=6 threads=%T ! queue ! webmmux' and records to WEBM using the VP8 codec. %T is used as a placeholder for a guess at the optimal thread count on the system."
|
||||||
msgstr "Sets the GStreamer pipeline used to encode recordings. It follows the syntax used for gst-launch. The pipeline should have an unconnected sink pad where the recorded video is recorded. It will normally have a unconnected source pad; output from that pad will be written into the output file. However the pipeline can also take care of its own output - this might be used to send the output to an icecast server via shout2send or similar. When unset or set to an empty value, the default pipeline will be used. This is currently 'vp8enc quality=8 speed=6 threads=%T ! queue ! webmmux' and records to WEBM using the VP8 codec. %T is used as a placeholder for a guess at the optimal thread count on the system."
|
msgstr "Sets the GStreamer pipeline used to encode recordings. It follows the syntax used for gst-launch. The pipeline should have an unconnected sink pad where the recorded video is recorded. It will normally have a unconnected source pad; output from that pad will be written into the output file. However the pipeline can also take care of its own output - this might be used to send the output to an icecast server via shout2send or similar. When unset or set to an empty value, the default pipeline will be used. This is currently 'vp8enc quality=8 speed=6 threads=%T ! queue ! webmmux' and records to WEBM using the VP8 codec. %T is used as a placeholder for a guess at the optimal thread count on the system."
|
||||||
|
|
||||||
#: ../data/org.gnome.shell.gschema.xml.in.h:27
|
#: ../data/org.gnome.shell.gschema.xml.in.h:29
|
||||||
msgid "File extension used for storing the screencast"
|
msgid "File extension used for storing the screencast"
|
||||||
msgstr "پسوند پروندهی قابل استفاده برای ذخیره تصویربرداری از صفحهنمایش"
|
msgstr "پسوند پروندهی قابل استفاده برای ذخیره تصویربرداری از صفحهنمایش"
|
||||||
|
|
||||||
#: ../data/org.gnome.shell.gschema.xml.in.h:28
|
#: ../data/org.gnome.shell.gschema.xml.in.h:30
|
||||||
msgid "The filename for recorded screencasts will be a unique filename based on the current date, and use this extension. It should be changed when recording to a different container format."
|
msgid "The filename for recorded screencasts will be a unique filename based on the current date, and use this extension. It should be changed when recording to a different container format."
|
||||||
msgstr "نام پروندهی ضبط شده برای تصویربرداری از صفحهنمایش یکتا و براساس تاریخ جاری خواهد بود و از این افزونه استفاده خواهد کرد. اگر در زمان ضبط از قالب دیگری استفاده کنید باید تغییر کند."
|
msgstr "نام پروندهی ضبط شده برای تصویربرداری از صفحهنمایش یکتا و براساس تاریخ جاری خواهد بود و از این افزونه استفاده خواهد کرد. اگر در زمان ضبط از قالب دیگری استفاده کنید باید تغییر کند."
|
||||||
|
|
||||||
@ -195,8 +191,8 @@ msgid "Not listed?"
|
|||||||
msgstr "فهرست نشده؟"
|
msgstr "فهرست نشده؟"
|
||||||
|
|
||||||
#: ../js/gdm/loginDialog.js:1020
|
#: ../js/gdm/loginDialog.js:1020
|
||||||
#: ../js/ui/endSessionDialog.js:419
|
#: ../js/ui/endSessionDialog.js:401
|
||||||
#: ../js/ui/extensionSystem.js:401
|
#: ../js/ui/extensionSystem.js:399
|
||||||
#: ../js/ui/networkAgent.js:153
|
#: ../js/ui/networkAgent.js:153
|
||||||
#: ../js/ui/polkitAuthenticationAgent.js:175
|
#: ../js/ui/polkitAuthenticationAgent.js:175
|
||||||
#: ../js/ui/status/bluetooth.js:462
|
#: ../js/ui/status/bluetooth.js:462
|
||||||
@ -212,18 +208,18 @@ msgstr "ورود"
|
|||||||
msgid "Login Window"
|
msgid "Login Window"
|
||||||
msgstr "پنجرهی ورود به سیستم"
|
msgstr "پنجرهی ورود به سیستم"
|
||||||
|
|
||||||
#: ../js/gdm/powerMenu.js:152
|
#: ../js/gdm/powerMenu.js:155
|
||||||
#: ../js/ui/userMenu.js:581
|
#: ../js/ui/userMenu.js:597
|
||||||
#: ../js/ui/userMenu.js:583
|
#: ../js/ui/userMenu.js:599
|
||||||
#: ../js/ui/userMenu.js:652
|
#: ../js/ui/userMenu.js:668
|
||||||
msgid "Suspend"
|
msgid "Suspend"
|
||||||
msgstr "تعلیق"
|
msgstr "تعلیق"
|
||||||
|
|
||||||
#: ../js/gdm/powerMenu.js:157
|
#: ../js/gdm/powerMenu.js:160
|
||||||
msgid "Restart"
|
msgid "Restart"
|
||||||
msgstr "راهاندازی مجدد"
|
msgstr "راهاندازی مجدد"
|
||||||
|
|
||||||
#: ../js/gdm/powerMenu.js:162
|
#: ../js/gdm/powerMenu.js:165
|
||||||
msgid "Power Off"
|
msgid "Power Off"
|
||||||
msgstr "خاموش کردن"
|
msgstr "خاموش کردن"
|
||||||
|
|
||||||
@ -243,27 +239,27 @@ msgid "Execution of '%s' failed:"
|
|||||||
msgstr "اجرای «%s» شکست خورد:"
|
msgstr "اجرای «%s» شکست خورد:"
|
||||||
|
|
||||||
#. Translators: Filter to display all applications
|
#. Translators: Filter to display all applications
|
||||||
#: ../js/ui/appDisplay.js:251
|
#: ../js/ui/appDisplay.js:255
|
||||||
msgid "All"
|
msgid "All"
|
||||||
msgstr "همه"
|
msgstr "همه"
|
||||||
|
|
||||||
#: ../js/ui/appDisplay.js:310
|
#: ../js/ui/appDisplay.js:314
|
||||||
msgid "APPLICATIONS"
|
msgid "APPLICATIONS"
|
||||||
msgstr "برنامهها"
|
msgstr "برنامهها"
|
||||||
|
|
||||||
#: ../js/ui/appDisplay.js:371
|
#: ../js/ui/appDisplay.js:375
|
||||||
msgid "SETTINGS"
|
msgid "SETTINGS"
|
||||||
msgstr "تنظیمات"
|
msgstr "تنظیمات"
|
||||||
|
|
||||||
#: ../js/ui/appDisplay.js:676
|
#: ../js/ui/appDisplay.js:680
|
||||||
msgid "New Window"
|
msgid "New Window"
|
||||||
msgstr "پنجرهی جدید"
|
msgstr "پنجرهی جدید"
|
||||||
|
|
||||||
#: ../js/ui/appDisplay.js:679
|
#: ../js/ui/appDisplay.js:683
|
||||||
msgid "Remove from Favorites"
|
msgid "Remove from Favorites"
|
||||||
msgstr "حذف از مورد پسندها"
|
msgstr "حذف از مورد پسندها"
|
||||||
|
|
||||||
#: ../js/ui/appDisplay.js:680
|
#: ../js/ui/appDisplay.js:684
|
||||||
msgid "Add to Favorites"
|
msgid "Add to Favorites"
|
||||||
msgstr "اضافه کردن به مورد پسندها"
|
msgstr "اضافه کردن به مورد پسندها"
|
||||||
|
|
||||||
@ -436,93 +432,93 @@ msgstr "این هفته"
|
|||||||
msgid "Next week"
|
msgid "Next week"
|
||||||
msgstr "هفته آینده"
|
msgstr "هفته آینده"
|
||||||
|
|
||||||
#: ../js/ui/contactDisplay.js:63
|
#: ../js/ui/contactDisplay.js:66
|
||||||
#: ../js/ui/notificationDaemon.js:486
|
#: ../js/ui/notificationDaemon.js:486
|
||||||
#: ../js/ui/status/power.js:215
|
#: ../js/ui/status/power.js:215
|
||||||
#: ../src/shell-app.c:372
|
#: ../src/shell-app.c:374
|
||||||
msgid "Unknown"
|
msgid "Unknown"
|
||||||
msgstr "ناشناخته"
|
msgstr "ناشناخته"
|
||||||
|
|
||||||
#: ../js/ui/contactDisplay.js:84
|
#: ../js/ui/contactDisplay.js:89
|
||||||
#: ../js/ui/userMenu.js:127
|
#: ../js/ui/userMenu.js:129
|
||||||
msgid "Available"
|
msgid "Available"
|
||||||
msgstr "در دسترس"
|
msgstr "در دسترس"
|
||||||
|
|
||||||
#: ../js/ui/contactDisplay.js:89
|
#: ../js/ui/contactDisplay.js:94
|
||||||
#: ../js/ui/userMenu.js:136
|
#: ../js/ui/userMenu.js:138
|
||||||
msgid "Away"
|
msgid "Away"
|
||||||
msgstr "غائب"
|
msgstr "غائب"
|
||||||
|
|
||||||
#: ../js/ui/contactDisplay.js:93
|
#: ../js/ui/contactDisplay.js:98
|
||||||
#: ../js/ui/userMenu.js:130
|
#: ../js/ui/userMenu.js:132
|
||||||
msgid "Busy"
|
msgid "Busy"
|
||||||
msgstr "مشغول"
|
msgstr "مشغول"
|
||||||
|
|
||||||
#: ../js/ui/contactDisplay.js:97
|
#: ../js/ui/contactDisplay.js:102
|
||||||
msgid "Offline"
|
msgid "Offline"
|
||||||
msgstr "برونخط"
|
msgstr "برونخط"
|
||||||
|
|
||||||
#: ../js/ui/contactDisplay.js:148
|
#: ../js/ui/contactDisplay.js:153
|
||||||
msgid "CONTACTS"
|
msgid "CONTACTS"
|
||||||
msgstr "CONTACTS"
|
msgstr "CONTACTS"
|
||||||
|
|
||||||
#: ../js/ui/dash.js:229
|
#: ../js/ui/dash.js:229
|
||||||
#: ../js/ui/messageTray.js:1204
|
#: ../js/ui/messageTray.js:1207
|
||||||
msgid "Remove"
|
msgid "Remove"
|
||||||
msgstr "حذف"
|
msgstr "حذف"
|
||||||
|
|
||||||
#: ../js/ui/dateMenu.js:97
|
#: ../js/ui/dateMenu.js:103
|
||||||
msgid "Date and Time Settings"
|
msgid "Date and Time Settings"
|
||||||
msgstr "تنظیمات تاریخ و ساعت"
|
msgstr "تنظیمات تاریخ و ساعت"
|
||||||
|
|
||||||
#: ../js/ui/dateMenu.js:123
|
#: ../js/ui/dateMenu.js:129
|
||||||
msgid "Open Calendar"
|
msgid "Open Calendar"
|
||||||
msgstr "بازکردن تقویم"
|
msgstr "بازکردن تقویم"
|
||||||
|
|
||||||
#. Translators: This is the time format with date used
|
#. Translators: This is the time format with date used
|
||||||
#. in 24-hour mode.
|
#. in 24-hour mode.
|
||||||
#: ../js/ui/dateMenu.js:181
|
#: ../js/ui/dateMenu.js:187
|
||||||
msgid "%a %b %e, %R:%S"
|
msgid "%a %b %e, %R:%S"
|
||||||
msgstr "%a %Od %b %OH:%OM:%OS"
|
msgstr "%a %Od %b %OH:%OM:%OS"
|
||||||
|
|
||||||
#: ../js/ui/dateMenu.js:182
|
#: ../js/ui/dateMenu.js:188
|
||||||
msgid "%a %b %e, %R"
|
msgid "%a %b %e, %R"
|
||||||
msgstr "%a %Od %b %OH:%OM"
|
msgstr "%a %Od %b %OH:%OM"
|
||||||
|
|
||||||
#. Translators: This is the time format without date used
|
#. Translators: This is the time format without date used
|
||||||
#. in 24-hour mode.
|
#. in 24-hour mode.
|
||||||
#: ../js/ui/dateMenu.js:186
|
#: ../js/ui/dateMenu.js:192
|
||||||
msgid "%a %R:%S"
|
msgid "%a %R:%S"
|
||||||
msgstr "%a %OH:%OM:%OS"
|
msgstr "%a %OH:%OM:%OS"
|
||||||
|
|
||||||
#: ../js/ui/dateMenu.js:187
|
#: ../js/ui/dateMenu.js:193
|
||||||
msgid "%a %R"
|
msgid "%a %R"
|
||||||
msgstr "%a %OH:%OM"
|
msgstr "%a %OH:%OM"
|
||||||
|
|
||||||
#. Translators: This is a time format with date used
|
#. Translators: This is a time format with date used
|
||||||
#. for AM/PM.
|
#. for AM/PM.
|
||||||
#: ../js/ui/dateMenu.js:194
|
#: ../js/ui/dateMenu.js:200
|
||||||
msgid "%a %b %e, %l:%M:%S %p"
|
msgid "%a %b %e, %l:%M:%S %p"
|
||||||
msgstr "%a Od% %b %OH:%OM:%OS"
|
msgstr "%a Od% %b %OH:%OM:%OS"
|
||||||
|
|
||||||
#: ../js/ui/dateMenu.js:195
|
#: ../js/ui/dateMenu.js:201
|
||||||
msgid "%a %b %e, %l:%M %p"
|
msgid "%a %b %e, %l:%M %p"
|
||||||
msgstr "%a %Od %b %OH:%OM"
|
msgstr "%a %Od %b %OH:%OM"
|
||||||
|
|
||||||
#. Translators: This is a time format without date used
|
#. Translators: This is a time format without date used
|
||||||
#. for AM/PM.
|
#. for AM/PM.
|
||||||
#: ../js/ui/dateMenu.js:199
|
#: ../js/ui/dateMenu.js:205
|
||||||
msgid "%a %l:%M:%S %p"
|
msgid "%a %l:%M:%S %p"
|
||||||
msgstr "%a %OH:%OM:%OS"
|
msgstr "%a %OH:%OM:%OS"
|
||||||
|
|
||||||
#: ../js/ui/dateMenu.js:200
|
#: ../js/ui/dateMenu.js:206
|
||||||
msgid "%a %l:%M %p"
|
msgid "%a %l:%M %p"
|
||||||
msgstr "%a %OH:%OM"
|
msgstr "%a %OH:%OM"
|
||||||
|
|
||||||
#. Translators: This is the date format to use when the calendar popup is
|
#. Translators: This is the date format to use when the calendar popup is
|
||||||
#. * shown - it is shown just below the time in the shell (e.g. "Tue 9:29 AM").
|
#. * shown - it is shown just below the time in the shell (e.g. "Tue 9:29 AM").
|
||||||
#.
|
#.
|
||||||
#: ../js/ui/dateMenu.js:211
|
#: ../js/ui/dateMenu.js:217
|
||||||
msgid "%A %B %e, %Y"
|
msgid "%A %B %e, %Y"
|
||||||
msgstr "%A %Od %B"
|
msgstr "%A %Od %B"
|
||||||
|
|
||||||
@ -615,20 +611,20 @@ msgstr[1] "سیستم پس از %Id ثانیه به طور خودکار مجدد
|
|||||||
msgid "Restarting the system."
|
msgid "Restarting the system."
|
||||||
msgstr "درحال راهاندازی مجدد سیستم."
|
msgstr "درحال راهاندازی مجدد سیستم."
|
||||||
|
|
||||||
#: ../js/ui/extensionSystem.js:405
|
#: ../js/ui/extensionSystem.js:403
|
||||||
msgid "Install"
|
msgid "Install"
|
||||||
msgstr "نصب"
|
msgstr "نصب"
|
||||||
|
|
||||||
#: ../js/ui/extensionSystem.js:409
|
#: ../js/ui/extensionSystem.js:407
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "Download and install '%s' from extensions.gnome.org?"
|
msgid "Download and install '%s' from extensions.gnome.org?"
|
||||||
msgstr "بارگیری و نصب «%s» از extensions.gnome.org؟"
|
msgstr "بارگیری و نصب «%s» از extensions.gnome.org؟"
|
||||||
|
|
||||||
#: ../js/ui/keyboard.js:322
|
#: ../js/ui/keyboard.js:327
|
||||||
msgid "tray"
|
msgid "tray"
|
||||||
msgstr "سینی"
|
msgstr "سینی"
|
||||||
|
|
||||||
#: ../js/ui/keyboard.js:539
|
#: ../js/ui/keyboard.js:544
|
||||||
#: ../js/ui/status/power.js:203
|
#: ../js/ui/status/power.js:203
|
||||||
msgid "Keyboard"
|
msgid "Keyboard"
|
||||||
msgstr "صفحهکلید"
|
msgstr "صفحهکلید"
|
||||||
@ -642,75 +638,75 @@ msgstr "گذرواژه"
|
|||||||
msgid "Type again:"
|
msgid "Type again:"
|
||||||
msgstr "تلاش مجدد:"
|
msgstr "تلاش مجدد:"
|
||||||
|
|
||||||
#: ../js/ui/lookingGlass.js:725
|
#: ../js/ui/lookingGlass.js:732
|
||||||
msgid "No extensions installed"
|
msgid "No extensions installed"
|
||||||
msgstr "هیچ افزونهای نصب نشده است"
|
msgstr "هیچ افزونهای نصب نشده است"
|
||||||
|
|
||||||
#. Translators: argument is an extension UUID.
|
#. Translators: argument is an extension UUID.
|
||||||
#: ../js/ui/lookingGlass.js:779
|
#: ../js/ui/lookingGlass.js:786
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "%s has not emitted any errors."
|
msgid "%s has not emitted any errors."
|
||||||
msgstr "افزونه %s هیچ خطایی منتشر نکرده است."
|
msgstr "افزونه %s هیچ خطایی منتشر نکرده است."
|
||||||
|
|
||||||
#: ../js/ui/lookingGlass.js:785
|
#: ../js/ui/lookingGlass.js:792
|
||||||
msgid "Hide Errors"
|
msgid "Hide Errors"
|
||||||
msgstr "مخفی کردن خطاها"
|
msgstr "مخفی کردن خطاها"
|
||||||
|
|
||||||
#: ../js/ui/lookingGlass.js:789
|
#: ../js/ui/lookingGlass.js:796
|
||||||
#: ../js/ui/lookingGlass.js:840
|
#: ../js/ui/lookingGlass.js:847
|
||||||
msgid "Show Errors"
|
msgid "Show Errors"
|
||||||
msgstr "نمایش خطاها"
|
msgstr "نمایش خطاها"
|
||||||
|
|
||||||
#: ../js/ui/lookingGlass.js:798
|
#: ../js/ui/lookingGlass.js:805
|
||||||
msgid "Enabled"
|
msgid "Enabled"
|
||||||
msgstr "به کار انداختن"
|
msgstr "به کار انداختن"
|
||||||
|
|
||||||
#. translators:
|
#. translators:
|
||||||
#. * The device has been disabled
|
#. * The device has been disabled
|
||||||
#: ../js/ui/lookingGlass.js:801
|
#: ../js/ui/lookingGlass.js:808
|
||||||
#: ../src/gvc/gvc-mixer-control.c:1093
|
#: ../src/gvc/gvc-mixer-control.c:1093
|
||||||
msgid "Disabled"
|
msgid "Disabled"
|
||||||
msgstr "از کار انداختن"
|
msgstr "از کار انداختن"
|
||||||
|
|
||||||
#: ../js/ui/lookingGlass.js:803
|
#: ../js/ui/lookingGlass.js:810
|
||||||
msgid "Error"
|
msgid "Error"
|
||||||
msgstr "خطا"
|
msgstr "خطا"
|
||||||
|
|
||||||
#: ../js/ui/lookingGlass.js:805
|
#: ../js/ui/lookingGlass.js:812
|
||||||
msgid "Out of date"
|
msgid "Out of date"
|
||||||
msgstr "قدیمی"
|
msgstr "قدیمی"
|
||||||
|
|
||||||
#: ../js/ui/lookingGlass.js:807
|
#: ../js/ui/lookingGlass.js:814
|
||||||
msgid "Downloading"
|
msgid "Downloading"
|
||||||
msgstr "در حال بارگیری"
|
msgstr "در حال بارگیری"
|
||||||
|
|
||||||
#: ../js/ui/lookingGlass.js:828
|
#: ../js/ui/lookingGlass.js:835
|
||||||
msgid "View Source"
|
msgid "View Source"
|
||||||
msgstr "نمایش منبع"
|
msgstr "نمایش منبع"
|
||||||
|
|
||||||
#: ../js/ui/lookingGlass.js:834
|
#: ../js/ui/lookingGlass.js:841
|
||||||
msgid "Web Page"
|
msgid "Web Page"
|
||||||
msgstr "صفحهی وب"
|
msgstr "صفحهی وب"
|
||||||
|
|
||||||
#. Translators: this is a filename used for screencast recording
|
#. Translators: this is a filename used for screencast recording
|
||||||
#: ../js/ui/main.js:116
|
#: ../js/ui/main.js:118
|
||||||
#, no-c-format
|
#, no-c-format
|
||||||
msgid "Screencast from %d %t"
|
msgid "Screencast from %d %t"
|
||||||
msgstr "ویدئو صفحهنمایش %Id %t"
|
msgstr "ویدئو صفحهنمایش %Id %t"
|
||||||
|
|
||||||
#: ../js/ui/messageTray.js:1197
|
#: ../js/ui/messageTray.js:1200
|
||||||
msgid "Open"
|
msgid "Open"
|
||||||
msgstr "بازکردن"
|
msgstr "بازکردن"
|
||||||
|
|
||||||
#: ../js/ui/messageTray.js:1214
|
#: ../js/ui/messageTray.js:1217
|
||||||
msgid "Unmute"
|
msgid "Unmute"
|
||||||
msgstr "باصدا"
|
msgstr "باصدا"
|
||||||
|
|
||||||
#: ../js/ui/messageTray.js:1214
|
#: ../js/ui/messageTray.js:1217
|
||||||
msgid "Mute"
|
msgid "Mute"
|
||||||
msgstr "بیصدا"
|
msgstr "بیصدا"
|
||||||
|
|
||||||
#: ../js/ui/messageTray.js:2447
|
#: ../js/ui/messageTray.js:2490
|
||||||
msgid "System Information"
|
msgid "System Information"
|
||||||
msgstr "اطلاعات سیستم"
|
msgstr "اطلاعات سیستم"
|
||||||
|
|
||||||
@ -798,31 +794,35 @@ msgstr "برای اتصال به «%s» گذرواژه لازم است."
|
|||||||
msgid "Undo"
|
msgid "Undo"
|
||||||
msgstr "برگردان"
|
msgstr "برگردان"
|
||||||
|
|
||||||
#: ../js/ui/overview.js:199
|
#: ../js/ui/overview.js:132
|
||||||
|
msgid "Overview"
|
||||||
|
msgstr "نمایکلی"
|
||||||
|
|
||||||
|
#: ../js/ui/overview.js:202
|
||||||
msgid "Windows"
|
msgid "Windows"
|
||||||
msgstr "پنجرهها"
|
msgstr "پنجرهها"
|
||||||
|
|
||||||
#: ../js/ui/overview.js:202
|
#: ../js/ui/overview.js:205
|
||||||
msgid "Applications"
|
msgid "Applications"
|
||||||
msgstr "برنامهها"
|
msgstr "برنامهها"
|
||||||
|
|
||||||
#. Translators: this is the name of the dock/favorites area on
|
#. Translators: this is the name of the dock/favorites area on
|
||||||
#. the left of the overview
|
#. the left of the overview
|
||||||
#: ../js/ui/overview.js:228
|
#: ../js/ui/overview.js:231
|
||||||
msgid "Dash"
|
msgid "Dash"
|
||||||
msgstr "دَش"
|
msgstr "دَش"
|
||||||
|
|
||||||
#: ../js/ui/panel.js:583
|
#: ../js/ui/panel.js:592
|
||||||
msgid "Quit"
|
msgid "Quit"
|
||||||
msgstr "خروج"
|
msgstr "خروج"
|
||||||
|
|
||||||
#. Translators: If there is no suitable word for "Activities"
|
#. Translators: If there is no suitable word for "Activities"
|
||||||
#. in your language, you can use the word for "Overview".
|
#. in your language, you can use the word for "Overview".
|
||||||
#: ../js/ui/panel.js:614
|
#: ../js/ui/panel.js:624
|
||||||
msgid "Activities"
|
msgid "Activities"
|
||||||
msgstr "فعالیتها"
|
msgstr "فعالیتها"
|
||||||
|
|
||||||
#: ../js/ui/panel.js:987
|
#: ../js/ui/panel.js:999
|
||||||
msgid "Top Bar"
|
msgid "Top Bar"
|
||||||
msgstr "نوار بالا"
|
msgstr "نوار بالا"
|
||||||
|
|
||||||
@ -868,7 +868,7 @@ msgstr "متاسفتم، تاثیری نداشت! مجددا تلاش کنید."
|
|||||||
#. "ON" and "OFF") or "toggle-switch-intl" (for toggle
|
#. "ON" and "OFF") or "toggle-switch-intl" (for toggle
|
||||||
#. switches containing "◯" and "|"). Other values will
|
#. switches containing "◯" and "|"). Other values will
|
||||||
#. simply result in invisible toggle switches.
|
#. simply result in invisible toggle switches.
|
||||||
#: ../js/ui/popupMenu.js:720
|
#: ../js/ui/popupMenu.js:724
|
||||||
msgid "toggle-switch-us"
|
msgid "toggle-switch-us"
|
||||||
msgstr "toggle-switch-intl"
|
msgstr "toggle-switch-intl"
|
||||||
|
|
||||||
@ -876,11 +876,11 @@ msgstr "toggle-switch-intl"
|
|||||||
msgid "Please enter a command:"
|
msgid "Please enter a command:"
|
||||||
msgstr "لطفا یک فرمان وارد کنید:"
|
msgstr "لطفا یک فرمان وارد کنید:"
|
||||||
|
|
||||||
#: ../js/ui/searchDisplay.js:349
|
#: ../js/ui/searchDisplay.js:332
|
||||||
msgid "Searching..."
|
msgid "Searching..."
|
||||||
msgstr "درحال حستجو..."
|
msgstr "درحال حستجو..."
|
||||||
|
|
||||||
#: ../js/ui/searchDisplay.js:417
|
#: ../js/ui/searchDisplay.js:414
|
||||||
msgid "No matching results."
|
msgid "No matching results."
|
||||||
msgstr "نتیجهی منطبقی پیدا نشد."
|
msgstr "نتیجهی منطبقی پیدا نشد."
|
||||||
|
|
||||||
@ -905,7 +905,6 @@ msgid "Wrong password, please try again"
|
|||||||
msgstr "گذرواژهی نادرست، لطفا دوباره تلاش کنید"
|
msgstr "گذرواژهی نادرست، لطفا دوباره تلاش کنید"
|
||||||
|
|
||||||
#: ../js/ui/status/accessibility.js:47
|
#: ../js/ui/status/accessibility.js:47
|
||||||
#| msgid "Visibility"
|
|
||||||
msgid "Accessibility"
|
msgid "Accessibility"
|
||||||
msgstr "دسترسیپذیری"
|
msgstr "دسترسیپذیری"
|
||||||
|
|
||||||
@ -1178,7 +1177,6 @@ msgid "Auto wireless"
|
|||||||
msgstr "بیسیم خودکار"
|
msgstr "بیسیم خودکار"
|
||||||
|
|
||||||
#: ../js/ui/status/network.js:1541
|
#: ../js/ui/status/network.js:1541
|
||||||
#| msgid "Network error"
|
|
||||||
msgid "Network"
|
msgid "Network"
|
||||||
msgstr "شبکه"
|
msgstr "شبکه"
|
||||||
|
|
||||||
@ -1523,7 +1521,6 @@ msgid "Connection has been lost"
|
|||||||
msgstr "اتصال از دست رفته است"
|
msgstr "اتصال از دست رفته است"
|
||||||
|
|
||||||
#: ../js/ui/telepathyClient.js:1319
|
#: ../js/ui/telepathyClient.js:1319
|
||||||
#| msgid "This resource is already connected to the server"
|
|
||||||
msgid "This account is already connected to the server"
|
msgid "This account is already connected to the server"
|
||||||
msgstr "این حساب قبلا به کارگزار متصل شده است"
|
msgstr "این حساب قبلا به کارگزار متصل شده است"
|
||||||
|
|
||||||
@ -1552,7 +1549,6 @@ msgid "The length of the server certificate, or the depth of the server certific
|
|||||||
msgstr "اندازه گواهینامه کارگزار، یا عمق حلقهی گواهینامه کارگزار، از محدودیت اعمال شده توسط کتابخانه cryptography تجاوز کرد"
|
msgstr "اندازه گواهینامه کارگزار، یا عمق حلقهی گواهینامه کارگزار، از محدودیت اعمال شده توسط کتابخانه cryptography تجاوز کرد"
|
||||||
|
|
||||||
#: ../js/ui/telepathyClient.js:1333
|
#: ../js/ui/telepathyClient.js:1333
|
||||||
#| msgid "Connection error"
|
|
||||||
msgid "Internal error"
|
msgid "Internal error"
|
||||||
msgstr "خطای داخلی"
|
msgstr "خطای داخلی"
|
||||||
|
|
||||||
@ -1575,53 +1571,53 @@ msgstr "ویرایش حساب"
|
|||||||
msgid "Unknown reason"
|
msgid "Unknown reason"
|
||||||
msgstr "دلیل ناشناخته"
|
msgstr "دلیل ناشناخته"
|
||||||
|
|
||||||
#: ../js/ui/userMenu.js:133
|
#: ../js/ui/userMenu.js:135
|
||||||
msgid "Hidden"
|
msgid "Hidden"
|
||||||
msgstr "نامرئی"
|
msgstr "نامرئی"
|
||||||
|
|
||||||
#: ../js/ui/userMenu.js:139
|
#: ../js/ui/userMenu.js:141
|
||||||
msgid "Idle"
|
msgid "Idle"
|
||||||
msgstr "بیکار"
|
msgstr "بیکار"
|
||||||
|
|
||||||
#: ../js/ui/userMenu.js:142
|
#: ../js/ui/userMenu.js:144
|
||||||
msgid "Unavailable"
|
msgid "Unavailable"
|
||||||
msgstr "خارج از دسترس"
|
msgstr "خارج از دسترس"
|
||||||
|
|
||||||
#: ../js/ui/userMenu.js:579
|
#: ../js/ui/userMenu.js:595
|
||||||
#: ../js/ui/userMenu.js:583
|
#: ../js/ui/userMenu.js:599
|
||||||
#: ../js/ui/userMenu.js:653
|
#: ../js/ui/userMenu.js:669
|
||||||
msgid "Power Off..."
|
msgid "Power Off..."
|
||||||
msgstr "خاموش کردن..."
|
msgstr "خاموش کردن..."
|
||||||
|
|
||||||
#: ../js/ui/userMenu.js:615
|
#: ../js/ui/userMenu.js:631
|
||||||
msgid "Notifications"
|
msgid "Notifications"
|
||||||
msgstr "اعلانها"
|
msgstr "اعلانها"
|
||||||
|
|
||||||
#: ../js/ui/userMenu.js:623
|
#: ../js/ui/userMenu.js:639
|
||||||
msgid "Online Accounts"
|
msgid "Online Accounts"
|
||||||
msgstr "حسابهای برخط"
|
msgstr "حسابهای برخط"
|
||||||
|
|
||||||
#: ../js/ui/userMenu.js:627
|
#: ../js/ui/userMenu.js:643
|
||||||
msgid "System Settings"
|
msgid "System Settings"
|
||||||
msgstr "تنظیمات سیستم"
|
msgstr "تنظیمات سیستم"
|
||||||
|
|
||||||
#: ../js/ui/userMenu.js:634
|
#: ../js/ui/userMenu.js:650
|
||||||
msgid "Lock Screen"
|
msgid "Lock Screen"
|
||||||
msgstr "قفل کردن صفحه"
|
msgstr "قفل کردن صفحه"
|
||||||
|
|
||||||
#: ../js/ui/userMenu.js:639
|
#: ../js/ui/userMenu.js:655
|
||||||
msgid "Switch User"
|
msgid "Switch User"
|
||||||
msgstr "تعویض کاربر"
|
msgstr "تعویض کاربر"
|
||||||
|
|
||||||
#: ../js/ui/userMenu.js:644
|
#: ../js/ui/userMenu.js:660
|
||||||
msgid "Log Out..."
|
msgid "Log Out..."
|
||||||
msgstr "خروج از سیستم..."
|
msgstr "خروج از سیستم..."
|
||||||
|
|
||||||
#: ../js/ui/userMenu.js:672
|
#: ../js/ui/userMenu.js:688
|
||||||
msgid "Your chat status will be set to busy"
|
msgid "Your chat status will be set to busy"
|
||||||
msgstr "وضعیت گپ شما «مشغول» تنظیم میشود"
|
msgstr "وضعیت گپ شما «مشغول» تنظیم میشود"
|
||||||
|
|
||||||
#: ../js/ui/userMenu.js:673
|
#: ../js/ui/userMenu.js:689
|
||||||
msgid "Notifications are now disabled, including chat messages. Your online status has been adjusted to let others know that you might not see their messages."
|
msgid "Notifications are now disabled, including chat messages. Your online status has been adjusted to let others know that you might not see their messages."
|
||||||
msgstr "هماکنون اعلانها، از جمله پیامهای گپ، غیرفعال هستند. وضعیتِ برخطِ شما به گونهای تنظیم شده است که به دیگران نشان دهد ممکن است شما پیامهایشان را نبینید."
|
msgstr "هماکنون اعلانها، از جمله پیامهای گپ، غیرفعال هستند. وضعیتِ برخطِ شما به گونهای تنظیم شده است که به دیگران نشان دهد ممکن است شما پیامهایشان را نبینید."
|
||||||
|
|
||||||
@ -1683,21 +1679,20 @@ msgstr[1] "%Iu ورودی"
|
|||||||
msgid "System Sounds"
|
msgid "System Sounds"
|
||||||
msgstr "صداهای سیستم"
|
msgstr "صداهای سیستم"
|
||||||
|
|
||||||
#: ../src/main.c:262
|
#: ../src/main.c:255
|
||||||
msgid "Print version"
|
msgid "Print version"
|
||||||
msgstr "چاپ نسخه"
|
msgstr "چاپ نسخه"
|
||||||
|
|
||||||
#: ../src/main.c:268
|
#: ../src/main.c:261
|
||||||
msgid "Mode used by GDM for login screen"
|
msgid "Mode used by GDM for login screen"
|
||||||
msgstr "حالت استفاده شده توسط GDM برای صفحه ورود به سیستم"
|
msgstr "حالت استفاده شده توسط GDM برای صفحه ورود به سیستم"
|
||||||
|
|
||||||
#: ../src/shell-app.c:617
|
#: ../src/shell-app.c:619
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "Failed to launch '%s'"
|
msgid "Failed to launch '%s'"
|
||||||
msgstr "راهاندازی «%s» شکست خورد"
|
msgstr "راهاندازی «%s» شکست خورد"
|
||||||
|
|
||||||
#: ../src/shell-keyring-prompt.c:708
|
#: ../src/shell-keyring-prompt.c:708
|
||||||
#| msgid "Does not match"
|
|
||||||
msgid "Passwords do not match."
|
msgid "Passwords do not match."
|
||||||
msgstr "گذرواژههای منطبق نیستند."
|
msgstr "گذرواژههای منطبق نیستند."
|
||||||
|
|
||||||
|
64
po/fr.po
64
po/fr.po
@ -15,8 +15,8 @@ msgstr ""
|
|||||||
"Project-Id-Version: gnome-shell master fr\n"
|
"Project-Id-Version: gnome-shell master fr\n"
|
||||||
"Report-Msgid-Bugs-To: http://bugzilla.gnome.org/enter_bug.cgi?product=gnome-"
|
"Report-Msgid-Bugs-To: http://bugzilla.gnome.org/enter_bug.cgi?product=gnome-"
|
||||||
"shell&keywords=I18N+L10N&component=general\n"
|
"shell&keywords=I18N+L10N&component=general\n"
|
||||||
"POT-Creation-Date: 2012-03-20 17:23+0000\n"
|
"POT-Creation-Date: 2012-04-03 18:35+0000\n"
|
||||||
"PO-Revision-Date: 2012-03-05 20:54+0100\n"
|
"PO-Revision-Date: 2012-03-31 15:56+0300\n"
|
||||||
"Last-Translator: Bruno Brouard <annoa.b@gmail.com>\n"
|
"Last-Translator: Bruno Brouard <annoa.b@gmail.com>\n"
|
||||||
"Language-Team: GNOME French Team <gnomefr@traduc.org>\n"
|
"Language-Team: GNOME French Team <gnomefr@traduc.org>\n"
|
||||||
"MIME-Version: 1.0\n"
|
"MIME-Version: 1.0\n"
|
||||||
@ -141,35 +141,43 @@ msgid "If true, display the ISO week date in the calendar."
|
|||||||
msgstr "Si vrai, afficher le numéro de semaine ISO dans le calendrier."
|
msgstr "Si vrai, afficher le numéro de semaine ISO dans le calendrier."
|
||||||
|
|
||||||
#: ../data/org.gnome.shell.gschema.xml.in.h:16
|
#: ../data/org.gnome.shell.gschema.xml.in.h:16
|
||||||
|
msgid "Keybinding to open the application menu"
|
||||||
|
msgstr "Combinaison de touches pour ouvrir le menu de l'application"
|
||||||
|
|
||||||
|
#: ../data/org.gnome.shell.gschema.xml.in.h:17
|
||||||
|
msgid "Keybinding to open the application menu."
|
||||||
|
msgstr "Combinaison de touches pour ouvrir le menu de l'application."
|
||||||
|
|
||||||
|
#: ../data/org.gnome.shell.gschema.xml.in.h:18
|
||||||
msgid "Which keyboard to use"
|
msgid "Which keyboard to use"
|
||||||
msgstr "Le clavier utilisé"
|
msgstr "Le clavier utilisé"
|
||||||
|
|
||||||
#: ../data/org.gnome.shell.gschema.xml.in.h:17
|
#: ../data/org.gnome.shell.gschema.xml.in.h:19
|
||||||
msgid "The type of keyboard to use."
|
msgid "The type of keyboard to use."
|
||||||
msgstr "Le type de clavier utilisé."
|
msgstr "Le type de clavier utilisé."
|
||||||
|
|
||||||
#: ../data/org.gnome.shell.gschema.xml.in.h:18
|
#: ../data/org.gnome.shell.gschema.xml.in.h:20
|
||||||
msgid "Show time with seconds"
|
msgid "Show time with seconds"
|
||||||
msgstr "Afficher l'heure avec les secondes"
|
msgstr "Afficher l'heure avec les secondes"
|
||||||
|
|
||||||
#: ../data/org.gnome.shell.gschema.xml.in.h:19
|
#: ../data/org.gnome.shell.gschema.xml.in.h:21
|
||||||
msgid "If true, display seconds in time."
|
msgid "If true, display seconds in time."
|
||||||
msgstr "Si vrai, afficher les secondes dans l'horloge."
|
msgstr "Si vrai, afficher les secondes dans l'horloge."
|
||||||
|
|
||||||
#: ../data/org.gnome.shell.gschema.xml.in.h:20
|
#: ../data/org.gnome.shell.gschema.xml.in.h:22
|
||||||
msgid "Show date in clock"
|
msgid "Show date in clock"
|
||||||
msgstr "Afficher la date dans l'horloge"
|
msgstr "Afficher la date dans l'horloge"
|
||||||
|
|
||||||
#: ../data/org.gnome.shell.gschema.xml.in.h:21
|
#: ../data/org.gnome.shell.gschema.xml.in.h:23
|
||||||
msgid "If true, display date in the clock, in addition to time."
|
msgid "If true, display date in the clock, in addition to time."
|
||||||
msgstr "Si vrai, afficher la date dans l'horloge, en plus de l'heure."
|
msgstr "Si vrai, afficher la date dans l'horloge, en plus de l'heure."
|
||||||
|
|
||||||
#: ../data/org.gnome.shell.gschema.xml.in.h:22
|
#: ../data/org.gnome.shell.gschema.xml.in.h:24
|
||||||
msgid "Framerate used for recording screencasts."
|
msgid "Framerate used for recording screencasts."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Nombre d'images par seconde pour l'enregistrement des animations d'écran."
|
"Nombre d'images par seconde pour l'enregistrement des animations d'écran."
|
||||||
|
|
||||||
#: ../data/org.gnome.shell.gschema.xml.in.h:23
|
#: ../data/org.gnome.shell.gschema.xml.in.h:25
|
||||||
msgid ""
|
msgid ""
|
||||||
"The framerate of the resulting screencast recordered by GNOME Shell's "
|
"The framerate of the resulting screencast recordered by GNOME Shell's "
|
||||||
"screencast recorder in frames-per-second."
|
"screencast recorder in frames-per-second."
|
||||||
@ -177,11 +185,11 @@ msgstr ""
|
|||||||
"Le nombre d'images par seconde des animations d'écran enregistrées par "
|
"Le nombre d'images par seconde des animations d'écran enregistrées par "
|
||||||
"l'outil idoine de GNOME Shell."
|
"l'outil idoine de GNOME Shell."
|
||||||
|
|
||||||
#: ../data/org.gnome.shell.gschema.xml.in.h:24
|
#: ../data/org.gnome.shell.gschema.xml.in.h:26
|
||||||
msgid "The gstreamer pipeline used to encode the screencast"
|
msgid "The gstreamer pipeline used to encode the screencast"
|
||||||
msgstr "Le pipeline GStreamer utilisé pour coder l'animation d'écran"
|
msgstr "Le pipeline GStreamer utilisé pour coder l'animation d'écran"
|
||||||
|
|
||||||
#: ../data/org.gnome.shell.gschema.xml.in.h:26
|
#: ../data/org.gnome.shell.gschema.xml.in.h:28
|
||||||
#, no-c-format
|
#, no-c-format
|
||||||
msgid ""
|
msgid ""
|
||||||
"Sets the GStreamer pipeline used to encode recordings. It follows the syntax "
|
"Sets the GStreamer pipeline used to encode recordings. It follows the syntax "
|
||||||
@ -208,11 +216,11 @@ msgstr ""
|
|||||||
"VP8. %T est utilisé comme paramètre pour une supposition quant au nombre "
|
"VP8. %T est utilisé comme paramètre pour une supposition quant au nombre "
|
||||||
"optimal de threads à utiliser sur le système."
|
"optimal de threads à utiliser sur le système."
|
||||||
|
|
||||||
#: ../data/org.gnome.shell.gschema.xml.in.h:27
|
#: ../data/org.gnome.shell.gschema.xml.in.h:29
|
||||||
msgid "File extension used for storing the screencast"
|
msgid "File extension used for storing the screencast"
|
||||||
msgstr "Extension de fichier à utiliser pour enregistrer l'animation d'écran"
|
msgstr "Extension de fichier à utiliser pour enregistrer l'animation d'écran"
|
||||||
|
|
||||||
#: ../data/org.gnome.shell.gschema.xml.in.h:28
|
#: ../data/org.gnome.shell.gschema.xml.in.h:30
|
||||||
msgid ""
|
msgid ""
|
||||||
"The filename for recorded screencasts will be a unique filename based on the "
|
"The filename for recorded screencasts will be a unique filename based on the "
|
||||||
"current date, and use this extension. It should be changed when recording to "
|
"current date, and use this extension. It should be changed when recording to "
|
||||||
@ -730,51 +738,51 @@ msgstr "Mot de passe :"
|
|||||||
msgid "Type again:"
|
msgid "Type again:"
|
||||||
msgstr "Saisissez à nouveau :"
|
msgstr "Saisissez à nouveau :"
|
||||||
|
|
||||||
#: ../js/ui/lookingGlass.js:725
|
#: ../js/ui/lookingGlass.js:732
|
||||||
msgid "No extensions installed"
|
msgid "No extensions installed"
|
||||||
msgstr "Aucune extension installée"
|
msgstr "Aucune extension installée"
|
||||||
|
|
||||||
#. Translators: argument is an extension UUID.
|
#. Translators: argument is an extension UUID.
|
||||||
#: ../js/ui/lookingGlass.js:779
|
#: ../js/ui/lookingGlass.js:786
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "%s has not emitted any errors."
|
msgid "%s has not emitted any errors."
|
||||||
msgstr "%s n'a émis aucune erreur."
|
msgstr "%s n'a émis aucune erreur."
|
||||||
|
|
||||||
#: ../js/ui/lookingGlass.js:785
|
#: ../js/ui/lookingGlass.js:792
|
||||||
msgid "Hide Errors"
|
msgid "Hide Errors"
|
||||||
msgstr "Masquer les erreurs"
|
msgstr "Masquer les erreurs"
|
||||||
|
|
||||||
#: ../js/ui/lookingGlass.js:789 ../js/ui/lookingGlass.js:840
|
#: ../js/ui/lookingGlass.js:796 ../js/ui/lookingGlass.js:847
|
||||||
msgid "Show Errors"
|
msgid "Show Errors"
|
||||||
msgstr "Afficher les erreurs"
|
msgstr "Afficher les erreurs"
|
||||||
|
|
||||||
#: ../js/ui/lookingGlass.js:798
|
#: ../js/ui/lookingGlass.js:805
|
||||||
msgid "Enabled"
|
msgid "Enabled"
|
||||||
msgstr "Activé"
|
msgstr "Activé"
|
||||||
|
|
||||||
#. translators:
|
#. translators:
|
||||||
#. * The device has been disabled
|
#. * The device has been disabled
|
||||||
#: ../js/ui/lookingGlass.js:801 ../src/gvc/gvc-mixer-control.c:1093
|
#: ../js/ui/lookingGlass.js:808 ../src/gvc/gvc-mixer-control.c:1093
|
||||||
msgid "Disabled"
|
msgid "Disabled"
|
||||||
msgstr "Désactivé"
|
msgstr "Désactivé"
|
||||||
|
|
||||||
#: ../js/ui/lookingGlass.js:803
|
#: ../js/ui/lookingGlass.js:810
|
||||||
msgid "Error"
|
msgid "Error"
|
||||||
msgstr "Erreur"
|
msgstr "Erreur"
|
||||||
|
|
||||||
#: ../js/ui/lookingGlass.js:805
|
#: ../js/ui/lookingGlass.js:812
|
||||||
msgid "Out of date"
|
msgid "Out of date"
|
||||||
msgstr "Périmé"
|
msgstr "Périmé"
|
||||||
|
|
||||||
#: ../js/ui/lookingGlass.js:807
|
#: ../js/ui/lookingGlass.js:814
|
||||||
msgid "Downloading"
|
msgid "Downloading"
|
||||||
msgstr "Téléchargement"
|
msgstr "Téléchargement"
|
||||||
|
|
||||||
#: ../js/ui/lookingGlass.js:828
|
#: ../js/ui/lookingGlass.js:835
|
||||||
msgid "View Source"
|
msgid "View Source"
|
||||||
msgstr "Afficher la source"
|
msgstr "Afficher la source"
|
||||||
|
|
||||||
#: ../js/ui/lookingGlass.js:834
|
#: ../js/ui/lookingGlass.js:841
|
||||||
msgid "Web Page"
|
msgid "Web Page"
|
||||||
msgstr "Page Web"
|
msgstr "Page Web"
|
||||||
|
|
||||||
@ -782,7 +790,7 @@ msgstr "Page Web"
|
|||||||
#: ../js/ui/main.js:118
|
#: ../js/ui/main.js:118
|
||||||
#, no-c-format
|
#, no-c-format
|
||||||
msgid "Screencast from %d %t"
|
msgid "Screencast from %d %t"
|
||||||
msgstr "Animation d'écran %d %t"
|
msgstr "Vidéo d'écran %d %t"
|
||||||
|
|
||||||
#: ../js/ui/messageTray.js:1200
|
#: ../js/ui/messageTray.js:1200
|
||||||
msgid "Open"
|
msgid "Open"
|
||||||
@ -903,17 +911,17 @@ msgstr "Applications"
|
|||||||
msgid "Dash"
|
msgid "Dash"
|
||||||
msgstr "Dash"
|
msgstr "Dash"
|
||||||
|
|
||||||
#: ../js/ui/panel.js:591
|
#: ../js/ui/panel.js:592
|
||||||
msgid "Quit"
|
msgid "Quit"
|
||||||
msgstr "Quitter"
|
msgstr "Quitter"
|
||||||
|
|
||||||
#. Translators: If there is no suitable word for "Activities"
|
#. Translators: If there is no suitable word for "Activities"
|
||||||
#. in your language, you can use the word for "Overview".
|
#. in your language, you can use the word for "Overview".
|
||||||
#: ../js/ui/panel.js:623
|
#: ../js/ui/panel.js:624
|
||||||
msgid "Activities"
|
msgid "Activities"
|
||||||
msgstr "Activités"
|
msgstr "Activités"
|
||||||
|
|
||||||
#: ../js/ui/panel.js:998
|
#: ../js/ui/panel.js:999
|
||||||
msgid "Top Bar"
|
msgid "Top Bar"
|
||||||
msgstr "Barre supérieure"
|
msgstr "Barre supérieure"
|
||||||
|
|
||||||
|
320
po/gu.po
320
po/gu.po
@ -9,8 +9,8 @@ msgstr ""
|
|||||||
"Project-Id-Version: gu\n"
|
"Project-Id-Version: gu\n"
|
||||||
"Report-Msgid-Bugs-To: http://bugzilla.gnome.org/enter_bug."
|
"Report-Msgid-Bugs-To: http://bugzilla.gnome.org/enter_bug."
|
||||||
"cgi?product=gnome-shell&keywords=I18N+L10N&component=general\n"
|
"cgi?product=gnome-shell&keywords=I18N+L10N&component=general\n"
|
||||||
"POT-Creation-Date: 2012-02-29 22:27+0000\n"
|
"POT-Creation-Date: 2012-03-30 17:59+0000\n"
|
||||||
"PO-Revision-Date: 2012-03-15 14:01+0530\n"
|
"PO-Revision-Date: 2012-04-03 11:24+0530\n"
|
||||||
"Last-Translator: \n"
|
"Last-Translator: \n"
|
||||||
"Language-Team: gu_IN <kde-i18n-doc@kde.org>\n"
|
"Language-Team: gu_IN <kde-i18n-doc@kde.org>\n"
|
||||||
"MIME-Version: 1.0\n"
|
"MIME-Version: 1.0\n"
|
||||||
@ -25,20 +25,20 @@ msgstr "GNOME શેલ"
|
|||||||
|
|
||||||
#: ../data/gnome-shell.desktop.in.in.h:2
|
#: ../data/gnome-shell.desktop.in.in.h:2
|
||||||
msgid "Window management and application launching"
|
msgid "Window management and application launching"
|
||||||
msgstr ""
|
msgstr "વિન્ડો સંચાલન અને કાર્યક્રમ શરૂઆત"
|
||||||
|
|
||||||
#: ../data/gnome-shell-extension-prefs.desktop.in.in.h:1
|
#: ../data/gnome-shell-extension-prefs.desktop.in.in.h:1
|
||||||
#: ../js/extensionPrefs/main.js:153
|
#: ../js/extensionPrefs/main.js:153
|
||||||
msgid "GNOME Shell Extension Preferences"
|
msgid "GNOME Shell Extension Preferences"
|
||||||
msgstr ""
|
msgstr "GNOME Shell ઍક્સટેન્શન પસંદગીઓ"
|
||||||
|
|
||||||
#: ../data/gnome-shell-extension-prefs.desktop.in.in.h:2
|
#: ../data/gnome-shell-extension-prefs.desktop.in.in.h:2
|
||||||
msgid "Configure GNOME Shell Extensions"
|
msgid "Configure GNOME Shell Extensions"
|
||||||
msgstr ""
|
msgstr "GNOME Shell ઍક્સટેન્શનને રૂપરેખાંકિત કરો"
|
||||||
|
|
||||||
#: ../data/org.gnome.shell.gschema.xml.in.h:1
|
#: ../data/org.gnome.shell.gschema.xml.in.h:1
|
||||||
msgid "Enable internal tools useful for developers and testers from Alt-F2"
|
msgid "Enable internal tools useful for developers and testers from Alt-F2"
|
||||||
msgstr ""
|
msgstr "Alt-F2 માંથી ડેવલપર અને ટેસ્ટર માટે ઉપયોગી આંતરિક સાધનોને સક્રિય કરો"
|
||||||
|
|
||||||
#: ../data/org.gnome.shell.gschema.xml.in.h:2
|
#: ../data/org.gnome.shell.gschema.xml.in.h:2
|
||||||
msgid ""
|
msgid ""
|
||||||
@ -47,7 +47,6 @@ msgid ""
|
|||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: ../data/org.gnome.shell.gschema.xml.in.h:3
|
#: ../data/org.gnome.shell.gschema.xml.in.h:3
|
||||||
#| msgid "No extensions installed"
|
|
||||||
msgid "Uuids of extensions to enable"
|
msgid "Uuids of extensions to enable"
|
||||||
msgstr "સક્રિય કરવા માટે એક્સટેન્શનનું Uuids"
|
msgstr "સક્રિય કરવા માટે એક્સટેન્શનનું Uuids"
|
||||||
|
|
||||||
@ -83,14 +82,13 @@ msgstr ""
|
|||||||
|
|
||||||
#: ../data/org.gnome.shell.gschema.xml.in.h:9
|
#: ../data/org.gnome.shell.gschema.xml.in.h:9
|
||||||
msgid "disabled OpenSearch providers"
|
msgid "disabled OpenSearch providers"
|
||||||
msgstr ""
|
msgstr "નિષ્ક્રિય થયેલ OpenSearch પ્રબંધક"
|
||||||
|
|
||||||
#: ../data/org.gnome.shell.gschema.xml.in.h:10
|
#: ../data/org.gnome.shell.gschema.xml.in.h:10
|
||||||
msgid "History for command (Alt-F2) dialog"
|
msgid "History for command (Alt-F2) dialog"
|
||||||
msgstr "આદેશ (Alt-F2) સંવાદ માટે ઇતિહાસ"
|
msgstr "આદેશ (Alt-F2) સંવાદ માટે ઇતિહાસ"
|
||||||
|
|
||||||
#: ../data/org.gnome.shell.gschema.xml.in.h:11
|
#: ../data/org.gnome.shell.gschema.xml.in.h:11
|
||||||
#| msgid "History for command (Alt-F2) dialog"
|
|
||||||
msgid "History for the looking glass dialog"
|
msgid "History for the looking glass dialog"
|
||||||
msgstr "ગ્લાસ સંવાદને જોવા માટે ઇતિહાસ"
|
msgstr "ગ્લાસ સંવાદને જોવા માટે ઇતિહાસ"
|
||||||
|
|
||||||
@ -112,47 +110,55 @@ msgstr "કૅલેન્ડરમાં અઠવાડિયા તારી
|
|||||||
|
|
||||||
#: ../data/org.gnome.shell.gschema.xml.in.h:15
|
#: ../data/org.gnome.shell.gschema.xml.in.h:15
|
||||||
msgid "If true, display the ISO week date in the calendar."
|
msgid "If true, display the ISO week date in the calendar."
|
||||||
msgstr ""
|
msgstr "જો true હોય તો, કૅલેન્ડરમાં ISO અઠવાડિયાની તારીખને દર્શાવો."
|
||||||
|
|
||||||
#: ../data/org.gnome.shell.gschema.xml.in.h:16
|
#: ../data/org.gnome.shell.gschema.xml.in.h:16
|
||||||
msgid "Which keyboard to use"
|
msgid "Keybinding to open the application menu"
|
||||||
msgstr ""
|
msgstr "કાર્યક્રમ મેનુને ખોલવા માટે કિબાઇન્ડીંગ"
|
||||||
|
|
||||||
#: ../data/org.gnome.shell.gschema.xml.in.h:17
|
#: ../data/org.gnome.shell.gschema.xml.in.h:17
|
||||||
msgid "The type of keyboard to use."
|
msgid "Keybinding to open the application menu."
|
||||||
msgstr ""
|
msgstr "કાર્યક્રમ મેનુને ખોલવા માટે કિબાઇન્ડીંગ."
|
||||||
|
|
||||||
#: ../data/org.gnome.shell.gschema.xml.in.h:18
|
#: ../data/org.gnome.shell.gschema.xml.in.h:18
|
||||||
|
msgid "Which keyboard to use"
|
||||||
|
msgstr "ક્યુ કિબોર્ડ વાપરવુ છે"
|
||||||
|
|
||||||
|
#: ../data/org.gnome.shell.gschema.xml.in.h:19
|
||||||
|
msgid "The type of keyboard to use."
|
||||||
|
msgstr "વાપરવા માટે કિબોર્ડનો પ્રકાર."
|
||||||
|
|
||||||
|
#: ../data/org.gnome.shell.gschema.xml.in.h:20
|
||||||
msgid "Show time with seconds"
|
msgid "Show time with seconds"
|
||||||
msgstr "સેકંડોમાં સમયને બતાવો"
|
msgstr "સેકંડોમાં સમયને બતાવો"
|
||||||
|
|
||||||
#: ../data/org.gnome.shell.gschema.xml.in.h:19
|
#: ../data/org.gnome.shell.gschema.xml.in.h:21
|
||||||
msgid "If true, display seconds in time."
|
msgid "If true, display seconds in time."
|
||||||
msgstr ""
|
msgstr "જો true હોય તો, સમયમાં સેકંડ બતાવો."
|
||||||
|
|
||||||
#: ../data/org.gnome.shell.gschema.xml.in.h:20
|
#: ../data/org.gnome.shell.gschema.xml.in.h:22
|
||||||
msgid "Show date in clock"
|
msgid "Show date in clock"
|
||||||
msgstr "ઘડિયાળમાં તારીખને બતાવો"
|
msgstr "ઘડિયાળમાં તારીખને બતાવો"
|
||||||
|
|
||||||
#: ../data/org.gnome.shell.gschema.xml.in.h:21
|
|
||||||
msgid "If true, display date in the clock, in addition to time."
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: ../data/org.gnome.shell.gschema.xml.in.h:22
|
|
||||||
msgid "Framerate used for recording screencasts."
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: ../data/org.gnome.shell.gschema.xml.in.h:23
|
#: ../data/org.gnome.shell.gschema.xml.in.h:23
|
||||||
|
msgid "If true, display date in the clock, in addition to time."
|
||||||
|
msgstr "જો true હોય તો, ઘડિયાળમાં તારીખ બતાવો, સમય સાથે વધુમાં."
|
||||||
|
|
||||||
|
#: ../data/org.gnome.shell.gschema.xml.in.h:24
|
||||||
|
msgid "Framerate used for recording screencasts."
|
||||||
|
msgstr "રેકોર્ડીંગ સ્ક્રીનકાસ્ટ માટે વાપરેલ ફ્રેમરેટ."
|
||||||
|
|
||||||
|
#: ../data/org.gnome.shell.gschema.xml.in.h:25
|
||||||
msgid ""
|
msgid ""
|
||||||
"The framerate of the resulting screencast recordered by GNOME Shell's "
|
"The framerate of the resulting screencast recordered by GNOME Shell's "
|
||||||
"screencast recorder in frames-per-second."
|
"screencast recorder in frames-per-second."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: ../data/org.gnome.shell.gschema.xml.in.h:24
|
|
||||||
msgid "The gstreamer pipeline used to encode the screencast"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: ../data/org.gnome.shell.gschema.xml.in.h:26
|
#: ../data/org.gnome.shell.gschema.xml.in.h:26
|
||||||
|
msgid "The gstreamer pipeline used to encode the screencast"
|
||||||
|
msgstr "સ્ક્રીનકાસ્ટને એનકોડ કરવા માટે વાપરેલ gstreamer પાઇપલાઇન"
|
||||||
|
|
||||||
|
#: ../data/org.gnome.shell.gschema.xml.in.h:28
|
||||||
#, no-c-format
|
#, no-c-format
|
||||||
msgid ""
|
msgid ""
|
||||||
"Sets the GStreamer pipeline used to encode recordings. It follows the syntax "
|
"Sets the GStreamer pipeline used to encode recordings. It follows the syntax "
|
||||||
@ -167,11 +173,11 @@ msgid ""
|
|||||||
"thread count on the system."
|
"thread count on the system."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: ../data/org.gnome.shell.gschema.xml.in.h:27
|
#: ../data/org.gnome.shell.gschema.xml.in.h:29
|
||||||
msgid "File extension used for storing the screencast"
|
msgid "File extension used for storing the screencast"
|
||||||
msgstr ""
|
msgstr "સ્ક્રીનકાસ્ટને સંગ્રહ કરવા માટે વાપરેલ ફાઇલ ઍક્સટેન્શન"
|
||||||
|
|
||||||
#: ../data/org.gnome.shell.gschema.xml.in.h:28
|
#: ../data/org.gnome.shell.gschema.xml.in.h:30
|
||||||
msgid ""
|
msgid ""
|
||||||
"The filename for recorded screencasts will be a unique filename based on the "
|
"The filename for recorded screencasts will be a unique filename based on the "
|
||||||
"current date, and use this extension. It should be changed when recording to "
|
"current date, and use this extension. It should be changed when recording to "
|
||||||
@ -181,15 +187,15 @@ msgstr ""
|
|||||||
#: ../js/extensionPrefs/main.js:125
|
#: ../js/extensionPrefs/main.js:125
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "There was an error loading the preferences dialog for %s:"
|
msgid "There was an error loading the preferences dialog for %s:"
|
||||||
msgstr ""
|
msgstr "ત્યાં %s માટે પસંદગી સંવાદને લાવવામાં ભૂલ હતી:"
|
||||||
|
|
||||||
#: ../js/extensionPrefs/main.js:165
|
#: ../js/extensionPrefs/main.js:165
|
||||||
msgid "<b>Extension</b>"
|
msgid "<b>Extension</b>"
|
||||||
msgstr ""
|
msgstr "<b>ઍક્સટેન્શન</b>"
|
||||||
|
|
||||||
#: ../js/extensionPrefs/main.js:189
|
#: ../js/extensionPrefs/main.js:189
|
||||||
msgid "Select an extension to configure using the combobox above."
|
msgid "Select an extension to configure using the combobox above."
|
||||||
msgstr ""
|
msgstr "ઉપર કોમ્બોબોક્સની મદદથી રૂપરેખાંકિત કરવા માટે ઍક્સટેન્શનને પસંદ કરો."
|
||||||
|
|
||||||
#: ../js/gdm/loginDialog.js:624
|
#: ../js/gdm/loginDialog.js:624
|
||||||
msgid "Session..."
|
msgid "Session..."
|
||||||
@ -198,23 +204,23 @@ msgstr "સત્ર..."
|
|||||||
#: ../js/gdm/loginDialog.js:786
|
#: ../js/gdm/loginDialog.js:786
|
||||||
msgctxt "title"
|
msgctxt "title"
|
||||||
msgid "Sign In"
|
msgid "Sign In"
|
||||||
msgstr ""
|
msgstr "પ્રવેશો"
|
||||||
|
|
||||||
#. Translators: this message is shown below the password entry field
|
#. Translators: this message is shown below the password entry field
|
||||||
#. to indicate the user can swipe their finger instead
|
#. to indicate the user can swipe their finger instead
|
||||||
#: ../js/gdm/loginDialog.js:831
|
#: ../js/gdm/loginDialog.js:831
|
||||||
msgid "(or swipe finger)"
|
msgid "(or swipe finger)"
|
||||||
msgstr ""
|
msgstr "(અથવા સ્વાઇપ આંગળી)"
|
||||||
|
|
||||||
#. translators: this message is shown below the user list on the
|
#. translators: this message is shown below the user list on the
|
||||||
#. login screen. It can be activated to reveal an entry for
|
#. login screen. It can be activated to reveal an entry for
|
||||||
#. manually entering the username.
|
#. manually entering the username.
|
||||||
#: ../js/gdm/loginDialog.js:852
|
#: ../js/gdm/loginDialog.js:852
|
||||||
msgid "Not listed?"
|
msgid "Not listed?"
|
||||||
msgstr ""
|
msgstr "શું યાદી થયેલ નથી?"
|
||||||
|
|
||||||
#: ../js/gdm/loginDialog.js:1020 ../js/ui/endSessionDialog.js:419
|
#: ../js/gdm/loginDialog.js:1020 ../js/ui/endSessionDialog.js:401
|
||||||
#: ../js/ui/extensionSystem.js:401 ../js/ui/networkAgent.js:153
|
#: ../js/ui/extensionSystem.js:399 ../js/ui/networkAgent.js:153
|
||||||
#: ../js/ui/polkitAuthenticationAgent.js:175 ../js/ui/status/bluetooth.js:462
|
#: ../js/ui/polkitAuthenticationAgent.js:175 ../js/ui/status/bluetooth.js:462
|
||||||
msgid "Cancel"
|
msgid "Cancel"
|
||||||
msgstr "રદ કરો"
|
msgstr "રદ કરો"
|
||||||
@ -222,23 +228,22 @@ msgstr "રદ કરો"
|
|||||||
#: ../js/gdm/loginDialog.js:1025
|
#: ../js/gdm/loginDialog.js:1025
|
||||||
msgctxt "button"
|
msgctxt "button"
|
||||||
msgid "Sign In"
|
msgid "Sign In"
|
||||||
msgstr ""
|
msgstr "પ્રવેશો"
|
||||||
|
|
||||||
#: ../js/gdm/loginDialog.js:1377
|
#: ../js/gdm/loginDialog.js:1377
|
||||||
#| msgid "New Window"
|
|
||||||
msgid "Login Window"
|
msgid "Login Window"
|
||||||
msgstr "પ્રવેશ વિન્ડો"
|
msgstr "પ્રવેશ વિન્ડો"
|
||||||
|
|
||||||
#: ../js/gdm/powerMenu.js:152 ../js/ui/userMenu.js:581
|
#: ../js/gdm/powerMenu.js:155 ../js/ui/userMenu.js:597
|
||||||
#: ../js/ui/userMenu.js:583 ../js/ui/userMenu.js:652
|
#: ../js/ui/userMenu.js:599 ../js/ui/userMenu.js:668
|
||||||
msgid "Suspend"
|
msgid "Suspend"
|
||||||
msgstr "અટકાવો"
|
msgstr "અટકાવો"
|
||||||
|
|
||||||
#: ../js/gdm/powerMenu.js:157
|
#: ../js/gdm/powerMenu.js:160
|
||||||
msgid "Restart"
|
msgid "Restart"
|
||||||
msgstr "પુન:શરૂ કરો"
|
msgstr "પુન:શરૂ કરો"
|
||||||
|
|
||||||
#: ../js/gdm/powerMenu.js:162
|
#: ../js/gdm/powerMenu.js:165
|
||||||
msgid "Power Off"
|
msgid "Power Off"
|
||||||
msgstr "પાવર બંધ"
|
msgstr "પાવર બંધ"
|
||||||
|
|
||||||
@ -255,30 +260,30 @@ msgstr "આદેશનું પદચ્છેદન કરી શક્યા
|
|||||||
#: ../js/misc/util.js:127
|
#: ../js/misc/util.js:127
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "Execution of '%s' failed:"
|
msgid "Execution of '%s' failed:"
|
||||||
msgstr ""
|
msgstr "'%s' ને અમલમાં મૂકવાનુ નિષ્ફળ:"
|
||||||
|
|
||||||
#. Translators: Filter to display all applications
|
#. Translators: Filter to display all applications
|
||||||
#: ../js/ui/appDisplay.js:251
|
#: ../js/ui/appDisplay.js:255
|
||||||
msgid "All"
|
msgid "All"
|
||||||
msgstr "બધા"
|
msgstr "બધા"
|
||||||
|
|
||||||
#: ../js/ui/appDisplay.js:310
|
#: ../js/ui/appDisplay.js:314
|
||||||
msgid "APPLICATIONS"
|
msgid "APPLICATIONS"
|
||||||
msgstr "APPLICATIONS"
|
msgstr "APPLICATIONS"
|
||||||
|
|
||||||
#: ../js/ui/appDisplay.js:371
|
#: ../js/ui/appDisplay.js:375
|
||||||
msgid "SETTINGS"
|
msgid "SETTINGS"
|
||||||
msgstr "SETTINGS"
|
msgstr "SETTINGS"
|
||||||
|
|
||||||
#: ../js/ui/appDisplay.js:676
|
#: ../js/ui/appDisplay.js:680
|
||||||
msgid "New Window"
|
msgid "New Window"
|
||||||
msgstr "નવી વિન્ડો"
|
msgstr "નવી વિન્ડો"
|
||||||
|
|
||||||
#: ../js/ui/appDisplay.js:679
|
#: ../js/ui/appDisplay.js:683
|
||||||
msgid "Remove from Favorites"
|
msgid "Remove from Favorites"
|
||||||
msgstr "પસંદીદાઓ માંથી દૂર કરો"
|
msgstr "પસંદીદાઓ માંથી દૂર કરો"
|
||||||
|
|
||||||
#: ../js/ui/appDisplay.js:680
|
#: ../js/ui/appDisplay.js:684
|
||||||
msgid "Add to Favorites"
|
msgid "Add to Favorites"
|
||||||
msgstr "પસંદીદાને ઉમેરો"
|
msgstr "પસંદીદાને ઉમેરો"
|
||||||
|
|
||||||
@ -294,15 +299,14 @@ msgstr "%s ને તમારી પસંદીદામાંથી દૂર
|
|||||||
|
|
||||||
#: ../js/ui/autorunManager.js:265
|
#: ../js/ui/autorunManager.js:265
|
||||||
msgid "Removable Devices"
|
msgid "Removable Devices"
|
||||||
msgstr ""
|
msgstr "દૂર કરી શકાય તેવા ઉપકરણો"
|
||||||
|
|
||||||
#: ../js/ui/autorunManager.js:560
|
#: ../js/ui/autorunManager.js:560
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "Open with %s"
|
msgid "Open with %s"
|
||||||
msgstr ""
|
msgstr "%s સાથે ખોલો"
|
||||||
|
|
||||||
#: ../js/ui/autorunManager.js:586
|
#: ../js/ui/autorunManager.js:586
|
||||||
#| msgid "Reject"
|
|
||||||
msgid "Eject"
|
msgid "Eject"
|
||||||
msgstr "રદ કરો"
|
msgstr "રદ કરો"
|
||||||
|
|
||||||
@ -422,7 +426,7 @@ msgstr "S"
|
|||||||
#. Translators: Text to show if there are no events
|
#. Translators: Text to show if there are no events
|
||||||
#: ../js/ui/calendar.js:681
|
#: ../js/ui/calendar.js:681
|
||||||
msgid "Nothing Scheduled"
|
msgid "Nothing Scheduled"
|
||||||
msgstr ""
|
msgstr "અનુસૂચિત કંઇ નથી"
|
||||||
|
|
||||||
#. Translators: Shown on calendar heading when selected day occurs on current year
|
#. Translators: Shown on calendar heading when selected day occurs on current year
|
||||||
#: ../js/ui/calendar.js:697
|
#: ../js/ui/calendar.js:697
|
||||||
@ -452,99 +456,97 @@ msgstr "આ અઠવાડિયે"
|
|||||||
msgid "Next week"
|
msgid "Next week"
|
||||||
msgstr "આગળનું અઠવાડિયું"
|
msgstr "આગળનું અઠવાડિયું"
|
||||||
|
|
||||||
#: ../js/ui/contactDisplay.js:63 ../js/ui/notificationDaemon.js:486
|
#: ../js/ui/contactDisplay.js:66 ../js/ui/notificationDaemon.js:486
|
||||||
#: ../js/ui/status/power.js:215 ../src/shell-app.c:372
|
#: ../js/ui/status/power.js:215 ../src/shell-app.c:374
|
||||||
msgid "Unknown"
|
msgid "Unknown"
|
||||||
msgstr "અજ્ઞાત"
|
msgstr "અજ્ઞાત"
|
||||||
|
|
||||||
#: ../js/ui/contactDisplay.js:84 ../js/ui/userMenu.js:127
|
#: ../js/ui/contactDisplay.js:89 ../js/ui/userMenu.js:129
|
||||||
msgid "Available"
|
msgid "Available"
|
||||||
msgstr "ઉપલબ્ધ"
|
msgstr "ઉપલબ્ધ"
|
||||||
|
|
||||||
#: ../js/ui/contactDisplay.js:89 ../js/ui/userMenu.js:136
|
#: ../js/ui/contactDisplay.js:94 ../js/ui/userMenu.js:138
|
||||||
msgid "Away"
|
msgid "Away"
|
||||||
msgstr ""
|
msgstr "દૂર"
|
||||||
|
|
||||||
#: ../js/ui/contactDisplay.js:93 ../js/ui/userMenu.js:130
|
#: ../js/ui/contactDisplay.js:98 ../js/ui/userMenu.js:132
|
||||||
msgid "Busy"
|
msgid "Busy"
|
||||||
msgstr "વ્યસ્ત"
|
msgstr "વ્યસ્ત"
|
||||||
|
|
||||||
#: ../js/ui/contactDisplay.js:97
|
#: ../js/ui/contactDisplay.js:102
|
||||||
msgid "Offline"
|
msgid "Offline"
|
||||||
msgstr "ઓફલાઇન"
|
msgstr "ઓફલાઇન"
|
||||||
|
|
||||||
#: ../js/ui/contactDisplay.js:148
|
#: ../js/ui/contactDisplay.js:153
|
||||||
msgid "CONTACTS"
|
msgid "CONTACTS"
|
||||||
msgstr ""
|
msgstr "સંપર્કો"
|
||||||
|
|
||||||
#: ../js/ui/dash.js:229 ../js/ui/messageTray.js:1204
|
#: ../js/ui/dash.js:229 ../js/ui/messageTray.js:1207
|
||||||
msgid "Remove"
|
msgid "Remove"
|
||||||
msgstr "દૂર કરો"
|
msgstr "દૂર કરો"
|
||||||
|
|
||||||
#: ../js/ui/dateMenu.js:97
|
#: ../js/ui/dateMenu.js:103
|
||||||
msgid "Date and Time Settings"
|
msgid "Date and Time Settings"
|
||||||
msgstr "તારીખ અને સમય સુયોજનો"
|
msgstr "તારીખ અને સમય સુયોજનો"
|
||||||
|
|
||||||
#: ../js/ui/dateMenu.js:123
|
#: ../js/ui/dateMenu.js:129
|
||||||
msgid "Open Calendar"
|
msgid "Open Calendar"
|
||||||
msgstr "કૅલેન્ડરને ખોલો"
|
msgstr "કૅલેન્ડરને ખોલો"
|
||||||
|
|
||||||
#. Translators: This is the time format with date used
|
#. Translators: This is the time format with date used
|
||||||
#. in 24-hour mode.
|
#. in 24-hour mode.
|
||||||
#: ../js/ui/dateMenu.js:181
|
#: ../js/ui/dateMenu.js:187
|
||||||
msgid "%a %b %e, %R:%S"
|
msgid "%a %b %e, %R:%S"
|
||||||
msgstr "%a %b %e, %R:%S"
|
msgstr "%a %b %e, %R:%S"
|
||||||
|
|
||||||
#: ../js/ui/dateMenu.js:182
|
#: ../js/ui/dateMenu.js:188
|
||||||
msgid "%a %b %e, %R"
|
msgid "%a %b %e, %R"
|
||||||
msgstr "%a %b %e, %R"
|
msgstr "%a %b %e, %R"
|
||||||
|
|
||||||
#. Translators: This is the time format without date used
|
#. Translators: This is the time format without date used
|
||||||
#. in 24-hour mode.
|
#. in 24-hour mode.
|
||||||
#: ../js/ui/dateMenu.js:186
|
#: ../js/ui/dateMenu.js:192
|
||||||
msgid "%a %R:%S"
|
msgid "%a %R:%S"
|
||||||
msgstr "%a %R:%S"
|
msgstr "%a %R:%S"
|
||||||
|
|
||||||
#: ../js/ui/dateMenu.js:187
|
#: ../js/ui/dateMenu.js:193
|
||||||
msgid "%a %R"
|
msgid "%a %R"
|
||||||
msgstr "%a %R"
|
msgstr "%a %R"
|
||||||
|
|
||||||
#. Translators: This is a time format with date used
|
#. Translators: This is a time format with date used
|
||||||
#. for AM/PM.
|
#. for AM/PM.
|
||||||
#: ../js/ui/dateMenu.js:194
|
#: ../js/ui/dateMenu.js:200
|
||||||
msgid "%a %b %e, %l:%M:%S %p"
|
msgid "%a %b %e, %l:%M:%S %p"
|
||||||
msgstr "%a %b %e, %l:%M:%S %p"
|
msgstr "%a %b %e, %l:%M:%S %p"
|
||||||
|
|
||||||
#: ../js/ui/dateMenu.js:195
|
#: ../js/ui/dateMenu.js:201
|
||||||
msgid "%a %b %e, %l:%M %p"
|
msgid "%a %b %e, %l:%M %p"
|
||||||
msgstr "%a %b %e, %l:%M %p"
|
msgstr "%a %b %e, %l:%M %p"
|
||||||
|
|
||||||
#. Translators: This is a time format without date used
|
#. Translators: This is a time format without date used
|
||||||
#. for AM/PM.
|
#. for AM/PM.
|
||||||
#: ../js/ui/dateMenu.js:199
|
#: ../js/ui/dateMenu.js:205
|
||||||
msgid "%a %l:%M:%S %p"
|
msgid "%a %l:%M:%S %p"
|
||||||
msgstr "%a %l:%M:%S %p"
|
msgstr "%a %l:%M:%S %p"
|
||||||
|
|
||||||
#: ../js/ui/dateMenu.js:200
|
#: ../js/ui/dateMenu.js:206
|
||||||
msgid "%a %l:%M %p"
|
msgid "%a %l:%M %p"
|
||||||
msgstr "%a %l:%M %p"
|
msgstr "%a %l:%M %p"
|
||||||
|
|
||||||
#. Translators: This is the date format to use when the calendar popup is
|
#. Translators: This is the date format to use when the calendar popup is
|
||||||
#. * shown - it is shown just below the time in the shell (e.g. "Tue 9:29 AM").
|
#. * shown - it is shown just below the time in the shell (e.g. "Tue 9:29 AM").
|
||||||
#.
|
#.
|
||||||
#: ../js/ui/dateMenu.js:211
|
#: ../js/ui/dateMenu.js:217
|
||||||
msgid "%A %B %e, %Y"
|
msgid "%A %B %e, %Y"
|
||||||
msgstr "%A %B %e, %Y"
|
msgstr "%A %B %e, %Y"
|
||||||
|
|
||||||
#: ../js/ui/endSessionDialog.js:61
|
#: ../js/ui/endSessionDialog.js:61
|
||||||
#, c-format
|
#, c-format
|
||||||
#| msgid "Log Out %s"
|
|
||||||
msgctxt "title"
|
msgctxt "title"
|
||||||
msgid "Log Out %s"
|
msgid "Log Out %s"
|
||||||
msgstr "%s માંથી બહાર નીકળો"
|
msgstr "%s માંથી બહાર નીકળો"
|
||||||
|
|
||||||
#: ../js/ui/endSessionDialog.js:62
|
#: ../js/ui/endSessionDialog.js:62
|
||||||
#| msgid "Log Out"
|
|
||||||
msgctxt "title"
|
msgctxt "title"
|
||||||
msgid "Log Out"
|
msgid "Log Out"
|
||||||
msgstr "બહાર નીકળો"
|
msgstr "બહાર નીકળો"
|
||||||
@ -556,7 +558,6 @@ msgstr ""
|
|||||||
|
|
||||||
#: ../js/ui/endSessionDialog.js:65
|
#: ../js/ui/endSessionDialog.js:65
|
||||||
#, c-format
|
#, c-format
|
||||||
#| msgid "The system will power off automatically in %d seconds."
|
|
||||||
msgid "%s will be logged out automatically in %d second."
|
msgid "%s will be logged out automatically in %d second."
|
||||||
msgid_plural "%s will be logged out automatically in %d seconds."
|
msgid_plural "%s will be logged out automatically in %d seconds."
|
||||||
msgstr[0] "%s એ %d સેકંડમાં આપમેળે બહાર નીકળી જશે."
|
msgstr[0] "%s એ %d સેકંડમાં આપમેળે બહાર નીકળી જશે."
|
||||||
@ -564,7 +565,6 @@ msgstr[1] "%s એ %d સેકંડોમાં આપમેળે બહાર
|
|||||||
|
|
||||||
#: ../js/ui/endSessionDialog.js:70
|
#: ../js/ui/endSessionDialog.js:70
|
||||||
#, c-format
|
#, c-format
|
||||||
#| msgid "The system will power off automatically in %d seconds."
|
|
||||||
msgid "You will be logged out automatically in %d second."
|
msgid "You will be logged out automatically in %d second."
|
||||||
msgid_plural "You will be logged out automatically in %d seconds."
|
msgid_plural "You will be logged out automatically in %d seconds."
|
||||||
msgstr[0] "તમે %d સેકંડમાં આપમેળે બહાર નીકળી જશે."
|
msgstr[0] "તમે %d સેકંડમાં આપમેળે બહાર નીકળી જશે."
|
||||||
@ -575,13 +575,11 @@ msgid "Logging out of the system."
|
|||||||
msgstr "સિસ્ટમની બહાર નીકળી રહ્યા છે."
|
msgstr "સિસ્ટમની બહાર નીકળી રહ્યા છે."
|
||||||
|
|
||||||
#: ../js/ui/endSessionDialog.js:76
|
#: ../js/ui/endSessionDialog.js:76
|
||||||
#| msgid "Log Out"
|
|
||||||
msgctxt "button"
|
msgctxt "button"
|
||||||
msgid "Log Out"
|
msgid "Log Out"
|
||||||
msgstr "બહાર નીકળો"
|
msgstr "બહાર નીકળો"
|
||||||
|
|
||||||
#: ../js/ui/endSessionDialog.js:81
|
#: ../js/ui/endSessionDialog.js:81
|
||||||
#| msgid "Power Off"
|
|
||||||
msgctxt "title"
|
msgctxt "title"
|
||||||
msgid "Power Off"
|
msgid "Power Off"
|
||||||
msgstr "પાવર બંધ"
|
msgstr "પાવર બંધ"
|
||||||
@ -593,7 +591,6 @@ msgstr ""
|
|||||||
|
|
||||||
#: ../js/ui/endSessionDialog.js:84
|
#: ../js/ui/endSessionDialog.js:84
|
||||||
#, c-format
|
#, c-format
|
||||||
#| msgid "The system will power off automatically in %d seconds."
|
|
||||||
msgid "The system will power off automatically in %d second."
|
msgid "The system will power off automatically in %d second."
|
||||||
msgid_plural "The system will power off automatically in %d seconds."
|
msgid_plural "The system will power off automatically in %d seconds."
|
||||||
msgstr[0] "સિસ્ટમ %d સેકંડમાં આપમેળે પાવર બંધ થઇ જશે."
|
msgstr[0] "સિસ્ટમ %d સેકંડમાં આપમેળે પાવર બંધ થઇ જશે."
|
||||||
@ -604,19 +601,16 @@ msgid "Powering off the system."
|
|||||||
msgstr "સિસ્ટમનો પાવર બંધ કરી રહ્યા છે."
|
msgstr "સિસ્ટમનો પાવર બંધ કરી રહ્યા છે."
|
||||||
|
|
||||||
#: ../js/ui/endSessionDialog.js:90 ../js/ui/endSessionDialog.js:107
|
#: ../js/ui/endSessionDialog.js:90 ../js/ui/endSessionDialog.js:107
|
||||||
#| msgid "Restart"
|
|
||||||
msgctxt "button"
|
msgctxt "button"
|
||||||
msgid "Restart"
|
msgid "Restart"
|
||||||
msgstr "પુન:શરૂ કરો"
|
msgstr "પુન:શરૂ કરો"
|
||||||
|
|
||||||
#: ../js/ui/endSessionDialog.js:92
|
#: ../js/ui/endSessionDialog.js:92
|
||||||
#| msgid "Power Off"
|
|
||||||
msgctxt "button"
|
msgctxt "button"
|
||||||
msgid "Power Off"
|
msgid "Power Off"
|
||||||
msgstr "પાવર બંધ"
|
msgstr "પાવર બંધ"
|
||||||
|
|
||||||
#: ../js/ui/endSessionDialog.js:98
|
#: ../js/ui/endSessionDialog.js:98
|
||||||
#| msgid "Restart"
|
|
||||||
msgctxt "title"
|
msgctxt "title"
|
||||||
msgid "Restart"
|
msgid "Restart"
|
||||||
msgstr "પુન:શરૂ કરો"
|
msgstr "પુન:શરૂ કરો"
|
||||||
@ -628,7 +622,6 @@ msgstr ""
|
|||||||
|
|
||||||
#: ../js/ui/endSessionDialog.js:101
|
#: ../js/ui/endSessionDialog.js:101
|
||||||
#, c-format
|
#, c-format
|
||||||
#| msgid "The system will restart automatically in %d seconds."
|
|
||||||
msgid "The system will restart automatically in %d second."
|
msgid "The system will restart automatically in %d second."
|
||||||
msgid_plural "The system will restart automatically in %d seconds."
|
msgid_plural "The system will restart automatically in %d seconds."
|
||||||
msgstr[0] "સિસ્ટમ %d સેકંડમાં આપમેળે પુન:શરૂ થઇ જશે."
|
msgstr[0] "સિસ્ટમ %d સેકંડમાં આપમેળે પુન:શરૂ થઇ જશે."
|
||||||
@ -638,21 +631,20 @@ msgstr[1] "સિસ્ટમ %d સેકંડોમાં આપમેળે
|
|||||||
msgid "Restarting the system."
|
msgid "Restarting the system."
|
||||||
msgstr "સિસ્ટમને પુન:શરૂ કરી રહ્યા છે."
|
msgstr "સિસ્ટમને પુન:શરૂ કરી રહ્યા છે."
|
||||||
|
|
||||||
#: ../js/ui/extensionSystem.js:405
|
#: ../js/ui/extensionSystem.js:403
|
||||||
msgid "Install"
|
msgid "Install"
|
||||||
msgstr "સ્થાપિત કરો"
|
msgstr "સ્થાપિત કરો"
|
||||||
|
|
||||||
#: ../js/ui/extensionSystem.js:409
|
#: ../js/ui/extensionSystem.js:407
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "Download and install '%s' from extensions.gnome.org?"
|
msgid "Download and install '%s' from extensions.gnome.org?"
|
||||||
msgstr "extensions.gnome.org માંથી '%s' ને સ્થાપિત અને ડાઉનલોડ કરો?"
|
msgstr "extensions.gnome.org માંથી '%s' ને સ્થાપિત અને ડાઉનલોડ કરો?"
|
||||||
|
|
||||||
#: ../js/ui/keyboard.js:322
|
#: ../js/ui/keyboard.js:327
|
||||||
#| msgid "Retry"
|
|
||||||
msgid "tray"
|
msgid "tray"
|
||||||
msgstr "ટ્રે"
|
msgstr "ટ્રે"
|
||||||
|
|
||||||
#: ../js/ui/keyboard.js:539 ../js/ui/status/power.js:203
|
#: ../js/ui/keyboard.js:544 ../js/ui/status/power.js:203
|
||||||
msgid "Keyboard"
|
msgid "Keyboard"
|
||||||
msgstr "કિબોર્ડ"
|
msgstr "કિબોર્ડ"
|
||||||
|
|
||||||
@ -664,78 +656,73 @@ msgstr "પાસવર્ડ:"
|
|||||||
msgid "Type again:"
|
msgid "Type again:"
|
||||||
msgstr "ફરીથી પ્રયત્ન કરો:"
|
msgstr "ફરીથી પ્રયત્ન કરો:"
|
||||||
|
|
||||||
#: ../js/ui/lookingGlass.js:725
|
#: ../js/ui/lookingGlass.js:732
|
||||||
msgid "No extensions installed"
|
msgid "No extensions installed"
|
||||||
msgstr "એક્સટેન્શનો સ્થાપિત થયેલ નથી"
|
msgstr "એક્સટેન્શનો સ્થાપિત થયેલ નથી"
|
||||||
|
|
||||||
#. Translators: argument is an extension UUID.
|
#. Translators: argument is an extension UUID.
|
||||||
#: ../js/ui/lookingGlass.js:779
|
#: ../js/ui/lookingGlass.js:786
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "%s has not emitted any errors."
|
msgid "%s has not emitted any errors."
|
||||||
msgstr ""
|
msgstr "%s એ કોઇપણ ભૂલોને બહાર કાઢતા નથી."
|
||||||
|
|
||||||
#: ../js/ui/lookingGlass.js:785
|
#: ../js/ui/lookingGlass.js:792
|
||||||
#| msgid "Error"
|
|
||||||
msgid "Hide Errors"
|
msgid "Hide Errors"
|
||||||
msgstr "ભૂલો છુપાડો"
|
msgstr "ભૂલો છુપાડો"
|
||||||
|
|
||||||
#: ../js/ui/lookingGlass.js:789 ../js/ui/lookingGlass.js:840
|
#: ../js/ui/lookingGlass.js:796 ../js/ui/lookingGlass.js:847
|
||||||
#| msgid "Error"
|
|
||||||
msgid "Show Errors"
|
msgid "Show Errors"
|
||||||
msgstr "ભૂલો બતાવો"
|
msgstr "ભૂલો બતાવો"
|
||||||
|
|
||||||
#: ../js/ui/lookingGlass.js:798
|
#: ../js/ui/lookingGlass.js:805
|
||||||
msgid "Enabled"
|
msgid "Enabled"
|
||||||
msgstr "સક્રિય"
|
msgstr "સક્રિય"
|
||||||
|
|
||||||
#. translators:
|
#. translators:
|
||||||
#. * The device has been disabled
|
#. * The device has been disabled
|
||||||
#: ../js/ui/lookingGlass.js:801 ../src/gvc/gvc-mixer-control.c:1093
|
#: ../js/ui/lookingGlass.js:808 ../src/gvc/gvc-mixer-control.c:1093
|
||||||
msgid "Disabled"
|
msgid "Disabled"
|
||||||
msgstr "નિષ્ક્રિય"
|
msgstr "નિષ્ક્રિય"
|
||||||
|
|
||||||
#: ../js/ui/lookingGlass.js:803
|
#: ../js/ui/lookingGlass.js:810
|
||||||
msgid "Error"
|
msgid "Error"
|
||||||
msgstr "ભૂલ"
|
msgstr "ભૂલ"
|
||||||
|
|
||||||
#: ../js/ui/lookingGlass.js:805
|
#: ../js/ui/lookingGlass.js:812
|
||||||
msgid "Out of date"
|
msgid "Out of date"
|
||||||
msgstr "અપ્રચલિત"
|
msgstr "અપ્રચલિત"
|
||||||
|
|
||||||
#: ../js/ui/lookingGlass.js:807
|
#: ../js/ui/lookingGlass.js:814
|
||||||
msgid "Downloading"
|
msgid "Downloading"
|
||||||
msgstr "ડાઉનલોડ કરી રહ્યા છે"
|
msgstr "ડાઉનલોડ કરી રહ્યા છે"
|
||||||
|
|
||||||
#: ../js/ui/lookingGlass.js:828
|
#: ../js/ui/lookingGlass.js:835
|
||||||
msgid "View Source"
|
msgid "View Source"
|
||||||
msgstr "સ્ત્રોત દર્શાવો"
|
msgstr "સ્ત્રોત દર્શાવો"
|
||||||
|
|
||||||
#: ../js/ui/lookingGlass.js:834
|
#: ../js/ui/lookingGlass.js:841
|
||||||
msgid "Web Page"
|
msgid "Web Page"
|
||||||
msgstr "વેબ પાનું"
|
msgstr "વેબ પાનું"
|
||||||
|
|
||||||
#. Translators: this is a filename used for screencast recording
|
#. Translators: this is a filename used for screencast recording
|
||||||
#: ../js/ui/main.js:116
|
#: ../js/ui/main.js:118
|
||||||
#, no-c-format
|
#, no-c-format
|
||||||
msgid "Screencast from %d %t"
|
msgid "Screencast from %d %t"
|
||||||
msgstr "%d %t માંથી સ્ક્રીનકાસ્ટ"
|
msgstr "%d %t માંથી સ્ક્રીનકાસ્ટ"
|
||||||
|
|
||||||
#: ../js/ui/messageTray.js:1197
|
#: ../js/ui/messageTray.js:1200
|
||||||
msgid "Open"
|
msgid "Open"
|
||||||
msgstr "ખોલો"
|
msgstr "ખોલો"
|
||||||
|
|
||||||
#: ../js/ui/messageTray.js:1214
|
#: ../js/ui/messageTray.js:1217
|
||||||
#| msgid "minute"
|
|
||||||
#| msgid_plural "minutes"
|
|
||||||
msgid "Unmute"
|
msgid "Unmute"
|
||||||
msgstr "અવાજ ચાલુ રાખો"
|
msgstr "અવાજ ચાલુ રાખો"
|
||||||
|
|
||||||
#: ../js/ui/messageTray.js:1214
|
#: ../js/ui/messageTray.js:1217
|
||||||
#| msgid "Mouse"
|
|
||||||
msgid "Mute"
|
msgid "Mute"
|
||||||
msgstr "મૂંગુ"
|
msgstr "મૂંગુ"
|
||||||
|
|
||||||
#: ../js/ui/messageTray.js:2447
|
#: ../js/ui/messageTray.js:2490
|
||||||
msgid "System Information"
|
msgid "System Information"
|
||||||
msgstr "સિસ્ટમ જાણકારી"
|
msgstr "સિસ્ટમ જાણકારી"
|
||||||
|
|
||||||
@ -815,40 +802,42 @@ msgstr "મોબાઇલ બ્રોડબેન્ડ નેટવર્ક
|
|||||||
|
|
||||||
#: ../js/ui/networkAgent.js:357
|
#: ../js/ui/networkAgent.js:357
|
||||||
#, c-format
|
#, c-format
|
||||||
#| msgid "You're now connected to '%s'"
|
|
||||||
msgid "A password is required to connect to '%s'."
|
msgid "A password is required to connect to '%s'."
|
||||||
msgstr "પાસવર્ડ '%s' સાથે જોડાવા માટે જરૂરી છે."
|
msgstr "પાસવર્ડ '%s' સાથે જોડાવા માટે જરૂરી છે."
|
||||||
|
|
||||||
#: ../js/ui/overview.js:90
|
#: ../js/ui/overview.js:90
|
||||||
msgid "Undo"
|
msgid "Undo"
|
||||||
msgstr ""
|
msgstr "રદ કરો"
|
||||||
|
|
||||||
#: ../js/ui/overview.js:199
|
#: ../js/ui/overview.js:132
|
||||||
|
msgid "Overview"
|
||||||
|
msgstr "ઝાંખી"
|
||||||
|
|
||||||
|
#: ../js/ui/overview.js:202
|
||||||
msgid "Windows"
|
msgid "Windows"
|
||||||
msgstr "વિન્ડો"
|
msgstr "વિન્ડો"
|
||||||
|
|
||||||
#: ../js/ui/overview.js:202
|
#: ../js/ui/overview.js:205
|
||||||
msgid "Applications"
|
msgid "Applications"
|
||||||
msgstr "કાર્યક્રમો"
|
msgstr "કાર્યક્રમો"
|
||||||
|
|
||||||
#. Translators: this is the name of the dock/favorites area on
|
#. Translators: this is the name of the dock/favorites area on
|
||||||
#. the left of the overview
|
#. the left of the overview
|
||||||
#: ../js/ui/overview.js:228
|
#: ../js/ui/overview.js:231
|
||||||
msgid "Dash"
|
msgid "Dash"
|
||||||
msgstr "ડૅશ"
|
msgstr "ડૅશ"
|
||||||
|
|
||||||
#: ../js/ui/panel.js:583
|
#: ../js/ui/panel.js:592
|
||||||
#| msgid "Quit %s"
|
|
||||||
msgid "Quit"
|
msgid "Quit"
|
||||||
msgstr "બહાર નીકળો"
|
msgstr "બહાર નીકળો"
|
||||||
|
|
||||||
#. Translators: If there is no suitable word for "Activities"
|
#. Translators: If there is no suitable word for "Activities"
|
||||||
#. in your language, you can use the word for "Overview".
|
#. in your language, you can use the word for "Overview".
|
||||||
#: ../js/ui/panel.js:614
|
#: ../js/ui/panel.js:624
|
||||||
msgid "Activities"
|
msgid "Activities"
|
||||||
msgstr "પ્રવૃત્તિઓ"
|
msgstr "પ્રવૃત્તિઓ"
|
||||||
|
|
||||||
#: ../js/ui/panel.js:987
|
#: ../js/ui/panel.js:999
|
||||||
msgid "Top Bar"
|
msgid "Top Bar"
|
||||||
msgstr "ટોચની પટ્ટી"
|
msgstr "ટોચની પટ્ટી"
|
||||||
|
|
||||||
@ -867,7 +856,7 @@ msgstr "ની સાથે જોડાવો..."
|
|||||||
|
|
||||||
#: ../js/ui/placeDisplay.js:367
|
#: ../js/ui/placeDisplay.js:367
|
||||||
msgid "PLACES & DEVICES"
|
msgid "PLACES & DEVICES"
|
||||||
msgstr ""
|
msgstr "સ્થાનો અને ઉપકરણો"
|
||||||
|
|
||||||
#: ../js/ui/polkitAuthenticationAgent.js:71
|
#: ../js/ui/polkitAuthenticationAgent.js:71
|
||||||
msgid "Authentication Required"
|
msgid "Authentication Required"
|
||||||
@ -894,7 +883,7 @@ msgstr "દિલગીર છું, કામ કરતુ નથી. મહ
|
|||||||
#. "ON" and "OFF") or "toggle-switch-intl" (for toggle
|
#. "ON" and "OFF") or "toggle-switch-intl" (for toggle
|
||||||
#. switches containing "◯" and "|"). Other values will
|
#. switches containing "◯" and "|"). Other values will
|
||||||
#. simply result in invisible toggle switches.
|
#. simply result in invisible toggle switches.
|
||||||
#: ../js/ui/popupMenu.js:720
|
#: ../js/ui/popupMenu.js:724
|
||||||
msgid "toggle-switch-us"
|
msgid "toggle-switch-us"
|
||||||
msgstr "toggle-switch-us"
|
msgstr "toggle-switch-us"
|
||||||
|
|
||||||
@ -902,11 +891,11 @@ msgstr "toggle-switch-us"
|
|||||||
msgid "Please enter a command:"
|
msgid "Please enter a command:"
|
||||||
msgstr "મહેરબાની કરીને આદેશને દાખલ કરો:"
|
msgstr "મહેરબાની કરીને આદેશને દાખલ કરો:"
|
||||||
|
|
||||||
#: ../js/ui/searchDisplay.js:349
|
#: ../js/ui/searchDisplay.js:332
|
||||||
msgid "Searching..."
|
msgid "Searching..."
|
||||||
msgstr "શોધી રહ્યા છે..."
|
msgstr "શોધી રહ્યા છે..."
|
||||||
|
|
||||||
#: ../js/ui/searchDisplay.js:417
|
#: ../js/ui/searchDisplay.js:414
|
||||||
msgid "No matching results."
|
msgid "No matching results."
|
||||||
msgstr "પરિણામો બંધબેસતાનથી."
|
msgstr "પરિણામો બંધબેસતાનથી."
|
||||||
|
|
||||||
@ -923,7 +912,6 @@ msgid "Show Text"
|
|||||||
msgstr "લખાણ બતાવો"
|
msgstr "લખાણ બતાવો"
|
||||||
|
|
||||||
#: ../js/ui/shellEntry.js:79
|
#: ../js/ui/shellEntry.js:79
|
||||||
#| msgid "Large Text"
|
|
||||||
msgid "Hide Text"
|
msgid "Hide Text"
|
||||||
msgstr "લખાણ છુપાડો"
|
msgstr "લખાણ છુપાડો"
|
||||||
|
|
||||||
@ -932,7 +920,6 @@ msgid "Wrong password, please try again"
|
|||||||
msgstr "ખોટો પાસવર્ડ, મહેરબાની કરીને ફરીથી પ્રયત્ન કરો"
|
msgstr "ખોટો પાસવર્ડ, મહેરબાની કરીને ફરીથી પ્રયત્ન કરો"
|
||||||
|
|
||||||
#: ../js/ui/status/accessibility.js:47
|
#: ../js/ui/status/accessibility.js:47
|
||||||
#| msgid "Visibility"
|
|
||||||
msgid "Accessibility"
|
msgid "Accessibility"
|
||||||
msgstr "ઉપલબ્ધતા"
|
msgstr "ઉપલબ્ધતા"
|
||||||
|
|
||||||
@ -944,13 +931,12 @@ msgstr "નાનુ મોટુ કરો"
|
|||||||
#. 'screen-reader-enabled');
|
#. 'screen-reader-enabled');
|
||||||
#. this.menu.addMenuItem(screenReader);
|
#. this.menu.addMenuItem(screenReader);
|
||||||
#: ../js/ui/status/accessibility.js:63
|
#: ../js/ui/status/accessibility.js:63
|
||||||
#| msgid "Keyboard"
|
|
||||||
msgid "Screen Keyboard"
|
msgid "Screen Keyboard"
|
||||||
msgstr "સ્ક્રીન કિબોર્ડ"
|
msgstr "સ્ક્રીન કિબોર્ડ"
|
||||||
|
|
||||||
#: ../js/ui/status/accessibility.js:67
|
#: ../js/ui/status/accessibility.js:67
|
||||||
msgid "Visual Alerts"
|
msgid "Visual Alerts"
|
||||||
msgstr ""
|
msgstr "દેખાતી ચેતવણીઓ"
|
||||||
|
|
||||||
#: ../js/ui/status/accessibility.js:70
|
#: ../js/ui/status/accessibility.js:70
|
||||||
msgid "Sticky Keys"
|
msgid "Sticky Keys"
|
||||||
@ -1013,7 +999,6 @@ msgid "Connection"
|
|||||||
msgstr "જોડાણ"
|
msgstr "જોડાણ"
|
||||||
|
|
||||||
#: ../js/ui/status/bluetooth.js:214 ../js/ui/status/network.js:491
|
#: ../js/ui/status/bluetooth.js:214 ../js/ui/status/network.js:491
|
||||||
#| msgid "connecting..."
|
|
||||||
msgid "disconnecting..."
|
msgid "disconnecting..."
|
||||||
msgstr "જોડાઇ તૂટી રહ્યુ છે..."
|
msgstr "જોડાઇ તૂટી રહ્યુ છે..."
|
||||||
|
|
||||||
@ -1058,7 +1043,7 @@ msgstr "%s માંથી સત્તાધિકરણ માંગણી"
|
|||||||
#: ../js/ui/status/bluetooth.js:378
|
#: ../js/ui/status/bluetooth.js:378
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "Device %s wants access to the service '%s'"
|
msgid "Device %s wants access to the service '%s'"
|
||||||
msgstr ""
|
msgstr "ઉપકરણ %s એ સેવા %s' માટે પ્રવેશ ઇચ્છે છે"
|
||||||
|
|
||||||
#: ../js/ui/status/bluetooth.js:380
|
#: ../js/ui/status/bluetooth.js:380
|
||||||
msgid "Always grant access"
|
msgid "Always grant access"
|
||||||
@ -1075,12 +1060,12 @@ msgstr "રદ કરો"
|
|||||||
#: ../js/ui/status/bluetooth.js:408
|
#: ../js/ui/status/bluetooth.js:408
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "Pairing confirmation for %s"
|
msgid "Pairing confirmation for %s"
|
||||||
msgstr ""
|
msgstr "%s માટો જોડીની ખાતરી"
|
||||||
|
|
||||||
#: ../js/ui/status/bluetooth.js:414 ../js/ui/status/bluetooth.js:444
|
#: ../js/ui/status/bluetooth.js:414 ../js/ui/status/bluetooth.js:444
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "Device %s wants to pair with this computer"
|
msgid "Device %s wants to pair with this computer"
|
||||||
msgstr ""
|
msgstr "ઉપકરણ %s આ કમ્પ્યૂટર સાથે જોડી કરવા માંગે છે"
|
||||||
|
|
||||||
#: ../js/ui/status/bluetooth.js:415
|
#: ../js/ui/status/bluetooth.js:415
|
||||||
#, c-format
|
#, c-format
|
||||||
@ -1098,7 +1083,7 @@ msgstr "બંધબેસતુ નથી"
|
|||||||
#: ../js/ui/status/bluetooth.js:437
|
#: ../js/ui/status/bluetooth.js:437
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "Pairing request for %s"
|
msgid "Pairing request for %s"
|
||||||
msgstr ""
|
msgstr "%s માટે જોડી માંગણી"
|
||||||
|
|
||||||
#: ../js/ui/status/bluetooth.js:445
|
#: ../js/ui/status/bluetooth.js:445
|
||||||
msgid "Please enter the PIN mentioned on the device."
|
msgid "Please enter the PIN mentioned on the device."
|
||||||
@ -1182,12 +1167,10 @@ msgstr ""
|
|||||||
#. TRANSLATORS: this the automatic wireless connection name (including the network name)
|
#. TRANSLATORS: this the automatic wireless connection name (including the network name)
|
||||||
#: ../js/ui/status/network.js:879 ../js/ui/status/network.js:1452
|
#: ../js/ui/status/network.js:879 ../js/ui/status/network.js:1452
|
||||||
#, c-format
|
#, c-format
|
||||||
#| msgid "Quit %s"
|
|
||||||
msgid "Auto %s"
|
msgid "Auto %s"
|
||||||
msgstr "આપમેળે %s"
|
msgstr "આપમેળે %s"
|
||||||
|
|
||||||
#: ../js/ui/status/network.js:881
|
#: ../js/ui/status/network.js:881
|
||||||
#| msgid "Bluetooth"
|
|
||||||
msgid "Auto bluetooth"
|
msgid "Auto bluetooth"
|
||||||
msgstr "આપમેળે બ્લુટુથ"
|
msgstr "આપમેળે બ્લુટુથ"
|
||||||
|
|
||||||
@ -1196,7 +1179,6 @@ msgid "Auto wireless"
|
|||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: ../js/ui/status/network.js:1541
|
#: ../js/ui/status/network.js:1541
|
||||||
#| msgid "Network error"
|
|
||||||
msgid "Network"
|
msgid "Network"
|
||||||
msgstr "નેટવર્ક"
|
msgstr "નેટવર્ક"
|
||||||
|
|
||||||
@ -1427,7 +1409,7 @@ msgstr "%s માં આમંત્રણ"
|
|||||||
#: ../js/ui/telepathyClient.js:1050
|
#: ../js/ui/telepathyClient.js:1050
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "%s is inviting you to join %s"
|
msgid "%s is inviting you to join %s"
|
||||||
msgstr ""
|
msgstr "%s એ તમને %s માં જોડાવા માટે આમંત્રણ આપી રહ્યા છે"
|
||||||
|
|
||||||
#: ../js/ui/telepathyClient.js:1052 ../js/ui/telepathyClient.js:1131
|
#: ../js/ui/telepathyClient.js:1052 ../js/ui/telepathyClient.js:1131
|
||||||
#: ../js/ui/telepathyClient.js:1229
|
#: ../js/ui/telepathyClient.js:1229
|
||||||
@ -1464,13 +1446,13 @@ msgstr "જવાબ"
|
|||||||
#: ../js/ui/telepathyClient.js:1125
|
#: ../js/ui/telepathyClient.js:1125
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "%s is sending you %s"
|
msgid "%s is sending you %s"
|
||||||
msgstr ""
|
msgstr "%s એ %s માં મોકલી રહ્યા છે"
|
||||||
|
|
||||||
#. To translators: The parameter is the contact's alias
|
#. To translators: The parameter is the contact's alias
|
||||||
#: ../js/ui/telepathyClient.js:1194
|
#: ../js/ui/telepathyClient.js:1194
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "%s would like permission to see when you are online"
|
msgid "%s would like permission to see when you are online"
|
||||||
msgstr ""
|
msgstr "%s ને જોવા માટે પરવાનગી આપવાનું ગમે થે જ્યારે તમે ઓનલાઇન હોય"
|
||||||
|
|
||||||
#: ../js/ui/telepathyClient.js:1287
|
#: ../js/ui/telepathyClient.js:1287
|
||||||
msgid "Network error"
|
msgid "Network error"
|
||||||
@ -1502,11 +1484,11 @@ msgstr "પ્રમાણપત્ર સક્રિય થયેલ નથી
|
|||||||
|
|
||||||
#: ../js/ui/telepathyClient.js:1301
|
#: ../js/ui/telepathyClient.js:1301
|
||||||
msgid "Certificate hostname mismatch"
|
msgid "Certificate hostname mismatch"
|
||||||
msgstr ""
|
msgstr "પ્રમાણપત્ર યજમાનનામ બંધબેસતુ નથી"
|
||||||
|
|
||||||
#: ../js/ui/telepathyClient.js:1303
|
#: ../js/ui/telepathyClient.js:1303
|
||||||
msgid "Certificate fingerprint mismatch"
|
msgid "Certificate fingerprint mismatch"
|
||||||
msgstr ""
|
msgstr "પ્રમાણપજ્ઞ ફિંગરપ્રિન્ટ બંધબેસતુ નથી"
|
||||||
|
|
||||||
#: ../js/ui/telepathyClient.js:1305
|
#: ../js/ui/telepathyClient.js:1305
|
||||||
msgid "Certificate self-signed"
|
msgid "Certificate self-signed"
|
||||||
@ -1525,7 +1507,6 @@ msgid "Certificate is invalid"
|
|||||||
msgstr "પ્રમાણપત્ર અમાન્ય છે"
|
msgstr "પ્રમાણપત્ર અમાન્ય છે"
|
||||||
|
|
||||||
#: ../js/ui/telepathyClient.js:1313
|
#: ../js/ui/telepathyClient.js:1313
|
||||||
#| msgid "Connection established"
|
|
||||||
msgid "Connection has been refused"
|
msgid "Connection has been refused"
|
||||||
msgstr "જોડાણને નામંજૂર કરી દેવામાં આવ્યુ છે"
|
msgstr "જોડાણને નામંજૂર કરી દેવામાં આવ્યુ છે"
|
||||||
|
|
||||||
@ -1538,7 +1519,6 @@ msgid "Connection has been lost"
|
|||||||
msgstr "જોડાણ ખોવાઈ ગયેલ છે"
|
msgstr "જોડાણ ખોવાઈ ગયેલ છે"
|
||||||
|
|
||||||
#: ../js/ui/telepathyClient.js:1319
|
#: ../js/ui/telepathyClient.js:1319
|
||||||
#| msgid "This resource is already connected to the server"
|
|
||||||
msgid "This account is already connected to the server"
|
msgid "This account is already connected to the server"
|
||||||
msgstr "આ ખાતુ પહેલેથી જ સર્વર સાથે જોડાયેલ છે"
|
msgstr "આ ખાતુ પહેલેથી જ સર્વર સાથે જોડાયેલ છે"
|
||||||
|
|
||||||
@ -1556,7 +1536,7 @@ msgstr "સર્વર એ જોડાણને સંચાલિત કર
|
|||||||
|
|
||||||
#: ../js/ui/telepathyClient.js:1327
|
#: ../js/ui/telepathyClient.js:1327
|
||||||
msgid "Certificate has been revoked"
|
msgid "Certificate has been revoked"
|
||||||
msgstr ""
|
msgstr "પ્રમાણપત્રને રદ કરી દેવામાં આવ્યુ છે"
|
||||||
|
|
||||||
#: ../js/ui/telepathyClient.js:1329
|
#: ../js/ui/telepathyClient.js:1329
|
||||||
msgid "Certificate uses an insecure cipher algorithm or is cryptographically weak"
|
msgid "Certificate uses an insecure cipher algorithm or is cryptographically weak"
|
||||||
@ -1569,7 +1549,6 @@ msgid ""
|
|||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: ../js/ui/telepathyClient.js:1333
|
#: ../js/ui/telepathyClient.js:1333
|
||||||
#| msgid "Connection error"
|
|
||||||
msgid "Internal error"
|
msgid "Internal error"
|
||||||
msgstr "આંતરિક ભૂલ"
|
msgstr "આંતરિક ભૂલ"
|
||||||
|
|
||||||
@ -1592,51 +1571,51 @@ msgstr "ખાતામાં ફેરફાર કરો"
|
|||||||
msgid "Unknown reason"
|
msgid "Unknown reason"
|
||||||
msgstr "અજ્ઞાત કારણ"
|
msgstr "અજ્ઞાત કારણ"
|
||||||
|
|
||||||
#: ../js/ui/userMenu.js:133
|
#: ../js/ui/userMenu.js:135
|
||||||
msgid "Hidden"
|
msgid "Hidden"
|
||||||
msgstr "છુપાયેલ"
|
msgstr "છુપાયેલ"
|
||||||
|
|
||||||
#: ../js/ui/userMenu.js:139
|
#: ../js/ui/userMenu.js:141
|
||||||
msgid "Idle"
|
msgid "Idle"
|
||||||
msgstr ""
|
msgstr "નિષ્ક્રિય"
|
||||||
|
|
||||||
#: ../js/ui/userMenu.js:142
|
#: ../js/ui/userMenu.js:144
|
||||||
msgid "Unavailable"
|
msgid "Unavailable"
|
||||||
msgstr "બિનઉપલબ્ધ"
|
msgstr "બિનઉપલબ્ધ"
|
||||||
|
|
||||||
#: ../js/ui/userMenu.js:579 ../js/ui/userMenu.js:583 ../js/ui/userMenu.js:653
|
#: ../js/ui/userMenu.js:595 ../js/ui/userMenu.js:599 ../js/ui/userMenu.js:669
|
||||||
msgid "Power Off..."
|
msgid "Power Off..."
|
||||||
msgstr "પાવર બંધ..."
|
msgstr "પાવર બંધ..."
|
||||||
|
|
||||||
#: ../js/ui/userMenu.js:615
|
#: ../js/ui/userMenu.js:631
|
||||||
msgid "Notifications"
|
msgid "Notifications"
|
||||||
msgstr "સૂચનાઓ"
|
msgstr "સૂચનાઓ"
|
||||||
|
|
||||||
#: ../js/ui/userMenu.js:623
|
#: ../js/ui/userMenu.js:639
|
||||||
msgid "Online Accounts"
|
msgid "Online Accounts"
|
||||||
msgstr "ઓનલાઇન ખાતુ"
|
msgstr "ઓનલાઇન ખાતુ"
|
||||||
|
|
||||||
#: ../js/ui/userMenu.js:627
|
#: ../js/ui/userMenu.js:643
|
||||||
msgid "System Settings"
|
msgid "System Settings"
|
||||||
msgstr "સિસ્ટમ સુયોજનો"
|
msgstr "સિસ્ટમ સુયોજનો"
|
||||||
|
|
||||||
#: ../js/ui/userMenu.js:634
|
#: ../js/ui/userMenu.js:650
|
||||||
msgid "Lock Screen"
|
msgid "Lock Screen"
|
||||||
msgstr "સ્ક્રીનને તાળુ મારો"
|
msgstr "સ્ક્રીનને તાળુ મારો"
|
||||||
|
|
||||||
#: ../js/ui/userMenu.js:639
|
#: ../js/ui/userMenu.js:655
|
||||||
msgid "Switch User"
|
msgid "Switch User"
|
||||||
msgstr "વપરાશકર્તાને બદલો"
|
msgstr "વપરાશકર્તાને બદલો"
|
||||||
|
|
||||||
#: ../js/ui/userMenu.js:644
|
#: ../js/ui/userMenu.js:660
|
||||||
msgid "Log Out..."
|
msgid "Log Out..."
|
||||||
msgstr "બહાર નીકળો..."
|
msgstr "બહાર નીકળો..."
|
||||||
|
|
||||||
#: ../js/ui/userMenu.js:672
|
#: ../js/ui/userMenu.js:688
|
||||||
msgid "Your chat status will be set to busy"
|
msgid "Your chat status will be set to busy"
|
||||||
msgstr ""
|
msgstr "તમારી વાર્તાલાપ પરિસ્થિતિ વ્યસ્ત તરીકે સુયોજિત હશે"
|
||||||
|
|
||||||
#: ../js/ui/userMenu.js:673
|
#: ../js/ui/userMenu.js:689
|
||||||
msgid ""
|
msgid ""
|
||||||
"Notifications are now disabled, including chat messages. Your online status "
|
"Notifications are now disabled, including chat messages. Your online status "
|
||||||
"has been adjusted to let others know that you might not see their messages."
|
"has been adjusted to let others know that you might not see their messages."
|
||||||
@ -1668,7 +1647,7 @@ msgstr ""
|
|||||||
|
|
||||||
#: ../js/ui/wanda.js:168
|
#: ../js/ui/wanda.js:168
|
||||||
msgid "Your favorite Easter Egg"
|
msgid "Your favorite Easter Egg"
|
||||||
msgstr ""
|
msgstr "તમારા મનગમતા ઇસ્ટર ઇંડા"
|
||||||
|
|
||||||
#: ../js/ui/windowAttentionHandler.js:19
|
#: ../js/ui/windowAttentionHandler.js:19
|
||||||
#, c-format
|
#, c-format
|
||||||
@ -1697,28 +1676,26 @@ msgstr[1] "%u ઇનપુટો"
|
|||||||
msgid "System Sounds"
|
msgid "System Sounds"
|
||||||
msgstr "સિસ્ટમ અવાજો"
|
msgstr "સિસ્ટમ અવાજો"
|
||||||
|
|
||||||
#: ../src/main.c:262
|
#: ../src/main.c:255
|
||||||
msgid "Print version"
|
msgid "Print version"
|
||||||
msgstr "ા"
|
msgstr "ા"
|
||||||
|
|
||||||
#: ../src/main.c:268
|
#: ../src/main.c:261
|
||||||
msgid "Mode used by GDM for login screen"
|
msgid "Mode used by GDM for login screen"
|
||||||
msgstr "લૉગિન સ્ક્રીન માટે GDM દ્દારા વાપરેલ સ્થિતિ"
|
msgstr "લૉગિન સ્ક્રીન માટે GDM દ્દારા વાપરેલ સ્થિતિ"
|
||||||
|
|
||||||
#: ../src/shell-app.c:617
|
#: ../src/shell-app.c:619
|
||||||
#, c-format
|
#, c-format
|
||||||
#| msgid "Failed to unmount '%s'"
|
|
||||||
msgid "Failed to launch '%s'"
|
msgid "Failed to launch '%s'"
|
||||||
msgstr "'%s' ને શરૂ કરવામાં નિષ્ફળતા"
|
msgstr "'%s' ને શરૂ કરવામાં નિષ્ફળતા"
|
||||||
|
|
||||||
#: ../src/shell-keyring-prompt.c:708
|
#: ../src/shell-keyring-prompt.c:708
|
||||||
#| msgid "Does not match"
|
|
||||||
msgid "Passwords do not match."
|
msgid "Passwords do not match."
|
||||||
msgstr "પાસવર્ડ બંધબેસતો નથી"
|
msgstr "પાસવર્ડ બંધબેસતો નથી"
|
||||||
|
|
||||||
#: ../src/shell-keyring-prompt.c:716
|
#: ../src/shell-keyring-prompt.c:716
|
||||||
msgid "Password cannot be blank"
|
msgid "Password cannot be blank"
|
||||||
msgstr ""
|
msgstr "પાસવર્ડને ખાલી રાખી શકાતો નથી"
|
||||||
|
|
||||||
#: ../src/shell-mobile-providers.c:80
|
#: ../src/shell-mobile-providers.c:80
|
||||||
msgid "United Kingdom"
|
msgid "United Kingdom"
|
||||||
@ -1735,7 +1712,6 @@ msgstr ""
|
|||||||
#. Translators: this is the same string as the one found in
|
#. Translators: this is the same string as the one found in
|
||||||
#. * nautilus
|
#. * nautilus
|
||||||
#: ../src/shell-util.c:97
|
#: ../src/shell-util.c:97
|
||||||
#| msgid "Volume"
|
|
||||||
msgid "Home"
|
msgid "Home"
|
||||||
msgstr "ઘર"
|
msgstr "ઘર"
|
||||||
|
|
||||||
|
70
po/hu.po
70
po/hu.po
@ -7,8 +7,8 @@ msgid ""
|
|||||||
msgstr ""
|
msgstr ""
|
||||||
"Project-Id-Version: gnome-shell master\n"
|
"Project-Id-Version: gnome-shell master\n"
|
||||||
"Report-Msgid-Bugs-To: \n"
|
"Report-Msgid-Bugs-To: \n"
|
||||||
"POT-Creation-Date: 2012-03-22 08:22+0100\n"
|
"POT-Creation-Date: 2012-04-04 15:45+0200\n"
|
||||||
"PO-Revision-Date: 2012-03-22 08:23+0100\n"
|
"PO-Revision-Date: 2012-04-04 15:45+0200\n"
|
||||||
"Last-Translator: Gabor Kelemen <kelemeng at gnome dot hu>\n"
|
"Last-Translator: Gabor Kelemen <kelemeng at gnome dot hu>\n"
|
||||||
"Language-Team: Hungarian <gnome-hu-list at gnome dot org>\n"
|
"Language-Team: Hungarian <gnome-hu-list at gnome dot org>\n"
|
||||||
"Language: \n"
|
"Language: \n"
|
||||||
@ -107,10 +107,18 @@ msgstr ""
|
|||||||
"állapot. Az itteni érték a GsmPresenceStatus felsorolásból származik."
|
"állapot. Az itteni érték a GsmPresenceStatus felsorolásból származik."
|
||||||
|
|
||||||
#: ../data/org.gnome.shell.gschema.xml.in.h:13
|
#: ../data/org.gnome.shell.gschema.xml.in.h:13
|
||||||
|
msgid "Keybinding to open the application menu"
|
||||||
|
msgstr "Billentyűtársítás az alkalmazásmenü megnyitásához"
|
||||||
|
|
||||||
|
#: ../data/org.gnome.shell.gschema.xml.in.h:14
|
||||||
|
msgid "Keybinding to open the application menu."
|
||||||
|
msgstr "Billentyűtársítás az alkalmazásmenü megnyitásához."
|
||||||
|
|
||||||
|
#: ../data/org.gnome.shell.gschema.xml.in.h:15
|
||||||
msgid "List of desktop file IDs for favorite applications"
|
msgid "List of desktop file IDs for favorite applications"
|
||||||
msgstr "A kedvenc alkalmazások asztalifájl-azonosítóinak listája"
|
msgstr "A kedvenc alkalmazások asztalifájl-azonosítóinak listája"
|
||||||
|
|
||||||
#: ../data/org.gnome.shell.gschema.xml.in.h:15
|
#: ../data/org.gnome.shell.gschema.xml.in.h:17
|
||||||
#, no-c-format
|
#, no-c-format
|
||||||
msgid ""
|
msgid ""
|
||||||
"Sets the GStreamer pipeline used to encode recordings. It follows the syntax "
|
"Sets the GStreamer pipeline used to encode recordings. It follows the syntax "
|
||||||
@ -137,19 +145,19 @@ msgstr ""
|
|||||||
"használatával. A %T egy helykitöltő, a rendszeren optimális szálmennyiség "
|
"használatával. A %T egy helykitöltő, a rendszeren optimális szálmennyiség "
|
||||||
"megtippelésére."
|
"megtippelésére."
|
||||||
|
|
||||||
#: ../data/org.gnome.shell.gschema.xml.in.h:16
|
#: ../data/org.gnome.shell.gschema.xml.in.h:18
|
||||||
msgid "Show date in clock"
|
msgid "Show date in clock"
|
||||||
msgstr "Dátum megjelenítése az órában"
|
msgstr "Dátum megjelenítése az órában"
|
||||||
|
|
||||||
#: ../data/org.gnome.shell.gschema.xml.in.h:17
|
#: ../data/org.gnome.shell.gschema.xml.in.h:19
|
||||||
msgid "Show the week date in the calendar"
|
msgid "Show the week date in the calendar"
|
||||||
msgstr "Hetek számának megjelenítése a naptárban"
|
msgstr "Hetek számának megjelenítése a naptárban"
|
||||||
|
|
||||||
#: ../data/org.gnome.shell.gschema.xml.in.h:18
|
#: ../data/org.gnome.shell.gschema.xml.in.h:20
|
||||||
msgid "Show time with seconds"
|
msgid "Show time with seconds"
|
||||||
msgstr "Másodpercek megjelenítése"
|
msgstr "Másodpercek megjelenítése"
|
||||||
|
|
||||||
#: ../data/org.gnome.shell.gschema.xml.in.h:19
|
#: ../data/org.gnome.shell.gschema.xml.in.h:21
|
||||||
msgid ""
|
msgid ""
|
||||||
"The applications corresponding to these identifiers will be displayed in the "
|
"The applications corresponding to these identifiers will be displayed in the "
|
||||||
"favorites area."
|
"favorites area."
|
||||||
@ -157,7 +165,7 @@ msgstr ""
|
|||||||
"Az itt felsorolt azonosítóknak megfelelő alkalmazások jelennek meg a "
|
"Az itt felsorolt azonosítóknak megfelelő alkalmazások jelennek meg a "
|
||||||
"kedvencek területen."
|
"kedvencek területen."
|
||||||
|
|
||||||
#: ../data/org.gnome.shell.gschema.xml.in.h:20
|
#: ../data/org.gnome.shell.gschema.xml.in.h:22
|
||||||
msgid ""
|
msgid ""
|
||||||
"The filename for recorded screencasts will be a unique filename based on the "
|
"The filename for recorded screencasts will be a unique filename based on the "
|
||||||
"current date, and use this extension. It should be changed when recording to "
|
"current date, and use this extension. It should be changed when recording to "
|
||||||
@ -167,7 +175,7 @@ msgstr ""
|
|||||||
"névvel, és ezzel a kiterjesztéssel fog rendelkezni. Más tárolóformátumba "
|
"névvel, és ezzel a kiterjesztéssel fog rendelkezni. Más tárolóformátumba "
|
||||||
"való rögzítéskor módosítani kell."
|
"való rögzítéskor módosítani kell."
|
||||||
|
|
||||||
#: ../data/org.gnome.shell.gschema.xml.in.h:21
|
#: ../data/org.gnome.shell.gschema.xml.in.h:23
|
||||||
msgid ""
|
msgid ""
|
||||||
"The framerate of the resulting screencast recordered by GNOME Shell's "
|
"The framerate of the resulting screencast recordered by GNOME Shell's "
|
||||||
"screencast recorder in frames-per-second."
|
"screencast recorder in frames-per-second."
|
||||||
@ -175,11 +183,11 @@ msgstr ""
|
|||||||
"A GNOME Shell képernyőfelvevője által felvett eredményül kapott "
|
"A GNOME Shell képernyőfelvevője által felvett eredményül kapott "
|
||||||
"képernyővideó képkockasebessége képkocka/másodpercben."
|
"képernyővideó képkockasebessége képkocka/másodpercben."
|
||||||
|
|
||||||
#: ../data/org.gnome.shell.gschema.xml.in.h:22
|
#: ../data/org.gnome.shell.gschema.xml.in.h:24
|
||||||
msgid "The gstreamer pipeline used to encode the screencast"
|
msgid "The gstreamer pipeline used to encode the screencast"
|
||||||
msgstr "A képernyővideó kódolására használt GStreamer adatcsatorna"
|
msgstr "A képernyővideó kódolására használt GStreamer adatcsatorna"
|
||||||
|
|
||||||
#: ../data/org.gnome.shell.gschema.xml.in.h:23
|
#: ../data/org.gnome.shell.gschema.xml.in.h:25
|
||||||
msgid ""
|
msgid ""
|
||||||
"The shell normally monitors active applications in order to present the most "
|
"The shell normally monitors active applications in order to present the most "
|
||||||
"used ones (e.g. in launchers). While this data will be kept private, you may "
|
"used ones (e.g. in launchers). While this data will be kept private, you may "
|
||||||
@ -191,23 +199,23 @@ msgstr ""
|
|||||||
"titkosak maradnak, magánszférájának védelme érdekében letilthatja ezek "
|
"titkosak maradnak, magánszférájának védelme érdekében letilthatja ezek "
|
||||||
"gyűjtését. Ne feledje, hogy ez nem fogja a már mentett adatokat törölni."
|
"gyűjtését. Ne feledje, hogy ez nem fogja a már mentett adatokat törölni."
|
||||||
|
|
||||||
#: ../data/org.gnome.shell.gschema.xml.in.h:24
|
#: ../data/org.gnome.shell.gschema.xml.in.h:26
|
||||||
msgid "The type of keyboard to use."
|
msgid "The type of keyboard to use."
|
||||||
msgstr "Használandó billentyűzet típusa."
|
msgstr "Használandó billentyűzet típusa."
|
||||||
|
|
||||||
#: ../data/org.gnome.shell.gschema.xml.in.h:25
|
#: ../data/org.gnome.shell.gschema.xml.in.h:27
|
||||||
msgid "Uuids of extensions to enable"
|
msgid "Uuids of extensions to enable"
|
||||||
msgstr "Engedélyezendő kiterjesztések uuid-jei"
|
msgstr "Engedélyezendő kiterjesztések uuid-jei"
|
||||||
|
|
||||||
#: ../data/org.gnome.shell.gschema.xml.in.h:26
|
#: ../data/org.gnome.shell.gschema.xml.in.h:28
|
||||||
msgid "Whether to collect stats about applications usage"
|
msgid "Whether to collect stats about applications usage"
|
||||||
msgstr "Statisztikák gyűjtése alkalmazások használatáról"
|
msgstr "Statisztikák gyűjtése alkalmazások használatáról"
|
||||||
|
|
||||||
#: ../data/org.gnome.shell.gschema.xml.in.h:27
|
#: ../data/org.gnome.shell.gschema.xml.in.h:29
|
||||||
msgid "Which keyboard to use"
|
msgid "Which keyboard to use"
|
||||||
msgstr "A használandó billentyűzet"
|
msgstr "A használandó billentyűzet"
|
||||||
|
|
||||||
#: ../data/org.gnome.shell.gschema.xml.in.h:28
|
#: ../data/org.gnome.shell.gschema.xml.in.h:30
|
||||||
msgid "disabled OpenSearch providers"
|
msgid "disabled OpenSearch providers"
|
||||||
msgstr "kikapcsolt OpenSearch szolgáltatók"
|
msgstr "kikapcsolt OpenSearch szolgáltatók"
|
||||||
|
|
||||||
@ -686,51 +694,51 @@ msgstr "Jelszó:"
|
|||||||
msgid "Type again:"
|
msgid "Type again:"
|
||||||
msgstr "Írja be újra:"
|
msgstr "Írja be újra:"
|
||||||
|
|
||||||
#: ../js/ui/lookingGlass.js:725
|
#: ../js/ui/lookingGlass.js:732
|
||||||
msgid "No extensions installed"
|
msgid "No extensions installed"
|
||||||
msgstr "Nincsenek kiterjesztések telepítve"
|
msgstr "Nincsenek kiterjesztések telepítve"
|
||||||
|
|
||||||
#. Translators: argument is an extension UUID.
|
#. Translators: argument is an extension UUID.
|
||||||
#: ../js/ui/lookingGlass.js:779
|
#: ../js/ui/lookingGlass.js:786
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "%s has not emitted any errors."
|
msgid "%s has not emitted any errors."
|
||||||
msgstr "%s nem adott hibát."
|
msgstr "%s nem adott hibát."
|
||||||
|
|
||||||
#: ../js/ui/lookingGlass.js:785
|
#: ../js/ui/lookingGlass.js:792
|
||||||
msgid "Hide Errors"
|
msgid "Hide Errors"
|
||||||
msgstr "Hibák elrejtése"
|
msgstr "Hibák elrejtése"
|
||||||
|
|
||||||
#: ../js/ui/lookingGlass.js:789 ../js/ui/lookingGlass.js:840
|
#: ../js/ui/lookingGlass.js:796 ../js/ui/lookingGlass.js:847
|
||||||
msgid "Show Errors"
|
msgid "Show Errors"
|
||||||
msgstr "Hibák megjelenítése"
|
msgstr "Hibák megjelenítése"
|
||||||
|
|
||||||
#: ../js/ui/lookingGlass.js:798
|
#: ../js/ui/lookingGlass.js:805
|
||||||
msgid "Enabled"
|
msgid "Enabled"
|
||||||
msgstr "Engedélyezve"
|
msgstr "Engedélyezve"
|
||||||
|
|
||||||
#. translators:
|
#. translators:
|
||||||
#. * The device has been disabled
|
#. * The device has been disabled
|
||||||
#: ../js/ui/lookingGlass.js:801 ../src/gvc/gvc-mixer-control.c:1093
|
#: ../js/ui/lookingGlass.js:808 ../src/gvc/gvc-mixer-control.c:1093
|
||||||
msgid "Disabled"
|
msgid "Disabled"
|
||||||
msgstr "Tiltva"
|
msgstr "Tiltva"
|
||||||
|
|
||||||
#: ../js/ui/lookingGlass.js:803
|
#: ../js/ui/lookingGlass.js:810
|
||||||
msgid "Error"
|
msgid "Error"
|
||||||
msgstr "Hiba"
|
msgstr "Hiba"
|
||||||
|
|
||||||
#: ../js/ui/lookingGlass.js:805
|
#: ../js/ui/lookingGlass.js:812
|
||||||
msgid "Out of date"
|
msgid "Out of date"
|
||||||
msgstr "Elavult"
|
msgstr "Elavult"
|
||||||
|
|
||||||
#: ../js/ui/lookingGlass.js:807
|
#: ../js/ui/lookingGlass.js:814
|
||||||
msgid "Downloading"
|
msgid "Downloading"
|
||||||
msgstr "Letöltés"
|
msgstr "Letöltés"
|
||||||
|
|
||||||
#: ../js/ui/lookingGlass.js:828
|
#: ../js/ui/lookingGlass.js:835
|
||||||
msgid "View Source"
|
msgid "View Source"
|
||||||
msgstr "Forrás megtekintése"
|
msgstr "Forrás megtekintése"
|
||||||
|
|
||||||
#: ../js/ui/lookingGlass.js:834
|
#: ../js/ui/lookingGlass.js:841
|
||||||
msgid "Web Page"
|
msgid "Web Page"
|
||||||
msgstr "Weblap"
|
msgstr "Weblap"
|
||||||
|
|
||||||
@ -860,17 +868,17 @@ msgstr "Alkalmazások"
|
|||||||
msgid "Dash"
|
msgid "Dash"
|
||||||
msgstr "Dash"
|
msgstr "Dash"
|
||||||
|
|
||||||
#: ../js/ui/panel.js:591
|
#: ../js/ui/panel.js:592
|
||||||
msgid "Quit"
|
msgid "Quit"
|
||||||
msgstr "Kilépés"
|
msgstr "Kilépés"
|
||||||
|
|
||||||
#. Translators: If there is no suitable word for "Activities"
|
#. Translators: If there is no suitable word for "Activities"
|
||||||
#. in your language, you can use the word for "Overview".
|
#. in your language, you can use the word for "Overview".
|
||||||
#: ../js/ui/panel.js:623
|
#: ../js/ui/panel.js:624
|
||||||
msgid "Activities"
|
msgid "Activities"
|
||||||
msgstr "Tevékenységek"
|
msgstr "Tevékenységek"
|
||||||
|
|
||||||
#: ../js/ui/panel.js:998
|
#: ../js/ui/panel.js:999
|
||||||
msgid "Top Bar"
|
msgid "Top Bar"
|
||||||
msgstr "Felső sáv"
|
msgstr "Felső sáv"
|
||||||
|
|
||||||
@ -1685,7 +1693,7 @@ msgstr ""
|
|||||||
#: ../js/ui/wanda.js:128
|
#: ../js/ui/wanda.js:128
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "%s the Oracle says"
|
msgid "%s the Oracle says"
|
||||||
msgstr "Az orákulum ezt mondja: %s"
|
msgstr "%s az orákulum ezt mondja"
|
||||||
|
|
||||||
#: ../js/ui/wanda.js:168
|
#: ../js/ui/wanda.js:168
|
||||||
msgid "Your favorite Easter Egg"
|
msgid "Your favorite Easter Egg"
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user