Compare commits

..

8 Commits

Author SHA1 Message Date
Giovanni Campagna
6e448a2711 ScreenShield: fix spacing of notifications and sources
Reduce padding around persistent sources, and ensure that spacing
around resident notifications is only applied once.
Also, add some padding to the clock.

https://bugzilla.gnome.org/show_bug.cgi?id=681143
2012-08-06 21:43:54 +02:00
Giovanni Campagna
1d484e2278 ScreenSheild: make notification view scrollable
Place a maximum height on the notification view, and show scrollbars
if the list of persistent sources would overflow.

https://bugzilla.gnome.org/show_bug.cgi?id=681143
2012-08-06 21:43:54 +02:00
Giovanni Campagna
0b7ca098ad ScreenShield: update the displayed title when the source changes
Notifications in the lock screen need to watch signals on source
and react accordingly.

https://bugzilla.gnome.org/show_bug.cgi?id=681143
2012-08-06 21:43:54 +02:00
Jasper St. Pierre
5cb9aa9cf3 messageTray: Hook SourceActor up to source icon changes automatically
Instead of manually tracking source icon changes, or requiring a manual
call to _setSummaryIcon, add a way to emit a signal when we're guaranteed
the icon has been changed, and then the source actor will automatically
update the icon.
_setSummaryIcon is still available for sources such as the notification
daemon, that require special treatment for the summary icon (to be used
with tray icons)

https://bugzilla.gnome.org/show_bug.cgi?id=680426
2012-08-06 21:43:54 +02:00
Giovanni Campagna
0171e561f2 ScreenShield: bump the lock screen slightly when pressing a key
When pressing a key different from escape (one thus that has no
effect), bump the screen up, to indicate that it eats keyboard
input and it must be lifted up.

https://bugzilla.gnome.org/show_bug.cgi?id=681143
2012-08-06 21:43:54 +02:00
Giovanni Campagna
82f7431a28 ScreenShield: handle Escape on the stage, not on the lock screen
This allows to press esc to unlock even if the focus is not on
the lock screen (for example after dismissing the auth failure
notification).

https://bugzilla.gnome.org/show_bug.cgi?id=681143
2012-08-06 21:43:54 +02:00
Giovanni Campagna
29958df7e7 ScreenShield: when explicitly locking, tween the shield from the top
The curtain should appear to be an overlay on top of the system,
and since it is lifted by dragging up, it makes sense to slide it
down on lock.

https://bugzilla.gnome.org/show_bug.cgi?id=681143
2012-08-06 21:43:54 +02:00
Giovanni Campagna
2f990346df ScreenShield: blur and desaturate the screenshield background
The background is the same as the normal desktop, so we blur and
desaturate it to clearly show that it's not the normal system state.

Includes a noticeable slowdown due to GLSL shading and FBO redirection.

https://bugzilla.gnome.org/show_bug.cgi?id=681143
2012-08-06 21:43:54 +02:00
77 changed files with 7031 additions and 6278 deletions

85
NEWS
View File

@@ -1,88 +1,3 @@
3.5.90
======
* Use symbolic icons for workspace switch OSD [Jon; #680738]
* Lock screen improvements:
- Hide user menu and a11y menu in the screen lock [Giovanni; #681143]
- Bump the lock screen slightly when pressing a key [Giovanni; #681143]
- Constrain vertical movement of the screen shield [Giovanni; #681143]
- Return to lock screen on idle [Giovanni; #682041]
- Unlock screen automatically after fast-user switching [Giovanni; #682096]
- Fix "other user" label [Ray; #681750]
* Constrain content of system modals to primary monitor [#681743]
* Respect automatic lock setting on suspend/user-switch [Giovanni; #680231]
* Improve styling of keyring prompt [Jasper; #681821]
* Do not hard-code <super> as overlay-key [Florian; #665547]
* Update style of attached modal dialogs [Florian; #681601]
* a11y: allow navigation on non reactive items [Alejandro; #667439, #667439]
* Implement mode-less overview design [Joost, Florian; #682109]
* Implement message-tray redesign:
- Restyle the message tray [Ana, Allan, Florian; #677213, #682342]
- Move the desktop upwards when showing the tray [Debarshi; #681392]
- Add a close button to notifications [Ana, Jasper; #682253]
- Add a keybinding to toggle the tray [Debarshi; #681392]
- Make the tray keyboard navigable [Debarshi; #681519]
- Add dwelling at the bottom of the screen to open the tray [Owen; #682310]
- Don't time out banners when the user is inactive [Marina, Jasper]
- Misc fixes and cleanups [Jasper, Marina]
* Fix showing "Next Week" on Sundays [Sebastian; #682198]
* Delay restoring IM presence until the network comes up [Florian; #677982]
* Display enterprise login hint [Ray; #681975]
* Ignore unrecognized/irrelevant network devices/connections [Dan; #682364]
* Misc bug fixes and cleanups: [Dan, Florian, Jasper, Jiro, Piotr, Rico;
#643687, #682045, #682189]
Contributors:
Giovanni Campagna, Allan Day, Piotr Drąg, William Jon McCann,
Sebastian Keller, Jiro Matsuzawa, Florian Müllner, Alejandro Piñeiro,
Debarshi Ray, Ana Risteska, Jasper St. Pierre, Ray Strode, Owen Taylor,
Rico Tzschichholz, Joost Verdoorn, Dan Winship, Marina Zhurakhinskaya
Translations:
Nilamdyuti Goswami [as], Daniel Mustieles [es], Yaron Shahrabani [he],
Chao-Hsiung Liao [zh_HK, zh_TW], Tobias Endrigkeit [de], A S Alam [pa],
Sandeep Sheshrao Shedmake [mr], Fran Diéguez [gl],
Мирослав Николић [sr, sr@latin]
3.5.5
=====
* Update style to match mockups [Allan]
- improve calendar layout and legibility
- update notifications and menus
- use a common style for entries
- update scrollbars to match GTK+
- improve clock/unlock button in lock screen
- update polkit dialogs [Jasper]
* Fix login dialog growing when selecting different users [Florian; #675076]
* Implement screen lock in the shell [Giovanni]
- restructure login code to be shared with session unlock [#619955]
- add initial screen shield / unlock dialog implementation [#619955]
- implement (optional) notification list on lock shield [#619955]
- update login dialog style to match lock screen [#619955]
- filter notifications to only show new ones on the screen lock [#681143]
- make notifications scrollable if necessary [#681143]
- use correct application names in notifications [#681143]
- allow to return to the shield by pressing Escape [#681143]
* Minor login dialog improvements [Florian]
- update style to match the overall visuals [#660913]
- indicate whether users are logged in [#658185]
* Add support for background-repeat CSS property [Jasper; #680801]
* Add :active pseudo class on scroll handles [Florian]
* Remove markup from translated strings [Matthias; #681270]
* Misc bug fixes and cleanups: [Alban, Florian, Giovanni, Jasper, Jeremy,
Matthias, Piotr; #677893, #679944, #680064, #680170, #680216, #680426,
#681101, #681382]
Contributors:
Jeremy Bicha, Alban Browaeys, Giovanni Campagna, Matthias Clasen, Allan Day,
Piotr Drąg , Florian Müllner, Jasper St. Pierre
Translations:
Matej Urbančič [sl], Tom Tryfonidis [el], Yaron Shahrabani [he],
Kjartan Maraas [nb], Baurzhan Muftakhidinov [kk], Praveen Illa [te],
Khaled Hosny [ar], Daniel Mustieles [es], Gabor Kelemen [hu],
Fran Diéguez [gl], Sweta Kothari [gu], Aleksej Kabanov [ru],
Nilamdyuti Goswami [as], Arash Mousavi [fa], Мирослав Николић [sr, sr@latin]
3.5.4
=====
* Fix wrong result handling of remote calls [Florian; #678852]

View File

@@ -1,5 +1,5 @@
AC_PREREQ(2.63)
AC_INIT([gnome-shell],[3.5.90],[https://bugzilla.gnome.org/enter_bug.cgi?product=gnome-shell],[gnome-shell])
AC_INIT([gnome-shell],[3.5.4],[https://bugzilla.gnome.org/enter_bug.cgi?product=gnome-shell],[gnome-shell])
AC_CONFIG_HEADERS([config.h])
AC_CONFIG_SRCDIR([src/shell-global.c])
@@ -60,10 +60,10 @@ fi
AM_CONDITIONAL(BUILD_RECORDER, $build_recorder)
CLUTTER_MIN_VERSION=1.11.11
CLUTTER_MIN_VERSION=1.9.16
GOBJECT_INTROSPECTION_MIN_VERSION=0.10.1
GJS_MIN_VERSION=1.33.2
MUTTER_MIN_VERSION=3.5.90
MUTTER_MIN_VERSION=3.5.4
GTK_MIN_VERSION=3.3.9
GIO_MIN_VERSION=2.31.6
LIBECAL_MIN_VERSION=3.5.3

View File

@@ -10,6 +10,11 @@ desktop_DATA = gnome-shell.desktop gnome-shell-extension-prefs.desktop
@INTLTOOL_DESKTOP_RULE@
searchprovidersdir = $(pkgdatadir)/open-search-providers
dist_searchproviders_DATA = \
open-search-providers/google.xml \
open-search-providers/wikipedia.xml
introspectiondir = $(datadir)/dbus-1/interfaces
introspection_DATA = org.gnome.ShellSearchProvider.xml
@@ -31,7 +36,6 @@ dist_theme_DATA = \
theme/filter-selected-rtl.svg \
theme/gnome-shell.css \
theme/logged-in-indicator.svg \
theme/message-tray-background.png \
theme/noise-texture.png \
theme/panel-button-border.svg \
theme/panel-button-highlight-narrow.svg \
@@ -43,8 +47,8 @@ dist_theme_DATA = \
theme/toggle-off-intl.svg \
theme/toggle-on-us.svg \
theme/toggle-on-intl.svg \
theme/ws-switch-arrow-up.png \
theme/ws-switch-arrow-down.png
theme/ws-switch-arrow-up.svg \
theme/ws-switch-arrow-down.svg
gsettings_SCHEMAS = org.gnome.shell.gschema.xml

View File

@@ -0,0 +1,7 @@
<OpenSearchDescription xmlns="http://a9.com/-/spec/opensearch/1.1/">
<ShortName>Google</ShortName>
<Description>Google Search</Description>
<InputEncoding>UTF-8</InputEncoding>
<Image width="16" height="16">data:image/x-icon;base64,AAABAAEAEBAAAAEAGABoAwAAFgAAACgAAAAQAAAAIAAAAAEAGAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADs9Pt8xetPtu9FsfFNtu%2BTzvb2%2B%2Fne4dFJeBw0egA%2FfAJAfAA8ewBBegAAAAD%2B%2FPtft98Mp%2BwWsfAVsvEbs%2FQeqvF8xO7%2F%2F%2F63yqkxdgM7gwE%2FggM%2BfQA%2BegBDeQDe7PIbotgQufcMufEPtfIPsvAbs%2FQvq%2Bfz%2Bf%2F%2B%2B%2FZKhR05hgBBhQI8hgBAgAI9ewD0%2B%2Fg3pswAtO8Cxf4Kw%2FsJvvYAqupKsNv%2B%2Fv7%2F%2FP5VkSU0iQA7jQA9hgBDgQU%2BfQH%2F%2Ff%2FQ6fM4sM4KsN8AteMCruIqqdbZ7PH8%2Fv%2Fg6Nc%2Fhg05kAA8jAM9iQI%2BhQA%2BgQDQu6b97uv%2F%2F%2F7V8Pqw3eiWz97q8%2Ff%2F%2F%2F%2F7%2FPptpkkqjQE4kwA7kAA5iwI8iAA8hQCOSSKdXjiyflbAkG7u2s%2F%2B%2F%2F39%2F%2F7r8utrqEYtjQE8lgA7kwA7kwA9jwA9igA9hACiWSekVRyeSgiYSBHx6N%2F%2B%2Fv7k7OFRmiYtlAA5lwI7lwI4lAA7kgI9jwE9iwI4iQCoVhWcTxCmb0K%2BooT8%2Fv%2F7%2F%2F%2FJ2r8fdwI1mwA3mQA3mgA8lAE8lAE4jwA9iwE%2BhwGfXifWvqz%2B%2Ff%2F58u%2Fev6Dt4tr%2B%2F%2F2ZuIUsggA7mgM6mAM3lgA5lgA6kQE%2FkwBChwHt4dv%2F%2F%2F728ei1bCi7VAC5XQ7kz7n%2F%2F%2F6bsZkgcB03lQA9lgM7kwA2iQktZToPK4r9%2F%2F%2F9%2F%2F%2FSqYK5UwDKZAS9WALIkFn%2B%2F%2F3%2F%2BP8oKccGGcIRJrERILYFEMwAAuEAAdX%2F%2Ff7%2F%2FP%2B%2BfDvGXQLIZgLEWgLOjlf7%2F%2F%2F%2F%2F%2F9QU90EAPQAAf8DAP0AAfMAAOUDAtr%2F%2F%2F%2F7%2B%2Fu2bCTIYwDPZgDBWQDSr4P%2F%2Fv%2F%2F%2FP5GRuABAPkAA%2FwBAfkDAPAAAesAAN%2F%2F%2B%2Fz%2F%2F%2F64g1C5VwDMYwK8Yg7y5tz8%2Fv%2FV1PYKDOcAAP0DAf4AAf0AAfYEAOwAAuAAAAD%2F%2FPvi28ymXyChTATRrIb8%2F%2F3v8fk6P8MAAdUCAvoAAP0CAP0AAfYAAO4AAACAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAAQAA</Image>
<Url type="text/html" method="GET" template="http://www.google.com/search?q={searchTerms}"/>
</OpenSearchDescription>

View File

@@ -0,0 +1,44 @@
<OpenSearchDescription xmlns="http://a9.com/-/spec/opensearch/1.1/">
<ShortName>Wikipedia</ShortName>
<Description>Wikipedia, the free encyclopedia</Description>
<InputEncoding>UTF-8</InputEncoding>
<Image width="16" height="16">data:image/x-icon;base64,AAABAAEAEBAQAAEABAAoAQAAFgAAACgAAAAQAAAAIAAAAAEABAAAAAAAAAAAAAAAAAAAAAAAEAAAAAAAAAAEAgQAhIOEAMjHyABIR0gA6ejpAGlqaQCpqKkAKCgoAPz9%2FAAZGBkAmJiYANjZ2ABXWFcAent6ALm6uQA8OjwAiIiIiIiIiIiIiI4oiL6IiIiIgzuIV4iIiIhndo53KIiIiB%2FWvXoYiIiIfEZfWBSIiIEGi%2FfoqoiIgzuL84i9iIjpGIoMiEHoiMkos3FojmiLlUipYliEWIF%2BiDe0GoRa7D6GPbjcu1yIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA</Image>
<Url type="text/html" method="GET" template="http://{language}.wikipedia.org/wiki/Special:Search?search={searchTerms}"/>
<!-- The criterion for being below is being listed with more than 100,000
articles on http://meta.wikimedia.org/wiki/List_of_Wikipedias -->
<Language>ar</Language>
<Language>bg</Language>
<Language>ca</Language>
<Language>cs</Language>
<Language>da</Language>
<Language>de</Language>
<Language>en</Language>
<Language>eo</Language>
<Language>es</Language>
<Language>fa</Language>
<Language>fi</Language>
<Language>fr</Language>
<Language>he</Language>
<Language>hu</Language>
<Language>id</Language>
<Language>it</Language>
<Language>ja</Language>
<Language>ko</Language>
<Language>lt</Language>
<Language>nl</Language>
<Language>no</Language>
<Language>pl</Language>
<Language>pt</Language>
<Language>ro</Language>
<Language>ru</Language>
<Language>sk</Language>
<Language>sl</Language>
<Language>sr</Language>
<Language>sv</Language>
<Language>tr</Language>
<Language>uk</Language>
<Language>vi</Language>
<Language>vo</Language>
<Language>war</Language>
<Language>zh</Language>
</OpenSearchDescription>

View File

@@ -87,13 +87,6 @@ value here is from the GsmPresenceStatus enumeration.</_summary>
Keybinding to open the application menu.
</_description>
</key>
<key name="toggle-message-tray" type="as">
<default>["&lt;Super&gt;m"]</default>
<_summary>Keybinding to toggle the visibility of the message tray</_summary>
<_description>
Keybinding to toggle the visibility of the message tray.
</_description>
</key>
<key name="toggle-recording" type="as">
<default><![CDATA[['<Control><Shift><Alt>r']]]></default>
<_summary>Keybinding to toggle the screen recorder</_summary>

View File

@@ -48,8 +48,9 @@ stage {
.dash-label,
.window-caption,
.switcher-list,
.source-title,
.app-well-app > .overview-icon,
.show-apps > .overview-icon,
.remove-favorite > .overview-icon,
.search-result-content > .overview-icon {
font-size: 9pt;
font-weight: bold;
@@ -603,30 +604,14 @@ StButton.popup-menu-item:insensitive {
-shell-caption-spacing: 12px;
}
.window-close, .notification-close {
.window-close {
background-image: url("close-window.svg");
background-size: 34px;
height: 34px;
width: 34px;
}
.window-close {
-shell-close-overlap: 20px;
}
.notification-close {
/* we start out in the top right of the
* notification, inset.
*
* center is 32px/2 = 17px
*
* adjust left 2px
* adjust down 8px */
-shell-close-overlap-x: 15px;
-shell-close-overlap-y: 12px;
}
.window-close:rtl {
-st-background-image-shadow: 2px 2px 6px rgba(0,0,0,0.5);
}
@@ -664,11 +649,19 @@ StButton.popup-menu-item:insensitive {
spacing: 1em;
}
#viewSelectorTabBar {
padding: 1em;
}
/* Search Box */
#searchArea {
padding: 0px 24px;
}
#searchEntry {
border-radius: 17px;
width: 320px;
width: 250px;
}
.search-entry-icon {
@@ -676,6 +669,26 @@ StButton.popup-menu-item:insensitive {
color: #8d8f8a;
}
/* View Tabs */
.view-tab-title {
color: #888a85;
font-size: 12pt;
font-weight: bold;
padding: 0px 0.75em;
height: 1.5em;
}
.view-tab-title:hover {
color: #bbb;
}
.view-tab-title:selected {
color: #000000;
background-color: #c2c7cd;
border-radius: 0.25em;
}
/* Search Results */
#searchResults {
@@ -791,12 +804,21 @@ StButton.popup-menu-item:insensitive {
outline: 1px solid #aaa;
}
.dash-item-container > StButton {
.dash-item-container > .app-well-app {
padding: 4px 8px;
}
.remove-favorite-icon {
color: #a0a0a0;
}
.remove-favorite-icon:hover {
color: white;
icon-shadow: black 0px 2px 2px;
}
.app-well-app > .overview-icon,
.show-apps > .overview-icon,
.remove-favorite > .overview-icon,
.search-result-content > .overview-icon {
border-radius: 4px;
padding: 3px;
@@ -812,44 +834,15 @@ StButton.popup-menu-item:insensitive {
}
.app-well-app:hover > .overview-icon,
.show-apps:hover > .overview-icon,
.remove-favorite:hover > .overview-icon,
.search-result-content:hover > .overview-icon {
background-color: rgba(255,255,255,0.1);
text-shadow: black 0px 2px 2px;
transition-duration: 100;
color:white;
}
.show-apps {
padding: 4px 0;
}
.show-apps-icon {
color: #a0a0a0;
}
.show-apps:hover .show-apps-icon {
color: white;
}
.show-apps:checked > .overview-icon {
background-gradient-start: rgba(255, 255, 255, .05);
background-gradient-end: rgba(255, 255, 255, .15);
background-gradient-direction: vertical;
border-radius: 4px;
box-shadow: inset 0px 1px 2px 0px rgba(0, 0, 0, 1);
transition-duration: 100;
}
.show-apps:checked .show-apps-icon,
.show-apps:focus .show-apps-icon {
color: white;
transition-duration: 100;
}
.app-well-app:focus > .overview-icon,
.search-result-content:focus > .overview-icon,
.show-apps:focus > .overview-icon,
.app-well-app:selected > .overview-icon,
.search-result-content:selected > .overview-icon {
background-color: rgba(255,255,255,0.33);
@@ -1180,27 +1173,19 @@ StButton.popup-menu-item:insensitive {
/* Message Tray */
#message-tray {
background: #2e3436 url(message-tray-background.png);
background-repeat: repeat;
transition-duration: 250;
height: 72px;
}
#message-tray:overview {
background: rgba(0, 0, 0, 0.1);
border-top: 1px solid rgba(128, 128, 128, 0.3);
background-gradient-direction: vertical;
background-gradient-start: rgba(0,0,0,0.01);
background-gradient-end: rgba(0,0,0,0.82);
height: 36px;
}
.notification {
font-size: 11pt;
border-radius: 10px 10px 0px 0px;
background: rgba(0,0,0,0.8);
padding: 8px 8px 4px 8px;
spacing-rows: 10px;
spacing-columns: 10px;
}
.notification, #notification-container {
font-size: 11pt;
width: 34em;
}
@@ -1222,7 +1207,6 @@ StButton.popup-menu-item:insensitive {
-arrow-base: 36px;
-arrow-rise: 18px;
color: white;
-boxpointer-gap: 4px;
}
.summary-boxpointer .notification {
@@ -1402,9 +1386,22 @@ StButton.popup-menu-item:insensitive {
border-radius: 4px;
}
/* The spacing and padding on the summary is tricky; we want to keep
* the icons from touching each other or the edges of the screen, but
* we also want them to be "Fitts"-y with respect to the edges, so the
* summary area's bottom and right padding must actually be part of
* the icons. However, we can't put *all* of the padding into the
* icons, because then the summary would be 0x0 when there were no
* icons in it, and so you wouldn't be able to hover over it to
* activate it.
*
* Also, the spacing between a summary-source's icon and title is
* actually specified as padding-left in source-title, because we
* want the spacing to collapse along with the title.
*/
#summary-mode {
padding: 2px 0px 0px 4px;
height: 72px;
height: 36px;
}
#summary-mode:rtl {
@@ -1412,22 +1409,45 @@ StButton.popup-menu-item:insensitive {
}
.summary-source-button {
border-radius: 4px;
transition-duration: 100;
text-shadow: black 0px 2px 2px;
}
.summary-source-button:hover {
background-color: rgba(255,255,255,0.1);
.summary-source-button:ltr {
padding-right: 12px;
}
.summary-source-button:focus,
.summary-source-button:selected {
background-color: rgba(255,255,255,0.33);
.summary-source-button:selected .summary-source {
background-image: url("panel-button-highlight-narrow.svg");
background-size: contain;
border-image: url("source-button-border.svg") 10 10 0 1;
}
.summary-source-button:expanded:selected .summary-source {
background-image: none;
border-image: none;
}
.summary-source-button:expanded:selected {
background-image: url("panel-button-highlight-wide.svg");
background-size: contain;
border-image: url("source-button-border.svg") 10 10 0 1;
}
.summary-source-button:rtl {
padding-left: 12px;
}
.summary-source-button:last-child:ltr {
padding-right: 12px;
}
.summary-source-button:last-child:rtl {
padding-left: 12px;
}
.summary-source {
padding-right: 6px;
padding-left: 6px;
padding-right: 4px;
padding-left: 4px;
}
.summary-source-counter {
@@ -1440,6 +1460,15 @@ StButton.popup-menu-item:insensitive {
min-width: 1em;
}
.source-title {
padding-left: 4px;
}
.source-title:rtl {
padding-left: 0px;
padding-right: 4px;
}
/* App Switcher */
#altTabPopup {
padding: 8px;
@@ -1550,7 +1579,7 @@ StButton.popup-menu-item:insensitive {
height: 100px;
border: 0px;
background: rgba(255,255,255,0.5);
background-image: url("ws-switch-arrow-up.png");
background-image: url("ws-switch-arrow-up.svg");
border-radius: 8px;
}
@@ -1558,7 +1587,7 @@ StButton.popup-menu-item:insensitive {
height: 100px;
border: 0px;
background: rgba(255,255,255,0.5);
background-image: url("ws-switch-arrow-down.png");
background-image: url("ws-switch-arrow-down.svg");
border-radius: 8px;
}
@@ -1878,7 +1907,6 @@ StButton.popup-menu-item:insensitive {
.keyring-dialog-control-table {
spacing-rows: 15px;
spacing-columns: 1em;
}
/* Magnifier */
@@ -1988,7 +2016,7 @@ StButton.popup-menu-item:insensitive {
min-width: 350px;
}
.login-dialog-prompt-login-hint-message {
.login-dialog-prompt-fingerprint-message {
font-size: 10.5pt;
}
@@ -2064,7 +2092,6 @@ StButton.popup-menu-item:insensitive {
font-size: 10.5pt;
font-weight: bold;
color: #666666;
padding-top: 1em;
}
.login-dialog-not-listed-button:hover .login-dialog-not-listed-label {
@@ -2144,7 +2171,7 @@ StButton.popup-menu-item:insensitive {
.login-dialog .modal-dialog-button {
border: 1px solid #666666;
border: 1px solid white;
border-radius: 5px;
padding: 3px 18px;
}
@@ -2156,13 +2183,13 @@ StButton.popup-menu-item:insensitive {
border: 2px solid #16335d;
}
.login-dialog .modal-dialog-button:default:hover {
.login-dialog .modal-dialog-button:hover {
background-gradient-start: #74a0d0;
background-gradient-end: #436d9f;
}
.login-dialog .modal-dialog-button:default:active,
.login-dialog .modal-dialog-button:default:pressed {
.login-dialog .modal-dialog-button:active,
.login-dialog .modal-dialog-button:pressed {
background-gradient-start: #436d9f;
background-gradient-end: #74a0d0;
}
@@ -2173,12 +2200,12 @@ StButton.popup-menu-item:insensitive {
/* Screen shield */
#lockDialogGroup {
#screenShieldGroup {
background: #2e3436 url(noise-texture.png);
background-repeat: repeat;
}
#lockScreenGroup .arrow {
#screenShieldGroup .arrow {
color: #333333;
width: 100px;
height: 50px;

Binary file not shown.

Before

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 850 B

View File

@@ -0,0 +1,376 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
version="1.1"
width="96"
height="96"
id="svg25070"
inkscape:version="0.48.0 r9654"
sodipodi:docname="ws-switch-arrow-down.svg">
<metadata
id="metadata3353">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
</cc:Work>
</rdf:RDF>
</metadata>
<sodipodi:namedview
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1"
objecttolerance="10"
gridtolerance="10"
guidetolerance="10"
inkscape:pageopacity="0"
inkscape:pageshadow="2"
inkscape:window-width="718"
inkscape:window-height="480"
id="namedview3351"
showgrid="false"
inkscape:zoom="2.6979167"
inkscape:cx="48"
inkscape:cy="48"
inkscape:window-x="0"
inkscape:window-y="26"
inkscape:window-maximized="0"
inkscape:current-layer="svg25070" />
<defs
id="defs25072">
<linearGradient
x1="-86.552246"
y1="185.439"
x2="-83.37072"
y2="197.31261"
id="linearGradient24957"
xlink:href="#linearGradient4034-0-4"
gradientUnits="userSpaceOnUse"
gradientTransform="translate(6,0)" />
<linearGradient
id="linearGradient4034-0-4">
<stop
id="stop4036-5-7"
style="stop-color:#eeeeec;stop-opacity:1"
offset="0" />
<stop
id="stop4038-9-6"
style="stop-color:#babdb6;stop-opacity:1"
offset="1" />
</linearGradient>
<filter
x="0"
y="0"
width="1"
height="1"
color-interpolation-filters="sRGB"
id="filter24765">
<feColorMatrix
result="fbSourceGraphic"
values="1"
type="saturate"
id="feColorMatrix24767" />
<feColorMatrix
values="-1 0 0 0 1 0 -1 0 0 1 0 0 -1 0 1 0 0 0 1 0"
in="fbSourceGraphic"
id="feColorMatrix24769" />
</filter>
<linearGradient
x1="-74.520325"
y1="169.06032"
x2="-74.520325"
y2="205.94189"
id="linearGradient24955"
xlink:href="#linearGradient4632-1-3-9-3-2"
gradientUnits="userSpaceOnUse"
gradientTransform="translate(-5,0)" />
<linearGradient
id="linearGradient4632-1-3-9-3-2">
<stop
id="stop4634-1-8-3-9-0"
style="stop-color:#eeeeec;stop-opacity:1"
offset="0" />
<stop
id="stop4636-1-9-9-8-8"
style="stop-color:#ffffff;stop-opacity:1"
offset="0.0274937" />
<stop
id="stop4638-8-3-9-6-6"
style="stop-color:#f2f2f2;stop-opacity:1"
offset="0.274937" />
<stop
id="stop4640-8-5-7-8-9"
style="stop-color:#eeeeec;stop-opacity:1"
offset="0.38707438" />
<stop
id="stop4642-5-41-9-6-9"
style="stop-color:#d9dad8;stop-opacity:1"
offset="0.66528589" />
<stop
id="stop4644-5-2-7-9-2"
style="stop-color:#dfe0dd;stop-opacity:1"
offset="0.76745707" />
<stop
id="stop4646-3-2-3-7-3"
style="stop-color:#f0f0f0;stop-opacity:1"
offset="1" />
</linearGradient>
<radialGradient
cx="-33.412369"
cy="185.74171"
r="2.3554697"
fx="-33.412369"
fy="185.74171"
id="radialGradient24959"
xlink:href="#linearGradient4869-4-1"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1.0075,0,0,1.0075,-5.4544,-1.25141)" />
<linearGradient
id="linearGradient4869-4-1">
<stop
id="stop4871-6-2"
style="stop-color:#ffffff;stop-opacity:1"
offset="0" />
<stop
id="stop4879-7-4"
style="stop-color:#eeeeec;stop-opacity:1"
offset="0.31807542" />
<stop
id="stop4877-6-1"
style="stop-color:#c8c9c6;stop-opacity:1"
offset="0.74691135" />
<stop
id="stop4873-1-0"
style="stop-color:#d3d7cf;stop-opacity:1"
offset="1" />
</linearGradient>
<filter
x="0"
y="0"
width="1"
height="1"
color-interpolation-filters="sRGB"
id="filter25011">
<feColorMatrix
result="fbSourceGraphic"
values="1"
type="saturate"
id="feColorMatrix25013" />
<feColorMatrix
values="-1 0 0 0 1 0 -1 0 0 1 0 0 -1 0 1 0 0 0 1 0"
in="fbSourceGraphic"
id="feColorMatrix25015" />
</filter>
<radialGradient
cx="-33.412369"
cy="185.74171"
r="2.3554697"
fx="-33.412369"
fy="185.74171"
id="radialGradient24961"
xlink:href="#linearGradient4869-4-0"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1.0075,0,0,1.0075,-5.4544,-1.25141)" />
<linearGradient
id="linearGradient4869-4-0">
<stop
id="stop4871-6-8"
style="stop-color:#ffffff;stop-opacity:1"
offset="0" />
<stop
id="stop4879-7-5"
style="stop-color:#eeeeec;stop-opacity:1"
offset="0.31807542" />
<stop
id="stop4877-6-5"
style="stop-color:#c8c9c6;stop-opacity:1"
offset="0.74691135" />
<stop
id="stop4873-1-4"
style="stop-color:#d3d7cf;stop-opacity:1"
offset="1" />
</linearGradient>
<filter
x="0"
y="0"
width="1"
height="1"
color-interpolation-filters="sRGB"
id="filter25023">
<feColorMatrix
result="fbSourceGraphic"
values="1"
type="saturate"
id="feColorMatrix25025" />
<feColorMatrix
values="-1 0 0 0 1 0 -1 0 0 1 0 0 -1 0 1 0 0 0 1 0"
in="fbSourceGraphic"
id="feColorMatrix25027" />
</filter>
<linearGradient
x1="-39.858727"
y1="184.61784"
x2="-38.244785"
y2="188.84898"
id="linearGradient24963"
xlink:href="#linearGradient4941"
gradientUnits="userSpaceOnUse" />
<linearGradient
id="linearGradient4941">
<stop
id="stop4943"
style="stop-color:#ffffff;stop-opacity:1"
offset="0" />
<stop
id="stop4945"
style="stop-color:#ffffff;stop-opacity:0"
offset="1" />
</linearGradient>
<filter
x="0"
y="0"
width="1"
height="1"
color-interpolation-filters="sRGB"
id="filter25033">
<feColorMatrix
result="fbSourceGraphic"
values="1"
type="saturate"
id="feColorMatrix25035" />
<feColorMatrix
values="-1 0 0 0 1 0 -1 0 0 1 0 0 -1 0 1 0 0 0 1 0"
in="fbSourceGraphic"
id="feColorMatrix25037" />
</filter>
<linearGradient
x1="-39.858727"
y1="184.61784"
x2="-38.244785"
y2="188.84898"
id="linearGradient24965"
xlink:href="#linearGradient4941-7"
gradientUnits="userSpaceOnUse" />
<linearGradient
id="linearGradient4941-7">
<stop
id="stop4943-2"
style="stop-color:#ffffff;stop-opacity:1"
offset="0" />
<stop
id="stop4945-5"
style="stop-color:#ffffff;stop-opacity:0"
offset="1" />
</linearGradient>
<filter
x="0"
y="0"
width="1"
height="1"
color-interpolation-filters="sRGB"
id="filter25043">
<feColorMatrix
result="fbSourceGraphic"
values="1"
type="saturate"
id="feColorMatrix25045" />
<feColorMatrix
values="-1 0 0 0 1 0 -1 0 0 1 0 0 -1 0 1 0 0 0 1 0"
in="fbSourceGraphic"
id="feColorMatrix25047" />
</filter>
<filter
x="0"
y="0"
width="1"
height="1"
color-interpolation-filters="sRGB"
id="filter25049">
<feColorMatrix
result="fbSourceGraphic"
values="1"
type="saturate"
id="feColorMatrix25051" />
<feColorMatrix
values="-1 0 0 0 1 0 -1 0 0 1 0 0 -1 0 1 0 0 0 1 0"
in="fbSourceGraphic"
id="feColorMatrix25053" />
</filter>
<filter
x="0"
y="0"
width="1"
height="1"
color-interpolation-filters="sRGB"
id="filter25055">
<feColorMatrix
result="fbSourceGraphic"
values="1"
type="saturate"
id="feColorMatrix25057" />
<feColorMatrix
values="-1 0 0 0 1 0 -1 0 0 1 0 0 -1 0 1 0 0 0 1 0"
in="fbSourceGraphic"
id="feColorMatrix25059" />
</filter>
</defs>
<g
transform="matrix(0,1,-1,0,48.0003,4.1307112e-7)"
id="layer1">
<g
transform="matrix(-2,0,0,2,-97.2497,-374.967)"
id="g4030-1-8"
style="stroke:#000000;stroke-opacity:1;display:inline">
<path
d="m -72.5,173.5 -14,14 14,14"
id="path3165-7-3"
style="color:#000000;fill:none;stroke:#000000;stroke-width:7;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible"
inkscape:connector-curvature="0" />
</g>
<path
d="m -36.5,186.40625 a 2.09375,2.09375 0 1 1 -4.1875,0 2.09375,2.09375 0 1 1 4.1875,0 z"
transform="matrix(-3.34328,0,0,3.34328,-89.2797,-623.176)"
id="path4050-2-7-9-4"
style="color:#000000;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.52343899;marker:none;visibility:visible;display:inline;overflow:visible"
inkscape:connector-curvature="0" />
<path
d="m -36.5,186.40625 a 2.09375,2.09375 0 1 1 -4.1875,0 2.09375,2.09375 0 1 1 4.1875,0 z"
transform="matrix(-3.34328,0,0,3.34328,-111.2797,-623.176)"
id="path4050-2-7-9-4-8"
style="color:#000000;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.52343899;marker:none;visibility:visible;display:inline;overflow:visible"
inkscape:connector-curvature="0" />
<path
d="m -36.5,186.40625 a 2.09375,2.09375 0 1 1 -4.1875,0 2.09375,2.09375 0 1 1 4.1875,0 z"
transform="matrix(-2.86565,0,0,2.86565,-70.8457,-534.143)"
id="path4050-2-7-9-4-0"
style="color:#000000;fill:none;stroke:#000000;stroke-width:0.69792098;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible"
inkscape:connector-curvature="0" />
<path
d="m -36.5,186.40625 a 2.09375,2.09375 0 1 1 -4.1875,0 2.09375,2.09375 0 1 1 4.1875,0 z"
transform="matrix(-2.86565,0,0,2.86565,-92.8457,-534.143)"
id="path4050-2-7-9-4-0-9"
style="color:#000000;fill:none;stroke:#000000;stroke-width:0.69792098;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible"
inkscape:connector-curvature="0" />
<path
d="m 47.87528,-34.0295 c 1.53896,0.0448 3.0511,0.70928 4.125,1.8125 l 32.25,32.25 -32.25,32.25 c -2.2253,2.2253 -6.2747,2.2253 -8.5,0 -2.2253,-2.22528 -2.2253,-6.2747 0,-8.5 l 23.75,-23.75 -23.75,-23.75 c -1.73168,-1.6731 -2.295,-4.44228 -1.3546,-6.65894 0.94042,-2.21668 3.32312,-3.73604 5.7296,-3.65356 z"
id="path3165-7-3-1"
style="font-size:medium;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0pt;text-align:start;text-decoration:none;line-height:normal;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;text-anchor:start;opacity:0.35;color:#000000;fill:none;stroke:#000000;stroke-width:2;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;marker:none;visibility:visible;display:inline;overflow:visible;font-family:Bitstream Vera Sans"
inkscape:connector-curvature="0" />
<path
d="m 41.8316,28.09418 c -0.014,-1.58898 0.54158,-3.18406 1.66868,-4.31118 l 23.75,-23.75 m -25.1046,-30.40894 c 0.94042,-2.21668 3.32312,-3.73604 5.7296,-3.65356 1.53896,0.0448 3.0511,0.70928 4.125,1.8125 l 32.25,32.25"
id="path3165-7-3-1-9"
style="font-size:medium;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0pt;text-align:start;text-decoration:none;line-height:normal;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;text-anchor:start;color:#000000;fill:none;stroke:#000000;stroke-width:2;stroke-linecap:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;marker:none;visibility:visible;display:inline;overflow:visible;font-family:Bitstream Vera Sans"
inkscape:connector-curvature="0" />
</g>
</svg>

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 841 B

View File

@@ -0,0 +1,447 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="96"
height="96"
id="svg25070"
version="1.1"
inkscape:version="0.48.0 r9654"
sodipodi:docname="ws-switch-arrow-up.svg">
<defs
id="defs25072">
<inkscape:perspective
sodipodi:type="inkscape:persp3d"
inkscape:vp_x="0 : 24 : 1"
inkscape:vp_y="0 : 1000 : 0"
inkscape:vp_z="48 : 24 : 1"
inkscape:persp3d-origin="24 : 16 : 1"
id="perspective25078" />
<inkscape:perspective
id="perspective24985"
inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
inkscape:vp_z="1 : 0.5 : 1"
inkscape:vp_y="0 : 1000 : 0"
inkscape:vp_x="0 : 0.5 : 1"
sodipodi:type="inkscape:persp3d" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4034-0-4"
id="linearGradient24957"
gradientUnits="userSpaceOnUse"
gradientTransform="translate(6)"
x1="-86.552246"
y1="185.439"
x2="-83.37072"
y2="197.31261" />
<linearGradient
inkscape:collect="always"
id="linearGradient4034-0-4">
<stop
style="stop-color: rgb(238, 238, 236); stop-opacity: 1;"
offset="0"
id="stop4036-5-7" />
<stop
style="stop-color: rgb(186, 189, 182); stop-opacity: 1;"
offset="1"
id="stop4038-9-6" />
</linearGradient>
<filter
id="filter24765"
inkscape:label="Invert"
x="0"
y="0"
width="1"
height="1"
inkscape:menu="Color"
inkscape:menu-tooltip="Invert colors"
color-interpolation-filters="sRGB">
<feColorMatrix
id="feColorMatrix24767"
type="saturate"
values="1"
result="fbSourceGraphic" />
<feColorMatrix
id="feColorMatrix24769"
in="fbSourceGraphic"
values="-1 0 0 0 1 0 -1 0 0 1 0 0 -1 0 1 0 0 0 1 0" />
</filter>
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4632-1-3-9-3-2"
id="linearGradient24955"
gradientUnits="userSpaceOnUse"
gradientTransform="translate(-5)"
x1="-74.520325"
y1="169.06032"
x2="-74.520325"
y2="205.94189" />
<linearGradient
id="linearGradient4632-1-3-9-3-2">
<stop
style="stop-color: rgb(238, 238, 236); stop-opacity: 1;"
offset="0"
id="stop4634-1-8-3-9-0" />
<stop
id="stop4636-1-9-9-8-8"
offset="0.0274937"
style="stop-color: rgb(255, 255, 255); stop-opacity: 1;" />
<stop
id="stop4638-8-3-9-6-6"
offset="0.274937"
style="stop-color: rgb(242, 242, 242); stop-opacity: 1;" />
<stop
id="stop4640-8-5-7-8-9"
offset="0.38707438"
style="stop-color: rgb(238, 238, 236); stop-opacity: 1;" />
<stop
id="stop4642-5-41-9-6-9"
offset="0.66528589"
style="stop-color: rgb(217, 218, 216); stop-opacity: 1;" />
<stop
id="stop4644-5-2-7-9-2"
offset="0.76745707"
style="stop-color: rgb(223, 224, 221); stop-opacity: 1;" />
<stop
style="stop-color: rgb(240, 240, 240); stop-opacity: 1;"
offset="1"
id="stop4646-3-2-3-7-3" />
</linearGradient>
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient4869-4-1"
id="radialGradient24959"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1.0075, 0, 0, 1.0075, -5.4544, -1.25141)"
cx="-33.412369"
cy="185.74171"
fx="-33.412369"
fy="185.74171"
r="2.3554697" />
<linearGradient
id="linearGradient4869-4-1">
<stop
style="stop-color: rgb(255, 255, 255); stop-opacity: 1;"
offset="0"
id="stop4871-6-2" />
<stop
id="stop4879-7-4"
offset="0.31807542"
style="stop-color: rgb(238, 238, 236); stop-opacity: 1;" />
<stop
id="stop4877-6-1"
offset="0.74691135"
style="stop-color: rgb(200, 201, 198); stop-opacity: 1;" />
<stop
style="stop-color: rgb(211, 215, 207); stop-opacity: 1;"
offset="1"
id="stop4873-1-0" />
</linearGradient>
<filter
id="filter25011"
inkscape:label="Invert"
x="0"
y="0"
width="1"
height="1"
inkscape:menu="Color"
inkscape:menu-tooltip="Invert colors"
color-interpolation-filters="sRGB">
<feColorMatrix
id="feColorMatrix25013"
type="saturate"
values="1"
result="fbSourceGraphic" />
<feColorMatrix
id="feColorMatrix25015"
in="fbSourceGraphic"
values="-1 0 0 0 1 0 -1 0 0 1 0 0 -1 0 1 0 0 0 1 0" />
</filter>
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient4869-4-0"
id="radialGradient24961"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1.0075, 0, 0, 1.0075, -5.4544, -1.25141)"
cx="-33.412369"
cy="185.74171"
fx="-33.412369"
fy="185.74171"
r="2.3554697" />
<linearGradient
id="linearGradient4869-4-0">
<stop
style="stop-color: rgb(255, 255, 255); stop-opacity: 1;"
offset="0"
id="stop4871-6-8" />
<stop
id="stop4879-7-5"
offset="0.31807542"
style="stop-color: rgb(238, 238, 236); stop-opacity: 1;" />
<stop
id="stop4877-6-5"
offset="0.74691135"
style="stop-color: rgb(200, 201, 198); stop-opacity: 1;" />
<stop
style="stop-color: rgb(211, 215, 207); stop-opacity: 1;"
offset="1"
id="stop4873-1-4" />
</linearGradient>
<filter
id="filter25023"
inkscape:label="Invert"
x="0"
y="0"
width="1"
height="1"
inkscape:menu="Color"
inkscape:menu-tooltip="Invert colors"
color-interpolation-filters="sRGB">
<feColorMatrix
id="feColorMatrix25025"
type="saturate"
values="1"
result="fbSourceGraphic" />
<feColorMatrix
id="feColorMatrix25027"
in="fbSourceGraphic"
values="-1 0 0 0 1 0 -1 0 0 1 0 0 -1 0 1 0 0 0 1 0" />
</filter>
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4941"
id="linearGradient24963"
gradientUnits="userSpaceOnUse"
x1="-39.858727"
y1="184.61784"
x2="-38.244785"
y2="188.84898" />
<linearGradient
inkscape:collect="always"
id="linearGradient4941">
<stop
style="stop-color: rgb(255, 255, 255); stop-opacity: 1;"
offset="0"
id="stop4943" />
<stop
style="stop-color: rgb(255, 255, 255); stop-opacity: 0;"
offset="1"
id="stop4945" />
</linearGradient>
<filter
id="filter25033"
inkscape:label="Invert"
x="0"
y="0"
width="1"
height="1"
inkscape:menu="Color"
inkscape:menu-tooltip="Invert colors"
color-interpolation-filters="sRGB">
<feColorMatrix
id="feColorMatrix25035"
type="saturate"
values="1"
result="fbSourceGraphic" />
<feColorMatrix
id="feColorMatrix25037"
in="fbSourceGraphic"
values="-1 0 0 0 1 0 -1 0 0 1 0 0 -1 0 1 0 0 0 1 0" />
</filter>
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4941-7"
id="linearGradient24965"
gradientUnits="userSpaceOnUse"
x1="-39.858727"
y1="184.61784"
x2="-38.244785"
y2="188.84898" />
<linearGradient
inkscape:collect="always"
id="linearGradient4941-7">
<stop
style="stop-color: rgb(255, 255, 255); stop-opacity: 1;"
offset="0"
id="stop4943-2" />
<stop
style="stop-color: rgb(255, 255, 255); stop-opacity: 0;"
offset="1"
id="stop4945-5" />
</linearGradient>
<filter
id="filter25043"
inkscape:label="Invert"
x="0"
y="0"
width="1"
height="1"
inkscape:menu="Color"
inkscape:menu-tooltip="Invert colors"
color-interpolation-filters="sRGB">
<feColorMatrix
id="feColorMatrix25045"
type="saturate"
values="1"
result="fbSourceGraphic" />
<feColorMatrix
id="feColorMatrix25047"
in="fbSourceGraphic"
values="-1 0 0 0 1 0 -1 0 0 1 0 0 -1 0 1 0 0 0 1 0" />
</filter>
<filter
id="filter25049"
inkscape:label="Invert"
x="0"
y="0"
width="1"
height="1"
inkscape:menu="Color"
inkscape:menu-tooltip="Invert colors"
color-interpolation-filters="sRGB">
<feColorMatrix
id="feColorMatrix25051"
type="saturate"
values="1"
result="fbSourceGraphic" />
<feColorMatrix
id="feColorMatrix25053"
in="fbSourceGraphic"
values="-1 0 0 0 1 0 -1 0 0 1 0 0 -1 0 1 0 0 0 1 0" />
</filter>
<filter
id="filter25055"
inkscape:label="Invert"
x="0"
y="0"
width="1"
height="1"
inkscape:menu="Color"
inkscape:menu-tooltip="Invert colors"
color-interpolation-filters="sRGB">
<feColorMatrix
id="feColorMatrix25057"
type="saturate"
values="1"
result="fbSourceGraphic" />
<feColorMatrix
id="feColorMatrix25059"
in="fbSourceGraphic"
values="-1 0 0 0 1 0 -1 0 0 1 0 0 -1 0 1 0 0 0 1 0" />
</filter>
</defs>
<sodipodi:namedview
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="2.8284271"
inkscape:cx="-12.356322"
inkscape:cy="57.536221"
inkscape:current-layer="layer1"
showgrid="true"
inkscape:grid-bbox="true"
inkscape:document-units="px"
inkscape:window-width="1200"
inkscape:window-height="840"
inkscape:window-x="0"
inkscape:window-y="26"
inkscape:window-maximized="0" />
<metadata
id="metadata25075">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title />
</cc:Work>
</rdf:RDF>
</metadata>
<g
id="layer1"
inkscape:label="Layer 1"
inkscape:groupmode="layer"
transform="translate(0, 48)">
<g
id="g3181"
transform="matrix(0,1,-1,0,48.0003,-48)">
<g
style="stroke:#000000;stroke-opacity:1;display:inline"
transform="matrix(2,0,0,2,193.25,-374.967)"
id="g4030-1-8">
<path
style="color:#000000;fill:none;stroke:#000000;stroke-width:7;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible"
d="m -72.5,173.5 -14,14 14,14"
id="path3165-7-3"
sodipodi:nodetypes="ccc"
inkscape:connector-curvature="0" />
</g>
<path
transform="matrix(3.34328,0,0,3.34328,185.28,-623.176)"
d="m -36.5,186.40625 c 0,1.15635 -0.937404,2.09375 -2.09375,2.09375 -1.156346,0 -2.09375,-0.9374 -2.09375,-2.09375 0,-1.15635 0.937404,-2.09375 2.09375,-2.09375 1.156346,0 2.09375,0.9374 2.09375,2.09375 z"
sodipodi:ry="2.09375"
sodipodi:rx="2.09375"
sodipodi:cy="186.40625"
sodipodi:cx="-38.59375"
id="path4050-2-7-9-4"
style="color:#000000;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.52343899;marker:none;visibility:visible;display:inline;overflow:visible"
sodipodi:type="arc" />
<path
transform="matrix(3.34328,0,0,3.34328,207.28,-623.176)"
d="m -36.5,186.40625 c 0,1.15635 -0.937404,2.09375 -2.09375,2.09375 -1.156346,0 -2.09375,-0.9374 -2.09375,-2.09375 0,-1.15635 0.937404,-2.09375 2.09375,-2.09375 1.156346,0 2.09375,0.9374 2.09375,2.09375 z"
sodipodi:ry="2.09375"
sodipodi:rx="2.09375"
sodipodi:cy="186.40625"
sodipodi:cx="-38.59375"
id="path4050-2-7-9-4-8"
style="color:#000000;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.52343899;marker:none;visibility:visible;display:inline;overflow:visible"
sodipodi:type="arc" />
<path
transform="matrix(2.86565,0,0,2.86565,166.846,-534.143)"
d="m -36.5,186.40625 c 0,1.15635 -0.937404,2.09375 -2.09375,2.09375 -1.156346,0 -2.09375,-0.9374 -2.09375,-2.09375 0,-1.15635 0.937404,-2.09375 2.09375,-2.09375 1.156346,0 2.09375,0.9374 2.09375,2.09375 z"
sodipodi:ry="2.09375"
sodipodi:rx="2.09375"
sodipodi:cy="186.40625"
sodipodi:cx="-38.59375"
id="path4050-2-7-9-4-0"
style="color:#000000;fill:none;stroke:#000000;stroke-width:0.69792098;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible"
sodipodi:type="arc" />
<path
transform="matrix(2.86565,0,0,2.86565,188.846,-534.143)"
d="m -36.5,186.40625 c 0,1.15635 -0.937404,2.09375 -2.09375,2.09375 -1.156346,0 -2.09375,-0.9374 -2.09375,-2.09375 0,-1.15635 0.937404,-2.09375 2.09375,-2.09375 1.156346,0 2.09375,0.9374 2.09375,2.09375 z"
sodipodi:ry="2.09375"
sodipodi:rx="2.09375"
sodipodi:cy="186.40625"
sodipodi:cx="-38.59375"
id="path4050-2-7-9-4-0-9"
style="color:#000000;fill:none;stroke:#000000;stroke-width:0.69792098;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible"
sodipodi:type="arc" />
<path
transform="matrix(2,0,0,2,-586,-765.967)"
sodipodi:nodetypes="ccccscccsc"
id="path3165-7-3-1"
d="m 317.06251,365.96875 c -0.76948,0.0224 -1.52555,0.35464 -2.0625,0.90625 l -16.125,16.125 16.125,16.125 c 1.11265,1.11265 3.13735,1.11265 4.25,0 1.11265,-1.11264 1.11265,-3.13735 0,-4.25 l -11.875,-11.875 11.875,-11.875 c 0.86584,-0.83655 1.1475,-2.22114 0.6773,-3.32947 -0.47021,-1.10834 -1.66156,-1.86802 -2.8648,-1.82678 z"
style="font-size:medium;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0pt;text-align:start;text-decoration:none;line-height:normal;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;text-anchor:start;opacity:0.35;color:#000000;fill:none;stroke:#000000;stroke-width:1;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;marker:none;visibility:visible;display:inline;overflow:visible;font-family:Bitstream Vera Sans"
inkscape:connector-curvature="0" />
<path
transform="matrix(2,0,0,2,-586,-765.967)"
sodipodi:nodetypes="ccccccc"
id="path3165-7-3-1-9"
d="m 320.08435,397.03059 c 0.007,-0.79449 -0.27079,-1.59203 -0.83434,-2.15559 L 307.37501,383 m 12.5523,-15.20447 c -0.47021,-1.10834 -1.66156,-1.86802 -2.8648,-1.82678 -0.76948,0.0224 -1.52555,0.35464 -2.0625,0.90625 L 298.87501,383"
style="font-size:medium;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0pt;text-align:start;text-decoration:none;line-height:normal;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;text-anchor:start;color:#000000;fill:none;stroke:#000000;stroke-width:1;stroke-linecap:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;marker:none;visibility:visible;display:inline;overflow:visible;font-family:Bitstream Vera Sans"
inkscape:connector-curvature="0" />
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 16 KiB

View File

@@ -17,10 +17,11 @@ jsdir = $(pkgdatadir)/js
nobase_dist_js_DATA = \
gdm/batch.js \
gdm/consoleKit.js \
gdm/fingerprint.js \
gdm/loginDialog.js \
gdm/powerMenu.js \
gdm/realmd.js \
gdm/systemd.js \
gdm/util.js \
extensionPrefs/main.js \
misc/config.js \
@@ -29,7 +30,6 @@ nobase_dist_js_DATA = \
misc/gnomeSession.js \
misc/history.js \
misc/jsParse.js \
misc/loginManager.js \
misc/modemManager.js \
misc/params.js \
misc/util.js \
@@ -52,7 +52,6 @@ nobase_dist_js_DATA = \
ui/extensionDownloader.js \
ui/flashspot.js \
ui/ibusCandidatePopup.js\
ui/grabHelper.js \
ui/iconGrid.js \
ui/keyboard.js \
ui/keyringPrompt.js \
@@ -73,7 +72,6 @@ nobase_dist_js_DATA = \
ui/panel.js \
ui/panelMenu.js \
ui/placeDisplay.js \
ui/pointerWatcher.js \
ui/polkitAuthenticationAgent.js \
ui/popupMenu.js \
ui/remoteSearch.js \

22
js/gdm/consoleKit.js Normal file
View File

@@ -0,0 +1,22 @@
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
const Gio = imports.gi.Gio;
const ConsoleKitManagerIface = <interface name='org.freedesktop.ConsoleKit.Manager'>
<method name='CanRestart'>
<arg type='b' direction='out'/>
</method>
<method name='CanStop'>
<arg type='b' direction='out'/>
</method>
<method name='Restart' />
<method name='Stop' />
</interface>;
const ConsoleKitProxy = Gio.DBusProxy.makeProxyWrapper(ConsoleKitManagerIface);
function ConsoleKitManager() {
return new ConsoleKitProxy(Gio.DBus.system,
'org.freedesktop.ConsoleKit',
'/org/freedesktop/ConsoleKit/Manager');
};

View File

@@ -696,8 +696,8 @@ const LoginDialog = new Lang.Class({
this._userVerifier.connect('verification-failed', Lang.bind(this, this._onVerificationFailed));
this._userVerifier.connect('reset', Lang.bind(this, this._onReset));
this._userVerifier.connect('show-login-hint', Lang.bind(this, this._showLoginHint));
this._userVerifier.connect('hide-login-hint', Lang.bind(this, this._hideLoginHint));
this._userVerifier.connect('show-fingerprint-prompt', Lang.bind(this, this._showFingerprintPrompt));
this._userVerifier.connect('hide-fingerprint-prompt', Lang.bind(this, this._hideFingerprintPrompt));
this._settings = new Gio.Settings({ schema: GdmUtil.LOGIN_SCREEN_SCHEMA });
@@ -761,9 +761,12 @@ const LoginDialog = new Lang.Class({
x_fill: true,
y_fill: false,
x_align: St.Align.START });
this._promptLoginHint = new St.Label({ style_class: 'login-dialog-prompt-login-hint-message' });
this._promptLoginHint.hide();
this._promptBox.add(this._promptLoginHint);
// Translators: this message is shown below the password entry field
// to indicate the user can swipe their finger instead
this._promptFingerprintMessage = new St.Label({ text: _("(or swipe finger)"),
style_class: 'login-dialog-prompt-fingerprint-message' });
this._promptFingerprintMessage.hide();
this._promptBox.add(this._promptFingerprintMessage);
this._sessionList = new SessionList();
this._sessionList.connect('session-activated',
@@ -851,7 +854,7 @@ const LoginDialog = new Lang.Class({
function() {
this._sessionList.close();
this._promptLoginHint.hide();
this._promptFingerprintMessage.hide();
this._userList.actor.show();
this._userList.actor.opacity = 255;
return this._userList.showItems();
@@ -872,14 +875,12 @@ const LoginDialog = new Lang.Class({
this._sessionList.setActiveSession(sessionId);
},
_showLoginHint: function(verifier, message) {
this._promptLoginHint.set_text(message)
GdmUtil.fadeInActor(this._promptLoginHint);
_showFingerprintPrompt: function() {
GdmUtil.fadeInActor(this._promptFingerprintMessage);
},
_hideLoginHint: function() {
GdmUtil.fadeOutActor(this._promptLoginHint);
this._promptLoginHint.set_text('');
_hideFingerprintPrompt: function() {
GdmUtil.fadeOutActor(this._promptFingerprintMessage);
},
cancel: function() {
@@ -898,8 +899,8 @@ const LoginDialog = new Lang.Class({
function() {
// Show it with 0 opacity so we preallocate space for it
// in the event we need to fade in the message
this._promptLoginHint.opacity = 0;
this._promptLoginHint.show();
this._promptFingerprintMessage.opacity = 0;
this._promptFingerprintMessage.show();
},
function() {
@@ -971,8 +972,9 @@ const LoginDialog = new Lang.Class({
},
function() {
this._promptLoginHint.hide();
this._promptFingerprintMessage.hide();
this._promptEntry.reactive = true;
this._promptEntry.remove_style_pseudo_class('insensitive');
this._promptEntry.set_text('');
}];
@@ -992,6 +994,7 @@ const LoginDialog = new Lang.Class({
function() {
let _text = this._promptEntry.get_text();
this._promptEntry.reactive = false;
this._promptEntry.add_style_pseudo_class('insensitive');
this._userVerifier.answerQuery(serviceName, _text);
}];

View File

@@ -21,7 +21,8 @@
const Lang = imports.lang;
const UPowerGlib = imports.gi.UPowerGlib;
const LoginManager = imports.misc.loginManager;
const ConsoleKit = imports.gdm.consoleKit;
const Systemd = imports.gdm.systemd;
const PanelMenu = imports.ui.panelMenu;
const PopupMenu = imports.ui.popupMenu;
@@ -34,7 +35,10 @@ const PowerMenuButton = new Lang.Class({
this.parent('system-shutdown', null);
this._upClient = new UPowerGlib.Client();
this._loginManager = LoginManager.getLoginManager();
if (Systemd.haveSystemd())
this._systemdLoginManager = new Systemd.SystemdLoginManager();
else
this._consoleKitManager = new ConsoleKit.ConsoleKitManager();
this._createSubMenu();
@@ -61,19 +65,57 @@ const PowerMenuButton = new Lang.Class({
},
_updateHaveShutdown: function() {
this._loginManager.canPowerOff(Lang.bind(this, function(result) {
this._haveShutdown = result;
this._powerOffItem.actor.visible = this._haveShutdown;
this._updateVisibility();
}));
if (Systemd.haveSystemd()) {
this._systemdLoginManager.CanPowerOffRemote(Lang.bind(this,
function(result, error) {
if (!error)
this._haveShutdown = result[0] != 'no';
else
this._haveShutdown = false;
this._powerOffItem.actor.visible = this._haveShutdown;
this._updateVisibility();
}));
} else {
this._consoleKitManager.CanStopRemote(Lang.bind(this,
function(result, error) {
if (!error)
this._haveShutdown = result[0];
else
this._haveShutdown = false;
this._powerOffItem.actor.visible = this._haveShutdown;
this._updateVisibility();
}));
}
},
_updateHaveRestart: function() {
this._loginManager.canReboot(Lang.bind(this, function(result) {
this._haveRestart = result;
this._restartItem.actor.visible = this._haveRestart;
this._updateVisibility();
}));
if (Systemd.haveSystemd()) {
this._systemdLoginManager.CanRebootRemote(Lang.bind(this,
function(result, error) {
if (!error)
this._haveRestart = result[0] != 'no';
else
this._haveRestart = false;
this._restartItem.actor.visible = this._haveRestart;
this._updateVisibility();
}));
} else {
this._consoleKitManager.CanRestartRemote(Lang.bind(this,
function(result, error) {
if (!error)
this._haveRestart = result[0];
else
this._haveRestart = false;
this._restartItem.actor.visible = this._haveRestart;
this._updateVisibility();
}));
}
},
_updateHaveSuspend: function() {
@@ -110,13 +152,19 @@ const PowerMenuButton = new Lang.Class({
if (!this._haveRestart)
return;
this._loginManager.reboot();
if (Systemd.haveSystemd())
this._systemdLoginManager.RebootRemote(true);
else
this._consoleKitManager.RestartRemote();
},
_onActivatePowerOff: function() {
if (!this._haveShutdown)
return;
this._loginManager.powerOff();
if (Systemd.haveSystemd())
this._systemdLoginManager.PowerOffRemote(true);
else
this._consoleKitManager.StopRemote();
}
});

View File

@@ -1,139 +0,0 @@
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
const Gio = imports.gi.Gio;
const Lang = imports.lang;
const Shell = imports.gi.Shell;
const Signals = imports.signals;
const ProviderIface = <interface name='org.freedesktop.realmd.Provider'>
<property name="Name" type="s" access="read"/>
<property name="Version" type="s" access="read"/>
<property name="Realms" type="ao" access="read"/>
<method name="Discover">
<arg name="string" type="s" direction="in"/>
<arg name="options" type="a{sv}" direction="in"/>
<arg name="relevance" type="i" direction="out"/>
<arg name="realm" type="ao" direction="out"/>
</method>
</interface>;
const Provider = Gio.DBusProxy.makeProxyWrapper(ProviderIface);
const ServiceIface = <interface name="org.freedesktop.realmd.Service">
<method name="Cancel">
<arg name="operation" type="s" direction="in"/>
</method>
<method name="Release" />
<method name="SetLocale">
<arg name="locale" type="s" direction="in"/>
</method>
<signal name="Diagnostics">
<arg name="data" type="s"/>
<arg name="operation" type="s"/>
</signal>
</interface>;
const Service = Gio.DBusProxy.makeProxyWrapper(ServiceIface);
const RealmIface = <interface name="org.freedesktop.realmd.Realm">
<property name="Name" type="s" access="read"/>
<property name="Configured" type="s" access="read"/>
<property name="Details" type="a(ss)" access="read"/>
<property name="LoginFormats" type="as" access="read"/>
<property name="LoginPolicy" type="s" access="read"/>
<property name="PermittedLogins" type="as" access="read"/>
<property name="SupportedInterfaces" type="as" access="read"/>
<method name="ChangeLoginPolicy">
<arg name="login_policy" type="s" direction="in"/>
<arg name="permitted_add" type="as" direction="in"/>
<arg name="permitted_remove" type="as" direction="in"/>
<arg name="options" type="a{sv}" direction="in"/>
</method>
<method name="Deconfigure">
<arg name="options" type="a{sv}" direction="in"/>
</method>
</interface>;
const Realm = Gio.DBusProxy.makeProxyWrapper(RealmIface);
const Manager = new Lang.Class({
Name: 'Manager',
_init: function(parentActor) {
this._aggregateProvider = Provider(Gio.DBus.system,
'org.freedesktop.realmd',
'/org/freedesktop/realmd',
Lang.bind(this, this._reloadRealms))
this._realms = {};
this._aggregateProvider.connect('g-properties-changed',
Lang.bind(this, function(proxy, properties) {
if ('Realms' in properties.deep_unpack())
this._reloadRealms();
}));
},
_reloadRealms: function() {
let realmPaths = this._aggregateProvider.Realms;
if (!realmPaths)
return;
for (let i = 0; i < realmPaths.length; i++) {
let realm = Realm(Gio.DBus.system,
'org.freedesktop.realmd',
realmPaths[i],
Lang.bind(this, this._onRealmLoaded));
}
},
_reloadRealm: function(realm) {
if (!realm.Configured) {
if (this._realms[realm.get_object_path()])
delete this._realms[realm.get_object_path()];
return;
}
this._realms[realm.get_object_path()] = realm;
this._updateLoginFormat();
},
_onRealmLoaded: function(realm, error) {
if (error)
return;
this._reloadRealm(realm);
realm.connect('g-properties-changed',
Lang.bind(this, function(proxy, properties) {
if ('Configured' in properties.deep_unpack())
this._reloadRealm();
}));
},
_updateLoginFormat: function() {
let newLoginFormat;
for (let realmPath in this._realms) {
let realm = this._realms[realmPath];
if (realm.LoginFormats && realm.LoginFormats.length > 0) {
newLoginFormat = realm.LoginFormats[0];
break;
}
}
if (this._loginFormat != newLoginFormat) {
this._loginFormat = newLoginFormat;
this.emit('login-format-changed', newLoginFormat);
}
},
get loginFormat() {
if (this._loginFormat !== undefined)
return this._loginFormat;
this._updateLoginFormat();
return this._loginFormat;
}
});
Signals.addSignalMethods(Manager.prototype)

31
js/gdm/systemd.js Normal file
View File

@@ -0,0 +1,31 @@
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
const GLib = imports.gi.GLib;
const Gio = imports.gi.Gio;
const SystemdLoginManagerIface = <interface name='org.freedesktop.login1.Manager'>
<method name='PowerOff'>
<arg type='b' direction='in'/>
</method>
<method name='Reboot'>
<arg type='b' direction='in'/>
</method>
<method name='CanPowerOff'>
<arg type='s' direction='out'/>
</method>
<method name='CanReboot'>
<arg type='s' direction='out'/>
</method>
</interface>;
const SystemdLoginManagerProxy = Gio.DBusProxy.makeProxyWrapper(SystemdLoginManagerIface);
function SystemdLoginManager() {
return new SystemdLoginManagerProxy(Gio.DBus.system,
'org.freedesktop.login1',
'/org/freedesktop/login1');
};
function haveSystemd() {
return GLib.access("/sys/fs/cgroup/systemd", 0) >= 0;
}

View File

@@ -6,7 +6,6 @@ const Signals = imports.signals;
const Batch = imports.gdm.batch;
const Fprint = imports.gdm.fingerprint;
const Realmd = imports.gdm.realmd;
const Main = imports.ui.main;
const Params = imports.misc.params;
const Tweener = imports.ui.tweener;
@@ -83,8 +82,6 @@ const ShellUserVerifier = new Lang.Class({
this._fprintManager = new Fprint.FprintManager();
this._checkForFingerprintReader();
this._realmManager = new Realmd.Manager();
},
begin: function(userName, hold) {
@@ -214,10 +211,7 @@ const ShellUserVerifier = new Lang.Class({
// as a cue to display our own message.
if (serviceName == FINGERPRINT_SERVICE_NAME &&
this._haveFingerprintReader) {
// Translators: this message is shown below the password entry field
// to indicate the user can swipe their finger instead
this.emit('show-login-hint', _("(or swipe finger)"));
this.emit('show-fingerprint-prompt');
} else if (serviceName == PASSWORD_SERVICE_NAME) {
Main.notifyError(info);
}
@@ -231,30 +225,11 @@ const ShellUserVerifier = new Lang.Class({
Main.notifyError(problem);
},
_showRealmLoginHint: function() {
if (this._realmManager.loginFormat) {
let hint = this._realmManager.loginFormat;
hint = hint.replace(/%U/g, 'user');
hint = hint.replace(/%D/g, 'DOMAIN');
hint = hint.replace(/%[^UD]/g, '');
// Translators: this message is shown below the username entry field
// to clue the user in on how to login to the local network realm
this.emit('show-login-hint',
_("(e.g., user or %s)").format(hint));
}
},
_onInfoQuery: function(client, serviceName, question) {
// We only expect questions to come from the main auth service
if (serviceName != PASSWORD_SERVICE_NAME)
return;
this._showRealmLoginHint();
this._realmLoginHintSignalId = this._realmManager.connect('login-format-changed',
Lang.bind(this, this._showRealmLoginHint));
this.emit('ask-question', serviceName, question, '');
},
@@ -285,13 +260,8 @@ const ShellUserVerifier = new Lang.Class({
// password authentication a chance to succeed
if (serviceName == PASSWORD_SERVICE_NAME) {
this.emit('verification-failed');
}
this.emit('hide-login-hint');
if (this._realmLoginHintSignalId) {
this._realmManager.disconnect(this._realmLoginHintSignalId);
this._realmLoginHintSignalId = 0;
} else if (serviceName == FINGERPRINT_SERVICE_NAME) {
this.emit('hide-fingerprint-prompt');
}
},
});

View File

@@ -1,197 +0,0 @@
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
const GLib = imports.gi.GLib;
const Gio = imports.gi.Gio;
const Lang = imports.lang;
const Shell = imports.gi.Shell;
const SystemdLoginManagerIface = <interface name='org.freedesktop.login1.Manager'>
<method name='PowerOff'>
<arg type='b' direction='in'/>
</method>
<method name='Reboot'>
<arg type='b' direction='in'/>
</method>
<method name='CanPowerOff'>
<arg type='s' direction='out'/>
</method>
<method name='CanReboot'>
<arg type='s' direction='out'/>
</method>
</interface>;
const SystemdLoginSessionIface = <interface name='org.freedesktop.login1.Session'>
<signal name='Lock' />
<signal name='Unlock' />
</interface>;
const SystemdLoginManager = Gio.DBusProxy.makeProxyWrapper(SystemdLoginManagerIface);
const SystemdLoginSession = Gio.DBusProxy.makeProxyWrapper(SystemdLoginSessionIface);
const ConsoleKitManagerIface = <interface name='org.freedesktop.ConsoleKit.Manager'>
<method name='CanRestart'>
<arg type='b' direction='out'/>
</method>
<method name='CanStop'>
<arg type='b' direction='out'/>
</method>
<method name='Restart' />
<method name='Stop' />
<method name='GetCurrentSession'>
<arg type='o' direction='out' />
</method>
</interface>;
const ConsoleKitSessionIface = <interface name='org.freedesktop.ConsoleKit.Session'>
<method name='IsActive'>
<arg type='b' direction='out' />
</method>
<signal name='ActiveChanged'>
<arg type='b' direction='out' />
</signal>
<signal name='Lock' />
<signal name='Unlock' />
</interface>;
const ConsoleKitSession = Gio.DBusProxy.makeProxyWrapper(ConsoleKitSessionIface);
const ConsoleKitManager = Gio.DBusProxy.makeProxyWrapper(ConsoleKitManagerIface);
function haveSystemd() {
return GLib.access("/sys/fs/cgroup/systemd", 0) >= 0;
}
let _loginManager = null;
/**
* LoginManager:
* An abstraction over systemd/logind and ConsoleKit.
*
*/
function getLoginManager() {
if (_loginManager == null) {
if (haveSystemd())
_loginManager = new LoginManagerSystemd();
else
_loginManager = new LoginManagerConsoleKit();
}
return _loginManager;
}
const LoginManagerSystemd = new Lang.Class({
Name: 'LoginManagerSystemd',
_init: function() {
this._proxy = new SystemdLoginManager(Gio.DBus.system,
'org.freedesktop.login1',
'/org/freedesktop/login1');
},
// Having this function is a bit of a hack since the Systemd and ConsoleKit
// session objects have different interfaces - but in both cases there are
// Lock/Unlock signals, and that's all we count upon at the moment.
getCurrentSessionProxy: function() {
if (!this._currentSession) {
this._currentSession = new SystemdLoginSession(Gio.DBus.system,
'org.freedesktop.login1',
'/org/freedesktop/login1/session/' +
GLib.getenv('XDG_SESSION_ID'));
}
return this._currentSession;
},
get sessionActive() {
return Shell.session_is_active_for_systemd();
},
canPowerOff: function(asyncCallback) {
this._proxy.CanPowerOffRemote(function(result, error) {
if (error)
asyncCallback(false);
else
asyncCallback(result[0] != 'no');
});
},
canReboot: function(asyncCallback) {
this._proxy.CanRebootRemote(function(result, error) {
if (error)
asyncCallback(false);
else
asyncCallback(result[0] != 'no');
});
},
powerOff: function() {
this._proxy.PowerOffRemote(true);
},
reboot: function() {
this._proxy.RebootRemote(true);
}
});
const LoginManagerConsoleKit = new Lang.Class({
Name: 'LoginManagerConsoleKit',
_init: function() {
this._proxy = new ConsoleKitManager(Gio.DBus.system,
'org.freedesktop.ConsoleKit',
'/org/freedesktop/ConsoleKit/Manager');
},
// Having this function is a bit of a hack since the Systemd and ConsoleKit
// session objects have different interfaces - but in both cases there are
// Lock/Unlock signals, and that's all we count upon at the moment.
getCurrentSessionProxy: function() {
if (!this._currentSession) {
let [currentSessionId] = this._proxy.GetCurrentSessionSync();
this._currentSession = new ConsoleKitSession(Gio.DBus.system,
'org.freedesktop.ConsoleKit',
currentSessionId);
}
return this._currentSession;
},
get sessionActive() {
if (this._sessionActive !== undefined)
return this._sessionActive;
let session = this.getCurrentSessionProxy();
session.connectSignal('ActiveChanged', Lang.bind(this, function(object, senderName, [isActive]) {
this._sessionActive = isActive;
}));
[this._sessionActive] = session.IsActiveSync();
return this._sessionActive;
},
canPowerOff: function(asyncCallback) {
this._proxy.CanStopRemote(function(result, error) {
if (error)
asyncCallback(false);
else
asyncCallback(result[0]);
});
},
canReboot: function(asyncCallback) {
this._proxy.CanRestartRemote(function(result, error) {
if (error)
asyncCallback(false);
else
asyncCallback(result[0]);
});
},
powerOff: function() {
this._proxy.StopRemote();
},
reboot: function() {
this._proxy.RestartRemote();
}
});

View File

@@ -84,7 +84,7 @@ function trySpawn(argv)
try {
[success, pid] = GLib.spawn_async(null, argv, null,
GLib.SpawnFlags.SEARCH_PATH | GLib.SpawnFlags.DO_NOT_REAP_CHILD,
null);
null, null);
} catch (err) {
/* Rewrite the error in case of ENOENT */
if (err.matches(GLib.SpawnError, GLib.SpawnError.NOENT)) {

View File

@@ -115,10 +115,10 @@ function run() {
for (let i = 0; i < 2; i++) {
Scripting.scriptEvent('applicationsShowStart');
Main.overview._dash.showAppsButton.checked = true;
Main.overview._viewSelector.switchTab('applications');
yield Scripting.waitLeisure();
Scripting.scriptEvent('applicationsShowDone');
Main.overview._dash.showAppsButton.checked = false;
Main.overview._viewSelector.switchTab('windows');
yield Scripting.waitLeisure();
}
}

View File

@@ -5,12 +5,11 @@ const Mainloop = imports.mainloop;
const GLib = imports.gi.GLib;
const Gio = imports.gi.Gio;
const Params = imports.misc.params;
const Shell = imports.gi.Shell;
const GnomeSession = imports.misc.gnomeSession;
const LoginManager = imports.misc.loginManager;
const Shell = imports.gi.Shell;
const Main = imports.ui.main;
const ShellMountOperation = imports.ui.shellMountOperation;
const GnomeSession = imports.misc.gnomeSession;
const GNOME_SESSION_AUTOMOUNT_INHIBIT = 16;
@@ -20,6 +19,62 @@ const SETTING_ENABLE_AUTOMOUNT = 'automount';
const AUTORUN_EXPIRE_TIMEOUT_SECS = 10;
const ConsoleKitSessionIface = <interface name="org.freedesktop.ConsoleKit.Session">
<method name="IsActive">
<arg type="b" direction="out" />
</method>
<signal name="ActiveChanged">
<arg type="b" direction="out" />
</signal>
</interface>;
const ConsoleKitSessionProxy = Gio.DBusProxy.makeProxyWrapper(ConsoleKitSessionIface);
const ConsoleKitManagerIface = <interface name="org.freedesktop.ConsoleKit.Manager">
<method name="GetCurrentSession">
<arg type="o" direction="out" />
</method>
</interface>;
const ConsoleKitManagerInfo = Gio.DBusInterfaceInfo.new_for_xml(ConsoleKitManagerIface);
function ConsoleKitManager() {
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) });
self._updateSessionActive = function() {
if (self.g_name_owner) {
self.GetCurrentSessionRemote(function([session]) {
self._ckSession = new ConsoleKitSessionProxy(Gio.DBus.system, 'org.freedesktop.ConsoleKit', session);
self._ckSession.connectSignal('ActiveChanged', function(object, senderName, [isActive]) {
self.sessionActive = isActive;
});
self._ckSession.IsActiveRemote(function([isActive]) {
self.sessionActive = isActive;
});
});
} else {
self.sessionActive = true;
}
};
self.connect('notify::g-name-owner',
Lang.bind(self, self._updateSessionActive));
self._updateSessionActive();
self.init(null);
return self;
}
function haveSystemd() {
return GLib.access("/sys/fs/cgroup/systemd", 0) >= 0;
}
const AutomountManager = new Lang.Class({
Name: 'AutomountManager',
@@ -33,7 +88,8 @@ const AutomountManager = new Lang.Class({
Lang.bind(this, this._InhibitorsChanged));
this._inhibited = false;
this._loginManager = LoginManager.getLoginManager();
if (!haveSystemd())
this.ckListener = new ConsoleKitManager();
Main.screenShield.connect('lock-status-changed', Lang.bind(this, this._lockStatusChanged));
@@ -90,10 +146,21 @@ const AutomountManager = new Lang.Class({
return false;
},
isSessionActive: function() {
// Return whether the current session is active, using the
// right mechanism: either systemd if available or ConsoleKit
// as fallback.
if (haveSystemd())
return Shell.session_is_active_for_systemd();
return this.ckListener.sessionActive;
},
_onDriveConnected: function() {
// if we're not in the current ConsoleKit session,
// or screensaver is active, don't play sounds
if (!this._loginManager.sessionActive)
if (!this.isSessionActive())
return;
if (Main.screenShield.locked)
@@ -105,7 +172,7 @@ const AutomountManager = new Lang.Class({
_onDriveDisconnected: function() {
// if we're not in the current ConsoleKit session,
// or screensaver is active, don't play sounds
if (!this._loginManager.sessionActive)
if (!this.isSessionActive())
return;
if (Main.screenShield.locked)
@@ -117,7 +184,7 @@ const AutomountManager = new Lang.Class({
_onDriveEjectButton: function(monitor, drive) {
// TODO: this code path is not tested, as the GVfs volume monitor
// doesn't emit this signal just yet.
if (!this._loginManager.sessionActive)
if (!this.isSessionActive())
return;
// we force stop/eject in this case, so we don't have to pass a
@@ -157,7 +224,7 @@ const AutomountManager = new Lang.Class({
if (params.checkSession) {
// if we're not in the current ConsoleKit session,
// don't attempt automount
if (!this._loginManager.sessionActive)
if (!this.isSessionActive())
return;
if (Main.screenShield.locked) {

View File

@@ -717,15 +717,13 @@ const EventsList = new Lang.Class({
let tomorrowEnd = new Date(dayEnd.getTime() + 86400 * 1000);
this._addPeriod(_("Tomorrow"), tomorrowBegin, tomorrowEnd, false, true);
let dayInWeek = (dayEnd.getDay() - this._weekStart + 7) % 7;
if (dayInWeek < 5) {
if (dayEnd.getDay() <= 4 + this._weekStart) {
/* If now is within the first 5 days we show "This week" and
* include events up until and including Saturday/Sunday
* (depending on whether a week starts on Sunday/Monday).
*/
let thisWeekBegin = new Date(dayBegin.getTime() + 2 * 86400 * 1000);
let thisWeekEnd = new Date(dayEnd.getTime() + (6 - dayInWeek) * 86400 * 1000);
let thisWeekEnd = new Date(dayEnd.getTime() + (6 + this._weekStart - dayEnd.getDay()) * 86400 * 1000);
this._addPeriod(_("This week"), thisWeekBegin, thisWeekEnd, true, false);
} else {
/* otherwise it's one of the two last days of the week ... show
@@ -733,7 +731,7 @@ const EventsList = new Lang.Class({
* Saturday/Sunday
*/
let nextWeekBegin = new Date(dayBegin.getTime() + 2 * 86400 * 1000);
let nextWeekEnd = new Date(dayEnd.getTime() + (13 - dayInWeek) * 86400 * 1000);
let nextWeekEnd = new Date(dayEnd.getTime() + (13 + this._weekStart - dayEnd.getDay()) * 86400 * 1000);
this._addPeriod(_("Next week"), nextWeekBegin, nextWeekEnd, true, false);
}
},

View File

@@ -27,6 +27,7 @@ const CtrlAltTabManager = new Lang.Class({
_init: function() {
this._items = [];
this._focusManager = St.FocusManager.get_for_stage(global.stage);
},
addGroup: function(root, name, icon, params) {
@@ -40,11 +41,11 @@ const CtrlAltTabManager = new Lang.Class({
this._items.push(item);
root.connect('destroy', Lang.bind(this, function() { this.removeGroup(root); }));
global.focus_manager.add_group(root);
this._focusManager.add_group(root);
},
removeGroup: function(root) {
global.focus_manager.remove_group(root);
this._focusManager.remove_group(root);
for (let i = 0; i < this._items.length; i++) {
if (this._items[i].root == root) {
this._items.splice(i, 1);

View File

@@ -226,39 +226,34 @@ const DashItemContainer = new Lang.Class({
}
});
const ShowAppsIcon = new Lang.Class({
Name: 'ShowAppsIcon',
const RemoveFavoriteIcon = new Lang.Class({
Name: 'RemoveFavoriteIcon',
Extends: DashItemContainer,
_init: function() {
this.parent();
this.toggleButton = new St.Button({ style_class: 'show-apps',
track_hover: true,
can_focus: true,
toggle_mode: true });
this._iconBin = new St.Bin({ style_class: 'remove-favorite' });
this._iconActor = null;
this.icon = new IconGrid.BaseIcon(_("Show Applications"),
this.icon = new IconGrid.BaseIcon(_("Remove"),
{ setSizeManually: true,
showLabel: false,
createIcon: Lang.bind(this, this._createIcon) });
this.toggleButton.add_actor(this.icon.actor);
this.toggleButton._delegate = this;
this._iconBin.set_child(this.icon.actor);
this._iconBin._delegate = this;
this.setChild(this.toggleButton);
this.setChild(this._iconBin);
},
_createIcon: function(size) {
this._iconActor = new St.Icon({ icon_name: 'view-grid-symbolic',
style_class: 'show-apps-icon',
track_hover: true,
icon_type: St.IconType.SYMBOLIC,
this._iconActor = new St.Icon({ icon_name: 'user-trash',
style_class: 'remove-favorite-icon',
icon_size: size });
return this._iconActor;
},
setHover: function(hovered) {
this.toggleButton.set_hover(hovered);
this._iconBin.set_hover(hovered);
if (this._iconActor)
this._iconActor.set_hover(hovered);
},
@@ -311,27 +306,17 @@ const Dash = new Lang.Class({
this._dragPlaceholder = null;
this._dragPlaceholderPos = -1;
this._animatingPlaceholdersCount = 0;
this._favRemoveTarget = null;
this._showLabelTimeoutId = 0;
this._resetHoverTimeoutId = 0;
this._labelShowing = false;
this._container = new St.BoxLayout({ name: 'dash',
vertical: true,
clip_to_allocation: true });
this._box = new St.BoxLayout({ vertical: true,
this._box = new St.BoxLayout({ name: 'dash',
vertical: true,
clip_to_allocation: true });
this._box._delegate = this;
this._container.add(this._box);
this._showAppsIcon = new ShowAppsIcon();
this._showAppsIcon.icon.setIconSize(this.iconSize);
this.showAppsButton = this._showAppsIcon.toggleButton;
this._container.add(this._showAppsIcon.actor);
this.actor = new St.Bin({ child: this._container });
this.actor = new St.Bin({ y_align: St.Align.START, child: this._box });
this.actor.connect('notify::height', Lang.bind(this,
function() {
if (this._maxHeight != this.actor.height)
@@ -384,6 +369,14 @@ const Dash = new Lang.Class({
_endDrag: function() {
this._clearDragPlaceholder();
if (this._favRemoveTarget) {
this._favRemoveTarget.animateOutAndDestroy();
this._favRemoveTarget.actor.connect('destroy', Lang.bind(this,
function() {
this._favRemoveTarget = null;
}));
this._adjustIconSize();
}
DND.removeDragMonitor(this._dragMonitor);
},
@@ -402,13 +395,28 @@ const Dash = new Lang.Class({
let srcIsFavorite = (id in favorites);
let showAppsHovered =
this._showAppsIcon.actor.contains(dragEvent.targetActor);
if (srcIsFavorite &&
app.get_state() != Shell.AppState.RUNNING &&
dragEvent.source.actor &&
this.actor.contains (dragEvent.source.actor) &&
this._favRemoveTarget == null) {
this._favRemoveTarget = new RemoveFavoriteIcon();
this._favRemoveTarget.icon.setIconSize(this.iconSize);
this._box.add(this._favRemoveTarget.actor);
this._adjustIconSize();
this._favRemoveTarget.animateIn();
}
if (!this._box.contains(dragEvent.targetActor) || showAppsHovered)
let favRemoveHovered = false;
if (this._favRemoveTarget)
favRemoveHovered =
this._favRemoveTarget.actor.contains(dragEvent.targetActor);
if (!this._box.contains(dragEvent.targetActor) || favRemoveHovered)
this._clearDragPlaceholder();
this._showAppsIcon.setHover(showAppsHovered);
if (this._favRemoveTarget)
this._favRemoveTarget.setHover(favRemoveHovered);
return DND.DragMotionResult.CONTINUE;
},
@@ -502,12 +510,18 @@ const Dash = new Lang.Class({
!actor._delegate.animatingOut;
});
iconChildren.push(this._showAppsIcon.actor);
if (iconChildren.length == 0) {
this._box.add_style_pseudo_class('empty');
return;
}
this._box.remove_style_pseudo_class('empty');
if (this._maxHeight == -1)
return;
let themeNode = this._container.get_theme_node();
let themeNode = this._box.get_theme_node();
let maxAllocation = new Clutter.ActorBox({ x1: 0, y1: 0,
x2: 42 /* whatever */,
y2: this._maxHeight });
@@ -533,6 +547,7 @@ const Dash = new Lang.Class({
[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;

View File

@@ -1,346 +0,0 @@
/* -*- mode: js2; js2-basic-offset: 4; indent-tabs-mode: nil -*- */
const Clutter = imports.gi.Clutter;
const Gtk = imports.gi.Gtk;
const Lang = imports.lang;
const Meta = imports.gi.Meta;
const Shell = imports.gi.Shell;
const St = imports.gi.St;
const Main = imports.ui.main;
const Params = imports.misc.params;
function _navigateActor(actor, needsGrab) {
if (!actor)
return;
if (needsGrab && actor instanceof St.Widget)
needsGrab = !actor.navigate_focus(null, Gtk.DirectionType.TAB_FORWARD, false);
if (needsGrab)
actor.grab_key_focus();
}
// GrabHelper:
// @owner: the actor that owns the GrabHelper
//
// Creates a new GrabHelper object, for dealing with keyboard and pointer grabs
// associated with a set of actors.
//
// Note that the grab can be automatically dropped at any time by the user, and
// your code just needs to deal with it; you shouldn't adjust behavior directly
// after you call ungrab(), but instead pass an 'onUngrab' callback when you
// call grab().
const GrabHelper = new Lang.Class({
Name: 'GrabHelper',
_init: function(owner) {
this._owner = owner;
this._grabStack = [];
this._actors = [];
this._capturedEventId = 0;
this._eventId = 0;
this._keyFocusNotifyId = 0;
this._focusWindowChangedId = 0;
this._ignoreRelease = false;
this._modalCount = 0;
this._grabFocusCount = 0;
},
// addActor:
// @actor: an actor
//
// Adds @actor to the set of actors that are allowed to process events
// during a grab.
addActor: function(actor) {
actor.__grabHelperDestroyId = actor.connect('destroy', Lang.bind(this, function() { this.removeActor(actor); }));
this._actors.push(actor);
},
// removeActor:
// @actor: an actor
//
// Removes @actor from the set of actors that are allowed to
// process events during a grab.
removeActor: function(actor) {
let index = this._actors.indexOf(actor);
if (index != -1)
this._actors.splice(index, 1);
if (actor.__grabHelperDestroyId) {
actor.disconnect(actor.__grabHelperDestroyId);
delete actor.__grabHelperDestroyId;
}
},
_isWithinGrabbedActor: function(actor) {
while (actor) {
if (this._actors.indexOf(actor) != -1)
return true;
actor = actor.get_parent();
}
return false;
},
get currentGrab() {
let idx = this._grabStack.length - 1;
while (idx >= 0 && this._grabStack[idx].untracked)
idx--;
return this._grabStack[idx] || {};
},
_findStackIndex: function(actor) {
if (!actor)
return -1;
for (let i = 0; i < this._grabStack.length; i++) {
if (this._grabStack[i].actor === actor)
return i;
}
return -1;
},
isActorGrabbed: function(actor) {
return this._findStackIndex(actor) >= 0;
},
// grab:
// @params: A bunch of parameters, see below
//
// Grabs the mouse and keyboard, according to the GrabHelper's
// parameters. If @newFocus is not %null, then the keyboard focus
// is moved to the first #StWidget:can-focus widget inside it.
//
// The grab will automatically be dropped if:
// - The user clicks outside the grabbed actors
// - The user types Escape
// - The keyboard focus is moved outside the grabbed actors
// - A window is focused
//
// If @params.actor is not null, then it will be focused as the
// new actor. If you attempt to grab an already focused actor, the
// request to be focused will be ignored. The actor will not be
// added to the grab stack, so do not call a paired ungrab().
//
// If @params contains { modal: true }, then grab() will push a modal
// on the owner of the GrabHelper. As long as there is at least one
// { modal: true } actor on the grab stack, the grab will be kept.
// When the last { modal: true } actor is ungrabbed, then the modal
// will be dropped.
//
// If @params contains { grabFocus: true }, then if you call grab()
// while the shell is outside the overview, it will set the stage
// input mode to %Shell.StageInputMode.FOCUSED, and ungrab() will
// revert it back, and re-focus the previously-focused window (if
// another window hasn't been explicitly focused before then).
//
// If @params contains { untracked: true }, then it will be skipped
// when the grab helper ungrabs for you, or when calculating
// currentGrab.
grab: function(params) {
params = Params.parse(params, { actor: null,
modal: false,
untracked: false,
grabFocus: false,
onUngrab: null });
let focus = global.stage.key_focus;
let hadFocus = focus && this._isWithinGrabbedActor(focus);
let newFocus = params.actor;
if (this.isActorGrabbed(params.actor))
return;
if (this._grabFocusCount == 0 && this._modalCount == 0)
this._fullGrab(hadFocus, params.modal, params.grabFocus);
params.savedFocus = focus;
this._grabStack.push(params);
if (params.modal)
this._modalCount++;
if (params.grabFocus)
this._grabFocusCount++;
_navigateActor(newFocus, hadFocus);
},
_fullGrab: function(hadFocus, modal, grabFocus) {
let metaDisplay = global.screen.get_display();
this._grabbedFromKeynav = hadFocus;
this._preGrabInputMode = global.stage_input_mode;
this._prevFocusedWindow = null;
if (modal) {
Main.pushModal(this._owner);
}
if (grabFocus) {
this._prevFocusedWindow = metaDisplay.focus_window;
if (this._preGrabInputMode == Shell.StageInputMode.NONREACTIVE ||
this._preGrabInputMode == Shell.StageInputMode.NORMAL) {
global.set_stage_input_mode(Shell.StageInputMode.FOCUSED);
}
}
if (modal || grabFocus) {
this._capturedEventId = global.stage.connect('captured-event', Lang.bind(this, this._onCapturedEvent));
this._eventId = global.stage.connect('event', Lang.bind(this, this._onEvent));
this._keyFocusNotifyId = global.stage.connect('notify::key-focus', Lang.bind(this, this._onKeyFocusChanged));
this._focusWindowChangedId = metaDisplay.connect('notify::focus-window', Lang.bind(this, this._focusWindowChanged));
}
},
// ignoreRelease:
//
// Make sure that the next button release event evaluated by the
// capture event handler returns false. This is designed for things
// like the ComboBoxMenu that go away on press, but need to eat
// the next release event.
ignoreRelease: function() {
this._ignoreRelease = true;
},
// ungrab:
// @params: The parameters for the grab; see below.
//
// Pops an actor from the grab stack, potentially dropping the grab.
//
// If the actor that was popped from the grab stack was not the actor
// That was passed in, this call is ignored.
ungrab: function(params) {
params = Params.parse(params, { actor: this.currentGrab.actor });
let grabStackIndex = this._findStackIndex(params.actor);
if (grabStackIndex < 0)
return;
let poppedGrabs = this._grabStack.slice(grabStackIndex);
// "Pop" all newly ungrabbed actors off the grab stack
// by truncating the array.
this._grabStack.length = grabStackIndex;
let wasModal = this._modalCount > 0;
for (let i = poppedGrabs.length - 1; i >= 0; i--) {
let poppedGrab = poppedGrabs[i];
if (poppedGrab.onUngrab)
poppedGrab.onUngrab();
if (poppedGrab.modal)
this._modalCount--;
if (poppedGrab.grabFocus)
this._grabFocusCount--;
}
let focus = global.stage.key_focus;
let hadFocus = focus && this._isWithinGrabbedActor(focus);
if (this._grabFocusCount == 0 && this._modalCount == 0)
this._fullUngrab(wasModal);
let poppedGrab = poppedGrabs[0];
_navigateActor(poppedGrab.savedFocus, hadFocus);
},
_fullUngrab: function(wasModal) {
if (this._capturedEventId > 0) {
global.stage.disconnect(this._capturedEventId);
this._capturedEventId = 0;
}
if (this._eventId > 0) {
global.stage.disconnect(this._eventId);
this._eventId = 0;
}
if (this._keyFocusNotifyId > 0) {
global.stage.disconnect(this._keyFocusNotifyId);
this._keyFocusNotifyId = 0;
}
if (!this._focusWindowChanged > 0) {
let metaDisplay = global.screen.get_display();
metaDisplay.disconnect(this._focusWindowChangedId);
this._focusWindowChangedId = 0;
}
let prePopInputMode = global.stage_input_mode;
if (wasModal) {
Main.popModal(this._owner);
global.sync_pointer();
}
if (this._grabbedFromKeynav) {
if (this._preGrabInputMode == Shell.StageInputMode.FOCUSED &&
prePopInputMode != Shell.StageInputMode.FULLSCREEN)
global.set_stage_input_mode(Shell.StageInputMode.FOCUSED);
}
if (this._prevFocusedWindow) {
let metaDisplay = global.screen.get_display();
if (!metaDisplay.focus_window) {
metaDisplay.set_input_focus_window(this._prevFocusedWindow,
false, global.get_current_time());
}
}
},
_onCapturedEvent: function(actor, event) {
let type = event.type();
let press = type == Clutter.EventType.BUTTON_PRESS;
let release = type == Clutter.EventType.BUTTON_RELEASE;
let button = press || release;
if (release && this._ignoreRelease) {
this._ignoreRelease = false;
return false;
}
if (!button && this._modalCount == 0)
return false;
if (this._isWithinGrabbedActor(event.get_source()))
return false;
if (button) {
// If we have a press event, ignore the next event,
// which should be a release event.
if (press)
this._ignoreRelease = true;
this.ungrab();
}
return this._modalCount > 0;
},
// We catch 'event' rather than 'key-press-event' so that we get
// a chance to run before the overview's own Escape check
_onEvent: function(actor, event) {
if (event.type() == Clutter.EventType.KEY_PRESS &&
event.get_key_symbol() == Clutter.KEY_Escape) {
this.ungrab();
return true;
}
return false;
},
_onKeyFocusChanged: function() {
let focus = global.stage.key_focus;
if (!focus || !this._isWithinGrabbedActor(focus))
this.ungrab();
},
_focusWindowChanged: function() {
let metaDisplay = global.screen.get_display();
if (metaDisplay.focus_window != null)
this.ungrab();
}
});

View File

@@ -84,10 +84,7 @@ const KeyringDialog = new Lang.Class({
if (this.prompt.password_visible) {
let label = new St.Label(({ style_class: 'prompt-dialog-password-label' }));
label.set_text(_("Password:"));
table.add(label, { row: row, col: 0,
x_expand: false, x_fill: true,
x_align: St.Align.START,
y_fill: false, y_align: St.Align.MIDDLE });
table.add(label, { row: row, col: 0, x_expand: false, x_fill: true, x_align: St.Align.START });
this._passwordEntry = new St.Entry({ style_class: 'prompt-dialog-password-entry',
text: '',
can_focus: true});
@@ -103,10 +100,7 @@ const KeyringDialog = new Lang.Class({
if (this.prompt.confirm_visible) {
var label = new St.Label(({ style_class: 'prompt-dialog-password-label' }));
label.set_text(_("Type again:"));
table.add(label, { row: row, col: 0,
x_expand: false, x_fill: true,
x_align: St.Align.START,
y_fill: false, y_align: St.Align.MIDDLE });
table.add(label, { row: row, col: 0, x_expand: false, x_fill: true, x_align: St.Align.START });
this._confirmEntry = new St.Entry({ style_class: 'prompt-dialog-password-entry',
text: '',
can_focus: true});

View File

@@ -1,7 +1,6 @@
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
const Clutter = imports.gi.Clutter;
const GObject = imports.gi.GObject;
const Lang = imports.lang;
const Mainloop = imports.mainloop;
const Meta = imports.gi.Meta;
@@ -18,79 +17,6 @@ const HOT_CORNER_ACTIVATION_TIMEOUT = 0.5;
const STARTUP_ANIMATION_TIME = 0.2;
const KEYBOARD_ANIMATION_TIME = 0.5;
const MonitorConstraint = new Lang.Class({
Name: 'MonitorConstraint',
Extends: Clutter.Constraint,
Properties: {'primary': GObject.ParamSpec.boolean('primary',
'Primary', 'Track primary monitor',
GObject.ParamFlags.READABLE | GObject.ParamFlags.WRITABLE,
false),
'index': GObject.ParamSpec.int('index',
'Monitor index', 'Track specific monitor',
GObject.ParamFlags.READABLE | GObject.ParamFlags.WRITABLE,
-1, 64, -1)},
_init: function(props) {
this._primary = false;
this._index = -1;
this.parent(props);
},
get primary() {
return this._primary;
},
set primary(v) {
this._primary = v;
if (this.actor)
this.actor.queue_relayout();
this.notify('primary');
},
get index() {
return this._index;
},
set index(v) {
this._index = v;
if (this.actor)
this.actor.queue_relayout();
this.notify('index');
},
vfunc_set_actor: function(actor) {
if (actor) {
if (!this._monitorsChangedId) {
this._monitorsChangedId = Main.layoutManager.connect('monitors-changed', Lang.bind(this, function() {
this.actor.queue_relayout();
}));
}
} else {
if (this._monitorsChangedId)
Main.layoutManager.disconnect(this._monitorsChangedId);
this._monitorsChangedId = 0;
}
this.parent(actor);
},
vfunc_update_allocation: function(actor, actorBox) {
if (!this._primary && this._index < 0)
return;
let monitor;
if (this._primary) {
monitor = Main.layoutManager.primaryMonitor;
} else {
let index = Math.min(this._index, Main.layoutManager.monitors.length - 1);
monitor = Main.layoutManager.monitors[index];
}
actorBox.init_rect(monitor.x, monitor.y, monitor.width, monitor.height);
}
});
const LayoutManager = new Lang.Class({
Name: 'LayoutManager',
@@ -109,7 +35,6 @@ const LayoutManager = new Lang.Class({
this.screenShieldGroup = new St.Widget({ name: 'screenShieldGroup',
visible: false,
clip_to_allocation: true,
layout_manager: new Clutter.BinLayout(),
});
this.addChrome(this.screenShieldGroup);

View File

@@ -588,6 +588,12 @@ function _globalKeyPressHandler(actor, event) {
// This relies on the fact that Clutter.ModifierType is the same as Gdk.ModifierType
let action = global.display.get_keybinding_action(keyCode, modifierState);
// This isn't a Meta.KeyBindingAction yet
if (symbol == Clutter.Super_L || symbol == Clutter.Super_R) {
overview.hide();
return true;
}
if (action == Meta.KeyBindingAction.SWITCH_PANELS) {
ctrlAltTabManager.popup(modifierState & Clutter.ModifierType.SHIFT_MASK,
modifierState);
@@ -630,7 +636,6 @@ function _globalKeyPressHandler(actor, event) {
getRunDialog().open();
return true;
case Meta.KeyBindingAction.PANEL_MAIN_MENU:
case Meta.KeyBindingAction.OVERLAY_KEY:
overview.hide();
return true;
}

File diff suppressed because it is too large Load Diff

View File

@@ -14,7 +14,6 @@ const Atk = imports.gi.Atk;
const Params = imports.misc.params;
const Layout = imports.ui.layout;
const Lightbox = imports.ui.lightbox;
const Main = imports.ui.main;
const Tweener = imports.ui.tweener;
@@ -60,14 +59,12 @@ const ModalDialog = new Lang.Class({
this._group.connect('key-release-event', Lang.bind(this, this._onKeyReleaseEvent));
this._backgroundBin = new St.Bin();
this._monitorConstraint = new Layout.MonitorConstraint();
this._backgroundBin.add_constraint(this._monitorConstraint);
this._group.add_actor(this._backgroundBin);
this.dialogLayout = new St.BoxLayout({ style_class: 'modal-dialog',
vertical: true });
this._dialogLayout = new St.BoxLayout({ style_class: 'modal-dialog',
vertical: true });
if (params.styleClass != null) {
this.dialogLayout.add_style_class_name(params.styleClass);
this._dialogLayout.add_style_class_name(params.styleClass);
}
if (!this._shellReactive) {
@@ -80,29 +77,29 @@ const ModalDialog = new Lang.Class({
this._eventBlocker = new Clutter.Group({ reactive: true });
stack.add_actor(this._eventBlocker);
stack.add_actor(this.dialogLayout);
stack.add_actor(this._dialogLayout);
} else {
this._backgroundBin.child = this.dialogLayout;
this._backgroundBin.child = this._dialogLayout;
}
this.contentLayout = new St.BoxLayout({ vertical: true });
this.dialogLayout.add(this.contentLayout,
{ x_fill: true,
y_fill: true,
x_align: St.Align.MIDDLE,
y_align: St.Align.START });
this._dialogLayout.add(this.contentLayout,
{ x_fill: true,
y_fill: true,
x_align: St.Align.MIDDLE,
y_align: St.Align.START });
this._buttonLayout = new St.BoxLayout({ style_class: 'modal-dialog-button-box',
visible: false,
vertical: false });
this.dialogLayout.add(this._buttonLayout,
{ expand: true,
x_align: St.Align.MIDDLE,
y_align: St.Align.END });
this._dialogLayout.add(this._buttonLayout,
{ expand: true,
x_align: St.Align.MIDDLE,
y_align: St.Align.END });
global.focus_manager.add_group(this.dialogLayout);
this._initialKeyFocus = this.dialogLayout;
global.focus_manager.add_group(this._dialogLayout);
this._initialKeyFocus = this._dialogLayout;
this._initialKeyFocusDestroyId = 0;
this._savedKeyFocus = null;
},
@@ -199,11 +196,14 @@ const ModalDialog = new Lang.Class({
},
_fadeOpen: function() {
this._monitorConstraint.index = global.screen.get_current_monitor();
let monitor = Main.layoutManager.currentMonitor;
this._backgroundBin.set_position(monitor.x, monitor.y);
this._backgroundBin.set_size(monitor.width, monitor.height);
this.state = State.OPENING;
this.dialogLayout.opacity = 255;
this._dialogLayout.opacity = 255;
if (this._lightbox)
this._lightbox.show();
this._group.opacity = 0;
@@ -227,7 +227,7 @@ const ModalDialog = new Lang.Class({
this._initialKeyFocus = actor;
this._initialKeyFocusDestroyId = actor.connect('destroy', Lang.bind(this, function() {
this._initialKeyFocus = this.dialogLayout;
this._initialKeyFocus = this._dialogLayout;
this._initialKeyFocusDestroyId = 0;
}));
},
@@ -320,7 +320,7 @@ const ModalDialog = new Lang.Class({
return;
this.popModal(timestamp);
Tweener.addTween(this.dialogLayout,
Tweener.addTween(this._dialogLayout,
{ opacity: 0,
time: FADE_OUT_DIALOG_TIME,
transition: 'easeOutQuad',

View File

@@ -357,7 +357,7 @@ const NotificationDaemon = new Lang.Class({
let gicon = this._iconForNotificationData(icon, hints);
let iconActor = new St.Icon({ gicon: gicon,
icon_type: St.IconType.FULLCOLOR,
icon_size: MessageTray.NOTIFICATION_ICON_SIZE });
icon_size: source.ICON_SIZE });
if (notification == null) {
notification = new MessageTray.Notification(source, summary, body,
@@ -630,16 +630,6 @@ const Source = new Lang.Class({
}
},
setTitle: function(title) {
// Do nothing if .app is set, we don't want to override the
// app name with whatever is provided through libnotify (usually
// garbage)
if (this.app)
return;
this.parent(title);
},
open: function(notification) {
this.destroyNonResidentNotifications();
this.openApp();

View File

@@ -10,14 +10,19 @@ const St = imports.gi.St;
const Shell = imports.gi.Shell;
const Gdk = imports.gi.Gdk;
const AppDisplay = imports.ui.appDisplay;
const Dash = imports.ui.dash;
const DND = imports.ui.dnd;
const Main = imports.ui.main;
const MessageTray = imports.ui.messageTray;
const Panel = imports.ui.panel;
const Params = imports.misc.params;
const PlaceDisplay = imports.ui.placeDisplay;
const RemoteSearch = imports.ui.remoteSearch;
const Tweener = imports.ui.tweener;
const ViewSelector = imports.ui.viewSelector;
const Wanda = imports.ui.wanda;
const WorkspacesView = imports.ui.workspacesView;
const WorkspaceThumbnail = imports.ui.workspaceThumbnail;
// Time for initial animation going into Overview mode
@@ -139,6 +144,8 @@ const Overview = new Lang.Class({
this._capturedEventId = 0;
this._buttonPressId = 0;
this._workspacesDisplay = null;
this.visible = false; // animating to overview, in overview, animating out
this._shown = false; // show() and not hide()
this._shownTemporarily = false; // showTemporarily() and not hideTemporarily()
@@ -185,23 +192,29 @@ const Overview = new Lang.Class({
this._shellInfo = new ShellInfo();
this._searchEntry = new St.Entry({ name: 'searchEntry',
/* Translators: this is the text displayed
in the search entry when no search is
active; it should not exceed ~30
characters. */
hint_text: _("Type to search..."),
track_hover: true,
can_focus: true });
this._group.add_actor(this._searchEntry);
this._dash = new Dash.Dash();
this._viewSelector = new ViewSelector.ViewSelector(this._searchEntry,
this._dash.showAppsButton);
this._viewSelector = new ViewSelector.ViewSelector();
this._group.add_actor(this._viewSelector.actor);
this._group.add_actor(this._dash.actor);
this._workspacesDisplay = new WorkspacesView.WorkspacesDisplay();
this._viewSelector.addViewTab('windows', _("Windows"), this._workspacesDisplay.actor, 'text-x-generic');
let appView = new AppDisplay.AllAppDisplay();
this._viewSelector.addViewTab('applications', _("Applications"), appView.actor, 'system-run');
// Default search providers
// Wanda comes obviously first
this.addSearchProvider(new Wanda.WandaSearchProvider());
this.addSearchProvider(new AppDisplay.AppSearchProvider());
this.addSearchProvider(new AppDisplay.SettingsSearchProvider());
this.addSearchProvider(new PlaceDisplay.PlaceSearchProvider());
// Load remote search providers provided by applications
RemoteSearch.loadRemoteSearchProviders(Lang.bind(this, this.addSearchProvider));
// TODO - recalculate everything when desktop size changes
this._dash = new Dash.Dash();
this._group.add_actor(this._dash.actor);
this._dash.actor.add_constraint(this._viewSelector.constrainY);
this._dash.actor.add_constraint(this._viewSelector.constrainHeight);
this.dashIconSize = this._dash.iconSize;
this._dash.connect('icon-size-changed',
@@ -487,13 +500,13 @@ const Overview = new Lang.Class({
this._coverPane.set_position(0, contentY);
this._coverPane.set_size(primary.width, contentHeight);
let searchWidth = this._searchEntry.get_width();
let searchHeight = this._searchEntry.get_height();
let searchX = (primary.width - searchWidth) / 2;
let searchY = contentY + this._spacing;
let dashWidth = Math.round(DASH_SPLIT_FRACTION * primary.width);
let dashY = searchY + searchHeight + this._spacing;
let viewWidth = primary.width - dashWidth - this._spacing;
let viewHeight = contentHeight - 2 * this._spacing;
let viewY = contentY + this._spacing;
let viewX = rtl ? 0 : dashWidth + this._spacing;
// Set the dash's x position - y is handled by a constraint
let dashX;
if (rtl) {
this._dash.actor.set_anchor_point_from_gravity(Clutter.Gravity.NORTH_EAST);
@@ -501,14 +514,8 @@ const Overview = new Lang.Class({
} else {
dashX = 0;
}
this._dash.actor.set_x(dashX);
let viewX = rtl ? 0 : dashWidth + this._spacing;
let viewY = searchY + searchHeight + this._spacing;
let viewWidth = primary.width - dashWidth - this._spacing;
let viewHeight = contentHeight - this._spacing - viewY;
this._searchEntry.set_position(searchX, searchY);
this._dash.actor.set_position(dashX, dashY);
this._viewSelector.actor.set_position(viewX, viewY);
this._viewSelector.actor.set_size(viewWidth, viewHeight);
},
@@ -558,28 +565,6 @@ const Overview = new Lang.Class({
Lang.bind(this, this._onButtonPress));
},
fadeInDesktop: function() {
this._desktopFade.opacity = 0;
this._desktopFade.show();
Tweener.addTween(this._desktopFade,
{ opacity: 255,
time: ANIMATION_TIME,
transition: 'easeOutQuad' });
},
fadeOutDesktop: function() {
if (!this._desktopFade.child)
this._desktopFade.child = this._getDesktopClone();
this._desktopFade.opacity = 255;
this._desktopFade.show();
Tweener.addTween(this._desktopFade,
{ opacity: 0,
time: ANIMATION_TIME,
transition: 'easeOutQuad'
});
},
_animateVisible: function() {
if (this.visible || this.animationInProgress)
return;
@@ -600,7 +585,21 @@ const Overview = new Lang.Class({
global.window_group.hide();
this._group.show();
this._background.show();
this._viewSelector.show();
this._workspacesDisplay.show();
if (!this._desktopFade.child)
this._desktopFade.child = this._getDesktopClone();
if (!this._workspacesDisplay.activeWorkspaceHasMaximizedWindows()) {
this._desktopFade.opacity = 255;
this._desktopFade.show();
Tweener.addTween(this._desktopFade,
{ opacity: 0,
time: ANIMATION_TIME,
transition: 'easeOutQuad'
});
}
this._group.opacity = 0;
Tweener.addTween(this._group,
@@ -727,7 +726,16 @@ const Overview = new Lang.Class({
this.animationInProgress = true;
this._hideInProgress = true;
this._viewSelector.zoomFromOverview();
if (!this._workspacesDisplay.activeWorkspaceHasMaximizedWindows()) {
this._desktopFade.opacity = 0;
this._desktopFade.show();
Tweener.addTween(this._desktopFade,
{ opacity: 255,
time: ANIMATION_TIME,
transition: 'easeOutQuad' });
}
this._workspacesDisplay.zoomFromOverview();
// Make other elements fade out.
Tweener.addTween(this._group,
@@ -769,7 +777,8 @@ const Overview = new Lang.Class({
global.window_group.show();
this._viewSelector.hide();
this._workspacesDisplay.hide();
this._desktopFade.hide();
this._background.hide();
this._group.hide();

View File

@@ -182,7 +182,8 @@ const Button = new Lang.Class({
_onMenuKeyPress: function(actor, event) {
let symbol = event.get_key_symbol();
if (symbol == Clutter.KEY_Left || symbol == Clutter.KEY_Right) {
let group = global.focus_manager.get_group(this.actor);
let focusManager = St.FocusManager.get_for_stage(global.stage);
let group = focusManager.get_group(this.actor);
if (group) {
let direction = (symbol == Clutter.KEY_Left) ? Gtk.DirectionType.LEFT : Gtk.DirectionType.RIGHT;
group.navigate_focus(this.actor, direction, false);

View File

@@ -1,126 +0,0 @@
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
const Lang = imports.lang;
const Mainloop = imports.mainloop;
const Shell = imports.gi.Shell;
// We stop polling if the user is idle for more than this amount of time
const IDLE_TIME = 1000;
// This file implements a reasonably efficient system for tracking the position
// of the mouse pointer. We simply query the pointer from the X server in a loop,
// but we turn off the polling when the user is idle.
let _pointerWatcher = null;
function getPointerWatcher() {
if (_pointerWatcher == null)
_pointerWatcher = new PointerWatcher();
return _pointerWatcher;
}
const PointerWatch = new Lang.Class({
Name: 'PointerWatch',
_init: function(watcher, interval, callback) {
this.watcher = watcher;
this.interval = interval;
this.callback = callback;
},
// remove:
// remove this watch. This function may safely be called
// while the callback is executing.
remove: function() {
this.watcher._removeWatch(this);
}
});
const PointerWatcher = new Lang.Class({
Name: 'PointerWatcher',
_init: function() {
let idleMonitor = Shell.IdleMonitor.get();
idleMonitor.add_watch(IDLE_TIME,
Lang.bind(this, this._onIdleMonitorWatch));
this._idle = idleMonitor.get_idletime() > IDLE_TIME;
this._watches = [];
this.pointerX = null;
this.pointerY = null;
},
// addWatch:
// @interval: hint as to the time resolution needed. When the user is
// not idle, the position of the pointer will be queried at least
// once every this many milliseconds.
// @callback: function to call when the pointer position changes - takes
// two arguments, X and Y.
//
// Set up a watch on the position of the mouse pointer. Returns a
// PointerWatch object which has a remove() method to remove the watch.
addWatch: function(interval, callback) {
// Avoid unreliably calling the watch for the current position
this._updatePointer();
let watch = new PointerWatch(this, interval, callback);
this._watches.push(watch);
this._updateTimeout();
return watch;
},
_removeWatch: function(watch) {
for (let i = 0; i < this._watches.length; i++) {
if (this._watches[i] == watch) {
this._watches.splice(i, 1);
this._updateTimeout();
return;
}
}
},
_onIdleMonitorWatch: function(monitor, id, userBecameIdle) {
this._idle = userBecameIdle;
if (!userBecameIdle)
this._updatePointer();
this._updateTimeout();
},
_updateTimeout: function() {
if (this._timeoutId) {
Mainloop.source_remove(this._timeoutId);
this._timeoutId = 0;
}
if (this._idle || this._watches.length == 0)
return;
let minInterval = this._watches[0].interval;
for (let i = 1; i < this._watches.length; i++)
minInterval = Math.min(this._watches[i].interval, minInterval);
this._timeoutId = Mainloop.timeout_add(minInterval,
Lang.bind(this, this._onTimeout));
},
_onTimeout: function() {
this._updatePointer();
return true;
},
_updatePointer: function() {
let [x, y, mods] = global.get_pointer();
if (this.pointerX == x && this.pointerY == y)
return;
this.pointerX = x;
this.pointerY = y;
for (let i = 0; i < this._watches.length;) {
let watch = this._watches[i];
watch.callback(x, y);
if (watch == this._watches[i]) // guard against self-removal
i++;
}
}
});

View File

@@ -37,13 +37,12 @@ const PopupBaseMenuItem = new Lang.Class({
activate: true,
hover: true,
sensitive: true,
style_class: null,
can_focus: true
style_class: null
});
this.actor = new Shell.GenericContainer({ style_class: 'popup-menu-item',
reactive: params.reactive,
track_hover: params.reactive,
can_focus: params.can_focus,
can_focus: params.reactive,
accessible_role: Atk.Role.MENU_ITEM});
this.actor.connect('get-preferred-width', Lang.bind(this, this._getPreferredWidth));
this.actor.connect('get-preferred-height', Lang.bind(this, this._getPreferredHeight));
@@ -70,9 +69,10 @@ const PopupBaseMenuItem = new Lang.Class({
}
if (params.reactive && params.hover)
this.actor.connect('notify::hover', Lang.bind(this, this._onHoverChanged));
this.actor.connect('key-focus-in', Lang.bind(this, this._onKeyFocusIn));
this.actor.connect('key-focus-out', Lang.bind(this, this._onKeyFocusOut));
if (params.reactive) {
this.actor.connect('key-focus-in', Lang.bind(this, this._onKeyFocusIn));
this.actor.connect('key-focus-out', Lang.bind(this, this._onKeyFocusOut));
}
},
_onStyleChanged: function (actor) {
@@ -179,14 +179,12 @@ const PopupBaseMenuItem = new Lang.Class({
this._dot = new St.DrawingArea({ style_class: 'popup-menu-item-dot' });
this._dot.connect('repaint', Lang.bind(this, this._onRepaintDot));
this.actor.add_actor(this._dot);
this.actor.add_accessible_state (Atk.StateType.CHECKED);
} else {
if (!this._dot)
return;
this._dot.destroy();
this._dot = null;
this.actor.remove_accessible_state (Atk.StateType.CHECKED);
}
},
@@ -397,8 +395,7 @@ const PopupSeparatorMenuItem = new Lang.Class({
Extends: PopupBaseMenuItem,
_init: function () {
this.parent({ reactive: false,
can_focus: false});
this.parent({ reactive: false });
this._drawingArea = new St.DrawingArea({ style_class: 'popup-separator-menu-item' });
this.addActor(this._drawingArea, { span: -1, expand: true });
@@ -865,6 +862,10 @@ const PopupMenuBase = new Lang.Class({
// for the menu which causes its prelight state to freeze
this.blockSourceEvents = false;
// Can be set while a menu is up to let all events through without special
// menu handling useful for scrollbars in menus, and probably not otherwise.
this.passEvents = false;
this._activeMenuItem = null;
this._childMenus = [];
this._settingsActions = { };
@@ -1283,6 +1284,24 @@ const PopupSubMenu = new Lang.Class({
hscrollbar_policy: Gtk.PolicyType.NEVER,
vscrollbar_policy: Gtk.PolicyType.NEVER });
// StScrollbar plays dirty tricks with events, calling
// clutter_set_motion_events_enabled (FALSE) during the scroll; this
// confuses our event tracking, so we just turn it off during the
// scroll.
let vscroll = this.actor.get_vscroll_bar();
vscroll.connect('scroll-start',
Lang.bind(this, function() {
let topMenu = this._getTopMenu();
if (topMenu)
topMenu.passEvents = true;
}));
vscroll.connect('scroll-stop',
Lang.bind(this, function() {
let topMenu = this._getTopMenu();
if (topMenu)
topMenu.passEvents = false;
}));
this.actor.add_actor(this.box);
this.actor._delegate = this;
this.actor.clip_to_allocation = true;
@@ -2259,6 +2278,9 @@ const PopupMenuManager = new Lang.Class({
this._owner.menuEventFilter(event))
return true;
if (this._activeMenu != null && this._activeMenu.passEvents)
return false;
if (this._didPop) {
this._didPop = false;
return true;

View File

@@ -2,7 +2,6 @@
const Clutter = imports.gi.Clutter;
const Gio = imports.gi.Gio;
const GLib = imports.gi.GLib;
const GnomeDesktop = imports.gi.GnomeDesktop;
const Lang = imports.lang;
const Meta = imports.gi.Meta;
@@ -10,8 +9,6 @@ const Signals = imports.signals;
const St = imports.gi.St;
const GnomeSession = imports.misc.gnomeSession;
const Layout = imports.ui.layout;
const LoginManager = imports.misc.loginManager;
const Lightbox = imports.ui.lightbox;
const Main = imports.ui.main;
const MessageTray = imports.ui.messageTray;
@@ -20,7 +17,7 @@ const Tweener = imports.ui.tweener;
const SCREENSAVER_SCHEMA = 'org.gnome.desktop.screensaver';
const LOCK_ENABLED_KEY = 'lock-enabled';
const CURTAIN_SLIDE_TIME = 0.5;
const CURTAIN_SLIDE_TIME = 0.8;
// fraction of screen height the arrow must reach before completing
// the slide up automatically
const ARROW_DRAG_TRESHOLD = 0.1;
@@ -80,8 +77,8 @@ const NotificationsBox = new Lang.Class({
_init: function() {
this.actor = new St.BoxLayout({ vertical: true,
name: 'screenShieldNotifications',
style_class: 'screen-shield-notifications-box' });
name: 'screenShieldNotifications',
style_class: 'screen-shield-notifications-box' });
this._residentNotificationBox = new St.BoxLayout({ vertical: true,
style_class: 'screen-shield-notifications-box' });
@@ -95,9 +92,8 @@ const NotificationsBox = new Lang.Class({
this._items = [];
Main.messageTray.getSummaryItems().forEach(Lang.bind(this, function(item) {
this._summaryItemAdded(Main.messageTray, item, true);
this._summaryItemAdded(Main.messageTray, item);
}));
this._updateVisibility();
this._summaryAddedId = Main.messageTray.connect('summary-item-added', Lang.bind(this, this._summaryItemAdded));
},
@@ -121,7 +117,7 @@ const NotificationsBox = new Lang.Class({
return;
}
let children = this._persistentNotificationBox.get_children();
let children = this._persistentNotificationBox.get_children()
this.actor.visible = children.some(function(a) { return a.visible; });
},
@@ -129,11 +125,11 @@ const NotificationsBox = new Lang.Class({
return source.hasResidentNotification() && !source.isChat;
},
_makeNotificationCountText: function(count, isChat) {
if (isChat)
return ngettext("%d new message", "%d new messages", count).format(count);
_makeNotificationCountText: function(source) {
if (source.isChat)
return ngettext("%d new message", "%d new messages", source.count).format(source.count);
else
return ngettext("%d new notification", "%d new notifications", count).format(count);
return ngettext("%d new notification", "%d new notifications", source.count).format(source.count);
},
_makeNotificationSource: function(source) {
@@ -149,16 +145,15 @@ const NotificationsBox = new Lang.Class({
style_class: 'screen-shield-notification-label' });
textBox.add(label);
let count = source.unseenCount;
let countLabel = new St.Label({ text: this._makeNotificationCountText(count, source.isChat),
let countLabel = new St.Label({ text: this._makeNotificationCountText(source),
style_class: 'screen-shield-notification-count-text' });
textBox.add(countLabel);
box.visible = count != 0;
box.visible = source.count != 0;
return [box, countLabel];
},
_summaryItemAdded: function(tray, item, dontUpdateVisibility) {
_summaryItemAdded: function(tray, item) {
// Ignore transient sources
if (item.source.isTransient)
return;
@@ -182,13 +177,12 @@ const NotificationsBox = new Lang.Class({
}
obj.contentUpdatedId = item.connect('content-updated', Lang.bind(this, this._onItemContentUpdated));
obj.sourceCountChangedId = item.source.connect('count-updated', Lang.bind(this, this._onSourceChanged));
obj.sourceCountChangedId = item.source.connect('count-changed', Lang.bind(this, this._onSourceChanged));
obj.sourceTitleChangedId = item.source.connect('title-changed', Lang.bind(this, this._onSourceChanged));
obj.sourceDestroyId = item.source.connect('destroy', Lang.bind(this, this._onSourceDestroy));
this._items.push(obj);
if (!dontUpdateVisibility)
this._updateVisibility();
this._updateVisibility();
},
_findSource: function(source) {
@@ -228,15 +222,13 @@ const NotificationsBox = new Lang.Class({
// make into a resident item
obj.sourceBox.destroy();
obj.sourceBox = obj.countLabel = null;
obj.resident = true;
obj.item.prepareNotificationStackForShowing();
this._residentNotificationBox.add(obj.item.notificationStackView);
} else {
// just update the counter
let count = obj.source.unseenCount;
obj.countLabel.text = this._makeNotificationCountText(count, obj.source.isChat);
obj.sourceBox.visible = count != 0;
obj.countLabel.text = this._makeNotificationCountText(obj.item.source);
obj.sourceBox.visible = obj.source.count != 0;
}
this._updateVisibility();
@@ -285,20 +277,14 @@ const ScreenShield = new Lang.Class({
y_expand: true,
reactive: true,
can_focus: true,
name: 'lockScreenGroup',
layout_manager: new Clutter.BinLayout()
});
this._lockScreenGroup.connect('key-release-event',
Lang.bind(this, this._onLockScreenKeyRelease));
this._lockScreenContents = new St.Widget({ layout_manager: new Clutter.BinLayout(),
name: 'lockScreenContents' });
this._lockScreenContents.add_constraint(new Layout.MonitorConstraint({ primary: true }));
this._background = Meta.BackgroundActor.new_for_screen(global.screen);
this._lockScreenGroup.add_actor(this._background);
this._lockScreenGroup.add_actor(this._lockScreenContents);
this._background.add_effect(new Clutter.BlurEffect());
this._background.add_effect(new Clutter.DesaturateEffect({ factor: 0.6 }));
// FIXME: build the rest of the lock screen here
this._lockScreenGroup.add_actor(this._background);
this._arrow = new St.DrawingArea({ style_class: 'arrow',
reactive: true,
@@ -310,20 +296,15 @@ const ScreenShield = new Lang.Class({
y_expand: true
});
this._arrow.connect('repaint', Lang.bind(this, this._drawArrow));
this._lockScreenContents.add_actor(this._arrow);
this._lockScreenGroup.add_actor(this._arrow);
let dragArea = new Clutter.Rect({ origin: new Clutter.Point({ x: 0, y: -global.screen_height, }),
size: new Clutter.Size({ width: global.screen_width,
height: global.screen_height }) });
let action = new Clutter.DragAction({ drag_axis: Clutter.DragAxis.Y_AXIS,
drag_area: dragArea });
let action = new Clutter.DragAction({ drag_axis: Clutter.DragAxis.Y_AXIS });
action.connect('drag-begin', Lang.bind(this, this._onDragBegin));
action.connect('drag-end', Lang.bind(this, this._onDragEnd));
this._lockScreenGroup.add_action(action);
this._lockDialogGroup = new St.Widget({ x_expand: true,
y_expand: true,
name: 'lockDialogGroup' });
y_expand: true });
this.actor.add_actor(this._lockDialogGroup);
this.actor.add_actor(this._lockScreenGroup);
@@ -340,11 +321,6 @@ const ScreenShield = new Lang.Class({
this._onStatusChanged(status);
}));
this._loginManager = LoginManager.getLoginManager();
this._loginSession = this._loginManager.getCurrentSessionProxy();
this._loginSession.connectSignal('Lock', Lang.bind(this, function() { this.lock(false); }));
this._loginSession.connectSignal('Unlock', Lang.bind(this, function() { this.unlock(); }));
this._settings = new Gio.Settings({ schema: SCREENSAVER_SCHEMA });
this._isModal = false;
@@ -357,18 +333,16 @@ const ScreenShield = new Lang.Class({
fadeFactor: 1 });
},
_onLockScreenKeyRelease: function(actor, event) {
_onStageKeyRelease: function(actor, event) {
if (!this._isLocked)
return false;
if (event.get_key_symbol() == Clutter.KEY_Escape) {
this._ensureUnlockDialog();
this._hideLockScreen(true);
this._showUnlockDialog(true);
return true;
}
// If the dialog is created, but hasn't received focus yet,
// the lock screen could be still focused, so bumping would
// make the curtain fall again.
if (!this._dialog)
this._bumpLockScreen();
this._bumpLockScreen();
return true;
},
@@ -387,13 +361,12 @@ const ScreenShield = new Lang.Class({
_onDragBegin: function() {
Tweener.removeTweens(this._lockScreenGroup);
this._ensureUnlockDialog();
},
_onDragEnd: function(action, actor, eventX, eventY, modifiers) {
if (this._lockScreenGroup.y < -(ARROW_DRAG_TRESHOLD * global.stage.height)) {
// Complete motion automatically
this._hideLockScreen(true);
this._showUnlockDialog(true);
} else {
// restore the lock screen to its original place
// try to use the same speed as the normal animation
@@ -408,14 +381,6 @@ const ScreenShield = new Lang.Class({
this.fixed_position_set = false;
}
});
// If we have a unlock dialog, cancel it
if (this._dialog) {
this._dialog.cancel();
if (!this._keepDialog) {
this._dialog = null;
}
}
}
},
@@ -450,8 +415,7 @@ const ScreenShield = new Lang.Class({
showDialog: function() {
this.lock(true);
this._ensureUnlockDialog();
this._hideLockScreen(false);
this._showUnlockDialog(false);
},
_bumpLockScreen: function() {
@@ -469,7 +433,7 @@ const ScreenShield = new Lang.Class({
});
},
_hideLockScreen: function(animate) {
_showUnlockDialog: function(animate) {
if (animate) {
// Tween the lock screen out of screen
// try to use the same speed regardless of original position
@@ -480,14 +444,12 @@ const ScreenShield = new Lang.Class({
{ y: -h,
time: time,
transition: 'linear',
onComplete: function() { this.hide(); }
onComplete: Lang.bind(this, this._hideLockScreen),
});
} else {
this._lockScreenGroup.hide();
this._hideLockScreen();
}
},
_ensureUnlockDialog: function() {
if (!this._dialog) {
[this._dialog, this._keepDialog] = Main.sessionMode.createUnlockDialog(this._lockDialogGroup);
if (!this._dialog) {
@@ -528,8 +490,14 @@ const ScreenShield = new Lang.Class({
this.unlock();
},
_hideLockScreen: function() {
this._arrow.hide();
this._lockScreenGroup.hide();
},
_resetLockScreen: function(animate) {
this._lockScreenGroup.show();
this._arrow.show();
if (animate) {
this._lockScreenGroup.y = -global.screen_height;
@@ -544,20 +512,14 @@ const ScreenShield = new Lang.Class({
},
onCompleteScope: this
});
this._lockDialogGroup.opacity = 0;
Tweener.removeTweens(this._lockDialogGroup);
Tweener.addTween(this._lockDialogGroup,
{ opacity: 255,
time: SHORT_FADE_TIME,
transition: 'easeOutQuad' });
} else {
this._lockScreenGroup.fixed_position_set = false;
this._lockDialogGroup.opacity = 255;
this.emit('lock-screen-shown');
}
this._lockScreenGroup.grab_key_focus();
if (!this._stageKeyHandler)
this._stageKeyHandler = global.stage.connect('key-release-event',
Lang.bind(this, this._onStageKeyRelease));
},
// Some of the actors in the lock screen are heavy in
@@ -572,7 +534,7 @@ const ScreenShield = new Lang.Class({
this._lockScreenContentsBox.add(this._clock.actor, { x_fill: true,
y_fill: true });
this._lockScreenContents.add_actor(this._lockScreenContentsBox);
this._lockScreenGroup.add_actor(this._lockScreenContentsBox);
if (this._settings.get_boolean('show-notifications')) {
this._notificationsBox = new NotificationsBox();
@@ -606,11 +568,16 @@ const ScreenShield = new Lang.Class({
if (this._hasLockScreen)
this._clearLockScreen();
if (this._stageKeyHandler) {
global.stage.disconnect(this._stageKeyHandler);
this._stageKeyHandler = 0;
}
if (this._keepDialog) {
// The dialog must be kept alive,
// so immediately go back to it
// This will also reset _isLocked
this._ensureUnlockDialog();
this._showUnlockDialog(false);
return;
}
@@ -621,14 +588,12 @@ const ScreenShield = new Lang.Class({
this._lightbox.hide();
if (this._isModal) {
Main.popModal(this.actor);
this._isModal = false;
}
this._isLocked = false;
Main.popModal(this.actor);
this.actor.hide();
this._isModal = false;
this._isLocked = false;
this.emit('lock-status-changed', false);
},

View File

@@ -10,6 +10,8 @@ const Util = imports.misc.util;
const FileUtils = imports.misc.fileUtils;
const Main = imports.ui.main;
const DISABLED_OPEN_SEARCH_PROVIDERS_KEY = 'disabled-open-search-providers';
// Not currently referenced by the search API, but
// this enumeration can be useful for provider
// implementations.
@@ -167,6 +169,99 @@ const SearchProvider = new Lang.Class({
});
Signals.addSignalMethods(SearchProvider.prototype);
const OpenSearchSystem = new Lang.Class({
Name: 'OpenSearchSystem',
_init: function() {
this._providers = [];
global.settings.connect('changed::' + DISABLED_OPEN_SEARCH_PROVIDERS_KEY, Lang.bind(this, this._refresh));
this._refresh();
},
getProviders: function() {
let res = [];
for (let i = 0; i < this._providers.length; i++)
res.push({ id: i, name: this._providers[i].name });
return res;
},
setSearchTerms: function(terms) {
this._terms = terms;
},
_checkSupportedProviderLanguage: function(provider) {
if (provider.url.search(/{language}/) == -1)
return true;
let langs = GLib.get_language_names();
langs.push('en');
let lang = null;
for (let i = 0; i < langs.length; i++) {
for (let k = 0; k < provider.langs.length; k++) {
if (langs[i] == provider.langs[k])
lang = langs[i];
}
if (lang)
break;
}
provider.lang = lang;
return lang != null;
},
activateResult: function(id, params) {
let searchTerms = this._terms.join(' ');
let url = this._providers[id].url.replace('{searchTerms}', encodeURIComponent(searchTerms));
if (url.match('{language}'))
url = url.replace('{language}', this._providers[id].lang);
try {
Gio.app_info_launch_default_for_uri(url, global.create_app_launch_context());
} catch (e) {
// TODO: remove this after glib will be removed from moduleset
// In the default jhbuild, gio is in our prefix but gvfs is not
Util.spawn(['gvfs-open', url])
}
Main.overview.hide();
},
_addProvider: function(fileName) {
let path = global.datadir + '/open-search-providers/' + fileName;
let source = Shell.get_file_contents_utf8_sync(path);
let [success, name, url, langs, icon_uri] = Shell.parse_search_provider(source);
let provider ={ name: name,
url: url,
id: this._providers.length,
icon_uri: icon_uri,
langs: langs };
if (this._checkSupportedProviderLanguage(provider)) {
this._providers.push(provider);
this.emit('changed');
}
},
_refresh: function() {
this._providers = [];
let names = global.settings.get_strv(DISABLED_OPEN_SEARCH_PROVIDERS_KEY);
let file = Gio.file_new_for_path(global.datadir + '/open-search-providers');
FileUtils.listDirAsync(file, Lang.bind(this, function(files) {
for (let i = 0; i < files.length; i++) {
let enabled = true;
let name = files[i].get_name();
for (let k = 0; k < names.length; k++)
if (names[k] == name)
enabled = false;
if (enabled)
this._addProvider(name);
}
}));
}
});
Signals.addSignalMethods(OpenSearchSystem.prototype);
const SearchSystem = new Lang.Class({
Name: 'SearchSystem',

View File

@@ -173,9 +173,10 @@ const GridSearchResults = new Lang.Class({
const SearchResults = new Lang.Class({
Name: 'SearchResults',
_init: function(searchSystem) {
_init: function(searchSystem, openSearchSystem) {
this._searchSystem = searchSystem;
this._searchSystem.connect('search-updated', Lang.bind(this, this._updateResults));
this._openSearchSystem = openSearchSystem;
this.actor = new St.BoxLayout({ name: 'searchResults',
vertical: true });
@@ -214,10 +215,55 @@ const SearchResults = new Lang.Class({
this._searchProvidersBox = new St.BoxLayout({ style_class: 'search-providers-box' });
this.actor.add(this._searchProvidersBox);
this._openSearchProviders = [];
this._openSearchSystem.connect('changed', Lang.bind(this, this._updateOpenSearchProviderButtons));
this._updateOpenSearchProviderButtons();
this._highlightDefault = false;
this._defaultResult = null;
},
_updateOpenSearchProviderButtons: function() {
for (let i = 0; i < this._openSearchProviders.length; i++)
this._openSearchProviders[i].actor.destroy();
this._openSearchProviders = this._openSearchSystem.getProviders();
for (let i = 0; i < this._openSearchProviders.length; i++)
this._createOpenSearchProviderButton(this._openSearchProviders[i]);
},
_createOpenSearchProviderButton: function(provider) {
let button = new St.Button({ style_class: 'dash-search-button',
reactive: true,
can_focus: true,
x_fill: true,
y_align: St.Align.MIDDLE });
let bin = new St.Bin({ x_fill: false,
x_align:St.Align.MIDDLE });
button.connect('clicked', Lang.bind(this, function() {
this._openSearchSystem.activateResult(provider.id);
}));
let title = new St.Label({ text: provider.name,
style_class: 'dash-search-button-label' });
button.label_actor = title;
bin.set_child(title);
button.set_child(bin);
provider.actor = button;
button.setSelected = function(selected) {
if (selected)
button.add_style_pseudo_class('selected');
else
button.remove_style_pseudo_class('selected');
};
button.activate = Lang.bind(this, function() {
this._openSearchSystem.activateResult(provider.id);
});
button.actor = button;
this._searchProvidersBox.add(button);
},
createProviderMeta: function(provider) {
let providerBox = new St.BoxLayout({ style_class: 'search-section',
vertical: true });
@@ -277,6 +323,8 @@ const SearchResults = new Lang.Class({
doSearch: function (searchString) {
this._searchSystem.updateSearch(searchString);
let terms = this._searchSystem.getTerms();
this._openSearchSystem.setSearchTerms(terms);
},
_metaForProvider: function(provider) {

View File

@@ -76,7 +76,7 @@ const ATIndicator = new Lang.Class({
},
setLockedState: function(locked) {
this.actor.visible = !locked;
this.menu.setSettingsVisibility(!locked);
},
_buildItemExtended: function(string, initial_value, writable, on_set) {

View File

@@ -178,9 +178,7 @@ const InputSourceIndicator = new Lang.Class({
},
setLockedState: function(locked) {
if (Main.sessionMode.allowSettings) {
this._showLayoutItem.actor.visible = !locked;
}
this._showLayoutItem.actor.visible = !locked;
this.menu.setSettingsVisibility(!locked);
},

View File

@@ -1832,7 +1832,8 @@ const NMApplet = new Lang.Class({
devices.push(wrapper);
this._syncSectionTitle(wrapper.category);
}
} else
log('Invalid network device type, is ' + device.get_device_type());
},
_deviceRemoved: function(client, device) {
@@ -1851,32 +1852,9 @@ const NMApplet = new Lang.Class({
this._syncSectionTitle(wrapper.category)
},
_getSupportedActiveConnections: function() {
let activeConnections = this._client.get_active_connections() || [ ];
let supportedConnections = [];
for (let i = 0; i < activeConnections.length; i++) {
let devices = activeConnections[i].get_devices();
if (!devices || !devices[0])
continue;
// Ignore connections via unrecognized device types
if (!this._dtypes[devices[0].device_type])
continue;
// Ignore slave connections
let connectionPath = activeConnections[i].connection;
let connection = this._settings.get_connection_by_path(connectionPath)
if (this._ignoreConnection(connection))
continue;
supportedConnections.push(activeConnections[i]);
}
return supportedConnections;
},
_syncActiveConnections: function() {
let closedConnections = [ ];
let newActiveConnections = this._getSupportedActiveConnections();
let newActiveConnections = this._client.get_active_connections() || [ ];
for (let i = 0; i < this._activeConnections.length; i++) {
let a = this._activeConnections[i];
if (newActiveConnections.indexOf(a) == -1) // connection is removed
@@ -1980,24 +1958,10 @@ const NMApplet = new Lang.Class({
this._updateIcon();
},
_ignoreConnection: function(connection) {
let setting = connection.get_setting_connection();
if (!setting)
return true;
// Ignore slave connections
if (setting.get_master())
return true;
return false;
},
_readConnections: function() {
let connections = this._settings.list_connections();
for (let i = 0; i < connections.length; i++) {
let connection = connections[i];
if (this._ignoreConnection(connection))
continue;
if (connection._updatedId) {
// connection was already seen (for example because NetworkManager was restarted)
continue;
@@ -2011,8 +1975,6 @@ const NMApplet = new Lang.Class({
},
_newConnection: function(settings, connection) {
if (this._ignoreConnection(connection))
return;
if (connection._updatedId) {
// connection was already seen
return;

View File

@@ -187,8 +187,6 @@ const DeviceItem = new Lang.Class({
let percentLabel = new St.Label({ text: C_("percent of battery remaining", "%d%%").format(Math.round(percentage)) });
this.addActor(percentLabel, { align: St.Align.END });
//FIXME: ideally we would like to expose this._label and percentLabel
this.actor.label_actor = percentLabel;
},
_deviceTypeToString: function(type) {

View File

@@ -132,7 +132,7 @@ const Client = new Lang.Class({
let channel = channels[i];
let [targetHandle, targetHandleType] = channel.get_handle();
if (channel.get_invalidated())
if (Shell.is_channel_invalidated(channel))
continue;
/* Only observe contact text channels */
@@ -184,7 +184,7 @@ const Client = new Lang.Class({
continue;
}
if (channel.get_invalidated())
if (Shell.is_channel_invalidated(channel))
continue;
// 'notify' will be true when coming from an actual HandleChannels
@@ -211,15 +211,13 @@ const Client = new Lang.Class({
// We can only approve the rooms if we have been invited to it
let selfContact = channel.group_get_self_contact();
if (selfContact == null) {
context.fail(new Tp.Error({ code: Tp.Error.INVALID_ARGUMENT,
message: 'Not invited to the room' }));
Shell.decline_dispatch_op(context, 'Not invited to the room');
return;
}
let [invited, inviter, reason, msg] = channel.group_get_local_pending_contact_info(selfContact);
if (!invited) {
context.fail(new Tp.Error({ code: Tp.Error.INVALID_ARGUMENT,
message: 'Not invited to the room' }));
Shell.decline_dispatch_op(context, 'Not invited to the room');
return;
}
@@ -239,9 +237,8 @@ const Client = new Lang.Class({
let channel = channels[0];
let chanType = channel.get_channel_type();
if (channel.get_invalidated()) {
context.fail(new Tp.Error({ code: Tp.Error.INVALID_ARGUMENT,
message: 'Channel is invalidated' }));
if (Shell.is_channel_invalidated(channel)) {
Shell.decline_dispatch_op(context, 'Channel is invalidated');
return;
}
@@ -252,8 +249,7 @@ const Client = new Lang.Class({
else if (chanType == Tp.IFACE_CHANNEL_TYPE_FILE_TRANSFER)
this._approveFileTransfer(account, conn, channel, dispatchOp, context);
else
context.fail(new Tp.Error({ code: Tp.Error.INVALID_ARGUMENT,
message: 'Unsupported channel type' }));
Shell.decline_dispatch_op(context, 'Unsupported channel type');
},
_approveTextChannel: function(account, conn, channel, dispatchOp, context) {
@@ -582,7 +578,7 @@ const ChatSource = new Lang.Class({
this._pendingMessages.push(message);
}
this.countUpdated();
this._updateCount();
let showTimestamp = false;
@@ -628,17 +624,8 @@ const ChatSource = new Lang.Class({
this.destroy();
},
/* All messages are new messages for Telepathy sources */
get count() {
return this._pendingMessages.length;
},
get unseenCount() {
return this.count;
},
get countVisible() {
return this.count > 0;
_updateCount: function() {
this._setCount(this._pendingMessages.length, this._pendingMessages.length > 0);
},
_messageReceived: function(channel, message) {
@@ -646,7 +633,7 @@ const ChatSource = new Lang.Class({
return;
this._pendingMessages.push(message);
this.countUpdated();
this._updateCount();
message = makeMessageFromTpMessage(message, NotificationDirection.RECEIVED);
this._notification.appendMessage(message);
@@ -723,7 +710,7 @@ const ChatSource = new Lang.Class({
if (idx >= 0) {
this._pendingMessages.splice(idx, 1);
this.countUpdated();
this._updateCount();
}
else
throw new Error('Message not in our pending list: ' + message);
@@ -1342,14 +1329,15 @@ const AccountNotification = new Lang.Class({
case 'reconnect':
// If it fails again, a new notification should pop up with the
// new error.
account.reconnect_async(null);
account.reconnect_async(null, null);
break;
case 'edit':
let cmd = '/usr/bin/empathy-accounts'
+ ' --select-account=%s'
.format(account.get_path_suffix());
let app_info = Gio.app_info_create_from_commandline(cmd, null, 0);
app_info.launch([], global.create_app_launch_context());
let app_info = Gio.app_info_create_from_commandline(cmd, null, 0,
null);
app_info.launch([], null, null);
break;
}
this.destroy();

View File

@@ -20,9 +20,6 @@ const UserMenu = imports.ui.userMenu;
const Batch = imports.gdm.batch;
const GdmUtil = imports.gdm.util;
// The timeout before going back automatically to the lock screen (in seconds)
const IDLE_TIMEOUT = 2 * 60;
// A widget showing the user avatar and name
const UserWidget = new Lang.Class({
Name: 'UserWidget',
@@ -33,7 +30,7 @@ const UserWidget = new Lang.Class({
this.actor = new St.BoxLayout({ style_class: 'unlock-dialog-user-name-container',
vertical: false });
this._avatar = new UserMenu.UserAvatarWidget(user, { reactive: false });
this._avatar = new UserMenu.UserAvatarWidget(user);
this.actor.add(this._avatar.actor,
{ x_fill: true, y_fill: true });
@@ -97,14 +94,14 @@ const UnlockDialog = new Lang.Class({
this._userVerifier.connect('verification-complete', Lang.bind(this, this._onVerificationComplete));
this._userVerifier.connect('verification-failed', Lang.bind(this, this._onVerificationFailed));
this._userVerifier.connect('show-login-hint', Lang.bind(this, this._showLoginHint));
this._userVerifier.connect('hide-login-hint', Lang.bind(this, this._hideLoginHint));
this._userVerifier.connect('show-fingerprint-prompt', Lang.bind(this, this._showFingerprintPrompt));
this._userVerifier.connect('hide-fingerprint-prompt', Lang.bind(this, this._hideFingerprintPrompt));
this._userWidget = new UserWidget(this._user);
this.contentLayout.add_actor(this._userWidget.actor);
this._promptLayout = new St.BoxLayout({ style_class: 'login-dialog-prompt-layout',
vertical: true });
vertical: false });
this._promptLabel = new St.Label({ style_class: 'login-dialog-prompt-label' });
this._promptLayout.add(this._promptLabel,
@@ -122,22 +119,14 @@ const UnlockDialog = new Lang.Class({
this.contentLayout.add_actor(this._promptLayout);
this._promptLoginHint = new St.Label({ style_class: 'login-dialog-prompt-login-hint' });
this._promptLoginHint.hide();
this.contentLayout.add_actor(this._promptLoginHint);
// Translators: this message is shown below the password entry field
// to indicate the user can swipe their finger instead
this._promptFingerprintMessage = new St.Label({ text: _("(or swipe finger)"),
style_class: 'login-dialog-prompt-fingerprint-message' });
this._promptFingerprintMessage.hide();
this.contentLayout.add_actor(this._promptFingerprintMessage);
let cancelButton = { label: _("Cancel"),
action: Lang.bind(this, this._escape),
key: Clutter.KEY_Escape };
this._okButton = { label: _("Unlock"),
action: Lang.bind(this, this._doUnlock),
default: true };
this.setButtons([cancelButton, this._okButton]);
this._updateOkButton(false);
this._reset();
let otherUserLabel = new St.Label({ text: _("Log in as another user"),
let otherUserLabel = new St.Label({ text: _("Login as another user"),
style_class: 'login-dialog-not-listed-label' });
this._otherUserButton = new St.Button({ style_class: 'login-dialog-not-listed-button',
can_focus: true,
@@ -146,19 +135,23 @@ const UnlockDialog = new Lang.Class({
x_align: St.Align.START,
x_fill: true });
this._otherUserButton.connect('clicked', Lang.bind(this, this._otherUserClicked));
this.dialogLayout.add(this._otherUserButton,
{ x_align: St.Align.START,
x_fill: false });
this.contentLayout.add(this._otherUserButton,
{ x_align: St.Align.START,
x_fill: false });
this._okButton = { label: _("Unlock"),
action: Lang.bind(this, this._doUnlock),
default: true };
this.setButtons([this._okButton]);
this.setActionKey(Clutter.KEY_Escape, Lang.bind(this, this._escape));
this._updateOkButton(false);
this._reset();
GLib.idle_add(GLib.PRIORITY_DEFAULT, Lang.bind(this, function() {
this.emit('loaded');
return false;
}));
this._idleMonitor = Shell.IdleMonitor.get();
// this dialog is only created after user activity (curtain drag or
// escape key press), so the timeout will fire after IDLE_TIMEOUT seconds of inactivity
this._idleWatchId = this._idleMonitor.add_watch(IDLE_TIMEOUT * 1000, Lang.bind(this, this._escape));
},
_updateOkButton: function(sensitive) {
@@ -180,13 +173,12 @@ const UnlockDialog = new Lang.Class({
this._updateOkButton(true);
},
_showLoginHint: function(verifier, message) {
this._promptLoginHint.set_text(message)
GdmUtil.fadeInActor(this._promptLoginHint);
_showFingerprintPrompt: function() {
GdmUtil.fadeInActor(this._promptFingerprintMessage);
},
_hideLoginHint: function() {
GdmUtil.fadeOutActor(this._promptLoginHint);
_hideFingerprintPrompt: function() {
GdmUtil.fadeOutActor(this._promptFingerprintMessage);
},
_doUnlock: function() {
@@ -216,7 +208,7 @@ const UnlockDialog = new Lang.Class({
},
_otherUserClicked: function(button, event) {
Gdm.goto_login_session_sync(null);
this._userManager.goto_login_session();
this._userVerifier.cancel();
this.emit('failed');
@@ -224,12 +216,6 @@ const UnlockDialog = new Lang.Class({
destroy: function() {
this._userVerifier.clear();
if (this._idleWatchId) {
this._idleMonitor.remove_watch(this._idleWatchId);
this._idleWatchId = 0;
}
this.parent();
},

View File

@@ -16,15 +16,12 @@ const GnomeSession = imports.misc.gnomeSession;
const Main = imports.ui.main;
const PanelMenu = imports.ui.panelMenu;
const PopupMenu = imports.ui.popupMenu;
const Params = imports.misc.params;
const Util = imports.misc.util;
const LOCKDOWN_SCHEMA = 'org.gnome.desktop.lockdown';
const SCREENSAVER_SCHEMA = 'org.gnome.desktop.screensaver';
const DISABLE_USER_SWITCH_KEY = 'disable-user-switching';
const DISABLE_LOCK_SCREEN_KEY = 'disable-lock-screen';
const DISABLE_LOG_OUT_KEY = 'disable-log-out';
const LOCK_ENABLED_KEY = 'lock-enabled';
const DIALOG_ICON_SIZE = 64;
@@ -46,13 +43,12 @@ const IMStatus = {
const UserAvatarWidget = new Lang.Class({
Name: 'UserAvatarWidget',
_init: function(user, params) {
_init: function(user) {
this._user = user;
params = Params.parse(params, { reactive: true });
this.actor = new St.Bin({ style_class: 'status-chooser-user-icon',
track_hover: params.reactive,
reactive: params.reactive });
track_hover: true,
reactive: true });
},
update: function() {
@@ -100,7 +96,6 @@ const IMUserNameItem = new Lang.Class({
_init: function() {
this.parent({ reactive: false,
can_focus: false,
style_class: 'status-chooser-user-name' });
this._wrapper = new Shell.GenericContainer();
@@ -138,7 +133,6 @@ const IMStatusChooserItem = new Lang.Class({
_init: function() {
this.parent({ reactive: false,
can_focus: false,
style_class: 'status-chooser' });
this._userManager = AccountsService.UserManager.get_default();
@@ -207,21 +201,20 @@ const IMStatusChooserItem = new Lang.Class({
Lang.bind(this, this._IMAccountsChanged));
this._accountMgr.prepare_async(null, Lang.bind(this,
function(mgr) {
let [presence, status, msg] = mgr.get_most_available_presence();
let savedPresence = global.settings.get_int('saved-im-presence');
this._IMAccountsChanged(mgr);
if (this._networkMonitor.network_available)
this._restorePresence();
else
this._setComboboxPresence(Tp.ConnectionPresenceType.OFFLINE);
}));
this._networkMonitor = Gio.NetworkMonitor.get_default();
this._networkMonitor.connect('network-changed',
Lang.bind(this, function(monitor, available) {
this._IMAccountsChanged(this._accountMgr);
if (available && !this._imPresenceRestored)
this._restorePresence();
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._userLoadedId = this._user.connect('notify::is-loaded',
@@ -236,21 +229,6 @@ const IMStatusChooserItem = new Lang.Class({
}));
},
_restorePresence: function() {
let [presence, status, msg] = this._accountMgr.get_most_available_presence();
let savedPresence = global.settings.get_int('saved-im-presence');
if (savedPresence == presence) {
this._IMStatusChanged(this._accountMgr, presence, status, msg);
} else {
this._setComboboxPresence(savedPresence);
status = this._statusForPresence(savedPresence);
msg = msg ? msg : '';
this._accountMgr.set_all_requested_presences(savedPresence, status, msg);
}
},
destroy: function() {
// clean up signal handlers
if (this._userLoadedId != 0) {
@@ -307,8 +285,7 @@ const IMStatusChooserItem = new Lang.Class({
let accounts = mgr.get_valid_accounts().filter(function(account) {
return account.enabled;
});
let sensitive = accounts.length > 0 && this._networkMonitor.network_available;
this._combo.setSensitive(sensitive);
this._combo.setSensitive(accounts.length > 0);
},
_IMStatusChanged: function(accountMgr, presence, status, message) {
@@ -461,7 +438,6 @@ const UserMenuButton = new Lang.Class({
let box = new St.BoxLayout({ name: 'panelUserMenu' });
this.actor.add_actor(box);
this._screenSaverSettings = new Gio.Settings({ schema: SCREENSAVER_SCHEMA });
this._lockdownSettings = new Gio.Settings({ schema: LOCKDOWN_SCHEMA });
this._userManager = AccountsService.UserManager.get_default();
@@ -561,7 +537,9 @@ const UserMenuButton = new Lang.Class({
},
setLockedState: function(locked) {
this.actor.visible = !locked;
if (locked)
this.menu.close();
this.actor.reactive = !locked;
},
_onDestroy: function() {
@@ -676,10 +654,8 @@ const UserMenuButton = new Lang.Class({
},
_onAccountRemoved: function(accountMgr, account) {
if (account._changingId) {
account.disconnect(account._changingId);
account._changingId = 0;
}
account.disconnect(account._changingId);
account._changingId = 0;
this._updateChangingPresence();
},
@@ -796,9 +772,8 @@ const UserMenuButton = new Lang.Class({
_onLoginScreenActivate: function() {
Main.overview.hide();
if (this._screenSaverSettings.get_boolean(LOCK_ENABLED_KEY))
Main.screenShield.lock(false);
Gdm.goto_login_session_sync(null);
Main.screenShield.lock(false);
this._userManager.goto_login_session();
},
_onQuitSessionActivate: function() {
@@ -820,17 +795,13 @@ const UserMenuButton = new Lang.Class({
this._suspendOrPowerOffItem.state == PopupMenu.PopupAlternatingMenuItemState.DEFAULT) {
this._session.ShutdownRemote();
} else {
if (this._screenSaverSettings.get_boolean(LOCK_ENABLED_KEY)) {
let tmpId = Main.screenShield.connect('lock-screen-shown', Lang.bind(this, function() {
Main.screenShield.disconnect(tmpId);
let tmpId = Main.screenShield.connect('lock-screen-shown', Lang.bind(this, function() {
Main.screenShield.disconnect(tmpId);
this._upClient.suspend_sync(null);
}));
Main.screenShield.lock(true);
} else {
this._upClient.suspend_sync(null);
}
}));
Main.screenShield.lock(true);
}
}
});

View File

@@ -9,68 +9,113 @@ const Lang = imports.lang;
const Shell = imports.gi.Shell;
const St = imports.gi.St;
const AppDisplay = imports.ui.appDisplay;
const Main = imports.ui.main;
const PlaceDisplay = imports.ui.placeDisplay;
const RemoteSearch = imports.ui.remoteSearch;
const Search = imports.ui.search;
const SearchDisplay = imports.ui.searchDisplay;
const ShellEntry = imports.ui.shellEntry;
const Tweener = imports.ui.tweener;
const Wanda = imports.ui.wanda;
const WorkspacesView = imports.ui.workspacesView;
const BaseTab = new Lang.Class({
Name: 'BaseTab',
_init: function(titleActor, pageActor, name, a11yIcon) {
this.title = titleActor;
this.page = new St.Bin({ child: pageActor,
x_align: St.Align.START,
y_align: St.Align.START,
x_fill: true,
y_fill: true,
style_class: 'view-tab-page' });
if (this.title.can_focus) {
Main.ctrlAltTabManager.addGroup(this.title, name, a11yIcon);
} else {
Main.ctrlAltTabManager.addGroup(this.page, name, a11yIcon,
{ proxy: this.title,
focusCallback: Lang.bind(this, this._a11yFocus) });
}
this.visible = false;
},
show: function(animate) {
this.visible = true;
this.page.show();
if (!animate)
return;
this.page.opacity = 0;
Tweener.addTween(this.page,
{ opacity: 255,
time: 0.1,
transition: 'easeOutQuad' });
},
hide: function() {
this.visible = false;
Tweener.addTween(this.page,
{ opacity: 0,
time: 0.1,
transition: 'easeOutQuad',
onComplete: Lang.bind(this,
function() {
this.page.hide();
})
});
},
_a11yFocus: function() {
this._activate();
this.page.navigate_focus(null, Gtk.DirectionType.TAB_FORWARD, false);
},
_activate: function() {
this.emit('activated');
}
});
Signals.addSignalMethods(BaseTab.prototype);
const FocusTrap = new Lang.Class({
Name: 'FocusTrap',
Extends: St.Widget,
const ViewTab = new Lang.Class({
Name: 'ViewTab',
Extends: BaseTab,
vfunc_navigate_focus: function(from, direction) {
if (direction == Gtk.DirectionType.TAB_FORWARD ||
direction == Gtk.DirectionType.TAB_BACKWARD)
return this.parent(from, direction);
return false;
_init: function(id, label, pageActor, a11yIcon) {
this.id = id;
let titleActor = new St.Button({ label: label,
style_class: 'view-tab-title' });
titleActor.connect('clicked', Lang.bind(this, this._activate));
this.parent(titleActor, pageActor, label, a11yIcon);
}
});
const ViewSelector = new Lang.Class({
Name: 'ViewSelector',
_init : function(searchEntry, showAppsButton) {
this.actor = new St.BoxLayout({ name: 'viewSelector',
vertical: true });
this._showAppsButton = showAppsButton;
this._showAppsButton.connect('notify::checked', Lang.bind(this, this._onShowAppsButtonToggled));
this._pageArea = new Shell.Stack();
this.actor.add(this._pageArea, { x_fill: true,
y_fill: true,
expand: true });
this._activePage = null;
const SearchTab = new Lang.Class({
Name: 'SearchTab',
Extends: BaseTab,
_init: function() {
this.active = false;
this._searchPending = false;
this._searchTimeoutId = 0;
this._searchSystem = new Search.SearchSystem();
this._openSearchSystem = new Search.OpenSearchSystem();
this._entry = searchEntry;
this._entry = new St.Entry({ name: 'searchEntry',
/* Translators: this is the text displayed
in the search entry when no search is
active; it should not exceed ~30
characters. */
hint_text: _("Type to search..."),
track_hover: true,
can_focus: true });
ShellEntry.addContextMenu(this._entry);
this._text = this._entry.clutter_text;
this._text.connect('text-changed', Lang.bind(this, this._onTextChanged));
this._text.connect('key-press-event', Lang.bind(this, this._onKeyPress));
this._text.connect('key-focus-in', Lang.bind(this, function() {
this._searchResults.highlightDefault(true);
}));
this._text.connect('key-focus-out', Lang.bind(this, function() {
this._searchResults.highlightDefault(false);
}));
this._entry.connect('notify::mapped', Lang.bind(this, this._onMapped));
global.stage.connect('notify::key-focus', Lang.bind(this, this._onStageKeyFocusChanged));
this._inactiveIcon = new St.Icon({ style_class: 'search-entry-icon',
icon_name: 'edit-find',
@@ -81,188 +126,59 @@ const ViewSelector = new Lang.Class({
this._entry.set_secondary_icon(this._inactiveIcon);
this._iconClickedId = 0;
this._searchResults = new SearchDisplay.SearchResults(this._searchSystem, this._openSearchSystem);
this.parent(this._entry, this._searchResults.actor, _("Search"), 'edit-find');
this._text.connect('text-changed', Lang.bind(this, this._onTextChanged));
this._text.connect('key-press-event', Lang.bind(this, function (o, e) {
// We can't connect to 'activate' here because search providers
// might want to do something with the modifiers in activateDefault.
let symbol = e.get_key_symbol();
if (symbol == Clutter.Return || symbol == Clutter.KP_Enter) {
if (this._searchTimeoutId > 0) {
Mainloop.source_remove(this._searchTimeoutId);
this._doSearch();
}
this._searchResults.activateDefault();
return true;
}
return false;
}));
this._entry.connect('notify::mapped', Lang.bind(this, this._onMapped));
global.stage.connect('notify::key-focus', Lang.bind(this, this._onStageKeyFocusChanged));
this._capturedEventId = 0;
this._workspacesDisplay = new WorkspacesView.WorkspacesDisplay();
this._workspacesPage = this._addPage(this._workspacesDisplay.actor, null,
_("Windows"), 'text-x-generic');
this._appDisplay = new AppDisplay.AllAppDisplay();
this._appsPage = this._addPage(this._appDisplay.actor, null,
_("Applications"), 'system-run');
this._searchResults = new SearchDisplay.SearchResults(this._searchSystem);
this._searchPage = this._addPage(this._searchResults.actor, this._entry,
_("Search"), 'edit-find');
// Default search providers
// Wanda comes obviously first
this.addSearchProvider(new Wanda.WandaSearchProvider());
this.addSearchProvider(new AppDisplay.AppSearchProvider());
this.addSearchProvider(new AppDisplay.SettingsSearchProvider());
this.addSearchProvider(new PlaceDisplay.PlaceSearchProvider());
// Load remote search providers provided by applications
RemoteSearch.loadRemoteSearchProviders(Lang.bind(this, this.addSearchProvider));
this._text.connect('key-focus-in', Lang.bind(this, function() {
this._searchResults.highlightDefault(true);
}));
this._text.connect('key-focus-out', Lang.bind(this, function() {
this._searchResults.highlightDefault(false);
}));
// Since the entry isn't inside the results container we install this
// dummy widget as the last results container child so that we can
// include the entry in the keynav tab path
this._focusTrap = new FocusTrap({ can_focus: true });
// include the entry in the keynav tab path...
this._focusTrap = new St.Bin({ can_focus: true });
this._focusTrap.connect('key-focus-in', Lang.bind(this, function() {
this._entry.grab_key_focus();
}));
// ... but make it unfocusable using arrow keys keynav by making its
// bounding box always contain the possible focus source's bounding
// box since StWidget's keynav logic won't ever select it as a target
// in that case.
this._focusTrap.add_constraint(new Clutter.BindConstraint({ source: this._searchResults.actor,
coordinate: Clutter.BindCoordinate.ALL }));
this._searchResults.actor.add_actor(this._focusTrap);
global.focus_manager.add_group(this._searchResults.actor);
Main.overview.connect('item-drag-begin',
Lang.bind(this, this._resetShowAppsButton));
this._stageKeyPressId = 0;
Main.overview.connect('showing', Lang.bind(this,
function () {
this._resetShowAppsButton();
this._stageKeyPressId = global.stage.connect('key-press-event',
Lang.bind(this, this._onStageKeyPress));
}));
Main.overview.connect('hiding', Lang.bind(this,
function () {
this._resetShowAppsButton();
if (this._stageKeyPressId != 0) {
global.stage.disconnect(this._stageKeyPressId);
this._stageKeyPressId = 0;
}
}));
// Public constraints which may be used to tie actors' height or
// vertical position to the current tab's content; as the content's
// height and position depend on the view selector's style properties
// (e.g. font size, padding, spacing, ...) it would be extremely hard
// and ugly to get these from the outside. While it would be possible
// to use position and height properties directly, outside code would
// need to ensure that the content is properly allocated before
// accessing the properties.
this.constrainHeight = new Clutter.BindConstraint({ source: this._pageArea,
coordinate: Clutter.BindCoordinate.HEIGHT });
},
show: function() {
this._activePage = this._workspacesPage;
this._appsPage.hide();
this._searchPage.hide();
this._workspacesDisplay.show();
if (!this._workspacesDisplay.activeWorkspaceHasMaximizedWindows())
Main.overview.fadeOutDesktop();
this._showPage(this._workspacesPage);
},
zoomFromOverview: function() {
this._workspacesDisplay.zoomFromOverview();
if (!this._workspacesDisplay.activeWorkspaceHasMaximizedWindows())
Main.overview.fadeInDesktop();
},
hide: function() {
this._workspacesDisplay.hide();
},
_addPage: function(actor, a11yFocus, name, a11yIcon) {
let page = new St.Bin({ child: actor,
x_align: St.Align.START,
y_align: St.Align.START,
x_fill: true,
y_fill: true });
if (a11yFocus)
Main.ctrlAltTabManager.addGroup(a11yFocus, name, a11yIcon);
else
Main.ctrlAltTabManager.addGroup(actor, name, a11yIcon,
{ proxy: this.actor,
focusCallback: Lang.bind(this,
function() {
this._a11yFocusPage(page);
})
});;
this._pageArea.add_actor(page);
return page
},
_showPage: function(page) {
if(page == this._activePage)
return;
if(this._activePage) {
Tweener.addTween(this._activePage,
{ opacity: 0,
time: 0.1,
transition: 'easeOutQuad',
onComplete: Lang.bind(this,
function() {
this._activePage.hide();
this._activePage = page;
})
});
}
page.show();
Tweener.addTween(page,
{ opacity: 255,
time: 0.1,
transition: 'easeOutQuad'
});
},
_a11yFocusPage: function(page) {
this._showAppsButton.checked = page == this._appsPage;
page.navigate_focus(null, Gtk.DirectionType.TAB_FORWARD, false);
},
_onShowAppsButtonToggled: function() {
if (this.active)
this.reset();
else
this._showPage(this._showAppsButton.checked ? this._appsPage
: this._workspacesPage);
},
_resetShowAppsButton: function() {
this._showAppsButton.checked = false;
},
_onStageKeyPress: function(actor, event) {
let modifiers = event.get_state();
let symbol = event.get_key_symbol();
if (symbol == Clutter.Escape) {
if (this.active)
this.reset();
else if (this._showAppsButton.checked)
this._resetShowAppsButton();
else
Main.overview.hide();
return true;
} else if (Clutter.keysym_to_unicode(symbol) ||
(symbol == Clutter.BackSpace && this.active)) {
this.startSearch(event);
} else if (!this.active) {
if (symbol == Clutter.Tab || symbol == Clutter.Down) {
this._activePage.navigate_focus(null, Gtk.DirectionType.TAB_FORWARD, false);
return true;
} else if (symbol == Clutter.ISO_Left_Tab) {
this._activePage.navigate_focus(null, Gtk.DirectionType.TAB_BACKWARD, false);
return true;
}
}
return false;
},
_searchCancelled: function() {
this._showPage(this._showAppsButton.checked ? this._appsPage
: this._workspacesPage);
this.parent();
// Leave the entry focused when it doesn't have any text;
// when replacing a selected search term, Clutter emits
@@ -311,6 +227,16 @@ const ViewSelector = new Lang.Class({
}
},
addSearchProvider: function(provider) {
this._searchSystem.registerProvider(provider);
this._searchResults.createProviderMeta(provider);
},
removeSearchProvider: function(provider) {
this._searchSystem.unregisterProvider(provider);
this._searchResults.destroyProviderMeta(provider);
},
startSearch: function(event) {
global.stage.set_key_focus(this._text);
this._text.event(event, false);
@@ -337,13 +263,14 @@ const ViewSelector = new Lang.Class({
this.reset();
}));
}
this._activate();
} else {
if (this._iconClickedId > 0)
this._entry.disconnect(this._iconClickedId);
this._iconClickedId = 0;
this._entry.set_secondary_icon(this._inactiveIcon);
this._searchCancelled();
this.emit('search-cancelled');
}
if (!this.active) {
if (this._searchTimeoutId > 0) {
@@ -364,15 +291,6 @@ const ViewSelector = new Lang.Class({
this.reset();
return true;
}
} else if (symbol == Clutter.Return || symbol == Clutter.KP_Enter) {
// We can't connect to 'activate' here because search providers
// might want to do something with the modifiers in activateDefault.
if (this._searchTimeoutId > 0) {
Mainloop.source_remove(this._searchTimeoutId);
this._doSearch();
}
this._searchResults.activateDefault();
return true;
} else if (this.active) {
let arrowNext, nextDirection;
if (entry.get_text_direction() == Clutter.TextDirection.RTL) {
@@ -422,17 +340,259 @@ const ViewSelector = new Lang.Class({
let text = this._text.get_text().replace(/^\s+/g, '').replace(/\s+$/g, '');
this._searchResults.doSearch(text);
this._showPage(this._searchPage);
return false;
}
});
const ViewSelector = new Lang.Class({
Name: 'ViewSelector',
_init : function() {
this.actor = new St.BoxLayout({ name: 'viewSelector',
vertical: true });
// The tab bar is located at the top of the view selector and
// holds both "normal" tab labels and the search entry. The former
// is left aligned, the latter right aligned - unless the text
// direction is RTL, in which case the order is reversed.
this._tabBar = new Shell.GenericContainer();
this._tabBar.connect('get-preferred-width',
Lang.bind(this, this._getPreferredTabBarWidth));
this._tabBar.connect('get-preferred-height',
Lang.bind(this, this._getPreferredTabBarHeight));
this._tabBar.connect('allocate',
Lang.bind(this, this._allocateTabBar));
this.actor.add(this._tabBar);
// Box to hold "normal" tab labels
this._tabBox = new St.BoxLayout({ name: 'viewSelectorTabBar' });
this._tabBar.add_actor(this._tabBox);
// The searchArea just holds the entry
this._searchArea = new St.Bin({ name: 'searchArea' });
this._tabBar.add_actor(this._searchArea);
// The page area holds the tab pages. Every page is given the
// area's full allocation, so that the pages would appear on top
// of each other if the inactive ones weren't hidden.
this._pageArea = new Shell.Stack();
this.actor.add(this._pageArea, { x_fill: true,
y_fill: true,
expand: true });
this._tabs = [];
this._activeTab = null;
this._searchTab = new SearchTab();
this._searchArea.set_child(this._searchTab.title);
this._addTab(this._searchTab);
this._searchTab.connect('search-cancelled', Lang.bind(this,
function() {
this._switchTab(this._activeTab);
}));
Main.overview.connect('item-drag-begin',
Lang.bind(this, this._switchDefaultTab));
this._stageKeyPressId = 0;
Main.overview.connect('showing', Lang.bind(this,
function () {
this._switchDefaultTab();
this._stageKeyPressId = global.stage.connect('key-press-event',
Lang.bind(this, this._onStageKeyPress));
}));
Main.overview.connect('hiding', Lang.bind(this,
function () {
this._switchDefaultTab();
if (this._stageKeyPressId != 0) {
global.stage.disconnect(this._stageKeyPressId);
this._stageKeyPressId = 0;
}
}));
// Public constraints which may be used to tie actors' height or
// vertical position to the current tab's content; as the content's
// height and position depend on the view selector's style properties
// (e.g. font size, padding, spacing, ...) it would be extremely hard
// and ugly to get these from the outside. While it would be possible
// to use position and height properties directly, outside code would
// need to ensure that the content is properly allocated before
// accessing the properties.
this.constrainY = new Clutter.BindConstraint({ source: this._pageArea,
coordinate: Clutter.BindCoordinate.Y });
this.constrainHeight = new Clutter.BindConstraint({ source: this._pageArea,
coordinate: Clutter.BindCoordinate.HEIGHT });
},
_addTab: function(tab) {
tab.page.hide();
this._pageArea.add_actor(tab.page);
tab.connect('activated', Lang.bind(this, function(tab) {
this._switchTab(tab);
}));
},
addViewTab: function(id, title, pageActor, a11yIcon) {
let viewTab = new ViewTab(id, title, pageActor, a11yIcon);
this._tabs.push(viewTab);
this._tabBox.add(viewTab.title);
this._addTab(viewTab);
},
_switchTab: function(tab) {
let firstSwitch = this._activeTab == null;
if (this._activeTab && this._activeTab.visible) {
if (this._activeTab == tab)
return;
this._activeTab.title.remove_style_pseudo_class('selected');
this._activeTab.hide();
}
if (tab != this._searchTab) {
tab.title.add_style_pseudo_class('selected');
this._activeTab = tab;
if (this._searchTab.visible) {
this._searchTab.hide();
}
}
// Only fade when switching between tabs,
// not when setting the initially selected one.
if (!tab.visible)
tab.show(!firstSwitch);
},
switchTab: function(id) {
for (let i = 0; i < this._tabs.length; i++)
if (this._tabs[i].id == id) {
this._switchTab(this._tabs[i]);
break;
}
},
_switchDefaultTab: function() {
if (this._tabs.length > 0)
this._switchTab(this._tabs[0]);
},
_nextTab: function() {
if (this._tabs.length == 0 ||
this._tabs[this._tabs.length - 1] == this._activeTab)
return;
for (let i = 0; i < this._tabs.length; i++)
if (this._tabs[i] == this._activeTab) {
this._switchTab(this._tabs[i + 1]);
return;
}
},
_prevTab: function() {
if (this._tabs.length == 0 || this._tabs[0] == this._activeTab)
return;
for (let i = 0; i < this._tabs.length; i++)
if (this._tabs[i] == this._activeTab) {
this._switchTab(this._tabs[i - 1]);
return;
}
},
_getPreferredTabBarWidth: function(box, forHeight, alloc) {
let children = box.get_children();
for (let i = 0; i < children.length; i++) {
let [childMin, childNat] = children[i].get_preferred_width(forHeight);
alloc.min_size += childMin;
alloc.natural_size += childNat;
}
},
_getPreferredTabBarHeight: function(box, forWidth, alloc) {
let children = box.get_children();
for (let i = 0; i < children.length; i++) {
let [childMin, childNatural] = children[i].get_preferred_height(forWidth);
if (childMin > alloc.min_size)
alloc.min_size = childMin;
if (childNatural > alloc.natural_size)
alloc.natural_size = childNatural;
}
},
_allocateTabBar: function(container, box, flags) {
let allocWidth = box.x2 - box.x1;
let allocHeight = box.y2 - box.y1;
let [searchMinWidth, searchNatWidth] = this._searchArea.get_preferred_width(-1);
let [barMinWidth, barNatWidth] = this._tabBox.get_preferred_width(-1);
let childBox = new Clutter.ActorBox();
childBox.y1 = 0;
childBox.y2 = allocHeight;
if (this.actor.get_text_direction() == Clutter.TextDirection.RTL) {
childBox.x1 = allocWidth - barNatWidth;
childBox.x2 = allocWidth;
} else {
childBox.x1 = 0;
childBox.x2 = barNatWidth;
}
this._tabBox.allocate(childBox, flags);
if (this.actor.get_text_direction() == Clutter.TextDirection.RTL) {
childBox.x1 = 0;
childBox.x2 = searchNatWidth;
} else {
childBox.x1 = allocWidth - searchNatWidth;
childBox.x2 = allocWidth;
}
this._searchArea.allocate(childBox, flags);
Meta.later_add(Meta.LaterType.BEFORE_REDRAW, Lang.bind(this,
function() {
this.constrainY.offset = this.actor.y;
}));
},
_onStageKeyPress: function(actor, event) {
let modifiers = event.get_state();
let symbol = event.get_key_symbol();
if (symbol == Clutter.Escape) {
if (this._searchTab.active)
this._searchTab.reset();
else
Main.overview.hide();
return true;
} else if (Clutter.keysym_to_unicode(symbol) ||
(symbol == Clutter.BackSpace && this._searchTab.active)) {
this._searchTab.startSearch(event);
} else if (!this._searchTab.active) {
if (modifiers & Clutter.ModifierType.CONTROL_MASK) {
if (symbol == Clutter.Page_Up) {
this._prevTab();
return true;
} else if (symbol == Clutter.Page_Down) {
this._nextTab();
return true;
}
} else if (symbol == Clutter.Tab) {
this._activeTab.page.navigate_focus(null, Gtk.DirectionType.TAB_FORWARD, false);
return true;
} else if (symbol == Clutter.ISO_Left_Tab) {
this._activeTab.page.navigate_focus(null, Gtk.DirectionType.TAB_BACKWARD, false);
return true;
}
}
return false;
},
addSearchProvider: function(provider) {
this._searchSystem.registerProvider(provider);
this._searchResults.createProviderMeta(provider);
this._searchTab.addSearchProvider(provider);
},
removeSearchProvider: function(provider) {
this._searchSystem.unregisterProvider(provider);
this._searchResults.destroyProviderMeta(provider);
this._searchTab.removeSearchProvider(provider);
}
});
Signals.addSignalMethods(ViewSelector.prototype);

View File

@@ -9,7 +9,6 @@ const Signals = imports.signals;
const St = imports.gi.St;
const IconGrid = imports.ui.iconGrid;
const Layout = imports.ui.layout;
const Main = imports.ui.main;
const Search = imports.ui.search;
@@ -143,18 +142,17 @@ const FortuneDialog = new Lang.Class({
this._button.connect('clicked', Lang.bind(this, this.destroy));
this._button.child = this._box;
this._bin = new St.Bin({ x_align: St.Align.MIDDLE,
y_align: St.Align.MIDDLE });
this._bin.add_constraint(new Layout.MonitorConstraint({ primary: true }));
this._bin.add_actor(this._button);
let monitor = Main.layoutManager.primaryMonitor;
Main.layoutManager.addChrome(this._bin);
Main.layoutManager.addChrome(this._button);
this._button.set_position(Math.floor(monitor.width / 2 - this._button.width / 2),
Math.floor(monitor.height / 2 - this._button.height / 2));
GLib.timeout_add_seconds(GLib.PRIORITY_DEFAULT, 10, Lang.bind(this, this.destroy));
},
destroy: function() {
this._bin.destroy();
this._button.destroy();
}
});

View File

@@ -15,7 +15,8 @@ const Tweener = imports.ui.tweener;
const SHELL_KEYBINDINGS_SCHEMA = 'org.gnome.shell.keybindings';
const WINDOW_ANIMATION_TIME = 0.25;
const DIM_BRIGHTNESS = -0.3;
const DIM_DESATURATION = 0.6;
const DIM_BRIGHTNESS = -0.1;
const DIM_TIME = 0.500;
const UNDIM_TIME = 0.250;
@@ -24,18 +25,22 @@ const WindowDimmer = new Lang.Class({
Name: 'WindowDimmer',
_init: function(actor) {
this._desaturateEffect = new Clutter.DesaturateEffect();
this._brightnessEffect = new Clutter.BrightnessContrastEffect();
actor.add_effect(this._desaturateEffect);
actor.add_effect(this._brightnessEffect);
this.actor = actor;
this._dimFactor = 0.0;
},
setEnabled: function(enabled) {
this._desaturateEffect.enabled = enabled;
this._brightnessEffect.enabled = enabled;
},
set dimFactor(factor) {
this._dimFactor = factor;
this._desaturateEffect.set_factor(factor * DIM_DESATURATION);
this._brightnessEffect.set_brightness(factor * DIM_BRIGHTNESS);
},
@@ -299,29 +304,12 @@ const WindowManager = new Lang.Class({
}));
if (actor.meta_window.is_attached_dialog()) {
this._checkDimming(actor.get_meta_window().get_transient_for());
if (this._shouldAnimate()) {
actor.set_scale(1.0, 0.0);
actor.scale_gravity = Clutter.Gravity.CENTER;
actor.show();
this._mapping.push(actor);
Tweener.addTween(actor,
{ scale_y: 1,
time: WINDOW_ANIMATION_TIME,
transition: "easeOutQuad",
onComplete: this._mapWindowDone,
onCompleteScope: this,
onCompleteParams: [shellwm, actor],
onOverwrite: this._mapWindowOverwrite,
onOverwriteScope: this,
onOverwriteParams: [shellwm, actor]
});
if (!this._shouldAnimate()) {
shellwm.completed_map(actor);
return;
}
shellwm.completed_map(actor);
return;
}
if (!this._shouldAnimateActor(actor)) {
} else if (!this._shouldAnimateActor(actor)) {
shellwm.completed_map(actor);
return;
}
@@ -377,8 +365,7 @@ const WindowManager = new Lang.Class({
return;
}
actor.set_scale(1.0, 1.0);
actor.scale_gravity = Clutter.Gravity.CENTER;
actor.opacity = 255;
actor.show();
this._destroying.push(actor);
@@ -388,7 +375,7 @@ const WindowManager = new Lang.Class({
}));
Tweener.addTween(actor,
{ scale_y: 0,
{ opacity: 0,
time: WINDOW_ANIMATION_TIME,
transition: "easeOutQuad",
onComplete: this._destroyWindowDone,

View File

@@ -499,9 +499,9 @@ const WindowOverlay = new Lang.Class({
this.title.opacity = 0;
this._parentActor.raise_top();
Tweener.addTween(this.title,
{ opacity: 255,
time: CLOSE_BUTTON_FADE_TIME,
transition: 'easeOutQuad' });
{ opacity: 255,
time: CLOSE_BUTTON_FADE_TIME,
transition: 'easeOutQuad' });
},
chromeWidth: function () {
@@ -510,7 +510,7 @@ const WindowOverlay = new Lang.Class({
chromeHeights: function () {
return [this.closeButton.height - this.closeButton._overlap,
this.title.height + this.title._spacing];
this.title.height + this.title._spacing];
},
/**
@@ -720,15 +720,12 @@ const Workspace = new Lang.Class({
Lang.bind(this, this._windowRemoved));
}
this._windowEnteredMonitorId = global.screen.connect('window-entered-monitor',
Lang.bind(this, this._windowEnteredMonitor));
Lang.bind(this, this._windowEnteredMonitor));
this._windowLeftMonitorId = global.screen.connect('window-left-monitor',
Lang.bind(this, this._windowLeftMonitor));
Lang.bind(this, this._windowLeftMonitor));
this._repositionWindowsId = 0;
this.leavingOverview = false;
this._positionWindowsFlags = 0;
this._positionWindowsId = 0;
},
setGeometry: function(x, y, width, height) {
@@ -737,13 +734,15 @@ const Workspace = new Lang.Class({
this._width = width;
this._height = height;
Meta.later_add(Meta.LaterType.BEFORE_REDRAW, Lang.bind(this, function() {
this._dropRect.set_position(x, y);
this._dropRect.set_size(width, height);
return false;
}));
// This is sometimes called during allocation, so we do this later
Meta.later_add(Meta.LaterType.BEFORE_REDRAW, Lang.bind(this,
function () {
this._dropRect.set_position(x, y);
this._dropRect.set_size(width, height);
this.positionWindows(WindowPositionFlags.ANIMATE);
return false;
}));
this.positionWindows(WindowPositionFlags.ANIMATE);
},
_lookupIndex: function (metaWindow) {
@@ -1004,21 +1003,7 @@ const Workspace = new Lang.Class({
* INITIAL - this is the initial positioning of the windows.
* ANIMATE - Indicates that we need animate changing position.
*/
positionWindows: function(flags) {
this._positionWindowsFlags |= flags;
if (this._positionWindowsId > 0)
return;
this._positionWindowsId = Meta.later_add(Meta.LaterType.BEFORE_REDRAW, Lang.bind(this, function() {
this._realPositionWindows(this._positionWindowsFlags);
this._positionWindowsFlags = 0;
this._positionWindowsId = 0;
return false;
}));
},
_realPositionWindows : function(flags) {
positionWindows : function(flags) {
if (this._repositionWindowsId > 0) {
Mainloop.source_remove(this._repositionWindowsId);
this._repositionWindowsId = 0;
@@ -1059,20 +1044,20 @@ const Workspace = new Lang.Class({
/* Hidden windows should fade in and grow
* therefore we need to resize them now so they
* can be scaled up later */
if (initialPositioning) {
clone.actor.opacity = 0;
clone.actor.scale_x = 0;
clone.actor.scale_y = 0;
clone.actor.x = x;
clone.actor.y = y;
}
if (initialPositioning) {
clone.actor.opacity = 0;
clone.actor.scale_x = 0;
clone.actor.scale_y = 0;
clone.actor.x = x;
clone.actor.y = y;
}
// Make the window slightly transparent to indicate it's hidden
Tweener.addTween(clone.actor,
{ opacity: 255,
time: Overview.ANIMATION_TIME,
transition: 'easeInQuad'
});
// Make the window slightly transparent to indicate it's hidden
Tweener.addTween(clone.actor,
{ opacity: 255,
time: Overview.ANIMATION_TIME,
transition: 'easeInQuad'
});
}
this._animateClone(clone, overlay, x, y, scale, initialPositioning);
@@ -1103,16 +1088,16 @@ const Workspace = new Lang.Class({
_animateClone: function(clone, overlay, x, y, scale, initialPositioning) {
Tweener.addTween(clone.actor,
{ x: x,
y: y,
scale_x: scale,
scale_y: scale,
time: Overview.ANIMATION_TIME,
transition: 'easeOutQuad',
onComplete: Lang.bind(this, function() {
this._showWindowOverlay(clone, overlay, true);
})
});
{ x: x,
y: y,
scale_x: scale,
scale_y: scale,
time: Overview.ANIMATION_TIME,
transition: 'easeOutQuad',
onComplete: Lang.bind(this, function() {
this._showWindowOverlay(clone, overlay, true);
})
});
this._updateWindowOverlayPositions(clone, overlay, x, y, scale, true);
},
@@ -1387,9 +1372,6 @@ const Workspace = new Lang.Class({
if (this._repositionWindowsId > 0)
Mainloop.source_remove(this._repositionWindowsId);
if (this._positionWindowsId > 0)
Meta.later_remove(this._positionWindowsId);
// Usually, the windows will be destroyed automatically with
// their parent (this.actor), but we might have a zoomed window
// which has been reparented to the stage - _windows[0] holds

View File

@@ -4,7 +4,6 @@ data/org.gnome.shell.gschema.xml.in.in
js/extensionPrefs/main.js
js/gdm/loginDialog.js
js/gdm/powerMenu.js
js/gdm/util.js
js/misc/util.js
js/ui/appDisplay.js
js/ui/appFavorites.js
@@ -28,7 +27,6 @@ js/ui/placeDisplay.js
js/ui/polkitAuthenticationAgent.js
js/ui/popupMenu.js
js/ui/runDialog.js
js/ui/screenShield.js
js/ui/searchDisplay.js
js/ui/shellEntry.js
js/ui/shellMountOperation.js

370
po/as.po

File diff suppressed because it is too large Load Diff

919
po/de.po

File diff suppressed because it is too large Load Diff

552
po/es.po

File diff suppressed because it is too large Load Diff

460
po/gl.po

File diff suppressed because it is too large Load Diff

250
po/gu.po
View File

@@ -9,8 +9,8 @@ msgstr ""
"Project-Id-Version: gu\n"
"Report-Msgid-Bugs-To: http://bugzilla.gnome.org/enter_bug."
"cgi?product=gnome-shell&keywords=I18N+L10N&component=general\n"
"POT-Creation-Date: 2012-08-06 17:11+0000\n"
"PO-Revision-Date: 2012-08-07 15:02+0530\n"
"POT-Creation-Date: 2012-07-21 17:14+0000\n"
"PO-Revision-Date: 2012-07-30 12:48+0530\n"
"Last-Translator: \n"
"Language-Team: gu_IN <kde-i18n-doc@kde.org>\n"
"Language: \n"
@@ -187,49 +187,48 @@ msgid "There was an error loading the preferences dialog for %s:"
msgstr "ત્યાં %s માટે પસંદગી સંવાદને લાવવામાં ભૂલ હતી:"
#: ../js/extensionPrefs/main.js:164
#| msgid "<b>Extension</b>"
msgid "Extension"
msgstr "ઍક્સટેન્શન"
msgid "<b>Extension</b>"
msgstr "<b>ઍક્સટેન્શન</b>"
#: ../js/extensionPrefs/main.js:188
msgid "Select an extension to configure using the combobox above."
msgstr "ઉપર કોમ્બોબોક્સની મદદથી રૂપરેખાંકિત કરવા માટે ઍક્સટેન્શનને પસંદ કરો."
#: ../js/gdm/loginDialog.js:572
#: ../js/gdm/loginDialog.js:550
msgid "Session..."
msgstr "સત્ર..."
#: ../js/gdm/loginDialog.js:721
#: ../js/gdm/loginDialog.js:699
msgctxt "title"
msgid "Sign In"
msgstr "પ્રવેશો"
#. Translators: this message is shown below the password entry field
#. to indicate the user can swipe their finger instead
#: ../js/gdm/loginDialog.js:766 ../js/ui/unlockDialog.js:124
#: ../js/gdm/loginDialog.js:744 ../js/ui/unlockDialog.js:124
msgid "(or swipe finger)"
msgstr "(અથવા સ્વાઇપ આંગળી)"
#. translators: this message is shown below the user list on the
#. login screen. It can be activated to reveal an entry for
#. manually entering the username.
#: ../js/gdm/loginDialog.js:787
#: ../js/gdm/loginDialog.js:765
msgid "Not listed?"
msgstr "શું યાદી થયેલ નથી?"
#: ../js/gdm/loginDialog.js:930 ../js/ui/endSessionDialog.js:406
#: ../js/gdm/loginDialog.js:908 ../js/ui/endSessionDialog.js:406
#: ../js/ui/extensionDownloader.js:195 ../js/ui/networkAgent.js:153
#: ../js/ui/polkitAuthenticationAgent.js:176
#: ../js/ui/shellMountOperation.js:396 ../js/ui/status/bluetooth.js:432
#: ../js/ui/shellMountOperation.js:396 ../js/ui/status/bluetooth.js:436
msgid "Cancel"
msgstr "રદ કરો"
#: ../js/gdm/loginDialog.js:935
#: ../js/gdm/loginDialog.js:913
msgctxt "button"
msgid "Sign In"
msgstr "પ્રવેશો"
#: ../js/gdm/loginDialog.js:1280
#: ../js/gdm/loginDialog.js:1256
msgid "Login Window"
msgstr "પ્રવેશ વિન્ડો"
@@ -301,12 +300,12 @@ msgstr "%s ને તમારી પસંદીદામાંથી દૂર
msgid "Removable Devices"
msgstr "દૂર કરી શકાય તેવા ઉપકરણો"
#: ../js/ui/autorunManager.js:548
#: ../js/ui/autorunManager.js:549
#, c-format
msgid "Open with %s"
msgstr "%s સાથે ખોલો"
#: ../js/ui/autorunManager.js:574
#: ../js/ui/autorunManager.js:575
msgid "Eject"
msgstr "રદ કરો"
@@ -456,7 +455,7 @@ msgstr "આ અઠવાડિયે"
msgid "Next week"
msgstr "આગળનું અઠવાડિયું"
#: ../js/ui/dash.js:238 ../js/ui/messageTray.js:1317
#: ../js/ui/dash.js:238 ../js/ui/messageTray.js:1321
msgid "Remove"
msgstr "દૂર કરો"
@@ -579,8 +578,8 @@ msgstr "extensions.gnome.org માંથી '%s' ને સ્થાપિત
msgid "tray"
msgstr "ટ્રે"
#: ../js/ui/keyboard.js:545 ../js/ui/status/keyboard.js:146
#: ../js/ui/status/power.js:205
#: ../js/ui/keyboard.js:545 ../js/ui/status/keyboard.js:149
#: ../js/ui/status/power.js:209
msgid "Keyboard"
msgstr "કિબોર્ડ"
@@ -641,24 +640,24 @@ msgid "Web Page"
msgstr "વેબ પાનું"
#. Translators: this is a filename used for screencast recording
#: ../js/ui/main.js:138
#: ../js/ui/main.js:140
#, no-c-format
msgid "Screencast from %d %t"
msgstr "%d %t માંથી સ્ક્રીનકાસ્ટ"
#: ../js/ui/messageTray.js:1310
#: ../js/ui/messageTray.js:1314
msgid "Open"
msgstr "ખોલો"
#: ../js/ui/messageTray.js:1327
#: ../js/ui/messageTray.js:1331
msgid "Unmute"
msgstr "અવાજ ચાલુ રાખો"
#: ../js/ui/messageTray.js:1327
#: ../js/ui/messageTray.js:1331
msgid "Mute"
msgstr "મૂંગુ"
#: ../js/ui/messageTray.js:2638
#: ../js/ui/messageTray.js:2642
msgid "System Information"
msgstr "સિસ્ટમ જાણકારી"
@@ -741,7 +740,8 @@ msgstr "મોબાઇલ બ્રોડબેન્ડ નેટવર્ક
msgid "A password is required to connect to '%s'."
msgstr "પાસવર્ડ '%s' સાથે જોડાવા માટે જરૂરી છે."
#: ../js/ui/notificationDaemon.js:506 ../src/shell-app.c:374
#: ../js/ui/notificationDaemon.js:484 ../src/shell-app.c:374
#| msgid "Unknown"
msgctxt "program"
msgid "Unknown"
msgstr "અજ્ઞાત"
@@ -778,7 +778,7 @@ msgstr "બહાર નીકળો"
msgid "Activities"
msgstr "પ્રવૃત્તિઓ"
#: ../js/ui/panel.js:971
#: ../js/ui/panel.js:975
msgid "Top Bar"
msgstr "ટોચની પટ્ટી"
@@ -825,7 +825,7 @@ msgstr "દિલગીર છું, કામ કરતુ નથી. મહ
#. "ON" and "OFF") or "toggle-switch-intl" (for toggle
#. switches containing "◯" and "|"). Other values will
#. simply result in invisible toggle switches.
#: ../js/ui/popupMenu.js:723
#: ../js/ui/popupMenu.js:727
msgid "toggle-switch-us"
msgstr "toggle-switch-us"
@@ -867,325 +867,326 @@ msgstr "પાસફ્રેજને યાદ રાખો"
#: ../js/ui/shellMountOperation.js:400 ../js/ui/unlockDialog.js:142
msgid "Unlock"
msgstr "તાળું ખોલો"
msgstr ""
#: ../js/ui/status/accessibility.js:39
#: ../js/ui/status/accessibility.js:47
msgid "Accessibility"
msgstr "ઉપલબ્ધતા"
#: ../js/ui/status/accessibility.js:44
#: ../js/ui/status/accessibility.js:52
msgid "Zoom"
msgstr "નાનુ મોટુ કરો"
#: ../js/ui/status/accessibility.js:51
#: ../js/ui/status/accessibility.js:59
#| msgid "Screen Keyboard"
msgid "Screen Reader"
msgstr "સ્ક્રીન રીડર"
#: ../js/ui/status/accessibility.js:55
#: ../js/ui/status/accessibility.js:63
msgid "Screen Keyboard"
msgstr "સ્ક્રીન કિબોર્ડ"
#: ../js/ui/status/accessibility.js:59
#: ../js/ui/status/accessibility.js:67
msgid "Visual Alerts"
msgstr "દેખાતી ચેતવણીઓ"
#: ../js/ui/status/accessibility.js:62
#: ../js/ui/status/accessibility.js:70
msgid "Sticky Keys"
msgstr "સ્ટીકી કી"
#: ../js/ui/status/accessibility.js:65
#: ../js/ui/status/accessibility.js:73
msgid "Slow Keys"
msgstr "ધીમી કી"
#: ../js/ui/status/accessibility.js:68
#: ../js/ui/status/accessibility.js:76
msgid "Bounce Keys"
msgstr "બાઉન્સ કી"
#: ../js/ui/status/accessibility.js:71
#: ../js/ui/status/accessibility.js:79
msgid "Mouse Keys"
msgstr "માઉસ કીઓ"
#: ../js/ui/status/accessibility.js:75
#: ../js/ui/status/accessibility.js:83
msgid "Universal Access Settings"
msgstr "યુનિવર્સલ વપરાશ સુયોજનો"
#: ../js/ui/status/accessibility.js:113
#: ../js/ui/status/accessibility.js:121
msgid "High Contrast"
msgstr "ઉચ્ચ વિરોધાભાસ"
#: ../js/ui/status/accessibility.js:150
#: ../js/ui/status/accessibility.js:158
msgid "Large Text"
msgstr "લાંબુ લખાણ"
#: ../js/ui/status/bluetooth.js:27 ../js/ui/status/bluetooth.js:31
#: ../js/ui/status/bluetooth.js:256 ../js/ui/status/bluetooth.js:309
#: ../js/ui/status/bluetooth.js:340 ../js/ui/status/bluetooth.js:376
#: ../js/ui/status/bluetooth.js:405 ../js/ui/status/network.js:841
#: ../js/ui/status/bluetooth.js:31 ../js/ui/status/bluetooth.js:35
#: ../js/ui/status/bluetooth.js:260 ../js/ui/status/bluetooth.js:313
#: ../js/ui/status/bluetooth.js:344 ../js/ui/status/bluetooth.js:380
#: ../js/ui/status/bluetooth.js:409 ../js/ui/status/network.js:844
msgid "Bluetooth"
msgstr "બ્લુટુથ"
#: ../js/ui/status/bluetooth.js:44
#: ../js/ui/status/bluetooth.js:48
msgid "Visibility"
msgstr "દૃશ્યતા"
#: ../js/ui/status/bluetooth.js:58
#: ../js/ui/status/bluetooth.js:62
msgid "Send Files to Device..."
msgstr "ઉપકરણમાં ફાઇલોને મોકલો..."
#: ../js/ui/status/bluetooth.js:59
#: ../js/ui/status/bluetooth.js:63
msgid "Set up a New Device..."
msgstr "નવા ઉપકરણને સુયોજિત કરો..."
#: ../js/ui/status/bluetooth.js:83
#: ../js/ui/status/bluetooth.js:87
msgid "Bluetooth Settings"
msgstr "બ્લુટુથ સુયોજનો"
#. TRANSLATORS: this means that bluetooth was disabled by hardware rfkill
#: ../js/ui/status/bluetooth.js:108 ../js/ui/status/network.js:208
#: ../js/ui/status/bluetooth.js:112 ../js/ui/status/network.js:211
msgid "hardware disabled"
msgstr "હાર્ડવેર નિષ્ક્રિય"
#: ../js/ui/status/bluetooth.js:201
#: ../js/ui/status/bluetooth.js:205
msgid "Connection"
msgstr "જોડાણ"
#: ../js/ui/status/bluetooth.js:212 ../js/ui/status/network.js:442
#: ../js/ui/status/bluetooth.js:216 ../js/ui/status/network.js:445
msgid "disconnecting..."
msgstr "જોડાઇ તૂટી રહ્યુ છે..."
#: ../js/ui/status/bluetooth.js:225 ../js/ui/status/network.js:448
#: ../js/ui/status/network.js:908
#: ../js/ui/status/bluetooth.js:229 ../js/ui/status/network.js:451
#: ../js/ui/status/network.js:911
msgid "connecting..."
msgstr "જોડાઇ રહ્યા છે..."
#: ../js/ui/status/bluetooth.js:243
#: ../js/ui/status/bluetooth.js:247
msgid "Send Files..."
msgstr "ફાઇલોને મોકલો..."
#: ../js/ui/status/bluetooth.js:248
#: ../js/ui/status/bluetooth.js:252
msgid "Browse Files..."
msgstr "ફાઇલોને બ્રાઉઝ કરો..."
#: ../js/ui/status/bluetooth.js:257
#: ../js/ui/status/bluetooth.js:261
msgid "Error browsing device"
msgstr "ઉપકરણને બ્રાઉઝ કરતી વખતે ભૂલ"
#: ../js/ui/status/bluetooth.js:258
#: ../js/ui/status/bluetooth.js:262
#, c-format
msgid "The requested device cannot be browsed, error is '%s'"
msgstr "સુચિત ઉપકરણને બ્રાઉઝ કરી શકાતુ નથી, ભૂલ '%s' છે"
#: ../js/ui/status/bluetooth.js:266
#: ../js/ui/status/bluetooth.js:270
msgid "Keyboard Settings"
msgstr "કીબોર્ડ સુયોજનો"
#: ../js/ui/status/bluetooth.js:269
#: ../js/ui/status/bluetooth.js:273
msgid "Mouse Settings"
msgstr "માઉસ સુયોજનો"
#: ../js/ui/status/bluetooth.js:274 ../js/ui/status/volume.js:54
#: ../js/ui/status/bluetooth.js:278 ../js/ui/status/volume.js:59
msgid "Sound Settings"
msgstr "સાઇન્ડ સુયોજનો"
#: ../js/ui/status/bluetooth.js:341
#: ../js/ui/status/bluetooth.js:345
#, c-format
msgid "Authorization request from %s"
msgstr "%s માંથી સત્તાધિકરણ માંગણી"
#: ../js/ui/status/bluetooth.js:347
#: ../js/ui/status/bluetooth.js:351
#, c-format
msgid "Device %s wants access to the service '%s'"
msgstr "ઉપકરણ %s એ સેવા %s' માટે પ્રવેશ ઇચ્છે છે"
#: ../js/ui/status/bluetooth.js:349
#: ../js/ui/status/bluetooth.js:353
msgid "Always grant access"
msgstr "હંમેશા વપરાશ મંજૂર કરો"
#: ../js/ui/status/bluetooth.js:350
#: ../js/ui/status/bluetooth.js:354
msgid "Grant this time only"
msgstr "ફક્ત આ સમયે સંમતિ આપો"
#: ../js/ui/status/bluetooth.js:351 ../js/ui/telepathyClient.js:1097
#: ../js/ui/status/bluetooth.js:355 ../js/ui/telepathyClient.js:1097
msgid "Reject"
msgstr "રદ કરો"
#: ../js/ui/status/bluetooth.js:377
#: ../js/ui/status/bluetooth.js:381
#, c-format
msgid "Pairing confirmation for %s"
msgstr "%s માટો જોડીની ખાતરી"
#: ../js/ui/status/bluetooth.js:383 ../js/ui/status/bluetooth.js:413
#: ../js/ui/status/bluetooth.js:387 ../js/ui/status/bluetooth.js:417
#, c-format
msgid "Device %s wants to pair with this computer"
msgstr "ઉપકરણ %s આ કમ્પ્યૂટર સાથે જોડી કરવા માંગે છે"
#: ../js/ui/status/bluetooth.js:384
#: ../js/ui/status/bluetooth.js:388
#, fuzzy, c-format
#| msgid "Please confirm whether the PIN '%s' matches the one on the device."
msgid "Please confirm whether the PIN '%06d' matches the one on the device."
msgstr "મહેરબાની કરીને ખાતરી કરો કે શું PIN '%s' એ ઉપકરણ પર એક સાથે બંધબેસે છે."
#: ../js/ui/status/bluetooth.js:386
#: ../js/ui/status/bluetooth.js:390
msgid "Matches"
msgstr "બંધબેસે છે"
#: ../js/ui/status/bluetooth.js:387
#: ../js/ui/status/bluetooth.js:391
msgid "Does not match"
msgstr "બંધબેસતુ નથી"
#: ../js/ui/status/bluetooth.js:406
#: ../js/ui/status/bluetooth.js:410
#, c-format
msgid "Pairing request for %s"
msgstr "%s માટે જોડી માંગણી"
#: ../js/ui/status/bluetooth.js:414
#: ../js/ui/status/bluetooth.js:418
msgid "Please enter the PIN mentioned on the device."
msgstr "મહેરબાની કરીને ઉપકરણ પર દર્શાવેલ PIN દાખલ કરો."
#: ../js/ui/status/bluetooth.js:431
#: ../js/ui/status/bluetooth.js:435
msgid "OK"
msgstr "બરાબર"
#: ../js/ui/status/keyboard.js:175
#: ../js/ui/status/keyboard.js:178
msgid "Show Keyboard Layout"
msgstr "કીબોર્ડ લેઆઉટને બતાવો"
#: ../js/ui/status/keyboard.js:177
#: ../js/ui/status/keyboard.js:180
msgid "Region and Language Settings"
msgstr "વિસ્તાર અને ભાષા સુયોજનો"
#: ../js/ui/status/network.js:93
#: ../js/ui/status/network.js:96
msgid "<unknown>"
msgstr "<અજ્ઞાત>"
#. Translators: this indicates that wireless or wwan is disabled by hardware killswitch
#: ../js/ui/status/network.js:230
#: ../js/ui/status/network.js:233
msgid "disabled"
msgstr "નિષ્ક્રિય"
#. Translators: this is for network devices that are physically present but are not
#. under NetworkManager's control (and thus cannot be used in the menu)
#: ../js/ui/status/network.js:440
#: ../js/ui/status/network.js:443
msgid "unmanaged"
msgstr "સંચાલિત થયેલ નથી"
#. Translators: this is for network connections that require some kind of key or password
#: ../js/ui/status/network.js:451 ../js/ui/status/network.js:911
#: ../js/ui/status/network.js:454 ../js/ui/status/network.js:914
msgid "authentication required"
msgstr "સત્તાધિકરણ જરૂરી"
#. Translators: this is for devices that require some kind of firmware or kernel
#. module, which is missing
#: ../js/ui/status/network.js:461
#: ../js/ui/status/network.js:464
msgid "firmware missing"
msgstr "ફર્મવેર ગેરહાજર"
#. Translators: this is for wired network devices that are physically disconnected
#: ../js/ui/status/network.js:468
#: ../js/ui/status/network.js:471
msgid "cable unplugged"
msgstr "કેબલ પ્લગ થયેલ નથી"
#. Translators: this is for a network device that cannot be activated (for example it
#. is disabled by rfkill, or it has no coverage
#: ../js/ui/status/network.js:473
#: ../js/ui/status/network.js:476
msgid "unavailable"
msgstr "બિનઉપલબ્ધ"
#: ../js/ui/status/network.js:475 ../js/ui/status/network.js:913
#: ../js/ui/status/network.js:478 ../js/ui/status/network.js:916
msgid "connection failed"
msgstr "જોડાણ નિષ્ફળ"
#: ../js/ui/status/network.js:536 ../js/ui/status/network.js:1534
#: ../js/ui/status/network.js:539 ../js/ui/status/network.js:1537
msgid "More..."
msgstr "વધારે..."
#. TRANSLATORS: this is the indication that a connection for another logged in user is active,
#. and we cannot access its settings (including the name)
#: ../js/ui/status/network.js:572 ../js/ui/status/network.js:1464
#: ../js/ui/status/network.js:575 ../js/ui/status/network.js:1467
msgid "Connected (private)"
msgstr "જોડાયેલ (ખાનગી)"
#: ../js/ui/status/network.js:647
#: ../js/ui/status/network.js:650
msgid "Auto Ethernet"
msgstr "આપમેળે ઇથરનેટ"
#: ../js/ui/status/network.js:705
#: ../js/ui/status/network.js:708
msgid "Auto broadband"
msgstr "આપમેળે બ્રોડબેન્ડ"
#: ../js/ui/status/network.js:708
#: ../js/ui/status/network.js:711
msgid "Auto dial-up"
msgstr ""
#. TRANSLATORS: this the automatic wireless connection name (including the network name)
#: ../js/ui/status/network.js:827 ../js/ui/status/network.js:1481
#: ../js/ui/status/network.js:830 ../js/ui/status/network.js:1484
#, c-format
msgid "Auto %s"
msgstr "આપમેળે %s"
#: ../js/ui/status/network.js:829
#: ../js/ui/status/network.js:832
msgid "Auto bluetooth"
msgstr "આપમેળે બ્લુટુથ"
#: ../js/ui/status/network.js:1483
#: ../js/ui/status/network.js:1486
msgid "Auto wireless"
msgstr ""
#: ../js/ui/status/network.js:1592
#: ../js/ui/status/network.js:1595
msgid "Enable networking"
msgstr "નેટવર્કીંગ સક્રિય કરો"
#: ../js/ui/status/network.js:1614
#: ../js/ui/status/network.js:1617
msgid "Wired"
msgstr "વાયરવાળું"
#: ../js/ui/status/network.js:1625
#: ../js/ui/status/network.js:1628
msgid "Wireless"
msgstr "વાયરલેસ"
#: ../js/ui/status/network.js:1635
#: ../js/ui/status/network.js:1638
msgid "Mobile broadband"
msgstr "મોબાઇલ બ્રોડબેન્ડ"
#: ../js/ui/status/network.js:1645
#: ../js/ui/status/network.js:1648
msgid "VPN Connections"
msgstr "VPN જોડાણો"
#: ../js/ui/status/network.js:1652
#: ../js/ui/status/network.js:1655
msgid "Network Settings"
msgstr "નેટવર્ક સુયોજનો"
#: ../js/ui/status/network.js:1709
#: ../js/ui/status/network.js:1712
msgid "Network Manager"
msgstr "નેટવર્ક સંચાલક"
#: ../js/ui/status/network.js:1802
#: ../js/ui/status/network.js:1805
msgid "Connection failed"
msgstr "જોડાણ નિષ્ફળ"
#: ../js/ui/status/network.js:1803
#: ../js/ui/status/network.js:1806
msgid "Activation of network connection failed"
msgstr "નેટવર્ક જોડાણનું સક્રિયકરણ નિષ્ફળ થયેલ છે"
#: ../js/ui/status/network.js:2066
#: ../js/ui/status/network.js:2069
msgid "Networking is disabled"
msgstr "નેટવર્કીંગ નિષ્ક્રિય થયેલ છે"
#: ../js/ui/status/power.js:55
#: ../js/ui/status/power.js:59
msgid "Battery"
msgstr "બેટરી"
#: ../js/ui/status/power.js:72
#: ../js/ui/status/power.js:76
msgid "Power Settings"
msgstr "પાવર સુયોજનો"
#. 0 is reported when UPower does not have enough data
#. to estimate battery life
#: ../js/ui/status/power.js:100
#: ../js/ui/status/power.js:104
msgid "Estimating..."
msgstr "અંદાજ કરી રહ્યા છે..."
#: ../js/ui/status/power.js:107
#: ../js/ui/status/power.js:111
#, c-format
msgid "%d hour remaining"
msgid_plural "%d hours remaining"
@@ -1193,87 +1194,88 @@ msgstr[0] "%d કલાક બાકી રહેલ છે"
msgstr[1] "%d કલાક બાકી રહેલ છે"
#. TRANSLATORS: this is a time string, as in "%d hours %d minutes remaining"
#: ../js/ui/status/power.js:110
#: ../js/ui/status/power.js:114
#, c-format
msgid "%d %s %d %s remaining"
msgstr "%d %s %d %s બાકી રહેલ છે"
#: ../js/ui/status/power.js:112
#: ../js/ui/status/power.js:116
msgid "hour"
msgid_plural "hours"
msgstr[0] "કલાક"
msgstr[1] "કલાકો"
#: ../js/ui/status/power.js:112
#: ../js/ui/status/power.js:116
msgid "minute"
msgid_plural "minutes"
msgstr[0] "મિનિટ"
msgstr[1] "મિનિટો"
#: ../js/ui/status/power.js:115
#: ../js/ui/status/power.js:119
#, c-format
msgid "%d minute remaining"
msgid_plural "%d minutes remaining"
msgstr[0] "%d મિનિટ બાકી રહી છે"
msgstr[1] "%d મિનિટ બાકી રહી છે"
#: ../js/ui/status/power.js:118 ../js/ui/status/power.js:188
#: ../js/ui/status/power.js:122 ../js/ui/status/power.js:192
#, c-format
msgctxt "percent of battery remaining"
msgid "%d%%"
msgstr "%d%%"
#: ../js/ui/status/power.js:195
#: ../js/ui/status/power.js:199
msgid "AC adapter"
msgstr "AC ઍડપ્ટર"
#: ../js/ui/status/power.js:197
#: ../js/ui/status/power.js:201
msgid "Laptop battery"
msgstr "લેપટોપ બેટરી"
#: ../js/ui/status/power.js:199
#: ../js/ui/status/power.js:203
msgid "UPS"
msgstr "UPS"
#: ../js/ui/status/power.js:201
#: ../js/ui/status/power.js:205
msgid "Monitor"
msgstr "મોનિટર"
#: ../js/ui/status/power.js:203
#: ../js/ui/status/power.js:207
msgid "Mouse"
msgstr "માઉસ"
#: ../js/ui/status/power.js:207
#: ../js/ui/status/power.js:211
msgid "PDA"
msgstr "PDA"
#: ../js/ui/status/power.js:209
#: ../js/ui/status/power.js:213
msgid "Cell phone"
msgstr "સેલ ફોન"
#: ../js/ui/status/power.js:211
#: ../js/ui/status/power.js:215
msgid "Media player"
msgstr "મીડિયા પ્લેયર"
#: ../js/ui/status/power.js:213
#: ../js/ui/status/power.js:217
msgid "Tablet"
msgstr "ટૅબલેટ"
#: ../js/ui/status/power.js:215
#: ../js/ui/status/power.js:219
msgid "Computer"
msgstr "કમ્પ્યૂટર"
#: ../js/ui/status/power.js:217
#: ../js/ui/status/power.js:221
#| msgid "Unknown"
msgctxt "device"
msgid "Unknown"
msgstr "અજ્ઞાત"
#. Translators: This is the label for audio volume
#: ../js/ui/status/volume.js:20 ../js/ui/status/volume.js:34
#: ../js/ui/status/volume.js:25 ../js/ui/status/volume.js:39
msgid "Volume"
msgstr "વોલ્યુમ"
#: ../js/ui/status/volume.js:46
#: ../js/ui/status/volume.js:51
msgid "Microphone"
msgstr "માઇક્રોફોન"
@@ -1538,6 +1540,7 @@ msgid "Switch User"
msgstr "વપરાશકર્તાને બદલો"
#: ../js/ui/userMenu.js:568
#| msgid "Switch User"
msgid "Switch Session"
msgstr "સત્ર બદલો"
@@ -1550,6 +1553,8 @@ msgid "System Settings"
msgstr "સિસ્ટમ સુયોજનો"
#: ../js/ui/userMenu.js:711
#| msgctxt "title"
#| msgid "Log Out"
msgid "Log Out"
msgstr "બહાર નીકળો"
@@ -1605,6 +1610,7 @@ msgid "'%s' is ready"
msgstr "'%s' તૈયાર છે"
#: ../src/calendar-server/evolution-calendar.desktop.in.in.h:1
#| msgid "Open Calendar"
msgid "Evolution Calendar"
msgstr "Evolution કૅલેન્ડર"

410
po/he.po

File diff suppressed because it is too large Load Diff

920
po/mr.po

File diff suppressed because it is too large Load Diff

657
po/pa.po

File diff suppressed because it is too large Load Diff

258
po/sl.po
View File

@@ -8,8 +8,8 @@ msgid ""
msgstr ""
"Project-Id-Version: gnome-shell master\n"
"Report-Msgid-Bugs-To: http://bugzilla.gnome.org/enter_bug.cgi?product=gnome-shell&keywords=I18N+L10N&component=general\n"
"POT-Creation-Date: 2012-08-06 22:25+0000\n"
"PO-Revision-Date: 2012-08-07 08:42+0100\n"
"POT-Creation-Date: 2012-07-29 08:27+0000\n"
"PO-Revision-Date: 2012-07-29 14:11+0100\n"
"Last-Translator: Matej Urbančič <mateju@svn.gnome.org>\n"
"Language-Team: Slovenian GNOME Translation Team <gnome-si@googlegroups.com>\n"
"Language: Slovenian\n"
@@ -153,25 +153,25 @@ msgid "There was an error loading the preferences dialog for %s:"
msgstr "Prišlo je do napake med nalaganjem pogovornega okna z možnosti za %s:"
#: ../js/extensionPrefs/main.js:164
msgid "Extension"
msgstr "Pripona"
msgid "<b>Extension</b>"
msgstr "<b>Pripona</b>"
#: ../js/extensionPrefs/main.js:188
msgid "Select an extension to configure using the combobox above."
msgstr "Razširitev za nastavljanje je mogoče izbrati iz spustnega seznama zgoraj."
#: ../js/gdm/loginDialog.js:572
#: ../js/gdm/loginDialog.js:550
msgid "Session..."
msgstr "Seja ..."
#: ../js/gdm/loginDialog.js:721
#: ../js/gdm/loginDialog.js:699
msgctxt "title"
msgid "Sign In"
msgstr "Prijava"
#. Translators: this message is shown below the password entry field
#. to indicate the user can swipe their finger instead
#: ../js/gdm/loginDialog.js:766
#: ../js/gdm/loginDialog.js:744
#: ../js/ui/unlockDialog.js:124
msgid "(or swipe finger)"
msgstr "(ali pa povlecite prst)"
@@ -179,26 +179,26 @@ msgstr "(ali pa povlecite prst)"
#. translators: this message is shown below the user list on the
#. login screen. It can be activated to reveal an entry for
#. manually entering the username.
#: ../js/gdm/loginDialog.js:787
#: ../js/gdm/loginDialog.js:765
msgid "Not listed?"
msgstr "Ali je ni na seznamu?"
#: ../js/gdm/loginDialog.js:930
#: ../js/gdm/loginDialog.js:908
#: ../js/ui/endSessionDialog.js:406
#: ../js/ui/extensionDownloader.js:195
#: ../js/ui/networkAgent.js:153
#: ../js/ui/polkitAuthenticationAgent.js:176
#: ../js/ui/shellMountOperation.js:396
#: ../js/ui/status/bluetooth.js:432
#: ../js/ui/status/bluetooth.js:436
msgid "Cancel"
msgstr "Prekliči"
#: ../js/gdm/loginDialog.js:935
#: ../js/gdm/loginDialog.js:913
msgctxt "button"
msgid "Sign In"
msgstr "Prijava"
#: ../js/gdm/loginDialog.js:1280
#: ../js/gdm/loginDialog.js:1256
msgid "Login Window"
msgstr "Prijavno okno"
@@ -274,12 +274,12 @@ msgstr "Program \"%s\" je odstranjen iz priljubljenih."
msgid "Removable Devices"
msgstr "Odstranljive naprave"
#: ../js/ui/autorunManager.js:548
#: ../js/ui/autorunManager.js:549
#, c-format
msgid "Open with %s"
msgstr "Odpri s programom %s"
#: ../js/ui/autorunManager.js:574
#: ../js/ui/autorunManager.js:575
msgid "Eject"
msgstr "Izvrzi"
@@ -560,8 +560,8 @@ msgid "tray"
msgstr "sistemska vrstica"
#: ../js/ui/keyboard.js:545
#: ../js/ui/status/keyboard.js:146
#: ../js/ui/status/power.js:205
#: ../js/ui/status/keyboard.js:149
#: ../js/ui/status/power.js:209
msgid "Keyboard"
msgstr "Tipkovnica"
@@ -625,7 +625,7 @@ msgid "Web Page"
msgstr "Spletna stran"
#. Translators: this is a filename used for screencast recording
#: ../js/ui/main.js:138
#: ../js/ui/main.js:140
#, no-c-format
msgid "Screencast from %d %t"
msgstr "Screencast z %d %t"
@@ -726,7 +726,7 @@ msgstr "Geslo mobilnega širokopasovnega dostopa"
msgid "A password is required to connect to '%s'."
msgstr "Za povezavo z omrežjem '%s' je zahtevano geslo."
#: ../js/ui/notificationDaemon.js:506
#: ../js/ui/notificationDaemon.js:484
#: ../src/shell-app.c:374
msgctxt "program"
msgid "Unknown"
@@ -764,7 +764,7 @@ msgstr "Končaj"
msgid "Activities"
msgstr "Dejavnosti"
#: ../js/ui/panel.js:971
#: ../js/ui/panel.js:975
msgid "Top Bar"
msgstr "Vrhnja vrstica"
@@ -856,337 +856,337 @@ msgstr "Zapomni si šifrirno geslo"
msgid "Unlock"
msgstr "Odkleni"
#: ../js/ui/status/accessibility.js:39
#: ../js/ui/status/accessibility.js:47
msgid "Accessibility"
msgstr "Dostopnost"
#: ../js/ui/status/accessibility.js:44
#: ../js/ui/status/accessibility.js:52
msgid "Zoom"
msgstr "Približanje"
#: ../js/ui/status/accessibility.js:51
#: ../js/ui/status/accessibility.js:59
msgid "Screen Reader"
msgstr "Zaslonski bralnik"
#: ../js/ui/status/accessibility.js:55
#: ../js/ui/status/accessibility.js:63
msgid "Screen Keyboard"
msgstr "Zaslonska tipkovnica"
#: ../js/ui/status/accessibility.js:59
#: ../js/ui/status/accessibility.js:67
msgid "Visual Alerts"
msgstr "Vidna opozorila"
#: ../js/ui/status/accessibility.js:62
#: ../js/ui/status/accessibility.js:70
msgid "Sticky Keys"
msgstr "Lepljive tipke"
#: ../js/ui/status/accessibility.js:65
#: ../js/ui/status/accessibility.js:73
msgid "Slow Keys"
msgstr "Počasne tipke"
#: ../js/ui/status/accessibility.js:68
#: ../js/ui/status/accessibility.js:76
msgid "Bounce Keys"
msgstr "Odskočne tipke"
#: ../js/ui/status/accessibility.js:71
#: ../js/ui/status/accessibility.js:79
msgid "Mouse Keys"
msgstr "Miškine tipke"
#: ../js/ui/status/accessibility.js:75
#: ../js/ui/status/accessibility.js:83
msgid "Universal Access Settings"
msgstr "Splošne nastavitve dostopa"
#: ../js/ui/status/accessibility.js:113
#: ../js/ui/status/accessibility.js:121
msgid "High Contrast"
msgstr "Visok kontrast"
#: ../js/ui/status/accessibility.js:150
#: ../js/ui/status/accessibility.js:158
msgid "Large Text"
msgstr "Veliko besedilo"
#: ../js/ui/status/bluetooth.js:27
#: ../js/ui/status/bluetooth.js:31
#: ../js/ui/status/bluetooth.js:256
#: ../js/ui/status/bluetooth.js:309
#: ../js/ui/status/bluetooth.js:340
#: ../js/ui/status/bluetooth.js:376
#: ../js/ui/status/bluetooth.js:405
#: ../js/ui/status/network.js:841
#: ../js/ui/status/bluetooth.js:35
#: ../js/ui/status/bluetooth.js:260
#: ../js/ui/status/bluetooth.js:313
#: ../js/ui/status/bluetooth.js:344
#: ../js/ui/status/bluetooth.js:380
#: ../js/ui/status/bluetooth.js:409
#: ../js/ui/status/network.js:844
msgid "Bluetooth"
msgstr "Bluetooth"
#: ../js/ui/status/bluetooth.js:44
#: ../js/ui/status/bluetooth.js:48
msgid "Visibility"
msgstr "Vidnost"
#: ../js/ui/status/bluetooth.js:58
#: ../js/ui/status/bluetooth.js:62
msgid "Send Files to Device..."
msgstr "Pošilji datoteke na napravo ..."
#: ../js/ui/status/bluetooth.js:59
#: ../js/ui/status/bluetooth.js:63
msgid "Set up a New Device..."
msgstr "Nastavitev nove naprave ..."
#: ../js/ui/status/bluetooth.js:83
#: ../js/ui/status/bluetooth.js:87
msgid "Bluetooth Settings"
msgstr "Nastavitve za Bluetooth"
#. TRANSLATORS: this means that bluetooth was disabled by hardware rfkill
#: ../js/ui/status/bluetooth.js:108
#: ../js/ui/status/network.js:208
#: ../js/ui/status/bluetooth.js:112
#: ../js/ui/status/network.js:211
msgid "hardware disabled"
msgstr "strojno onemogočen"
#: ../js/ui/status/bluetooth.js:201
#: ../js/ui/status/bluetooth.js:205
msgid "Connection"
msgstr "Povezava"
#: ../js/ui/status/bluetooth.js:212
#: ../js/ui/status/network.js:442
#: ../js/ui/status/bluetooth.js:216
#: ../js/ui/status/network.js:445
msgid "disconnecting..."
msgstr "prekinjanje povezave ..."
#: ../js/ui/status/bluetooth.js:225
#: ../js/ui/status/network.js:448
#: ../js/ui/status/network.js:908
#: ../js/ui/status/bluetooth.js:229
#: ../js/ui/status/network.js:451
#: ../js/ui/status/network.js:911
msgid "connecting..."
msgstr "povezovanje ..."
#: ../js/ui/status/bluetooth.js:243
#: ../js/ui/status/bluetooth.js:247
msgid "Send Files..."
msgstr "Pošlji datoteke ..."
#: ../js/ui/status/bluetooth.js:248
#: ../js/ui/status/bluetooth.js:252
msgid "Browse Files..."
msgstr "Brskanje datotek ..."
#: ../js/ui/status/bluetooth.js:257
#: ../js/ui/status/bluetooth.js:261
msgid "Error browsing device"
msgstr "Napaka med brskanjem po napravi"
#: ../js/ui/status/bluetooth.js:258
#: ../js/ui/status/bluetooth.js:262
#, c-format
msgid "The requested device cannot be browsed, error is '%s'"
msgstr "Po zahtevani naprave ni mogoče brskati, napaka je '%s'"
#: ../js/ui/status/bluetooth.js:266
#: ../js/ui/status/bluetooth.js:270
msgid "Keyboard Settings"
msgstr "Nastavitve tipkovnice"
#: ../js/ui/status/bluetooth.js:269
#: ../js/ui/status/bluetooth.js:273
msgid "Mouse Settings"
msgstr "Nastavitve miške"
#: ../js/ui/status/bluetooth.js:274
#: ../js/ui/status/volume.js:54
#: ../js/ui/status/bluetooth.js:278
#: ../js/ui/status/volume.js:59
msgid "Sound Settings"
msgstr "Nastavitve zvoka"
#: ../js/ui/status/bluetooth.js:341
#: ../js/ui/status/bluetooth.js:345
#, c-format
msgid "Authorization request from %s"
msgstr "Zahteva za pooblastitev od %s"
#: ../js/ui/status/bluetooth.js:347
#: ../js/ui/status/bluetooth.js:351
#, c-format
msgid "Device %s wants access to the service '%s'"
msgstr "Naprava %s želi dostop do storitve '%s'."
#: ../js/ui/status/bluetooth.js:349
#: ../js/ui/status/bluetooth.js:353
msgid "Always grant access"
msgstr "Vedno odobri dostop"
#: ../js/ui/status/bluetooth.js:350
#: ../js/ui/status/bluetooth.js:354
msgid "Grant this time only"
msgstr "Odobri le tokrat"
#: ../js/ui/status/bluetooth.js:351
#: ../js/ui/status/bluetooth.js:355
#: ../js/ui/telepathyClient.js:1097
msgid "Reject"
msgstr "Zavrni"
#: ../js/ui/status/bluetooth.js:377
#: ../js/ui/status/bluetooth.js:381
#, c-format
msgid "Pairing confirmation for %s"
msgstr "Potrditev razčlenjevanja za %s"
#: ../js/ui/status/bluetooth.js:383
#: ../js/ui/status/bluetooth.js:413
#: ../js/ui/status/bluetooth.js:387
#: ../js/ui/status/bluetooth.js:417
#, c-format
msgid "Device %s wants to pair with this computer"
msgstr "Naprava %s se poskuša seznaniti s tem računalnikom"
#: ../js/ui/status/bluetooth.js:384
#: ../js/ui/status/bluetooth.js:388
#, c-format
msgid "Please confirm whether the PIN '%06d' matches the one on the device."
msgstr "Potrdite, ali se PIN '%06d' ujema s tistim na napravi."
#: ../js/ui/status/bluetooth.js:386
#: ../js/ui/status/bluetooth.js:390
msgid "Matches"
msgstr "Ujemanja"
#: ../js/ui/status/bluetooth.js:387
#: ../js/ui/status/bluetooth.js:391
msgid "Does not match"
msgstr "Se ne ujema"
#: ../js/ui/status/bluetooth.js:406
#: ../js/ui/status/bluetooth.js:410
#, c-format
msgid "Pairing request for %s"
msgstr "Zahteva razčlenjevanja za %s"
#: ../js/ui/status/bluetooth.js:414
#: ../js/ui/status/bluetooth.js:418
msgid "Please enter the PIN mentioned on the device."
msgstr "Vnesite PIN, ki je naveden na napravi."
#: ../js/ui/status/bluetooth.js:431
#: ../js/ui/status/bluetooth.js:435
msgid "OK"
msgstr "V redu"
#: ../js/ui/status/keyboard.js:175
#: ../js/ui/status/keyboard.js:178
msgid "Show Keyboard Layout"
msgstr "Pokaži razporeditev tipkovnice"
#: ../js/ui/status/keyboard.js:177
#: ../js/ui/status/keyboard.js:180
msgid "Region and Language Settings"
msgstr "Nastavitve območja in jezika"
#: ../js/ui/status/network.js:93
#: ../js/ui/status/network.js:96
msgid "<unknown>"
msgstr "<neznano>"
#. Translators: this indicates that wireless or wwan is disabled by hardware killswitch
#: ../js/ui/status/network.js:230
#: ../js/ui/status/network.js:233
msgid "disabled"
msgstr "onemogočeno"
#. Translators: this is for network devices that are physically present but are not
#. under NetworkManager's control (and thus cannot be used in the menu)
#: ../js/ui/status/network.js:440
#: ../js/ui/status/network.js:443
msgid "unmanaged"
msgstr "neupravljano"
#. Translators: this is for network connections that require some kind of key or password
#: ../js/ui/status/network.js:451
#: ../js/ui/status/network.js:911
#: ../js/ui/status/network.js:454
#: ../js/ui/status/network.js:914
msgid "authentication required"
msgstr "zahtevana je overitev"
#. Translators: this is for devices that require some kind of firmware or kernel
#. module, which is missing
#: ../js/ui/status/network.js:461
#: ../js/ui/status/network.js:464
msgid "firmware missing"
msgstr "manjka strojna programska oprema"
#. Translators: this is for wired network devices that are physically disconnected
#: ../js/ui/status/network.js:468
#: ../js/ui/status/network.js:471
msgid "cable unplugged"
msgstr "kabel ni priklopljen"
#. Translators: this is for a network device that cannot be activated (for example it
#. is disabled by rfkill, or it has no coverage
#: ../js/ui/status/network.js:473
#: ../js/ui/status/network.js:476
msgid "unavailable"
msgstr "ni na voljo"
#: ../js/ui/status/network.js:475
#: ../js/ui/status/network.js:913
#: ../js/ui/status/network.js:478
#: ../js/ui/status/network.js:916
msgid "connection failed"
msgstr "povezovanje je spodletelo"
#: ../js/ui/status/network.js:536
#: ../js/ui/status/network.js:1534
#: ../js/ui/status/network.js:539
#: ../js/ui/status/network.js:1537
msgid "More..."
msgstr "Več ..."
#. TRANSLATORS: this is the indication that a connection for another logged in user is active,
#. and we cannot access its settings (including the name)
#: ../js/ui/status/network.js:572
#: ../js/ui/status/network.js:1464
#: ../js/ui/status/network.js:575
#: ../js/ui/status/network.js:1467
msgid "Connected (private)"
msgstr "Povezano (zasebna povezava)"
#: ../js/ui/status/network.js:647
#: ../js/ui/status/network.js:650
msgid "Auto Ethernet"
msgstr "Samodejni eternet"
#: ../js/ui/status/network.js:705
#: ../js/ui/status/network.js:708
msgid "Auto broadband"
msgstr "Samodejni širokopasovni dostop"
#: ../js/ui/status/network.js:708
#: ../js/ui/status/network.js:711
msgid "Auto dial-up"
msgstr "Samodejni klicni dostop"
#. TRANSLATORS: this the automatic wireless connection name (including the network name)
#: ../js/ui/status/network.js:827
#: ../js/ui/status/network.js:1481
#: ../js/ui/status/network.js:830
#: ../js/ui/status/network.js:1484
#, c-format
msgid "Auto %s"
msgstr "Samodejna povezava z %s"
#: ../js/ui/status/network.js:829
#: ../js/ui/status/network.js:832
msgid "Auto bluetooth"
msgstr "Samodejna povezava z Bluetooth"
#: ../js/ui/status/network.js:1483
#: ../js/ui/status/network.js:1486
msgid "Auto wireless"
msgstr "Samodejni brezžični dostop"
#: ../js/ui/status/network.js:1592
#: ../js/ui/status/network.js:1595
msgid "Enable networking"
msgstr "Omogoči omrežje"
#: ../js/ui/status/network.js:1614
#: ../js/ui/status/network.js:1617
msgid "Wired"
msgstr "Žično"
#: ../js/ui/status/network.js:1625
#: ../js/ui/status/network.js:1628
msgid "Wireless"
msgstr "Brezžično"
#: ../js/ui/status/network.js:1635
#: ../js/ui/status/network.js:1638
msgid "Mobile broadband"
msgstr "Mobilni širokopasovni dostop"
#: ../js/ui/status/network.js:1645
#: ../js/ui/status/network.js:1648
msgid "VPN Connections"
msgstr "Povezave VPN"
#: ../js/ui/status/network.js:1652
#: ../js/ui/status/network.js:1655
msgid "Network Settings"
msgstr "Omrežne nastavitve"
#: ../js/ui/status/network.js:1709
#: ../js/ui/status/network.js:1712
msgid "Network Manager"
msgstr "Upravljalnik omrežij"
#: ../js/ui/status/network.js:1802
#: ../js/ui/status/network.js:1805
msgid "Connection failed"
msgstr "Povezava je spodletela"
#: ../js/ui/status/network.js:1803
#: ../js/ui/status/network.js:1806
msgid "Activation of network connection failed"
msgstr "Omogočanje omrežne povezave je spodletelo."
#: ../js/ui/status/network.js:2066
#: ../js/ui/status/network.js:2069
msgid "Networking is disabled"
msgstr "Omrežje je onemogočeno"
#: ../js/ui/status/power.js:55
#: ../js/ui/status/power.js:59
msgid "Battery"
msgstr "Baterija"
#: ../js/ui/status/power.js:72
#: ../js/ui/status/power.js:76
msgid "Power Settings"
msgstr "Upravljanje napajanja"
#. 0 is reported when UPower does not have enough data
#. to estimate battery life
#: ../js/ui/status/power.js:100
#: ../js/ui/status/power.js:104
msgid "Estimating..."
msgstr "Ocenjevanje ...."
#: ../js/ui/status/power.js:107
#: ../js/ui/status/power.js:111
#, c-format
msgid "%d hour remaining"
msgid_plural "%d hours remaining"
@@ -1196,12 +1196,12 @@ msgstr[2] "preostajata še %d uri"
msgstr[3] "preostajajo še %d ure"
#. TRANSLATORS: this is a time string, as in "%d hours %d minutes remaining"
#: ../js/ui/status/power.js:110
#: ../js/ui/status/power.js:114
#, c-format
msgid "%d %s %d %s remaining"
msgstr "Preostaja še %d %s %d %s"
#: ../js/ui/status/power.js:112
#: ../js/ui/status/power.js:116
msgid "hour"
msgid_plural "hours"
msgstr[0] "ur"
@@ -1209,7 +1209,7 @@ msgstr[1] "ura"
msgstr[2] "uri"
msgstr[3] "ure"
#: ../js/ui/status/power.js:112
#: ../js/ui/status/power.js:116
msgid "minute"
msgid_plural "minutes"
msgstr[0] "minut"
@@ -1217,7 +1217,7 @@ msgstr[1] "minuta"
msgstr[2] "minuti"
msgstr[3] "minute"
#: ../js/ui/status/power.js:115
#: ../js/ui/status/power.js:119
#, c-format
msgid "%d minute remaining"
msgid_plural "%d minutes remaining"
@@ -1226,65 +1226,65 @@ msgstr[1] "preostaja še %d minuta"
msgstr[2] "preostajata še %d minuti"
msgstr[3] "preostajajo še %d minute"
#: ../js/ui/status/power.js:118
#: ../js/ui/status/power.js:188
#: ../js/ui/status/power.js:122
#: ../js/ui/status/power.js:192
#, c-format
msgctxt "percent of battery remaining"
msgid "%d%%"
msgstr "%d%%"
#: ../js/ui/status/power.js:195
#: ../js/ui/status/power.js:199
msgid "AC adapter"
msgstr "Električni prilagodilnik"
#: ../js/ui/status/power.js:197
#: ../js/ui/status/power.js:201
msgid "Laptop battery"
msgstr "Baterija prenosnika"
#: ../js/ui/status/power.js:199
#: ../js/ui/status/power.js:203
msgid "UPS"
msgstr "UPS"
#: ../js/ui/status/power.js:201
#: ../js/ui/status/power.js:205
msgid "Monitor"
msgstr "Zaslon"
#: ../js/ui/status/power.js:203
#: ../js/ui/status/power.js:207
msgid "Mouse"
msgstr "Miška"
#: ../js/ui/status/power.js:207
#: ../js/ui/status/power.js:211
msgid "PDA"
msgstr "Dlančnik"
#: ../js/ui/status/power.js:209
#: ../js/ui/status/power.js:213
msgid "Cell phone"
msgstr "Mobilni telefon"
#: ../js/ui/status/power.js:211
#: ../js/ui/status/power.js:215
msgid "Media player"
msgstr "Predstavni predvajalnik"
#: ../js/ui/status/power.js:213
#: ../js/ui/status/power.js:217
msgid "Tablet"
msgstr "Tablični računalnik"
#: ../js/ui/status/power.js:215
#: ../js/ui/status/power.js:219
msgid "Computer"
msgstr "Računalnik"
#: ../js/ui/status/power.js:217
#: ../js/ui/status/power.js:221
msgctxt "device"
msgid "Unknown"
msgstr "Neznano"
#. Translators: This is the label for audio volume
#: ../js/ui/status/volume.js:20
#: ../js/ui/status/volume.js:34
#: ../js/ui/status/volume.js:25
#: ../js/ui/status/volume.js:39
msgid "Volume"
msgstr "Glasnost"
#: ../js/ui/status/volume.js:46
#: ../js/ui/status/volume.js:51
msgid "Microphone"
msgstr "Mikrofon"

1025
po/sr.po

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -316,21 +316,15 @@ shell_idle_monitor_init (ShellIdleMonitor *monitor)
monitor->priv->counter = None;
}
/**
* shell_idle_monitor_get:
*
* Returns: (transfer none): the global #ShellIdleMonitor.
*/
ShellIdleMonitor *
shell_idle_monitor_get (void)
shell_idle_monitor_new (void)
{
static ShellIdleMonitor *idle_monitor;
GObject *idle_monitor;
if (G_UNLIKELY (idle_monitor == NULL))
idle_monitor = g_object_new (SHELL_TYPE_IDLE_MONITOR,
NULL);
idle_monitor = g_object_new (SHELL_TYPE_IDLE_MONITOR,
NULL);
return idle_monitor;
return SHELL_IDLE_MONITOR (idle_monitor);
}
static gboolean
@@ -416,14 +410,3 @@ shell_idle_monitor_remove_watch (ShellIdleMonitor *monitor,
g_hash_table_remove (monitor->priv->watches,
GUINT_TO_POINTER (id));
}
gint64
shell_idle_monitor_get_idletime (ShellIdleMonitor *monitor)
{
XSyncValue value;
if (!XSyncQueryCounter (monitor->priv->display, monitor->priv->counter, &value))
return FALSE;
return _xsyncvalue_to_int64 (value);
}

View File

@@ -56,7 +56,7 @@ typedef void (*ShellIdleMonitorWatchFunc) (ShellIdleMonitor *monitor,
GType shell_idle_monitor_get_type (void);
ShellIdleMonitor * shell_idle_monitor_get (void);
ShellIdleMonitor * shell_idle_monitor_new (void);
guint shell_idle_monitor_add_watch (ShellIdleMonitor *monitor,
guint interval,
@@ -67,8 +67,6 @@ guint shell_idle_monitor_add_watch (ShellIdleMonitor *mo
void shell_idle_monitor_remove_watch (ShellIdleMonitor *monitor,
guint id);
gint64 shell_idle_monitor_get_idletime (ShellIdleMonitor *monitor);
G_END_DECLS
#endif /* __SHELL_IDLE_MONITOR_H */

View File

@@ -327,3 +327,23 @@ shell_tp_client_grab_contact_list_changed (ShellTpClient *self,
G_CALLBACK (on_contact_list_changed),
self);
}
/* Telepathy utility functions */
/* gjs doesn't allow us to craft a GError so we need a C wrapper */
void
shell_decline_dispatch_op (TpAddDispatchOperationContext *context,
const gchar *message)
{
GError *error = g_error_new_literal (TP_ERRORS, TP_ERROR_INVALID_ARGUMENT,
message);
tp_add_dispatch_operation_context_fail (context, error);
g_error_free (error);
}
/* gjs doesn't cope with tp_proxy_get_invalidated() returning a GError */
gboolean shell_is_channel_invalidated (TpChannel *channel)
{
return tp_proxy_get_invalidated (channel) != NULL;
}

View File

@@ -100,5 +100,12 @@ void shell_tp_client_set_contact_list_changed_func (ShellTpClient *self,
void shell_tp_client_grab_contact_list_changed (ShellTpClient *self,
TpConnection *conn);
/* Telepathy utility functions */
void shell_decline_dispatch_op (TpAddDispatchOperationContext *context,
const gchar *message);
gboolean shell_is_channel_invalidated (TpChannel *channel);
G_END_DECLS
#endif /* __SHELL_TP_CLIENT_H__ */

View File

@@ -14,6 +14,10 @@
#include <langinfo.h>
#endif
#include <libxml/parser.h>
#include <libxml/tree.h>
#include <libxml/xmlmemory.h>
#ifdef WITH_SYSTEMD
#include <systemd/sd-daemon.h>
#include <systemd/sd-login.h>
@@ -642,6 +646,134 @@ shell_get_file_contents_utf8_sync (const char *path,
return contents;
}
/**
* shell_parse_search_provider:
* @data: description of provider
* @name: (out): location to store a display name
* @url: (out): location to store template of url
* @langs: (out) (transfer full) (element-type utf8): list of supported languages
* @icon_data_uri: (out): location to store uri
* @error: location to store GError
*
* Returns: %TRUE on success
*/
gboolean
shell_parse_search_provider (const char *data,
char **name,
char **url,
GList **langs,
char **icon_data_uri,
GError **error)
{
xmlDocPtr doc = xmlParseMemory (data, strlen (data));
xmlNode *root;
*name = NULL;
*url = NULL;
*icon_data_uri = NULL;
*langs = NULL;
if (!doc)
{
g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, "Malformed xml");
return FALSE;
}
root = xmlDocGetRootElement (doc);
if (root && root->name && xmlStrcmp (root->name, (const xmlChar *)"OpenSearchDescription") == 0)
{
xmlNode *child;
for (child = root->children; child; child = child->next)
{
if (!child->name)
continue;
if (xmlStrcmp (child->name, (const xmlChar *)"Language") == 0)
{
xmlChar *val = xmlNodeListGetString(doc, child->xmlChildrenNode, 1);
if (!val)
continue;
*langs = g_list_append (*langs, g_strdup ((char *)val));
xmlFree (val);
}
if (!*name && xmlStrcmp (child->name, (const xmlChar *)"ShortName") == 0)
{
xmlChar *val = xmlNodeListGetString(doc, child->xmlChildrenNode, 1);
*name = g_strdup ((char *)val);
xmlFree (val);
}
if (!*icon_data_uri && xmlStrcmp (child->name, (const xmlChar *)"Image") == 0)
{
xmlChar *val = xmlNodeListGetString(doc, child->xmlChildrenNode, 1);
if (val)
*icon_data_uri = g_strdup ((char *)val);
xmlFree (val);
}
if (!*url && xmlStrcmp (child->name, (const xmlChar *)"Url") == 0)
{
xmlChar *template;
xmlChar *type;
type = xmlGetProp(child, (const xmlChar *)"type");
if (!type)
continue;
if (xmlStrcmp (type, (const xmlChar *)"text/html") != 0)
{
xmlFree (type);
continue;
}
xmlFree (type);
template = xmlGetProp(child, (const xmlChar *)"template");
if (!template)
continue;
*url = g_strdup ((char *)template);
xmlFree (template);
}
}
}
else
{
g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, "Invalid OpenSearch document");
xmlFreeDoc (doc);
return FALSE;
}
xmlFreeDoc (doc);
if (*icon_data_uri && *name && *url)
return TRUE;
if (*icon_data_uri)
g_free (*icon_data_uri);
else
g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
"search provider doesn't have icon");
if (*name)
g_free (*name);
else if (error && !*error)
g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
"search provider doesn't have ShortName");
if (*url)
g_free (*url);
else if (error && !*error)
g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
"search provider doesn't have template for url");
if (*langs)
{
g_list_foreach (*langs, (GFunc)g_free, NULL);
g_list_free (*langs);
}
*url = NULL;
*name = NULL;
*icon_data_uri = NULL;
*langs = NULL;
return FALSE;
}
/**
* shell_session_is_active_for_systemd:
*

View File

@@ -33,6 +33,13 @@ gboolean shell_write_string_to_stream (GOutputStream *stream,
char *shell_get_file_contents_utf8_sync (const char *path,
GError **error);
gboolean shell_parse_search_provider (const char *data,
char **name,
char **url,
GList **langs,
char **icon_data_uri,
GError **error);
gboolean shell_session_is_active_for_systemd (void);
gboolean shell_util_wifexited (int status,

View File

@@ -195,7 +195,8 @@ st_bin_navigate_focus (StWidget *widget,
StBinPrivate *priv = ST_BIN (widget)->priv;
ClutterActor *bin_actor = CLUTTER_ACTOR (widget);
if (st_widget_get_can_focus (widget))
if (clutter_actor_get_reactive (bin_actor) &&
st_widget_get_can_focus (widget))
{
if (from && clutter_actor_contains (bin_actor, from))
return FALSE;

View File

@@ -285,7 +285,8 @@ st_entry_navigate_focus (StWidget *widget,
if (from == priv->entry)
return FALSE;
else if (st_widget_get_can_focus (widget))
else if (clutter_actor_get_reactive (CLUTTER_ACTOR (widget)) &&
st_widget_get_can_focus (widget))
{
clutter_actor_grab_key_focus (priv->entry);
return TRUE;

View File

@@ -52,7 +52,7 @@ struct _StScrollBarPrivate
{
StAdjustment *adjustment;
gboolean grabbed;
gulong capture_handler;
gfloat x_origin;
gfloat y_origin;
@@ -586,37 +586,52 @@ move_slider (StScrollBar *bar,
static void
stop_scrolling (StScrollBar *bar)
{
if (!bar->priv->grabbed)
ClutterStage *stage;
if (!bar->priv->capture_handler)
return;
st_widget_remove_style_pseudo_class (ST_WIDGET (bar->priv->handle), "active");
clutter_ungrab_pointer ();
bar->priv->grabbed = FALSE;
stage = CLUTTER_STAGE (clutter_actor_get_stage (bar->priv->trough));
g_signal_handler_disconnect (stage, bar->priv->capture_handler);
bar->priv->capture_handler = 0;
clutter_stage_set_motion_events_enabled (stage, TRUE);
g_signal_emit (bar, signals[SCROLL_STOP], 0);
}
static gboolean
handle_motion_event_cb (ClutterActor *trough,
ClutterMotionEvent *event,
StScrollBar *bar)
handle_capture_event_cb (ClutterActor *trough,
ClutterEvent *event,
StScrollBar *bar)
{
if (!bar->priv->grabbed)
return FALSE;
if (clutter_event_type (event) == CLUTTER_MOTION)
{
move_slider (bar,
((ClutterMotionEvent*) event)->x,
((ClutterMotionEvent*) event)->y);
}
else if (clutter_event_type (event) == CLUTTER_BUTTON_RELEASE
&& ((ClutterButtonEvent*) event)->button == 1)
{
ClutterActor *stage, *target;
move_slider (bar, event->x, event->y);
return TRUE;
}
stop_scrolling (bar);
static gboolean
handle_button_release_event_cb (ClutterActor *trough,
ClutterButtonEvent *event,
StScrollBar *bar)
{
if (event->button != 1)
return FALSE;
/* check if the mouse pointer has left the handle during the drag and
* remove the hover state if it has */
stage = clutter_actor_get_stage (bar->priv->trough);
target = clutter_stage_get_actor_at_pos ((ClutterStage*) stage,
CLUTTER_PICK_REACTIVE,
((ClutterButtonEvent*) event)->x,
((ClutterButtonEvent*) event)->y);
if (target != bar->priv->handle)
{
st_widget_remove_style_pseudo_class ((StWidget*) bar->priv->handle, "hover");
}
}
stop_scrolling (bar);
return TRUE;
}
@@ -625,6 +640,7 @@ handle_button_press_event_cb (ClutterActor *actor,
ClutterButtonEvent *event,
StScrollBar *bar)
{
ClutterStage *stage;
StScrollBarPrivate *priv = bar->priv;
if (event->button != 1)
@@ -643,10 +659,16 @@ handle_button_press_event_cb (ClutterActor *actor,
priv->x_origin += clutter_actor_get_x (priv->trough);
priv->y_origin += clutter_actor_get_y (priv->trough);
g_assert (!priv->grabbed);
stage = CLUTTER_STAGE (clutter_actor_get_stage (bar->priv->trough));
clutter_grab_pointer (priv->handle);
priv->grabbed = TRUE;
/* Turn off picking for motion events */
clutter_stage_set_motion_events_enabled (stage, FALSE);
priv->capture_handler = g_signal_connect_after (
clutter_actor_get_stage (priv->trough),
"captured-event",
G_CALLBACK (handle_capture_event_cb),
bar);
g_signal_emit (bar, signals[SCROLL_START], 0);
return TRUE;
@@ -863,10 +885,6 @@ st_scroll_bar_init (StScrollBar *self)
CLUTTER_ACTOR (self->priv->handle));
g_signal_connect (self->priv->handle, "button-press-event",
G_CALLBACK (handle_button_press_event_cb), self);
g_signal_connect (self->priv->handle, "button-release-event",
G_CALLBACK (handle_button_release_event_cb), self);
g_signal_connect (self->priv->handle, "motion-event",
G_CALLBACK (handle_motion_event_cb), self);
clutter_actor_set_reactive (CLUTTER_ACTOR (self), TRUE);

View File

@@ -1892,7 +1892,8 @@ st_widget_real_navigate_focus (StWidget *widget,
while (focus_child && clutter_actor_get_parent (focus_child) != widget_actor)
focus_child = clutter_actor_get_parent (focus_child);
if (widget->priv->can_focus)
if (clutter_actor_get_reactive (widget_actor) &&
widget->priv->can_focus)
{
if (!focus_child)
{

View File

@@ -39,6 +39,7 @@ EXTRA_DIST += $(TEST_MISC)
run-test.sh: run-test.sh.in
$(AM_V_GEN) sed \
-e "s|@MUTTER_TYPELIB_DIR[@]|$(MUTTER_TYPELIB_DIR)|" \
-e "s|@JHBUILD_TYPELIBDIR[@]|$(JHBUILD_TYPELIBDIR)|" \
-e "s|@srcdir[@]|$(srcdir)|" \
$< > $@ && chmod a+x $@

View File

@@ -30,7 +30,7 @@ builddir=`cd $builddir && pwd`
srcdir=$builddir/@srcdir@
srcdir=`cd $srcdir && pwd`
GI_TYPELIB_PATH="$GI_TYPELIB_PATH${GI_TYPELIB_PATH:+:}@MUTTER_TYPELIB_DIR@:$builddir/../src"
GI_TYPELIB_PATH="$GI_TYPELIB_PATH${GI_TYPELIB_PATH:+:}@MUTTER_TYPELIB_DIR@:@JHBUILD_TYPELIBDIR@:$builddir/../src"
GJS_PATH="$srcdir:$srcdir/../js"
GJS_DEBUG_OUTPUT=stderr
$verbose || GJS_DEBUG_TOPICS="JS ERROR;JS LOG"