Compare commits
318 Commits
Author | SHA1 | Date | |
---|---|---|---|
4c7cc94cdc | |||
5ff2285707 | |||
d714dfd82e | |||
b1064cbe50 | |||
8d3e5ea507 | |||
001b6afc7e | |||
55d6c5ea8f | |||
fa2ff8158f | |||
97e7ea0b5d | |||
65dec2b72a | |||
5fd3ca8d09 | |||
dc9a8d505d | |||
fc8d13f4bd | |||
d1aa7de5d0 | |||
e279ef1c7c | |||
b88657ab83 | |||
d20e646ed6 | |||
8678b87120 | |||
960571a589 | |||
d856338f86 | |||
2b6b2d93a9 | |||
363bd04166 | |||
9bc1a68fe4 | |||
2c2729f7be | |||
9011959356 | |||
c79b8bbe7e | |||
da59eebf8e | |||
7854024326 | |||
a9ab8784c4 | |||
de5b00fd52 | |||
6547f75b12 | |||
827bf506a7 | |||
adc187c32e | |||
5350302b09 | |||
167ca75388 | |||
46cea67258 | |||
463e0919d4 | |||
98906c1da3 | |||
b71e66c335 | |||
2b6c5bb416 | |||
628e59894b | |||
703d2ead33 | |||
43f53a708f | |||
07e7331e7b | |||
c516af3130 | |||
39727d1156 | |||
85cd189a69 | |||
a8e35422f2 | |||
3941961f8b | |||
d9c6485cbf | |||
c52ccc76a3 | |||
be1c4f26b5 | |||
a6ee6739e0 | |||
54a8ad8bc6 | |||
2541bfcdf2 | |||
d7d5da0301 | |||
d2bd9efc25 | |||
779b18bf48 | |||
618a53b34f | |||
f4eaadb948 | |||
ea061b0f46 | |||
3652e42699 | |||
398489f661 | |||
70fc13500d | |||
18541c447e | |||
3294a6e1a7 | |||
38563c38e8 | |||
a465c5f996 | |||
1760ba1279 | |||
3d3c9546a2 | |||
203c5db5eb | |||
cf44234323 | |||
cc94076ffb | |||
8d137eae5b | |||
51fa9ae513 | |||
9951c92459 | |||
ee77e5d582 | |||
d74721f229 | |||
1aa97b19f7 | |||
95de48e986 | |||
a147d0428d | |||
90b3f7b7f6 | |||
c80acfda08 | |||
8a39145e3c | |||
b62f5ef07d | |||
bd5c6c5cd6 | |||
f874a57439 | |||
6a4525e554 | |||
d553a5bdc0 | |||
80076965a7 | |||
84e8d38d4c | |||
33f3f9d997 | |||
be72b1d066 | |||
dc5d2b83ef | |||
3dabe645c2 | |||
e9ede362dc | |||
01357aca35 | |||
c944dd6768 | |||
ff01ed5e4b | |||
d23c374326 | |||
a69ebc8a68 | |||
f4d8a35b9d | |||
2b140f8fb7 | |||
ab603bdbbf | |||
44e2f7f555 | |||
fd1b3b4fee | |||
4ae2a0b2a5 | |||
0cb415b3bd | |||
c1fa9a82e6 | |||
dde124ab5a | |||
668920cec4 | |||
9b38c5b304 | |||
e63c2da433 | |||
38c768fdb3 | |||
0dd4584157 | |||
b7bf712b97 | |||
615723d8df | |||
de352a309d | |||
c573e7f9a1 | |||
d59fd1a75d | |||
18d69d7032 | |||
5d25716cee | |||
840e79c18c | |||
ddf562e306 | |||
20a6ce7003 | |||
8c43298af0 | |||
4bb48e56d2 | |||
338ba10ca2 | |||
36eb745ecc | |||
b07e45e214 | |||
bba5198e63 | |||
9e2bab008a | |||
5ea032bbf7 | |||
897fadfb40 | |||
b05f71eb9b | |||
4ce0e80956 | |||
577ccc4d56 | |||
39d12351ba | |||
e37bc6d7f0 | |||
9593ff3582 | |||
ad8dfd7b04 | |||
ca5ab20f67 | |||
0eab448221 | |||
a26a77f9db | |||
c3df6bb8bd | |||
ce3a26cf37 | |||
04482c23c4 | |||
ff20fe856e | |||
12e3921f81 | |||
928fbee15b | |||
a103c028f9 | |||
775347d865 | |||
6d0be86a4e | |||
a4b69db8af | |||
790b9d3371 | |||
adef2009a5 | |||
1721db6d8d | |||
6d95e8b988 | |||
b07f9932db | |||
9439da81c4 | |||
6257e64d03 | |||
ba110f2d2e | |||
6bdf621d05 | |||
1c4db98c95 | |||
dadac957e4 | |||
cf3976d496 | |||
82ed80c9c3 | |||
67222525ad | |||
fff0861773 | |||
13ffe41498 | |||
96e0528a7b | |||
3df30fbd57 | |||
b57d8b336b | |||
3169b2c440 | |||
6bc34e0f32 | |||
cecb1a41fb | |||
b9069df85c | |||
aee3c6f041 | |||
c427bba9f1 | |||
da83ad561b | |||
85520e34ab | |||
d0edd970e1 | |||
8529ca70af | |||
1a8d78212f | |||
4270a2806d | |||
4333bdc709 | |||
75b824d032 | |||
7bc2573d85 | |||
67b7b7a950 | |||
786cfbd397 | |||
9df8b583cf | |||
8e32290dc9 | |||
23478f3336 | |||
2e244ecb63 | |||
e307680206 | |||
6bb1a3e2c4 | |||
8a1ac6b13f | |||
61b8af2252 | |||
c99afed012 | |||
2947b92148 | |||
39c5d23a87 | |||
d839670f54 | |||
0d1b7e15d1 | |||
ac678f63ee | |||
d862c0879b | |||
23a4d4c69e | |||
472b20d933 | |||
492dd718fb | |||
0d5618fdd1 | |||
503508af41 | |||
4ec5e55122 | |||
8daca865ca | |||
f9b37a21e8 | |||
c398f319fc | |||
1e049f88b8 | |||
4831d9c3a3 | |||
f13f5bc1bb | |||
4e114107ed | |||
0ccb280008 | |||
28c3e0693e | |||
c321c8a02f | |||
2407ec7b47 | |||
70eeb75716 | |||
751d250471 | |||
c28217db80 | |||
0968e556fa | |||
130f2cf808 | |||
4eec7413c7 | |||
efc3246d26 | |||
9930dbc0ff | |||
754f87dac3 | |||
51139bd096 | |||
6e0119d620 | |||
a3528bf973 | |||
77c36af588 | |||
69c0a52a33 | |||
a7442cd0a5 | |||
d47a013931 | |||
745f9c0e6e | |||
414f49fd80 | |||
e49a595f54 | |||
77485c2a04 | |||
e9b28634e5 | |||
b43dcb8876 | |||
f0c1eeece8 | |||
1e6b824ede | |||
1e2d16273c | |||
32dc24c59b | |||
7a8a189c48 | |||
6aa411fecc | |||
9c76318df8 | |||
6510904711 | |||
a9817f4832 | |||
9067689839 | |||
4e9e91fdce | |||
73cc91ba60 | |||
0ab0d0860f | |||
337b399a75 | |||
46f21e81e3 | |||
c1300ddbbc | |||
8bd5b1e696 | |||
40c5db397d | |||
8b52919b4d | |||
2859f23038 | |||
00384ccb47 | |||
0191cc589a | |||
dae6db9b51 | |||
4d912c9feb | |||
07c4b46466 | |||
e9cdce49a3 | |||
84c3ce8778 | |||
d5a32a7fe4 | |||
cc4dfda21b | |||
703b37aa7b | |||
b433de9022 | |||
0c1a22ff95 | |||
4d526e40c3 | |||
4586c7b36b | |||
3d60b73b60 | |||
4ef5cd8ef6 | |||
6959bd19f1 | |||
17e4ce5ea8 | |||
33094b4988 | |||
a8fdcffd44 | |||
5adb5411fa | |||
ff0d11c89c | |||
5f6dce2b5c | |||
a7405e8b39 | |||
d87c520bad | |||
24959f8d34 | |||
6d1432e166 | |||
2c7ba2c125 | |||
a0ba664c64 | |||
131da5f523 | |||
7c6144450a | |||
4c7369db16 | |||
f4355de896 | |||
4a3db9f44d | |||
6c0a9ff9cc | |||
57b1695fcf | |||
045c6546cc | |||
ce5bd954bf | |||
6ef00a4a3b | |||
569d9718a0 | |||
00a3a8697f | |||
c93444e390 | |||
5e5788ab14 | |||
abf57e6362 | |||
74c2074d5a | |||
b74606312e | |||
0c849df4d5 | |||
38690d4a09 | |||
b64c237cb3 | |||
3fbee8e027 | |||
a68e6e3c63 | |||
db5a72774d | |||
966f90f24a | |||
eaa664c023 |
13
.gitignore
vendored
13
.gitignore
vendored
@ -21,6 +21,19 @@ data/gnome-shell.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
|
||||||
|
docs/reference/*/*.args
|
||||||
|
docs/reference/*/*.bak
|
||||||
|
docs/reference/*/*.hierarchy
|
||||||
|
docs/reference/*/*.interfaces
|
||||||
|
docs/reference/*/*.prerequisites
|
||||||
|
docs/reference/*/*.sgml
|
||||||
|
docs/reference/*/*.signals
|
||||||
|
docs/reference/*/*.stamp
|
||||||
|
docs/reference/*/*.txt
|
||||||
|
docs/reference/*/*.types
|
||||||
|
docs/reference/*/html/
|
||||||
|
docs/reference/*/xml/
|
||||||
|
gtk-doc.make
|
||||||
js/misc/config.js
|
js/misc/config.js
|
||||||
intltool-extract.in
|
intltool-extract.in
|
||||||
intltool-merge.in
|
intltool-merge.in
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
# Point to our macro directory and pick up user flags from the environment
|
# Point to our macro directory and pick up user flags from the environment
|
||||||
ACLOCAL_AMFLAGS = -I m4 ${ACLOCAL_FLAGS}
|
ACLOCAL_AMFLAGS = -I m4 ${ACLOCAL_FLAGS}
|
||||||
|
|
||||||
SUBDIRS = data js src browser-plugin tests po man
|
SUBDIRS = data js src browser-plugin tests po man docs
|
||||||
|
|
||||||
EXTRA_DIST = \
|
EXTRA_DIST = \
|
||||||
.project \
|
.project \
|
||||||
@ -19,3 +19,5 @@ DIST_EXCLUDE = \
|
|||||||
distcheck-hook:
|
distcheck-hook:
|
||||||
@echo "Checking disted files against files in git"
|
@echo "Checking disted files against files in git"
|
||||||
@$(srcdir)/tools/check-for-missing.py $(srcdir) $(distdir) $(DIST_EXCLUDE)
|
@$(srcdir)/tools/check-for-missing.py $(srcdir) $(distdir) $(DIST_EXCLUDE)
|
||||||
|
|
||||||
|
DISTCHECK_CONFIGURE_FLAGS = --enable-gtk-doc
|
||||||
|
167
NEWS
167
NEWS
@ -1,3 +1,170 @@
|
|||||||
|
3.3.2
|
||||||
|
=====
|
||||||
|
* Port D-Bus usage in the shell to GDBus [Giovanni, Marc-Antoine, Florian,
|
||||||
|
Jasper, Matthias; #648651, #658078, #663902, #663941]
|
||||||
|
* Message tray
|
||||||
|
- Add right-click option to chats to mute the conversation [Ana; #659962]
|
||||||
|
- Don't steal the focus when popping up under the pointer [Rui; #661358]
|
||||||
|
* Looking Glass
|
||||||
|
- Add alt-Tab completion [Jason; #661054]
|
||||||
|
- Show errors from extensions in the extensions tab [Jasper; #660546]
|
||||||
|
- Allow switching tabs with <Control>PageUp/PageDown
|
||||||
|
- Theme consistently with the rest of the shell [Jason; 650900]
|
||||||
|
* Extension system
|
||||||
|
- Don't try to load disabled extensions at all [Jasper; #661815, #662704]
|
||||||
|
- Enable and disable plugins in a consistent order [Jasper; #661815, #662704]
|
||||||
|
- Add options to enable/disable extensions to gnome-shell-extension-tool
|
||||||
|
[Jasper; #661815]
|
||||||
|
* Adapt to Mutter change to GSettings [Florian, Matthias; #663429]
|
||||||
|
* Allow creating a new workspace by dragging a window or launcher in the
|
||||||
|
middle of two existing ones [Jasper; #646409]
|
||||||
|
* Allow using Alt-Tab while during drag-and-drop and other operations
|
||||||
|
that grab the pointer [Adel; #660457]
|
||||||
|
* Do a better job of finding the right user to authenticate
|
||||||
|
as when showing a PolKit dialog [Matthias; #651547]
|
||||||
|
* Control the D-Bus Eval() method by the developer-tools GSetting which
|
||||||
|
is used for looking glass and screen recorder. [Jasper; #662891]
|
||||||
|
* Fix browser plugin to work under WebKit-based browser [Jasper; #663823]
|
||||||
|
* Fix certain stacking issues with alt-Tab [Jasper; #660650]
|
||||||
|
* Fixes for GLib deprecations [Jasper; #662011]p
|
||||||
|
* Fixes for GTK+ deprecations [Florian, Rico; #662245]p
|
||||||
|
* Fixes for Clutter deprecations [Jasper; #662627]
|
||||||
|
* Visual improvements and UI tweaks [Florian, Jakub, Jasper;
|
||||||
|
#662800, #658096, #662226]
|
||||||
|
* Hard-code "Home" as the name for the home dir, rather than looking
|
||||||
|
it up via GSettings; avoids schema dependency [Cosimo; #559895]
|
||||||
|
* Don't show "Switch User" on single user machines [Florian; #657011]
|
||||||
|
* Generate documentation for St toolkit [Florian]
|
||||||
|
* Improve marking of strings for translation [Matthias, Piotr; #658664]
|
||||||
|
* Networking menu bug fixes [Giovanni; #650007, #651378, #659277, #663278]
|
||||||
|
* Code cleanups and leak fixes to StTextureCache
|
||||||
|
[Jasper, Florian; #660968, #662998]
|
||||||
|
* Code cleanups [Adel, Florian, Jasper; #662238, #663584]
|
||||||
|
* Build fixes [Adel, Colin, Florian, Ming Han]
|
||||||
|
* Misc bug fixes [Adel, Florian, "Fry", Jasper, Giovanni, Ray, Rui, Stefan;
|
||||||
|
#660520, #661029, #661231, #661623, #661921, #662235, #662236, #662502,
|
||||||
|
#662394, #662799, #662969, #663175, #663277, #663815, #663891, #662967]
|
||||||
|
|
||||||
|
Contributors:
|
||||||
|
Giovanni Campagna, Cosimo Cecchi, Matthias Clasen, Piotr Drąg, Adel Gadllah,
|
||||||
|
Rui Matos, Florian Müllner, Marc-Antoine Perennou, Ana Risteska,
|
||||||
|
Jason Siefken, Jakub Steiner, Ray Strode, Jasper St. Pierre, Ming Han Teh,
|
||||||
|
Rico Tzschichholz, Colin Walters, Stefan Zwanenburg
|
||||||
|
|
||||||
|
Translation:
|
||||||
|
Alexander Shopov [bg], Marek Černocký [cs], Mario Blättermann [de],
|
||||||
|
Kostas Papadimas [el], Bruce Cowan [en_GB], Kristjan Schmidt [eo],
|
||||||
|
Jorge González, Daniel Mustieles, Benjamín Valero Espinosa [es],
|
||||||
|
Mattias Põldaru [et], Arash Mousavi [fa], Ville-Pekka Vainio [fi],
|
||||||
|
Fran Diéguez [gl], Yaron Shahrabani [he], Hideki Yamane [ja],
|
||||||
|
Algimantas Margevičius [lt], Kjartan Maraas [nb], Daniel Nylander [se],
|
||||||
|
Matej Urbančič [sl], Praveen Illa [te], Muhammet Kara [tr],
|
||||||
|
Nguyễn Thái Ngọc Duy [vi], Cheng-Chia Tseng [zh_HK, zh_TW]
|
||||||
|
|
||||||
|
3.2.1
|
||||||
|
=====
|
||||||
|
* Restore the IM state on startup - if you were available in when you logged
|
||||||
|
out, then you'll be set available again when you log in.
|
||||||
|
[Florian; #65902, #661485]
|
||||||
|
* Improve searching for contacts in the overview: search more fields,
|
||||||
|
show a more meaningful name, require that all search terms match.
|
||||||
|
[Florian, Matthias; #660580]
|
||||||
|
* Improve search for applications in the overview: take frequency into
|
||||||
|
account and tweak match algorithm [Florian; #623372]
|
||||||
|
* Remove the "Show Password" switch from network password prompts, and
|
||||||
|
move the functionality to a right-click menu [Florian; #658948]
|
||||||
|
* Add context menus with Cut/Paste options to most entries [Florian; #659275]
|
||||||
|
* On screen keyboard:
|
||||||
|
- Show the keyboard immediately when it's turned enabled [Dan; #659743]
|
||||||
|
- Fix problem where keyboard would hide when starting to type
|
||||||
|
in the search entry [Nohemi; #661340]
|
||||||
|
- Fix problem with keyboard hiding when selected accented characters
|
||||||
|
[Nohemi; 661707]
|
||||||
|
* Login mode:
|
||||||
|
- Allow hitting Enter to select the first user [Ray; #657996]
|
||||||
|
- Fix flicker of a fingerprint prompt that could show up [Ray; #660492]
|
||||||
|
- Fix password bullets vanishing during login [Ray; #657894]
|
||||||
|
- Misc bug fixes and visual tweaks [Ray; #659763, #660919, #661479]
|
||||||
|
* Display a caps-lock warning in password entries [Florian; #660806]
|
||||||
|
* Show the state of installed extensions in Looking Glass [Jasper; #660494]
|
||||||
|
* Load user extensions after system ones [Jasper; #661815]
|
||||||
|
* Fix problem with many applications showing extra-large icons in
|
||||||
|
notifications [Marina; #659158]
|
||||||
|
* Fix a problem where alt-Tab had trouble tracking the current
|
||||||
|
application with certain applications such as Emacs. [Dan; #645026]
|
||||||
|
* Fix confusion between different users avatar images [Florian; #660585]
|
||||||
|
* Remove behavior where you could switch workspaces by bumping
|
||||||
|
a dragged window in the overview against a screen edge; it was
|
||||||
|
leftover and just confusing. [Florian; #660838]
|
||||||
|
* Fix long-standing bug where the Dash in the overview could end up mis-sized
|
||||||
|
and run off the screen [Florian; #649248]
|
||||||
|
* Fix automatic launching of applications when media is inserted
|
||||||
|
[Cosimo; #660821]
|
||||||
|
* Fix handling of vertically stacked monitors with NVIDIA drivers
|
||||||
|
[Florian; #661387]
|
||||||
|
* Translation marking fixes [Jasper, Wouter; #660600]
|
||||||
|
* Code cleanups and warning fixes [Adel, Dan, Florian, Jasper;
|
||||||
|
#659822, #659940, #660122, #660358, #660968, #661231]
|
||||||
|
* Small memory leak fixes [Florian, Jasper; #661231]
|
||||||
|
* Misc bug fixes [Adel, Florian, Jasper; #659274, #659861, #660166, #660310,
|
||||||
|
#660397, #660608, #660606, #660674, #660774. #660848, #661151, #661617]
|
||||||
|
|
||||||
|
Contributors:
|
||||||
|
Wouter Bolsterlee, Cosimo Cecchi, Matthias Clasen, Nohemi Fernandez,
|
||||||
|
Adel Gadllah, Florian Müllner, Jasper St. Pierre, Ray Strode, Dan Winship,
|
||||||
|
Marina Zhurakhinskaya
|
||||||
|
|
||||||
|
Translations:
|
||||||
|
Tiffany Antopolski [eo], Xandru Armesto [ast], Alexander Shopov,
|
||||||
|
Ivaylo Valkov [bg], Gil Forcada [ca], Carles Ferrando [ca@valencia],
|
||||||
|
Mario Blättermann, Paul Seyfert [de], Bruce Cowan [en_GB],
|
||||||
|
Jorge González, Daniel Mustieles [es], Arash Mousavi [fa], Bruno Brouard [fr],
|
||||||
|
Seán de Búrca [ga], Fran Diéguez [gl], Gabor Kelemen [hu], Luca Ferretti [it],
|
||||||
|
Takayuki Kusano [ja], Changwoo Ryu [ko], Erdal Ronahi [ku],
|
||||||
|
Algimantas Margevičius [lt], Rudolfs Mazurs [lv], Wouter Bolsterlee [nl],
|
||||||
|
Piotr Drąg [pl], Adorilson Bezerra [pt_BR], Yuri Myasoedov [ru],
|
||||||
|
Matej Urbančič [sl], Daniel Nylander [sv], Miroslav Nikolić [sr, sr@latin],
|
||||||
|
Tirumurti Vasudevan [ta], Krishnababu Krothapalli [te], Daniel Korostil [uk],
|
||||||
|
Nguyễn Thái Ngọc Duy [vi], YunQiang Su [zh_CN]
|
||||||
|
|
||||||
|
3.2.0
|
||||||
|
=====
|
||||||
|
* Prevent the fallback on-screen keyboard from showing up while
|
||||||
|
GNOME Shell is running [Dan, #659865]
|
||||||
|
* Disable code to reposition windows around the on-screen keyboard;
|
||||||
|
it wasn't finished or working properly. [Dan; #659643]
|
||||||
|
* Fix interaction between on-screen keyboard and notifications
|
||||||
|
[Dan; #658603]
|
||||||
|
* Fix menu-sizing problems in right-to-left locales. [Florian; #659827]
|
||||||
|
* Update chat icons in the message tray when an avatar image changes
|
||||||
|
[Marina; #659768]
|
||||||
|
* Fix problem with empty notification bubbles being left [Marina; #659862]
|
||||||
|
* Fix problem with chat notifications bouncing when new messages come in.
|
||||||
|
[Marina; #659768]
|
||||||
|
* Fix bug that was causing SIP calls to automatically be accepted in some
|
||||||
|
circumstances [Guillaume; #660084]
|
||||||
|
* Fix string that should have been marked translatable [Frédéric]
|
||||||
|
* Fix a crash that could happen during CSS transitions [Florian; #659676]
|
||||||
|
* Build fixes [Colin, Florian]
|
||||||
|
|
||||||
|
Contributors:
|
||||||
|
Guillaume Desmottes, Florian Müllner, Frédéric Péters, Colin Walters,
|
||||||
|
Dan Winship, Marina Zhurakhinskaya
|
||||||
|
|
||||||
|
Translations:
|
||||||
|
Friedel Wolff [af], Nilamdyuti Goswami [as], Ihar Hrachyshka [be],
|
||||||
|
Ivaylo Valkov [bg], Gil Forcada [ca], Carles Ferrando [ca@valencia],
|
||||||
|
Petr Kovar [cz], Mario Blättermann [de], Kris Thomsen [dk],
|
||||||
|
Tiffany Antopolski, Kristjan Schmidt [eo], Daniel Mustieles [es],
|
||||||
|
Inaki Larranaga Murgoitio [eu], Tommi Vainikainen [fi], Bruno Brouard [fr],
|
||||||
|
Fran Dieguez [gl], Yaron Shahrabani [he], Gabor Kelemen [hu],
|
||||||
|
Andika Triwidada [id], Jiro Matsuzawa [ja], Changwoo Ryu [ko],
|
||||||
|
Rudolfs Mazurs [lv], Aurimas Černius [lt], Kjartan Maraas [nb],
|
||||||
|
A S Alam [pa], Piotr Drąg [pl], Duarte Loreto [pt], Djavan Fagundes,
|
||||||
|
Rodolfo Ribeiro Gomes, Gabriel F. Vilar [pt_BR], Yuri Myasoedov [ru],
|
||||||
|
Daniel Nylander [se], Martin Srebotnjak [sl], Michal Štrba [sv],
|
||||||
|
Krishnababu Krothapalli, Praveen Illa [te], Cheng-Chia Tseng [zh_KH, zh_TW]
|
||||||
|
|
||||||
3.1.92
|
3.1.92
|
||||||
======
|
======
|
||||||
|
|
||||||
|
@ -47,8 +47,6 @@ typedef struct {
|
|||||||
GDBusProxy *proxy;
|
GDBusProxy *proxy;
|
||||||
} PluginData;
|
} PluginData;
|
||||||
|
|
||||||
/* =============== public entry points =================== */
|
|
||||||
|
|
||||||
static NPNetscapeFuncs funcs;
|
static NPNetscapeFuncs funcs;
|
||||||
|
|
||||||
static inline gchar *
|
static inline gchar *
|
||||||
@ -71,10 +69,7 @@ get_string_property (NPP instance,
|
|||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
result_str = NPVARIANT_TO_STRING (result);
|
result_str = NPVARIANT_TO_STRING (result);
|
||||||
if (strlen (result_str.UTF8Characters) != result_str.UTF8Length)
|
result_copy = g_strndup (result_str.UTF8Characters, result_str.UTF8Length);
|
||||||
goto out;
|
|
||||||
|
|
||||||
result_copy = g_strdup (result_str.UTF8Characters);
|
|
||||||
|
|
||||||
out:
|
out:
|
||||||
funcs.releasevariantvalue (&result);
|
funcs.releasevariantvalue (&result);
|
||||||
@ -150,6 +145,8 @@ check_origin_and_protocol (NPP instance)
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* =============== public entry points =================== */
|
||||||
|
|
||||||
NPError
|
NPError
|
||||||
NP_Initialize(NPNetscapeFuncs *pfuncs, NPPluginFuncs *plugin)
|
NP_Initialize(NPNetscapeFuncs *pfuncs, NPPluginFuncs *plugin)
|
||||||
{
|
{
|
||||||
@ -816,6 +813,11 @@ NPP_GetValue(NPP instance,
|
|||||||
|
|
||||||
*(NPObject**)value = funcs.createobject (instance, &plugin_class);
|
*(NPObject**)value = funcs.createobject (instance, &plugin_class);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case NPPVpluginNeedsXEmbed:
|
||||||
|
*(bool *)value = TRUE;
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
;
|
;
|
||||||
}
|
}
|
||||||
|
32
configure.ac
32
configure.ac
@ -1,5 +1,5 @@
|
|||||||
AC_PREREQ(2.63)
|
AC_PREREQ(2.63)
|
||||||
AC_INIT([gnome-shell],[3.1.92],[https://bugzilla.gnome.org/enter_bug.cgi?product=gnome-shell],[gnome-shell])
|
AC_INIT([gnome-shell],[3.3.2],[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])
|
||||||
@ -9,7 +9,7 @@ AC_CONFIG_AUX_DIR([config])
|
|||||||
AC_SUBST([PACKAGE_NAME], ["$PACKAGE_NAME"])
|
AC_SUBST([PACKAGE_NAME], ["$PACKAGE_NAME"])
|
||||||
AC_SUBST([PACKAGE_VERSION], ["$PACKAGE_VERSION"])
|
AC_SUBST([PACKAGE_VERSION], ["$PACKAGE_VERSION"])
|
||||||
|
|
||||||
AM_INIT_AUTOMAKE([1.10 dist-xz no-dist-gzip foreign])
|
AM_INIT_AUTOMAKE([1.11 no-dist-gzip dist-xz tar-ustar foreign])
|
||||||
AM_MAINTAINER_MODE([enable])
|
AM_MAINTAINER_MODE([enable])
|
||||||
|
|
||||||
m4_ifdef([AM_SILENT_RULES],[AM_SILENT_RULES([yes])])
|
m4_ifdef([AM_SILENT_RULES],[AM_SILENT_RULES([yes])])
|
||||||
@ -36,10 +36,6 @@ AC_DEFINE_UNQUOTED(GETTEXT_PACKAGE, "$GETTEXT_PACKAGE",
|
|||||||
|
|
||||||
PKG_PROG_PKG_CONFIG([0.22])
|
PKG_PROG_PKG_CONFIG([0.22])
|
||||||
|
|
||||||
# GConf stuff
|
|
||||||
AC_PATH_PROG(GCONFTOOL, gconftool-2, no)
|
|
||||||
AM_GCONF_SOURCE_2
|
|
||||||
|
|
||||||
GLIB_GSETTINGS
|
GLIB_GSETTINGS
|
||||||
|
|
||||||
# Get a value to substitute into gnome-shell.in
|
# Get a value to substitute into gnome-shell.in
|
||||||
@ -66,11 +62,11 @@ AM_CONDITIONAL(BUILD_RECORDER, $build_recorder)
|
|||||||
|
|
||||||
CLUTTER_MIN_VERSION=1.7.5
|
CLUTTER_MIN_VERSION=1.7.5
|
||||||
GOBJECT_INTROSPECTION_MIN_VERSION=0.10.1
|
GOBJECT_INTROSPECTION_MIN_VERSION=0.10.1
|
||||||
GJS_MIN_VERSION=1.29.15
|
GJS_MIN_VERSION=1.29.18
|
||||||
MUTTER_MIN_VERSION=3.0.0
|
MUTTER_MIN_VERSION=3.3.2
|
||||||
FOLKS_MIN_VERSION=0.5.2
|
FOLKS_MIN_VERSION=0.5.2
|
||||||
GTK_MIN_VERSION=3.0.0
|
GTK_MIN_VERSION=3.0.0
|
||||||
GIO_MIN_VERSION=2.29.10
|
GIO_MIN_VERSION=2.31.0
|
||||||
LIBECAL_MIN_VERSION=2.32.0
|
LIBECAL_MIN_VERSION=2.32.0
|
||||||
LIBEDATASERVER_MIN_VERSION=1.2.0
|
LIBEDATASERVER_MIN_VERSION=1.2.0
|
||||||
LIBEDATASERVERUI_MIN_VERSION=2.91.6
|
LIBEDATASERVERUI_MIN_VERSION=2.91.6
|
||||||
@ -80,13 +76,13 @@ POLKIT_MIN_VERSION=0.100
|
|||||||
STARTUP_NOTIFICATION_MIN_VERSION=0.11
|
STARTUP_NOTIFICATION_MIN_VERSION=0.11
|
||||||
|
|
||||||
# Collect more than 20 libraries for a prize!
|
# Collect more than 20 libraries for a prize!
|
||||||
PKG_CHECK_MODULES(GNOME_SHELL, gio-2.0 >= $GIO_MIN_VERSION
|
PKG_CHECK_MODULES(GNOME_SHELL, gio-unix-2.0 >= $GIO_MIN_VERSION
|
||||||
gio-unix-2.0 dbus-glib-1 libxml-2.0
|
libxml-2.0
|
||||||
gtk+-3.0 >= $GTK_MIN_VERSION
|
gtk+-3.0 >= $GTK_MIN_VERSION
|
||||||
folks >= $FOLKS_MIN_VERSION
|
folks >= $FOLKS_MIN_VERSION
|
||||||
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 gconf-2.0
|
libgnome-menu-3.0 $recorder_modules
|
||||||
gdk-x11-3.0 libsoup-2.4
|
gdk-x11-3.0 libsoup-2.4
|
||||||
clutter-x11-1.0 >= $CLUTTER_MIN_VERSION
|
clutter-x11-1.0 >= $CLUTTER_MIN_VERSION
|
||||||
clutter-glx-1.0 >= $CLUTTER_MIN_VERSION
|
clutter-glx-1.0 >= $CLUTTER_MIN_VERSION
|
||||||
@ -121,7 +117,6 @@ CFLAGS=$saved_CFLAGS
|
|||||||
LIBS=$saved_LIBS
|
LIBS=$saved_LIBS
|
||||||
|
|
||||||
PKG_CHECK_MODULES(ST, clutter-1.0 gtk+-3.0 libcroco-0.6 >= 0.6.2 gnome-desktop-3.0 >= 2.90.0 x11)
|
PKG_CHECK_MODULES(ST, clutter-1.0 gtk+-3.0 libcroco-0.6 >= 0.6.2 gnome-desktop-3.0 >= 2.90.0 x11)
|
||||||
PKG_CHECK_MODULES(GDMUSER, dbus-glib-1 gtk+-3.0)
|
|
||||||
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 >= 0.1.7)
|
||||||
@ -131,6 +126,7 @@ PKG_CHECK_EXISTS([gnome-bluetooth-1.0 >= 3.1.0],
|
|||||||
[BLUETOOTH_DIR=`$PKG_CONFIG --variable=applet_libdir gnome-bluetooth-1.0`
|
[BLUETOOTH_DIR=`$PKG_CONFIG --variable=applet_libdir gnome-bluetooth-1.0`
|
||||||
BLUETOOTH_LIBS=`$PKG_CONFIG --variable=applet_libs gnome-bluetooth-1.0`
|
BLUETOOTH_LIBS=`$PKG_CONFIG --variable=applet_libs gnome-bluetooth-1.0`
|
||||||
AC_SUBST([BLUETOOTH_LIBS],["$BLUETOOTH_LIBS"])
|
AC_SUBST([BLUETOOTH_LIBS],["$BLUETOOTH_LIBS"])
|
||||||
|
AC_SUBST([BLUETOOTH_DIR],["$BLUETOOTH_DIR"])
|
||||||
AC_DEFINE_UNQUOTED([BLUETOOTH_DIR],["$BLUETOOTH_DIR"],[Path to installed GnomeBluetooth typelib and library])
|
AC_DEFINE_UNQUOTED([BLUETOOTH_DIR],["$BLUETOOTH_DIR"],[Path to installed GnomeBluetooth typelib and library])
|
||||||
AC_DEFINE([HAVE_BLUETOOTH],[1],[Define if you have libgnome-bluetooth-applet])
|
AC_DEFINE([HAVE_BLUETOOTH],[1],[Define if you have libgnome-bluetooth-applet])
|
||||||
AC_SUBST([HAVE_BLUETOOTH],[1])
|
AC_SUBST([HAVE_BLUETOOTH],[1])
|
||||||
@ -179,11 +175,13 @@ AC_SUBST(GIRDIR)
|
|||||||
TYPELIBDIR="$($PKG_CONFIG --variable=typelibdir gobject-introspection-1.0)"
|
TYPELIBDIR="$($PKG_CONFIG --variable=typelibdir gobject-introspection-1.0)"
|
||||||
AC_SUBST(TYPELIBDIR)
|
AC_SUBST(TYPELIBDIR)
|
||||||
|
|
||||||
|
GTK_DOC_CHECK([1.15], [--flavour no-tmpl])
|
||||||
|
|
||||||
# Stay command-line compatible with the gnome-common configure option. Here
|
# Stay command-line compatible with the gnome-common configure option. Here
|
||||||
# minimum/yes/maximum are the same, however.
|
# minimum/yes/maximum are the same, however.
|
||||||
AC_ARG_ENABLE(compile_warnings,
|
AC_ARG_ENABLE(compile_warnings,
|
||||||
AS_HELP_STRING([--enable-compile-warnings=@<:@no/minimum/yes/maximum/error@:>@],[Turn on compiler warnings]),,
|
AS_HELP_STRING([--enable-compile-warnings=@<:@no/minimum/yes/maximum/error@:>@],[Turn on compiler warnings]),,
|
||||||
enable_compile_warnings=error)
|
enable_compile_warnings=maximum)
|
||||||
|
|
||||||
changequote(,)dnl
|
changequote(,)dnl
|
||||||
if test "$enable_compile_warnings" != no ; then
|
if test "$enable_compile_warnings" != no ; then
|
||||||
@ -241,6 +239,12 @@ AC_ARG_VAR([BROWSER_PLUGIN_DIR],[Where to install the plugin to])
|
|||||||
AC_CONFIG_FILES([
|
AC_CONFIG_FILES([
|
||||||
Makefile
|
Makefile
|
||||||
data/Makefile
|
data/Makefile
|
||||||
|
docs/Makefile
|
||||||
|
docs/reference/Makefile
|
||||||
|
docs/reference/shell/Makefile
|
||||||
|
docs/reference/shell/shell-docs.sgml
|
||||||
|
docs/reference/st/Makefile
|
||||||
|
docs/reference/st/st-docs.sgml
|
||||||
js/Makefile
|
js/Makefile
|
||||||
js/misc/config.js
|
js/misc/config.js
|
||||||
src/Makefile
|
src/Makefile
|
||||||
|
@ -60,23 +60,14 @@ gschemas.compiled: $(gsettings_SCHEMAS:.xml=.valid)
|
|||||||
all-local: gschemas.compiled
|
all-local: gschemas.compiled
|
||||||
|
|
||||||
|
|
||||||
# GConf schemas: provide defaults for keys from Metacity we are overriding
|
|
||||||
gconfschemadir = @GCONF_SCHEMA_FILE_DIR@
|
|
||||||
gconfschema_DATA = gnome-shell.schemas
|
|
||||||
|
|
||||||
shadersdir = $(pkgdatadir)/shaders
|
shadersdir = $(pkgdatadir)/shaders
|
||||||
shaders_DATA = \
|
shaders_DATA = \
|
||||||
shaders/dim-window.glsl
|
shaders/dim-window.glsl
|
||||||
|
|
||||||
install-data-local:
|
|
||||||
GCONF_CONFIG_SOURCE=$(GCONF_SCHEMA_CONFIG_SOURCE) $(GCONFTOOL) --makefile-install-rule $(srcdir)/$(gconfschema_DATA)
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
EXTRA_DIST = \
|
EXTRA_DIST = \
|
||||||
gnome-shell.desktop.in.in \
|
gnome-shell.desktop.in.in \
|
||||||
$(menu_DATA) \
|
$(menu_DATA) \
|
||||||
$(gconfschema_DATA) \
|
|
||||||
$(shaders_DATA) \
|
$(shaders_DATA) \
|
||||||
org.gnome.shell.gschema.xml.in
|
org.gnome.shell.gschema.xml.in
|
||||||
|
|
||||||
|
@ -1,100 +0,0 @@
|
|||||||
<gconfschemafile>
|
|
||||||
<schemalist>
|
|
||||||
|
|
||||||
<!-- Metacity overrides -->
|
|
||||||
<schema>
|
|
||||||
<key>/schemas/desktop/gnome/shell/windows/attach_modal_dialogs</key>
|
|
||||||
<applyto>/desktop/gnome/shell/windows/attach_modal_dialogs</applyto>
|
|
||||||
<owner>gnome-shell</owner>
|
|
||||||
<type>bool</type>
|
|
||||||
<default>true</default>
|
|
||||||
<locale name="C">
|
|
||||||
<short>Attach modal dialog to the parent window</short>
|
|
||||||
<long>
|
|
||||||
This key overrides /apps/mutter/general/attach_modal_dialogs when
|
|
||||||
running GNOME Shell.
|
|
||||||
</long>
|
|
||||||
</locale>
|
|
||||||
</schema>
|
|
||||||
|
|
||||||
<schema>
|
|
||||||
<key>/schemas/desktop/gnome/shell/windows/button_layout</key>
|
|
||||||
<applyto>/desktop/gnome/shell/windows/button_layout</applyto>
|
|
||||||
<owner>gnome-shell</owner>
|
|
||||||
<type>string</type>
|
|
||||||
<default>:close</default>
|
|
||||||
<locale name="C">
|
|
||||||
<short>Arrangement of buttons on the titlebar</short>
|
|
||||||
<long>
|
|
||||||
Arrangement of buttons on the titlebar. The
|
|
||||||
value should be a string, such as
|
|
||||||
"menu:minimize,maximize,spacer,close"; the colon separates the
|
|
||||||
left corner of the window from the right corner, and
|
|
||||||
the button names are comma-separated. Duplicate buttons
|
|
||||||
are not allowed. Unknown button names are silently ignored
|
|
||||||
so that buttons can be added in future gnome-shell versions
|
|
||||||
without breaking older versions.
|
|
||||||
A special spacer tag can be used to insert some space between
|
|
||||||
two adjacent buttons.
|
|
||||||
|
|
||||||
This key overrides /apps/metacity/general/button_layout when
|
|
||||||
running GNOME Shell.
|
|
||||||
</long>
|
|
||||||
</locale>
|
|
||||||
</schema>
|
|
||||||
|
|
||||||
<schema>
|
|
||||||
<key>/schemas/desktop/gnome/shell/windows/edge_tiling</key>
|
|
||||||
<applyto>/desktop/gnome/shell/windows/edge_tiling</applyto>
|
|
||||||
<owner>gnome-shell</owner>
|
|
||||||
<type>bool</type>
|
|
||||||
<default>true</default>
|
|
||||||
<locale name="C">
|
|
||||||
<short>enable edge tiling when dropping windows on screen edges</short>
|
|
||||||
<long>
|
|
||||||
If enabled, dropping windows on vertical screen edges maximizes them
|
|
||||||
vertically and resizes them horizontally to cover half of the
|
|
||||||
available area. Dropping windows on the top screen edge maximizes them
|
|
||||||
completely.
|
|
||||||
|
|
||||||
This key overrides /apps/metacity/general/edge_tiling when
|
|
||||||
running GNOME Shell.
|
|
||||||
</long>
|
|
||||||
</locale>
|
|
||||||
</schema>
|
|
||||||
|
|
||||||
<schema>
|
|
||||||
<key>/schemas/desktop/gnome/shell/windows/theme</key>
|
|
||||||
<applyto>/desktop/gnome/shell/windows/theme</applyto>
|
|
||||||
<owner>gnome-shell</owner>
|
|
||||||
<type>string</type>
|
|
||||||
<default>Adwaita</default>
|
|
||||||
<locale name="C">
|
|
||||||
<short>Current theme</short>
|
|
||||||
<long>
|
|
||||||
The theme determines the appearance of window borders,
|
|
||||||
titlebar, and so forth.
|
|
||||||
|
|
||||||
This key overrides /apps/metacity/general/theme when
|
|
||||||
running GNOME Shell.
|
|
||||||
</long>
|
|
||||||
</locale>
|
|
||||||
</schema>
|
|
||||||
|
|
||||||
<schema>
|
|
||||||
<key>/schemas/desktop/gnome/shell/windows/workspaces_only_on_primary</key>
|
|
||||||
<applyto>/desktop/gnome/shell/windows/workspaces_only_on_primary</applyto>
|
|
||||||
<owner>gnome-shell</owner>
|
|
||||||
<type>bool</type>
|
|
||||||
<default>true</default>
|
|
||||||
<locale name="C">
|
|
||||||
<short>Workspaces only on primary monitor</short>
|
|
||||||
<long>
|
|
||||||
This key overrides /apps/mutter/general/workspaces_only_on_primary when
|
|
||||||
running GNOME Shell.
|
|
||||||
</long>
|
|
||||||
</locale>
|
|
||||||
</schema>
|
|
||||||
|
|
||||||
</schemalist>
|
|
||||||
</gconfschemafile>
|
|
@ -16,8 +16,9 @@
|
|||||||
<_summary>Uuids of extensions to enable</_summary>
|
<_summary>Uuids of extensions to enable</_summary>
|
||||||
<_description>
|
<_description>
|
||||||
GNOME Shell extensions have a uuid property; this key lists extensions
|
GNOME Shell extensions have a uuid property; this key lists extensions
|
||||||
which should be loaded. disabled-extensions overrides this setting for
|
which should be loaded. Any extension that wants to be loaded needs
|
||||||
extensions that appear in both lists.
|
to be in this list. You can also manipulate this list with the
|
||||||
|
EnableExtension and DisableExtension DBus methods on org.gnome.Shell.
|
||||||
</_description>
|
</_description>
|
||||||
</key>
|
</key>
|
||||||
<key name="enable-app-monitoring" type="b">
|
<key name="enable-app-monitoring" type="b">
|
||||||
@ -50,6 +51,14 @@
|
|||||||
<default>[]</default>
|
<default>[]</default>
|
||||||
<_summary>History for the looking glass dialog</_summary>
|
<_summary>History for the looking glass dialog</_summary>
|
||||||
</key>
|
</key>
|
||||||
|
<key name="saved-im-presence" type="i">
|
||||||
|
<default>1</default>
|
||||||
|
<_summary></_summary>
|
||||||
|
</key>
|
||||||
|
<key name="saved-session-presence" type="i">
|
||||||
|
<default>0</default>
|
||||||
|
<_summary></_summary>
|
||||||
|
</key>
|
||||||
<child name="clock" schema="org.gnome.shell.clock"/>
|
<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"/>
|
||||||
@ -133,4 +142,40 @@
|
|||||||
</_description>
|
</_description>
|
||||||
</key>
|
</key>
|
||||||
</schema>
|
</schema>
|
||||||
|
|
||||||
|
<schema id="org.gnome.shell.overrides" path="/org/gnome/shell/overrides/">
|
||||||
|
<key name="attach-modal-dialogs" type="b">
|
||||||
|
<default>true</default>
|
||||||
|
<summary>Attach modal dialog to the parent window</summary>
|
||||||
|
<description>
|
||||||
|
This key overrides the key in org.gnome.mutter when running
|
||||||
|
GNOME Shell.
|
||||||
|
</description>
|
||||||
|
</key>
|
||||||
|
|
||||||
|
<key name="button-layout" type="s">
|
||||||
|
<default>":close"</default>
|
||||||
|
<summary>Arrangement of buttons on the titlebar</summary>
|
||||||
|
<description>
|
||||||
|
This key overrides the key in org.gnome.desktop.wm.preferences when
|
||||||
|
running GNOME Shell.
|
||||||
|
</description>
|
||||||
|
</key>
|
||||||
|
|
||||||
|
<key name="edge-tiling" type="b">
|
||||||
|
<default>true</default>
|
||||||
|
<summary>Enable edge tiling when dropping windows on screen edges</summary>
|
||||||
|
<description>
|
||||||
|
This key overrides the key in org.gnome.mutter when running GNOME Shell.
|
||||||
|
</description>
|
||||||
|
</key>
|
||||||
|
|
||||||
|
<key name="workspaces-only-on-primary" type="b">
|
||||||
|
<default>true</default>
|
||||||
|
<summary>Workspaces only on primary monitor</summary>
|
||||||
|
<description>
|
||||||
|
This key overrides the key in org.gnome.mutter when running GNOME Shell.
|
||||||
|
</description>
|
||||||
|
</key>
|
||||||
|
</schema>
|
||||||
</schemalist>
|
</schemalist>
|
||||||
|
@ -98,8 +98,12 @@
|
|||||||
color: #666666;
|
color: #666666;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.login-dialog-not-listed-button:hover .login-dialog-not-listed-label {
|
||||||
|
color: white;
|
||||||
|
}
|
||||||
|
|
||||||
.login-dialog-prompt-layout {
|
.login-dialog-prompt-layout {
|
||||||
padding-bottom: 64px;
|
padding-bottom: 32px;
|
||||||
}
|
}
|
||||||
.login-dialog-prompt-label {
|
.login-dialog-prompt-label {
|
||||||
color: white;
|
color: white;
|
||||||
@ -117,6 +121,16 @@
|
|||||||
width: 15em;
|
width: 15em;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.login-dialog-prompt-entry .capslock-warning {
|
||||||
|
icon-size: 16px;
|
||||||
|
warning-color: #999;
|
||||||
|
}
|
||||||
|
|
||||||
|
.login-dialog-prompt-entry:insensitive {
|
||||||
|
color: rgba(0,0,0,0.7);
|
||||||
|
border: 2px solid #565656;
|
||||||
|
}
|
||||||
|
|
||||||
.login-dialog-session-list {
|
.login-dialog-session-list {
|
||||||
color: #ffffff;
|
color: #ffffff;
|
||||||
font-size: 10.5pt;
|
font-size: 10.5pt;
|
||||||
|
@ -36,18 +36,18 @@ stage {
|
|||||||
|
|
||||||
StScrollBar
|
StScrollBar
|
||||||
{
|
{
|
||||||
padding: 0px;
|
padding: 0px;
|
||||||
}
|
}
|
||||||
|
|
||||||
StScrollView.vfade
|
StScrollView.vfade
|
||||||
{
|
{
|
||||||
-st-vfade-offset: 68px;
|
-st-vfade-offset: 68px;
|
||||||
}
|
}
|
||||||
|
|
||||||
StScrollView StScrollBar
|
StScrollView StScrollBar
|
||||||
{
|
{
|
||||||
min-width: 16px;
|
min-width: 16px;
|
||||||
min-height: 16px;
|
min-height: 16px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -509,8 +509,9 @@ StTooltip StLabel {
|
|||||||
width: 60px;
|
width: 60px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.dash-placeholder {
|
.placeholder {
|
||||||
background-image: url("dash-placeholder.svg");
|
background-image: url("dash-placeholder.svg");
|
||||||
|
height: 24px;
|
||||||
}
|
}
|
||||||
|
|
||||||
#viewSelector {
|
#viewSelector {
|
||||||
@ -742,24 +743,24 @@ StTooltip StLabel {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.contact-icon {
|
.contact-icon {
|
||||||
border-radius: 4px;
|
border-radius: 4px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.contact-details {
|
.contact-details {
|
||||||
padding: 6px 8px 11px 8px;
|
padding: 6px 8px 11px 8px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.contact-details-alias {
|
.contact-details-alias {
|
||||||
font-size: 16px;
|
font-size: 16px;
|
||||||
padding-bottom: 11px;
|
padding-bottom: 11px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.contact-details-status {
|
.contact-details-status {
|
||||||
font-size: 11pt;
|
font-size: 11pt;
|
||||||
}
|
}
|
||||||
|
|
||||||
.contact-details-status-icon {
|
.contact-details-status-icon {
|
||||||
padding-right: 2px;
|
padding-right: 2px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.contact:hover {
|
.contact:hover {
|
||||||
@ -800,37 +801,45 @@ StTooltip StLabel {
|
|||||||
|
|
||||||
#LookingGlassDialog
|
#LookingGlassDialog
|
||||||
{
|
{
|
||||||
background-color: rgba(0,0,0,0.85);
|
background-color: rgba(0,0,0,0.80);
|
||||||
spacing: 4px;
|
spacing: 4px;
|
||||||
padding: 4px;
|
padding: 4px;
|
||||||
border: 2px solid grey;
|
border: 2px solid grey;
|
||||||
border-radius: 4px;
|
border-radius: 4px;
|
||||||
|
|
||||||
color: #88ff66;
|
color: #ffffff;
|
||||||
}
|
}
|
||||||
|
|
||||||
#LookingGlassDialog > #Toolbar
|
#LookingGlassDialog > #Toolbar
|
||||||
{
|
{
|
||||||
border: 1px solid grey;
|
border: 1px solid grey;
|
||||||
border-radius: 4px;
|
border-radius: 4px;
|
||||||
}
|
}
|
||||||
|
|
||||||
#LookingGlassDialog .labels {
|
#LookingGlassDialog .labels {
|
||||||
spacing: 4px;
|
spacing: 4px;
|
||||||
}
|
}
|
||||||
|
|
||||||
#LookingGlassDialog .notebook-tab {
|
#LookingGlassDialog .notebook-tab {
|
||||||
padding: 2px;
|
-natural-hpadding: 12px;
|
||||||
|
-minimum-hpadding: 6px;
|
||||||
|
font-weight: bold;
|
||||||
|
color: #ccc;
|
||||||
|
transition-duration: 100;
|
||||||
|
padding-left: .3em;
|
||||||
|
padding-right: .3em;
|
||||||
}
|
}
|
||||||
|
|
||||||
#LookingGlassDialog .notebook-tab:hover {
|
#LookingGlassDialog .notebook-tab:hover {
|
||||||
color: #00ff00;
|
color: white;
|
||||||
|
text-shadow: black 0px 2px 2px;
|
||||||
}
|
}
|
||||||
|
|
||||||
#LookingGlassDialog .notebook-tab:selected {
|
#LookingGlassDialog .notebook-tab:selected {
|
||||||
border: 1px solid #88ff66;
|
border-image: url("panel-button-border.svg") 10 10 0 2;
|
||||||
border-radius: 4px;
|
background-image: url("panel-button-highlight-wide.svg");
|
||||||
padding: 5px;
|
color: white;
|
||||||
|
text-shadow: black 0px 2px 2px;
|
||||||
}
|
}
|
||||||
|
|
||||||
#LookingGlassDialog .lg-inspector-title {
|
#LookingGlassDialog .lg-inspector-title {
|
||||||
@ -840,52 +849,58 @@ StTooltip StLabel {
|
|||||||
|
|
||||||
.lg-dialog StLabel
|
.lg-dialog StLabel
|
||||||
{
|
{
|
||||||
color: #88ff66;
|
color: #ffffff;
|
||||||
}
|
}
|
||||||
|
|
||||||
.lg-dialog StEntry
|
.lg-dialog StEntry
|
||||||
{
|
{
|
||||||
color: #88ff66;
|
color: #ffffff;
|
||||||
selection-background-color: #88ff66;
|
selection-background-color: #bbbbbb;
|
||||||
selected-color: black;
|
selected-color: #333333;
|
||||||
|
}
|
||||||
|
|
||||||
|
.lg-completions-text
|
||||||
|
{
|
||||||
|
font-size: .9em;
|
||||||
|
font-style: italic;
|
||||||
}
|
}
|
||||||
|
|
||||||
.lg-obj-inspector-title
|
.lg-obj-inspector-title
|
||||||
{
|
{
|
||||||
spacing: 4px;
|
spacing: 4px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.lg-obj-inspector-button
|
.lg-obj-inspector-button
|
||||||
{
|
{
|
||||||
border: 1px solid #88ff66;
|
border: 1px solid gray;
|
||||||
padding: 4px;
|
padding: 4px;
|
||||||
border-radius: 4px;
|
border-radius: 4px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.lg-obj-inspector-button:hover
|
.lg-obj-inspector-button:hover
|
||||||
{
|
{
|
||||||
border: 1px solid #00ff00;
|
border: 1px solid #ffffff;
|
||||||
}
|
}
|
||||||
|
|
||||||
.lg-dialog .shell-link
|
.lg-dialog .shell-link
|
||||||
{
|
{
|
||||||
color: #88ff66;
|
color: #999999;
|
||||||
}
|
}
|
||||||
|
|
||||||
.lg-dialog .shell-link:hover
|
.lg-dialog .shell-link:hover
|
||||||
{
|
{
|
||||||
color: #00ff00;
|
color: #dddddd;
|
||||||
}
|
}
|
||||||
|
|
||||||
#LookingGlassDialog StBoxLayout#EvalBox
|
#LookingGlassDialog StBoxLayout#EvalBox
|
||||||
{
|
{
|
||||||
padding: 4px;
|
padding: 4px;
|
||||||
spacing: 4px;
|
spacing: 4px;
|
||||||
}
|
}
|
||||||
|
|
||||||
#LookingGlassDialog StBoxLayout#ResultsArea
|
#LookingGlassDialog StBoxLayout#ResultsArea
|
||||||
{
|
{
|
||||||
spacing: 4px;
|
spacing: 4px;
|
||||||
}
|
}
|
||||||
|
|
||||||
#lookingGlassExtensions {
|
#lookingGlassExtensions {
|
||||||
@ -907,16 +922,16 @@ StTooltip StLabel {
|
|||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
}
|
}
|
||||||
|
|
||||||
.lg-extension-actions {
|
.lg-extension-meta {
|
||||||
spacing: 6px;
|
spacing: 6px;
|
||||||
}
|
}
|
||||||
|
|
||||||
#LookingGlassPropertyInspector {
|
#LookingGlassPropertyInspector {
|
||||||
background: rgba(0, 0, 0, 0.9);
|
background: rgba(0, 0, 0, 0.8);
|
||||||
border: 2px solid grey;
|
border: 2px solid grey;
|
||||||
border-radius: 4px;
|
border-radius: 4px;
|
||||||
padding: 6px;
|
padding: 6px;
|
||||||
color: #88ff66;
|
color: #ffffff;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Calendar popup */
|
/* Calendar popup */
|
||||||
@ -1209,6 +1224,7 @@ StTooltip StLabel {
|
|||||||
|
|
||||||
#notification-scrollview {
|
#notification-scrollview {
|
||||||
max-height: 10em;
|
max-height: 10em;
|
||||||
|
-st-vfade-offset: 24px;
|
||||||
}
|
}
|
||||||
|
|
||||||
#notification-scrollview > .top-shadow, #notification-scrollview > .bottom-shadow {
|
#notification-scrollview > .top-shadow, #notification-scrollview > .bottom-shadow {
|
||||||
@ -1251,7 +1267,8 @@ StTooltip StLabel {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.notification-icon-button > StIcon {
|
.notification-icon-button > StIcon {
|
||||||
icon-size: 36px;
|
icon-size: 16px;
|
||||||
|
padding: 8px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.hotplug-transient-box {
|
.hotplug-transient-box {
|
||||||
@ -1321,9 +1338,8 @@ StTooltip StLabel {
|
|||||||
padding: 8px 0;
|
padding: 8px 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.chat-sent {
|
.chat-received {
|
||||||
padding-left: 4px;
|
padding-left: 4px;
|
||||||
border-radius: 4px;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.chat-received:rtl {
|
.chat-received:rtl {
|
||||||
@ -1333,8 +1349,7 @@ StTooltip StLabel {
|
|||||||
|
|
||||||
.chat-sent {
|
.chat-sent {
|
||||||
padding-left: 18pt;
|
padding-left: 18pt;
|
||||||
border-radius: 4px;
|
color: #959595;
|
||||||
color: #7E7E7E;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.chat-sent:rtl {
|
.chat-sent:rtl {
|
||||||
@ -1344,7 +1359,6 @@ StTooltip StLabel {
|
|||||||
|
|
||||||
.chat-meta-message {
|
.chat-meta-message {
|
||||||
padding-left: 4px;
|
padding-left: 4px;
|
||||||
border-radius: 4px;
|
|
||||||
font-size: 9pt;
|
font-size: 9pt;
|
||||||
color: #bbbbbb;
|
color: #bbbbbb;
|
||||||
}
|
}
|
||||||
@ -1899,6 +1913,7 @@ StTooltip StLabel {
|
|||||||
background-gradient-end: white;
|
background-gradient-end: white;
|
||||||
background-gradient-direction: vertical;
|
background-gradient-direction: vertical;
|
||||||
color: black;
|
color: black;
|
||||||
|
selected-color: white;
|
||||||
border-radius: 5px;
|
border-radius: 5px;
|
||||||
border: 2px solid #555753;
|
border: 2px solid #555753;
|
||||||
}
|
}
|
||||||
@ -1907,6 +1922,12 @@ StTooltip StLabel {
|
|||||||
border: 2px solid #3465a4;
|
border: 2px solid #3465a4;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.polkit-dialog-password-entry .capslock-warning {
|
||||||
|
icon-size: 16px;
|
||||||
|
warning-color: #999;
|
||||||
|
padding: 0 4px;
|
||||||
|
}
|
||||||
|
|
||||||
.polkit-dialog-error-label {
|
.polkit-dialog-error-label {
|
||||||
font-size: 10pt;
|
font-size: 10pt;
|
||||||
color: #ffff00;
|
color: #ffff00;
|
||||||
@ -1925,14 +1946,6 @@ StTooltip StLabel {
|
|||||||
padding-bottom: 8px;
|
padding-bottom: 8px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.network-dialog-show-password-checkbox {
|
|
||||||
padding-top: 5px;
|
|
||||||
padding-bottom: 5px;
|
|
||||||
font-size: 10pt;
|
|
||||||
color: white;
|
|
||||||
spacing: 10px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.network-dialog-secret-table {
|
.network-dialog-secret-table {
|
||||||
spacing-rows: 15px;
|
spacing-rows: 15px;
|
||||||
}
|
}
|
||||||
|
1
docs/Makefile.am
Normal file
1
docs/Makefile.am
Normal file
@ -0,0 +1 @@
|
|||||||
|
SUBDIRS = reference
|
1
docs/reference/Makefile.am
Normal file
1
docs/reference/Makefile.am
Normal file
@ -0,0 +1 @@
|
|||||||
|
SUBDIRS = shell st
|
105
docs/reference/shell/Makefile.am
Normal file
105
docs/reference/shell/Makefile.am
Normal file
@ -0,0 +1,105 @@
|
|||||||
|
## Process this file with automake to produce Makefile.in
|
||||||
|
|
||||||
|
# We require automake 1.6 at least.
|
||||||
|
AUTOMAKE_OPTIONS = 1.6
|
||||||
|
|
||||||
|
# This is a blank Makefile.am for using gtk-doc.
|
||||||
|
# Copy this to your project's API docs directory and modify the variables to
|
||||||
|
# suit your project. See the GTK+ Makefiles in gtk+/docs/reference for examples
|
||||||
|
# of using the various options.
|
||||||
|
|
||||||
|
# The name of the module, e.g. 'glib'.
|
||||||
|
DOC_MODULE=shell
|
||||||
|
|
||||||
|
# Uncomment for versioned docs and specify the version of the module, e.g. '2'.
|
||||||
|
#DOC_MODULE_VERSION=2
|
||||||
|
|
||||||
|
|
||||||
|
# The top-level SGML file. You can change this if you want to.
|
||||||
|
DOC_MAIN_SGML_FILE=$(DOC_MODULE)-docs.sgml
|
||||||
|
|
||||||
|
# Directories containing the source code, relative to $(srcdir).
|
||||||
|
# gtk-doc will search all .c and .h files beneath these paths
|
||||||
|
# for inline comments documenting functions and macros.
|
||||||
|
# e.g. DOC_SOURCE_DIR=../../../gtk ../../../gdk
|
||||||
|
DOC_SOURCE_DIR=../../../src
|
||||||
|
|
||||||
|
# Extra options to pass to gtkdoc-scangobj. Not normally needed.
|
||||||
|
SCANGOBJ_OPTIONS=
|
||||||
|
|
||||||
|
# Extra options to supply to gtkdoc-scan.
|
||||||
|
# e.g. SCAN_OPTIONS=--deprecated-guards="GTK_DISABLE_DEPRECATED"
|
||||||
|
SCAN_OPTIONS=--rebuild-types
|
||||||
|
|
||||||
|
# Extra options to supply to gtkdoc-mkdb.
|
||||||
|
# e.g. MKDB_OPTIONS=--xml-mode --output-format=xml
|
||||||
|
MKDB_OPTIONS=--xml-mode --output-format=xml
|
||||||
|
|
||||||
|
# Extra options to supply to gtkdoc-mktmpl
|
||||||
|
# e.g. MKTMPL_OPTIONS=--only-section-tmpl
|
||||||
|
MKTMPL_OPTIONS=
|
||||||
|
|
||||||
|
# Extra options to supply to gtkdoc-mkhtml
|
||||||
|
MKHTML_OPTIONS=
|
||||||
|
|
||||||
|
# Extra options to supply to gtkdoc-fixref. Not normally needed.
|
||||||
|
# e.g. FIXXREF_OPTIONS=--extra-dir=../gdk-pixbuf/html --extra-dir=../gdk/html
|
||||||
|
FIXXREF_OPTIONS=
|
||||||
|
|
||||||
|
# Used for dependencies. The docs will be rebuilt if any of these change.
|
||||||
|
# e.g. HFILE_GLOB=$(top_srcdir)/gtk/*.h
|
||||||
|
# e.g. CFILE_GLOB=$(top_srcdir)/gtk/*.c
|
||||||
|
HFILE_GLOB=$(top_srcdir)/src/*.h
|
||||||
|
CFILE_GLOB=$(top_srcdir)/src/*.c
|
||||||
|
|
||||||
|
# Extra header to include when scanning, which are not under DOC_SOURCE_DIR
|
||||||
|
# e.g. EXTRA_HFILES=$(top_srcdir}/contrib/extra.h
|
||||||
|
EXTRA_HFILES=
|
||||||
|
|
||||||
|
# Header files or dirs to ignore when scanning. Use base file/dir names
|
||||||
|
# e.g. IGNORE_HFILES=gtkdebug.h gtkintl.h private_code
|
||||||
|
IGNORE_HFILES=calendar-server gvc hotplug-sniffer st tray
|
||||||
|
|
||||||
|
# Images to copy into HTML directory.
|
||||||
|
# e.g. HTML_IMAGES=$(top_srcdir)/gtk/stock-icons/stock_about_24.png
|
||||||
|
HTML_IMAGES=
|
||||||
|
|
||||||
|
# Extra SGML files that are included by $(DOC_MAIN_SGML_FILE).
|
||||||
|
# e.g. content_files=running.sgml building.sgml changes-2.0.sgml
|
||||||
|
content_files=
|
||||||
|
|
||||||
|
# SGML files where gtk-doc abbrevations (#GtkWidget) are expanded
|
||||||
|
# These files must be listed here *and* in content_files
|
||||||
|
# e.g. expand_content_files=running.sgml
|
||||||
|
expand_content_files=
|
||||||
|
|
||||||
|
# CFLAGS and LDFLAGS for compiling gtkdoc-scangobj with your library.
|
||||||
|
# Only needed if you are using gtkdoc-scangobj to dynamically query widget
|
||||||
|
# signals and properties.
|
||||||
|
# e.g. GTKDOC_CFLAGS=-I$(top_srcdir) -I$(top_builddir) $(GTK_DEBUG_FLAGS)
|
||||||
|
# e.g. GTKDOC_LIBS=$(top_builddir)/gtk/$(gtktargetlib)
|
||||||
|
GTKDOC_CFLAGS=$(GNOME_SHELL_CFLAGS)
|
||||||
|
GTKDOC_LIBS=$(GNOME_SHELL_LIBS) $(top_builddir)/src/libgnome-shell.la
|
||||||
|
|
||||||
|
# This includes the standard gtk-doc make rules, copied by gtkdocize.
|
||||||
|
include $(top_srcdir)/gtk-doc.make
|
||||||
|
|
||||||
|
# Other files to distribute
|
||||||
|
# e.g. EXTRA_DIST += version.xml.in
|
||||||
|
EXTRA_DIST +=
|
||||||
|
|
||||||
|
# Files not to distribute
|
||||||
|
# for --rebuild-types in $(SCAN_OPTIONS), e.g. $(DOC_MODULE).types
|
||||||
|
# for --rebuild-sections in $(SCAN_OPTIONS) e.g. $(DOC_MODULE)-sections.txt
|
||||||
|
DISTCLEANFILES = $(DOC_MODULES).types
|
||||||
|
|
||||||
|
# Comment this out if you want 'make check' to test you doc status
|
||||||
|
# and run some sanity checks
|
||||||
|
if ENABLE_GTK_DOC
|
||||||
|
TESTS_ENVIRONMENT = cd $(srcdir) && \
|
||||||
|
DOC_MODULE=$(DOC_MODULE) DOC_MAIN_SGML_FILE=$(DOC_MAIN_SGML_FILE) \
|
||||||
|
SRCDIR=$(abs_srcdir) BUILDDIR=$(abs_builddir)
|
||||||
|
#TESTS = $(GTKDOC_CHECK)
|
||||||
|
endif
|
||||||
|
|
||||||
|
-include $(top_srcdir)/git.mk
|
73
docs/reference/shell/shell-docs.sgml.in
Normal file
73
docs/reference/shell/shell-docs.sgml.in
Normal file
@ -0,0 +1,73 @@
|
|||||||
|
<?xml version="1.0"?>
|
||||||
|
<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.3//EN"
|
||||||
|
"http://www.oasis-open.org/docbook/xml/4.3/docbookx.dtd"
|
||||||
|
[
|
||||||
|
<!ENTITY % local.common.attrib "xmlns:xi CDATA #FIXED 'http://www.w3.org/2003/XInclude'">
|
||||||
|
]>
|
||||||
|
<book id="index">
|
||||||
|
<bookinfo>
|
||||||
|
<title>Shell Reference Manual</title>
|
||||||
|
<releaseinfo>
|
||||||
|
for Shell @VERSION@.
|
||||||
|
<!--The latest version of this documentation can be found on-line at
|
||||||
|
<ulink role="online-location" url="http://[SERVER]/shell/index.html">http://[SERVER]/shell/</ulink>.-->
|
||||||
|
</releaseinfo>
|
||||||
|
</bookinfo>
|
||||||
|
|
||||||
|
<chapter>
|
||||||
|
<title>Actors</title>
|
||||||
|
<xi:include href="xml/shell-generic-container.xml"/>
|
||||||
|
<xi:include href="xml/shell-slicer.xml"/>
|
||||||
|
<xi:include href="xml/shell-stack.xml"/>
|
||||||
|
</chapter>
|
||||||
|
<chapter>
|
||||||
|
<title>Application tracking</title>
|
||||||
|
<xi:include href="xml/shell-app.xml"/>
|
||||||
|
<xi:include href="xml/shell-app-usage.xml"/>
|
||||||
|
<xi:include href="xml/shell-window-tracker.xml"/>
|
||||||
|
</chapter>
|
||||||
|
<chapter>
|
||||||
|
<title>Search</title>
|
||||||
|
<xi:include href="xml/shell-app-system.xml"/>
|
||||||
|
<xi:include href="xml/shell-contact-system.xml"/>
|
||||||
|
<xi:include href="xml/shell-doc-system.xml"/>
|
||||||
|
</chapter>
|
||||||
|
<chapter>
|
||||||
|
<title>Tray Icons</title>
|
||||||
|
<xi:include href="xml/shell-embedded-window.xml"/>
|
||||||
|
<xi:include href="xml/shell-gtk-embed.xml"/>
|
||||||
|
<xi:include href="xml/shell-tray-icon.xml"/>
|
||||||
|
<xi:include href="xml/shell-tray-manager.xml"/>
|
||||||
|
</chapter>
|
||||||
|
<chapter>
|
||||||
|
<title>Recorder</title>
|
||||||
|
<xi:include href="xml/shell-recorder.xml"/>
|
||||||
|
<xi:include href="xml/shell-recorder-src.xml"/>
|
||||||
|
</chapter>
|
||||||
|
<chapter>
|
||||||
|
<title>Integration helpers and utilities</title>
|
||||||
|
<xi:include href="xml/shell-global.xml"/>
|
||||||
|
<xi:include href="xml/shell-wm.xml"/>
|
||||||
|
<xi:include href="xml/shell-xfixes-cursor.xml"/>
|
||||||
|
<xi:include href="xml/shell-util.xml"/>
|
||||||
|
<xi:include href="xml/shell-mount-operation.xml"/>
|
||||||
|
<xi:include href="xml/shell-mobile-providers.xml"/>
|
||||||
|
<xi:include href="xml/shell-network-agent.xml"/>
|
||||||
|
<xi:include href="xml/shell-polkit-authentication-agent.xml"/>
|
||||||
|
<xi:include href="xml/shell-tp-client.xml"/>
|
||||||
|
</chapter>
|
||||||
|
<chapter id="object-tree">
|
||||||
|
<title>Object Hierarchy</title>
|
||||||
|
<xi:include href="xml/tree_index.sgml"/>
|
||||||
|
</chapter>
|
||||||
|
<index id="api-index-full">
|
||||||
|
<title>API Index</title>
|
||||||
|
<xi:include href="xml/api-index-full.xml"><xi:fallback /></xi:include>
|
||||||
|
</index>
|
||||||
|
<index id="deprecated-api-index" role="deprecated">
|
||||||
|
<title>Index of deprecated API</title>
|
||||||
|
<xi:include href="xml/api-index-deprecated.xml"><xi:fallback /></xi:include>
|
||||||
|
</index>
|
||||||
|
|
||||||
|
<xi:include href="xml/annotation-glossary.xml"><xi:fallback /></xi:include>
|
||||||
|
</book>
|
105
docs/reference/st/Makefile.am
Normal file
105
docs/reference/st/Makefile.am
Normal file
@ -0,0 +1,105 @@
|
|||||||
|
## Process this file with automake to produce Makefile.in
|
||||||
|
|
||||||
|
# We require automake 1.6 at least.
|
||||||
|
AUTOMAKE_OPTIONS = 1.6
|
||||||
|
|
||||||
|
# This is a blank Makefile.am for using gtk-doc.
|
||||||
|
# Copy this to your project's API docs directory and modify the variables to
|
||||||
|
# suit your project. See the GTK+ Makefiles in gtk+/docs/reference for examples
|
||||||
|
# of using the various options.
|
||||||
|
|
||||||
|
# The name of the module, e.g. 'glib'.
|
||||||
|
DOC_MODULE=st
|
||||||
|
|
||||||
|
# Uncomment for versioned docs and specify the version of the module, e.g. '2'.
|
||||||
|
#DOC_MODULE_VERSION=2
|
||||||
|
|
||||||
|
|
||||||
|
# The top-level SGML file. You can change this if you want to.
|
||||||
|
DOC_MAIN_SGML_FILE=$(DOC_MODULE)-docs.sgml
|
||||||
|
|
||||||
|
# Directories containing the source code, relative to $(srcdir).
|
||||||
|
# gtk-doc will search all .c and .h files beneath these paths
|
||||||
|
# for inline comments documenting functions and macros.
|
||||||
|
# e.g. DOC_SOURCE_DIR=../../../gtk ../../../gdk
|
||||||
|
DOC_SOURCE_DIR=../../../src/st
|
||||||
|
|
||||||
|
# Extra options to pass to gtkdoc-scangobj. Not normally needed.
|
||||||
|
SCANGOBJ_OPTIONS=
|
||||||
|
|
||||||
|
# Extra options to supply to gtkdoc-scan.
|
||||||
|
# e.g. SCAN_OPTIONS=--deprecated-guards="GTK_DISABLE_DEPRECATED"
|
||||||
|
SCAN_OPTIONS=--rebuild-types --rebuild-sections
|
||||||
|
|
||||||
|
# Extra options to supply to gtkdoc-mkdb.
|
||||||
|
# e.g. MKDB_OPTIONS=--xml-mode --output-format=xml
|
||||||
|
MKDB_OPTIONS=--xml-mode --output-format=xml
|
||||||
|
|
||||||
|
# Extra options to supply to gtkdoc-mktmpl
|
||||||
|
# e.g. MKTMPL_OPTIONS=--only-section-tmpl
|
||||||
|
MKTMPL_OPTIONS=
|
||||||
|
|
||||||
|
# Extra options to supply to gtkdoc-mkhtml
|
||||||
|
MKHTML_OPTIONS=
|
||||||
|
|
||||||
|
# Extra options to supply to gtkdoc-fixref. Not normally needed.
|
||||||
|
# e.g. FIXXREF_OPTIONS=--extra-dir=../gdk-pixbuf/html --extra-dir=../gdk/html
|
||||||
|
FIXXREF_OPTIONS=
|
||||||
|
|
||||||
|
# Used for dependencies. The docs will be rebuilt if any of these change.
|
||||||
|
# e.g. HFILE_GLOB=$(top_srcdir)/gtk/*.h
|
||||||
|
# e.g. CFILE_GLOB=$(top_srcdir)/gtk/*.c
|
||||||
|
HFILE_GLOB=$(top_srcdir)/src/st/*.h
|
||||||
|
CFILE_GLOB=$(top_srcdir)/src/st/*.c
|
||||||
|
|
||||||
|
# Extra header to include when scanning, which are not under DOC_SOURCE_DIR
|
||||||
|
# e.g. EXTRA_HFILES=$(top_srcdir}/contrib/extra.h
|
||||||
|
EXTRA_HFILES=
|
||||||
|
|
||||||
|
# Header files or dirs to ignore when scanning. Use base file/dir names
|
||||||
|
# e.g. IGNORE_HFILES=gtkdebug.h gtkintl.h private_code
|
||||||
|
IGNORE_HFILES=st-private.h st-theme-node-private.h
|
||||||
|
|
||||||
|
# Images to copy into HTML directory.
|
||||||
|
# e.g. HTML_IMAGES=$(top_srcdir)/gtk/stock-icons/stock_about_24.png
|
||||||
|
HTML_IMAGES=
|
||||||
|
|
||||||
|
# Extra SGML files that are included by $(DOC_MAIN_SGML_FILE).
|
||||||
|
# e.g. content_files=running.sgml building.sgml changes-2.0.sgml
|
||||||
|
content_files=
|
||||||
|
|
||||||
|
# SGML files where gtk-doc abbrevations (#GtkWidget) are expanded
|
||||||
|
# These files must be listed here *and* in content_files
|
||||||
|
# e.g. expand_content_files=running.sgml
|
||||||
|
expand_content_files=
|
||||||
|
|
||||||
|
# CFLAGS and LDFLAGS for compiling gtkdoc-scangobj with your library.
|
||||||
|
# Only needed if you are using gtkdoc-scangobj to dynamically query widget
|
||||||
|
# signals and properties.
|
||||||
|
# e.g. GTKDOC_CFLAGS=-I$(top_srcdir) -I$(top_builddir) $(GTK_DEBUG_FLAGS)
|
||||||
|
# e.g. GTKDOC_LIBS=$(top_builddir)/gtk/$(gtktargetlib)
|
||||||
|
GTKDOC_CFLAGS=
|
||||||
|
GTKDOC_LIBS=$(top_builddir)/src/libst-1.0.la
|
||||||
|
|
||||||
|
# This includes the standard gtk-doc make rules, copied by gtkdocize.
|
||||||
|
include $(top_srcdir)/gtk-doc.make
|
||||||
|
|
||||||
|
# Other files to distribute
|
||||||
|
# e.g. EXTRA_DIST += version.xml.in
|
||||||
|
EXTRA_DIST +=
|
||||||
|
|
||||||
|
# Files not to distribute
|
||||||
|
# for --rebuild-types in $(SCAN_OPTIONS), e.g. $(DOC_MODULE).types
|
||||||
|
# for --rebuild-sections in $(SCAN_OPTIONS) e.g. $(DOC_MODULE)-sections.txt
|
||||||
|
DISTCLEANFILES = $(DOC_MODULE).types $(DOC_MODULE)-sections.txt
|
||||||
|
|
||||||
|
# Comment this out if you want 'make check' to test you doc status
|
||||||
|
# and run some sanity checks
|
||||||
|
if ENABLE_GTK_DOC
|
||||||
|
TESTS_ENVIRONMENT = cd $(srcdir) && \
|
||||||
|
DOC_MODULE=$(DOC_MODULE) DOC_MAIN_SGML_FILE=$(DOC_MAIN_SGML_FILE) \
|
||||||
|
SRCDIR=$(abs_srcdir) BUILDDIR=$(abs_builddir)
|
||||||
|
#TESTS = $(GTKDOC_CHECK)
|
||||||
|
endif
|
||||||
|
|
||||||
|
-include $(top_srcdir)/git.mk
|
68
docs/reference/st/st-docs.sgml.in
Normal file
68
docs/reference/st/st-docs.sgml.in
Normal file
@ -0,0 +1,68 @@
|
|||||||
|
<?xml version="1.0"?>
|
||||||
|
<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.3//EN"
|
||||||
|
"http://www.oasis-open.org/docbook/xml/4.3/docbookx.dtd"
|
||||||
|
[
|
||||||
|
<!ENTITY % local.common.attrib "xmlns:xi CDATA #FIXED 'http://www.w3.org/2003/XInclude'">
|
||||||
|
]>
|
||||||
|
<book id="index">
|
||||||
|
<bookinfo>
|
||||||
|
<title>St Reference Manual</title>
|
||||||
|
<releaseinfo>
|
||||||
|
for St @VERSION@.
|
||||||
|
<!--The latest version of this documentation can be found on-line at
|
||||||
|
<ulink role="online-location" url="http://[SERVER]/st/index.html">http://[SERVER]/st/</ulink>.-->
|
||||||
|
</releaseinfo>
|
||||||
|
</bookinfo>
|
||||||
|
|
||||||
|
<part>
|
||||||
|
<title>API reference</title>
|
||||||
|
<chapter id="base">
|
||||||
|
<title>Abstract classes and Interfaces</title>
|
||||||
|
<xi:include href="xml/st-widget.xml"/>
|
||||||
|
<xi:include href="xml/st-widget-accessible.xml"/>
|
||||||
|
<xi:include href="xml/st-container.xml"/>
|
||||||
|
<xi:include href="xml/st-scrollable.xml"/>
|
||||||
|
</chapter>
|
||||||
|
<chapter id="widgets">
|
||||||
|
<title>Widgets</title>
|
||||||
|
<xi:include href="xml/st-button.xml"/>
|
||||||
|
<xi:include href="xml/st-drawing-area.xml"/>
|
||||||
|
<xi:include href="xml/st-entry.xml"/>
|
||||||
|
<xi:include href="xml/st-icon.xml"/>
|
||||||
|
<xi:include href="xml/st-label.xml"/>
|
||||||
|
<xi:include href="xml/st-tooltip.xml"/>
|
||||||
|
</chapter>
|
||||||
|
<chapter id="containers">
|
||||||
|
<title>Containers</title>
|
||||||
|
<xi:include href="xml/st-bin.xml"/>
|
||||||
|
<xi:include href="xml/st-box-layout.xml"/>
|
||||||
|
<xi:include href="xml/st-group.xml"/>
|
||||||
|
<xi:include href="xml/st-overflow-box.xml"/>
|
||||||
|
<xi:include href="xml/st-scroll-view.xml"/>
|
||||||
|
<xi:include href="xml/st-table.xml"/>
|
||||||
|
</chapter>
|
||||||
|
|
||||||
|
<chapter id="styling">
|
||||||
|
<title>Styling</title>
|
||||||
|
<xi:include href="xml/st-theme.xml"/>
|
||||||
|
<xi:include href="xml/st-theme-context.xml"/>
|
||||||
|
<xi:include href="xml/st-theme-node.xml"/>
|
||||||
|
<xi:include href="xml/st-theme-node-transition.xml"/>
|
||||||
|
<xi:include href="xml/st-texture-cache.xml"/>
|
||||||
|
</chapter>
|
||||||
|
</part>
|
||||||
|
<chapter id="object-tree">
|
||||||
|
<title>Object Hierarchy</title>
|
||||||
|
<xi:include href="xml/tree_index.sgml"/>
|
||||||
|
</chapter>
|
||||||
|
<index id="api-index-full">
|
||||||
|
<title>API Index</title>
|
||||||
|
<xi:include href="xml/api-index-full.xml"><xi:fallback /></xi:include>
|
||||||
|
</index>
|
||||||
|
<index id="deprecated-api-index" role="deprecated">
|
||||||
|
<title>Index of deprecated API</title>
|
||||||
|
<xi:include href="xml/api-index-deprecated.xml"><xi:fallback /></xi:include>
|
||||||
|
</index>
|
||||||
|
|
||||||
|
<xi:include href="xml/annotation-glossary.xml"><xi:fallback /></xi:include>
|
||||||
|
</book>
|
@ -13,6 +13,7 @@ nobase_dist_js_DATA = \
|
|||||||
misc/format.js \
|
misc/format.js \
|
||||||
misc/gnomeSession.js \
|
misc/gnomeSession.js \
|
||||||
misc/history.js \
|
misc/history.js \
|
||||||
|
misc/jsParse.js \
|
||||||
misc/modemManager.js \
|
misc/modemManager.js \
|
||||||
misc/params.js \
|
misc/params.js \
|
||||||
misc/screenSaver.js \
|
misc/screenSaver.js \
|
||||||
@ -46,6 +47,7 @@ nobase_dist_js_DATA = \
|
|||||||
ui/messageTray.js \
|
ui/messageTray.js \
|
||||||
ui/modalDialog.js \
|
ui/modalDialog.js \
|
||||||
ui/networkAgent.js \
|
ui/networkAgent.js \
|
||||||
|
ui/shellEntry.js \
|
||||||
ui/shellMountOperation.js \
|
ui/shellMountOperation.js \
|
||||||
ui/notificationDaemon.js \
|
ui/notificationDaemon.js \
|
||||||
ui/overview.js \
|
ui/overview.js \
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/* -*- mode: js2; js2-basic-offset: 4; indent-tabs-mode: nil -*-
|
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
|
||||||
*
|
/*
|
||||||
* Copyright 2011 Red Hat, Inc
|
* Copyright 2011 Red Hat, Inc
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
// -*- mode: js2; indent-tabs-mode: nil; js2-basic-offset: 4 -*-
|
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
|
||||||
|
|
||||||
const DBus = imports.dbus;
|
const DBus = imports.dbus;
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
// -*- mode: js2; indent-tabs-mode: nil; js2-basic-offset: 4 -*-
|
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
|
||||||
|
|
||||||
const DBus = imports.dbus;
|
const DBus = imports.dbus;
|
||||||
const Lang = imports.lang;
|
const Lang = imports.lang;
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/* -*- mode: js2; js2-basic-offset: 4; indent-tabs-mode: nil -*-
|
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
|
||||||
*
|
/*
|
||||||
* Copyright 2011 Red Hat, Inc
|
* Copyright 2011 Red Hat, Inc
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* This program is free software; you can redistribute it and/or modify
|
||||||
@ -297,6 +297,20 @@ UserList.prototype = {
|
|||||||
x_align: St.Align.START,
|
x_align: St.Align.START,
|
||||||
y_align: St.Align.MIDDLE });
|
y_align: St.Align.MIDDLE });
|
||||||
this._items = {};
|
this._items = {};
|
||||||
|
|
||||||
|
this.actor.connect('key-focus-in', Lang.bind(this, this._moveFocusToItems));
|
||||||
|
},
|
||||||
|
|
||||||
|
_moveFocusToItems: function() {
|
||||||
|
let hasItems = Object.keys(this._items).length > 0;
|
||||||
|
|
||||||
|
if (!hasItems)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (global.stage.get_key_focus() != this.actor)
|
||||||
|
return;
|
||||||
|
|
||||||
|
this.actor.navigate_focus(null, Gtk.DirectionType.TAB_FORWARD, false);
|
||||||
},
|
},
|
||||||
|
|
||||||
_showItem: function(item) {
|
_showItem: function(item) {
|
||||||
@ -502,6 +516,8 @@ UserList.prototype = {
|
|||||||
item.showFocusAnimation(0);
|
item.showFocusAnimation(0);
|
||||||
}));
|
}));
|
||||||
|
|
||||||
|
this._moveFocusToItems();
|
||||||
|
|
||||||
this.emit('item-added', item);
|
this.emit('item-added', item);
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -694,10 +710,13 @@ SessionList.prototype = {
|
|||||||
let ids = GdmGreeter.get_session_ids();
|
let ids = GdmGreeter.get_session_ids();
|
||||||
ids.sort();
|
ids.sort();
|
||||||
|
|
||||||
if (ids.length <= 1)
|
if (ids.length <= 1) {
|
||||||
this._box.hide();
|
this._box.hide();
|
||||||
else
|
this._button.hide();
|
||||||
|
} else {
|
||||||
|
this._button.show();
|
||||||
this._box.show();
|
this._box.show();
|
||||||
|
}
|
||||||
|
|
||||||
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] = GdmGreeter.get_session_name_and_description(ids[i]);
|
||||||
@ -825,7 +844,7 @@ LoginDialog.prototype = {
|
|||||||
x_fill: true,
|
x_fill: true,
|
||||||
y_fill: false,
|
y_fill: false,
|
||||||
x_align: St.Align.START });
|
x_align: St.Align.START });
|
||||||
// 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
|
||||||
this._promptFingerprintMessage = new St.Label({ text: _("(or swipe finger)"),
|
this._promptFingerprintMessage = new St.Label({ text: _("(or swipe finger)"),
|
||||||
style_class: 'login-dialog-prompt-fingerprint-message' });
|
style_class: 'login-dialog-prompt-fingerprint-message' });
|
||||||
@ -845,6 +864,9 @@ LoginDialog.prototype = {
|
|||||||
x_align: St.Align.START });
|
x_align: St.Align.START });
|
||||||
this._promptBox.hide();
|
this._promptBox.hide();
|
||||||
|
|
||||||
|
// translators: this message is shown below the user list on the
|
||||||
|
// login screen. It can be activated to reveal an entry for
|
||||||
|
// manually entering the username.
|
||||||
let notListedLabel = new St.Label({ text: _("Not listed?"),
|
let notListedLabel = new St.Label({ text: _("Not listed?"),
|
||||||
style_class: 'login-dialog-not-listed-label' });
|
style_class: 'login-dialog-not-listed-label' });
|
||||||
this._notListedButton = new St.Button({ style_class: 'login-dialog-not-listed-button',
|
this._notListedButton = new St.Button({ style_class: 'login-dialog-not-listed-button',
|
||||||
@ -922,6 +944,7 @@ LoginDialog.prototype = {
|
|||||||
|
|
||||||
function() {
|
function() {
|
||||||
this._sessionList.close();
|
this._sessionList.close();
|
||||||
|
this._promptFingerprintMessage.hide();
|
||||||
this._userList.actor.show();
|
this._userList.actor.show();
|
||||||
this._userList.actor.opacity = 255;
|
this._userList.actor.opacity = 255;
|
||||||
return this._userList.showItems();
|
return this._userList.showItems();
|
||||||
@ -943,7 +966,18 @@ LoginDialog.prototype = {
|
|||||||
},
|
},
|
||||||
|
|
||||||
_onInfo: function(client, serviceName, info) {
|
_onInfo: function(client, serviceName, info) {
|
||||||
// we don't want fingerprint messages with the word UPEK in them
|
// We don't display fingerprint messages, because they
|
||||||
|
// have words like UPEK in them. Instead we use the messages
|
||||||
|
// as a cue to display our own message.
|
||||||
|
if (serviceName == _FINGERPRINT_SERVICE_NAME &&
|
||||||
|
this._haveFingerprintReader &&
|
||||||
|
(!this._promptFingerprintMessage.visible ||
|
||||||
|
this._promptFingerprintMessage.opacity != 255)) {
|
||||||
|
|
||||||
|
_fadeInActor(this._promptFingerprintMessage);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (serviceName != _PASSWORD_SERVICE_NAME)
|
if (serviceName != _PASSWORD_SERVICE_NAME)
|
||||||
return;
|
return;
|
||||||
Main.notifyError(info);
|
Main.notifyError(info);
|
||||||
@ -971,10 +1005,10 @@ LoginDialog.prototype = {
|
|||||||
},
|
},
|
||||||
|
|
||||||
function() {
|
function() {
|
||||||
if (!this._haveFingerprintReader)
|
// Show it with 0 opacity so we preallocate space for it
|
||||||
return null;
|
// in the event we need to fade in the message
|
||||||
|
this._promptFingerprintMessage.opacity = 0;
|
||||||
return _fadeInActor(this._promptFingerprintMessage);
|
this._promptFingerprintMessage.show();
|
||||||
},
|
},
|
||||||
|
|
||||||
function() {
|
function() {
|
||||||
@ -1046,6 +1080,8 @@ LoginDialog.prototype = {
|
|||||||
|
|
||||||
function() {
|
function() {
|
||||||
this._promptFingerprintMessage.hide();
|
this._promptFingerprintMessage.hide();
|
||||||
|
this._promptEntry.reactive = true;
|
||||||
|
this._promptEntry.remove_style_pseudo_class('insensitive');
|
||||||
this._promptEntry.set_text('');
|
this._promptEntry.set_text('');
|
||||||
}];
|
}];
|
||||||
|
|
||||||
@ -1061,7 +1097,8 @@ LoginDialog.prototype = {
|
|||||||
|
|
||||||
function() {
|
function() {
|
||||||
let _text = this._promptEntry.get_text();
|
let _text = this._promptEntry.get_text();
|
||||||
this._promptEntry.set_text('');
|
this._promptEntry.reactive = false;
|
||||||
|
this._promptEntry.add_style_pseudo_class('insensitive');
|
||||||
this._greeterClient.call_answer_query(serviceName, _text);
|
this._greeterClient.call_answer_query(serviceName, _text);
|
||||||
}];
|
}];
|
||||||
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/* -*- mode: js2; js2-basic-offset: 4; indent-tabs-mode: nil -*-
|
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
|
||||||
*
|
/*
|
||||||
* Copyright 2011 Red Hat, Inc
|
* Copyright 2011 Red Hat, Inc
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
/* mode: js2; indent-tabs-mode: nil; tab-size: 4 */
|
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
|
||||||
|
|
||||||
/* The name of this package (not localized) */
|
/* The name of this package (not localized) */
|
||||||
const PACKAGE_NAME = '@PACKAGE_NAME@';
|
const PACKAGE_NAME = '@PACKAGE_NAME@';
|
||||||
/* The version of this package */
|
/* The version of this package */
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
/* -*- mode: js2; js2-basic-offset: 4; indent-tabs-mode: nil -*- */
|
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
|
||||||
|
|
||||||
const St = imports.gi.St;
|
const St = imports.gi.St;
|
||||||
const Shell = imports.gi.Shell;
|
const Shell = imports.gi.Shell;
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
|
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
|
||||||
|
|
||||||
const Gio = imports.gi.Gio;
|
const Gio = imports.gi.Gio;
|
||||||
const GLib = imports.gi.GLib;
|
const GLib = imports.gi.GLib;
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
/* -*- mode: js2; js2-basic-offset: 4; indent-tabs-mode: nil -*- */
|
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This function is intended to extend the String object and provide
|
* This function is intended to extend the String object and provide
|
||||||
|
@ -1,20 +1,18 @@
|
|||||||
/* -*- mode: js2; js2-basic-offset: 4; indent-tabs-mode: nil -*- */
|
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
|
||||||
|
|
||||||
const DBus = imports.dbus;
|
const Gio = imports.gi.Gio;
|
||||||
const Lang = imports.lang;
|
const Lang = imports.lang;
|
||||||
const Signals = imports.signals;
|
const Signals = imports.signals;
|
||||||
|
|
||||||
const PresenceIface = {
|
const PresenceIface = <interface name="org.gnome.SessionManager.Presence">
|
||||||
name: 'org.gnome.SessionManager.Presence',
|
<method name="SetStatus">
|
||||||
methods: [{ name: 'SetStatus',
|
<arg type="u" direction="in"/>
|
||||||
inSignature: 'u',
|
</method>
|
||||||
outSignature: '' }],
|
<property name="status" type="u" access="readwrite"/>
|
||||||
properties: [{ name: 'status',
|
<signal name="StatusChanged">
|
||||||
signature: 'u',
|
<arg type="u" direction="out"/>
|
||||||
access: 'readwrite' }],
|
</signal>
|
||||||
signals: [{ name: 'StatusChanged',
|
</interface>;
|
||||||
inSignature: 'u' }]
|
|
||||||
};
|
|
||||||
|
|
||||||
const PresenceStatus = {
|
const PresenceStatus = {
|
||||||
AVAILABLE: 0,
|
AVAILABLE: 0,
|
||||||
@ -23,104 +21,41 @@ const PresenceStatus = {
|
|||||||
IDLE: 3
|
IDLE: 3
|
||||||
};
|
};
|
||||||
|
|
||||||
function Presence() {
|
var PresenceProxy = Gio.DBusProxy.makeProxyWrapper(PresenceIface);
|
||||||
this._init();
|
function Presence(initCallback, cancellable) {
|
||||||
|
return new PresenceProxy(Gio.DBus.session, 'org.gnome.SessionManager',
|
||||||
|
'/org/gnome/SessionManager/Presence', initCallback, cancellable);
|
||||||
}
|
}
|
||||||
|
|
||||||
Presence.prototype = {
|
|
||||||
_init: function() {
|
|
||||||
DBus.session.proxifyObject(this, 'org.gnome.SessionManager', '/org/gnome/SessionManager/Presence', this);
|
|
||||||
},
|
|
||||||
|
|
||||||
getStatus: function(callback) {
|
|
||||||
this.GetRemote('status', Lang.bind(this,
|
|
||||||
function(status, ex) {
|
|
||||||
if (!ex)
|
|
||||||
callback(this, status);
|
|
||||||
}));
|
|
||||||
},
|
|
||||||
|
|
||||||
setStatus: function(status) {
|
|
||||||
this.SetStatusRemote(status);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
DBus.proxifyPrototype(Presence.prototype, PresenceIface);
|
|
||||||
|
|
||||||
// Note inhibitors are immutable objects, so they don't
|
// Note inhibitors are immutable objects, so they don't
|
||||||
// change at runtime (changes always come in the form
|
// change at runtime (changes always come in the form
|
||||||
// of new inhibitors)
|
// of new inhibitors)
|
||||||
const InhibitorIface = {
|
const InhibitorIface = <interface name="org.gnome.SessionManager.Inhibitor">
|
||||||
name: 'org.gnome.SessionManager.Inhibitor',
|
<property name="app_id" type="s" access="read" />
|
||||||
properties: [{ name: 'app_id',
|
<property name="client_id" type="s" access="read" />
|
||||||
signature: 's',
|
<property name="reason" type="s" access="read" />
|
||||||
access: 'readonly' },
|
<property name="flags" type="u" access="read" />
|
||||||
{ name: 'client_id',
|
<property name="toplevel_xid" type="u" access="read" />
|
||||||
signature: 's',
|
<property name="cookie" type="u" access="read" />
|
||||||
access: 'readonly' },
|
</interface>;
|
||||||
{ name: 'reason',
|
|
||||||
signature: 's',
|
|
||||||
access: 'readonly' },
|
|
||||||
{ name: 'flags',
|
|
||||||
signature: 'u',
|
|
||||||
access: 'readonly' },
|
|
||||||
{ name: 'toplevel_xid',
|
|
||||||
signature: 'u',
|
|
||||||
access: 'readonly' },
|
|
||||||
{ name: 'cookie',
|
|
||||||
signature: 'u',
|
|
||||||
access: 'readonly' }],
|
|
||||||
};
|
|
||||||
|
|
||||||
function Inhibitor(objectPath) {
|
var InhibitorProxy = Gio.DBusProxy.makeProxyWrapper(InhibitorIface);
|
||||||
this._init(objectPath);
|
function Inhibitor(objectPath, initCallback, cancellable) {
|
||||||
|
return new InhibitorProxy(Gio.DBus.session, 'org.gnome.SessionManager', objectPath, initCallback, cancellable);
|
||||||
}
|
}
|
||||||
|
|
||||||
Inhibitor.prototype = {
|
|
||||||
_init: function(objectPath) {
|
|
||||||
DBus.session.proxifyObject(this,
|
|
||||||
"org.gnome.SessionManager",
|
|
||||||
objectPath);
|
|
||||||
this.isLoaded = false;
|
|
||||||
this._loadingPropertiesCount = InhibitorIface.properties.length;
|
|
||||||
for (let i = 0; i < InhibitorIface.properties.length; i++) {
|
|
||||||
let propertyName = InhibitorIface.properties[i].name;
|
|
||||||
this.GetRemote(propertyName, Lang.bind(this,
|
|
||||||
function(value, exception) {
|
|
||||||
if (exception)
|
|
||||||
return;
|
|
||||||
|
|
||||||
this[propertyName] = value;
|
|
||||||
this._loadingPropertiesCount--;
|
|
||||||
|
|
||||||
if (this._loadingPropertiesCount == 0) {
|
|
||||||
this.isLoaded = true;
|
|
||||||
this.emit("is-loaded");
|
|
||||||
}
|
|
||||||
}));
|
|
||||||
}
|
|
||||||
},
|
|
||||||
};
|
|
||||||
DBus.proxifyPrototype(Inhibitor.prototype, InhibitorIface);
|
|
||||||
Signals.addSignalMethods(Inhibitor.prototype);
|
|
||||||
|
|
||||||
|
|
||||||
// Not the full interface, only the methods we use
|
// Not the full interface, only the methods we use
|
||||||
const SessionManagerIface = {
|
const SessionManagerIface = <interface name="org.gnome.SessionManager">
|
||||||
name: 'org.gnome.SessionManager',
|
<method name="Logout">
|
||||||
methods: [
|
<arg type="u" direction="in" />
|
||||||
{ name: 'Logout', inSignature: 'u', outSignature: '' },
|
</method>
|
||||||
{ name: 'Shutdown', inSignature: '', outSignature: '' },
|
<method name="Shutdown" />
|
||||||
{ name: 'CanShutdown', inSignature: '', outSignature: 'b' }
|
<method name="CanShutdown">
|
||||||
]
|
<arg type="b" direction="out" />
|
||||||
};
|
</method>
|
||||||
|
</interface>;
|
||||||
|
|
||||||
function SessionManager() {
|
var SessionManagerProxy = Gio.DBusProxy.makeProxyWrapper(SessionManagerIface);
|
||||||
this._init();
|
function SessionManager(initCallback, cancellable) {
|
||||||
|
return new SessionManagerProxy(Gio.DBus.session, 'org.gnome.SessionManager', '/org/gnome/SessionManager', initCallback, cancellable);
|
||||||
}
|
}
|
||||||
|
|
||||||
SessionManager.prototype = {
|
|
||||||
_init: function() {
|
|
||||||
DBus.session.proxifyObject(this, 'org.gnome.SessionManager', '/org/gnome/SessionManager');
|
|
||||||
}
|
|
||||||
};
|
|
||||||
DBus.proxifyPrototype(SessionManager.prototype, SessionManagerIface);
|
|
@ -1,4 +1,4 @@
|
|||||||
/* -*- mode: js2; js2-basic-offset: 4; indent-tabs-mode: nil -*- */
|
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
|
||||||
|
|
||||||
const Lang = imports.lang;
|
const Lang = imports.lang;
|
||||||
const Signals = imports.signals;
|
const Signals = imports.signals;
|
||||||
|
246
js/misc/jsParse.js
Normal file
246
js/misc/jsParse.js
Normal file
@ -0,0 +1,246 @@
|
|||||||
|
/* -*- mode: js2; js2-basic-offset: 4; indent-tabs-mode: nil -*- */
|
||||||
|
|
||||||
|
// Returns a list of potential completions for text. Completions either
|
||||||
|
// follow a dot (e.g. foo.ba -> bar) or they are picked from globalCompletionList (e.g. fo -> foo)
|
||||||
|
// commandHeader is prefixed on any expression before it is eval'ed. It will most likely
|
||||||
|
// consist of global constants that might not carry over from the calling environment.
|
||||||
|
//
|
||||||
|
// This function is likely the one you want to call from external modules
|
||||||
|
function getCompletions(text, commandHeader, globalCompletionList) {
|
||||||
|
let methods = [];
|
||||||
|
let expr, base;
|
||||||
|
let attrHead = '';
|
||||||
|
if (globalCompletionList == null) {
|
||||||
|
globalCompletionList = [];
|
||||||
|
}
|
||||||
|
|
||||||
|
let offset = getExpressionOffset(text, text.length - 1);
|
||||||
|
if (offset >= 0) {
|
||||||
|
text = text.slice(offset);
|
||||||
|
|
||||||
|
// Look for expressions like "Main.panel.foo" and match Main.panel and foo
|
||||||
|
let matches = text.match(/(.*)\.(.*)/);
|
||||||
|
if (matches) {
|
||||||
|
[expr, base, attrHead] = matches;
|
||||||
|
|
||||||
|
methods = getPropertyNamesFromExpression(base, commandHeader).filter(function(attr) {
|
||||||
|
return attr.slice(0, attrHead.length) == attrHead;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// Look for the empty expression or partially entered words
|
||||||
|
// not proceeded by a dot and match them against global constants
|
||||||
|
matches = text.match(/^(\w*)$/);
|
||||||
|
if (text == '' || matches) {
|
||||||
|
[expr, attrHead] = matches;
|
||||||
|
methods = globalCompletionList.filter(function(attr) {
|
||||||
|
return attr.slice(0, attrHead.length) == attrHead;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return [methods, attrHead];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
// A few functions for parsing strings of javascript code.
|
||||||
|
//
|
||||||
|
|
||||||
|
// Identify characters that delimit an expression. That is,
|
||||||
|
// if we encounter anything that isn't a letter, '.', ')', or ']',
|
||||||
|
// we should stop parsing.
|
||||||
|
function isStopChar(c) {
|
||||||
|
return !c.match(/[\w\.\)\]]/);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Given the ending position of a quoted string, find where it starts
|
||||||
|
function findMatchingQuote(expr, offset) {
|
||||||
|
let quoteChar = expr.charAt(offset);
|
||||||
|
for (let i = offset - 1; i >= 0; --i) {
|
||||||
|
if (expr.charAt(i) == quoteChar && expr.charAt(i-1) != '\\'){
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Given the ending position of a regex, find where it starts
|
||||||
|
function findMatchingSlash(expr, offset) {
|
||||||
|
for (let i = offset - 1; i >= 0; --i) {
|
||||||
|
if (expr.charAt(i) == '/' && expr.charAt(i-1) != '\\'){
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// If expr.charAt(offset) is ')' or ']',
|
||||||
|
// return the position of the corresponding '(' or '[' bracket.
|
||||||
|
// This function does not check for syntactic correctness. e.g.,
|
||||||
|
// findMatchingBrace("[(])", 3) returns 1.
|
||||||
|
function findMatchingBrace(expr, offset) {
|
||||||
|
let closeBrace = expr.charAt(offset);
|
||||||
|
let openBrace = ({')': '(', ']': '['})[closeBrace];
|
||||||
|
|
||||||
|
function findTheBrace(expr, offset) {
|
||||||
|
if (offset < 0) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (expr.charAt(offset) == openBrace) {
|
||||||
|
return offset;
|
||||||
|
}
|
||||||
|
if (expr.charAt(offset).match(/['"]/)) {
|
||||||
|
return findTheBrace(expr, findMatchingQuote(expr, offset) - 1);
|
||||||
|
}
|
||||||
|
if (expr.charAt(offset) == '/') {
|
||||||
|
return findTheBrace(expr, findMatchingSlash(expr, offset) - 1);
|
||||||
|
}
|
||||||
|
if (expr.charAt(offset) == closeBrace) {
|
||||||
|
return findTheBrace(expr, findTheBrace(expr, offset - 1) - 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
return findTheBrace(expr, offset - 1);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return findTheBrace(expr, offset - 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Walk expr backwards from offset looking for the beginning of an
|
||||||
|
// expression suitable for passing to eval.
|
||||||
|
// There is no guarantee of correct javascript syntax between the return
|
||||||
|
// value and offset. This function is meant to take a string like
|
||||||
|
// "foo(Obj.We.Are.Completing" and allow you to extract "Obj.We.Are.Completing"
|
||||||
|
function getExpressionOffset(expr, offset) {
|
||||||
|
while (offset >= 0) {
|
||||||
|
let currChar = expr.charAt(offset);
|
||||||
|
|
||||||
|
if (isStopChar(currChar)){
|
||||||
|
return offset + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (currChar.match(/[\)\]]/)) {
|
||||||
|
offset = findMatchingBrace(expr, offset);
|
||||||
|
}
|
||||||
|
|
||||||
|
--offset;
|
||||||
|
}
|
||||||
|
|
||||||
|
return offset + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Things with non-word characters or that start with a number
|
||||||
|
// are not accessible via .foo notation and so aren't returned
|
||||||
|
function isValidPropertyName(w) {
|
||||||
|
return !(w.match(/\W/) || w.match(/^\d/));
|
||||||
|
}
|
||||||
|
|
||||||
|
// To get all properties (enumerable and not), we need to walk
|
||||||
|
// the prototype chain ourselves
|
||||||
|
function getAllProps(obj) {
|
||||||
|
if (obj === null || obj === undefined) {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
return Object.getOwnPropertyNames(obj).concat( getAllProps(Object.getPrototypeOf(obj)) );
|
||||||
|
}
|
||||||
|
|
||||||
|
// Given a string _expr_, returns all methods
|
||||||
|
// that can be accessed via '.' notation.
|
||||||
|
// e.g., expr="({ foo: null, bar: null, 4: null })" will
|
||||||
|
// return ["foo", "bar", ...] but the list will not include "4",
|
||||||
|
// since methods accessed with '.' notation must star with a letter or _.
|
||||||
|
function getPropertyNamesFromExpression(expr, commandHeader) {
|
||||||
|
if (commandHeader == null) {
|
||||||
|
commandHeader = '';
|
||||||
|
}
|
||||||
|
|
||||||
|
let obj = {};
|
||||||
|
if (!isUnsafeExpression(expr)) {
|
||||||
|
try {
|
||||||
|
obj = eval(commandHeader + expr);
|
||||||
|
} catch (e) {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
|
||||||
|
let propsUnique = {};
|
||||||
|
if (typeof obj === 'object'){
|
||||||
|
let allProps = getAllProps(obj);
|
||||||
|
// Get only things we are allowed to complete following a '.'
|
||||||
|
allProps = allProps.filter( isValidPropertyName );
|
||||||
|
|
||||||
|
// Make sure propsUnique contains one key for every
|
||||||
|
// property so we end up with a unique list of properties
|
||||||
|
allProps.map(function(p){ propsUnique[p] = null; });
|
||||||
|
}
|
||||||
|
return Object.keys(propsUnique).sort();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Given a list of words, returns the longest prefix they all have in common
|
||||||
|
function getCommonPrefix(words) {
|
||||||
|
let word = words[0];
|
||||||
|
for (let i = 0; i < word.length; i++) {
|
||||||
|
for (let w = 1; w < words.length; w++) {
|
||||||
|
if (words[w].charAt(i) != word.charAt(i))
|
||||||
|
return word.slice(0, i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return word;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Returns true if there is reason to think that eval(str)
|
||||||
|
// will modify the global scope
|
||||||
|
function isUnsafeExpression(str) {
|
||||||
|
// Remove any blocks that are quoted or are in a regex
|
||||||
|
function removeLiterals(str) {
|
||||||
|
if (str.length == 0) {
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
|
||||||
|
let currChar = str.charAt(str.length - 1);
|
||||||
|
if (currChar == '"' || currChar == '\'') {
|
||||||
|
return removeLiterals(str.slice(0, findMatchingQuote(str, str.length - 1)));
|
||||||
|
} else if (currChar == '/') {
|
||||||
|
return removeLiterals(str.slice(0, findMatchingSlash(str, str.length - 1)));
|
||||||
|
}
|
||||||
|
|
||||||
|
return removeLiterals(str.slice(0, str.length - 1)) + currChar;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check for any sort of assignment
|
||||||
|
// The strategy used is dumb: remove any quotes
|
||||||
|
// or regexs and comparison operators and see if there is an '=' character.
|
||||||
|
// If there is, it might be an unsafe assignment.
|
||||||
|
|
||||||
|
let prunedStr = removeLiterals(str);
|
||||||
|
prunedStr = prunedStr.replace(/[=!]==/g, ''); //replace === and !== with nothing
|
||||||
|
prunedStr = prunedStr.replace(/[=<>!]=/g, ''); //replace ==, <=, >=, != with nothing
|
||||||
|
|
||||||
|
if (prunedStr.match(/=/)) {
|
||||||
|
return true;
|
||||||
|
} else if (prunedStr.match(/;/)) {
|
||||||
|
// If we contain a semicolon not inside of a quote/regex, assume we're unsafe as well
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Returns a list of global keywords derived from str
|
||||||
|
function getDeclaredConstants(str) {
|
||||||
|
let ret = [];
|
||||||
|
str.split(';').forEach(function(s) {
|
||||||
|
let base, keyword;
|
||||||
|
let match = s.match(/const\s+(\w+)\s*=/);
|
||||||
|
if (match) {
|
||||||
|
[base, keyword] = match;
|
||||||
|
ret.push(keyword);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
@ -1,6 +1,6 @@
|
|||||||
// -*- mode: js2; indent-tabs-mode: nil; js2-basic-offset: 4 -*-
|
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
|
||||||
|
|
||||||
const DBus = imports.dbus;
|
const Gio = imports.gi.Gio;
|
||||||
const Lang = imports.lang;
|
const Lang = imports.lang;
|
||||||
const Shell = imports.gi.Shell;
|
const Shell = imports.gi.Shell;
|
||||||
const Signals = imports.signals;
|
const Signals = imports.signals;
|
||||||
@ -8,33 +8,43 @@ const Signals = imports.signals;
|
|||||||
// The following are not the complete interfaces, just the methods we need
|
// The following are not the complete interfaces, just the methods we need
|
||||||
// (or may need in the future)
|
// (or may need in the future)
|
||||||
|
|
||||||
const ModemGsmNetworkInterface = {
|
const ModemGsmNetworkInterface = <interface name="org.freedesktop.ModemManager.Modem.Gsm.Network">
|
||||||
name: 'org.freedesktop.ModemManager.Modem.Gsm.Network',
|
<method name="GetRegistrationInfo">
|
||||||
methods: [
|
<arg type="u" direction="out" />
|
||||||
{ name: 'GetRegistrationInfo', inSignature: '', outSignature: 'uss' },
|
<arg type="s" direction="out" />
|
||||||
{ name: 'GetSignalQuality', inSignature: '', outSignature: 'u' }
|
<arg type="s" direction="out" />
|
||||||
],
|
</method>
|
||||||
properties: [
|
<method name="GetSignalQuality">
|
||||||
{ name: 'AccessTechnology', signature: 'u', access: 'read' }
|
<arg type="u" direction="out" />
|
||||||
],
|
</method>
|
||||||
signals: [
|
<property name="AccessTechnology" type="u" access="read" />
|
||||||
{ name: 'SignalQuality', inSignature: 'u' },
|
<signal name="SignalQuality">
|
||||||
{ name: 'RegistrationInfo', inSignature: 'uss' }
|
<arg type="u" direction="out" />
|
||||||
]
|
</signal>
|
||||||
};
|
<signal name="RegistrationInfo">
|
||||||
const ModemGsmNetworkProxy = DBus.makeProxyClass(ModemGsmNetworkInterface);
|
<arg type="u" direction="out" />
|
||||||
|
<arg type="s" direction="out" />
|
||||||
|
<arg type="s" direction="out" />
|
||||||
|
</signal>
|
||||||
|
</interface>;
|
||||||
|
|
||||||
const ModemCdmaInterface = {
|
const ModemGsmNetworkProxy = Gio.DBusProxy.makeProxyWrapper(ModemGsmNetworkInterface);
|
||||||
name: 'org.freedesktop.ModemManager.Modem.Cdma',
|
|
||||||
methods: [
|
const ModemCdmaInterface = <interface name="org.freedesktop.ModemManager.Modem.Cdma">
|
||||||
{ name: 'GetSignalQuality', inSignature: '', outSignature: 'u' },
|
<method name="GetSignalQuality">
|
||||||
{ name: 'GetServingSystem', inSignature: '', outSignature: 'usu' }
|
<arg type="u" direction="out" />
|
||||||
],
|
</method>
|
||||||
signals: [
|
<method name="GetServingSystem">
|
||||||
{ name: 'SignalQuality', inSignature: 'u' }
|
<arg type="u" direction="out" />
|
||||||
]
|
<arg type="s" direction="out" />
|
||||||
};
|
<arg type="u" direction="out" />
|
||||||
const ModemCdmaProxy = DBus.makeProxyClass(ModemCdmaInterface);
|
</method>
|
||||||
|
<signal name="SignalQuality">
|
||||||
|
<arg type="u" direction="out" />
|
||||||
|
</signal>
|
||||||
|
</interface>;
|
||||||
|
|
||||||
|
const ModemCdmaProxy = Gio.DBusProxy.makeProxyWrapper(ModemCdmaInterface);
|
||||||
|
|
||||||
let _providersTable;
|
let _providersTable;
|
||||||
function _getProvidersTable() {
|
function _getProvidersTable() {
|
||||||
@ -50,17 +60,17 @@ function ModemGsm() {
|
|||||||
|
|
||||||
ModemGsm.prototype = {
|
ModemGsm.prototype = {
|
||||||
_init: function(path) {
|
_init: function(path) {
|
||||||
this._proxy = new ModemGsmNetworkProxy(DBus.system, 'org.freedesktop.ModemManager', path);
|
this._proxy = new ModemGsmNetworkProxy(Gio.DBus.system, 'org.freedesktop.ModemManager', path);
|
||||||
|
|
||||||
this.signal_quality = 0;
|
this.signal_quality = 0;
|
||||||
this.operator_name = null;
|
this.operator_name = null;
|
||||||
|
|
||||||
// Code is duplicated because the function have different signatures
|
// Code is duplicated because the function have different signatures
|
||||||
this._proxy.connect('SignalQuality', Lang.bind(this, function(proxy, quality) {
|
this._proxy.connectSignal('SignalQuality', Lang.bind(this, function(proxy, sender, [quality]) {
|
||||||
this.signal_quality = quality;
|
this.signal_quality = quality;
|
||||||
this.emit('notify::signal-quality');
|
this.emit('notify::signal-quality');
|
||||||
}));
|
}));
|
||||||
this._proxy.connect('RegistrationInfo', Lang.bind(this, function(proxy, status, code, name) {
|
this._proxy.connectSignal('RegistrationInfo', Lang.bind(this, function(proxy, sender, [status, code, name]) {
|
||||||
this.operator_name = this._findOperatorName(name, code);
|
this.operator_name = this._findOperatorName(name, code);
|
||||||
this.emit('notify::operator-name');
|
this.emit('notify::operator-name');
|
||||||
}));
|
}));
|
||||||
@ -155,12 +165,12 @@ function ModemCdma() {
|
|||||||
|
|
||||||
ModemCdma.prototype = {
|
ModemCdma.prototype = {
|
||||||
_init: function(path) {
|
_init: function(path) {
|
||||||
this._proxy = new ModemCdmaProxy(DBus.system, 'org.freedesktop.ModemManager', path);
|
this._proxy = new ModemCdmaProxy(Gio.DBus.system, 'org.freedesktop.ModemManager', path);
|
||||||
|
|
||||||
this.signal_quality = 0;
|
this.signal_quality = 0;
|
||||||
this.operator_name = null;
|
this.operator_name = null;
|
||||||
this._proxy.connect('SignalQuality', Lang.bind(this, function(proxy, quality) {
|
this._proxy.connect('SignalQuality', Lang.bind(this, function(proxy, sender, params) {
|
||||||
this.signal_quality = quality;
|
this.signal_quality = params[0];
|
||||||
this.emit('notify::signal-quality');
|
this.emit('notify::signal-quality');
|
||||||
|
|
||||||
// receiving this signal means the device got activated
|
// receiving this signal means the device got activated
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
/* -*- mode: js2; js2-basic-offset: 4; indent-tabs-mode: nil -*- */
|
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
|
||||||
|
|
||||||
// parse:
|
// parse:
|
||||||
// @params: caller-provided parameter object, or %null
|
// @params: caller-provided parameter object, or %null
|
||||||
|
@ -1,53 +1,48 @@
|
|||||||
/* -*- mode: js2; js2-basic-offset: 4; indent-tabs-mode: nil -*- */
|
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
|
||||||
|
|
||||||
const DBus = imports.dbus;
|
const Gio = imports.gi.Gio;
|
||||||
const Lang = imports.lang;
|
const Lang = imports.lang;
|
||||||
|
|
||||||
const ScreenSaverIface = {
|
const ScreenSaverIface = <interface name="org.gnome.ScreenSaver">
|
||||||
name: 'org.gnome.ScreenSaver',
|
<method name="GetActive">
|
||||||
methods: [{ name: 'GetActive',
|
<arg type="b" direction="out" />
|
||||||
inSignature: '',
|
</method>
|
||||||
outSignature: 'b' },
|
<method name="Lock" />
|
||||||
{ name: 'Lock',
|
<method name="SetActive">
|
||||||
inSignature: '' },
|
<arg type="b" direction="in" />
|
||||||
{ name: 'SetActive',
|
</method>
|
||||||
inSignature: 'b' }],
|
<signal name="ActiveChanged">
|
||||||
signals: [{ name: 'ActiveChanged',
|
<arg type="b" direction="out" />
|
||||||
inSignature: 'b' }]
|
</signal>
|
||||||
};
|
</interface>;
|
||||||
|
|
||||||
|
const ScreenSaverInfo = Gio.DBusInterfaceInfo.new_for_xml(ScreenSaverIface);
|
||||||
|
|
||||||
function ScreenSaverProxy() {
|
function ScreenSaverProxy() {
|
||||||
this._init();
|
var self = new Gio.DBusProxy({ g_connection: Gio.DBus.session,
|
||||||
|
g_interface_name: ScreenSaverInfo.name,
|
||||||
|
g_interface_info: ScreenSaverInfo,
|
||||||
|
g_name: 'org.gnome.ScreenSaver',
|
||||||
|
g_object_path: '/org/gnome/ScreenSaver',
|
||||||
|
g_flags: (Gio.DBusProxyFlags.DO_NOT_AUTO_START |
|
||||||
|
Gio.DBusProxyFlags.DO_NOT_LOAD_PROPERTIES) });
|
||||||
|
self.init(null);
|
||||||
|
self.screenSaverActive = false;
|
||||||
|
|
||||||
|
self.connectSignal('ActiveChanged', function(proxy, senderName, [isActive]) {
|
||||||
|
self.screenSaverActive = isActive;
|
||||||
|
});
|
||||||
|
self.connect('notify::g-name-owner', function() {
|
||||||
|
if (self.g_name_owner) {
|
||||||
|
self.GetActiveRemote(function(result, excp) {
|
||||||
|
if (result) {
|
||||||
|
let [isActive] = result;
|
||||||
|
self.screenSaverActive = isActive;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} else
|
||||||
|
self.screenSaverActive = false;
|
||||||
|
});
|
||||||
|
|
||||||
|
return self;
|
||||||
}
|
}
|
||||||
|
|
||||||
ScreenSaverProxy.prototype = {
|
|
||||||
_init: function() {
|
|
||||||
DBus.session.proxifyObject(this,
|
|
||||||
'org.gnome.ScreenSaver',
|
|
||||||
'/org/gnome/ScreenSaver');
|
|
||||||
|
|
||||||
DBus.session.watch_name('org.gnome.ScreenSaver',
|
|
||||||
false, // do not launch a name-owner if none exists
|
|
||||||
Lang.bind(this, this._onSSAppeared),
|
|
||||||
Lang.bind(this, this._onSSVanished));
|
|
||||||
|
|
||||||
this.screenSaverActive = false;
|
|
||||||
this.connect('ActiveChanged',
|
|
||||||
Lang.bind(this, this._onActiveChanged));
|
|
||||||
},
|
|
||||||
|
|
||||||
_onSSAppeared: function(owner) {
|
|
||||||
this.GetActiveRemote(Lang.bind(this, function(isActive) {
|
|
||||||
this.screenSaverActive = isActive;
|
|
||||||
}))
|
|
||||||
},
|
|
||||||
|
|
||||||
_onSSVanished: function(oldOwner) {
|
|
||||||
this.screenSaverActive = false;
|
|
||||||
},
|
|
||||||
|
|
||||||
_onActiveChanged: function(object, isActive) {
|
|
||||||
this.screenSaverActive = isActive;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
DBus.proxifyPrototype(ScreenSaverProxy.prototype, ScreenSaverIface);
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
/* -*- mode: js2; js2-basic-offset: 4; indent-tabs-mode: nil -*- */
|
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
|
||||||
|
|
||||||
const Gdk = imports.gi.Gdk;
|
const Gdk = imports.gi.Gdk;
|
||||||
const Gio = imports.gi.Gio;
|
const Gio = imports.gi.Gio;
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
/* -*- mode: js2; js2-basic-offset: 4; indent-tabs-mode: nil -*- */
|
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
|
||||||
|
|
||||||
const Main = imports.ui.main;
|
const Main = imports.ui.main;
|
||||||
const Scripting = imports.ui.scripting;
|
const Scripting = imports.ui.scripting;
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
/* -*- mode: js2; js2-basic-offset: 4; indent-tabs-mode: nil -*- */
|
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
|
||||||
|
|
||||||
const Clutter = imports.gi.Clutter;
|
const Clutter = imports.gi.Clutter;
|
||||||
const Gdk = imports.gi.Gdk;
|
const Gdk = imports.gi.Gdk;
|
||||||
@ -134,15 +134,48 @@ AltTabPopup.prototype = {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
show : function(backward, binding, mask) {
|
_getAppLists: function() {
|
||||||
|
let tracker = Shell.WindowTracker.get_default();
|
||||||
let appSys = Shell.AppSystem.get_default();
|
let appSys = Shell.AppSystem.get_default();
|
||||||
let apps = appSys.get_running ();
|
let allApps = appSys.get_running ();
|
||||||
|
|
||||||
if (!apps.length)
|
let screen = global.screen;
|
||||||
|
let display = screen.get_display();
|
||||||
|
let windows = display.get_tab_list(Meta.TabList.NORMAL, screen,
|
||||||
|
screen.get_active_workspace());
|
||||||
|
|
||||||
|
// windows is only the windows on the current workspace. For
|
||||||
|
// each one, if it corresponds to an app we know, move that
|
||||||
|
// app from allApps to apps.
|
||||||
|
let apps = [];
|
||||||
|
for (let i = 0; i < windows.length && allApps.length != 0; i++) {
|
||||||
|
let app = tracker.get_window_app(windows[i]);
|
||||||
|
let index = allApps.indexOf(app);
|
||||||
|
if (index != -1) {
|
||||||
|
apps.push(app);
|
||||||
|
allApps.splice(index, 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Now @apps is a list of apps on the current workspace, in
|
||||||
|
// standard Alt+Tab order (MRU except for minimized windows),
|
||||||
|
// and allApps is a list of apps that only appear on other
|
||||||
|
// workspaces, sorted by user_time, which is good enough.
|
||||||
|
return [apps, allApps];
|
||||||
|
},
|
||||||
|
|
||||||
|
show : function(backward, binding, mask) {
|
||||||
|
let [localApps, otherApps] = this._getAppLists();
|
||||||
|
|
||||||
|
if (localApps.length == 0 && otherApps.length == 0)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (!Main.pushModal(this.actor))
|
if (!Main.pushModal(this.actor)) {
|
||||||
return false;
|
// Probably someone else has a pointer grab, try again with keyboard only
|
||||||
|
if (!Main.pushModal(this.actor, global.get_current_time(), Meta.ModalOptions.POINTER_ALREADY_GRABBED)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
this._haveModal = true;
|
this._haveModal = true;
|
||||||
this._modifierMask = primaryModifier(mask);
|
this._modifierMask = primaryModifier(mask);
|
||||||
|
|
||||||
@ -152,7 +185,7 @@ AltTabPopup.prototype = {
|
|||||||
this.actor.connect('button-press-event', Lang.bind(this, this._clickedOutside));
|
this.actor.connect('button-press-event', Lang.bind(this, this._clickedOutside));
|
||||||
this.actor.connect('scroll-event', Lang.bind(this, this._onScroll));
|
this.actor.connect('scroll-event', Lang.bind(this, this._onScroll));
|
||||||
|
|
||||||
this._appSwitcher = new AppSwitcher(apps, this);
|
this._appSwitcher = new AppSwitcher(localApps, otherApps, this);
|
||||||
this.actor.add_actor(this._appSwitcher.actor);
|
this.actor.add_actor(this._appSwitcher.actor);
|
||||||
this._appSwitcher.connect('item-activated', Lang.bind(this, this._appActivated));
|
this._appSwitcher.connect('item-activated', Lang.bind(this, this._appActivated));
|
||||||
this._appSwitcher.connect('item-entered', Lang.bind(this, this._appEntered));
|
this._appSwitcher.connect('item-entered', Lang.bind(this, this._appEntered));
|
||||||
@ -166,7 +199,7 @@ AltTabPopup.prototype = {
|
|||||||
this.actor.get_allocation_box();
|
this.actor.get_allocation_box();
|
||||||
|
|
||||||
// Make the initial selection
|
// Make the initial selection
|
||||||
if (binding == 'switch_group') {
|
if (binding == 'switch-group') {
|
||||||
if (backward) {
|
if (backward) {
|
||||||
this._select(0, this._appIcons[0].cachedWindows.length - 1);
|
this._select(0, this._appIcons[0].cachedWindows.length - 1);
|
||||||
} else {
|
} else {
|
||||||
@ -175,9 +208,9 @@ AltTabPopup.prototype = {
|
|||||||
else
|
else
|
||||||
this._select(0, 0);
|
this._select(0, 0);
|
||||||
}
|
}
|
||||||
} else if (binding == 'switch_group_backward') {
|
} else if (binding == 'switch-group-backward') {
|
||||||
this._select(0, this._appIcons[0].cachedWindows.length - 1);
|
this._select(0, this._appIcons[0].cachedWindows.length - 1);
|
||||||
} else if (binding == 'switch_windows_backward') {
|
} else if (binding == 'switch-windows-backward') {
|
||||||
this._select(this._appIcons.length - 1);
|
this._select(this._appIcons.length - 1);
|
||||||
} else if (this._appIcons.length == 1) {
|
} else if (this._appIcons.length == 1) {
|
||||||
this._select(0);
|
this._select(0);
|
||||||
@ -846,33 +879,32 @@ AppIcon.prototype = {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
function AppSwitcher(apps, altTabPopup) {
|
function AppSwitcher() {
|
||||||
this._init(apps, altTabPopup);
|
this._init.apply(this, arguments);
|
||||||
}
|
}
|
||||||
|
|
||||||
AppSwitcher.prototype = {
|
AppSwitcher.prototype = {
|
||||||
__proto__ : SwitcherList.prototype,
|
__proto__ : SwitcherList.prototype,
|
||||||
|
|
||||||
_init : function(apps, altTabPopup) {
|
_init : function(localApps, otherApps, altTabPopup) {
|
||||||
SwitcherList.prototype._init.call(this, true);
|
SwitcherList.prototype._init.call(this, true);
|
||||||
|
|
||||||
// Construct the AppIcons, sort by time, add to the popup
|
// Construct the AppIcons, add to the popup
|
||||||
let activeWorkspace = global.screen.get_active_workspace();
|
let activeWorkspace = global.screen.get_active_workspace();
|
||||||
let workspaceIcons = [];
|
let workspaceIcons = [];
|
||||||
let otherIcons = [];
|
let otherIcons = [];
|
||||||
for (let i = 0; i < apps.length; i++) {
|
for (let i = 0; i < localApps.length; i++) {
|
||||||
let appIcon = new AppIcon(apps[i]);
|
let appIcon = new AppIcon(localApps[i]);
|
||||||
// Cache the window list now; we don't handle dynamic changes here,
|
// Cache the window list now; we don't handle dynamic changes here,
|
||||||
// and we don't want to be continually retrieving it
|
// and we don't want to be continually retrieving it
|
||||||
appIcon.cachedWindows = appIcon.app.get_windows();
|
appIcon.cachedWindows = appIcon.app.get_windows();
|
||||||
if (this._hasWindowsOnWorkspace(appIcon, activeWorkspace))
|
workspaceIcons.push(appIcon);
|
||||||
workspaceIcons.push(appIcon);
|
}
|
||||||
else
|
for (let i = 0; i < otherApps.length; i++) {
|
||||||
otherIcons.push(appIcon);
|
let appIcon = new AppIcon(otherApps[i]);
|
||||||
|
appIcon.cachedWindows = appIcon.app.get_windows();
|
||||||
|
otherIcons.push(appIcon);
|
||||||
}
|
}
|
||||||
|
|
||||||
workspaceIcons.sort(Lang.bind(this, this._sortAppIcon));
|
|
||||||
otherIcons.sort(Lang.bind(this, this._sortAppIcon));
|
|
||||||
|
|
||||||
this.icons = [];
|
this.icons = [];
|
||||||
this._arrows = [];
|
this._arrows = [];
|
||||||
@ -1012,19 +1044,6 @@ AppSwitcher.prototype = {
|
|||||||
|
|
||||||
if (appIcon.cachedWindows.length == 1)
|
if (appIcon.cachedWindows.length == 1)
|
||||||
arrow.hide();
|
arrow.hide();
|
||||||
},
|
|
||||||
|
|
||||||
_hasWindowsOnWorkspace: function(appIcon, workspace) {
|
|
||||||
let windows = appIcon.cachedWindows;
|
|
||||||
for (let i = 0; i < windows.length; i++) {
|
|
||||||
if (windows[i].get_workspace() == workspace)
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
},
|
|
||||||
|
|
||||||
_sortAppIcon : function(appIcon1, appIcon2) {
|
|
||||||
return appIcon1.app.compare(appIcon2.app);
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
/* -*- mode: js2; js2-basic-offset: 4; indent-tabs-mode: nil -*- */
|
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
|
||||||
|
|
||||||
const Clutter = imports.gi.Clutter;
|
const Clutter = imports.gi.Clutter;
|
||||||
const GLib = imports.gi.GLib;
|
const GLib = imports.gi.GLib;
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
/* -*- mode: js2; js2-basic-offset: 4; indent-tabs-mode: nil -*- */
|
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
|
||||||
|
|
||||||
const Shell = imports.gi.Shell;
|
const Shell = imports.gi.Shell;
|
||||||
const Lang = imports.lang;
|
const Lang = imports.lang;
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
/* -*- mode: js2; js2-basic-offset: 4; indent-tabs-mode: nil -*- */
|
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
|
||||||
|
|
||||||
const Lang = imports.lang;
|
const Lang = imports.lang;
|
||||||
const DBus = imports.dbus;
|
|
||||||
const Mainloop = imports.mainloop;
|
const Mainloop = imports.mainloop;
|
||||||
const Gio = imports.gi.Gio;
|
const Gio = imports.gi.Gio;
|
||||||
const Params = imports.misc.params;
|
const Params = imports.misc.params;
|
||||||
@ -16,63 +15,54 @@ const SETTING_ENABLE_AUTOMOUNT = 'automount';
|
|||||||
|
|
||||||
const AUTORUN_EXPIRE_TIMEOUT_SECS = 10;
|
const AUTORUN_EXPIRE_TIMEOUT_SECS = 10;
|
||||||
|
|
||||||
const ConsoleKitSessionIface = {
|
const ConsoleKitSessionIface = <interface name="org.freedesktop.ConsoleKit.Session">
|
||||||
name: 'org.freedesktop.ConsoleKit.Session',
|
<method name="IsActive">
|
||||||
methods: [{ name: 'IsActive',
|
<arg type="b" direction="out" />
|
||||||
inSignature: '',
|
</method>
|
||||||
outSignature: 'b' }],
|
<signal name="ActiveChanged">
|
||||||
signals: [{ name: 'ActiveChanged',
|
<arg type="b" direction="out" />
|
||||||
inSignature: 'b' }]
|
</signal>
|
||||||
};
|
</interface>;
|
||||||
|
|
||||||
const ConsoleKitSessionProxy = DBus.makeProxyClass(ConsoleKitSessionIface);
|
const ConsoleKitSessionProxy = Gio.DBusProxy.makeProxyWrapper(ConsoleKitSessionIface);
|
||||||
|
|
||||||
const ConsoleKitManagerIface = {
|
const ConsoleKitManagerIface = <interface name="org.freedesktop.ConsoleKit.Manager">
|
||||||
name: 'org.freedesktop.ConsoleKit.Manager',
|
<method name="GetCurrentSession">
|
||||||
methods: [{ name: 'GetCurrentSession',
|
<arg type="o" direction="out" />
|
||||||
inSignature: '',
|
</method>
|
||||||
outSignature: 'o' }]
|
</interface>;
|
||||||
};
|
|
||||||
|
const ConsoleKitManagerInfo = Gio.DBusInterfaceInfo.new_for_xml(ConsoleKitManagerIface);
|
||||||
|
|
||||||
function ConsoleKitManager() {
|
function ConsoleKitManager() {
|
||||||
this._init();
|
var self = new Gio.DBusProxy({ g_connection: Gio.DBus.system,
|
||||||
};
|
g_interface_name: ConsoleKitManagerInfo.name,
|
||||||
|
g_interface_info: ConsoleKitManagerInfo,
|
||||||
|
g_name: 'org.freedesktop.ConsoleKit',
|
||||||
|
g_object_path: '/org/freedesktop/ConsoleKit/Manager',
|
||||||
|
g_flags: (Gio.DBusProxyFlags.DO_NOT_AUTO_START |
|
||||||
|
Gio.DBusProxyFlags.DO_NOT_LOAD_PROPERTIES) });
|
||||||
|
|
||||||
ConsoleKitManager.prototype = {
|
self.connect('notify::g-name-owner', function() {
|
||||||
_init: function() {
|
if (self.g_name_owner) {
|
||||||
this.sessionActive = true;
|
self.GetCurrentSessionRemote(function([session]) {
|
||||||
|
self._ckSession = new ConsoleKitSessionProxy(Gio.DBus.system, 'org.freedesktop.ConsoleKit', session);
|
||||||
|
|
||||||
DBus.system.proxifyObject(this,
|
self._ckSession.connectSignal('ActiveChanged', function(object, senderName, [isActive]) {
|
||||||
'org.freedesktop.ConsoleKit',
|
self.sessionActive = isActive;
|
||||||
'/org/freedesktop/ConsoleKit/Manager');
|
});
|
||||||
|
self._ckSession.IsActiveRemote(function([isActive]) {
|
||||||
|
self.sessionActive = isActive;
|
||||||
|
});
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
self.sessionActive = true;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
DBus.system.watch_name('org.freedesktop.ConsoleKit',
|
self.init(null);
|
||||||
false, // do not launch a name-owner if none exists
|
return self;
|
||||||
Lang.bind(this, this._onManagerAppeared),
|
}
|
||||||
Lang.bind(this, this._onManagerVanished));
|
|
||||||
},
|
|
||||||
|
|
||||||
_onManagerAppeared: function(owner) {
|
|
||||||
this.GetCurrentSessionRemote(Lang.bind(this, this._onCurrentSession));
|
|
||||||
},
|
|
||||||
|
|
||||||
_onManagerVanished: function(oldOwner) {
|
|
||||||
this.sessionActive = true;
|
|
||||||
},
|
|
||||||
|
|
||||||
_onCurrentSession: function(session) {
|
|
||||||
this._ckSession = new ConsoleKitSessionProxy(DBus.system, 'org.freedesktop.ConsoleKit', session);
|
|
||||||
|
|
||||||
this._ckSession.connect
|
|
||||||
('ActiveChanged', Lang.bind(this, function(object, isActive) {
|
|
||||||
this.sessionActive = isActive;
|
|
||||||
}));
|
|
||||||
this._ckSession.IsActiveRemote(Lang.bind(this, function(isActive) {
|
|
||||||
this.sessionActive = isActive;
|
|
||||||
}));
|
|
||||||
}
|
|
||||||
};
|
|
||||||
DBus.proxifyPrototype(ConsoleKitManager.prototype, ConsoleKitManagerIface);
|
|
||||||
|
|
||||||
function AutomountManager() {
|
function AutomountManager() {
|
||||||
this._init();
|
this._init();
|
||||||
@ -86,9 +76,8 @@ AutomountManager.prototype = {
|
|||||||
this.ckListener = new ConsoleKitManager();
|
this.ckListener = new ConsoleKitManager();
|
||||||
|
|
||||||
this._ssProxy = new ScreenSaver.ScreenSaverProxy();
|
this._ssProxy = new ScreenSaver.ScreenSaverProxy();
|
||||||
this._ssProxy.connect('ActiveChanged',
|
this._ssProxy.connectSignal('ActiveChanged',
|
||||||
Lang.bind(this,
|
Lang.bind(this, this._screenSaverActiveChanged));
|
||||||
this._screenSaverActiveChanged));
|
|
||||||
|
|
||||||
this._volumeMonitor = Gio.VolumeMonitor.get();
|
this._volumeMonitor = Gio.VolumeMonitor.get();
|
||||||
|
|
||||||
@ -111,7 +100,7 @@ AutomountManager.prototype = {
|
|||||||
Mainloop.idle_add(Lang.bind(this, this._startupMountAll));
|
Mainloop.idle_add(Lang.bind(this, this._startupMountAll));
|
||||||
},
|
},
|
||||||
|
|
||||||
_screenSaverActiveChanged: function(object, 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) {
|
||||||
this._checkAndMountVolume(volume);
|
this._checkAndMountVolume(volume);
|
||||||
@ -209,10 +198,14 @@ AutomountManager.prototype = {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Volume is already mounted, don't bother.
|
||||||
|
if (volume.get_mount())
|
||||||
|
return;
|
||||||
|
|
||||||
if (!this._settings.get_boolean(SETTING_ENABLE_AUTOMOUNT) ||
|
if (!this._settings.get_boolean(SETTING_ENABLE_AUTOMOUNT) ||
|
||||||
!volume.should_automount() ||
|
!volume.should_automount() ||
|
||||||
!volume.can_mount()) {
|
!volume.can_mount()) {
|
||||||
// allow the autorun to run anyway; this can happen if the
|
// allow the autorun to run anyway; this can happen if the
|
||||||
// mount gets added programmatically later, even if
|
// mount gets added programmatically later, even if
|
||||||
// should_automount() or can_mount() are false, like for
|
// should_automount() or can_mount() are false, like for
|
||||||
// blank optical media.
|
// blank optical media.
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
/* -*- mode: js2; js2-basic-offset: 4; indent-tabs-mode: nil -*- */
|
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
|
||||||
|
|
||||||
const Lang = imports.lang;
|
const Lang = imports.lang;
|
||||||
const DBus = imports.dbus;
|
|
||||||
const Gio = imports.gi.Gio;
|
const Gio = imports.gi.Gio;
|
||||||
const St = imports.gi.St;
|
const St = imports.gi.St;
|
||||||
|
|
||||||
@ -62,25 +61,19 @@ function startAppForMount(app, mount) {
|
|||||||
|
|
||||||
/******************************************/
|
/******************************************/
|
||||||
|
|
||||||
const HotplugSnifferIface = {
|
const HotplugSnifferIface = <interface name="org.gnome.Shell.HotplugSniffer">
|
||||||
name: 'org.gnome.Shell.HotplugSniffer',
|
<method name="SniffURI">
|
||||||
methods: [{ name: 'SniffURI',
|
<arg type="s" direction="in" />
|
||||||
inSignature: 's',
|
<arg type="as" direction="out" />
|
||||||
outSignature: 'as' }]
|
</method>
|
||||||
};
|
</interface>;
|
||||||
|
|
||||||
const HotplugSniffer = function() {
|
const HotplugSnifferProxy = Gio.DBusProxy.makeProxyWrapper(HotplugSnifferIface);
|
||||||
this._init();
|
function HotplugSniffer() {
|
||||||
};
|
return new HotplugSnifferProxy(Gio.DBus.session,
|
||||||
|
|
||||||
HotplugSniffer.prototype = {
|
|
||||||
_init: function() {
|
|
||||||
DBus.session.proxifyObject(this,
|
|
||||||
'org.gnome.Shell.HotplugSniffer',
|
'org.gnome.Shell.HotplugSniffer',
|
||||||
'/org/gnome/Shell/HotplugSniffer');
|
'/org/gnome/Shell/HotplugSniffer');
|
||||||
},
|
}
|
||||||
};
|
|
||||||
DBus.proxifyPrototype(HotplugSniffer.prototype, HotplugSnifferIface);
|
|
||||||
|
|
||||||
function ContentTypeDiscoverer(callback) {
|
function ContentTypeDiscoverer(callback) {
|
||||||
this._init(callback);
|
this._init(callback);
|
||||||
@ -114,9 +107,8 @@ ContentTypeDiscoverer.prototype = {
|
|||||||
let root = mount.get_root();
|
let root = mount.get_root();
|
||||||
|
|
||||||
let hotplugSniffer = new HotplugSniffer();
|
let hotplugSniffer = new HotplugSniffer();
|
||||||
hotplugSniffer.SniffURIRemote
|
hotplugSniffer.SniffURIRemote(root.get_uri(),
|
||||||
(root.get_uri(), DBus.CALL_FLAG_START,
|
Lang.bind(this, function([contentTypes]) {
|
||||||
Lang.bind(this, function(contentTypes) {
|
|
||||||
this._emitCallback(mount, contentTypes);
|
this._emitCallback(mount, contentTypes);
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
@ -277,7 +269,7 @@ AutorunResidentSource.prototype = {
|
|||||||
__proto__: MessageTray.Source.prototype,
|
__proto__: MessageTray.Source.prototype,
|
||||||
|
|
||||||
_init: function() {
|
_init: function() {
|
||||||
MessageTray.Source.prototype._init.call(this, _('Removable Devices'));
|
MessageTray.Source.prototype._init.call(this, _("Removable Devices"));
|
||||||
|
|
||||||
this._mounts = [];
|
this._mounts = [];
|
||||||
|
|
||||||
@ -491,7 +483,7 @@ AutorunTransientDispatcher.prototype = {
|
|||||||
let app = null;
|
let app = null;
|
||||||
|
|
||||||
if (setting == AutorunSetting.RUN) {
|
if (setting == AutorunSetting.RUN) {
|
||||||
app = Gio.app_info_get_default_for_type(type, false);
|
app = Gio.app_info_get_default_for_type(contentTypes[0], false);
|
||||||
} else if (setting == AutorunSetting.FILES) {
|
} else if (setting == AutorunSetting.FILES) {
|
||||||
app = Gio.app_info_get_default_for_type('inode/directory', false);
|
app = Gio.app_info_get_default_for_type('inode/directory', false);
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
/* -*- mode: js2; js2-basic-offset: 4; indent-tabs-mode: nil -*- */
|
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
|
||||||
|
|
||||||
const Clutter = imports.gi.Clutter;
|
const Clutter = imports.gi.Clutter;
|
||||||
const Lang = imports.lang;
|
const Lang = imports.lang;
|
||||||
@ -46,6 +46,7 @@ BoxPointer.prototype = {
|
|||||||
this._yOffset = 0;
|
this._yOffset = 0;
|
||||||
this._xPosition = 0;
|
this._xPosition = 0;
|
||||||
this._yPosition = 0;
|
this._yPosition = 0;
|
||||||
|
this._sourceAlignment = 0.5;
|
||||||
},
|
},
|
||||||
|
|
||||||
show: function(animate, onComplete) {
|
show: function(animate, onComplete) {
|
||||||
@ -75,7 +76,7 @@ BoxPointer.prototype = {
|
|||||||
Tweener.addTween(this, { opacity: 255,
|
Tweener.addTween(this, { opacity: 255,
|
||||||
xOffset: 0,
|
xOffset: 0,
|
||||||
yOffset: 0,
|
yOffset: 0,
|
||||||
transition: "linear",
|
transition: 'linear',
|
||||||
onComplete: onComplete,
|
onComplete: onComplete,
|
||||||
time: POPUP_ANIMATION_TIME });
|
time: POPUP_ANIMATION_TIME });
|
||||||
},
|
},
|
||||||
@ -106,7 +107,7 @@ BoxPointer.prototype = {
|
|||||||
Tweener.addTween(this, { opacity: 0,
|
Tweener.addTween(this, { opacity: 0,
|
||||||
xOffset: xOffset,
|
xOffset: xOffset,
|
||||||
yOffset: yOffset,
|
yOffset: yOffset,
|
||||||
transition: "linear",
|
transition: 'linear',
|
||||||
time: POPUP_ANIMATION_TIME,
|
time: POPUP_ANIMATION_TIME,
|
||||||
onComplete: Lang.bind(this, function () {
|
onComplete: Lang.bind(this, function () {
|
||||||
this.actor.hide();
|
this.actor.hide();
|
||||||
@ -180,7 +181,7 @@ BoxPointer.prototype = {
|
|||||||
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._alignment);
|
this._reposition(this._sourceActor, this._arrowAlignment);
|
||||||
},
|
},
|
||||||
|
|
||||||
_drawBorder: function(area) {
|
_drawBorder: function(area) {
|
||||||
@ -312,24 +313,37 @@ BoxPointer.prototype = {
|
|||||||
this.actor.show();
|
this.actor.show();
|
||||||
|
|
||||||
this._sourceActor = sourceActor;
|
this._sourceActor = sourceActor;
|
||||||
this._alignment = alignment;
|
this._arrowAlignment = alignment;
|
||||||
|
|
||||||
this._reposition(sourceActor, alignment);
|
this._reposition(sourceActor, alignment);
|
||||||
},
|
},
|
||||||
|
|
||||||
|
setSourceAlignment: function(alignment) {
|
||||||
|
this._sourceAlignment = alignment;
|
||||||
|
|
||||||
|
if (!this._sourceActor)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// We need to show it now to force an allocation,
|
||||||
|
// 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) {
|
||||||
// Position correctly relative to the sourceActor
|
// Position correctly relative to the sourceActor
|
||||||
let sourceNode = sourceActor.get_theme_node();
|
let sourceNode = sourceActor.get_theme_node();
|
||||||
let sourceContentBox = sourceNode.get_content_box(sourceActor.get_allocation_box());
|
let sourceContentBox = sourceNode.get_content_box(sourceActor.get_allocation_box());
|
||||||
let sourceAllocation = Shell.util_get_transformed_allocation(sourceActor);
|
let sourceAllocation = Shell.util_get_transformed_allocation(sourceActor);
|
||||||
let sourceCenterX = sourceAllocation.x1 + sourceContentBox.x1 + (sourceContentBox.x2 - sourceContentBox.x1) / 2;
|
let sourceCenterX = sourceAllocation.x1 + sourceContentBox.x1 + (sourceContentBox.x2 - sourceContentBox.x1) * this._sourceAlignment;
|
||||||
let sourceCenterY = sourceAllocation.y1 + sourceContentBox.y1 + (sourceContentBox.y2 - sourceContentBox.y1) / 2;
|
let sourceCenterY = sourceAllocation.y1 + sourceContentBox.y1 + (sourceContentBox.y2 - sourceContentBox.y1) * this._sourceAlignment;
|
||||||
let [minWidth, minHeight, natWidth, natHeight] = this.actor.get_preferred_size();
|
let [minWidth, minHeight, natWidth, natHeight] = this.actor.get_preferred_size();
|
||||||
|
|
||||||
// We also want to keep it onscreen, and separated from the
|
// We also want to keep it onscreen, and separated from the
|
||||||
// edge by the same distance as the main part of the box is
|
// edge by the same distance as the main part of the box is
|
||||||
// separated from its sourceActor
|
// separated from its sourceActor
|
||||||
let primary = Main.layoutManager.primaryMonitor;
|
let monitor = Main.layoutManager.findMonitorForActor(sourceActor);
|
||||||
let themeNode = this.actor.get_theme_node();
|
let themeNode = this.actor.get_theme_node();
|
||||||
let borderWidth = themeNode.get_length('-arrow-border-width');
|
let borderWidth = themeNode.get_length('-arrow-border-width');
|
||||||
let arrowBase = themeNode.get_length('-arrow-base');
|
let arrowBase = themeNode.get_length('-arrow-base');
|
||||||
@ -364,8 +378,8 @@ BoxPointer.prototype = {
|
|||||||
case St.Side.BOTTOM:
|
case St.Side.BOTTOM:
|
||||||
resX = sourceCenterX - (halfMargin + (natWidth - margin) * alignment);
|
resX = sourceCenterX - (halfMargin + (natWidth - margin) * alignment);
|
||||||
|
|
||||||
resX = Math.max(resX, primary.x + 10);
|
resX = Math.max(resX, monitor.x + 10);
|
||||||
resX = Math.min(resX, primary.x + primary.width - (10 + natWidth));
|
resX = Math.min(resX, monitor.x + monitor.width - (10 + natWidth));
|
||||||
this.setArrowOrigin(sourceCenterX - resX);
|
this.setArrowOrigin(sourceCenterX - resX);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -373,8 +387,8 @@ BoxPointer.prototype = {
|
|||||||
case St.Side.RIGHT:
|
case St.Side.RIGHT:
|
||||||
resY = sourceCenterY - (halfMargin + (natHeight - margin) * alignment);
|
resY = sourceCenterY - (halfMargin + (natHeight - margin) * alignment);
|
||||||
|
|
||||||
resY = Math.max(resY, primary.y + 10);
|
resY = Math.max(resY, monitor.y + 10);
|
||||||
resY = Math.min(resY, primary.y + primary.height - (10 + natHeight));
|
resY = Math.min(resY, monitor.y + monitor.height - (10 + natHeight));
|
||||||
|
|
||||||
this.setArrowOrigin(sourceCenterY - resY);
|
this.setArrowOrigin(sourceCenterY - resY);
|
||||||
break;
|
break;
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
/* -*- mode: js2; js2-basic-offset: 4; indent-tabs-mode: nil -*- */
|
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
|
||||||
|
|
||||||
const DBus = imports.dbus;
|
|
||||||
const Clutter = imports.gi.Clutter;
|
const Clutter = imports.gi.Clutter;
|
||||||
const Gio = imports.gi.Gio;
|
const Gio = imports.gi.Gio;
|
||||||
const Lang = imports.lang;
|
const Lang = imports.lang;
|
||||||
@ -195,30 +194,34 @@ EmptyEventSource.prototype = {
|
|||||||
};
|
};
|
||||||
Signals.addSignalMethods(EmptyEventSource.prototype);
|
Signals.addSignalMethods(EmptyEventSource.prototype);
|
||||||
|
|
||||||
const CalendarServerIface = {
|
const CalendarServerIface = <interface name="org.gnome.Shell.CalendarServer">
|
||||||
name: 'org.gnome.Shell.CalendarServer',
|
<method name="GetEvents">
|
||||||
methods: [{ name: 'GetEvents',
|
<arg type="x" direction="in" />
|
||||||
inSignature: 'xxb',
|
<arg type="x" direction="in" />
|
||||||
outSignature: 'a(sssbxxa{sv})' }],
|
<arg type="b" direction="in" />
|
||||||
signals: [{ name: 'Changed',
|
<arg type="a(sssbxxa{sv})" direction="out" />
|
||||||
inSignature: '' }]
|
</method>
|
||||||
};
|
<signal name="Changed" />
|
||||||
|
</interface>;
|
||||||
|
|
||||||
const CalendarServer = function () {
|
const CalendarServerInfo = Gio.DBusInterfaceInfo.new_for_xml(CalendarServerIface);
|
||||||
this._init();
|
|
||||||
};
|
|
||||||
|
|
||||||
CalendarServer.prototype = {
|
function CalendarServer() {
|
||||||
_init: function() {
|
var self = new Gio.DBusProxy({ g_connection: Gio.DBus.session,
|
||||||
DBus.session.proxifyObject(this, 'org.gnome.Shell.CalendarServer', '/org/gnome/Shell/CalendarServer');
|
g_interface_name: CalendarServerInfo.name,
|
||||||
}
|
g_interface_info: CalendarServerInfo,
|
||||||
};
|
g_name: 'org.gnome.Shell.CalendarServer',
|
||||||
|
g_object_path: '/org/gnome/Shell/CalendarServer',
|
||||||
|
g_flags: (Gio.DBusProxyFlags.DO_NOT_AUTO_START |
|
||||||
|
Gio.DBusProxyFlags.DO_NOT_LOAD_PROPERTIES) });
|
||||||
|
|
||||||
DBus.proxifyPrototype(CalendarServer.prototype, CalendarServerIface);
|
self.init(null);
|
||||||
|
return self;
|
||||||
|
}
|
||||||
|
|
||||||
// an implementation that reads data from a session bus service
|
// an implementation that reads data from a session bus service
|
||||||
function DBusEventSource(owner) {
|
function DBusEventSource() {
|
||||||
this._init(owner);
|
this._init();
|
||||||
}
|
}
|
||||||
|
|
||||||
function _datesEqual(a, b) {
|
function _datesEqual(a, b) {
|
||||||
@ -241,16 +244,18 @@ function _dateIntervalsOverlap(a0, a1, b0, b1)
|
|||||||
|
|
||||||
|
|
||||||
DBusEventSource.prototype = {
|
DBusEventSource.prototype = {
|
||||||
_init: function(owner) {
|
_init: function() {
|
||||||
this._resetCache();
|
this._resetCache();
|
||||||
|
|
||||||
this._dbusProxy = new CalendarServer(owner);
|
this._dbusProxy = new CalendarServer();
|
||||||
this._dbusProxy.connect('Changed', Lang.bind(this, this._onChanged));
|
this._dbusProxy.connectSignal('Changed', Lang.bind(this, this._onChanged));
|
||||||
|
|
||||||
DBus.session.watch_name('org.gnome.Shell.CalendarServer',
|
this._dbusProxy.connect('notify::g-name-owner', Lang.bind(this, function() {
|
||||||
false, // do not launch a name-owner if none exists
|
if (this._dbusProxy.g_name_owner)
|
||||||
Lang.bind(this, this._onNameAppeared),
|
this._onNameAppeared();
|
||||||
Lang.bind(this, this._onNameVanished));
|
else
|
||||||
|
this._onNameVanished();
|
||||||
|
}));
|
||||||
},
|
},
|
||||||
|
|
||||||
_resetCache: function() {
|
_resetCache: function() {
|
||||||
@ -273,7 +278,7 @@ DBusEventSource.prototype = {
|
|||||||
this._loadEvents(false);
|
this._loadEvents(false);
|
||||||
},
|
},
|
||||||
|
|
||||||
_onEventsReceived: function(appointments) {
|
_onEventsReceived: function([appointments]) {
|
||||||
let newEvents = [];
|
let newEvents = [];
|
||||||
if (appointments != null) {
|
if (appointments != null) {
|
||||||
for (let n = 0; n < appointments.length; n++) {
|
for (let n = 0; n < appointments.length; n++) {
|
||||||
@ -296,9 +301,9 @@ DBusEventSource.prototype = {
|
|||||||
|
|
||||||
_loadEvents: function(forceReload) {
|
_loadEvents: function(forceReload) {
|
||||||
if (this._curRequestBegin && this._curRequestEnd){
|
if (this._curRequestBegin && this._curRequestEnd){
|
||||||
let callFlags = 0;
|
let callFlags = Gio.DBusCallFlags.NO_AUTO_START;
|
||||||
if (forceReload)
|
if (forceReload)
|
||||||
callFlags |= DBus.CALL_FLAG_START;
|
callFlags = Gio.DBusCallFlags.NONE;
|
||||||
this._dbusProxy.GetEventsRemote(this._curRequestBegin.getTime() / 1000,
|
this._dbusProxy.GetEventsRemote(this._curRequestBegin.getTime() / 1000,
|
||||||
this._curRequestEnd.getTime() / 1000,
|
this._curRequestEnd.getTime() / 1000,
|
||||||
forceReload,
|
forceReload,
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
/* -*- mode: js2; js2-basic-offset: 4; indent-tabs-mode: nil -*- */
|
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
|
||||||
|
|
||||||
const Folks = imports.gi.Folks
|
const Folks = imports.gi.Folks
|
||||||
const Lang = imports.lang;
|
const Lang = imports.lang;
|
||||||
@ -26,7 +26,8 @@ function Contact(id) {
|
|||||||
|
|
||||||
Contact.prototype = {
|
Contact.prototype = {
|
||||||
_init: function(id) {
|
_init: function(id) {
|
||||||
this.individual = Shell.ContactSystem.get_default().get_individual(id);
|
this._contactSys = Shell.ContactSystem.get_default();
|
||||||
|
this.individual = this._contactSys.get_individual(id);
|
||||||
|
|
||||||
this.actor = new St.Bin({ style_class: 'contact',
|
this.actor = new St.Bin({ style_class: 'contact',
|
||||||
reactive: true,
|
reactive: true,
|
||||||
@ -56,7 +57,12 @@ Contact.prototype = {
|
|||||||
x_align: St.Align.START,
|
x_align: St.Align.START,
|
||||||
y_align: St.Align.MIDDLE });
|
y_align: St.Align.MIDDLE });
|
||||||
|
|
||||||
let aliasText = this.individual.alias || _("Unknown");
|
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,
|
let aliasLabel = new St.Label({ text: aliasText,
|
||||||
style_class: 'contact-details-alias' });
|
style_class: 'contact-details-alias' });
|
||||||
details.add(aliasLabel, { x_fill: true,
|
details.add(aliasLabel, { x_fill: true,
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
/* -*- mode: js2; js2-basic-offset: 4; indent-tabs-mode: nil -*- */
|
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
|
||||||
|
|
||||||
const Clutter = imports.gi.Clutter;
|
const Clutter = imports.gi.Clutter;
|
||||||
const Gdk = imports.gi.Gdk;
|
const Gdk = imports.gi.Gdk;
|
||||||
@ -187,7 +187,7 @@ CtrlAltTabPopup.prototype = {
|
|||||||
let [childMinHeight, childNaturalHeight] = this._switcher.actor.get_preferred_height(primary.width - hPadding);
|
let [childMinHeight, childNaturalHeight] = this._switcher.actor.get_preferred_height(primary.width - hPadding);
|
||||||
let [childMinWidth, childNaturalWidth] = this._switcher.actor.get_preferred_width(childNaturalHeight);
|
let [childMinWidth, childNaturalWidth] = this._switcher.actor.get_preferred_width(childNaturalHeight);
|
||||||
childBox.x1 = Math.max(primary.x + leftPadding, primary.x + Math.floor((primary.width - childNaturalWidth) / 2));
|
childBox.x1 = Math.max(primary.x + leftPadding, primary.x + Math.floor((primary.width - childNaturalWidth) / 2));
|
||||||
childBox.x2 = Math.min(primary.width - hPadding, childBox.x1 + childNaturalWidth);
|
childBox.x2 = Math.min(primary.x + primary.width - hPadding, childBox.x1 + childNaturalWidth);
|
||||||
childBox.y1 = primary.y + Math.floor((primary.height - childNaturalHeight) / 2);
|
childBox.y1 = primary.y + Math.floor((primary.height - childNaturalHeight) / 2);
|
||||||
childBox.y2 = childBox.y1 + childNaturalHeight;
|
childBox.y2 = childBox.y1 + childNaturalHeight;
|
||||||
this._switcher.actor.allocate(childBox, flags);
|
this._switcher.actor.allocate(childBox, flags);
|
||||||
|
112
js/ui/dash.js
112
js/ui/dash.js
@ -1,4 +1,4 @@
|
|||||||
/* -*- mode: js2; js2-basic-offset: 4; indent-tabs-mode: nil -*- */
|
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
|
||||||
|
|
||||||
const Clutter = imports.gi.Clutter;
|
const Clutter = imports.gi.Clutter;
|
||||||
const Signals = imports.signals;
|
const Signals = imports.signals;
|
||||||
@ -37,6 +37,7 @@ DashItemContainer.prototype = {
|
|||||||
this.child = null;
|
this.child = null;
|
||||||
this._childScale = 1;
|
this._childScale = 1;
|
||||||
this._childOpacity = 255;
|
this._childOpacity = 255;
|
||||||
|
this.animatingOut = false;
|
||||||
},
|
},
|
||||||
|
|
||||||
_allocate: function(actor, box, flags) {
|
_allocate: function(actor, box, flags) {
|
||||||
@ -115,6 +116,7 @@ DashItemContainer.prototype = {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this.animatingOut = true;
|
||||||
this.childScale = 1.0;
|
this.childScale = 1.0;
|
||||||
Tweener.addTween(this,
|
Tweener.addTween(this,
|
||||||
{ childScale: 0.0,
|
{ childScale: 0.0,
|
||||||
@ -177,12 +179,6 @@ RemoveFavoriteIcon.prototype = {
|
|||||||
this._iconBin._delegate = this;
|
this._iconBin._delegate = this;
|
||||||
|
|
||||||
this.setChild(this._iconBin);
|
this.setChild(this._iconBin);
|
||||||
this.hiding = false;
|
|
||||||
},
|
|
||||||
|
|
||||||
animateOutAndDestroy: function() {
|
|
||||||
DashItemContainer.prototype.animateOutAndDestroy.call(this);
|
|
||||||
this.hiding = true;
|
|
||||||
},
|
},
|
||||||
|
|
||||||
_createIcon: function(size) {
|
_createIcon: function(size) {
|
||||||
@ -235,7 +231,7 @@ DragPlaceholderItem.prototype = {
|
|||||||
|
|
||||||
_init: function() {
|
_init: function() {
|
||||||
DashItemContainer.prototype._init.call(this);
|
DashItemContainer.prototype._init.call(this);
|
||||||
this.setChild(new St.Bin({ style_class: 'dash-placeholder' }));
|
this.setChild(new St.Bin({ style_class: 'placeholder' }));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -314,15 +310,12 @@ Dash.prototype = {
|
|||||||
_endDrag: function() {
|
_endDrag: function() {
|
||||||
this._clearDragPlaceholder();
|
this._clearDragPlaceholder();
|
||||||
if (this._favRemoveTarget) {
|
if (this._favRemoveTarget) {
|
||||||
this._favRemoveTarget.actor.hide();
|
|
||||||
this._adjustIconSize();
|
|
||||||
this._favRemoveTarget.actor.show();
|
|
||||||
|
|
||||||
this._favRemoveTarget.animateOutAndDestroy();
|
this._favRemoveTarget.animateOutAndDestroy();
|
||||||
this._favRemoveTarget.actor.connect('destroy', Lang.bind(this,
|
this._favRemoveTarget.actor.connect('destroy', Lang.bind(this,
|
||||||
function() {
|
function() {
|
||||||
this._favRemoveTarget = null;
|
this._favRemoveTarget = null;
|
||||||
}));
|
}));
|
||||||
|
this._adjustIconSize();
|
||||||
}
|
}
|
||||||
DND.removeDragMonitor(this._dragMonitor);
|
DND.removeDragMonitor(this._dragMonitor);
|
||||||
},
|
},
|
||||||
@ -401,8 +394,18 @@ Dash.prototype = {
|
|||||||
},
|
},
|
||||||
|
|
||||||
_adjustIconSize: function() {
|
_adjustIconSize: function() {
|
||||||
let children = this._box.get_children();
|
// For the icon size, we only consider children which are "proper"
|
||||||
if (children.length == 0) {
|
// icons (i.e. ignoring drag placeholders) and which are not
|
||||||
|
// animating out (which means they will be destroyed at the end of
|
||||||
|
// the animation)
|
||||||
|
let iconChildren = this._box.get_children().filter(function(actor) {
|
||||||
|
return actor._delegate.child &&
|
||||||
|
actor._delegate.child._delegate &&
|
||||||
|
actor._delegate.child._delegate.icon &&
|
||||||
|
!actor._delegate.animatingOut;
|
||||||
|
});
|
||||||
|
|
||||||
|
if (iconChildren.length == 0) {
|
||||||
this._box.add_style_pseudo_class('empty');
|
this._box.add_style_pseudo_class('empty');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -412,23 +415,45 @@ Dash.prototype = {
|
|||||||
if (this._maxHeight == -1)
|
if (this._maxHeight == -1)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
let iconChildren = children.filter(function(actor) {
|
|
||||||
return actor.visible &&
|
|
||||||
actor._delegate.child &&
|
|
||||||
actor._delegate.child._delegate &&
|
|
||||||
actor._delegate.child._delegate.icon;
|
|
||||||
});
|
|
||||||
|
|
||||||
// Compute the amount of extra space (or missing space) we have
|
let themeNode = this.actor.get_theme_node();
|
||||||
// per icon with the current icon size
|
let maxAllocation = new Clutter.ActorBox({ x1: 0, y1: 0,
|
||||||
let [minHeight, natHeight] = this.actor.get_preferred_height(-1);
|
x2: 42 /* whatever */,
|
||||||
let diff = (this._maxHeight - natHeight) / iconChildren.length;
|
y2: this._maxHeight });
|
||||||
|
let maxContent = themeNode.get_content_box(maxAllocation);
|
||||||
|
let availHeight = maxContent.y2 - maxContent.y1;
|
||||||
|
let spacing = themeNode.get_length('spacing');
|
||||||
|
|
||||||
|
|
||||||
|
let firstIcon = iconChildren[0]._delegate.child._delegate.icon;
|
||||||
|
|
||||||
|
let minHeight, natHeight;
|
||||||
|
|
||||||
|
// Enforce the current icon size during the size request if
|
||||||
|
// the icon is animating
|
||||||
|
if (firstIcon._animating) {
|
||||||
|
let [currentWidth, currentHeight] = firstIcon.icon.get_size();
|
||||||
|
|
||||||
|
firstIcon.icon.set_size(this.iconSize, this.iconSize);
|
||||||
|
[minHeight, natHeight] = iconChildren[0].get_preferred_height(-1);
|
||||||
|
|
||||||
|
firstIcon.icon.set_size(currentWidth, currentHeight);
|
||||||
|
} else {
|
||||||
|
[minHeight, natHeight] = iconChildren[0].get_preferred_height(-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Subtract icon padding and box spacing from the available height
|
||||||
|
availHeight -= iconChildren.length * (natHeight - this.iconSize) +
|
||||||
|
(iconChildren.length - 1) * spacing;
|
||||||
|
|
||||||
|
let availSize = availHeight / iconChildren.length;
|
||||||
|
|
||||||
let iconSizes = [ 16, 22, 24, 32, 48, 64 ];
|
let iconSizes = [ 16, 22, 24, 32, 48, 64 ];
|
||||||
|
|
||||||
let newIconSize = 16;
|
let newIconSize = 16;
|
||||||
for (let i = 0; i < iconSizes.length; i++) {
|
for (let i = 0; i < iconSizes.length; i++) {
|
||||||
if (iconSizes[i] < this.iconSize + diff)
|
if (iconSizes[i] < availSize)
|
||||||
newIconSize = iconSizes[i];
|
newIconSize = iconSizes[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -459,11 +484,15 @@ Dash.prototype = {
|
|||||||
icon.icon.set_size(icon.icon.width * scale,
|
icon.icon.set_size(icon.icon.width * scale,
|
||||||
icon.icon.height * scale);
|
icon.icon.height * scale);
|
||||||
|
|
||||||
|
icon._animating = true;
|
||||||
Tweener.addTween(icon.icon,
|
Tweener.addTween(icon.icon,
|
||||||
{ width: targetWidth,
|
{ width: targetWidth,
|
||||||
height: targetHeight,
|
height: targetHeight,
|
||||||
time: DASH_ANIMATION_TIME,
|
time: DASH_ANIMATION_TIME,
|
||||||
transition: 'easeOutQuad'
|
transition: 'easeOutQuad',
|
||||||
|
onComplete: function() {
|
||||||
|
icon._animating = false;
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -566,29 +595,7 @@ Dash.prototype = {
|
|||||||
this._box.insert_actor(addedItems[i].item.actor,
|
this._box.insert_actor(addedItems[i].item.actor,
|
||||||
addedItems[i].pos);
|
addedItems[i].pos);
|
||||||
|
|
||||||
// Hide removed actors to not take them into account
|
|
||||||
// when adjusting the icon size ...
|
|
||||||
for (let i = 0; i < removedActors.length; i++)
|
|
||||||
removedActors[i].hide();
|
|
||||||
|
|
||||||
// ... and do the same for the remove target if necessary
|
|
||||||
if (this._favRemoveTarget && this._favRemoveTarget.hiding)
|
|
||||||
this._favRemoveTarget.actor.hide();
|
|
||||||
|
|
||||||
this._adjustIconSize();
|
|
||||||
|
|
||||||
if (this._favRemoveTarget && this._favRemoveTarget.hiding)
|
|
||||||
this._favRemoveTarget.actor.show();
|
|
||||||
|
|
||||||
// Skip animations on first run when adding the initial set
|
|
||||||
// of items, to avoid all items zooming in at once
|
|
||||||
if (!this._shownInitially) {
|
|
||||||
this._shownInitially = true;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (let i = 0; i < removedActors.length; i++) {
|
for (let i = 0; i < removedActors.length; i++) {
|
||||||
removedActors[i].show();
|
|
||||||
let item = removedActors[i]._delegate;
|
let item = removedActors[i]._delegate;
|
||||||
|
|
||||||
// Don't animate item removal when the overview is hidden
|
// Don't animate item removal when the overview is hidden
|
||||||
@ -598,6 +605,15 @@ Dash.prototype = {
|
|||||||
item.actor.destroy();
|
item.actor.destroy();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this._adjustIconSize();
|
||||||
|
|
||||||
|
// Skip animations on first run when adding the initial set
|
||||||
|
// of items, to avoid all items zooming in at once
|
||||||
|
if (!this._shownInitially) {
|
||||||
|
this._shownInitially = true;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// Don't animate item addition when the overview is hidden
|
// Don't animate item addition when the overview is hidden
|
||||||
if (!Main.overview.visible)
|
if (!Main.overview.visible)
|
||||||
return;
|
return;
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
/* -*- mode: js2; js2-basic-offset: 4; indent-tabs-mode: nil -*- */
|
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
|
||||||
|
|
||||||
const GLib = imports.gi.GLib;
|
const GLib = imports.gi.GLib;
|
||||||
const Gio = imports.gi.Gio;
|
const Gio = imports.gi.Gio;
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
/* -*- mode: js2; js2-basic-offset: 4; indent-tabs-mode: nil -*- */
|
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
|
||||||
|
|
||||||
const Clutter = imports.gi.Clutter;
|
const Clutter = imports.gi.Clutter;
|
||||||
const Gtk = imports.gi.Gtk;
|
const Gtk = imports.gi.Gtk;
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
/* -*- mode: js2; js2-basic-offset: 4; indent-tabs-mode: nil -*- */
|
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
|
||||||
|
|
||||||
const DocInfo = imports.misc.docInfo;
|
const DocInfo = imports.misc.docInfo;
|
||||||
const Params = imports.misc.params;
|
const Params = imports.misc.params;
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/* -*- mode: js2; js2-basic-offset: 4; indent-tabs-mode: nil -*-
|
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
|
||||||
*
|
/*
|
||||||
* Copyright 2010 Red Hat, Inc
|
* Copyright 2010 Red Hat, Inc
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* This program is free software; you can redistribute it and/or modify
|
||||||
@ -18,19 +18,19 @@
|
|||||||
* 02111-1307, USA.
|
* 02111-1307, USA.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
const DBus = imports.dbus;
|
|
||||||
const Lang = imports.lang;
|
const Lang = imports.lang;
|
||||||
const Signals = imports.signals;
|
const Signals = imports.signals;
|
||||||
|
|
||||||
const AccountsService = imports.gi.AccountsService;
|
const AccountsService = imports.gi.AccountsService;
|
||||||
const Clutter = imports.gi.Clutter;
|
const Clutter = imports.gi.Clutter;
|
||||||
|
const Gio = imports.gi.Gio;
|
||||||
const GLib = imports.gi.GLib;
|
const GLib = imports.gi.GLib;
|
||||||
const Gtk = imports.gi.Gtk;
|
const Gtk = imports.gi.Gtk;
|
||||||
const 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 GnomeSession = imports.misc.gnomeSession
|
const GnomeSession = imports.misc.gnomeSession;
|
||||||
const Lightbox = imports.ui.lightbox;
|
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;
|
||||||
@ -43,22 +43,23 @@ const _DIALOG_ICON_SIZE = 32;
|
|||||||
|
|
||||||
const GSM_SESSION_MANAGER_LOGOUT_FORCE = 2;
|
const GSM_SESSION_MANAGER_LOGOUT_FORCE = 2;
|
||||||
|
|
||||||
const EndSessionDialogIface = {
|
const EndSessionDialogIface = <interface name="org.gnome.SessionManager.EndSessionDialog">
|
||||||
name: 'org.gnome.SessionManager.EndSessionDialog',
|
<method name="Open">
|
||||||
methods: [{ name: 'Open',
|
<arg type="u" direction="in" />
|
||||||
inSignature: 'uuuao',
|
<arg type="u" direction="in" />
|
||||||
outSignature: ''
|
<arg type="u" direction="in" />
|
||||||
}
|
<arg type="ao" direction="in" />
|
||||||
],
|
</method>
|
||||||
signals: [{ name: 'Canceled',
|
<signal name="ConfirmedLogout" />
|
||||||
inSignature: '',
|
<signal name="ConfirmedReboot" />
|
||||||
}],
|
<signal name="ConfirmedShutdown" />
|
||||||
properties: []
|
<signal name="Canceled" />
|
||||||
};
|
<signal name="Closed" />
|
||||||
|
</interface>;
|
||||||
|
|
||||||
const logoutDialogContent = {
|
const logoutDialogContent = {
|
||||||
subjectWithUser: _("Log Out %s"),
|
subjectWithUser: C_("title", "Log Out %s"),
|
||||||
subject: _("Log Out"),
|
subject: C_("title", "Log Out"),
|
||||||
inhibitedDescription: _("Click Log Out to quit these applications and log out of the system."),
|
inhibitedDescription: _("Click Log Out to quit these applications and log out of the system."),
|
||||||
uninhibitedDescriptionWithUser: function(user, seconds) {
|
uninhibitedDescriptionWithUser: function(user, seconds) {
|
||||||
return ngettext("%s will be logged out automatically in %d second.",
|
return ngettext("%s will be logged out automatically in %d second.",
|
||||||
@ -72,12 +73,12 @@ const logoutDialogContent = {
|
|||||||
},
|
},
|
||||||
endDescription: _("Logging out of the system."),
|
endDescription: _("Logging out of the system."),
|
||||||
confirmButtons: [{ signal: 'ConfirmedLogout',
|
confirmButtons: [{ signal: 'ConfirmedLogout',
|
||||||
label: _("Log Out") }],
|
label: C_("button", "Log Out") }],
|
||||||
iconStyleClass: 'end-session-dialog-logout-icon'
|
iconStyleClass: 'end-session-dialog-logout-icon'
|
||||||
};
|
};
|
||||||
|
|
||||||
const shutdownDialogContent = {
|
const shutdownDialogContent = {
|
||||||
subject: _("Power Off"),
|
subject: C_("title", "Power Off"),
|
||||||
inhibitedDescription: _("Click Power Off to quit these applications and power off the system."),
|
inhibitedDescription: _("Click Power Off to quit these applications and power off the system."),
|
||||||
uninhibitedDescription: function(seconds) {
|
uninhibitedDescription: function(seconds) {
|
||||||
return ngettext("The system will power off automatically in %d second.",
|
return ngettext("The system will power off automatically in %d second.",
|
||||||
@ -86,15 +87,15 @@ const shutdownDialogContent = {
|
|||||||
},
|
},
|
||||||
endDescription: _("Powering off the system."),
|
endDescription: _("Powering off the system."),
|
||||||
confirmButtons: [{ signal: 'ConfirmedReboot',
|
confirmButtons: [{ signal: 'ConfirmedReboot',
|
||||||
label: _("Restart") },
|
label: C_("button", "Restart") },
|
||||||
{ signal: 'ConfirmedShutdown',
|
{ signal: 'ConfirmedShutdown',
|
||||||
label: _("Power Off") }],
|
label: C_("button", "Power Off") }],
|
||||||
iconName: 'system-shutdown',
|
iconName: 'system-shutdown',
|
||||||
iconStyleClass: 'end-session-dialog-shutdown-icon'
|
iconStyleClass: 'end-session-dialog-shutdown-icon'
|
||||||
};
|
};
|
||||||
|
|
||||||
const restartDialogContent = {
|
const restartDialogContent = {
|
||||||
subject: _("Restart"),
|
subject: C_("title", "Restart"),
|
||||||
inhibitedDescription: _("Click Restart to quit these applications and restart the system."),
|
inhibitedDescription: _("Click Restart to quit these applications and restart the system."),
|
||||||
uninhibitedDescription: function(seconds) {
|
uninhibitedDescription: function(seconds) {
|
||||||
return ngettext("The system will restart automatically in %d second.",
|
return ngettext("The system will restart automatically in %d second.",
|
||||||
@ -103,7 +104,7 @@ const restartDialogContent = {
|
|||||||
},
|
},
|
||||||
endDescription: _("Restarting the system."),
|
endDescription: _("Restarting the system."),
|
||||||
confirmButtons: [{ signal: 'ConfirmedReboot',
|
confirmButtons: [{ signal: 'ConfirmedReboot',
|
||||||
label: _("Restart") }],
|
label: C_("button", "Restart") }],
|
||||||
iconName: 'system-shutdown',
|
iconName: 'system-shutdown',
|
||||||
iconStyleClass: 'end-session-dialog-shutdown-icon'
|
iconStyleClass: 'end-session-dialog-shutdown-icon'
|
||||||
};
|
};
|
||||||
@ -232,8 +233,6 @@ function _setLabelText(label, text) {
|
|||||||
function EndSessionDialog() {
|
function EndSessionDialog() {
|
||||||
if (_endSessionDialog == null) {
|
if (_endSessionDialog == null) {
|
||||||
this._init();
|
this._init();
|
||||||
DBus.session.exportObject('/org/gnome/SessionManager/EndSessionDialog',
|
|
||||||
this);
|
|
||||||
_endSessionDialog = this;
|
_endSessionDialog = this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -326,6 +325,9 @@ EndSessionDialog.prototype = {
|
|||||||
if (this._applicationList.get_children().length == 0)
|
if (this._applicationList.get_children().length == 0)
|
||||||
scrollView.hide();
|
scrollView.hide();
|
||||||
}));
|
}));
|
||||||
|
|
||||||
|
this._dbusImpl = Gio.DBusExportedObject.wrapJSObject(EndSessionDialogIface, this);
|
||||||
|
this._dbusImpl.export(Gio.DBus.session, '/org/gnome/SessionManager/EndSessionDialog');
|
||||||
},
|
},
|
||||||
|
|
||||||
_onDestroy: function() {
|
_onDestroy: function() {
|
||||||
@ -440,25 +442,19 @@ EndSessionDialog.prototype = {
|
|||||||
|
|
||||||
close: function() {
|
close: function() {
|
||||||
ModalDialog.ModalDialog.prototype.close.call(this);
|
ModalDialog.ModalDialog.prototype.close.call(this);
|
||||||
DBus.session.emit_signal('/org/gnome/SessionManager/EndSessionDialog',
|
this._dbusImpl.emit_signal('Closed', null);
|
||||||
'org.gnome.SessionManager.EndSessionDialog',
|
|
||||||
'Closed', '', []);
|
|
||||||
},
|
},
|
||||||
|
|
||||||
cancel: function() {
|
cancel: function() {
|
||||||
this._stopTimer();
|
this._stopTimer();
|
||||||
DBus.session.emit_signal('/org/gnome/SessionManager/EndSessionDialog',
|
this._dbusImpl.emit_signal('Canceled', null);
|
||||||
'org.gnome.SessionManager.EndSessionDialog',
|
|
||||||
'Canceled', '', []);
|
|
||||||
this.close(global.get_current_time());
|
this.close(global.get_current_time());
|
||||||
},
|
},
|
||||||
|
|
||||||
_confirm: function(signal) {
|
_confirm: function(signal) {
|
||||||
this._fadeOutDialog();
|
this._fadeOutDialog();
|
||||||
this._stopTimer();
|
this._stopTimer();
|
||||||
DBus.session.emit_signal('/org/gnome/SessionManager/EndSessionDialog',
|
this._dbusImpl.emit_signal(signal, null);
|
||||||
'org.gnome.SessionManager.EndSessionDialog',
|
|
||||||
signal, '', []);
|
|
||||||
},
|
},
|
||||||
|
|
||||||
_onOpened: function() {
|
_onOpened: function() {
|
||||||
@ -510,39 +506,41 @@ EndSessionDialog.prototype = {
|
|||||||
this._updateContent();
|
this._updateContent();
|
||||||
},
|
},
|
||||||
|
|
||||||
OpenAsync: function(type, timestamp, totalSecondsToStayOpen, inhibitorObjectPaths, callback) {
|
OpenAsync: function(parameters, invocation) {
|
||||||
|
let [type, timestamp, totalSecondsToStayOpen, inhibitorObjectPaths] = parameters;
|
||||||
this._totalSecondsToStayOpen = totalSecondsToStayOpen;
|
this._totalSecondsToStayOpen = totalSecondsToStayOpen;
|
||||||
this._inhibitors = [];
|
this._inhibitors = [];
|
||||||
this._applicationList.destroy_children();
|
this._applicationList.destroy_children();
|
||||||
this._type = type;
|
this._type = type;
|
||||||
|
|
||||||
if (!(this._type in DialogContent))
|
if (!(this._type in DialogContent)) {
|
||||||
throw new DBus.DBusError('org.gnome.Shell.ModalDialog.TypeError',
|
invocation.report_dbus_error('org.gnome.Shell.ModalDialog.TypeError',
|
||||||
"Unknown dialog type requested");
|
"Unknown dialog type requested");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
for (let i = 0; i < inhibitorObjectPaths.length; i++) {
|
for (let i = 0; i < inhibitorObjectPaths.length; i++) {
|
||||||
let inhibitor = new GnomeSession.Inhibitor(inhibitorObjectPaths[i]);
|
let inhibitor = new GnomeSession.Inhibitor(inhibitorObjectPaths[i], Lang.bind(this, function(proxy, error) {
|
||||||
|
this._onInhibitorLoaded(proxy);
|
||||||
|
}));
|
||||||
|
|
||||||
inhibitor.connect('is-loaded',
|
|
||||||
Lang.bind(this, function() {
|
|
||||||
this._onInhibitorLoaded(inhibitor);
|
|
||||||
}));
|
|
||||||
this._inhibitors.push(inhibitor);
|
this._inhibitors.push(inhibitor);
|
||||||
}
|
}
|
||||||
|
|
||||||
this._updateButtons();
|
this._updateButtons();
|
||||||
|
|
||||||
if (!this.open(timestamp))
|
if (!this.open(timestamp)) {
|
||||||
throw new DBus.DBusError('org.gnome.Shell.ModalDialog.GrabError',
|
invocation.report_dbus_error('org.gnome.Shell.ModalDialog.GrabError',
|
||||||
"Cannot grab pointer and keyboard");
|
"Cannot grab pointer and keyboard");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
this._updateContent();
|
this._updateContent();
|
||||||
|
|
||||||
let signalId = this.connect('opened',
|
let signalId = this.connect('opened',
|
||||||
Lang.bind(this, function() {
|
Lang.bind(this, function() {
|
||||||
callback();
|
invocation.return_value(null);
|
||||||
this.disconnect(signalId);
|
this.disconnect(signalId);
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
DBus.conformExport(EndSessionDialog.prototype, EndSessionDialogIface);
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
/* -*- mode: js2; js2-basic-offset: 4; indent-tabs-mode: nil -*- */
|
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
|
||||||
|
|
||||||
imports.gi.versions.Clutter = '1.0';
|
imports.gi.versions.Clutter = '1.0';
|
||||||
imports.gi.versions.Gio = '2.0';
|
imports.gi.versions.Gio = '2.0';
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
/* -*- mode: js2; js2-basic-offset: 4; indent-tabs-mode: nil -*- */
|
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
|
||||||
|
|
||||||
const Lang = imports.lang;
|
const Lang = imports.lang;
|
||||||
const Signals = imports.signals;
|
const Signals = imports.signals;
|
||||||
@ -22,6 +22,7 @@ const ExtensionState = {
|
|||||||
ERROR: 3,
|
ERROR: 3,
|
||||||
OUT_OF_DATE: 4,
|
OUT_OF_DATE: 4,
|
||||||
DOWNLOADING: 5,
|
DOWNLOADING: 5,
|
||||||
|
INITIALIZED: 6,
|
||||||
|
|
||||||
// Used as an error state for operations on unknown extensions,
|
// Used as an error state for operations on unknown extensions,
|
||||||
// should never be in a real extensionMeta object.
|
// should never be in a real extensionMeta object.
|
||||||
@ -62,6 +63,9 @@ const extensionMeta = {};
|
|||||||
const extensions = {};
|
const extensions = {};
|
||||||
// Maps uuid -> extension state object (returned from init())
|
// Maps uuid -> extension state object (returned from init())
|
||||||
const extensionStateObjs = {};
|
const extensionStateObjs = {};
|
||||||
|
// Contains the order that extensions were enabled in.
|
||||||
|
const extensionOrder = [];
|
||||||
|
|
||||||
// Arrays of uuids
|
// Arrays of uuids
|
||||||
var enabledExtensions;
|
var enabledExtensions;
|
||||||
// GFile for user extensions
|
// GFile for user extensions
|
||||||
@ -212,6 +216,27 @@ function disableExtension(uuid) {
|
|||||||
|
|
||||||
let extensionState = extensionStateObjs[uuid];
|
let extensionState = extensionStateObjs[uuid];
|
||||||
|
|
||||||
|
// "Rebase" the extension order by disabling and then enabling extensions
|
||||||
|
// in order to help prevent conflicts.
|
||||||
|
|
||||||
|
// Example:
|
||||||
|
// order = [A, B, C, D, E]
|
||||||
|
// user disables C
|
||||||
|
// this should: disable E, disable D, disable C, enable D, enable E
|
||||||
|
|
||||||
|
let orderIdx = extensionOrder.indexOf(uuid);
|
||||||
|
let order = extensionOrder.slice(orderIdx + 1);
|
||||||
|
let orderReversed = order.slice().reverse();
|
||||||
|
|
||||||
|
for (let i = 0; i < orderReversed.length; i++) {
|
||||||
|
let uuid = orderReversed[i];
|
||||||
|
try {
|
||||||
|
extensionStateObjs[uuid].disable();
|
||||||
|
} catch(e) {
|
||||||
|
logExtensionError(uuid, e.toString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
extensionState.disable();
|
extensionState.disable();
|
||||||
} catch(e) {
|
} catch(e) {
|
||||||
@ -219,6 +244,17 @@ function disableExtension(uuid) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (let i = 0; i < order.length; i++) {
|
||||||
|
let uuid = order[i];
|
||||||
|
try {
|
||||||
|
extensionStateObjs[uuid].enable();
|
||||||
|
} catch(e) {
|
||||||
|
logExtensionError(uuid, e.toString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
extensionOrder.splice(orderIdx, 1);
|
||||||
|
|
||||||
meta.state = ExtensionState.DISABLED;
|
meta.state = ExtensionState.DISABLED;
|
||||||
_signals.emit('extension-state-changed', meta);
|
_signals.emit('extension-state-changed', meta);
|
||||||
}
|
}
|
||||||
@ -228,11 +264,18 @@ function enableExtension(uuid) {
|
|||||||
if (!meta)
|
if (!meta)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
if (meta.state == ExtensionState.INITIALIZED) {
|
||||||
|
loadExtension(meta.dir, meta.type, true);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (meta.state != ExtensionState.DISABLED)
|
if (meta.state != ExtensionState.DISABLED)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
let extensionState = extensionStateObjs[uuid];
|
let extensionState = extensionStateObjs[uuid];
|
||||||
|
|
||||||
|
extensionOrder.push(uuid);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
extensionState.enable();
|
extensionState.enable();
|
||||||
} catch(e) {
|
} catch(e) {
|
||||||
@ -254,7 +297,7 @@ function logExtensionError(uuid, message, state) {
|
|||||||
state: state });
|
state: state });
|
||||||
}
|
}
|
||||||
|
|
||||||
function loadExtension(dir, enabled, type) {
|
function loadExtension(dir, type, enabled) {
|
||||||
let info;
|
let info;
|
||||||
let uuid = dir.get_basename();
|
let uuid = dir.get_basename();
|
||||||
|
|
||||||
@ -289,7 +332,7 @@ function loadExtension(dir, enabled, type) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (extensions[uuid] != undefined) {
|
if (extensions[uuid] != undefined) {
|
||||||
logExtensionError(uuid, "extension already loaded");
|
logExtensionError(uuid, 'extension already loaded');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -303,14 +346,9 @@ function loadExtension(dir, enabled, type) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!versionCheck(meta['shell-version'], Config.PACKAGE_VERSION) ||
|
|
||||||
(meta['js-version'] && !versionCheck(meta['js-version'], Config.GJS_VERSION))) {
|
|
||||||
logExtensionError(uuid, 'extension is not compatible with current GNOME Shell and/or GJS version');
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
extensionMeta[uuid] = meta;
|
extensionMeta[uuid] = meta;
|
||||||
meta.type = type;
|
meta.type = type;
|
||||||
|
meta.dir = dir;
|
||||||
meta.path = dir.get_path();
|
meta.path = dir.get_path();
|
||||||
meta.error = '';
|
meta.error = '';
|
||||||
|
|
||||||
@ -324,6 +362,11 @@ function loadExtension(dir, enabled, type) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!enabled) {
|
||||||
|
meta.state = ExtensionState.INITIALIZED;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
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');
|
logExtensionError(uuid, 'Missing extension.js');
|
||||||
@ -383,8 +426,7 @@ function loadExtension(dir, enabled, type) {
|
|||||||
|
|
||||||
meta.state = ExtensionState.DISABLED;
|
meta.state = ExtensionState.DISABLED;
|
||||||
|
|
||||||
if (enabled)
|
enableExtension(uuid);
|
||||||
enableExtension(uuid);
|
|
||||||
|
|
||||||
_signals.emit('extension-loaded', meta.uuid);
|
_signals.emit('extension-loaded', meta.uuid);
|
||||||
_signals.emit('extension-state-changed', meta);
|
_signals.emit('extension-state-changed', meta);
|
||||||
@ -444,13 +486,12 @@ function _loadExtensionsIn(dir, type) {
|
|||||||
let name = info.get_name();
|
let name = info.get_name();
|
||||||
let child = dir.get_child(name);
|
let child = dir.get_child(name);
|
||||||
let enabled = enabledExtensions.indexOf(name) != -1;
|
let enabled = enabledExtensions.indexOf(name) != -1;
|
||||||
loadExtension(child, enabled, type);
|
loadExtension(child, type, enabled);
|
||||||
}
|
}
|
||||||
fileEnum.close(null);
|
fileEnum.close(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
function loadExtensions() {
|
function loadExtensions() {
|
||||||
_loadExtensionsIn(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 = systemDataDirs[i] + '/gnome-shell/extensions';
|
let dirPath = systemDataDirs[i] + '/gnome-shell/extensions';
|
||||||
@ -458,6 +499,7 @@ function loadExtensions() {
|
|||||||
if (dir.query_exists(null))
|
if (dir.query_exists(null))
|
||||||
_loadExtensionsIn(dir, ExtensionType.SYSTEM);
|
_loadExtensionsIn(dir, ExtensionType.SYSTEM);
|
||||||
}
|
}
|
||||||
|
_loadExtensionsIn(userExtensionsDir, ExtensionType.PER_USER);
|
||||||
}
|
}
|
||||||
|
|
||||||
function InstallExtensionDialog(uuid, version_tag, name) {
|
function InstallExtensionDialog(uuid, version_tag, name) {
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
/* -*- mode: js2; js2-basic-offset: 4; indent-tabs-mode: nil -*- */
|
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
|
||||||
|
|
||||||
const Clutter = imports.gi.Clutter;
|
const Clutter = imports.gi.Clutter;
|
||||||
const Shell = imports.gi.Shell;
|
const Shell = imports.gi.Shell;
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
/* -*- mode: js2; js2-basic-offset: 4; indent-tabs-mode: nil -*- */
|
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
|
||||||
|
|
||||||
const Caribou = imports.gi.Caribou;
|
const Caribou = imports.gi.Caribou;
|
||||||
const Clutter = imports.gi.Clutter;
|
const Clutter = imports.gi.Clutter;
|
||||||
@ -75,7 +75,7 @@ Key.prototype = {
|
|||||||
this._extended_keys = this._key.get_extended_keys();
|
this._extended_keys = this._key.get_extended_keys();
|
||||||
this._extended_keyboard = null;
|
this._extended_keyboard = null;
|
||||||
|
|
||||||
if (this._key.name == "Control_L" || this._key.name == "Alt_L")
|
if (this._key.name == 'Control_L' || this._key.name == 'Alt_L')
|
||||||
this._key.latch = true;
|
this._key.latch = true;
|
||||||
|
|
||||||
this._key.connect('key-pressed', Lang.bind(this, function ()
|
this._key.connect('key-pressed', Lang.bind(this, function ()
|
||||||
@ -218,7 +218,7 @@ Keyboard.prototype = {
|
|||||||
this._redraw();
|
this._redraw();
|
||||||
},
|
},
|
||||||
|
|
||||||
_settingsChanged: function () {
|
_settingsChanged: function (settings, key) {
|
||||||
this._enableKeyboard = this._a11yApplicationsSettings.get_boolean(SHOW_KEYBOARD);
|
this._enableKeyboard = this._a11yApplicationsSettings.get_boolean(SHOW_KEYBOARD);
|
||||||
if (!this._enableKeyboard && !this._keyboard)
|
if (!this._enableKeyboard && !this._keyboard)
|
||||||
return;
|
return;
|
||||||
@ -228,9 +228,20 @@ Keyboard.prototype = {
|
|||||||
|
|
||||||
if (this._keyboard)
|
if (this._keyboard)
|
||||||
this._destroyKeyboard();
|
this._destroyKeyboard();
|
||||||
if (this._enableKeyboard)
|
|
||||||
this._setupKeyboard();
|
if (this._enableKeyboard) {
|
||||||
else
|
// If we've been called because the setting actually just
|
||||||
|
// changed to true (as opposed to being called from
|
||||||
|
// this._init()), then we want to pop up the keyboard.
|
||||||
|
let showKeyboard = (settings != null);
|
||||||
|
|
||||||
|
// However, caribou-gtk-module or this._onKeyFocusChanged
|
||||||
|
// will probably immediately tell us to hide it, so we
|
||||||
|
// have to fake things out so we'll ignore that request.
|
||||||
|
if (showKeyboard)
|
||||||
|
this._timestamp = global.display.get_current_time_roundtrip() + 1;
|
||||||
|
this._setupKeyboard(showKeyboard);
|
||||||
|
} else
|
||||||
Main.layoutManager.hideKeyboard(true);
|
Main.layoutManager.hideKeyboard(true);
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -246,7 +257,7 @@ Keyboard.prototype = {
|
|||||||
this._destroySource();
|
this._destroySource();
|
||||||
},
|
},
|
||||||
|
|
||||||
_setupKeyboard: function() {
|
_setupKeyboard: function(show) {
|
||||||
this.actor = new St.BoxLayout({ name: 'keyboard', vertical: true, reactive: true });
|
this.actor = new St.BoxLayout({ name: 'keyboard', vertical: true, reactive: true });
|
||||||
Main.layoutManager.keyboardBox.add_actor(this.actor);
|
Main.layoutManager.keyboardBox.add_actor(this.actor);
|
||||||
Main.layoutManager.trackChrome(this.actor);
|
Main.layoutManager.trackChrome(this.actor);
|
||||||
@ -263,20 +274,26 @@ Keyboard.prototype = {
|
|||||||
|
|
||||||
this._keyboardNotifyId = this._keyboard.connect('notify::active-group', Lang.bind(this, this._onGroupChanged));
|
this._keyboardNotifyId = this._keyboard.connect('notify::active-group', Lang.bind(this, this._onGroupChanged));
|
||||||
this._focusNotifyId = global.stage.connect('notify::key-focus', Lang.bind(this, this._onKeyFocusChanged));
|
this._focusNotifyId = global.stage.connect('notify::key-focus', Lang.bind(this, this._onKeyFocusChanged));
|
||||||
this._createSource();
|
|
||||||
|
if (show)
|
||||||
|
this.show();
|
||||||
|
else
|
||||||
|
this._createSource();
|
||||||
},
|
},
|
||||||
|
|
||||||
_onKeyFocusChanged: function () {
|
_onKeyFocusChanged: function () {
|
||||||
let focus = global.stage.key_focus;
|
let focus = global.stage.key_focus;
|
||||||
|
|
||||||
// Showing an extended key popup will grab focus, but ignore that
|
// Showing an extended key popup and clicking a key from the extended keys
|
||||||
if (focus && focus._extended_keys)
|
// will grab focus, but ignore that
|
||||||
|
if (focus && (focus._extended_keys || (focus._key && focus._key.extended_key)))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
let time = global.get_current_time();
|
||||||
if (focus instanceof Clutter.Text)
|
if (focus instanceof Clutter.Text)
|
||||||
this.show();
|
this.Show(time);
|
||||||
else
|
else
|
||||||
this.hide();
|
this.Hide(time);
|
||||||
},
|
},
|
||||||
|
|
||||||
_addKeys: function () {
|
_addKeys: function () {
|
||||||
@ -305,7 +322,8 @@ Keyboard.prototype = {
|
|||||||
},
|
},
|
||||||
|
|
||||||
_getTrayIcon: function () {
|
_getTrayIcon: function () {
|
||||||
let trayButton = new St.Button ({ label: "tray", style_class: 'keyboard-key' });
|
let trayButton = new St.Button ({ label: _("tray"),
|
||||||
|
style_class: 'keyboard-key' });
|
||||||
trayButton.key_width = 1;
|
trayButton.key_width = 1;
|
||||||
trayButton.connect('button-press-event', Lang.bind(this, function () {
|
trayButton.connect('button-press-event', Lang.bind(this, function () {
|
||||||
Main.messageTray.toggle();
|
Main.messageTray.toggle();
|
||||||
@ -339,7 +357,7 @@ Keyboard.prototype = {
|
|||||||
right_box.add(button.actor);
|
right_box.add(button.actor);
|
||||||
else
|
else
|
||||||
left_box.add(button.actor);
|
left_box.add(button.actor);
|
||||||
if (key.name == "Caribou_Prefs") {
|
if (key.name == 'Caribou_Prefs') {
|
||||||
key.connect('key-released', Lang.bind(this, this.hide));
|
key.connect('key-released', Lang.bind(this, this.hide));
|
||||||
|
|
||||||
// Add new key for hiding message tray
|
// Add new key for hiding message tray
|
||||||
@ -476,6 +494,9 @@ Keyboard.prototype = {
|
|||||||
|
|
||||||
// D-Bus methods
|
// D-Bus methods
|
||||||
Show: function(timestamp) {
|
Show: function(timestamp) {
|
||||||
|
if (!this._enableKeyboard)
|
||||||
|
return;
|
||||||
|
|
||||||
if (timestamp - this._timestamp < 0)
|
if (timestamp - this._timestamp < 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@ -484,6 +505,9 @@ Keyboard.prototype = {
|
|||||||
},
|
},
|
||||||
|
|
||||||
Hide: function(timestamp) {
|
Hide: function(timestamp) {
|
||||||
|
if (!this._enableKeyboard)
|
||||||
|
return;
|
||||||
|
|
||||||
if (timestamp - this._timestamp < 0)
|
if (timestamp - this._timestamp < 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@ -492,11 +516,17 @@ Keyboard.prototype = {
|
|||||||
},
|
},
|
||||||
|
|
||||||
SetCursorLocation: function(x, y, w, h) {
|
SetCursorLocation: function(x, y, w, h) {
|
||||||
this._setLocation(x, y);
|
if (!this._enableKeyboard)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// this._setLocation(x, y);
|
||||||
},
|
},
|
||||||
|
|
||||||
SetEntryLocation: function(x, y, w, h) {
|
SetEntryLocation: function(x, y, w, h) {
|
||||||
this._setLocation(x, y);
|
if (!this._enableKeyboard)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// this._setLocation(x, y);
|
||||||
},
|
},
|
||||||
|
|
||||||
get Name() {
|
get Name() {
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
/* -*- mode: js2; js2-basic-offset: 4; indent-tabs-mode: nil -*- */
|
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
|
||||||
|
|
||||||
const Clutter = imports.gi.Clutter;
|
const Clutter = imports.gi.Clutter;
|
||||||
const Lang = imports.lang;
|
const Lang = imports.lang;
|
||||||
@ -45,7 +45,9 @@ LayoutManager.prototype = {
|
|||||||
this.trayBox.connect('allocation-changed',
|
this.trayBox.connect('allocation-changed',
|
||||||
Lang.bind(this, this._updateTrayBarrier));
|
Lang.bind(this, this._updateTrayBarrier));
|
||||||
|
|
||||||
this.keyboardBox = new St.BoxLayout({ name: 'keyboardBox' });
|
this.keyboardBox = new St.BoxLayout({ name: 'keyboardBox',
|
||||||
|
reactive: true,
|
||||||
|
track_hover: true });
|
||||||
this.addChrome(this.keyboardBox, { visibleInFullscreen: true });
|
this.addChrome(this.keyboardBox, { visibleInFullscreen: true });
|
||||||
this._keyboardHeightNotifyId = 0;
|
this._keyboardHeightNotifyId = 0;
|
||||||
|
|
||||||
@ -214,10 +216,10 @@ LayoutManager.prototype = {
|
|||||||
let monitorLeft = monitor.x, monitorRight = monitor.x + monitor.width;
|
let monitorLeft = monitor.x, monitorRight = monitor.x + monitor.width;
|
||||||
let primaryLeft = primary.x, primaryRight = primary.x + primary.width;
|
let primaryLeft = primary.x, primaryRight = primary.x + primary.width;
|
||||||
|
|
||||||
if ((monitorLeft >= primaryLeft && monitorLeft <= primaryRight) ||
|
if ((monitorLeft >= primaryLeft && monitorLeft < primaryRight) ||
|
||||||
(monitorRight >= primaryLeft && monitorRight <= primaryRight) ||
|
(monitorRight > primaryLeft && monitorRight <= primaryRight) ||
|
||||||
(primaryLeft >= monitorLeft && primaryLeft <= monitorRight) ||
|
(primaryLeft >= monitorLeft && primaryLeft < monitorRight) ||
|
||||||
(primaryRight >= monitorLeft && primaryRight <= monitorRight))
|
(primaryRight > monitorLeft && primaryRight <= monitorRight))
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
@ -367,6 +369,10 @@ LayoutManager.prototype = {
|
|||||||
// Removes @actor from the chrome
|
// Removes @actor from the chrome
|
||||||
removeChrome: function(actor) {
|
removeChrome: function(actor) {
|
||||||
this._chrome.removeActor(actor);
|
this._chrome.removeActor(actor);
|
||||||
|
},
|
||||||
|
|
||||||
|
findMonitorForActor: function(actor) {
|
||||||
|
return this._chrome.findMonitorForActor(actor);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
Signals.addSignalMethods(LayoutManager.prototype);
|
Signals.addSignalMethods(LayoutManager.prototype);
|
||||||
@ -581,12 +587,13 @@ Chrome.prototype = {
|
|||||||
|
|
||||||
this._screenSaverActive = false;
|
this._screenSaverActive = false;
|
||||||
this._screenSaverProxy = new ScreenSaver.ScreenSaverProxy();
|
this._screenSaverProxy = new ScreenSaver.ScreenSaverProxy();
|
||||||
this._screenSaverProxy.connect('ActiveChanged', Lang.bind(this, this._onScreenSaverActiveChanged));
|
this._screenSaverProxy.connectSignal('ActiveChanged', Lang.bind(this, function(proxy, senderName, [isActive]) {
|
||||||
this._screenSaverProxy.GetActiveRemote(Lang.bind(this,
|
this._onScreenSaverActiveChanged(isActive);
|
||||||
function(result, err) {
|
}));
|
||||||
if (!err)
|
this._screenSaverProxy.GetActiveRemote(Lang.bind(this, function(result, err) {
|
||||||
this._onScreenSaverActiveChanged(this._screenSaverProxy, result);
|
if (!err)
|
||||||
}));
|
this._onScreenSaverActiveChanged(result[0]);
|
||||||
|
}));
|
||||||
|
|
||||||
this._relayout();
|
this._relayout();
|
||||||
},
|
},
|
||||||
@ -619,7 +626,7 @@ Chrome.prototype = {
|
|||||||
// We can't use Params.parse here because we want to drop
|
// We can't use Params.parse here because we want to drop
|
||||||
// the extra values like ancestorData.actor
|
// the extra values like ancestorData.actor
|
||||||
for (let prop in defaultParams) {
|
for (let prop in defaultParams) {
|
||||||
if (!params[prop])
|
if (!params.hasOwnProperty(prop))
|
||||||
params[prop] = ancestorData[prop];
|
params[prop] = ancestorData[prop];
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -698,7 +705,7 @@ Chrome.prototype = {
|
|||||||
else if (this._inOverview)
|
else if (this._inOverview)
|
||||||
visible = true;
|
visible = true;
|
||||||
else if (!actorData.visibleInFullscreen &&
|
else if (!actorData.visibleInFullscreen &&
|
||||||
this._findMonitorForActor(actorData.actor).inFullscreen)
|
this.findMonitorForActor(actorData.actor).inFullscreen)
|
||||||
visible = false;
|
visible = false;
|
||||||
else
|
else
|
||||||
visible = true;
|
visible = true;
|
||||||
@ -727,7 +734,7 @@ Chrome.prototype = {
|
|||||||
this._queueUpdateRegions();
|
this._queueUpdateRegions();
|
||||||
},
|
},
|
||||||
|
|
||||||
_onScreenSaverActiveChanged: function(proxy, screenSaverActive) {
|
_onScreenSaverActiveChanged: function(screenSaverActive) {
|
||||||
this._screenSaverActive = screenSaverActive;
|
this._screenSaverActive = screenSaverActive;
|
||||||
this._updateVisibility();
|
this._updateVisibility();
|
||||||
this._queueUpdateRegions();
|
this._queueUpdateRegions();
|
||||||
@ -760,7 +767,7 @@ Chrome.prototype = {
|
|||||||
|
|
||||||
// This call guarantees that we return some monitor to simplify usage of it
|
// This call guarantees that we return some monitor to simplify usage of it
|
||||||
// In practice all tracked actors should be visible on some monitor anyway
|
// In practice all tracked actors should be visible on some monitor anyway
|
||||||
_findMonitorForActor: function(actor) {
|
findMonitorForActor: function(actor) {
|
||||||
let [x, y] = actor.get_transformed_position();
|
let [x, y] = actor.get_transformed_position();
|
||||||
let [w, h] = actor.get_transformed_size();
|
let [w, h] = actor.get_transformed_size();
|
||||||
let monitor = this._findMonitorForRect(x, y, w, h);
|
let monitor = this._findMonitorForRect(x, y, w, h);
|
||||||
@ -819,6 +826,18 @@ Chrome.prototype = {
|
|||||||
monitor.inFullscreen = true;
|
monitor.inFullscreen = true;
|
||||||
}
|
}
|
||||||
if (layer == Meta.StackLayer.OVERRIDE_REDIRECT) {
|
if (layer == Meta.StackLayer.OVERRIDE_REDIRECT) {
|
||||||
|
// Check whether the window is screen sized
|
||||||
|
let isScreenSized =
|
||||||
|
(window.x == 0 && window.y == 0 &&
|
||||||
|
window.width == global.screen_width &&
|
||||||
|
window.height == global.screen_height);
|
||||||
|
|
||||||
|
if (isScreenSized) {
|
||||||
|
for (let i = 0; i < this._monitors.length; i++)
|
||||||
|
this._monitors[i].inFullscreen = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Or whether it is monitor sized
|
||||||
let monitor = this._findMonitorForWindow(window);
|
let monitor = this._findMonitorForWindow(window);
|
||||||
if (monitor &&
|
if (monitor &&
|
||||||
window.x <= monitor.x &&
|
window.x <= monitor.x &&
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
/* -*- mode: js2; js2-basic-offset: 4; indent-tabs-mode: nil -*- */
|
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
|
||||||
|
|
||||||
const Lang = imports.lang;
|
const Lang = imports.lang;
|
||||||
const Meta = imports.gi.Meta;
|
const Meta = imports.gi.Meta;
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
/* -*- mode: js2; js2-basic-offset: 4; indent-tabs-mode: nil -*- */
|
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
|
||||||
|
|
||||||
const Lang = imports.lang;
|
const Lang = imports.lang;
|
||||||
const Signals = imports.signals;
|
const Signals = imports.signals;
|
||||||
|
@ -1,8 +1,7 @@
|
|||||||
/* -*- mode: js2; js2-basic-offset: 4; indent-tabs-mode: nil -*- */
|
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
|
||||||
|
|
||||||
const Clutter = imports.gi.Clutter;
|
const Clutter = imports.gi.Clutter;
|
||||||
const Cogl = imports.gi.Cogl;
|
const Cogl = imports.gi.Cogl;
|
||||||
const GConf = imports.gi.GConf;
|
|
||||||
const GLib = imports.gi.GLib;
|
const GLib = imports.gi.GLib;
|
||||||
const Gio = imports.gi.Gio;
|
const Gio = imports.gi.Gio;
|
||||||
const Gtk = imports.gi.Gtk;
|
const Gtk = imports.gi.Gtk;
|
||||||
@ -17,8 +16,10 @@ const Mainloop = imports.mainloop;
|
|||||||
const History = imports.misc.history;
|
const History = imports.misc.history;
|
||||||
const ExtensionSystem = imports.ui.extensionSystem;
|
const ExtensionSystem = imports.ui.extensionSystem;
|
||||||
const Link = imports.ui.link;
|
const Link = imports.ui.link;
|
||||||
|
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;
|
||||||
|
|
||||||
/* 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; ' +
|
||||||
@ -40,6 +41,86 @@ var commandHeader = 'const Clutter = imports.gi.Clutter; ' +
|
|||||||
'const r = Lang.bind(Main.lookingGlass, Main.lookingGlass.getResult); ';
|
'const r = Lang.bind(Main.lookingGlass, Main.lookingGlass.getResult); ';
|
||||||
|
|
||||||
const HISTORY_KEY = 'looking-glass-history';
|
const HISTORY_KEY = 'looking-glass-history';
|
||||||
|
// Time between tabs for them to count as a double-tab event
|
||||||
|
const AUTO_COMPLETE_DOUBLE_TAB_DELAY = 500;
|
||||||
|
const AUTO_COMPLETE_SHOW_COMPLETION_ANIMATION_DURATION = 0.2;
|
||||||
|
const AUTO_COMPLETE_GLOBAL_KEYWORDS = _getAutoCompleteGlobalKeywords();
|
||||||
|
|
||||||
|
function _getAutoCompleteGlobalKeywords() {
|
||||||
|
const keywords = ['true', 'false', 'null', 'new'];
|
||||||
|
// Don't add the private properties of window (i.e., ones starting with '_')
|
||||||
|
const windowProperties = Object.getOwnPropertyNames(window).filter(function(a){ return a.charAt(0) != '_' });
|
||||||
|
const headerProperties = JsParse.getDeclaredConstants(commandHeader);
|
||||||
|
|
||||||
|
return keywords.concat(windowProperties).concat(headerProperties);
|
||||||
|
}
|
||||||
|
|
||||||
|
function AutoComplete(entry) {
|
||||||
|
this._init(entry);
|
||||||
|
}
|
||||||
|
|
||||||
|
AutoComplete.prototype = {
|
||||||
|
_init: function(entry) {
|
||||||
|
this._entry = entry;
|
||||||
|
this._entry.connect('key-press-event', Lang.bind(this, this._entryKeyPressEvent));
|
||||||
|
this._lastTabTime = global.get_current_time();
|
||||||
|
},
|
||||||
|
|
||||||
|
_processCompletionRequest: function(event) {
|
||||||
|
if (event.completions.length == 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// Unique match = go ahead and complete; multiple matches + single tab = complete the common starting string;
|
||||||
|
// multiple matches + double tab = emit a suggest event with all possible options
|
||||||
|
if (event.completions.length == 1) {
|
||||||
|
this.additionalCompletionText(event.completions[0], event.attrHead);
|
||||||
|
this.emit('completion', { completion: event.completions[0], type: 'whole-word' });
|
||||||
|
} else if (event.completions.length > 1 && event.tabType === 'single') {
|
||||||
|
let commonPrefix = JsParse.getCommonPrefix(event.completions);
|
||||||
|
|
||||||
|
if (commonPrefix.length > 0) {
|
||||||
|
this.additionalCompletionText(commonPrefix, event.attrHead);
|
||||||
|
this.emit('completion', { completion: commonPrefix, type: 'prefix' });
|
||||||
|
this.emit('suggest', { completions: event.completions});
|
||||||
|
}
|
||||||
|
} else if (event.completions.length > 1 && event.tabType === 'double') {
|
||||||
|
this.emit('suggest', { completions: event.completions});
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
_entryKeyPressEvent: function(actor, event) {
|
||||||
|
let cursorPos = this._entry.clutter_text.get_cursor_position();
|
||||||
|
let text = this._entry.get_text();
|
||||||
|
if (cursorPos != -1) {
|
||||||
|
text = text.slice(0, cursorPos);
|
||||||
|
}
|
||||||
|
if (event.get_key_symbol() == Clutter.Tab) {
|
||||||
|
let [completions, attrHead] = JsParse.getCompletions(text, commandHeader, AUTO_COMPLETE_GLOBAL_KEYWORDS);
|
||||||
|
let currTime = global.get_current_time();
|
||||||
|
if ((currTime - this._lastTabTime) < AUTO_COMPLETE_DOUBLE_TAB_DELAY) {
|
||||||
|
this._processCompletionRequest({ tabType: 'double',
|
||||||
|
completions: completions,
|
||||||
|
attrHead: attrHead });
|
||||||
|
} else {
|
||||||
|
this._processCompletionRequest({ tabType: 'single',
|
||||||
|
completions: completions,
|
||||||
|
attrHead: attrHead });
|
||||||
|
}
|
||||||
|
this._lastTabTime = currTime;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
// Insert characters of text not already included in head at cursor position. i.e., if text="abc" and head="a",
|
||||||
|
// the string "bc" will be appended to this._entry
|
||||||
|
additionalCompletionText: function(text, head) {
|
||||||
|
let additionalCompletionText = text.slice(head.length);
|
||||||
|
let cursorPos = this._entry.clutter_text.get_cursor_position();
|
||||||
|
|
||||||
|
this._entry.clutter_text.insert_text(additionalCompletionText, cursorPos);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
Signals.addSignalMethods(AutoComplete.prototype);
|
||||||
|
|
||||||
|
|
||||||
function Notebook() {
|
function Notebook() {
|
||||||
this._init();
|
this._init();
|
||||||
@ -150,6 +231,24 @@ Notebook.prototype = {
|
|||||||
return;
|
return;
|
||||||
let vAdjust = tabData.scrollView.vscroll.adjustment;
|
let vAdjust = tabData.scrollView.vscroll.adjustment;
|
||||||
vAdjust.value = vAdjust.upper - vAdjust.page_size;
|
vAdjust.value = vAdjust.upper - vAdjust.page_size;
|
||||||
|
},
|
||||||
|
|
||||||
|
nextTab: function() {
|
||||||
|
let nextIndex = this._selectedIndex;
|
||||||
|
if (nextIndex < this._tabs.length - 1) {
|
||||||
|
++nextIndex;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.selectIndex(nextIndex);
|
||||||
|
},
|
||||||
|
|
||||||
|
prevTab: function() {
|
||||||
|
let prevIndex = this._selectedIndex;
|
||||||
|
if (prevIndex > 0) {
|
||||||
|
--prevIndex;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.selectIndex(prevIndex);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
Signals.addSignalMethods(Notebook.prototype);
|
Signals.addSignalMethods(Notebook.prototype);
|
||||||
@ -157,9 +256,9 @@ Signals.addSignalMethods(Notebook.prototype);
|
|||||||
function objectToString(o) {
|
function objectToString(o) {
|
||||||
if (typeof(o) == typeof(objectToString)) {
|
if (typeof(o) == typeof(objectToString)) {
|
||||||
// special case this since the default is way, way too verbose
|
// special case this since the default is way, way too verbose
|
||||||
return "<js function>";
|
return '<js function>';
|
||||||
} else {
|
} else {
|
||||||
return "" + o;
|
return '' + o;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -322,7 +421,7 @@ ObjInspector.prototype = {
|
|||||||
link = new St.Label({ text: '<error>' });
|
link = new St.Label({ text: '<error>' });
|
||||||
}
|
}
|
||||||
let hbox = new St.BoxLayout();
|
let hbox = new St.BoxLayout();
|
||||||
let propText = propName + ": " + valueStr;
|
let propText = propName + ': ' + valueStr;
|
||||||
hbox.add(new St.Label({ text: propName + ': ' }));
|
hbox.add(new St.Label({ text: propName + ': ' }));
|
||||||
hbox.add(link);
|
hbox.add(link);
|
||||||
this._container.add_actor(hbox);
|
this._container.add_actor(hbox);
|
||||||
@ -343,7 +442,7 @@ ObjInspector.prototype = {
|
|||||||
this.actor.move_anchor_point(Math.floor(sourceX + sourceWidth / 2),
|
this.actor.move_anchor_point(Math.floor(sourceX + sourceWidth / 2),
|
||||||
Math.floor(sourceY + sourceHeight / 2));
|
Math.floor(sourceY + sourceHeight / 2));
|
||||||
Tweener.addTween(this.actor, { scale_x: 1, scale_y: 1,
|
Tweener.addTween(this.actor, { scale_x: 1, scale_y: 1,
|
||||||
transition: "easeOutQuad",
|
transition: 'easeOutQuad',
|
||||||
time: 0.2 });
|
time: 0.2 });
|
||||||
} else {
|
} else {
|
||||||
this.actor.set_scale(1, 1);
|
this.actor.set_scale(1, 1);
|
||||||
@ -685,11 +784,40 @@ Extensions.prototype = {
|
|||||||
Main.lookingGlass.close();
|
Main.lookingGlass.close();
|
||||||
},
|
},
|
||||||
|
|
||||||
|
_onViewErrors: function (actor) {
|
||||||
|
let meta = actor._extensionMeta;
|
||||||
|
let shouldShow = !actor._isShowing;
|
||||||
|
|
||||||
|
if (shouldShow) {
|
||||||
|
let errors = ExtensionSystem.errors[meta.uuid];
|
||||||
|
let errorDisplay = new St.BoxLayout({ vertical: true });
|
||||||
|
if (errors && errors.length) {
|
||||||
|
for (let i = 0; i < errors.length; i ++)
|
||||||
|
errorDisplay.add(new St.Label({ text: errors[i] }));
|
||||||
|
} else {
|
||||||
|
/* Translators: argument is an extension UUID. */
|
||||||
|
let message = _("%s has not emitted any errors.").format(meta.uuid);
|
||||||
|
errorDisplay.add(new St.Label({ text: message }));
|
||||||
|
}
|
||||||
|
|
||||||
|
actor._errorDisplay = errorDisplay;
|
||||||
|
actor._parentBox.add(errorDisplay);
|
||||||
|
actor.label = _("Hide Errors");
|
||||||
|
} else {
|
||||||
|
actor._errorDisplay.destroy();
|
||||||
|
actor._errorDisplay = null;
|
||||||
|
actor.label = _("Show Errors");
|
||||||
|
}
|
||||||
|
|
||||||
|
actor._isShowing = shouldShow;
|
||||||
|
},
|
||||||
|
|
||||||
_stateToString: function(extensionState) {
|
_stateToString: function(extensionState) {
|
||||||
switch (extensionState) {
|
switch (extensionState) {
|
||||||
case ExtensionSystem.ExtensionState.ENABLED:
|
case ExtensionSystem.ExtensionState.ENABLED:
|
||||||
return _("Enabled");
|
return _("Enabled");
|
||||||
case ExtensionSystem.ExtensionState.DISABLED:
|
case ExtensionSystem.ExtensionState.DISABLED:
|
||||||
|
case ExtensionSystem.ExtensionState.INITIALIZED:
|
||||||
return _("Disabled");
|
return _("Disabled");
|
||||||
case ExtensionSystem.ExtensionState.ERROR:
|
case ExtensionSystem.ExtensionState.ERROR:
|
||||||
return _("Error");
|
return _("Error");
|
||||||
@ -710,29 +838,32 @@ Extensions.prototype = {
|
|||||||
text: meta.description || 'No description' });
|
text: meta.description || 'No description' });
|
||||||
box.add(description, { expand: true });
|
box.add(description, { expand: true });
|
||||||
|
|
||||||
let metaBox = new St.BoxLayout();
|
let metaBox = new St.BoxLayout({ style_class: 'lg-extension-meta' });
|
||||||
box.add(metaBox);
|
box.add(metaBox);
|
||||||
let stateString = this._stateToString(meta.state);
|
let stateString = this._stateToString(meta.state);
|
||||||
let state = new St.Label({ style_class: 'lg-extension-state',
|
let state = new St.Label({ style_class: 'lg-extension-state',
|
||||||
text: this._stateToString(meta.state) });
|
text: this._stateToString(meta.state) });
|
||||||
|
metaBox.add(state);
|
||||||
let actionsContainer = new St.Bin({ x_align: St.Align.END });
|
|
||||||
metaBox.add(actionsContainer);
|
|
||||||
let actionsBox = new St.BoxLayout({ style_class: 'lg-extension-actions' });
|
|
||||||
actionsContainer.set_child(actionsBox);
|
|
||||||
|
|
||||||
let viewsource = new Link.Link({ label: _("View Source") });
|
let viewsource = new Link.Link({ label: _("View Source") });
|
||||||
viewsource.actor._extensionMeta = meta;
|
viewsource.actor._extensionMeta = meta;
|
||||||
viewsource.actor.connect('clicked', Lang.bind(this, this._onViewSource));
|
viewsource.actor.connect('clicked', Lang.bind(this, this._onViewSource));
|
||||||
actionsBox.add(viewsource.actor);
|
metaBox.add(viewsource.actor);
|
||||||
|
|
||||||
if (meta.url) {
|
if (meta.url) {
|
||||||
let webpage = new Link.Link({ label: _("Web Page") });
|
let webpage = new Link.Link({ label: _("Web Page") });
|
||||||
webpage.actor._extensionMeta = meta;
|
webpage.actor._extensionMeta = meta;
|
||||||
webpage.actor.connect('clicked', Lang.bind(this, this._onWebPage));
|
webpage.actor.connect('clicked', Lang.bind(this, this._onWebPage));
|
||||||
actionsBox.add(webpage.actor);
|
metaBox.add(webpage.actor);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let viewerrors = new Link.Link({ label: _("Show Errors") });
|
||||||
|
viewerrors.actor._extensionMeta = meta;
|
||||||
|
viewerrors.actor._parentBox = box;
|
||||||
|
viewerrors.actor._isShowing = false;
|
||||||
|
viewerrors.actor.connect('clicked', Lang.bind(this, this._onViewErrors));
|
||||||
|
metaBox.add(viewerrors.actor);
|
||||||
|
|
||||||
return box;
|
return box;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -813,14 +944,15 @@ LookingGlass.prototype = {
|
|||||||
this._resultsArea = new St.BoxLayout({ name: 'ResultsArea', vertical: true });
|
this._resultsArea = new St.BoxLayout({ name: 'ResultsArea', vertical: true });
|
||||||
this._evalBox.add(this._resultsArea, { expand: true });
|
this._evalBox.add(this._resultsArea, { expand: true });
|
||||||
|
|
||||||
let entryArea = new St.BoxLayout({ name: 'EntryArea' });
|
this._entryArea = new St.BoxLayout({ name: 'EntryArea' });
|
||||||
this._evalBox.add_actor(entryArea);
|
this._evalBox.add_actor(this._entryArea);
|
||||||
|
|
||||||
let label = new St.Label({ text: 'js>>> ' });
|
let label = new St.Label({ text: 'js>>> ' });
|
||||||
entryArea.add(label);
|
this._entryArea.add(label);
|
||||||
|
|
||||||
this._entry = new St.Entry({ can_focus: true });
|
this._entry = new St.Entry({ can_focus: true });
|
||||||
entryArea.add(this._entry, { expand: true });
|
ShellEntry.addContextMenu(this._entry);
|
||||||
|
this._entryArea.add(this._entry, { expand: true });
|
||||||
|
|
||||||
this._windowList = new WindowList();
|
this._windowList = new WindowList();
|
||||||
this._windowList.connect('selected', Lang.bind(this, function(list, window) {
|
this._windowList.connect('selected', Lang.bind(this, function(list, window) {
|
||||||
@ -839,6 +971,9 @@ LookingGlass.prototype = {
|
|||||||
notebook.appendPage('Extensions', this._extensions.actor);
|
notebook.appendPage('Extensions', this._extensions.actor);
|
||||||
|
|
||||||
this._entry.clutter_text.connect('activate', Lang.bind(this, function (o, e) {
|
this._entry.clutter_text.connect('activate', Lang.bind(this, function (o, e) {
|
||||||
|
// Hide any completions we are currently showing
|
||||||
|
this._hideCompletions();
|
||||||
|
|
||||||
let text = o.get_text();
|
let text = o.get_text();
|
||||||
// Ensure we don't get newlines in the command; the history file is
|
// Ensure we don't get newlines in the command; the history file is
|
||||||
// newline-separated.
|
// newline-separated.
|
||||||
@ -854,6 +989,17 @@ LookingGlass.prototype = {
|
|||||||
this._history = new History.HistoryManager({ gsettingsKey: HISTORY_KEY,
|
this._history = new History.HistoryManager({ gsettingsKey: HISTORY_KEY,
|
||||||
entry: this._entry.clutter_text });
|
entry: this._entry.clutter_text });
|
||||||
|
|
||||||
|
this._autoComplete = new AutoComplete(this._entry);
|
||||||
|
this._autoComplete.connect('suggest', Lang.bind(this, function(a,e) {
|
||||||
|
this._showCompletions(e.completions);
|
||||||
|
}));
|
||||||
|
// If a completion is completed unambiguously, the currently-displayed completion
|
||||||
|
// suggestions become irrelevant.
|
||||||
|
this._autoComplete.connect('completion', Lang.bind(this, function(a,e) {
|
||||||
|
if (e.type == 'whole-word')
|
||||||
|
this._hideCompletions();
|
||||||
|
}));
|
||||||
|
|
||||||
this._resize();
|
this._resize();
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -898,6 +1044,59 @@ LookingGlass.prototype = {
|
|||||||
this._notebook.scrollToBottom(0);
|
this._notebook.scrollToBottom(0);
|
||||||
},
|
},
|
||||||
|
|
||||||
|
_showCompletions: function(completions) {
|
||||||
|
if (!this._completionActor) {
|
||||||
|
let actor = new St.BoxLayout({ vertical: true });
|
||||||
|
|
||||||
|
this._completionText = new St.Label({ name: 'LookingGlassAutoCompletionText', style_class: 'lg-completions-text' });
|
||||||
|
this._completionText.clutter_text.ellipsize = Pango.EllipsizeMode.NONE;
|
||||||
|
this._completionText.clutter_text.line_wrap = true;
|
||||||
|
actor.add(this._completionText);
|
||||||
|
|
||||||
|
let line = new Clutter.Rectangle();
|
||||||
|
let padBin = new St.Bin({ x_fill: true, y_fill: true });
|
||||||
|
padBin.add_actor(line);
|
||||||
|
actor.add(padBin);
|
||||||
|
|
||||||
|
this._completionActor = actor;
|
||||||
|
this._evalBox.insert_before(this._completionActor, this._entryArea);
|
||||||
|
}
|
||||||
|
|
||||||
|
this._completionText.set_text(completions.join(', '));
|
||||||
|
|
||||||
|
// Setting the height to -1 allows us to get its actual preferred height rather than
|
||||||
|
// whatever was last given in set_height by Tweener.
|
||||||
|
this._completionActor.set_height(-1);
|
||||||
|
let [minHeight, naturalHeight] = this._completionText.get_preferred_height(this._resultsArea.get_width());
|
||||||
|
|
||||||
|
// Don't reanimate if we are already visible
|
||||||
|
if (this._completionActor.visible) {
|
||||||
|
this._completionActor.height = naturalHeight;
|
||||||
|
} else {
|
||||||
|
this._completionActor.show();
|
||||||
|
Tweener.removeTweens(this._completionActor);
|
||||||
|
Tweener.addTween(this._completionActor, { time: AUTO_COMPLETE_SHOW_COMPLETION_ANIMATION_DURATION / St.get_slow_down_factor(),
|
||||||
|
transition: 'easeOutQuad',
|
||||||
|
height: naturalHeight,
|
||||||
|
opacity: 255
|
||||||
|
});
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
_hideCompletions: function() {
|
||||||
|
if (this._completionActor) {
|
||||||
|
Tweener.removeTweens(this._completionActor);
|
||||||
|
Tweener.addTween(this._completionActor, { time: AUTO_COMPLETE_SHOW_COMPLETION_ANIMATION_DURATION / St.get_slow_down_factor(),
|
||||||
|
transition: 'easeOutQuad',
|
||||||
|
height: 0,
|
||||||
|
opacity: 0,
|
||||||
|
onComplete: Lang.bind(this, function () {
|
||||||
|
this._completionActor.hide();
|
||||||
|
})
|
||||||
|
});
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
_evaluate : function(command) {
|
_evaluate : function(command) {
|
||||||
this._history.addItem(command);
|
this._history.addItem(command);
|
||||||
|
|
||||||
@ -962,6 +1161,7 @@ LookingGlass.prototype = {
|
|||||||
// Handle key events which are relevant for all tabs of the LookingGlass
|
// Handle key events which are relevant for all tabs of the LookingGlass
|
||||||
_globalKeyPressEvent : function(actor, event) {
|
_globalKeyPressEvent : function(actor, event) {
|
||||||
let symbol = event.get_key_symbol();
|
let symbol = event.get_key_symbol();
|
||||||
|
let modifierState = Shell.get_event_state(event);
|
||||||
if (symbol == Clutter.Escape) {
|
if (symbol == Clutter.Escape) {
|
||||||
if (this._objInspector.actor.visible) {
|
if (this._objInspector.actor.visible) {
|
||||||
this._objInspector.close();
|
this._objInspector.close();
|
||||||
@ -970,6 +1170,14 @@ LookingGlass.prototype = {
|
|||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
// Ctrl+PgUp and Ctrl+PgDown switches tabs in the notebook view
|
||||||
|
if (modifierState & Clutter.ModifierType.CONTROL_MASK) {
|
||||||
|
if (symbol == Clutter.KEY_Page_Up) {
|
||||||
|
this._notebook.prevTab();
|
||||||
|
} else if (symbol == Clutter.KEY_Page_Down) {
|
||||||
|
this._notebook.nextTab();
|
||||||
|
}
|
||||||
|
}
|
||||||
return false;
|
return false;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
/* -*- mode: js2; js2-basic-offset: 4; indent-tabs-mode: nil -*- */
|
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
|
||||||
|
|
||||||
const Clutter = imports.gi.Clutter;
|
const Clutter = imports.gi.Clutter;
|
||||||
|
const GDesktopEnums = imports.gi.GDesktopEnums;
|
||||||
const Gio = imports.gi.Gio;
|
const Gio = imports.gi.Gio;
|
||||||
const Shell = imports.gi.Shell;
|
const Shell = imports.gi.Shell;
|
||||||
const St = imports.gi.St;
|
const St = imports.gi.St;
|
||||||
@ -12,22 +13,6 @@ const Main = imports.ui.main;
|
|||||||
const MagnifierDBus = imports.ui.magnifierDBus;
|
const MagnifierDBus = imports.ui.magnifierDBus;
|
||||||
const Params = imports.misc.params;
|
const Params = imports.misc.params;
|
||||||
|
|
||||||
// Keep enums in sync with GSettings schemas
|
|
||||||
const MouseTrackingMode = {
|
|
||||||
NONE: 0,
|
|
||||||
CENTERED: 1,
|
|
||||||
PROPORTIONAL: 2,
|
|
||||||
PUSH: 3
|
|
||||||
};
|
|
||||||
|
|
||||||
const ScreenPosition = {
|
|
||||||
NONE: 0,
|
|
||||||
FULL_SCREEN: 1,
|
|
||||||
TOP_HALF: 2,
|
|
||||||
BOTTOM_HALF: 3,
|
|
||||||
LEFT_HALF: 4,
|
|
||||||
RIGHT_HALF: 5
|
|
||||||
};
|
|
||||||
|
|
||||||
const MOUSE_POLL_FREQUENCY = 50;
|
const MOUSE_POLL_FREQUENCY = 50;
|
||||||
const CROSSHAIRS_CLIP_SIZE = [100, 100];
|
const CROSSHAIRS_CLIP_SIZE = [100, 100];
|
||||||
@ -520,7 +505,7 @@ Magnifier.prototype = {
|
|||||||
if (this._zoomRegions.length) {
|
if (this._zoomRegions.length) {
|
||||||
let position = this._settings.get_enum(SCREEN_POSITION_KEY);
|
let position = this._settings.get_enum(SCREEN_POSITION_KEY);
|
||||||
this._zoomRegions[0].setScreenPosition(position);
|
this._zoomRegions[0].setScreenPosition(position);
|
||||||
if (position != ScreenPosition.FULL_SCREEN)
|
if (position != GDesktopEnums.MagnifierScreenPosition.FULL_SCREEN)
|
||||||
this._updateLensMode();
|
this._updateLensMode();
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -569,10 +554,10 @@ ZoomRegion.prototype = {
|
|||||||
_init: function(magnifier, mouseSourceActor) {
|
_init: function(magnifier, mouseSourceActor) {
|
||||||
this._magnifier = magnifier;
|
this._magnifier = magnifier;
|
||||||
|
|
||||||
this._mouseTrackingMode = MouseTrackingMode.NONE;
|
this._mouseTrackingMode = GDesktopEnums.MagnifierMouseTrackingMode.NONE;
|
||||||
this._clampScrollingAtEdges = false;
|
this._clampScrollingAtEdges = false;
|
||||||
this._lensMode = false;
|
this._lensMode = false;
|
||||||
this._screenPosition = ScreenPosition.FULL_SCREEN;
|
this._screenPosition = GDesktopEnums.MagnifierScreenPosition.FULL_SCREEN;
|
||||||
|
|
||||||
this._magView = null;
|
this._magView = null;
|
||||||
this._uiGroupClone = null;
|
this._uiGroupClone = null;
|
||||||
@ -647,7 +632,8 @@ ZoomRegion.prototype = {
|
|||||||
* @mode: One of the enum MouseTrackingMode values.
|
* @mode: One of the enum MouseTrackingMode values.
|
||||||
*/
|
*/
|
||||||
setMouseTrackingMode: function(mode) {
|
setMouseTrackingMode: function(mode) {
|
||||||
if (mode >= MouseTrackingMode.NONE && mode <= MouseTrackingMode.PUSH)
|
if (mode >= GDesktopEnums.MagnifierMouseTrackingMode.NONE &&
|
||||||
|
mode <= GDesktopEnums.MagnifierMouseTrackingMode.PUSH)
|
||||||
this._mouseTrackingMode = mode;
|
this._mouseTrackingMode = mode;
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -668,7 +654,7 @@ ZoomRegion.prototype = {
|
|||||||
*/
|
*/
|
||||||
setViewPort: function(viewPort) {
|
setViewPort: function(viewPort) {
|
||||||
this._setViewPort(viewPort);
|
this._setViewPort(viewPort);
|
||||||
this._screenPosition = ScreenPosition.NONE;
|
this._screenPosition = GDesktopEnums.MagnifierScreenPosition.NONE;
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -750,7 +736,7 @@ ZoomRegion.prototype = {
|
|||||||
viewPort.width = global.screen_width;
|
viewPort.width = global.screen_width;
|
||||||
viewPort.height = global.screen_height/2;
|
viewPort.height = global.screen_height/2;
|
||||||
this._setViewPort(viewPort);
|
this._setViewPort(viewPort);
|
||||||
this._screenPosition = ScreenPosition.TOP_HALF;
|
this._screenPosition = GDesktopEnums.MagnifierScreenPosition.TOP_HALF;
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -764,7 +750,7 @@ ZoomRegion.prototype = {
|
|||||||
viewPort.width = global.screen_width;
|
viewPort.width = global.screen_width;
|
||||||
viewPort.height = global.screen_height/2;
|
viewPort.height = global.screen_height/2;
|
||||||
this._setViewPort(viewPort);
|
this._setViewPort(viewPort);
|
||||||
this._screenPosition = ScreenPosition.BOTTOM_HALF;
|
this._screenPosition = GDesktopEnums.MagnifierScreenPosition.BOTTOM_HALF;
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -778,7 +764,7 @@ ZoomRegion.prototype = {
|
|||||||
viewPort.width = global.screen_width/2;
|
viewPort.width = global.screen_width/2;
|
||||||
viewPort.height = global.screen_height;
|
viewPort.height = global.screen_height;
|
||||||
this._setViewPort(viewPort);
|
this._setViewPort(viewPort);
|
||||||
this._screenPosition = ScreenPosition.LEFT_HALF;
|
this._screenPosition = GDesktopEnums.MagnifierScreenPosition.LEFT_HALF;
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -792,7 +778,7 @@ ZoomRegion.prototype = {
|
|||||||
viewPort.width = global.screen_width/2;
|
viewPort.width = global.screen_width/2;
|
||||||
viewPort.height = global.screen_height;
|
viewPort.height = global.screen_height;
|
||||||
this._setViewPort(viewPort);
|
this._setViewPort(viewPort);
|
||||||
this._screenPosition = ScreenPosition.RIGHT_HALF;
|
this._screenPosition = GDesktopEnums.MagnifierScreenPosition.RIGHT_HALF;
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -808,7 +794,7 @@ ZoomRegion.prototype = {
|
|||||||
viewPort.height = global.screen_height;
|
viewPort.height = global.screen_height;
|
||||||
this.setViewPort(viewPort);
|
this.setViewPort(viewPort);
|
||||||
|
|
||||||
this._screenPosition = ScreenPosition.FULL_SCREEN;
|
this._screenPosition = GDesktopEnums.MagnifierScreenPosition.FULL_SCREEN;
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -821,19 +807,19 @@ ZoomRegion.prototype = {
|
|||||||
*/
|
*/
|
||||||
setScreenPosition: function(inPosition) {
|
setScreenPosition: function(inPosition) {
|
||||||
switch (inPosition) {
|
switch (inPosition) {
|
||||||
case ScreenPosition.FULL_SCREEN:
|
case GDesktopEnums.MagnifierScreenPosition.FULL_SCREEN:
|
||||||
this.setFullScreenMode();
|
this.setFullScreenMode();
|
||||||
break;
|
break;
|
||||||
case ScreenPosition.TOP_HALF:
|
case GDesktopEnums.MagnifierScreenPosition.TOP_HALF:
|
||||||
this.setTopHalf();
|
this.setTopHalf();
|
||||||
break;
|
break;
|
||||||
case ScreenPosition.BOTTOM_HALF:
|
case GDesktopEnums.MagnifierScreenPosition.BOTTOM_HALF:
|
||||||
this.setBottomHalf();
|
this.setBottomHalf();
|
||||||
break;
|
break;
|
||||||
case ScreenPosition.LEFT_HALF:
|
case GDesktopEnums.MagnifierScreenPosition.LEFT_HALF:
|
||||||
this.setLeftHalf();
|
this.setLeftHalf();
|
||||||
break;
|
break;
|
||||||
case ScreenPosition.RIGHT_HALF:
|
case GDesktopEnums.MagnifierScreenPosition.RIGHT_HALF:
|
||||||
this.setRightHalf();
|
this.setRightHalf();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -856,7 +842,7 @@ ZoomRegion.prototype = {
|
|||||||
*/
|
*/
|
||||||
scrollToMousePos: function() {
|
scrollToMousePos: function() {
|
||||||
this._followingCursor = true;
|
this._followingCursor = true;
|
||||||
if (this._mouseTrackingMode != MouseTrackingMode.NONE)
|
if (this._mouseTrackingMode != GDesktopEnums.MagnifierMouseTrackingMode.NONE)
|
||||||
this._changeROI({ redoCursorTracking: true });
|
this._changeROI({ redoCursorTracking: true });
|
||||||
else
|
else
|
||||||
this._updateMousePosition();
|
this._updateMousePosition();
|
||||||
@ -991,7 +977,7 @@ ZoomRegion.prototype = {
|
|||||||
this._yMagFactor = params.yMagFactor;
|
this._yMagFactor = params.yMagFactor;
|
||||||
|
|
||||||
if (params.redoCursorTracking &&
|
if (params.redoCursorTracking &&
|
||||||
this._mouseTrackingMode != MouseTrackingMode.NONE) {
|
this._mouseTrackingMode != GDesktopEnums.MagnifierMouseTrackingMode.NONE) {
|
||||||
// This depends on this.xMagFactor/yMagFactor already being updated
|
// This depends on this.xMagFactor/yMagFactor already being updated
|
||||||
[params.xCenter, params.yCenter] = this._centerFromMousePosition();
|
[params.xCenter, params.yCenter] = this._centerFromMousePosition();
|
||||||
}
|
}
|
||||||
@ -1041,7 +1027,7 @@ ZoomRegion.prototype = {
|
|||||||
_isFullScreen: function() {
|
_isFullScreen: function() {
|
||||||
// Does the magnified view occupy the whole screen? Note that this
|
// Does the magnified view occupy the whole screen? Note that this
|
||||||
// doesn't necessarily imply
|
// doesn't necessarily imply
|
||||||
// this._screenPosition = ScreenPosition.FULL_SCREEN;
|
// this._screenPosition = GDesktopEnums.MagnifierScreenPosition.FULL_SCREEN;
|
||||||
|
|
||||||
if (this._viewPortX != 0 || this._viewPortY != 0)
|
if (this._viewPortX != 0 || this._viewPortY != 0)
|
||||||
return false;
|
return false;
|
||||||
@ -1058,13 +1044,13 @@ ZoomRegion.prototype = {
|
|||||||
let xMouse = this._magnifier.xMouse;
|
let xMouse = this._magnifier.xMouse;
|
||||||
let yMouse = this._magnifier.yMouse;
|
let yMouse = this._magnifier.yMouse;
|
||||||
|
|
||||||
if (this._mouseTrackingMode == MouseTrackingMode.PROPORTIONAL) {
|
if (this._mouseTrackingMode == GDesktopEnums.MagnifierMouseTrackingMode.PROPORTIONAL) {
|
||||||
return this._centerFromMouseProportional(xMouse, yMouse);
|
return this._centerFromMouseProportional(xMouse, yMouse);
|
||||||
}
|
}
|
||||||
else if (this._mouseTrackingMode == MouseTrackingMode.PUSH) {
|
else if (this._mouseTrackingMode == GDesktopEnums.MagnifierMouseTrackingMode.PUSH) {
|
||||||
return this._centerFromMousePush(xMouse, yMouse);
|
return this._centerFromMousePush(xMouse, yMouse);
|
||||||
}
|
}
|
||||||
else if (this._mouseTrackingMode == MouseTrackingMode.CENTERED) {
|
else if (this._mouseTrackingMode == GDesktopEnums.MagnifierMouseTrackingMode.CENTERED) {
|
||||||
return this._centerFromMouseCentered(xMouse, yMouse);
|
return this._centerFromMouseCentered(xMouse, yMouse);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
/* -*- mode: js2; js2-basic-offset: 4; indent-tabs-mode: nil -*- */
|
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
|
||||||
|
|
||||||
const DBus = imports.dbus;
|
const Gio = imports.gi.Gio;
|
||||||
const Main = imports.ui.main;
|
const Main = imports.ui.main;
|
||||||
|
|
||||||
const MAG_SERVICE_NAME = 'org.gnome.Magnifier';
|
const MAG_SERVICE_NAME = 'org.gnome.Magnifier';
|
||||||
@ -10,47 +10,85 @@ const ZOOM_SERVICE_PATH = '/org/gnome/Magnifier/ZoomRegion';
|
|||||||
|
|
||||||
// Subset of gnome-mag's Magnifier dbus interface -- to be expanded. See:
|
// Subset of gnome-mag's Magnifier dbus interface -- to be expanded. See:
|
||||||
// http://git.gnome.org/browse/gnome-mag/tree/xml/...Magnifier.xml
|
// http://git.gnome.org/browse/gnome-mag/tree/xml/...Magnifier.xml
|
||||||
const MagnifierIface = {
|
const MagnifierIface = <interface name={MAG_SERVICE_NAME}>
|
||||||
name: MAG_SERVICE_NAME,
|
<method name="setActive">
|
||||||
methods: [
|
<arg type="b" direction="in" />
|
||||||
{ name: 'setActive', inSignature: 'b', outSignature: '' },
|
</method>
|
||||||
{ name: 'isActive', inSignature: '', outSignature: 'b' },
|
<method name="isActive">
|
||||||
{ name: 'showCursor', inSignature: '', outSignature: '' },
|
<arg type="b" direction="out" />
|
||||||
{ name: 'hideCursor', inSignature: '', outSignature: '' },
|
</method>
|
||||||
{ name: 'createZoomRegion', inSignature: 'ddaiai', outSignature: 'o' },
|
<method name="showCursor" />
|
||||||
{ name: 'addZoomRegion', inSignature: 'o', outSignature: 'b' },
|
<method name="hideCursor" />
|
||||||
{ name: 'getZoomRegions', inSignature: '', outSignature: 'ao' },
|
<method name="createZoomRegion">
|
||||||
{ name: 'clearAllZoomRegions', inSignature: '', outSignature: '' },
|
<arg type="d" direction="in" />
|
||||||
{ name: 'fullScreenCapable', inSignature: '', outSignature: 'b' },
|
<arg type="d" direction="in" />
|
||||||
|
<arg type="ai" direction="in" />
|
||||||
{ name: 'setCrosswireSize', inSignature: 'i', outSignature: '' },
|
<arg type="ai" direction="in" />
|
||||||
{ name: 'getCrosswireSize', inSignature: '', outSignature: 'i' },
|
<arg type="o" direction="out" />
|
||||||
{ name: 'setCrosswireLength', inSignature: 'i', outSignature: '' },
|
</method>
|
||||||
{ name: 'getCrosswireLength', inSignature: '', outSignature: 'i' },
|
<method name="addZoomRegion">
|
||||||
{ name: 'setCrosswireClip', inSignature: 'b', outSignature: '' },
|
<arg type="o" direction="in" />
|
||||||
{ name: 'getCrosswireClip', inSignature: '', outSignature: 'b' },
|
<arg type="b" direction="out" />
|
||||||
{ name: 'setCrosswireColor', inSignature: 'u', outSignature: '' },
|
</method>
|
||||||
{ name: 'getCrosswireColor', inSignature: '', outSignature: 'u' }
|
<method name="getZoomRegions">
|
||||||
],
|
<arg type="ao" direction="out" />
|
||||||
signals: [],
|
</method>
|
||||||
properties: []
|
<method name="clearAllZoomRegions" />
|
||||||
};
|
<method name="fullScreenCapable">
|
||||||
|
<arg type="b" direction="out" />
|
||||||
|
</method>
|
||||||
|
<method name="setCrosswireSize">
|
||||||
|
<arg type="i" direction="in" />
|
||||||
|
</method>
|
||||||
|
<method name="getCrosswireSize">
|
||||||
|
<arg type="i" direction="out" />
|
||||||
|
</method>
|
||||||
|
<method name="setCrosswireLength">
|
||||||
|
<arg type="i" direction="in" />
|
||||||
|
</method>
|
||||||
|
<method name="getCrosswireLength">
|
||||||
|
<arg type="i" direction="out" />
|
||||||
|
</method>
|
||||||
|
<method name="setCrosswireClip">
|
||||||
|
<arg type="b" direction="in" />
|
||||||
|
</method>
|
||||||
|
<method name="getCrosswireClip">
|
||||||
|
<arg type="b" direction="out" />
|
||||||
|
</method>
|
||||||
|
<method name="setCrosswireColor">
|
||||||
|
<arg type="u" direction="in" />
|
||||||
|
</method>
|
||||||
|
<method name="getCrosswireColor">
|
||||||
|
<arg type="u" direction="out" />
|
||||||
|
</method>
|
||||||
|
</interface>;
|
||||||
|
|
||||||
// Subset of gnome-mag's ZoomRegion dbus interface -- to be expanded. See:
|
// Subset of gnome-mag's ZoomRegion dbus interface -- to be expanded. See:
|
||||||
// http://git.gnome.org/browse/gnome-mag/tree/xml/...ZoomRegion.xml
|
// http://git.gnome.org/browse/gnome-mag/tree/xml/...ZoomRegion.xml
|
||||||
const ZoomRegionIface = {
|
const ZoomRegionIface = <interface name={ZOOM_SERVICE_NAME}>
|
||||||
name: ZOOM_SERVICE_NAME,
|
<method name="setMagFactor">
|
||||||
methods: [
|
<arg type="d" direction="in" />
|
||||||
{ name: 'setMagFactor', inSignature: 'dd', outSignature: ''},
|
<arg type="d" direction="in" />
|
||||||
{ name: 'getMagFactor', inSignature: '', outSignature: 'dd' },
|
</method>
|
||||||
{ name: 'setRoi', inSignature: 'ai', outSignature: '' },
|
<method name="getMagFactor">
|
||||||
{ name: 'getRoi', inSignature: '', outSignature: 'ai' },
|
<arg type="d" direction="out" />
|
||||||
{ name: 'shiftContentsTo', inSignature: 'ii', outSignature: 'b' },
|
<arg type="d" direction="out" />
|
||||||
{ name: 'moveResize', inSignature: 'ai', outSignature: '' }
|
</method>
|
||||||
],
|
<method name="setRoi">
|
||||||
signals: [],
|
<arg type="ai" direction="in" />
|
||||||
properties: []
|
</method>
|
||||||
};
|
<method name="getRoi">
|
||||||
|
<arg type="ai" direction="out" />
|
||||||
|
</method>
|
||||||
|
<method name="shiftContentsTo">
|
||||||
|
<arg type="i" direction="in" />
|
||||||
|
<arg type="i" direction="in" />
|
||||||
|
<arg type="b" direction="out" />
|
||||||
|
</method>
|
||||||
|
<method name="moveResize">
|
||||||
|
<arg type="ai" direction="in" />
|
||||||
|
</method>
|
||||||
|
</interface>;
|
||||||
|
|
||||||
// For making unique ZoomRegion DBus proxy object paths of the form:
|
// For making unique ZoomRegion DBus proxy object paths of the form:
|
||||||
// '/org/gnome/Magnifier/ZoomRegion/zoomer0',
|
// '/org/gnome/Magnifier/ZoomRegion/zoomer0',
|
||||||
@ -64,7 +102,9 @@ function ShellMagnifier() {
|
|||||||
ShellMagnifier.prototype = {
|
ShellMagnifier.prototype = {
|
||||||
_init: function() {
|
_init: function() {
|
||||||
this._zoomers = {};
|
this._zoomers = {};
|
||||||
DBus.session.exportObject(MAG_SERVICE_PATH, this);
|
|
||||||
|
this._dbusImpl = Gio.DBusExportedObject.wrapJSObject(MagnifierIface, this);
|
||||||
|
this._dbusImpl.export(Gio.DBus.session, MAG_SERVICE_PATH);
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -195,10 +235,10 @@ ShellMagnifier.prototype = {
|
|||||||
Main.magnifier.clearAllZoomRegions();
|
Main.magnifier.clearAllZoomRegions();
|
||||||
for (let objectPath in this._zoomers) {
|
for (let objectPath in this._zoomers) {
|
||||||
let proxyAndZoomer = this._zoomers[objectPath];
|
let proxyAndZoomer = this._zoomers[objectPath];
|
||||||
|
proxyAndZoomer.proxy.destroy();
|
||||||
proxyAndZoomer.proxy = null;
|
proxyAndZoomer.proxy = null;
|
||||||
proxyAndZoomer.zoomRegion = null;
|
proxyAndZoomer.zoomRegion = null;
|
||||||
delete this._zoomers[objectPath];
|
delete this._zoomers[objectPath];
|
||||||
DBus.session.unexportObject(proxyAndZoomer);
|
|
||||||
}
|
}
|
||||||
this._zoomers = {};
|
this._zoomers = {};
|
||||||
},
|
},
|
||||||
@ -300,8 +340,9 @@ function ShellMagnifierZoomRegion(zoomerObjectPath, zoomRegion) {
|
|||||||
ShellMagnifierZoomRegion.prototype = {
|
ShellMagnifierZoomRegion.prototype = {
|
||||||
_init: function(zoomerObjectPath, zoomRegion) {
|
_init: function(zoomerObjectPath, zoomRegion) {
|
||||||
this._zoomRegion = zoomRegion;
|
this._zoomRegion = zoomRegion;
|
||||||
DBus.session.proxifyObject(this, ZOOM_SERVICE_NAME, zoomerObjectPath);
|
|
||||||
DBus.session.exportObject(zoomerObjectPath, this);
|
this._dbusImpl = Gio.DBusExportedObject.wrapJSObject(ZoomRegionIface, this);
|
||||||
|
this._dbusImpl.export(Gio.DBus.session, zoomerObjectPath);
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -376,8 +417,9 @@ ShellMagnifierZoomRegion.prototype = {
|
|||||||
moveResize: function(viewPort) {
|
moveResize: function(viewPort) {
|
||||||
let viewRect = { x: viewPort[0], y: viewPort[1], width: viewPort[2] - viewPort[0], height: viewPort[3] - viewPort[1] };
|
let viewRect = { x: viewPort[0], y: viewPort[1], width: viewPort[2] - viewPort[0], height: viewPort[3] - viewPort[1] };
|
||||||
this._zoomRegion.setViewPort(viewRect);
|
this._zoomRegion.setViewPort(viewRect);
|
||||||
|
},
|
||||||
|
|
||||||
|
destroy: function() {
|
||||||
|
this._dbusImpl.unexport();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
DBus.conformExport(ShellMagnifier.prototype, MagnifierIface);
|
|
||||||
DBus.conformExport(ShellMagnifierZoomRegion.prototype, ZoomRegionIface);
|
|
||||||
|
@ -1,11 +1,9 @@
|
|||||||
/* -*- mode: js2; js2-basic-offset: 4; indent-tabs-mode: nil -*- */
|
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
|
||||||
|
|
||||||
const Clutter = imports.gi.Clutter;
|
const Clutter = imports.gi.Clutter;
|
||||||
const DBus = imports.dbus;
|
|
||||||
const Gdk = imports.gi.Gdk;
|
const Gdk = imports.gi.Gdk;
|
||||||
const Gio = imports.gi.Gio;
|
const Gio = imports.gi.Gio;
|
||||||
const GLib = imports.gi.GLib;
|
const GLib = imports.gi.GLib;
|
||||||
const GConf = imports.gi.GConf;
|
|
||||||
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;
|
||||||
@ -129,22 +127,16 @@ function _initRecorder() {
|
|||||||
function _initUserSession() {
|
function _initUserSession() {
|
||||||
_initRecorder();
|
_initRecorder();
|
||||||
|
|
||||||
keyboard.init();
|
|
||||||
|
|
||||||
global.screen.override_workspace_layout(Meta.ScreenCorner.TOPLEFT, false, -1, 1);
|
global.screen.override_workspace_layout(Meta.ScreenCorner.TOPLEFT, false, -1, 1);
|
||||||
|
|
||||||
ExtensionSystem.init();
|
ExtensionSystem.init();
|
||||||
ExtensionSystem.loadExtensions();
|
ExtensionSystem.loadExtensions();
|
||||||
|
|
||||||
let shellwm = global.window_manager;
|
Meta.keybindings_set_custom_handler('panel-run-dialog', function() {
|
||||||
|
|
||||||
shellwm.takeover_keybinding('panel_run_dialog');
|
|
||||||
shellwm.connect('keybinding::panel_run_dialog', function () {
|
|
||||||
getRunDialog().open();
|
getRunDialog().open();
|
||||||
});
|
});
|
||||||
|
|
||||||
shellwm.takeover_keybinding('panel_main_menu');
|
Meta.keybindings_set_custom_handler('panel-main-menu', function () {
|
||||||
shellwm.connect('keybinding::panel_main_menu', function () {
|
|
||||||
overview.toggle();
|
overview.toggle();
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -165,11 +157,6 @@ function start() {
|
|||||||
Gio.DesktopAppInfo.set_desktop_env('GNOME');
|
Gio.DesktopAppInfo.set_desktop_env('GNOME');
|
||||||
|
|
||||||
shellDBusService = new ShellDBus.GnomeShell();
|
shellDBusService = new ShellDBus.GnomeShell();
|
||||||
// Force a connection now; dbus.js will do this internally
|
|
||||||
// if we use its name acquisition stuff but we aren't right
|
|
||||||
// now; to do so we'd need to convert from its async calls
|
|
||||||
// back into sync ones.
|
|
||||||
DBus.session.flush();
|
|
||||||
|
|
||||||
// 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
|
||||||
@ -496,9 +483,9 @@ function notify(msg, details) {
|
|||||||
function notifyError(msg, details) {
|
function notifyError(msg, details) {
|
||||||
// Also print to stderr so it's logged somewhere
|
// Also print to stderr so it's logged somewhere
|
||||||
if (details)
|
if (details)
|
||||||
log("error: " + msg + ": " + details);
|
log('error: ' + msg + ': ' + details);
|
||||||
else
|
else
|
||||||
log("error: " + msg)
|
log('error: ' + msg);
|
||||||
|
|
||||||
notify(msg, details);
|
notify(msg, details);
|
||||||
}
|
}
|
||||||
@ -585,16 +572,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);
|
||||||
|
|
||||||
// The screenshot action should always be available (even if a
|
|
||||||
// modal dialog is present)
|
|
||||||
if (action == Meta.KeyBindingAction.COMMAND_SCREENSHOT) {
|
|
||||||
let gconf = GConf.Client.get_default();
|
|
||||||
let command = gconf.get_string('/apps/metacity/keybinding_commands/command_screenshot');
|
|
||||||
if (command != null && command != '')
|
|
||||||
Util.spawnCommandLine(command);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Other bindings are only available to the user session when the overview is up and
|
// Other bindings are only available to the user session when the overview is up and
|
||||||
// no modal dialog is present.
|
// no modal dialog is present.
|
||||||
if (global.session_type == Shell.SessionType.USER && (!overview.visible || modalCount > 1))
|
if (global.session_type == Shell.SessionType.USER && (!overview.visible || modalCount > 1))
|
||||||
@ -670,14 +647,17 @@ function _findModal(actor) {
|
|||||||
* initiated event. If not provided then the value of
|
* initiated event. If not provided then the value of
|
||||||
* global.get_current_time() is assumed.
|
* global.get_current_time() is assumed.
|
||||||
*
|
*
|
||||||
|
* @options: optional Meta.ModalOptions flags to indicate that the
|
||||||
|
* pointer is alrady grabbed
|
||||||
|
*
|
||||||
* Returns: true iff we successfully acquired a grab or already had one
|
* Returns: true iff we successfully acquired a grab or already had one
|
||||||
*/
|
*/
|
||||||
function pushModal(actor, timestamp) {
|
function pushModal(actor, timestamp, options) {
|
||||||
if (timestamp == undefined)
|
if (timestamp == undefined)
|
||||||
timestamp = global.get_current_time();
|
timestamp = global.get_current_time();
|
||||||
|
|
||||||
if (modalCount == 0) {
|
if (modalCount == 0) {
|
||||||
if (!global.begin_modal(timestamp)) {
|
if (!global.begin_modal(timestamp, options ? options : 0)) {
|
||||||
log('pushModal: invocation of begin_modal failed');
|
log('pushModal: invocation of begin_modal failed');
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
/* -*- mode: js2; js2-basic-offset: 4; indent-tabs-mode: nil -*- */
|
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
|
||||||
|
|
||||||
const Clutter = imports.gi.Clutter;
|
const Clutter = imports.gi.Clutter;
|
||||||
const GLib = imports.gi.GLib;
|
const GLib = imports.gi.GLib;
|
||||||
@ -252,7 +252,8 @@ FocusGrabber.prototype = {
|
|||||||
this._prevFocusedWindow = global.display.focus_window;
|
this._prevFocusedWindow = global.display.focus_window;
|
||||||
this._prevKeyFocusActor = global.stage.get_key_focus();
|
this._prevKeyFocusActor = global.stage.get_key_focus();
|
||||||
|
|
||||||
if (!Main.overview.visible)
|
if (global.stage_input_mode == Shell.StageInputMode.NONREACTIVE ||
|
||||||
|
global.stage_input_mode == Shell.StageInputMode.NORMAL)
|
||||||
global.set_stage_input_mode(Shell.StageInputMode.FOCUSED);
|
global.set_stage_input_mode(Shell.StageInputMode.FOCUSED);
|
||||||
|
|
||||||
// Use captured-event to notice clicks outside the focused actor
|
// Use captured-event to notice clicks outside the focused actor
|
||||||
@ -416,6 +417,7 @@ Notification.prototype = {
|
|||||||
|
|
||||||
_init: function(source, title, banner, params) {
|
_init: function(source, title, banner, params) {
|
||||||
this.source = source;
|
this.source = source;
|
||||||
|
this.title = title;
|
||||||
this.urgency = Urgency.NORMAL;
|
this.urgency = Urgency.NORMAL;
|
||||||
this.resident = false;
|
this.resident = false;
|
||||||
// 'transient' is a reserved keyword in JS, so we have to use an alternate variable name
|
// 'transient' is a reserved keyword in JS, so we have to use an alternate variable name
|
||||||
@ -503,8 +505,11 @@ Notification.prototype = {
|
|||||||
|
|
||||||
let oldFocus = global.stage.key_focus;
|
let oldFocus = global.stage.key_focus;
|
||||||
|
|
||||||
if (this._icon)
|
if (this._icon && (params.icon || params.clear)) {
|
||||||
this._icon.destroy();
|
this._icon.destroy();
|
||||||
|
this._icon = 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.
|
||||||
@ -530,14 +535,17 @@ Notification.prototype = {
|
|||||||
if (!this._scrollArea && !this._actionArea && !this._imageBin)
|
if (!this._scrollArea && !this._actionArea && !this._imageBin)
|
||||||
this._table.remove_style_class_name('multi-line-notification');
|
this._table.remove_style_class_name('multi-line-notification');
|
||||||
|
|
||||||
this._icon = params.icon || this.source.createNotificationIcon();
|
if (!this._icon) {
|
||||||
this._table.add(this._icon, { row: 0,
|
this._icon = params.icon || this.source.createNotificationIcon();
|
||||||
col: 0,
|
this._table.add(this._icon, { row: 0,
|
||||||
x_expand: false,
|
col: 0,
|
||||||
y_expand: false,
|
x_expand: false,
|
||||||
y_fill: false,
|
y_expand: false,
|
||||||
y_align: St.Align.START });
|
y_fill: false,
|
||||||
|
y_align: St.Align.START });
|
||||||
|
}
|
||||||
|
|
||||||
|
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>');
|
||||||
|
|
||||||
@ -589,8 +597,7 @@ Notification.prototype = {
|
|||||||
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({ name: 'notification-scrollview',
|
||||||
vscrollbar_policy: this._scrollPolicy,
|
vscrollbar_policy: this._scrollPolicy,
|
||||||
hscrollbar_policy: Gtk.PolicyType.NEVER,
|
hscrollbar_policy: Gtk.PolicyType.NEVER });
|
||||||
style_class: 'vfade' });
|
|
||||||
this._table.add(this._scrollArea, { row: 1,
|
this._table.add(this._scrollArea, { row: 1,
|
||||||
col: 2 });
|
col: 2 });
|
||||||
this._updateLastColumnSettings();
|
this._updateLastColumnSettings();
|
||||||
@ -695,6 +702,7 @@ Notification.prototype = {
|
|||||||
this._imageBin.opacity = 230;
|
this._imageBin.opacity = 230;
|
||||||
this._table.add_style_class_name('multi-line-notification');
|
this._table.add_style_class_name('multi-line-notification');
|
||||||
this._table.add_style_class_name('notification-with-image');
|
this._table.add_style_class_name('notification-with-image');
|
||||||
|
this._addBannerBody();
|
||||||
this._updateLastColumnSettings();
|
this._updateLastColumnSettings();
|
||||||
this._table.add(this._imageBin, { row: 1,
|
this._table.add(this._imageBin, { row: 1,
|
||||||
col: 1,
|
col: 1,
|
||||||
@ -983,6 +991,7 @@ Source.prototype = {
|
|||||||
|
|
||||||
this.isTransient = false;
|
this.isTransient = false;
|
||||||
this.isChat = false;
|
this.isChat = false;
|
||||||
|
this.isMuted = false;
|
||||||
|
|
||||||
this.notifications = [];
|
this.notifications = [];
|
||||||
},
|
},
|
||||||
@ -1047,6 +1056,13 @@ Source.prototype = {
|
|||||||
this.emit('title-changed');
|
this.emit('title-changed');
|
||||||
},
|
},
|
||||||
|
|
||||||
|
setMuted: function(muted) {
|
||||||
|
if (!this.isChat || this.isMuted == muted)
|
||||||
|
return;
|
||||||
|
this.isMuted = muted;
|
||||||
|
this.emit('muted-changed');
|
||||||
|
},
|
||||||
|
|
||||||
// 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
|
// Must be overridden by the subclass if you do not pass icons
|
||||||
// explicitly to the Notification() constructor.
|
// explicitly to the Notification() constructor.
|
||||||
@ -1085,7 +1101,8 @@ Source.prototype = {
|
|||||||
|
|
||||||
notify: function(notification) {
|
notify: function(notification) {
|
||||||
this.pushNotification(notification);
|
this.pushNotification(notification);
|
||||||
this.emit('notify', notification);
|
if (!this.isMuted)
|
||||||
|
this.emit('notify', notification);
|
||||||
},
|
},
|
||||||
|
|
||||||
destroy: function(reason) {
|
destroy: function(reason) {
|
||||||
@ -1201,6 +1218,18 @@ SummaryItem.prototype = {
|
|||||||
}));
|
}));
|
||||||
this.rightClickMenu.add(item.actor);
|
this.rightClickMenu.add(item.actor);
|
||||||
|
|
||||||
|
if (source.isChat) {
|
||||||
|
item = new PopupMenu.PopupMenuItem('');
|
||||||
|
item.actor.connect('notify::mapped', Lang.bind(this, function() {
|
||||||
|
item.label.set_text(source.isMuted ? _("Unmute") : _("Mute"));
|
||||||
|
}));
|
||||||
|
item.connect('activate', Lang.bind(this, function() {
|
||||||
|
source.setMuted(!source.isMuted);
|
||||||
|
this.emit('done-displaying-content');
|
||||||
|
}));
|
||||||
|
this.rightClickMenu.add(item.actor);
|
||||||
|
}
|
||||||
|
|
||||||
let focusManager = St.FocusManager.get_for_stage(global.stage);
|
let focusManager = St.FocusManager.get_for_stage(global.stage);
|
||||||
focusManager.add_group(this.rightClickMenu);
|
focusManager.add_group(this.rightClickMenu);
|
||||||
},
|
},
|
||||||
@ -1320,12 +1349,15 @@ function MessageTray() {
|
|||||||
|
|
||||||
MessageTray.prototype = {
|
MessageTray.prototype = {
|
||||||
_init: function() {
|
_init: function() {
|
||||||
this._presence = new GnomeSession.Presence();
|
this._presence = new GnomeSession.Presence(Lang.bind(this, function(proxy, error) {
|
||||||
|
this._onStatusChanged(proxy.status);
|
||||||
|
}));
|
||||||
this._userStatus = GnomeSession.PresenceStatus.AVAILABLE;
|
this._userStatus = GnomeSession.PresenceStatus.AVAILABLE;
|
||||||
this._busy = false;
|
this._busy = false;
|
||||||
this._backFromAway = false;
|
this._backFromAway = false;
|
||||||
this._presence.connect('StatusChanged', Lang.bind(this, this._onStatusChanged));
|
this._presence.connectSignal('StatusChanged', Lang.bind(this, function(proxy, senderName, [status]) {
|
||||||
this._presence.getStatus(Lang.bind(this, this._onStatusChanged));
|
this._onStatusChanged(status);
|
||||||
|
}));
|
||||||
|
|
||||||
this.actor = new St.Group({ name: 'message-tray',
|
this.actor = new St.Group({ name: 'message-tray',
|
||||||
reactive: true,
|
reactive: true,
|
||||||
@ -1349,6 +1381,7 @@ MessageTray.prototype = {
|
|||||||
this._summaryBin.opacity = 0;
|
this._summaryBin.opacity = 0;
|
||||||
|
|
||||||
this._summaryMotionId = 0;
|
this._summaryMotionId = 0;
|
||||||
|
this._trayMotionId = 0;
|
||||||
|
|
||||||
this._summaryBoxPointer = new BoxPointer.BoxPointer(St.Side.BOTTOM,
|
this._summaryBoxPointer = new BoxPointer.BoxPointer(St.Side.BOTTOM,
|
||||||
{ reactive: true,
|
{ reactive: true,
|
||||||
@ -1388,12 +1421,15 @@ MessageTray.prototype = {
|
|||||||
}));
|
}));
|
||||||
this._focusGrabber.connect('escape-pressed', Lang.bind(this, this._escapeTray));
|
this._focusGrabber.connect('escape-pressed', Lang.bind(this, this._escapeTray));
|
||||||
|
|
||||||
|
Main.layoutManager.keyboardBox.connect('notify::hover', Lang.bind(this, this._onKeyboardHoverChanged));
|
||||||
|
|
||||||
this._trayState = State.HIDDEN;
|
this._trayState = State.HIDDEN;
|
||||||
this._locked = false;
|
this._locked = false;
|
||||||
this._traySummoned = false;
|
this._traySummoned = false;
|
||||||
this._useLongerTrayLeftTimeout = false;
|
this._useLongerTrayLeftTimeout = false;
|
||||||
this._trayLeftTimeoutId = 0;
|
this._trayLeftTimeoutId = 0;
|
||||||
this._pointerInTray = false;
|
this._pointerInTray = false;
|
||||||
|
this._pointerInKeyboard = false;
|
||||||
this._summaryState = State.HIDDEN;
|
this._summaryState = State.HIDDEN;
|
||||||
this._summaryTimeoutId = 0;
|
this._summaryTimeoutId = 0;
|
||||||
this._pointerInSummary = false;
|
this._pointerInSummary = false;
|
||||||
@ -1505,6 +1541,14 @@ MessageTray.prototype = {
|
|||||||
|
|
||||||
source.connect('notify', Lang.bind(this, this._onNotify));
|
source.connect('notify', Lang.bind(this, this._onNotify));
|
||||||
|
|
||||||
|
source.connect('muted-changed', Lang.bind(this,
|
||||||
|
function () {
|
||||||
|
if (source.isMuted)
|
||||||
|
this._notificationQueue = this._notificationQueue.filter(function(notification) {
|
||||||
|
return source != notification.source;
|
||||||
|
});
|
||||||
|
}));
|
||||||
|
|
||||||
summaryItem.actor.connect('notify::hover', Lang.bind(this,
|
summaryItem.actor.connect('notify::hover', Lang.bind(this,
|
||||||
function () {
|
function () {
|
||||||
this._onSummaryItemHoverChanged(summaryItem);
|
this._onSummaryItemHoverChanged(summaryItem);
|
||||||
@ -1574,7 +1618,7 @@ MessageTray.prototype = {
|
|||||||
|
|
||||||
summaryItemToRemove.actor.destroy();
|
summaryItemToRemove.actor.destroy();
|
||||||
|
|
||||||
if (needUpdate);
|
if (needUpdate)
|
||||||
this._updateState();
|
this._updateState();
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -1819,7 +1863,7 @@ MessageTray.prototype = {
|
|||||||
// automatically. Instead, the user is able to expand the notification by mousing away from it and then
|
// automatically. Instead, the user is able to expand the notification by mousing away from it and then
|
||||||
// mousing back in. Because this is an expected action, we set the boolean flag that indicates that a longer
|
// mousing back in. Because this is an expected action, we set the boolean flag that indicates that a longer
|
||||||
// timeout should be used before popping down the notification.
|
// timeout should be used before popping down the notification.
|
||||||
if (this._notificationBin.contains(actorAtShowNotificationPosition)) {
|
if (this.actor.contains(actorAtShowNotificationPosition)) {
|
||||||
this._useLongerTrayLeftTimeout = true;
|
this._useLongerTrayLeftTimeout = true;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -1843,7 +1887,25 @@ MessageTray.prototype = {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
_onStatusChanged: function(presence, status) {
|
_onKeyboardHoverChanged: function(keyboard) {
|
||||||
|
this._pointerInKeyboard = keyboard.hover;
|
||||||
|
|
||||||
|
if (!keyboard.hover) {
|
||||||
|
let event = Clutter.get_current_event();
|
||||||
|
if (event && event.type() == Clutter.EventType.LEAVE) {
|
||||||
|
let into = event.get_related();
|
||||||
|
if (into && this.actor.contains(into)) {
|
||||||
|
// Don't call _updateState, because pointerInTray is
|
||||||
|
// still false
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
this._updateState();
|
||||||
|
},
|
||||||
|
|
||||||
|
_onStatusChanged: function(status) {
|
||||||
this._backFromAway = (this._userStatus == GnomeSession.PresenceStatus.IDLE && this._userStatus != status);
|
this._backFromAway = (this._userStatus == GnomeSession.PresenceStatus.IDLE && this._userStatus != status);
|
||||||
this._userStatus = status;
|
this._userStatus = status;
|
||||||
|
|
||||||
@ -1907,7 +1969,7 @@ MessageTray.prototype = {
|
|||||||
let notificationsPending = this._notificationQueue.length > 0 && (!this._busy || notificationUrgent);
|
let notificationsPending = this._notificationQueue.length > 0 && (!this._busy || 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 < 0;
|
||||||
let notificationExpired = (this._notificationTimeoutId == 0 && !(this._notification && this._notification.urgency == Urgency.CRITICAL) && !this._pointerInTray && !this._locked) || 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;
|
||||||
|
|
||||||
if (this._notificationState == State.HIDDEN) {
|
if (this._notificationState == State.HIDDEN) {
|
||||||
@ -2265,6 +2327,8 @@ MessageTray.prototype = {
|
|||||||
// _clickedSummaryItem.actor can change absolute position without changing allocation
|
// _clickedSummaryItem.actor can change absolute position without changing allocation
|
||||||
this._summaryMotionId = this._summary.connect('allocation-changed',
|
this._summaryMotionId = this._summary.connect('allocation-changed',
|
||||||
Lang.bind(this, this._adjustSummaryBoxPointerPosition));
|
Lang.bind(this, this._adjustSummaryBoxPointerPosition));
|
||||||
|
this._trayMotionId = Main.layoutManager.trayBox.connect('notify::anchor-y',
|
||||||
|
Lang.bind(this, this._adjustSummaryBoxPointerPosition));
|
||||||
|
|
||||||
this._summaryBoxPointer.actor.opacity = 0;
|
this._summaryBoxPointer.actor.opacity = 0;
|
||||||
this._summaryBoxPointer.actor.show();
|
this._summaryBoxPointer.actor.show();
|
||||||
@ -2296,8 +2360,10 @@ MessageTray.prototype = {
|
|||||||
if (this._clickedSummaryItemAllocationChangedId) {
|
if (this._clickedSummaryItemAllocationChangedId) {
|
||||||
this._clickedSummaryItem.actor.disconnect(this._clickedSummaryItemAllocationChangedId);
|
this._clickedSummaryItem.actor.disconnect(this._clickedSummaryItemAllocationChangedId);
|
||||||
this._summary.disconnect(this._summaryMotionId);
|
this._summary.disconnect(this._summaryMotionId);
|
||||||
|
Main.layoutManager.trayBox.disconnect(this._trayMotionId);
|
||||||
this._clickedSummaryItemAllocationChangedId = 0;
|
this._clickedSummaryItemAllocationChangedId = 0;
|
||||||
this._summaryMotionId = 0;
|
this._summaryMotionId = 0;
|
||||||
|
this._trayMotionId = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this._clickedSummaryItem)
|
if (this._clickedSummaryItem)
|
||||||
@ -2316,8 +2382,9 @@ MessageTray.prototype = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
this._summaryBoxPointerState = State.HIDING;
|
this._summaryBoxPointerState = State.HIDING;
|
||||||
// Unset this._clickedSummaryItem if we are no longer showing the summary
|
// Unset this._clickedSummaryItem if we are no longer showing the summary or if
|
||||||
if (this._summaryState != State.SHOWN)
|
// this._clickedSummaryItem is still the item associated with the currently showing box pointer
|
||||||
|
if (this._summaryState != State.SHOWN || this._summaryBoxPointerItem == this._clickedSummaryItem)
|
||||||
this._unsetClickedSummaryItem();
|
this._unsetClickedSummaryItem();
|
||||||
|
|
||||||
this._focusGrabber.ungrabFocus();
|
this._focusGrabber.ungrabFocus();
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
/* -*- mode: js2; js2-basic-offset: 4; indent-tabs-mode: nil -*- */
|
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
|
||||||
|
|
||||||
const Clutter = imports.gi.Clutter;
|
const Clutter = imports.gi.Clutter;
|
||||||
const Gdk = imports.gi.Gdk;
|
const Gdk = imports.gi.Gdk;
|
||||||
@ -110,7 +110,7 @@ ModalDialog.prototype = {
|
|||||||
this._buttonLayout.destroy_children();
|
this._buttonLayout.destroy_children();
|
||||||
this._actionKeys = {};
|
this._actionKeys = {};
|
||||||
|
|
||||||
for (let i = 0; i < buttons.length; i ++) {
|
for (let i = 0; i < buttons.length; i++) {
|
||||||
let buttonInfo = buttons[i];
|
let buttonInfo = buttons[i];
|
||||||
let label = buttonInfo['label'];
|
let label = buttonInfo['label'];
|
||||||
let action = buttonInfo['action'];
|
let action = buttonInfo['action'];
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/* -*- mode: js2; js2-basic-offset: 4; indent-tabs-mode: nil -*-
|
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
|
||||||
*
|
/*
|
||||||
* Copyright 2011 Giovanni Campagna <scampa.giovanni@gmail.com>
|
* Copyright 2011 Giovanni Campagna <scampa.giovanni@gmail.com>
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* This program is free software; you can redistribute it and/or modify
|
||||||
@ -30,6 +30,7 @@ const St = imports.gi.St;
|
|||||||
|
|
||||||
const ModalDialog = imports.ui.modalDialog;
|
const ModalDialog = imports.ui.modalDialog;
|
||||||
const PopupMenu = imports.ui.popupMenu;
|
const PopupMenu = imports.ui.popupMenu;
|
||||||
|
const ShellEntry = imports.ui.shellEntry;
|
||||||
|
|
||||||
function NetworkSecretDialog() {
|
function NetworkSecretDialog() {
|
||||||
this._init.apply(this, arguments);
|
this._init.apply(this, arguments);
|
||||||
@ -103,6 +104,8 @@ NetworkSecretDialog.prototype = {
|
|||||||
secret.entry = new St.Entry({ style_class: 'polkit-dialog-password-entry',
|
secret.entry = new St.Entry({ style_class: 'polkit-dialog-password-entry',
|
||||||
text: secret.value, can_focus: reactive,
|
text: secret.value, can_focus: reactive,
|
||||||
reactive: reactive });
|
reactive: reactive });
|
||||||
|
ShellEntry.addContextMenu(secret.entry,
|
||||||
|
{ isPassword: secret.password });
|
||||||
|
|
||||||
if (secret.validate)
|
if (secret.validate)
|
||||||
secret.valid = secret.validate(secret);
|
secret.valid = secret.validate(secret);
|
||||||
@ -127,34 +130,14 @@ NetworkSecretDialog.prototype = {
|
|||||||
} else
|
} else
|
||||||
secret.valid = true;
|
secret.valid = true;
|
||||||
|
|
||||||
secretTable.add(label, { row: pos, col: 0, x_align: St.Align.START, y_align: St.Align.START });
|
secretTable.add(label, { row: pos, col: 0, x_expand: false, x_fill: true, x_align: St.Align.START, y_align: St.Align.START });
|
||||||
secretTable.add(secret.entry, { row: pos, col: 1, x_expand: true, x_fill: true, y_align: St.Align.END });
|
secretTable.add(secret.entry, { row: pos, col: 1, x_expand: true, x_fill: true, y_align: St.Align.END });
|
||||||
pos++;
|
pos++;
|
||||||
|
|
||||||
if (secret.password) {
|
if (secret.password)
|
||||||
secret.entry.clutter_text.set_password_char('\u25cf');
|
secret.entry.clutter_text.set_password_char('\u25cf');
|
||||||
|
|
||||||
// FIXME: need a real checkbox here
|
|
||||||
let button = new St.Button({ button_mask: St.ButtonMask.ONE,
|
|
||||||
can_focus: true });
|
|
||||||
let checkbox = new St.BoxLayout({ vertical: false,
|
|
||||||
style_class: 'network-dialog-show-password-checkbox'
|
|
||||||
});
|
|
||||||
let _switch = new PopupMenu.Switch(false);
|
|
||||||
checkbox.add(_switch.actor);
|
|
||||||
checkbox.add(new St.Label({ text: _("Show password") }), { expand: true });
|
|
||||||
button.connect('clicked', function() {
|
|
||||||
_switch.toggle();
|
|
||||||
if (_switch.state)
|
|
||||||
secret.entry.clutter_text.set_password_char('');
|
|
||||||
else
|
|
||||||
secret.entry.clutter_text.set_password_char('\u25cf');
|
|
||||||
});
|
|
||||||
button.child = checkbox;
|
|
||||||
secretTable.add(button, { row: pos, col: 1, x_expand: true, x_fill: true, y_fill: true })
|
|
||||||
pos++;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
messageBox.add(secretTable);
|
messageBox.add(secretTable);
|
||||||
|
|
||||||
this._okButton = { label: _("Connect"),
|
this._okButton = { label: _("Connect"),
|
||||||
@ -404,4 +387,4 @@ NetworkAgent.prototype = {
|
|||||||
this._dialogs[requestId].close(global.get_current_time());
|
this._dialogs[requestId].close(global.get_current_time());
|
||||||
this._dialogs[requestId].destroy();
|
this._dialogs[requestId].destroy();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/* -*- mode: js2; js2-basic-offset: 4; indent-tabs-mode: nil -*- */
|
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
|
||||||
|
|
||||||
const Clutter = imports.gi.Clutter;
|
const Clutter = imports.gi.Clutter;
|
||||||
const DBus = imports.dbus;
|
const Gio = imports.gi.Gio;
|
||||||
const GLib = imports.gi.GLib;
|
const GLib = imports.gi.GLib;
|
||||||
const Lang = imports.lang;
|
const Lang = imports.lang;
|
||||||
const Shell = imports.gi.Shell;
|
const Shell = imports.gi.Shell;
|
||||||
@ -16,49 +16,52 @@ const Util = imports.misc.util;
|
|||||||
|
|
||||||
let nextNotificationId = 1;
|
let nextNotificationId = 1;
|
||||||
|
|
||||||
// Should really be defined in dbus.js
|
// Should really be defined in Gio.js
|
||||||
const BusIface = {
|
const BusIface = <interface name="org.freedesktop.DBus">
|
||||||
name: 'org.freedesktop.DBus',
|
<method name="GetConnectionUnixProcessID">
|
||||||
methods: [{ name: 'GetConnectionUnixProcessID',
|
<arg type="s" direction="in" />
|
||||||
inSignature: 's',
|
<arg type="u" direction="out" />
|
||||||
outSignature: 'i' }]
|
</method>
|
||||||
};
|
</interface>;
|
||||||
|
|
||||||
const Bus = function () {
|
var BusProxy = Gio.DBusProxy.makeProxyWrapper(BusIface);
|
||||||
this._init();
|
function Bus() {
|
||||||
};
|
return new BusProxy(Gio.DBus.session, 'org.freedesktop.DBus', '/org/freedesktop/DBus');
|
||||||
|
}
|
||||||
|
|
||||||
Bus.prototype = {
|
const NotificationDaemonIface = <interface name="org.freedesktop.Notifications">
|
||||||
_init: function() {
|
<method name="Notify">
|
||||||
DBus.session.proxifyObject(this, 'org.freedesktop.DBus', '/org/freedesktop/DBus');
|
<arg type="s" direction="in"/>
|
||||||
}
|
<arg type="u" direction="in"/>
|
||||||
};
|
<arg type="s" direction="in"/>
|
||||||
|
<arg type="s" direction="in"/>
|
||||||
DBus.proxifyPrototype(Bus.prototype, BusIface);
|
<arg type="s" direction="in"/>
|
||||||
|
<arg type="as" direction="in"/>
|
||||||
const NotificationDaemonIface = {
|
<arg type="a{sv}" direction="in"/>
|
||||||
name: 'org.freedesktop.Notifications',
|
<arg type="i" direction="in"/>
|
||||||
methods: [{ name: 'Notify',
|
<arg type="u" direction="out"/>
|
||||||
inSignature: 'susssasa{sv}i',
|
</method>
|
||||||
outSignature: 'u'
|
<method name="CloseNotification">
|
||||||
},
|
<arg type="u" direction="in"/>
|
||||||
{ name: 'CloseNotification',
|
</method>
|
||||||
inSignature: 'u',
|
<method name="GetCapabilities">
|
||||||
outSignature: ''
|
<arg type="as" direction="out"/>
|
||||||
},
|
</method>
|
||||||
{ name: 'GetCapabilities',
|
<method name="GetServerInformation">
|
||||||
inSignature: '',
|
<arg type="s" direction="out"/>
|
||||||
outSignature: 'as'
|
<arg type="s" direction="out"/>
|
||||||
},
|
<arg type="s" direction="out"/>
|
||||||
{ name: 'GetServerInformation',
|
<arg type="s" direction="out"/>
|
||||||
inSignature: '',
|
</method>
|
||||||
outSignature: 'ssss'
|
<signal name="NotificationClosed">
|
||||||
}],
|
<arg type="u"/>
|
||||||
signals: [{ name: 'NotificationClosed',
|
<arg type="u"/>
|
||||||
inSignature: 'uu' },
|
</signal>
|
||||||
{ name: 'ActionInvoked',
|
<signal name="ActionInvoked">
|
||||||
inSignature: 'us' }]
|
<arg type="u"/>
|
||||||
};
|
<arg type="s"/>
|
||||||
|
</signal>
|
||||||
|
</interface>;
|
||||||
|
|
||||||
const NotificationClosedReason = {
|
const NotificationClosedReason = {
|
||||||
EXPIRED: 1,
|
EXPIRED: 1,
|
||||||
@ -90,7 +93,8 @@ function NotificationDaemon() {
|
|||||||
|
|
||||||
NotificationDaemon.prototype = {
|
NotificationDaemon.prototype = {
|
||||||
_init: function() {
|
_init: function() {
|
||||||
DBus.session.exportObject('/org/freedesktop/Notifications', this);
|
this._dbusImpl = Gio.DBusExportedObject.wrapJSObject(NotificationDaemonIface, this);
|
||||||
|
this._dbusImpl.export(Gio.DBus.session, '/org/freedesktop/Notifications');
|
||||||
|
|
||||||
this._sources = {};
|
this._sources = {};
|
||||||
this._senderToPid = {};
|
this._senderToPid = {};
|
||||||
@ -109,6 +113,14 @@ NotificationDaemon.prototype = {
|
|||||||
_iconForNotificationData: function(icon, hints, size) {
|
_iconForNotificationData: function(icon, hints, size) {
|
||||||
let textureCache = St.TextureCache.get_default();
|
let textureCache = St.TextureCache.get_default();
|
||||||
|
|
||||||
|
// If an icon is not specified, we use 'image-data' or 'image-path' hint for an icon
|
||||||
|
// and don't show a large image. There are currently many applications that use
|
||||||
|
// notify_notification_set_icon_from_pixbuf() from libnotify, which in turn sets
|
||||||
|
// the 'image-data' hint. These applications don't typically pass in 'app_icon'
|
||||||
|
// argument to Notify() and actually expect the pixbuf to be shown as an icon.
|
||||||
|
// So the logic here does the right thing for this case. If both an icon and either
|
||||||
|
// one of 'image-data' or 'image-path' are specified, we show both an icon and
|
||||||
|
// a large image.
|
||||||
if (icon) {
|
if (icon) {
|
||||||
if (icon.substr(0, 7) == 'file://')
|
if (icon.substr(0, 7) == 'file://')
|
||||||
return textureCache.load_uri_async(icon, size, size);
|
return textureCache.load_uri_async(icon, size, size);
|
||||||
@ -119,6 +131,12 @@ NotificationDaemon.prototype = {
|
|||||||
return new St.Icon({ icon_name: icon,
|
return new St.Icon({ icon_name: icon,
|
||||||
icon_type: St.IconType.FULLCOLOR,
|
icon_type: St.IconType.FULLCOLOR,
|
||||||
icon_size: size });
|
icon_size: size });
|
||||||
|
} else if (hints['image-data']) {
|
||||||
|
let [width, height, rowStride, hasAlpha,
|
||||||
|
bitsPerSample, nChannels, data] = hints['image-data'];
|
||||||
|
return textureCache.load_from_raw(data, hasAlpha, width, height, rowStride, size);
|
||||||
|
} else if (hints['image-path']) {
|
||||||
|
return textureCache.load_uri_async(GLib.filename_to_uri(hints['image-path'], null), size, size);
|
||||||
} else {
|
} else {
|
||||||
let stockIcon;
|
let stockIcon;
|
||||||
switch (hints.urgency) {
|
switch (hints.urgency) {
|
||||||
@ -181,8 +199,8 @@ NotificationDaemon.prototype = {
|
|||||||
return source;
|
return source;
|
||||||
},
|
},
|
||||||
|
|
||||||
Notify: function(appName, replacesId, icon, summary, body,
|
NotifyAsync: function(params, invocation) {
|
||||||
actions, hints, timeout) {
|
let [appName, replacesId, icon, summary, body, actions, hints, timeout] = params;
|
||||||
let id;
|
let id;
|
||||||
|
|
||||||
// Filter out chat, presence, calls and invitation notifications from
|
// Filter out chat, presence, calls and invitation notifications from
|
||||||
@ -201,7 +219,7 @@ NotificationDaemon.prototype = {
|
|||||||
function () {
|
function () {
|
||||||
this._emitNotificationClosed(id, NotificationClosedReason.DISMISSED);
|
this._emitNotificationClosed(id, NotificationClosedReason.DISMISSED);
|
||||||
}));
|
}));
|
||||||
return id;
|
return invocation.return_value(GLib.Variant.new('(u)', [id]));
|
||||||
}
|
}
|
||||||
|
|
||||||
let rewrites = rewriteRules[appName];
|
let rewrites = rewriteRules[appName];
|
||||||
@ -213,6 +231,11 @@ NotificationDaemon.prototype = {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (let hint in hints) {
|
||||||
|
// unpack the variants
|
||||||
|
hints[hint] = hints[hint].deep_unpack();
|
||||||
|
}
|
||||||
|
|
||||||
hints = Params.parse(hints, { urgency: Urgency.NORMAL }, true);
|
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
|
||||||
@ -244,51 +267,55 @@ NotificationDaemon.prototype = {
|
|||||||
}
|
}
|
||||||
this._notifications[id] = ndata;
|
this._notifications[id] = ndata;
|
||||||
|
|
||||||
let sender = DBus.getCurrentMessageContext().sender;
|
let sender = invocation.get_sender();
|
||||||
let pid = this._senderToPid[sender];
|
let pid = this._senderToPid[sender];
|
||||||
|
|
||||||
let source = this._getSource(appName, pid, ndata, sender);
|
let source = this._getSource(appName, pid, ndata, sender);
|
||||||
|
|
||||||
if (source) {
|
if (source) {
|
||||||
this._notifyForSource(source, ndata);
|
this._notifyForSource(source, ndata);
|
||||||
return id;
|
return invocation.return_value(GLib.Variant.new('(u)', [id]));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (replacesId) {
|
if (replacesId) {
|
||||||
// There's already a pending call to GetConnectionUnixProcessID,
|
// There's already a pending call to GetConnectionUnixProcessID,
|
||||||
// which will see the new notification data when it finishes,
|
// which will see the new notification data when it finishes,
|
||||||
// so we don't have to do anything.
|
// so we don't have to do anything.
|
||||||
return id;
|
return invocation.return_value(GLib.Variant.new('(u)', [id]));;
|
||||||
}
|
}
|
||||||
|
|
||||||
this._busProxy.GetConnectionUnixProcessIDRemote(sender, Lang.bind(this,
|
this._busProxy.GetConnectionUnixProcessIDRemote(sender, Lang.bind(this, function (result, excp) {
|
||||||
function (pid, ex) {
|
// The app may have updated or removed the notification
|
||||||
// The app may have updated or removed the notification
|
ndata = this._notifications[id];
|
||||||
ndata = this._notifications[id];
|
if (!ndata)
|
||||||
if (!ndata)
|
return;
|
||||||
return;
|
|
||||||
|
|
||||||
source = this._getSource(appName, pid, ndata, sender);
|
if (excp) {
|
||||||
|
logError(excp, 'Call to GetConnectionUnixProcessID failed');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// We only store sender-pid entries for persistent sources.
|
let [pid] = result;
|
||||||
// Removing the entries once the source is destroyed
|
source = this._getSource(appName, pid, ndata, sender);
|
||||||
// would result in the entries associated with transient
|
|
||||||
// sources removed once the notification is shown anyway.
|
|
||||||
// However, keeping these pairs would mean that we would
|
|
||||||
// possibly remove an entry associated with a persistent
|
|
||||||
// source when a transient source for the same sender is
|
|
||||||
// distroyed.
|
|
||||||
if (!source.isTransient) {
|
|
||||||
this._senderToPid[sender] = pid;
|
|
||||||
source.connect('destroy', Lang.bind(this,
|
|
||||||
function() {
|
|
||||||
delete this._senderToPid[sender];
|
|
||||||
}));
|
|
||||||
}
|
|
||||||
this._notifyForSource(source, ndata);
|
|
||||||
}));
|
|
||||||
|
|
||||||
return id;
|
// We only store sender-pid entries for persistent sources.
|
||||||
|
// Removing the entries once the source is destroyed
|
||||||
|
// would result in the entries associated with transient
|
||||||
|
// sources removed once the notification is shown anyway.
|
||||||
|
// However, keeping these pairs would mean that we would
|
||||||
|
// possibly remove an entry associated with a persistent
|
||||||
|
// source when a transient source for the same sender is
|
||||||
|
// distroyed.
|
||||||
|
if (!source.isTransient) {
|
||||||
|
this._senderToPid[sender] = pid;
|
||||||
|
source.connect('destroy', Lang.bind(this, function() {
|
||||||
|
delete this._senderToPid[sender];
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
this._notifyForSource(source, ndata);
|
||||||
|
}));
|
||||||
|
|
||||||
|
return invocation.return_value(GLib.Variant.new('(u)', [id]));
|
||||||
},
|
},
|
||||||
|
|
||||||
_notifyForSource: function(source, ndata) {
|
_notifyForSource: function(source, ndata) {
|
||||||
@ -330,7 +357,8 @@ NotificationDaemon.prototype = {
|
|||||||
clear: true });
|
clear: true });
|
||||||
}
|
}
|
||||||
|
|
||||||
if (hints['image-data'] || hints['image-path']) {
|
// We only display a large image if an icon is also specified.
|
||||||
|
if (icon && (hints['image-data'] || hints['image-path'])) {
|
||||||
let image = null;
|
let image = null;
|
||||||
if (hints['image-data']) {
|
if (hints['image-data']) {
|
||||||
let [width, height, rowStride, hasAlpha,
|
let [width, height, rowStride, hasAlpha,
|
||||||
@ -427,17 +455,13 @@ NotificationDaemon.prototype = {
|
|||||||
},
|
},
|
||||||
|
|
||||||
_emitNotificationClosed: function(id, reason) {
|
_emitNotificationClosed: function(id, reason) {
|
||||||
DBus.session.emit_signal('/org/freedesktop/Notifications',
|
this._dbusImpl.emit_signal('NotificationClosed',
|
||||||
'org.freedesktop.Notifications',
|
GLib.Variant.new('(uu)', [id, reason]));
|
||||||
'NotificationClosed', 'uu',
|
|
||||||
[id, reason]);
|
|
||||||
},
|
},
|
||||||
|
|
||||||
_emitActionInvoked: function(id, action) {
|
_emitActionInvoked: function(id, action) {
|
||||||
DBus.session.emit_signal('/org/freedesktop/Notifications',
|
this._dbusImpl.emit_signal('ActionInvoked',
|
||||||
'org.freedesktop.Notifications',
|
GLib.Variant.new('(us)', [id, action]));
|
||||||
'ActionInvoked', 'us',
|
|
||||||
[id, action]);
|
|
||||||
},
|
},
|
||||||
|
|
||||||
_onTrayIconAdded: function(o, icon) {
|
_onTrayIconAdded: function(o, icon) {
|
||||||
@ -452,8 +476,6 @@ NotificationDaemon.prototype = {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
DBus.conformExport(NotificationDaemon.prototype, NotificationDaemonIface);
|
|
||||||
|
|
||||||
function Source(title, pid, sender) {
|
function Source(title, pid, sender) {
|
||||||
this._init(title, pid, sender);
|
this._init(title, pid, sender);
|
||||||
}
|
}
|
||||||
@ -466,15 +488,12 @@ Source.prototype = {
|
|||||||
|
|
||||||
this._pid = pid;
|
this._pid = pid;
|
||||||
if (sender)
|
if (sender)
|
||||||
// TODO: dbus-glib implementation of watch_name() doesn’t return an id to be used for
|
this._nameWatcherId = Gio.DBus.session.watch_name(sender,
|
||||||
// unwatch_name() or implement unwatch_name(), however when we move to using GDBus implementation,
|
Gio.BusNameWatcherFlags.NONE,
|
||||||
// we should save the id here and call unwatch_name() with it in destroy().
|
null,
|
||||||
// Moving to GDBus is the work in progress: https://bugzilla.gnome.org/show_bug.cgi?id=648651
|
Lang.bind(this, this._onNameVanished));
|
||||||
// and https://bugzilla.gnome.org/show_bug.cgi?id=622921 .
|
else
|
||||||
DBus.session.watch_name(sender,
|
this._nameWatcherId = 0;
|
||||||
false,
|
|
||||||
null,
|
|
||||||
Lang.bind(this, this._onNameVanished));
|
|
||||||
|
|
||||||
this._setApp();
|
this._setApp();
|
||||||
if (this.app)
|
if (this.app)
|
||||||
@ -582,6 +601,11 @@ Source.prototype = {
|
|||||||
},
|
},
|
||||||
|
|
||||||
destroy: function() {
|
destroy: function() {
|
||||||
|
if (this._nameWatcherId) {
|
||||||
|
Gio.DBus.session.unwatch_name(this._nameWatcherId);
|
||||||
|
this._nameWatcherId = 0;
|
||||||
|
}
|
||||||
|
|
||||||
MessageTray.Source.prototype.destroy.call(this);
|
MessageTray.Source.prototype.destroy.call(this);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
/* -*- mode: js2; js2-basic-offset: 4; indent-tabs-mode: nil -*- */
|
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
|
||||||
|
|
||||||
const Clutter = imports.gi.Clutter;
|
const Clutter = imports.gi.Clutter;
|
||||||
const Gtk = imports.gi.Gtk;
|
const Gtk = imports.gi.Gtk;
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
/* -*- mode: js2; js2-basic-offset: 4; indent-tabs-mode: nil -*- */
|
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
|
||||||
|
|
||||||
const Cairo = imports.cairo;
|
const Cairo = imports.cairo;
|
||||||
const Clutter = imports.gi.Clutter;
|
const Clutter = imports.gi.Clutter;
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
/* -*- mode: js2; js2-basic-offset: 4; indent-tabs-mode: nil -*- */
|
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
|
||||||
|
|
||||||
const Clutter = imports.gi.Clutter;
|
const Clutter = imports.gi.Clutter;
|
||||||
const Gtk = imports.gi.Gtk;
|
const Gtk = imports.gi.Gtk;
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
/* -*- mode: js2; js2-basic-offset: 4; indent-tabs-mode: nil -*- */
|
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
|
||||||
|
|
||||||
const GLib = imports.gi.GLib;
|
const GLib = imports.gi.GLib;
|
||||||
const Gio = imports.gi.Gio;
|
const Gio = imports.gi.Gio;
|
||||||
@ -195,9 +195,9 @@ PlacesManager.prototype = {
|
|||||||
|
|
||||||
this._bookmarksPath = GLib.build_filenamev([GLib.get_home_dir(), '.gtk-bookmarks']);
|
this._bookmarksPath = GLib.build_filenamev([GLib.get_home_dir(), '.gtk-bookmarks']);
|
||||||
this._bookmarksFile = Gio.file_new_for_path(this._bookmarksPath);
|
this._bookmarksFile = Gio.file_new_for_path(this._bookmarksPath);
|
||||||
let 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;
|
||||||
monitor.connect('changed', Lang.bind(this, function () {
|
this._monitor.connect('changed', Lang.bind(this, function () {
|
||||||
if (this._bookmarkTimeoutId > 0)
|
if (this._bookmarkTimeoutId > 0)
|
||||||
return;
|
return;
|
||||||
/* Defensive event compression */
|
/* Defensive event compression */
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/* -*- mode: js2; js2-basic-offset: 4; indent-tabs-mode: nil -*-
|
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
|
||||||
*
|
/*
|
||||||
* Copyright 2010 Red Hat, Inc
|
* Copyright 2010 Red Hat, Inc
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* This program is free software; you can redistribute it and/or modify
|
||||||
@ -27,12 +27,14 @@ const AccountsService = imports.gi.AccountsService;
|
|||||||
const Clutter = imports.gi.Clutter;
|
const Clutter = imports.gi.Clutter;
|
||||||
const St = imports.gi.St;
|
const St = imports.gi.St;
|
||||||
const Pango = imports.gi.Pango;
|
const Pango = imports.gi.Pango;
|
||||||
|
const GLib = imports.gi.GLib;
|
||||||
const Gio = imports.gi.Gio;
|
const Gio = imports.gi.Gio;
|
||||||
const Mainloop = imports.mainloop;
|
const Mainloop = imports.mainloop;
|
||||||
const Polkit = imports.gi.Polkit;
|
const Polkit = imports.gi.Polkit;
|
||||||
const PolkitAgent = imports.gi.PolkitAgent;
|
const PolkitAgent = imports.gi.PolkitAgent;
|
||||||
|
|
||||||
const ModalDialog = imports.ui.modalDialog;
|
const ModalDialog = imports.ui.modalDialog;
|
||||||
|
const ShellEntry = imports.ui.shellEntry;
|
||||||
|
|
||||||
function AuthenticationDialog(actionId, message, cookie, userNames) {
|
function AuthenticationDialog(actionId, message, cookie, userNames) {
|
||||||
this._init(actionId, message, cookie, userNames);
|
this._init(actionId, message, cookie, userNames);
|
||||||
@ -87,10 +89,14 @@ AuthenticationDialog.prototype = {
|
|||||||
if (userNames.length > 1) {
|
if (userNames.length > 1) {
|
||||||
log('polkitAuthenticationAgent: Received ' + userNames.length +
|
log('polkitAuthenticationAgent: Received ' + userNames.length +
|
||||||
' identities that can be used for authentication. Only ' +
|
' identities that can be used for authentication. Only ' +
|
||||||
'considering the first one.');
|
'considering one.');
|
||||||
}
|
}
|
||||||
|
|
||||||
let userName = userNames[0];
|
let userName = GLib.get_user_name();
|
||||||
|
if (userNames.indexOf(userName) < 0)
|
||||||
|
userName = 'root';
|
||||||
|
if (userNames.indexOf(userName) < 0)
|
||||||
|
userName = userNames[0];
|
||||||
|
|
||||||
this._user = AccountsService.UserManager.get_default().get_user(userName);
|
this._user = AccountsService.UserManager.get_default().get_user(userName);
|
||||||
let userRealName = this._user.get_real_name()
|
let userRealName = this._user.get_real_name()
|
||||||
@ -139,6 +145,7 @@ AuthenticationDialog.prototype = {
|
|||||||
this._passwordEntry = new St.Entry({ style_class: 'polkit-dialog-password-entry',
|
this._passwordEntry = new St.Entry({ style_class: 'polkit-dialog-password-entry',
|
||||||
text: "",
|
text: "",
|
||||||
can_focus: true});
|
can_focus: true});
|
||||||
|
ShellEntry.addContextMenu(this._passwordEntry, { isPassword: true });
|
||||||
this._passwordEntry.clutter_text.connect('activate', Lang.bind(this, this._onEntryActivate));
|
this._passwordEntry.clutter_text.connect('activate', Lang.bind(this, this._onEntryActivate));
|
||||||
this._passwordBox.add(this._passwordEntry,
|
this._passwordBox.add(this._passwordEntry,
|
||||||
{expand: true });
|
{expand: true });
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
/* -*- mode: js2; js2-basic-offset: 4; indent-tabs-mode: nil -*- */
|
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
|
||||||
|
|
||||||
const Cairo = imports.cairo;
|
const Cairo = imports.cairo;
|
||||||
const Clutter = imports.gi.Clutter;
|
const Clutter = imports.gi.Clutter;
|
||||||
@ -108,14 +108,16 @@ PopupBaseMenuItem.prototype = {
|
|||||||
this.emit('activate', event);
|
this.emit('activate', event);
|
||||||
},
|
},
|
||||||
|
|
||||||
setActive: function (active) {
|
setActive: function (active, params) {
|
||||||
let activeChanged = active != this.active;
|
let activeChanged = active != this.active;
|
||||||
|
params = Params.parse (params, { grabKeyboard: true });
|
||||||
|
|
||||||
if (activeChanged) {
|
if (activeChanged) {
|
||||||
this.active = active;
|
this.active = active;
|
||||||
if (active) {
|
if (active) {
|
||||||
this.actor.add_style_pseudo_class('active');
|
this.actor.add_style_pseudo_class('active');
|
||||||
this.actor.grab_key_focus();
|
if (params.grabKeyboard)
|
||||||
|
this.actor.grab_key_focus();
|
||||||
} else
|
} else
|
||||||
this.actor.remove_style_pseudo_class('active');
|
this.actor.remove_style_pseudo_class('active');
|
||||||
this.emit('active-changed', active);
|
this.emit('active-changed', active);
|
||||||
@ -320,10 +322,14 @@ PopupBaseMenuItem.prototype = {
|
|||||||
}
|
}
|
||||||
extraWidth = availWidth - naturalWidth;
|
extraWidth = availWidth - naturalWidth;
|
||||||
} else {
|
} else {
|
||||||
if (child.span == -1)
|
if (child.span == -1) {
|
||||||
availWidth = box.x2 - x;
|
if (direction == St.TextDirection.LTR)
|
||||||
else
|
availWidth = box.x2 - x;
|
||||||
|
else
|
||||||
|
availWidth = x - box.x1;
|
||||||
|
} else {
|
||||||
availWidth = naturalWidth;
|
availWidth = naturalWidth;
|
||||||
|
}
|
||||||
extraWidth = 0;
|
extraWidth = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1015,6 +1021,11 @@ PopupMenuBase.prototype = {
|
|||||||
}
|
}
|
||||||
if (menuItem instanceof PopupMenuSection) {
|
if (menuItem instanceof PopupMenuSection) {
|
||||||
this._connectSubMenuSignals(menuItem, menuItem);
|
this._connectSubMenuSignals(menuItem, menuItem);
|
||||||
|
menuItem._closingId = this.connect('open-state-changed',
|
||||||
|
function(self, open) {
|
||||||
|
if (!open)
|
||||||
|
menuItem.close(false);
|
||||||
|
});
|
||||||
menuItem.connect('destroy', Lang.bind(this, function() {
|
menuItem.connect('destroy', Lang.bind(this, function() {
|
||||||
menuItem.disconnect(menuItem._subMenuActivateId);
|
menuItem.disconnect(menuItem._subMenuActivateId);
|
||||||
menuItem.disconnect(menuItem._subMenuActiveChangeId);
|
menuItem.disconnect(menuItem._subMenuActiveChangeId);
|
||||||
@ -1138,10 +1149,10 @@ function PopupMenu() {
|
|||||||
PopupMenu.prototype = {
|
PopupMenu.prototype = {
|
||||||
__proto__: PopupMenuBase.prototype,
|
__proto__: PopupMenuBase.prototype,
|
||||||
|
|
||||||
_init: function(sourceActor, alignment, arrowSide) {
|
_init: function(sourceActor, arrowAlignment, arrowSide) {
|
||||||
PopupMenuBase.prototype._init.call (this, sourceActor, 'popup-menu-content');
|
PopupMenuBase.prototype._init.call (this, sourceActor, 'popup-menu-content');
|
||||||
|
|
||||||
this._alignment = alignment;
|
this._arrowAlignment = arrowAlignment;
|
||||||
this._arrowSide = arrowSide;
|
this._arrowSide = arrowSide;
|
||||||
|
|
||||||
this._boxPointer = new BoxPointer.BoxPointer(arrowSide,
|
this._boxPointer = new BoxPointer.BoxPointer(arrowSide,
|
||||||
@ -1194,13 +1205,17 @@ PopupMenu.prototype = {
|
|||||||
this._boxPointer.setArrowOrigin(origin);
|
this._boxPointer.setArrowOrigin(origin);
|
||||||
},
|
},
|
||||||
|
|
||||||
|
setSourceAlignment: function(alignment) {
|
||||||
|
this._boxPointer.setSourceAlignment(alignment);
|
||||||
|
},
|
||||||
|
|
||||||
open: function(animate) {
|
open: function(animate) {
|
||||||
if (this.isOpen)
|
if (this.isOpen)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
this.isOpen = true;
|
this.isOpen = true;
|
||||||
|
|
||||||
this._boxPointer.setPosition(this.sourceActor, this._alignment);
|
this._boxPointer.setPosition(this.sourceActor, this._arrowAlignment);
|
||||||
this._boxPointer.show(animate);
|
this._boxPointer.show(animate);
|
||||||
|
|
||||||
this.actor.raise_top();
|
this.actor.raise_top();
|
||||||
@ -1410,9 +1425,10 @@ PopupMenuSection.prototype = {
|
|||||||
this.isOpen = true;
|
this.isOpen = true;
|
||||||
},
|
},
|
||||||
|
|
||||||
// deliberately ignore any attempt to open() or close()
|
// deliberately ignore any attempt to open() or close(), but emit the
|
||||||
open: function(animate) { },
|
// corresponding signal so children can still pick it up
|
||||||
close: function() { },
|
open: function(animate) { this.emit('open-state-changed', true); },
|
||||||
|
close: function() { this.emit('open-state-changed', false); },
|
||||||
}
|
}
|
||||||
|
|
||||||
function PopupSubMenuMenuItem() {
|
function PopupSubMenuMenuItem() {
|
||||||
@ -1486,6 +1502,8 @@ PopupComboMenu.prototype = {
|
|||||||
this.actor._delegate = this;
|
this.actor._delegate = this;
|
||||||
this.actor.connect('key-press-event', Lang.bind(this, this._onKeyPressEvent));
|
this.actor.connect('key-press-event', Lang.bind(this, this._onKeyPressEvent));
|
||||||
this.actor.connect('key-focus-in', Lang.bind(this, this._onKeyFocusIn));
|
this.actor.connect('key-focus-in', Lang.bind(this, this._onKeyFocusIn));
|
||||||
|
sourceActor.connect('style-changed',
|
||||||
|
Lang.bind(this, this._onSourceActorStyleChanged));
|
||||||
this._activeItemPos = -1;
|
this._activeItemPos = -1;
|
||||||
global.focus_manager.add_group(this.actor);
|
global.focus_manager.add_group(this.actor);
|
||||||
},
|
},
|
||||||
@ -1505,6 +1523,26 @@ PopupComboMenu.prototype = {
|
|||||||
activeItem.actor.grab_key_focus();
|
activeItem.actor.grab_key_focus();
|
||||||
},
|
},
|
||||||
|
|
||||||
|
_onSourceActorStyleChanged: function() {
|
||||||
|
// PopupComboBoxMenuItem clones the active item's actors
|
||||||
|
// to work with arbitrary items in the menu; this means
|
||||||
|
// that we need to propagate some style information and
|
||||||
|
// enforce style updates even when the menu is closed
|
||||||
|
let activeItem = this._getMenuItems()[this._activeItemPos];
|
||||||
|
if (this.sourceActor.has_style_pseudo_class('insensitive'))
|
||||||
|
activeItem.actor.add_style_pseudo_class('insensitive');
|
||||||
|
else
|
||||||
|
activeItem.actor.remove_style_pseudo_class('insensitive');
|
||||||
|
|
||||||
|
// To propagate the :active style, we need to make sure that the
|
||||||
|
// internal state of the PopupComboMenu is updated as well, but
|
||||||
|
// we must not move the keyboard grab
|
||||||
|
activeItem.setActive(this.sourceActor.has_style_pseudo_class('active'),
|
||||||
|
{ grabKeyboard: false });
|
||||||
|
|
||||||
|
_ensureStyle(this.actor);
|
||||||
|
},
|
||||||
|
|
||||||
open: function() {
|
open: function() {
|
||||||
if (this.isOpen)
|
if (this.isOpen)
|
||||||
return;
|
return;
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
/* -*- mode: js2; js2-basic-offset: 4; indent-tabs-mode: nil -*- */
|
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
|
||||||
|
|
||||||
const Clutter = imports.gi.Clutter;
|
const Clutter = imports.gi.Clutter;
|
||||||
const Gio = imports.gi.Gio;
|
const Gio = imports.gi.Gio;
|
||||||
@ -12,6 +12,7 @@ const Signals = imports.signals;
|
|||||||
const FileUtils = imports.misc.fileUtils;
|
const FileUtils = imports.misc.fileUtils;
|
||||||
const Main = imports.ui.main;
|
const Main = imports.ui.main;
|
||||||
const ModalDialog = imports.ui.modalDialog;
|
const ModalDialog = imports.ui.modalDialog;
|
||||||
|
const ShellEntry = imports.ui.shellEntry;
|
||||||
const Tweener = imports.ui.tweener;
|
const Tweener = imports.ui.tweener;
|
||||||
const Util = imports.misc.util;
|
const Util = imports.misc.util;
|
||||||
const History = imports.misc.history;
|
const History = imports.misc.history;
|
||||||
@ -210,6 +211,7 @@ __proto__: ModalDialog.ModalDialog.prototype,
|
|||||||
this.contentLayout.add(label, { y_align: St.Align.START });
|
this.contentLayout.add(label, { y_align: St.Align.START });
|
||||||
|
|
||||||
let entry = new St.Entry({ style_class: 'run-dialog-entry' });
|
let entry = new St.Entry({ style_class: 'run-dialog-entry' });
|
||||||
|
ShellEntry.addContextMenu(entry);
|
||||||
|
|
||||||
this._entryText = entry.clutter_text;
|
this._entryText = entry.clutter_text;
|
||||||
this.contentLayout.add(entry, { y_align: St.Align.START });
|
this.contentLayout.add(entry, { y_align: St.Align.START });
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
/* -*- mode: js2; js2-basic-offset: 4; indent-tabs-mode: nil -*- */
|
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
|
||||||
|
|
||||||
const DBus = imports.dbus;
|
|
||||||
const Gio = imports.gi.Gio;
|
const Gio = imports.gi.Gio;
|
||||||
const Mainloop = imports.mainloop;
|
const Mainloop = imports.mainloop;
|
||||||
const Meta = imports.gi.Meta;
|
const Meta = imports.gi.Meta;
|
||||||
@ -70,24 +69,21 @@ function waitLeisure() {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
const PerfHelperIface = {
|
const PerfHelperIface = <interface name="org.gnome.Shell.PerfHelper">
|
||||||
name: 'org.gnome.Shell.PerfHelper',
|
<method name="CreateWindow">
|
||||||
methods: [{ name: 'CreateWindow', inSignature: 'iibb', outSignature: '' },
|
<arg type="i" direction="in" />
|
||||||
{ name: 'WaitWindows', inSignature: '', outSignature: '' },
|
<arg type="i" direction="in" />
|
||||||
{ name: 'DestroyWindows', inSignature: '', outSignature: ''}]
|
<arg type="b" direction="in" />
|
||||||
};
|
<arg type="b" direction="in" />
|
||||||
|
</method>
|
||||||
|
<method name="WaitWindows" />
|
||||||
|
<method name="DestroyWindows" />
|
||||||
|
</interface>;
|
||||||
|
|
||||||
const PerfHelper = function () {
|
var PerfHelperProxy = Gio.DBusProxy.makeProxyWrapper(PerfHelperIface);
|
||||||
this._init();
|
function PerfHelper() {
|
||||||
};
|
return new PerfHelperProxy(Gio.DBus.session, 'org.gnome.Shell.PerfHelper', '/org/gnome/Shell/PerfHelper');
|
||||||
|
}
|
||||||
PerfHelper.prototype = {
|
|
||||||
_init: function() {
|
|
||||||
DBus.session.proxifyObject(this, 'org.gnome.Shell.PerfHelper', '/org/gnome/Shell/PerfHelper');
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
DBus.proxifyPrototype(PerfHelper.prototype, PerfHelperIface);
|
|
||||||
|
|
||||||
let _perfHelper = null;
|
let _perfHelper = null;
|
||||||
function _getPerfHelper() {
|
function _getPerfHelper() {
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
/* -*- mode: js2; js2-basic-offset: 4; indent-tabs-mode: nil -*- */
|
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
|
||||||
|
|
||||||
const Gio = imports.gi.Gio;
|
const Gio = imports.gi.Gio;
|
||||||
const GLib = imports.gi.GLib;
|
const GLib = imports.gi.GLib;
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
/* -*- mode: js2; js2-basic-offset: 4; indent-tabs-mode: nil -*- */
|
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
|
||||||
|
|
||||||
const Clutter = imports.gi.Clutter;
|
const Clutter = imports.gi.Clutter;
|
||||||
const Lang = imports.lang;
|
const Lang = imports.lang;
|
||||||
|
@ -1,71 +1,70 @@
|
|||||||
/* -*- mode: js2; js2-basic-offset: 4; indent-tabs-mode: nil -*- */
|
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
|
||||||
|
|
||||||
const DBus = imports.dbus;
|
|
||||||
const Lang = imports.lang;
|
const Lang = imports.lang;
|
||||||
|
const Gio = imports.gi.Gio;
|
||||||
|
const GLib = imports.gi.GLib;
|
||||||
|
|
||||||
const Config = imports.misc.config;
|
const Config = imports.misc.config;
|
||||||
const ExtensionSystem = imports.ui.extensionSystem;
|
const ExtensionSystem = imports.ui.extensionSystem;
|
||||||
const Main = imports.ui.main;
|
const Main = imports.ui.main;
|
||||||
|
|
||||||
const GnomeShellIface = {
|
const GnomeShellIface = <interface name="org.gnome.Shell">
|
||||||
name: 'org.gnome.Shell',
|
<method name="Eval">
|
||||||
methods: [{ name: 'Eval',
|
<arg type="s" direction="in" name="script" />
|
||||||
inSignature: 's',
|
<arg type="b" direction="out" name="success" />
|
||||||
outSignature: 'bs'
|
<arg type="s" direction="out" name="result" />
|
||||||
},
|
</method>
|
||||||
{ name: 'ListExtensions',
|
<method name="ListExtensions">
|
||||||
inSignature: '',
|
<arg type="a{sa{sv}}" direction="out" name="extensions" />
|
||||||
outSignature: 'a{sa{sv}}'
|
</method>
|
||||||
},
|
<method name="GetExtensionInfo">
|
||||||
{ name: 'GetExtensionInfo',
|
<arg type="s" direction="in" name="extension" />
|
||||||
inSignature: 's',
|
<arg type="a{sv}" direction="out" name="info" />
|
||||||
outSignature: 'a{sv}'
|
</method>
|
||||||
},
|
<method name="GetExtensionErrors">
|
||||||
{ name: 'GetExtensionErrors',
|
<arg type="s" direction="in" name="extension" />
|
||||||
inSignature: 's',
|
<arg type="as" direction="out" name="errors" />
|
||||||
outSignature: 'as'
|
</method>
|
||||||
},
|
<method name="ScreenshotArea">
|
||||||
{ name: 'ScreenshotArea',
|
<arg type="i" direction="in" name="x"/>
|
||||||
inSignature: 'iiiis',
|
<arg type="i" direction="in" name="y"/>
|
||||||
outSignature: 'b'
|
<arg type="i" direction="in" name="width"/>
|
||||||
},
|
<arg type="i" direction="in" name="height"/>
|
||||||
{ name: 'ScreenshotWindow',
|
<arg type="s" direction="in" name="filename"/>
|
||||||
inSignature: 'bs',
|
<arg type="b" direction="out" name="success"/>
|
||||||
outSignature: 'b'
|
</method>
|
||||||
},
|
<method name="ScreenshotWindow">
|
||||||
{ name: 'Screenshot',
|
<arg type="b" direction="in" name="include_frame"/>
|
||||||
inSignature: 's',
|
<arg type="s" direction="in" name="filename"/>
|
||||||
outSignature: 'b'
|
<arg type="b" direction="out" name="success"/>
|
||||||
},
|
</method>
|
||||||
{ name: 'EnableExtension',
|
<method name="Screenshot">
|
||||||
inSignature: 's',
|
<arg type="s" direction="in" name="filename"/>
|
||||||
outSignature: ''
|
<arg type="b" direction="out" name="success"/>
|
||||||
},
|
</method>
|
||||||
{ name: 'DisableExtension',
|
<method name="EnableExtension">
|
||||||
inSignature: 's',
|
<arg type="s" direction="in" name="uuid"/>
|
||||||
outSignature: ''
|
</method>
|
||||||
},
|
<method name="DisableExtension">
|
||||||
{ name: 'InstallRemoteExtension',
|
<arg type="s" direction="in" name="uuid"/>
|
||||||
inSignature: 'ss',
|
</method>
|
||||||
outSignature: ''
|
<method name="InstallRemoteExtension">
|
||||||
},
|
<arg type="s" direction="in" name="uuid"/>
|
||||||
{ name: 'UninstallExtension',
|
<arg type="s" direction="in" name="version"/>
|
||||||
inSignature: 's',
|
</method>
|
||||||
outSignature: 'b'
|
<method name="UninstallExtension">
|
||||||
}
|
<arg type="s" direction="in" name="uuid"/>
|
||||||
],
|
<arg type="b" direction="out" name="success"/>
|
||||||
signals: [{ name: 'ExtensionStatusChanged',
|
</method>
|
||||||
inSignature: 'sis' }],
|
<property name="OverviewActive" type="b" access="readwrite" />
|
||||||
properties: [{ name: 'OverviewActive',
|
<property name="ApiVersion" type="i" access="read" />
|
||||||
signature: 'b',
|
<property name="ShellVersion" type="s" access="read" />
|
||||||
access: 'readwrite' },
|
<signal name="ExtensionStatusChanged">
|
||||||
{ name: 'ApiVersion',
|
<arg type="s" name="uuid"/>
|
||||||
signature: 'i',
|
<arg type="i" name="state"/>
|
||||||
access: 'read' },
|
<arg type="s" name="error"/>
|
||||||
{ name: 'ShellVersion',
|
</signal>
|
||||||
signature: 's',
|
</interface>;
|
||||||
access: 'read' }]
|
|
||||||
};
|
|
||||||
|
|
||||||
function GnomeShell() {
|
function GnomeShell() {
|
||||||
this._init();
|
this._init();
|
||||||
@ -73,7 +72,8 @@ function GnomeShell() {
|
|||||||
|
|
||||||
GnomeShell.prototype = {
|
GnomeShell.prototype = {
|
||||||
_init: function() {
|
_init: function() {
|
||||||
DBus.session.exportObject('/org/gnome/Shell', this);
|
this._dbusImpl = Gio.DBusExportedObject.wrapJSObject(GnomeShellIface, this);
|
||||||
|
this._dbusImpl.export(Gio.DBus.session, '/org/gnome/Shell');
|
||||||
ExtensionSystem.connect('extension-state-changed',
|
ExtensionSystem.connect('extension-state-changed',
|
||||||
Lang.bind(this, this._extensionStateChanged));
|
Lang.bind(this, this._extensionStateChanged));
|
||||||
},
|
},
|
||||||
@ -93,6 +93,9 @@ GnomeShell.prototype = {
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
Eval: function(code) {
|
Eval: function(code) {
|
||||||
|
if (!global.settings.get_boolean('development-tools'))
|
||||||
|
return [false, null];
|
||||||
|
|
||||||
let returnValue;
|
let returnValue;
|
||||||
let success;
|
let success;
|
||||||
try {
|
try {
|
||||||
@ -153,11 +156,33 @@ GnomeShell.prototype = {
|
|||||||
},
|
},
|
||||||
|
|
||||||
ListExtensions: function() {
|
ListExtensions: function() {
|
||||||
return ExtensionSystem.extensionMeta;
|
let out = {};
|
||||||
|
for (let uuid in ExtensionSystem.extensionMeta) {
|
||||||
|
let dbusObj = this.GetExtensionInfo(uuid);
|
||||||
|
out[uuid] = dbusObj;
|
||||||
|
}
|
||||||
|
return out;
|
||||||
},
|
},
|
||||||
|
|
||||||
GetExtensionInfo: function(uuid) {
|
GetExtensionInfo: function(uuid) {
|
||||||
return ExtensionSystem.extensionMeta[uuid] || {};
|
let meta = ExtensionSystem.extensionMeta[uuid] || {};
|
||||||
|
let out = {};
|
||||||
|
for (let key in meta) {
|
||||||
|
let val = meta[key];
|
||||||
|
let type;
|
||||||
|
switch (typeof val) {
|
||||||
|
case 'string':
|
||||||
|
type = 's';
|
||||||
|
break;
|
||||||
|
case 'number':
|
||||||
|
type = 'd';
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
out[key] = GLib.Variant.new(type, val);
|
||||||
|
}
|
||||||
|
return out;
|
||||||
},
|
},
|
||||||
|
|
||||||
GetExtensionErrors: function(uuid) {
|
GetExtensionErrors: function(uuid) {
|
||||||
@ -202,12 +227,7 @@ GnomeShell.prototype = {
|
|||||||
ShellVersion: Config.PACKAGE_VERSION,
|
ShellVersion: Config.PACKAGE_VERSION,
|
||||||
|
|
||||||
_extensionStateChanged: function(_, newState) {
|
_extensionStateChanged: function(_, newState) {
|
||||||
DBus.session.emit_signal('/org/gnome/Shell',
|
this._dbusImpl.emit_signal('ExtensionStatusChanged',
|
||||||
'org.gnome.Shell',
|
GLib.Variant.new('(sis)', [newState.uuid, newState.state, newState.error]));
|
||||||
'ExtensionStatusChanged', 'sis',
|
|
||||||
[newState.uuid, newState.state, newState.error]);
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
DBus.conformExport(GnomeShell.prototype, GnomeShellIface);
|
|
||||||
|
|
||||||
|
173
js/ui/shellEntry.js
Normal file
173
js/ui/shellEntry.js
Normal file
@ -0,0 +1,173 @@
|
|||||||
|
const Clutter = imports.gi.Clutter;
|
||||||
|
const Gtk = imports.gi.Gtk;
|
||||||
|
const Lang = imports.lang;
|
||||||
|
const St = imports.gi.St;
|
||||||
|
|
||||||
|
const Main = imports.ui.main;
|
||||||
|
const Params = imports.misc.params;
|
||||||
|
const PopupMenu = imports.ui.popupMenu;
|
||||||
|
|
||||||
|
|
||||||
|
function _EntryMenu(entry, params) {
|
||||||
|
this._init(entry, params);
|
||||||
|
};
|
||||||
|
|
||||||
|
_EntryMenu.prototype = {
|
||||||
|
__proto__: PopupMenu.PopupMenu.prototype,
|
||||||
|
|
||||||
|
_init: function(entry, params) {
|
||||||
|
params = Params.parse (params, { isPassword: false });
|
||||||
|
|
||||||
|
PopupMenu.PopupMenu.prototype._init.call(this, entry, 0, St.Side.TOP);
|
||||||
|
|
||||||
|
this.actor.add_style_class_name('entry-context-menu');
|
||||||
|
|
||||||
|
this._entry = entry;
|
||||||
|
this._clipboard = St.Clipboard.get_default();
|
||||||
|
|
||||||
|
// Populate menu
|
||||||
|
let item;
|
||||||
|
item = new PopupMenu.PopupMenuItem(_("Copy"));
|
||||||
|
item.connect('activate', Lang.bind(this, this._onCopyActivated));
|
||||||
|
this.addMenuItem(item);
|
||||||
|
this._copyItem = item;
|
||||||
|
|
||||||
|
item = new PopupMenu.PopupMenuItem(_("Paste"));
|
||||||
|
item.connect('activate', Lang.bind(this, this._onPasteActivated));
|
||||||
|
this.addMenuItem(item);
|
||||||
|
this._pasteItem = item;
|
||||||
|
|
||||||
|
this._passwordItem = null;
|
||||||
|
if (params.isPassword) {
|
||||||
|
item = new PopupMenu.PopupMenuItem('');
|
||||||
|
item.connect('activate', Lang.bind(this,
|
||||||
|
this._onPasswordActivated));
|
||||||
|
this.addMenuItem(item);
|
||||||
|
this._passwordItem = item;
|
||||||
|
}
|
||||||
|
|
||||||
|
Main.uiGroup.add_actor(this.actor);
|
||||||
|
this.actor.hide();
|
||||||
|
},
|
||||||
|
|
||||||
|
open: function() {
|
||||||
|
this._updatePasteItem();
|
||||||
|
this._updateCopyItem();
|
||||||
|
if (this._passwordItem)
|
||||||
|
this._updatePasswordItem();
|
||||||
|
|
||||||
|
let direction = Gtk.DirectionType.TAB_FORWARD;
|
||||||
|
if (!this.actor.navigate_focus(null, direction, false))
|
||||||
|
this.actor.grab_key_focus();
|
||||||
|
|
||||||
|
PopupMenu.PopupMenu.prototype.open.call(this);
|
||||||
|
},
|
||||||
|
|
||||||
|
_updateCopyItem: function() {
|
||||||
|
let selection = this._entry.clutter_text.get_selection();
|
||||||
|
this._copyItem.setSensitive(selection && selection != '');
|
||||||
|
},
|
||||||
|
|
||||||
|
_updatePasteItem: function() {
|
||||||
|
this._clipboard.get_text(Lang.bind(this,
|
||||||
|
function(clipboard, text) {
|
||||||
|
this._pasteItem.setSensitive(text && text != '');
|
||||||
|
}));
|
||||||
|
},
|
||||||
|
|
||||||
|
_updatePasswordItem: function() {
|
||||||
|
let textHidden = (this._entry.clutter_text.password_char);
|
||||||
|
if (textHidden)
|
||||||
|
this._passwordItem.label.set_text(_("Show Text"));
|
||||||
|
else
|
||||||
|
this._passwordItem.label.set_text(_("Hide Text"));
|
||||||
|
},
|
||||||
|
|
||||||
|
_onCopyActivated: function() {
|
||||||
|
let selection = this._entry.clutter_text.get_selection();
|
||||||
|
this._clipboard.set_text(selection);
|
||||||
|
},
|
||||||
|
|
||||||
|
_onPasteActivated: function() {
|
||||||
|
this._clipboard.get_text(Lang.bind(this,
|
||||||
|
function(clipboard, text) {
|
||||||
|
if (!text)
|
||||||
|
return;
|
||||||
|
this._entry.clutter_text.delete_selection();
|
||||||
|
let pos = this._entry.clutter_text.get_cursor_position();
|
||||||
|
this._entry.clutter_text.insert_text(text, pos);
|
||||||
|
}));
|
||||||
|
},
|
||||||
|
|
||||||
|
_onPasswordActivated: function() {
|
||||||
|
let visible = !!(this._entry.clutter_text.password_char);
|
||||||
|
this._entry.clutter_text.set_password_char(visible ? '' : '\u25cf');
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
function _setMenuAlignment(entry, stageX) {
|
||||||
|
let [success, entryX, entryY] = entry.transform_stage_point(stageX, 0);
|
||||||
|
if (success)
|
||||||
|
entry._menu.setSourceAlignment(entryX / entry.width);
|
||||||
|
};
|
||||||
|
|
||||||
|
function _onClicked(action, actor) {
|
||||||
|
let entry = actor._menu ? actor : actor.get_parent();
|
||||||
|
|
||||||
|
if (entry._menu.isOpen) {
|
||||||
|
entry._menu.close();
|
||||||
|
} else if (action.get_button() == 3) {
|
||||||
|
let [stageX, stageY] = action.get_coords();
|
||||||
|
_setMenuAlignment(entry, stageX);
|
||||||
|
entry._menu.open();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
function _onLongPress(action, actor, state) {
|
||||||
|
let entry = actor._menu ? actor : actor.get_parent();
|
||||||
|
|
||||||
|
if (state == Clutter.LongPressState.QUERY)
|
||||||
|
return action.get_button() == 1 && !entry._menu.isOpen;
|
||||||
|
|
||||||
|
if (state == Clutter.LongPressState.ACTIVATE) {
|
||||||
|
let [stageX, stageY] = action.get_coords();
|
||||||
|
_setMenuAlignment(entry, stageX);
|
||||||
|
entry._menu.open();
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
};
|
||||||
|
|
||||||
|
function _onPopup(actor) {
|
||||||
|
let entry = actor._menu ? actor : actor.get_parent();
|
||||||
|
let [success, textX, textY, lineHeight] = entry.clutter_text.position_to_coords(-1);
|
||||||
|
if (success)
|
||||||
|
entry._menu.setSourceAlignment(textX / entry.width);
|
||||||
|
entry._menu.open();
|
||||||
|
};
|
||||||
|
|
||||||
|
function addContextMenu(entry, params) {
|
||||||
|
if (entry._menu)
|
||||||
|
return;
|
||||||
|
|
||||||
|
entry._menu = new _EntryMenu(entry, params);
|
||||||
|
entry._menuManager = new PopupMenu.PopupMenuManager({ actor: entry });
|
||||||
|
entry._menuManager.addMenu(entry._menu);
|
||||||
|
|
||||||
|
let clickAction;
|
||||||
|
|
||||||
|
// Add a click action to both the entry and its clutter_text; the former
|
||||||
|
// so padding is included in the clickable area, the latter because the
|
||||||
|
// event processing of ClutterText prevents event-bubbling.
|
||||||
|
clickAction = new Clutter.ClickAction();
|
||||||
|
clickAction.connect('clicked', _onClicked);
|
||||||
|
clickAction.connect('long-press', _onLongPress);
|
||||||
|
entry.clutter_text.add_action(clickAction);
|
||||||
|
|
||||||
|
clickAction = new Clutter.ClickAction();
|
||||||
|
clickAction.connect('clicked', _onClicked);
|
||||||
|
clickAction.connect('long-press', _onLongPress);
|
||||||
|
entry.add_action(clickAction);
|
||||||
|
|
||||||
|
entry.connect('popup-menu', _onPopup);
|
||||||
|
}
|
@ -1,4 +1,4 @@
|
|||||||
/* -*- mode: js2; js2-basic-offset: 4; indent-tabs-mode: nil -*- */
|
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
|
||||||
|
|
||||||
const Lang = imports.lang;
|
const Lang = imports.lang;
|
||||||
const Signals = imports.signals;
|
const Signals = imports.signals;
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/* -*- mode: js2; js2-basic-offset: 4; indent-tabs-mode: nil -*- */
|
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
|
||||||
|
|
||||||
const DBus = imports.dbus;
|
const DBus = imports.dbus;
|
||||||
const GConf = imports.gi.GConf;
|
const GDesktopEnums = imports.gi.GDesktopEnums;
|
||||||
const Gio = imports.gi.Gio;
|
const Gio = imports.gi.Gio;
|
||||||
const Gtk = imports.gi.Gtk;
|
const Gtk = imports.gi.Gtk;
|
||||||
const Lang = imports.lang;
|
const Lang = imports.lang;
|
||||||
@ -30,8 +30,8 @@ const DPI_FACTOR_LARGE = 1.25;
|
|||||||
const DPI_FACTOR_LARGER = 1.5;
|
const DPI_FACTOR_LARGER = 1.5;
|
||||||
const DPI_FACTOR_LARGEST = 2.0;
|
const DPI_FACTOR_LARGEST = 2.0;
|
||||||
|
|
||||||
const KEY_META_DIR = '/apps/metacity/general';
|
const WM_SCHEMA = 'org.gnome.desktop.wm.preferences';
|
||||||
const KEY_VISUAL_BELL = KEY_META_DIR + '/visual_bell';
|
const KEY_VISUAL_BELL = 'visual-bell';
|
||||||
|
|
||||||
const DESKTOP_INTERFACE_SCHEMA = 'org.gnome.desktop.interface';
|
const DESKTOP_INTERFACE_SCHEMA = 'org.gnome.desktop.interface';
|
||||||
const KEY_GTK_THEME = 'gtk-theme';
|
const KEY_GTK_THEME = 'gtk-theme';
|
||||||
@ -50,10 +50,6 @@ ATIndicator.prototype = {
|
|||||||
_init: function() {
|
_init: function() {
|
||||||
PanelMenu.SystemStatusButton.prototype._init.call(this, 'preferences-desktop-accessibility', null);
|
PanelMenu.SystemStatusButton.prototype._init.call(this, 'preferences-desktop-accessibility', null);
|
||||||
|
|
||||||
let client = GConf.Client.get_default();
|
|
||||||
client.add_dir(KEY_META_DIR, GConf.ClientPreloadType.PRELOAD_ONELEVEL, null);
|
|
||||||
client.notify_add(KEY_META_DIR, Lang.bind(this, this._keyChanged), null, null);
|
|
||||||
|
|
||||||
let highContrast = this._buildHCItem();
|
let highContrast = this._buildHCItem();
|
||||||
this.menu.addMenuItem(highContrast);
|
this.menu.addMenuItem(highContrast);
|
||||||
|
|
||||||
@ -72,7 +68,7 @@ ATIndicator.prototype = {
|
|||||||
'screen-keyboard-enabled');
|
'screen-keyboard-enabled');
|
||||||
this.menu.addMenuItem(screenKeyboard);
|
this.menu.addMenuItem(screenKeyboard);
|
||||||
|
|
||||||
let visualBell = this._buildItemGConf(_("Visual Alerts"), client, KEY_VISUAL_BELL);
|
let visualBell = this._buildItem(_("Visual Alerts"), WM_SCHEMA, KEY_VISUAL_BELL);
|
||||||
this.menu.addMenuItem(visualBell);
|
this.menu.addMenuItem(visualBell);
|
||||||
|
|
||||||
let stickyKeys = this._buildItem(_("Sticky Keys"), A11Y_SCHEMA, KEY_STICKY_KEYS_ENABLED);
|
let stickyKeys = this._buildItem(_("Sticky Keys"), A11Y_SCHEMA, KEY_STICKY_KEYS_ENABLED);
|
||||||
@ -102,22 +98,6 @@ ATIndicator.prototype = {
|
|||||||
return widget;
|
return widget;
|
||||||
},
|
},
|
||||||
|
|
||||||
_buildItemGConf: function(string, client, key) {
|
|
||||||
function on_get() {
|
|
||||||
return client.get_bool(key);
|
|
||||||
}
|
|
||||||
let widget = this._buildItemExtended(string,
|
|
||||||
client.get_bool(key),
|
|
||||||
client.key_is_writable(key),
|
|
||||||
function(enabled) {
|
|
||||||
client.set_bool(key, enabled);
|
|
||||||
});
|
|
||||||
this.connect('gconf-changed', function() {
|
|
||||||
widget.setToggleState(client.get_bool(key));
|
|
||||||
});
|
|
||||||
return widget;
|
|
||||||
},
|
|
||||||
|
|
||||||
_buildItem: function(string, schema, key) {
|
_buildItem: function(string, schema, key) {
|
||||||
let settings = new Gio.Settings({ schema: schema });
|
let settings = new Gio.Settings({ schema: schema });
|
||||||
let widget = this._buildItemExtended(string,
|
let widget = this._buildItemExtended(string,
|
||||||
@ -191,10 +171,6 @@ ATIndicator.prototype = {
|
|||||||
widget.setToggleState(active);
|
widget.setToggleState(active);
|
||||||
});
|
});
|
||||||
return widget;
|
return widget;
|
||||||
},
|
|
||||||
|
|
||||||
_keyChanged: function() {
|
|
||||||
this.emit('gconf-changed');
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
Signals.addSignalMethods(ATIndicator.prototype);
|
Signals.addSignalMethods(ATIndicator.prototype);
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
/* -*- mode: js2; js2-basic-offset: 4; indent-tabs-mode: nil -*- */
|
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
|
||||||
|
|
||||||
const Clutter = imports.gi.Clutter;
|
const Clutter = imports.gi.Clutter;
|
||||||
const Gdk = imports.gi.Gdk;
|
const Gdk = imports.gi.Gdk;
|
||||||
@ -204,9 +204,10 @@ Indicator.prototype = {
|
|||||||
|
|
||||||
_buildDeviceSubMenu: function(item, device) {
|
_buildDeviceSubMenu: function(item, device) {
|
||||||
if (device.can_connect) {
|
if (device.can_connect) {
|
||||||
|
let menuitem = new PopupMenu.PopupSwitchMenuItem(_("Connection"), device.connected);
|
||||||
item._connected = device.connected;
|
item._connected = device.connected;
|
||||||
item._connectedMenuitem = new PopupMenu.PopupSwitchMenuItem(_("Connection"), device.connected);
|
item._connectedMenuItem = menuitem;
|
||||||
item._connectedMenuitem.connect('toggled', Lang.bind(this, function() {
|
menuitem.connect('toggled', Lang.bind(this, function() {
|
||||||
if (item._connected > ConnectionState.CONNECTED) {
|
if (item._connected > ConnectionState.CONNECTED) {
|
||||||
// operation already in progress, revert
|
// operation already in progress, revert
|
||||||
// (should not happen anyway)
|
// (should not happen anyway)
|
||||||
@ -241,7 +242,7 @@ Indicator.prototype = {
|
|||||||
}
|
}
|
||||||
}));
|
}));
|
||||||
|
|
||||||
item.menu.addMenuItem(item._connectedMenuitem);
|
item.menu.addMenuItem(menuitem);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (device.capabilities & GnomeBluetoothApplet.Capabilities.OBEX_PUSH) {
|
if (device.capabilities & GnomeBluetoothApplet.Capabilities.OBEX_PUSH) {
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
/* -*- mode: js2; js2-basic-offset: 4; indent-tabs-mode: nil -*- */
|
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
|
||||||
|
|
||||||
const Clutter = imports.gi.Clutter;
|
const Clutter = imports.gi.Clutter;
|
||||||
const GdkPixbuf = imports.gi.GdkPixbuf;
|
const GdkPixbuf = imports.gi.GdkPixbuf;
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
// -*- mode: js2; indent-tabs-mode: nil; js2-basic-offset: 4 -*-
|
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
|
||||||
const ByteArray = imports.byteArray;
|
const ByteArray = imports.byteArray;
|
||||||
const DBus = imports.dbus;
|
|
||||||
const GLib = imports.gi.GLib;
|
const GLib = imports.gi.GLib;
|
||||||
const GObject = imports.gi.GObject;
|
const GObject = imports.gi.GObject;
|
||||||
const Lang = imports.lang;
|
const Lang = imports.lang;
|
||||||
@ -1104,10 +1103,10 @@ NMDeviceWireless.prototype = {
|
|||||||
let activeAp = this.device.active_access_point;
|
let activeAp = this.device.active_access_point;
|
||||||
|
|
||||||
if (activeAp) {
|
if (activeAp) {
|
||||||
let pos = this._findNetwork(activeAp);
|
let res = this._findExistingNetwork(activeAp);
|
||||||
|
|
||||||
if (pos != -1)
|
if (res != null)
|
||||||
this._activeNetwork = this._networks[pos];
|
this._activeNetwork = this._networks[res.network];
|
||||||
}
|
}
|
||||||
|
|
||||||
// we don't refresh the view here, setActiveConnection will
|
// we don't refresh the view here, setActiveConnection will
|
||||||
@ -1181,6 +1180,18 @@ NMDeviceWireless.prototype = {
|
|||||||
return true;
|
return true;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
_findExistingNetwork: function(accessPoint) {
|
||||||
|
for (let i = 0; i < this._networks.length; i++) {
|
||||||
|
let apObj = this._networks[i];
|
||||||
|
for (let j = 0; j < apObj.accessPoints.length; j++) {
|
||||||
|
if (apObj.accessPoints[j] == accessPoint)
|
||||||
|
return { network: i, ap: j };
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
},
|
||||||
|
|
||||||
_findNetwork: function(accessPoint) {
|
_findNetwork: function(accessPoint) {
|
||||||
if (accessPoint.get_ssid() == null)
|
if (accessPoint.get_ssid() == null)
|
||||||
return -1;
|
return -1;
|
||||||
@ -1273,22 +1284,15 @@ NMDeviceWireless.prototype = {
|
|||||||
},
|
},
|
||||||
|
|
||||||
_accessPointRemoved: function(device, accessPoint) {
|
_accessPointRemoved: function(device, accessPoint) {
|
||||||
let pos = this._findNetwork(accessPoint);
|
let res = this._findExistingNetwork(accessPoint);
|
||||||
|
|
||||||
if (pos == -1) {
|
if (res == null) {
|
||||||
log('Removing an access point that was never added');
|
log('Removing an access point that was never added');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
let apObj = this._networks[pos];
|
let apObj = this._networks[res.network];
|
||||||
let i = apObj.accessPoints.indexOf(accessPoint);
|
apObj.accessPoints.splice(res.ap, 1);
|
||||||
|
|
||||||
if (i == -1) {
|
|
||||||
log('Removing an access point that was never added');
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
apObj.accessPoints.splice(i, 1);
|
|
||||||
|
|
||||||
if (apObj.accessPoints.length == 0) {
|
if (apObj.accessPoints.length == 0) {
|
||||||
if (this._activeNetwork == apObj)
|
if (this._activeNetwork == apObj)
|
||||||
@ -1302,22 +1306,26 @@ NMDeviceWireless.prototype = {
|
|||||||
// we removed an item in the main menu, and we have a more submenu
|
// we removed an item in the main menu, and we have a more submenu
|
||||||
// we need to extract the first item in more and move it to the submenu
|
// we need to extract the first item in more and move it to the submenu
|
||||||
|
|
||||||
let apObj = this._overflowItem.menu.firstMenuItem;
|
let item = this._overflowItem.menu.firstMenuItem;
|
||||||
if (apObj.item) {
|
if (item && item._apObj) {
|
||||||
apObj.item.destroy();
|
item.destroy();
|
||||||
|
// clear the cycle, and allow the construction of the new item
|
||||||
|
item._apObj.item = null;
|
||||||
|
|
||||||
this._createNetworkItem(apObj, NUM_VISIBLE_NETWORKS-1);
|
this._createNetworkItem(item._apObj, NUM_VISIBLE_NETWORKS-1);
|
||||||
|
} else {
|
||||||
|
log('The more... menu was existing and empty! This should not happen');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// This can happen if the removed connection is from the overflow
|
// This can happen if the removed connection is from the overflow
|
||||||
// menu, or if we just moved the last connection out from the menu
|
// menu, or if we just moved the last connection out from the menu
|
||||||
if (this._overflowItem.menu.length == 0) {
|
if (this._overflowItem.menu.numMenuItems == 0) {
|
||||||
this._overflowItem.destroy();
|
this._overflowItem.destroy();
|
||||||
this._overflowItem = null;
|
this._overflowItem = null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
this._networks.splice(pos, 1);
|
this._networks.splice(res.network, 1);
|
||||||
|
|
||||||
} else if (apObj.item)
|
} else if (apObj.item)
|
||||||
apObj.item.updateAccessPoints(apObj.accessPoints);
|
apObj.item.updateAccessPoints(apObj.accessPoints);
|
||||||
@ -1489,18 +1497,16 @@ NMDeviceWireless.prototype = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if(apObj.connections.length > 0) {
|
if(apObj.connections.length > 0) {
|
||||||
if (apObj.connections.length == 1)
|
if (apObj.connections.length == 1) {
|
||||||
apObj.item = this._createAPItem(apObj.connections[0], apObj, false);
|
apObj.item = this._createAPItem(apObj.connections[0], apObj, false);
|
||||||
else {
|
} else {
|
||||||
let title = apObj.ssidText;
|
let title = apObj.ssidText;
|
||||||
apObj.item = new PopupMenu.PopupSubMenuMenuItem(title);
|
apObj.item = new PopupMenu.PopupSubMenuMenuItem(title);
|
||||||
apObj.item._apObj = apObj;
|
|
||||||
for (let i = 0; i < apObj.connections.length; i++)
|
for (let i = 0; i < apObj.connections.length; i++)
|
||||||
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);
|
||||||
apObj.item._apObj = apObj;
|
|
||||||
apObj.item.connect('activate', Lang.bind(this, function() {
|
apObj.item.connect('activate', Lang.bind(this, function() {
|
||||||
let accessPoints = sortAccessPoints(apObj.accessPoints);
|
let accessPoints = sortAccessPoints(apObj.accessPoints);
|
||||||
if ( (accessPoints[0]._secType == NMAccessPointSecurity.WPA2_ENT)
|
if ( (accessPoints[0]._secType == NMAccessPointSecurity.WPA2_ENT)
|
||||||
@ -1515,6 +1521,8 @@ NMDeviceWireless.prototype = {
|
|||||||
}
|
}
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
apObj.item._apObj = apObj;
|
||||||
|
|
||||||
if (position < NUM_VISIBLE_NETWORKS) {
|
if (position < NUM_VISIBLE_NETWORKS) {
|
||||||
apObj.isMore = false;
|
apObj.isMore = false;
|
||||||
this.section.addMenuItem(apObj.item, position);
|
this.section.addMenuItem(apObj.item, position);
|
||||||
@ -2056,10 +2064,11 @@ NMApplet.prototype = {
|
|||||||
}
|
}
|
||||||
this.setIcon('network-wireless-connected');
|
this.setIcon('network-wireless-connected');
|
||||||
} else {
|
} else {
|
||||||
if (this._accessPointUpdateId && this._activeAccessPoint != ap) {
|
if (this._activeAccessPoint != ap) {
|
||||||
this._activeAccessPoint.disconnect(this._accessPointUpdateId);
|
if (this._accessPointUpdateId)
|
||||||
|
this._activeAccessPoint.disconnect(this._accessPointUpdateId);
|
||||||
this._activeAccessPoint = ap;
|
this._activeAccessPoint = ap;
|
||||||
this._activeAccessPointUpdateId = ap.connect('notify::strength', Lang.bind(function() {
|
this._activeAccessPointUpdateId = ap.connect('notify::strength', Lang.bind(this, function() {
|
||||||
this.setIcon('network-wireless-signal-' + signalToIcon(ap.strength));
|
this.setIcon('network-wireless-signal-' + signalToIcon(ap.strength));
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
@ -2086,8 +2095,9 @@ NMApplet.prototype = {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this._mobileUpdateId && this._mobileUpdateDevice != dev) {
|
if (dev.mobileDevice != this._mobileUpdateDevice) {
|
||||||
this._mobileUpdateDevice.disconnect(this._mobileUpdateId);
|
if (this._mobileUpdateId)
|
||||||
|
this._mobileUpdateDevice.disconnect(this._mobileUpdateId);
|
||||||
this._mobileUpdateDevice = dev.mobileDevice;
|
this._mobileUpdateDevice = dev.mobileDevice;
|
||||||
this._mobileUpdateId = dev.mobileDevice.connect('notify::signal-quality', Lang.bind(this, function() {
|
this._mobileUpdateId = dev.mobileDevice.connect('notify::signal-quality', Lang.bind(this, function() {
|
||||||
this.setIcon('network-cellular-signal-' + signalToIcon(dev.mobileDevice.signal_quality));
|
this.setIcon('network-cellular-signal-' + signalToIcon(dev.mobileDevice.signal_quality));
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
/* -*- mode: js2; js2-basic-offset: 4; indent-tabs-mode: nil -*- */
|
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
|
||||||
|
|
||||||
const Gio = imports.gi.Gio;
|
const Gio = imports.gi.Gio;
|
||||||
const DBus = imports.dbus;
|
|
||||||
const Lang = imports.lang;
|
const Lang = imports.lang;
|
||||||
const Mainloop = imports.mainloop;
|
const Mainloop = imports.mainloop;
|
||||||
const Shell = imports.gi.Shell;
|
const Shell = imports.gi.Shell;
|
||||||
@ -40,20 +39,18 @@ const UPDeviceState = {
|
|||||||
PENDING_DISCHARGE: 6
|
PENDING_DISCHARGE: 6
|
||||||
};
|
};
|
||||||
|
|
||||||
const PowerManagerInterface = {
|
const PowerManagerInterface = <interface name="org.gnome.SettingsDaemon.Power">
|
||||||
name: 'org.gnome.SettingsDaemon.Power',
|
<method name="GetDevices">
|
||||||
methods: [
|
<arg type="a(susdut)" direction="out" />
|
||||||
{ name: 'GetDevices', inSignature: '', outSignature: 'a(susbut)' },
|
</method>
|
||||||
{ name: 'GetPrimaryDevice', inSignature: '', outSignature: '(susbut)' },
|
<method name="GetPrimaryDevice">
|
||||||
],
|
<arg type="(susdut)" direction="out" />
|
||||||
signals: [
|
</method>
|
||||||
{ name: 'Changed', inSignature: '' },
|
<signal name="Changed" />
|
||||||
],
|
<property name="Icon" type="s" access="read" />
|
||||||
properties: [
|
</interface>;
|
||||||
{ name: 'Icon', signature: 's', access: 'read' },
|
|
||||||
]
|
const PowerManagerProxy = Gio.DBusProxy.makeProxyWrapper(PowerManagerInterface);
|
||||||
};
|
|
||||||
let PowerManagerProxy = DBus.makeProxyClass(PowerManagerInterface);
|
|
||||||
|
|
||||||
function Indicator() {
|
function Indicator() {
|
||||||
this._init.apply(this, arguments);
|
this._init.apply(this, arguments);
|
||||||
@ -64,7 +61,7 @@ Indicator.prototype = {
|
|||||||
|
|
||||||
_init: function() {
|
_init: function() {
|
||||||
PanelMenu.SystemStatusButton.prototype._init.call(this, 'battery-missing');
|
PanelMenu.SystemStatusButton.prototype._init.call(this, 'battery-missing');
|
||||||
this._proxy = new PowerManagerProxy(DBus.session, BUS_NAME, OBJECT_PATH);
|
this._proxy = new PowerManagerProxy(Gio.DBus.session, BUS_NAME, OBJECT_PATH);
|
||||||
|
|
||||||
this._deviceItems = [ ];
|
this._deviceItems = [ ];
|
||||||
this._hasPrimary = false;
|
this._hasPrimary = false;
|
||||||
@ -81,19 +78,19 @@ Indicator.prototype = {
|
|||||||
this.menu.addMenuItem(new PopupMenu.PopupSeparatorMenuItem());
|
this.menu.addMenuItem(new PopupMenu.PopupSeparatorMenuItem());
|
||||||
this.menu.addSettingsAction(_("Power Settings"), 'gnome-power-panel.desktop');
|
this.menu.addSettingsAction(_("Power Settings"), 'gnome-power-panel.desktop');
|
||||||
|
|
||||||
this._proxy.connect('Changed', Lang.bind(this, this._devicesChanged));
|
this._proxy.connectSignal('Changed', Lang.bind(this, this._devicesChanged));
|
||||||
this._devicesChanged();
|
this._devicesChanged();
|
||||||
},
|
},
|
||||||
|
|
||||||
_readPrimaryDevice: function() {
|
_readPrimaryDevice: function() {
|
||||||
this._proxy.GetPrimaryDeviceRemote(Lang.bind(this, function(device, error) {
|
this._proxy.GetPrimaryDeviceRemote(Lang.bind(this, function(result, error) {
|
||||||
if (error) {
|
if (error) {
|
||||||
this._hasPrimary = false;
|
this._hasPrimary = false;
|
||||||
this._primaryDeviceId = null;
|
this._primaryDeviceId = null;
|
||||||
this._batteryItem.actor.hide();
|
this._batteryItem.actor.hide();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
let [device_id, device_type, icon, percentage, state, seconds] = device;
|
let [[device_id, device_type, icon, percentage, state, seconds]] = result;
|
||||||
if (device_type == UPDeviceType.BATTERY) {
|
if (device_type == UPDeviceType.BATTERY) {
|
||||||
this._hasPrimary = true;
|
this._hasPrimary = true;
|
||||||
let time = Math.round(seconds / 60);
|
let time = Math.round(seconds / 60);
|
||||||
@ -130,7 +127,7 @@ Indicator.prototype = {
|
|||||||
},
|
},
|
||||||
|
|
||||||
_readOtherDevices: function() {
|
_readOtherDevices: function() {
|
||||||
this._proxy.GetDevicesRemote(Lang.bind(this, function(devices, error) {
|
this._proxy.GetDevicesRemote(Lang.bind(this, function(result, error) {
|
||||||
this._deviceItems.forEach(function(i) { i.destroy(); });
|
this._deviceItems.forEach(function(i) { i.destroy(); });
|
||||||
this._deviceItems = [];
|
this._deviceItems = [];
|
||||||
|
|
||||||
@ -139,6 +136,7 @@ Indicator.prototype = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
let position = 0;
|
let position = 0;
|
||||||
|
let [devices] = result;
|
||||||
for (let i = 0; i < devices.length; i++) {
|
for (let i = 0; i < devices.length; i++) {
|
||||||
let [device_id, device_type] = devices[i];
|
let [device_id, device_type] = devices[i];
|
||||||
if (device_type == UPDeviceType.AC_POWER || device_id == this._primaryDeviceId)
|
if (device_type == UPDeviceType.AC_POWER || device_id == this._primaryDeviceId)
|
||||||
@ -153,16 +151,15 @@ Indicator.prototype = {
|
|||||||
},
|
},
|
||||||
|
|
||||||
_devicesChanged: function() {
|
_devicesChanged: function() {
|
||||||
this._proxy.GetRemote('Icon', Lang.bind(this, function(icon, error) {
|
let icon = this._proxy.Icon;
|
||||||
if (icon) {
|
if (icon) {
|
||||||
let gicon = Shell.util_icon_from_string (icon);
|
let gicon = Gio.icon_new_for_string(icon);
|
||||||
this.setGIcon(gicon);
|
this.setGIcon(gicon);
|
||||||
this.actor.show();
|
this.actor.show();
|
||||||
} else {
|
} else {
|
||||||
this.menu.close();
|
this.menu.close();
|
||||||
this.actor.hide();
|
this.actor.hide();
|
||||||
}
|
}
|
||||||
}));
|
|
||||||
this._readPrimaryDevice();
|
this._readPrimaryDevice();
|
||||||
this._readOtherDevices();
|
this._readOtherDevices();
|
||||||
}
|
}
|
||||||
@ -183,7 +180,7 @@ DeviceItem.prototype = {
|
|||||||
this._box = new St.BoxLayout({ style_class: 'popup-device-menu-item' });
|
this._box = new St.BoxLayout({ style_class: 'popup-device-menu-item' });
|
||||||
this._label = new St.Label({ text: this._deviceTypeToString(device_type) });
|
this._label = new St.Label({ text: this._deviceTypeToString(device_type) });
|
||||||
|
|
||||||
this._icon = new St.Icon({ gicon: Shell.util_icon_from_string(icon),
|
this._icon = new St.Icon({ gicon: Gio.icon_new_for_string(icon),
|
||||||
icon_type: St.IconType.SYMBOLIC,
|
icon_type: St.IconType.SYMBOLIC,
|
||||||
style_class: 'popup-menu-icon' });
|
style_class: 'popup-menu-icon' });
|
||||||
|
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
/* -*- mode: js2; js2-basic-offset: 4; indent-tabs-mode: nil -*- */
|
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
|
||||||
|
|
||||||
const Clutter = imports.gi.Clutter;
|
const Clutter = imports.gi.Clutter;
|
||||||
const DBus = imports.dbus;
|
|
||||||
const Lang = imports.lang;
|
const Lang = imports.lang;
|
||||||
const Mainloop = imports.mainloop;
|
const Mainloop = imports.mainloop;
|
||||||
const Shell = imports.gi.Shell;
|
const Shell = imports.gi.Shell;
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
/* -*- mode: js2; js2-basic-offset: 4; indent-tabs-mode: nil -*- */
|
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
|
||||||
|
|
||||||
const Lang = imports.lang;
|
const Lang = imports.lang;
|
||||||
const Shell = imports.gi.Shell;
|
const Shell = imports.gi.Shell;
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
/* -*- mode: js2; js2-basic-offset: 4; indent-tabs-mode: nil -*- */
|
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
|
||||||
|
|
||||||
const DBus = imports.dbus;
|
|
||||||
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;
|
||||||
@ -257,7 +256,7 @@ Client.prototype = {
|
|||||||
// FIXME: We don't have a 'chat room' icon (bgo #653737) use
|
// FIXME: We don't have a 'chat room' icon (bgo #653737) use
|
||||||
// system-users for now as Empathy does.
|
// system-users for now as Empathy does.
|
||||||
let source = new ApproverSource(dispatchOp, _("Invitation"),
|
let source = new ApproverSource(dispatchOp, _("Invitation"),
|
||||||
Shell.util_icon_from_string('system-users'));
|
Gio.icon_new_for_string('system-users'));
|
||||||
Main.messageTray.add(source);
|
Main.messageTray.add(source);
|
||||||
|
|
||||||
let notif = new RoomInviteNotification(source, dispatchOp, channel, contacts[0]);
|
let notif = new RoomInviteNotification(source, dispatchOp, channel, contacts[0]);
|
||||||
@ -305,6 +304,8 @@ Client.prototype = {
|
|||||||
Shell.get_tp_contacts(conn, [targetHandle],
|
Shell.get_tp_contacts(conn, [targetHandle],
|
||||||
contactFeatures,
|
contactFeatures,
|
||||||
Lang.bind(this, this._createAudioVideoSource, channel, context, dispatchOp));
|
Lang.bind(this, this._createAudioVideoSource, channel, context, dispatchOp));
|
||||||
|
|
||||||
|
context.delay();
|
||||||
},
|
},
|
||||||
|
|
||||||
_createAudioVideoSource: function(connection, contacts, failed, channel, context, dispatchOp) {
|
_createAudioVideoSource: function(connection, contacts, failed, channel, context, dispatchOp) {
|
||||||
@ -323,8 +324,8 @@ Client.prototype = {
|
|||||||
|
|
||||||
// We got the TpContact
|
// We got the TpContact
|
||||||
let source = new ApproverSource(dispatchOp, _("Call"), isVideo ?
|
let source = new ApproverSource(dispatchOp, _("Call"), isVideo ?
|
||||||
Shell.util_icon_from_string('camera-web') :
|
Gio.icon_new_for_string('camera-web') :
|
||||||
Shell.util_icon_from_string('audio-input-microphone'));
|
Gio.icon_new_for_string('audio-input-microphone'));
|
||||||
Main.messageTray.add(source);
|
Main.messageTray.add(source);
|
||||||
|
|
||||||
let notif = new AudioVideoNotification(source, dispatchOp, channel, contacts[0], isVideo);
|
let notif = new AudioVideoNotification(source, dispatchOp, channel, contacts[0], isVideo);
|
||||||
@ -338,6 +339,8 @@ Client.prototype = {
|
|||||||
Shell.get_tp_contacts(conn, [targetHandle],
|
Shell.get_tp_contacts(conn, [targetHandle],
|
||||||
contactFeatures,
|
contactFeatures,
|
||||||
Lang.bind(this, this._createFileTransferSource, channel, context, dispatchOp));
|
Lang.bind(this, this._createFileTransferSource, channel, context, dispatchOp));
|
||||||
|
|
||||||
|
context.delay();
|
||||||
},
|
},
|
||||||
|
|
||||||
_createFileTransferSource: function(connection, contacts, failed, channel, context, dispatchOp) {
|
_createFileTransferSource: function(connection, contacts, failed, channel, context, dispatchOp) {
|
||||||
@ -535,21 +538,18 @@ ChatSource.prototype = {
|
|||||||
|
|
||||||
_updateAlias: function() {
|
_updateAlias: function() {
|
||||||
let oldAlias = this.title;
|
let oldAlias = this.title;
|
||||||
this.setTitle(this._contact.get_alias());
|
let newAlias = this._contact.get_alias();
|
||||||
this._notification.appendAliasChange(oldAlias, this.title);
|
|
||||||
this.pushNotification(this._notification);
|
if (oldAlias == newAlias)
|
||||||
|
return;
|
||||||
|
|
||||||
|
this.setTitle(newAlias);
|
||||||
|
this._notification.appendAliasChange(oldAlias, newAlias);
|
||||||
},
|
},
|
||||||
|
|
||||||
createNotificationIcon: function() {
|
createNotificationIcon: function() {
|
||||||
this._iconBox = new St.Bin({ style_class: 'avatar-box' });
|
this._iconBox = new St.Bin({ style_class: 'avatar-box' });
|
||||||
this._iconBox._size = this.ICON_SIZE;
|
this._iconBox._size = this.ICON_SIZE;
|
||||||
|
|
||||||
this._updateAvatarIcon();
|
|
||||||
|
|
||||||
return this._iconBox;
|
|
||||||
},
|
|
||||||
|
|
||||||
_updateAvatarIcon: function() {
|
|
||||||
let textureCache = St.TextureCache.get_default();
|
let textureCache = St.TextureCache.get_default();
|
||||||
let file = this._contact.get_avatar_file();
|
let file = this._contact.get_avatar_file();
|
||||||
|
|
||||||
@ -561,12 +561,19 @@ ChatSource.prototype = {
|
|||||||
icon_type: St.IconType.FULLCOLOR,
|
icon_type: St.IconType.FULLCOLOR,
|
||||||
icon_size: this._iconBox._size });
|
icon_size: this._iconBox._size });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return this._iconBox;
|
||||||
|
},
|
||||||
|
|
||||||
|
_updateAvatarIcon: function() {
|
||||||
|
this._setSummaryIcon(this.createNotificationIcon());
|
||||||
|
this._notification.update(this._notification.title, null, { customContent: true, icon: this.createNotificationIcon() });
|
||||||
},
|
},
|
||||||
|
|
||||||
open: function(notification) {
|
open: function(notification) {
|
||||||
if (this._client.is_handling_channel(this._channel)) {
|
if (this._client.is_handling_channel(this._channel)) {
|
||||||
// We are handling the channel, try to pass it to Empathy
|
// We are handling the channel, try to pass it to Empathy
|
||||||
this._client.delegate_channels_async([this._channel], global.get_current_time(), "", null);
|
this._client.delegate_channels_async([this._channel], global.get_current_time(), '', null);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// We are not the handler, just ask to present the channel
|
// We are not the handler, just ask to present the channel
|
||||||
@ -892,7 +899,7 @@ ChatNotification.prototype = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
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_children().length == 0)
|
||||||
group.destroy();
|
group.destroy();
|
||||||
@ -930,7 +937,7 @@ ChatNotification.prototype = {
|
|||||||
let body = highlighter.actor;
|
let body = highlighter.actor;
|
||||||
|
|
||||||
let styles = props.styles;
|
let styles = props.styles;
|
||||||
for (let i = 0; i < styles.length; i ++)
|
for (let i = 0; i < styles.length; i++)
|
||||||
body.add_style_class_name(styles[i]);
|
body.add_style_class_name(styles[i]);
|
||||||
|
|
||||||
let group = props.group;
|
let group = props.group;
|
||||||
@ -1194,6 +1201,7 @@ AudioVideoNotification.prototype = {
|
|||||||
this.setResident(true);
|
this.setResident(true);
|
||||||
|
|
||||||
this.addButton('reject', _("Reject"));
|
this.addButton('reject', _("Reject"));
|
||||||
|
/* translators: this is a button label (verb), not a noun */
|
||||||
this.addButton('answer', _("Answer"));
|
this.addButton('answer', _("Answer"));
|
||||||
|
|
||||||
this.connect('action-invoked', Lang.bind(this, function(self, action) {
|
this.connect('action-invoked', Lang.bind(this, function(self, action) {
|
||||||
@ -1288,7 +1296,7 @@ MultiNotificationSource.prototype = {
|
|||||||
},
|
},
|
||||||
|
|
||||||
createNotificationIcon: function() {
|
createNotificationIcon: function() {
|
||||||
return new St.Icon({ gicon: Shell.util_icon_from_string(this._icon),
|
return new St.Icon({ gicon: Gio.icon_new_for_string(this._icon),
|
||||||
icon_type: St.IconType.FULLCOLOR,
|
icon_type: St.IconType.FULLCOLOR,
|
||||||
icon_size: this.ICON_SIZE });
|
icon_size: this.ICON_SIZE });
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
/* -*- mode: js2; js2-basic-offset: 4; indent-tabs-mode: nil -*- */
|
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
|
||||||
|
|
||||||
const Clutter = imports.gi.Clutter;
|
const Clutter = imports.gi.Clutter;
|
||||||
const Lang = imports.lang;
|
const Lang = imports.lang;
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
/* -*- mode: js2; js2-basic-offset: 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 DBus = imports.dbus;
|
|
||||||
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;
|
||||||
@ -158,22 +157,39 @@ IMStatusChooserItem.prototype = {
|
|||||||
Lang.bind(this, this._changeIMStatus));
|
Lang.bind(this, this._changeIMStatus));
|
||||||
|
|
||||||
this._presence = new GnomeSession.Presence();
|
this._presence = new GnomeSession.Presence();
|
||||||
this._presence.getStatus(Lang.bind(this, this._sessionStatusChanged));
|
this._presence.connectSignal('StatusChanged', Lang.bind(this, function(proxy, senderName, [status]) {
|
||||||
this._presence.connect('StatusChanged',
|
this._sessionStatusChanged(status);
|
||||||
Lang.bind(this, this._sessionStatusChanged));
|
}));
|
||||||
|
|
||||||
|
this._sessionPresenceRestored = false;
|
||||||
|
this._imPresenceRestored = false;
|
||||||
this._currentPresence = undefined;
|
this._currentPresence = undefined;
|
||||||
this._previousPresence = undefined;
|
|
||||||
|
|
||||||
this._accountMgr = Tp.AccountManager.dup()
|
this._accountMgr = Tp.AccountManager.dup();
|
||||||
this._accountMgr.connect('most-available-presence-changed',
|
this._accountMgr.connect('most-available-presence-changed',
|
||||||
Lang.bind(this, this._IMStatusChanged));
|
Lang.bind(this, this._IMStatusChanged));
|
||||||
|
this._accountMgr.connect('account-enabled',
|
||||||
|
Lang.bind(this, this._IMAccountsChanged));
|
||||||
|
this._accountMgr.connect('account-disabled',
|
||||||
|
Lang.bind(this, this._IMAccountsChanged));
|
||||||
|
this._accountMgr.connect('account-removed',
|
||||||
|
Lang.bind(this, this._IMAccountsChanged));
|
||||||
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, status, msg] = mgr.get_most_available_presence();
|
||||||
|
|
||||||
this._previousPresence = presence;
|
let savedPresence = global.settings.get_int('saved-im-presence');
|
||||||
this._IMStatusChanged(mgr, presence, s, msg);
|
|
||||||
|
this._IMAccountsChanged(mgr);
|
||||||
|
|
||||||
|
if (savedPresence == presence) {
|
||||||
|
this._IMStatusChanged(mgr, presence, status, msg);
|
||||||
|
} else {
|
||||||
|
this._setComboboxPresence(savedPresence);
|
||||||
|
status = this._statusForPresence(savedPresence);
|
||||||
|
msg = msg ? msg : '';
|
||||||
|
mgr.set_all_requested_presences(savedPresence, status, msg);
|
||||||
|
}
|
||||||
}));
|
}));
|
||||||
|
|
||||||
this._userManager = AccountsService.UserManager.get_default();
|
this._userManager = AccountsService.UserManager.get_default();
|
||||||
@ -192,6 +208,21 @@ IMStatusChooserItem.prototype = {
|
|||||||
}));
|
}));
|
||||||
},
|
},
|
||||||
|
|
||||||
|
destroy: function() {
|
||||||
|
// clean up signal handlers
|
||||||
|
if (this._userLoadedId != 0) {
|
||||||
|
this._user.disconnect(this._userLoadedId);
|
||||||
|
this._userLoadedId = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this._userChangedId != 0) {
|
||||||
|
this._user.disconnect(this._userChangedId);
|
||||||
|
this._userChangedId = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
PopupMenu.PopupBaseMenuItem.prototype.destroy.call(this);
|
||||||
|
},
|
||||||
|
|
||||||
// Override getColumnWidths()/setColumnWidths() to make the item
|
// Override getColumnWidths()/setColumnWidths() to make the item
|
||||||
// independent from the overall column layout of the menu
|
// independent from the overall column layout of the menu
|
||||||
getColumnWidths: function() {
|
getColumnWidths: function() {
|
||||||
@ -260,20 +291,43 @@ IMStatusChooserItem.prototype = {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
_IMAccountsChanged: function(mgr) {
|
||||||
|
let accounts = mgr.get_valid_accounts().filter(function(account) {
|
||||||
|
return account.enabled;
|
||||||
|
});
|
||||||
|
this._combo.setSensitive(accounts.length > 0);
|
||||||
|
},
|
||||||
|
|
||||||
_IMStatusChanged: function(accountMgr, presence, status, message) {
|
_IMStatusChanged: function(accountMgr, presence, status, message) {
|
||||||
|
if (!this._imPresenceRestored)
|
||||||
|
this._imPresenceRestored = true;
|
||||||
|
|
||||||
if (presence == this._currentPresence)
|
if (presence == this._currentPresence)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
this._currentPresence = presence;
|
this._currentPresence = presence;
|
||||||
|
this._setComboboxPresence(presence);
|
||||||
|
|
||||||
|
if (!this._sessionPresenceRestored) {
|
||||||
|
this._sessionStatusChanged(this._presence.status);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (presence == Tp.ConnectionPresenceType.AVAILABLE)
|
if (presence == Tp.ConnectionPresenceType.AVAILABLE)
|
||||||
this._presence.setStatus(GnomeSession.PresenceStatus.AVAILABLE);
|
this._presence.status = GnomeSession.PresenceStatus.AVAILABLE;
|
||||||
|
|
||||||
if (!this._expectedPresence || presence != this._expectedPresence)
|
// We ignore the actual value of _expectedPresence and never safe
|
||||||
this._previousPresence = presence;
|
// the first presence change after an "automatic" change, assuming
|
||||||
|
// that it is the response to our request; this is to account for
|
||||||
|
// mission control falling back to "similar" presences if an account
|
||||||
|
// type does not implement the requested presence.
|
||||||
|
if (!this._expectedPresence)
|
||||||
|
global.settings.set_int('saved-im-presence', presence);
|
||||||
else
|
else
|
||||||
this._expectedPresence = undefined;
|
this._expectedPresence = undefined;
|
||||||
|
},
|
||||||
|
|
||||||
|
_setComboboxPresence: function(presence) {
|
||||||
let activatedItem;
|
let activatedItem;
|
||||||
|
|
||||||
if (presence == Tp.ConnectionPresenceType.AVAILABLE)
|
if (presence == Tp.ConnectionPresenceType.AVAILABLE)
|
||||||
@ -310,13 +364,16 @@ IMStatusChooserItem.prototype = {
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
status = this._statusForPresence(newPresence);
|
status = this._statusForPresence(newPresence);
|
||||||
msg = msg ? msg : "";
|
msg = msg ? msg : '';
|
||||||
this._accountMgr.set_all_requested_presences(newPresence, status, msg);
|
this._accountMgr.set_all_requested_presences(newPresence, status, msg);
|
||||||
},
|
},
|
||||||
|
|
||||||
getIMPresenceForSessionStatus: function(sessionStatus) {
|
getIMPresenceForSessionStatus: function(sessionStatus) {
|
||||||
|
// Restore the last user-set presence when coming back from
|
||||||
|
// BUSY/IDLE (otherwise the last user-set presence matches
|
||||||
|
// the current one)
|
||||||
if (sessionStatus == GnomeSession.PresenceStatus.AVAILABLE)
|
if (sessionStatus == GnomeSession.PresenceStatus.AVAILABLE)
|
||||||
return this._previousPresence;
|
return global.settings.get_int('saved-im-presence');
|
||||||
|
|
||||||
if (sessionStatus == GnomeSession.PresenceStatus.BUSY) {
|
if (sessionStatus == GnomeSession.PresenceStatus.BUSY) {
|
||||||
// Only change presence if the current one is "more present" than
|
// Only change presence if the current one is "more present" than
|
||||||
@ -336,7 +393,21 @@ IMStatusChooserItem.prototype = {
|
|||||||
return this._currentPresence;
|
return this._currentPresence;
|
||||||
},
|
},
|
||||||
|
|
||||||
_sessionStatusChanged: function(sessionPresence, sessionStatus) {
|
_sessionStatusChanged: function(sessionStatus) {
|
||||||
|
if (!this._imPresenceRestored)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (!this._sessionPresenceRestored) {
|
||||||
|
let savedStatus = global.settings.get_int('saved-session-presence');
|
||||||
|
if (sessionStatus != savedStatus) {
|
||||||
|
this._presence.status = savedStatus;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this._sessionPresenceRestored = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
global.settings.set_int('saved-session-presence', sessionStatus);
|
||||||
|
|
||||||
let [presence, s, msg] = this._accountMgr.get_most_available_presence();
|
let [presence, s, msg] = this._accountMgr.get_most_available_presence();
|
||||||
let newPresence, status;
|
let newPresence, status;
|
||||||
|
|
||||||
@ -346,7 +417,7 @@ IMStatusChooserItem.prototype = {
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
status = this._statusForPresence(newPresence);
|
status = this._statusForPresence(newPresence);
|
||||||
msg = msg ? msg : "";
|
msg = msg ? msg : '';
|
||||||
|
|
||||||
this._expectedPresence = newPresence;
|
this._expectedPresence = newPresence;
|
||||||
this._accountMgr.set_all_requested_presences(newPresence, status, msg);
|
this._accountMgr.set_all_requested_presences(newPresence, status, msg);
|
||||||
@ -375,7 +446,7 @@ UserMenuButton.prototype = {
|
|||||||
this._session = new GnomeSession.SessionManager();
|
this._session = new GnomeSession.SessionManager();
|
||||||
this._haveShutdown = true;
|
this._haveShutdown = true;
|
||||||
|
|
||||||
this._account_mgr = Tp.AccountManager.dup()
|
this._accountMgr = Tp.AccountManager.dup();
|
||||||
|
|
||||||
this._upClient = new UPowerGlib.Client();
|
this._upClient = new UPowerGlib.Client();
|
||||||
this._screenSaverProxy = new ScreenSaver.ScreenSaverProxy();
|
this._screenSaverProxy = new ScreenSaver.ScreenSaverProxy();
|
||||||
@ -398,13 +469,9 @@ UserMenuButton.prototype = {
|
|||||||
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._presence.connect('StatusChanged',
|
this._accountMgr.connect('most-available-presence-changed',
|
||||||
Lang.bind(this, this._updateSwitch));
|
|
||||||
this._presence.getStatus(Lang.bind(this, this._updateSwitch));
|
|
||||||
|
|
||||||
this._account_mgr.connect('most-available-presence-changed',
|
|
||||||
Lang.bind(this, this._updatePresenceIcon));
|
Lang.bind(this, this._updatePresenceIcon));
|
||||||
this._account_mgr.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);
|
||||||
@ -417,8 +484,16 @@ UserMenuButton.prototype = {
|
|||||||
this._updateUserName();
|
this._updateUserName();
|
||||||
|
|
||||||
this._createSubMenu();
|
this._createSubMenu();
|
||||||
|
|
||||||
|
this._updateSwitch(this._presence.status);
|
||||||
|
this._presence.connectSignal('StatusChanged', Lang.bind(this, function (proxy, senderName, [status]) {
|
||||||
|
this._updateSwitch(status);
|
||||||
|
}));
|
||||||
|
|
||||||
this._userManager.connect('notify::is-loaded',
|
this._userManager.connect('notify::is-loaded',
|
||||||
Lang.bind(this, this._updateSwitchUser));
|
Lang.bind(this, this._updateSwitchUser));
|
||||||
|
this._userManager.connect('notify::has-multiple-users',
|
||||||
|
Lang.bind(this, this._updateSwitchUser));
|
||||||
this._userManager.connect('user-added',
|
this._userManager.connect('user-added',
|
||||||
Lang.bind(this, this._updateSwitchUser));
|
Lang.bind(this, this._updateSwitchUser));
|
||||||
this._userManager.connect('user-removed',
|
this._userManager.connect('user-removed',
|
||||||
@ -463,7 +538,9 @@ UserMenuButton.prototype = {
|
|||||||
|
|
||||||
_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 && this._userManager.can_switch ())
|
if (allowSwitch &&
|
||||||
|
this._userManager.can_switch() &&
|
||||||
|
this._userManager.has_multiple_users)
|
||||||
this._loginScreenItem.actor.show();
|
this._loginScreenItem.actor.show();
|
||||||
else
|
else
|
||||||
this._loginScreenItem.actor.hide();
|
this._loginScreenItem.actor.hide();
|
||||||
@ -517,7 +594,7 @@ UserMenuButton.prototype = {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
_updateSwitch: function(presence, status) {
|
_updateSwitch: function(status) {
|
||||||
let active = status == GnomeSession.PresenceStatus.AVAILABLE;
|
let active = status == GnomeSession.PresenceStatus.AVAILABLE;
|
||||||
this._notificationsSwitch.setToggleState(active);
|
this._notificationsSwitch.setToggleState(active);
|
||||||
},
|
},
|
||||||
@ -598,7 +675,7 @@ UserMenuButton.prototype = {
|
|||||||
} else {
|
} else {
|
||||||
status = GnomeSession.PresenceStatus.BUSY;
|
status = GnomeSession.PresenceStatus.BUSY;
|
||||||
|
|
||||||
let [presence, s, msg] = this._account_mgr.get_most_available_presence();
|
let [presence, s, msg] = this._accountMgr.get_most_available_presence();
|
||||||
let newPresence = this._statusChooser.getIMPresenceForSessionStatus(status);
|
let newPresence = this._statusChooser.getIMPresenceForSessionStatus(status);
|
||||||
if (newPresence != presence &&
|
if (newPresence != presence &&
|
||||||
newPresence == Tp.ConnectionPresenceType.BUSY)
|
newPresence == Tp.ConnectionPresenceType.BUSY)
|
||||||
@ -606,7 +683,7 @@ UserMenuButton.prototype = {
|
|||||||
_("Notifications are now disabled, including chat messages. Your online status has been adjusted to let others know that you might not see their messages."));
|
_("Notifications are now disabled, including chat messages. Your online status has been adjusted to let others know that you might not see their messages."));
|
||||||
}
|
}
|
||||||
|
|
||||||
this._presence.setStatus(status);
|
this._presence.status = status;
|
||||||
},
|
},
|
||||||
|
|
||||||
_onMyAccountActivate: function() {
|
_onMyAccountActivate: function() {
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
/* -*- mode: js2; js2-basic-offset: 4; indent-tabs-mode: nil -*- */
|
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
|
||||||
|
|
||||||
const Clutter = imports.gi.Clutter;
|
const Clutter = imports.gi.Clutter;
|
||||||
const Gtk = imports.gi.Gtk;
|
const Gtk = imports.gi.Gtk;
|
||||||
@ -12,6 +12,7 @@ const St = imports.gi.St;
|
|||||||
const Main = imports.ui.main;
|
const Main = imports.ui.main;
|
||||||
const Search = imports.ui.search;
|
const Search = imports.ui.search;
|
||||||
const SearchDisplay = imports.ui.searchDisplay;
|
const SearchDisplay = imports.ui.searchDisplay;
|
||||||
|
const ShellEntry = imports.ui.shellEntry;
|
||||||
const Tweener = imports.ui.tweener;
|
const Tweener = imports.ui.tweener;
|
||||||
|
|
||||||
function BaseTab(titleActor, pageActor, name, a11yIcon) {
|
function BaseTab(titleActor, pageActor, name, a11yIcon) {
|
||||||
@ -120,6 +121,7 @@ SearchTab.prototype = {
|
|||||||
hint_text: _("Type to search..."),
|
hint_text: _("Type to search..."),
|
||||||
track_hover: true,
|
track_hover: true,
|
||||||
can_focus: true });
|
can_focus: true });
|
||||||
|
ShellEntry.addContextMenu(this._entry);
|
||||||
this._text = this._entry.clutter_text;
|
this._text = this._entry.clutter_text;
|
||||||
this._text.connect('key-press-event', Lang.bind(this, this._onKeyPress));
|
this._text.connect('key-press-event', Lang.bind(this, this._onKeyPress));
|
||||||
|
|
||||||
@ -289,9 +291,11 @@ SearchTab.prototype = {
|
|||||||
_onCapturedEvent: function(actor, event) {
|
_onCapturedEvent: function(actor, event) {
|
||||||
if (event.type() == Clutter.EventType.BUTTON_PRESS) {
|
if (event.type() == Clutter.EventType.BUTTON_PRESS) {
|
||||||
let source = event.get_source();
|
let source = event.get_source();
|
||||||
if (source != this._text && this._text.text == '') {
|
if (source != this._text && this._text.text == '' &&
|
||||||
|
!Main.layoutManager.keyboardBox.contains(source)) {
|
||||||
// the user clicked outside after activating the entry, but
|
// the user clicked outside after activating the entry, but
|
||||||
// with no search term entered - cancel the search
|
// with no search term entered and no keyboard button pressed
|
||||||
|
// - cancel the search
|
||||||
this._reset();
|
this._reset();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
/* -*- mode: js2; js2-basic-offset: 4; indent-tabs-mode: nil -*- */
|
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
|
||||||
|
|
||||||
const Lang = imports.lang;
|
const Lang = imports.lang;
|
||||||
const Shell = imports.gi.Shell;
|
const Shell = imports.gi.Shell;
|
||||||
@ -12,35 +12,10 @@ function WindowAttentionHandler() {
|
|||||||
|
|
||||||
WindowAttentionHandler.prototype = {
|
WindowAttentionHandler.prototype = {
|
||||||
_init : function() {
|
_init : function() {
|
||||||
this._startupIds = {};
|
|
||||||
this._tracker = Shell.WindowTracker.get_default();
|
this._tracker = Shell.WindowTracker.get_default();
|
||||||
this._tracker.connect('startup-sequence-changed', Lang.bind(this, this._onStartupSequenceChanged));
|
|
||||||
|
|
||||||
global.display.connect('window-demands-attention', Lang.bind(this, this._onWindowDemandsAttention));
|
global.display.connect('window-demands-attention', Lang.bind(this, this._onWindowDemandsAttention));
|
||||||
},
|
},
|
||||||
|
|
||||||
_onStartupSequenceChanged : function(tracker) {
|
|
||||||
let sequences = tracker.get_startup_sequences();
|
|
||||||
this._startupIds = {};
|
|
||||||
for(let i = 0; i < sequences.length; i++) {
|
|
||||||
this._startupIds[sequences[i].get_id()] = true;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
_getTitle : function(app, window) {
|
|
||||||
if (this._startupIds[window.get_startup_id()])
|
|
||||||
return app.get_name();
|
|
||||||
else
|
|
||||||
return window.title;
|
|
||||||
},
|
|
||||||
|
|
||||||
_getBanner : function(app, window) {
|
|
||||||
if (this._startupIds[window.get_startup_id()])
|
|
||||||
return _("%s has finished starting").format(app.get_name());
|
|
||||||
else
|
|
||||||
return _("'%s' is ready").format(window.title);
|
|
||||||
},
|
|
||||||
|
|
||||||
_onWindowDemandsAttention : function(display, window) {
|
_onWindowDemandsAttention : function(display, window) {
|
||||||
// We don't want to show the notification when the window is already focused,
|
// We don't want to show the notification when the window is already focused,
|
||||||
// because this is rather pointless.
|
// because this is rather pointless.
|
||||||
@ -57,12 +32,16 @@ WindowAttentionHandler.prototype = {
|
|||||||
let source = new Source(app, window);
|
let source = new Source(app, window);
|
||||||
Main.messageTray.add(source);
|
Main.messageTray.add(source);
|
||||||
|
|
||||||
let notification = new MessageTray.Notification(source, this._getTitle(app, window), this._getBanner(app, window));
|
let banner = _("'%s' is ready").format(window.title);
|
||||||
|
let title = app.get_name();
|
||||||
|
|
||||||
|
let notification = new MessageTray.Notification(source, title, banner);
|
||||||
source.notify(notification);
|
source.notify(notification);
|
||||||
|
|
||||||
source.signalIDs.push(window.connect('notify::title', Lang.bind(this, function(win) {
|
source.signalIDs.push(window.connect('notify::title',
|
||||||
notification.update(this._getTitle(app, win), this._getBanner(app, win));
|
Lang.bind(this, function() {
|
||||||
})));
|
notification.update(title, banner);
|
||||||
|
})));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
/* -*- mode: js2; js2-basic-offset: 4; indent-tabs-mode: nil -*- */
|
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
|
||||||
|
|
||||||
const Clutter = imports.gi.Clutter;
|
const Clutter = imports.gi.Clutter;
|
||||||
const GLib = imports.gi.GLib;
|
const GLib = imports.gi.GLib;
|
||||||
@ -37,28 +37,36 @@ function WindowDimmer(actor) {
|
|||||||
|
|
||||||
WindowDimmer.prototype = {
|
WindowDimmer.prototype = {
|
||||||
_init: function(actor) {
|
_init: function(actor) {
|
||||||
this.effect = new Clutter.ShaderEffect({ shader_type: Clutter.ShaderType.FRAGMENT_SHADER });
|
if (Clutter.feature_available(Clutter.FeatureFlags.SHADERS_GLSL)) {
|
||||||
this.effect.set_shader_source(getDimShaderSource());
|
this._effect = new Clutter.ShaderEffect({ shader_type: Clutter.ShaderType.FRAGMENT_SHADER });
|
||||||
|
this._effect.set_shader_source(getDimShaderSource());
|
||||||
|
} else {
|
||||||
|
this._effect = null;
|
||||||
|
}
|
||||||
|
|
||||||
this.actor = actor;
|
this.actor = actor;
|
||||||
},
|
},
|
||||||
|
|
||||||
set dimFraction(fraction) {
|
set dimFraction(fraction) {
|
||||||
this._dimFraction = fraction;
|
this._dimFraction = fraction;
|
||||||
|
|
||||||
|
if (this._effect == null)
|
||||||
|
return;
|
||||||
|
|
||||||
if (!Meta.prefs_get_attach_modal_dialogs()) {
|
if (!Meta.prefs_get_attach_modal_dialogs()) {
|
||||||
this.effect.enabled = false;
|
this._effect.enabled = false;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fraction > 0.01) {
|
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, 'height', this.actor.get_height());
|
||||||
Shell.shader_effect_set_double_uniform(this.effect, 'fraction', fraction);
|
Shell.shader_effect_set_double_uniform(this._effect, 'fraction', fraction);
|
||||||
|
|
||||||
if (!this.effect.actor)
|
if (!this._effect.actor)
|
||||||
this.actor.add_effect(this.effect);
|
this.actor.add_effect(this._effect);
|
||||||
} else {
|
} else {
|
||||||
if (this.effect.actor)
|
if (this._effect.actor)
|
||||||
this.actor.remove_effect(this.effect);
|
this.actor.remove_effect(this._effect);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -84,7 +92,6 @@ WindowManager.prototype = {
|
|||||||
_init : function() {
|
_init : function() {
|
||||||
this._shellwm = global.window_manager;
|
this._shellwm = global.window_manager;
|
||||||
|
|
||||||
this._keyBindingHandlers = [];
|
|
||||||
this._minimizing = [];
|
this._minimizing = [];
|
||||||
this._maximizing = [];
|
this._maximizing = [];
|
||||||
this._unmaximizing = [];
|
this._unmaximizing = [];
|
||||||
@ -113,15 +120,24 @@ WindowManager.prototype = {
|
|||||||
this._shellwm.connect('destroy', Lang.bind(this, this._destroyWindow));
|
this._shellwm.connect('destroy', Lang.bind(this, this._destroyWindow));
|
||||||
|
|
||||||
this._workspaceSwitcherPopup = null;
|
this._workspaceSwitcherPopup = null;
|
||||||
this.setKeybindingHandler('switch_to_workspace_left', Lang.bind(this, this._showWorkspaceSwitcher));
|
Meta.keybindings_set_custom_handler('switch-to-workspace-left',
|
||||||
this.setKeybindingHandler('switch_to_workspace_right', Lang.bind(this, this._showWorkspaceSwitcher));
|
Lang.bind(this, this._showWorkspaceSwitcher));
|
||||||
this.setKeybindingHandler('switch_to_workspace_up', Lang.bind(this, this._showWorkspaceSwitcher));
|
Meta.keybindings_set_custom_handler('switch-to-workspace-right',
|
||||||
this.setKeybindingHandler('switch_to_workspace_down', Lang.bind(this, this._showWorkspaceSwitcher));
|
Lang.bind(this, this._showWorkspaceSwitcher));
|
||||||
this.setKeybindingHandler('switch_windows', Lang.bind(this, this._startAppSwitcher));
|
Meta.keybindings_set_custom_handler('switch-to-workspace-up',
|
||||||
this.setKeybindingHandler('switch_group', Lang.bind(this, this._startAppSwitcher));
|
Lang.bind(this, this._showWorkspaceSwitcher));
|
||||||
this.setKeybindingHandler('switch_windows_backward', Lang.bind(this, this._startAppSwitcher));
|
Meta.keybindings_set_custom_handler('switch-to-workspace-down',
|
||||||
this.setKeybindingHandler('switch_group_backward', Lang.bind(this, this._startAppSwitcher));
|
Lang.bind(this, this._showWorkspaceSwitcher));
|
||||||
this.setKeybindingHandler('switch_panels', Lang.bind(this, this._startA11ySwitcher));
|
Meta.keybindings_set_custom_handler('switch-windows',
|
||||||
|
Lang.bind(this, this._startAppSwitcher));
|
||||||
|
Meta.keybindings_set_custom_handler('switch-group',
|
||||||
|
Lang.bind(this, this._startAppSwitcher));
|
||||||
|
Meta.keybindings_set_custom_handler('switch-windows-backward',
|
||||||
|
Lang.bind(this, this._startAppSwitcher));
|
||||||
|
Meta.keybindings_set_custom_handler('switch-group-backward',
|
||||||
|
Lang.bind(this, this._startAppSwitcher));
|
||||||
|
Meta.keybindings_set_custom_handler('switch-panels',
|
||||||
|
Lang.bind(this, this._startA11ySwitcher));
|
||||||
|
|
||||||
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++)
|
||||||
@ -133,16 +149,6 @@ WindowManager.prototype = {
|
|||||||
}));
|
}));
|
||||||
},
|
},
|
||||||
|
|
||||||
setKeybindingHandler: function(keybinding, handler){
|
|
||||||
if (this._keyBindingHandlers[keybinding])
|
|
||||||
this._shellwm.disconnect(this._keyBindingHandlers[keybinding]);
|
|
||||||
else
|
|
||||||
this._shellwm.takeover_keybinding(keybinding);
|
|
||||||
|
|
||||||
this._keyBindingHandlers[keybinding] =
|
|
||||||
this._shellwm.connect('keybinding::' + keybinding, handler);
|
|
||||||
},
|
|
||||||
|
|
||||||
blockAnimations: function() {
|
blockAnimations: function() {
|
||||||
this._animationBlockCount++;
|
this._animationBlockCount++;
|
||||||
},
|
},
|
||||||
@ -152,7 +158,7 @@ WindowManager.prototype = {
|
|||||||
},
|
},
|
||||||
|
|
||||||
_shouldAnimate : function(actor) {
|
_shouldAnimate : function(actor) {
|
||||||
if (Main.overview.visible || this._animationsBlocked > 0)
|
if (Main.overview.visible || this._animationBlockCount > 0)
|
||||||
return false;
|
return false;
|
||||||
if (actor && (actor.meta_window.get_window_type() != Meta.WindowType.NORMAL))
|
if (actor && (actor.meta_window.get_window_type() != Meta.WindowType.NORMAL))
|
||||||
return false;
|
return false;
|
||||||
@ -526,37 +532,41 @@ WindowManager.prototype = {
|
|||||||
shellwm.completed_switch_workspace();
|
shellwm.completed_switch_workspace();
|
||||||
},
|
},
|
||||||
|
|
||||||
_startAppSwitcher : function(shellwm, binding, mask, window, backwards) {
|
_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.actor.hide();
|
||||||
|
|
||||||
let tabPopup = new AltTab.AltTabPopup();
|
let tabPopup = new AltTab.AltTabPopup();
|
||||||
|
|
||||||
if (!tabPopup.show(backwards, binding, mask))
|
let modifiers = binding.get_modifiers();
|
||||||
|
let backwards = modifiers & Meta.VirtualModifier.SHIFT_MASK;
|
||||||
|
if (!tabPopup.show(backwards, binding.get_name(), binding.get_mask()))
|
||||||
tabPopup.destroy();
|
tabPopup.destroy();
|
||||||
},
|
},
|
||||||
|
|
||||||
_startA11ySwitcher : function(shellwm, binding, mask, window, backwards) {
|
_startA11ySwitcher : function(display, screen, window, binding) {
|
||||||
Main.ctrlAltTabManager.popup(backwards, mask);
|
let modifiers = binding.get_modifiers();
|
||||||
|
let backwards = modifiers & Meta.VirtualModifier.SHIFT_MASK;
|
||||||
|
Main.ctrlAltTabManager.popup(backwards, binding.get_mask());
|
||||||
},
|
},
|
||||||
|
|
||||||
_showWorkspaceSwitcher : function(shellwm, binding, mask, window, backwards) {
|
_showWorkspaceSwitcher : function(display, screen, window, binding) {
|
||||||
if (global.screen.n_workspaces == 1)
|
if (screen.n_workspaces == 1)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (this._workspaceSwitcherPopup == null)
|
if (this._workspaceSwitcherPopup == null)
|
||||||
this._workspaceSwitcherPopup = new WorkspaceSwitcherPopup.WorkspaceSwitcherPopup();
|
this._workspaceSwitcherPopup = new WorkspaceSwitcherPopup.WorkspaceSwitcherPopup();
|
||||||
|
|
||||||
if (binding == 'switch_to_workspace_up')
|
if (binding.get_name() == 'switch-to-workspace-up')
|
||||||
this.actionMoveWorkspaceUp();
|
this.actionMoveWorkspaceUp();
|
||||||
else if (binding == 'switch_to_workspace_down')
|
else if (binding.get_name() == 'switch-to-workspace-down')
|
||||||
this.actionMoveWorkspaceDown();
|
this.actionMoveWorkspaceDown();
|
||||||
// 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.
|
// but that could be considered confusing.
|
||||||
// else if (binding == 'switch_to_workspace_left')
|
// else if (binding.get_name() == 'switch-to-workspace-left')
|
||||||
// this.actionMoveWorkspaceLeft();
|
// this.actionMoveWorkspaceLeft();
|
||||||
// else if (binding == 'switch_to_workspace_right')
|
// else if (binding.get_name() == 'switch-to-workspace-right')
|
||||||
// this.actionMoveWorkspaceRight();
|
// this.actionMoveWorkspaceRight();
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/* -*- mode: js2; js2-basic-offset: 4; indent-tabs-mode: nil -*- */
|
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
|
||||||
|
|
||||||
const Clutter = imports.gi.Clutter;
|
const Clutter = imports.gi.Clutter;
|
||||||
const GConf = imports.gi.GConf;
|
const Gio = imports.gi.Gio;
|
||||||
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;
|
||||||
@ -28,7 +28,8 @@ const CLOSE_BUTTON_FADE_TIME = 0.1;
|
|||||||
|
|
||||||
const DRAGGING_WINDOW_OPACITY = 100;
|
const DRAGGING_WINDOW_OPACITY = 100;
|
||||||
|
|
||||||
const BUTTON_LAYOUT_KEY = '/desktop/gnome/shell/windows/button_layout';
|
const BUTTON_LAYOUT_SCHEMA = 'org.gnome.shell.overrides';
|
||||||
|
const BUTTON_LAYOUT_KEY = 'button-layout';
|
||||||
|
|
||||||
// Define a layout scheme for small window counts. For larger
|
// Define a layout scheme for small window counts. For larger
|
||||||
// counts we fall back to an algorithm. We need more schemes here
|
// counts we fall back to an algorithm. We need more schemes here
|
||||||
@ -135,8 +136,11 @@ WindowClone.prototype = {
|
|||||||
this._realWindowDestroyId = this.realWindow.connect('destroy',
|
this._realWindowDestroyId = this.realWindow.connect('destroy',
|
||||||
Lang.bind(this, this._disconnectRealWindowSignals));
|
Lang.bind(this, this._disconnectRealWindowSignals));
|
||||||
|
|
||||||
this.actor.connect('button-release-event',
|
let clickAction = new Clutter.ClickAction();
|
||||||
Lang.bind(this, this._onButtonRelease));
|
clickAction.connect('clicked', Lang.bind(this, this._onClicked));
|
||||||
|
clickAction.connect('long-press', Lang.bind(this, this._onLongPress));
|
||||||
|
|
||||||
|
this.actor.add_action(clickAction);
|
||||||
|
|
||||||
this.actor.connect('scroll-event',
|
this.actor.connect('scroll-event',
|
||||||
Lang.bind(this, this._onScroll));
|
Lang.bind(this, this._onScroll));
|
||||||
@ -147,6 +151,7 @@ WindowClone.prototype = {
|
|||||||
|
|
||||||
this._draggable = DND.makeDraggable(this.actor,
|
this._draggable = DND.makeDraggable(this.actor,
|
||||||
{ restoreOnSuccess: true,
|
{ restoreOnSuccess: true,
|
||||||
|
manualMode: true,
|
||||||
dragActorMaxSize: WINDOW_DND_SIZE,
|
dragActorMaxSize: WINDOW_DND_SIZE,
|
||||||
dragActorOpacity: DRAGGING_WINDOW_OPACITY });
|
dragActorOpacity: DRAGGING_WINDOW_OPACITY });
|
||||||
this._draggable.connect('drag-begin', Lang.bind(this, this._onDragBegin));
|
this._draggable.connect('drag-begin', Lang.bind(this, this._onDragBegin));
|
||||||
@ -345,9 +350,27 @@ WindowClone.prototype = {
|
|||||||
this._zoomStep = undefined;
|
this._zoomStep = undefined;
|
||||||
},
|
},
|
||||||
|
|
||||||
_onButtonRelease : function (actor, event) {
|
_onClicked: function(action, actor) {
|
||||||
this._selected = true;
|
this._selected = true;
|
||||||
this.emit('selected', event.get_time());
|
this.emit('selected', global.get_current_time());
|
||||||
|
},
|
||||||
|
|
||||||
|
_onLongPress: function(action, actor, state) {
|
||||||
|
// Take advantage of the Clutter policy to consider
|
||||||
|
// a long-press canceled when the pointer movement
|
||||||
|
// exceeds dnd-drag-threshold to manually start the drag
|
||||||
|
if (state == Clutter.LongPressState.CANCEL) {
|
||||||
|
// A click cancels a long-press before any click handler is
|
||||||
|
// run - make sure to not start a drag in that case
|
||||||
|
Meta.later_add(Meta.LaterType.BEFORE_REDRAW, Lang.bind(this,
|
||||||
|
function() {
|
||||||
|
if (this._selected)
|
||||||
|
return;
|
||||||
|
let [x, y] = action.get_coords();
|
||||||
|
this._draggable.startDrag(x, y, global.get_current_time());
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
return true;
|
||||||
},
|
},
|
||||||
|
|
||||||
_onDragBegin : function (draggable, time) {
|
_onDragBegin : function (draggable, time) {
|
||||||
@ -505,8 +528,8 @@ WindowOverlay.prototype = {
|
|||||||
let button = this.closeButton;
|
let button = this.closeButton;
|
||||||
let title = this.title;
|
let title = this.title;
|
||||||
|
|
||||||
let gconf = GConf.Client.get_default();
|
let settings = new Gio.Settings({ schema: BUTTON_LAYOUT_SCHEMA });
|
||||||
let layout = gconf.get_string(BUTTON_LAYOUT_KEY);
|
let layout = settings.get_string(BUTTON_LAYOUT_KEY);
|
||||||
let rtl = St.Widget.get_default_direction() == St.TextDirection.RTL;
|
let rtl = St.Widget.get_default_direction() == St.TextDirection.RTL;
|
||||||
|
|
||||||
let split = layout.split(":");
|
let split = layout.split(":");
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
/* -*- mode: js2; js2-basic-offset: 4; indent-tabs-mode: nil -*- */
|
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
|
||||||
|
|
||||||
const Clutter = imports.gi.Clutter;
|
const Clutter = imports.gi.Clutter;
|
||||||
const Lang = imports.lang;
|
const Lang = imports.lang;
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
/* -*- mode: js2; js2-basic-offset: 4; indent-tabs-mode: nil -*- */
|
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
|
||||||
|
|
||||||
const Clutter = imports.gi.Clutter;
|
const Clutter = imports.gi.Clutter;
|
||||||
const Lang = imports.lang;
|
const Lang = imports.lang;
|
||||||
@ -20,6 +20,11 @@ let MAX_THUMBNAIL_SCALE = 1/8.;
|
|||||||
const RESCALE_ANIMATION_TIME = 0.2;
|
const RESCALE_ANIMATION_TIME = 0.2;
|
||||||
const SLIDE_ANIMATION_TIME = 0.2;
|
const SLIDE_ANIMATION_TIME = 0.2;
|
||||||
|
|
||||||
|
// When we create workspaces by dragging, we add a "cut" into the top and
|
||||||
|
// bottom of each workspace so that the user doesn't have to hit the
|
||||||
|
// placeholder exactly.
|
||||||
|
const WORKSPACE_CUT_SIZE = 10;
|
||||||
|
|
||||||
function WindowClone(realWindow) {
|
function WindowClone(realWindow) {
|
||||||
this._init(realWindow);
|
this._init(realWindow);
|
||||||
}
|
}
|
||||||
@ -422,6 +427,11 @@ WorkspaceThumbnail.prototype = {
|
|||||||
if (this.state > ThumbnailState.NORMAL)
|
if (this.state > ThumbnailState.NORMAL)
|
||||||
return DND.DragMotionResult.CONTINUE;
|
return DND.DragMotionResult.CONTINUE;
|
||||||
|
|
||||||
|
let [w, h] = this.actor.get_transformed_size();
|
||||||
|
// Bubble up if we're in the "workspace cut".
|
||||||
|
if (y < WORKSPACE_CUT_SIZE || y > h - WORKSPACE_CUT_SIZE)
|
||||||
|
return DND.DragMotionResult.CONTINUE;
|
||||||
|
|
||||||
if (source.realWindow && !this._isMyWindow(source.realWindow))
|
if (source.realWindow && !this._isMyWindow(source.realWindow))
|
||||||
return DND.DragMotionResult.MOVE_DROP;
|
return DND.DragMotionResult.MOVE_DROP;
|
||||||
if (source.shellWorkspaceLaunch)
|
if (source.shellWorkspaceLaunch)
|
||||||
@ -475,6 +485,7 @@ ThumbnailsBox.prototype = {
|
|||||||
this.actor.connect('get-preferred-width', Lang.bind(this, this._getPreferredWidth));
|
this.actor.connect('get-preferred-width', Lang.bind(this, this._getPreferredWidth));
|
||||||
this.actor.connect('get-preferred-height', Lang.bind(this, this._getPreferredHeight));
|
this.actor.connect('get-preferred-height', Lang.bind(this, this._getPreferredHeight));
|
||||||
this.actor.connect('allocate', Lang.bind(this, this._allocate));
|
this.actor.connect('allocate', Lang.bind(this, this._allocate));
|
||||||
|
this.actor._delegate = this;
|
||||||
|
|
||||||
// When we animate the scale, we don't animate the requested size of the thumbnails, rather
|
// When we animate the scale, we don't animate the requested size of the thumbnails, rather
|
||||||
// we ask for our final size and then animate within that size. This slightly simplifies the
|
// we ask for our final size and then animate within that size. This slightly simplifies the
|
||||||
@ -498,6 +509,10 @@ ThumbnailsBox.prototype = {
|
|||||||
this._indicator = indicator;
|
this._indicator = indicator;
|
||||||
this.actor.add_actor(indicator);
|
this.actor.add_actor(indicator);
|
||||||
|
|
||||||
|
this._dropPlaceholderPos = -1;
|
||||||
|
this._dropPlaceholder = new St.Bin({ style_class: 'placeholder' });
|
||||||
|
this.actor.add_actor(this._dropPlaceholder);
|
||||||
|
|
||||||
this._targetScale = 0;
|
this._targetScale = 0;
|
||||||
this._scale = 0;
|
this._scale = 0;
|
||||||
this._pendingScaleUpdate = false;
|
this._pendingScaleUpdate = false;
|
||||||
@ -512,6 +527,83 @@ ThumbnailsBox.prototype = {
|
|||||||
this._thumbnails = [];
|
this._thumbnails = [];
|
||||||
},
|
},
|
||||||
|
|
||||||
|
// Draggable target interface
|
||||||
|
handleDragOver : function(source, actor, x, y, time) {
|
||||||
|
if (!source.realWindow && !source.shellWorkspaceLaunch)
|
||||||
|
return DND.DragMotionResult.CONTINUE;
|
||||||
|
|
||||||
|
let spacing = this.actor.get_theme_node().get_length('spacing');
|
||||||
|
let thumbHeight = this._porthole.height * this._scale;
|
||||||
|
|
||||||
|
let workspace = -1;
|
||||||
|
let firstThumbY = this._thumbnails[0].actor.y;
|
||||||
|
for (let i = 0; i < this._thumbnails.length; i ++) {
|
||||||
|
let targetBase = firstThumbY + (thumbHeight + spacing) * i;
|
||||||
|
|
||||||
|
// Allow the reorder target to have a 10px "cut" into
|
||||||
|
// each side of the thumbnail, to make dragging onto the
|
||||||
|
// placeholder easier
|
||||||
|
let targetTop = targetBase - spacing - WORKSPACE_CUT_SIZE;
|
||||||
|
let targetBottom = targetBase + WORKSPACE_CUT_SIZE;
|
||||||
|
|
||||||
|
// Expand the target to include the placeholder, if it exists.
|
||||||
|
if (i == this._dropPlaceholderPos)
|
||||||
|
targetBottom += this._dropPlaceholder.get_height();
|
||||||
|
|
||||||
|
if (y > targetTop && y <= targetBottom) {
|
||||||
|
workspace = i;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
this._dropPlaceholderPos = workspace;
|
||||||
|
this.actor.queue_relayout();
|
||||||
|
|
||||||
|
if (workspace == -1)
|
||||||
|
return DND.DragMotionResult.CONTINUE;
|
||||||
|
|
||||||
|
return DND.DragMotionResult.MOVE_DROP;
|
||||||
|
},
|
||||||
|
|
||||||
|
acceptDrop: function(source, actor, x, y, time) {
|
||||||
|
if (this._dropPlaceholderPos == -1)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (!source.realWindow && !source.shellWorkspaceLaunch)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
let isWindow = !!source.realWindow;
|
||||||
|
|
||||||
|
// To create a new workspace, we first slide all the windows on workspaces
|
||||||
|
// below us to the next workspace, leaving a blank workspace for us to recycle.
|
||||||
|
let newWorkspaceIndex;
|
||||||
|
[newWorkspaceIndex, this._dropPlaceholderPos] = [this._dropPlaceholderPos, -1];
|
||||||
|
|
||||||
|
// Nab all the windows below us.
|
||||||
|
let windows = global.get_window_actors().filter(function(win) {
|
||||||
|
if (isWindow)
|
||||||
|
return win.get_workspace() >= newWorkspaceIndex && win != source;
|
||||||
|
else
|
||||||
|
return win.get_workspace() >= newWorkspaceIndex;
|
||||||
|
});
|
||||||
|
|
||||||
|
// ... move them down one.
|
||||||
|
windows.forEach(function(win) {
|
||||||
|
win.meta_window.change_workspace_by_index(win.get_workspace() + 1,
|
||||||
|
true, time);
|
||||||
|
});
|
||||||
|
|
||||||
|
if (isWindow)
|
||||||
|
// ... and bam, a workspace, good as new.
|
||||||
|
source.metaWindow.change_workspace_by_index(newWorkspaceIndex,
|
||||||
|
true, time);
|
||||||
|
else if (source.shellWorkspaceLaunch)
|
||||||
|
source.shellWorkspaceLaunch({ workspace: newWorkspaceIndex,
|
||||||
|
timestamp: time });
|
||||||
|
|
||||||
|
return true;
|
||||||
|
},
|
||||||
|
|
||||||
show: function() {
|
show: function() {
|
||||||
this._switchWorkspaceNotifyId =
|
this._switchWorkspaceNotifyId =
|
||||||
global.window_manager.connect('switch-workspace',
|
global.window_manager.connect('switch-workspace',
|
||||||
@ -840,20 +932,18 @@ ThumbnailsBox.prototype = {
|
|||||||
|
|
||||||
let y = contentBox.y1;
|
let y = contentBox.y1;
|
||||||
|
|
||||||
|
if (this._dropPlaceholderPos == -1) {
|
||||||
|
Meta.later_add(Meta.LaterType.BEFORE_REDRAW, Lang.bind(this, function() {
|
||||||
|
this._dropPlaceholder.hide();
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
for (let i = 0; i < this._thumbnails.length; i++) {
|
for (let i = 0; i < this._thumbnails.length; i++) {
|
||||||
let thumbnail = this._thumbnails[i];
|
let thumbnail = this._thumbnails[i];
|
||||||
|
|
||||||
if (i > 0)
|
if (i > 0)
|
||||||
y += spacing - Math.round(thumbnail.collapseFraction * spacing);
|
y += spacing - Math.round(thumbnail.collapseFraction * spacing);
|
||||||
|
|
||||||
// We might end up with thumbnailHeight being something like 99.33
|
|
||||||
// pixels. To make this work and not end up with a gap at the bottom,
|
|
||||||
// we need some thumbnails to be 99 pixels and some 100 pixels height;
|
|
||||||
// we compute an actual scale separately for each thumbnail.
|
|
||||||
let y1 = Math.round(y);
|
|
||||||
let y2 = Math.round(y + thumbnailHeight);
|
|
||||||
let roundedVScale = (y2 - y1) / portholeHeight;
|
|
||||||
|
|
||||||
let x1, x2;
|
let x1, x2;
|
||||||
if (rtl) {
|
if (rtl) {
|
||||||
x1 = contentBox.x1 + slideOffset * thumbnail.slidePosition;
|
x1 = contentBox.x1 + slideOffset * thumbnail.slidePosition;
|
||||||
@ -863,6 +953,27 @@ ThumbnailsBox.prototype = {
|
|||||||
x2 = x1 + thumbnailWidth;
|
x2 = x1 + thumbnailWidth;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (i == this._dropPlaceholderPos) {
|
||||||
|
let [minHeight, placeholderHeight] = this._dropPlaceholder.get_preferred_height(-1);
|
||||||
|
childBox.x1 = x1;
|
||||||
|
childBox.x2 = x1 + thumbnailWidth;
|
||||||
|
childBox.y1 = Math.round(y);
|
||||||
|
childBox.y2 = Math.round(y + placeholderHeight);
|
||||||
|
this._dropPlaceholder.allocate(childBox, flags);
|
||||||
|
Meta.later_add(Meta.LaterType.BEFORE_REDRAW, Lang.bind(this, function() {
|
||||||
|
this._dropPlaceholder.show();
|
||||||
|
}));
|
||||||
|
y += placeholderHeight + spacing;
|
||||||
|
}
|
||||||
|
|
||||||
|
// We might end up with thumbnailHeight being something like 99.33
|
||||||
|
// pixels. To make this work and not end up with a gap at the bottom,
|
||||||
|
// we need some thumbnails to be 99 pixels and some 100 pixels height;
|
||||||
|
// we compute an actual scale separately for each thumbnail.
|
||||||
|
let y1 = Math.round(y);
|
||||||
|
let y2 = Math.round(y + thumbnailHeight);
|
||||||
|
let roundedVScale = (y2 - y1) / portholeHeight;
|
||||||
|
|
||||||
if (thumbnail.metaWorkspace == indicatorWorkspace)
|
if (thumbnail.metaWorkspace == indicatorWorkspace)
|
||||||
indicatorY = y1;
|
indicatorY = y1;
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
/* -*- mode: js2; js2-basic-offset: 4; indent-tabs-mode: nil -*- */
|
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
|
||||||
|
|
||||||
const Clutter = imports.gi.Clutter;
|
const Clutter = imports.gi.Clutter;
|
||||||
const Lang = imports.lang;
|
const Lang = imports.lang;
|
||||||
@ -109,8 +109,6 @@ WorkspacesView.prototype = {
|
|||||||
this._scrollAdjustment.connect('notify::value',
|
this._scrollAdjustment.connect('notify::value',
|
||||||
Lang.bind(this, this._onScroll));
|
Lang.bind(this, this._onScroll));
|
||||||
|
|
||||||
this._timeoutId = 0;
|
|
||||||
|
|
||||||
this._switchWorkspaceNotifyId =
|
this._switchWorkspaceNotifyId =
|
||||||
global.window_manager.connect('switch-workspace',
|
global.window_manager.connect('switch-workspace',
|
||||||
Lang.bind(this, this._activeWorkspaceChanged));
|
Lang.bind(this, this._activeWorkspaceChanged));
|
||||||
@ -321,10 +319,6 @@ WorkspacesView.prototype = {
|
|||||||
if (this._inDrag)
|
if (this._inDrag)
|
||||||
this._dragEnd();
|
this._dragEnd();
|
||||||
|
|
||||||
if (this._timeoutId) {
|
|
||||||
Mainloop.source_remove(this._timeoutId);
|
|
||||||
this._timeoutId = 0;
|
|
||||||
}
|
|
||||||
if (this._itemDragBeginId > 0) {
|
if (this._itemDragBeginId > 0) {
|
||||||
Main.overview.disconnect(this._itemDragBeginId);
|
Main.overview.disconnect(this._itemDragBeginId);
|
||||||
this._itemDragBeginId = 0;
|
this._itemDragBeginId = 0;
|
||||||
@ -383,72 +377,10 @@ WorkspacesView.prototype = {
|
|||||||
this._extraWorkspaces[i].setReservedSlot(dragEvent.dragActor._delegate);
|
this._extraWorkspaces[i].setReservedSlot(dragEvent.dragActor._delegate);
|
||||||
}
|
}
|
||||||
|
|
||||||
let primary = Main.layoutManager.primaryMonitor;
|
return DND.DragMotionResult.CONTINUE;
|
||||||
|
|
||||||
let activeWorkspaceIndex = global.screen.get_active_workspace_index();
|
|
||||||
let topWorkspace, bottomWorkspace;
|
|
||||||
topWorkspace = this._workspaces[activeWorkspaceIndex - 1];
|
|
||||||
bottomWorkspace = this._workspaces[activeWorkspaceIndex + 1];
|
|
||||||
let hoverWorkspace = null;
|
|
||||||
|
|
||||||
// reactive monitor edges
|
|
||||||
let topEdge = primary.y;
|
|
||||||
let switchTop = (dragEvent.y <= topEdge && topWorkspace);
|
|
||||||
if (switchTop && this._dragOverLastY != topEdge) {
|
|
||||||
topWorkspace.metaWorkspace.activate(global.get_current_time());
|
|
||||||
this._dragOverLastY = topEdge;
|
|
||||||
|
|
||||||
return DND.DragMotionResult.CONTINUE;
|
|
||||||
}
|
|
||||||
let bottomEdge = primary.y + primary.height - 1;
|
|
||||||
let switchBottom = (dragEvent.y >= bottomEdge && bottomWorkspace);
|
|
||||||
if (switchBottom && this._dragOverLastY != bottomEdge) {
|
|
||||||
bottomWorkspace.metaWorkspace.activate(global.get_current_time());
|
|
||||||
this._dragOverLastY = bottomEdge;
|
|
||||||
|
|
||||||
return DND.DragMotionResult.CONTINUE;
|
|
||||||
}
|
|
||||||
this._dragOverLastY = dragEvent.y;
|
|
||||||
let result = DND.DragMotionResult.CONTINUE;
|
|
||||||
|
|
||||||
// check hover state of new workspace area / inactive workspaces
|
|
||||||
if (topWorkspace) {
|
|
||||||
if (topWorkspace.actor.contains(dragEvent.targetActor)) {
|
|
||||||
hoverWorkspace = topWorkspace;
|
|
||||||
result = topWorkspace.handleDragOver(dragEvent.source, dragEvent.dragActor);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (bottomWorkspace) {
|
|
||||||
if (bottomWorkspace.actor.contains(dragEvent.targetActor)) {
|
|
||||||
hoverWorkspace = bottomWorkspace;
|
|
||||||
result = bottomWorkspace.handleDragOver(dragEvent.source, dragEvent.dragActor);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// handle delayed workspace switches
|
|
||||||
if (hoverWorkspace) {
|
|
||||||
if (!this._timeoutId)
|
|
||||||
this._timeoutId = Mainloop.timeout_add_seconds(1,
|
|
||||||
Lang.bind(this, function() {
|
|
||||||
hoverWorkspace.metaWorkspace.activate(global.get_current_time());
|
|
||||||
return false;
|
|
||||||
}));
|
|
||||||
} else {
|
|
||||||
if (this._timeoutId) {
|
|
||||||
Mainloop.source_remove(this._timeoutId);
|
|
||||||
this._timeoutId = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
},
|
},
|
||||||
|
|
||||||
_dragEnd: function() {
|
_dragEnd: function() {
|
||||||
if (this._timeoutId) {
|
|
||||||
Mainloop.source_remove(this._timeoutId);
|
|
||||||
this._timeoutId = 0;
|
|
||||||
}
|
|
||||||
DND.removeDragMonitor(this._dragMonitor);
|
DND.removeDragMonitor(this._dragMonitor);
|
||||||
this._inDrag = false;
|
this._inDrag = false;
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
/* -*- mode: js2; js2-basic-offset: 4; indent-tabs-mode: nil -*- */
|
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
|
||||||
|
|
||||||
const Clutter = imports.gi.Clutter;
|
const Clutter = imports.gi.Clutter;
|
||||||
const Lang = imports.lang;
|
const Lang = imports.lang;
|
||||||
|
@ -1,6 +1,8 @@
|
|||||||
af
|
af
|
||||||
an
|
an
|
||||||
ar
|
ar
|
||||||
|
as
|
||||||
|
ast
|
||||||
be
|
be
|
||||||
bg
|
bg
|
||||||
bn
|
bn
|
||||||
@ -30,6 +32,7 @@ it
|
|||||||
ja
|
ja
|
||||||
ko
|
ko
|
||||||
kn
|
kn
|
||||||
|
ku
|
||||||
lt
|
lt
|
||||||
lv
|
lv
|
||||||
mr
|
mr
|
||||||
|
@ -25,6 +25,7 @@ js/ui/polkitAuthenticationAgent.js
|
|||||||
js/ui/popupMenu.js
|
js/ui/popupMenu.js
|
||||||
js/ui/runDialog.js
|
js/ui/runDialog.js
|
||||||
js/ui/searchDisplay.js
|
js/ui/searchDisplay.js
|
||||||
|
js/ui/shellEntry.js
|
||||||
js/ui/shellMountOperation.js
|
js/ui/shellMountOperation.js
|
||||||
js/ui/status/accessibility.js
|
js/ui/status/accessibility.js
|
||||||
js/ui/status/bluetooth.js
|
js/ui/status/bluetooth.js
|
||||||
@ -44,4 +45,3 @@ src/shell-global.c
|
|||||||
src/shell-mobile-providers.c
|
src/shell-mobile-providers.c
|
||||||
src/shell-polkit-authentication-agent.c
|
src/shell-polkit-authentication-agent.c
|
||||||
src/shell-util.c
|
src/shell-util.c
|
||||||
|
|
||||||
|
136
po/be.po
136
po/be.po
@ -2,8 +2,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: 2011-09-19 21:58+0300\n"
|
"POT-Creation-Date: 2011-09-21 22:18+0300\n"
|
||||||
"PO-Revision-Date: 2011-09-19 21:58+0300\n"
|
"PO-Revision-Date: 2011-09-21 22:18+0300\n"
|
||||||
"Last-Translator: Ігар Грачышка <ihar.hrachyshka@gmail.com>\n"
|
"Last-Translator: Ігар Грачышка <ihar.hrachyshka@gmail.com>\n"
|
||||||
"Language-Team: Belarusian <i18n-bel-gnome@googlegroups.com>\n"
|
"Language-Team: Belarusian <i18n-bel-gnome@googlegroups.com>\n"
|
||||||
"Language: be\n"
|
"Language: be\n"
|
||||||
@ -169,8 +169,8 @@ msgid "Not listed?"
|
|||||||
msgstr "Няма ў спісе?"
|
msgstr "Няма ў спісе?"
|
||||||
|
|
||||||
#: ../js/gdm/loginDialog.js:1004 ../js/ui/endSessionDialog.js:426
|
#: ../js/gdm/loginDialog.js:1004 ../js/ui/endSessionDialog.js:426
|
||||||
#: ../js/ui/extensionSystem.js:477 ../js/ui/networkAgent.js:158
|
#: ../js/ui/extensionSystem.js:477 ../js/ui/networkAgent.js:165
|
||||||
#: ../js/ui/polkitAuthenticationAgent.js:170 ../js/ui/status/bluetooth.js:480
|
#: ../js/ui/polkitAuthenticationAgent.js:171 ../js/ui/status/bluetooth.js:480
|
||||||
msgid "Cancel"
|
msgid "Cancel"
|
||||||
msgstr "Скасаваць"
|
msgstr "Скасаваць"
|
||||||
|
|
||||||
@ -183,8 +183,8 @@ msgstr "Увайсці"
|
|||||||
msgid "Login Window"
|
msgid "Login Window"
|
||||||
msgstr "Акно ўваходу"
|
msgstr "Акно ўваходу"
|
||||||
|
|
||||||
#: ../js/gdm/powerMenu.js:116 ../js/ui/userMenu.js:525
|
#: ../js/gdm/powerMenu.js:116 ../js/ui/userMenu.js:514
|
||||||
#: ../js/ui/userMenu.js:527 ../js/ui/userMenu.js:596
|
#: ../js/ui/userMenu.js:516 ../js/ui/userMenu.js:585
|
||||||
msgid "Suspend"
|
msgid "Suspend"
|
||||||
msgstr "Прыпыніць камп'ютар"
|
msgstr "Прыпыніць камп'ютар"
|
||||||
|
|
||||||
@ -248,12 +248,16 @@ msgstr "%s дададзены ў ваш спіс упадабанага."
|
|||||||
msgid "%s has been removed from your favorites."
|
msgid "%s has been removed from your favorites."
|
||||||
msgstr "%s выдалены з вашага спіса ўпадабанага."
|
msgstr "%s выдалены з вашага спіса ўпадабанага."
|
||||||
|
|
||||||
#: ../js/ui/autorunManager.js:592
|
#: ../js/ui/autorunManager.js:280
|
||||||
|
msgid "Removable Devices"
|
||||||
|
msgstr "Зменныя прыстасаванні"
|
||||||
|
|
||||||
|
#: ../js/ui/autorunManager.js:590
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "Open with %s"
|
msgid "Open with %s"
|
||||||
msgstr "Адкрыць у %s"
|
msgstr "Адкрыць у %s"
|
||||||
|
|
||||||
#: ../js/ui/autorunManager.js:618
|
#: ../js/ui/autorunManager.js:616
|
||||||
msgid "Eject"
|
msgid "Eject"
|
||||||
msgstr "Выняць"
|
msgstr "Выняць"
|
||||||
|
|
||||||
@ -408,15 +412,15 @@ msgstr "На наступным тыдні"
|
|||||||
msgid "Unknown"
|
msgid "Unknown"
|
||||||
msgstr "Невядома"
|
msgstr "Невядома"
|
||||||
|
|
||||||
#: ../js/ui/contactDisplay.js:80 ../js/ui/userMenu.js:147
|
#: ../js/ui/contactDisplay.js:80 ../js/ui/userMenu.js:139
|
||||||
msgid "Available"
|
msgid "Available"
|
||||||
msgstr "Даступны"
|
msgstr "Даступны"
|
||||||
|
|
||||||
#: ../js/ui/contactDisplay.js:85 ../js/ui/userMenu.js:156
|
#: ../js/ui/contactDisplay.js:85 ../js/ui/userMenu.js:148
|
||||||
msgid "Away"
|
msgid "Away"
|
||||||
msgstr "Адсутны"
|
msgstr "Адсутны"
|
||||||
|
|
||||||
#: ../js/ui/contactDisplay.js:89 ../js/ui/userMenu.js:150
|
#: ../js/ui/contactDisplay.js:89 ../js/ui/userMenu.js:142
|
||||||
msgid "Busy"
|
msgid "Busy"
|
||||||
msgstr "Заняты"
|
msgstr "Заняты"
|
||||||
|
|
||||||
@ -428,7 +432,7 @@ msgstr "Па-за сеткай"
|
|||||||
msgid "CONTACTS"
|
msgid "CONTACTS"
|
||||||
msgstr "КАНТАКТЫ"
|
msgstr "КАНТАКТЫ"
|
||||||
|
|
||||||
#: ../js/ui/dash.js:172 ../js/ui/messageTray.js:1196
|
#: ../js/ui/dash.js:172 ../js/ui/messageTray.js:1197
|
||||||
msgid "Remove"
|
msgid "Remove"
|
||||||
msgstr "Выдаліць"
|
msgstr "Выдаліць"
|
||||||
|
|
||||||
@ -609,58 +613,58 @@ msgstr "Паглядзець выточны код"
|
|||||||
msgid "Web Page"
|
msgid "Web Page"
|
||||||
msgstr "Сеціўная старонка"
|
msgstr "Сеціўная старонка"
|
||||||
|
|
||||||
#: ../js/ui/messageTray.js:1189
|
#: ../js/ui/messageTray.js:1190
|
||||||
msgid "Open"
|
msgid "Open"
|
||||||
msgstr "Адкрыць"
|
msgstr "Адкрыць"
|
||||||
|
|
||||||
#: ../js/ui/messageTray.js:2371
|
#: ../js/ui/messageTray.js:2372
|
||||||
msgid "System Information"
|
msgid "System Information"
|
||||||
msgstr "Сістэмная інфармацыя"
|
msgstr "Сістэмная інфармацыя"
|
||||||
|
|
||||||
#: ../js/ui/networkAgent.js:138
|
#: ../js/ui/networkAgent.js:145
|
||||||
msgid "Show password"
|
msgid "Show password"
|
||||||
msgstr "Паказваць пароль"
|
msgstr "Паказваць пароль"
|
||||||
|
|
||||||
#: ../js/ui/networkAgent.js:153
|
#: ../js/ui/networkAgent.js:160
|
||||||
msgid "Connect"
|
msgid "Connect"
|
||||||
msgstr "Злучыць"
|
msgstr "Злучыць"
|
||||||
|
|
||||||
#. Cisco LEAP
|
#. Cisco LEAP
|
||||||
#: ../js/ui/networkAgent.js:248 ../js/ui/networkAgent.js:260
|
#: ../js/ui/networkAgent.js:255 ../js/ui/networkAgent.js:267
|
||||||
#: ../js/ui/networkAgent.js:287 ../js/ui/networkAgent.js:307
|
#: ../js/ui/networkAgent.js:294 ../js/ui/networkAgent.js:314
|
||||||
#: ../js/ui/networkAgent.js:317
|
#: ../js/ui/networkAgent.js:324
|
||||||
msgid "Password: "
|
msgid "Password: "
|
||||||
msgstr "Пароль: "
|
msgstr "Пароль: "
|
||||||
|
|
||||||
#. static WEP
|
#. static WEP
|
||||||
#: ../js/ui/networkAgent.js:253
|
#: ../js/ui/networkAgent.js:260
|
||||||
msgid "Key: "
|
msgid "Key: "
|
||||||
msgstr "Ключ: "
|
msgstr "Ключ: "
|
||||||
|
|
||||||
#. TTLS and PEAP are actually much more complicated, but this complication
|
#. TTLS and PEAP are actually much more complicated, but this complication
|
||||||
#. is not visible here since we only care about phase2 authentication
|
#. is not visible here since we only care about phase2 authentication
|
||||||
#. (and don't even care of which one)
|
#. (and don't even care of which one)
|
||||||
#: ../js/ui/networkAgent.js:285 ../js/ui/networkAgent.js:303
|
#: ../js/ui/networkAgent.js:292 ../js/ui/networkAgent.js:310
|
||||||
msgid "Username: "
|
msgid "Username: "
|
||||||
msgstr "Імя карыстальніка: "
|
msgstr "Імя карыстальніка: "
|
||||||
|
|
||||||
#: ../js/ui/networkAgent.js:291
|
#: ../js/ui/networkAgent.js:298
|
||||||
msgid "Identity: "
|
msgid "Identity: "
|
||||||
msgstr "Ідэнтычнасць: "
|
msgstr "Ідэнтычнасць: "
|
||||||
|
|
||||||
#: ../js/ui/networkAgent.js:293
|
#: ../js/ui/networkAgent.js:300
|
||||||
msgid "Private key password: "
|
msgid "Private key password: "
|
||||||
msgstr "Пароль да прыватнага ключа: "
|
msgstr "Пароль да прыватнага ключа: "
|
||||||
|
|
||||||
#: ../js/ui/networkAgent.js:305
|
#: ../js/ui/networkAgent.js:312
|
||||||
msgid "Service: "
|
msgid "Service: "
|
||||||
msgstr "Паслуга: "
|
msgstr "Паслуга: "
|
||||||
|
|
||||||
#: ../js/ui/networkAgent.js:334
|
#: ../js/ui/networkAgent.js:341
|
||||||
msgid "Authentication required by wireless network"
|
msgid "Authentication required by wireless network"
|
||||||
msgstr "Для бесправадной сеткі патрэбная ідэнтыфікацыя"
|
msgstr "Для бесправадной сеткі патрэбная ідэнтыфікацыя"
|
||||||
|
|
||||||
#: ../js/ui/networkAgent.js:335
|
#: ../js/ui/networkAgent.js:342
|
||||||
#, 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 "
|
||||||
@ -669,37 +673,37 @@ msgstr ""
|
|||||||
"Для доступу да бесправадной сеткі \"%s\" патрэбны пароль або ключы "
|
"Для доступу да бесправадной сеткі \"%s\" патрэбны пароль або ключы "
|
||||||
"шыфравання."
|
"шыфравання."
|
||||||
|
|
||||||
#: ../js/ui/networkAgent.js:339
|
#: ../js/ui/networkAgent.js:346
|
||||||
msgid "Wired 802.1X authentication"
|
msgid "Wired 802.1X authentication"
|
||||||
msgstr "Правадная ідэнтыфікацыя 802.1X"
|
msgstr "Правадная ідэнтыфікацыя 802.1X"
|
||||||
|
|
||||||
#: ../js/ui/networkAgent.js:341
|
#: ../js/ui/networkAgent.js:348
|
||||||
msgid "Network name: "
|
msgid "Network name: "
|
||||||
msgstr "Назва сеткі: "
|
msgstr "Назва сеткі: "
|
||||||
|
|
||||||
#: ../js/ui/networkAgent.js:346
|
#: ../js/ui/networkAgent.js:353
|
||||||
msgid "DSL authentication"
|
msgid "DSL authentication"
|
||||||
msgstr "DSL-ідэнтыфікацыя"
|
msgstr "DSL-ідэнтыфікацыя"
|
||||||
|
|
||||||
#: ../js/ui/networkAgent.js:353
|
#: ../js/ui/networkAgent.js:360
|
||||||
msgid "PIN code required"
|
msgid "PIN code required"
|
||||||
msgstr "Патрэбны PIN-код"
|
msgstr "Патрэбны PIN-код"
|
||||||
|
|
||||||
#: ../js/ui/networkAgent.js:354
|
#: ../js/ui/networkAgent.js:361
|
||||||
msgid "PIN code is needed for the mobile broadband device"
|
msgid "PIN code is needed for the mobile broadband device"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Для прыстасавання для доступу да шырокапалоснай мабільнай сеткі патрэбны PIN-"
|
"Для прыстасавання для доступу да шырокапалоснай мабільнай сеткі патрэбны PIN-"
|
||||||
"код"
|
"код"
|
||||||
|
|
||||||
#: ../js/ui/networkAgent.js:355
|
#: ../js/ui/networkAgent.js:362
|
||||||
msgid "PIN: "
|
msgid "PIN: "
|
||||||
msgstr "PIN-код: "
|
msgstr "PIN-код: "
|
||||||
|
|
||||||
#: ../js/ui/networkAgent.js:361
|
#: ../js/ui/networkAgent.js:368
|
||||||
msgid "Mobile broadband network password"
|
msgid "Mobile broadband network password"
|
||||||
msgstr "Пароль да шырокапалоснай мабільнай сеткі"
|
msgstr "Пароль да шырокапалоснай мабільнай сеткі"
|
||||||
|
|
||||||
#: ../js/ui/networkAgent.js:362
|
#: ../js/ui/networkAgent.js:369
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "A password is required to connect to '%s'."
|
msgid "A password is required to connect to '%s'."
|
||||||
msgstr "Каб злучыцца з \"%s\", патрэбны пароль."
|
msgstr "Каб злучыцца з \"%s\", патрэбны пароль."
|
||||||
@ -763,7 +767,7 @@ msgstr "Патрэбная ідэнтыфікацыя"
|
|||||||
msgid "Administrator"
|
msgid "Administrator"
|
||||||
msgstr "Адміністратар"
|
msgstr "Адміністратар"
|
||||||
|
|
||||||
#: ../js/ui/polkitAuthenticationAgent.js:174
|
#: ../js/ui/polkitAuthenticationAgent.js:175
|
||||||
msgid "Authenticate"
|
msgid "Authenticate"
|
||||||
msgstr "Ідэнтыфікаваць"
|
msgstr "Ідэнтыфікаваць"
|
||||||
|
|
||||||
@ -771,11 +775,11 @@ msgstr "Ідэнтыфікаваць"
|
|||||||
#. * requested authentication was not gained; this can happen
|
#. * requested authentication was not gained; this can happen
|
||||||
#. * because of an authentication error (like invalid password),
|
#. * because of an authentication error (like invalid password),
|
||||||
#. * for instance.
|
#. * for instance.
|
||||||
#: ../js/ui/polkitAuthenticationAgent.js:262
|
#: ../js/ui/polkitAuthenticationAgent.js:256
|
||||||
msgid "Sorry, that didn't work. Please try again."
|
msgid "Sorry, that didn't work. Please try again."
|
||||||
msgstr "На жаль, ідэнтыфікацыя не адбылася. Паўтарыце спробу."
|
msgstr "На жаль, ідэнтыфікацыя не адбылася. Паўтарыце спробу."
|
||||||
|
|
||||||
#: ../js/ui/polkitAuthenticationAgent.js:274
|
#: ../js/ui/polkitAuthenticationAgent.js:268
|
||||||
msgid "Password:"
|
msgid "Password:"
|
||||||
msgstr "Пароль:"
|
msgstr "Пароль:"
|
||||||
|
|
||||||
@ -784,7 +788,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:709
|
#: ../js/ui/popupMenu.js:727
|
||||||
msgid "toggle-switch-us"
|
msgid "toggle-switch-us"
|
||||||
msgstr "toggle-switch-intl"
|
msgstr "toggle-switch-intl"
|
||||||
|
|
||||||
@ -974,11 +978,11 @@ msgstr "Увядзіце PIN, які паказвае прыстасаванне
|
|||||||
msgid "OK"
|
msgid "OK"
|
||||||
msgstr "Добра"
|
msgstr "Добра"
|
||||||
|
|
||||||
#: ../js/ui/status/keyboard.js:72
|
#: ../js/ui/status/keyboard.js:73
|
||||||
msgid "Show Keyboard Layout"
|
msgid "Show Keyboard Layout"
|
||||||
msgstr "Паказаць раскладку"
|
msgstr "Паказаць раскладку"
|
||||||
|
|
||||||
#: ../js/ui/status/keyboard.js:77
|
#: ../js/ui/status/keyboard.js:78
|
||||||
msgid "Region and Language Settings"
|
msgid "Region and Language Settings"
|
||||||
msgstr "Настройкі мясцовасці і мовы"
|
msgstr "Настройкі мясцовасці і мовы"
|
||||||
|
|
||||||
@ -1023,13 +1027,13 @@ msgstr "недаступна"
|
|||||||
msgid "connection failed"
|
msgid "connection failed"
|
||||||
msgstr "не ўдалося злучыцца"
|
msgstr "не ўдалося злучыцца"
|
||||||
|
|
||||||
#: ../js/ui/status/network.js:575 ../js/ui/status/network.js:1515
|
#: ../js/ui/status/network.js:575 ../js/ui/status/network.js:1523
|
||||||
msgid "More..."
|
msgid "More..."
|
||||||
msgstr "Яшчэ..."
|
msgstr "Яшчэ..."
|
||||||
|
|
||||||
#. 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)
|
||||||
#: ../js/ui/status/network.js:611 ../js/ui/status/network.js:1455
|
#: ../js/ui/status/network.js:611 ../js/ui/status/network.js:1458
|
||||||
msgid "Connected (private)"
|
msgid "Connected (private)"
|
||||||
msgstr "Злучана (прыватна)"
|
msgstr "Злучана (прыватна)"
|
||||||
|
|
||||||
@ -1046,7 +1050,7 @@ msgid "Auto dial-up"
|
|||||||
msgstr "Аўтаматычна: мадэм"
|
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:878 ../js/ui/status/network.js:1467
|
#: ../js/ui/status/network.js:878 ../js/ui/status/network.js:1470
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "Auto %s"
|
msgid "Auto %s"
|
||||||
msgstr "Аўтаматычна: %s"
|
msgstr "Аўтаматычна: %s"
|
||||||
@ -1055,47 +1059,47 @@ msgstr "Аўтаматычна: %s"
|
|||||||
msgid "Auto bluetooth"
|
msgid "Auto bluetooth"
|
||||||
msgstr "Аўтаматычна: Bluetooth"
|
msgstr "Аўтаматычна: Bluetooth"
|
||||||
|
|
||||||
#: ../js/ui/status/network.js:1469
|
#: ../js/ui/status/network.js:1472
|
||||||
msgid "Auto wireless"
|
msgid "Auto wireless"
|
||||||
msgstr "Аўтаматычна: wireless"
|
msgstr "Аўтаматычна: wireless"
|
||||||
|
|
||||||
#: ../js/ui/status/network.js:1558
|
#: ../js/ui/status/network.js:1566
|
||||||
msgid "Enable networking"
|
msgid "Enable networking"
|
||||||
msgstr "Уключыць сеткавыя функцыі"
|
msgstr "Уключыць сеткавыя функцыі"
|
||||||
|
|
||||||
#: ../js/ui/status/network.js:1570
|
#: ../js/ui/status/network.js:1578
|
||||||
msgid "Wired"
|
msgid "Wired"
|
||||||
msgstr "Правадное злучэнне"
|
msgstr "Правадное злучэнне"
|
||||||
|
|
||||||
#: ../js/ui/status/network.js:1581
|
#: ../js/ui/status/network.js:1589
|
||||||
msgid "Wireless"
|
msgid "Wireless"
|
||||||
msgstr "Бесправадное злучэнне"
|
msgstr "Бесправадное злучэнне"
|
||||||
|
|
||||||
#: ../js/ui/status/network.js:1591
|
#: ../js/ui/status/network.js:1599
|
||||||
msgid "Mobile broadband"
|
msgid "Mobile broadband"
|
||||||
msgstr "Мабільны broadband"
|
msgstr "Мабільны broadband"
|
||||||
|
|
||||||
#: ../js/ui/status/network.js:1601
|
#: ../js/ui/status/network.js:1609
|
||||||
msgid "VPN Connections"
|
msgid "VPN Connections"
|
||||||
msgstr "VPN-злучэнні"
|
msgstr "VPN-злучэнні"
|
||||||
|
|
||||||
#: ../js/ui/status/network.js:1612
|
#: ../js/ui/status/network.js:1620
|
||||||
msgid "Network Settings"
|
msgid "Network Settings"
|
||||||
msgstr "Сеткавыя настройкі"
|
msgstr "Сеткавыя настройкі"
|
||||||
|
|
||||||
#: ../js/ui/status/network.js:1749
|
#: ../js/ui/status/network.js:1757
|
||||||
msgid "Connection failed"
|
msgid "Connection failed"
|
||||||
msgstr "Не ўдалося злучыцца"
|
msgstr "Не ўдалося злучыцца"
|
||||||
|
|
||||||
#: ../js/ui/status/network.js:1750
|
#: ../js/ui/status/network.js:1758
|
||||||
msgid "Activation of network connection failed"
|
msgid "Activation of network connection failed"
|
||||||
msgstr "Не ўдалося ўключыць сеткавае злучэнне"
|
msgstr "Не ўдалося ўключыць сеткавае злучэнне"
|
||||||
|
|
||||||
#: ../js/ui/status/network.js:2000
|
#: ../js/ui/status/network.js:2008
|
||||||
msgid "Networking is disabled"
|
msgid "Networking is disabled"
|
||||||
msgstr "Сеткавыя функцыі выключаныя"
|
msgstr "Сеткавыя функцыі выключаныя"
|
||||||
|
|
||||||
#: ../js/ui/status/network.js:2125
|
#: ../js/ui/status/network.js:2133
|
||||||
msgid "Network Manager"
|
msgid "Network Manager"
|
||||||
msgstr "Сеткавы кіраўнік"
|
msgstr "Сеткавы кіраўнік"
|
||||||
|
|
||||||
@ -1447,51 +1451,51 @@ msgstr "Рэдагаваць конт"
|
|||||||
msgid "Unknown reason"
|
msgid "Unknown reason"
|
||||||
msgstr "Невядомая прычына"
|
msgstr "Невядомая прычына"
|
||||||
|
|
||||||
#: ../js/ui/userMenu.js:153
|
#: ../js/ui/userMenu.js:145
|
||||||
msgid "Hidden"
|
msgid "Hidden"
|
||||||
msgstr "Схаваны"
|
msgstr "Схаваны"
|
||||||
|
|
||||||
#: ../js/ui/userMenu.js:159
|
#: ../js/ui/userMenu.js:151
|
||||||
msgid "Idle"
|
msgid "Idle"
|
||||||
msgstr "Бяздзейны"
|
msgstr "Бяздзейны"
|
||||||
|
|
||||||
#: ../js/ui/userMenu.js:162
|
#: ../js/ui/userMenu.js:154
|
||||||
msgid "Unavailable"
|
msgid "Unavailable"
|
||||||
msgstr "Недаступны"
|
msgstr "Недаступны"
|
||||||
|
|
||||||
#: ../js/ui/userMenu.js:523 ../js/ui/userMenu.js:527 ../js/ui/userMenu.js:597
|
#: ../js/ui/userMenu.js:512 ../js/ui/userMenu.js:516 ../js/ui/userMenu.js:586
|
||||||
msgid "Power Off..."
|
msgid "Power Off..."
|
||||||
msgstr "Выключыць камп'ютар..."
|
msgstr "Выключыць камп'ютар..."
|
||||||
|
|
||||||
#: ../js/ui/userMenu.js:559
|
#: ../js/ui/userMenu.js:548
|
||||||
msgid "Notifications"
|
msgid "Notifications"
|
||||||
msgstr "Апавяшчэнні"
|
msgstr "Апавяшчэнні"
|
||||||
|
|
||||||
#: ../js/ui/userMenu.js:567
|
#: ../js/ui/userMenu.js:556
|
||||||
msgid "Online Accounts"
|
msgid "Online Accounts"
|
||||||
msgstr "Сеціўныя конты"
|
msgstr "Сеціўныя конты"
|
||||||
|
|
||||||
#: ../js/ui/userMenu.js:571
|
#: ../js/ui/userMenu.js:560
|
||||||
msgid "System Settings"
|
msgid "System Settings"
|
||||||
msgstr "Сістэмныя настройкі"
|
msgstr "Сістэмныя настройкі"
|
||||||
|
|
||||||
#: ../js/ui/userMenu.js:578
|
#: ../js/ui/userMenu.js:567
|
||||||
msgid "Lock Screen"
|
msgid "Lock Screen"
|
||||||
msgstr "Замкнуць экран"
|
msgstr "Замкнуць экран"
|
||||||
|
|
||||||
#: ../js/ui/userMenu.js:583
|
#: ../js/ui/userMenu.js:572
|
||||||
msgid "Switch User"
|
msgid "Switch User"
|
||||||
msgstr "Перамяніць карыстальніка"
|
msgstr "Перамяніць карыстальніка"
|
||||||
|
|
||||||
#: ../js/ui/userMenu.js:588
|
#: ../js/ui/userMenu.js:577
|
||||||
msgid "Log Out..."
|
msgid "Log Out..."
|
||||||
msgstr "Скончыць сеанс..."
|
msgstr "Скончыць сеанс..."
|
||||||
|
|
||||||
#: ../js/ui/userMenu.js:616
|
#: ../js/ui/userMenu.js:605
|
||||||
msgid "Your chat status will be set to busy"
|
msgid "Your chat status will be set to busy"
|
||||||
msgstr "Вам прызначаны стан занятасці для чату"
|
msgstr "Вам прызначаны стан занятасці для чату"
|
||||||
|
|
||||||
#: ../js/ui/userMenu.js:617
|
#: ../js/ui/userMenu.js:606
|
||||||
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."
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user