Compare commits

..

33 Commits

Author SHA1 Message Date
555d45f06c wip center layout garbage 2012-11-01 12:58:12 -04:00
0a8713770b overview, viewSelector: Don't use two signals for checking the app button
Just one will do.
2012-11-01 12:58:12 -04:00
7d3ea1ac68 overview, viewSelector: show/hide workspaces and message tray on apps button 2012-11-01 12:58:12 -04:00
7785710964 messageTray: Always show message tray upon entering overview
We hide the message tray while searching, but it should always be visible when
not searching, including when initially entering overview.
2012-11-01 12:58:12 -04:00
3730dc01cf viewSelector: remove switching from search results on app-drag-begin
https://bugzilla.gnome.org/show_bug.cgi?id=682050
2012-11-01 12:58:12 -04:00
66bf0df737 viewSelector: this.active --> this.entryNonEmpty
'active' isn't terribly clear about just what is active, this variable is
true/false depending on whether or not the search entry has text.

https://bugzilla.gnome.org/show_bug.cgi?id=682050
2012-11-01 12:58:12 -04:00
4590b33f2e messageTray, viewSelector: show/hide message tray on search signals
https://bugzilla.gnome.org/show_bug.cgi?id=682050
2012-11-01 12:58:12 -04:00
6538f60322 overview: Connect app-drag signals to show/hide overview elements
Anytime we begin dragging an app launcher, ensure the overview elements are
showing. While searching, if an app-drag ends or is cancelled, hide the
overview elements, but don't switch back to windows (which was the old
behavior).

https://bugzilla.gnome.org/show_bug.cgi?id=682050
2012-11-01 12:58:12 -04:00
4b0ba8b7b8 viewSelector, overview: Add search signals and connect them to hide/show
Hide the elements when the search entry is non-empty. Show them if the search
is cancelled.

https://bugzilla.gnome.org/show_bug.cgi?id=682050
2012-11-01 12:58:11 -04:00
bc8965fe63 overview: Center the main overview group accordingly
Using the same logic as the panel which smartly centers everything,
smartly center the overview contents if we have enough space to do so.
2012-11-01 12:58:11 -04:00
e7fcce3484 overview, workspacesView: Use ThumbnailsBox for independent workspace thumbnails
Both WorkspacesDisplay and ThumbnailsBox need to know when windows have been
restacked. Instead of each tracking changes on their own or trying to call
each other, have the overview keep track and do the calculations, emitting
a signal with the result.

https://bugzilla.gnome.org/show_bug.cgi?id=682050
2012-11-01 12:58:11 -04:00
b1e4d3335c workspaceThumbnail: Add keyboard nav to ThumbnailsBox
https://bugzilla.gnome.org/show_bug.cgi?id=682050
2012-11-01 12:58:11 -04:00
a3a3f24ed3 workspaceThumbnail: Rename show(), hide() and add new methods
show() and hide() now slide the thumbnails in and out, respectively. The old
show and hide are now _createThumbnails and _destroyThumbnails. We only care
about these thumbnails while in the overview, so create them when entering and
destroy them on exit.

https://bugzilla.gnome.org/show_bug.cgi?id=682050
2012-11-01 12:58:11 -04:00
96191a9c96 workspaceThumbnail: React to scroll event
https://bugzilla.gnome.org/show_bug.cgi?id=682050
2012-11-01 12:58:11 -04:00
f4814d200b workspaceThumbnail: Make ThumbnailsBox track workspace changes itself
https://bugzilla.gnome.org/show_bug.cgi?id=682050
2012-11-01 12:58:11 -04:00
52156930d3 overview: Respect multi-monitor situations 2012-11-01 12:58:11 -04:00
cbaa999ced overview: overview as boxlayouts
https://bugzilla.gnome.org/show_bug.cgi?id=682286
2012-11-01 12:58:10 -04:00
9491f6bd23 dash: fix for shrinking dash while animating
The this.actor.height > this._maxHeight check is needed because animating the
dash out causes constant notify::height signals and so after each one the max
height would shrink to the actor height causing the icons to shrink until
eventually we get to 16px icons. This way, only increase maxHeight if the
actor can be drawn bigger than it is currently set.

https://bugzilla.gnome.org/show_bug.cgi?id=682050
2012-11-01 12:58:10 -04:00
afe8198d4b dash: Add show/hide methods
https://bugzilla.gnome.org/show_bug.cgi?id=682050
2012-11-01 12:58:10 -04:00
6aa8f14285 overview and others: Rename item-drag signals to app-drag
Since results other than apps should not be draggable, be more descriptive and
rename item-drag signals to app-drag signals.

https://bugzilla.gnome.org/show_bug.cgi?id=682050
2012-11-01 12:58:09 -04:00
e073670c4d workspace: Don't recalculate window positions when leaving the overview
https://bugzilla.gnome.org/show_bug.cgi?id=682286
2012-11-01 12:58:09 -04:00
17a3d2c63f searchDisplay: Put the grid search results in the middle
This is still "off-balance" due to the dash on the left.
2012-11-01 12:58:09 -04:00
ca38e05ed4 appDisplay: Don't use icons in results for settings
The search results are not necessarily improved by including icons, so don't.

https://bugzilla.gnome.org/show_bug.cgi?id=681797
2012-11-01 12:58:09 -04:00
9841e56ebf remoteSearch: We do not need a fallback for createIcon
Remote providers no longer have access to a grid layout, where an icon is
a requirement. If they don't specify an icon, don't create one.

https://bugzilla.gnome.org/show_bug.cgi?id=681797
2012-11-01 12:58:09 -04:00
c0d3a14ac2 popupMenu: Break separator drawing code out of PopupSeparatorMenuItem
https://bugzilla.gnome.org/show_bug.cgi?id=681797
2012-11-01 12:58:09 -04:00
d485fcf9ec appDisplay: Add provider icons for the search system
Only temporary, to test with, unless a remote provider for Settings doesn't
materialize. this.icon should be a GIcon since that is what remote providers
will return.

https://bugzilla.gnome.org/show_bug.cgi?id=681797
2012-11-01 12:58:09 -04:00
ce2c5106f8 theme: Update for search redesign
https://bugzilla.gnome.org/show_bug.cgi?id=681797
2012-11-01 12:58:09 -04:00
5e96c3dfb4 searchDisplay: Set can_focus on provider icon only if its results have focus
This way, the search results take priority, but while the user is in the
search section, they can navigate to that provider icon to launch a search.

https://bugzilla.gnome.org/show_bug.cgi?id=681797
2012-11-01 12:58:09 -04:00
a72b642f3e searchDisplay: Add ListSearchResult and ListSearchResults
These are for all search results except apps.

https://bugzilla.gnome.org/show_bug.cgi?id=681797
2012-11-01 12:58:09 -04:00
8507d3c4e4 searchDisplay, and others: Switch from provider title to provider icon
Display a '+' icon on the provider icon if there are more results that are
hidden. If the provider icon is clicked, ask the provider to launch itself and
perform a search with the current terms.

https://bugzilla.gnome.org/show_bug.cgi?id=681797
2012-11-01 12:58:09 -04:00
c985fdccba iconGrid: Handle preferred height requests for infinite widths
Request enough height to fit all children in a single line instead of
requesting 0.

https://bugzilla.gnome.org/show_bug.cgi?id=679168
2012-11-01 12:58:08 -04:00
1d7c2b1c26 centerLayout: Add some utilities to connect us up to CSS
This allows us to automatically adjust the "spacing" property of the
layout manager whenever the CSS changes.
2012-11-01 12:58:07 -04:00
ab60c628e7 panel: Abstract the centered panel logic out into a ClutterLayoutManager
Since we want to use this in the overview as well, put it into centerLayout.js

Panel corners are disabled for now. They'll be added back eventually.
2012-11-01 12:58:07 -04:00
101 changed files with 5137 additions and 6406 deletions

1
.gitignore vendored
View File

@ -45,7 +45,6 @@ intltool-merge.in
intltool-update.in
libtool
m4/
man/gnome-shell.1
omf.make
po/*.gmo
po/gnome-shell.pot

View File

@ -1,11 +1,7 @@
# Point to our macro directory and pick up user flags from the environment
ACLOCAL_AMFLAGS = -I m4 ${ACLOCAL_FLAGS}
SUBDIRS = data js src browser-plugin tests po docs
if ENABLE_MAN
SUBDIRS += man
endif
SUBDIRS = data js src browser-plugin tests po man docs
EXTRA_DIST = \
.project \
@ -25,4 +21,4 @@ distcheck-hook:
@echo "Checking disted files against files in git"
@$(srcdir)/tools/check-for-missing.py $(srcdir) $(distdir) $(DIST_EXCLUDE)
DISTCHECK_CONFIGURE_FLAGS = --enable-gtk-doc --enable-man
DISTCHECK_CONFIGURE_FLAGS = --enable-gtk-doc

63
NEWS
View File

@ -1,66 +1,3 @@
3.7.2
=====
* Enforce RTL in he for messages that might end up as LTR [Florian; #686630]
* gdm: Move logo into the panel [Florian; #685852]
* Hide notifications when closed button is clicked [Jasper, Florian; #682237]
* Tweak screenShield animations [Rui; #686745]
* Restore Fittsability of summary items in message tray [Florian; #686474]
* Save screencasts as recent item [Ray; #680647]
* overview: Resize window captions on content change [Giovanni, Alex; #620874]
* App search: Match GenericName too [Matthias; #687121]
* runDialog: Better match style of other modal dialogs [Florian, Allan; #687127]
* Improve the button insensitive style [Stéphane; #687110]
* network: Don't use a global switch for all VPN connections [Giovanni; #682929]
* appMenu: Update on icon theme changes [Florian; #687224]
* Show 'Log out' in more situations [Matthias; #686736]
* Add a setting to force the 'Log out' menuitem [Matthias; #686057]
* overview: Improve styling of search box [Stéphane; #686479]
* Implement 'disable-user-list' in login screen [Ray; #660660]
* Fix auto-scroll to bottom in chat notifications [Sjoerd; #686571]
* Show feedback notifications when user is busy [Stéphane; #662900]
* Disable login button when there is no input [Stéphane; #687112]
* Use non-linear overview shade for background [Giovanni, Pierre-Eric; #669798]
* Reduce blocking in compositor thread [Simon, Jasper; #687465]
* network: new country-specific type to gather providers [Aleksander; #687356]
* Update man page [Matthias; #680601]
* st-entry: Change the pointer cursor on enter/leave events [Thomas; #687130]
* screenShield: Blur and desaturate the background [Giovanni, Cosimo; #682536]
* Change height of chat notifications to have more context [Carlos; #665255]
* screenShield: Account for motion velocity when hiding [Giovanni; #682537]
* screenShield: hide the cursor while the lock screen is on [Giovanni; #682535]
* Support remote search provider settings [Cosimo; #687491]
* unlockDialog: Improve label of confirmation button [Stéphane; #687656]
* userMenu: Rename "System Settings" item to "Settings" [Elad; #687738]
* messageTray: Add keybinding to focus current notification [Stéphane; #652082]
* Remove shell-screen-grabber [Neil; #685915]
* main: Stop using Metacity's keybinding files [Florian; #687672]
* Bluetooth: Remove ObexFTP functionality [Bastien; #688160]
* a11y: Also set WM theme when HighContrast is switched on [Cosimo; #688256]
* network: Rework multiple NIC support [Giovanni; #677142]
* Rework keybindings to allow selective blocking/processing [Florian; #688202]
* recorder: Show indicator on primary monitor [Adel; #688470]
* recorder: Set frame duration to fix broken video headers [Adel; #688487]
* Misc. bugfixes and cleanups [Florian, Jasper, Giovanni, Matthew, Stéphane,
Allan, Daiki, Owen, Alejandro, Jean-François, Cosimo, Sebastian, Adel, Alban;
#686484, #686728, #686805, #686574, #686763, #682428, #687132, #685239,
#687189, #687226, #658091, #670687, #687457, #687242, #687287, #687020,
#686583, #661194, #687491, #657315, #687958, #683986, #688089, #687708,
#686530, #684810, #688181, #688475, #688557, #688507, #638351]
Contributors:
Elad Alfassa, Matthew Barnes, Alban Browaeys, Giovanni Campagna,
Cosimo Cecchi, Matthias Clasen, Allan Day, Stéphane Démurget,
Jean-François Fortin Tam, Adel Gadllah, Alex Hultman, Sebastian Keller,
Rui Matos, Simon McVittie, Aleksander Morgado, Florian Müllner,
Bastien Nocera, Pierre-Eric Pelloux-Prayer, Alejandro Piñeiro, Neil Roberts,
Sjoerd Simons, Carlos Soriano Sánchez, Jasper St. Pierre, Ray Strode,
Owen Taylor, Daiki Ueno, Thomas Wood
Translations:
Dušan Kazik [sk], Pavol Klačanský [sk], Piotr Drąg [pl], Yuri Myasoedov [ru],
Marek Černocký [cs], Kjartan Maraas [nb], Wolfgang Stöggl [de],
Yaron Shahrabani [he], Fran Diéguez [gl], Mattias Põldaru [et]
3.7.1
=====
* Add shortcut to open application view directly [Jeremy; #685738]

View File

@ -1,5 +1,5 @@
AC_PREREQ(2.63)
AC_INIT([gnome-shell],[3.7.2],[https://bugzilla.gnome.org/enter_bug.cgi?product=gnome-shell],[gnome-shell])
AC_INIT([gnome-shell],[3.7.1],[https://bugzilla.gnome.org/enter_bug.cgi?product=gnome-shell],[gnome-shell])
AC_CONFIG_HEADERS([config.h])
AC_CONFIG_SRCDIR([src/shell-global.c])
@ -36,8 +36,6 @@ AC_DEFINE_UNQUOTED(GETTEXT_PACKAGE, "$GETTEXT_PACKAGE",
PKG_PROG_PKG_CONFIG([0.22])
AC_PATH_PROG([XSLTPROC], [xsltproc])
GLIB_GSETTINGS
# Get a value to substitute into gnome-shell.in
@ -65,7 +63,7 @@ AM_CONDITIONAL(BUILD_RECORDER, $build_recorder)
CLUTTER_MIN_VERSION=1.11.11
GOBJECT_INTROSPECTION_MIN_VERSION=0.10.1
GJS_MIN_VERSION=1.33.2
MUTTER_MIN_VERSION=3.7.2
MUTTER_MIN_VERSION=3.7.1
GTK_MIN_VERSION=3.3.9
GIO_MIN_VERSION=2.35.0
LIBECAL_MIN_VERSION=3.5.3
@ -78,7 +76,6 @@ STARTUP_NOTIFICATION_MIN_VERSION=0.11
GCR_MIN_VERSION=3.3.90
GNOME_DESKTOP_REQUIRED_VERSION=3.7.1
GNOME_MENUS_REQUIRED_VERSION=3.5.3
NETWORKMANAGER_MIN_VERSION=0.9.7
# Collect more than 20 libraries for a prize!
PKG_CHECK_MODULES(GNOME_SHELL, gio-unix-2.0 >= $GIO_MIN_VERSION
@ -99,9 +96,8 @@ PKG_CHECK_MODULES(GNOME_SHELL, gio-unix-2.0 >= $GIO_MIN_VERSION
telepathy-glib >= $TELEPATHY_GLIB_MIN_VERSION
telepathy-logger-0.2 >= $TELEPATHY_LOGGER_MIN_VERSION
polkit-agent-1 >= $POLKIT_MIN_VERSION xfixes
libnm-glib libnm-util >= $NETWORKMANAGER_MIN_VERSION
libnm-gtk >= $NETWORKMANAGER_MIN_VERSION
gnome-keyring-1 gcr-3 >= $GCR_MIN_VERSION)
libnm-glib libnm-util gnome-keyring-1
gcr-3 >= $GCR_MIN_VERSION)
PKG_CHECK_MODULES(SHELL_PERF_HELPER, gtk+-3.0 gio-2.0)
@ -126,7 +122,7 @@ PKG_CHECK_MODULES(GNOME_SHELL_JS, gio-2.0 gjs-internals-1.0 >= $GJS_MIN_VERSION)
PKG_CHECK_MODULES(ST, clutter-1.0 gtk+-3.0 libcroco-0.6 >= 0.6.8 x11)
PKG_CHECK_MODULES(TRAY, gtk+-3.0)
PKG_CHECK_MODULES(GVC, libpulse libpulse-mainloop-glib gobject-2.0)
PKG_CHECK_MODULES(DESKTOP_SCHEMAS, gsettings-desktop-schemas >= 3.7.2)
PKG_CHECK_MODULES(DESKTOP_SCHEMAS, gsettings-desktop-schemas >= 3.5.4)
AC_MSG_CHECKING([for bluetooth support])
PKG_CHECK_EXISTS([gnome-bluetooth-1.0 >= 3.1.0],
@ -211,18 +207,6 @@ AC_SUBST(TYPELIBDIR)
GTK_DOC_CHECK([1.15], [--flavour no-tmpl])
AC_ARG_ENABLE(man,
[AS_HELP_STRING([--enable-man],
[generate man pages [default=yes]])],,
enable_man=yes)
if test "$enable_man" != no; then
AC_PATH_PROG([XSLTPROC], [xsltproc])
if test -z "$XSLTPROC"; then
AC_MSG_ERROR([xsltproc is required for --enable-man])
fi
fi
AM_CONDITIONAL(ENABLE_MAN, test "$enable_man" != no)
# Stay command-line compatible with the gnome-common configure option. Here
# minimum/yes/maximum are the same, however.
AC_ARG_ENABLE(compile_warnings,

View File

@ -8,9 +8,6 @@
<KeyListEntry name="toggle-message-tray"
_description="Show the message tray"/>
<KeyListEntry name="focus-active-notification"
_description="Focus the active notification"/>
<KeyListEntry name="toggle-application-view"
_description="Show all applications"/>

View File

@ -54,9 +54,7 @@ keys_in_files = \
$(NULL)
keys_DATA = $(keys_in_files:.xml.in=.xml)
gsettings_SCHEMAS = \
org.gnome.shell.gschema.xml \
org.gnome.shell-foo.gschema.xml
gsettings_SCHEMAS = org.gnome.shell.gschema.xml
@INTLTOOL_XML_NOMERGE_RULE@
@ -83,8 +81,7 @@ EXTRA_DIST = \
$(menu_DATA) \
$(convert_DATA) \
$(keys_in_files) \
org.gnome.shell.gschema.xml.in.in \
org.gnome.shell-foo.gschema.xml.in.in
org.gnome.shell.gschema.xml.in.in
CLEANFILES = \
gnome-shell.desktop.in \
@ -94,6 +91,4 @@ CLEANFILES = \
$(gsettings_SCHEMAS) \
gschemas.compiled \
org.gnome.shell.gschema.valid \
org.gnome.shell.gschema.xml.in \
org.gnome.shell-foo.gschema.valid \
org.gnome.shell-foo.gschema.xml.in
org.gnome.shell.gschema.xml.in

View File

@ -113,9 +113,13 @@
<doc:summary>
<doc:para>
A dictionary describing the given search result, containing
'id', 'name' (both strings) and either 'icon' (a serialized
GIcon) or 'icon-data' (raw image data as (iiibiiay) - width,
height, rowstride, has-alpha, bits per sample, channels, data)
'id' and 'name' (both strings). Optionally, either 'gicon' (a
serialized GIcon) or 'icon-data' (raw image data as (iiibiiay)
- width, height, rowstride, has-alpha, bits per sample,
channels, data) can be specified if the result can be better
served with a thumbnail of the content (such as with images).
A 'description' field (string) may also be specified if more
context would help the user find the desired result.
</doc:para>
</doc:summary>
</doc:doc>
@ -143,5 +147,25 @@
</doc:doc>
</arg>
</method>
<method name="LaunchSearch">
<doc:doc>
<doc:description>
<doc:para>
Called when the user clicks on the provider icon. The provider
application should open and run the active search term itself.
</doc:para>
</doc:description>
</doc:doc>
<arg type="as" direction="in">
<doc:doc>
<doc:summary>
<doc:para>
The current search term(s).
</doc:para>
</doc:summary>
</doc:doc>
</arg>
</method>
</interface>
</node>

View File

@ -1,13 +0,0 @@
<schemalist>
<schema id="org.gnome.shell-foo.overrides" path="/org/gnome/shell-foo/overrides/"
gettext-domain="@GETTEXT_PACKAGE@">
<key name="button-layout" type="s">
<default>":minimize,close"</default>
<_summary>Arrangement of buttons on the titlebar</_summary>
<_description>
This key overrides the key in org.gnome.desktop.wm.preferences when
running GNOME Shell in Foo mode.
</_description>
</key>
</schema>
</schemalist>

View File

@ -65,11 +65,6 @@ value here is from the GsmPresenceStatus enumeration.</_summary>
menuitem in single-user, single-session situations.
</_description>
</key>
<key name="show-full-name" type="b">
<default>true</default>
<_summary>Show full name in the user menu</_summary>
<_description>Whether the users full name is shown in the user menu or not.</_description>
</key>
<child name="calendar" schema="org.gnome.shell.calendar"/>
<child name="recorder" schema="org.gnome.shell.recorder"/>
<child name="keybindings" schema="org.gnome.shell.keybindings"/>
@ -111,13 +106,6 @@ value here is from the GsmPresenceStatus enumeration.</_summary>
Keybinding to toggle the visibility of the message tray.
</_description>
</key>
<key name="focus-active-notification" type="as">
<default>["&lt;Super&gt;n"]</default>
<_summary>Keybinding to focus the active notification</_summary>
<_description>
Keybinding to focus the active notification.
</_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

@ -405,13 +405,11 @@ StScrollBar StButton#vhandle:active {
padding: 0 4px;
}
.modal-dialog StEntry:insensitive {
border-color: #666666;
color: #9f9f9f;
border: 2px solid #9f9f9f;
background-gradient-direction: none;
background-color: rgba(102, 102, 102, 0.15);
box-shadow: inset 0 0 rgba(0,0,0,1.0);
.login-dialog-prompt-entry:insensitive {
color: rgba(0,0,0,0.7);
border: 2px solid #565656;
background-gradient-start: rgb(200,200,200);
background-gradient-end: rgb(210,210,210);
}
/* Panel */
@ -420,18 +418,6 @@ StScrollBar StButton#vhandle:active {
background-color: black;
font-weight: bold;
height: 1.86em;
transition-duration: 250;
}
#panel.lock-screen {
height: 2em;
background-color: rgba(0,0,0,0.3);
}
#panel.unlock-screen,
#panel.login-screen {
height: 2em;
background-color: transparent;
}
#panelLeft, #panelCenter {
@ -467,13 +453,6 @@ StScrollBar StButton#vhandle:active {
-panel-corner-border-color: rgba(255,255,255,0.8);
}
.panel-corner.lock-screen,
.panel-corner.unlock-screen,
.panel-corner.login-screen {
-panel-corner-background-color: transparent;
-panel-corner-border-color: transparent;
}
#appMenu {
spacing: 4px;
}
@ -506,24 +485,6 @@ StScrollBar StButton#vhandle:active {
transition-duration: 100;
}
#panel.unlock-screen .panel-button,
#panel.lock-screen .panel-button,
#panel.login-screen .panel-button {
color: #e6e6e6;
}
#panel.unlock-screen .panel-button:hover,
#panel.lock-screen .panel-button:hover,
#panel.login-screen .panel-button:hover,
#panel.unlock-screen .panel-button:active,
#panel.lock-screen .panel-button:active,
#panel.login-screen .panel-button:active,
#panel.unlock-screen .panel-button:focus,
#panel.lock-screen .panel-button:focus,
#panel.login-screen .panel-button:focus {
color: white;
}
.panel-button:hover {
color: white;
text-shadow: black 0px 2px 2px;
@ -616,6 +577,10 @@ StScrollBar StButton#vhandle:active {
spacing: 40px;
}
#overview-group {
spacing: 12px;
}
.window-caption {
spacing: 25px;
}
@ -654,7 +619,6 @@ StScrollBar StButton#vhandle:active {
border-radius: 8px;
padding: 4px 12px;
-shell-caption-spacing: 12px;
border: 2px solid rgba(0, 0, 0, 0);
}
.window-close, .notification-close {
@ -665,16 +629,7 @@ StScrollBar StButton#vhandle:active {
}
.window-close {
-shell-close-overlap: 16px;
}
.window-caption:hover {
border: 2px solid rgba(255, 255, 255, 0);
}
.window-clone-border {
border: 4px solid rgba(255, 255, 255, 0.5);
border-radius: 4px;
-shell-close-overlap: 20px;
}
.notification-close {
@ -760,7 +715,7 @@ StScrollBar StButton#vhandle:active {
#searchResultsContent {
padding-right: 20px;
spacing: 36px;
spacing: 16px;
}
#searchResultsContent:rtl {
@ -768,6 +723,25 @@ StScrollBar StButton#vhandle:active {
padding-left: 20px;
}
.search-section {
/* This should be equal to #searchResultsContent spacing */
spacing: 16px;
}
.search-section-separator {
-gradient-height: 1px;
-gradient-start: rgba(255,255,255,0);
-gradient-end: rgba(255,255,255,0.5);
-margin-horizontal: 1.5em;
height: 1px;
}
.search-section-content {
/* This is the space between the provider icon and the results container */
spacing: 25px;
}
.search-statustext,
.search-section-header {
padding: 4px 12px;
spacing: 4px;
@ -793,6 +767,14 @@ StScrollBar StButton#vhandle:active {
spacing: 4px;
}
.search-providers-box {
spacing: 12px;
}
.results-list {
spacing: 5px;
}
/* Text labels are an odd number of pixels tall. The uneven top and bottom
* padding compensates for this and ensures that the label is vertically
* centered */
@ -873,7 +855,10 @@ StScrollBar StButton#vhandle:active {
.app-well-app > .overview-icon,
.show-apps > .overview-icon,
.search-result-content > .overview-icon {
.remove-favorite > .overview-icon,
.search-section-icon-bin,
.search-result,
.grid-search-result-content > .overview-icon {
border-radius: 4px;
padding: 3px;
border: 1px rgba(0,0,0,0);
@ -889,7 +874,10 @@ StScrollBar StButton#vhandle:active {
.app-well-app:hover > .overview-icon,
.show-apps:hover > .overview-icon,
.search-result-content:hover > .overview-icon {
.remove-favorite:hover > .overview-icon,
.search-section-icon-bin:hover,
.search-result:hover,
.grid-search-result-content:hover > .overview-icon {
background-color: rgba(255,255,255,0.1);
text-shadow: black 0px 2px 2px;
transition-duration: 100;
@ -924,13 +912,39 @@ StScrollBar StButton#vhandle:active {
}
.app-well-app:focus > .overview-icon,
.search-result-content:focus > .overview-icon,
.show-apps:focus > .overview-icon,
.search-section-icon-bin:focus,
.search-result:focus,
.grid-search-result-content:focus > .overview-icon,
.app-well-app:selected > .overview-icon,
.search-result-content:selected > .overview-icon {
.search-section-icon-bin:selected,
.search-result:selected,
.grid-search-result-content:selected > .overview-icon {
background-color: rgba(255,255,255,0.33);
}
/* List Results */
.search-result {
padding: 15px;
}
.search-result-content {
spacing: 12px;
}
.search-result-details {
font-weight: bold;
}
.search-result-details-title {
font-size: 16pt;
}
.search-result-details-description {
font-size: 14pt;
}
/* LookingGlass */
#LookingGlassDialog {
@ -1271,12 +1285,6 @@ StScrollBar StButton#vhandle:active {
outline: 1px solid rgba(128, 128, 128, 0.3);
}
.no-messages-label {
font-family: cantarell, sans-serif;
font-size: 11pt;
color: #999999;
}
.notification {
border-radius: 10px 10px 0px 0px;
background: rgba(0,0,0,0.8);
@ -1310,7 +1318,7 @@ StScrollBar StButton#vhandle:active {
}
.summary-boxpointer {
-arrow-border-radius: 15px;
-arrow-border-radius: 8px;
-arrow-background-color: rgba(0,0,0,0.8);
-arrow-base: 36px;
-arrow-rise: 18px;
@ -1331,8 +1339,8 @@ StScrollBar StButton#vhandle:active {
.summary-notification-stack-scrollview {
max-height: 18em;
padding-top: 8px;
padding-bottom: 8px;
padding-top: 6px;
padding-bottom: 6px;
}
.summary-notification-stack-scrollview:ltr {
@ -1487,10 +1495,6 @@ StScrollBar StButton#vhandle:active {
padding-right: 4px;
}
.chat-notification-scrollview{
max-height: 22em;
}
.subscription-message {
font-style: italic;
}
@ -2184,7 +2188,7 @@ StScrollBar StButton#vhandle:active {
font-weight: bold;
text-align: left;
padding-left: 15px;
text-shadow: black 0px 4px 3px 0px;
text-shadow: black 4px 4px 3px 0px;
}
.login-dialog-prompt-layout {
@ -2250,10 +2254,6 @@ StScrollBar StButton#vhandle:active {
height: .75em;
}
.login-dialog .modal-dialog-button-box {
spacing: 3px;
}
.login-dialog .modal-dialog-button {
border-radius: 5px;
padding: 3px 18px;

View File

@ -41,6 +41,7 @@ nobase_dist_js_DATA = \
ui/boxpointer.js \
ui/calendar.js \
ui/checkBox.js \
ui/centerLayout.js \
ui/ctrlAltTab.js \
ui/dash.js \
ui/dateMenu.js \

View File

@ -39,7 +39,6 @@ const GdmUtil = imports.gdm.util;
const Lightbox = imports.ui.lightbox;
const Main = imports.ui.main;
const ModalDialog = imports.ui.modalDialog;
const Panel = imports.ui.panel;
const PanelMenu = imports.ui.panelMenu;
const Tweener = imports.ui.tweener;
const UserMenu = imports.ui.userMenu;
@ -49,10 +48,6 @@ const _SCROLL_ANIMATION_TIME = 0.5;
const _TIMED_LOGIN_IDLE_THRESHOLD = 5.0;
const _LOGO_ICON_HEIGHT = 16;
const WORK_SPINNER_ICON_SIZE = 24;
const WORK_SPINNER_ANIMATION_DELAY = 1.0;
const WORK_SPINNER_ANIMATION_TIME = 0.3;
let _loginDialog = null;
function _smoothlyResizeActor(actor, width, height) {
@ -609,14 +604,6 @@ const SessionList = new Lang.Class({
this.close();
},
updateSensitivity: function(sensitive) {
this._button.reactive = sensitive;
this._button.can_focus = sensitive;
for (let id in this._items)
this._items[id].actor.reactive = sensitive;
},
setActiveSession: function(sessionId) {
if (sessionId == this._activeSessionId)
return;
@ -673,7 +660,6 @@ const LoginDialog = new Lang.Class({
this.parent({ shellReactive: true,
styleClass: 'login-dialog',
parentActor: parentActor,
keybindingMode: Main.KeybindingMode.LOGIN_SCREEN,
shouldFadeIn: false });
this.connect('destroy',
Lang.bind(this, this._onDestroy));
@ -698,11 +684,9 @@ const LoginDialog = new Lang.Class({
this._userVerifier = new GdmUtil.ShellUserVerifier(this._greeterClient);
this._userVerifier.connect('ask-question', Lang.bind(this, this._askQuestion));
this._userVerifier.connect('show-message', Lang.bind(this, this._showMessage));
this._userVerifier.connect('verification-failed', Lang.bind(this, this._verificationFailed));
this._userVerifier.connect('reset', Lang.bind(this, this._reset));
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._verifyingUser = false;
this._settings = new Gio.Settings({ schema: GdmUtil.LOGIN_SCREEN_SCHEMA });
@ -710,8 +694,6 @@ const LoginDialog = new Lang.Class({
Lang.bind(this, this._updateBanner));
this._settings.connect('changed::' + GdmUtil.BANNER_MESSAGE_TEXT_KEY,
Lang.bind(this, this._updateBanner));
this._settings.connect('changed::' + GdmUtil.DISABLE_USER_LIST_KEY,
Lang.bind(this, this._updateDisableUserList));
this._bannerLabel = new St.Label({ style_class: 'login-dialog-banner',
text: '' });
@ -719,8 +701,7 @@ const LoginDialog = new Lang.Class({
this._updateBanner();
this._titleLabel = new St.Label({ style_class: 'login-dialog-title',
text: C_("title", "Sign In"),
visible: false });
text: C_("title", "Sign In") });
this.contentLayout.add(this._titleLabel,
{ y_fill: false,
@ -750,7 +731,6 @@ const LoginDialog = new Lang.Class({
x_align: St.Align.START });
this._promptEntry = new St.Entry({ style_class: 'login-dialog-prompt-entry',
can_focus: true });
this._promptEntryTextChangedId = 0;
this._promptBox.add(this._promptEntry,
{ expand: true,
x_fill: true,
@ -764,9 +744,6 @@ const LoginDialog = new Lang.Class({
this._promptLoginHint.hide();
this._promptBox.add(this._promptLoginHint);
this._signInButton = null;
this._workSpinner = null;
this._sessionList = new SessionList();
this._sessionList.connect('session-activated',
Lang.bind(this, function(list, sessionId) {
@ -792,7 +769,7 @@ const LoginDialog = new Lang.Class({
x_align: St.Align.START,
x_fill: true });
this._notListedButton.connect('clicked', Lang.bind(this, this._hideUserListAndLogIn));
this._notListedButton.connect('clicked', Lang.bind(this, this._onNotListedClicked));
this.contentLayout.add(this._notListedButton,
{ expand: false,
@ -818,21 +795,6 @@ const LoginDialog = new Lang.Class({
},
_updateDisableUserList: function() {
let disableUserList = this._settings.get_boolean(GdmUtil.DISABLE_USER_LIST_KEY);
// If this is the first time around, set initial focus
if (this._disableUserList == undefined && disableUserList)
this.setInitialKeyFocus(this._promptEntry);
if (disableUserList != this._disableUserList) {
this._disableUserList = disableUserList;
if (!this._verifyingUser)
this._reset();
}
},
_updateBanner: function() {
let enabled = this._settings.get_boolean(GdmUtil.BANNER_MESSAGE_KEY);
let text = this._settings.get_string(GdmUtil.BANNER_MESSAGE_TEXT_KEY);
@ -845,23 +807,31 @@ const LoginDialog = new Lang.Class({
}
},
_reset: function() {
this._updateSensitivity(true);
_onReset: function(client, serviceName) {
this._promptMessage.hide();
let tasks = [this._hidePrompt,
new Batch.ConcurrentBatch(this, [this._fadeInTitleLabel,
this._fadeInNotListedButton]),
function() {
this._sessionList.close();
this._promptLoginHint.hide();
this._userList.actor.show();
this._userList.actor.opacity = 255;
return this._userList.showItems();
},
function() {
this._userList.actor.reactive = true;
this._userList.actor.grab_key_focus();
}];
this._user = null;
this._verifyingUser = false;
if (this._disableUserList)
this._hideUserListAndLogIn();
else
this._showUserList();
},
_verificationFailed: function() {
this._promptEntry.text = '';
this._updateSensitivity(true);
this._setWorking(false);
let batch = new Batch.ConsecutiveBatch(this, tasks);
batch.run();
},
_onDefaultSessionChanged: function(client, sessionId) {
@ -916,9 +886,6 @@ const LoginDialog = new Lang.Class({
if (this._user && this._user.is_logged_in())
return null;
if (!this._verifyingUser)
return null;
return GdmUtil.fadeInActor(this._sessionList.actor);
},
@ -931,15 +898,24 @@ const LoginDialog = new Lang.Class({
return batch.run();
},
_showPrompt: function(forSecret) {
_showPrompt: function() {
let hold = new Batch.Hold();
let buttons = [{ action: Lang.bind(this, this.cancel),
label: _("Cancel"),
key: Clutter.Escape },
{ action: Lang.bind(this, function() {
hold.release();
}),
label: C_("button", "Sign In"),
default: true }];
let tasks = [function() {
return this._fadeInPrompt();
},
function() {
this._prepareDialog(forSecret, hold);
this.setButtons(buttons);
},
hold];
@ -949,86 +925,17 @@ const LoginDialog = new Lang.Class({
return batch.run();
},
_prepareDialog: function(forSecret, hold) {
this._workSpinner = new Panel.AnimatedIcon('process-working.svg', WORK_SPINNER_ICON_SIZE);
this._workSpinner.actor.opacity = 0;
this._workSpinner.actor.show();
this.buttonLayout.visible = true;
this.clearButtons();
if (!this._disableUserList || this._verifyingUser)
this.addButton({ action: Lang.bind(this, this.cancel),
label: _("Cancel"),
key: Clutter.Escape },
{ expand: true,
x_fill: false,
y_fill: false,
x_align: St.Align.START,
y_align: St.Align.MIDDLE });
this.buttonLayout.add(this._workSpinner.actor,
{ expand: false,
x_fill: false,
y_fill: false,
x_align: St.Align.END,
y_align: St.Align.MIDDLE });
this._signInButton = this.addButton({ action: Lang.bind(this, function() {
hold.release();
}),
label: forSecret ? C_("button", "Sign In") : _("Next"),
default: true },
{ expand: false,
x_fill: false,
y_fill: false,
x_align: St.Align.END,
y_align: St.Align.MIDDLE });
this._updateSignInButtonSensitivity(this._promptEntry.text.length > 0);
this._promptEntryTextChangedId =
this._promptEntry.clutter_text.connect('text-changed',
Lang.bind(this, function() {
this._updateSignInButtonSensitivity(this._promptEntry.text.length > 0);
}));
},
_updateSensitivity: function(sensitive) {
this._promptEntry.reactive = sensitive;
this._promptEntry.clutter_text.editable = sensitive;
this._sessionList.updateSensitivity(sensitive);
this._updateSignInButtonSensitivity(sensitive);
},
_updateSignInButtonSensitivity: function(sensitive) {
if (this._signInButton) {
this._signInButton.reactive = sensitive;
this._signInButton.can_focus = sensitive;
}
},
_hidePrompt: function() {
this.setButtons([]);
if (this._promptEntryTextChangedId > 0) {
this._promptEntry.clutter_text.disconnect(this._promptEntryTextChangedId);
this._promptEntryTextChangedId = 0;
}
let tasks = [function() {
this._setWorking(false);
return GdmUtil.fadeOutActor(this._promptBox);
},
function() {
this._promptLoginHint.hide();
this._updateSensitivity(true);
this._promptEntry.reactive = true;
this._promptEntry.set_text('');
this.clearButtons();
this._workSpinner = null;
this._signInButton = null;
}];
let batch = new Batch.ConsecutiveBatch(this, tasks);
@ -1036,63 +943,18 @@ const LoginDialog = new Lang.Class({
return batch.run();
},
_setWorking: function(working) {
if (!this._workSpinner)
return;
if (working) {
this._workSpinner.play();
Tweener.addTween(this._workSpinner.actor,
{ opacity: 255,
delay: WORK_SPINNER_ANIMATION_DELAY,
time: WORK_SPINNER_ANIMATION_TIME,
transition: 'linear'
});
} else {
Tweener.addTween(this._workSpinner.actor,
{ opacity: 0,
time: WORK_SPINNER_ANIMATION_TIME,
transition: 'linear',
onCompleteScope: this,
onComplete: function() {
this._workSpinner.stop();
}
});
}
},
_askQuestion: function(verifier, serviceName, question, passwordChar) {
this._promptLabel.set_text(question);
this._promptEntry.set_text('');
this._promptEntry.clutter_text.set_password_char(passwordChar);
let tasks = [function() {
return this._showPrompt(!!passwordChar);
},
function() {
let text = this._promptEntry.get_text();
this._updateSensitivity(false);
this._setWorking(true);
this._userVerifier.answerQuery(serviceName, text);
}];
let batch = new Batch.ConsecutiveBatch(this, tasks);
return batch.run();
},
_askForUsernameAndLogIn: function() {
this._promptLabel.set_text(_("Username: "));
this._promptEntry.set_text('');
this._promptEntry.clutter_text.set_password_char('');
let tasks = [this._showPrompt,
function() {
let userName = this._promptEntry.get_text();
let _text = this._promptEntry.get_text();
this._promptEntry.reactive = false;
return this._beginVerificationForUser(userName);
this._userVerifier.answerQuery(serviceName, _text);
}];
let batch = new Batch.ConsecutiveBatch(this, tasks);
@ -1227,7 +1089,7 @@ const LoginDialog = new Lang.Class({
}));
},
_hideUserListAndLogIn: function() {
_onNotListedClicked: function(user) {
let tasks = [function() {
return this._userList.hideItems();
},
@ -1244,30 +1106,10 @@ const LoginDialog = new Lang.Class({
this._fadeOutNotListedButton]),
function() {
return this._askForUsernameAndLogIn();
}];
let hold = new Batch.Hold();
let batch = new Batch.ConsecutiveBatch(this, tasks);
batch.run();
},
_showUserList: function() {
let tasks = [this._hidePrompt,
new Batch.ConcurrentBatch(this, [this._fadeInTitleLabel,
this._fadeInNotListedButton]),
function() {
this._sessionList.close();
this._promptLoginHint.hide();
this._userList.actor.show();
this._userList.actor.opacity = 255;
return this._userList.showItems();
},
function() {
this._userList.actor.reactive = true;
this._userList.actor.grab_key_focus();
this._userVerifier.begin(null, hold);
return hold;
}];
let batch = new Batch.ConsecutiveBatch(this, tasks);
@ -1302,7 +1144,6 @@ const LoginDialog = new Lang.Class({
let hold = new Batch.Hold();
this._userVerifier.begin(userName, hold);
this._verifyingUser = true;
return hold;
},
@ -1355,8 +1196,6 @@ const LoginDialog = new Lang.Class({
this._userList.addUser(users[i]);
}
this._updateDisableUserList();
this._userManager.connect('user-added',
Lang.bind(this, function(userManager, user) {
this._userList.addUser(user);
@ -1380,7 +1219,7 @@ const LoginDialog = new Lang.Class({
_onOpened: function() {
Main.ctrlAltTabManager.addGroup(this.dialogLayout,
_("Login Window"),
'dialog-password-symbolic',
'dialog-password',
{ sortGroup: CtrlAltTab.SortGroup.MIDDLE });
},
@ -1388,6 +1227,6 @@ const LoginDialog = new Lang.Class({
close: function() {
this.parent();
Main.ctrlAltTabManager.removeGroup(this.dialogLayout);
Main.ctrlAltTabManager.removeGroup(this._group);
}
});

View File

@ -23,7 +23,6 @@ const BANNER_MESSAGE_TEXT_KEY = 'banner-message-text';
const ALLOWED_FAILURES_KEY = 'allowed-failures';
const LOGO_KEY = 'logo';
const DISABLE_USER_LIST_KEY = 'disable-user-list';
function fadeInActor(actor) {
if (actor.opacity == 255 && actor.visible)

View File

@ -46,70 +46,8 @@ let _providersTable;
function _getProvidersTable() {
if (_providersTable)
return _providersTable;
return _providersTable = Shell.mobile_providers_parse(null,null);
}
function findProviderForMCCMNC(table, needle) {
let needlemcc = needle.substring(0, 3);
let needlemnc = needle.substring(3, needle.length);
let name2, name3;
for (let iter in table) {
let country = table[iter];
let providers = country.get_providers();
// Search through each country's providers
for (let i = 0; i < providers.length; i++) {
let provider = providers[i];
// Search through MCC/MNC list
let list = provider.get_gsm_mcc_mnc();
for (let j = 0; j < list.length; j++) {
let mccmnc = list[j];
// Match both 2-digit and 3-digit MNC; prefer a
// 3-digit match if found, otherwise a 2-digit one.
if (mccmnc.mcc != needlemcc)
continue; // MCC was wrong
if (!name3 && needle.length == 6 && needlemnc == mccmnc.mnc)
name3 = provider.name;
if (!name2 && needlemnc.substring(0, 2) == mccmnc.mnc.substring(0, 2))
name2 = provider.name;
if (name2 && name3)
break;
}
}
}
return name3 || name2 || null;
}
function findProviderForSid(table, sid) {
if (sid == 0)
return null;
// Search through each country
for (let iter in table) {
let country = table[iter];
let providers = country.get_providers();
// Search through each country's providers
for (let i = 0; i < providers.length; i++) {
let provider = providers[i];
let cdma_sid = provider.get_cdma_sid();
// Search through CDMA SID list
for (let j = 0; j < cdma_sid.length; j++) {
if (cdma_sid[j] == sid)
return provider.name;
}
}
}
return null;
let [providers, countryCodes] = Shell.mobile_providers_parse();
return _providersTable = providers;
}
const ModemGsm = new Lang.Class({
@ -153,29 +91,64 @@ const ModemGsm = new Lang.Class({
},
_findOperatorName: function(name, opCode) {
if (name) {
if (name && name.length != 0 && (name.length > 6 || name.length < 5)) {
// this looks like a valid name, i.e. not an MCCMNC (that some
// devices return when not yet connected
return name;
}
if (isNaN(parseInt(name))) {
// name is definitely not a MCCMNC, so it may be a name
// after all; return that
return name;
}
if (name.length != 0 && (name.length > 6 || name.length < 5)) {
// this looks like a valid name, i.e. not an MCCMNC (that some
// devices return when not yet connected
return name;
}
if (isNaN(parseInt(name))) {
// name is definitely not a MCCMNC, so it may be a name
// after all; return that
return name;
}
let needle;
if ((name == null || name.length == 0) && opCode)
if (name.length == 0 && opCode)
needle = opCode;
else if (name.length == 6 || name.length == 5)
needle = name;
else // nothing to search
return null;
return this._findProviderForMCCMNC(needle);
},
_findProviderForMCCMNC: function(needle) {
let table = _getProvidersTable();
return findProviderForMCCMNC(table, needle);
let needlemcc = needle.substring(0, 3);
let needlemnc = needle.substring(3, needle.length);
let name2, name3;
for (let iter in table) {
let providers = table[iter];
// Search through each country's providers
for (let i = 0; i < providers.length; i++) {
let provider = providers[i];
// Search through MCC/MNC list
let list = provider.get_gsm_mcc_mnc();
for (let j = 0; j < list.length; j++) {
let mccmnc = list[j];
// Match both 2-digit and 3-digit MNC; prefer a
// 3-digit match if found, otherwise a 2-digit one.
if (mccmnc.mcc != needlemcc)
continue; // MCC was wrong
if (!name3 && needle.length == 6 && needlemnc == mccmnc.mnc)
name3 = provider.name;
if (!name2 && needlemnc.substring(0, 2) == mccmnc.mnc.substring(0, 2))
name2 = provider.name;
if (name2 && name3)
break;
}
}
}
return name3 || name2 || null;
}
});
Signals.addSignalMethods(ModemGsm.prototype);
@ -216,14 +189,39 @@ const ModemCdma = new Lang.Class({
this.operator_name = null;
} else {
let [bandClass, band, id] = result;
if (name.length > 0) {
let table = _getProvidersTable();
this.operator_name = findProviderForSid(table, id);
} else
if (name.length > 0)
this.operator_name = this._findProviderForSid(id);
else
this.operator_name = null;
}
this.emit('notify::operator-name');
}));
},
_findProviderForSid: function(sid) {
if (sid == 0)
return null;
let table = _getProvidersTable();
// Search through each country
for (let iter in table) {
let providers = table[iter];
// Search through each country's providers
for (let i = 0; i < providers.length; i++) {
let provider = providers[i];
let cdma_sid = provider.get_cdma_sid();
// Search through CDMA SID list
for (let j = 0; j < cdma_sid.length; j++) {
if (cdma_sid[j] == sid)
return provider.name;
}
}
}
return null;
}
});
Signals.addSignalMethods(ModemCdma.prototype);

View File

@ -159,6 +159,86 @@ function killall(processName) {
}
}
// This was ported from network-manager-applet
// Copyright 2007 - 2011 Red Hat, Inc.
// Author: Dan Williams <dcbw@redhat.com>
const _IGNORED_WORDS = [
'Semiconductor',
'Components',
'Corporation',
'Communications',
'Company',
'Corp.',
'Corp',
'Co.',
'Inc.',
'Inc',
'Incorporated',
'Ltd.',
'Limited.',
'Intel',
'chipset',
'adapter',
'[hex]',
'NDIS',
'Module'
];
const _IGNORED_PHRASES = [
'Multiprotocol MAC/baseband processor',
'Wireless LAN Controller',
'Wireless LAN Adapter',
'Wireless Adapter',
'Network Connection',
'Wireless Cardbus Adapter',
'Wireless CardBus Adapter',
'54 Mbps Wireless PC Card',
'Wireless PC Card',
'Wireless PC',
'PC Card with XJACK(r) Antenna',
'Wireless cardbus',
'Wireless LAN PC Card',
'Technology Group Ltd.',
'Communication S.p.A.',
'Business Mobile Networks BV',
'Mobile Broadband Minicard Composite Device',
'Mobile Communications AB',
'(PC-Suite Mode)'
];
function fixupPCIDescription(desc) {
desc = desc.replace(/[_,]/, ' ');
/* Attempt to shorten ID by ignoring certain phrases */
for (let i = 0; i < _IGNORED_PHRASES.length; i++) {
let item = _IGNORED_PHRASES[i];
let pos = desc.indexOf(item);
if (pos != -1) {
let before = desc.substring(0, pos);
let after = desc.substring(pos + item.length, desc.length);
desc = before + after;
}
}
/* Attmept to shorten ID by ignoring certain individual words */
let words = desc.split(' ');
let out = [ ];
for (let i = 0; i < words.length; i++) {
let item = words[i];
// skip empty items (that come out from consecutive spaces)
if (item.length == 0)
continue;
if (_IGNORED_WORDS.indexOf(item) == -1) {
out.push(item);
}
}
return out.join(' ');
}
// lowerBound:
// @array: an array or array-like object, already sorted
// according to @cmp

View File

@ -172,7 +172,7 @@ const AltTabPopup = new Lang.Class({
if (!Main.pushModal(this.actor)) {
// Probably someone else has a pointer grab, try again with keyboard only
if (!Main.pushModal(this.actor, { options: Meta.ModalOptions.POINTER_ALREADY_GRABBED })) {
if (!Main.pushModal(this.actor, global.get_current_time(), Meta.ModalOptions.POINTER_ALREADY_GRABBED)) {
return false;
}
}

View File

@ -1,6 +1,7 @@
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
const Clutter = imports.gi.Clutter;
const Gio = imports.gi.Gio;
const GLib = imports.gi.GLib;
const Gtk = imports.gi.Gtk;
const GMenu = imports.gi.GMenu;
@ -216,16 +217,6 @@ const ViewByCategories = new Lang.Class({
},
_addCategory: function(name, index, dir) {
let apps;
if (dir != null) {
apps = [];
this._loadCategory(dir, apps);
if (apps.length == 0)
return;
}
let button = new St.Button({ label: GLib.markup_escape_text (name, -1),
style_class: 'app-filter',
x_align: St.Align.START,
@ -235,9 +226,12 @@ const ViewByCategories = new Lang.Class({
this._selectCategory(index);
}));
var apps;
if (dir == null) {
this._allCategoryButton = button;
} else {
apps = [];
this._loadCategory(dir, apps);
this._categories.push({ apps: apps,
name: name,
button: button });
@ -378,6 +372,8 @@ const SettingsSearchProvider = new Lang.Class({
this._appSys = Shell.AppSystem.get_default();
this._gnomecc = this._appSys.lookup_app('gnome-control-center.desktop');
let appInfo = Gio.DesktopAppInfo.new('gnome-control-center.desktop');
this.icon = appInfo.get_icon();
},
getResultMetas: function(prefs, callback) {
@ -386,9 +382,7 @@ const SettingsSearchProvider = new Lang.Class({
let pref = prefs[i];
metas.push({ 'id': pref,
'name': pref.get_name(),
'createIcon': function(size) {
return pref.create_icon_texture(size);
}
'createIcon': function(size) { return; }
});
}
callback(metas);
@ -468,15 +462,15 @@ const AppWellIcon = new Lang.Class({
this._draggable.connect('drag-begin', Lang.bind(this,
function () {
this._removeMenuTimeout();
Main.overview.beginItemDrag(this);
Main.overview.beginAppDrag(this);
}));
this._draggable.connect('drag-cancelled', Lang.bind(this,
function () {
Main.overview.cancelledItemDrag(this);
Main.overview.cancelledAppDrag(this);
}));
this._draggable.connect('drag-end', Lang.bind(this,
function () {
Main.overview.endItemDrag(this);
Main.overview.endAppDrag(this);
}));
this.actor.connect('destroy', Lang.bind(this, this._onDestroy));
@ -486,6 +480,7 @@ const AppWellIcon = new Lang.Class({
Lang.bind(this,
this._onStateChanged));
this._onStateChanged();
this.isMenuUp = false;
},
_onDestroy: function() {
@ -567,8 +562,7 @@ const AppWellIcon = new Lang.Class({
this._menuManager.addMenu(this._menu);
}
this.emit('menu-state-changed', true);
this.isMenuUp = true;
this.actor.set_hover(true);
this._menu.popup();
@ -585,7 +579,7 @@ const AppWellIcon = new Lang.Class({
_onMenuPoppedDown: function() {
this.actor.sync_hover();
this.emit('menu-state-changed', false);
this.isMenuUp = false;
},
_onActivate: function (event) {

View File

@ -84,12 +84,9 @@ const AppFavorites = new Lang.Class({
let app = Shell.AppSystem.get_default().lookup_app(appId);
Main.overview.setMessage(_("%s has been added to your favorites.").format(app.get_name()),
{ forFeedback: true,
undoCallback: Lang.bind(this, function () {
this._removeFavorite(appId);
})
});
Main.overview.setMessage(_("%s has been added to your favorites.").format(app.get_name()), Lang.bind(this, function () {
this._removeFavorite(appId);
}));
},
addFavorite: function(appId) {
@ -119,11 +116,9 @@ const AppFavorites = new Lang.Class({
return;
Main.overview.setMessage(_("%s has been removed from your favorites.").format(app.get_name()),
{ forFeedback: true,
undoCallback: Lang.bind(this, function () {
this._addFavorite(appId, pos);
})
});
Lang.bind(this, function () {
this._addFavorite(appId, pos);
}));
}
});
Signals.addSignalMethods(AppFavorites.prototype);

93
js/ui/centerLayout.js Normal file
View File

@ -0,0 +1,93 @@
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
const Lang = imports.lang;
const Clutter = imports.gi.Clutter;
const St = imports.gi.St;
function connectLayoutManager(layoutManager, styleChanged) {
let widget, styleChangedId;
function _styleChanged() {
let themeNode = widget.get_theme_node();
styleChanged(themeNode, widget);
}
function actorChanged() {
if (widget) {
widget.disconnect(styleChangedId);
styleChangedId = 0;
}
let actor = layoutManager.get_actor();
if (actor && actor instanceof St.Widget) {
widget = actor;
styleChangedId = widget.connect('style-changed', _styleChanged);
_styleChanged();
}
}
layoutManager.connect('notify::actor', actorChanged);
return layoutManager;
}
function connectSpacing(layoutManager) {
return connectLayoutManager(layoutManager, function(themeNode, widget) {
layoutManager.spacing = themeNode.get_length('spacing');
});
}
const CenterLayout = new Lang.Class({
Name: 'CenterLayout',
Extends: Clutter.BoxLayout,
vfunc_allocate: function(container, box, flags) {
let rtl = container.get_text_direction() == Clutter.TextDirection.RTL;
let availWidth = box.x2 - box.x1;
let availHeight = box.y2 - box.y1;
// Assume that these are the first three widgets and they are all visible.
let [left, center, right] = container.get_children();
// Only support horizontal layouts for now.
let [centerMinWidth, centerNaturalWidth] = center.get_preferred_width(availWidth);
let sideWidth = (availWidth - centerNaturalWidth) / 2;
let childBox = new Clutter.ActorBox();
childBox.y1 = box.y1;
childBox.y2 = box.y1 + availHeight;
if (left) {
let [leftMinWidth, leftNaturalWidth] = left.get_preferred_width(availWidth);
let leftSide = Math.min(Math.floor(sideWidth), leftNaturalWidth);
if (rtl) {
childBox.x1 = availWidth - leftSide;
childBox.x2 = availWidth;
} else {
childBox.x1 = 0;
childBox.x2 = leftSide;
}
childBox.x1 += box.x1;
left.allocate(childBox, flags);
}
childBox.x1 = box.x1 + Math.ceil(sideWidth);
childBox.x2 = childBox.x1 + centerNaturalWidth;
center.allocate(childBox, flags);
if (right) {
let [rightMinWidth, rightNaturalWidth] = right.get_preferred_width(availWidth);
let rightSide = Math.min(Math.floor(sideWidth), rightNaturalWidth);
if (rtl) {
childBox.x1 = 0;
childBox.x2 = rightSide;
} else {
childBox.x1 = availWidth - rightSide;
childBox.x2 = availWidth;
}
childBox.x1 += box.x1;
right.allocate(childBox, flags);
}
}
});

View File

@ -598,7 +598,7 @@ const NetworkAgent = new Lang.Class({
},
enable: function() {
this._native.auto_register = true;
this._native.register();
},
disable: function() {
@ -612,7 +612,6 @@ const NetworkAgent = new Lang.Class({
this._vpnRequests[requestId].cancel(true);
this._vpnRequests = { };
this._native.auto_register = false;
this._native.unregister();
},

View File

@ -49,7 +49,7 @@ const AuthenticationDialog = new Lang.Class({
let messageBox = new St.BoxLayout({ style_class: 'prompt-dialog-message-layout',
vertical: true });
mainContentBox.add(messageBox,
{ expand: true, y_align: St.Align.START });
{ y_align: St.Align.START });
this._subjectLabel = new St.Label({ style_class: 'prompt-dialog-headline',
text: _("Authentication Required") });

View File

@ -1,6 +1,5 @@
const Lang = imports.lang;
const Main = imports.ui.main;
const Gio = imports.gi.Gio;
const Meta = imports.gi.Meta;
@ -17,16 +16,13 @@ const Recorder = new Lang.Class({
},
enable: function() {
Main.wm.addKeybinding('toggle-recording',
this._bindingSettings,
Meta.KeyBindingFlags.NONE,
Main.KeybindingMode.NORMAL |
Main.KeybindingMode.OVERVIEW,
Lang.bind(this, this._toggleRecorder));
global.display.add_keybinding('toggle-recording',
this._bindingSettings,
Meta.KeyBindingFlags.NONE, Lang.bind(this, this._toggleRecorder));
},
disable: function() {
Main.wm.removeKeybinding('toggle-recording');
global.display.remove_keybinding('toggle-recording');
},
_ensureRecorder: function() {

View File

@ -383,12 +383,25 @@ const TelepathyClient = new Lang.Class({
}
/* Display notification to ask user to accept/reject request */
let source = this._ensureAppSource();
let source = this._ensureSubscriptionSource();
let notif = new SubscriptionRequestNotification(source, contact);
source.notify(notif);
},
_ensureSubscriptionSource: function() {
if (this._subscriptionSource == null) {
this._subscriptionSource = new MessageTray.Source(_("Subscription request"),
'gtk-dialog-question');
Main.messageTray.add(this._subscriptionSource);
this._subscriptionSource.connect('destroy', Lang.bind(this, function () {
this._subscriptionSource = null;
}));
}
return this._subscriptionSource;
},
_accountConnectionStatusNotifyCb: function(account) {
let connectionError = account.connection_error;
@ -402,7 +415,7 @@ const TelepathyClient = new Lang.Class({
return;
/* Display notification that account failed to connect */
let source = this._ensureAppSource();
let source = this._ensureAccountSource();
notif = new AccountNotification(source, account, connectionError);
this._accountNotifications[account.get_object_path()] = notif;
@ -412,16 +425,17 @@ const TelepathyClient = new Lang.Class({
source.notify(notif);
},
_ensureAppSource: function() {
if (this._appSource == null) {
this._appSource = new MessageTray.Source(_("Chat"), 'empathy');
Main.messageTray.add(this._appSource);
this._appSource.connect('destroy', Lang.bind(this, function () {
this._appSource = null;
_ensureAccountSource: function() {
if (this._accountSource == null) {
this._accountSource = new MessageTray.Source(_("Connection error"),
'gtk-dialog-error');
Main.messageTray.add(this._accountSource);
this._accountSource.connect('destroy', Lang.bind(this, function () {
this._accountSource = null;
}));
}
return this._appSource;
return this._accountSource;
}
});
@ -730,7 +744,8 @@ const ChatSource = new Lang.Class({
_ackMessages: function() {
// Don't clear our messages here, tp-glib will send a
// 'pending-message-removed' for each one.
this._channel.ack_all_pending_messages_async(null);
this._channel.ack_all_pending_messages_async(Lang.bind(this, function(src, result) {
this._channel.ack_all_pending_messages_finish(result);}));
}
});
@ -756,19 +771,16 @@ const ChatNotification = new Lang.Class({
this.emit('unfocused');
}));
this._oldMaxScrollAdjustment = 0;
this._createScrollArea();
this._lastGroup = null;
this._lastGroupActor = null;
// Keep track of the bottom position for the current adjustment and
// force a scroll to the bottom if things change while we were at the
// bottom
this._oldMaxScrollValue = this._scrollArea.vscroll.adjustment.value;
this._scrollArea.add_style_class_name('chat-notification-scrollview');
this._scrollArea.vscroll.adjustment.connect('changed', Lang.bind(this, function(adjustment) {
if (adjustment.value == this._oldMaxScrollValue)
let currentValue = adjustment.value + adjustment.page_size;
if (currentValue == this._oldMaxScrollAdjustment)
this.scrollTo(St.Side.BOTTOM);
this._oldMaxScrollValue = Math.max(adjustment.lower, adjustment.upper - adjustment.page_size);
this._oldMaxScrollAdjustment = adjustment.upper;
}));
this._inputHistory = new History.HistoryManager({ entry: this._responseEntry.clutter_text });
@ -1121,7 +1133,7 @@ const AudioVideoNotification = new Lang.Class({
this.parent(source, title, null, { customContent: true });
this.setResident(true);
this.addButton('reject', _("Decline"));
this.addButton('reject', _("Reject"));
/* translators: this is a button label (verb), not a noun */
this.addButton('answer', _("Answer"));
@ -1338,16 +1350,26 @@ const AccountNotification = new Lang.Class({
this.parent(source,
/* translators: argument is the account name, like
* name@jabber.org for example. */
_("Unable to connect to %s").format(account.get_display_name()),
this._getMessage(connectionError));
_("Connection to %s failed").format(account.get_display_name()),
null, { customContent: true });
this._label = new St.Label();
this.addActor(this._label);
this._updateMessage(connectionError);
this._account = account;
this.addButton('view', _("View account"));
this.addButton('reconnect', _("Reconnect"));
this.addButton('edit', _("Edit account"));
this.connect('action-invoked', Lang.bind(this, function(self, action) {
switch (action) {
case 'view':
case 'reconnect':
// If it fails again, a new notification should pop up with the
// new error.
account.reconnect_async(null);
break;
case 'edit':
let cmd = '/usr/bin/empathy-accounts'
+ ' --select-account=%s'
.format(account.get_path_suffix());
@ -1373,19 +1395,19 @@ const AccountNotification = new Lang.Class({
if (status == Tp.ConnectionStatus.CONNECTED) {
this.destroy();
} else if (status == Tp.ConnectionStatus.DISCONNECTED) {
this.update(this.title, this._getMessage(account.connection_error));
this._updateMessage(account.connection_error);
}
}));
},
_getMessage: function(connectionError) {
_updateMessage: function(connectionError) {
let message;
if (connectionError in _connectionErrorMessages) {
message = _connectionErrorMessages[connectionError];
} else {
message = _("Unknown reason");
}
return message;
this._label.set_text(message);
},
destroy: function() {

View File

@ -23,7 +23,8 @@ const DASH_ITEM_HOVER_TIMEOUT = 300;
function getAppFromSource(source) {
if (source instanceof AppDisplay.AppWellIcon) {
return source.app;
let appSystem = Shell.AppSystem.get_default();
return appSystem.lookup_app(source.getId());
} else if (source.metaWindow) {
let tracker = Shell.WindowTracker.get_default();
return tracker.get_window_app(source.metaWindow);
@ -141,7 +142,6 @@ const DashItemContainer = new Lang.Class({
setLabelText: function(text) {
this._labelText = text;
this.child.accessible_name = text;
},
hideLabel: function () {
@ -259,6 +259,7 @@ const ShowAppsIcon = new Lang.Class({
this.setChild(this.toggleButton);
this.setDragApp(null);
this.toggleButton.label_actor = this.label;
},
_createIcon: function(size) {
@ -371,6 +372,9 @@ const Dash = new Lang.Class({
this._maxHeight = -1;
this.iconSize = 64;
this._shownInitially = false;
this.visible = false;
this._hiddenX;
this._targetX;
this._dragPlaceholder = null;
this._dragPlaceholderPos = -1;
@ -398,7 +402,8 @@ const Dash = new Lang.Class({
function() {
if (this._maxHeight != this.actor.height)
this._queueRedisplay();
this._maxHeight = this.actor.height;
if (this.actor.height > this._maxHeight)
this._maxHeight = this.actor.height;
}));
this._workId = Main.initializeDeferredWork(this._box, Lang.bind(this, this._redisplay));
@ -409,11 +414,11 @@ const Dash = new Lang.Class({
AppFavorites.getAppFavorites().connect('changed', Lang.bind(this, this._queueRedisplay));
this._appSystem.connect('app-state-changed', Lang.bind(this, this._queueRedisplay));
Main.overview.connect('item-drag-begin',
Main.overview.connect('app-drag-begin',
Lang.bind(this, this._onDragBegin));
Main.overview.connect('item-drag-end',
Main.overview.connect('app-drag-end',
Lang.bind(this, this._onDragEnd));
Main.overview.connect('item-drag-cancelled',
Main.overview.connect('app-drag-cancelled',
Lang.bind(this, this._onDragCancelled));
Main.overview.connect('window-drag-begin',
Lang.bind(this, this._onDragBegin));
@ -491,51 +496,32 @@ const Dash = new Lang.Class({
},
_createAppItem: function(app) {
let appIcon = new AppDisplay.AppWellIcon(app,
let display = new AppDisplay.AppWellIcon(app,
{ setSizeManually: true,
showLabel: false });
appIcon._draggable.connect('drag-begin',
display._draggable.connect('drag-begin',
Lang.bind(this, function() {
appIcon.actor.opacity = 50;
display.actor.opacity = 50;
}));
appIcon._draggable.connect('drag-end',
display._draggable.connect('drag-end',
Lang.bind(this, function() {
appIcon.actor.opacity = 255;
display.actor.opacity = 255;
}));
appIcon.connect('menu-state-changed',
Lang.bind(this, function(appIcon, opened) {
this._itemMenuStateChanged(item, opened);
}));
let item = new DashItemContainer();
item.setChild(appIcon.actor);
item.setChild(display.actor);
// Override default AppWellIcon label_actor, now the
// accessible_name is set at DashItemContainer.setLabelText
appIcon.actor.label_actor = null;
item.setLabelText(app.get_name());
appIcon.icon.setIconSize(this.iconSize);
// Override default AppWellIcon label_actor
display.actor.label_actor = item.label;
display.icon.setIconSize(this.iconSize);
this._hookUpLabel(item);
return item;
},
_itemMenuStateChanged: function(item, opened) {
// When the menu closes, it calls sync_hover, which means
// that the notify::hover handler does everything we need to.
if (opened) {
if (this._showLabelTimeoutId > 0) {
Mainloop.source_remove(this._showLabelTimeoutId);
this._showLabelTimeoutId = 0;
}
item.hideLabel();
}
},
_onHover: function (item) {
if (item.child.get_hover()) {
if (item.child.get_hover() && !item.child._delegate.isMenuUp) {
if (this._showLabelTimeoutId == 0) {
let timeout = this._labelShowing ? 0 : DASH_ITEM_HOVER_TIMEOUT;
this._showLabelTimeoutId = Mainloop.timeout_add(timeout,
@ -564,6 +550,17 @@ const Dash = new Lang.Class({
}
},
_computeDashX: function() {
this._targetX = this.actor.get_x();
let rtl = (this.actor.get_text_direction() == Clutter.TextDirection.RTL);
if (rtl)
this._hiddenX = this._targetX + this.actor.width;
else
this._hiddenX = -this.actor.width;
},
_adjustIconSize: function() {
// For the icon size, we only consider children which are "proper"
// icons (i.e. ignoring drag placeholders) and which are not
@ -637,10 +634,8 @@ const Dash = new Lang.Class({
icon.setIconSize(this.iconSize);
// Don't animate the icon size change when the overview
// is transitioning, not visible or when initially filling
// the dash
if (!Main.overview.visible || Main.overview.animationInProgress ||
!this._shownInitially)
// is not visible or when initially filling the dash
if (!Main.overview.visible || !this._shownInitially)
continue;
let [targetWidth, targetHeight] = icon.icon.get_size();
@ -661,6 +656,8 @@ const Dash = new Lang.Class({
}
});
}
this._computeDashX();
},
_redisplay: function () {
@ -764,9 +761,8 @@ const Dash = new Lang.Class({
for (let i = 0; i < removedActors.length; i++) {
let item = removedActors[i]._delegate;
// Don't animate item removal when the overview is transitioning
// or hidden
if (Main.overview.visible && !Main.overview.animationInProgress)
// Don't animate item removal when the overview is hidden
if (Main.overview.visible)
item.animateOutAndDestroy();
else
item.destroy();
@ -778,12 +774,12 @@ const Dash = new Lang.Class({
// of items, to avoid all items zooming in at once
if (!this._shownInitially) {
this._shownInitially = true;
this.visible = true;
return;
}
// Don't animate item addition when the overview is transitioning
// or hidden
if (!Main.overview.visible || Main.overview.animationInProgress)
// Don't animate item addition when the overview is hidden
if (!Main.overview.visible)
return;
for (let i = 0; i < addedItems.length; i++)
@ -923,6 +919,34 @@ const Dash = new Lang.Class({
}));
return true;
},
show: function() {
if (this.visible)
return;
this.visible = true;
this.actor.show();
Tweener.addTween(this.actor, { translation_x: this._targetX,
transition: 'easeOutQuad',
time: DASH_ANIMATION_TIME
});
},
hide: function() {
if (!this.visible)
return;
this.visible = false;
Tweener.addTween(this.actor, { translation_x: this._hiddenX,
transition: 'easeOutQuad',
time: DASH_ANIMATION_TIME,
onComplete: Lang.bind(this, function () {
this.actor.hide();
})
});
}
});

View File

@ -105,7 +105,7 @@ const restartDialogContent = {
endDescription: _("Restarting the system."),
confirmButtons: [{ signal: 'ConfirmedReboot',
label: C_("button", "Restart") }],
iconName: 'view-refresh-symbolic',
iconName: 'system-shutdown-symbolic',
iconStyleClass: 'end-session-dialog-shutdown-icon'
};

View File

@ -126,7 +126,11 @@ function logExtensionError(uuid, error) {
let message = '' + error;
extension.state = ExtensionState.ERROR;
if (error.state)
extension.state = error.state;
else
extension.state = ExtensionState.ERROR;
if (!extension.errors)
extension.errors = [];
@ -141,16 +145,18 @@ function loadExtension(extension) {
extension.state = ExtensionState.ERROR;
if (ExtensionUtils.isOutOfDate(extension)) {
extension.state = ExtensionState.OUT_OF_DATE;
let error = new Error('extension is not compatible with current GNOME Shell and/or GJS version');
error.state = ExtensionState.OUT_OF_DATE;
throw error;
}
let enabled = enabledExtensions.indexOf(extension.uuid) != -1;
if (enabled) {
initExtension(extension.uuid);
if (extension.state == ExtensionState.DISABLED)
enableExtension(extension.uuid);
} else {
let enabled = enabledExtensions.indexOf(extension.uuid) != -1;
if (enabled) {
initExtension(extension.uuid);
if (extension.state == ExtensionState.DISABLED)
enableExtension(extension.uuid);
} else {
extension.state = ExtensionState.INITIALIZED;
}
extension.state = ExtensionState.INITIALIZED;
}
_signals.emit('extension-state-changed', extension);

View File

@ -23,7 +23,6 @@ function _navigateActor(actor) {
// GrabHelper:
// @owner: the actor that owns the GrabHelper
// @params: optional parameters to pass to Main.pushModal()
//
// Creates a new GrabHelper object, for dealing with keyboard and pointer grabs
// associated with a set of actors.
@ -35,9 +34,8 @@ function _navigateActor(actor) {
const GrabHelper = new Lang.Class({
Name: 'GrabHelper',
_init: function(owner, params) {
_init: function(owner) {
this._owner = owner;
this._modalParams = params;
this._grabStack = [];
@ -167,7 +165,7 @@ const GrabHelper = new Lang.Class({
_takeModalGrab: function() {
let firstGrab = (this._modalCount == 0);
if (firstGrab) {
if (!Main.pushModal(this._owner, this._modalParams))
if (!Main.pushModal(this._owner))
return false;
this._capturedEventId = global.stage.connect('captured-event', Lang.bind(this, this._onCapturedEvent));

View File

@ -198,7 +198,11 @@ const IconGrid = new Lang.Class({
_getPreferredHeight: function (grid, forWidth, alloc) {
let children = this._getVisibleChildren();
let [nColumns, usedWidth] = this._computeLayout(forWidth);
let nColumns;
if (forWidth < 0)
nColumns = children.length;
else
nColumns = this._computeLayout(forWidth)[0];
let nRows;
if (nColumns > 0)
nRows = Math.ceil(children.length / nColumns);

View File

@ -20,6 +20,25 @@ const KEYBOARD_TYPE = 'keyboard-type';
const A11Y_APPLICATIONS_SCHEMA = 'org.gnome.desktop.a11y.applications';
const SHOW_KEYBOARD = 'screen-keyboard-enabled';
// Key constants taken from Antler
// FIXME: ought to be moved into libcaribou
const PRETTY_KEYS = {
'BackSpace': '\u232b',
'space': ' ',
'Return': '\u23ce',
'Caribou_Prefs': '\u2328',
'Caribou_ShiftUp': '\u2b06',
'Caribou_ShiftDown': '\u2b07',
'Caribou_Emoticons': '\u263a',
'Caribou_Symbols': '123',
'Caribou_Symbols_More': '{#*',
'Caribou_Alpha': 'Abc',
'Tab': 'Tab',
'Escape': 'Esc',
'Control_L': 'Ctrl',
'Alt_L': 'Alt'
};
const CaribouKeyboardIface = <interface name='org.gnome.Caribou.Keyboard'>
<method name='Show'>
<arg type='u' direction='in' />
@ -79,7 +98,17 @@ const Key = new Lang.Class({
},
_makeKey: function () {
let label = GLib.markup_escape_text(this._key.label, -1);
let label = this._key.name;
if (label.length > 1) {
let pretty = PRETTY_KEYS[label];
if (pretty)
label = pretty;
else
label = this._getUnichar(this._key);
}
label = GLib.markup_escape_text(label, -1);
let button = new St.Button ({ label: label,
style_class: 'keyboard-key' });
@ -251,7 +280,7 @@ const Keyboard = new Lang.Class({
this._focusNotifyId = global.stage.connect('notify::key-focus', Lang.bind(this, this._onKeyFocusChanged));
if (show)
this.show(Main.layoutManager.focusIndex);
this.show();
else
this._createSource();
},
@ -375,7 +404,7 @@ const Keyboard = new Lang.Class({
if (!this._enableKeyboard)
return;
let monitor = Main.layoutManager.keyboardMonitor;
let monitor = Main.layoutManager.bottomMonitor;
let maxHeight = monitor.height / 3;
this.actor.width = monitor.width;
@ -462,9 +491,9 @@ const Keyboard = new Lang.Class({
actor._extended_keys || actor.extended_key;
},
show: function (monitor) {
Main.layoutManager.keyboardIndex = monitor;
show: function () {
this._redraw();
Main.layoutManager.showKeyboard();
this._destroySource();
},
@ -512,7 +541,7 @@ const Keyboard = new Lang.Class({
if (timestamp != Clutter.CURRENT_TIME)
this._timestamp = timestamp;
this.show(Main.layoutManager.focusIndex);
this.show();
},
Hide: function(timestamp) {
@ -566,7 +595,6 @@ const KeyboardSource = new Lang.Class({
},
open: function() {
// Show the OSK below the message tray
this._keyboard.show(Main.layoutManager.bottomIndex);
this._keyboard.show();
}
});

View File

@ -103,7 +103,6 @@ const LayoutManager = new Lang.Class({
this.monitors = [];
this.primaryMonitor = null;
this.primaryIndex = -1;
this._keyboardIndex = -1;
this._hotCorners = [];
this._background = null;
this._leftPanelBarrier = 0;
@ -129,6 +128,8 @@ const LayoutManager = new Lang.Class({
this.trayBox = new St.Widget({ name: 'trayBox',
layout_manager: new Clutter.BinLayout() });
this.addChrome(this.trayBox);
this.trayBox.connect('allocation-changed',
Lang.bind(this, this._updateTrayBarrier));
this.keyboardBox = new St.BoxLayout({ name: 'keyboardBox',
reactive: true,
@ -241,8 +242,9 @@ const LayoutManager = new Lang.Class({
this.panelBox.set_position(this.primaryMonitor.x, this.primaryMonitor.y);
this.panelBox.set_size(this.primaryMonitor.width, -1);
if (this.keyboardIndex < 0)
this.keyboardIndex = this.primaryIndex;
this.keyboardBox.set_position(this.bottomMonitor.x,
this.bottomMonitor.y + this.bottomMonitor.height);
this.keyboardBox.set_size(this.bottomMonitor.width, -1);
this.trayBox.set_position(this.bottomMonitor.x,
this.bottomMonitor.y + this.bottomMonitor.height);
@ -278,6 +280,22 @@ const LayoutManager = new Lang.Class({
}
},
_updateTrayBarrier: function() {
let monitor = this.bottomMonitor;
if (this._trayBarrier)
global.destroy_pointer_barrier(this._trayBarrier);
if (Main.messageTray) {
this._trayBarrier =
global.create_pointer_barrier(monitor.x + monitor.width, monitor.y + monitor.height - Main.messageTray.actor.height,
monitor.x + monitor.width, monitor.y + monitor.height,
4 /* BarrierNegativeX */);
} else {
this._trayBarrier = 0;
}
},
_monitorsChanged: function() {
this._updateMonitors();
this._updateBoxes();
@ -305,42 +323,6 @@ const LayoutManager = new Lang.Class({
return this.monitors[index];
},
get keyboardMonitor() {
return this.monitors[this.keyboardIndex];
},
get focusIndex() {
let i = Main.layoutManager.primaryIndex;
if (global.stage_input_mode == Shell.StageInputMode.FOCUSED ||
global.stage_input_mode == Shell.StageInputMode.FULLSCREEN) {
let focusActor = global.stage.key_focus;
if (focusActor)
i = this._chrome.findIndexForActor(focusActor);
} else {
let focusWindow = global.display.focus_window;
if (focusWindow)
i = this._chrome.findIndexForWindow(focusWindow.get_compositor_private());
}
return i;
},
get focusMonitor() {
return this.monitors[this.focusIndex];
},
set keyboardIndex(v) {
this._keyboardIndex = v;
this.keyboardBox.set_position(this.keyboardMonitor.x,
this.keyboardMonitor.y + this.keyboardMonitor.height);
this.keyboardBox.set_size(this.keyboardMonitor.width, -1);
},
get keyboardIndex() {
return this._keyboardIndex;
},
_startupAnimation: function() {
this.panelBox.anchor_y = this.panelBox.height;
@ -399,14 +381,11 @@ const LayoutManager = new Lang.Class({
onComplete: this._showKeyboardComplete,
onCompleteScope: this
});
if (this.keyboardIndex == this.bottomIndex) {
Tweener.addTween(this.trayBox,
{ anchor_y: this.keyboardBox.height,
time: KEYBOARD_ANIMATION_TIME,
transition: 'easeOutQuad'
});
}
Tweener.addTween(this.trayBox,
{ anchor_y: this.keyboardBox.height,
time: KEYBOARD_ANIMATION_TIME,
transition: 'easeOutQuad'
});
this.emit('keyboard-visible-changed', true);
},
@ -418,8 +397,7 @@ const LayoutManager = new Lang.Class({
this._keyboardHeightNotifyId = this.keyboardBox.connect('notify::height', Lang.bind(this, function () {
this.keyboardBox.anchor_y = this.keyboardBox.height;
if (this.keyboardIndex == this.bottomIndex)
this.trayBox.anchor_y = this.keyboardBox.height;
this.trayBox.anchor_y = this.keyboardBox.height;
}));
},
@ -435,14 +413,11 @@ const LayoutManager = new Lang.Class({
onComplete: this._hideKeyboardComplete,
onCompleteScope: this
});
if (this.keyboardIndex == this.bottomIndex) {
Tweener.addTween(this.trayBox,
{ anchor_y: 0,
time: immediate ? 0 : KEYBOARD_ANIMATION_TIME,
transition: 'easeOutQuad'
});
}
Tweener.addTween(this.trayBox,
{ anchor_y: 0,
time: immediate ? 0 : KEYBOARD_ANIMATION_TIME,
transition: 'easeOutQuad'
});
this.emit('keyboard-visible-changed', false);
},
@ -506,7 +481,7 @@ const LayoutManager = new Lang.Class({
},
findMonitorForActor: function(actor) {
return this.monitors[this._chrome.findIndexForActor(actor)];
return this._chrome.findMonitorForActor(actor);
}
});
Signals.addSignalMethods(LayoutManager.prototype);
@ -855,7 +830,6 @@ const Chrome = new Lang.Class({
_relayout: function() {
this._monitors = this._layoutManager.monitors;
this._primaryIndex = this._layoutManager.primaryIndex;
this._primaryMonitor = this._layoutManager.primaryMonitor;
this._updateFullscreen();
@ -871,47 +845,32 @@ const Chrome = new Lang.Class({
let monitor = this._monitors[i];
if (cx >= monitor.x && cx < monitor.x + monitor.width &&
cy >= monitor.y && cy < monitor.y + monitor.height)
return i;
return monitor;
}
// If the center is not on a monitor, return the first overlapping monitor
for (let i = 0; i < this._monitors.length; i++) {
let monitor = this._monitors[i];
if (x + w > monitor.x && x < monitor.x + monitor.width &&
y + h > monitor.y && y < monitor.y + monitor.height)
return i;
return monitor;
}
// otherwise on no monitor
return -1;
return null;
},
findIndexForWindow: function(window) {
let i = this._findMonitorForRect(window.x, window.y, window.width, window.height);
if (i >= 0)
return i;
return this._primaryIndex; // Not on any monitor, pretend its on the primary
_findMonitorForWindow: function(window) {
return this._findMonitorForRect(window.x, window.y, window.width, window.height);
},
// This call guarantees that we return some monitor to simplify usage of it
// In practice all tracked actors should be visible on some monitor anyway
findIndexForActor: function(actor) {
findMonitorForActor: function(actor) {
let [x, y] = actor.get_transformed_position();
let [w, h] = actor.get_transformed_size();
let i = this._findMonitorForRect(x, y, w, h);
if (i >= 0)
return i;
return this._primaryIndex; // Not on any monitor, pretend its on the primary
},
findMonitorForWindow: function(window) {
let i = this._findMonitorForRect(window.x, window.y, window.width, window.height);
if (i >= 0)
return this._monitors[i];
else
return null;
},
findMonitorForActor: function(actor) {
return this._monitors[this.findIndexForActor(actor)];
let monitor = this._findMonitorForRect(x, y, w, h);
if (monitor)
return monitor;
return this._primaryMonitor; // Not on any monitor, pretend its on the primary
},
_queueUpdateRegions: function() {
@ -959,7 +918,7 @@ const Chrome = new Lang.Class({
continue;
if (layer == Meta.StackLayer.FULLSCREEN) {
let monitor = this.findMonitorForWindow(window);
let monitor = this._findMonitorForWindow(window);
if (monitor)
monitor.inFullscreen = true;
}
@ -976,7 +935,7 @@ const Chrome = new Lang.Class({
}
// Or whether it is monitor sized
let monitor = this.findMonitorForWindow(window);
let monitor = this._findMonitorForWindow(window);
if (monitor &&
window.x <= monitor.x &&
window.x + window.width >= monitor.x + monitor.width &&

View File

@ -1129,7 +1129,7 @@ const LookingGlass = new Lang.Class({
if (this._open)
return;
if (!Main.pushModal(this._entry, { keybindingMode: Main.KeybindingMode.LOOKING_GLASS }))
if (!Main.pushModal(this._entry))
return;
this._notebook.selectIndex(0);

View File

@ -20,7 +20,6 @@ const Keyboard = imports.ui.keyboard;
const MessageTray = imports.ui.messageTray;
const Overview = imports.ui.overview;
const Panel = imports.ui.panel;
const Params = imports.misc.params;
const RunDialog = imports.ui.runDialog;
const Layout = imports.ui.layout;
const LookingGlass = imports.ui.lookingGlass;
@ -40,18 +39,6 @@ const Util = imports.misc.util;
const OVERRIDES_SCHEMA = 'org.gnome.shell.overrides';
const DEFAULT_BACKGROUND_COLOR = Clutter.Color.from_pixel(0x2e3436ff);
const KeybindingMode = {
NONE: 0, // block all keybindings
NORMAL: 1 << 0, // window mode
OVERVIEW: 1 << 1,
LOCK_SCREEN: 1 << 2,
UNLOCK_SCREEN: 1 << 3,
LOGIN_SCREEN: 1 << 4,
MESSAGE_TRAY: 1 << 5,
SYSTEM_MODAL: 1 << 6,
LOOKING_GLASS: 1 << 7
};
let componentManager = null;
let panel = null;
let overview = null;
@ -68,7 +55,6 @@ let shellDBusService = null;
let shellMountOpDBusService = null;
let screenSaverDBus = null;
let modalCount = 0;
let keybindingMode = KeybindingMode.NORMAL;
let modalActorFocusStack = [];
let uiGroup = null;
let magnifier = null;
@ -83,17 +69,7 @@ let _overridesSettings = null;
let background = null;
function _sessionUpdated() {
wm.setCustomKeybindingHandler('panel-main-menu',
KeybindingMode.NORMAL |
KeybindingMode.OVERVIEW,
sessionMode.hasOverview ? Lang.bind(overview, overview.toggle) : null);
wm.allowKeybinding('overlay-key', KeybindingMode.NORMAL |
KeybindingMode.OVERVIEW);
wm.setCustomKeybindingHandler('panel-run-dialog',
KeybindingMode.NORMAL |
KeybindingMode.OVERVIEW,
sessionMode.hasRunDialog ? openRunDialog : null);
Meta.keybindings_set_custom_handler('panel-run-dialog', sessionMode.hasRunDialog ? openRunDialog : null);
if (sessionMode.isGreeter)
screenShield.showDialog();
}
@ -109,8 +85,6 @@ function start() {
Gio.DesktopAppInfo.set_desktop_env('GNOME');
sessionMode = new SessionMode.SessionMode();
Meta.prefs_override_preference_schema(sessionMode.buttonLayout[0], sessionMode.buttonLayout[1]);
shellDBusService = new ShellDBus.GnomeShell();
shellMountOpDBusService = new ShellMountOperation.GnomeShellMountOpHandler();
@ -181,7 +155,9 @@ function start() {
global.screen.override_workspace_layout(Meta.ScreenCorner.TOPLEFT,
false, -1, 1);
Meta.keybindings_set_custom_handler('panel-main-menu', Lang.bind(overview, overview.toggle));
global.display.connect('overlay-key', Lang.bind(overview, overview.toggle));
sessionMode.connect('update', _sessionUpdated);
_sessionUpdated();
@ -191,6 +167,8 @@ function start() {
_startDate = new Date();
global.stage.connect('captured-event', _globalKeyPressHandler);
log('GNOME Shell started at ' + _startDate);
let perfModuleName = GLib.getenv("SHELL_PERF_MODULE");
@ -487,6 +465,80 @@ function getWindowActorsForWorkspace(workspaceIndex) {
});
}
// This function encapsulates hacks to make certain global keybindings
// work even when we are in one of our modes where global keybindings
// are disabled with a global grab. (When there is a global grab, then
// all key events will be delivered to the stage, so ::captured-event
// on the stage can be used for global keybindings.)
function _globalKeyPressHandler(actor, event) {
if (modalCount == 0)
return false;
if (event.type() != Clutter.EventType.KEY_PRESS)
return false;
if (!sessionMode.allowKeybindingsWhenModal) {
if (modalCount > (overview.visible ? 1 : 0))
return false;
}
let symbol = event.get_key_symbol();
let keyCode = event.get_key_code();
let ignoredModifiers = global.display.get_ignored_modifier_mask();
let modifierState = event.get_state() & ~ignoredModifiers;
// This relies on the fact that Clutter.ModifierType is the same as Gdk.ModifierType
let action = global.display.get_keybinding_action(keyCode, modifierState);
if (action == Meta.KeyBindingAction.SWITCH_PANELS) {
ctrlAltTabManager.popup(modifierState & Clutter.ModifierType.SHIFT_MASK,
modifierState);
return true;
}
switch (action) {
// left/right would effectively act as synonyms for up/down if we enabled them;
// but that could be considered confusing; we also disable them in the main view.
//
// case Meta.KeyBindingAction.WORKSPACE_LEFT:
// if (!sessionMode.hasWorkspaces)
// return false;
//
// wm.actionMoveWorkspaceLeft();
// return true;
// case Meta.KeyBindingAction.WORKSPACE_RIGHT:
// if (!sessionMode.hasWorkspaces)
// return false;
//
// wm.actionMoveWorkspaceRight();
// return true;
case Meta.KeyBindingAction.WORKSPACE_UP:
if (!sessionMode.hasWorkspaces)
return false;
wm.actionMoveWorkspace(Meta.MotionDirection.UP);
return true;
case Meta.KeyBindingAction.WORKSPACE_DOWN:
if (!sessionMode.hasWorkspaces)
return false;
wm.actionMoveWorkspace(Meta.MotionDirection.DOWN);
return true;
case Meta.KeyBindingAction.PANEL_RUN_DIALOG:
case Meta.KeyBindingAction.COMMAND_2:
if (!sessionMode.hasRunDialog)
return false;
openRunDialog();
return true;
case Meta.KeyBindingAction.PANEL_MAIN_MENU:
case Meta.KeyBindingAction.OVERLAY_KEY:
overview.hide();
return true;
}
return false;
}
function _findModal(actor) {
for (let i = 0; i < modalActorFocusStack.length; i++) {
if (modalActorFocusStack[i].actor == actor)
@ -502,7 +554,7 @@ function isInModalStack(actor) {
/**
* pushModal:
* @actor: #ClutterActor which will be given keyboard focus
* @params: optional parameters
* @timestamp: optional timestamp
*
* Ensure we are in a mode where all keyboard and mouse input goes to
* the stage, and focus @actor. Multiple calls to this function act in
@ -513,27 +565,21 @@ function isInModalStack(actor) {
* modal stack returns to this actor, reset the focus to the actor
* which was focused at the time pushModal() was invoked.
*
* @params may be used to provide the following parameters:
* - timestamp: used to associate the call with a specific user initiated
* event. If not provided then the value of
* global.get_current_time() is assumed.
* @timestamp is optionally used to associate the call with a specific user
* initiated event. If not provided then the value of
* global.get_current_time() is assumed.
*
* - options: Meta.ModalOptions flags to indicate that the pointer is
* already grabbed
*
* - keybindingMode: used to set the current Main.KeybindingMode to filter
* global keybindings; the default of NONE will filter
* out all keybindings
* @options: optional Meta.ModalOptions flags to indicate that the
* pointer is alrady grabbed
*
* Returns: true iff we successfully acquired a grab or already had one
*/
function pushModal(actor, params) {
params = Params.parse(params, { timestamp: global.get_current_time(),
options: 0,
keybindingMode: KeybindingMode.NONE });
function pushModal(actor, timestamp, options) {
if (timestamp == undefined)
timestamp = global.get_current_time();
if (modalCount == 0) {
if (!global.begin_modal(params.timestamp, params.options)) {
if (!global.begin_modal(timestamp, options ? options : 0)) {
log('pushModal: invocation of begin_modal failed');
return false;
}
@ -560,10 +606,8 @@ function pushModal(actor, params) {
modalActorFocusStack.push({ actor: actor,
focus: curFocus,
destroyId: actorDestroyId,
focusDestroyId: curFocusDestroyId,
keybindingMode: keybindingMode });
focusDestroyId: curFocusDestroyId });
keybindingMode = params.keybindingMode;
global.stage.set_key_focus(actor);
return true;
}
@ -590,7 +634,6 @@ function popModal(actor, timestamp) {
global.stage.set_key_focus(null);
global.end_modal(timestamp);
global.set_stage_input_mode(Shell.StageInputMode.NORMAL);
keybindingMode = KeybindingMode.NORMAL;
throw new Error('incorrect pop');
}
@ -603,7 +646,6 @@ function popModal(actor, timestamp) {
if (focusIndex == modalActorFocusStack.length - 1) {
if (record.focus)
record.focus.disconnect(record.focusDestroyId);
keybindingMode = record.keybindingMode;
global.stage.set_key_focus(record.focus);
} else {
let t = modalActorFocusStack[modalActorFocusStack.length - 1];
@ -613,7 +655,6 @@ function popModal(actor, timestamp) {
for (let i = modalActorFocusStack.length - 1; i > focusIndex; i--) {
modalActorFocusStack[i].focus = modalActorFocusStack[i - 1].focus;
modalActorFocusStack[i].focusDestroyId = modalActorFocusStack[i - 1].focusDestroyId;
modalActorFocusStack[i].keybindingMode = modalActorFocusStack[i - 1].keybindingMode;
}
}
modalActorFocusStack.splice(focusIndex, 1);
@ -624,7 +665,6 @@ function popModal(actor, timestamp) {
global.end_modal(timestamp);
global.set_stage_input_mode(Shell.StageInputMode.NORMAL);
Meta.enable_unredirect_for_screen(global.screen);
keybindingMode = KeybindingMode.NORMAL;
}
function createLookingGlass() {

View File

@ -314,7 +314,6 @@ const Notification = new Lang.Class({
this.resident = false;
// 'transient' is a reserved keyword in JS, so we have to use an alternate variable name
this.isTransient = false;
this.forFeedback = false;
this.expanded = false;
this.focused = false;
this.acknowledged = false;
@ -714,10 +713,6 @@ const Notification = new Lang.Class({
this.isTransient = isTransient;
},
setForFeedback: function(forFeedback) {
this.forFeedback = forFeedback;
},
setUseActionIcons: function(useIcons) {
this._useActionIcons = useIcons;
},
@ -1394,8 +1389,6 @@ const MessageTray = new Lang.Class({
y_expand: true,
x_expand: true,
layout_manager: new Clutter.BinLayout() });
this._notificationWidget.connect('key-release-event', Lang.bind(this, this._onNotificationKeyRelease));
this.actor.add_actor(this._notificationWidget);
this._notificationBin = new St.Bin({ y_expand: true });
@ -1445,7 +1438,7 @@ const MessageTray = new Lang.Class({
this._closeButton = makeCloseButton();
this._closeButton.hide();
this._closeButton.connect('clicked', Lang.bind(this, this._closeNotification));
this._closeButton.connect('clicked', Lang.bind(this, this._onCloseClicked));
this._notificationWidget.add_actor(this._closeButton);
this._idleMonitorBecameActiveId = 0;
@ -1453,8 +1446,7 @@ const MessageTray = new Lang.Class({
this.idleMonitor = new GnomeDesktop.IdleMonitor();
this._grabHelper = new GrabHelper.GrabHelper(this.actor,
{ keybindingMode: Main.KeybindingMode.MESSAGE_TRAY });
this._grabHelper = new GrabHelper.GrabHelper(this.actor);
this._grabHelper.addActor(this._summaryBoxPointer.actor);
this._grabHelper.addActor(this.actor);
if (Main.panel.statusArea.activities)
@ -1471,7 +1463,6 @@ const MessageTray = new Lang.Class({
this._pointerInTray = false;
this._pointerInKeyboard = false;
this._keyboardVisible = false;
this._keyboardUnderMessageTray = false;
this._summaryState = State.HIDDEN;
this._pointerInSummary = false;
this._notificationClosed = false;
@ -1507,7 +1498,7 @@ const MessageTray = new Lang.Class({
this._overviewVisible = true;
this._grabHelper.ungrab(); // drop modal grab if necessary
this.actor.add_style_pseudo_class('overview');
this._updateState();
this.show();
}));
Main.overview.connect('hiding', Lang.bind(this,
function() {
@ -1519,20 +1510,10 @@ const MessageTray = new Lang.Class({
Main.sessionMode.connect('updated', Lang.bind(this, this._sessionUpdated));
Main.wm.addKeybinding('toggle-message-tray',
new Gio.Settings({ schema: SHELL_KEYBINDINGS_SCHEMA }),
Meta.KeyBindingFlags.NONE,
Main.KeybindingMode.NORMAL |
Main.KeybindingMode.MESSAGE_TRAY |
Main.KeybindingMode.OVERVIEW,
Lang.bind(this, this.toggleAndNavigate));
Main.wm.addKeybinding('focus-active-notification',
new Gio.Settings({ schema: SHELL_KEYBINDINGS_SCHEMA }),
Meta.KeyBindingFlags.NONE,
Main.KeybindingMode.NORMAL |
Main.KeybindingMode.MESSAGE_TRAY |
Main.KeybindingMode.OVERVIEW,
Lang.bind(this, this._expandActiveNotification));
global.display.add_keybinding('toggle-message-tray',
new Gio.Settings({ schema: SHELL_KEYBINDINGS_SCHEMA }),
Meta.KeyBindingFlags.NONE,
Lang.bind(this, this.toggleAndNavigate));
this._summaryItems = [];
this._chatSummaryItemsCount = 0;
@ -1544,29 +1525,13 @@ const MessageTray = new Lang.Class({
this._trayDwellUserTime = 0;
this._sessionUpdated();
this._updateNoMessagesLabel();
},
_updateNoMessagesLabel: function() {
if (this._summaryItems.length == 0 && !this._noMessages) {
this._noMessages = new St.Label({ text: _("No Messages"),
style_class: 'no-messages-label',
x_align: Clutter.ActorAlign.CENTER,
x_expand: true,
y_align: Clutter.ActorAlign.CENTER,
y_expand: true });
this.actor.add_actor(this._noMessages);
} else if (this._summaryItems.length > 0 && this._noMessages) {
this._noMessages.destroy();
this._noMessages = null;
}
},
_sessionUpdated: function() {
if (Main.sessionMode.isLocked || Main.sessionMode.isGreeter)
Main.ctrlAltTabManager.removeGroup(this._summary);
else
Main.ctrlAltTabManager.addGroup(this._summary, _("Message Tray"), 'user-available-symbolic',
Main.ctrlAltTabManager.addGroup(this._summary, _("Message Tray"), 'start-here-symbolic',
{ focusCallback: Lang.bind(this, this.toggleAndNavigate),
sortGroup: CtrlAltTab.SortGroup.BOTTOM });
this._updateState();
@ -1606,8 +1571,6 @@ const MessageTray = new Lang.Class({
},
_trayDwellTimeout: function() {
this._trayDwellTimeoutId = 0;
if (Main.modalCount > 0)
return false;
@ -1618,25 +1581,15 @@ const MessageTray = new Lang.Class({
if (currentUserTime != this._trayDwellUserTime)
return false;
this._trayDwellTimeoutId = 0;
this._traySummoned = true;
this._updateState();
return false;
},
_onNotificationKeyRelease: function(actor, event) {
let ignoredModifiers = global.display.get_ignored_modifier_mask();
let modifierState = event.get_state() & ~ignoredModifiers;
if (event.get_key_symbol() == Clutter.KEY_Escape && modifierState == 0) {
this._closeNotification();
return true;
}
return false;
},
_closeNotification: function() {
_onCloseClicked: function() {
if (this._notificationState == State.SHOWN) {
this._closeButton.hide();
this._notificationClosed = true;
@ -1704,8 +1657,6 @@ const MessageTray = new Lang.Class({
Meta.later_add(Meta.LaterType.BEFORE_REDRAW, Lang.bind(this, function() { this._updateState(); return false; }));
this.emit('summary-item-added', summaryItem);
this._updateNoMessagesLabel();
},
getSummaryItems: function() {
@ -1738,8 +1689,6 @@ const MessageTray = new Lang.Class({
summaryItemToRemove.actor.destroy();
this._updateNoMessagesLabel();
if (needUpdate)
this._updateState();
},
@ -1787,6 +1736,11 @@ const MessageTray = new Lang.Class({
this._updateState();
},
show: function() {
this._traySummoned = true;
this._updateState();
},
_onNotify: function(source, notification) {
if (this._summaryBoxPointerItem && this._summaryBoxPointerItem.source == source) {
if (this._summaryBoxPointerState == State.HIDING) {
@ -1925,15 +1879,12 @@ const MessageTray = new Lang.Class({
},
_onKeyboardVisibleChanged: function(layoutManager, keyboardVisible) {
let keyboardUnderMessageTray = layoutManager.keyboardIndex == layoutManager.bottomIndex;
if (this._keyboardVisible == keyboardVisible &&
this._keyboardUnderMesssageTray == keyboardUnderMessageTray)
if (this._keyboardVisible == keyboardVisible)
return;
this._keyboardVisible = keyboardVisible;
this._keyboardUnderMessageTray = keyboardUnderMessageTray;
if (keyboardVisible && keyboardUnderMessageTray)
if (keyboardVisible)
this.actor.add_style_pseudo_class('keyboard');
else
this.actor.remove_style_pseudo_class('keyboard');
@ -2003,9 +1954,8 @@ const MessageTray = new Lang.Class({
// Notifications
let notificationQueue = this._notificationQueue;
let notificationUrgent = notificationQueue.length > 0 && notificationQueue[0].urgency == Urgency.CRITICAL;
let notificationForFeedback = notificationQueue.length > 0 && notificationQueue[0].forFeedback;
let notificationsLimited = this._busy || this._inFullscreen;
let notificationsPending = notificationQueue.length > 0 && (!notificationsLimited || notificationUrgent || notificationForFeedback) && Main.sessionMode.hasNotifications;
let notificationsPending = notificationQueue.length > 0 && (!notificationsLimited || notificationUrgent) && Main.sessionMode.hasNotifications;
let nextNotification = notificationQueue.length > 0 ? notificationQueue[0] : null;
let notificationPinned = this._pointerInTray && !this._pointerInSummary && !this._notificationRemoved;
let notificationExpanded = this._notification && this._notification.expanded;
@ -2033,14 +1983,15 @@ const MessageTray = new Lang.Class({
}
// Summary
let summarySummoned = this._pointerInSummary || this._overviewVisible || this._traySummoned;
let summarySummoned = this._pointerInSummary || this._traySummoned;
let summaryPinned = this._pointerInTray || summarySummoned || this._locked;
let summaryHovered = this._pointerInTray || this._pointerInSummary;
let notificationsVisible = this._notificationState != State.HIDDEN;
let notificationsVisible = (this._notificationState == State.SHOWING ||
this._notificationState == State.SHOWN);
let notificationsDone = !notificationsVisible && !notificationsPending;
let summaryOptionalInOverview = this._overviewVisible && !this._locked && !summaryHovered;
let summaryOptionalInOverview = !this._locked && !summaryHovered;
let mustHideSummary = (notificationsPending && (notificationUrgent || summaryOptionalInOverview))
|| notificationsVisible || !Main.sessionMode.hasNotifications;
@ -2090,12 +2041,12 @@ const MessageTray = new Lang.Class({
this._desktopCloneState == State.SHOWN);
let desktopCloneShouldBeVisible = (trayShouldBeVisible &&
!this._overviewVisible &&
(!this._keyboardVisible || !this._keyboardUnderMessageTray));
!this._keyboardVisible);
if (!desktopCloneIsVisible && desktopCloneShouldBeVisible) {
this._showDesktopClone();
} else if (desktopCloneIsVisible && !desktopCloneShouldBeVisible) {
this._hideDesktopClone (this._keyboardVisible && this._keyboardUnderMessageTray);
this._hideDesktopClone (this._keyboardVisible);
}
},
@ -2108,8 +2059,6 @@ const MessageTray = new Lang.Class({
params.onCompleteScope = this;
params.onCompleteParams = [statevar, value, onComplete, onCompleteScope, onCompleteParams];
// Remove other tweens that could mess with the state machine
Tweener.removeTweens(actor);
Tweener.addTween(actor, params);
let valuing = (value == State.SHOWN) ? State.SHOWING : State.HIDING;
@ -2342,18 +2291,6 @@ const MessageTray = new Lang.Class({
},
_hideNotification: function() {
// HACK!
// There seems to be a reentrancy issue in calling .ungrab() here,
// which causes _updateState to be called before _notificationState
// becomes HIDING. That hides the notification again, nullifying the
// object but not setting _notificationState (and that's the weird part)
// As then _notificationState is stuck into SHOWN but _notification
// is null, every new _updateState fails and the message tray is
// lost forever.
//
// See more at https://bugzilla.gnome.org/show_bug.cgi?id=683986
this._notificationState = State.HIDING;
this._grabHelper.ungrab({ actor: this._notification.actor });
if (this._idleMonitorBecameActiveId) {
@ -2367,7 +2304,6 @@ const MessageTray = new Lang.Class({
}
if (this._notificationRemoved) {
Tweener.removeTweens(this._notificationWidget);
this._notificationWidget.y = this.actor.height;
this._notificationWidget.opacity = 0;
this._notificationState = State.HIDDEN;
@ -2401,13 +2337,6 @@ const MessageTray = new Lang.Class({
notification.destroy(NotificationDestroyedReason.EXPIRED);
},
_expandActiveNotification: function() {
if (!this._notification)
return;
this._expandNotification(false);
},
_expandNotification: function(autoExpanding) {
// Don't grab focus in notifications that are auto-expanded.
if (!autoExpanding)
@ -2431,11 +2360,8 @@ const MessageTray = new Lang.Class({
if (this._notificationWidget.y < expandedY) {
this._notificationWidget.y = expandedY;
} else if (this._notification.y != expandedY) {
// Tween also opacity here, to override a possible tween that's
// currently hiding the notification.
this._tween(this._notificationWidget, '_notificationState', State.SHOWN,
{ y: expandedY,
opacity: 255,
time: ANIMATION_TIME,
transition: 'easeOutQuad'
});
@ -2494,7 +2420,6 @@ const MessageTray = new Lang.Class({
this._summaryBoxPointerItem.prepareNotificationStackForShowing();
} else if (this._clickedSummaryItemMouseButton == 3) {
this._summaryBoxPointer.bin.child = this._clickedSummaryItem.rightClickMenu;
this._summaryBoxPointerCloseClickedId = 0;
}
this._grabHelper.grab({ actor: this._summaryBoxPointer.bin.child,
@ -2601,10 +2526,8 @@ const MessageTray = new Lang.Class({
this._summaryBoxPointer.bin.child = null;
this._summaryBoxPointerItem.disconnect(this._summaryBoxPointerContentUpdatedId);
this._summaryBoxPointerContentUpdatedId = 0;
if (this._summaryBoxPointerCloseClickedId != 0) {
this._summaryBoxPointerItem.closeButton.disconnect(this._summaryBoxPointerCloseClickedId);
this._summaryBoxPointerCloseClickedId = 0;
}
this._summaryBoxPointerItem.closeButton.disconnect(this._summaryBoxPointerCloseClickedId);
this._summaryBoxPointerCloseClickedId = 0;
this._summaryBoxPointerItem.source.disconnect(this._sourceDoneDisplayingId);
this._summaryBoxPointerDoneDisplayingId = 0;

View File

@ -37,12 +37,10 @@ const ModalDialog = new Lang.Class({
params = Params.parse(params, { shellReactive: false,
styleClass: null,
parentActor: Main.uiGroup,
keybindingMode: Main.KeybindingMode.SYSTEM_MODAL,
shouldFadeIn: true });
this.state = State.CLOSED;
this._hasModal = false;
this._keybindingMode = params.keybindingMode;
this._shellReactive = params.shellReactive;
this._shouldFadeIn = params.shouldFadeIn;
@ -58,7 +56,7 @@ const ModalDialog = new Lang.Class({
this._group.connect('destroy', Lang.bind(this, this._onGroupDestroy));
this._buttonKeys = {};
this._actionKeys = {};
this._group.connect('key-release-event', Lang.bind(this, this._onKeyReleaseEvent));
this._backgroundBin = new St.Bin();
@ -95,10 +93,10 @@ const ModalDialog = new Lang.Class({
x_align: St.Align.MIDDLE,
y_align: St.Align.START });
this.buttonLayout = new St.BoxLayout({ style_class: 'modal-dialog-button-box',
this._buttonLayout = new St.BoxLayout({ style_class: 'modal-dialog-button-box',
visible: false,
vertical: false });
this.dialogLayout.add(this.buttonLayout,
this.dialogLayout.add(this._buttonLayout,
{ expand: true,
x_align: St.Align.MIDDLE,
y_align: St.Align.END });
@ -113,17 +111,35 @@ const ModalDialog = new Lang.Class({
this._group.destroy();
},
clearButtons: function() {
this.buttonLayout.destroy_all_children();
this._buttonKeys = {};
setActionKey: function(key, action) {
this._actionKeys[key] = action;
},
setButtons: function(buttons) {
this.clearButtons();
this.buttonLayout.visible = (buttons.length > 0);
this._buttonLayout.destroy_all_children();
this._actionKeys = {};
this._buttonLayout.visible = (buttons.length > 0);
for (let i = 0; i < buttons.length; i++) {
let buttonInfo = buttons[i];
let label = buttonInfo['label'];
let action = buttonInfo['action'];
let key = buttonInfo['key'];
let isDefault = buttonInfo['default'];
if (isDefault && !key) {
this._actionKeys[Clutter.KEY_KP_Enter] = action;
this._actionKeys[Clutter.KEY_ISO_Enter] = action;
key = Clutter.KEY_Return;
}
buttonInfo.button = new St.Button({ style_class: 'modal-dialog-button',
reactive: true,
can_focus: true,
label: label });
if (isDefault)
buttonInfo.button.add_style_pseudo_class('default');
let x_alignment;
if (buttons.length == 1)
@ -135,62 +151,29 @@ const ModalDialog = new Lang.Class({
else
x_alignment = St.Align.MIDDLE;
this.addButton(buttonInfo, { expand: true,
x_fill: false,
y_fill: false,
x_align: x_alignment,
y_align: St.Align.MIDDLE });
if (!this._initialKeyFocusDestroyId)
this._initialKeyFocus = buttonInfo.button;
this._buttonLayout.add(buttonInfo.button,
{ expand: true,
x_fill: false,
y_fill: false,
x_align: x_alignment,
y_align: St.Align.MIDDLE });
buttonInfo.button.connect('clicked', action);
if (key)
this._actionKeys[key] = action;
}
},
addButton: function(buttonInfo, layoutInfo) {
let label = buttonInfo['label'];
let action = buttonInfo['action'];
let key = buttonInfo['key'];
let isDefault = buttonInfo['default'];
let keys;
if (key)
keys = [key];
else if (isDefault)
keys = [Clutter.KEY_Return, Clutter.KEY_KP_Enter, Clutter.KEY_ISO_Enter];
else
keys = [];
let button = new St.Button({ style_class: 'modal-dialog-button',
reactive: true,
can_focus: true,
label: label });
button.connect('clicked', action);
buttonInfo['button'] = button;
if (isDefault)
button.add_style_pseudo_class('default');
if (!this._initialKeyFocusDestroyId)
this._initialKeyFocus = button;
for (let i in keys)
this._buttonKeys[keys[i]] = buttonInfo;
this.buttonLayout.add(button, layoutInfo);
return button;
this.emit('buttons-set');
},
_onKeyReleaseEvent: function(object, event) {
let symbol = event.get_key_symbol();
let buttonInfo = this._buttonKeys[symbol];
let action = this._actionKeys[symbol];
if (!buttonInfo)
return false;
let button = buttonInfo['button'];
let action = buttonInfo['action'];
if (action && button.reactive) {
if (action) {
action();
return true;
}
@ -243,7 +226,7 @@ const ModalDialog = new Lang.Class({
if (this.state == State.OPENED || this.state == State.OPENING)
return true;
if (!this.pushModal({ timestamp: timestamp }))
if (!this.pushModal(timestamp))
return false;
this._fadeOpen(onPrimary);
@ -293,8 +276,7 @@ const ModalDialog = new Lang.Class({
pushModal: function (timestamp) {
if (this._hasModal)
return true;
if (!Main.pushModal(this._group, { timestamp: timestamp,
keybindingMode: this._keybindingMode }))
if (!Main.pushModal(this._group, timestamp))
return false;
this._hasModal = true;

View File

@ -10,6 +10,7 @@ const St = imports.gi.St;
const Shell = imports.gi.Shell;
const Gdk = imports.gi.Gdk;
const CenterLayout = imports.ui.centerLayout;
const Dash = imports.ui.dash;
const DND = imports.ui.dnd;
const Main = imports.ui.main;
@ -23,29 +24,8 @@ const WorkspaceThumbnail = imports.ui.workspaceThumbnail;
// Time for initial animation going into Overview mode
const ANIMATION_TIME = 0.25;
// XXX -- grab this automatically. Hard to do.
const DASH_MAX_WIDTH = 96;
const DND_WINDOW_SWITCH_TIMEOUT = 1250;
const GLSL_DIM_EFFECT_DECLARATIONS = '';
const GLSL_DIM_EFFECT_CODE = '\
vec2 dist = cogl_tex_coord_in[0].xy - vec2(0.5, 0.5); \
float elipse_radius = 0.5; \
/* from https://bugzilla.gnome.org/show_bug.cgi?id=669798: \
the alpha on the gradient goes from 165 at its darkest to 98 at its most transparent. */ \
float y = 165.0 / 255.0; \
float x = 98.0 / 255.0; \
/* interpolate darkening value, based on distance from screen center */ \
float val = min(length(dist), elipse_radius); \
float a = mix(x, y, val / elipse_radius); \
/* dim_factor varies from [1.0 -> 0.5] when overview is showing \
We use it to smooth value, then we clamp it to valid color interval */ \
a = clamp(a - cogl_color_in.r + 0.5, 0.0, 1.0); \
/* We\'re blending between: color and black color (obviously omitted in the equation) */ \
cogl_color_out.xyz = cogl_color_out.xyz * (1.0 - a); \
cogl_color_out.a = 1.0;';
const SwipeScrollDirection = {
NONE: 0,
HORIZONTAL: 1,
@ -75,14 +55,7 @@ const ShellInfo = new Lang.Class({
this._source.destroy();
},
setMessage: function(text, options) {
options = Params.parse(options, { undoCallback: null,
forFeedback: false
});
let undoCallback = options.undoCallback;
let forFeedback = options.forFeedback;
setMessage: function(text, undoCallback, undoLabel) {
if (this._source == null) {
this._source = new MessageTray.SystemNotificationSource();
this._source.connect('destroy', Lang.bind(this,
@ -96,7 +69,6 @@ const ShellInfo = new Lang.Class({
if (this._source.notifications.length == 0) {
notification = new MessageTray.Notification(this._source, text, null);
notification.setTransient(true);
notification.setForFeedback(forFeedback);
} else {
notification = this._source.notifications[0];
notification.update(text, null, { clear: true });
@ -104,8 +76,10 @@ const ShellInfo = new Lang.Class({
this._undoCallback = undoCallback;
if (undoCallback) {
notification.addButton('system-undo', _("Undo"));
notification.connect('action-invoked', Lang.bind(this, this._onUndoClicked));
notification.addButton('system-undo',
undoLabel ? undoLabel : _("Undo"));
notification.connect('action-invoked',
Lang.bind(this, this._onUndoClicked));
}
this._source.notify(notification);
@ -137,33 +111,24 @@ const Overview = new Lang.Class({
// scenes which allows us to show the background with different
// rendering options without duplicating the texture data.
this._background = Meta.BackgroundActor.new_for_screen(global.screen);
this._background.add_glsl_snippet(Meta.SnippetHook.FRAGMENT,
GLSL_DIM_EFFECT_DECLARATIONS,
GLSL_DIM_EFFECT_CODE,
false);
this._background.hide();
global.overlay_group.add_actor(this._background);
this._desktopFade = new St.Bin();
global.overlay_group.add_actor(this._desktopFade);
this._spacing = 0;
/* Translators: This is the main view to select
activities. See also note for "Activities" string. */
this._group = new St.Widget({ name: 'overview',
accessible_name: _("Overview"),
reactive: true });
this._group._delegate = this;
this._group.connect('style-changed',
Lang.bind(this, function() {
let node = this._group.get_theme_node();
let spacing = node.get_length('spacing');
if (spacing != this._spacing) {
this._spacing = spacing;
this._relayout();
}
}));
this._overview = new St.BoxLayout({ name: 'overview',
accessible_name: _("Overview"),
reactive: true,
vertical: true });
this._overview._delegate = this;
let layout = new CenterLayout.CenterLayout();
CenterLayout.connectSpacing(layout);
this._group = new St.Widget({ name: 'overview-group',
layout_manager: layout });
this._scrollDirection = SwipeScrollDirection.NONE;
this._scrollAdjustment = null;
@ -176,18 +141,19 @@ const Overview = new Lang.Class({
this._modal = false; // have a modal grab
this.animationInProgress = false;
this._hideInProgress = false;
this.searchActive = false;
this.appsActive = false;
// During transitions, we raise this to the top to avoid having the overview
// area be reactive; it causes too many issues such as double clicks on
// Dash elements, or mouseover handlers in the workspaces.
this._coverPane = new Clutter.Rectangle({ opacity: 0,
reactive: true });
this._group.add_actor(this._coverPane);
this._overview.add_actor(this._coverPane);
this._coverPane.connect('event', Lang.bind(this, function (actor, event) { return true; }));
this._group.hide();
global.overlay_group.add_actor(this._group);
this._overview.hide();
global.overlay_group.add_actor(this._overview);
this._coverPane.hide();
@ -199,6 +165,8 @@ const Overview = new Lang.Class({
Main.xdndHandler.connect('drag-begin', Lang.bind(this, this._onDragBegin));
Main.xdndHandler.connect('drag-end', Lang.bind(this, this._onDragEnd));
global.screen.connect('restacked', Lang.bind(this, this._onRestacked));
this._windowSwitchTimeoutId = 0;
this._windowSwitchTimestamp = 0;
this._lastActiveWorkspaceIndex = -1;
@ -221,6 +189,13 @@ const Overview = new Lang.Class({
this._shellInfo = new ShellInfo();
// Add a clone of the panel to the overview so spacing and such is
// automatic
this._panelGhost = new St.Bin({ child: new Clutter.Clone({ source: Main.panel.actor }),
reactive: false,
opacity: 0 });
this._overview.add_actor(this._panelGhost);
this._searchEntry = new St.Entry({ name: 'searchEntry',
/* Translators: this is the text displayed
in the search entry when no search is
@ -229,16 +204,13 @@ const Overview = new Lang.Class({
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._group.add_actor(this._viewSelector.actor);
this._group.add_actor(this._dash.actor);
this._searchEntryBin = new St.Bin({ child: this._searchEntry,
x_align: St.Align.MIDDLE });
this._overview.add_actor(this._searchEntryBin);
// TODO - recalculate everything when desktop size changes
this._dash.actor.add_constraint(this._viewSelector.constrainHeight);
this._dash = new Dash.Dash();
this._group.add_actor(this._dash.actor);
this.dashIconSize = this._dash.iconSize;
this._dash.connect('icon-size-changed',
Lang.bind(this, function() {
@ -249,6 +221,82 @@ const Overview = new Lang.Class({
// the left of the overview
Main.ctrlAltTabManager.addGroup(this._dash.actor, _("Dash"), 'user-bookmarks-symbolic');
this._viewSelector = new ViewSelector.ViewSelector(this._searchEntry,
this._dash.showAppsButton);
this._group.add_actor(this._viewSelector.actor);
this._thumbnailsBox = new WorkspaceThumbnail.ThumbnailsBox();
this._group.add_actor(this._thumbnailsBox.actor);
// TODO: unique icon
Main.ctrlAltTabManager.addGroup(this._thumbnailsBox.actor, _("Workspaces"), 'user-bookmarks-symbolic');
// Add our same-line elements after the search entry
this._overview.add_actor(this._group);
// Then account for message tray
this._messageTrayGhost = new St.Bin({ child: new Clutter.Clone({ source: Main.messageTray.actor }),
reactive: false,
opacity: 0 });
this._overview.add_actor(this._messageTrayGhost);
this._viewSelector.connect('search-begin', Lang.bind(this,
function() {
this.searchActive = true;
this._dash.hide();
this._thumbnailsBox.hide();
Main.messageTray.hide();
}));
this._viewSelector.connect('search-cancelled', Lang.bind(this,
function() {
this.searchActive = false;
this._dash.show();
this._thumbnailsBox.show();
// search-cancelled is emitted if we leave the overview
// directly from searching. That means the message tray will
// be shown when we reach the workspace. Don't do this, only
// show the message tray on search-cancelled if we are still
// in the overview/not transitioning out of it.
if (this.visible && !this.animationInProgress)
Main.messageTray.show();
}));
this._viewSelector.connect('apps-button-checked', Lang.bind(this,
function(vs, checked) {
this.appsActive = checked;
if (checked) {
this._thumbnailsBox.hide();
Main.messageTray.hide();
} else {
this._thumbnailsBox.show();
if (this.visible && !this.animationInProgress)
Main.messageTray.show();
}
}));
this.connect('app-drag-begin',
Lang.bind(this, function () {
this._dash.show();
this._thumbnailsBox.show();
}));
this.connect('app-drag-cancelled',
Lang.bind(this, function () {
if (this.searchActive) {
this._dash.hide();
this._thumbnailsBox.hide();
} else if (this.appsActive) {
this._thumbnailsBox.hide();
}
}));
this.connect('app-drag-end',
Lang.bind(this, function () {
if (this.searchActive) {
this._dash.hide();
this._thumbnailsBox.hide();
} else if (this.appsActive) {
this._thumbnailsBox.hide();
}
}));
Main.layoutManager.connect('monitors-changed', Lang.bind(this, this._relayout));
this._relayout();
},
@ -261,16 +309,11 @@ const Overview = new Lang.Class({
this._viewSelector.removeSearchProvider(provider);
},
//
// options:
// - undoCallback (function): the callback to be called if undo support is needed
// - forFeedback (boolean): whether the message is for direct feedback of a user action
//
setMessage: function(text, options) {
setMessage: function(text, undoCallback, undoLabel) {
if (this.isDummy)
return;
this._shellInfo.setMessage(text, options);
this._shellInfo.setMessage(text, undoCallback, undoLabel);
},
_onDragBegin: function() {
@ -519,55 +562,41 @@ const Overview = new Lang.Class({
this.hide();
let primary = Main.layoutManager.primaryMonitor;
let rtl = (Clutter.get_default_text_direction() == Clutter.TextDirection.RTL);
let contentY = Main.panel.actor.height;
let contentHeight = primary.height - contentY - Main.messageTray.actor.height;
this._group.set_position(primary.x, primary.y);
this._group.set_size(primary.width, primary.height);
this._overview.set_position(primary.x, primary.y);
this._overview.set_size(primary.width, primary.height);
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;
_onRestacked: function() {
let stack = global.get_window_actors();
let stackIndices = {};
let dashWidth = DASH_MAX_WIDTH;
let dashY = searchY + searchHeight + this._spacing;
let dashX;
if (rtl) {
this._dash.actor.set_anchor_point_from_gravity(Clutter.Gravity.NORTH_EAST);
dashX = primary.width;
} else {
dashX = 0;
for (let i = 0; i < stack.length; i++) {
// Use the stable sequence for an integer to use as a hash key
stackIndices[stack[i].get_meta_window().get_stable_sequence()] = i;
}
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);
this.emit('sync-window-stacking', stackIndices);
},
//// Public methods ////
beginItemDrag: function(source) {
this.emit('item-drag-begin');
beginAppDrag: function(source) {
this.emit('app-drag-begin');
},
cancelledItemDrag: function(source) {
this.emit('item-drag-cancelled');
cancelledAppDrag: function(source) {
this.emit('app-drag-cancelled');
},
endItemDrag: function(source) {
this.emit('item-drag-end');
endAppDrag: function(source) {
this.emit('app-drag-end');
},
beginWindowDrag: function(source) {
@ -591,13 +620,13 @@ const Overview = new Lang.Class({
if (this._shown)
return;
// Do this manually instead of using _syncInputMode, to handle failure
if (!Main.pushModal(this._group, { keybindingMode: Main.KeybindingMode.OVERVIEW }))
if (!Main.pushModal(this._overview))
return;
this._modal = true;
this._animateVisible();
this._shown = true;
this._buttonPressId = this._group.connect('button-press-event',
this._buttonPressId = this._overview.connect('button-press-event',
Lang.bind(this, this._onButtonPress));
},
@ -641,12 +670,12 @@ const Overview = new Lang.Class({
// Disable unredirection while in the overview
Meta.disable_unredirect_for_screen(global.screen);
global.window_group.hide();
this._group.show();
this._overview.show();
this._background.show();
this._viewSelector.show();
this._group.opacity = 0;
Tweener.addTween(this._group,
this._overview.opacity = 0;
Tweener.addTween(this._overview,
{ opacity: 255,
transition: 'easeOutQuad',
time: ANIMATION_TIME,
@ -655,7 +684,7 @@ const Overview = new Lang.Class({
});
Tweener.addTween(this._background,
{ dim_factor: 0.8,
{ dim_factor: 0.4,
time: ANIMATION_TIME,
transition: 'easeOutQuad'
});
@ -700,7 +729,7 @@ const Overview = new Lang.Class({
this._syncInputMode();
if (this._buttonPressId > 0)
this._group.disconnect(this._buttonPressId);
this._overview.disconnect(this._buttonPressId);
this._buttonPressId = 0;
},
@ -742,21 +771,20 @@ const Overview = new Lang.Class({
if (this._shown) {
if (!this._modal) {
if (Main.pushModal(this._group,
{ keybindingMode: Main.KeybindingMode.OVERVIEW }))
if (Main.pushModal(this._overview))
this._modal = true;
else
this.hide();
}
} else if (this._shownTemporarily) {
if (this._modal) {
Main.popModal(this._group);
Main.popModal(this._overview);
this._modal = false;
}
global.stage_input_mode = Shell.StageInputMode.FULLSCREEN;
} else {
if (this._modal) {
Main.popModal(this._group);
Main.popModal(this._overview);
this._modal = false;
}
else if (global.stage_input_mode == Shell.StageInputMode.FULLSCREEN)
@ -774,7 +802,7 @@ const Overview = new Lang.Class({
this._viewSelector.zoomFromOverview();
// Make other elements fade out.
Tweener.addTween(this._group,
Tweener.addTween(this._overview,
{ opacity: 0,
transition: 'easeOutQuad',
time: ANIMATION_TIME,
@ -816,7 +844,7 @@ const Overview = new Lang.Class({
this._viewSelector.hide();
this._desktopFade.hide();
this._background.hide();
this._group.hide();
this._overview.hide();
this.visible = false;
this.animationInProgress = false;

View File

@ -15,6 +15,7 @@ const Signals = imports.signals;
const Atk = imports.gi.Atk;
const CenterLayout = imports.ui.centerLayout;
const Config = imports.misc.config;
const CtrlAltTab = imports.ui.ctrlAltTab;
const DND = imports.ui.dnd;
@ -75,41 +76,33 @@ function _unpremultiply(color) {
blue: blue, alpha: color.alpha });
};
const Animation = new Lang.Class({
Name: 'Animation',
_init: function(filename, width, height, speed) {
this.actor = new St.Bin();
const AnimatedIcon = new Lang.Class({
Name: 'AnimatedIcon',
_init: function(name, size) {
this.actor = new St.Bin({ visible: false });
this.actor.connect('destroy', Lang.bind(this, this._onDestroy));
this._speed = speed;
this.actor.connect('notify::visible', Lang.bind(this, this._onVisibleNotify));
this._isLoaded = false;
this._isPlaying = false;
this._timeoutId = 0;
this._frame = 0;
this._animations = St.TextureCache.get_default().load_sliced_image (filename, width, height,
Lang.bind(this, this._animationsLoaded));
this._animations = St.TextureCache.get_default().load_sliced_image (global.datadir + '/theme/' + name, size, size);
this.actor.set_child(this._animations);
},
play: function() {
if (this._isLoaded && this._timeoutId == 0) {
if (this._frame == 0)
this._showFrame(0);
this._timeoutId = Mainloop.timeout_add(this._speed, Lang.bind(this, this._update));
}
this._isPlaying = true;
},
stop: function() {
_disconnectTimeout: function() {
if (this._timeoutId > 0) {
Mainloop.source_remove(this._timeoutId);
this._timeoutId = 0;
}
},
this._isPlaying = false;
_onVisibleNotify: function() {
if (this.actor.visible)
this._timeoutId = Mainloop.timeout_add(ANIMATED_ICON_UPDATE_TIMEOUT, Lang.bind(this, this._update));
else
this._disconnectTimeout();
},
_showFrame: function(frame) {
@ -129,24 +122,8 @@ const Animation = new Lang.Class({
return true;
},
_animationsLoaded: function() {
this._isLoaded = true;
if (this._isPlaying)
this.play();
},
_onDestroy: function() {
this.stop();
}
});
const AnimatedIcon = new Lang.Class({
Name: 'AnimatedIcon',
Extends: Animation,
_init: function(name, size) {
this.parent(global.datadir + '/theme/' + name, size, size, ANIMATED_ICON_UPDATE_TIMEOUT);
this._disconnectTimeout();
}
});
@ -301,7 +278,6 @@ const AppMenuButton = new Lang.Class({
this._spinner = new AnimatedIcon('process-working.svg',
PANEL_ICON_SIZE);
this._container.add_actor(this._spinner.actor);
this._spinner.actor.hide();
this._spinner.actor.lower_bottom();
let tracker = Shell.WindowTracker.get_default();
@ -392,7 +368,6 @@ const AppMenuButton = new Lang.Class({
transition: "easeOutQuad",
onCompleteScope: this,
onComplete: function() {
this._spinner.stop();
this._spinner.actor.opacity = 255;
this._spinner.actor.hide();
}
@ -402,7 +377,6 @@ const AppMenuButton = new Lang.Class({
startAnimation: function() {
this._stop = false;
this.actor.reactive = false;
this._spinner.play();
this._spinner.actor.show();
},
@ -890,13 +864,10 @@ const PanelCorner = new Lang.Class({
let backgroundColor = node.get_color('-panel-corner-background-color');
let borderColor = node.get_color('-panel-corner-border-color');
let noOverlap = borderColor.alpha == 0;
let offsetY = noOverlap ? borderWidth : 0;
let cr = this.actor.get_context();
cr.setOperator(Cairo.Operator.SOURCE);
cr.moveTo(0, offsetY);
cr.moveTo(0, 0);
if (this._side == St.Side.LEFT)
cr.arc(cornerRadius,
borderWidth + cornerRadius,
@ -905,7 +876,7 @@ const PanelCorner = new Lang.Class({
cr.arc(0,
borderWidth + cornerRadius,
cornerRadius, 3 * Math.PI / 2, 2 * Math.PI);
cr.lineTo(cornerRadius, offsetY);
cr.lineTo(cornerRadius, 0);
cr.closePath();
let savedPath = cr.copyPath();
@ -915,9 +886,6 @@ const PanelCorner = new Lang.Class({
Clutter.cairo_set_source_color(cr, over);
cr.fill();
if (noOverlap)
return;
let offset = borderWidth;
Clutter.cairo_set_source_color(cr, backgroundColor);
@ -964,18 +932,58 @@ try {
log('NMApplet is not supported. It is possible that your NetworkManager version is too old');
}
const PanelLayout = new Lang.Class({
Name: 'PanelLayout',
Extends: CenterLayout.CenterLayout,
vfunc_allocate: function(container, box, flags) {
this.parent(container, box, flags);
let availWidth = box.x2 - box.x1;
let availHeight = box.y2 - box.y1;
let [left, center, right, leftCorner, rightCorner] = container.get_children();
let childBox = new Clutter.ActorBox();
let cornerMinWidth, cornerMinHeight;
let cornerWidth, cornerHeight;
[cornerMinWidth, cornerWidth] = leftCorner.get_preferred_width(-1);
[cornerMinHeight, cornerHeight] = leftCorner.get_preferred_height(-1);
childBox.x1 = 0;
childBox.x2 = cornerWidth;
childBox.y1 = availHeight;
childBox.y2 = availHeight + cornerHeight;
leftCorner.allocate(childBox, flags);
[cornerMinWidth, cornerWidth] = rightCorner.get_preferred_width(-1);
[cornerMinHeight, cornerHeight] = rightCorner.get_preferred_height(-1);
childBox.x1 = availWidth - cornerWidth;
childBox.x2 = availWidth;
childBox.y1 = availHeight;
childBox.y2 = availHeight + cornerHeight;
rightCorner.allocate(childBox, flags);
}
});
const Panel = new Lang.Class({
Name: 'Panel',
_init : function() {
this.actor = new Shell.GenericContainer({ name: 'panel',
reactive: true });
this.actor = new St.Widget({ name: 'panel',
reactive: true,
layoutManager: new PanelLayout() });
this.actor._delegate = this;
this._sessionStyle = null;
this.statusArea = {};
Main.overview.connect('shown', Lang.bind(this, function () {
this.actor.add_style_class_name('in-overview');
}));
Main.overview.connect('hiding', Lang.bind(this, function () {
this.actor.remove_style_class_name('in-overview');
}));
this.menuManager = new PopupMenu.PopupMenuManager(this);
this._leftBox = new St.BoxLayout({ name: 'panelLeft' });
@ -989,7 +997,6 @@ const Panel = new Lang.Class({
this._leftCorner = new PanelCorner(this._rightBox, St.Side.LEFT);
else
this._leftCorner = new PanelCorner(this._leftBox, St.Side.LEFT);
this.actor.add_actor(this._leftCorner.actor);
if (this.actor.get_text_direction() == Clutter.TextDirection.RTL)
@ -998,96 +1005,16 @@ const Panel = new Lang.Class({
this._rightCorner = new PanelCorner(this._rightBox, St.Side.RIGHT);
this.actor.add_actor(this._rightCorner.actor);
this.actor.connect('get-preferred-width', Lang.bind(this, this._getPreferredWidth));
this.actor.connect('get-preferred-height', Lang.bind(this, this._getPreferredHeight));
this.actor.connect('allocate', Lang.bind(this, this._allocate));
this.actor.connect('button-press-event', Lang.bind(this, this._onButtonPress));
Main.layoutManager.panelBox.add(this.actor);
Main.ctrlAltTabManager.addGroup(this.actor, _("Top Bar"), 'emblem-system-symbolic',
Main.ctrlAltTabManager.addGroup(this.actor, _("Top Bar"), 'start-here-symbolic',
{ sortGroup: CtrlAltTab.SortGroup.TOP });
Main.sessionMode.connect('updated', Lang.bind(this, this._updatePanel));
this._updatePanel();
},
_getPreferredWidth: function(actor, forHeight, alloc) {
alloc.min_size = -1;
alloc.natural_size = Main.layoutManager.primaryMonitor.width;
},
_getPreferredHeight: function(actor, forWidth, alloc) {
// We don't need to implement this; it's forced by the CSS
alloc.min_size = -1;
alloc.natural_size = -1;
},
_allocate: function(actor, box, flags) {
let allocWidth = box.x2 - box.x1;
let allocHeight = box.y2 - box.y1;
let [leftMinWidth, leftNaturalWidth] = this._leftBox.get_preferred_width(-1);
let [centerMinWidth, centerNaturalWidth] = this._centerBox.get_preferred_width(-1);
let [rightMinWidth, rightNaturalWidth] = this._rightBox.get_preferred_width(-1);
let sideWidth, centerWidth;
centerWidth = centerNaturalWidth;
sideWidth = (allocWidth - centerWidth) / 2;
let childBox = new Clutter.ActorBox();
childBox.y1 = 0;
childBox.y2 = allocHeight;
if (this.actor.get_text_direction() == Clutter.TextDirection.RTL) {
childBox.x1 = allocWidth - Math.min(Math.floor(sideWidth),
leftNaturalWidth);
childBox.x2 = allocWidth;
} else {
childBox.x1 = 0;
childBox.x2 = Math.min(Math.floor(sideWidth),
leftNaturalWidth);
}
this._leftBox.allocate(childBox, flags);
childBox.x1 = Math.ceil(sideWidth);
childBox.y1 = 0;
childBox.x2 = childBox.x1 + centerWidth;
childBox.y2 = allocHeight;
this._centerBox.allocate(childBox, flags);
childBox.y1 = 0;
childBox.y2 = allocHeight;
if (this.actor.get_text_direction() == Clutter.TextDirection.RTL) {
childBox.x1 = 0;
childBox.x2 = Math.min(Math.floor(sideWidth),
rightNaturalWidth);
} else {
childBox.x1 = allocWidth - Math.min(Math.floor(sideWidth),
rightNaturalWidth);
childBox.x2 = allocWidth;
}
this._rightBox.allocate(childBox, flags);
let cornerMinWidth, cornerMinHeight;
let cornerWidth, cornerHeight;
[cornerMinWidth, cornerWidth] = this._leftCorner.actor.get_preferred_width(-1);
[cornerMinHeight, cornerHeight] = this._leftCorner.actor.get_preferred_height(-1);
childBox.x1 = 0;
childBox.x2 = cornerWidth;
childBox.y1 = allocHeight;
childBox.y2 = allocHeight + cornerHeight;
this._leftCorner.actor.allocate(childBox, flags);
[cornerMinWidth, cornerWidth] = this._rightCorner.actor.get_preferred_width(-1);
[cornerMinHeight, cornerHeight] = this._rightCorner.actor.get_preferred_height(-1);
childBox.x1 = allocWidth - cornerWidth;
childBox.x2 = allocWidth;
childBox.y1 = allocHeight;
childBox.y2 = allocHeight + cornerHeight;
this._rightCorner.actor.allocate(childBox, flags);
},
_onButtonPress: function(actor, event) {
if (event.get_source() != actor)
return false;
@ -1161,13 +1088,6 @@ const Panel = new Lang.Class({
this._updateBox(panel.left, this._leftBox);
this._updateBox(panel.center, this._centerBox);
this._updateBox(panel.right, this._rightBox);
if (this._sessionStyle)
this._removeStyleClassName(this._sessionStyle);
this._sessionStyle = Main.sessionMode.panelStyle;
if (this._sessionStyle)
this._addStyleClassName(this._sessionStyle);
},
_initBox: function(elements, box) {
@ -1256,17 +1176,5 @@ const Panel = new Lang.Class({
this.statusArea[role] = indicator;
this._addToPanelBox(role, indicator, position, boxContainer);
return indicator;
},
_addStyleClassName: function(className) {
this.actor.add_style_class_name(className);
this._rightCorner.actor.add_style_class_name(className);
this._leftCorner.actor.add_style_class_name(className);
},
_removeStyleClassName: function(className) {
this.actor.remove_style_class_name(className);
this._rightCorner.actor.remove_style_class_name(className);
this._leftCorner.actor.remove_style_class_name(className);
}
});

View File

@ -404,9 +404,17 @@ const PopupSeparatorMenuItem = new Lang.Class({
this.parent({ reactive: false,
can_focus: false});
this._drawingArea = new St.DrawingArea({ style_class: 'popup-separator-menu-item' });
this.addActor(this._drawingArea, { span: -1, expand: true });
this._drawingArea.connect('repaint', Lang.bind(this, this._onRepaint));
this._separator = new HorzSeparator({ style_class: 'popup-separator-menu-item' });
this.addActor(this._separator.actor, { span: -1, expand: true });
}
});
const HorzSeparator = new Lang.Class({
Name: 'HorzSeparator',
_init: function (params) {
this.actor = new St.DrawingArea(params);
this.actor.connect('repaint', Lang.bind(this, this._onRepaint));
},
_onRepaint: function(area) {

View File

@ -27,41 +27,27 @@ const SearchProviderIface = <interface name="org.gnome.Shell.SearchProvider">
<method name="ActivateResult">
<arg type="s" direction="in" />
</method>
<method name="LaunchSearch">
<arg type="as" direction="in" />
</method>
</interface>;
var SearchProviderProxy = Gio.DBusProxy.makeProxyWrapper(SearchProviderIface);
function loadRemoteSearchProviders(addProviderCallback) {
let loadState = { loadedProviders: [],
objectPaths: {},
numLoading: 0,
addProviderCallback: addProviderCallback };
function loadRemoteSearchProviders(addProviderCallback) {
let dataDirs = GLib.get_system_data_dirs();
let loadedProviders = {};
for (let i = 0; i < dataDirs.length; i++) {
let path = GLib.build_filenamev([dataDirs[i], 'gnome-shell', 'search-providers']);
let dir = Gio.file_new_for_path(path);
dir.query_info_async('standard:type', Gio.FileQueryInfoFlags.NONE,
GLib.PRIORITY_DEFAULT, null,
function(object, res) {
let exists = false;
try {
object.query_info_finish(res);
exists = true;
} catch (e) {
}
if (!exists)
return;
loadState.numLoading++;
loadRemoteSearchProvidersFromDir(dir, loadState);
});
if (!dir.query_exists(null))
continue;
loadRemoteSearchProvidersFromDir(dir, loadedProviders, addProviderCallback);
}
};
function loadRemoteSearchProvidersFromDir(dir, loadState) {
function loadRemoteSearchProvidersFromDir(dir, loadedProviders, addProviderCallback) {
let dirPath = dir.get_path();
FileUtils.listDirAsync(dir, Lang.bind(this, function(files) {
for (let i = 0; i < files.length; i++) {
@ -77,13 +63,13 @@ function loadRemoteSearchProvidersFromDir(dir, loadState) {
if (!keyfile.has_group(KEY_FILE_GROUP))
continue;
let remoteProvider;
let remoteProvider, title;
try {
let group = KEY_FILE_GROUP;
let busName = keyfile.get_string(group, 'BusName');
let objectPath = keyfile.get_string(group, 'ObjectPath');
if (loadState.objectPaths[objectPath])
if (loadedProviders[objectPath])
continue;
let appInfo = null;
@ -91,91 +77,45 @@ function loadRemoteSearchProvidersFromDir(dir, loadState) {
let desktopId = keyfile.get_string(group, 'DesktopId');
appInfo = Gio.DesktopAppInfo.new(desktopId);
} catch (e) {
log('Ignoring search provider ' + path + ': missing DesktopId');
continue;
}
remoteProvider = new RemoteSearchProvider(appInfo,
let icon;
if (appInfo) {
icon = appInfo.get_icon();
title = appInfo.get_name();
} else {
let iconName = keyfile.get_string(group, 'Icon');
icon = new Gio.ThemedIcon({ name: iconName });
title = keyfile.get_locale_string(group, 'Title', null);
}
remoteProvider = new RemoteSearchProvider(title,
icon,
busName,
objectPath);
loadState.objectPaths[objectPath] = remoteProvider;
loadState.loadedProviders.push(remoteProvider);
loadedProviders[objectPath] = remoteProvider;
} catch(e) {
log('Failed to add search provider %s: %s'.format(path, e.toString()));
log('Failed to add search provider "%s": %s'.format(title, e.toString()));
continue;
}
}
remoteProvidersDirLoaded(loadState);
addProviderCallback(remoteProvider);
}
}));
};
function remoteProvidersDirLoaded(loadState) {
loadState.numLoading--;
if (loadState.numLoading > 0)
return;
let searchSettings = new Gio.Settings({ schema: Search.SEARCH_PROVIDERS_SCHEMA });
let sortOrder = searchSettings.get_strv('sort-order');
let numSorted = sortOrder.length;
loadState.loadedProviders.sort(
function(providerA, providerB) {
let idxA, idxB;
let appIdA, appIdB;
appIdA = providerA.appInfo.get_id();
appIdB = providerB.appInfo.get_id();
idxA = sortOrder.indexOf(appIdA);
idxB = sortOrder.indexOf(appIdB);
// if no provider is found in the order, use alphabetical order
if ((idxA == -1) && (idxB == -1))
return GLib.utf8_collate(providerA.title, providerB.title);
if (numSorted > 1) {
// if providerA is the last, it goes after everything
if ((idxA + 1) == numSorted)
return 1;
// if providerB is the last, it goes after everything
else if ((idxB + 1) == numSorted)
return -1;
}
// if providerA isn't found, it's sorted after providerB
if (idxA == -1)
return 1;
// if providerB isn't found, it's sorted after providerA
if (idxB == -1)
return -1;
// finally, if both providers are found, return their order in the list
return (idxA - idxB);
});
loadState.loadedProviders.forEach(
function(provider) {
loadState.addProviderCallback(provider);
});
}
const RemoteSearchProvider = new Lang.Class({
Name: 'RemoteSearchProvider',
Extends: Search.SearchProvider,
_init: function(appInfo, dbusName, dbusPath) {
_init: function(title, icon, dbusName, dbusPath) {
this._proxy = new SearchProviderProxy(Gio.DBus.session,
dbusName, dbusPath, Lang.bind(this, this._onProxyConstructed));
dbusName, dbusPath);
this.parent(appInfo.get_name().toUpperCase(), appInfo, true);
this.parent(title.toUpperCase());
this._cancellable = new Gio.Cancellable();
},
_onProxyConstructed: function(proxy) {
// Do nothing
this.icon = icon;
},
createIcon: function(size, meta) {
@ -190,9 +130,7 @@ const RemoteSearchProvider = new Lang.Class({
width, height, rowStride, size);
}
// Ugh, but we want to fall back to something ...
return new St.Icon({ icon_name: 'text-x-generic',
icon_size: size });
return null;
},
_getResultsFinished: function(results, error) {
@ -260,6 +198,10 @@ const RemoteSearchProvider = new Lang.Class({
activateResult: function(id) {
this._proxy.ActivateResultRemote(id);
},
launchSearch: function(terms) {
this._proxy.LaunchSearchRemote(terms);
}
});

View File

@ -49,38 +49,6 @@ const SUMMARY_ICON_SIZE = 48;
const STANDARD_FADE_TIME = 10;
const SHORT_FADE_TIME = 0.3;
function sample(offx, offy) {
return 'texel += texture2D (sampler, tex_coord.st + pixel_step * ' +
'vec2 (' + offx + ',' + offy + '));\n'
}
const GLSL_BLUR_EFFECT_DECLARATIONS = ' \
uniform vec2 pixel_step;\n \
uniform float desaturation;\n \
vec4 apply_blur(in sampler2D sampler, in vec2 tex_coord) {\n \
vec4 texel;\n \
texel = texture2D (sampler, tex_coord.st);\n'
+ sample(-1.0, -1.0)
+ sample( 0.0, -1.0)
+ sample(+1.0, -1.0)
+ sample(-1.0, 0.0)
+ sample(+1.0, 0.0)
+ sample(-1.0, +1.0)
+ sample( 0.0, +1.0)
+ sample(+1.0, +1.0) + ' \
texel /= 9.0;\n \
return texel;\n \
}\n \
vec3 desaturate (const vec3 color)\n \
{\n \
const vec3 gray_conv = vec3 (0.299, 0.587, 0.114);\n \
vec3 gray = vec3 (dot (gray_conv, color));\n \
return vec3 (mix (color.rgb, gray, desaturation));\n \
}';
const GLSL_BLUR_EFFECT_CODE = ' \
cogl_texel = apply_blur(cogl_sampler, cogl_tex_coord.st);\n \
cogl_texel.rgb = desaturate(cogl_texel.rgb);\n';
const Clock = new Lang.Class({
Name: 'ScreenShieldClock',
@ -367,10 +335,6 @@ const Arrow = new Lang.Class({
}
});
function clamp(value, min, max) {
return Math.max(min, Math.min(max, value));
}
/**
* To test screen shield, make sure to kill gnome-screensaver.
*
@ -398,25 +362,13 @@ const ScreenShield = new Lang.Class({
Lang.bind(this, this._onLockScreenKeyRelease));
this._lockScreenGroup.connect('scroll-event',
Lang.bind(this, this._onLockScreenScroll));
Main.ctrlAltTabManager.addGroup(this._lockScreenGroup, _("Lock"), 'changes-prevent-symbolic');
this._lockScreenContents = new St.Widget({ layout_manager: new Clutter.BinLayout(),
name: 'lockScreenContents' });
this._lockScreenContents.add_constraint(new Layout.MonitorConstraint({ primary: true }));
let backgroundActor = Meta.BackgroundActor.new_for_screen(global.screen);
backgroundActor.add_glsl_snippet(Meta.SnippetHook.TEXTURE_LOOKUP,
GLSL_BLUR_EFFECT_DECLARATIONS,
GLSL_BLUR_EFFECT_CODE,
true);
backgroundActor.set_uniform_float('desaturation',
1, 1, [0.6]);
backgroundActor.connect('notify::size', function(actor) {
actor.set_uniform_float('pixel_step', 2, 1, [1/actor.width, 1/actor.height]);
});
this._background = new St.Bin({ style_class: 'screen-shield-background',
child: backgroundActor });
child: Meta.BackgroundActor.new_for_screen(global.screen) });
this._lockScreenGroup.add_actor(this._background);
this._lockScreenGroup.add_actor(this._lockScreenContents);
@ -435,11 +387,14 @@ const ScreenShield = new Lang.Class({
}
this._lockScreenContents.add_actor(this._arrowContainer);
this._dragAction = new Clutter.GestureAction();
this._dragAction.connect('gesture-begin', Lang.bind(this, this._onDragBegin));
this._dragAction.connect('gesture-progress', Lang.bind(this, this._onDragMotion));
this._dragAction.connect('gesture-end', Lang.bind(this, this._onDragEnd));
this._lockScreenGroup.add_action(this._dragAction);
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 });
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,
@ -481,8 +436,6 @@ const ScreenShield = new Lang.Class({
{ inhibitEvents: true,
fadeInTime: STANDARD_FADE_TIME,
fadeFactor: 1 });
this.idleMonitor = new GnomeDesktop.IdleMonitor();
},
_onLockScreenKeyRelease: function(actor, event) {
@ -502,8 +455,8 @@ const ScreenShield = new Lang.Class({
if (symbol == Clutter.KEY_Escape ||
symbol == Clutter.KEY_Return ||
symbol == Clutter.KEY_KP_Enter) {
this._ensureUnlockDialog(true, true);
this._hideLockScreen(true, 0);
this._ensureUnlockDialog(true);
this._hideLockScreen(true);
return true;
}
@ -525,8 +478,8 @@ const ScreenShield = new Lang.Class({
// 7 standard scrolls to lift up
if (this._lockScreenScrollCounter > 35) {
this._ensureUnlockDialog(false, true);
this._hideLockScreen(true, 0);
this._ensureUnlockDialog(false);
this._hideLockScreen(true);
}
return true;
@ -557,29 +510,13 @@ const ScreenShield = new Lang.Class({
_onDragBegin: function() {
Tweener.removeTweens(this._lockScreenGroup);
this._lockScreenState = MessageTray.State.HIDING;
this._ensureUnlockDialog(false, false);
return true;
},
_onDragMotion: function() {
let [origX, origY] = this._dragAction.get_press_coords(0);
let [currentX, currentY] = this._dragAction.get_motion_coords(0);
let newY = currentY - origY;
newY = clamp(newY, -global.stage.height, 0);
this._lockScreenGroup.y = newY;
return true;
this._ensureUnlockDialog(false);
},
_onDragEnd: function(action, actor, eventX, eventY, modifiers) {
if (this._lockScreenGroup.y < -(ARROW_DRAG_THRESHOLD * global.stage.height)) {
// Complete motion automatically
let [velocity, velocityX, velocityY] = this._dragAction.get_velocity(0);
this._hideLockScreen(true, -velocityY);
this._ensureUnlockDialog(false, true);
this._hideLockScreen(true);
} else {
// restore the lock screen to its original place
// try to use the same speed as the normal animation
@ -608,43 +545,35 @@ const ScreenShield = new Lang.Class({
},
_onStatusChanged: function(status) {
if (status != GnomeSession.PresenceStatus.IDLE)
return;
if (this._dialog) {
this._dialog.cancel();
if (!this._isGreeter) {
this._dialog = null;
}
}
if (!this._isModal) {
Main.pushModal(this.actor, { keybindingMode: Main.KeybindingMode.LOCK_SCREEN });
this._isModal = true;
}
if (!this._isActive) {
this._lightbox.show();
if (this._activationTime == 0)
this._activationTime = GLib.get_monotonic_time();
this._becameActiveId = this.idleMonitor.connect('became-active', Lang.bind(this, function() {
this.idleMonitor.disconnect(this._becameActiveId);
let lightboxWasShown = this._lightbox.shown;
this._lightbox.hide();
let shouldLock = lightboxWasShown && this._settings.get_boolean(LOCK_ENABLED_KEY);
if (shouldLock || this._isLocked) {
this.lock(false);
} else if (this._isActive) {
this.unlock();
if (status == GnomeSession.PresenceStatus.IDLE) {
if (this._dialog) {
this._dialog.cancel();
if (!this._isGreeter) {
this._dialog = null;
}
}));
}
this._isActive = true;
this.emit('lock-status-changed');
if (!this._isModal) {
Main.pushModal(this.actor);
this._isModal = true;
}
if (!this._isActive) {
this._lightbox.show();
if (this._activationTime == 0)
this._activationTime = GLib.get_monotonic_time();
}
} else {
let lightboxWasShown = this._lightbox.shown;
this._lightbox.hide();
let shouldLock = lightboxWasShown && this._settings.get_boolean(LOCK_ENABLED_KEY);
if (shouldLock || this._isActive) {
this.lock(false);
} else if (this._isModal) {
this.unlock();
}
}
},
@ -662,8 +591,8 @@ const ScreenShield = new Lang.Class({
this.actor.show();
this._isGreeter = Main.sessionMode.isGreeter;
this._ensureUnlockDialog(true, true);
this._hideLockScreen(false, 0);
this._ensureUnlockDialog(true);
this._hideLockScreen(false);
},
_bumpLockScreen: function() {
@ -681,21 +610,14 @@ const ScreenShield = new Lang.Class({
});
},
_hideLockScreen: function(animate, velocity) {
_hideLockScreen: function(animate) {
this._lockScreenState = MessageTray.State.HIDING;
if (animate) {
// Tween the lock screen out of screen
// if velocity is not specified (i.e. we come here from pressing ESC),
// use the same speed regardless of original position
// if velocity is specified, it's in pixels per milliseconds
// try to use the same speed regardless of original position
let h = global.stage.height;
let delta = (h + this._lockScreenGroup.y);
let min_velocity = global.stage.height / (CURTAIN_SLIDE_TIME * 1000);
velocity = Math.max(min_velocity, velocity);
let time = (delta / velocity) / 1000;
let time = CURTAIN_SLIDE_TIME * (h + this._lockScreenGroup.y) / h;
Tweener.removeTweens(this._lockScreenGroup);
Tweener.addTween(this._lockScreenGroup,
{ y: -h,
@ -712,24 +634,20 @@ const ScreenShield = new Lang.Class({
this._lockScreenGroup.hide();
}
global.stage.show_cursor();
if (Main.sessionMode.currentMode == 'lock-screen')
Main.sessionMode.popMode('lock-screen');
},
_ensureUnlockDialog: function(onPrimary, allowCancel) {
_ensureUnlockDialog: function(onPrimary) {
if (!this._dialog) {
let constructor = Main.sessionMode.unlockDialog;
if (!constructor) {
this._dialog = new constructor(this._lockDialogGroup);
if (!this._dialog) {
// This session mode has no locking capabilities
this.unlock();
return;
}
this._dialog = new constructor(this._lockDialogGroup);
let time = global.get_current_time();
this._dialog.connect('loaded', Lang.bind(this, function() {
if (!this._dialog.open(time, onPrimary)) {
@ -741,8 +659,6 @@ const ScreenShield = new Lang.Class({
this._dialog.connect('failed', Lang.bind(this, this._onUnlockFailed));
this._dialog.connect('unlocked', Lang.bind(this, this._onUnlockSucceded));
}
this._dialog.allowCancel = allowCancel;
},
_onUnlockFailed: function() {
@ -806,16 +722,6 @@ const ScreenShield = new Lang.Class({
this._arrowAnimationId = Mainloop.timeout_add(6000, Lang.bind(this, this._animateArrows));
this._animateArrows();
let motionId = global.stage.connect('captured-event', function(stage, event) {
if (event.type() == Clutter.EventType.MOTION) {
global.stage.show_cursor();
global.stage.disconnect(motionId);
}
return false;
});
global.stage.hide_cursor();
this._lockScreenState = MessageTray.State.SHOWN;
this._lockScreenGroup.fixed_position_set = false;
this._lockScreenScrollCounter = 0;
@ -924,13 +830,12 @@ const ScreenShield = new Lang.Class({
this._activationTime = 0;
this._isActive = false;
this._isLocked = false;
this.emit('lock-status-changed');
},
lock: function(animate) {
if (!this._isModal) {
Main.pushModal(this.actor, { keybindingMode: Main.KeybindingMode.LOCK_SCREEN });
Main.pushModal(this.actor);
this._isModal = true;
}
@ -949,7 +854,6 @@ const ScreenShield = new Lang.Class({
this._resetLockScreen(animate, animate);
this._isActive = true;
this._isLocked = true;
this.emit('lock-status-changed');
},
});

View File

@ -10,8 +10,6 @@ const Util = imports.misc.util;
const FileUtils = imports.misc.fileUtils;
const Main = imports.ui.main;
const SEARCH_PROVIDERS_SCHEMA = 'org.gnome.desktop.search-providers';
// Not currently referenced by the search API, but
// this enumeration can be useful for provider
// implementations.
@ -76,11 +74,9 @@ const SearchResultDisplay = new Lang.Class({
const SearchProvider = new Lang.Class({
Name: 'SearchProvider',
_init: function(title, appInfo, isRemoteProvider) {
_init: function(title) {
this.title = title;
this.appInfo = appInfo;
this.searchSystem = null;
this.isRemoteProvider = !!isRemoteProvider;
},
/**
@ -167,6 +163,16 @@ const SearchProvider = new Lang.Class({
*/
activateResult: function(id) {
throw new Error('Not implemented');
},
/**
* launchSearch:
* @terms: Current search terms
*
* Called when the user clicks the provider icon.
*/
launchSearch: function(terms) {
throw new Error('Not implemented');
}
});
Signals.addSignalMethods(SearchProvider.prototype);
@ -176,16 +182,12 @@ const SearchSystem = new Lang.Class({
_init: function() {
this._providers = [];
this._remoteProviders = [];
this.reset();
},
registerProvider: function (provider) {
provider.searchSystem = this;
this._providers.push(provider);
if (provider.isRemoteProvider)
this._remoteProviders.push(provider);
},
unregisterProvider: function (provider) {
@ -194,20 +196,12 @@ const SearchSystem = new Lang.Class({
return;
provider.searchSystem = null;
this._providers.splice(index, 1);
let remoteIndex = this._remoteProviders.indexOf(provider);
if (remoteIndex != -1)
this._remoteProviders.splice(index, 1);
},
getProviders: function() {
return this._providers;
},
getRemoteProviders: function() {
return this._remoteProviders;
},
getTerms: function() {
return this._previousTerms;
},
@ -277,5 +271,11 @@ const SearchSystem = new Lang.Class({
}
}
},
launchSearch: function(provider) {
let terms = this.getTerms();
provider.launchSearch(terms);
Main.overview.toggle();
}
});
Signals.addSignalMethods(SearchSystem.prototype);

View File

@ -4,25 +4,191 @@ const Clutter = imports.gi.Clutter;
const Lang = imports.lang;
const Gtk = imports.gi.Gtk;
const Meta = imports.gi.Meta;
const Signals = imports.signals;
const St = imports.gi.St;
const Atk = imports.gi.Atk;
const AppDisplay = imports.ui.appDisplay;
const DND = imports.ui.dnd;
const IconGrid = imports.ui.iconGrid;
const Main = imports.ui.main;
const Overview = imports.ui.overview;
const PopupMenu = imports.ui.popupMenu;
const Search = imports.ui.search;
const MAX_SEARCH_RESULTS_ROWS = 1;
const MAX_SEARCH_RESULTS_ROWS = 3;
const MAX_GRID_SEARCH_RESULTS_ROWS = 1;
const SearchResult = new Lang.Class({
Name: 'SearchResult',
const ListSearchResult = new Lang.Class({
Name: 'ListSearchResult',
ICON_SIZE: 64,
_init: function(provider, metaInfo, terms) {
this.provider = provider;
this.metaInfo = metaInfo;
this.actor = new St.Button({ style_class: 'search-result',
reactive: true,
can_focus: true,
track_hover: true,
x_align: St.Align.START,
x_fill: true,
y_fill: true });
this.actor._delegate = this;
let content = new St.BoxLayout({ style_class: 'search-result-content',
vertical: false });
this._content = content;
this.actor.set_child(content);
// An icon for, or thumbnail of, content
let icon = this.metaInfo['createIcon'](this.ICON_SIZE);
if (icon) {
let iconBin = new St.Bin({ style_class: 'search-result-icon',
child: icon });
content.add(iconBin);
}
let details = new St.BoxLayout({ style_class: 'search-result-details',
vertical: true });
content.add(details, { x_fill: true,
y_fill: false,
x_align: St.Align.START,
y_align: St.Align.MIDDLE });
let title = new St.Label({ style_class: 'search-result-details-title',
text: this.metaInfo['name'] })
details.add(title, { x_fill: true,
y_fill: false,
x_align: St.Align.START,
y_align: St.Align.START });
// TODO: could highlight terms in the description here, or should
// providers provide what should be highlighted?
if (this.metaInfo['description']) {
let description = new St.Label({ style_class: 'search-result-details-description',
text: this.metaInfo['description'] });
details.add(description, { x_fill: false,
y_fill: true,
x_align: St.Align.START,
y_align: St.Align.END });
}
this.actor.connect('clicked', Lang.bind(this, this._onResultClicked));
},
setSelected: function(selected) {
if (selected)
this.actor.add_style_pseudo_class('selected');
else
this.actor.remove_style_pseudo_class('selected');
},
activate: function() {
this.provider.activateResult(this.metaInfo.id);
Main.overview.toggle();
},
_onResultClicked: function(actor) {
this.activate();
}
});
const ListSearchResults = new Lang.Class({
Name: 'ListSearchResults',
Extends: Search.SearchResultDisplay,
_init: function(provider) {
this.parent(provider);
this.actor = new St.BoxLayout({ style_class: 'results-list',
vertical: true });
this.actor.connect('notify::width', Lang.bind(this, function() {
Meta.later_add(Meta.LaterType.BEFORE_REDRAW, Lang.bind(this, function() {
let results = this.getResultsForDisplay();
if (results.length == 0)
return;
provider.getResultMetas(results, Lang.bind(this, this.renderResults));
}));
}));
this._notDisplayedResult = [];
this._terms = [];
this._pendingClear = false;
},
getResultsForDisplay: function() {
let alreadyVisible = this._pendingClear ? 0 : this.getVisibleResultCount();
let canDisplay = MAX_SEARCH_RESULTS_ROWS - alreadyVisible;
let numResults = Math.min(this._notDisplayedResult.length, canDisplay);
return this._notDisplayedResult.splice(0, numResults);
},
getVisibleResultCount: function() {
return this.actor.get_n_children();
},
hasMoreResults: function() {
return this._notDisplayedResult.length > 0;
},
setResults: function(results, terms) {
// copy the lists
this._notDisplayedResult = results.slice(0);
this._terms = terms.slice(0);
this._pendingClear = true;
},
renderResults: function(metas) {
for (let i = 0; i < metas.length; i++) {
let display = new ListSearchResult(this.provider, metas[i], this._terms);
this.addItem(display.actor);
display.actor.connect('key-focus-in', Lang.bind(this, this._onFocusedProviderChanged));
}
},
clear: function () {
this.actor.destroy_all_children();
this._pendingClear = false;
},
getFirstResult: function() {
if (this.getVisibleResultCount() > 0)
return this.getItemAtIndex(0)._delegate;
else
return null;
},
addItem: function(actor, index) {
if (index !== undefined)
this.actor.insert_child_at_index(actor, index);
else
this.actor.add_actor(actor);
},
getItemAtIndex: function(index) {
return this.actor.get_child_at_index(index);
},
_onFocusedProviderChanged: function() {
this.emit('focused-provider-changed');
}
});
Signals.addSignalMethods(ListSearchResults.prototype);
const GridSearchResult = new Lang.Class({
Name: 'GridSearchResult',
_init: function(provider, metaInfo, terms) {
this.provider = provider;
this.metaInfo = metaInfo;
this.actor = new St.Button({ style_class: 'grid-search-result',
reactive: true,
x_align: St.Align.START,
y_fill: true });
@ -31,7 +197,7 @@ const SearchResult = new Lang.Class({
let content = provider.createResultActor(metaInfo, terms);
if (content == null) {
content = new St.Bin({ style_class: 'search-result-content',
content = new St.Bin({ style_class: 'grid-search-result-content',
reactive: true,
can_focus: true,
track_hover: true,
@ -45,7 +211,7 @@ const SearchResult = new Lang.Class({
if (content._delegate && content._delegate.getDragActorSource)
this._dragActorSource = content._delegate.getDragActorSource();
}
this._content = content;
this.content = content;
this.actor.set_child(content);
this.actor.connect('clicked', Lang.bind(this, this._onResultClicked));
@ -53,23 +219,23 @@ const SearchResult = new Lang.Class({
let draggable = DND.makeDraggable(this.actor);
draggable.connect('drag-begin',
Lang.bind(this, function() {
Main.overview.beginItemDrag(this);
Main.overview.beginAppDrag(this);
}));
draggable.connect('drag-cancelled',
Lang.bind(this, function() {
Main.overview.cancelledItemDrag(this);
Main.overview.cancelledAppDrag(this);
}));
draggable.connect('drag-end',
Lang.bind(this, function() {
Main.overview.endItemDrag(this);
Main.overview.endAppDrag(this);
}));
},
setSelected: function(selected) {
if (selected)
this._content.add_style_pseudo_class('selected');
this.content.add_style_pseudo_class('selected');
else
this._content.remove_style_pseudo_class('selected');
this.content.remove_style_pseudo_class('selected');
},
activate: function() {
@ -85,7 +251,7 @@ const SearchResult = new Lang.Class({
if (this._dragActorSource)
return this._dragActorSource;
// not exactly right, but alignment problems are hard to notice
return this._content;
return this.content;
},
getDragActor: function(stageX, stageY) {
@ -108,11 +274,11 @@ const GridSearchResults = new Lang.Class({
_init: function(provider, grid) {
this.parent(provider);
this._grid = grid || new IconGrid.IconGrid({ rowLimit: MAX_SEARCH_RESULTS_ROWS,
this._grid = grid || new IconGrid.IconGrid({ rowLimit: MAX_GRID_SEARCH_RESULTS_ROWS,
xAlign: St.Align.START });
this.actor = new St.Bin({ x_align: St.Align.START });
this.actor = new St.Bin({ x_align: St.Align.MIDDLE });
this.actor.set_child(this._grid.actor);
this._width = 0;
this.actor.connect('notify::width', Lang.bind(this, function() {
this._width = this.actor.width;
@ -130,6 +296,7 @@ const GridSearchResults = new Lang.Class({
},
getResultsForDisplay: function() {
this._grid.actor.ensure_style();
let alreadyVisible = this._pendingClear ? 0 : this._grid.visibleItemsCount();
let canDisplay = this._grid.childrenInRow(this._width) * this._grid.getRowLimit()
- alreadyVisible;
@ -143,6 +310,10 @@ const GridSearchResults = new Lang.Class({
return this._grid.visibleItemsCount();
},
hasMoreResults: function() {
return this._notDisplayedResult.length > 0;
},
setResults: function(results, terms) {
// copy the lists
this._notDisplayedResult = results.slice(0);
@ -152,8 +323,10 @@ const GridSearchResults = new Lang.Class({
renderResults: function(metas) {
for (let i = 0; i < metas.length; i++) {
let display = new SearchResult(this.provider, metas[i], this._terms);
let display = new GridSearchResult(this.provider, metas[i], this._terms);
this._grid.addItem(display.actor);
display.content.connect('key-focus-in', Lang.bind(this, this._onFocusedProviderChanged));
}
},
@ -167,11 +340,17 @@ const GridSearchResults = new Lang.Class({
return this._grid.getItemAtIndex(0)._delegate;
else
return null;
},
_onFocusedProviderChanged: function() {
this.emit('focused-provider-changed');
}
});
Signals.addSignalMethods(GridSearchResults.prototype);
const SearchResults = new Lang.Class({
Name: 'SearchResults',
const SearchDisplay = new Lang.Class({
Name: 'SearchDisplay',
_init: function(searchSystem) {
this._searchSystem = searchSystem;
@ -222,19 +401,43 @@ const SearchResults = new Lang.Class({
createProviderMeta: function(provider) {
let providerBox = new St.BoxLayout({ style_class: 'search-section',
vertical: true });
let title = new St.Label({ style_class: 'search-section-header',
text: provider.title });
providerBox.add(title, { x_fill: false, x_align: St.Align.START });
let providerBoxContent = new St.BoxLayout({ style_class: 'search-section-content' });
let isAppsProvider = (provider instanceof AppDisplay.AppSearchProvider);
let providerIcon;
if (!isAppsProvider) {
let separator = new PopupMenu.HorzSeparator({ style_class: 'search-section-separator' });
providerBox.add(separator.actor, { expand: true });
providerIcon = new ProviderIcon(provider);
providerIcon.connect('launch-search', Lang.bind(this, function(providerIcon) {
this._searchSystem.launchSearch(providerIcon.provider);
}));
providerBoxContent.add(providerIcon.actor, { x_fill: false,
y_fill: false,
x_align: St.Align.START,
y_align: St.Align.START });
}
let resultDisplayBin = new St.Bin({ style_class: 'search-section-results',
x_fill: true,
y_fill: true });
providerBox.add(resultDisplayBin, { expand: true });
let resultDisplay = new GridSearchResults(provider);
providerBoxContent.add(resultDisplayBin, { expand: true });
providerBox.add(providerBoxContent);
let resultDisplay;
if (isAppsProvider)
resultDisplay = new GridSearchResults(provider);
else
resultDisplay = new ListSearchResults(provider);
resultDisplay.connect('focused-provider-changed', Lang.bind(this, this._updateProviderIconCanFocus));
resultDisplayBin.set_child(resultDisplay.actor);
this._providerMeta.push({ provider: provider,
actor: providerBox,
icon: providerIcon,
resultDisplay: resultDisplay });
this._content.add(providerBox);
},
@ -255,6 +458,7 @@ const SearchResults = new Lang.Class({
let meta = this._providerMeta[i];
meta.resultDisplay.clear();
meta.actor.hide();
if (meta.icon) meta.icon.actor.can_focus = false;
}
},
@ -262,6 +466,7 @@ const SearchResults = new Lang.Class({
let meta = this._metaForProvider(provider);
meta.resultDisplay.clear();
meta.actor.hide();
if (meta.icon) meta.icon.actor.can_focus = false;
},
reset: function() {
@ -284,6 +489,11 @@ const SearchResults = new Lang.Class({
return this._providerMeta[this._providers.indexOf(provider)];
},
_metaForProvidersExcept: function(provider) {
let skip = this._providers.indexOf(provider);
return this._providerMeta.filter(function(meta, index) { return index != skip }, this);
},
_maybeSetInitialSelection: function() {
let newDefaultResult = null;
@ -341,6 +551,9 @@ const SearchResults = new Lang.Class({
meta.resultDisplay.setResults(providerResults, terms);
let results = meta.resultDisplay.getResultsForDisplay();
if (meta.icon)
meta.icon.moreIcon.visible = meta.resultDisplay.hasMoreResults();
provider.getResultMetas(results, Lang.bind(this, function(metas) {
this._clearDisplayForProvider(provider);
meta.actor.show();
@ -374,6 +587,15 @@ const SearchResults = new Lang.Class({
this._defaultResult.setSelected(highlight);
},
_updateProviderIconCanFocus: function(resultDisplay) {
let meta = this._metaForProvider(resultDisplay.provider);
if (meta.icon)
meta.icon.actor.can_focus = true;
let others = this._metaForProvidersExcept(resultDisplay.provider);
others.forEach(function(meta) { if (meta.icon) meta.icon.actor.can_focus = false; });
},
navigateFocus: function(direction) {
let rtl = this.actor.get_text_direction() == Clutter.TextDirection.RTL;
if (direction == Gtk.DirectionType.TAB_BACKWARD ||
@ -393,3 +615,65 @@ const SearchResults = new Lang.Class({
}
}
});
const ProviderIcon = new Lang.Class({
Name: 'ProviderIcon',
PROVIDER_ICON_SIZE: 48,
MORE_ICON_SIZE: 16,
_init: function(provider) {
this.provider = provider;
this.actor = new St.Button({ style_class: 'search-section-icon-bin',
reactive: true,
track_hover: true });
this.actor.connect('clicked', Lang.bind(this, this._onIconClicked));
this._content = new St.Widget({ layout_manager: new Clutter.BinLayout() });
this.actor.set_child(this._content);
let rtl = (this.actor.get_text_direction() == Clutter.TextDirection.RTL);
this.moreIcon = new St.Icon({ style_class: 'search-section-icon-more',
icon_size: this.MORE_ICON_SIZE,
icon_name: 'list-add-symbolic',
visible: false,
x_align: rtl ? Clutter.ActorAlign.START : Clutter.ActorAlign.END,
y_align: Clutter.ActorAlign.END,
// HACK: without these, ClutterBinLayout
// ignores alignment properties on the actor
x_expand: true,
y_expand: true });
this._iconBin = new St.Bin({ style_class: 'search-section-icon',
width: this.PROVIDER_ICON_SIZE,
height: this.PROVIDER_ICON_SIZE });
this._content.add_actor(this._iconBin);
this._content.add_actor(this.moreIcon);
this._createProviderIcon();
},
_createProviderIcon: function() {
let icon = new St.Icon({ icon_size: this.PROVIDER_ICON_SIZE });
if (this.provider.icon)
icon.gicon = this.provider.icon;
else
icon.icon_name = 'application-x-executable';
this._iconBin.set_child(icon);
},
activate: function() {
this.emit('launch-search');
},
_onIconClicked: function(actor) {
this.activate();
}
});
Signals.addSignalMethods(ProviderIcon.prototype);

View File

@ -14,6 +14,7 @@ const _modes = {
showCalendarEvents: false,
allowSettings: false,
allowExtensions: false,
allowKeybindingsWhenModal: false,
hasRunDialog: false,
hasWorkspaces: false,
hasWindows: false,
@ -21,7 +22,6 @@ const _modes = {
isLocked: false,
isGreeter: false,
isPrimary: false,
buttonLayout: ['button-layout', 'org.gnome.shell.overrides'],
unlockDialog: null,
components: [],
panel: {
@ -29,10 +29,10 @@ const _modes = {
center: [],
right: []
},
panelStyle: null
},
'gdm': {
allowKeybindingsWhenModal: true,
hasNotifications: true,
isGreeter: true,
isPrimary: true,
@ -43,8 +43,7 @@ const _modes = {
center: ['dateMenu'],
right: ['a11y', 'display', 'keyboard',
'volume', 'battery', 'powerMenu']
},
panelStyle: 'login-screen'
}
},
'lock-screen': {
@ -57,7 +56,6 @@ const _modes = {
center: [],
right: ['lockScreen']
},
panelStyle: 'lock-screen'
},
'unlock-dialog': {
@ -69,7 +67,6 @@ const _modes = {
center: [],
right: ['a11y', 'keyboard', 'lockScreen']
},
panelStyle: 'unlock-screen'
},
'initial-setup': {
@ -102,29 +99,6 @@ const _modes = {
right: ['a11y', 'keyboard', 'volume', 'bluetooth',
'network', 'battery', 'userMenu']
}
},
'foo': {
hasOverview: true,
showCalendarEvents: true,
allowSettings: true,
allowExtensions: true,
hasRunDialog: true,
hasWorkspaces: true,
hasWindows: true,
hasNotifications: true,
isLocked: false,
isPrimary: true,
buttonLayout: ['button-layout', 'org.gnome.shell-foo.overrides'],
unlockDialog: imports.ui.unlockDialog.UnlockDialog,
components: ['networkAgent', 'polkitAgent', 'telepathyClient',
'keyring', 'recorder', 'autorunManager', 'automountManager'],
panel: {
left: ['activities', 'appMenu'],
center: ['dateMenu'],
right: ['a11y', 'keyboard', 'volume', 'bluetooth',
'network', 'battery', 'userMenu']
}
}
};

View File

@ -111,7 +111,7 @@ const GnomeShell = new Lang.Class({
},
_onScreenshotComplete: function(obj, result, area, flash, invocation) {
if (flash && result) {
if (flash) {
let flashspot = new Flashspot.Flashspot(area);
flashspot.fire();
}

View File

@ -27,7 +27,6 @@ const KEY_VISUAL_BELL = 'visual-bell';
const DESKTOP_INTERFACE_SCHEMA = 'org.gnome.desktop.interface';
const KEY_GTK_THEME = 'gtk-theme';
const KEY_ICON_THEME = 'icon-theme';
const KEY_WM_THEME = 'theme';
const KEY_TEXT_SCALING_FACTOR = 'text-scaling-factor';
const HIGH_CONTRAST_THEME = 'HighContrast';
@ -102,35 +101,28 @@ const ATIndicator = new Lang.Class({
},
_buildHCItem: function() {
let interfaceSettings = new Gio.Settings({ schema: DESKTOP_INTERFACE_SCHEMA });
let wmSettings = new Gio.Settings({ schema: WM_SCHEMA });
let gtkTheme = interfaceSettings.get_string(KEY_GTK_THEME);
let iconTheme = interfaceSettings.get_string(KEY_ICON_THEME);
let wmTheme = wmSettings.get_string(KEY_WM_THEME);
let settings = new Gio.Settings({ schema: DESKTOP_INTERFACE_SCHEMA });
let gtkTheme = settings.get_string(KEY_GTK_THEME);
let iconTheme = settings.get_string(KEY_ICON_THEME);
let hasHC = (gtkTheme == HIGH_CONTRAST_THEME);
let highContrast = this._buildItemExtended(
_("High Contrast"),
hasHC,
interfaceSettings.is_writable(KEY_GTK_THEME) &&
interfaceSettings.is_writable(KEY_ICON_THEME) &&
wmSettings.is_writable(KEY_WM_THEME),
settings.is_writable(KEY_GTK_THEME) && settings.is_writable(KEY_ICON_THEME),
function (enabled) {
if (enabled) {
interfaceSettings.set_string(KEY_GTK_THEME, HIGH_CONTRAST_THEME);
interfaceSettings.set_string(KEY_ICON_THEME, HIGH_CONTRAST_THEME);
wmSettings.set_string(KEY_WM_THEME, HIGH_CONTRAST_THEME);
settings.set_string(KEY_GTK_THEME, HIGH_CONTRAST_THEME);
settings.set_string(KEY_ICON_THEME, HIGH_CONTRAST_THEME);
} else if(!hasHC) {
interfaceSettings.set_string(KEY_GTK_THEME, gtkTheme);
interfaceSettings.set_string(KEY_ICON_THEME, iconTheme);
wmSettings.set_string(KEY_WM_THEME, wmTheme);
settings.set_string(KEY_GTK_THEME, gtkTheme);
settings.set_string(KEY_ICON_THEME, iconTheme);
} else {
interfaceSettings.reset(KEY_GTK_THEME);
interfaceSettings.reset(KEY_ICON_THEME);
wmSettings.reset(KEY_WM_THEME);
settings.reset(KEY_GTK_THEME);
settings.reset(KEY_ICON_THEME);
}
});
interfaceSettings.connect('changed::' + KEY_GTK_THEME, function() {
let value = interfaceSettings.get_string(KEY_GTK_THEME);
settings.connect('changed::' + KEY_GTK_THEME, function() {
let value = settings.get_string(KEY_GTK_THEME);
if (value == HIGH_CONTRAST_THEME) {
highContrast.setToggleState(true);
} else {
@ -138,16 +130,11 @@ const ATIndicator = new Lang.Class({
gtkTheme = value;
}
});
interfaceSettings.connect('changed::' + KEY_ICON_THEME, function() {
let value = interfaceSettings.get_string(KEY_ICON_THEME);
settings.connect('changed::' + KEY_ICON_THEME, function() {
let value = settings.get_string(KEY_ICON_THEME);
if (value != HIGH_CONTRAST_THEME)
iconTheme = value;
});
wmSettings.connect('changed::' + KEY_WM_THEME, function() {
let value = wmSettings.get_string(KEY_WM_THEME);
if (value != HIGH_CONTRAST_THEME)
wmTheme = value;
});
return highContrast;
},

View File

@ -239,6 +239,22 @@ const Indicator = new Lang.Class({
this._applet.send_to_address(device.bdaddr, device.alias);
}));
}
if (device.capabilities & GnomeBluetoothApplet.Capabilities.OBEX_FILE_TRANSFER) {
item.menu.addAction(_("Browse Files..."), Lang.bind(this, function(event) {
this._applet.browse_address(device.bdaddr, event.get_time(),
Lang.bind(this, function(applet, result) {
try {
applet.browse_address_finish(result);
} catch (e) {
this._ensureSource();
this._source.notify(new MessageTray.Notification(this._source,
_("Bluetooth"),
_("Error browsing device"),
{ body: _("The requested device cannot be browsed, error is '%s'").format(e) }));
}
}));
}));
}
switch (device.type) {
case GnomeBluetoothApplet.Type.KEYBOARD:
@ -353,7 +369,6 @@ const ConfirmNotification = new Lang.Class({
_init: function(source, applet, device_path, name, long_name, pin) {
this.parent(source,
_("Bluetooth"),
/* Translators: argument is the device short name */
_("Pairing confirmation for %s").format(name),
{ customContent: true });
this.setResident(true);
@ -363,7 +378,6 @@ const ConfirmNotification = new Lang.Class({
this.addBody(_("Device %s wants to pair with this computer").format(long_name));
this.addBody(_("Please confirm whether the PIN '%06d' matches the one on the device.").format(pin));
/* Translators: this is the verb, not the noun */
this.addButton('matches', _("Matches"));
this.addButton('does-not-match', _("Does not match"));

View File

@ -5,7 +5,6 @@ const Gio = imports.gi.Gio;
const Lang = imports.lang;
const NetworkManager = imports.gi.NetworkManager;
const NMClient = imports.gi.NMClient;
const NMGtk = imports.gi.NMGtk;
const Signals = imports.signals;
const St = imports.gi.St;
@ -140,6 +139,46 @@ const NMNetworkMenuItem = new Lang.Class({
}
});
const NMWiredSectionTitleMenuItem = new Lang.Class({
Name: 'NMWiredSectionTitleMenuItem',
Extends: PopupMenu.PopupSwitchMenuItem,
_init: function(label, params) {
params = params || { };
params.style_class = 'popup-subtitle-menu-item';
this.parent(label, false, params);
},
updateForDevice: function(device) {
if (device) {
this._device = device;
this.setStatus(device.getStatusLabel());
this.setToggleState(device.connected);
} else
this.setStatus('');
},
activate: function(event) {
this.parent(event);
if (!this._device) {
log('Section title activated when there is more than one device, should be non reactive');
return;
}
let newState = this._switch.state;
let ok;
if (newState)
ok = this._device.activate();
else
ok = this._device.deactivate();
if (!ok)
this._switch.setToggleState(false);
}
});
const NMWirelessSectionTitleMenuItem = new Lang.Class({
Name: 'NMWirelessSectionTitleMenuItem',
Extends: PopupMenu.PopupSwitchMenuItem,
@ -312,7 +351,7 @@ const NMDevice = new Lang.Class({
this._autoConnectionItem = null;
this._overflowItem = null;
this.statusItem = new PopupMenu.PopupSwitchMenuItem('', this.connected, { style_class: 'popup-subtitle-menu-item' });
this.statusItem = new PopupMenu.PopupSwitchMenuItem(this._getDescription(), this.connected, { style_class: 'popup-subtitle-menu-item' });
this._statusChanged = this.statusItem.connect('toggled', Lang.bind(this, function(item, state) {
let ok;
if (state)
@ -473,10 +512,6 @@ const NMDevice = new Lang.Class({
}
},
syncDescription: function() {
this.statusItem.label.text = this.device._description;
},
// protected
_createAutomaticConnection: function() {
throw new TypeError('Invoking pure virtual function NMDevice.createAutomaticConnection');
@ -604,6 +639,25 @@ const NMDevice = new Lang.Class({
this.statusItem.setStatus(this.getStatusLabel());
this.emit('state-changed');
},
_getDescription: function() {
let dev_product = this.device.get_product();
let dev_vendor = this.device.get_vendor();
if (!dev_product || !dev_vendor)
return '';
let product = Util.fixupPCIDescription(dev_product);
let vendor = Util.fixupPCIDescription(dev_vendor);
let out = '';
// Another quick hack; if all of the fixed up vendor string
// is found in product, ignore the vendor.
if (product.indexOf(vendor) == -1)
out += vendor + ' ';
out += product;
return out;
}
});
@ -813,6 +867,10 @@ const NMDeviceBluetooth = new Lang.Class({
this._clearSection();
this._queueCreateSection();
this._updateStatusItem();
},
_getDescription: function() {
return this.device.name || _("Bluetooth");
}
});
@ -1593,14 +1651,15 @@ const NMApplet = new Lang.Class({
this._mobileUpdateId = 0;
this._mobileUpdateDevice = null;
this._nmDevices = [];
this._devices = { };
this._devices.wired = {
section: new PopupMenu.PopupMenuSection(),
devices: [ ],
item: new NMWiredSectionTitleMenuItem(_("Wired"))
};
this._devices.wired.section.addMenuItem(this._devices.wired.item);
this._devices.wired.section.actor.hide();
this.menu.addMenuItem(this._devices.wired.section);
this.menu.addMenuItem(new PopupMenu.PopupSeparatorMenuItem());
@ -1608,7 +1667,7 @@ const NMApplet = new Lang.Class({
this._devices.wireless = {
section: new PopupMenu.PopupMenuSection(),
devices: [ ],
item: this._makeToggleItem('wireless', _("Wi-Fi"))
item: this._makeToggleItem('wireless', _("Wireless"))
};
this._devices.wireless.section.addMenuItem(this._devices.wireless.item);
this._devices.wireless.section.actor.hide();
@ -1618,7 +1677,9 @@ const NMApplet = new Lang.Class({
this._devices.wwan = {
section: new PopupMenu.PopupMenuSection(),
devices: [ ],
item: this._makeToggleItem('wwan', _("Mobile broadband"))
};
this._devices.wwan.section.addMenuItem(this._devices.wwan.item);
this._devices.wwan.section.actor.hide();
this.menu.addMenuItem(this._devices.wwan.section);
this.menu.addMenuItem(new PopupMenu.PopupSeparatorMenuItem());
@ -1701,23 +1762,16 @@ const NMApplet = new Lang.Class({
section.actor.hide();
else {
section.actor.show();
// Sync the relation between the section title
// item (the one with the airplane mode switch)
// and the individual device switches
if (item) {
if (devices.length == 1) {
let dev = devices[0];
dev.statusItem.actor.hide();
item.updateForDevice(dev);
} else {
devices.forEach(function(dev) {
dev.statusItem.actor.show();
});
// remove status text from the section title item
item.updateForDevice(null);
}
if (devices.length == 1) {
let dev = devices[0];
dev.statusItem.actor.hide();
item.updateForDevice(dev);
} else {
devices.forEach(function(dev) {
dev.statusItem.actor.show();
});
// remove status text from the section title item
item.updateForDevice(null);
}
}
},
@ -1725,9 +1779,8 @@ const NMApplet = new Lang.Class({
_readDevices: function() {
let devices = this._client.get_devices() || [ ];
for (let i = 0; i < devices.length; ++i) {
this._deviceAdded(this._client, devices[i], true);
this._deviceAdded(this._client, devices[i]);
}
this._syncDeviceNames();
},
_notifyForDevice: function(device, iconName, title, text, urgency) {
@ -1775,18 +1828,7 @@ const NMApplet = new Lang.Class({
return wrapper;
},
_syncDeviceNames: function() {
let names = NMGtk.utils_disambiguate_device_names(this._nmDevices);
for (let i = 0; i < this._nmDevices.length; i++) {
let device = this._nmDevices[i];
if (device._description != names[i]) {
device._description = names[i];
device._delegate.syncDescription();
}
}
},
_deviceAdded: function(client, device, skipSyncDeviceNames) {
_deviceAdded: function(client, device) {
if (device._delegate) {
// already seen, not adding again
return;
@ -1797,14 +1839,10 @@ const NMApplet = new Lang.Class({
let section = this._devices[wrapper.category].section;
let devices = this._devices[wrapper.category].devices;
section.addMenuItem(wrapper.statusItem);
section.addMenuItem(wrapper.section);
section.addMenuItem(wrapper.section, 1);
section.addMenuItem(wrapper.statusItem, 1);
devices.push(wrapper);
this._nmDevices.push(device);
if (!skipSyncDeviceNames)
this._syncDeviceNames();
this._syncSectionTitle(wrapper.category);
}
},
@ -1822,10 +1860,6 @@ const NMApplet = new Lang.Class({
let pos = devices.indexOf(wrapper);
devices.splice(pos, 1);
pos = this._nmDevices.indexOf(device);
this._nmDevices.splice(pos, 1);
this._syncDeviceNames();
this._syncSectionTitle(wrapper.category)
},

View File

@ -96,7 +96,7 @@ const Indicator = new Lang.Class({
let minutes = time % 60;
let hours = Math.floor(time / 60);
let timestring;
if (time >= 60) {
if (time > 60) {
if (minutes == 0) {
timestring = ngettext("%d hour remaining", "%d hours remaining", hours).format(hours);
} else {

View File

@ -14,14 +14,12 @@ const St = imports.gi.St;
const Main = imports.ui.main;
const ModalDialog = imports.ui.modalDialog;
const Panel = imports.ui.panel;
const ShellEntry = imports.ui.shellEntry;
const Tweener = imports.ui.tweener;
const UserMenu = imports.ui.userMenu;
const Batch = imports.gdm.batch;
const GdmUtil = imports.gdm.util;
const LoginDialog = imports.gdm.loginDialog;
// The timeout before going back automatically to the lock screen (in seconds)
const IDLE_TIMEOUT = 2 * 60;
@ -115,7 +113,6 @@ const UnlockDialog = new Lang.Class({
_init: function(parentActor) {
this.parent({ shellReactive: true,
styleClass: 'login-dialog',
keybindingMode: Main.KeybindingMode.UNLOCK_SCREEN,
parentActor: parentActor
});
@ -153,9 +150,7 @@ const UnlockDialog = new Lang.Class({
this._promptEntry.clutter_text.set_password_char('\u25cf');
ShellEntry.addContextMenu(this._promptEntry, { isPassword: true });
this.setInitialKeyFocus(this._promptEntry);
this._promptEntry.clutter_text.connect('text-changed', Lang.bind(this, function() {
this._updateOkButtonSensitivity(this._promptEntry.text.length > 0);
}));
this._promptEntry.clutter_text.connect('activate', Lang.bind(this, this._doUnlock));
this._promptLayout.add(this._promptEntry,
{ expand: true,
@ -170,33 +165,15 @@ const UnlockDialog = new Lang.Class({
this._promptLoginHint.hide();
this.contentLayout.add_actor(this._promptLoginHint);
this._workSpinner = new Panel.AnimatedIcon('process-working.svg', LoginDialog.WORK_SPINNER_ICON_SIZE);
this._workSpinner.actor.opacity = 0;
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.allowCancel = false;
this.buttonLayout.visible = true;
this.addButton({ label: _("Cancel"),
action: Lang.bind(this, this._escape),
key: Clutter.KEY_Escape },
{ expand: true,
x_fill: false,
y_fill: false,
x_align: St.Align.START,
y_align: St.Align.MIDDLE });
this.buttonLayout.add(this._workSpinner.actor,
{ expand: false,
x_fill: false,
y_fill: false,
x_align: St.Align.END,
y_align: St.Align.MIDDLE });
this._okButton = this.addButton({ label: _("Unlock"),
action: Lang.bind(this, this._doUnlock),
default: true },
{ expand: false,
x_fill: false,
y_fill: false,
x_align: St.Align.END,
y_align: St.Align.MIDDLE });
this._updateSensitivity(true);
let otherUserLabel = new St.Label({ text: _("Log in as another user"),
style_class: 'login-dialog-not-listed-label' });
@ -211,8 +188,6 @@ const UnlockDialog = new Lang.Class({
{ x_align: St.Align.START,
x_fill: false });
this._updateSensitivity(true);
let batch = new Batch.Hold();
this._userVerifier.begin(this._userName, batch);
@ -221,8 +196,6 @@ const UnlockDialog = new Lang.Class({
return false;
}));
Main.ctrlAltTabManager.addGroup(this.dialogLayout, _("Unlock Window"), 'dialog-password-symbolic');
this._idleMonitor = new GnomeDesktop.IdleMonitor();
this._idleWatchId = this._idleMonitor.add_watch(IDLE_TIMEOUT * 1000, Lang.bind(this, this._escape));
},
@ -230,36 +203,8 @@ const UnlockDialog = new Lang.Class({
_updateSensitivity: function(sensitive) {
this._promptEntry.reactive = sensitive;
this._promptEntry.clutter_text.editable = sensitive;
this._updateOkButtonSensitivity(sensitive && this._promptEntry.text.length > 0);
this._otherUserButton.reactive = sensitive;
this._otherUserButton.can_focus = sensitive;
},
_updateOkButtonSensitivity: function(sensitive) {
this._okButton.reactive = sensitive;
this._okButton.can_focus = sensitive;
},
_setWorking: function(working) {
if (working) {
this._workSpinner.play();
Tweener.addTween(this._workSpinner.actor,
{ opacity: 255,
delay: LoginDialog.WORK_SPINNER_ANIMATION_DELAY,
time: LoginDialog.WORK_SPINNER_ANIMATION_TIME,
transition: 'linear'
});
} else {
Tweener.addTween(this._workSpinner.actor,
{ opacity: 0,
time: LoginDialog.WORK_SPINNER_ANIMATION_TIME,
transition: 'linear',
onCompleteScope: this,
onComplete: function() {
this._workSpinner.stop();
}
});
}
this._okButton.button.reactive = sensitive;
this._okButton.button.can_focus = sensitive;
},
_showMessage: function(userVerifier, message, styleClass) {
@ -292,7 +237,6 @@ const UnlockDialog = new Lang.Class({
this._currentQuery = serviceName;
this._updateSensitivity(true);
this._setWorking(false);
},
_showLoginHint: function(verifier, message) {
@ -311,7 +255,6 @@ const UnlockDialog = new Lang.Class({
// the actual reply to GDM will be sent as soon as asked
this._firstQuestionAnswer = this._promptEntry.text;
this._updateSensitivity(false);
this._setWorking(true);
return;
}
@ -322,7 +265,6 @@ const UnlockDialog = new Lang.Class({
this._currentQuery = null;
this._updateSensitivity(false);
this._setWorking(true);
this._userVerifier.answerQuery(query, this._promptEntry.text);
},
@ -345,14 +287,11 @@ const UnlockDialog = new Lang.Class({
this._promptEntry.menu.isPassword = true;
this._updateSensitivity(false);
this._setWorking(false);
},
_escape: function() {
if (this.allowCancel) {
this._userVerifier.cancel();
this.emit('failed');
}
this._userVerifier.cancel();
this.emit('failed');
},
_otherUserClicked: function(button, event) {

View File

@ -27,7 +27,6 @@ const DISABLE_LOCK_SCREEN_KEY = 'disable-lock-screen';
const DISABLE_LOG_OUT_KEY = 'disable-log-out';
const LOCK_ENABLED_KEY = 'lock-enabled';
const ALWAYS_SHOW_LOG_OUT_KEY = 'always-show-log-out';
const SHOW_FULL_NAME_KEY = 'show-full-name';
const DIALOG_ICON_SIZE = 64;
@ -551,12 +550,9 @@ const UserMenuButton = new Lang.Class({
Lang.bind(this, this._updateSwitchUser));
this._lockdownSettings.connect('changed::' + DISABLE_LOG_OUT_KEY,
Lang.bind(this, this._updateLogout));
this._lockdownSettings.connect('changed::' + DISABLE_LOCK_SCREEN_KEY,
Lang.bind(this, this._updateLockScreen));
this._screenSaverSettings.connect('changed::' + SHOW_FULL_NAME_KEY,
Lang.bind(this, this._updateUserName));
global.settings.connect('changed::' + SHOW_FULL_NAME_KEY,
Lang.bind(this, this._updateUserName));
this._updateSwitchUser();
this._updateLogout();
this._updateLockScreen();
@ -601,10 +597,7 @@ const UserMenuButton = new Lang.Class({
},
_updateUserName: function() {
let settings = global.settings;
if (Main.sessionMode.isLocked)
settings = this._screenSaverSettings;
if (this._user.is_loaded && settings.get_boolean(SHOW_FULL_NAME_KEY))
if (this._user.is_loaded)
this._name.set_text(this._user.get_real_name());
else
this._name.set_text("");
@ -759,7 +752,7 @@ const UserMenuButton = new Lang.Class({
item = new PopupMenu.PopupSeparatorMenuItem();
this.menu.addMenuItem(item);
item = new PopupMenu.PopupMenuItem(_("Settings"));
item = new PopupMenu.PopupMenuItem(_("System Settings"));
item.connect('activate', Lang.bind(this, this._onPreferencesActivate));
this.menu.addMenuItem(item);
this._systemSettings = item;

View File

@ -52,7 +52,7 @@ const ViewSelector = new Lang.Class({
this._activePage = null;
this.active = false;
this.entryNonEmpty = false;
this._searchPending = false;
this._searchTimeoutId = 0;
@ -84,21 +84,16 @@ const ViewSelector = new Lang.Class({
this._workspacesDisplay = new WorkspacesView.WorkspacesDisplay();
this._workspacesPage = this._addPage(this._workspacesDisplay.actor, null,
_("Windows"), 'emblem-documents-symbolic');
_("Windows"), 'text-x-generic-symbolic');
this._appDisplay = new AppDisplay.AllAppDisplay();
this._appsPage = this._addPage(this._appDisplay.actor, null,
_("Applications"), 'view-grid-symbolic');
_("Applications"), 'system-run-symbolic');
this._searchResults = new SearchDisplay.SearchResults(this._searchSystem);
this._searchResults = new SearchDisplay.SearchDisplay(this._searchSystem);
this._searchPage = this._addPage(this._searchResults.actor, this._entry,
_("Search"), 'edit-find-symbolic');
this._searchSettings = new Gio.Settings({ schema: Search.SEARCH_PROVIDERS_SCHEMA });
this._searchSettings.connect('changed::disabled', Lang.bind(this, this._reloadRemoteProviders));
this._searchSettings.connect('changed::disable-external', Lang.bind(this, this._reloadRemoteProviders));
this._searchSettings.connect('changed::sort-order', Lang.bind(this, this._reloadRemoteProviders));
// Default search providers
// Wanda comes obviously first
this.addSearchProvider(new Wanda.WandaSearchProvider());
@ -119,9 +114,6 @@ const ViewSelector = new Lang.Class({
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 () {
@ -138,28 +130,15 @@ const ViewSelector = new Lang.Class({
}
}));
// 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 });
Main.wm.addKeybinding('toggle-application-view',
new Gio.Settings({ schema: SHELL_KEYBINDINGS_SCHEMA }),
Meta.KeyBindingFlags.NONE,
Main.KeybindingMode.NORMAL |
Main.KeybindingMode.OVERVIEW,
Lang.bind(this, this._toggleAppsPage));
global.display.add_keybinding('toggle-application-view',
new Gio.Settings({ schema: SHELL_KEYBINDINGS_SCHEMA }),
Meta.KeyBindingFlags.NONE,
Lang.bind(this, this._showWithAppsPage));
},
_toggleAppsPage: function() {
_showWithAppsPage: function() {
Main.overview.show();
this._showAppsButton.checked = !this._showAppsButton.checked;
this._showAppsButton.set_checked(true);
},
show: function() {
@ -203,7 +182,7 @@ const ViewSelector = new Lang.Class({
})
});;
this._pageArea.add_actor(page);
return page;
return page
},
_showPage: function(page) {
@ -237,7 +216,9 @@ const ViewSelector = new Lang.Class({
},
_onShowAppsButtonToggled: function() {
if (this.active)
this.emit('apps-button-checked', this._showAppsButton.checked);
if (this.entryNonEmpty)
this.reset();
else
this._showPage(this._showAppsButton.checked ? this._appsPage
@ -253,7 +234,7 @@ const ViewSelector = new Lang.Class({
let symbol = event.get_key_symbol();
if (symbol == Clutter.Escape) {
if (this.active)
if (this.entryNonEmpty)
this.reset();
else if (this._showAppsButton.checked)
this._resetShowAppsButton();
@ -261,9 +242,9 @@ const ViewSelector = new Lang.Class({
Main.overview.hide();
return true;
} else if (Clutter.keysym_to_unicode(symbol) ||
(symbol == Clutter.BackSpace && this.active)) {
(symbol == Clutter.BackSpace && this.entryNonEmpty)) {
this.startSearch(event);
} else if (!this.active) {
} else if (!this.entryNonEmpty) {
if (symbol == Clutter.Tab || symbol == Clutter.Down) {
this._activePage.navigate_focus(null, Gtk.DirectionType.TAB_FORWARD, false);
return true;
@ -276,6 +257,7 @@ const ViewSelector = new Lang.Class({
},
_searchCancelled: function() {
this.emit('search-cancelled');
this._showPage(this._showAppsButton.checked ? this._appsPage
: this._workspacesPage);
@ -337,13 +319,14 @@ const ViewSelector = new Lang.Class({
},
_onTextChanged: function (se, prop) {
let searchPreviouslyActive = this.active;
this.active = this._entry.get_text() != '';
this._searchPending = this.active && !searchPreviouslyActive;
let searchPreviouslyActive = this.entryNonEmpty;
this.entryNonEmpty = this._entry.get_text() != '';
this._searchPending = this.entryNonEmpty && !searchPreviouslyActive;
if (this._searchPending) {
this._searchResults.startingSearch();
}
if (this.active) {
if (this.entryNonEmpty) {
this.emit('search-begin');
this._entry.set_secondary_icon(this._activeIcon);
if (this._iconClickedId == 0) {
@ -360,7 +343,7 @@ const ViewSelector = new Lang.Class({
this._entry.set_secondary_icon(this._inactiveIcon);
this._searchCancelled();
}
if (!this.active) {
if (!this.entryNonEmpty) {
if (this._searchTimeoutId > 0) {
Mainloop.source_remove(this._searchTimeoutId);
this._searchTimeoutId = 0;
@ -388,7 +371,7 @@ const ViewSelector = new Lang.Class({
}
this._searchResults.activateDefault();
return true;
} else if (this.active) {
} else if (this.entryNonEmpty) {
let arrowNext, nextDirection;
if (entry.get_text_direction() == Clutter.TextDirection.RTL) {
arrowNext = Clutter.Left;
@ -440,32 +423,7 @@ const ViewSelector = new Lang.Class({
this._showPage(this._searchPage);
},
_shouldUseSearchProvider: function(provider) {
// the disable-external GSetting only affects remote providers
if (!provider.isRemoteProvider)
return true;
if (this._searchSettings.get_boolean('disable-external'))
return false;
let appId = provider.appInfo.get_id();
let disable = this._searchSettings.get_strv('disabled');
return disable.indexOf(appId) == -1;
},
_reloadRemoteProviders: function() {
// removeSearchProvider() modifies the provider list we iterate on,
// so make a copy first
let remoteProviders = this._searchSystem.getRemoteProviders().slice(0);
remoteProviders.forEach(Lang.bind(this, this.removeSearchProvider));
RemoteSearch.loadRemoteSearchProviders(Lang.bind(this, this.addSearchProvider));
},
addSearchProvider: function(provider) {
if (!this._shouldUseSearchProvider(provider))
return;
this._searchSystem.registerProvider(provider);
this._searchResults.createProviderMeta(provider);
},

View File

@ -9,7 +9,6 @@ const St = imports.gi.St;
const IconGrid = imports.ui.iconGrid;
const Layout = imports.ui.layout;
const Main = imports.ui.main;
const Panel = imports.ui.panel;
const Search = imports.ui.search;
// we could make these gsettings
@ -54,9 +53,20 @@ const WandaIcon = new Lang.Class({
icon_size: iconSize });
}
this._animations = new Panel.Animation(this._imageFile, this._imgWidth, this._imgHeight, FISH_SPEED);
this._animations.play();
return this._animations.actor;
this._animations = St.TextureCache.get_default().load_sliced_image(this._imageFile, this._imgWidth, this._imgHeight);
this._animations.connect('notify::mapped', Lang.bind(this, function() {
if (this._animations.mapped && !this._timeoutId) {
this._timeoutId = GLib.timeout_add(GLib.PRIORITY_DEFAULT, FISH_SPEED, Lang.bind(this, this._update));
this._i = 0;
this._update();
} else if (!this._animations.mapped && this._timeoutId) {
GLib.source_remove(this._timeoutId);
this._timeoutId = 0;
}
}));
return this._animations;
},
_createIconTexture: function(size) {
@ -64,7 +74,20 @@ const WandaIcon = new Lang.Class({
return;
this.parent(size);
}
},
_update: function() {
let n = this._animations.get_n_children();
if (n == 0) {
return true;
}
this._animations.get_child_at_index(this._i).hide();
this._i = (this._i + 1) % n;
this._animations.get_child_at_index(this._i).show();
return true;
},
});
const WandaIconBin = new Lang.Class({

View File

@ -39,8 +39,6 @@ const WindowAttentionHandler = new Lang.Class({
let [title, banner] = this._getTitleAndBanner(app, window);
let notification = new MessageTray.Notification(source, title, banner);
notification.setForFeedback(true);
source.notify(notification);
source.signalIDs.push(window.connect('notify::title', Lang.bind(this, function() {

View File

@ -83,8 +83,6 @@ const WindowManager = new Lang.Class({
this._animationBlockCount = 0;
this._allowedKeybindings = {};
this._switchData = null;
this._shellwm.connect('kill-switch-workspace', Lang.bind(this, this._switchWorkspaceDone));
this._shellwm.connect('kill-window-effects', Lang.bind(this, function (shellwm, actor) {
@ -101,66 +99,38 @@ const WindowManager = new Lang.Class({
this._shellwm.connect('unmaximize', Lang.bind(this, this._unmaximizeWindow));
this._shellwm.connect('map', Lang.bind(this, this._mapWindow));
this._shellwm.connect('destroy', Lang.bind(this, this._destroyWindow));
this._shellwm.connect('filter-keybinding', Lang.bind(this, this._filterKeybinding));
this._workspaceSwitcherPopup = null;
this.setCustomKeybindingHandler('switch-to-workspace-left',
Main.KeybindingMode.NORMAL |
Main.KeybindingMode.OVERVIEW,
Lang.bind(this, this._showWorkspaceSwitcher));
this.setCustomKeybindingHandler('switch-to-workspace-right',
Main.KeybindingMode.NORMAL |
Main.KeybindingMode.OVERVIEW,
Lang.bind(this, this._showWorkspaceSwitcher));
this.setCustomKeybindingHandler('switch-to-workspace-up',
Main.KeybindingMode.NORMAL |
Main.KeybindingMode.OVERVIEW,
Lang.bind(this, this._showWorkspaceSwitcher));
this.setCustomKeybindingHandler('switch-to-workspace-down',
Main.KeybindingMode.NORMAL |
Main.KeybindingMode.OVERVIEW,
Lang.bind(this, this._showWorkspaceSwitcher));
this.setCustomKeybindingHandler('move-to-workspace-left',
Main.KeybindingMode.NORMAL |
Main.KeybindingMode.OVERVIEW,
Lang.bind(this, this._showWorkspaceSwitcher));
this.setCustomKeybindingHandler('move-to-workspace-right',
Main.KeybindingMode.NORMAL |
Main.KeybindingMode.OVERVIEW,
Lang.bind(this, this._showWorkspaceSwitcher));
this.setCustomKeybindingHandler('move-to-workspace-up',
Main.KeybindingMode.NORMAL |
Main.KeybindingMode.OVERVIEW,
Lang.bind(this, this._showWorkspaceSwitcher));
this.setCustomKeybindingHandler('move-to-workspace-down',
Main.KeybindingMode.NORMAL |
Main.KeybindingMode.OVERVIEW,
Lang.bind(this, this._showWorkspaceSwitcher));
this.setCustomKeybindingHandler('switch-windows',
Main.KeybindingMode.NORMAL,
Lang.bind(this, this._startAppSwitcher));
this.setCustomKeybindingHandler('switch-group',
Main.KeybindingMode.NORMAL,
Lang.bind(this, this._startAppSwitcher));
this.setCustomKeybindingHandler('switch-windows-backward',
Main.KeybindingMode.NORMAL,
Lang.bind(this, this._startAppSwitcher));
this.setCustomKeybindingHandler('switch-group-backward',
Main.KeybindingMode.NORMAL,
Lang.bind(this, this._startAppSwitcher));
this.setCustomKeybindingHandler('switch-panels',
Main.KeybindingMode.NORMAL |
Main.KeybindingMode.OVERVIEW |
Main.KeybindingMode.LOCK_SCREEN |
Main.KeybindingMode.UNLOCK_SCREEN |
Main.KeybindingMode.LOGIN_SCREEN,
Lang.bind(this, this._startA11ySwitcher));
this.addKeybinding('open-application-menu',
new Gio.Settings({ schema: SHELL_KEYBINDINGS_SCHEMA }),
Meta.KeyBindingFlags.NONE,
Main.KeybindingMode.NORMAL,
Lang.bind(this, this._openAppMenu));
Meta.keybindings_set_custom_handler('switch-to-workspace-left',
Lang.bind(this, this._showWorkspaceSwitcher));
Meta.keybindings_set_custom_handler('switch-to-workspace-right',
Lang.bind(this, this._showWorkspaceSwitcher));
Meta.keybindings_set_custom_handler('switch-to-workspace-up',
Lang.bind(this, this._showWorkspaceSwitcher));
Meta.keybindings_set_custom_handler('switch-to-workspace-down',
Lang.bind(this, this._showWorkspaceSwitcher));
Meta.keybindings_set_custom_handler('move-to-workspace-left',
Lang.bind(this, this._showWorkspaceSwitcher));
Meta.keybindings_set_custom_handler('move-to-workspace-right',
Lang.bind(this, this._showWorkspaceSwitcher));
Meta.keybindings_set_custom_handler('move-to-workspace-up',
Lang.bind(this, this._showWorkspaceSwitcher));
Meta.keybindings_set_custom_handler('move-to-workspace-down',
Lang.bind(this, this._showWorkspaceSwitcher));
Meta.keybindings_set_custom_handler('switch-windows',
Lang.bind(this, this._startAppSwitcher));
Meta.keybindings_set_custom_handler('switch-group',
Lang.bind(this, this._startAppSwitcher));
Meta.keybindings_set_custom_handler('switch-windows-backward',
Lang.bind(this, this._startAppSwitcher));
Meta.keybindings_set_custom_handler('switch-group-backward',
Lang.bind(this, this._startAppSwitcher));
Meta.keybindings_set_custom_handler('switch-panels',
Lang.bind(this, this._startA11ySwitcher));
global.display.add_keybinding('open-application-menu',
new Gio.Settings({ schema: SHELL_KEYBINDINGS_SCHEMA }),
Meta.KeyBindingFlags.NONE,
Lang.bind(this, this._openAppMenu));
Main.overview.connect('showing', Lang.bind(this, function() {
for (let i = 0; i < this._dimmedWindows.length; i++)
@ -172,25 +142,6 @@ const WindowManager = new Lang.Class({
}));
},
setCustomKeybindingHandler: function(name, modes, handler) {
if (Meta.keybindings_set_custom_handler(name, handler))
this.allowKeybinding(name, modes);
},
addKeybinding: function(name, settings, flags, modes, handler) {
if (global.display.add_keybinding(name, settings, flags, handler))
this.allowKeybinding(name, modes);
},
removeKeybinding: function(name) {
if (global.display.remove_keybinding(name))
this.allowKeybinding(name, Main.KeybindingMode.NONE);
},
allowKeybinding: function(name, modes) {
this._allowedKeybindings[name] = modes;
},
blockAnimations: function() {
this._animationBlockCount++;
},
@ -473,21 +424,6 @@ const WindowManager = new Lang.Class({
}
},
_filterKeybinding: function(shellwm, binding) {
if (Main.keybindingMode == Main.KeybindingMode.NONE)
return true;
// There's little sense in implementing a keybinding in mutter and
// not having it work in NORMAL mode; handle this case generically
// so we don't have to explicitly allow all builtin keybindings in
// NORMAL mode.
if (Main.keybindingMode == Main.KeybindingMode.NORMAL &&
binding.is_builtin())
return false;
return !(this._allowedKeybindings[binding.get_name()] & Main.keybindingMode);
},
_switchWorkspace : function(shellwm, from, to, direction) {
if (!this._shouldAnimate()) {
shellwm.completed_switch_workspace();

View File

@ -30,6 +30,9 @@ const CLOSE_BUTTON_FADE_TIME = 0.1;
const DRAGGING_WINDOW_OPACITY = 100;
const BUTTON_LAYOUT_SCHEMA = 'org.gnome.shell.overrides';
const BUTTON_LAYOUT_KEY = 'button-layout';
// When calculating a layout, we calculate the scale of windows and the percent
// of the available area the new layout uses. If the values for the new layout,
// when weighted with the values as below, are worse than the previous layout's,
@ -442,9 +445,6 @@ const WindowOverlay = new Lang.Class({
this._parentActor = parentActor;
this._hidden = false;
this.borderSize = 0;
this.border = new St.Bin({ style_class: 'window-clone-border' });
let title = new St.Label({ style_class: 'window-caption',
text: metaWindow.title });
title.clutter_text.ellipsize = Pango.EllipsizeMode.END;
@ -482,13 +482,11 @@ const WindowOverlay = new Lang.Class({
this.closeButton = button;
parentActor.add_actor(this.title);
parentActor.add_actor(this.border);
parentActor.add_actor(this.closeButton);
title.connect('style-changed',
Lang.bind(this, this._onStyleChanged));
button.connect('style-changed',
Lang.bind(this, this._onStyleChanged));
this.border.connect('style-changed', Lang.bind(this, this._onStyleChanged));
// force a style change if we are already on a stage - otherwise
// the signal will be emitted normally when we are added
if (parentActor.get_stage())
@ -497,17 +495,15 @@ const WindowOverlay = new Lang.Class({
hide: function() {
this._hidden = true;
this.closeButton.hide();
this.title.hide();
this.hideCloseButton();
},
show: function() {
this._hidden = false;
this.title.show();
if (this._windowClone.actor.has_pointer)
this._animateVisible();
this.closeButton.show();
this.title.show();
},
fadeIn: function() {
@ -524,14 +520,10 @@ const WindowOverlay = new Lang.Class({
},
chromeHeights: function () {
return [Math.max(this.borderSize, this.closeButton.height - this.closeButton._overlap),
return [this.closeButton.height - this.closeButton._overlap,
this.title.height + this.title._spacing];
},
chromeWidths: function () {
return [this.borderSize, this.borderSize];
},
_repositionSelf: function() {
let [cloneX, cloneY, cloneWidth, cloneHeight] = this._windowClone.slot;
this.updatePositions(cloneX, cloneY, cloneWidth, cloneHeight, false);
@ -551,8 +543,8 @@ const WindowOverlay = new Lang.Class({
let button = this.closeButton;
let title = this.title;
let settings = new Gio.Settings({ schema: Main.sessionMode.buttonLayout[1] });
let layout = settings.get_string(Main.sessionMode.buttonLayout[0]);
let settings = new Gio.Settings({ schema: BUTTON_LAYOUT_SCHEMA });
let layout = settings.get_string(BUTTON_LAYOUT_KEY);
let rtl = Clutter.get_default_text_direction() == Clutter.TextDirection.RTL;
let split = layout.split(":");
@ -586,32 +578,16 @@ const WindowOverlay = new Lang.Class({
title.width = titleWidth;
title.set_position(Math.floor(titleX), Math.floor(titleY));
}
let borderX = cloneX - this.borderSize;
let borderY = cloneY - this.borderSize;
let borderWidth = cloneWidth + 2 * this.borderSize;
let borderHeight = cloneHeight + 2 * this.borderSize;
if (animate) {
this._animateOverlayActor(this.border, borderX, borderY,
borderWidth, borderHeight);
} else {
this.border.set_position(borderX, borderY);
this.border.set_size(borderWidth, borderHeight);
}
},
_animateOverlayActor: function(actor, x, y, width, height) {
let params = { x: x,
y: y,
width: width,
time: Overview.ANIMATION_TIME,
transition: 'easeOutQuad' };
if (height !== undefined)
params.height = height;
Tweener.addTween(actor, params);
_animateOverlayActor: function(actor, x, y, width) {
Tweener.addTween(actor,
{ x: x,
y: y,
width: width,
time: Overview.ANIMATION_TIME,
transition: 'easeOutQuad'
});
},
_closeWindow: function(actor) {
@ -654,43 +630,6 @@ const WindowOverlay = new Lang.Class({
this._windowClone.metaWindow.disconnect(this._updateCaptionId);
this.title.destroy();
this.closeButton.destroy();
this.border.destroy();
},
_animateVisible: function() {
this._parentActor.raise_top();
this.closeButton.show();
this.closeButton.opacity = 0;
Tweener.addTween(this.closeButton,
{ opacity: 255,
time: CLOSE_BUTTON_FADE_TIME,
transition: 'easeOutQuad' });
this.border.show();
this.border.opacity = 0;
Tweener.addTween(this.border,
{ opacity: 255,
time: CLOSE_BUTTON_FADE_TIME,
transition: 'easeOutQuad' });
this.title.add_style_pseudo_class('hover');
},
_animateInvisible: function() {
this.closeButton.opacity = 255;
Tweener.addTween(this.closeButton,
{ opacity: 0,
time: CLOSE_BUTTON_FADE_TIME,
transition: 'easeInQuad' });
this.border.opacity = 255;
Tweener.addTween(this.border,
{ opacity: 0,
time: CLOSE_BUTTON_FADE_TIME,
transition: 'easeInQuad' });
this.title.remove_style_pseudo_class('hover');
},
_onEnter: function() {
@ -700,8 +639,8 @@ const WindowOverlay = new Lang.Class({
// are shown again
if (this._hidden)
return;
this._animateVisible();
this._parentActor.raise_top();
this.closeButton.show();
this.emit('show-close-button');
},
@ -712,10 +651,9 @@ const WindowOverlay = new Lang.Class({
_idleToggleCloseButton: function() {
this._idleToggleCloseId = 0;
if (!this._windowClone.actor.has_pointer &&
!this.closeButton.has_pointer)
this._animateInvisible();
this.closeButton.hide();
return false;
},
@ -726,8 +664,6 @@ const WindowOverlay = new Lang.Class({
this._idleToggleCloseId = 0;
}
this.closeButton.hide();
this.border.hide();
this.title.remove_style_pseudo_class('hover');
},
_onStyleChanged: function() {
@ -737,9 +673,6 @@ const WindowOverlay = new Lang.Class({
let closeNode = this.closeButton.get_theme_node();
this.closeButton._overlap = closeNode.get_length('-shell-close-overlap');
let borderNode = this.border.get_theme_node();
this.borderSize = borderNode.get_border_width(St.Side.TOP);
this._parentActor.queue_relayout();
}
});
@ -1140,6 +1073,9 @@ const Workspace = new Lang.Class({
* ANIMATE - Indicates that we need animate changing position.
*/
positionWindows: function(flags) {
if (this.leavingOverview)
return;
this._positionWindowsFlags |= flags;
if (this._positionWindowsId > 0)
@ -1690,25 +1626,20 @@ const Workspace = new Lang.Class({
return [];
let closeButtonHeight, captionHeight;
let leftBorder, rightBorder;
if (this._windowOverlays.length) {
// All of the overlays have the same chrome sizes,
// so just pick the first one.
let overlay = this._windowOverlays[0];
[closeButtonHeight, captionHeight] = overlay.chromeHeights();
[leftBorder, rightBorder] = overlay.chromeWidths();
} else {
[closeButtonHeight, captionHeight] = [0, 0];
}
rowSpacing += captionHeight;
columnSpacing += rightBorder;
let area = { x: this._x, y: this._y, width: this._width, height: this._height };
area.y += closeButtonHeight;
area.height -= closeButtonHeight;
area.x += leftBorder;
area.width -= leftBorder;
if (!this._currentLayout)
this._currentLayout = this._computeLayout(windows, area, rowSpacing, columnSpacing, captionHeight);

View File

@ -493,6 +493,7 @@ const ThumbnailsBox = new Lang.Class({
_init: function() {
this.actor = new Shell.GenericContainer({ reactive: true,
style_class: 'workspace-thumbnails',
can_focus: true,
request_mode: Clutter.RequestMode.WIDTH_FOR_HEIGHT });
this.actor.connect('get-preferred-width', Lang.bind(this, this._getPreferredWidth));
this.actor.connect('get-preferred-height', Lang.bind(this, this._getPreferredHeight));
@ -526,6 +527,8 @@ const ThumbnailsBox = new Lang.Class({
this._dropPlaceholder = new St.Bin({ style_class: 'placeholder' });
this.actor.add_actor(this._dropPlaceholder);
this.visible = true;
this._targetScale = 0;
this._scale = 0;
this._pendingScaleUpdate = false;
@ -541,12 +544,21 @@ const ThumbnailsBox = new Lang.Class({
this.actor.connect('button-press-event', function() { return true; });
this.actor.connect('button-release-event', Lang.bind(this, this._onButtonRelease));
this.actor.connect('scroll-event',
Lang.bind(this, this._onScrollEvent));
this.actor.connect('key-release-event',
Lang.bind(this, this._onKeyRelease));
Main.overview.connect('item-drag-begin',
Main.overview.connect('showing',
Lang.bind(this, this._createThumbnails));
Main.overview.connect('hidden',
Lang.bind(this, this._destroyThumbnails));
Main.overview.connect('app-drag-begin',
Lang.bind(this, this._onDragBegin));
Main.overview.connect('item-drag-end',
Main.overview.connect('app-drag-end',
Lang.bind(this, this._onDragEnd));
Main.overview.connect('item-drag-cancelled',
Main.overview.connect('app-drag-cancelled',
Lang.bind(this, this._onDragCancelled));
Main.overview.connect('window-drag-begin',
Lang.bind(this, this._onDragBegin));
@ -719,10 +731,16 @@ const ThumbnailsBox = new Lang.Class({
}
},
show: function() {
_createThumbnails: function() {
this._switchWorkspaceNotifyId =
global.window_manager.connect('switch-workspace',
Lang.bind(this, this._activeWorkspaceChanged));
this._nWorkspacesNotifyId =
global.screen.connect('notify::n-workspaces',
Lang.bind(this, this._workspacesChanged));
this._syncStackingId =
Main.overview.connect('sync-window-stacking',
Lang.bind(this, this.syncStacking));
this._targetScale = 0;
this._scale = 0;
@ -746,17 +764,86 @@ const ThumbnailsBox = new Lang.Class({
this.addThumbnails(0, global.screen.n_workspaces);
},
hide: function() {
_destroyThumbnails: function() {
if (this._switchWorkspaceNotifyId > 0) {
global.window_manager.disconnect(this._switchWorkspaceNotifyId);
this._switchWorkspaceNotifyId = 0;
}
if (this._nWorkspacesNotifyId > 0) {
global.screen.disconnect(this._nWorkspacesNotifyId);
this._nWorkspacesNotifyId = 0;
}
if (this._syncStackingId > 0) {
Main.overview.disconnect(this._syncStackingId);
this._syncStackingId = 0;
}
for (let w = 0; w < this._thumbnails.length; w++)
this._thumbnails[w].destroy();
this._thumbnails = [];
},
_computeThumbnailsX: function() {
this._targetX = this.actor.get_x();
let rtl = (this.actor.get_text_direction() == Clutter.TextDirection.RTL);
if (rtl)
this._hiddenX = -this.actor.width;
else
this._hiddenX = this._targetX + this.actor.width;
},
show: function() {
if (this.visible)
return;
this.visible = true;
this.actor.show();
Tweener.addTween(this.actor, { translation_x: this._targetX,
transition: 'easeOutQuad',
time: SLIDE_ANIMATION_TIME
});
},
hide: function() {
if (!this.visible)
return;
this.visible = false;
Tweener.addTween(this.actor, { translation_x: this._hiddenX,
transition: 'easeOutQuad',
time: SLIDE_ANIMATION_TIME,
onComplete: Lang.bind(this, function () {
this.actor.hide();
})
});
},
_workspacesChanged: function() {
let oldNumWorkspaces = this._thumbnails.length;
let newNumWorkspaces = global.screen.n_workspaces;
let active = global.screen.get_active_workspace_index();
if (newNumWorkspaces > oldNumWorkspaces) {
this.addThumbnails(oldNumWorkspaces, newNumWorkspaces - oldNumWorkspaces);
} else {
let removedIndex;
let removedNum = oldNumWorkspaces - newNumWorkspaces;
for (let w = 0; w < oldNumWorkspaces; w++) {
let metaWorkspace = global.screen.get_workspace_by_index(w);
if (this._thumbnails[w].metaWorkspace != metaWorkspace) {
removedIndex = w;
break;
}
}
this.removeThumbnails(removedIndex, removedNum);
}
},
addThumbnails: function(start, count) {
for (let k = start; k < start + count; k++) {
let metaWorkspace = global.screen.get_workspace_by_index(k);
@ -802,7 +889,7 @@ const ThumbnailsBox = new Lang.Class({
this._queueUpdateStates();
},
syncStacking: function(stackIndices) {
syncStacking: function(actor, stackIndices) {
for (let i = 0; i < this._thumbnails.length; i++)
this._thumbnails[i].syncStacking(stackIndices);
},
@ -924,6 +1011,8 @@ const ThumbnailsBox = new Lang.Class({
onCompleteScope: this
});
});
this._computeThumbnailsX();
},
_queueUpdateStates: function() {
@ -1157,5 +1246,30 @@ const ThumbnailsBox = new Lang.Class({
},
onCompleteScope: this
});
},
_onScrollEvent: function (actor, event) {
switch (event.get_scroll_direction()) {
case Clutter.ScrollDirection.UP:
Main.wm.actionMoveWorkspace(Meta.MotionDirection.UP);
break;
case Clutter.ScrollDirection.DOWN:
Main.wm.actionMoveWorkspace(Meta.MotionDirection.DOWN);
break;
}
},
_onKeyRelease: function (actor, event) {
switch (event.get_key_symbol()) {
case Clutter.KEY_Up:
Main.wm.actionMoveWorkspace(Meta.MotionDirection.UP);
break;
case Clutter.KEY_Down:
Main.wm.actionMoveWorkspace(Meta.MotionDirection.DOWN);
break;
case Clutter.KEY_Return:
Main.overview.toggle();
break;
}
}
});

View File

@ -22,8 +22,6 @@ const MAX_WORKSPACES = 16;
const OVERRIDE_SCHEMA = 'org.gnome.shell.overrides';
const CONTROLS_POP_IN_TIME = 0.1;
const WorkspacesView = new Lang.Class({
Name: 'WorkspacesView',
@ -106,9 +104,9 @@ const WorkspacesView = new Lang.Class({
global.window_manager.connect('switch-workspace',
Lang.bind(this, this._activeWorkspaceChanged));
this._itemDragBeginId = Main.overview.connect('item-drag-begin',
this._appDragBeginId = Main.overview.connect('app-drag-begin',
Lang.bind(this, this._dragBegin));
this._itemDragEndId = Main.overview.connect('item-drag-end',
this._appDragEndId = Main.overview.connect('app-drag-end',
Lang.bind(this, this._dragEnd));
this._windowDragBeginId = Main.overview.connect('window-drag-begin',
Lang.bind(this, this._dragBegin));
@ -128,11 +126,8 @@ const WorkspacesView = new Lang.Class({
continue;
let ws = new Workspace.Workspace(null, i);
let overviewSpacing = Main.overview._spacing;
ws.setGeometry(monitors[i].x + overviewSpacing/2,
monitors[i].y + overviewSpacing/2,
monitors[i].width - overviewSpacing,
monitors[i].height - overviewSpacing);
ws.setGeometry(monitors[i].x, monitors[i].y,
monitors[i].width, monitors[i].height);
global.overlay_group.add_actor(ws.actor);
this._extraWorkspaces.push(ws);
}
@ -330,13 +325,13 @@ const WorkspacesView = new Lang.Class({
if (this._inDrag)
this._dragEnd();
if (this._itemDragBeginId > 0) {
Main.overview.disconnect(this._itemDragBeginId);
this._itemDragBeginId = 0;
if (this._appDragBeginId > 0) {
Main.overview.disconnect(this._appDragBeginId);
this._appDragBeginId = 0;
}
if (this._itemDragEndId > 0) {
Main.overview.disconnect(this._itemDragEndId);
this._itemDragEndId = 0;
if (this._appDragEndId > 0) {
Main.overview.disconnect(this._appDragEndId);
this._appDragEndId = 0;
}
if (this._windowDragBeginId > 0) {
Main.overview.disconnect(this._windowDragBeginId);
@ -463,25 +458,8 @@ const WorkspacesDisplay = new Lang.Class({
this.actor.connect('parent-set', Lang.bind(this, this._parentSet));
this.actor.set_clip_to_allocation(true);
let controls = new St.Bin({ style_class: 'workspace-controls',
request_mode: Clutter.RequestMode.WIDTH_FOR_HEIGHT,
y_align: St.Align.START,
y_fill: true });
this._controls = controls;
this.actor.add_actor(controls);
controls.reactive = true;
controls.track_hover = true;
controls.connect('notify::hover',
Lang.bind(this, this._onControlsHoverChanged));
controls.connect('scroll-event',
Lang.bind(this, this._onScrollEvent));
this._primaryIndex = Main.layoutManager.primaryIndex;
this._thumbnailsBox = new WorkspaceThumbnail.ThumbnailsBox();
controls.add_actor(this._thumbnailsBox.actor);
this._workspacesViews = null;
this._primaryScrollAdjustment = null;
@ -494,34 +472,14 @@ const WorkspacesDisplay = new Lang.Class({
this._inDrag = false;
this._cancelledDrag = false;
this._controlsInitiallyHovered = false;
this._alwaysZoomOut = false;
this._zoomOut = false;
this._zoomFraction = 0;
this._updateAlwaysZoom();
// If we stop hiding the overview on layout changes, we will need to
// update the _workspacesViews here
Main.layoutManager.connect('monitors-changed', Lang.bind(this, this._updateAlwaysZoom));
Main.xdndHandler.connect('drag-begin', Lang.bind(this, function(){
this._alwaysZoomOut = true;
}));
Main.xdndHandler.connect('drag-end', Lang.bind(this, function(){
this._alwaysZoomOut = false;
this._updateAlwaysZoom();
}));
global.screen.connect('notify::n-workspaces',
Lang.bind(this, this._workspacesChanged));
this._switchWorkspaceNotifyId = 0;
this._itemDragBeginId = 0;
this._itemDragCancelledId = 0;
this._itemDragEndId = 0;
this._appDragBeginId = 0;
this._appDragCancelledId = 0;
this._appDragEndId = 0;
this._windowDragBeginId = 0;
this._windowDragCancelledId = 0;
this._windowDragEndId = 0;
@ -541,41 +499,20 @@ const WorkspacesDisplay = new Lang.Class({
},
show: function() {
if(!this._alwaysZoomOut) {
let [mouseX, mouseY] = global.get_pointer();
let [x, y] = this._controls.get_transformed_position();
let [width, height] = this._controls.get_transformed_size();
let visibleWidth = this._controls.get_theme_node().get_length('visible-width');
let rtl = (Clutter.get_default_text_direction () == Clutter.TextDirection.RTL);
if(rtl)
x = x + width - visibleWidth;
if(mouseX > x - 0.5 && mouseX < x + visibleWidth + 0.5 &&
mouseY > y - 0.5 && mouseY < y + height + 0.5)
this._controlsInitiallyHovered = true;
}
this._zoomOut = this._alwaysZoomOut;
this._zoomFraction = this._alwaysZoomOut ? 1 : 0;
this._updateZoom();
this._controls.show();
this._thumbnailsBox.show();
this._updateSwitcherVisibility();
this._updateWorkspacesViews();
this._restackedNotifyId =
global.screen.connect('restacked',
Main.overview.connect('sync-window-stacking',
Lang.bind(this, this._onRestacked));
if (this._itemDragBeginId == 0)
this._itemDragBeginId = Main.overview.connect('item-drag-begin',
if (this._appDragBeginId == 0)
this._appDragBeginId = Main.overview.connect('app-drag-begin',
Lang.bind(this, this._dragBegin));
if (this._itemDragCancelledId == 0)
this._itemDragCancelledId = Main.overview.connect('item-drag-cancelled',
if (this._appDragCancelledId == 0)
this._appDragCancelledId = Main.overview.connect('app-drag-cancelled',
Lang.bind(this, this._dragCancelled));
if (this._itemDragEndId == 0)
this._itemDragEndId = Main.overview.connect('item-drag-end',
if (this._appDragEndId == 0)
this._appDragEndId = Main.overview.connect('app-drag-end',
Lang.bind(this, this._dragEnd));
if (this._windowDragBeginId == 0)
this._windowDragBeginId = Main.overview.connect('window-drag-begin',
@ -586,8 +523,6 @@ const WorkspacesDisplay = new Lang.Class({
if (this._windowDragEndId == 0)
this._windowDragEndId = Main.overview.connect('window-drag-end',
Lang.bind(this, this._dragEnd));
this._onRestacked();
},
zoomFromOverview: function() {
@ -597,27 +532,21 @@ const WorkspacesDisplay = new Lang.Class({
},
hide: function() {
this._controls.hide();
this._thumbnailsBox.hide();
if (!this._alwaysZoomOut)
this.zoomFraction = 0;
if (this._restackedNotifyId > 0){
global.screen.disconnect(this._restackedNotifyId);
Main.overview.disconnect(this._restackedNotifyId);
this._restackedNotifyId = 0;
}
if (this._itemDragBeginId > 0) {
Main.overview.disconnect(this._itemDragBeginId);
this._itemDragBeginId = 0;
if (this._appDragBeginId > 0) {
Main.overview.disconnect(this._appDragBeginId);
this._appDragBeginId = 0;
}
if (this._itemDragCancelledId > 0) {
Main.overview.disconnect(this._itemDragCancelledId);
this._itemDragCancelledId = 0;
if (this._appDragCancelledId > 0) {
Main.overview.disconnect(this._appDragCancelledId);
this._appDragCancelledId = 0;
}
if (this._itemDragEndId > 0) {
Main.overview.disconnect(this._itemDragEndId);
this._itemDragEndId = 0;
if (this._appDragEndId > 0) {
Main.overview.disconnect(this._appDragEndId);
this._appDragEndId = 0;
}
if (this._windowDragBeginId > 0) {
Main.overview.disconnect(this._windowDragBeginId);
@ -748,73 +677,15 @@ const WorkspacesDisplay = new Lang.Class({
return this._getPrimaryView().getActiveWorkspace().hasMaximizedWindows();
},
// zoomFraction property allows us to tween the controls sliding in and out
set zoomFraction(fraction) {
this._zoomFraction = fraction;
this.actor.queue_relayout();
},
get zoomFraction() {
return this._zoomFraction;
},
_updateAlwaysZoom: function() {
// Always show the pager if workspaces are actually used,
// e.g. there are windows on more than one
this._alwaysZoomOut = global.screen.n_workspaces > 2;
if (this._alwaysZoomOut)
return;
let monitors = Main.layoutManager.monitors;
let primary = Main.layoutManager.primaryMonitor;
/* Look for any monitor to the right of the primary, if there is
* one, we always keep zoom out, otherwise its hard to reach
* the thumbnail area without passing into the next monitor. */
for (let i = 0; i < monitors.length; i++) {
if (monitors[i].x >= primary.x + primary.width) {
this._alwaysZoomOut = true;
break;
}
}
},
_getPreferredWidth: function (actor, forHeight, alloc) {
// pass through the call in case the child needs it, but report 0x0
this._controls.get_preferred_width(forHeight);
},
_getPreferredHeight: function (actor, forWidth, alloc) {
// pass through the call in case the child needs it, but report 0x0
this._controls.get_preferred_height(forWidth);
},
_allocate: function (actor, box, flags) {
let childBox = new Clutter.ActorBox();
let totalWidth = box.x2 - box.x1;
// width of the controls
let [controlsMin, controlsNatural] = this._controls.get_preferred_width(box.y2 - box.y1);
// Amount of space on the screen we reserve for the visible control
let controlsVisible = this._controls.get_theme_node().get_length('visible-width');
let controlsReserved = controlsVisible * (1 - this._zoomFraction) + controlsNatural * this._zoomFraction;
let rtl = (Clutter.get_default_text_direction () == Clutter.TextDirection.RTL);
if (rtl) {
childBox.x2 = controlsReserved;
childBox.x1 = childBox.x2 - controlsNatural;
} else {
childBox.x1 = totalWidth - controlsReserved;
childBox.x2 = childBox.x1 + controlsNatural;
}
childBox.y1 = 0;
childBox.y2 = box.y2- box.y1;
this._controls.allocate(childBox, flags);
this._updateWorkspacesGeometry();
},
@ -854,25 +725,15 @@ const WorkspacesDisplay = new Lang.Class({
let width = fullWidth;
let height = fullHeight;
let [controlsMin, controlsNatural] = this._controls.get_preferred_width(height);
let controlsVisible = this._controls.get_theme_node().get_length('visible-width');
let [x, y] = this.actor.get_transformed_position();
let rtl = (Clutter.get_default_text_direction () == Clutter.TextDirection.RTL);
let clipWidth = width - controlsVisible;
let clipWidth = width;
let clipHeight = fullHeight;
let clipX = rtl ? x + controlsVisible : x;
let clipX = x;
let clipY = y + (fullHeight - clipHeight) / 2;
let overviewSpacing = Main.overview._spacing;
let widthAdjust = this._zoomOut ? controlsNatural : controlsVisible;
widthAdjust += overviewSpacing;
width -= widthAdjust;
if (rtl)
x += widthAdjust;
let monitors = Main.layoutManager.monitors;
let m = 0;
for (let i = 0; i < monitors.length; i++) {
@ -886,34 +747,21 @@ const WorkspacesDisplay = new Lang.Class({
monitors[i].y,
monitors[i].width,
monitors[i].height);
this._workspacesViews[m].setGeometry(monitors[i].x + overviewSpacing/2,
monitors[i].y + overviewSpacing/2,
monitors[i].width - overviewSpacing,
monitors[i].height - overviewSpacing);
this._workspacesViews[m].setGeometry(monitors[i].x,
monitors[i].y,
monitors[i].width,
monitors[i].height);
m++;
}
}
},
_onRestacked: function() {
let stack = global.get_window_actors();
let stackIndices = {};
for (let i = 0; i < stack.length; i++) {
// Use the stable sequence for an integer to use as a hash key
stackIndices[stack[i].get_meta_window().get_stable_sequence()] = i;
}
_onRestacked: function(actor, stackIndices) {
for (let i = 0; i < this._workspacesViews.length; i++)
this._workspacesViews[i].syncStacking(stackIndices);
this._thumbnailsBox.syncStacking(stackIndices);
},
_workspacesChanged: function() {
this._updateAlwaysZoom();
this._updateZoom();
if (this._workspacesViews == null)
return;
@ -938,8 +786,6 @@ const WorkspacesDisplay = new Lang.Class({
}
m++;
}
this._thumbnailsBox.addThumbnails(oldNumWorkspaces, newNumWorkspaces - oldNumWorkspaces);
} else {
// Assume workspaces are only removed sequentially
// (e.g. 2,3,4 - not 2,4,7)
@ -962,8 +808,6 @@ const WorkspacesDisplay = new Lang.Class({
lostWorkspaces[l].destroy();
}
}
this._thumbnailsBox.removeThumbnails(removedIndex, removedNum);
}
for (let i = 0; i < this._workspacesViews.length; i++)
@ -972,35 +816,6 @@ const WorkspacesDisplay = new Lang.Class({
this._updateSwitcherVisibility();
},
_updateZoom : function() {
if (Main.overview.animationInProgress)
return;
let shouldZoom = this._alwaysZoomOut || this._controls.hover;
if (shouldZoom != this._zoomOut) {
this._zoomOut = shouldZoom;
this._updateWorkspacesGeometry();
if (!this._workspacesViews)
return;
Tweener.addTween(this,
{ zoomFraction: this._zoomOut ? 1 : 0,
time: WORKSPACE_SWITCH_TIME,
transition: 'easeOutQuad' });
for (let i = 0; i < this._workspacesViews.length; i++)
this._workspacesViews[i].updateWindowPositions();
}
},
_onControlsHoverChanged: function() {
if(!this._controls.hover)
this._controlsInitiallyHovered = false;
if(!this._controlsInitiallyHovered)
this._updateZoom();
},
_dragBegin: function() {
this._inDrag = true;
this._cancelledDrag = false;
@ -1016,33 +831,11 @@ const WorkspacesDisplay = new Lang.Class({
},
_onDragMotion: function(dragEvent) {
let controlsHovered = this._controls.contains(dragEvent.targetActor);
this._controls.set_hover(controlsHovered);
return DND.DragMotionResult.CONTINUE;
},
_dragEnd: function() {
this._inDrag = false;
// We do this deferred because drag-end is emitted before dnd.js emits
// event/leave events that were suppressed during the drag. If we didn't
// defer this, we'd zoom out then immediately zoom in because of the
// enter event we received. That would normally be invisible but we
// might as well avoid it.
Meta.later_add(Meta.LaterType.BEFORE_REDRAW,
Lang.bind(this, this._updateZoom));
},
_onScrollEvent: function (actor, event) {
switch ( event.get_scroll_direction() ) {
case Clutter.ScrollDirection.UP:
Main.wm.actionMoveWorkspace(Meta.MotionDirection.UP);
break;
case Clutter.ScrollDirection.DOWN:
Main.wm.actionMoveWorkspace(Meta.MotionDirection.DOWN);
break;
}
}
});
Signals.addSignalMethods(WorkspacesDisplay.prototype);

View File

@ -1,19 +1 @@
XSLTPROC_FLAGS = \
--nonet \
--stringparam man.output.quietly 1 \
--stringparam funcsynopsis.style ansi \
--stringparam man.th.extra1.suppress 1 \
--stringparam man.authors.section.enabled 0 \
--stringparam man.copyright.section.enabled 0
.xml.1:
$(AM_V_GEN) $(XSLTPROC) $(XSLTPROC_FLAGS) http://docbook.sourceforge.net/release/xsl/current/manpages/docbook.xsl $<
man_MANS = \
gnome-shell.1
xml_files = $(man_MANS:.1=.xml)
EXTRA_DIST = $(xml_files)
DISTCLEANFILES = $(man_MANS)
dist_man_MANS = gnome-shell.1

94
man/gnome-shell.1 Normal file
View File

@ -0,0 +1,94 @@
.\" Copyright (c) 2009, Marcelo Jorge Vieira (metal) <metal@alucinados.com>
.\"
.\" This is free documentation; you can redistribute it and/or
.\" modify it under the terms of the GNU General Public License as
.\" published by the Free Software Foundation; either version 2 of
.\" the License, or (at your option) any later version.
.\"
.\" The GNU General Public License's references to "object code"
.\" and "executables" are to be interpreted as the output of any
.\" document formatting or typesetting system, including
.\" intermediate and printed output.
.\"
.\" This manual is distributed in the hope that it will be useful,
.\" but WITHOUT ANY WARRANTY; without even the implied warranty of
.\" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
.\" GNU General Public License for more details.
.\"
.\" You should have received a copy of the GNU General Public
.\" License along with this manual; if not, write to the Free
.\" Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
.\" Boston, MA 02111-1301 USA.
.TH GNOME-SHELL 1
.SH NAME
gnome-shell \- Graphical shell for the GNOME desktop
.SH SYNOPSIS
.B gnome-shell [options]
.SH DESCRIPTION
GNOME Shell provides core user interface functions for the GNOME 3
desktop, like switching to windows and launching applications. GNOME
Shell takes advantage of the capabilities of modern graphics hardware
and introduces innovative user interface concepts to provide a
visually attractive and easy to use experience.
.SH OPTIONS
.TP
.B \-\-replace
Replace the running window manager
.br
.TP
.B \-\-sm-disable
Disable connection to the session manager
.br
.TP
.B \-\-sm-client-id=ID
Specify session management ID
.br
.TP
.B \-\-sm-save-file=FILE
Initialize session from savefile
.br
.TP
.B \-\-screen=SCREEN
X screen to use
.br
.TP
.B \-d, \-\-display=DISPLAY
X display to use
.br
.TP
.B \-\-sync
Make X calls synchronous
.br
.TP
.B \-\-version
Print version and exit
.br
.TP
.B \-\-help
Display help and exit
.br
.SH BUGS
The bug tracker can be reached by visiting the website
\fIhttps://bugzilla.gnome.org/buglist.cgi?product=gnome-shell\fR
Before sending a bug report, please verify that you have the latest
version of gnome-shell. Many bugs (major and minor) are fixed at each
release, and if yours is out of date, the problem may already have
been solved.
.SH ADDITIONAL INFORMATION
For further information, visit the website \fIhttp://live.gnome.org/GnomeShell\fR

View File

@ -1,159 +0,0 @@
<?xml version='1.0'?>
<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"
"http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
<refentry id="gnome-shell">
<refentryinfo>
<title>gnome-shell</title>
<productname>gnome-shell</productname>
<authorgroup>
<author>
<contrib>wrote the original gnome-shell man page</contrib>
<firstname>Marcelo Jorge</firstname>
<surname>Vieira</surname>
<email>metal@alucinados.com</email>
</author>
</authorgroup>
</refentryinfo>
<refmeta>
<refentrytitle>gnome-shell</refentrytitle>
<manvolnum>1</manvolnum>
</refmeta>
<refnamediv>
<refname>gnome-shell</refname>
<refpurpose>Graphical shell for the GNOME desktop</refpurpose>
</refnamediv>
<refsynopsisdiv>
<cmdsynopsis>
<command>gnome-shell <arg choice="opt" rep="repeat">OPTION</arg></command>
</cmdsynopsis>
</refsynopsisdiv>
<refsect1>
<title>Description</title>
<para>GNOME shell provides core user
interface functions for the GNOME 3 desktop, like switching
to windows and launching applications. GNOME shell takes
advantage of the capabilities of modern graphics hardware
and introduces innovative user interface concepts to provide
a visually attractive and easy to use experience.</para>
<para>gnome-shell is a required component of
the GNOME desktop, i.e. it is listed in the
RequiredComponents field of
<filename>/usr/share/gnome-session/sessions/gnome.session</filename>.
It is started in the window manager phase of the session.
</para>
</refsect1>
<refsect1>
<title>Options</title>
<variablelist>
<varlistentry>
<term><option>-r</option>, <option>--replace</option></term>
<listitem><para>Replace the running window manager</para></listitem>
</varlistentry>
<varlistentry>
<term><option>--sm-disable</option></term>
<listitem><para>Disable connection to the session manager</para></listitem>
</varlistentry>
<varlistentry>
<term><option>--sm-client-id=<replaceable>ID</replaceable></option></term>
<listitem><para>Specify session management <replaceable>ID</replaceable></para></listitem>
</varlistentry>
<varlistentry>
<term><option>--sm-save-file=<replaceable>FILE</replaceable></option></term>
<listitem><para>Initialize session from <replaceable>FILE</replaceable></para></listitem>
</varlistentry>
<varlistentry>
<term><option>--screen=<replaceable>SCREEN</replaceable></option></term>
<listitem><para>X screen to use</para></listitem>
</varlistentry>
<varlistentry>
<term><option>-d</option>, <option>--display=<replaceable>DISPLAY</replaceable></option></term>
<listitem><para>X Display to use</para></listitem>
</varlistentry>
<varlistentry>
<term><option>--sync</option></term>
<listitem><para>Make X calls synchronous</para></listitem>
</varlistentry>
<varlistentry>
<term><option>--version</option></term>
<listitem><para>Print version and exit</para></listitem>
</varlistentry>
<varlistentry>
<term><option>--help</option></term>
<listitem><para>Display help and exit</para></listitem>
</varlistentry>
<varlistentry>
<term><option>--mode=<replaceable>MODE</replaceable></option></term>
<listitem><para>Use a specific mode, e.g. "gdm" for login screen</para></listitem>
</varlistentry>
<varlistentry>
<term><option>--list-modes</option></term>
<listitem><para>List possible modes and exit</para></listitem>
</varlistentry>
</variablelist>
</refsect1>
<refsect1>
<title>Files</title>
<para>
<filename>/usr/share/gnome-session/sessions/gnome.session</filename>,
<filename>/usr/share/applications/gnome-shell.desktop</filename>.</para>
</refsect1>
<refsect1>
<title>Bugs</title>
<para>The bug tracker can be reached by visiting the
website <ulink url="https://bugzilla.gnome.org/buglist.cgi?product=gnome-shell">https://bugzilla.gnome.org/buglist.cgi?product=gnome-shell</ulink>.
Before sending a bug report, please verify that you have
the latest version of gnome-shell. Many bugs (major and
minor) are fixed at each release, and if yours is out of
date, the problem may already have been solved.</para>
</refsect1>
<refsect1>
<title>Additional Information</title>
<para>For further information, visit the website
<ulink url="http://live.gnome.org/GnomeShell">http://live.gnome.org/GnomeShell</ulink>.</para>
</refsect1>
</refentry>

761
po/as.po

File diff suppressed because it is too large Load Diff

487
po/cs.po

File diff suppressed because it is too large Load Diff

194
po/de.po
View File

@ -19,9 +19,9 @@ 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-11-06 04:39+0000\n"
"PO-Revision-Date: 2012-11-06 20:04+0100\n"
"Last-Translator: Wolfgang Stoeggl <c72578@yahoo.de>\n"
"POT-Creation-Date: 2012-10-14 16:48+0000\n"
"PO-Revision-Date: 2012-10-10 23:10+0100\n"
"Last-Translator: Tobias Endrigkeit <tobiasendrigkeit@googlemail.com>\n"
"Language-Team: Deutsch <gnome-de@gnome.org>\n"
"Language: \n"
"MIME-Version: 1.0\n"
@ -148,68 +148,56 @@ msgstr ""
"Aufzählung entnommen."
#: ../data/org.gnome.shell.gschema.xml.in.in.h:13
msgid "Always show the 'Log out' menuitem in the user menu."
msgstr "Den Menüeintrag »Abmelden« immer im Benutzermenü anzeigen."
#: ../data/org.gnome.shell.gschema.xml.in.in.h:14
msgid ""
"This key overrides the automatic hiding of the 'Log out' menuitem in single-"
"user, single-session situations."
msgstr ""
"Dieser Schlüssel überschreibt das automatische Verbergen des Menüeintrags "
"»Abmelden« in Einzelbenutzer, Einzelsitzungssituationen."
#: ../data/org.gnome.shell.gschema.xml.in.in.h:15
msgid "Show the week date in the calendar"
msgstr "Wochentag im Kalender anzeigen"
#: ../data/org.gnome.shell.gschema.xml.in.in.h:16
#: ../data/org.gnome.shell.gschema.xml.in.in.h:14
msgid "If true, display the ISO week date in the calendar."
msgstr ""
"Wenn dieser Wert gesetzt ist, wird der ISO-Wochentag im Kalender angezeigt."
#: ../data/org.gnome.shell.gschema.xml.in.in.h:17
#: ../data/org.gnome.shell.gschema.xml.in.in.h:15
msgid "Keybinding to open the application menu"
msgstr "Tastenkombination zum Öffnen des Anwendungsmenüs"
#: ../data/org.gnome.shell.gschema.xml.in.in.h:18
#: ../data/org.gnome.shell.gschema.xml.in.in.h:16
msgid "Keybinding to open the application menu."
msgstr "Tastenkombination zum Öffnen des Anwendungsmenüs."
#: ../data/org.gnome.shell.gschema.xml.in.in.h:19
#: ../data/org.gnome.shell.gschema.xml.in.in.h:17
msgid "Keybinding to toggle the visibility of the message tray"
msgstr ""
"Tastenkombination zum Umschalten der Sichtbarkeit des Benachrichtigungsfeldes"
#: ../data/org.gnome.shell.gschema.xml.in.in.h:20
#: ../data/org.gnome.shell.gschema.xml.in.in.h:18
msgid "Keybinding to toggle the visibility of the message tray."
msgstr ""
"Tastenkombination zum Umschalten der Sichtbarkeit des "
"Benachrichtigungsfeldes."
#: ../data/org.gnome.shell.gschema.xml.in.in.h:21
#: ../data/org.gnome.shell.gschema.xml.in.in.h:19
msgid "Keybinding to toggle the screen recorder"
msgstr "Tastenkombination zum Umschalten des Bildschirmaufzeichners"
#: ../data/org.gnome.shell.gschema.xml.in.in.h:22
#: ../data/org.gnome.shell.gschema.xml.in.in.h:20
msgid "Keybinding to start/stop the builtin screen recorder."
msgstr ""
"Tastenkombination zum Starten/Entfernen des eingebauten "
"Bildschirmaufzeichners."
#: ../data/org.gnome.shell.gschema.xml.in.in.h:23
#: ../data/org.gnome.shell.gschema.xml.in.in.h:21
msgid "Which keyboard to use"
msgstr "Zu verwendende Tastatur"
#: ../data/org.gnome.shell.gschema.xml.in.in.h:24
#: ../data/org.gnome.shell.gschema.xml.in.in.h:22
msgid "The type of keyboard to use."
msgstr "Der Typ der zu verwendenden Tastatur"
#: ../data/org.gnome.shell.gschema.xml.in.in.h:25
#: ../data/org.gnome.shell.gschema.xml.in.in.h:23
msgid "Framerate used for recording screencasts."
msgstr "Bildwiederholungsrate zur Aufnahme von Screencasts"
#: ../data/org.gnome.shell.gschema.xml.in.in.h:26
#: ../data/org.gnome.shell.gschema.xml.in.in.h:24
msgid ""
"The framerate of the resulting screencast recordered by GNOME Shell's "
"screencast recorder in frames-per-second."
@ -218,11 +206,11 @@ msgstr ""
"der GNOME-Shell aufgezeichnet werden soll, in Einzelbildern pro Sekunde."
# hmm Enkodieren oder Kodieren?
#: ../data/org.gnome.shell.gschema.xml.in.in.h:27
#: ../data/org.gnome.shell.gschema.xml.in.in.h:25
msgid "The gstreamer pipeline used to encode the screencast"
msgstr "Die GStreamer-Weiterleitung zur Enkodierung des Screencasts"
#: ../data/org.gnome.shell.gschema.xml.in.in.h:29
#: ../data/org.gnome.shell.gschema.xml.in.in.h:27
#, no-c-format
msgid ""
"Sets the GStreamer pipeline used to encode recordings. It follows the syntax "
@ -250,11 +238,11 @@ msgstr ""
"aufzeichnet. %T wird als Platzhalter für die vermutete optimale Thread-"
"Anzahl auf dem System verwendet."
#: ../data/org.gnome.shell.gschema.xml.in.in.h:30
#: ../data/org.gnome.shell.gschema.xml.in.in.h:28
msgid "File extension used for storing the screencast"
msgstr "Die Dateiendung zum Speichern des Screencast"
#: ../data/org.gnome.shell.gschema.xml.in.in.h:31
#: ../data/org.gnome.shell.gschema.xml.in.in.h:29
msgid ""
"The filename for recorded screencasts will be a unique filename based on the "
"current date, and use this extension. It should be changed when recording to "
@ -315,8 +303,8 @@ msgstr "Anmeldefenster"
msgid "Power"
msgstr "Ausschalten"
#: ../js/gdm/powerMenu.js:89 ../js/ui/userMenu.js:664 ../js/ui/userMenu.js:668
#: ../js/ui/userMenu.js:779
#: ../js/gdm/powerMenu.js:89 ../js/ui/userMenu.js:660 ../js/ui/userMenu.js:664
#: ../js/ui/userMenu.js:775
msgid "Suspend"
msgstr "Bereitschaft"
@ -324,8 +312,8 @@ msgstr "Bereitschaft"
msgid "Restart"
msgstr "Neu starten"
#: ../js/gdm/powerMenu.js:99 ../js/ui/userMenu.js:666 ../js/ui/userMenu.js:668
#: ../js/ui/userMenu.js:778
#: ../js/gdm/powerMenu.js:99 ../js/ui/userMenu.js:662 ../js/ui/userMenu.js:664
#: ../js/ui/userMenu.js:774
msgid "Power Off"
msgstr "Ausschalten"
@ -710,35 +698,35 @@ msgstr "Stumm"
#. Translators: this is a time format string followed by a date.
#. If applicable, replace %X with a strftime format valid for your
#. locale, without seconds.
#: ../js/ui/components/telepathyClient.js:952
#: ../js/ui/components/telepathyClient.js:948
#, no-c-format
msgid "Sent at <b>%X</b> on <b>%A</b>"
msgstr "Gesendet am <b>%A</b> um <b>%X</b> "
#. Translators: this is a time format in the style of "Wednesday, May 25",
#. shown when you get a chat message in the same year.
#: ../js/ui/components/telepathyClient.js:958
#: ../js/ui/components/telepathyClient.js:954
#, no-c-format
msgid "Sent on <b>%A</b>, <b>%B %d</b>"
msgstr "Gesendet am <b>%A</b>, <b>%d. %B</b>"
#. Translators: this is a time format in the style of "Wednesday, May 25, 2012",
#. shown when you get a chat message in a different year.
#: ../js/ui/components/telepathyClient.js:963
#: ../js/ui/components/telepathyClient.js:959
#, no-c-format
msgid "Sent on <b>%A</b>, <b>%B %d</b>, %Y"
msgstr "Gesendet am <b>%A</b>, <b>%d. %B</b> %Y"
#. Translators: this is the other person changing their old IM name to their new
#. IM name.
#: ../js/ui/components/telepathyClient.js:992
#: ../js/ui/components/telepathyClient.js:988
#, c-format
msgid "%s is now known as %s"
msgstr "%s heißt jetzt %s"
#. translators: argument is a room name like
#. * room@jabber.org for example.
#: ../js/ui/components/telepathyClient.js:1092
#: ../js/ui/components/telepathyClient.js:1088
#, c-format
msgid "Invitation to %s"
msgstr "Einladung zum Betreten von %s"
@ -746,42 +734,42 @@ msgstr "Einladung zum Betreten von %s"
#. translators: first argument is the name of a contact and the second
#. * one the name of a room. "Alice is inviting you to join room@jabber.org
#. * for example.
#: ../js/ui/components/telepathyClient.js:1100
#: ../js/ui/components/telepathyClient.js:1096
#, c-format
msgid "%s is inviting you to join %s"
msgstr "%s lädt Sie ein, %s beizutreten"
#: ../js/ui/components/telepathyClient.js:1102
#: ../js/ui/components/telepathyClient.js:1181
#: ../js/ui/components/telepathyClient.js:1244
#: ../js/ui/components/telepathyClient.js:1098
#: ../js/ui/components/telepathyClient.js:1177
#: ../js/ui/components/telepathyClient.js:1240
msgid "Decline"
msgstr "Ablehnen"
#: ../js/ui/components/telepathyClient.js:1103
#: ../js/ui/components/telepathyClient.js:1182
#: ../js/ui/components/telepathyClient.js:1245
#: ../js/ui/components/telepathyClient.js:1099
#: ../js/ui/components/telepathyClient.js:1178
#: ../js/ui/components/telepathyClient.js:1241
msgid "Accept"
msgstr "Annehmen"
#. translators: argument is a contact name like Alice for example.
#: ../js/ui/components/telepathyClient.js:1133
#: ../js/ui/components/telepathyClient.js:1129
#, c-format
msgid "Video call from %s"
msgstr "Video-Anruf von %s"
#. translators: argument is a contact name like Alice for example.
#: ../js/ui/components/telepathyClient.js:1136
#: ../js/ui/components/telepathyClient.js:1132
#, c-format
msgid "Call from %s"
msgstr "Anruf von %s"
#: ../js/ui/components/telepathyClient.js:1141
#: ../js/ui/components/telepathyClient.js:1137
#: ../js/ui/status/bluetooth.js:346
msgid "Reject"
msgstr "Abweisen"
#. translators: this is a button label (verb), not a noun
#: ../js/ui/components/telepathyClient.js:1143
#: ../js/ui/components/telepathyClient.js:1139
msgid "Answer"
msgstr "Antworten"
@ -790,113 +778,113 @@ msgstr "Antworten"
#. * file name. The string will be something
#. * like: "Alice is sending you test.ogg"
#.
#: ../js/ui/components/telepathyClient.js:1175
#: ../js/ui/components/telepathyClient.js:1171
#, c-format
msgid "%s is sending you %s"
msgstr "%s sendet Ihnen %s"
#. To translators: The parameter is the contact's alias
#: ../js/ui/components/telepathyClient.js:1210
#: ../js/ui/components/telepathyClient.js:1206
#, c-format
msgid "%s would like permission to see when you are online"
msgstr "%s bittet um das Recht, Ihre Online-Verfügbarkeit sehen zu dürfen"
#: ../js/ui/components/telepathyClient.js:1302
#: ../js/ui/components/telepathyClient.js:1298
msgid "Network error"
msgstr "Netzwerkfehler"
#: ../js/ui/components/telepathyClient.js:1304
#: ../js/ui/components/telepathyClient.js:1300
msgid "Authentication failed"
msgstr "Legitimierung fehlgeschlagen"
#: ../js/ui/components/telepathyClient.js:1306
#: ../js/ui/components/telepathyClient.js:1302
msgid "Encryption error"
msgstr "Verschlüsselungsfehler"
#: ../js/ui/components/telepathyClient.js:1308
#: ../js/ui/components/telepathyClient.js:1304
msgid "Certificate not provided"
msgstr "Zertifikat wurde nicht bereitgestellt"
#: ../js/ui/components/telepathyClient.js:1310
#: ../js/ui/components/telepathyClient.js:1306
msgid "Certificate untrusted"
msgstr "Zertifikat nicht vertrauenswürdig"
#: ../js/ui/components/telepathyClient.js:1312
#: ../js/ui/components/telepathyClient.js:1308
msgid "Certificate expired"
msgstr "Zertifikat abgelaufen"
#: ../js/ui/components/telepathyClient.js:1314
#: ../js/ui/components/telepathyClient.js:1310
msgid "Certificate not activated"
msgstr "Zertifikat nicht aktiviert"
#: ../js/ui/components/telepathyClient.js:1316
#: ../js/ui/components/telepathyClient.js:1312
msgid "Certificate hostname mismatch"
msgstr "Rechnername des Zertifikats stimmt nicht überein"
#: ../js/ui/components/telepathyClient.js:1318
#: ../js/ui/components/telepathyClient.js:1314
msgid "Certificate fingerprint mismatch"
msgstr "Fingerabdruck des Zertifikats stimmt nicht überein"
#: ../js/ui/components/telepathyClient.js:1320
#: ../js/ui/components/telepathyClient.js:1316
msgid "Certificate self-signed"
msgstr "Selbstsigniertes Zertifikat"
#: ../js/ui/components/telepathyClient.js:1322
#: ../js/ui/components/telepathyClient.js:1318
msgid "Status is set to offline"
msgstr "Der Status ist auf »Abgemeldet« gesetzt"
#: ../js/ui/components/telepathyClient.js:1324
#: ../js/ui/components/telepathyClient.js:1320
msgid "Encryption is not available"
msgstr "Verschlüsselung ist nicht verfügbar"
#: ../js/ui/components/telepathyClient.js:1326
#: ../js/ui/components/telepathyClient.js:1322
msgid "Certificate is invalid"
msgstr "Zertifikat ist ungültig"
#: ../js/ui/components/telepathyClient.js:1328
#: ../js/ui/components/telepathyClient.js:1324
msgid "Connection has been refused"
msgstr "Verbindungsaufbau wurde verweigert"
#: ../js/ui/components/telepathyClient.js:1330
#: ../js/ui/components/telepathyClient.js:1326
msgid "Connection can't be established"
msgstr "Verbindung kann nicht hergestellt werden"
#: ../js/ui/components/telepathyClient.js:1332
#: ../js/ui/components/telepathyClient.js:1328
msgid "Connection has been lost"
msgstr "Verbindung wurde unterbrochen"
#: ../js/ui/components/telepathyClient.js:1334
#: ../js/ui/components/telepathyClient.js:1330
msgid "This account is already connected to the server"
msgstr "Dieses Konto ist bereits mit dem Server verbunden"
#: ../js/ui/components/telepathyClient.js:1336
#: ../js/ui/components/telepathyClient.js:1332
msgid ""
"Connection has been replaced by a new connection using the same resource"
msgstr ""
"Die Verbindung wurde durch eine neue Verbindung mit der gleichen Ressource "
"ersetzt"
#: ../js/ui/components/telepathyClient.js:1338
#: ../js/ui/components/telepathyClient.js:1334
msgid "The account already exists on the server"
msgstr "Dieses Konto ist bereits auf dem Server vorhanden"
#: ../js/ui/components/telepathyClient.js:1340
#: ../js/ui/components/telepathyClient.js:1336
msgid "Server is currently too busy to handle the connection"
msgstr ""
"Der Server ist derzeit überlastet und kann die Verbindung nicht annehmen"
#: ../js/ui/components/telepathyClient.js:1342
#: ../js/ui/components/telepathyClient.js:1338
msgid "Certificate has been revoked"
msgstr "Zertifikat wurde zurückgezogen"
#: ../js/ui/components/telepathyClient.js:1344
#: ../js/ui/components/telepathyClient.js:1340
msgid ""
"Certificate uses an insecure cipher algorithm or is cryptographically weak"
msgstr ""
"Das Zertifikat verwendet einen unsicheren Chiffrier-Algorithmus oder ist "
"kryptografisch schwach"
#: ../js/ui/components/telepathyClient.js:1346
#: ../js/ui/components/telepathyClient.js:1342
msgid ""
"The length of the server certificate, or the depth of the server certificate "
"chain, exceed the limits imposed by the cryptography library"
@ -905,26 +893,26 @@ msgstr ""
"überschreiten die durch die kryptografische Bibliothek gegebenen "
"Beschränkungen"
#: ../js/ui/components/telepathyClient.js:1348
#: ../js/ui/components/telepathyClient.js:1344
msgid "Internal error"
msgstr "Interner Fehler"
#. translators: argument is the account name, like
#. * name@jabber.org for example.
#: ../js/ui/components/telepathyClient.js:1358
#: ../js/ui/components/telepathyClient.js:1354
#, c-format
msgid "Connection to %s failed"
msgstr "Verbindung zu %s ist fehlgeschlagen"
#: ../js/ui/components/telepathyClient.js:1367
#: ../js/ui/components/telepathyClient.js:1363
msgid "Reconnect"
msgstr "Erneut verbinden"
#: ../js/ui/components/telepathyClient.js:1368
#: ../js/ui/components/telepathyClient.js:1364
msgid "Edit account"
msgstr "Konto bearbeiten"
#: ../js/ui/components/telepathyClient.js:1413
#: ../js/ui/components/telepathyClient.js:1409
msgid "Unknown reason"
msgstr "Unbekannter Grund"
@ -1107,23 +1095,23 @@ msgstr "Quelle zeigen"
msgid "Web Page"
msgstr "Webseite"
#: ../js/ui/messageTray.js:1084
#: ../js/ui/messageTray.js:1081
msgid "Open"
msgstr "Öffnen"
#: ../js/ui/messageTray.js:1091
#: ../js/ui/messageTray.js:1088
msgid "Remove"
msgstr "Entfernen"
#: ../js/ui/messageTray.js:1543
#: ../js/ui/messageTray.js:1540
msgid "Message Tray"
msgstr "Benachrichtigungsfeld"
#: ../js/ui/messageTray.js:2549
#: ../js/ui/messageTray.js:2547
msgid "System Information"
msgstr "Systeminformationen"
#: ../js/ui/notificationDaemon.js:506 ../src/shell-app.c:374
#: ../js/ui/notificationDaemon.js:506 ../src/shell-app.c:373
msgctxt "program"
msgid "Unknown"
msgstr "Unbekannt"
@ -1183,18 +1171,18 @@ msgstr "Bitte geben Sie einen Befehl ein:"
# %B - ausgeschriebener Name des Monats, abhängig von der gesetzten Umgebung
#. Translators: This is a time format for a date in
#. long format
#: ../js/ui/screenShield.js:80
#: ../js/ui/screenShield.js:79
msgid "%A, %B %d"
msgstr "%A, %d. %B"
#: ../js/ui/screenShield.js:144
#: ../js/ui/screenShield.js:143
#, c-format
msgid "%d new message"
msgid_plural "%d new messages"
msgstr[0] "%d neue Nachricht"
msgstr[1] "%d neue Nachrichten"
#: ../js/ui/screenShield.js:146
#: ../js/ui/screenShield.js:145
#, c-format
msgid "%d new notification"
msgid_plural "%d new notifications"
@ -1650,59 +1638,59 @@ msgstr "Mikrofon"
msgid "Log in as another user"
msgstr "Als anderer Benutzer anmelden"
#: ../js/ui/userMenu.js:181
#: ../js/ui/userMenu.js:180
msgid "Available"
msgstr "Verfügbar"
#: ../js/ui/userMenu.js:184
#: ../js/ui/userMenu.js:183
msgid "Busy"
msgstr "Beschäftigt"
#: ../js/ui/userMenu.js:187
#: ../js/ui/userMenu.js:186
msgid "Invisible"
msgstr "Unsichtbar"
#: ../js/ui/userMenu.js:190
#: ../js/ui/userMenu.js:189
msgid "Away"
msgstr "Abwesend"
#: ../js/ui/userMenu.js:193
#: ../js/ui/userMenu.js:192
msgid "Idle"
msgstr "Untätig"
#: ../js/ui/userMenu.js:196
#: ../js/ui/userMenu.js:195
msgid "Unavailable"
msgstr "Nicht verfügbar"
#: ../js/ui/userMenu.js:744
#: ../js/ui/userMenu.js:740
msgid "Notifications"
msgstr "Benachrichtigungen"
#: ../js/ui/userMenu.js:752
#: ../js/ui/userMenu.js:748
msgid "System Settings"
msgstr "Systemeinstellungen"
#: ../js/ui/userMenu.js:760
#: ../js/ui/userMenu.js:756
msgid "Switch User"
msgstr "Benutzer wechseln"
#: ../js/ui/userMenu.js:765
#: ../js/ui/userMenu.js:761
msgid "Log Out"
msgstr "Abmelden"
#: ../js/ui/userMenu.js:770
#: ../js/ui/userMenu.js:766
msgid "Lock"
msgstr "Sperren"
#: ../js/ui/userMenu.js:785
#: ../js/ui/userMenu.js:781
msgid "Install Updates & Restart"
msgstr "Aktualisierungen installieren und neustarten"
#: ../js/ui/userMenu.js:803
#: ../js/ui/userMenu.js:799
msgid "Your chat status will be set to busy"
msgstr "Ihr Anwesenheitsstatus wird auf »Beschäftigt« gesetzt"
#: ../js/ui/userMenu.js:804
#: ../js/ui/userMenu.js:800
msgid ""
"Notifications are now disabled, including chat messages. Your online status "
"has been adjusted to let others know that you might not see their messages."
@ -1789,7 +1777,7 @@ msgstr ""
msgid "List possible modes"
msgstr "Die möglichen Modi auflisten"
#: ../src/shell-app.c:622
#: ../src/shell-app.c:621
#, c-format
msgid "Failed to launch '%s'"
msgstr "»%s« konnte nicht gestartet werden"

158
po/et.po
View File

@ -13,8 +13,8 @@ msgstr ""
"Project-Id-Version: gnome-shell MASTER\n"
"Report-Msgid-Bugs-To: http://bugzilla.gnome.org/enter_bug.cgi?product=gnome-"
"shell&keywords=I18N+L10N&component=general\n"
"POT-Creation-Date: 2012-11-16 18:27+0000\n"
"PO-Revision-Date: 2012-11-16 20:40+0300\n"
"POT-Creation-Date: 2012-09-22 22:24+0000\n"
"PO-Revision-Date: 2012-09-23 08:48+0300\n"
"Last-Translator: Mattias Põldaru <mahfiaz@gmail.com>\n"
"Language-Team: Estonian <>\n"
"Language: et\n"
@ -37,15 +37,6 @@ msgstr "Arvuti"
msgid "Show the message tray"
msgstr "Teateala näitamine"
msgid "Focus the active notification"
msgstr "Aktiivse märguande fokuseerimine"
msgid "Show all applications"
msgstr "Kõigi rakenduste kuvamine"
msgid "Open the application menu"
msgstr "Rakenduste menüü avamine"
msgid "GNOME Shell"
msgstr "GNOME Shell"
@ -125,16 +116,6 @@ msgstr ""
"Kasutatakse kasutaja poolt viimati vahetult määratud kiirsuhtluse oleku "
"salvestamiseks. See väärtus pärineb GsmPresenceStatus nummerdusest."
msgid "Always show the 'Log out' menuitem in the user menu."
msgstr "Kasutajamenüüs näidatakse alati 'Logi välja' menüükirjet."
msgid ""
"This key overrides the automatic hiding of the 'Log out' menuitem in single-"
"user, single-session situations."
msgstr ""
"See võti keelab automaatse 'Logi välja' menüükirje peitmise, kui arvutis on "
"üks kasutaja ning avatud üks seanss."
msgid "Show the week date in the calendar"
msgstr "Kalendris näidatakse kuupäeva nädalavormingus"
@ -147,25 +128,12 @@ msgstr "Rakenduste menüü avamise kiirklahv"
msgid "Keybinding to open the application menu."
msgstr "Kiirklahv rakenduste menüü avamiseks."
msgid "Keybinding to open the \"Show Applications\" view"
msgstr "\"Rakenduste vaate\" avamise kiirklahv"
msgid ""
"Keybinding to open the \"Show Applications\" view of the Activities Overview."
msgstr "\"Rakenduste vaate\" avamise kiirklahv tegevuste ülevaates."
msgid "Keybinding to toggle the visibility of the message tray"
msgstr "Teateala nähtavuse muutmise kiirklahv"
msgid "Keybinding to toggle the visibility of the message tray."
msgstr "Kiirklahv teateala nähtavuse muutmiseks."
msgid "Keybinding to focus the active notification"
msgstr "Aktiivse teate fokuseerimise kiirklahv"
msgid "Keybinding to focus the active notification."
msgstr "Aktiivse teate fokuseerimise kiirklahv."
msgid "Keybinding to toggle the screen recorder"
msgstr "Erkaanilindistaja lülitamise kiirklahv"
@ -227,34 +195,6 @@ msgstr ""
"konteinervormingusse salvestades tuleks ka sellele vormingule vastav laiend "
"määrata."
msgid "Attach modal dialog to the parent window"
msgstr "Modaaldialoog kuulub vanemakna juurde"
msgid ""
"This key overrides the key in org.gnome.mutter when running GNOME Shell."
msgstr ""
"See võti on ülimuslik võtme org.gnome.mutter suhtes, kui kasutatakse GNOME "
"Shelli."
msgid "Arrangement of buttons on the titlebar"
msgstr "Nuppude järjekord tiitliribal"
msgid ""
"This key overrides the key in org.gnome.desktop.wm.preferences when running "
"GNOME Shell."
msgstr ""
"See võti on ülimuslik võtme org.gnome.desktop.wm.preferences suhtes, kui "
"kasutatakse GNOME Shelli."
msgid "Enable edge tiling when dropping windows on screen edges"
msgstr "Akende lohistamisel ekraani serva lubatakse serva paigutamine"
msgid "Workspaces are managed dynamically"
msgstr "Tööalasid hallatakse dünaamiliselt"
msgid "Workspaces only on primary monitor"
msgstr "Tööalad peamisel monitoril"
#, c-format
msgid "There was an error loading the preferences dialog for %s:"
msgstr "%s jaoks eelistuste dialoogi laadimisel esines viga:"
@ -285,22 +225,9 @@ msgctxt "button"
msgid "Sign In"
msgstr "Logi sisse"
msgid "Next"
msgstr "Järgmine"
#. TTLS and PEAP are actually much more complicated, but this complication
#. is not visible here since we only care about phase2 authentication
#. (and don't even care of which one)
msgid "Username: "
msgstr "Kasutajanimi: "
msgid "Login Window"
msgstr "Sisselogimisaken"
#. Translators: accessible name of the power menu in the login screen
msgid "Power"
msgstr "Vool"
msgid "Suspend"
msgstr "Uinak"
@ -510,6 +437,12 @@ msgstr "Parool: "
msgid "Key: "
msgstr "Võti: "
#. TTLS and PEAP are actually much more complicated, but this complication
#. is not visible here since we only care about phase2 authentication
#. (and don't even care of which one)
msgid "Username: "
msgstr "Kasutajanimi: "
msgid "Identity: "
msgstr "Identiteet: "
@ -600,27 +533,24 @@ msgstr "Heli peale"
msgid "Mute"
msgstr "Heli maha"
#. Translators: this is a time format string followed by the word "Yesterday". i.e. "14:30 on Yesterday"
#. Translators: this is a time format string followed by a date.
#. If applicable, replace %X with a strftime format valid for your
#. locale, without seconds.
#, no-c-format
msgid "<b>%H:%M</b> on Yesterday"
msgstr "Eile <b>%H:%M</b>"
msgid "Sent at <b>%X</b> on <b>%A</b>"
msgstr "Saadetud: <b>%A</b>, <b>%X</b>"
#. Translators: this is a time format string followed by a week day name. i.e. "14:30 on Monday
#. Translators: this is a time format in the style of "Wednesday, May 25",
#. shown when you get a chat message in the same year.
#, no-c-format
msgid "<b>%H:%M</b> on <b>%A</b>"
msgstr "<b>%H:%M</b>, <b>%A</b>"
msgid "Sent on <b>%A</b>, <b>%B %d</b>"
msgstr "Saadeti <b>%A</b>, <b>%B %d</b>"
#. Translators: this is a time format in the style of "14:30 on Wednesday, May 25",
#. shown when you get a chat message in the same year
#. Translators: this is a time format in the style of "Wednesday, May 25, 2012",
#. shown when you get a chat message in a different year.
#, no-c-format
msgid "<b>%H:%M</b> on <b>%A</b>, <b>%B</b> <b>%d</b>"
msgstr "<b>%H:%M</b>, <b>%A</b>, <b>%d. %B</b>"
#. Translators: this is a time format in the style of "14:30 on Wednesday, May 25, 2012",
#. shown when you get a chat message in a different year
#, no-c-format
msgid "<b>%H:%M</b> on <b>%A</b>, <b>%B</b> <b>%d</b>, %Y"
msgstr "<b>%H:%M</b>, <b>%A</b>, <b>%d. %B</b> %Y"
msgid "Sent on <b>%A</b>, <b>%B %d</b>, %Y"
msgstr "Saadeti <b>%A</b>, <b>%B %d</b>, %Y"
#. Translators: this is the other person changing their old IM name to their new
#. IM name.
@ -657,6 +587,9 @@ msgstr "%s tahab alustada videokõnet"
msgid "Call from %s"
msgstr "%s helistab"
msgid "Reject"
msgstr "Lükka tagasi"
#. translators: this is a button label (verb), not a noun
msgid "Answer"
msgstr "Vasta"
@ -964,11 +897,8 @@ msgstr "Ülemine riba"
msgid "toggle-switch-us"
msgstr "toggle-switch-intl"
msgid "Enter a Command"
msgstr "Palun sisesta käsk"
msgid "Close"
msgstr "Sulge"
msgid "Please enter a command:"
msgstr "Palun sisesta käsk:"
#. Translators: This is a time format for a date in
#. long format
@ -1081,6 +1011,16 @@ msgstr "ühendumine..."
msgid "Send Files..."
msgstr "Failide saatmine..."
msgid "Browse Files..."
msgstr "Failide sirvimine..."
msgid "Error browsing device"
msgstr "Viga seadme sirvimisel"
#, c-format
msgid "The requested device cannot be browsed, error is '%s'"
msgstr "Küsitud seadet pole võimalik sirvida, viga on '%s'"
msgid "Keyboard Settings"
msgstr "Klaviatuurisätted"
@ -1104,9 +1044,6 @@ msgstr "Luba alati"
msgid "Grant this time only"
msgstr "Luba ainult seekord"
msgid "Reject"
msgstr "Lükka tagasi"
#, c-format
msgid "Pairing confirmation for %s"
msgstr "Paardumise kinnitus seadmele %s"
@ -1217,6 +1154,9 @@ msgstr "Juhtmeta"
msgid "Mobile broadband"
msgstr "Mobiiliühendus"
msgid "VPN Connections"
msgstr "VPN-ühendused"
msgid "Network Settings"
msgstr "Võrgusätted"
@ -1334,17 +1274,20 @@ msgstr "Eemal"
msgid "Idle"
msgstr "Jõude"
msgid "Offline"
msgstr "Ühendamata"
msgid "Unavailable"
msgstr "Pole saadaval"
msgid "Switch User"
msgstr "Vaheta kasutajat"
msgid "Switch Session"
msgstr "Vaheta seanssi"
msgid "Notifications"
msgstr "Märguanded"
msgid "Settings"
msgstr "Sätted"
msgid "Switch User"
msgstr "Vaheta kasutajat"
msgid "System Settings"
msgstr "Süsteemi sätted"
msgid "Log Out"
msgstr "Logi välja"
@ -1461,6 +1404,9 @@ msgstr "Kasutaja katkestas autentimisdialoogi"
#~ msgid "If true, display date in the clock, in addition to time."
#~ msgstr "Kui määratud, siis kuvatakse kellaaja kõrval ka kuupäeva."
#~ msgid "Offline"
#~ msgstr "Ühendamata"
#~ msgid "CONTACTS"
#~ msgstr "KONTAKTID"

551
po/gl.po

File diff suppressed because it is too large Load Diff

819
po/he.po

File diff suppressed because it is too large Load Diff

111
po/ml.po
View File

@ -11,15 +11,15 @@ msgstr ""
"Report-Msgid-Bugs-To: http://bugzilla.gnome.org/enter_bug."
"cgi?product=gnome-shell&keywords=I18N+L10N&component=general\n"
"POT-Creation-Date: 2012-09-20 16:11+0000\n"
"PO-Revision-Date: 2012-11-26 15:02+0530\n"
"Last-Translator: Ani Peter <peter.ani@gmail.com>\n"
"PO-Revision-Date: 2012-09-20 22:56+0000\n"
"Last-Translator: Ani Peter <apeter@redhat.com>\n"
"Language-Team: Malayalam <discuss@lists.smc.org.in>\n"
"Language: ml\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
"X-Generator: Lokalize 1.5\n"
"X-Generator: Lokalize 1.0\n"
"X-DamnedLies-Scope: partial\n"
#: ../data/50-gnome-shell-screenshot.xml.in.h:1
@ -61,8 +61,7 @@ msgstr "ഗ്നോം ഷെല്‍ എക്സ്റ്റെന്‍ഷ
#: ../data/org.gnome.shell.gschema.xml.in.in.h:1
msgid "Enable internal tools useful for developers and testers from Alt-F2"
msgstr ""
"Alt-F2-ല്‍ ഡവലപ്പര്‍മാര്‍ക്കും ടെസ്റ്റേര്‍സിനും പ്രയോജനകരമായ ആന്തരിക "
"പ്രയോഗങ്ങള്‍ പ്രവര്‍ത്തന "
"Alt-F2-ല്‍ ഡവലപ്പര്‍മാര്‍ക്കും ടെസ്റ്റേര്‍സിനും പ്രയോജനകരമായ ആന്തരിക പ്രയോഗങ്ങള്‍ പ്രവര്‍ത്തന "
"സജ്ജമാക്കുന്നു"
#: ../data/org.gnome.shell.gschema.xml.in.in.h:2
@ -70,8 +69,7 @@ msgid ""
"Allows access to internal debugging and monitoring tools using the Alt-F2 "
"dialog."
msgstr ""
"Alt-F2 ഡയലോഗ് ഉപയോഗിച്ചു് ആന്തരിക ഡീബഗ്ഗിലേക്കും നീരീക്ഷണ പ്രയോഗങ്ങളിലേക്കും "
"പ്രവേശനം "
"Alt-F2 ഡയലോഗ് ഉപയോഗിച്ചു് ആന്തരിക ഡീബഗ്ഗിലേക്കും നീരീക്ഷണ പ്രയോഗങ്ങളിലേക്കും പ്രവേശനം "
"അനുവദിയ്ക്കുക."
#: ../data/org.gnome.shell.gschema.xml.in.in.h:3
@ -85,19 +83,14 @@ msgid ""
"list. You can also manipulate this list with the EnableExtension and "
"DisableExtension DBus methods on org.gnome.Shell."
msgstr ""
"ഗ്നോം ഷെല്‍ എക്സ്റ്റെന്‍ഷനുകള്‍ക്കു് ഒരു യുയുഐഡി വിശേഷതയുണ്ടു്; ലഭ്യമാക്കേണ്ട "
"എക്സ്റ്റെന്‍ഷനുകള്‍ ഈ കീ പട്ടിക "
"ലഭ്യമാക്കുന്നു. ലഭ്യമാക്കേണ്ട ഏതു് എക്സ്റ്റെന്‍ഷനും ഈ പട്ടികയിലുണ്ടാവണം. "
"org.gnome.Shell-ല്‍ "
"നിങ്ങള്‍ക്കു് EnableExtension, DisableExtension എന്നീ ഡീബസ് രീതികളിലൂടെ ഈ "
"പട്ടിക "
"ഗ്നോം ഷെല്‍ എക്സ്റ്റെന്‍ഷനുകള്‍ക്കു് ഒരു യുയുഐഡി വിശേഷതയുണ്ടു്; ലഭ്യമാക്കേണ്ട എക്സ്റ്റെന്‍ഷനുകള്‍ ഈ കീ പട്ടിക "
"ലഭ്യമാക്കുന്നു. ലഭ്യമാക്കേണ്ട ഏതു് എക്സ്റ്റെന്‍ഷനും ഈ പട്ടികയിലുണ്ടാവണം. org.gnome.Shell-ല്‍ "
"നിങ്ങള്‍ക്കു് EnableExtension, DisableExtension എന്നീ ഡീബസ് രീതികളിലൂടെ ഈ പട്ടിക "
"കൈകാര്യം ചെയ്യുവാനും സാധിയ്ക്കുന്നു."
#: ../data/org.gnome.shell.gschema.xml.in.in.h:5
msgid "Whether to collect stats about applications usage"
msgstr ""
"പ്രയോഗങ്ങളുടെ ഉപയോഗത്തെപ്പറ്റിയുള്ള സ്ഥിതിവിവരക്കണക്കുകള്‍ ശേഖരിയ്ക്കണമോ "
"എന്നു്"
msgstr "പ്രയോഗങ്ങളുടെ ഉപയോഗത്തെപ്പറ്റിയുള്ള സ്ഥിതിവിവരക്കണക്കുകള്‍ ശേഖരിയ്ക്കണമോ എന്നു്"
#: ../data/org.gnome.shell.gschema.xml.in.in.h:6
msgid ""
@ -106,12 +99,9 @@ msgid ""
"want to disable this for privacy reasons. Please note that doing so won't "
"remove already saved data."
msgstr ""
"ഏറ്റവും കൂടുതല്‍ തവണ ഉപയോഗിയ്ക്കുന്ന പ്രയോഗങ്ങള്‍ ലഭ്യമാക്കുന്നതിനായി ഷെല്‍ "
"സാധാരണയായി സജീവമായ "
"പ്രയോഗങ്ങളെ നിരീക്ഷിയ്ക്കുന്നു. (ഉദാഹരണത്തിനു്, ലോഞ്ചേര്‍സ്). ഈ ഡേറ്റാ "
"സ്വകാര്യമായി "
"സൂക്ഷിയ്ക്കുന്നെങ്കിലും, ചില കാരണങ്ങളാല്‍ ഇതു് പ്രവര്‍ത്തന "
"രഹിതമാക്കേണ്ടതുണ്ടു്. ഇങ്ങനെ ചെയ്യുന്നതു് "
"ഏറ്റവും കൂടുതല്‍ തവണ ഉപയോഗിയ്ക്കുന്ന പ്രയോഗങ്ങള്‍ ലഭ്യമാക്കുന്നതിനായി ഷെല്‍ സാധാരണയായി സജീവമായ "
"പ്രയോഗങ്ങളെ നിരീക്ഷിയ്ക്കുന്നു. (ഉദാഹരണത്തിനു്, ലോഞ്ചേര്‍സ്). ഈ ഡേറ്റാ സ്വകാര്യമായി "
"സൂക്ഷിയ്ക്കുന്നെങ്കിലും, ചില കാരണങ്ങളാല്‍ ഇതു് പ്രവര്‍ത്തന രഹിതമാക്കേണ്ടതുണ്ടു്. ഇങ്ങനെ ചെയ്യുന്നതു് "
"നിങ്ങള്‍ സൂക്ഷിച്ച ഡേറ്റയെ ബാധിയ്ക്കുന്നതല്ല."
#: ../data/org.gnome.shell.gschema.xml.in.in.h:7
@ -122,8 +112,7 @@ msgstr "ഇഷ്ടമുള്ള പ്രയോഗങ്ങള്‍ക്
msgid ""
"The applications corresponding to these identifiers will be displayed in the "
"favorites area."
msgstr ""
"ഈ ഐഡന്റിഫയറുകള്‍ക്കുള്ള പ്രയോഗങ്ങള്‍ ഉചിതമായ സ്ഥലങ്ങളില്‍ കാണിയ്ക്കുന്നു."
msgstr "ഈ ഐഡന്റിഫയറുകള്‍ക്കുള്ള പ്രയോഗങ്ങള്‍ ഉചിതമായ സ്ഥലങ്ങളില്‍ കാണിയ്ക്കുന്നു."
#: ../data/org.gnome.shell.gschema.xml.in.in.h:9
msgid "History for command (Alt-F2) dialog"
@ -138,8 +127,7 @@ msgid ""
"Internally used to store the last IM presence explicitly set by the user. "
"The value here is from the TpConnectionPresenceType enumeration."
msgstr ""
"ഉപയോക്താവു് സജ്ജമാക്കിയ അവസാന ഐഎം ആന്തരികമായി സൂക്ഷിയ്ക്കുന്നതിനു് "
"ഉപയോഗിയ്ക്കുന്നു. മൂല്യം "
"ഉപയോക്താവു് സജ്ജമാക്കിയ അവസാന ഐഎം ആന്തരികമായി സൂക്ഷിയ്ക്കുന്നതിനു് ഉപയോഗിയ്ക്കുന്നു. മൂല്യം "
"TpConnectionPresenceType തരത്തിലുള്ളതാകുന്നു."
#: ../data/org.gnome.shell.gschema.xml.in.in.h:12
@ -147,8 +135,7 @@ msgid ""
"Internally used to store the last session presence status for the user. The "
"value here is from the GsmPresenceStatus enumeration."
msgstr ""
"ഉപയോക്താവിനുള്ള അവസാന സെഷന്‍ അവസ്ഥ ആന്തരികമായി സൂക്ഷിയ്ക്കുന്നതിനു് "
"ഉപയോഗിയ്ക്കുന്നു. മൂല്യം "
"ഉപയോക്താവിനുള്ള അവസാന സെഷന്‍ അവസ്ഥ ആന്തരികമായി സൂക്ഷിയ്ക്കുന്നതിനു് ഉപയോഗിയ്ക്കുന്നു. മൂല്യം "
"GsmPresenceStatus തരത്തിലുള്ളതാകുന്നു."
#: ../data/org.gnome.shell.gschema.xml.in.in.h:13
@ -181,9 +168,7 @@ msgstr "സ്ക്രീന്‍ റിക്കോര്‍ഡര്‍ ട
#: ../data/org.gnome.shell.gschema.xml.in.in.h:20
msgid "Keybinding to start/stop the builtin screen recorder."
msgstr ""
"ബിള്‍ട്ടിന്‍ സ്ക്രീന്‍ റിക്കോര്‍ഡര്‍ തുടങ്ങുവാന്‍/നിര്‍ത്തുന്നതിനുള്ള "
"കീക്കൂട്ടം."
msgstr "ബിള്‍ട്ടിന്‍ സ്ക്രീന്‍ റിക്കോര്‍ഡര്‍ തുടങ്ങുവാന്‍/നിര്‍ത്തുന്നതിനുള്ള കീക്കൂട്ടം."
#: ../data/org.gnome.shell.gschema.xml.in.in.h:21
msgid "Which keyboard to use"
@ -202,8 +187,7 @@ msgid ""
"The framerate of the resulting screencast recordered by GNOME Shell's "
"screencast recorder in frames-per-second."
msgstr ""
"ഗ്നോം ഷെല്ലിന്റെ സ്ക്രീന്‍കാസ്റ്റ് റിക്കോര്‍ഡര്‍ റീക്കോര്‍ഡ് ചെയ്തിട്ടുള്ള "
"സ്ക്രീന്‍കാസ്റ്റിന്റെ "
"ഗ്നോം ഷെല്ലിന്റെ സ്ക്രീന്‍കാസ്റ്റ് റിക്കോര്‍ഡര്‍ റീക്കോര്‍ഡ് ചെയ്തിട്ടുള്ള സ്ക്രീന്‍കാസ്റ്റിന്റെ "
"ഫ്രെയിംറേറ്റ്, ഒരു സെക്കന്‍ഡില്‍ ഒരു ഫ്രെയിം."
#: ../data/org.gnome.shell.gschema.xml.in.in.h:25
@ -235,12 +219,9 @@ msgid ""
"threads=%T ! queue ! webmmux' and records to WEBM using the VP8 codec. %T is "
"used as a placeholder for a guess at the optimal thread count on the system."
msgstr ""
"റിക്കോര്‍ഡിങുകള്‍ എന്‍കോഡ് ചെയ്യുന്നതിനായി GStreamer പൈപ്പ് ലൈന്‍ "
"ഉപയോഗിയ്ക്കുന്നു. "
"gst-launch-നുള്ള സിന്റാക്സ് ഉപയോഗിയ്ക്കുന്നു. കാലിയായി സജ്ജമാക്കുമ്പോള്‍ "
"കാലിയാകുന്നു."
"ഇതു് നിലവില്‍ 'vp8enc min_quantizer=13 max_quantizer=13 cpu-used=5 "
"deadline=1000000 "
"റിക്കോര്‍ഡിങുകള്‍ എന്‍കോഡ് ചെയ്യുന്നതിനായി GStreamer പൈപ്പ് ലൈന്‍ ഉപയോഗിയ്ക്കുന്നു. "
"gst-launch-നുള്ള സിന്റാക്സ് ഉപയോഗിയ്ക്കുന്നു. കാലിയായി സജ്ജമാക്കുമ്പോള്‍ കാലിയാകുന്നു."
"ഇതു് നിലവില്‍ 'vp8enc min_quantizer=13 max_quantizer=13 cpu-used=5 deadline=1000000 "
"threads=%T ! queue ! webmmux' ആകുന്നുസ WEBM VP8 കോഡ് ഉപയോഗിച്ചു് റിക്കോര്‍ഡ് "
"ചെയ്യുന്നു."
@ -254,10 +235,8 @@ msgid ""
"current date, and use this extension. It should be changed when recording to "
"a different container format."
msgstr ""
"റിക്കോര്‍ഡ് ചെയ്ത സ്ക്രീന്‍കാസ്റ്റുകള്‍ക്കുള്ള ഫയല്‍നാമം നിലവിലുള്ള തീയതി, "
"എക്സ്റ്റെന്‍ഷന്‍ എന്നിവ "
"അനുസരിച്ചാകുന്നു. മറ്റൊരു ശൈലിയിലേക്കു് റിക്കോര്‍ഡ് ചെയ്യുമ്പോള്‍ ഇതു് "
"മാറ്റണം."
"റിക്കോര്‍ഡ് ചെയ്ത സ്ക്രീന്‍കാസ്റ്റുകള്‍ക്കുള്ള ഫയല്‍നാമം നിലവിലുള്ള തീയതി, എക്സ്റ്റെന്‍ഷന്‍ എന്നിവ "
"അനുസരിച്ചാകുന്നു. മറ്റൊരു ശൈലിയിലേക്കു് റിക്കോര്‍ഡ് ചെയ്യുമ്പോള്‍ ഇതു് മാറ്റണം."
#: ../js/extensionPrefs/main.js:124
#, c-format
@ -270,9 +249,7 @@ msgstr "എക്സ്റ്റെന്‍ഷന്‍"
#: ../js/extensionPrefs/main.js:188
msgid "Select an extension to configure using the combobox above."
msgstr ""
"മുകളിലുള്ള കോമ്പോ ബോക്സ് ഉപയോഗിച്ചു് ക്രമീകരിയ്ക്കുന്നതിനുള്ളൊരു "
"എക്സ്റ്റെന്‍ഷന്‍ തെര‍ഞ്ഞെടുക്കുക."
msgstr "മുകളിലുള്ള കോമ്പോ ബോക്സ് ഉപയോഗിച്ചു് ക്രമീകരിയ്ക്കുന്നതിനുള്ളൊരു എക്സ്റ്റെന്‍ഷന്‍ തെര‍ഞ്ഞെടുക്കുക."
#: ../js/gdm/loginDialog.js:526
msgid "Session..."
@ -601,8 +578,7 @@ msgid ""
"Passwords or encryption keys are required to access the wireless network "
"'%s'."
msgstr ""
"വയര്‍ലെസ് നെറ്റ്‌വര്‍ക്ക് '%s'-ലേക്ക് പ്രവേശിക്കുന്നതിനായി രഹസ്യവാക്കുകള്‍ "
"അല്ലെങ്കില്‍ എന്‍ക്രിപ്ഷന്‍ കീകള്‍ "
"വയര്‍ലെസ് നെറ്റ്‌വര്‍ക്ക് '%s'-ലേക്ക് പ്രവേശിക്കുന്നതിനായി രഹസ്യവാക്കുകള്‍ അല്ലെങ്കില്‍ എന്‍ക്രിപ്ഷന്‍ കീകള്‍ "
"ആവശ്യമുണ്ടു്."
#: ../js/ui/components/networkAgent.js:314
@ -788,8 +764,7 @@ msgstr "%s നിങ്ങള്‍ക്കു് %s അയച്ചിരി
#: ../js/ui/components/telepathyClient.js:1206
#, c-format
msgid "%s would like permission to see when you are online"
msgstr ""
"നിങ്ങള്‍ ഓണ്‍ലൈന്‍ ആകുമ്പോള്‍ കാണുന്നതിനുള്ള അനുമതി %s-നു് ആവശ്യമുണ്ടു്"
msgstr "നിങ്ങള്‍ ഓണ്‍ലൈന്‍ ആകുമ്പോള്‍ കാണുന്നതിനുള്ള അനുമതി %s-നു് ആവശ്യമുണ്ടു്"
#: ../js/ui/components/telepathyClient.js:1298
msgid "Network error"
@ -860,11 +835,8 @@ msgid "This account is already connected to the server"
msgstr "ഈ അക്കൌണ്ട് നിലവില്‍ സര്‍വറിലേക്കു് കണക്ട് ചെയ്തിരിയ്ക്കുന്നു"
#: ../js/ui/components/telepathyClient.js:1332
msgid ""
"Connection has been replaced by a new connection using the same resource"
msgstr ""
"അതേ ശ്രോതസ്സ് ഉപയോഗിച്ചു് ഒരു പുതിയ കണക്ഷന്‍ ഉപയോഗിച്ചു് ഈ കണക്ഷന്‍ "
"മാറ്റിസ്ഥാപിയ്ക്കുന്നു"
msgid "Connection has been replaced by a new connection using the same resource"
msgstr "അതേ ശ്രോതസ്സ് ഉപയോഗിച്ചു് ഒരു പുതിയ കണക്ഷന്‍ ഉപയോഗിച്ചു് ഈ കണക്ഷന്‍ മാറ്റിസ്ഥാപിയ്ക്കുന്നു"
#: ../js/ui/components/telepathyClient.js:1334
msgid "The account already exists on the server"
@ -879,19 +851,15 @@ msgid "Certificate has been revoked"
msgstr "സമ്മതപത്രം വീണ്ടും ആവശ്യപ്പെട്ടിരിയ്ക്കുന്നു"
#: ../js/ui/components/telepathyClient.js:1340
msgid ""
"Certificate uses an insecure cipher algorithm or is cryptographically weak"
msgstr ""
"സമ്മതപത്രം സുരക്ഷിതമല്ലാത്തൊരു സിഫര്‍ ആല്‍ഗോരിഥം ഉപയോഗിയ്ക്കുന്നു "
"അല്ലെങ്കില്‍ ഉചിതമല്ല"
msgid "Certificate uses an insecure cipher algorithm or is cryptographically weak"
msgstr "സമ്മതപത്രം സുരക്ഷിതമല്ലാത്തൊരു സിഫര്‍ ആല്‍ഗോരിഥം ഉപയോഗിയ്ക്കുന്നു അല്ലെങ്കില്‍ ഉചിതമല്ല"
#: ../js/ui/components/telepathyClient.js:1342
msgid ""
"The length of the server certificate, or the depth of the server certificate "
"chain, exceed the limits imposed by the cryptography library"
msgstr ""
"സര്‍വറിന്റെ സമ്മതപത്രത്തിന്റെ വ്യാപ്തി, അല്ലെങ്കില്‍ സര്‍വര്‍ സമ്മതപത്ര "
"ചെയിന്റെ വ്യാപ്തി, എന്നിവ "
"സര്‍വറിന്റെ സമ്മതപത്രത്തിന്റെ വ്യാപ്തി, അല്ലെങ്കില്‍ സര്‍വര്‍ സമ്മതപത്ര ചെയിന്റെ വ്യാപ്തി, എന്നിവ "
"പരിധിയില്‍ കൂടുന്നു"
#: ../js/ui/components/telepathyClient.js:1344
@ -950,8 +918,7 @@ msgstr "പുറത്ത് കടക്കുക"
#: ../js/ui/endSessionDialog.js:63
msgid "Click Log Out to quit these applications and log out of the system."
msgstr ""
"ഈ പ്രയോഗങ്ങളില്‍ നിന്നും പുറത്തു് കടക്കുന്നതിനായി പുറത്തു കടക്കുക ക്ലിക്ക് "
"ചെയ്തു് സിസ്റ്റത്തില്‍ നിന്നും "
"ഈ പ്രയോഗങ്ങളില്‍ നിന്നും പുറത്തു് കടക്കുന്നതിനായി പുറത്തു കടക്കുക ക്ലിക്ക് ചെയ്തു് സിസ്റ്റത്തില്‍ നിന്നും "
"പുറത്തു് കടക്കുക."
#: ../js/ui/endSessionDialog.js:65
@ -985,8 +952,7 @@ msgstr "നിര്‍ത്തുക"
#: ../js/ui/endSessionDialog.js:82
msgid "Click Power Off to quit these applications and power off the system."
msgstr ""
"ഈ പ്രയോഗങ്ങളില്‍ നിന്നും പുറത്തു് കടക്കുന്നതിനായി പവര്‍ ഓഫ് ചെയ്യുക ക്ലിക്ക് "
"ചെയ്തു സിസ്റ്റിന്റെ പവര്‍ "
"ഈ പ്രയോഗങ്ങളില്‍ നിന്നും പുറത്തു് കടക്കുന്നതിനായി പവര്‍ ഓഫ് ചെയ്യുക ക്ലിക്ക് ചെയ്തു സിസ്റ്റിന്റെ പവര്‍ "
"ഓഫ് ചെയ്യുക."
#: ../js/ui/endSessionDialog.js:84
@ -1017,8 +983,7 @@ msgstr "പുനരാരംഭിക്കുക"
#: ../js/ui/endSessionDialog.js:99
msgid "Click Restart to quit these applications and restart the system."
msgstr ""
"ഈ പ്രയോഗങ്ങള്‍ നിറുത്തി സിസ്റ്റം പുനരാരംഭിക്കുവാന്‍ പുനരാരംഭിക്കൂ അമര്‍ത്തുക"
msgstr "ഈ പ്രയോഗങ്ങള്‍ നിറുത്തി സിസ്റ്റം പുനരാരംഭിക്കുവാന്‍ പുനരാരംഭിക്കൂ അമര്‍ത്തുക"
#: ../js/ui/endSessionDialog.js:101
#, c-format
@ -1038,9 +1003,7 @@ msgstr "ഇന്‍സ്റ്റോള്‍"
#: ../js/ui/extensionDownloader.js:204
#, c-format
msgid "Download and install '%s' from extensions.gnome.org?"
msgstr ""
"extensions.gnome.org ഇല്‍ നിന്നും '%s' ഡൗണ്‍ലോട് ചെയ്ത് ഇന്‍സ്റ്റോള്‍ "
"ചെയ്യേണമോ?"
msgstr "extensions.gnome.org ഇല്‍ നിന്നും '%s' ഡൗണ്‍ലോട് ചെയ്ത് ഇന്‍സ്റ്റോള്‍ ചെയ്യേണമോ?"
#: ../js/ui/keyboard.js:327
msgid "tray"
@ -1697,10 +1660,8 @@ msgid ""
"Notifications are now disabled, including chat messages. Your online status "
"has been adjusted to let others know that you might not see their messages."
msgstr ""
"ചാറ്റ് സന്ദേശങ്ങള്‍ എന്ന പോലെ അറിയിപ്പുകള്‍ പ്രവര്‍ത്തന രഹിതമാക്കുന്നു. "
"മറ്റുള്ളവരുടെ ചാറ്റ് സന്ദേശങ്ങള്‍ "
"നിങ്ങള്‍ക്കു് കാണുവാന്‍ സാധ്യമല്ല എന്നു് നിങ്ങളുടെ ഓണ്‍ലൈന്‍ അവസ്ഥയില്‍ "
"വ്യക്തമാക്കുന്നു."
"ചാറ്റ് സന്ദേശങ്ങള്‍ എന്ന പോലെ അറിയിപ്പുകള്‍ പ്രവര്‍ത്തന രഹിതമാക്കുന്നു. മറ്റുള്ളവരുടെ ചാറ്റ് സന്ദേശങ്ങള്‍ "
"നിങ്ങള്‍ക്കു് കാണുവാന്‍ സാധ്യമല്ല എന്നു് നിങ്ങളുടെ ഓണ്‍ലൈന്‍ അവസ്ഥയില്‍ വ്യക്തമാക്കുന്നു."
#: ../js/ui/viewSelector.js:85
msgid "Windows"

419
po/nb.po
View File

@ -6,10 +6,10 @@
# Torstein Adolf Winterseth <kvikende@fsfe.org>, 2010.
msgid ""
msgstr ""
"Project-Id-Version: gnome-shell 3.7.x\n"
"Project-Id-Version: gnome-shell 3.5.x\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2012-11-05 19:06+0100\n"
"PO-Revision-Date: 2012-11-05 19:10+0100\n"
"POT-Creation-Date: 2012-10-11 20:24+0200\n"
"PO-Revision-Date: 2012-10-11 20:25+0200\n"
"Last-Translator: Kjartan Maraas <kmaraas@gnome.org>\n"
"Language-Team: Norwegian bokmål <i18n-nb@lister.ping.uio.no>\n"
"Language: \n"
@ -34,14 +34,6 @@ msgstr "System"
msgid "Show the message tray"
msgstr "Vis meldingstrau"
#: ../data/50-gnome-shell-system.xml.in.h:3
msgid "Show all applications"
msgstr "Vis alle programmer"
#: ../data/50-gnome-shell-system.xml.in.h:4
msgid "Open the application menu"
msgstr "Åpne programmenyen"
#: ../data/gnome-shell.desktop.in.in.h:1
msgid "GNOME Shell"
msgstr "GNOME Shell"
@ -136,71 +128,50 @@ msgid ""
msgstr ""
#: ../data/org.gnome.shell.gschema.xml.in.in.h:13
msgid "Always show the 'Log out' menuitem in the user menu."
msgstr ""
#: ../data/org.gnome.shell.gschema.xml.in.in.h:14
msgid ""
"This key overrides the automatic hiding of the 'Log out' menuitem in single-"
"user, single-session situations."
msgstr ""
#: ../data/org.gnome.shell.gschema.xml.in.in.h:15
msgid "Show the week date in the calendar"
msgstr "Vis dato for uken i kalender"
#: ../data/org.gnome.shell.gschema.xml.in.in.h:16
#: ../data/org.gnome.shell.gschema.xml.in.in.h:14
msgid "If true, display the ISO week date in the calendar."
msgstr "Viser ISO-ukedato i kalenderen hvis «true»."
#: ../data/org.gnome.shell.gschema.xml.in.in.h:17
#: ../data/org.gnome.shell.gschema.xml.in.in.h:15
msgid "Keybinding to open the application menu"
msgstr "Tastaturbinding som åpner programmenyen"
#: ../data/org.gnome.shell.gschema.xml.in.in.h:18
#: ../data/org.gnome.shell.gschema.xml.in.in.h:16
msgid "Keybinding to open the application menu."
msgstr "Tastaturbinding som åpner programmenyen."
#: ../data/org.gnome.shell.gschema.xml.in.in.h:19
#, fuzzy
msgid "Keybinding to open the \"Show Applications\" view"
msgstr "Tastaturbinding som åpner programmenyen"
#: ../data/org.gnome.shell.gschema.xml.in.in.h:20
#, fuzzy
msgid ""
"Keybinding to open the \"Show Applications\" view of the Activities Overview."
msgstr "Tastaturbinding som åpner programmenyen."
#: ../data/org.gnome.shell.gschema.xml.in.in.h:21
#: ../data/org.gnome.shell.gschema.xml.in.in.h:17
msgid "Keybinding to toggle the visibility of the message tray"
msgstr "Tastaturbinding som slår av/på synlighet for meldingstrau"
#: ../data/org.gnome.shell.gschema.xml.in.in.h:22
#: ../data/org.gnome.shell.gschema.xml.in.in.h:18
msgid "Keybinding to toggle the visibility of the message tray."
msgstr "Tastaturbinding som slår av/på synlighet for meldingstrauet."
#: ../data/org.gnome.shell.gschema.xml.in.in.h:23
#: ../data/org.gnome.shell.gschema.xml.in.in.h:19
msgid "Keybinding to toggle the screen recorder"
msgstr "Tastaturbinding som slår av/på skjermopptak"
#: ../data/org.gnome.shell.gschema.xml.in.in.h:24
#: ../data/org.gnome.shell.gschema.xml.in.in.h:20
msgid "Keybinding to start/stop the builtin screen recorder."
msgstr "Tastaturbinding som starter/stopper innebygget opptak av skjerm."
#: ../data/org.gnome.shell.gschema.xml.in.in.h:25
#: ../data/org.gnome.shell.gschema.xml.in.in.h:21
msgid "Which keyboard to use"
msgstr "Tastatur som skal brukes"
#: ../data/org.gnome.shell.gschema.xml.in.in.h:26
#: ../data/org.gnome.shell.gschema.xml.in.in.h:22
msgid "The type of keyboard to use."
msgstr "Type tastatur som skal brukes."
#: ../data/org.gnome.shell.gschema.xml.in.in.h:27
#: ../data/org.gnome.shell.gschema.xml.in.in.h:23
msgid "Framerate used for recording screencasts."
msgstr "Bildefrekvens i bruk ved lagring av skjermvideoer."
#: ../data/org.gnome.shell.gschema.xml.in.in.h:28
#: ../data/org.gnome.shell.gschema.xml.in.in.h:24
msgid ""
"The framerate of the resulting screencast recordered by GNOME Shell's "
"screencast recorder in frames-per-second."
@ -208,11 +179,11 @@ msgstr ""
"Bildefrekvensen i den ferdige skjermvideoen tatt opp med GNOME Shells "
"skjermvideoopptaker i bilder per sekund."
#: ../data/org.gnome.shell.gschema.xml.in.in.h:29
#: ../data/org.gnome.shell.gschema.xml.in.in.h:25
msgid "The gstreamer pipeline used to encode the screencast"
msgstr "Gstreamer-kommandokø brukt til å kode skjermvideoen"
#: ../data/org.gnome.shell.gschema.xml.in.in.h:31
#: ../data/org.gnome.shell.gschema.xml.in.in.h:27
#, fuzzy, no-c-format
msgid ""
"Sets the GStreamer pipeline used to encode recordings. It follows the syntax "
@ -229,11 +200,11 @@ msgstr ""
"Setter GStreamer-rør som brukes til å kode opptak. Den følger syntaksen som "
"brukes for gst-launch. Røret må ha en..."
#: ../data/org.gnome.shell.gschema.xml.in.in.h:32
#: ../data/org.gnome.shell.gschema.xml.in.in.h:28
msgid "File extension used for storing the screencast"
msgstr "Filendelse i bruk ved lagring av skjermvideo"
#: ../data/org.gnome.shell.gschema.xml.in.in.h:33
#: ../data/org.gnome.shell.gschema.xml.in.in.h:29
msgid ""
"The filename for recorded screencasts will be a unique filename based on the "
"current date, and use this extension. It should be changed when recording to "
@ -243,37 +214,6 @@ msgstr ""
"og bruke denne filendelsen. Den bør endres når du gjør opptak til et nytt "
"oppbevaringsformat."
#: ../data/org.gnome.shell.gschema.xml.in.in.h:34
msgid "Attach modal dialog to the parent window"
msgstr ""
#: ../data/org.gnome.shell.gschema.xml.in.in.h:35
msgid ""
"This key overrides the key in org.gnome.mutter when running GNOME Shell."
msgstr ""
#: ../data/org.gnome.shell.gschema.xml.in.in.h:36
msgid "Arrangement of buttons on the titlebar"
msgstr ""
#: ../data/org.gnome.shell.gschema.xml.in.in.h:37
msgid ""
"This key overrides the key in org.gnome.desktop.wm.preferences when running "
"GNOME Shell."
msgstr ""
#: ../data/org.gnome.shell.gschema.xml.in.in.h:38
msgid "Enable edge tiling when dropping windows on screen edges"
msgstr ""
#: ../data/org.gnome.shell.gschema.xml.in.in.h:39
msgid "Workspaces are managed dynamically"
msgstr ""
#: ../data/org.gnome.shell.gschema.xml.in.in.h:40
msgid "Workspaces only on primary monitor"
msgstr ""
#: ../js/extensionPrefs/main.js:124
#, c-format
msgid "There was an error loading the preferences dialog for %s:"
@ -287,11 +227,11 @@ msgstr "Utvidelse"
msgid "Select an extension to configure using the combobox above."
msgstr "Velg en utvidelse som skal konfigureres med komboboksen over."
#: ../js/gdm/loginDialog.js:560
#: ../js/gdm/loginDialog.js:529
msgid "Session..."
msgstr "Økt …"
#: ../js/gdm/loginDialog.js:704
#: ../js/gdm/loginDialog.js:677
msgctxt "title"
msgid "Sign In"
msgstr "Logg inn"
@ -299,56 +239,56 @@ msgstr "Logg inn"
#. 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:764
#: ../js/gdm/loginDialog.js:736
msgid "Not listed?"
msgstr "Ikke listet?"
#: ../js/gdm/loginDialog.js:906 ../js/ui/components/networkAgent.js:137
#: ../js/gdm/loginDialog.js:889 ../js/ui/components/networkAgent.js:137
#: ../js/ui/components/polkitAgent.js:162 ../js/ui/endSessionDialog.js:373
#: ../js/ui/extensionDownloader.js:195 ../js/ui/shellMountOperation.js:396
#: ../js/ui/status/bluetooth.js:427 ../js/ui/unlockDialog.js:171
#: ../js/ui/status/bluetooth.js:427 ../js/ui/unlockDialog.js:166
msgid "Cancel"
msgstr "Avbryt"
#: ../js/gdm/loginDialog.js:911
#: ../js/gdm/loginDialog.js:894
msgctxt "button"
msgid "Sign In"
msgstr "Logg inn"
#: ../js/gdm/loginDialog.js:1237
#: ../js/gdm/loginDialog.js:1215
msgid "Login Window"
msgstr "Innloggingsvindu"
#. Translators: accessible name of the power menu in the login screen
#: ../js/gdm/powerMenu.js:36
#: ../js/gdm/powerMenu.js:35
msgid "Power"
msgstr "Strøm"
#: ../js/gdm/powerMenu.js:93 ../js/ui/userMenu.js:667 ../js/ui/userMenu.js:671
#: ../js/ui/userMenu.js:782
#: ../js/gdm/powerMenu.js:89 ../js/ui/userMenu.js:660 ../js/ui/userMenu.js:664
#: ../js/ui/userMenu.js:775
msgid "Suspend"
msgstr "Hvilemodus"
#: ../js/gdm/powerMenu.js:98
#: ../js/gdm/powerMenu.js:94
msgid "Restart"
msgstr "Start på nytt"
#: ../js/gdm/powerMenu.js:103 ../js/ui/userMenu.js:669
#: ../js/ui/userMenu.js:671 ../js/ui/userMenu.js:781
#: ../js/gdm/powerMenu.js:99 ../js/ui/userMenu.js:662 ../js/ui/userMenu.js:664
#: ../js/ui/userMenu.js:774
msgid "Power Off"
msgstr "Slå av"
#: ../js/gdm/util.js:151
#: ../js/gdm/util.js:148
msgid "Authentication error"
msgstr "Autentiseringsfeil"
#. Translators: this message is shown below the password entry field
#. to indicate the user can swipe their finger instead
#: ../js/gdm/util.js:268
#: ../js/gdm/util.js:265
msgid "(or swipe finger)"
msgstr "(eller dra finger)"
#: ../js/gdm/util.js:293
#: ../js/gdm/util.js:290
#, c-format
msgid "(e.g., user or %s)"
msgstr "(f.eks. bruker eller %s)"
@ -398,7 +338,7 @@ msgstr "Legg til i favoritter"
msgid "%s has been added to your favorites."
msgstr "%s ble lagt til i dine favoritter."
#: ../js/ui/appFavorites.js:121
#: ../js/ui/appFavorites.js:118
#, c-format
msgid "%s has been removed from your favorites."
msgstr "%s ble fjernet fra dine favoritter."
@ -517,48 +457,48 @@ msgid "S"
msgstr "Lø"
#. Translators: Text to show if there are no events
#: ../js/ui/calendar.js:700
#: ../js/ui/calendar.js:699
msgid "Nothing Scheduled"
msgstr "Ingenting planlagt"
#. Translators: Shown on calendar heading when selected day occurs on current year
#: ../js/ui/calendar.js:716
#: ../js/ui/calendar.js:715
msgctxt "calendar heading"
msgid "%A, %B %d"
msgstr "%A %B %d"
#. Translators: Shown on calendar heading when selected day occurs on different year
#: ../js/ui/calendar.js:719
#: ../js/ui/calendar.js:718
msgctxt "calendar heading"
msgid "%A, %B %d, %Y"
msgstr "%A %B %d, %Y"
#: ../js/ui/calendar.js:729
#: ../js/ui/calendar.js:728
msgid "Today"
msgstr "I dag"
#: ../js/ui/calendar.js:733
#: ../js/ui/calendar.js:732
msgid "Tomorrow"
msgstr "I morgen"
#: ../js/ui/calendar.js:744
#: ../js/ui/calendar.js:743
msgid "This week"
msgstr "Denne uken"
#: ../js/ui/calendar.js:752
#: ../js/ui/calendar.js:751
msgid "Next week"
msgstr "Neste uke"
#: ../js/ui/components/autorunManager.js:295
#: ../js/ui/components/autorunManager.js:297
msgid "Removable Devices"
msgstr "Avtagbare enheter"
#: ../js/ui/components/autorunManager.js:591
#: ../js/ui/components/autorunManager.js:594
#, c-format
msgid "Open with %s"
msgstr "Åpne med %s"
#: ../js/ui/components/autorunManager.js:617
#: ../js/ui/components/autorunManager.js:620
msgid "Eject"
msgstr "Løs ut"
@ -712,42 +652,38 @@ msgstr "Fjern demping"
msgid "Mute"
msgstr "Demp"
#. Translators: this is a time format string followed by the word "Yesterday". i.e. "14:30 on Yesterday"
#: ../js/ui/components/telepathyClient.js:945
#. Translators: this is a time format string followed by a date.
#. If applicable, replace %X with a strftime format valid for your
#. locale, without seconds.
#: ../js/ui/components/telepathyClient.js:948
#, no-c-format
msgid "<b>%H:%M</b> on Yesterday"
msgstr "<b>%H.%M</b> i går"
msgid "Sent at <b>%X</b> on <b>%A</b>"
msgstr "Sendt <b>%X</b> på <b>%A</b>"
#. Translators: this is a time format string followed by a week day name. i.e. "14:30 on Monday
#: ../js/ui/components/telepathyClient.js:951
#. Translators: this is a time format in the style of "Wednesday, May 25",
#. shown when you get a chat message in the same year.
#: ../js/ui/components/telepathyClient.js:954
#, no-c-format
msgid "<b>%H:%M</b> on <b>%A</b>"
msgstr "<b>%H.%M</b> <b>%A</b>"
msgid "Sent on <b>%A</b>, <b>%B %d</b>"
msgstr "Sendt <b>%A</b>, <b>%B %d</b>"
#. Translators: this is a time format in the style of "14:30 on Wednesday, May 25",
#. shown when you get a chat message in the same year
#: ../js/ui/components/telepathyClient.js:957
#. Translators: this is a time format in the style of "Wednesday, May 25, 2012",
#. shown when you get a chat message in a different year.
#: ../js/ui/components/telepathyClient.js:959
#, no-c-format
msgid "<b>%H:%M</b> on <b>%A</b>, <b>%B</b> <b>%d</b>"
msgstr "<b>%H.%M</b>, <b>%A</b>, <b>%B</b> <b>%d</b>"
#. Translators: this is a time format in the style of "14:30 on Wednesday, May 25, 2012",
#. shown when you get a chat message in a different year
#: ../js/ui/components/telepathyClient.js:962
#, no-c-format
msgid "<b>%H:%M</b> on <b>%A</b>, <b>%B</b> <b>%d</b>, %Y"
msgstr "<b>%H.%M</b>, <b>%A</b>, <b>%B</b> <b>%d</b>, %Y"
msgid "Sent on <b>%A</b>, <b>%B %d</b>, %Y"
msgstr "Sendt <b>%A</b>, <b>%B %d</b>, %Y"
#. Translators: this is the other person changing their old IM name to their new
#. IM name.
#: ../js/ui/components/telepathyClient.js:990
#: ../js/ui/components/telepathyClient.js:988
#, c-format
msgid "%s is now known as %s"
msgstr "%s er nå kjent som %s"
#. translators: argument is a room name like
#. * room@jabber.org for example.
#: ../js/ui/components/telepathyClient.js:1089
#: ../js/ui/components/telepathyClient.js:1088
#, c-format
msgid "Invitation to %s"
msgstr "Invitasjon til %s"
@ -755,42 +691,42 @@ msgstr "Invitasjon til %s"
#. translators: first argument is the name of a contact and the second
#. * one the name of a room. "Alice is inviting you to join room@jabber.org
#. * for example.
#: ../js/ui/components/telepathyClient.js:1097
#: ../js/ui/components/telepathyClient.js:1096
#, c-format
msgid "%s is inviting you to join %s"
msgstr "%s inviterer deg til å bli med i %s"
#: ../js/ui/components/telepathyClient.js:1099
#: ../js/ui/components/telepathyClient.js:1178
#: ../js/ui/components/telepathyClient.js:1241
#: ../js/ui/components/telepathyClient.js:1098
#: ../js/ui/components/telepathyClient.js:1177
#: ../js/ui/components/telepathyClient.js:1240
msgid "Decline"
msgstr "Avslå"
#: ../js/ui/components/telepathyClient.js:1100
#: ../js/ui/components/telepathyClient.js:1179
#: ../js/ui/components/telepathyClient.js:1242
#: ../js/ui/components/telepathyClient.js:1099
#: ../js/ui/components/telepathyClient.js:1178
#: ../js/ui/components/telepathyClient.js:1241
msgid "Accept"
msgstr "Godta"
#. translators: argument is a contact name like Alice for example.
#: ../js/ui/components/telepathyClient.js:1130
#: ../js/ui/components/telepathyClient.js:1129
#, c-format
msgid "Video call from %s"
msgstr "Videosamtale fra %s"
#. translators: argument is a contact name like Alice for example.
#: ../js/ui/components/telepathyClient.js:1133
#: ../js/ui/components/telepathyClient.js:1132
#, c-format
msgid "Call from %s"
msgstr "Samtale fra %s"
#: ../js/ui/components/telepathyClient.js:1138
#: ../js/ui/components/telepathyClient.js:1137
#: ../js/ui/status/bluetooth.js:346
msgid "Reject"
msgstr "Avvis"
#. translators: this is a button label (verb), not a noun
#: ../js/ui/components/telepathyClient.js:1140
#: ../js/ui/components/telepathyClient.js:1139
msgid "Answer"
msgstr "Svar"
@ -799,110 +735,110 @@ msgstr "Svar"
#. * file name. The string will be something
#. * like: "Alice is sending you test.ogg"
#.
#: ../js/ui/components/telepathyClient.js:1172
#: ../js/ui/components/telepathyClient.js:1171
#, c-format
msgid "%s is sending you %s"
msgstr "%s sender deg %s"
#. To translators: The parameter is the contact's alias
#: ../js/ui/components/telepathyClient.js:1207
#: ../js/ui/components/telepathyClient.js:1206
#, c-format
msgid "%s would like permission to see when you are online"
msgstr "%s vil ha rettigheter til å se når du er tilkoblet"
#: ../js/ui/components/telepathyClient.js:1299
#: ../js/ui/components/telepathyClient.js:1298
msgid "Network error"
msgstr "Nettverksfeil"
#: ../js/ui/components/telepathyClient.js:1301
#: ../js/ui/components/telepathyClient.js:1300
msgid "Authentication failed"
msgstr "Autentisering feilet"
#: ../js/ui/components/telepathyClient.js:1303
#: ../js/ui/components/telepathyClient.js:1302
msgid "Encryption error"
msgstr "Feil ved kryptering"
#: ../js/ui/components/telepathyClient.js:1305
#: ../js/ui/components/telepathyClient.js:1304
msgid "Certificate not provided"
msgstr "Sertifikat ikke oppgitt"
#: ../js/ui/components/telepathyClient.js:1307
#: ../js/ui/components/telepathyClient.js:1306
msgid "Certificate untrusted"
msgstr "Stoler ikke på sertifikatet"
#: ../js/ui/components/telepathyClient.js:1309
#: ../js/ui/components/telepathyClient.js:1308
msgid "Certificate expired"
msgstr "Sertifikatet er utløpt"
#: ../js/ui/components/telepathyClient.js:1311
#: ../js/ui/components/telepathyClient.js:1310
msgid "Certificate not activated"
msgstr "Sertifikatet er ikke aktivert"
#: ../js/ui/components/telepathyClient.js:1313
#: ../js/ui/components/telepathyClient.js:1312
msgid "Certificate hostname mismatch"
msgstr "Feil vertsnavn for sertifikat"
#: ../js/ui/components/telepathyClient.js:1315
#: ../js/ui/components/telepathyClient.js:1314
msgid "Certificate fingerprint mismatch"
msgstr "Feil fingeravtrykk for sertifikat"
#: ../js/ui/components/telepathyClient.js:1317
#: ../js/ui/components/telepathyClient.js:1316
msgid "Certificate self-signed"
msgstr "Sertifikatet er selvsignert"
#: ../js/ui/components/telepathyClient.js:1319
#: ../js/ui/components/telepathyClient.js:1318
msgid "Status is set to offline"
msgstr "Status er satt til frakoblet"
#: ../js/ui/components/telepathyClient.js:1321
#: ../js/ui/components/telepathyClient.js:1320
msgid "Encryption is not available"
msgstr "Kryptering er ikke tilgjengelig"
#: ../js/ui/components/telepathyClient.js:1323
#: ../js/ui/components/telepathyClient.js:1322
msgid "Certificate is invalid"
msgstr "Sertifikatet er ugyldig"
#: ../js/ui/components/telepathyClient.js:1325
#: ../js/ui/components/telepathyClient.js:1324
msgid "Connection has been refused"
msgstr "Tilkobling ble nektet"
#: ../js/ui/components/telepathyClient.js:1327
#: ../js/ui/components/telepathyClient.js:1326
msgid "Connection can't be established"
msgstr "Tilkobling kan ikke etableres"
#: ../js/ui/components/telepathyClient.js:1329
#: ../js/ui/components/telepathyClient.js:1328
msgid "Connection has been lost"
msgstr "Tilkobling tapt"
#: ../js/ui/components/telepathyClient.js:1331
#: ../js/ui/components/telepathyClient.js:1330
msgid "This account is already connected to the server"
msgstr "Denne kontoen er allerede koblet til tjeneren"
#: ../js/ui/components/telepathyClient.js:1333
#: ../js/ui/components/telepathyClient.js:1332
msgid ""
"Connection has been replaced by a new connection using the same resource"
msgstr ""
"Tilkoblingen har blitt erstattet av en ny tilkobling som bruker samme ressurs"
#: ../js/ui/components/telepathyClient.js:1335
#: ../js/ui/components/telepathyClient.js:1334
msgid "The account already exists on the server"
msgstr "Kontoen eksisterer allerede på tjeneren"
#: ../js/ui/components/telepathyClient.js:1337
#: ../js/ui/components/telepathyClient.js:1336
msgid "Server is currently too busy to handle the connection"
msgstr "Tjener er for opptatt til å håndtere tilkoblingen"
#: ../js/ui/components/telepathyClient.js:1339
#: ../js/ui/components/telepathyClient.js:1338
msgid "Certificate has been revoked"
msgstr "Sertifikatet er tilbaketrukket"
#: ../js/ui/components/telepathyClient.js:1341
#: ../js/ui/components/telepathyClient.js:1340
msgid ""
"Certificate uses an insecure cipher algorithm or is cryptographically weak"
msgstr ""
"Sertifikatet bruker en usikker sifferalgoritme eller er krytografisk svakt"
#: ../js/ui/components/telepathyClient.js:1343
#: ../js/ui/components/telepathyClient.js:1342
msgid ""
"The length of the server certificate, or the depth of the server certificate "
"chain, exceed the limits imposed by the cryptography library"
@ -910,26 +846,26 @@ msgstr ""
"Lengden eller dybden på tjenersertifikatet oversteg grensen som er satt i "
"kryptografibiblioteket"
#: ../js/ui/components/telepathyClient.js:1345
#: ../js/ui/components/telepathyClient.js:1344
msgid "Internal error"
msgstr "Intern feil"
#. translators: argument is the account name, like
#. * name@jabber.org for example.
#: ../js/ui/components/telepathyClient.js:1355
#: ../js/ui/components/telepathyClient.js:1354
#, c-format
msgid "Connection to %s failed"
msgstr "Tilkobling til %s feilet"
#: ../js/ui/components/telepathyClient.js:1364
#: ../js/ui/components/telepathyClient.js:1363
msgid "Reconnect"
msgstr "Koble til på nytt"
#: ../js/ui/components/telepathyClient.js:1365
#: ../js/ui/components/telepathyClient.js:1364
msgid "Edit account"
msgstr "Rediger konto"
#: ../js/ui/components/telepathyClient.js:1410
#: ../js/ui/components/telepathyClient.js:1409
msgid "Unknown reason"
msgstr "Ukjent årsak"
@ -948,7 +884,7 @@ msgstr "Åpne kalender"
#. Translators: This is the date format to use when the calendar popup is
#. * shown - it is shown just below the time in the shell (e.g. "Tue 9:29 AM").
#.
#: ../js/ui/dateMenu.js:201
#: ../js/ui/dateMenu.js:190
msgid "%A %B %e, %Y"
msgstr "%a %e %B, %Y"
@ -1053,11 +989,11 @@ msgstr "Installer"
msgid "Download and install '%s' from extensions.gnome.org?"
msgstr "Last ned og installer «%s» fra extensions.gnome.org?"
#: ../js/ui/keyboard.js:308
#: ../js/ui/keyboard.js:337
msgid "tray"
msgstr "varslingsområde"
#: ../js/ui/keyboard.js:555 ../js/ui/status/keyboard.js:195
#: ../js/ui/keyboard.js:584 ../js/ui/status/keyboard.js:195
#: ../js/ui/status/power.js:205
msgid "Keyboard"
msgstr "Tastatur"
@ -1110,32 +1046,32 @@ msgstr "Vis kildekode"
msgid "Web Page"
msgstr "Nettside"
#: ../js/ui/messageTray.js:1088
#: ../js/ui/messageTray.js:1081
msgid "Open"
msgstr "Åpne"
#: ../js/ui/messageTray.js:1095
#: ../js/ui/messageTray.js:1088
msgid "Remove"
msgstr "Fjern"
#: ../js/ui/messageTray.js:1539
#: ../js/ui/messageTray.js:1540
msgid "Message Tray"
msgstr "Meldingstrau"
#: ../js/ui/messageTray.js:2563
#: ../js/ui/messageTray.js:2547
msgid "System Information"
msgstr "Systeminformasjon"
#: ../js/ui/notificationDaemon.js:504 ../src/shell-app.c:374
#: ../js/ui/notificationDaemon.js:506 ../src/shell-app.c:373
msgctxt "program"
msgid "Unknown"
msgstr "Ukjent"
#: ../js/ui/overview.js:89
#: ../js/ui/overview.js:82
msgid "Undo"
msgstr "Angre"
#: ../js/ui/overview.js:133
#: ../js/ui/overview.js:127
msgid "Overview"
msgstr "Oversikt"
@ -1143,27 +1079,27 @@ msgstr "Oversikt"
#. in the search entry when no search is
#. active; it should not exceed ~30
#. characters.
#: ../js/ui/overview.js:207
#: ../js/ui/overview.js:201
msgid "Type to search..."
msgstr "Skriv for å søke …"
#. Translators: this is the name of the dock/favorites area on
#. the left of the overview
#: ../js/ui/overview.js:228
#: ../js/ui/overview.js:222
msgid "Dash"
msgstr "Favoritter"
#: ../js/ui/panel.js:581
#: ../js/ui/panel.js:567
msgid "Quit"
msgstr "Avslutt"
#. Translators: If there is no suitable word for "Activities"
#. in your language, you can use the word for "Overview".
#: ../js/ui/panel.js:613
#: ../js/ui/panel.js:599
msgid "Activities"
msgstr "Aktiviteter"
#: ../js/ui/panel.js:980
#: ../js/ui/panel.js:965
msgid "Top Bar"
msgstr "Topp-panel"
@ -1177,27 +1113,23 @@ msgid "toggle-switch-us"
msgstr "toggle-switch-intl"
#: ../js/ui/runDialog.js:205
msgid "Enter a Command"
msgstr "Oppgi en kommando"
#: ../js/ui/runDialog.js:241
msgid "Close"
msgstr "Lukk"
msgid "Please enter a command:"
msgstr "Oppgi en kommando:"
#. Translators: This is a time format for a date in
#. long format
#: ../js/ui/screenShield.js:80
#: ../js/ui/screenShield.js:79
msgid "%A, %B %d"
msgstr "%A, %B %d"
#: ../js/ui/screenShield.js:144
#: ../js/ui/screenShield.js:143
#, c-format
msgid "%d new message"
msgid_plural "%d new messages"
msgstr[0] "%d ny melding"
msgstr[1] "%d nye meldinger"
#: ../js/ui/screenShield.js:146
#: ../js/ui/screenShield.js:145
#, c-format
msgid "%d new notification"
msgid_plural "%d new notifications"
@ -1236,7 +1168,7 @@ msgstr "Passord"
msgid "Remember Password"
msgstr "Husk passord"
#: ../js/ui/shellMountOperation.js:400 ../js/ui/unlockDialog.js:174
#: ../js/ui/shellMountOperation.js:400 ../js/ui/unlockDialog.js:169
msgid "Unlock"
msgstr "Lås opp"
@ -1291,7 +1223,7 @@ msgstr "Stor tekst"
#: ../js/ui/status/bluetooth.js:27 ../js/ui/status/bluetooth.js:31
#: ../js/ui/status/bluetooth.js:251 ../js/ui/status/bluetooth.js:304
#: ../js/ui/status/bluetooth.js:335 ../js/ui/status/bluetooth.js:371
#: ../js/ui/status/bluetooth.js:400 ../js/ui/status/network.js:873
#: ../js/ui/status/bluetooth.js:400 ../js/ui/status/network.js:867
msgid "Bluetooth"
msgstr "Bluetooth"
@ -1320,12 +1252,12 @@ msgstr "maskinvare slått av"
msgid "Connection"
msgstr "Tilkobling"
#: ../js/ui/status/bluetooth.js:207 ../js/ui/status/network.js:475
#: ../js/ui/status/bluetooth.js:207 ../js/ui/status/network.js:458
msgid "disconnecting..."
msgstr "kobler fra …"
#: ../js/ui/status/bluetooth.js:220 ../js/ui/status/network.js:481
#: ../js/ui/status/network.js:1507
#: ../js/ui/status/bluetooth.js:220 ../js/ui/status/network.js:464
#: ../js/ui/status/network.js:934
msgid "connecting..."
msgstr "kobler til …"
@ -1435,106 +1367,109 @@ msgstr "slått av"
#. 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:473
#: ../js/ui/status/network.js:456
msgid "unmanaged"
msgstr "ikke håndtert"
#. Translators: this is for network connections that require some kind of key or password
#: ../js/ui/status/network.js:484 ../js/ui/status/network.js:1510
#: ../js/ui/status/network.js:467 ../js/ui/status/network.js:937
msgid "authentication required"
msgstr "autentisering kreves"
#. Translators: this is for devices that require some kind of firmware or kernel
#. module, which is missing
#: ../js/ui/status/network.js:494
#: ../js/ui/status/network.js:477
msgid "firmware missing"
msgstr "fastvare mangler"
#. Translators: this is for wired network devices that are physically disconnected
#: ../js/ui/status/network.js:501
#: ../js/ui/status/network.js:484
msgid "cable unplugged"
msgstr "kabel koblet fra"
#. 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:506
#: ../js/ui/status/network.js:489
msgid "unavailable"
msgstr "ikke tilgjengelig"
#: ../js/ui/status/network.js:508 ../js/ui/status/network.js:1512
#: ../js/ui/status/network.js:491 ../js/ui/status/network.js:939
msgid "connection failed"
msgstr "tilkobling feilet"
#: ../js/ui/status/network.js:560 ../js/ui/status/network.js:1446
#: ../js/ui/status/network.js:1588
#: ../js/ui/status/network.js:552 ../js/ui/status/network.js:1529
msgid "More..."
msgstr "Mer …"
#. 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:596 ../js/ui/status/network.js:1376
#: ../js/ui/status/network.js:588 ../js/ui/status/network.js:1459
msgid "Connected (private)"
msgstr "Tilkoblet (privat)"
#: ../js/ui/status/network.js:669
#: ../js/ui/status/network.js:663
msgid "Auto Ethernet"
msgstr "Automatisk Ethernet"
#: ../js/ui/status/network.js:727
#: ../js/ui/status/network.js:721
msgid "Auto broadband"
msgstr "Automatisk bredbånd"
#: ../js/ui/status/network.js:730
#: ../js/ui/status/network.js:724
msgid "Auto dial-up"
msgstr "Automatisk oppringt"
#. TRANSLATORS: this the automatic wireless connection name (including the network name)
#: ../js/ui/status/network.js:859 ../js/ui/status/network.js:1393
#: ../js/ui/status/network.js:853 ../js/ui/status/network.js:1476
#, c-format
msgid "Auto %s"
msgstr "Automatisk %s"
#: ../js/ui/status/network.js:861
#: ../js/ui/status/network.js:855
msgid "Auto bluetooth"
msgstr "Automatisk Bluetooth"
#: ../js/ui/status/network.js:1395
#: ../js/ui/status/network.js:1478
msgid "Auto wireless"
msgstr "Automatisk trådløst"
#: ../js/ui/status/network.js:1637
#: ../js/ui/status/network.js:1575
msgid "Enable networking"
msgstr "Slå på nettverk"
#: ../js/ui/status/network.js:1659
#: ../js/ui/status/network.js:1597
msgid "Wired"
msgstr "Kablet"
#: ../js/ui/status/network.js:1670
#: ../js/ui/status/network.js:1608
msgid "Wireless"
msgstr "Trådløst"
#: ../js/ui/status/network.js:1680
#: ../js/ui/status/network.js:1618
msgid "Mobile broadband"
msgstr "Mobilt bredbånd"
#: ../js/ui/status/network.js:1691
#: ../js/ui/status/network.js:1628
msgid "VPN Connections"
msgstr "VPN-tilkoblinger"
#: ../js/ui/status/network.js:1635
msgid "Network Settings"
msgstr "Innstillinger for nettverk"
#: ../js/ui/status/network.js:1735
#: ../js/ui/status/network.js:1679
msgid "Network Manager"
msgstr "Nettverkshåndtering"
#: ../js/ui/status/network.js:1809
#: ../js/ui/status/network.js:1769
msgid "Connection failed"
msgstr "Tilkobling feilet"
#: ../js/ui/status/network.js:1810
#: ../js/ui/status/network.js:1770
msgid "Activation of network connection failed"
msgstr "Aktivering av nettverkstilkobling feilet"
#: ../js/ui/status/network.js:2108
#: ../js/ui/status/network.js:2065
msgid "Networking is disabled"
msgstr "Nettverk er slått av"
@ -1644,63 +1579,63 @@ msgstr "Volum"
msgid "Microphone"
msgstr "Mikrofon"
#: ../js/ui/unlockDialog.js:181
#: ../js/ui/unlockDialog.js:176
msgid "Log in as another user"
msgstr "Logg inn som en annen bruker"
#: ../js/ui/userMenu.js:176
#: ../js/ui/userMenu.js:180
msgid "Available"
msgstr "Tilgjengelig"
#: ../js/ui/userMenu.js:179
#: ../js/ui/userMenu.js:183
msgid "Busy"
msgstr "Opptatt"
#: ../js/ui/userMenu.js:182
#: ../js/ui/userMenu.js:186
msgid "Invisible"
msgstr "Usynlig"
#: ../js/ui/userMenu.js:185
#: ../js/ui/userMenu.js:189
msgid "Away"
msgstr "Borte"
#: ../js/ui/userMenu.js:188
#: ../js/ui/userMenu.js:192
msgid "Idle"
msgstr "Ledig"
#: ../js/ui/userMenu.js:191
msgid "Offline"
msgstr "Frakoblet"
#: ../js/ui/userMenu.js:195
msgid "Unavailable"
msgstr "Ikke tilgjengelig"
#: ../js/ui/userMenu.js:747
#: ../js/ui/userMenu.js:740
msgid "Notifications"
msgstr "Varslinger"
#: ../js/ui/userMenu.js:755
#: ../js/ui/userMenu.js:748
msgid "System Settings"
msgstr "Systeminnstillinger"
#: ../js/ui/userMenu.js:763
#: ../js/ui/userMenu.js:756
msgid "Switch User"
msgstr "Bytt bruker"
#: ../js/ui/userMenu.js:768
#: ../js/ui/userMenu.js:761
msgid "Log Out"
msgstr "Logg ut"
#: ../js/ui/userMenu.js:773
#: ../js/ui/userMenu.js:766
msgid "Lock"
msgstr "Lås"
#: ../js/ui/userMenu.js:788
#: ../js/ui/userMenu.js:781
msgid "Install Updates & Restart"
msgstr "Installer oppdateringer og start på nytt"
#: ../js/ui/userMenu.js:806
#: ../js/ui/userMenu.js:799
msgid "Your chat status will be set to busy"
msgstr "Din pratestatus vil bli satt til opptatt"
#: ../js/ui/userMenu.js:807
#: ../js/ui/userMenu.js:800
msgid ""
"Notifications are now disabled, including chat messages. Your online status "
"has been adjusted to let others know that you might not see their messages."
@ -1709,15 +1644,15 @@ msgstr ""
"tilkoblingsstatus er justert for å la andre vite at du kanskje ikke ser "
"deres meldinger."
#: ../js/ui/viewSelector.js:87
#: ../js/ui/viewSelector.js:85
msgid "Windows"
msgstr "Vinduer"
#: ../js/ui/viewSelector.js:91
#: ../js/ui/viewSelector.js:89
msgid "Applications"
msgstr "Programmer"
#: ../js/ui/viewSelector.js:95
#: ../js/ui/viewSelector.js:93
msgid "Search"
msgstr "Søk"
@ -1786,7 +1721,7 @@ msgstr "Bruk spesifikt modus, f.eks «gdm» for innloggingsskjerm"
msgid "List possible modes"
msgstr "Vis mulige modi"
#: ../src/shell-app.c:622
#: ../src/shell-app.c:621
#, c-format
msgid "Failed to launch '%s'"
msgstr "Klarte ikke å starte «%s»"

1975
po/nl.po

File diff suppressed because it is too large Load Diff

505
po/ru.po

File diff suppressed because it is too large Load Diff

View File

@ -119,6 +119,7 @@ shell_public_headers_h = \
shell-network-agent.h \
shell-perf-log.h \
shell-screenshot.h \
shell-screen-grabber.h \
shell-slicer.h \
shell-stack.h \
shell-tp-client.h \
@ -166,6 +167,7 @@ libgnome_shell_la_SOURCES = \
shell-polkit-authentication-agent.h \
shell-polkit-authentication-agent.c \
shell-screenshot.c \
shell-screen-grabber.c \
shell-secure-text-buffer.c \
shell-secure-text-buffer.h \
shell-slicer.c \
@ -230,6 +232,8 @@ test_recorder_LDADD = $(TEST_SHELL_RECORDER_LIBS)
test_recorder_SOURCES = \
$(shell_recorder_sources) $(shell_recorder_private_sources) \
shell-screen-grabber.c \
shell-screen-grabber.h \
test-recorder.c
endif BUILD_RECORDER

View File

@ -1035,6 +1035,8 @@ main (int argc,
name_owner_id = 0;
stdin_channel = NULL;
g_type_init ();
introspection_data = g_dbus_node_info_new_for_xml (introspection_xml, NULL);
g_assert (introspection_data != NULL);

View File

@ -28,7 +28,7 @@ def show_version(option, opt_str, value, parser):
def wait_for_dbus_name(wait_name):
loop = GLib.MainLoop()
def on_name_appeared(connection, name, new_owner, *args):
def on_name_appeared(connection, name, name_owner, *args):
if not (name == wait_name and new_owner != ''):
return
loop.quit()
@ -60,18 +60,13 @@ def start_perf_helper():
wait_for_dbus_name (PERF_HELPER_NAME)
def stop_perf_helper():
bus = Gio.bus_get_sync(Gio.BusType.SESSION, None)
proxy = Gio.DBusProxy.new_sync(bus,
Gio.DBusProxyFlags.NONE,
None,
PERF_HELPER_NAME,
PERF_HELPER_PATH,
PERF_HELPER_IFACE,
None)
proxy = Gio.DBusProxy(g_bus_type=Gio.BusType.SESSION,
g_name=PERF_HELPER_NAME,
g_interface=PERF_HELPER_IFACE,
g_object_path=PERF_HELPER_PATH)
proxy.Exit()
def start_shell(perf_output=None):
def start_shell(extra_args, perf_output=None):
# Set up environment
env = dict(os.environ)
env['SHELL_PERF_MODULE'] = options.perf
@ -81,21 +76,19 @@ def start_shell(perf_output=None):
env['SHELL_PERF_OUTPUT'] = perf_output
self_dir = os.path.dirname(os.path.abspath(sys.argv[0]))
args = []
args.append(os.path.join(self_dir, 'gnome-shell'))
if options.replace:
args.append('--replace')
# pass on any additional arguments
args += extra_args
return subprocess.Popen(args, env=env)
def run_shell(perf_output=None):
def run_shell(args, perf_output=None):
# we do no additional supervision of gnome-shell,
# beyond that of wait
# in particular, we don't kill the shell upon
# receving a KeyboardInterrupt, as we expect to be
# in the same process group
shell = start_shell(perf_output=perf_output)
shell = start_shell(extra_args, perf_output=perf_output)
shell.wait()
return shell.returncode == 0
@ -180,7 +173,7 @@ def upload_performance_report(report_text):
print "Performance report upload failed with status %d" % response.status
print response.read()
def run_performance_test():
def run_performance_test(args):
iters = options.perf_iters
if options.perf_warmup:
iters += 1
@ -199,7 +192,7 @@ def run_performance_test():
# Run the performance test and collect the output as JSON
normal_exit = False
try:
normal_exit = run_shell(perf_output=output_file)
normal_exit = run_shell(args, perf_output=output_file)
except:
stop_perf_helper()
raise
@ -295,8 +288,7 @@ def run_performance_test():
parser = optparse.OptionParser()
parser.add_option("", "--perf", metavar="PERF_MODULE",
help="Specify the name of a performance module to run",
default="core")
help="Specify the name of a performance module to run")
parser.add_option("", "--perf-iters", type="int", metavar="ITERS",
help="Numbers of iterations of performance module to run",
default=1)
@ -309,16 +301,9 @@ parser.add_option("", "--perf-upload", action="store_true",
parser.add_option("", "--version", action="callback", callback=show_version,
help="Display version and exit")
parser.add_option("-r", "--replace", action="store_true",
help="Replace the running window manager")
options, args = parser.parse_args()
if args:
parser.print_usage()
sys.exit(1)
normal_exit = run_performance_test()
normal_exit = run_performance_test(args)
if normal_exit:
sys.exit(0)
else:

View File

@ -72,9 +72,6 @@ static void gnome_shell_plugin_kill_switch_workspace (MetaPlugin *plugin);
static gboolean gnome_shell_plugin_xevent_filter (MetaPlugin *plugin,
XEvent *event);
static gboolean gnome_shell_plugin_keybinding_filter (MetaPlugin *plugin,
MetaKeyBinding *binding);
static const MetaPluginInfo *gnome_shell_plugin_plugin_info (MetaPlugin *plugin);
@ -129,9 +126,8 @@ gnome_shell_plugin_class_init (GnomeShellPluginClass *klass)
plugin_class->kill_window_effects = gnome_shell_plugin_kill_window_effects;
plugin_class->kill_switch_workspace = gnome_shell_plugin_kill_switch_workspace;
plugin_class->xevent_filter = gnome_shell_plugin_xevent_filter;
plugin_class->keybinding_filter = gnome_shell_plugin_keybinding_filter;
plugin_class->plugin_info = gnome_shell_plugin_plugin_info;
plugin_class->xevent_filter = gnome_shell_plugin_xevent_filter;
plugin_class->plugin_info = gnome_shell_plugin_plugin_info;
}
static void
@ -341,13 +337,6 @@ gnome_shell_plugin_xevent_filter (MetaPlugin *plugin,
return clutter_x11_handle_event (xev) != CLUTTER_X11_FILTER_CONTINUE;
}
static gboolean
gnome_shell_plugin_keybinding_filter (MetaPlugin *plugin,
MetaKeyBinding *binding)
{
return _shell_wm_filter_keybinding (get_shell_wm (), binding);
}
static const
MetaPluginInfo *gnome_shell_plugin_plugin_info (MetaPlugin *plugin)
{

View File

@ -38,7 +38,7 @@ extern GType gnome_shell_plugin_get_type (void);
#define OVERRIDES_SCHEMA "org.gnome.shell.overrides"
#define WM_NAME "GNOME Shell"
#define GNOME_WM_KEYBINDINGS "Mutter,GNOME Shell"
#define GNOME_WM_KEYBINDINGS "Metacity,Mutter,GNOME Shell"
static gboolean is_gdm_mode = FALSE;
static char *session_mode = NULL;
@ -174,6 +174,8 @@ shell_prefs_init (void)
OVERRIDES_SCHEMA);
meta_prefs_override_preference_schema ("workspaces-only-on-primary",
OVERRIDES_SCHEMA);
meta_prefs_override_preference_schema ("button-layout",
OVERRIDES_SCHEMA);
meta_prefs_override_preference_schema ("edge-tiling",
OVERRIDES_SCHEMA);
meta_prefs_override_preference_schema ("focus-change-on-pointer-rest",

View File

@ -37,11 +37,10 @@
#define ISO_3166_COUNTRY_CODES DATADIR "/zoneinfo/iso3166.tab"
static ShellCountryMobileProvider *country_mobile_provider_new (const char *country_code,
const gchar *country_name);
static GHashTable *
read_country_codes (const gchar *country_codes)
read_country_codes (void)
{
GHashTable *table;
GIOChannel *channel;
@ -49,21 +48,18 @@ read_country_codes (const gchar *country_codes)
GError *error = NULL;
GIOStatus status;
channel = g_io_channel_new_file (country_codes, "r", &error);
channel = g_io_channel_new_file (ISO_3166_COUNTRY_CODES, "r", &error);
if (!channel) {
if (error) {
g_warning ("Could not read %s: %s", country_codes, error->message);
g_warning ("Could not read " ISO_3166_COUNTRY_CODES ": %s", error->message);
g_error_free (error);
} else
g_warning ("Could not read %s: Unknown error", country_codes);
g_warning ("Could not read " ISO_3166_COUNTRY_CODES ": Unknown error");
return NULL;
}
table = g_hash_table_new_full (g_str_hash,
g_str_equal,
g_free,
(GDestroyNotify)shell_country_mobile_provider_unref);
table = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free);
buffer = g_string_sized_new (32);
status = G_IO_STATUS_NORMAL;
@ -73,7 +69,6 @@ read_country_codes (const gchar *country_codes)
switch (status) {
case G_IO_STATUS_NORMAL:
if (buffer->str[0] != '#') {
ShellCountryMobileProvider *country_provider;
char **pieces;
pieces = g_strsplit (buffer->str, "\t", 2);
@ -85,8 +80,7 @@ read_country_codes (const gchar *country_codes)
pieces[1] = g_strdup (_("United Kingdom"));
}
country_provider = country_mobile_provider_new (pieces[0], pieces[1]);
g_hash_table_insert (table, pieces[0], country_provider);
g_hash_table_insert (table, pieces[0], pieces[1]);
g_free (pieces);
}
@ -123,6 +117,7 @@ typedef enum {
} MobileContextState;
typedef struct {
GHashTable *country_codes;
GHashTable *table;
char *current_country;
@ -281,86 +276,6 @@ shell_mobile_provider_get_type (void)
return type;
}
static ShellCountryMobileProvider *
country_mobile_provider_new (const char *country_code,
const gchar *country_name)
{
ShellCountryMobileProvider *country_provider;
country_provider = g_slice_new0 (ShellCountryMobileProvider);
country_provider->refs = 1;
country_provider->country_code = g_strdup (country_code);
country_provider->country_name = g_strdup (country_name);
return country_provider;
}
ShellCountryMobileProvider *
shell_country_mobile_provider_ref (ShellCountryMobileProvider *country_provider)
{
country_provider->refs++;
return country_provider;
}
void
shell_country_mobile_provider_unref (ShellCountryMobileProvider *country_provider)
{
if (--country_provider->refs == 0) {
g_free (country_provider->country_code);
g_free (country_provider->country_name);
g_slist_free_full (country_provider->providers,
(GDestroyNotify) shell_mobile_provider_unref);
g_slice_free (ShellCountryMobileProvider, country_provider);
}
}
/**
* shell_country_mobile_provider_get_country_code:
*
* Returns: (transfer none): the code of the country.
*/
const gchar *
shell_country_mobile_provider_get_country_code (ShellCountryMobileProvider *country_provider)
{
return country_provider->country_code;
}
/**
* shell_country_mobile_provider_get_country_name:
*
* Returns: (transfer none): the name of the country.
*/
const gchar *
shell_country_mobile_provider_get_country_name (ShellCountryMobileProvider *country_provider)
{
return country_provider->country_name;
}
/**
* shell_country_mobile_provider_get_providers:
*
* Returns: (element-type Shell.MobileProvider) (transfer none): the
* list of #ShellMobileProvider this country exposes.
*/
GSList *
shell_country_mobile_provider_get_providers (ShellCountryMobileProvider *country_provider)
{
return country_provider->providers;
}
GType
shell_country_mobile_provider_get_type (void)
{
static GType type = 0;
if (G_UNLIKELY (type == 0)) {
type = g_boxed_type_register_static ("ShellCountryMobileProvider",
(GBoxedCopyFunc) shell_country_mobile_provider_ref,
(GBoxedFreeFunc) shell_country_mobile_provider_unref);
}
return type;
}
static void
provider_list_free (gpointer data)
{
@ -395,17 +310,15 @@ parser_toplevel_start (MobileParser *parser,
for (i = 0; attribute_names && attribute_names[i]; i++) {
if (!strcmp (attribute_names[i], "code")) {
char *country_code;
ShellCountryMobileProvider *country_provider;
char *country;
country_code = g_ascii_strup (attribute_values[i], -1);
country_provider = g_hash_table_lookup (parser->table, country_code);
/* Ensure we have a country provider for this country code */
if (!country_provider) {
g_warning ("%s: adding providers for unknown country '%s'", __func__, country_code);
country_provider = country_mobile_provider_new (country_code, NULL);
g_hash_table_insert (parser->table, country_code, country_provider);
}
parser->current_country = country_code;
country = g_hash_table_lookup (parser->country_codes, country_code);
if (country) {
parser->current_country = g_strdup (country);
g_free (country_code);
} else
parser->current_country = country_code;
parser->state = PARSER_COUNTRY;
break;
@ -542,13 +455,7 @@ parser_country_end (MobileParser *parser,
const char *name)
{
if (!strcmp (name, "country")) {
ShellCountryMobileProvider *country_provider;
country_provider = g_hash_table_lookup (parser->table, parser->current_country);
if (country_provider)
/* Store providers for this country */
country_provider->providers = parser->current_providers;
g_hash_table_insert (parser->table, parser->current_country, parser->current_providers);
parser->current_country = NULL;
parser->current_providers = NULL;
parser->text_buffer = NULL;
@ -709,16 +616,15 @@ static const GMarkupParser mobile_parser = {
/**
* shell_mobile_providers_parse:
* @country_codes: (allow-none) File with the list of country codes.
* @service_providers: (allow-none) File with the list of service providers.
* @out_ccs: (out) (allow-none): (element-type utf8 utf8): a #GHashTable containing
* country codes
*
* Returns: (element-type utf8 Shell.CountryMobileProvider) (transfer full): a
* hash table where keys are country names #gchar and values are #ShellCountryMobileProvider.
* Everything is destroyed with g_hash_table_destroy().
*/
* Returns: (element-type utf8 GList) (transfer container): a
* hash table where keys are country names #gchar, values are a #GSList
* of #ShellMobileProvider. Everything is destroyed with g_hash_table_destroy().
*/
GHashTable *
shell_mobile_providers_parse (const gchar *country_codes,
const gchar *service_providers)
shell_mobile_providers_parse (GHashTable **out_ccs)
{
GMarkupParseContext *ctx;
GIOChannel *channel;
@ -728,29 +634,24 @@ shell_mobile_providers_parse (const gchar *country_codes,
GIOStatus status;
gsize len = 0;
/* Use default paths if none given */
if (!country_codes)
country_codes = ISO_3166_COUNTRY_CODES;
if (!service_providers)
service_providers = MOBILE_BROADBAND_PROVIDER_INFO;
memset (&parser, 0, sizeof (MobileParser));
parser.table = read_country_codes (country_codes);
if (!parser.table)
parser.country_codes = read_country_codes ();
if (!parser.country_codes)
goto out;
channel = g_io_channel_new_file (service_providers, "r", &error);
channel = g_io_channel_new_file (MOBILE_BROADBAND_PROVIDER_INFO, "r", &error);
if (!channel) {
if (error) {
g_warning ("Could not read %s: %s", service_providers, error->message);
g_warning ("Could not read " MOBILE_BROADBAND_PROVIDER_INFO ": %s", error->message);
g_error_free (error);
} else
g_warning ("Could not read %s: Unknown error", service_providers);
g_warning ("Could not read " MOBILE_BROADBAND_PROVIDER_INFO ": Unknown error");
goto out;
}
parser.table = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, provider_list_free);
parser.state = PARSER_TOPLEVEL;
ctx = g_markup_parse_context_new (&mobile_parser, 0, &parser, NULL);
@ -795,7 +696,13 @@ shell_mobile_providers_parse (const gchar *country_codes,
g_free (parser.current_country);
g_free (parser.text_buffer);
out:
out:
if (parser.country_codes) {
if (out_ccs)
*out_ccs = parser.country_codes;
else
g_hash_table_destroy (parser.country_codes);
}
return parser.table;
}
@ -837,17 +744,12 @@ dump_gsm (ShellMobileAccessMethod *method)
static void
dump_country (gpointer key, gpointer value, gpointer user_data)
{
GSList *miter, *citer;
ShellCountryMobileProvider *country_provider = value;
GSList *citer, *miter;
g_print ("Country: %s (%s)\n",
country_provider->country_code,
country_provider->country_name);
for (citer = country_provider->providers; citer; citer = g_slist_next (citer)) {
for (citer = value; citer; citer = g_slist_next (citer)) {
ShellMobileProvider *provider = citer->data;
g_print (" Provider: %s (%s)\n", provider->name, (const char *) key);
g_print ("Provider: %s (%s)\n", provider->name, (const char *) key);
for (miter = provider->methods; miter; miter = g_slist_next (miter)) {
ShellMobileAccessMethod *method = miter->data;
GSList *liter;
@ -877,10 +779,10 @@ dump_country (gpointer key, gpointer value, gpointer user_data)
}
void
shell_mobile_providers_dump (GHashTable *country_providers)
shell_mobile_providers_dump (GHashTable *providers)
{
g_return_if_fail (country_providers != NULL);
g_hash_table_foreach (country_providers, dump_country, NULL);
g_return_if_fail (providers != NULL);
g_hash_table_foreach (providers, dump_country, NULL);
}
/* All the following don't exist in nm-applet, because C doesn't need

View File

@ -76,19 +76,10 @@ typedef struct {
gint refs;
} ShellMobileProvider;
typedef struct {
char *country_code;
char *country_name;
GSList *providers;
gint refs;
} ShellCountryMobileProvider;
GType shell_gsm_mcc_mnc_get_type (void); /* added in porting */
GType shell_mobile_access_method_get_type (void);
GType shell_mobile_provider_get_type (void);
GType shell_country_mobile_provider_get_type (void);
GType shell_mobile_access_method_get_type (void);
ShellMobileProvider *shell_mobile_provider_ref (ShellMobileProvider *provider);
void shell_mobile_provider_unref (ShellMobileProvider *provider);
@ -98,14 +89,8 @@ GSList * shell_mobile_provider_get_cdma_sid (ShellMobileProvider *pr
ShellMobileAccessMethod *shell_mobile_access_method_ref (ShellMobileAccessMethod *method);
void shell_mobile_access_method_unref (ShellMobileAccessMethod *method);
ShellCountryMobileProvider *shell_country_mobile_provider_ref (ShellCountryMobileProvider *country_provider);
void shell_country_mobile_provider_unref (ShellCountryMobileProvider *country_provider);
const gchar *shell_country_mobile_provider_get_country_code (ShellCountryMobileProvider *country_provider);
const gchar *shell_country_mobile_provider_get_country_name (ShellCountryMobileProvider *country_provider);
GSList *shell_country_mobile_provider_get_providers (ShellCountryMobileProvider *country_provider);
GHashTable *shell_mobile_providers_parse (GHashTable **out_ccs);
GHashTable *shell_mobile_providers_parse (const gchar *country_codes,
const gchar *service_providers);
void shell_mobile_providers_dump (GHashTable *country_providers);
void shell_mobile_providers_dump (GHashTable *providers);
#endif /* SHELL_MOBILE_PROVIDERS_H */

View File

@ -14,9 +14,6 @@ struct _ShellRecorderSrc
GMutex mutex_data;
GMutex *mutex;
GstClock *clock;
GstClockTime last_frame_time;
GstCaps *caps;
GAsyncQueue *queue;
gboolean closed;
@ -44,10 +41,6 @@ static void
shell_recorder_src_init (ShellRecorderSrc *src)
{
gst_base_src_set_format (GST_BASE_SRC (src), GST_FORMAT_TIME);
gst_base_src_set_live (GST_BASE_SRC (src), TRUE);
src->clock = gst_system_clock_obtain ();
src->last_frame_time = 0;
src->queue = g_async_queue_new ();
src->mutex = &src->mutex_data;
@ -96,10 +89,6 @@ shell_recorder_src_create (GstPushSrc *push_src,
return GST_FLOW_EOS;
buffer = g_async_queue_pop (src->queue);
if (src->last_frame_time == 0)
src->last_frame_time = gst_clock_get_time (GST_CLOCK (src->clock));
if (buffer == RECORDER_QUEUE_END)
{
/* Returning UNEXPECTED here will cause a EOS message to be sent */
@ -111,9 +100,6 @@ shell_recorder_src_create (GstPushSrc *push_src,
- (int)(gst_buffer_get_size(buffer) / 1024));
*buffer_out = buffer;
GST_BUFFER_DURATION(*buffer_out) = GST_CLOCK_DIFF (src->last_frame_time, gst_clock_get_time (GST_CLOCK (src->clock)));
src->last_frame_time = gst_clock_get_time (GST_CLOCK (src->clock));
return GST_FLOW_OK;
}
@ -155,8 +141,6 @@ shell_recorder_src_finalize (GObject *object)
g_mutex_clear (src->mutex);
gst_object_unref (src->clock);
G_OBJECT_CLASS (shell_recorder_src_parent_class)->finalize (object);
}

View File

@ -12,10 +12,10 @@
#include <gst/gst.h>
#include <gtk/gtk.h>
#include <gdk/gdk.h>
#include "shell-recorder-src.h"
#include "shell-recorder.h"
#include "shell-screen-grabber.h"
#include <clutter/x11/clutter-x11.h>
#include <X11/extensions/Xfixes.h>
@ -48,7 +48,7 @@ struct _ShellRecorder {
int stage_width;
int stage_height;
GdkScreen *gdk_screen;
ShellScreenGrabber *grabber;
gboolean have_pointer;
int pointer_x;
@ -259,11 +259,11 @@ shell_recorder_init (ShellRecorder *recorder)
shell_recorder_src_register ();
recorder->gdk_screen = gdk_screen_get_default ();
recorder->recording_icon = create_recording_icon ();
recorder->memory_target = get_memory_target();
recorder->grabber = shell_screen_grabber_new ();
recorder->state = RECORDER_STATE_CLOSED;
recorder->framerate = DEFAULT_FRAMES_PER_SECOND;
}
@ -283,6 +283,8 @@ shell_recorder_finalize (GObject *object)
recorder_set_pipeline (recorder, NULL);
recorder_set_file_template (recorder, NULL);
g_object_unref (recorder->grabber);
cogl_handle_unref (recorder->recording_icon);
G_OBJECT_CLASS (shell_recorder_parent_class)->finalize (object);
@ -460,12 +462,6 @@ static void
recorder_draw_buffer_meter (ShellRecorder *recorder)
{
int fill_level;
GdkRectangle primary_monitor;
float rects[16];
gdk_screen_get_monitor_geometry (recorder->gdk_screen,
gdk_screen_get_primary_monitor (recorder->gdk_screen),
&primary_monitor);
recorder_update_memory_used (recorder, FALSE);
@ -480,27 +476,14 @@ recorder_draw_buffer_meter (ShellRecorder *recorder)
fill_level = MIN (60, (recorder->memory_used * 60) / recorder->memory_target);
/* A hollow rectangle filled from the left to fill_level */
rects[0] = primary_monitor.x + primary_monitor.width - 64;
rects[1] = primary_monitor.y + primary_monitor.height - 10;
rects[2] = primary_monitor.x + primary_monitor.width - 2;
rects[3] = primary_monitor.y + primary_monitor.height - 9;
rects[4] = primary_monitor.x + primary_monitor.width - 64;
rects[5] = primary_monitor.y + primary_monitor.height - 9;
rects[6] = primary_monitor.x + primary_monitor.width - (63 - fill_level);
rects[7] = primary_monitor.y + primary_monitor.height - 3;
rects[8] = primary_monitor.x + primary_monitor.width - 3;
rects[9] = primary_monitor.y + primary_monitor.height - 9;
rects[10] = primary_monitor.x + primary_monitor.width - 2;
rects[11] = primary_monitor.y + primary_monitor.height - 3;
rects[12] = primary_monitor.x + primary_monitor.width - 64;
rects[13] = primary_monitor.y + primary_monitor.height - 3;
rects[14] = primary_monitor.x + primary_monitor.width - 2;
rects[15] = primary_monitor.y + primary_monitor.height - 2;
cogl_rectangles (rects, 4);
cogl_rectangle (recorder->stage_width - 64, recorder->stage_height - 10,
recorder->stage_width - 2, recorder->stage_height - 9);
cogl_rectangle (recorder->stage_width - 64, recorder->stage_height - 9,
recorder->stage_width - (63 - fill_level), recorder->stage_height - 3);
cogl_rectangle (recorder->stage_width - 3, recorder->stage_height - 9,
recorder->stage_width - 2, recorder->stage_height - 3);
cogl_rectangle (recorder->stage_width - 64, recorder->stage_height - 3,
recorder->stage_width - 2, recorder->stage_height - 2);
}
/* We want to time-stamp each frame based on the actual time it was
@ -550,13 +533,8 @@ recorder_record_frame (ShellRecorder *recorder)
size = recorder->stage_width * recorder->stage_height * 4;
data = g_malloc (recorder->stage_width * 4 * recorder->stage_height);
cogl_read_pixels (0, 0, /* x/y */
recorder->stage_width,
recorder->stage_height,
COGL_READ_PIXELS_COLOR_BUFFER,
CLUTTER_CAIRO_FORMAT_ARGB32,
data);
data = shell_screen_grabber_grab (recorder->grabber,
0, 0, recorder->stage_width, recorder->stage_height);
buffer = gst_buffer_new();
gst_buffer_insert_memory (buffer, -1,
@ -584,17 +562,12 @@ recorder_on_stage_paint (ClutterActor *actor,
{
if (recorder->state == RECORDER_STATE_RECORDING)
{
GdkRectangle primary_monitor;
gdk_screen_get_monitor_geometry (recorder->gdk_screen,
gdk_screen_get_primary_monitor (recorder->gdk_screen),
&primary_monitor);
if (!recorder->only_paint)
recorder_record_frame (recorder);
cogl_set_source_texture (recorder->recording_icon);
cogl_rectangle (primary_monitor.x + primary_monitor.width - 32, primary_monitor.y + primary_monitor.height - 42,
primary_monitor.x + primary_monitor.width, primary_monitor.y + primary_monitor.height - 10);
cogl_rectangle (recorder->stage_width - 32, recorder->stage_height - 42,
recorder->stage_width, recorder->stage_height - 10);
}
if (recorder->state == RECORDER_STATE_RECORDING || recorder->memory_used != 0)
@ -1730,6 +1703,9 @@ shell_recorder_close (ShellRecorder *recorder)
recorder->repaint_hook_id = 0;
}
recorder_remove_redraw_timeout (recorder);
recorder_close_pipeline (recorder);
recorder->state = RECORDER_STATE_CLOSED;
/* Release the refcount we took when we started recording */

210
src/shell-screen-grabber.c Normal file
View File

@ -0,0 +1,210 @@
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
#include <string.h>
#include <clutter/clutter.h>
#include <cogl/cogl.h>
#include <GL/gl.h>
#include <GL/glx.h>
#include <GL/glext.h>
#include "shell-screen-grabber.h"
PFNGLBINDBUFFERARBPROC pf_glBindBufferARB;
PFNGLBUFFERDATAARBPROC pf_glBufferDataARB;
PFNGLDELETEBUFFERSARBPROC pf_glDeleteBuffersARB;
PFNGLGENBUFFERSARBPROC pf_glGenBuffersARB;
PFNGLMAPBUFFERARBPROC pf_glMapBufferARB;
PFNGLUNMAPBUFFERARBPROC pf_glUnmapBufferARB;
struct _ShellScreenGrabberClass
{
GObjectClass parent_class;
};
struct _ShellScreenGrabber
{
GObject parent_instance;
int have_pixel_buffers;
int have_pack_invert;
int width, height;
GLuint pixel_buffer;
};
G_DEFINE_TYPE(ShellScreenGrabber, shell_screen_grabber, G_TYPE_OBJECT);
static void
shell_screen_grabber_finalize (GObject *gobject)
{
ShellScreenGrabber *grabber = SHELL_SCREEN_GRABBER (gobject);
if (grabber->pixel_buffer != 0)
pf_glDeleteBuffersARB (1, &grabber->pixel_buffer);
}
static void
shell_screen_grabber_class_init (ShellScreenGrabberClass *grabber_class)
{
GObjectClass *gobject_class = G_OBJECT_CLASS (grabber_class);
gobject_class->finalize = shell_screen_grabber_finalize;
}
static void
shell_screen_grabber_init (ShellScreenGrabber *grabber)
{
grabber->have_pixel_buffers = -1;
grabber->width = -1;
grabber->height= -1;
grabber->pixel_buffer = 0;
}
ShellScreenGrabber *
shell_screen_grabber_new (void)
{
return g_object_new (SHELL_TYPE_SCREEN_GRABBER, NULL);
}
/**
* shell_screen_grabber_grab:
* x: X coordinate of the rectangle to grab
* y: Y coordinate of the rectangle to grab
* width: width of the rectangle to grab
* height: heigth of the rectangle to grab
*
* Grabs pixel data from a portion of the screen.
*
* Return value: buffer holding the grabbed data. The data is stored as 32-bit
* words with native-endian xRGB pixels (i.e., the same as CAIRO_FORMAT_RGB24)
* with no padding on the rows. So, the size of the buffer is width * height * 4
* bytes. Free with g_free().
**/
guchar *
shell_screen_grabber_grab (ShellScreenGrabber *grabber,
int x,
int y,
int width,
int height)
{
guchar *data;
gsize row_bytes;
gsize data_size;
row_bytes = width * 4;
data_size = row_bytes * height;
data = g_malloc (data_size);
if (grabber->have_pixel_buffers == -1)
{
const GLubyte* extensions = glGetString (GL_EXTENSIONS);
grabber->have_pixel_buffers = strstr ((const char *)extensions, "GL_EXT_pixel_buffer_object") != NULL;
grabber->have_pack_invert = strstr ((const char *)extensions, "GL_MESA_pack_invert") != NULL;
}
if (grabber->have_pixel_buffers)
{
GLubyte *mapped_data;
GLint old_swap_bytes, old_lsb_first, old_row_length, old_skip_pixels, old_skip_rows, old_alignment;
GLint old_pack_invert = GL_FALSE;
GLint vp_size[4];
guchar *src_row, *dest_row;
int i;
cogl_flush ();
if (pf_glBindBufferARB == NULL)
{
pf_glBindBufferARB = (PFNGLBINDBUFFERARBPROC) cogl_get_proc_address ("glBindBufferARB");
pf_glBufferDataARB = (PFNGLBUFFERDATAARBPROC) cogl_get_proc_address ("glBufferDataARB");
pf_glDeleteBuffersARB = (PFNGLDELETEBUFFERSARBPROC) cogl_get_proc_address ("glDeleteBuffersARB");
pf_glGenBuffersARB = (PFNGLGENBUFFERSARBPROC) cogl_get_proc_address ("glGenBuffersARB");
pf_glMapBufferARB = (PFNGLMAPBUFFERARBPROC) cogl_get_proc_address ("glMapBufferARB");
pf_glUnmapBufferARB = (PFNGLUNMAPBUFFERARBPROC) cogl_get_proc_address ("glUnmapBufferARB");
}
glGetIntegerv (GL_PACK_SWAP_BYTES, &old_swap_bytes);
glGetIntegerv (GL_PACK_LSB_FIRST, &old_lsb_first);
glGetIntegerv (GL_PACK_ROW_LENGTH, &old_row_length);
glGetIntegerv (GL_PACK_SKIP_PIXELS, &old_skip_pixels);
glGetIntegerv (GL_PACK_SKIP_ROWS, &old_skip_rows);
glGetIntegerv (GL_PACK_ALIGNMENT, &old_alignment);
glPixelStorei (GL_PACK_SWAP_BYTES, GL_FALSE);
glPixelStorei (GL_PACK_LSB_FIRST, GL_FALSE);
glPixelStorei (GL_PACK_ROW_LENGTH, 0);
glPixelStorei (GL_PACK_SKIP_PIXELS, 0);
glPixelStorei (GL_PACK_SKIP_ROWS, 0);
glPixelStorei (GL_PACK_ALIGNMENT, 1);
if (grabber->have_pack_invert)
{
glGetIntegerv (GL_PACK_INVERT_MESA, &old_pack_invert);
glPixelStorei (GL_PACK_INVERT_MESA, GL_FALSE);
}
if (grabber->pixel_buffer != 0 &&
(grabber->width != width ||
grabber->height != height))
{
pf_glDeleteBuffersARB (1, &grabber->pixel_buffer);
grabber->pixel_buffer = 0;
}
if (grabber->pixel_buffer == 0)
{
pf_glGenBuffersARB (1, &grabber->pixel_buffer);
pf_glBindBufferARB (GL_PIXEL_PACK_BUFFER_ARB, grabber->pixel_buffer);
pf_glBufferDataARB (GL_PIXEL_PACK_BUFFER_ARB, data_size, 0, GL_STREAM_READ_ARB);
grabber->width = width;
grabber->height = height;
}
else
{
pf_glBindBufferARB (GL_PIXEL_PACK_BUFFER_ARB, grabber->pixel_buffer);
}
/* In OpenGL, (x,y) specifies the bottom-left corner rather than the
* top-left */
glGetIntegerv (GL_VIEWPORT, vp_size);
y = vp_size[3] - (y + height);
glReadPixels (x, y, width, height, GL_BGRA, GL_UNSIGNED_BYTE, 0);
mapped_data = pf_glMapBufferARB (GL_PIXEL_PACK_BUFFER_ARB, GL_READ_ONLY_ARB);
src_row = mapped_data + (height - 1) * row_bytes;
dest_row = data;
for (i = 0; i < height; i++)
{
memcpy (dest_row, src_row, row_bytes);
src_row -= row_bytes;
dest_row += row_bytes;
}
pf_glUnmapBufferARB (GL_PIXEL_PACK_BUFFER_ARB);
pf_glBindBufferARB (GL_PIXEL_PACK_BUFFER_ARB, 0);
glPixelStorei (GL_PACK_SWAP_BYTES, old_swap_bytes);
glPixelStorei (GL_PACK_LSB_FIRST, old_lsb_first);
glPixelStorei (GL_PACK_ROW_LENGTH, old_row_length);
glPixelStorei (GL_PACK_SKIP_PIXELS, old_skip_pixels);
glPixelStorei (GL_PACK_SKIP_ROWS, old_skip_rows);
glPixelStorei (GL_PACK_ALIGNMENT, old_alignment);
if (grabber->have_pack_invert)
glPixelStorei (GL_PACK_INVERT_MESA, old_pack_invert);
}
else
{
cogl_read_pixels (x, y,
width, height,
COGL_READ_PIXELS_COLOR_BUFFER,
CLUTTER_CAIRO_FORMAT_ARGB32,
data);
}
return data;
}

View File

@ -0,0 +1,44 @@
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
#ifndef __SHELL_SCREEN_GRABBER_H__
#define __SHELL_SCREEN_GRABBER_H__
#include <glib-object.h>
G_BEGIN_DECLS
/**
* SECTION:shell-screen-grabber
* @short_description: Grab pixel data from the screen
*
* The #ShellScreenGrabber object is used to download previous drawn
* content to the screen. It internally uses pixel-buffer objects if
* available, otherwise falls back to cogl_read_pixels().
*
* If you are repeatedly grabbing images of the same size from the
* screen, it makes sense to create one #ShellScreenGrabber and keep
* it around. Otherwise, it's fine to simply create one as needed and
* then get rid of it.
*/
typedef struct _ShellScreenGrabber ShellScreenGrabber;
typedef struct _ShellScreenGrabberClass ShellScreenGrabberClass;
#define SHELL_TYPE_SCREEN_GRABBER (shell_screen_grabber_get_type ())
#define SHELL_SCREEN_GRABBER(object) (G_TYPE_CHECK_INSTANCE_CAST ((object), SHELL_TYPE_SCREEN_GRABBER, ShellScreenGrabber))
#define SHELL_SCREEN_GRABBER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), SHELL_TYPE_SCREEN_GRABBER, ShellScreenGrabberClass))
#define SHELL_IS_SCREEN_GRABBER(object) (G_TYPE_CHECK_INSTANCE_TYPE ((object), SHELL_TYPE_SCREEN_GRABBER))
#define SHELL_IS_SCREEN_GRABBER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), SHELL_TYPE_SCREEN_GRABBER))
#define SHELL_SCREEN_GRABBER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), SHELL_TYPE_SCREEN_GRABBER, ShellScreenGrabberClass))
GType shell_screen_grabber_get_type (void) G_GNUC_CONST;
ShellScreenGrabber *shell_screen_grabber_new (void);
guchar * shell_screen_grabber_grab (ShellScreenGrabber *grabber,
int x,
int y,
int width,
int height);
G_END_DECLS
#endif /* __SHELL_SCREEN_GRABBER_H__ */

View File

@ -1,8 +1,5 @@
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
#define COGL_ENABLE_EXPERIMENTAL_API
#define CLUTTER_ENABLE_EXPERIMENTAL_API
#include <X11/extensions/Xfixes.h>
#include <clutter/x11/clutter-x11.h>
#include <clutter/clutter.h>
@ -13,6 +10,7 @@
#include <meta/meta-shaped-texture.h>
#include "shell-global.h"
#include "shell-screen-grabber.h"
#include "shell-screenshot.h"
struct _ShellScreenshotClass
@ -92,33 +90,18 @@ do_grab_screenshot (_screenshot_data *screenshot_data,
int width,
int height)
{
CoglBitmap *bitmap;
ClutterBackend *backend;
CoglContext *context;
int stride;
ShellScreenGrabber *grabber;
static const cairo_user_data_key_t key;
guchar *data;
backend = clutter_get_default_backend ();
context = clutter_backend_get_cogl_context (backend);
grabber = shell_screen_grabber_new ();
data = shell_screen_grabber_grab (grabber, x, y, width, height);
g_object_unref (grabber);
screenshot_data->image = cairo_image_surface_create (CAIRO_FORMAT_RGB24,
width, height);
data = cairo_image_surface_get_data (screenshot_data->image);
stride = cairo_image_surface_get_stride (screenshot_data->image);
bitmap = cogl_bitmap_new_for_data (context,
width,
height,
CLUTTER_CAIRO_FORMAT_ARGB32,
stride,
data);
cogl_framebuffer_read_pixels_into_bitmap (cogl_get_draw_framebuffer (),
x, y,
COGL_READ_PIXELS_COLOR_BUFFER,
bitmap);
cogl_object_unref (bitmap);
screenshot_data->image = cairo_image_surface_create_for_data (data, CAIRO_FORMAT_RGB24,
width, height, width * 4);
cairo_surface_set_user_data (screenshot_data->image, &key,
data, (cairo_destroy_func_t)g_free);
}
static void

View File

@ -35,9 +35,6 @@ void _shell_wm_kill_window_effects (ShellWM *wm,
MetaWindowActor *actor);
void _shell_wm_kill_switch_workspace (ShellWM *wm);
gboolean _shell_wm_filter_keybinding (ShellWM *wm,
MetaKeyBinding *binding);
G_END_DECLS
#endif /* __SHELL_WM_PRIVATE_H__ */

View File

@ -26,7 +26,6 @@ enum
SWITCH_WORKSPACE,
KILL_SWITCH_WORKSPACE,
KILL_WINDOW_EFFECTS,
FILTER_KEYBINDING,
LAST_SIGNAL
};
@ -116,14 +115,6 @@ shell_wm_class_init (ShellWMClass *klass)
NULL, NULL, NULL,
G_TYPE_NONE, 1,
META_TYPE_WINDOW_ACTOR);
shell_wm_signals[FILTER_KEYBINDING] =
g_signal_new ("filter-keybinding",
G_TYPE_FROM_CLASS (klass),
G_SIGNAL_RUN_LAST,
0,
g_signal_accumulator_true_handled, NULL, NULL,
G_TYPE_BOOLEAN, 1,
META_TYPE_KEY_BINDING);
}
void
@ -276,17 +267,6 @@ _shell_wm_destroy (ShellWM *wm,
g_signal_emit (wm, shell_wm_signals[DESTROY], 0, actor);
}
gboolean
_shell_wm_filter_keybinding (ShellWM *wm,
MetaKeyBinding *binding)
{
gboolean rv;
g_signal_emit (wm, shell_wm_signals[FILTER_KEYBINDING], 0, binding, &rv);
return rv;
}
/**
* shell_wm_new:
* @plugin: the #MetaPlugin

View File

@ -65,10 +65,6 @@
#include "st-clipboard.h"
#include "st-private.h"
#include <clutter/x11/clutter-x11.h>
#include <X11/Xlib.h>
#include <X11/cursorfont.h>
#include "st-widget-accessible.h"
#define HAS_FOCUS(actor) (clutter_actor_get_stage (actor) && clutter_stage_get_key_focus ((ClutterStage *) clutter_actor_get_stage (actor)) == actor)
@ -617,38 +613,6 @@ st_entry_key_focus_in (ClutterActor *actor)
clutter_actor_grab_key_focus (priv->entry);
}
static void
st_entry_set_cursor (StEntry *entry,
gboolean use_ibeam)
{
Display *dpy;
ClutterActor *stage, *actor = CLUTTER_ACTOR (entry);
Window wid;
static Cursor ibeam = None;
dpy = clutter_x11_get_default_display ();
stage = clutter_actor_get_stage (actor);
wid = clutter_x11_get_stage_window (CLUTTER_STAGE (stage));
if (ibeam == None)
ibeam = XCreateFontCursor (dpy, XC_xterm);
if (use_ibeam)
XDefineCursor (dpy, wid, ibeam);
else
XUndefineCursor (dpy, wid);
}
static gboolean
st_entry_crossing_event (ClutterActor *actor,
ClutterCrossingEvent *event)
{
if (event->source == ST_ENTRY (actor)->priv->entry && event->related != NULL)
st_entry_set_cursor (ST_ENTRY (actor), (event->type == CLUTTER_ENTER));
return FALSE;
}
static void
st_entry_class_init (StEntryClass *klass)
{
@ -671,9 +635,6 @@ st_entry_class_init (StEntryClass *klass)
actor_class->key_press_event = st_entry_key_press_event;
actor_class->key_focus_in = st_entry_key_focus_in;
actor_class->enter_event = st_entry_crossing_event;
actor_class->leave_event = st_entry_crossing_event;
widget_class->style_changed = st_entry_style_changed;
widget_class->navigate_focus = st_entry_navigate_focus;
widget_class->get_accessible_type = st_entry_accessible_get_type;

View File

@ -1073,8 +1073,6 @@ typedef struct {
gchar *path;
gint grid_width, grid_height;
ClutterActor *actor;
GFunc load_callback;
gpointer load_callback_data;
} AsyncImageData;
static void
@ -1091,7 +1089,6 @@ on_sliced_image_loaded (GObject *source_object,
GAsyncResult *res,
gpointer user_data)
{
GObject *cache = source_object;
AsyncImageData *data = (AsyncImageData *)user_data;
GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (res);
GList *list;
@ -1105,9 +1102,6 @@ on_sliced_image_loaded (GObject *source_object,
clutter_actor_hide (actor);
clutter_actor_add_child (data->actor, actor);
}
if (data->load_callback != NULL)
data->load_callback (cache, data->load_callback_data);
}
static void
@ -1162,8 +1156,6 @@ load_sliced_image (GSimpleAsyncResult *result,
* @path: Path to a filename
* @grid_width: Width in pixels
* @grid_height: Height in pixels
* @load_callback: (scope async) (allow-none): Function called when the image is loaded, or %NULL
* @user_data: Data to pass to the load callback
*
* This function reads a single image file which contains multiple images internally.
* The image file will be divided using @grid_width and @grid_height;
@ -1173,12 +1165,10 @@ load_sliced_image (GSimpleAsyncResult *result,
* Returns: (transfer none): A new #ClutterActor
*/
ClutterActor *
st_texture_cache_load_sliced_image (StTextureCache *cache,
const gchar *path,
gint grid_width,
gint grid_height,
GFunc load_callback,
gpointer user_data)
st_texture_cache_load_sliced_image (StTextureCache *cache,
const gchar *path,
gint grid_width,
gint grid_height)
{
AsyncImageData *data;
GSimpleAsyncResult *result;
@ -1189,8 +1179,6 @@ st_texture_cache_load_sliced_image (StTextureCache *cache,
data->grid_height = grid_height;
data->path = g_strdup (path);
data->actor = actor;
data->load_callback = load_callback;
data->load_callback_data = user_data;
g_object_ref (G_OBJECT (actor));
result = g_simple_async_result_new (G_OBJECT (cache), on_sliced_image_loaded, data, st_texture_cache_load_sliced_image);

View File

@ -69,12 +69,10 @@ GType st_texture_cache_get_type (void) G_GNUC_CONST;
StTextureCache* st_texture_cache_get_default (void);
ClutterActor *
st_texture_cache_load_sliced_image (StTextureCache *cache,
const gchar *path,
gint grid_width,
gint grid_height,
GFunc load_callback,
gpointer user_data);
st_texture_cache_load_sliced_image (StTextureCache *cache,
const gchar *path,
gint grid_width,
gint grid_height);
ClutterActor *st_texture_cache_bind_pixbuf_property (StTextureCache *cache,
GObject *object,

View File

@ -31,9 +31,6 @@ struct _StThemeContext {
PangoFontDescription *font;
StThemeNode *root_node;
StTheme *theme;
/* set of StThemeNode */
GHashTable *nodes;
};
struct _StThemeContextClass {
@ -69,8 +66,6 @@ st_theme_context_finalize (GObject *object)
(gpointer) st_theme_context_changed,
context);
if (context->nodes)
g_hash_table_unref (context->nodes);
if (context->root_node)
g_object_unref (context->root_node);
if (context->theme)
@ -110,10 +105,6 @@ st_theme_context_init (StThemeContext *context)
"resolution-changed",
G_CALLBACK (st_theme_context_changed),
context);
context->nodes = g_hash_table_new_full ((GHashFunc) st_theme_node_hash,
(GEqualFunc) st_theme_node_equal,
g_object_unref, NULL);
}
/**
@ -155,7 +146,6 @@ st_theme_context_changed (StThemeContext *context)
{
StThemeNode *old_root = context->root_node;
context->root_node = NULL;
g_hash_table_remove_all (context->nodes);
emit_changed (context);
@ -309,27 +299,3 @@ st_theme_context_get_root_node (StThemeContext *context)
return context->root_node;
}
/**
* st_theme_context_intern_node:
* @context: a #StThemeContext
* @node: a #StThemeNode
*
* Return an existing node matching @node, or if that isn't possible,
* @node itself.
*
* Return value: (transfer none): a node with the same properties as @node
*/
StThemeNode *
st_theme_context_intern_node (StThemeContext *context,
StThemeNode *node)
{
StThemeNode *mine = g_hash_table_lookup (context->nodes, node);
/* this might be node or not - it doesn't actually matter */
if (mine != NULL)
return mine;
g_hash_table_add (context->nodes, g_object_ref (node));
return node;
}

View File

@ -62,9 +62,6 @@ const PangoFontDescription *st_theme_context_get_font (StThemeContext
StThemeNode * st_theme_context_get_root_node (StThemeContext *context);
StThemeNode * st_theme_context_intern_node (StThemeContext *context,
StThemeNode *node);
G_END_DECLS
#endif /* __ST_THEME_CONTEXT_H__ */

View File

@ -1553,7 +1553,7 @@ st_theme_node_paint_borders (StThemeNode *node,
{
ClutterColor effective_border;
gboolean skip_corner_1, skip_corner_2;
float rects[16];
float x1, y1, x2, y2;
over (&border_color, &node->background_color, &effective_border);
alpha = paint_opacity * effective_border.alpha / 255;
@ -1569,44 +1569,46 @@ st_theme_node_paint_borders (StThemeNode *node,
skip_corner_1 = border_radius[ST_CORNER_TOPLEFT] > 0;
skip_corner_2 = border_radius[ST_CORNER_TOPRIGHT] > 0;
rects[0] = skip_corner_1 ? max_width_radius[ST_CORNER_TOPLEFT] : 0;
rects[1] = 0;
rects[2] = skip_corner_2 ? width - max_width_radius[ST_CORNER_TOPRIGHT] : width;
rects[3] = border_width[ST_SIDE_TOP];
x1 = skip_corner_1 ? max_width_radius[ST_CORNER_TOPLEFT] : 0;
y1 = 0;
x2 = skip_corner_2 ? width - max_width_radius[ST_CORNER_TOPRIGHT] : width;
y2 = border_width[ST_SIDE_TOP];
cogl_rectangle (x1, y1, x2, y2);
/* EAST */
skip_corner_1 = border_radius[ST_CORNER_TOPRIGHT] > 0;
skip_corner_2 = border_radius[ST_CORNER_BOTTOMRIGHT] > 0;
rects[4] = width - border_width[ST_SIDE_RIGHT];
rects[5] = skip_corner_1 ? max_width_radius[ST_CORNER_TOPRIGHT]
x1 = width - border_width[ST_SIDE_RIGHT];
y1 = skip_corner_1 ? max_width_radius[ST_CORNER_TOPRIGHT]
: border_width[ST_SIDE_TOP];
rects[6] = width;
rects[7] = skip_corner_2 ? height - max_width_radius[ST_CORNER_BOTTOMRIGHT]
x2 = width;
y2 = skip_corner_2 ? height - max_width_radius[ST_CORNER_BOTTOMRIGHT]
: height - border_width[ST_SIDE_BOTTOM];
cogl_rectangle (x1, y1, x2, y2);
/* SOUTH */
skip_corner_1 = border_radius[ST_CORNER_BOTTOMLEFT] > 0;
skip_corner_2 = border_radius[ST_CORNER_BOTTOMRIGHT] > 0;
rects[8] = skip_corner_1 ? max_width_radius[ST_CORNER_BOTTOMLEFT] : 0;
rects[9] = height - border_width[ST_SIDE_BOTTOM];
rects[10] = skip_corner_2 ? width - max_width_radius[ST_CORNER_BOTTOMRIGHT]
x1 = skip_corner_1 ? max_width_radius[ST_CORNER_BOTTOMLEFT] : 0;
y1 = height - border_width[ST_SIDE_BOTTOM];
x2 = skip_corner_2 ? width - max_width_radius[ST_CORNER_BOTTOMRIGHT]
: width;
rects[11] = height;
y2 = height;
cogl_rectangle (x1, y1, x2, y2);
/* WEST */
skip_corner_1 = border_radius[ST_CORNER_TOPLEFT] > 0;
skip_corner_2 = border_radius[ST_CORNER_BOTTOMLEFT] > 0;
rects[12] = 0;
rects[13] = skip_corner_1 ? max_width_radius[ST_CORNER_TOPLEFT]
x1 = 0;
y1 = skip_corner_1 ? max_width_radius[ST_CORNER_TOPLEFT]
: border_width[ST_SIDE_TOP];
rects[14] = border_width[ST_SIDE_LEFT];
rects[15] = skip_corner_2 ? height - max_width_radius[ST_CORNER_BOTTOMLEFT]
x2 = border_width[ST_SIDE_LEFT];
y2 = skip_corner_2 ? height - max_width_radius[ST_CORNER_BOTTOMLEFT]
: height - border_width[ST_SIDE_BOTTOM];
cogl_rectangles (rects, 4);
cogl_rectangle (x1, y1, x2, y2);
}
}
@ -1873,7 +1875,6 @@ st_theme_node_paint_outline (StThemeNode *node,
{
float width, height;
int outline_width;
float rects[16];
ClutterColor outline_color, effective_outline;
width = box->x2 - box->x1;
@ -1898,30 +1899,20 @@ st_theme_node_paint_outline (StThemeNode *node,
*/
/* NORTH */
rects[0] = -outline_width;
rects[1] = -outline_width;
rects[2] = width + outline_width;
rects[3] = 0;
cogl_rectangle (-outline_width, -outline_width,
width + outline_width, 0);
/* EAST */
rects[4] = width;
rects[5] = 0;
rects[6] = width + outline_width;
rects[7] = height;
cogl_rectangle (width, 0,
width + outline_width, height);
/* SOUTH */
rects[8] = -outline_width;
rects[9] = height;
rects[10] = width + outline_width;
rects[11] = height + outline_width;
cogl_rectangle (-outline_width, height,
width + outline_width, height + outline_width);
/* WEST */
rects[12] = -outline_width;
rects[13] = 0;
rects[14] = 0;
rects[15] = height;
cogl_rectangles (rects, 4);
cogl_rectangle (-outline_width, 0,
0, height);
}
void
@ -2069,9 +2060,6 @@ st_theme_node_copy_cached_paint_state (StThemeNode *node,
g_return_if_fail (ST_IS_THEME_NODE (node));
g_return_if_fail (ST_IS_THEME_NODE (other));
if (node == other)
return;
/* Check omitted for speed: */
/* g_return_if_fail (st_theme_node_paint_equal (node, other)); */

View File

@ -77,8 +77,8 @@ struct _StThemeNode {
GType element_type;
char *element_id;
GStrv element_classes;
GStrv pseudo_classes;
char *element_class;
char *pseudo_class;
char *inline_style;
CRDeclaration **properties;

View File

@ -41,6 +41,7 @@ struct _StThemeNodeTransitionPrivate {
CoglHandle material;
ClutterAlpha *alpha;
ClutterTimeline *timeline;
guint timeline_completed_id;
@ -90,6 +91,7 @@ st_theme_node_transition_new (StThemeNode *from_node,
transition->priv->old_theme_node = g_object_ref (from_node);
transition->priv->new_theme_node = g_object_ref (to_node);
transition->priv->alpha = clutter_alpha_new ();
transition->priv->timeline = clutter_timeline_new (duration);
transition->priv->timeline_completed_id =
@ -99,7 +101,9 @@ st_theme_node_transition_new (StThemeNode *from_node,
g_signal_connect (transition->priv->timeline, "new-frame",
G_CALLBACK (on_timeline_new_frame), transition);
clutter_timeline_set_progress_mode (transition->priv->timeline, CLUTTER_EASE_IN_OUT_QUAD);
clutter_alpha_set_mode (transition->priv->alpha, CLUTTER_EASE_IN_OUT_QUAD);
clutter_alpha_set_timeline (transition->priv->alpha,
transition->priv->timeline);
clutter_timeline_start (transition->priv->timeline);
@ -330,7 +334,7 @@ st_theme_node_transition_paint (StThemeNodeTransition *transition,
}
cogl_color_set_from_4f (&constant, 0., 0., 0.,
clutter_timeline_get_progress (priv->timeline));
clutter_alpha_get_alpha (priv->alpha));
cogl_material_set_layer_combine_constant (priv->material, 1, &constant);
cogl_material_set_color4ub (priv->material,
@ -408,6 +412,12 @@ st_theme_node_transition_dispose (GObject *object)
priv->timeline_completed_id = 0;
priv->timeline_new_frame_id = 0;
if (priv->alpha)
{
g_object_unref (priv->alpha);
priv->alpha = NULL;
}
G_OBJECT_CLASS (st_theme_node_transition_parent_class)->dispose (object);
}
@ -426,6 +436,8 @@ st_theme_node_transition_init (StThemeNodeTransition *transition)
transition->priv->new_offscreen = NULL;
transition->priv->needs_setup = TRUE;
transition->priv->alpha = NULL;
}
static void

View File

@ -96,8 +96,8 @@ st_theme_node_finalize (GObject *object)
StThemeNode *node = ST_THEME_NODE (object);
g_free (node->element_id);
g_strfreev (node->element_classes);
g_strfreev (node->pseudo_classes);
g_free (node->element_class);
g_free (node->pseudo_class);
g_free (node->inline_style);
if (node->properties)
@ -145,33 +145,6 @@ st_theme_node_finalize (GObject *object)
G_OBJECT_CLASS (st_theme_node_parent_class)->finalize (object);
}
static GStrv
split_on_whitespace (const gchar *s)
{
gchar *cur;
gchar *l;
gchar *temp;
GPtrArray *arr;
if (s == NULL)
return NULL;
arr = g_ptr_array_new ();
l = g_strdup (s);
cur = strtok_r (l, " \t\f\r\n", &temp);
while (cur != NULL)
{
g_ptr_array_add (arr, g_strdup (cur));
cur = strtok_r (NULL, " \t\f\r\n", &temp);
}
g_free (l);
g_ptr_array_add (arr, NULL);
return (GStrv) g_ptr_array_free (arr, FALSE);
}
/**
* st_theme_node_new:
* @context: the context representing global state for this themed tree
@ -228,8 +201,8 @@ st_theme_node_new (StThemeContext *context,
node->element_type = element_type;
node->element_id = g_strdup (element_id);
node->element_classes = split_on_whitespace (element_class);
node->pseudo_classes = split_on_whitespace (pseudo_class);
node->element_class = g_strdup (element_class);
node->pseudo_class = g_strdup (pseudo_class);
node->inline_style = g_strdup (inline_style);
return node;
@ -284,30 +257,20 @@ st_theme_node_get_element_id (StThemeNode *node)
return node->element_id;
}
/**
* st_theme_node_get_element_classes:
*
* Returns: (transfer none): the element's classes
*/
GStrv
st_theme_node_get_element_classes (StThemeNode *node)
const char *
st_theme_node_get_element_class (StThemeNode *node)
{
g_return_val_if_fail (ST_IS_THEME_NODE (node), NULL);
return node->element_classes;
return node->element_class;
}
/**
* st_theme_node_get_pseudo_classes:
*
* Returns: (transfer none): the element's pseudo-classes
*/
GStrv
st_theme_node_get_pseudo_classes (StThemeNode *node)
const char *
st_theme_node_get_pseudo_class (StThemeNode *node)
{
g_return_val_if_fail (ST_IS_THEME_NODE (node), NULL);
return node->pseudo_classes;
return node->pseudo_class;
}
/**
@ -341,91 +304,16 @@ gboolean
st_theme_node_equal (StThemeNode *node_a, StThemeNode *node_b)
{
g_return_val_if_fail (ST_IS_THEME_NODE (node_a), FALSE);
if (node_a == node_b)
return TRUE;
g_return_val_if_fail (ST_IS_THEME_NODE (node_b), FALSE);
if (node_a->parent_node != node_b->parent_node ||
node_a->context != node_b->context ||
node_a->theme != node_b->theme ||
node_a->element_type != node_b->element_type ||
g_strcmp0 (node_a->element_id, node_b->element_id) ||
g_strcmp0 (node_a->inline_style, node_b->inline_style))
return FALSE;
if ((node_a->element_classes == NULL) != (node_b->element_classes == NULL))
return FALSE;
if ((node_a->pseudo_classes == NULL) != (node_b->pseudo_classes == NULL))
return FALSE;
if (node_a->element_classes != NULL)
{
int i;
for (i = 0; ; i++)
{
if (g_strcmp0 (node_a->element_classes[i],
node_b->element_classes[i]))
return FALSE;
if (node_a->element_classes[i] == NULL)
break;
}
}
if (node_a->pseudo_classes != NULL)
{
int i;
for (i = 0; ; i++)
{
if (g_strcmp0 (node_a->pseudo_classes[i],
node_b->pseudo_classes[i]))
return FALSE;
if (node_a->pseudo_classes[i] == NULL)
break;
}
}
return TRUE;
}
guint
st_theme_node_hash (StThemeNode *node)
{
guint hash = GPOINTER_TO_UINT (node->parent_node);
hash = hash * 33 + GPOINTER_TO_UINT (node->context);
hash = hash * 33 + GPOINTER_TO_UINT (node->theme);
hash = hash * 33 + ((guint) node->element_type);
if (node->element_id != NULL)
hash = hash * 33 + g_str_hash (node->element_id);
if (node->inline_style != NULL)
hash = hash * 33 + g_str_hash (node->inline_style);
if (node->element_classes != NULL)
{
gchar **it;
for (it = node->element_classes; *it != NULL; it++)
hash = hash * 33 + g_str_hash (*it) + 1;
}
if (node->pseudo_classes != NULL)
{
gchar **it;
for (it = node->pseudo_classes; *it != NULL; it++)
hash = hash * 33 + g_str_hash (*it) + 1;
}
return hash;
return node_a->parent_node == node_b->parent_node &&
node_a->context == node_b->context &&
node_a->theme == node_b->theme &&
node_a->element_type == node_b->element_type &&
!g_strcmp0 (node_a->element_id, node_b->element_id) &&
!g_strcmp0 (node_a->element_class, node_b->element_class) &&
!g_strcmp0 (node_a->pseudo_class, node_b->pseudo_class) &&
!g_strcmp0 (node_a->inline_style, node_b->inline_style);
}
static void
@ -3552,10 +3440,6 @@ st_theme_node_geometry_equal (StThemeNode *node,
StSide side;
g_return_val_if_fail (ST_IS_THEME_NODE (node), FALSE);
if (node == other)
return TRUE;
g_return_val_if_fail (ST_IS_THEME_NODE (other), FALSE);
_st_theme_node_ensure_geometry (node);
@ -3600,10 +3484,6 @@ st_theme_node_paint_equal (StThemeNode *node,
int i;
g_return_val_if_fail (ST_IS_THEME_NODE (node), FALSE);
if (node == other)
return TRUE;
g_return_val_if_fail (ST_IS_THEME_NODE (other), FALSE);
_st_theme_node_ensure_background (node);

View File

@ -110,12 +110,11 @@ StThemeNode *st_theme_node_get_parent (StThemeNode *node);
StTheme *st_theme_node_get_theme (StThemeNode *node);
gboolean st_theme_node_equal (StThemeNode *node_a, StThemeNode *node_b);
guint st_theme_node_hash (StThemeNode *node);
GType st_theme_node_get_element_type (StThemeNode *node);
const char *st_theme_node_get_element_id (StThemeNode *node);
GStrv st_theme_node_get_element_classes (StThemeNode *node);
GStrv st_theme_node_get_pseudo_classes (StThemeNode *node);
const char *st_theme_node_get_element_class (StThemeNode *node);
const char *st_theme_node_get_pseudo_class (StThemeNode *node);
/* Generic getters ... these are not cached so are less efficient. The other
* reason for adding the more specific version is that we can handle the

View File

@ -448,17 +448,25 @@ st_theme_new (const char *application_stylesheet,
static gboolean
string_in_list (GString *stryng,
GStrv list)
const char *list)
{
gchar **it;
const char *cur;
if (list == NULL)
return FALSE;
for (it = list; *it != NULL; it++)
for (cur = list; *cur;)
{
if (!strqcmp (*it, stryng->str, stryng->len))
return TRUE;
while (*cur && cr_utils_is_white_space (*cur))
cur++;
if (strncmp (cur, stryng->str, stryng->len) == 0)
{
cur += stryng->len;
if ((!*cur) || cr_utils_is_white_space (*cur))
return TRUE;
}
/* skip to next whitespace character */
while (*cur && !cr_utils_is_white_space (*cur))
cur++;
}
return FALSE;
@ -469,7 +477,7 @@ pseudo_class_add_sel_matches_style (StTheme *a_this,
CRAdditionalSel *a_add_sel,
StThemeNode *a_node)
{
GStrv node_pseudo_classes;
const char *node_pseudo_class;
g_return_val_if_fail (a_this
&& a_add_sel
@ -479,10 +487,12 @@ pseudo_class_add_sel_matches_style (StTheme *a_this,
&& a_add_sel->content.pseudo->name->stryng->str
&& a_node, FALSE);
node_pseudo_classes = st_theme_node_get_pseudo_classes (a_node);
node_pseudo_class = st_theme_node_get_pseudo_class (a_node);
return string_in_list (a_add_sel->content.pseudo->name->stryng,
node_pseudo_classes);
if (node_pseudo_class == NULL)
return FALSE;
return string_in_list (a_add_sel->content.pseudo->name->stryng, node_pseudo_class);
}
/**
@ -497,7 +507,7 @@ static gboolean
class_add_sel_matches_style (CRAdditionalSel *a_add_sel,
StThemeNode *a_node)
{
GStrv element_classes;
const char *element_class;
g_return_val_if_fail (a_add_sel
&& a_add_sel->type == CLASS_ADD_SELECTOR
@ -506,10 +516,11 @@ class_add_sel_matches_style (CRAdditionalSel *a_add_sel,
&& a_add_sel->content.class_name->stryng->str
&& a_node, FALSE);
element_classes = st_theme_node_get_element_classes (a_node);
element_class = st_theme_node_get_element_class (a_node);
if (element_class == NULL)
return FALSE;
return string_in_list (a_add_sel->content.class_name->stryng,
element_classes);
return string_in_list (a_add_sel->content.class_name->stryng, element_class);
}
/*

View File

@ -316,6 +316,7 @@ st_widget_dispose (GObject *gobject)
if (priv->theme_node)
{
g_object_run_dispose (G_OBJECT (priv->theme_node));
g_object_unref (priv->theme_node);
priv->theme_node = NULL;
}
@ -588,8 +589,6 @@ st_widget_get_theme_node (StWidget *widget)
if (priv->theme_node == NULL)
{
StThemeContext *context;
StThemeNode *tmp_node;
StThemeNode *parent_node = NULL;
ClutterStage *stage = NULL;
ClutterActor *parent;
@ -630,20 +629,16 @@ st_widget_get_theme_node (StWidget *widget)
else
pseudo_class = direction_pseudo_class;
context = st_theme_context_get_for_stage (stage);
tmp_node = st_theme_node_new (context, parent_node, priv->theme,
G_OBJECT_TYPE (widget),
clutter_actor_get_name (CLUTTER_ACTOR (widget)),
priv->style_class,
pseudo_class,
priv->inline_style);
priv->theme_node = st_theme_node_new (st_theme_context_get_for_stage (stage),
parent_node, priv->theme,
G_OBJECT_TYPE (widget),
clutter_actor_get_name (CLUTTER_ACTOR (widget)),
priv->style_class,
pseudo_class,
priv->inline_style);
if (pseudo_class != direction_pseudo_class)
g_free (pseudo_class);
priv->theme_node = g_object_ref (st_theme_context_intern_node (context,
tmp_node));
g_object_unref (tmp_node);
}
return priv->theme_node;
@ -1531,12 +1526,6 @@ st_widget_recompute_style (StWidget *widget,
int transition_duration;
gboolean paint_equal;
if (new_theme_node == old_theme_node)
{
widget->priv->is_style_dirty = FALSE;
return;
}
if (!old_theme_node ||
!st_theme_node_geometry_equal (old_theme_node, new_theme_node))
clutter_actor_queue_relayout ((ClutterActor *) widget);

View File

@ -47,7 +47,7 @@ on_stage_realized (ClutterActor *stage,
gpointer data)
{
recorder = shell_recorder_new (CLUTTER_STAGE (stage));
shell_recorder_set_file_template (recorder, "test-recorder.webm");
shell_recorder_set_file_template (recorder, "test-recorder.ogg");
shell_recorder_record (recorder);
}

View File

@ -18,7 +18,6 @@ TEST_JS = \
interactive/scrolling.js \
interactive/scroll-view-sizing.js \
interactive/table.js \
interactive/test-title.js \
interactive/transitions.js \
testcommon/100-200.svg \
testcommon/200-100.svg \
@ -26,14 +25,11 @@ TEST_JS = \
testcommon/border-image.png \
testcommon/face-plain.png \
testcommon/ui.js \
testcommon/iso3166-test.tab \
testcommon/serviceproviders-test.xml \
unit/format.js \
unit/insertSorted.js \
unit/markup.js \
unit/jsParse.js \
unit/url.js \
unit/mobileProviders.js
unit/url.js
EXTRA_DIST += $(TEST_JS)
TEST_MISC = \

View File

@ -0,0 +1,30 @@
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
const Clutter = imports.gi.Clutter;
const St = imports.gi.St;
const CenterLayout = imports.ui.centerLayout;
const UI = imports.testcommon.ui;
function test() {
let stage = new Clutter.Stage({ user_resizable: true });
UI.init(stage);
////////////////////////////////////////////////////////////////////////////////
let container = new St.Widget({ style: 'border: 2px solid black;',
layout_manager: new CenterLayout.CenterLayout() });
container.add_constraint(new Clutter.BindConstraint({ coordinate: Clutter.BindCoordinate.SIZE, source: stage }));
stage.add_actor(container);
let left = new Clutter.Actor({ background_color: Clutter.Color.get_static(Clutter.StaticColor.RED), width: 300 });
let center = new Clutter.Actor({ background_color: Clutter.Color.get_static(Clutter.StaticColor.BLUE), width: 100 });
let right = new Clutter.Actor({ background_color: Clutter.Color.get_static(Clutter.StaticColor.YELLOW), width: 200 });
container.add_actor(left);
container.add_actor(center);
container.add_actor(right);
UI.main(stage);
}
test();

View File

@ -1,3 +0,0 @@
# Test country list
ES Spain
US United States

View File

@ -1,44 +0,0 @@
<?xml version="1.0"?>
<!-- -*- Mode: XML; tab-width: 2; indent-tabs-mode: t; c-basic-offset: 2 -*- -->
<!DOCTYPE serviceproviders SYSTEM "serviceproviders.2.dtd">
<serviceproviders format="2.0">
<!-- United States -->
<country code="us">
<provider>
<name>AT&amp;T</name>
<gsm>
<network-id mcc="310" mnc="038"/>
<network-id mcc="310" mnc="090"/>
<network-id mcc="310" mnc="150"/>
</gsm>
</provider>
<provider>
<name>Verizon</name>
<gsm>
<network-id mcc="310" mnc="995"/>
<network-id mcc="311" mnc="480"/>
</gsm>
<cdma>
<sid value="2"/>
<sid value="4"/>
<sid value="5"/>
</cdma>
</provider>
</country>
<!-- Spain -->
<country code="es">
<provider>
<name>Movistar (Telefónica)</name>
<gsm>
<network-id mcc="214" mnc="05"/>
<network-id mcc="214" mnc="07"/>
</gsm>
</provider>
</country>
</serviceproviders>

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