Compare commits

..

80 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
2c34c8e20f Overview search box is too subtle
When it isn't focused, the search box can be quite hard to see.

The text/icon/border color is changed to be brighter in order to increase
contrast with the dark background and this works well with various
wallpapers.

https://bugzilla.gnome.org/show_bug.cgi?id=686479
2012-11-01 11:32:40 +00:00
d19fa731d6 Updated Polish translation 2012-10-31 19:15:34 +01:00
59bb1cc387 Add a setting to force the 'Log out' menuitem
I've heard quite a bit of feedback from people who want to log out,
even if they are the sole user on their system. It doesn't seem worth
alienating them over this; so add a setting to make the 'Log out' item
always show up.
https://bugzilla.gnome.org/show_bug.cgi?id=686057
2012-10-31 12:46:49 -04:00
56909d0646 Show 'Log out' in more situations
When the current user is a remote account, or a we are logged in
as root, we should always show 'Log out'.

https://bugzilla.gnome.org/show_bug.cgi?id=686736
2012-10-31 12:45:08 -04:00
04da29c939 appMenu: Update on icon theme changes
While we recreate icons on style changes elsewhere, the faded
icon in the application menu will stick around after icon theme
changes until another application is focused.

https://bugzilla.gnome.org/show_bug.cgi?id=687224
2012-10-31 00:06:46 +01:00
307f7a3024 IM status menu: adjust the combo popup background
The transparent background for available/unavailable IM status menu
makes the text difficult to read.

Simplifies that by using the default combo-popup background instead of a
custom one.

https://bugzilla.gnome.org/show_bug.cgi?id=658091
2012-10-30 22:51:50 +00:00
e80bfa39f5 userMenu: Use "offline" instead of "unavailable"
https://bugzilla.gnome.org/show_bug.cgi?id=687226
2012-10-30 23:01:22 +01:00
29714922ea calendar: Drop unnecessary libedataserverui dependency
The libedataserverui dependency is a relic of the old E-D-S API.
As of 3.6.0, E-D-S now centralizes authentication prompts so clients
don't have to display their own.  This also allows trading the GTK+
main loop for a plain GMainLoop in gnome-shell-calendar-server.c.

https://bugzilla.gnome.org/show_bug.cgi?id=687189
2012-10-30 14:18:39 -04:00
88192114ac NetworkAgent: cancel requests when disabling component
When the NetworkAgent is disabled (for example because the lock screen
is being activated), cancel all modal dialogs.

https://bugzilla.gnome.org/show_bug.cgi?id=685239
2012-10-30 16:34:13 +01:00
9d78208b76 NetworkMenu: don't use a global switch for all VPN connections
Stop pretending that VPN is a NMDevice, and split the useful bits into
a NMConnectionBased interface.
Make each connection have its own switch menu item and handle its own
status, and remove the VPN section title, which is no longer needed.

https://bugzilla.gnome.org/show_bug.cgi?id=682929
2012-10-30 16:08:33 +01:00
d817bf0395 theme: standardize the run dialog text styles a bit
Use the standard color for dialog headings, and use the standard
text style for the entry field. These tweaks make the dialog easier
to read.

https://bugzilla.gnome.org/show_bug.cgi?id=687127
2012-10-30 15:50:05 +01:00
4d51056226 runDialog: Remove "Run" button again
While not in the mockups, it was introduced during review of commit
0c807bddaf after discussion on IRC, but the designers disagree;
remove it again.

https://bugzilla.gnome.org/show_bug.cgi?id=687127
2012-10-30 15:50:05 +01:00
a607174a25 runDialog: Add entry to focus chain
Currently the entry takes the intial key focus, but is not actually
part of the focus chain. Fix that, even though keynav does not work
too well for the dialog anyway, due to the entry consuming tab for
command completion.

https://bugzilla.gnome.org/show_bug.cgi?id=687127
2012-10-30 15:50:05 +01:00
37d6a624b7 Improve the button insensitive style
The current insensitive style for buttons needs to be improved. Right
now we just change the text color: this doesn't make it clear that the
button is actually insensitive.

Instead of just changing the text color, we make the button background
almost transparent. We also make the text color the same as the border
color, use a thinner border.

This patch also simplifies some border rule overwrites to emphasis
only the border width is changed on focus, and makes the button look
closer to the mockups.

https://bugzilla.gnome.org/show_bug.cgi?id=687110
2012-10-30 12:35:48 +00:00
0c807bddaf runDialog: Better match style of other modal dialogs
Update the run dialog to
 - use a proper title
 - use dialog buttons
 - use the standard entry style

https://bugzilla.gnome.org/show_bug.cgi?id=687127
2012-10-29 19:12:12 +01:00
a0470bfc66 UnlockDialog: clear the password on failure
It is wrong, and the user can't correct it because it's obfuscated.
Just let him type it again.

https://bugzilla.gnome.org/show_bug.cgi?id=687132
2012-10-29 17:54:12 +01:00
b9463d23e8 ShellUserVerifier: fix fail counter
If it is updated after checking, it counts the number of failures
not including the current one, so it allows one extra attempt. Instead,
by updating it before checking, we get the expected result of dropping the
curtain at the third password.

https://bugzilla.gnome.org/show_bug.cgi?id=687132
2012-10-29 17:54:12 +01:00
04debd1623 LoginDialog: clear previous auth failed messages when trying again
When the user has the entered the password for the second time
and clicked OK, clear messages from the previous attempt, so any
new failure is shown clearly.

https://bugzilla.gnome.org/show_bug.cgi?id=687132
2012-10-29 17:54:11 +01:00
9d31576cf5 App search: Match GenericName too
This is making shell search results more useful in many cases,
such as 'web', 'browser', spreadsheet'.
https://bugzilla.gnome.org/show_bug.cgi?id=687121
2012-10-29 11:24:36 -04:00
8daca28a90 Updated Slovak translation 2012-10-28 19:50:05 +00:00
9899604261 Updated Slovak translation 2012-10-28 18:27:51 +00:00
687e1eabed Overview: Resize the window title labels on content change
Reposition the window overlay when the title changes, using the current
transformed size of the window clone.
Includes a test that changes title to a string of random length every 3 seconds.

Based on a patch by Alex Hultman <alexhultman@gmail.com>

https://bugzilla.gnome.org/show_bug.cgi?id=620874
2012-10-27 18:18:48 +02:00
eb09f34114 recorder: save recorded video as recent item
Often the first thing a user wants to do after making a recording
is post it somewhere.

This commit adds the video to recently used items, so that it shows
up prominently in open file choosers.

https://bugzilla.gnome.org/show_bug.cgi?id=680647
2012-10-26 13:29:30 -04:00
fbeb446ed7 recorder: rename "filename" property to "file-template"
The filename property is actually a template string with
substitution variables, not a filename.

This commit renames for clarity.

https://bugzilla.gnome.org/show_bug.cgi?id=680647
2012-10-26 13:29:30 -04:00
92033ce0f5 recorder: keep test-recorder alive until done recording
Recording continues for some time after the recorder object
is closed, since closing isn't a synchronous operation.

This commit defers quiting the test-recorder application until
the recording is finished.

https://bugzilla.gnome.org/show_bug.cgi?id=680647
2012-10-26 13:29:30 -04:00
9171bab5e5 recorder: keep recorder object alive until pipeline finishes
We want to make sure the recorder isn't finalized until the
saved recording hits disk.  This means the pipeline object needs
a hard reference on the recorder.

https://bugzilla.gnome.org/show_bug.cgi?id=680647
2012-10-26 13:29:30 -04:00
f9819eb7b0 recorder: Clean up stage lifetime handling
The stage is a floating object. We don't own a reference
to it, so we shouldn't unref it.

This commit removes the erroneous unref call and makes sure
we call clutter_actor_destroy on the stage when we're done
with it.

https://bugzilla.gnome.org/show_bug.cgi?id=680647
2012-10-26 13:29:30 -04:00
85728f0d15 layout: Use a MetaBackgroundActor, not a custom ClutterX11TexturePixmap
While looking at how the plymouth implementation was built, I was so
short-sighted and focused on the string "_XROOTPMAP_ID" that I didn't
realize it was the name of the standard background on the root window.
Remove our own implementation, and switch to using a standard mutter
MetaBackgroundActor.

https://bugzilla.gnome.org/show_bug.cgi?id=682428
2012-10-26 11:54:25 -04:00
9396849d56 message-tray: Restore Fittsability of summary items
The reactive area of tray items should extend to the screen edge. This
regressed when implementing the new tray design, make it work again.

https://bugzilla.gnome.org/show_bug.cgi?id=686474
2012-10-26 16:32:07 +02:00
6f5e5672bb panelMenu: Fix exception when destroying menuless button
There's explicit API to create PanelMenu.Buttons with no menu, so
guard against this case in destroy().

https://bugzilla.gnome.org/show_bug.cgi?id=686763
2012-10-26 15:49:26 +02:00
b936e60876 screenShield: Tweak curtain animation timings
Rationale:
 - Getting something out of the way should be quick;

 - Very few things in the real world move linearly so, linear
   animations, especially for something as big and visible as this,
   felt too artificial;

 - Moving the curtain out should start slower to make it feel like
   having weight (it fills the whole screen after all) but quickly
   accelerate towards the end to make it snappy too.

https://bugzilla.gnome.org/show_bug.cgi?id=686745
2012-10-26 12:56:17 +02:00
fa4bd91213 build: Stop linking gnome-desktop
Since commit 80eac7370e removed the last build-time dependency ages
ago, we only use GnomeDesktop via introspection.
2012-10-26 12:37:33 +02:00
81eeef7d3c messageTray: Hide summary notification immediately when closing the tray
When the summary notification is open when the tray is closed, we end
up with two concurrent animations: the notification fading out, and the
tray moving away from underneath it. Sliding out the tray should be the
primary transition here, so hide the notification immediately to not
draw the user's attention away from it.

https://bugzilla.gnome.org/show_bug.cgi?id=686888
2012-10-25 22:45:36 +02:00
a7b5134820 messageTray: Hide notification close button immediately on click
Having the close button move away from under the pointer after
clicking it is confusing and distracts from the main transition,
which is hiding the notification. Just hide it immediately.

https://bugzilla.gnome.org/show_bug.cgi?id=682237
2012-10-25 22:41:32 +02:00
92a01c67ba messageTray: Don't destroy the notification when clicking on the close button
Clicking on the close button should simply hide the notification.

https://bugzilla.gnome.org/show_bug.cgi?id=682237
2012-10-25 22:41:32 +02:00
71c23613b5 messageTray: Only hide the notification stack on clicking close
Rather than destroying the entire source, which is unintuitive, simply
close the notification. Removing the entire source is still possible
by right-clicking on the summary item and choosing "Remove".

https://bugzilla.gnome.org/show_bug.cgi?id=682237
2012-10-25 22:41:05 +02:00
4f876995de messageTray: make SummaryItem._closeButton public
Use this to show/hide the close button instead of closeButtonVisible.

https://bugzilla.gnome.org/show_bug.cgi?id=682237
2012-10-25 21:45:18 +02:00
9cf4a76196 po: Enforce RTL in fa/ug for messages that might end up as LTR
See commit 8b796d80a7.

https://bugzilla.gnome.org/show_bug.cgi?id=686630
2012-10-25 20:12:25 +02:00
9efe5287e4 gdm: Move logo into the panel
GDM has a 'logo' key in its schema to allow distributors to add
some branding. It is currently placed above the user list, which
no longer works too well since the login screen lost its dialog
window. Display the logo in the top-left corner instead of the
Activities button instead.

https://bugzilla.gnome.org/show_bug.cgi?id=685852
2012-10-25 18:31:16 +02:00
8c4b34de4e messageTray: Fix close button position in RTL locales 2012-10-25 18:31:16 +02:00
93e3559dc3 style: Adjust close button overlap
After changing the button size, we need to adjust the x-offset by
1px (apparently the y-offset already assumed the correct size).
2012-10-25 18:31:16 +02:00
caa0f63e1f style: Fix close button size
The image is actually 32px, so we end up with a slightly fuzzy
button when scaling up to 34px. Don't do that.

Spotted by lamefun.xOr<at>gmail.com

https://bugzilla.gnome.org/show_bug.cgi?id=686574
2012-10-25 18:27:59 +02:00
a4e29e1244 calendar: Handle calendar-server errors
The current code assumes that the GetEvents call will always
receive, causing an exception in the error case.

https://bugzilla.gnome.org/show_bug.cgi?id=686805
2012-10-24 18:26:03 +02:00
599f2f43e3 Revert "screenShield: Connect to the actor's show signal instead of using BEFORE_REDRAW"
This reverts commit bdeb7d86b6.

git bz PEBKAC
2012-10-24 10:17:43 -04:00
3a453c5f73 messageTray: Fix lightbox
Commit 448517032e accidentally reverted the condition for showing
the lightbox. Fix that.

https://bugzilla.gnome.org/show_bug.cgi?id=686728
2012-10-24 09:03:12 +02:00
98b313c75f popupMenu: Overwrite ongoing animations when calling close repeatedly
Currently close() is a no-op when the menu has already been closed.
However, repeated calls could pass different animation parameters.
For instance in the user menu, we try to hide the menu immediately
before locking the screen, to avoid the popup jumping across the
screen while fading out - as we do this from the corresponding
item's activate handler, the closing is still animated if the menu's
own handler (which requests a full animation) is run first.
Fix this by changing close() to overwrite ongoing animations before
bailing out early.

https://bugzilla.gnome.org/show_bug.cgi?id=686484
2012-10-23 22:21:45 +02:00
8b796d80a7 po: Enforce RTL in he for messages that might end up as LTR
As the messages start with a string placeholder that might be
untranslated, we need an explicit mark to ensure that the string
does not end up as LTR.

https://bugzilla.gnome.org/show_bug.cgi?id=686630
2012-10-23 22:21:45 +02:00
49 changed files with 1980 additions and 1274 deletions

View File

@ -52,7 +52,7 @@ AC_MSG_CHECKING([for GStreamer (needed for recording functionality)])
if $PKG_CONFIG --exists gstreamer-1.0 '>=' $GSTREAMER_MIN_VERSION ; then if $PKG_CONFIG --exists gstreamer-1.0 '>=' $GSTREAMER_MIN_VERSION ; then
AC_MSG_RESULT(yes) AC_MSG_RESULT(yes)
build_recorder=true build_recorder=true
recorder_modules="gstreamer-1.0 gstreamer-base-1.0 x11" recorder_modules="gstreamer-1.0 gstreamer-base-1.0 x11 gtk+-3.0"
PKG_CHECK_MODULES(TEST_SHELL_RECORDER, $recorder_modules clutter-1.0 xfixes gl) PKG_CHECK_MODULES(TEST_SHELL_RECORDER, $recorder_modules clutter-1.0 xfixes gl)
else else
AC_MSG_RESULT(no) AC_MSG_RESULT(no)
@ -97,8 +97,7 @@ PKG_CHECK_MODULES(GNOME_SHELL, gio-unix-2.0 >= $GIO_MIN_VERSION
telepathy-logger-0.2 >= $TELEPATHY_LOGGER_MIN_VERSION telepathy-logger-0.2 >= $TELEPATHY_LOGGER_MIN_VERSION
polkit-agent-1 >= $POLKIT_MIN_VERSION xfixes polkit-agent-1 >= $POLKIT_MIN_VERSION xfixes
libnm-glib libnm-util gnome-keyring-1 libnm-glib libnm-util gnome-keyring-1
gcr-3 >= $GCR_MIN_VERSION gcr-3 >= $GCR_MIN_VERSION)
gnome-desktop-3.0 >= $GNOME_DESKTOP_REQUIRED_VERSION)
PKG_CHECK_MODULES(SHELL_PERF_HELPER, gtk+-3.0 gio-2.0) PKG_CHECK_MODULES(SHELL_PERF_HELPER, gtk+-3.0 gio-2.0)
@ -139,7 +138,7 @@ PKG_CHECK_EXISTS([gnome-bluetooth-1.0 >= 3.1.0],
AC_SUBST([HAVE_BLUETOOTH],[0]) AC_SUBST([HAVE_BLUETOOTH],[0])
AC_MSG_RESULT([no])]) AC_MSG_RESULT([no])])
PKG_CHECK_MODULES(CALENDAR_SERVER, libecal-1.2 >= $LIBECAL_MIN_VERSION libedataserver-1.2 >= $LIBEDATASERVER_MIN_VERSION libedataserverui-3.0 >= $LIBEDATASERVERUI_MIN_VERSION gio-2.0) PKG_CHECK_MODULES(CALENDAR_SERVER, libecal-1.2 >= $LIBECAL_MIN_VERSION libedataserver-1.2 >= $LIBEDATASERVER_MIN_VERSION gio-2.0)
AC_SUBST(CALENDAR_SERVER_CFLAGS) AC_SUBST(CALENDAR_SERVER_CFLAGS)
AC_SUBST(CALENDAR_SERVER_LIBS) AC_SUBST(CALENDAR_SERVER_LIBS)

View File

@ -113,9 +113,13 @@
<doc:summary> <doc:summary>
<doc:para> <doc:para>
A dictionary describing the given search result, containing A dictionary describing the given search result, containing
'id', 'name' (both strings) and either 'icon' (a serialized 'id' and 'name' (both strings). Optionally, either 'gicon' (a
GIcon) or 'icon-data' (raw image data as (iiibiiay) - width, serialized GIcon) or 'icon-data' (raw image data as (iiibiiay)
height, rowstride, has-alpha, bits per sample, channels, data) - 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:para>
</doc:summary> </doc:summary>
</doc:doc> </doc:doc>
@ -143,5 +147,25 @@
</doc:doc> </doc:doc>
</arg> </arg>
</method> </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> </interface>
</node> </node>

View File

@ -57,6 +57,14 @@ value here is from the TpConnectionPresenceType enumeration.</_summary>
<_summary>Internally used to store the last session presence status for the user. The <_summary>Internally used to store the last session presence status for the user. The
value here is from the GsmPresenceStatus enumeration.</_summary> value here is from the GsmPresenceStatus enumeration.</_summary>
</key> </key>
<key name="always-show-log-out" type="b">
<default>false</default>
<_summary>Always show the 'Log out' menuitem in the user menu.</_summary>
<_description>
This key overrides the automatic hiding of the 'Log out'
menuitem in single-user, single-session situations.
</_description>
</key>
<child name="calendar" schema="org.gnome.shell.calendar"/> <child name="calendar" schema="org.gnome.shell.calendar"/>
<child name="recorder" schema="org.gnome.shell.recorder"/> <child name="recorder" schema="org.gnome.shell.recorder"/>
<child name="keybindings" schema="org.gnome.shell.keybindings"/> <child name="keybindings" schema="org.gnome.shell.keybindings"/>

View File

@ -39,7 +39,6 @@ stage {
/* small */ /* small */
.app-well-menu, .app-well-menu,
.contact-details-status, .contact-details-status,
.run-dialog-label,
.run-dialog-error-label { .run-dialog-error-label {
font-size: 9pt; font-size: 9pt;
} }
@ -311,7 +310,7 @@ StScrollBar StButton#vhandle:active {
.notification-icon-button:focus, .notification-icon-button:focus,
.hotplug-notification-item:focus, .hotplug-notification-item:focus,
.modal-dialog-button:focus { .modal-dialog-button:focus {
border: 2px solid #8b8b8b; border-width: 2px;
} }
.dash-search-button:active, .dash-search-button:active,
@ -326,17 +325,20 @@ StScrollBar StButton#vhandle:active {
background-gradient-end: rgba(255, 255, 255, 0.2); background-gradient-end: rgba(255, 255, 255, 0.2);
} }
.notification-button:insensitive,
.notification-icon-button:insensitive, .notification-icon-button:insensitive,
.notification-button:insensitive { .modal-dialog-button:insensitive {
border-color: #666666;
color: #9f9f9f; color: #9f9f9f;
background-gradient-direction: none;
background-color: rgba(102, 102, 102, 0.15);
} }
/* Entries */ /* Entries */
#searchEntry, #searchEntry,
.notification StEntry, .notification StEntry,
.login-dialog-prompt-entry, .modal-dialog StEntry {
.prompt-dialog-password-entry {
color: rgb(64, 64, 64); color: rgb(64, 64, 64);
caret-color: rgb(64, 64, 64); caret-color: rgb(64, 64, 64);
font-size: 12pt; font-size: 12pt;
@ -346,6 +348,7 @@ StScrollBar StButton#vhandle:active {
} }
#searchEntry, #searchEntry,
.run-dialog-entry,
.notification StEntry { .notification StEntry {
border: 2px solid rgba(245,245,245,0.2); border: 2px solid rgba(245,245,245,0.2);
background-gradient-start: rgba(5,5,6,0.1); background-gradient-start: rgba(5,5,6,0.1);
@ -358,8 +361,7 @@ StScrollBar StButton#vhandle:active {
#searchEntry:focus, #searchEntry:focus,
#searchEntry:hover, #searchEntry:hover,
.notification StEntry:focus, .notification StEntry:focus,
.login-dialog-prompt-entry, .modal-dialog StEntry {
.prompt-dialog-password-entry {
border: 2px solid rgb(136,138,133); border: 2px solid rgb(136,138,133);
background-gradient-start: rgb(200,200,200); background-gradient-start: rgb(200,200,200);
background-gradient-end: white; background-gradient-end: white;
@ -368,12 +370,17 @@ StScrollBar StButton#vhandle:active {
} }
.notification StEntry:focus, .notification StEntry:focus,
.prompt-dialog-password-entry:focus, .modal-dialog StEntry:focus {
.login-dialog-prompt-entry:focus {
border: 2px solid #3465a4; border: 2px solid #3465a4;
} }
#searchEntry { #searchEntry {
border-color: rgba(245,245,245,0.3);
color: rgb(192, 192, 192);
caret-color: rgb(192, 192, 192);
}
#searchEntry:hover {
color: rgb(128, 128, 128); color: rgb(128, 128, 128);
caret-color: rgb(128, 128, 128); caret-color: rgb(128, 128, 128);
} }
@ -386,8 +393,7 @@ StScrollBar StButton#vhandle:active {
} }
.notification StEntry, .notification StEntry,
.prompt-dialog-password-entry, .modal-dialog StEntry {
.login-dialog-prompt-entry {
border-radius: 5px; border-radius: 5px;
padding: 4px 4px; padding: 4px 4px;
} }
@ -551,7 +557,6 @@ StScrollBar StButton#vhandle:active {
} }
.status-chooser-combo.popup-combo-menu { .status-chooser-combo.popup-combo-menu {
background-color: rgba(0,0,0,0.7);
padding: .4em 0em; padding: .4em 0em;
border-radius: 4px; border-radius: 4px;
border: 1px solid #5f5f5f; border: 1px solid #5f5f5f;
@ -572,6 +577,10 @@ StScrollBar StButton#vhandle:active {
spacing: 40px; spacing: 40px;
} }
#overview-group {
spacing: 12px;
}
.window-caption { .window-caption {
spacing: 25px; spacing: 25px;
} }
@ -614,9 +623,9 @@ StScrollBar StButton#vhandle:active {
.window-close, .notification-close { .window-close, .notification-close {
background-image: url("close-window.svg"); background-image: url("close-window.svg");
background-size: 34px; background-size: 32px;
height: 34px; height: 32px;
width: 34px; width: 32px;
} }
.window-close { .window-close {
@ -627,15 +636,22 @@ StScrollBar StButton#vhandle:active {
/* we start out in the top right of the /* we start out in the top right of the
* notification, inset. * notification, inset.
* *
* center is 32px/2 = 17px * center is 32px/2 = 16px
* *
* adjust left 2px * adjust left 2px
* adjust down 8px */ * adjust down 8px */
-shell-close-overlap-x: 15px; -shell-close-overlap-x: 14px;
-shell-close-overlap-y: -12px; -shell-close-overlap-y: -12px;
} }
.notification-close:rtl {
/* as above, but starting out in the top left of the
* notification. */
-shell-close-overlap-x: -14px;
}
.window-close:rtl { .window-close:rtl {
-st-background-image-shadow: 2px 2px 6px rgba(0,0,0,0.5); -st-background-image-shadow: 2px 2px 6px rgba(0,0,0,0.5);
} }
@ -682,6 +698,11 @@ StScrollBar StButton#vhandle:active {
.search-entry-icon { .search-entry-icon {
icon-size: 1em; icon-size: 1em;
color: #c0c0c0;
}
#searchEntry:hover .search-entry-icon,
#searchEntry:focus .search-entry-icon {
color: #8d8f8a; color: #8d8f8a;
} }
@ -694,7 +715,7 @@ StScrollBar StButton#vhandle:active {
#searchResultsContent { #searchResultsContent {
padding-right: 20px; padding-right: 20px;
spacing: 36px; spacing: 16px;
} }
#searchResultsContent:rtl { #searchResultsContent:rtl {
@ -702,6 +723,25 @@ StScrollBar StButton#vhandle:active {
padding-left: 20px; 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 { .search-section-header {
padding: 4px 12px; padding: 4px 12px;
spacing: 4px; spacing: 4px;
@ -727,6 +767,14 @@ StScrollBar StButton#vhandle:active {
spacing: 4px; 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 /* 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 * padding compensates for this and ensures that the label is vertically
* centered */ * centered */
@ -807,7 +855,10 @@ StScrollBar StButton#vhandle:active {
.app-well-app > .overview-icon, .app-well-app > .overview-icon,
.show-apps > .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; border-radius: 4px;
padding: 3px; padding: 3px;
border: 1px rgba(0,0,0,0); border: 1px rgba(0,0,0,0);
@ -823,7 +874,10 @@ StScrollBar StButton#vhandle:active {
.app-well-app:hover > .overview-icon, .app-well-app:hover > .overview-icon,
.show-apps: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); background-color: rgba(255,255,255,0.1);
text-shadow: black 0px 2px 2px; text-shadow: black 0px 2px 2px;
transition-duration: 100; transition-duration: 100;
@ -858,13 +912,39 @@ StScrollBar StButton#vhandle:active {
} }
.app-well-app:focus > .overview-icon, .app-well-app:focus > .overview-icon,
.search-result-content:focus > .overview-icon,
.show-apps: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, .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); 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 */ /* LookingGlass */
#LookingGlassDialog { #LookingGlassDialog {
@ -1193,7 +1273,6 @@ StScrollBar StButton#vhandle:active {
background: #2e3436 url(message-tray-background.png); background: #2e3436 url(message-tray-background.png);
background-repeat: repeat; background-repeat: repeat;
transition-duration: 250; transition-duration: 250;
height: 72px;
} }
#message-tray:keyboard { #message-tray:keyboard {
@ -1203,7 +1282,7 @@ StScrollBar StButton#vhandle:active {
#message-tray:overview { #message-tray:overview {
background: rgba(0, 0, 0, 0.1); background: rgba(0, 0, 0, 0.1);
border-top: 1px solid rgba(128, 128, 128, 0.3); outline: 1px solid rgba(128, 128, 128, 0.3);
} }
.notification { .notification {
@ -1425,28 +1504,34 @@ StScrollBar StButton#vhandle:active {
} }
#summary-mode { #summary-mode {
padding: 0px 6px 0px 6px; /* same as the values in .summary-source */ height: 72px;
height: 60px;
spacing: 10px;
} }
.summary-source-button { .summary-source-button {
border-radius: 4px; padding: 6px 3px 6px 3px;
transition-duration: 100;
} }
.summary-source-button:hover { .summary-source-button:last-child:ltr {
padding-right: 6px;
}
.summary-source-button:last-child:rtl {
padding-left: 6px;
}
.summary-source-button:hover .summary-source {
background-color: rgba(255,255,255,0.1); background-color: rgba(255,255,255,0.1);
} }
.summary-source-button:focus, .summary-source-button:focus .summary-source,
.summary-source-button:selected { .summary-source-button:selected .summary-source {
background-color: rgba(255,255,255,0.33); background-color: rgba(255,255,255,0.33);
} }
.summary-source { .summary-source {
padding-right: 6px; border-radius: 4px;
padding-left: 6px; padding: 0 6px 0 6px;
transition-duration: 100;
} }
.summary-source-counter { .summary-source-counter {
@ -1624,35 +1709,26 @@ StScrollBar StButton#vhandle:active {
padding: 4px 32px 5px; padding: 4px 32px 5px;
} }
.modal-dialog-button:insensitive {
color: rgb(60, 60, 60);
}
.modal-dialog-button:focus { .modal-dialog-button:focus {
padding: 3px 31px 4px; padding: 3px 31px 4px;
} }
/* Run Dialog */ /* Run Dialog */
.run-dialog-label {
font-size: 12pt;
font-weight: bold;
color: #999999;
padding-bottom: .4em;
}
.run-dialog-error-box { .run-dialog-error-box {
padding-top: 15px; padding-top: 15px;
spacing: 5px; spacing: 5px;
} }
.run-dialog-entry { .modal-dialog .run-dialog-entry {
font-weight: bold; width: 20em;
width: 23em;
selection-background-color: white;
selected-color: black;
}
.run-dialog {
border-radius: 16px;
padding-right: 21px;
padding-left: 21px;
padding-bottom: 15px;
padding-top: 15px;
} }
.lightbox { .lightbox {
@ -2178,24 +2254,20 @@ StScrollBar StButton#vhandle:active {
height: .75em; height: .75em;
} }
.login-dialog .modal-dialog-button { .login-dialog .modal-dialog-button {
border: 1px solid #666666;
border-radius: 5px; border-radius: 5px;
padding: 3px 18px; padding: 3px 18px;
} }
.login-dialog .modal-dialog-button:focus { .login-dialog .modal-dialog-button:focus {
padding: 2px 17px; padding: 2px 17px;
border: 2px solid #8b8b8b;
} }
.login-dialog .modal-dialog-button:default { .login-dialog .modal-dialog-button:default {
background-gradient-start: #6793c4; background-gradient-start: #6793c4;
background-gradient-end: #335d8f; background-gradient-end: #335d8f;
background-gradient-direction: vertical; background-gradient-direction: vertical;
padding: 2px 17px; border-color: #16335d;
border: 2px solid #16335d;
} }
.login-dialog .modal-dialog-button:default:focus { .login-dialog .modal-dialog-button:default:focus {
@ -2213,6 +2285,13 @@ StScrollBar StButton#vhandle:active {
background-gradient-end: #74a0d0; background-gradient-end: #74a0d0;
} }
.login-dialog .modal-dialog-button:default:insensitive {
border-color: #666666;
color: #9f9f9f;
background-gradient-direction: none;
background-color: rgba(102, 102, 102, 0.15);
}
.login-dialog-message-warning { .login-dialog-message-warning {
color: orange; color: orange;
} }

View File

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

View File

@ -39,13 +39,14 @@ const GdmUtil = imports.gdm.util;
const Lightbox = imports.ui.lightbox; const Lightbox = imports.ui.lightbox;
const Main = imports.ui.main; const Main = imports.ui.main;
const ModalDialog = imports.ui.modalDialog; const ModalDialog = imports.ui.modalDialog;
const PanelMenu = imports.ui.panelMenu;
const Tweener = imports.ui.tweener; const Tweener = imports.ui.tweener;
const UserMenu = imports.ui.userMenu; const UserMenu = imports.ui.userMenu;
const _RESIZE_ANIMATION_TIME = 0.25; const _RESIZE_ANIMATION_TIME = 0.25;
const _SCROLL_ANIMATION_TIME = 0.5; const _SCROLL_ANIMATION_TIME = 0.5;
const _TIMED_LOGIN_IDLE_THRESHOLD = 5.0; const _TIMED_LOGIN_IDLE_THRESHOLD = 5.0;
const _LOGO_ICON_NAME_SIZE = 48; const _LOGO_ICON_HEIGHT = 16;
let _loginDialog = null; let _loginDialog = null;
@ -82,6 +83,36 @@ function _smoothlyResizeActor(actor, width, height) {
return hold; return hold;
} }
const LogoMenuButton = new Lang.Class({
Name: 'LogoMenuButton',
Extends: PanelMenu.Button,
_init: function() {
this.parent(0.0, null, true);
this._settings = new Gio.Settings({ schema: GdmUtil.LOGIN_SCREEN_SCHEMA });
this._settings.connect('changed::' + GdmUtil.LOGO_KEY,
Lang.bind(this, this._updateLogo));
this._iconBin = new St.Bin();
this.actor.add_actor(this._iconBin);
this._updateLogo();
},
_updateLogo: function() {
let path = this._settings.get_string(GdmUtil.LOGO_KEY);
let icon = null;
if (path) {
let file = Gio.file_new_for_path(path);
let cache = St.TextureCache.get_default();
icon = cache.load_uri_async(file.get_uri(), -1, _LOGO_ICON_HEIGHT);
}
this._iconBin.set_child(icon);
}
});
const UserListItem = new Lang.Class({ const UserListItem = new Lang.Class({
Name: 'UserListItem', Name: 'UserListItem',
@ -659,17 +690,11 @@ const LoginDialog = new Lang.Class({
this._settings = new Gio.Settings({ schema: GdmUtil.LOGIN_SCREEN_SCHEMA }); this._settings = new Gio.Settings({ schema: GdmUtil.LOGIN_SCREEN_SCHEMA });
this._settings.connect('changed::' + GdmUtil.LOGO_KEY,
Lang.bind(this, this._updateLogo));
this._settings.connect('changed::' + GdmUtil.BANNER_MESSAGE_KEY, this._settings.connect('changed::' + GdmUtil.BANNER_MESSAGE_KEY,
Lang.bind(this, this._updateBanner)); Lang.bind(this, this._updateBanner));
this._settings.connect('changed::' + GdmUtil.BANNER_MESSAGE_TEXT_KEY, this._settings.connect('changed::' + GdmUtil.BANNER_MESSAGE_TEXT_KEY,
Lang.bind(this, this._updateBanner)); Lang.bind(this, this._updateBanner));
this._logoBox = new St.Bin({ style_class: 'login-dialog-logo-box' });
this.contentLayout.add(this._logoBox);
this._updateLogo();
this._bannerLabel = new St.Label({ style_class: 'login-dialog-banner', this._bannerLabel = new St.Label({ style_class: 'login-dialog-banner',
text: '' }); text: '' });
this.contentLayout.add(this._bannerLabel); this.contentLayout.add(this._bannerLabel);
@ -770,20 +795,6 @@ const LoginDialog = new Lang.Class({
}, },
_updateLogo: function() {
this._logoBox.child = null;
let path = this._settings.get_string(GdmUtil.LOGO_KEY);
if (path) {
let file = Gio.file_new_for_path(path);
let uri = file.get_uri();
let textureCache = St.TextureCache.get_default();
this._logoBox.child = textureCache.load_uri_async(uri, -1, _LOGO_ICON_NAME_SIZE);
}
},
_updateBanner: function() { _updateBanner: function() {
let enabled = this._settings.get_boolean(GdmUtil.BANNER_MESSAGE_KEY); let enabled = this._settings.get_boolean(GdmUtil.BANNER_MESSAGE_KEY);
let text = this._settings.get_string(GdmUtil.BANNER_MESSAGE_TEXT_KEY); let text = this._settings.get_string(GdmUtil.BANNER_MESSAGE_TEXT_KEY);
@ -802,8 +813,7 @@ const LoginDialog = new Lang.Class({
let tasks = [this._hidePrompt, let tasks = [this._hidePrompt,
new Batch.ConcurrentBatch(this, [this._fadeInTitleLabel, new Batch.ConcurrentBatch(this, [this._fadeInTitleLabel,
this._fadeInNotListedButton, this._fadeInNotListedButton]),
this._fadeInLogo]),
function() { function() {
this._sessionList.close(); this._sessionList.close();
@ -829,9 +839,13 @@ const LoginDialog = new Lang.Class({
}, },
_showMessage: function(userVerifier, message, styleClass) { _showMessage: function(userVerifier, message, styleClass) {
this._promptMessage.text = message; if (message) {
this._promptMessage.styleClass = styleClass; this._promptMessage.text = message;
GdmUtil.fadeInActor(this._promptMessage); this._promptMessage.styleClass = styleClass;
GdmUtil.fadeInActor(this._promptMessage);
} else {
GdmUtil.fadeOutActor(this._promptMessage);
}
}, },
_showLoginHint: function(verifier, message) { _showLoginHint: function(verifier, message) {
@ -1089,8 +1103,7 @@ const LoginDialog = new Lang.Class({
}, },
new Batch.ConcurrentBatch(this, [this._fadeOutTitleLabel, new Batch.ConcurrentBatch(this, [this._fadeOutTitleLabel,
this._fadeOutNotListedButton, this._fadeOutNotListedButton]),
this._fadeOutLogo]),
function() { function() {
let hold = new Batch.Hold(); let hold = new Batch.Hold();
@ -1103,14 +1116,6 @@ const LoginDialog = new Lang.Class({
batch.run(); batch.run();
}, },
_fadeInLogo: function() {
return GdmUtil.fadeInActor(this._logoBox);
},
_fadeOutLogo: function() {
return GdmUtil.fadeOutActor(this._logoBox);
},
_fadeInBanner: function() { _fadeInBanner: function() {
return GdmUtil.fadeInActor(this._bannerLabel); return GdmUtil.fadeInActor(this._bannerLabel);
}, },
@ -1159,8 +1164,7 @@ const LoginDialog = new Lang.Class({
}, },
new Batch.ConcurrentBatch(this, [this._fadeOutTitleLabel, new Batch.ConcurrentBatch(this, [this._fadeOutTitleLabel,
this._fadeOutNotListedButton, this._fadeOutNotListedButton]),
this._fadeOutLogo]),
function() { function() {
return this._userList.shrinkToNaturalHeight(); return this._userList.shrinkToNaturalHeight();

View File

@ -125,6 +125,9 @@ const ShellUserVerifier = new Lang.Class({
}, },
answerQuery: function(serviceName, answer) { answerQuery: function(serviceName, answer) {
// Clear any previous message
this.emit('show-message', null, null);
this._userVerifier.call_answer_query(serviceName, answer, this._cancellable, null); this._userVerifier.call_answer_query(serviceName, answer, this._cancellable, null);
}, },
@ -330,12 +333,11 @@ const ShellUserVerifier = new Lang.Class({
// Otherwise, we allow ALLOWED_FAILURES attempts. After that, we // Otherwise, we allow ALLOWED_FAILURES attempts. After that, we
// go back to the welcome screen. // go back to the welcome screen.
this._failCounter++;
let canRetry = retry && this._userName && let canRetry = retry && this._userName &&
this._failCounter < this._settings.get_int(ALLOWED_FAILURES_KEY); this._failCounter < this._settings.get_int(ALLOWED_FAILURES_KEY);
if (canRetry) { if (canRetry) {
this._failCounter++;
this.clear(); this.clear();
this.begin(this._userName, new Batch.Hold()); this.begin(this._userName, new Batch.Hold());
} else { } else {

View File

@ -1,6 +1,7 @@
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*- // -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
const Clutter = imports.gi.Clutter; const Clutter = imports.gi.Clutter;
const Gio = imports.gi.Gio;
const GLib = imports.gi.GLib; const GLib = imports.gi.GLib;
const Gtk = imports.gi.Gtk; const Gtk = imports.gi.Gtk;
const GMenu = imports.gi.GMenu; const GMenu = imports.gi.GMenu;
@ -371,6 +372,8 @@ const SettingsSearchProvider = new Lang.Class({
this._appSys = Shell.AppSystem.get_default(); this._appSys = Shell.AppSystem.get_default();
this._gnomecc = this._appSys.lookup_app('gnome-control-center.desktop'); 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) { getResultMetas: function(prefs, callback) {
@ -379,9 +382,7 @@ const SettingsSearchProvider = new Lang.Class({
let pref = prefs[i]; let pref = prefs[i];
metas.push({ 'id': pref, metas.push({ 'id': pref,
'name': pref.get_name(), 'name': pref.get_name(),
'createIcon': function(size) { 'createIcon': function(size) { return; }
return pref.create_icon_texture(size);
}
}); });
} }
callback(metas); callback(metas);
@ -461,15 +462,15 @@ const AppWellIcon = new Lang.Class({
this._draggable.connect('drag-begin', Lang.bind(this, this._draggable.connect('drag-begin', Lang.bind(this,
function () { function () {
this._removeMenuTimeout(); this._removeMenuTimeout();
Main.overview.beginItemDrag(this); Main.overview.beginAppDrag(this);
})); }));
this._draggable.connect('drag-cancelled', Lang.bind(this, this._draggable.connect('drag-cancelled', Lang.bind(this,
function () { function () {
Main.overview.cancelledItemDrag(this); Main.overview.cancelledAppDrag(this);
})); }));
this._draggable.connect('drag-end', Lang.bind(this, this._draggable.connect('drag-end', Lang.bind(this,
function () { function () {
Main.overview.endItemDrag(this); Main.overview.endAppDrag(this);
})); }));
this.actor.connect('destroy', Lang.bind(this, this._onDestroy)); this.actor.connect('destroy', Lang.bind(this, this._onDestroy));

View File

@ -141,6 +141,7 @@ const BoxPointer = new Lang.Class({
this._muteInput(); this._muteInput();
Tweener.removeTweens(this);
Tweener.addTween(this, { opacity: fade ? 0 : 255, Tweener.addTween(this, { opacity: fade ? 0 : 255,
xOffset: xOffset, xOffset: xOffset,
yOffset: yOffset, yOffset: yOffset,

View File

@ -270,8 +270,9 @@ const DBusEventSource = new Lang.Class({
this._loadEvents(false); this._loadEvents(false);
}, },
_onEventsReceived: function([appointments]) { _onEventsReceived: function(results, error) {
let newEvents = []; let newEvents = [];
let appointments = results ? results[0] : null;
if (appointments != null) { if (appointments != null) {
for (let n = 0; n < appointments.length; n++) { for (let n = 0; n < appointments.length; n++) {
let a = appointments[n]; let a = appointments[n];

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

@ -408,7 +408,10 @@ const VPNRequestHandler = new Lang.Class({
} }
}, },
cancel: function() { cancel: function(respond) {
if (respond)
this._agent.respond(this._requestId, Shell.NetworkAgentResponse.USER_CANCELED);
if (this._newStylePlugin && this._shellDialog) { if (this._newStylePlugin && this._shellDialog) {
this._shellDialog.close(global.get_current_time()); this._shellDialog.close(global.get_current_time());
this._shellDialog.destroy(); this._shellDialog.destroy();
@ -599,6 +602,16 @@ const NetworkAgent = new Lang.Class({
}, },
disable: function() { disable: function() {
let requestId;
for (requestId in this._dialogs)
this._dialogs[requestId].cancel();
this._dialogs = { };
for (requestId in this._vpnRequests)
this._vpnRequests[requestId].cancel(true);
this._vpnRequests = { };
this._native.unregister(); this._native.unregister();
}, },
@ -622,7 +635,7 @@ const NetworkAgent = new Lang.Class({
this._dialogs[requestId].destroy(); this._dialogs[requestId].destroy();
delete this._dialogs[requestId]; delete this._dialogs[requestId];
} else if (this._vpnRequests[requestId]) { } else if (this._vpnRequests[requestId]) {
this._vpnRequests[requestId].cancel(); this._vpnRequests[requestId].cancel(false);
delete this._vpnRequests[requestId]; delete this._vpnRequests[requestId];
} }
}, },

View File

@ -41,7 +41,7 @@ const Recorder = new Lang.Class({
recorder.set_framerate(this._recorderSettings.get_int('framerate')); recorder.set_framerate(this._recorderSettings.get_int('framerate'));
/* Translators: this is a filename used for screencast recording */ /* Translators: this is a filename used for screencast recording */
// xgettext:no-c-format // xgettext:no-c-format
recorder.set_filename(_("Screencast from %d %t") + '.' + this._recorderSettings.get_string('file-extension')); recorder.set_file_template(_("Screencast from %d %t") + '.' + this._recorderSettings.get_string('file-extension'));
let pipeline = this._recorderSettings.get_string('pipeline'); let pipeline = this._recorderSettings.get_string('pipeline');
if (!pipeline.match(/^\s*$/)) if (!pipeline.match(/^\s*$/))

View File

@ -372,6 +372,9 @@ const Dash = new Lang.Class({
this._maxHeight = -1; this._maxHeight = -1;
this.iconSize = 64; this.iconSize = 64;
this._shownInitially = false; this._shownInitially = false;
this.visible = false;
this._hiddenX;
this._targetX;
this._dragPlaceholder = null; this._dragPlaceholder = null;
this._dragPlaceholderPos = -1; this._dragPlaceholderPos = -1;
@ -399,7 +402,8 @@ const Dash = new Lang.Class({
function() { function() {
if (this._maxHeight != this.actor.height) if (this._maxHeight != this.actor.height)
this._queueRedisplay(); 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)); this._workId = Main.initializeDeferredWork(this._box, Lang.bind(this, this._redisplay));
@ -410,11 +414,11 @@ const Dash = new Lang.Class({
AppFavorites.getAppFavorites().connect('changed', Lang.bind(this, this._queueRedisplay)); AppFavorites.getAppFavorites().connect('changed', Lang.bind(this, this._queueRedisplay));
this._appSystem.connect('app-state-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)); Lang.bind(this, this._onDragBegin));
Main.overview.connect('item-drag-end', Main.overview.connect('app-drag-end',
Lang.bind(this, this._onDragEnd)); Lang.bind(this, this._onDragEnd));
Main.overview.connect('item-drag-cancelled', Main.overview.connect('app-drag-cancelled',
Lang.bind(this, this._onDragCancelled)); Lang.bind(this, this._onDragCancelled));
Main.overview.connect('window-drag-begin', Main.overview.connect('window-drag-begin',
Lang.bind(this, this._onDragBegin)); Lang.bind(this, this._onDragBegin));
@ -546,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() { _adjustIconSize: function() {
// For the icon size, we only consider children which are "proper" // For the icon size, we only consider children which are "proper"
// icons (i.e. ignoring drag placeholders) and which are not // icons (i.e. ignoring drag placeholders) and which are not
@ -641,6 +656,8 @@ const Dash = new Lang.Class({
} }
}); });
} }
this._computeDashX();
}, },
_redisplay: function () { _redisplay: function () {
@ -757,6 +774,7 @@ const Dash = new Lang.Class({
// of items, to avoid all items zooming in at once // of items, to avoid all items zooming in at once
if (!this._shownInitially) { if (!this._shownInitially) {
this._shownInitially = true; this._shownInitially = true;
this.visible = true;
return; return;
} }
@ -901,6 +919,34 @@ const Dash = new Lang.Class({
})); }));
return true; 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

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

View File

@ -104,7 +104,7 @@ const LayoutManager = new Lang.Class({
this.primaryMonitor = null; this.primaryMonitor = null;
this.primaryIndex = -1; this.primaryIndex = -1;
this._hotCorners = []; this._hotCorners = [];
this._rootPixmap = null; this._background = null;
this._leftPanelBarrier = 0; this._leftPanelBarrier = 0;
this._rightPanelBarrier = 0; this._rightPanelBarrier = 0;
this._trayBarrier = 0; this._trayBarrier = 0;
@ -333,30 +333,30 @@ const LayoutManager = new Lang.Class({
// to the greeter. Otherwise, we'll just animate the panel, // to the greeter. Otherwise, we'll just animate the panel,
// as usual. // as usual.
if (Main.sessionMode.isGreeter) { if (Main.sessionMode.isGreeter) {
this._rootPixmap = global.create_xrootpmap_texture(); this._background = Meta.BackgroundActor.new_for_screen(global.screen);
if (this._rootPixmap != null) { if (this._background != null) {
Main.uiGroup.add_actor(this._rootPixmap); Main.uiGroup.add_actor(this._background);
Tweener.addTween(this._rootPixmap, Tweener.addTween(this._background,
{ opacity: 0, { opacity: 0,
time: PLYMOUTH_TRANSITION_TIME, time: PLYMOUTH_TRANSITION_TIME,
transition: 'linear', transition: 'linear',
onComplete: this._fadeRootpmapComplete, onComplete: this._fadeBackgroundComplete,
onCompleteScope: this }); onCompleteScope: this });
plymouthTransitionRunning = true; plymouthTransitionRunning = true;
} }
} }
if (!plymouthTransitionRunning) if (!plymouthTransitionRunning)
this._fadeRootpmapComplete(); this._fadeBackgroundComplete();
}, },
_fadeRootpmapComplete: function() { _fadeBackgroundComplete: function() {
// Don't animate the strut // Don't animate the strut
this._chrome.freezeUpdateRegions(); this._chrome.freezeUpdateRegions();
if (this._rootPixmap != null) { if (this._background != null) {
this._rootPixmap.destroy(); this._background.destroy();
this._rootPixmap = null; this._background = null;
} }
Tweener.addTween(this.panelBox, Tweener.addTween(this.panelBox,

View File

@ -1237,12 +1237,6 @@ const SummaryItem = new Lang.Class({
this.notificationStackWidget = new St.Widget({ layout_manager: new Clutter.BinLayout() }); this.notificationStackWidget = new St.Widget({ layout_manager: new Clutter.BinLayout() });
this._closeButton = makeCloseButton();
this._closeButton.connect('clicked', Lang.bind(this, function() {
source.destroy();
source.emit('done-displaying-content');
}));
this.notificationStackView = new St.ScrollView({ style_class: source.isChat ? '' : 'summary-notification-stack-scrollview', this.notificationStackView = new St.ScrollView({ style_class: source.isChat ? '' : 'summary-notification-stack-scrollview',
vscrollbar_policy: source.isChat ? Gtk.PolicyType.NEVER : Gtk.PolicyType.AUTOMATIC, vscrollbar_policy: source.isChat ? Gtk.PolicyType.NEVER : Gtk.PolicyType.AUTOMATIC,
hscrollbar_policy: Gtk.PolicyType.NEVER }); hscrollbar_policy: Gtk.PolicyType.NEVER });
@ -1251,7 +1245,9 @@ const SummaryItem = new Lang.Class({
vertical: true }); vertical: true });
this.notificationStackView.add_actor(this.notificationStack); this.notificationStackView.add_actor(this.notificationStack);
this.notificationStackWidget.add_actor(this.notificationStackView); this.notificationStackWidget.add_actor(this.notificationStackView);
this.notificationStackWidget.add_actor(this._closeButton);
this.closeButton = makeCloseButton();
this.notificationStackWidget.add_actor(this.closeButton);
this._stackedNotifications = []; this._stackedNotifications = [];
this._oldMaxScrollAdjustment = 0; this._oldMaxScrollAdjustment = 0;
@ -1268,14 +1264,6 @@ const SummaryItem = new Lang.Class({
global.focus_manager.add_group(this.rightClickMenu); global.focus_manager.add_group(this.rightClickMenu);
}, },
get closeButtonVisible() {
return this._closeButton.visible;
},
set closeButtonVisible(v) {
this._closeButton.visible = v;
},
_onKeyPress: function(actor, event) { _onKeyPress: function(actor, event) {
if (event.get_key_symbol() == Clutter.KEY_Up) { if (event.get_key_symbol() == Clutter.KEY_Up) {
actor.emit('clicked', 1); actor.emit('clicked', 1);
@ -1510,7 +1498,7 @@ const MessageTray = new Lang.Class({
this._overviewVisible = true; this._overviewVisible = true;
this._grabHelper.ungrab(); // drop modal grab if necessary this._grabHelper.ungrab(); // drop modal grab if necessary
this.actor.add_style_pseudo_class('overview'); this.actor.add_style_pseudo_class('overview');
this._updateState(); this.show();
})); }));
Main.overview.connect('hiding', Lang.bind(this, Main.overview.connect('hiding', Lang.bind(this,
function() { function() {
@ -1603,12 +1591,9 @@ const MessageTray = new Lang.Class({
_onCloseClicked: function() { _onCloseClicked: function() {
if (this._notificationState == State.SHOWN) { if (this._notificationState == State.SHOWN) {
this._closeButton.hide();
this._notificationClosed = true; this._notificationClosed = true;
this._notification.emit('done-displaying'); this._updateState();
if (!this._notification.resident)
this._notification.destroy();
this._notificationClosed = false; this._notificationClosed = false;
} }
}, },
@ -1751,6 +1736,11 @@ const MessageTray = new Lang.Class({
this._updateState(); this._updateState();
}, },
show: function() {
this._traySummoned = true;
this._updateState();
},
_onNotify: function(source, notification) { _onNotify: function(source, notification) {
if (this._summaryBoxPointerItem && this._summaryBoxPointerItem.source == source) { if (this._summaryBoxPointerItem && this._summaryBoxPointerItem.source == source) {
if (this._summaryBoxPointerState == State.HIDING) { if (this._summaryBoxPointerState == State.HIDING) {
@ -1993,7 +1983,7 @@ const MessageTray = new Lang.Class({
} }
// Summary // Summary
let summarySummoned = this._pointerInSummary || this._overviewVisible || this._traySummoned; let summarySummoned = this._pointerInSummary || this._traySummoned;
let summaryPinned = this._pointerInTray || summarySummoned || this._locked; let summaryPinned = this._pointerInTray || summarySummoned || this._locked;
let summaryHovered = this._pointerInTray || this._pointerInSummary; let summaryHovered = this._pointerInTray || this._pointerInSummary;
@ -2001,7 +1991,7 @@ const MessageTray = new Lang.Class({
this._notificationState == State.SHOWN); this._notificationState == State.SHOWN);
let notificationsDone = !notificationsVisible && !notificationsPending; let notificationsDone = !notificationsVisible && !notificationsPending;
let summaryOptionalInOverview = this._overviewVisible && !this._locked && !summaryHovered; let summaryOptionalInOverview = !this._locked && !summaryHovered;
let mustHideSummary = (notificationsPending && (notificationUrgent || summaryOptionalInOverview)) let mustHideSummary = (notificationsPending && (notificationUrgent || summaryOptionalInOverview))
|| notificationsVisible || !Main.sessionMode.hasNotifications; || notificationsVisible || !Main.sessionMode.hasNotifications;
@ -2101,9 +2091,8 @@ const MessageTray = new Lang.Class({
transition: 'easeOutQuad' transition: 'easeOutQuad'
}); });
if (this._overviewVisible) { if (!this._overviewVisible)
this._lightbox.show(); this._lightbox.show();
}
return true; return true;
}, },
@ -2141,6 +2130,10 @@ const MessageTray = new Lang.Class({
}, },
_hideTray: function() { _hideTray: function() {
// Having the summary item animate out while sliding down the tray
// is distracting, so hide it immediately in case it was visible.
this._summaryBoxPointer.actor.hide();
this._tween(this.actor, '_trayState', State.HIDDEN, this._tween(this.actor, '_trayState', State.HIDDEN,
{ y: 0, { y: 0,
time: ANIMATION_TIME, time: ANIMATION_TIME,
@ -2420,7 +2413,10 @@ const MessageTray = new Lang.Class({
this._notificationQueue = newQueue; this._notificationQueue = newQueue;
this._summaryBoxPointer.bin.child = this._summaryBoxPointerItem.notificationStackWidget; this._summaryBoxPointer.bin.child = this._summaryBoxPointerItem.notificationStackWidget;
this._summaryBoxPointerItem.closeButtonVisible = true;
let closeButton = this._summaryBoxPointerItem.closeButton;
closeButton.show();
this._summaryBoxPointerCloseClickedId = closeButton.connect('clicked', Lang.bind(this, this._hideSummaryBoxPointer));
this._summaryBoxPointerItem.prepareNotificationStackForShowing(); this._summaryBoxPointerItem.prepareNotificationStackForShowing();
} else if (this._clickedSummaryItemMouseButton == 3) { } else if (this._clickedSummaryItemMouseButton == 3) {
this._summaryBoxPointer.bin.child = this._clickedSummaryItem.rightClickMenu; this._summaryBoxPointer.bin.child = this._clickedSummaryItem.rightClickMenu;
@ -2530,6 +2526,8 @@ const MessageTray = new Lang.Class({
this._summaryBoxPointer.bin.child = null; this._summaryBoxPointer.bin.child = null;
this._summaryBoxPointerItem.disconnect(this._summaryBoxPointerContentUpdatedId); this._summaryBoxPointerItem.disconnect(this._summaryBoxPointerContentUpdatedId);
this._summaryBoxPointerContentUpdatedId = 0; this._summaryBoxPointerContentUpdatedId = 0;
this._summaryBoxPointerItem.closeButton.disconnect(this._summaryBoxPointerCloseClickedId);
this._summaryBoxPointerCloseClickedId = 0;
this._summaryBoxPointerItem.source.disconnect(this._sourceDoneDisplayingId); this._summaryBoxPointerItem.source.disconnect(this._sourceDoneDisplayingId);
this._summaryBoxPointerDoneDisplayingId = 0; this._summaryBoxPointerDoneDisplayingId = 0;

View File

@ -10,6 +10,7 @@ const St = imports.gi.St;
const Shell = imports.gi.Shell; const Shell = imports.gi.Shell;
const Gdk = imports.gi.Gdk; const Gdk = imports.gi.Gdk;
const CenterLayout = imports.ui.centerLayout;
const Dash = imports.ui.dash; const Dash = imports.ui.dash;
const DND = imports.ui.dnd; const DND = imports.ui.dnd;
const Main = imports.ui.main; const Main = imports.ui.main;
@ -23,9 +24,6 @@ const WorkspaceThumbnail = imports.ui.workspaceThumbnail;
// Time for initial animation going into Overview mode // Time for initial animation going into Overview mode
const ANIMATION_TIME = 0.25; const ANIMATION_TIME = 0.25;
// XXX -- grab this automatically. Hard to do.
const DASH_MAX_WIDTH = 96;
const DND_WINDOW_SWITCH_TIMEOUT = 1250; const DND_WINDOW_SWITCH_TIMEOUT = 1250;
const SwipeScrollDirection = { const SwipeScrollDirection = {
@ -119,23 +117,18 @@ const Overview = new Lang.Class({
this._desktopFade = new St.Bin(); this._desktopFade = new St.Bin();
global.overlay_group.add_actor(this._desktopFade); global.overlay_group.add_actor(this._desktopFade);
this._spacing = 0;
/* Translators: This is the main view to select /* Translators: This is the main view to select
activities. See also note for "Activities" string. */ activities. See also note for "Activities" string. */
this._group = new St.Widget({ name: 'overview', this._overview = new St.BoxLayout({ name: 'overview',
accessible_name: _("Overview"), accessible_name: _("Overview"),
reactive: true }); reactive: true,
this._group._delegate = this; vertical: true });
this._group.connect('style-changed', this._overview._delegate = this;
Lang.bind(this, function() {
let node = this._group.get_theme_node(); let layout = new CenterLayout.CenterLayout();
let spacing = node.get_length('spacing'); CenterLayout.connectSpacing(layout);
if (spacing != this._spacing) { this._group = new St.Widget({ name: 'overview-group',
this._spacing = spacing; layout_manager: layout });
this._relayout();
}
}));
this._scrollDirection = SwipeScrollDirection.NONE; this._scrollDirection = SwipeScrollDirection.NONE;
this._scrollAdjustment = null; this._scrollAdjustment = null;
@ -148,18 +141,19 @@ const Overview = new Lang.Class({
this._modal = false; // have a modal grab this._modal = false; // have a modal grab
this.animationInProgress = false; this.animationInProgress = false;
this._hideInProgress = false; this._hideInProgress = false;
this.searchActive = false;
this.appsActive = false;
// During transitions, we raise this to the top to avoid having the overview // 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 // area be reactive; it causes too many issues such as double clicks on
// Dash elements, or mouseover handlers in the workspaces. // Dash elements, or mouseover handlers in the workspaces.
this._coverPane = new Clutter.Rectangle({ opacity: 0, this._coverPane = new Clutter.Rectangle({ opacity: 0,
reactive: true }); 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._coverPane.connect('event', Lang.bind(this, function (actor, event) { return true; }));
this._overview.hide();
this._group.hide(); global.overlay_group.add_actor(this._overview);
global.overlay_group.add_actor(this._group);
this._coverPane.hide(); this._coverPane.hide();
@ -171,6 +165,8 @@ const Overview = new Lang.Class({
Main.xdndHandler.connect('drag-begin', Lang.bind(this, this._onDragBegin)); Main.xdndHandler.connect('drag-begin', Lang.bind(this, this._onDragBegin));
Main.xdndHandler.connect('drag-end', Lang.bind(this, this._onDragEnd)); Main.xdndHandler.connect('drag-end', Lang.bind(this, this._onDragEnd));
global.screen.connect('restacked', Lang.bind(this, this._onRestacked));
this._windowSwitchTimeoutId = 0; this._windowSwitchTimeoutId = 0;
this._windowSwitchTimestamp = 0; this._windowSwitchTimestamp = 0;
this._lastActiveWorkspaceIndex = -1; this._lastActiveWorkspaceIndex = -1;
@ -193,6 +189,13 @@ const Overview = new Lang.Class({
this._shellInfo = new ShellInfo(); 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', this._searchEntry = new St.Entry({ name: 'searchEntry',
/* Translators: this is the text displayed /* Translators: this is the text displayed
in the search entry when no search is in the search entry when no search is
@ -201,16 +204,13 @@ const Overview = new Lang.Class({
hint_text: _("Type to search..."), hint_text: _("Type to search..."),
track_hover: true, track_hover: true,
can_focus: true }); can_focus: true });
this._group.add_actor(this._searchEntry); this._searchEntryBin = new St.Bin({ child: this._searchEntry,
x_align: St.Align.MIDDLE });
this._dash = new Dash.Dash(); this._overview.add_actor(this._searchEntryBin);
this._viewSelector = new ViewSelector.ViewSelector(this._searchEntry,
this._dash.showAppsButton);
this._group.add_actor(this._viewSelector.actor);
this._group.add_actor(this._dash.actor);
// TODO - recalculate everything when desktop size changes // 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.dashIconSize = this._dash.iconSize;
this._dash.connect('icon-size-changed', this._dash.connect('icon-size-changed',
Lang.bind(this, function() { Lang.bind(this, function() {
@ -221,6 +221,82 @@ const Overview = new Lang.Class({
// the left of the overview // the left of the overview
Main.ctrlAltTabManager.addGroup(this._dash.actor, _("Dash"), 'user-bookmarks-symbolic'); 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)); Main.layoutManager.connect('monitors-changed', Lang.bind(this, this._relayout));
this._relayout(); this._relayout();
}, },
@ -486,55 +562,41 @@ const Overview = new Lang.Class({
this.hide(); this.hide();
let primary = Main.layoutManager.primaryMonitor; let primary = Main.layoutManager.primaryMonitor;
let rtl = (Clutter.get_default_text_direction() == Clutter.TextDirection.RTL);
let contentY = Main.panel.actor.height; let contentY = Main.panel.actor.height;
let contentHeight = primary.height - contentY - Main.messageTray.actor.height; let contentHeight = primary.height - contentY - Main.messageTray.actor.height;
this._group.set_position(primary.x, primary.y); this._overview.set_position(primary.x, primary.y);
this._group.set_size(primary.width, primary.height); this._overview.set_size(primary.width, primary.height);
this._coverPane.set_position(0, contentY); this._coverPane.set_position(0, contentY);
this._coverPane.set_size(primary.width, contentHeight); this._coverPane.set_size(primary.width, contentHeight);
},
let searchWidth = this._searchEntry.get_width(); _onRestacked: function() {
let searchHeight = this._searchEntry.get_height(); let stack = global.get_window_actors();
let searchX = (primary.width - searchWidth) / 2; let stackIndices = {};
let searchY = contentY + this._spacing;
let dashWidth = DASH_MAX_WIDTH; for (let i = 0; i < stack.length; i++) {
let dashY = searchY + searchHeight + this._spacing; // Use the stable sequence for an integer to use as a hash key
let dashX; stackIndices[stack[i].get_meta_window().get_stable_sequence()] = i;
if (rtl) {
this._dash.actor.set_anchor_point_from_gravity(Clutter.Gravity.NORTH_EAST);
dashX = primary.width;
} else {
dashX = 0;
} }
let viewX = rtl ? 0 : dashWidth + this._spacing; this.emit('sync-window-stacking', stackIndices);
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);
}, },
//// Public methods //// //// Public methods ////
beginItemDrag: function(source) { beginAppDrag: function(source) {
this.emit('item-drag-begin'); this.emit('app-drag-begin');
}, },
cancelledItemDrag: function(source) { cancelledAppDrag: function(source) {
this.emit('item-drag-cancelled'); this.emit('app-drag-cancelled');
}, },
endItemDrag: function(source) { endAppDrag: function(source) {
this.emit('item-drag-end'); this.emit('app-drag-end');
}, },
beginWindowDrag: function(source) { beginWindowDrag: function(source) {
@ -558,13 +620,13 @@ const Overview = new Lang.Class({
if (this._shown) if (this._shown)
return; return;
// Do this manually instead of using _syncInputMode, to handle failure // Do this manually instead of using _syncInputMode, to handle failure
if (!Main.pushModal(this._group)) if (!Main.pushModal(this._overview))
return; return;
this._modal = true; this._modal = true;
this._animateVisible(); this._animateVisible();
this._shown = true; this._shown = true;
this._buttonPressId = this._group.connect('button-press-event', this._buttonPressId = this._overview.connect('button-press-event',
Lang.bind(this, this._onButtonPress)); Lang.bind(this, this._onButtonPress));
}, },
@ -608,12 +670,12 @@ const Overview = new Lang.Class({
// Disable unredirection while in the overview // Disable unredirection while in the overview
Meta.disable_unredirect_for_screen(global.screen); Meta.disable_unredirect_for_screen(global.screen);
global.window_group.hide(); global.window_group.hide();
this._group.show(); this._overview.show();
this._background.show(); this._background.show();
this._viewSelector.show(); this._viewSelector.show();
this._group.opacity = 0; this._overview.opacity = 0;
Tweener.addTween(this._group, Tweener.addTween(this._overview,
{ opacity: 255, { opacity: 255,
transition: 'easeOutQuad', transition: 'easeOutQuad',
time: ANIMATION_TIME, time: ANIMATION_TIME,
@ -667,7 +729,7 @@ const Overview = new Lang.Class({
this._syncInputMode(); this._syncInputMode();
if (this._buttonPressId > 0) if (this._buttonPressId > 0)
this._group.disconnect(this._buttonPressId); this._overview.disconnect(this._buttonPressId);
this._buttonPressId = 0; this._buttonPressId = 0;
}, },
@ -709,20 +771,20 @@ const Overview = new Lang.Class({
if (this._shown) { if (this._shown) {
if (!this._modal) { if (!this._modal) {
if (Main.pushModal(this._group)) if (Main.pushModal(this._overview))
this._modal = true; this._modal = true;
else else
this.hide(); this.hide();
} }
} else if (this._shownTemporarily) { } else if (this._shownTemporarily) {
if (this._modal) { if (this._modal) {
Main.popModal(this._group); Main.popModal(this._overview);
this._modal = false; this._modal = false;
} }
global.stage_input_mode = Shell.StageInputMode.FULLSCREEN; global.stage_input_mode = Shell.StageInputMode.FULLSCREEN;
} else { } else {
if (this._modal) { if (this._modal) {
Main.popModal(this._group); Main.popModal(this._overview);
this._modal = false; this._modal = false;
} }
else if (global.stage_input_mode == Shell.StageInputMode.FULLSCREEN) else if (global.stage_input_mode == Shell.StageInputMode.FULLSCREEN)
@ -740,7 +802,7 @@ const Overview = new Lang.Class({
this._viewSelector.zoomFromOverview(); this._viewSelector.zoomFromOverview();
// Make other elements fade out. // Make other elements fade out.
Tweener.addTween(this._group, Tweener.addTween(this._overview,
{ opacity: 0, { opacity: 0,
transition: 'easeOutQuad', transition: 'easeOutQuad',
time: ANIMATION_TIME, time: ANIMATION_TIME,
@ -782,7 +844,7 @@ const Overview = new Lang.Class({
this._viewSelector.hide(); this._viewSelector.hide();
this._desktopFade.hide(); this._desktopFade.hide();
this._background.hide(); this._background.hide();
this._group.hide(); this._overview.hide();
this.visible = false; this.visible = false;
this.animationInProgress = false; this.animationInProgress = false;

View File

@ -15,6 +15,7 @@ const Signals = imports.signals;
const Atk = imports.gi.Atk; const Atk = imports.gi.Atk;
const CenterLayout = imports.ui.centerLayout;
const Config = imports.misc.config; const Config = imports.misc.config;
const CtrlAltTab = imports.ui.ctrlAltTab; const CtrlAltTab = imports.ui.ctrlAltTab;
const DND = imports.ui.dnd; const DND = imports.ui.dnd;
@ -247,6 +248,10 @@ const AppMenuButton = new Lang.Class({
this._container.connect('get-preferred-height', Lang.bind(this, this._getContentPreferredHeight)); this._container.connect('get-preferred-height', Lang.bind(this, this._getContentPreferredHeight));
this._container.connect('allocate', Lang.bind(this, this._contentAllocate)); this._container.connect('allocate', Lang.bind(this, this._contentAllocate));
let textureCache = St.TextureCache.get_default();
textureCache.connect('icon-theme-changed',
Lang.bind(this, this._onIconThemeChanged));
this._iconBox = new Shell.Slicer({ name: 'appMenuIcon' }); this._iconBox = new Shell.Slicer({ name: 'appMenuIcon' });
this._iconBox.connect('style-changed', this._iconBox.connect('style-changed',
Lang.bind(this, this._onIconBoxStyleChanged)); Lang.bind(this, this._onIconBoxStyleChanged));
@ -332,6 +337,15 @@ const AppMenuButton = new Lang.Class({
this._updateIconBoxClip(); this._updateIconBoxClip();
}, },
_onIconThemeChanged: function() {
if (this._iconBox.child == null)
return;
this._iconBox.child.destroy();
let icon = this._targetApp.get_faded_icon(2 * PANEL_ICON_SIZE);
this._iconBox.set_child(icon);
},
_updateIconBoxClip: function() { _updateIconBoxClip: function() {
let allocation = this._iconBox.allocation; let allocation = this._iconBox.allocation;
if (this._iconBottomClip > 0) if (this._iconBottomClip > 0)
@ -901,6 +915,7 @@ const PANEL_ITEM_IMPLEMENTATIONS = {
'volume': imports.ui.status.volume.Indicator, 'volume': imports.ui.status.volume.Indicator,
'battery': imports.ui.status.power.Indicator, 'battery': imports.ui.status.power.Indicator,
'lockScreen': imports.ui.status.lockScreenMenu.Indicator, 'lockScreen': imports.ui.status.lockScreenMenu.Indicator,
'logo': imports.gdm.loginDialog.LogoMenuButton,
'keyboard': imports.ui.status.keyboard.InputSourceIndicator, 'keyboard': imports.ui.status.keyboard.InputSourceIndicator,
'powerMenu': imports.gdm.powerMenu.PowerMenuButton, 'powerMenu': imports.gdm.powerMenu.PowerMenuButton,
'userMenu': imports.ui.userMenu.UserMenuButton 'userMenu': imports.ui.userMenu.UserMenuButton
@ -917,12 +932,47 @@ try {
log('NMApplet is not supported. It is possible that your NetworkManager version is too old'); 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({ const Panel = new Lang.Class({
Name: 'Panel', Name: 'Panel',
_init : function() { _init : function() {
this.actor = new Shell.GenericContainer({ name: 'panel', this.actor = new St.Widget({ name: 'panel',
reactive: true }); reactive: true,
layoutManager: new PanelLayout() });
this.actor._delegate = this; this.actor._delegate = this;
this.statusArea = {}; this.statusArea = {};
@ -947,7 +997,6 @@ const Panel = new Lang.Class({
this._leftCorner = new PanelCorner(this._rightBox, St.Side.LEFT); this._leftCorner = new PanelCorner(this._rightBox, St.Side.LEFT);
else else
this._leftCorner = new PanelCorner(this._leftBox, St.Side.LEFT); this._leftCorner = new PanelCorner(this._leftBox, St.Side.LEFT);
this.actor.add_actor(this._leftCorner.actor); this.actor.add_actor(this._leftCorner.actor);
if (this.actor.get_text_direction() == Clutter.TextDirection.RTL) if (this.actor.get_text_direction() == Clutter.TextDirection.RTL)
@ -956,9 +1005,6 @@ const Panel = new Lang.Class({
this._rightCorner = new PanelCorner(this._rightBox, St.Side.RIGHT); this._rightCorner = new PanelCorner(this._rightBox, St.Side.RIGHT);
this.actor.add_actor(this._rightCorner.actor); 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)); this.actor.connect('button-press-event', Lang.bind(this, this._onButtonPress));
Main.layoutManager.panelBox.add(this.actor); Main.layoutManager.panelBox.add(this.actor);
@ -969,83 +1015,6 @@ const Panel = new Lang.Class({
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) { _onButtonPress: function(actor, event) {
if (event.get_source() != actor) if (event.get_source() != actor)
return false; return false;

View File

@ -214,7 +214,8 @@ const Button = new Lang.Class({
destroy: function() { destroy: function() {
this.actor._delegate = null; this.actor._delegate = null;
this.menu.destroy(); if (this.menu)
this.menu.destroy();
this.actor.destroy(); this.actor.destroy();
this.emit('destroy'); this.emit('destroy');

View File

@ -404,9 +404,17 @@ const PopupSeparatorMenuItem = new Lang.Class({
this.parent({ reactive: false, this.parent({ reactive: false,
can_focus: false}); can_focus: false});
this._drawingArea = new St.DrawingArea({ style_class: 'popup-separator-menu-item' }); this._separator = new HorzSeparator({ style_class: 'popup-separator-menu-item' });
this.addActor(this._drawingArea, { span: -1, expand: true }); this.addActor(this._separator.actor, { span: -1, expand: true });
this._drawingArea.connect('repaint', Lang.bind(this, this._onRepaint)); }
});
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) { _onRepaint: function(area) {
@ -1269,13 +1277,14 @@ const PopupMenu = new Lang.Class({
}, },
close: function(animate) { close: function(animate) {
if (!this.isOpen)
return;
if (this._activeMenuItem) if (this._activeMenuItem)
this._activeMenuItem.setActive(false); this._activeMenuItem.setActive(false);
this._boxPointer.hide(animate); if (this._boxPointer.actor.visible)
this._boxPointer.hide(animate);
if (!this.isOpen)
return;
this.isOpen = false; this.isOpen = false;
this.emit('open-state-changed', false); this.emit('open-state-changed', false);

View File

@ -27,6 +27,9 @@ const SearchProviderIface = <interface name="org.gnome.Shell.SearchProvider">
<method name="ActivateResult"> <method name="ActivateResult">
<arg type="s" direction="in" /> <arg type="s" direction="in" />
</method> </method>
<method name="LaunchSearch">
<arg type="as" direction="in" />
</method>
</interface>; </interface>;
var SearchProviderProxy = Gio.DBusProxy.makeProxyWrapper(SearchProviderIface); var SearchProviderProxy = Gio.DBusProxy.makeProxyWrapper(SearchProviderIface);
@ -112,6 +115,7 @@ const RemoteSearchProvider = new Lang.Class({
this.parent(title.toUpperCase()); this.parent(title.toUpperCase());
this._cancellable = new Gio.Cancellable(); this._cancellable = new Gio.Cancellable();
this.icon = icon;
}, },
createIcon: function(size, meta) { createIcon: function(size, meta) {
@ -126,9 +130,7 @@ const RemoteSearchProvider = new Lang.Class({
width, height, rowStride, size); width, height, rowStride, size);
} }
// Ugh, but we want to fall back to something ... return null;
return new St.Icon({ icon_name: 'text-x-generic',
icon_size: size });
}, },
_getResultsFinished: function(results, error) { _getResultsFinished: function(results, error) {
@ -196,6 +198,10 @@ const RemoteSearchProvider = new Lang.Class({
activateResult: function(id) { activateResult: function(id) {
this._proxy.ActivateResultRemote(id); this._proxy.ActivateResultRemote(id);
},
launchSearch: function(terms) {
this._proxy.LaunchSearchRemote(terms);
} }
}); });

View File

@ -202,11 +202,12 @@ const RunDialog = new Lang.Class({
let label = new St.Label({ style_class: 'run-dialog-label', let label = new St.Label({ style_class: 'run-dialog-label',
text: _("Please enter a command:") }); text: _("Enter a Command") });
this.contentLayout.add(label, { y_align: St.Align.START }); this.contentLayout.add(label, { y_align: St.Align.START });
let entry = new St.Entry({ style_class: 'run-dialog-entry' }); let entry = new St.Entry({ style_class: 'run-dialog-entry',
can_focus: true });
ShellEntry.addContextMenu(entry); ShellEntry.addContextMenu(entry);
entry.label_actor = label; entry.label_actor = label;
@ -236,6 +237,10 @@ const RunDialog = new Lang.Class({
this._errorBox.hide(); this._errorBox.hide();
this.setButtons([{ action: Lang.bind(this, this.close),
label: _("Close"),
key: Clutter.Escape }]);
this._pathCompleter = new Gio.FilenameCompleter(); this._pathCompleter = new Gio.FilenameCompleter();
this._commandCompleter = new CommandCompleter(); this._commandCompleter = new CommandCompleter();
this._group.connect('notify::visible', Lang.bind(this._commandCompleter, this._commandCompleter.update)); this._group.connect('notify::visible', Lang.bind(this._commandCompleter, this._commandCompleter.update));
@ -246,20 +251,12 @@ const RunDialog = new Lang.Class({
let symbol = e.get_key_symbol(); let symbol = e.get_key_symbol();
if (symbol == Clutter.Return || symbol == Clutter.KP_Enter) { if (symbol == Clutter.Return || symbol == Clutter.KP_Enter) {
this.popModal(); this.popModal();
if (e.get_state() & Clutter.ModifierType.CONTROL_MASK) this._run(o.get_text(),
this._run(o.get_text(), true); e.get_state() & Clutter.ModifierType.CONTROL_MASK);
else if (!this._commandError ||
this._run(o.get_text(), false); !this.pushModal())
if (!this._commandError)
this.close(); this.close();
else {
if (!this.pushModal())
this.close();
}
return true;
}
if (symbol == Clutter.Escape) {
this.close();
return true; return true;
} }
if (symbol == Clutter.slash) { if (symbol == Clutter.slash) {

View File

@ -26,7 +26,7 @@ const Util = imports.misc.util;
const SCREENSAVER_SCHEMA = 'org.gnome.desktop.screensaver'; const SCREENSAVER_SCHEMA = 'org.gnome.desktop.screensaver';
const LOCK_ENABLED_KEY = 'lock-enabled'; const LOCK_ENABLED_KEY = 'lock-enabled';
const CURTAIN_SLIDE_TIME = 0.5; const CURTAIN_SLIDE_TIME = 0.3;
// fraction of screen height the arrow must reach before completing // fraction of screen height the arrow must reach before completing
// the slide up automatically // the slide up automatically
const ARROW_DRAG_THRESHOLD = 0.1; const ARROW_DRAG_THRESHOLD = 0.1;
@ -47,7 +47,7 @@ const SUMMARY_ICON_SIZE = 48;
// STANDARD_FADE_TIME is used when the session goes idle, while // STANDARD_FADE_TIME is used when the session goes idle, while
// SHORT_FADE_TIME is used when requesting lock explicitly from the user menu // SHORT_FADE_TIME is used when requesting lock explicitly from the user menu
const STANDARD_FADE_TIME = 10; const STANDARD_FADE_TIME = 10;
const SHORT_FADE_TIME = 0.8; const SHORT_FADE_TIME = 0.3;
const Clock = new Lang.Class({ const Clock = new Lang.Class({
Name: 'ScreenShieldClock', Name: 'ScreenShieldClock',
@ -186,7 +186,7 @@ const NotificationsBox = new Lang.Class({
if (obj.resident) { if (obj.resident) {
this._residentNotificationBox.add(item.notificationStackWidget); this._residentNotificationBox.add(item.notificationStackWidget);
item.closeButtonVisible = false; item.closeButton.hide();
item.prepareNotificationStackForShowing(); item.prepareNotificationStackForShowing();
} else { } else {
[obj.sourceBox, obj.countLabel] = this._makeNotificationSource(item.source); [obj.sourceBox, obj.countLabel] = this._makeNotificationSource(item.source);
@ -244,7 +244,7 @@ const NotificationsBox = new Lang.Class({
obj.resident = true; obj.resident = true;
this._residentNotificationBox.add(obj.item.notificationStackWidget); this._residentNotificationBox.add(obj.item.notificationStackWidget);
obj.item.closeButtonVisible = false; obj.item.closeButton.hide();
obj.item.prepareNotificationStackForShowing(); obj.item.prepareNotificationStackForShowing();
} else { } else {
// just update the counter // just update the counter
@ -526,7 +526,7 @@ const ScreenShield = new Lang.Class({
Tweener.addTween(this._lockScreenGroup, Tweener.addTween(this._lockScreenGroup,
{ y: 0, { y: 0,
time: time, time: time,
transition: 'linear', transition: 'easeInQuad',
onComplete: function() { onComplete: function() {
this._lockScreenGroup.fixed_position_set = false; this._lockScreenGroup.fixed_position_set = false;
this._lockScreenState = MessageTray.State.SHOWN; this._lockScreenState = MessageTray.State.SHOWN;
@ -580,14 +580,13 @@ const ScreenShield = new Lang.Class({
showDialog: function() { showDialog: function() {
// Ensure that the stage window is mapped, before taking a grab // Ensure that the stage window is mapped, before taking a grab
// otherwise X errors out // otherwise X errors out
let actorShownId = 0; Meta.later_add(Meta.LaterType.BEFORE_REDRAW, Lang.bind(this, function() {
actorShownId = this.actor.connect('show', Lang.bind(this, function() {
if (!this._isModal) { if (!this._isModal) {
Main.pushModal(this.actor); Main.pushModal(this.actor);
this._isModal = true; this._isModal = true;
} }
this.actor.disconnect(actorShownId); return false;
})); }));
this.actor.show(); this.actor.show();
@ -623,7 +622,7 @@ const ScreenShield = new Lang.Class({
Tweener.addTween(this._lockScreenGroup, Tweener.addTween(this._lockScreenGroup,
{ y: -h, { y: -h,
time: time, time: time,
transition: 'linear', transition: 'easeInQuad',
onComplete: function() { onComplete: function() {
this._lockScreenState = MessageTray.State.HIDDEN; this._lockScreenState = MessageTray.State.HIDDEN;
this._lockScreenGroup.hide(); this._lockScreenGroup.hide();
@ -684,7 +683,7 @@ const ScreenShield = new Lang.Class({
Tweener.addTween(this._lockScreenGroup, Tweener.addTween(this._lockScreenGroup,
{ y: 0, { y: 0,
time: SHORT_FADE_TIME, time: SHORT_FADE_TIME,
transition: 'linear', transition: 'easeOutQuad',
onComplete: function() { onComplete: function() {
this._lockScreenShown(); this._lockScreenShown();
}, },

View File

@ -163,6 +163,16 @@ const SearchProvider = new Lang.Class({
*/ */
activateResult: function(id) { activateResult: function(id) {
throw new Error('Not implemented'); 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); Signals.addSignalMethods(SearchProvider.prototype);
@ -261,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); Signals.addSignalMethods(SearchSystem.prototype);

View File

@ -4,25 +4,191 @@ const Clutter = imports.gi.Clutter;
const Lang = imports.lang; const Lang = imports.lang;
const Gtk = imports.gi.Gtk; const Gtk = imports.gi.Gtk;
const Meta = imports.gi.Meta; const Meta = imports.gi.Meta;
const Signals = imports.signals;
const St = imports.gi.St; const St = imports.gi.St;
const Atk = imports.gi.Atk; const Atk = imports.gi.Atk;
const AppDisplay = imports.ui.appDisplay;
const DND = imports.ui.dnd; const DND = imports.ui.dnd;
const IconGrid = imports.ui.iconGrid; const IconGrid = imports.ui.iconGrid;
const Main = imports.ui.main; const Main = imports.ui.main;
const Overview = imports.ui.overview; const Overview = imports.ui.overview;
const PopupMenu = imports.ui.popupMenu;
const Search = imports.ui.search; 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({ const ListSearchResult = new Lang.Class({
Name: 'SearchResult', Name: 'ListSearchResult',
ICON_SIZE: 64,
_init: function(provider, metaInfo, terms) { _init: function(provider, metaInfo, terms) {
this.provider = provider; this.provider = provider;
this.metaInfo = metaInfo; this.metaInfo = metaInfo;
this.actor = new St.Button({ style_class: 'search-result', 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, reactive: true,
x_align: St.Align.START, x_align: St.Align.START,
y_fill: true }); y_fill: true });
@ -31,7 +197,7 @@ const SearchResult = new Lang.Class({
let content = provider.createResultActor(metaInfo, terms); let content = provider.createResultActor(metaInfo, terms);
if (content == null) { if (content == null) {
content = new St.Bin({ style_class: 'search-result-content', content = new St.Bin({ style_class: 'grid-search-result-content',
reactive: true, reactive: true,
can_focus: true, can_focus: true,
track_hover: true, track_hover: true,
@ -45,7 +211,7 @@ const SearchResult = new Lang.Class({
if (content._delegate && content._delegate.getDragActorSource) if (content._delegate && content._delegate.getDragActorSource)
this._dragActorSource = content._delegate.getDragActorSource(); this._dragActorSource = content._delegate.getDragActorSource();
} }
this._content = content; this.content = content;
this.actor.set_child(content); this.actor.set_child(content);
this.actor.connect('clicked', Lang.bind(this, this._onResultClicked)); this.actor.connect('clicked', Lang.bind(this, this._onResultClicked));
@ -53,23 +219,23 @@ const SearchResult = new Lang.Class({
let draggable = DND.makeDraggable(this.actor); let draggable = DND.makeDraggable(this.actor);
draggable.connect('drag-begin', draggable.connect('drag-begin',
Lang.bind(this, function() { Lang.bind(this, function() {
Main.overview.beginItemDrag(this); Main.overview.beginAppDrag(this);
})); }));
draggable.connect('drag-cancelled', draggable.connect('drag-cancelled',
Lang.bind(this, function() { Lang.bind(this, function() {
Main.overview.cancelledItemDrag(this); Main.overview.cancelledAppDrag(this);
})); }));
draggable.connect('drag-end', draggable.connect('drag-end',
Lang.bind(this, function() { Lang.bind(this, function() {
Main.overview.endItemDrag(this); Main.overview.endAppDrag(this);
})); }));
}, },
setSelected: function(selected) { setSelected: function(selected) {
if (selected) if (selected)
this._content.add_style_pseudo_class('selected'); this.content.add_style_pseudo_class('selected');
else else
this._content.remove_style_pseudo_class('selected'); this.content.remove_style_pseudo_class('selected');
}, },
activate: function() { activate: function() {
@ -85,7 +251,7 @@ const SearchResult = new Lang.Class({
if (this._dragActorSource) if (this._dragActorSource)
return this._dragActorSource; return this._dragActorSource;
// not exactly right, but alignment problems are hard to notice // not exactly right, but alignment problems are hard to notice
return this._content; return this.content;
}, },
getDragActor: function(stageX, stageY) { getDragActor: function(stageX, stageY) {
@ -108,11 +274,11 @@ const GridSearchResults = new Lang.Class({
_init: function(provider, grid) { _init: function(provider, grid) {
this.parent(provider); 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 }); 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.actor.set_child(this._grid.actor);
this._width = 0; this._width = 0;
this.actor.connect('notify::width', Lang.bind(this, function() { this.actor.connect('notify::width', Lang.bind(this, function() {
this._width = this.actor.width; this._width = this.actor.width;
@ -130,6 +296,7 @@ const GridSearchResults = new Lang.Class({
}, },
getResultsForDisplay: function() { getResultsForDisplay: function() {
this._grid.actor.ensure_style();
let alreadyVisible = this._pendingClear ? 0 : this._grid.visibleItemsCount(); let alreadyVisible = this._pendingClear ? 0 : this._grid.visibleItemsCount();
let canDisplay = this._grid.childrenInRow(this._width) * this._grid.getRowLimit() let canDisplay = this._grid.childrenInRow(this._width) * this._grid.getRowLimit()
- alreadyVisible; - alreadyVisible;
@ -143,6 +310,10 @@ const GridSearchResults = new Lang.Class({
return this._grid.visibleItemsCount(); return this._grid.visibleItemsCount();
}, },
hasMoreResults: function() {
return this._notDisplayedResult.length > 0;
},
setResults: function(results, terms) { setResults: function(results, terms) {
// copy the lists // copy the lists
this._notDisplayedResult = results.slice(0); this._notDisplayedResult = results.slice(0);
@ -152,8 +323,10 @@ const GridSearchResults = new Lang.Class({
renderResults: function(metas) { renderResults: function(metas) {
for (let i = 0; i < metas.length; i++) { 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); 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; return this._grid.getItemAtIndex(0)._delegate;
else else
return null; 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) { _init: function(searchSystem) {
this._searchSystem = searchSystem; this._searchSystem = searchSystem;
@ -222,19 +401,43 @@ const SearchResults = new Lang.Class({
createProviderMeta: function(provider) { createProviderMeta: function(provider) {
let providerBox = new St.BoxLayout({ style_class: 'search-section', let providerBox = new St.BoxLayout({ style_class: 'search-section',
vertical: true }); vertical: true });
let title = new St.Label({ style_class: 'search-section-header', let providerBoxContent = new St.BoxLayout({ style_class: 'search-section-content' });
text: provider.title }); let isAppsProvider = (provider instanceof AppDisplay.AppSearchProvider);
providerBox.add(title, { x_fill: false, x_align: St.Align.START });
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', let resultDisplayBin = new St.Bin({ style_class: 'search-section-results',
x_fill: true, x_fill: true,
y_fill: true }); y_fill: true });
providerBox.add(resultDisplayBin, { expand: true }); providerBoxContent.add(resultDisplayBin, { expand: true });
let resultDisplay = new GridSearchResults(provider);
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); resultDisplayBin.set_child(resultDisplay.actor);
this._providerMeta.push({ provider: provider, this._providerMeta.push({ provider: provider,
actor: providerBox, actor: providerBox,
icon: providerIcon,
resultDisplay: resultDisplay }); resultDisplay: resultDisplay });
this._content.add(providerBox); this._content.add(providerBox);
}, },
@ -255,6 +458,7 @@ const SearchResults = new Lang.Class({
let meta = this._providerMeta[i]; let meta = this._providerMeta[i];
meta.resultDisplay.clear(); meta.resultDisplay.clear();
meta.actor.hide(); 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); let meta = this._metaForProvider(provider);
meta.resultDisplay.clear(); meta.resultDisplay.clear();
meta.actor.hide(); meta.actor.hide();
if (meta.icon) meta.icon.actor.can_focus = false;
}, },
reset: function() { reset: function() {
@ -284,6 +489,11 @@ const SearchResults = new Lang.Class({
return this._providerMeta[this._providers.indexOf(provider)]; 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() { _maybeSetInitialSelection: function() {
let newDefaultResult = null; let newDefaultResult = null;
@ -341,6 +551,9 @@ const SearchResults = new Lang.Class({
meta.resultDisplay.setResults(providerResults, terms); meta.resultDisplay.setResults(providerResults, terms);
let results = meta.resultDisplay.getResultsForDisplay(); let results = meta.resultDisplay.getResultsForDisplay();
if (meta.icon)
meta.icon.moreIcon.visible = meta.resultDisplay.hasMoreResults();
provider.getResultMetas(results, Lang.bind(this, function(metas) { provider.getResultMetas(results, Lang.bind(this, function(metas) {
this._clearDisplayForProvider(provider); this._clearDisplayForProvider(provider);
meta.actor.show(); meta.actor.show();
@ -374,6 +587,15 @@ const SearchResults = new Lang.Class({
this._defaultResult.setSelected(highlight); 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) { navigateFocus: function(direction) {
let rtl = this.actor.get_text_direction() == Clutter.TextDirection.RTL; let rtl = this.actor.get_text_direction() == Clutter.TextDirection.RTL;
if (direction == Gtk.DirectionType.TAB_BACKWARD || 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

@ -39,7 +39,7 @@ const _modes = {
unlockDialog: imports.gdm.loginDialog.LoginDialog, unlockDialog: imports.gdm.loginDialog.LoginDialog,
components: ['polkitAgent'], components: ['polkitAgent'],
panel: { panel: {
left: [], left: ['logo'],
center: ['dateMenu'], center: ['dateMenu'],
right: ['a11y', 'display', 'keyboard', right: ['a11y', 'display', 'keyboard',
'volume', 'battery', 'powerMenu'] 'volume', 'battery', 'powerMenu']

View File

@ -233,20 +233,11 @@ const NMWirelessSectionTitleMenuItem = new Lang.Class({
} }
}); });
const NMDevice = new Lang.Class({ const NMConnectionBased = new Lang.Class({
Name: 'NMDevice', Name: 'NMConnectionBased',
Abstract: true, Abstract: true,
_init: function(client, device, connections) { _init: function(connections) {
this.device = device;
if (device) {
this.device._delegate = this;
this._stateChangedId = this.device.connect('state-changed', Lang.bind(this, this._deviceStateChanged));
} else
this._stateChangedId = 0;
// protected
this._client = client;
this._connections = [ ]; this._connections = [ ];
for (let i = 0; i < connections.length; i++) { for (let i = 0; i < connections.length; i++) {
if (!connections[i].get_uuid()) if (!connections[i].get_uuid())
@ -264,26 +255,115 @@ const NMDevice = new Lang.Class({
this._connections.push(obj); this._connections.push(obj);
} }
this._connections.sort(this._connectionSortFunction); this._connections.sort(this._connectionSortFunction);
},
checkConnection: function(connection) {
let pos = this._findConnection(connection.get_uuid());
let exists = pos != -1;
let valid = this.connectionValid(connection);
let similar = false;
if (exists) {
let existing = this._connections[pos];
// Check if connection changed name or id
similar = existing.name == connection.get_id() &&
existing.timestamp == connection._timestamp;
}
if (exists && valid && similar) {
// Nothing to do
return;
}
if (exists)
this.removeConnection(connection);
if (valid)
this.addConnection(connection);
},
addConnection: function(connection) {
// record the connection
let obj = {
connection: connection,
name: connection.get_id(),
uuid: connection.get_uuid(),
timestamp: connection._timestamp,
item: null,
};
Util.insertSorted(this._connections, obj, this._connectionSortFunction);
this._queueCreateSection();
},
removeConnection: function(connection) {
let pos = this._findConnection(connection.get_uuid());
if (pos == -1) {
// this connection was never added, nothing to do here
return;
}
let obj = this._connections[pos];
if (obj.item)
obj.item.destroy();
this._connections.splice(pos, 1);
if (this._connections.length <= 1) {
// We need to show the automatic connection again
// (or in the case of NMDeviceWired, we want to hide
// the only explicit connection)
this._queueCreateSection();
}
},
_findConnection: function(uuid) {
for (let i = 0; i < this._connections.length; i++) {
let obj = this._connections[i];
if (obj.uuid == uuid)
return i;
}
return -1;
},
_connectionSortFunction: function(one, two) {
if (one.timestamp == two.timestamp)
return GLib.utf8_collate(one.name, two.name);
return two.timestamp - one.timestamp;
},
});
Signals.addSignalMethods(NMConnectionBased.prototype);
const NMDevice = new Lang.Class({
Name: 'NMDevice',
Abstract: true,
Extends: NMConnectionBased,
_init: function(client, device, connections) {
this.device = device;
this.device._delegate = this;
this._stateChangedId = this.device.connect('state-changed', Lang.bind(this, this._deviceStateChanged));
// protected
this._client = client;
this.parent(connections);
this._activeConnection = null; this._activeConnection = null;
this._activeConnectionItem = null; this._activeConnectionItem = null;
this._autoConnectionItem = null; this._autoConnectionItem = null;
this._overflowItem = null; this._overflowItem = null;
if (this.device) { this.statusItem = new PopupMenu.PopupSwitchMenuItem(this._getDescription(), 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) {
this._statusChanged = this.statusItem.connect('toggled', Lang.bind(this, function(item, state) { let ok;
let ok; if (state)
if (state) ok = this.activate();
ok = this.activate(); else
else ok = this.deactivate();
ok = this.deactivate();
if (!ok) if (!ok)
item.setToggleState(!state); item.setToggleState(!state);
})); }));
this._updateStatusItem(); this._updateStatusItem();
}
this.section = new PopupMenu.PopupMenuSection(); this.section = new PopupMenu.PopupMenuSection();
this._deferredWorkId = Main.initializeDeferredWork(this.section.actor, Lang.bind(this, this._createSection)); this._deferredWorkId = Main.initializeDeferredWork(this.section.actor, Lang.bind(this, this._createSection));
@ -352,6 +432,10 @@ const NMDevice = new Lang.Class({
return this.device.state == NetworkManager.DeviceState.ACTIVATED; return this.device.state == NetworkManager.DeviceState.ACTIVATED;
}, },
clearActiveConnection: function(activeConnection) {
this.setActiveConnection(null);
},
setActiveConnection: function(activeConnection) { setActiveConnection: function(activeConnection) {
if (activeConnection == this._activeConnection) if (activeConnection == this._activeConnection)
// nothing to do // nothing to do
@ -369,80 +453,13 @@ const NMDevice = new Lang.Class({
this._queueCreateSection(); this._queueCreateSection();
}, },
checkConnection: function(connection) {
let pos = this._findConnection(connection.get_uuid());
let exists = pos != -1;
let valid = this.connectionValid(connection);
let similar = false;
if (exists) {
let existing = this._connections[pos];
// Check if connection changed name or id
similar = existing.name == connection.get_id() &&
existing.timestamp == connection._timestamp;
}
if (exists && valid && similar) {
// Nothing to do
return;
}
if (exists)
this.removeConnection(connection);
if (valid)
this.addConnection(connection);
},
addConnection: function(connection) {
// record the connection
let obj = {
connection: connection,
name: connection.get_id(),
uuid: connection.get_uuid(),
timestamp: connection._timestamp,
item: null,
};
Util.insertSorted(this._connections, obj, this._connectionSortFunction);
this._clearSection();
this._queueCreateSection();
},
removeConnection: function(connection) {
let pos = this._findConnection(connection.get_uuid());
if (pos == -1) {
// this connection was never added, nothing to do here
return;
}
let obj = this._connections[pos];
if (obj.item)
obj.item.destroy();
this._connections.splice(pos, 1);
if (this._connections.length <= 1) {
// We need to show the automatic connection again
// (or in the case of NMDeviceWired, we want to hide
// the only explicit connection)
this._clearSection();
this._queueCreateSection();
}
},
connectionValid: function(connection) { connectionValid: function(connection) {
return this.device.connection_valid(connection); return this.device.connection_valid(connection);
}, },
_connectionSortFunction: function(one, two) {
if (one.timestamp == two.timestamp)
return GLib.utf8_collate(one.name, two.name);
return two.timestamp - one.timestamp;
},
setEnabled: function(enabled) { setEnabled: function(enabled) {
// do nothing by default, we want to keep the conneciton list visible // do nothing by default, we want to keep the conneciton list visible
// in the majority of cases (wired, wwan, vpn) // in the majority of cases (wired, wwan)
}, },
getStatusLabel: function() { getStatusLabel: function() {
@ -500,15 +517,6 @@ const NMDevice = new Lang.Class({
throw new TypeError('Invoking pure virtual function NMDevice.createAutomaticConnection'); throw new TypeError('Invoking pure virtual function NMDevice.createAutomaticConnection');
}, },
_findConnection: function(uuid) {
for (let i = 0; i < this._connections.length; i++) {
let obj = this._connections[i];
if (obj.uuid == uuid)
return i;
}
return -1;
},
_queueCreateSection: function() { _queueCreateSection: function() {
this._clearSection(); this._clearSection();
Main.queueDeferredWork(this._deferredWorkId); Main.queueDeferredWork(this._deferredWorkId);
@ -652,8 +660,6 @@ const NMDevice = new Lang.Class({
return out; return out;
} }
}); });
Signals.addSignalMethods(NMDevice.prototype);
const NMDeviceWired = new Lang.Class({ const NMDeviceWired = new Lang.Class({
Name: 'NMDeviceWired', Name: 'NMDeviceWired',
@ -868,95 +874,6 @@ const NMDeviceBluetooth = new Lang.Class({
} }
}); });
// Not a real device, but I save a lot code this way
const NMDeviceVPN = new Lang.Class({
Name: 'NMDeviceVPN',
Extends: NMDevice,
_init: function(client, device, connections) {
// Disable autoconnections
this._autoConnectionName = null;
this.category = NMConnectionCategory.VPN;
this.parent(client, null, connections);
},
connectionValid: function(connection) {
return connection._type == NetworkManager.SETTING_VPN_SETTING_NAME;
},
get empty() {
return this._connections.length == 0;
},
get connected() {
if (!this._activeConnection)
return false;
return this._activeConnection.vpn_state == NetworkManager.VPNConnectionState.ACTIVATED;
},
setActiveConnection: function(activeConnection) {
if (this._stateChangeId)
this._activeConnection.disconnect(this._stateChangeId);
this._stateChangeId = 0;
this.parent(activeConnection);
if (this._activeConnection)
this._stateChangeId = this._activeConnection.connect('vpn-state-changed',
Lang.bind(this, this._connectionStateChanged));
this.emit('state-changed');
},
_shouldShowConnectionList: function() {
return true;
},
deactivate: function() {
if (this._activeConnection)
this._client.deactivate_connection(this._activeConnection);
},
getStatusLabel: function() {
if (!this._activeConnection) // Same as DISCONNECTED
return null;
switch(this._activeConnection.vpn_state) {
case NetworkManager.VPNConnectionState.DISCONNECTED:
case NetworkManager.VPNConnectionState.ACTIVATED:
return null;
case NetworkManager.VPNConnectionState.PREPARE:
case NetworkManager.VPNConnectionState.CONNECT:
case NetworkManager.VPNConnectionState.IP_CONFIG_GET:
return _("connecting...");
case NetworkManager.VPNConnectionState.NEED_AUTH:
/* Translators: this is for network connections that require some kind of key or password */
return _("authentication required");
case NetworkManager.VPNConnectionState.FAILED:
return _("connection failed");
default:
log('VPN connection state invalid, is %d'.format(this.device.state));
return 'invalid';
}
},
_connectionStateChanged: function(connection, newstate, reason) {
if (newstate == NetworkManager.VPNConnectionState.FAILED) {
// FIXME: if we ever want to show something based on reason,
// we need to convert from NetworkManager.VPNConnectionStateReason
// to NetworkManager.DeviceStateReason
this.emit('activation-failed', reason);
}
// Differently from real NMDevices, there is no need to queue
// an update of the menu section, contents wouldn't change anyway
this.emit('state-changed');
}
});
const NMDeviceWireless = new Lang.Class({ const NMDeviceWireless = new Lang.Class({
Name: 'NMDeviceWireless', Name: 'NMDeviceWireless',
Extends: NMDevice, Extends: NMDevice,
@ -1557,6 +1474,151 @@ const NMDeviceWireless = new Lang.Class({
}, },
}); });
const NMVPNSection = new Lang.Class({
Name: 'NMVPNSection',
Extends: NMConnectionBased,
category: NMConnectionCategory.VPN,
_init: function(client, connections) {
this.parent(connections);
this._client = client;
this.section = new PopupMenu.PopupMenuSection();
this._deferredWorkId = Main.initializeDeferredWork(this.section.actor, Lang.bind(this, this._createSection));
},
get empty() {
return this._connections.length == 0;
},
connectionValid: function(connection) {
// filtering is done by NMApplet code
return true;
},
getStatusLabel: function(activeConnection) {
switch(activeConnection.vpn_state) {
case NetworkManager.VPNConnectionState.DISCONNECTED:
case NetworkManager.VPNConnectionState.ACTIVATED:
return null;
case NetworkManager.VPNConnectionState.PREPARE:
case NetworkManager.VPNConnectionState.CONNECT:
case NetworkManager.VPNConnectionState.IP_CONFIG_GET:
return _("connecting...");
case NetworkManager.VPNConnectionState.NEED_AUTH:
/* Translators: this is for network connections that require some kind of key or password */
return _("authentication required");
case NetworkManager.VPNConnectionState.FAILED:
return _("connection failed");
default:
log('VPN connection state invalid, is %d'.format(this.device.state));
return 'invalid';
}
},
clearActiveConnection: function(activeConnection) {
let pos = this._findConnection(activeConnection.uuid);
if (pos < 0)
return;
let obj = this._connections[pos];
obj.active.disconnect(obj.stateChangedId);
obj.active = null;
if (obj.item) {
obj.item.setToggleState(false);
obj.item.setStatus(null);
}
},
setActiveConnection: function(activeConnection) {
let pos = this._findConnection(activeConnection.uuid);
if (pos < 0)
return;
let obj = this._connections[pos];
obj.active = activeConnection;
obj.stateChangedId = obj.active.connect('vpn-state-changed',
Lang.bind(this, this._connectionStateChanged));
if (obj.item) {
obj.item.setToggleState(obj.active.vpn_state ==
NetworkManager.VPNConnectionState.ACTIVATED);
obj.item.setStatus(this.getStatusLabel(obj.active));
}
},
_queueCreateSection: function() {
this.section.removeAll();
Main.queueDeferredWork(this._deferredWorkId);
},
_createConnectionItem: function(obj) {
let menuItem = new PopupMenu.PopupSwitchMenuItem(obj.name, false,
{ style_class: 'popup-subtitle-menu-item' });
menuItem.connect('toggled', Lang.bind(this, function(menuItem) {
if (menuItem.state) {
this._client.activate_connection(obj.connection, null, null, null);
// Immediately go back to disconnected, until NM tells us to change
menuItem.setToggleState(false);
} else if (obj.active) {
this._client.deactivate_connection(obj.active);
}
}));
if (obj.active) {
menuItem.setToggleState(obj.active.vpn_state ==
NetworkManager.VPNConnectionState.ACTIVATED);
menuItem.setStatus(this.getStatusLabel(obj.active));
}
return menuItem;
},
_createSection: function() {
if (this._connections.length > 0) {
this.section.actor.show();
for(let j = 0; j < this._connections.length; ++j) {
let obj = this._connections[j];
obj.item = this._createConnectionItem(obj);
if (j >= NUM_VISIBLE_NETWORKS) {
if (!this._overflowItem) {
this._overflowItem = new PopupMenu.PopupSubMenuMenuItem(_("More..."));
this.section.addMenuItem(this._overflowItem);
}
this._overflowItem.menu.addMenuItem(obj.item);
} else
this.section.addMenuItem(obj.item);
}
} else {
this.section.actor.hide()
}
},
_connectionStateChanged: function(vpnConnection, newstate, reason) {
if (newstate == NetworkManager.VPNConnectionState.FAILED) {
// FIXME: if we ever want to show something based on reason,
// we need to convert from NetworkManager.VPNConnectionStateReason
// to NetworkManager.DeviceStateReason
this.emit('activation-failed', reason);
}
let pos = this._findConnection(vpnConnection.uuid);
if (pos >= 0) {
let obj = this._connections[pos];
if (obj.item) {
obj.item.setToggleState(vpnConnection.vpn_state ==
NetworkManager.VPNConnectionState.ACTIVATED);
obj.item.setStatus(this.getStatusLabel(vpnConnection));
}
} else {
log('Could not find connection for vpn-state-changed handler');
}
},
});
const NMApplet = new Lang.Class({ const NMApplet = new Lang.Class({
Name: 'NMApplet', Name: 'NMApplet',
Extends: PanelMenu.SystemStatusButton, Extends: PanelMenu.SystemStatusButton,
@ -1622,15 +1684,9 @@ const NMApplet = new Lang.Class({
this.menu.addMenuItem(this._devices.wwan.section); this.menu.addMenuItem(this._devices.wwan.section);
this.menu.addMenuItem(new PopupMenu.PopupSeparatorMenuItem()); this.menu.addMenuItem(new PopupMenu.PopupSeparatorMenuItem());
this._devices.vpn = { this._vpnSection = new NMVPNSection(this._client, this._connections);
section: new PopupMenu.PopupMenuSection(), this._vpnSection.connect('activation-failed', Lang.bind(this, this._onActivationFailed));
device: this._makeWrapperDevice(NMDeviceVPN, null), this.menu.addMenuItem(this._vpnSection.section);
item: new NMWiredSectionTitleMenuItem(_("VPN Connections"))
};
this._devices.vpn.section.addMenuItem(this._devices.vpn.item);
this._devices.vpn.section.addMenuItem(this._devices.vpn.device.section);
this._devices.vpn.section.actor.hide();
this.menu.addMenuItem(this._devices.vpn.section);
this.menu.addMenuItem(new PopupMenu.PopupSeparatorMenuItem()); this.menu.addMenuItem(new PopupMenu.PopupSeparatorMenuItem());
this.menu.addSettingsAction(_("Network Settings"), 'gnome-network-panel.desktop'); this.menu.addSettingsAction(_("Network Settings"), 'gnome-network-panel.desktop');
@ -1699,18 +1755,6 @@ const NMApplet = new Lang.Class({
}, },
_syncSectionTitle: function(category) { _syncSectionTitle: function(category) {
if (category == NMConnectionCategory.VPN) {
// Special case VPN: it's only one device (and a fake one
// actually), and we don't show it if empty
let device = this._devices.vpn.device;
let section = this._devices.vpn.section;
let item = this._devices.vpn.item;
section.actor.visible = !device.empty;
item.updateForDevice(device);
return;
}
let devices = this._devices[category].devices; let devices = this._devices[category].devices;
let item = this._devices[category].item; let item = this._devices[category].item;
let section = this._devices[category].section; let section = this._devices[category].section;
@ -1758,17 +1802,20 @@ const NMApplet = new Lang.Class({
this._source.notify(device._notification); this._source.notify(device._notification);
}, },
_onActivationFailed: function(device, reason) {
// XXX: nm-applet has no special text depending on reason
// but I'm not sure of this generic message
this._notifyForDevice(device, 'network-error-symbolic',
_("Connection failed"),
_("Activation of network connection failed"),
MessageTray.Urgency.HIGH);
},
_makeWrapperDevice: function(wrapperClass, device) { _makeWrapperDevice: function(wrapperClass, device) {
let wrapper = new wrapperClass(this._client, device, this._connections); let wrapper = new wrapperClass(this._client, device, this._connections);
wrapper._activationFailedId = wrapper.connect('activation-failed', Lang.bind(this, function(device, reason) { wrapper._activationFailedId = wrapper.connect('activation-failed',
// XXX: nm-applet has no special text depending on reason Lang.bind(this, this._onActivationFailed));
// but I'm not sure of this generic message
this._notifyForDevice(device, 'network-error-symbolic',
_("Connection failed"),
_("Activation of network connection failed"),
MessageTray.Urgency.HIGH);
}));
wrapper._deviceStateChangedId = wrapper.connect('state-changed', Lang.bind(this, function(dev) { wrapper._deviceStateChangedId = wrapper.connect('state-changed', Lang.bind(this, function(dev) {
this._syncSectionTitle(dev.category); this._syncSectionTitle(dev.category);
})); }));
@ -1851,7 +1898,7 @@ const NMApplet = new Lang.Class({
for (let i = 0; i < closedConnections.length; i++) { for (let i = 0; i < closedConnections.length; i++) {
let active = closedConnections[i]; let active = closedConnections[i];
if (active._primaryDevice) { if (active._primaryDevice) {
active._primaryDevice.setActiveConnection(null); active._primaryDevice.clearActiveConnection(active);
active._primaryDevice = null; active._primaryDevice = null;
} }
if (active._inited) { if (active._inited) {
@ -1918,7 +1965,7 @@ const NMApplet = new Lang.Class({
} }
} }
} else } else
a._primaryDevice = this._devices.vpn.device a._primaryDevice = this._vpnSection;
if (a._primaryDevice) if (a._primaryDevice)
a._primaryDevice.setActiveConnection(a); a._primaryDevice.setActiveConnection(a);
@ -2000,8 +2047,7 @@ const NMApplet = new Lang.Class({
let section = connection._section; let section = connection._section;
if (section == NMConnectionCategory.VPN) { if (section == NMConnectionCategory.VPN) {
this._devices.vpn.device.removeConnection(connection); this._vpnSection.removeConnection(connection);
this._syncSectionTitle(section);
} else if (section != NMConnectionCategory.INVALID) { } else if (section != NMConnectionCategory.INVALID) {
let devices = this._devices[section].devices; let devices = this._devices[section].devices;
for (let i = 0; i < devices.length; i++) for (let i = 0; i < devices.length; i++)
@ -2024,8 +2070,7 @@ const NMApplet = new Lang.Class({
if (section == NMConnectionCategory.INVALID) if (section == NMConnectionCategory.INVALID)
return; return;
if (section == NMConnectionCategory.VPN) { if (section == NMConnectionCategory.VPN) {
this._devices.vpn.device.checkConnection(connection); this._vpnSection.checkConnection(connection);
this._syncSectionTitle(section);
} else { } else {
let devices = this._devices[section].devices; let devices = this._devices[section].devices;
for (let i = 0; i < devices.length; i++) { for (let i = 0; i < devices.length; i++) {
@ -2051,7 +2096,6 @@ const NMApplet = new Lang.Class({
this._syncSectionTitle(NMConnectionCategory.WIRED); this._syncSectionTitle(NMConnectionCategory.WIRED);
this._syncSectionTitle(NMConnectionCategory.WIRELESS); this._syncSectionTitle(NMConnectionCategory.WIRELESS);
this._syncSectionTitle(NMConnectionCategory.WWAN); this._syncSectionTitle(NMConnectionCategory.WWAN);
this._syncSectionTitle(NMConnectionCategory.VPN);
}, },
_syncNMState: function() { _syncNMState: function() {

View File

@ -208,9 +208,13 @@ const UnlockDialog = new Lang.Class({
}, },
_showMessage: function(userVerifier, message, styleClass) { _showMessage: function(userVerifier, message, styleClass) {
this._promptMessage.text = message; if (message) {
this._promptMessage.styleClass = styleClass; this._promptMessage.text = message;
GdmUtil.fadeInActor(this._promptMessage); this._promptMessage.styleClass = styleClass;
GdmUtil.fadeInActor(this._promptMessage);
} else {
GdmUtil.fadeOutActor(this._promptMessage);
}
}, },
_onAskQuestion: function(verifier, serviceName, question, passwordChar) { _onAskQuestion: function(verifier, serviceName, question, passwordChar) {
@ -278,6 +282,7 @@ const UnlockDialog = new Lang.Class({
this._currentQuery = null; this._currentQuery = null;
this._firstQuestion = true; this._firstQuestion = true;
this._promptEntry.text = '';
this._promptEntry.clutter_text.set_password_char('\u25cf'); this._promptEntry.clutter_text.set_password_char('\u25cf');
this._promptEntry.menu.isPassword = true; this._promptEntry.menu.isPassword = true;

View File

@ -26,6 +26,7 @@ const DISABLE_USER_SWITCH_KEY = 'disable-user-switching';
const DISABLE_LOCK_SCREEN_KEY = 'disable-lock-screen'; const DISABLE_LOCK_SCREEN_KEY = 'disable-lock-screen';
const DISABLE_LOG_OUT_KEY = 'disable-log-out'; const DISABLE_LOG_OUT_KEY = 'disable-log-out';
const LOCK_ENABLED_KEY = 'lock-enabled'; const LOCK_ENABLED_KEY = 'lock-enabled';
const ALWAYS_SHOW_LOG_OUT_KEY = 'always-show-log-out';
const DIALOG_ICON_SIZE = 64; const DIALOG_ICON_SIZE = 64;
@ -187,7 +188,7 @@ const IMStatusChooserItem = new Lang.Class({
item = new IMStatusItem(_("Idle"), 'user-idle-symbolic'); item = new IMStatusItem(_("Idle"), 'user-idle-symbolic');
this._combo.addMenuItem(item, IMStatus.IDLE); this._combo.addMenuItem(item, IMStatus.IDLE);
item = new IMStatusItem(_("Unavailable"), 'user-offline-symbolic'); item = new IMStatusItem(_("Offline"), 'user-offline-symbolic');
this._combo.addMenuItem(item, IMStatus.OFFLINE); this._combo.addMenuItem(item, IMStatus.OFFLINE);
this._combo.connect('active-item-changed', this._combo.connect('active-item-changed',
@ -616,10 +617,13 @@ const UserMenuButton = new Lang.Class({
_updateLogout: function() { _updateLogout: function() {
let allowLogout = !this._lockdownSettings.get_boolean(DISABLE_LOG_OUT_KEY); let allowLogout = !this._lockdownSettings.get_boolean(DISABLE_LOG_OUT_KEY);
let alwaysShow = global.settings.get_boolean(ALWAYS_SHOW_LOG_OUT_KEY);
let systemAccount = this._user.system_account;
let localAccount = this._user.local_account;
let multiUser = this._userManager.has_multiple_users; let multiUser = this._userManager.has_multiple_users;
let multiSession = Gdm.get_session_ids().length > 1; let multiSession = Gdm.get_session_ids().length > 1;
this._logoutItem.actor.visible = allowLogout && (multiUser || multiSession); this._logoutItem.actor.visible = allowLogout && (alwaysShow || multiUser || multiSession || systemAccount || !localAccount);
}, },
_updateLockScreen: function() { _updateLockScreen: function() {

View File

@ -52,7 +52,7 @@ const ViewSelector = new Lang.Class({
this._activePage = null; this._activePage = null;
this.active = false; this.entryNonEmpty = false;
this._searchPending = false; this._searchPending = false;
this._searchTimeoutId = 0; this._searchTimeoutId = 0;
@ -90,7 +90,7 @@ const ViewSelector = new Lang.Class({
this._appsPage = this._addPage(this._appDisplay.actor, null, this._appsPage = this._addPage(this._appDisplay.actor, null,
_("Applications"), 'system-run-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, this._searchPage = this._addPage(this._searchResults.actor, this._entry,
_("Search"), 'edit-find-symbolic'); _("Search"), 'edit-find-symbolic');
@ -114,9 +114,6 @@ const ViewSelector = new Lang.Class({
global.focus_manager.add_group(this._searchResults.actor); global.focus_manager.add_group(this._searchResults.actor);
Main.overview.connect('item-drag-begin',
Lang.bind(this, this._resetShowAppsButton));
this._stageKeyPressId = 0; this._stageKeyPressId = 0;
Main.overview.connect('showing', Lang.bind(this, Main.overview.connect('showing', Lang.bind(this,
function () { function () {
@ -133,17 +130,6 @@ 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 });
global.display.add_keybinding('toggle-application-view', global.display.add_keybinding('toggle-application-view',
new Gio.Settings({ schema: SHELL_KEYBINDINGS_SCHEMA }), new Gio.Settings({ schema: SHELL_KEYBINDINGS_SCHEMA }),
Meta.KeyBindingFlags.NONE, Meta.KeyBindingFlags.NONE,
@ -230,7 +216,9 @@ const ViewSelector = new Lang.Class({
}, },
_onShowAppsButtonToggled: function() { _onShowAppsButtonToggled: function() {
if (this.active) this.emit('apps-button-checked', this._showAppsButton.checked);
if (this.entryNonEmpty)
this.reset(); this.reset();
else else
this._showPage(this._showAppsButton.checked ? this._appsPage this._showPage(this._showAppsButton.checked ? this._appsPage
@ -246,7 +234,7 @@ const ViewSelector = new Lang.Class({
let symbol = event.get_key_symbol(); let symbol = event.get_key_symbol();
if (symbol == Clutter.Escape) { if (symbol == Clutter.Escape) {
if (this.active) if (this.entryNonEmpty)
this.reset(); this.reset();
else if (this._showAppsButton.checked) else if (this._showAppsButton.checked)
this._resetShowAppsButton(); this._resetShowAppsButton();
@ -254,9 +242,9 @@ const ViewSelector = new Lang.Class({
Main.overview.hide(); Main.overview.hide();
return true; return true;
} else if (Clutter.keysym_to_unicode(symbol) || } else if (Clutter.keysym_to_unicode(symbol) ||
(symbol == Clutter.BackSpace && this.active)) { (symbol == Clutter.BackSpace && this.entryNonEmpty)) {
this.startSearch(event); this.startSearch(event);
} else if (!this.active) { } else if (!this.entryNonEmpty) {
if (symbol == Clutter.Tab || symbol == Clutter.Down) { if (symbol == Clutter.Tab || symbol == Clutter.Down) {
this._activePage.navigate_focus(null, Gtk.DirectionType.TAB_FORWARD, false); this._activePage.navigate_focus(null, Gtk.DirectionType.TAB_FORWARD, false);
return true; return true;
@ -269,6 +257,7 @@ const ViewSelector = new Lang.Class({
}, },
_searchCancelled: function() { _searchCancelled: function() {
this.emit('search-cancelled');
this._showPage(this._showAppsButton.checked ? this._appsPage this._showPage(this._showAppsButton.checked ? this._appsPage
: this._workspacesPage); : this._workspacesPage);
@ -330,13 +319,14 @@ const ViewSelector = new Lang.Class({
}, },
_onTextChanged: function (se, prop) { _onTextChanged: function (se, prop) {
let searchPreviouslyActive = this.active; let searchPreviouslyActive = this.entryNonEmpty;
this.active = this._entry.get_text() != ''; this.entryNonEmpty = this._entry.get_text() != '';
this._searchPending = this.active && !searchPreviouslyActive; this._searchPending = this.entryNonEmpty && !searchPreviouslyActive;
if (this._searchPending) { if (this._searchPending) {
this._searchResults.startingSearch(); this._searchResults.startingSearch();
} }
if (this.active) { if (this.entryNonEmpty) {
this.emit('search-begin');
this._entry.set_secondary_icon(this._activeIcon); this._entry.set_secondary_icon(this._activeIcon);
if (this._iconClickedId == 0) { if (this._iconClickedId == 0) {
@ -353,7 +343,7 @@ const ViewSelector = new Lang.Class({
this._entry.set_secondary_icon(this._inactiveIcon); this._entry.set_secondary_icon(this._inactiveIcon);
this._searchCancelled(); this._searchCancelled();
} }
if (!this.active) { if (!this.entryNonEmpty) {
if (this._searchTimeoutId > 0) { if (this._searchTimeoutId > 0) {
Mainloop.source_remove(this._searchTimeoutId); Mainloop.source_remove(this._searchTimeoutId);
this._searchTimeoutId = 0; this._searchTimeoutId = 0;
@ -381,7 +371,7 @@ const ViewSelector = new Lang.Class({
} }
this._searchResults.activateDefault(); this._searchResults.activateDefault();
return true; return true;
} else if (this.active) { } else if (this.entryNonEmpty) {
let arrowNext, nextDirection; let arrowNext, nextDirection;
if (entry.get_text_direction() == Clutter.TextDirection.RTL) { if (entry.get_text_direction() == Clutter.TextDirection.RTL) {
arrowNext = Clutter.Left; arrowNext = Clutter.Left;

View File

@ -159,6 +159,24 @@ const WindowClone = new Lang.Class({
this._selected = false; this._selected = false;
}, },
get slot() {
let x, y, w, h;
if (this.inDrag) {
x = this.dragOrigX;
y = this.dragOrigY;
w = this.actor.width * this.dragOrigScale;
h = this.actor.height * this.dragOrigScale;
} else {
x = this.actor.x;
y = this.actor.y;
w = this.actor.width * this.actor.scale_x;
h = this.actor.height * this.actor.scale_y;
}
return [x, y, w, h];
},
setStackAbove: function (actor) { setStackAbove: function (actor) {
this._stackAbove = actor; this._stackAbove = actor;
if (this.inDrag || this._zooming) if (this.inDrag || this._zooming)
@ -435,6 +453,11 @@ const WindowOverlay = new Lang.Class({
this._updateCaptionId = metaWindow.connect('notify::title', this._updateCaptionId = metaWindow.connect('notify::title',
Lang.bind(this, function(w) { Lang.bind(this, function(w) {
this.title.text = w.title; this.title.text = w.title;
// we need this for the next call to get_preferred_width
// to return useful results
this.title.set_size(-1, -1);
this._repositionSelf();
})); }));
let button = new St.Button({ style_class: 'window-close' }); let button = new St.Button({ style_class: 'window-close' });
@ -501,6 +524,11 @@ const WindowOverlay = new Lang.Class({
this.title.height + this.title._spacing]; this.title.height + this.title._spacing];
}, },
_repositionSelf: function() {
let [cloneX, cloneY, cloneWidth, cloneHeight] = this._windowClone.slot;
this.updatePositions(cloneX, cloneY, cloneWidth, cloneHeight, false);
},
/** /**
* @cloneX: x position of windowClone * @cloneX: x position of windowClone
* @cloneY: y position of windowClone * @cloneY: y position of windowClone
@ -538,9 +566,8 @@ const WindowOverlay = new Lang.Class({
else else
button.set_position(Math.floor(buttonX), Math.floor(buttonY)); button.set_position(Math.floor(buttonX), Math.floor(buttonY));
if (!title.fullWidth) let [titleMinWidth, titleNatWidth] = title.get_preferred_width(-1);
title.fullWidth = title.width; let titleWidth = Math.max(titleMinWidth, Math.min(titleNatWidth, cloneWidth));
let titleWidth = Math.min(title.fullWidth, cloneWidth);
let titleX = cloneX + (cloneWidth - titleWidth) / 2; let titleX = cloneX + (cloneWidth - titleWidth) / 2;
let titleY = cloneY + cloneHeight + title._spacing; let titleY = cloneY + cloneHeight + title._spacing;
@ -1046,6 +1073,9 @@ const Workspace = new Lang.Class({
* ANIMATE - Indicates that we need animate changing position. * ANIMATE - Indicates that we need animate changing position.
*/ */
positionWindows: function(flags) { positionWindows: function(flags) {
if (this.leavingOverview)
return;
this._positionWindowsFlags |= flags; this._positionWindowsFlags |= flags;
if (this._positionWindowsId > 0) if (this._positionWindowsId > 0)

View File

@ -493,6 +493,7 @@ const ThumbnailsBox = new Lang.Class({
_init: function() { _init: function() {
this.actor = new Shell.GenericContainer({ reactive: true, this.actor = new Shell.GenericContainer({ reactive: true,
style_class: 'workspace-thumbnails', style_class: 'workspace-thumbnails',
can_focus: true,
request_mode: Clutter.RequestMode.WIDTH_FOR_HEIGHT }); request_mode: Clutter.RequestMode.WIDTH_FOR_HEIGHT });
this.actor.connect('get-preferred-width', Lang.bind(this, this._getPreferredWidth)); this.actor.connect('get-preferred-width', Lang.bind(this, this._getPreferredWidth));
this.actor.connect('get-preferred-height', Lang.bind(this, this._getPreferredHeight)); this.actor.connect('get-preferred-height', Lang.bind(this, this._getPreferredHeight));
@ -526,6 +527,8 @@ const ThumbnailsBox = new Lang.Class({
this._dropPlaceholder = new St.Bin({ style_class: 'placeholder' }); this._dropPlaceholder = new St.Bin({ style_class: 'placeholder' });
this.actor.add_actor(this._dropPlaceholder); this.actor.add_actor(this._dropPlaceholder);
this.visible = true;
this._targetScale = 0; this._targetScale = 0;
this._scale = 0; this._scale = 0;
this._pendingScaleUpdate = false; 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-press-event', function() { return true; });
this.actor.connect('button-release-event', Lang.bind(this, this._onButtonRelease)); 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)); Lang.bind(this, this._onDragBegin));
Main.overview.connect('item-drag-end', Main.overview.connect('app-drag-end',
Lang.bind(this, this._onDragEnd)); Lang.bind(this, this._onDragEnd));
Main.overview.connect('item-drag-cancelled', Main.overview.connect('app-drag-cancelled',
Lang.bind(this, this._onDragCancelled)); Lang.bind(this, this._onDragCancelled));
Main.overview.connect('window-drag-begin', Main.overview.connect('window-drag-begin',
Lang.bind(this, this._onDragBegin)); Lang.bind(this, this._onDragBegin));
@ -719,10 +731,16 @@ const ThumbnailsBox = new Lang.Class({
} }
}, },
show: function() { _createThumbnails: function() {
this._switchWorkspaceNotifyId = this._switchWorkspaceNotifyId =
global.window_manager.connect('switch-workspace', global.window_manager.connect('switch-workspace',
Lang.bind(this, this._activeWorkspaceChanged)); Lang.bind(this, this._activeWorkspaceChanged));
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._targetScale = 0;
this._scale = 0; this._scale = 0;
@ -746,17 +764,86 @@ const ThumbnailsBox = new Lang.Class({
this.addThumbnails(0, global.screen.n_workspaces); this.addThumbnails(0, global.screen.n_workspaces);
}, },
hide: function() { _destroyThumbnails: function() {
if (this._switchWorkspaceNotifyId > 0) { if (this._switchWorkspaceNotifyId > 0) {
global.window_manager.disconnect(this._switchWorkspaceNotifyId); global.window_manager.disconnect(this._switchWorkspaceNotifyId);
this._switchWorkspaceNotifyId = 0; 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++) for (let w = 0; w < this._thumbnails.length; w++)
this._thumbnails[w].destroy(); this._thumbnails[w].destroy();
this._thumbnails = []; 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) { addThumbnails: function(start, count) {
for (let k = start; k < start + count; k++) { for (let k = start; k < start + count; k++) {
let metaWorkspace = global.screen.get_workspace_by_index(k); let metaWorkspace = global.screen.get_workspace_by_index(k);
@ -802,7 +889,7 @@ const ThumbnailsBox = new Lang.Class({
this._queueUpdateStates(); this._queueUpdateStates();
}, },
syncStacking: function(stackIndices) { syncStacking: function(actor, stackIndices) {
for (let i = 0; i < this._thumbnails.length; i++) for (let i = 0; i < this._thumbnails.length; i++)
this._thumbnails[i].syncStacking(stackIndices); this._thumbnails[i].syncStacking(stackIndices);
}, },
@ -924,6 +1011,8 @@ const ThumbnailsBox = new Lang.Class({
onCompleteScope: this onCompleteScope: this
}); });
}); });
this._computeThumbnailsX();
}, },
_queueUpdateStates: function() { _queueUpdateStates: function() {
@ -1157,5 +1246,30 @@ const ThumbnailsBox = new Lang.Class({
}, },
onCompleteScope: this 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 OVERRIDE_SCHEMA = 'org.gnome.shell.overrides';
const CONTROLS_POP_IN_TIME = 0.1;
const WorkspacesView = new Lang.Class({ const WorkspacesView = new Lang.Class({
Name: 'WorkspacesView', Name: 'WorkspacesView',
@ -106,9 +104,9 @@ const WorkspacesView = new Lang.Class({
global.window_manager.connect('switch-workspace', global.window_manager.connect('switch-workspace',
Lang.bind(this, this._activeWorkspaceChanged)); 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)); 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)); Lang.bind(this, this._dragEnd));
this._windowDragBeginId = Main.overview.connect('window-drag-begin', this._windowDragBeginId = Main.overview.connect('window-drag-begin',
Lang.bind(this, this._dragBegin)); Lang.bind(this, this._dragBegin));
@ -327,13 +325,13 @@ const WorkspacesView = new Lang.Class({
if (this._inDrag) if (this._inDrag)
this._dragEnd(); this._dragEnd();
if (this._itemDragBeginId > 0) { if (this._appDragBeginId > 0) {
Main.overview.disconnect(this._itemDragBeginId); Main.overview.disconnect(this._appDragBeginId);
this._itemDragBeginId = 0; this._appDragBeginId = 0;
} }
if (this._itemDragEndId > 0) { if (this._appDragEndId > 0) {
Main.overview.disconnect(this._itemDragEndId); Main.overview.disconnect(this._appDragEndId);
this._itemDragEndId = 0; this._appDragEndId = 0;
} }
if (this._windowDragBeginId > 0) { if (this._windowDragBeginId > 0) {
Main.overview.disconnect(this._windowDragBeginId); Main.overview.disconnect(this._windowDragBeginId);
@ -460,25 +458,8 @@ const WorkspacesDisplay = new Lang.Class({
this.actor.connect('parent-set', Lang.bind(this, this._parentSet)); this.actor.connect('parent-set', Lang.bind(this, this._parentSet));
this.actor.set_clip_to_allocation(true); 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._primaryIndex = Main.layoutManager.primaryIndex;
this._thumbnailsBox = new WorkspaceThumbnail.ThumbnailsBox();
controls.add_actor(this._thumbnailsBox.actor);
this._workspacesViews = null; this._workspacesViews = null;
this._primaryScrollAdjustment = null; this._primaryScrollAdjustment = null;
@ -491,34 +472,14 @@ const WorkspacesDisplay = new Lang.Class({
this._inDrag = false; this._inDrag = false;
this._cancelledDrag = 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', global.screen.connect('notify::n-workspaces',
Lang.bind(this, this._workspacesChanged)); Lang.bind(this, this._workspacesChanged));
this._switchWorkspaceNotifyId = 0; this._switchWorkspaceNotifyId = 0;
this._itemDragBeginId = 0; this._appDragBeginId = 0;
this._itemDragCancelledId = 0; this._appDragCancelledId = 0;
this._itemDragEndId = 0; this._appDragEndId = 0;
this._windowDragBeginId = 0; this._windowDragBeginId = 0;
this._windowDragCancelledId = 0; this._windowDragCancelledId = 0;
this._windowDragEndId = 0; this._windowDragEndId = 0;
@ -538,41 +499,20 @@ const WorkspacesDisplay = new Lang.Class({
}, },
show: function() { 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._updateWorkspacesViews();
this._restackedNotifyId = this._restackedNotifyId =
global.screen.connect('restacked', Main.overview.connect('sync-window-stacking',
Lang.bind(this, this._onRestacked)); Lang.bind(this, this._onRestacked));
if (this._itemDragBeginId == 0) if (this._appDragBeginId == 0)
this._itemDragBeginId = Main.overview.connect('item-drag-begin', this._appDragBeginId = Main.overview.connect('app-drag-begin',
Lang.bind(this, this._dragBegin)); Lang.bind(this, this._dragBegin));
if (this._itemDragCancelledId == 0) if (this._appDragCancelledId == 0)
this._itemDragCancelledId = Main.overview.connect('item-drag-cancelled', this._appDragCancelledId = Main.overview.connect('app-drag-cancelled',
Lang.bind(this, this._dragCancelled)); Lang.bind(this, this._dragCancelled));
if (this._itemDragEndId == 0) if (this._appDragEndId == 0)
this._itemDragEndId = Main.overview.connect('item-drag-end', this._appDragEndId = Main.overview.connect('app-drag-end',
Lang.bind(this, this._dragEnd)); Lang.bind(this, this._dragEnd));
if (this._windowDragBeginId == 0) if (this._windowDragBeginId == 0)
this._windowDragBeginId = Main.overview.connect('window-drag-begin', this._windowDragBeginId = Main.overview.connect('window-drag-begin',
@ -583,8 +523,6 @@ const WorkspacesDisplay = new Lang.Class({
if (this._windowDragEndId == 0) if (this._windowDragEndId == 0)
this._windowDragEndId = Main.overview.connect('window-drag-end', this._windowDragEndId = Main.overview.connect('window-drag-end',
Lang.bind(this, this._dragEnd)); Lang.bind(this, this._dragEnd));
this._onRestacked();
}, },
zoomFromOverview: function() { zoomFromOverview: function() {
@ -594,27 +532,21 @@ const WorkspacesDisplay = new Lang.Class({
}, },
hide: function() { hide: function() {
this._controls.hide();
this._thumbnailsBox.hide();
if (!this._alwaysZoomOut)
this.zoomFraction = 0;
if (this._restackedNotifyId > 0){ if (this._restackedNotifyId > 0){
global.screen.disconnect(this._restackedNotifyId); Main.overview.disconnect(this._restackedNotifyId);
this._restackedNotifyId = 0; this._restackedNotifyId = 0;
} }
if (this._itemDragBeginId > 0) { if (this._appDragBeginId > 0) {
Main.overview.disconnect(this._itemDragBeginId); Main.overview.disconnect(this._appDragBeginId);
this._itemDragBeginId = 0; this._appDragBeginId = 0;
} }
if (this._itemDragCancelledId > 0) { if (this._appDragCancelledId > 0) {
Main.overview.disconnect(this._itemDragCancelledId); Main.overview.disconnect(this._appDragCancelledId);
this._itemDragCancelledId = 0; this._appDragCancelledId = 0;
} }
if (this._itemDragEndId > 0) { if (this._appDragEndId > 0) {
Main.overview.disconnect(this._itemDragEndId); Main.overview.disconnect(this._appDragEndId);
this._itemDragEndId = 0; this._appDragEndId = 0;
} }
if (this._windowDragBeginId > 0) { if (this._windowDragBeginId > 0) {
Main.overview.disconnect(this._windowDragBeginId); Main.overview.disconnect(this._windowDragBeginId);
@ -745,73 +677,15 @@ const WorkspacesDisplay = new Lang.Class({
return this._getPrimaryView().getActiveWorkspace().hasMaximizedWindows(); 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) { _getPreferredWidth: function (actor, forHeight, alloc) {
// pass through the call in case the child needs it, but report 0x0 // pass through the call in case the child needs it, but report 0x0
this._controls.get_preferred_width(forHeight);
}, },
_getPreferredHeight: function (actor, forWidth, alloc) { _getPreferredHeight: function (actor, forWidth, alloc) {
// pass through the call in case the child needs it, but report 0x0 // pass through the call in case the child needs it, but report 0x0
this._controls.get_preferred_height(forWidth);
}, },
_allocate: function (actor, box, flags) { _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(); this._updateWorkspacesGeometry();
}, },
@ -851,24 +725,15 @@ const WorkspacesDisplay = new Lang.Class({
let width = fullWidth; let width = fullWidth;
let height = fullHeight; 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 [x, y] = this.actor.get_transformed_position();
let rtl = (Clutter.get_default_text_direction () == Clutter.TextDirection.RTL); let rtl = (Clutter.get_default_text_direction () == Clutter.TextDirection.RTL);
let clipWidth = width - controlsVisible; let clipWidth = width;
let clipHeight = fullHeight; let clipHeight = fullHeight;
let clipX = rtl ? x + controlsVisible : x; let clipX = x;
let clipY = y + (fullHeight - clipHeight) / 2; let clipY = y + (fullHeight - clipHeight) / 2;
let widthAdjust = this._zoomOut ? controlsNatural : controlsVisible;
widthAdjust += Main.overview._spacing;
width -= widthAdjust;
if (rtl)
x += widthAdjust;
let monitors = Main.layoutManager.monitors; let monitors = Main.layoutManager.monitors;
let m = 0; let m = 0;
for (let i = 0; i < monitors.length; i++) { for (let i = 0; i < monitors.length; i++) {
@ -891,25 +756,12 @@ const WorkspacesDisplay = new Lang.Class({
} }
}, },
_onRestacked: function() { _onRestacked: function(actor, stackIndices) {
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;
}
for (let i = 0; i < this._workspacesViews.length; i++) for (let i = 0; i < this._workspacesViews.length; i++)
this._workspacesViews[i].syncStacking(stackIndices); this._workspacesViews[i].syncStacking(stackIndices);
this._thumbnailsBox.syncStacking(stackIndices);
}, },
_workspacesChanged: function() { _workspacesChanged: function() {
this._updateAlwaysZoom();
this._updateZoom();
if (this._workspacesViews == null) if (this._workspacesViews == null)
return; return;
@ -934,8 +786,6 @@ const WorkspacesDisplay = new Lang.Class({
} }
m++; m++;
} }
this._thumbnailsBox.addThumbnails(oldNumWorkspaces, newNumWorkspaces - oldNumWorkspaces);
} else { } else {
// Assume workspaces are only removed sequentially // Assume workspaces are only removed sequentially
// (e.g. 2,3,4 - not 2,4,7) // (e.g. 2,3,4 - not 2,4,7)
@ -958,8 +808,6 @@ const WorkspacesDisplay = new Lang.Class({
lostWorkspaces[l].destroy(); lostWorkspaces[l].destroy();
} }
} }
this._thumbnailsBox.removeThumbnails(removedIndex, removedNum);
} }
for (let i = 0; i < this._workspacesViews.length; i++) for (let i = 0; i < this._workspacesViews.length; i++)
@ -968,35 +816,6 @@ const WorkspacesDisplay = new Lang.Class({
this._updateSwitcherVisibility(); 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() { _dragBegin: function() {
this._inDrag = true; this._inDrag = true;
this._cancelledDrag = false; this._cancelledDrag = false;
@ -1012,33 +831,11 @@ const WorkspacesDisplay = new Lang.Class({
}, },
_onDragMotion: function(dragEvent) { _onDragMotion: function(dragEvent) {
let controlsHovered = this._controls.contains(dragEvent.targetActor);
this._controls.set_hover(controlsHovered);
return DND.DragMotionResult.CONTINUE; return DND.DragMotionResult.CONTINUE;
}, },
_dragEnd: function() { _dragEnd: function() {
this._inDrag = false; 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); Signals.addSignalMethods(WorkspacesDisplay.prototype);

View File

@ -708,7 +708,7 @@ msgstr "ارسال در <b>%A</b>, <b>%B %d</b>, %Y"
#: ../js/ui/components/telepathyClient.js:988 #: ../js/ui/components/telepathyClient.js:988
#, c-format #, c-format
msgid "%s is now known as %s" msgid "%s is now known as %s"
msgstr "%s با عنوان %s شناخته می‌شود" msgstr "%s با عنوان %s شناخته می‌شود"
#. translators: argument is a room name like #. translators: argument is a room name like
#. * room@jabber.org for example. #. * room@jabber.org for example.
@ -723,7 +723,7 @@ msgstr "دعوتنامه به %s"
#: ../js/ui/components/telepathyClient.js:1096 #: ../js/ui/components/telepathyClient.js:1096
#, c-format #, c-format
msgid "%s is inviting you to join %s" msgid "%s is inviting you to join %s"
msgstr "%s از شما دعوت می‌کند که به %s بپیوندید" msgstr "%s از شما دعوت می‌کند که به %s بپیوندید"
#: ../js/ui/components/telepathyClient.js:1098 #: ../js/ui/components/telepathyClient.js:1098
#: ../js/ui/components/telepathyClient.js:1177 #: ../js/ui/components/telepathyClient.js:1177
@ -767,13 +767,13 @@ msgstr "پاسخگویی"
#: ../js/ui/components/telepathyClient.js:1171 #: ../js/ui/components/telepathyClient.js:1171
#, c-format #, c-format
msgid "%s is sending you %s" msgid "%s is sending you %s"
msgstr "%s در حال ارسال %s به شما است" msgstr "%s در حال ارسال %s به شما است"
#. To translators: The parameter is the contact's alias #. To translators: The parameter is the contact's alias
#: ../js/ui/components/telepathyClient.js:1206 #: ../js/ui/components/telepathyClient.js:1206
#, c-format #, c-format
msgid "%s would like permission to see when you are online" msgid "%s would like permission to see when you are online"
msgstr "%s اجازه دسترسی برای دیدن زمان‌هایی که شما برخط هستید را دارد" msgstr "%s اجازه دسترسی برای دیدن زمان‌هایی که شما برخط هستید را دارد"
#: ../js/ui/components/telepathyClient.js:1298 #: ../js/ui/components/telepathyClient.js:1298
msgid "Network error" msgid "Network error"
@ -938,8 +938,8 @@ msgstr ""
#, c-format #, c-format
msgid "%s will be logged out automatically in %d second." msgid "%s will be logged out automatically in %d second."
msgid_plural "%s will be logged out automatically in %d seconds." msgid_plural "%s will be logged out automatically in %d seconds."
msgstr[0] "%s به طور خودکار در مدت %Id ثانیه از سیستم خارج خواهد شد." msgstr[0] "%s به طور خودکار در مدت %Id ثانیه از سیستم خارج خواهد شد."
msgstr[1] "%s به طور خودکار در مدت %Id ثانیه از سیستم خارج خواهد شد." msgstr[1] "%s به طور خودکار در مدت %Id ثانیه از سیستم خارج خواهد شد."
#: ../js/ui/endSessionDialog.js:70 #: ../js/ui/endSessionDialog.js:70
#, c-format #, c-format
@ -1698,7 +1698,7 @@ msgstr ""
#: ../js/ui/wanda.js:121 #: ../js/ui/wanda.js:121
#, c-format #, c-format
msgid "%s the Oracle says" msgid "%s the Oracle says"
msgstr "%s پیشگو می‌گوید" msgstr "%s پیشگو می‌گوید"
#: ../js/ui/wanda.js:162 #: ../js/ui/wanda.js:162
msgid "Your favorite Easter Egg" msgid "Your favorite Easter Egg"
@ -1852,16 +1852,16 @@ msgstr "محاوره تایید هویت از طرف کاربر رد شد"
#~ msgstr "شبکه" #~ msgstr "شبکه"
#~ msgid "%s is online." #~ msgid "%s is online."
#~ msgstr "%s بر خط است." #~ msgstr "%s بر خط است."
#~ msgid "%s is offline." #~ msgid "%s is offline."
#~ msgstr "%s برون خط است." #~ msgstr "%s برون خط است."
#~ msgid "%s is away." #~ msgid "%s is away."
#~ msgstr "%s غایب است." #~ msgstr "%s غایب است."
#~ msgid "%s is busy." #~ msgid "%s is busy."
#~ msgstr "%s مشغول است." #~ msgstr "%s مشغول است."
#~ msgid "Hidden" #~ msgid "Hidden"
#~ msgstr "نامرئی" #~ msgstr "نامرئی"

View File

@ -351,12 +351,12 @@ msgstr "הוספה למועדפים"
#: ../js/ui/appFavorites.js:87 #: ../js/ui/appFavorites.js:87
#, c-format #, c-format
msgid "%s has been added to your favorites." msgid "%s has been added to your favorites."
msgstr "%s נוסף למועדפים שלך." msgstr "%s נוסף למועדפים שלך."
#: ../js/ui/appFavorites.js:118 #: ../js/ui/appFavorites.js:118
#, c-format #, c-format
msgid "%s has been removed from your favorites." msgid "%s has been removed from your favorites."
msgstr "%s הוסר מהמועדפים שלך." msgstr "%s הוסר מהמועדפים שלך."
#. Translators: Shown in calendar event list for all day events #. Translators: Shown in calendar event list for all day events
#. * Keep it short, best if you can use less then 10 characters #. * Keep it short, best if you can use less then 10 characters
@ -751,13 +751,13 @@ msgstr "מענה"
#: ../js/ui/components/telepathyClient.js:1171 #: ../js/ui/components/telepathyClient.js:1171
#, c-format #, c-format
msgid "%s is sending you %s" msgid "%s is sending you %s"
msgstr "%s שולח/ת אליך %s" msgstr "%s שולח/ת אליך %s"
#. To translators: The parameter is the contact's alias #. To translators: The parameter is the contact's alias
#: ../js/ui/components/telepathyClient.js:1206 #: ../js/ui/components/telepathyClient.js:1206
#, c-format #, c-format
msgid "%s would like permission to see when you are online" msgid "%s would like permission to see when you are online"
msgstr "%s רוצה לקבל הרשאות כדי לראות מתי מצבך הוא מקוון" msgstr "%s רוצה לקבל הרשאות כדי לראות מתי מצבך הוא מקוון"
#: ../js/ui/components/telepathyClient.js:1298 #: ../js/ui/components/telepathyClient.js:1298
msgid "Network error" msgid "Network error"
@ -1017,7 +1017,7 @@ msgstr "לא מותקנות הרחבות"
#: ../js/ui/lookingGlass.js:745 #: ../js/ui/lookingGlass.js:745
#, c-format #, c-format
msgid "%s has not emitted any errors." msgid "%s has not emitted any errors."
msgstr "%s לא העלה שגיאות כלשהן." msgstr "%s לא העלה שגיאות כלשהן."
#: ../js/ui/lookingGlass.js:751 #: ../js/ui/lookingGlass.js:751
msgid "Hide Errors" msgid "Hide Errors"
@ -1436,7 +1436,7 @@ msgstr "חיוג אוטומטי"
#: ../js/ui/status/network.js:853 ../js/ui/status/network.js:1476 #: ../js/ui/status/network.js:853 ../js/ui/status/network.js:1476
#, c-format #, c-format
msgid "Auto %s" msgid "Auto %s"
msgstr "%s אוטומטי" msgstr "%s אוטומטי"
#: ../js/ui/status/network.js:855 #: ../js/ui/status/network.js:855
msgid "Auto bluetooth" msgid "Auto bluetooth"
@ -1688,7 +1688,7 @@ msgstr ""
#: ../js/ui/wanda.js:123 #: ../js/ui/wanda.js:123
#, c-format #, c-format
msgid "%s the Oracle says" msgid "%s the Oracle says"
msgstr "%s, כה אמרה האוראקל" msgstr "%s, כה אמרה האוראקל"
#: ../js/ui/wanda.js:164 #: ../js/ui/wanda.js:164
msgid "Your favorite Easter Egg" msgid "Your favorite Easter Egg"
@ -1697,7 +1697,7 @@ msgstr "ביצת הפסחא האהובה עליך"
#: ../js/ui/windowAttentionHandler.js:19 #: ../js/ui/windowAttentionHandler.js:19
#, c-format #, c-format
msgid "'%s' is ready" msgid "'%s' is ready"
msgstr "'%s' מוכן" msgstr "'%s' מוכן"
#: ../src/calendar-server/evolution-calendar.desktop.in.in.h:1 #: ../src/calendar-server/evolution-calendar.desktop.in.in.h:1
msgid "Evolution Calendar" msgid "Evolution Calendar"
@ -1845,16 +1845,16 @@ msgstr "המשתמש בחר להתעלם מתיבת דו־שיח האימות"
#~ msgstr "רשת" #~ msgstr "רשת"
#~ msgid "%s is online." #~ msgid "%s is online."
#~ msgstr "%s התחבר/ה." #~ msgstr "%s התחבר/ה."
#~ msgid "%s is offline." #~ msgid "%s is offline."
#~ msgstr "%s התנתק/ה." #~ msgstr "%s התנתק/ה."
#~ msgid "%s is away." #~ msgid "%s is away."
#~ msgstr "'%s' מרוחק/ת." #~ msgstr "'%s' מרוחק/ת."
#~ msgid "%s is busy." #~ msgid "%s is busy."
#~ msgstr "%s עסוק/ה." #~ msgstr "%s עסוק/ה."
#~ msgid "Hidden" #~ msgid "Hidden"
#~ msgstr "מוסתר" #~ msgstr "מוסתר"
@ -1887,7 +1887,7 @@ msgstr "המשתמש בחר להתעלם מתיבת דו־שיח האימות"
#~ msgstr "הצגת ססמה" #~ msgstr "הצגת ססמה"
#~ msgid "%s has finished starting" #~ msgid "%s has finished starting"
#~ msgstr "%s סיים את תהליך ההתחלה" #~ msgstr "%s סיים את תהליך ההתחלה"
#~ msgid "Home Folder" #~ msgid "Home Folder"
#~ msgstr "תיקיית הבית" #~ msgstr "תיקיית הבית"

244
po/pl.po
View File

@ -11,8 +11,8 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: gnome-shell\n" "Project-Id-Version: gnome-shell\n"
"Report-Msgid-Bugs-To: \n" "Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2012-09-25 15:12+0200\n" "POT-Creation-Date: 2012-10-31 19:12+0100\n"
"PO-Revision-Date: 2012-09-25 15:13+0200\n" "PO-Revision-Date: 2012-10-31 19:13+0100\n"
"Last-Translator: Piotr Drąg <piotrdrag@gmail.com>\n" "Last-Translator: Piotr Drąg <piotrdrag@gmail.com>\n"
"Language-Team: Polish <gnomepl@aviary.pl>\n" "Language-Team: Polish <gnomepl@aviary.pl>\n"
"Language: pl\n" "Language: pl\n"
@ -142,62 +142,74 @@ msgstr ""
"użytkownika. Wartość pochodzi ze spisu GsmPresenceStatus." "użytkownika. Wartość pochodzi ze spisu GsmPresenceStatus."
#: ../data/org.gnome.shell.gschema.xml.in.in.h:13 #: ../data/org.gnome.shell.gschema.xml.in.in.h:13
msgid "Always show the 'Log out' menuitem in the user menu."
msgstr "Wyświetlanie elementu menu \"Wyloguj się\" w menu użytkownika."
#: ../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 ""
"Ten klucz zastępuje automatyczne ukrywanie elementu menu \"Wyloguj się\" w "
"sytuacji, gdy istnieje tylko jeden użytkownik i jedna sesja."
#: ../data/org.gnome.shell.gschema.xml.in.in.h:15
msgid "Show the week date in the calendar" msgid "Show the week date in the calendar"
msgstr "Wyświetlanie dnia tygodnia w kalendarzu" msgstr "Wyświetlanie dnia tygodnia w kalendarzu"
#: ../data/org.gnome.shell.gschema.xml.in.in.h:14 #: ../data/org.gnome.shell.gschema.xml.in.in.h:16
msgid "If true, display the ISO week date in the calendar." msgid "If true, display the ISO week date in the calendar."
msgstr "" msgstr ""
"Jeśli jest ustawione na \"true\", to wyświetla w kalendarzu dzień tygodnia w " "Jeśli jest ustawione na \"true\", to wyświetla w kalendarzu dzień tygodnia w "
"formacie ISO." "formacie ISO."
#: ../data/org.gnome.shell.gschema.xml.in.in.h:15 #: ../data/org.gnome.shell.gschema.xml.in.in.h:17
msgid "Keybinding to open the application menu" msgid "Keybinding to open the application menu"
msgstr "Skrót do otwarcia menu programu" msgstr "Skrót do otwarcia menu programu"
#: ../data/org.gnome.shell.gschema.xml.in.in.h:16 #: ../data/org.gnome.shell.gschema.xml.in.in.h:18
msgid "Keybinding to open the application menu." msgid "Keybinding to open the application menu."
msgstr "Skrót do otwarcia menu programu." msgstr "Skrót do otwarcia menu programu."
#: ../data/org.gnome.shell.gschema.xml.in.in.h:17 #: ../data/org.gnome.shell.gschema.xml.in.in.h:19
msgid "Keybinding to toggle the visibility of the message tray" msgid "Keybinding to toggle the visibility of the message tray"
msgstr "Skrót do przełączenia widoczności obszaru powiadamiania" msgstr "Skrót do przełączenia widoczności obszaru powiadamiania"
#: ../data/org.gnome.shell.gschema.xml.in.in.h:18 #: ../data/org.gnome.shell.gschema.xml.in.in.h:20
msgid "Keybinding to toggle the visibility of the message tray." msgid "Keybinding to toggle the visibility of the message tray."
msgstr "Skrót do przełączenia widoczności obszaru powiadamiania." msgstr "Skrót do przełączenia widoczności obszaru powiadamiania."
#: ../data/org.gnome.shell.gschema.xml.in.in.h:19 #: ../data/org.gnome.shell.gschema.xml.in.in.h:21
msgid "Keybinding to toggle the screen recorder" msgid "Keybinding to toggle the screen recorder"
msgstr "Skrót do przełączenia nagrywania ekranu" msgstr "Skrót do przełączenia nagrywania ekranu"
#: ../data/org.gnome.shell.gschema.xml.in.in.h:20 #: ../data/org.gnome.shell.gschema.xml.in.in.h:22
msgid "Keybinding to start/stop the builtin screen recorder." msgid "Keybinding to start/stop the builtin screen recorder."
msgstr "Skrót do uruchomienia/zatrzymania wbudowanego nagrywania ekranu." msgstr "Skrót do uruchomienia/zatrzymania wbudowanego nagrywania ekranu."
#: ../data/org.gnome.shell.gschema.xml.in.in.h:21 #: ../data/org.gnome.shell.gschema.xml.in.in.h:23
msgid "Which keyboard to use" msgid "Which keyboard to use"
msgstr "Której klawiatury używać" msgstr "Której klawiatury używać"
#: ../data/org.gnome.shell.gschema.xml.in.in.h:22 #: ../data/org.gnome.shell.gschema.xml.in.in.h:24
msgid "The type of keyboard to use." msgid "The type of keyboard to use."
msgstr "Typ używanej klawiatury." msgstr "Typ używanej klawiatury."
#: ../data/org.gnome.shell.gschema.xml.in.in.h:23 #: ../data/org.gnome.shell.gschema.xml.in.in.h:25
msgid "Framerate used for recording screencasts." msgid "Framerate used for recording screencasts."
msgstr "Liczba klatek na sekundę do nagrywania ekranu." msgstr "Liczba klatek na sekundę do nagrywania ekranu."
#: ../data/org.gnome.shell.gschema.xml.in.in.h:24 #: ../data/org.gnome.shell.gschema.xml.in.in.h:26
msgid "" msgid ""
"The framerate of the resulting screencast recordered by GNOME Shell's " "The framerate of the resulting screencast recordered by GNOME Shell's "
"screencast recorder in frames-per-second." "screencast recorder in frames-per-second."
msgstr "Liczba klatek na sekundę wynikowego nagrania ekranu." msgstr "Liczba klatek na sekundę wynikowego nagrania ekranu."
#: ../data/org.gnome.shell.gschema.xml.in.in.h:25 #: ../data/org.gnome.shell.gschema.xml.in.in.h:27
msgid "The gstreamer pipeline used to encode the screencast" msgid "The gstreamer pipeline used to encode the screencast"
msgstr "Potok biblioteki GStreamer używany do zakodowania nagrania ekranu" msgstr "Potok biblioteki GStreamer używany do zakodowania nagrania ekranu"
#: ../data/org.gnome.shell.gschema.xml.in.in.h:27 #: ../data/org.gnome.shell.gschema.xml.in.in.h:29
#, no-c-format #, no-c-format
msgid "" msgid ""
"Sets the GStreamer pipeline used to encode recordings. It follows the syntax " "Sets the GStreamer pipeline used to encode recordings. It follows the syntax "
@ -222,11 +234,11 @@ msgstr ""
"i nagrywa do formatu WebM używając kodeka VP8. %T jest zamieniane na " "i nagrywa do formatu WebM używając kodeka VP8. %T jest zamieniane na "
"odgadniętą optymalną liczbę wątków dla komputera." "odgadniętą optymalną liczbę wątków dla komputera."
#: ../data/org.gnome.shell.gschema.xml.in.in.h:28 #: ../data/org.gnome.shell.gschema.xml.in.in.h:30
msgid "File extension used for storing the screencast" msgid "File extension used for storing the screencast"
msgstr "Rozszerzenie pliku używane do przechowywania nagrań ekranu" msgstr "Rozszerzenie pliku używane do przechowywania nagrań ekranu"
#: ../data/org.gnome.shell.gschema.xml.in.in.h:29 #: ../data/org.gnome.shell.gschema.xml.in.in.h:31
msgid "" msgid ""
"The filename for recorded screencasts will be a unique filename based on the " "The filename for recorded screencasts will be a unique filename based on the "
"current date, and use this extension. It should be changed when recording to " "current date, and use this extension. It should be changed when recording to "
@ -252,11 +264,11 @@ msgstr ""
"Proszę wybrać rozszerzenie do skonfigurowania używając powyższego pola " "Proszę wybrać rozszerzenie do skonfigurowania używając powyższego pola "
"wyboru." "wyboru."
#: ../js/gdm/loginDialog.js:528 #: ../js/gdm/loginDialog.js:529
msgid "Session..." msgid "Session..."
msgstr "Sesja..." msgstr "Sesja..."
#: ../js/gdm/loginDialog.js:676 #: ../js/gdm/loginDialog.js:677
msgctxt "title" msgctxt "title"
msgid "Sign In" msgid "Sign In"
msgstr "Proszę się zalogować" msgstr "Proszę się zalogować"
@ -264,23 +276,23 @@ msgstr "Proszę się zalogować"
#. translators: this message is shown below the user list on the #. translators: this message is shown below the user list on the
#. login screen. It can be activated to reveal an entry for #. login screen. It can be activated to reveal an entry for
#. manually entering the username. #. manually entering the username.
#: ../js/gdm/loginDialog.js:743 #: ../js/gdm/loginDialog.js:736
msgid "Not listed?" msgid "Not listed?"
msgstr "Inny użytkownik?" msgstr "Inny użytkownik?"
#: ../js/gdm/loginDialog.js:896 ../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/components/polkitAgent.js:162 ../js/ui/endSessionDialog.js:373
#: ../js/ui/extensionDownloader.js:195 ../js/ui/shellMountOperation.js:396 #: ../js/ui/extensionDownloader.js:195 ../js/ui/shellMountOperation.js:396
#: ../js/ui/status/bluetooth.js:427 ../js/ui/unlockDialog.js:166 #: ../js/ui/status/bluetooth.js:427 ../js/ui/unlockDialog.js:167
msgid "Cancel" msgid "Cancel"
msgstr "Anuluj" msgstr "Anuluj"
#: ../js/gdm/loginDialog.js:901 #: ../js/gdm/loginDialog.js:894
msgctxt "button" msgctxt "button"
msgid "Sign In" msgid "Sign In"
msgstr "Zaloguj" msgstr "Zaloguj"
#: ../js/gdm/loginDialog.js:1240 #: ../js/gdm/loginDialog.js:1215
msgid "Login Window" msgid "Login Window"
msgstr "Okno logowania" msgstr "Okno logowania"
@ -289,8 +301,8 @@ msgstr "Okno logowania"
msgid "Power" msgid "Power"
msgstr "Zasilanie" msgstr "Zasilanie"
#: ../js/gdm/powerMenu.js:89 ../js/ui/userMenu.js:663 ../js/ui/userMenu.js:667 #: ../js/gdm/powerMenu.js:89 ../js/ui/userMenu.js:664 ../js/ui/userMenu.js:668
#: ../js/ui/userMenu.js:778 #: ../js/ui/userMenu.js:779
msgid "Suspend" msgid "Suspend"
msgstr "Uśpij" msgstr "Uśpij"
@ -298,8 +310,8 @@ msgstr "Uśpij"
msgid "Restart" msgid "Restart"
msgstr "Uruchom ponownie" msgstr "Uruchom ponownie"
#: ../js/gdm/powerMenu.js:99 ../js/ui/userMenu.js:665 ../js/ui/userMenu.js:667 #: ../js/gdm/powerMenu.js:99 ../js/ui/userMenu.js:666 ../js/ui/userMenu.js:668
#: ../js/ui/userMenu.js:777 #: ../js/ui/userMenu.js:778
msgid "Power Off" msgid "Power Off"
msgstr "Wyłącz komputer" msgstr "Wyłącz komputer"
@ -350,7 +362,7 @@ msgstr "Ustawienia"
msgid "New Window" msgid "New Window"
msgstr "Nowe okno" msgstr "Nowe okno"
#: ../js/ui/appDisplay.js:678 ../js/ui/dash.js:271 #: ../js/ui/appDisplay.js:678 ../js/ui/dash.js:290
msgid "Remove from Favorites" msgid "Remove from Favorites"
msgstr "Usuń z ulubionych" msgstr "Usuń z ulubionych"
@ -514,16 +526,16 @@ msgstr "Ten tydzień"
msgid "Next week" msgid "Next week"
msgstr "Następny tydzień" msgstr "Następny tydzień"
#: ../js/ui/components/autorunManager.js:278 #: ../js/ui/components/autorunManager.js:297
msgid "Removable Devices" msgid "Removable Devices"
msgstr "Urządzenia wymienne" msgstr "Urządzenia wymienne"
#: ../js/ui/components/autorunManager.js:575 #: ../js/ui/components/autorunManager.js:594
#, c-format #, c-format
msgid "Open with %s" msgid "Open with %s"
msgstr "Otwórz za pomocą %s" msgstr "Otwórz za pomocą %s"
#: ../js/ui/components/autorunManager.js:601 #: ../js/ui/components/autorunManager.js:620
msgid "Eject" msgid "Eject"
msgstr "Wysuń" msgstr "Wysuń"
@ -680,35 +692,35 @@ msgstr "Wycisz"
#. Translators: this is a time format string followed by a date. #. Translators: this is a time format string followed by a date.
#. If applicable, replace %X with a strftime format valid for your #. If applicable, replace %X with a strftime format valid for your
#. locale, without seconds. #. locale, without seconds.
#: ../js/ui/components/telepathyClient.js:948 #: ../js/ui/components/telepathyClient.js:950
#, no-c-format #, no-c-format
msgid "Sent at <b>%X</b> on <b>%A</b>" msgid "Sent at <b>%X</b> on <b>%A</b>"
msgstr "Wysłano w dniu <b>%e %b</b> o godzinie <b>%H:%M</b>" msgstr "Wysłano w dniu <b>%e %b</b> o godzinie <b>%H:%M</b>"
#. Translators: this is a time format in the style of "Wednesday, May 25", #. Translators: this is a time format in the style of "Wednesday, May 25",
#. shown when you get a chat message in the same year. #. shown when you get a chat message in the same year.
#: ../js/ui/components/telepathyClient.js:954 #: ../js/ui/components/telepathyClient.js:956
#, no-c-format #, no-c-format
msgid "Sent on <b>%A</b>, <b>%B %d</b>" msgid "Sent on <b>%A</b>, <b>%B %d</b>"
msgstr "Wysłano w dniu <b>%d %B</b>, <b>%A</b>" msgstr "Wysłano w dniu <b>%d %B</b>, <b>%A</b>"
#. Translators: this is a time format in the style of "Wednesday, May 25, 2012", #. 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. #. shown when you get a chat message in a different year.
#: ../js/ui/components/telepathyClient.js:959 #: ../js/ui/components/telepathyClient.js:961
#, no-c-format #, no-c-format
msgid "Sent on <b>%A</b>, <b>%B %d</b>, %Y" msgid "Sent on <b>%A</b>, <b>%B %d</b>, %Y"
msgstr "Wysłano w dniu <b>%d %B</b> %Y, <b>%A</b>" msgstr "Wysłano w dniu <b>%d %B</b> %Y, <b>%A</b>"
#. Translators: this is the other person changing their old IM name to their new #. Translators: this is the other person changing their old IM name to their new
#. IM name. #. IM name.
#: ../js/ui/components/telepathyClient.js:988 #: ../js/ui/components/telepathyClient.js:990
#, c-format #, c-format
msgid "%s is now known as %s" msgid "%s is now known as %s"
msgstr "Użytkownik %s jest teraz znany jako %s" msgstr "Użytkownik %s jest teraz znany jako %s"
#. translators: argument is a room name like #. translators: argument is a room name like
#. * room@jabber.org for example. #. * room@jabber.org for example.
#: ../js/ui/components/telepathyClient.js:1088 #: ../js/ui/components/telepathyClient.js:1090
#, c-format #, c-format
msgid "Invitation to %s" msgid "Invitation to %s"
msgstr "Zaproszenie do pokoju %s" msgstr "Zaproszenie do pokoju %s"
@ -716,42 +728,42 @@ msgstr "Zaproszenie do pokoju %s"
#. translators: first argument is the name of a contact and the second #. 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 #. * one the name of a room. "Alice is inviting you to join room@jabber.org
#. * for example. #. * for example.
#: ../js/ui/components/telepathyClient.js:1096 #: ../js/ui/components/telepathyClient.js:1098
#, c-format #, c-format
msgid "%s is inviting you to join %s" msgid "%s is inviting you to join %s"
msgstr "Użytkownik %s zaprasza do dołączenia do pokoju %s" msgstr "Użytkownik %s zaprasza do dołączenia do pokoju %s"
#: ../js/ui/components/telepathyClient.js:1098 #: ../js/ui/components/telepathyClient.js:1100
#: ../js/ui/components/telepathyClient.js:1177 #: ../js/ui/components/telepathyClient.js:1179
#: ../js/ui/components/telepathyClient.js:1240 #: ../js/ui/components/telepathyClient.js:1242
msgid "Decline" msgid "Decline"
msgstr "Odmów" msgstr "Odmów"
#: ../js/ui/components/telepathyClient.js:1099 #: ../js/ui/components/telepathyClient.js:1101
#: ../js/ui/components/telepathyClient.js:1178 #: ../js/ui/components/telepathyClient.js:1180
#: ../js/ui/components/telepathyClient.js:1241 #: ../js/ui/components/telepathyClient.js:1243
msgid "Accept" msgid "Accept"
msgstr "Zaakceptuj" msgstr "Zaakceptuj"
#. translators: argument is a contact name like Alice for example. #. translators: argument is a contact name like Alice for example.
#: ../js/ui/components/telepathyClient.js:1129 #: ../js/ui/components/telepathyClient.js:1131
#, c-format #, c-format
msgid "Video call from %s" msgid "Video call from %s"
msgstr "Wideorozmowa z użytkownikiem %s" msgstr "Wideorozmowa z użytkownikiem %s"
#. translators: argument is a contact name like Alice for example. #. translators: argument is a contact name like Alice for example.
#: ../js/ui/components/telepathyClient.js:1132 #: ../js/ui/components/telepathyClient.js:1134
#, c-format #, c-format
msgid "Call from %s" msgid "Call from %s"
msgstr "Rozmowa z użytkownikiem %s" msgstr "Rozmowa z użytkownikiem %s"
#: ../js/ui/components/telepathyClient.js:1137 #: ../js/ui/components/telepathyClient.js:1139
#: ../js/ui/status/bluetooth.js:346 #: ../js/ui/status/bluetooth.js:346
msgid "Reject" msgid "Reject"
msgstr "Odrzuć" msgstr "Odrzuć"
#. translators: this is a button label (verb), not a noun #. translators: this is a button label (verb), not a noun
#: ../js/ui/components/telepathyClient.js:1139 #: ../js/ui/components/telepathyClient.js:1141
msgid "Answer" msgid "Answer"
msgstr "Odbierz" msgstr "Odbierz"
@ -760,111 +772,111 @@ msgstr "Odbierz"
#. * file name. The string will be something #. * file name. The string will be something
#. * like: "Alice is sending you test.ogg" #. * like: "Alice is sending you test.ogg"
#. #.
#: ../js/ui/components/telepathyClient.js:1171 #: ../js/ui/components/telepathyClient.js:1173
#, c-format #, c-format
msgid "%s is sending you %s" msgid "%s is sending you %s"
msgstr "Użytkownik %s przysyła plik %s" msgstr "Użytkownik %s przysyła plik %s"
#. To translators: The parameter is the contact's alias #. To translators: The parameter is the contact's alias
#: ../js/ui/components/telepathyClient.js:1206 #: ../js/ui/components/telepathyClient.js:1208
#, c-format #, c-format
msgid "%s would like permission to see when you are online" msgid "%s would like permission to see when you are online"
msgstr "Użytkownik %s prosi o uprawnienie do wyświetlania stanu" msgstr "Użytkownik %s prosi o uprawnienie do wyświetlania stanu"
#: ../js/ui/components/telepathyClient.js:1298 #: ../js/ui/components/telepathyClient.js:1300
msgid "Network error" msgid "Network error"
msgstr "Błąd sieci" msgstr "Błąd sieci"
#: ../js/ui/components/telepathyClient.js:1300 #: ../js/ui/components/telepathyClient.js:1302
msgid "Authentication failed" msgid "Authentication failed"
msgstr "Uwierzytelnienie się nie powiodło" msgstr "Uwierzytelnienie się nie powiodło"
#: ../js/ui/components/telepathyClient.js:1302 #: ../js/ui/components/telepathyClient.js:1304
msgid "Encryption error" msgid "Encryption error"
msgstr "Błąd szyfrowania" msgstr "Błąd szyfrowania"
#: ../js/ui/components/telepathyClient.js:1304 #: ../js/ui/components/telepathyClient.js:1306
msgid "Certificate not provided" msgid "Certificate not provided"
msgstr "Nie podano certyfikatu" msgstr "Nie podano certyfikatu"
#: ../js/ui/components/telepathyClient.js:1306 #: ../js/ui/components/telepathyClient.js:1308
msgid "Certificate untrusted" msgid "Certificate untrusted"
msgstr "Certyfikat jest niezaufany" msgstr "Certyfikat jest niezaufany"
#: ../js/ui/components/telepathyClient.js:1308 #: ../js/ui/components/telepathyClient.js:1310
msgid "Certificate expired" msgid "Certificate expired"
msgstr "Certyfikat wygasł" msgstr "Certyfikat wygasł"
#: ../js/ui/components/telepathyClient.js:1310 #: ../js/ui/components/telepathyClient.js:1312
msgid "Certificate not activated" msgid "Certificate not activated"
msgstr "Certyfikat nie został aktywowany" msgstr "Certyfikat nie został aktywowany"
#: ../js/ui/components/telepathyClient.js:1312 #: ../js/ui/components/telepathyClient.js:1314
msgid "Certificate hostname mismatch" msgid "Certificate hostname mismatch"
msgstr "Nazwa komputera certyfikatu się nie zgadza" msgstr "Nazwa komputera certyfikatu się nie zgadza"
#: ../js/ui/components/telepathyClient.js:1314 #: ../js/ui/components/telepathyClient.js:1316
msgid "Certificate fingerprint mismatch" msgid "Certificate fingerprint mismatch"
msgstr "Odcisk palca certyfikatu się nie zgadza" msgstr "Odcisk palca certyfikatu się nie zgadza"
#: ../js/ui/components/telepathyClient.js:1316 #: ../js/ui/components/telepathyClient.js:1318
msgid "Certificate self-signed" msgid "Certificate self-signed"
msgstr "Certyfikat został samodzielnie podpisany" msgstr "Certyfikat został samodzielnie podpisany"
#: ../js/ui/components/telepathyClient.js:1318 #: ../js/ui/components/telepathyClient.js:1320
msgid "Status is set to offline" msgid "Status is set to offline"
msgstr "Stan jest ustawiony na offline" msgstr "Stan jest ustawiony na offline"
#: ../js/ui/components/telepathyClient.js:1320 #: ../js/ui/components/telepathyClient.js:1322
msgid "Encryption is not available" msgid "Encryption is not available"
msgstr "Szyfrowanie jest niedostępne" msgstr "Szyfrowanie jest niedostępne"
#: ../js/ui/components/telepathyClient.js:1322 #: ../js/ui/components/telepathyClient.js:1324
msgid "Certificate is invalid" msgid "Certificate is invalid"
msgstr "Certyfikat jest nieprawidłowy" msgstr "Certyfikat jest nieprawidłowy"
#: ../js/ui/components/telepathyClient.js:1324 #: ../js/ui/components/telepathyClient.js:1326
msgid "Connection has been refused" msgid "Connection has been refused"
msgstr "Odrzucono połączenie" msgstr "Odrzucono połączenie"
#: ../js/ui/components/telepathyClient.js:1326 #: ../js/ui/components/telepathyClient.js:1328
msgid "Connection can't be established" msgid "Connection can't be established"
msgstr "Nie można nawiązać połączenia" msgstr "Nie można nawiązać połączenia"
#: ../js/ui/components/telepathyClient.js:1328 #: ../js/ui/components/telepathyClient.js:1330
msgid "Connection has been lost" msgid "Connection has been lost"
msgstr "Utracono połączenie" msgstr "Utracono połączenie"
#: ../js/ui/components/telepathyClient.js:1330 #: ../js/ui/components/telepathyClient.js:1332
msgid "This account is already connected to the server" msgid "This account is already connected to the server"
msgstr "To konto jest już połączone z serwerem" msgstr "To konto jest już połączone z serwerem"
#: ../js/ui/components/telepathyClient.js:1332 #: ../js/ui/components/telepathyClient.js:1334
msgid "" msgid ""
"Connection has been replaced by a new connection using the same resource" "Connection has been replaced by a new connection using the same resource"
msgstr "" msgstr ""
"Połączenie zostało zastąpione nowym z wykorzystaniem tego samego zasobu" "Połączenie zostało zastąpione nowym z wykorzystaniem tego samego zasobu"
#: ../js/ui/components/telepathyClient.js:1334 #: ../js/ui/components/telepathyClient.js:1336
msgid "The account already exists on the server" msgid "The account already exists on the server"
msgstr "Konto już istnieje na serwerze" msgstr "Konto już istnieje na serwerze"
#: ../js/ui/components/telepathyClient.js:1336 #: ../js/ui/components/telepathyClient.js:1338
msgid "Server is currently too busy to handle the connection" msgid "Server is currently too busy to handle the connection"
msgstr "Serwer jest obecnie zbyt zajęty, aby obsłużyć połączenie" msgstr "Serwer jest obecnie zbyt zajęty, aby obsłużyć połączenie"
#: ../js/ui/components/telepathyClient.js:1338 #: ../js/ui/components/telepathyClient.js:1340
msgid "Certificate has been revoked" msgid "Certificate has been revoked"
msgstr "Certyfikat został unieważniony" msgstr "Certyfikat został unieważniony"
#: ../js/ui/components/telepathyClient.js:1340 #: ../js/ui/components/telepathyClient.js:1342
msgid "" msgid ""
"Certificate uses an insecure cipher algorithm or is cryptographically weak" "Certificate uses an insecure cipher algorithm or is cryptographically weak"
msgstr "" msgstr ""
"Certyfikat używa niezabezpieczonego algorytmu szyfrowania lub jest " "Certyfikat używa niezabezpieczonego algorytmu szyfrowania lub jest "
"kryptograficznie słaby" "kryptograficznie słaby"
#: ../js/ui/components/telepathyClient.js:1342 #: ../js/ui/components/telepathyClient.js:1344
msgid "" msgid ""
"The length of the server certificate, or the depth of the server certificate " "The length of the server certificate, or the depth of the server certificate "
"chain, exceed the limits imposed by the cryptography library" "chain, exceed the limits imposed by the cryptography library"
@ -872,30 +884,30 @@ msgstr ""
"Długość certyfikatu serwera lub głębokość jego łańcucha przekracza " "Długość certyfikatu serwera lub głębokość jego łańcucha przekracza "
"ograniczenia nałożone przez bibliotekę kryptograficzną" "ograniczenia nałożone przez bibliotekę kryptograficzną"
#: ../js/ui/components/telepathyClient.js:1344 #: ../js/ui/components/telepathyClient.js:1346
msgid "Internal error" msgid "Internal error"
msgstr "Błąd wewnętrzny" msgstr "Błąd wewnętrzny"
#. translators: argument is the account name, like #. translators: argument is the account name, like
#. * name@jabber.org for example. #. * name@jabber.org for example.
#: ../js/ui/components/telepathyClient.js:1354 #: ../js/ui/components/telepathyClient.js:1356
#, c-format #, c-format
msgid "Connection to %s failed" msgid "Connection to %s failed"
msgstr "Połączenie z kontem %s się nie powiodło" msgstr "Połączenie z kontem %s się nie powiodło"
#: ../js/ui/components/telepathyClient.js:1363 #: ../js/ui/components/telepathyClient.js:1365
msgid "Reconnect" msgid "Reconnect"
msgstr "Połącz ponownie" msgstr "Połącz ponownie"
#: ../js/ui/components/telepathyClient.js:1364 #: ../js/ui/components/telepathyClient.js:1366
msgid "Edit account" msgid "Edit account"
msgstr "Modyfikuj konto" msgstr "Modyfikuj konto"
#: ../js/ui/components/telepathyClient.js:1409 #: ../js/ui/components/telepathyClient.js:1411
msgid "Unknown reason" msgid "Unknown reason"
msgstr "Nieznana przyczyna" msgstr "Nieznana przyczyna"
#: ../js/ui/dash.js:245 ../js/ui/dash.js:273 #: ../js/ui/dash.js:253 ../js/ui/dash.js:292
msgid "Show Applications" msgid "Show Applications"
msgstr "Wyświetl programy" msgstr "Wyświetl programy"
@ -903,14 +915,14 @@ msgstr "Wyświetl programy"
msgid "Date and Time Settings" msgid "Date and Time Settings"
msgstr "Ustawienia daty i czasu" msgstr "Ustawienia daty i czasu"
#: ../js/ui/dateMenu.js:109 #: ../js/ui/dateMenu.js:111
msgid "Open Calendar" msgid "Open Calendar"
msgstr "Otwórz kalendarz" msgstr "Otwórz kalendarz"
#. Translators: This is the date format to use when the calendar popup is #. Translators: This is the date format to use when the calendar popup is
#. * shown - it is shown just below the time in the shell (e.g. "Tue 9:29 AM"). #. * shown - it is shown just below the time in the shell (e.g. "Tue 9:29 AM").
#. #.
#: ../js/ui/dateMenu.js:175 #: ../js/ui/dateMenu.js:201
msgid "%A %B %e, %Y" msgid "%A %B %e, %Y"
msgstr "%A, %e %B %Y" msgstr "%A, %e %B %Y"
@ -1075,23 +1087,23 @@ msgstr "Wyświetl źródło"
msgid "Web Page" msgid "Web Page"
msgstr "Strona WWW" msgstr "Strona WWW"
#: ../js/ui/messageTray.js:1081 #: ../js/ui/messageTray.js:1084
msgid "Open" msgid "Open"
msgstr "Otwórz" msgstr "Otwórz"
#: ../js/ui/messageTray.js:1088 #: ../js/ui/messageTray.js:1091
msgid "Remove" msgid "Remove"
msgstr "Usuń" msgstr "Usuń"
#: ../js/ui/messageTray.js:2088 #: ../js/ui/messageTray.js:1543
msgid "Message Tray" msgid "Message Tray"
msgstr "Obszar powiadamiania" msgstr "Obszar powiadamiania"
#: ../js/ui/messageTray.js:2551 #: ../js/ui/messageTray.js:2549
msgid "System Information" msgid "System Information"
msgstr "Informacje systemowe" msgstr "Informacje systemowe"
#: ../js/ui/notificationDaemon.js:506 ../src/shell-app.c:373 #: ../js/ui/notificationDaemon.js:506 ../src/shell-app.c:374
msgctxt "program" msgctxt "program"
msgid "Unknown" msgid "Unknown"
msgstr "Nieznany" msgstr "Nieznany"
@ -1147,7 +1159,7 @@ msgstr "Proszę wprowadzić polecenie:"
#. Translators: This is a time format for a date in #. Translators: This is a time format for a date in
#. long format #. long format
#: ../js/ui/screenShield.js:79 #: ../js/ui/screenShield.js:80
msgid "%A, %B %d" msgid "%A, %B %d"
msgstr "%A, %e %B" msgstr "%A, %e %B"
@ -1199,7 +1211,7 @@ msgstr "Hasło"
msgid "Remember Password" msgid "Remember Password"
msgstr "Zapamiętanie hasła" msgstr "Zapamiętanie hasła"
#: ../js/ui/shellMountOperation.js:400 ../js/ui/unlockDialog.js:169 #: ../js/ui/shellMountOperation.js:400 ../js/ui/unlockDialog.js:170
msgid "Unlock" msgid "Unlock"
msgstr "Odblokuj" msgstr "Odblokuj"
@ -1614,67 +1626,63 @@ msgstr "Głośność"
msgid "Microphone" msgid "Microphone"
msgstr "Mikrofon" msgstr "Mikrofon"
#: ../js/ui/unlockDialog.js:176 #: ../js/ui/unlockDialog.js:177
msgid "Log in as another user" msgid "Log in as another user"
msgstr "Zaloguj jako inny użytkownik" msgstr "Zaloguj jako inny użytkownik"
#: ../js/ui/userMenu.js:180 #: ../js/ui/userMenu.js:181
msgid "Available" msgid "Available"
msgstr "Dostępny" msgstr "Dostępny"
#: ../js/ui/userMenu.js:183 #: ../js/ui/userMenu.js:184
msgid "Busy" msgid "Busy"
msgstr "Zajęty" msgstr "Zajęty"
#: ../js/ui/userMenu.js:186 #: ../js/ui/userMenu.js:187
msgid "Invisible" msgid "Invisible"
msgstr "Niewidoczny" msgstr "Niewidoczny"
#: ../js/ui/userMenu.js:189 #: ../js/ui/userMenu.js:190
msgid "Away" msgid "Away"
msgstr "Nieobecny" msgstr "Nieobecny"
#: ../js/ui/userMenu.js:192 #: ../js/ui/userMenu.js:193
msgid "Idle" msgid "Idle"
msgstr "Bezczynny" msgstr "Bezczynny"
#: ../js/ui/userMenu.js:195 #: ../js/ui/userMenu.js:196
msgid "Unavailable" msgid "Unavailable"
msgstr "Niedostępny" msgstr "Niedostępny"
#: ../js/ui/userMenu.js:618 ../js/ui/userMenu.js:759 #: ../js/ui/userMenu.js:744
msgid "Switch User"
msgstr "Przełącz użytkownika"
#: ../js/ui/userMenu.js:619
msgid "Switch Session"
msgstr "Przełącz sesję"
#: ../js/ui/userMenu.js:743
msgid "Notifications" msgid "Notifications"
msgstr "Powiadomienia" msgstr "Powiadomienia"
#: ../js/ui/userMenu.js:751 #: ../js/ui/userMenu.js:752
msgid "System Settings" msgid "System Settings"
msgstr "Ustawienia systemu" msgstr "Ustawienia systemu"
#: ../js/ui/userMenu.js:764 #: ../js/ui/userMenu.js:760
msgid "Switch User"
msgstr "Przełącz użytkownika"
#: ../js/ui/userMenu.js:765
msgid "Log Out" msgid "Log Out"
msgstr "Wyloguj się" msgstr "Wyloguj się"
#: ../js/ui/userMenu.js:769 #: ../js/ui/userMenu.js:770
msgid "Lock" msgid "Lock"
msgstr "Zablokuj ekran" msgstr "Zablokuj ekran"
#: ../js/ui/userMenu.js:784 #: ../js/ui/userMenu.js:785
msgid "Install Updates & Restart" msgid "Install Updates & Restart"
msgstr "Zaktualizuj i uruchom ponownie" msgstr "Zaktualizuj i uruchom ponownie"
#: ../js/ui/userMenu.js:802 #: ../js/ui/userMenu.js:803
msgid "Your chat status will be set to busy" msgid "Your chat status will be set to busy"
msgstr "Stan komunikatora zostanie ustawiony na \"zajęty\"" msgstr "Stan komunikatora zostanie ustawiony na \"zajęty\""
#: ../js/ui/userMenu.js:803 #: ../js/ui/userMenu.js:804
msgid "" msgid ""
"Notifications are now disabled, including chat messages. Your online status " "Notifications are now disabled, including chat messages. Your online status "
"has been adjusted to let others know that you might not see their messages." "has been adjusted to let others know that you might not see their messages."
@ -1696,7 +1704,7 @@ msgstr "Programy"
msgid "Search" msgid "Search"
msgstr "Wyszukiwanie" msgstr "Wyszukiwanie"
#: ../js/ui/wanda.js:119 #: ../js/ui/wanda.js:117
#, c-format #, c-format
msgid "" msgid ""
"Sorry, no wisdom for you today:\n" "Sorry, no wisdom for you today:\n"
@ -1705,12 +1713,12 @@ msgstr ""
"Nic mądrego na dzisiaj:\n" "Nic mądrego na dzisiaj:\n"
"%s" "%s"
#: ../js/ui/wanda.js:123 #: ../js/ui/wanda.js:121
#, c-format #, c-format
msgid "%s the Oracle says" msgid "%s the Oracle says"
msgstr "Wyrocznia %s przemawia" msgstr "Wyrocznia %s przemawia"
#: ../js/ui/wanda.js:164 #: ../js/ui/wanda.js:162
msgid "Your favorite Easter Egg" msgid "Your favorite Easter Egg"
msgstr "Twój ulubiony żart" msgstr "Twój ulubiony żart"
@ -1747,23 +1755,23 @@ msgstr[2] "%u wejść"
msgid "System Sounds" msgid "System Sounds"
msgstr "Dźwięki systemowe" msgstr "Dźwięki systemowe"
#: ../src/main.c:330 #: ../src/main.c:332
msgid "Print version" msgid "Print version"
msgstr "Wyświetla wersję" msgstr "Wyświetla wersję"
#: ../src/main.c:336 #: ../src/main.c:338
msgid "Mode used by GDM for login screen" msgid "Mode used by GDM for login screen"
msgstr "Tryb używany przez GDM dla ekranu logowania" msgstr "Tryb używany przez GDM dla ekranu logowania"
#: ../src/main.c:342 #: ../src/main.c:344
msgid "Use a specific mode, e.g. \"gdm\" for login screen" msgid "Use a specific mode, e.g. \"gdm\" for login screen"
msgstr "Używa podanego trybu, np. \"gdm\" dla ekranu logowania" msgstr "Używa podanego trybu, np. \"gdm\" dla ekranu logowania"
#: ../src/main.c:348 #: ../src/main.c:350
msgid "List possible modes" msgid "List possible modes"
msgstr "Wyświetla listę możliwych trybów" msgstr "Wyświetla listę możliwych trybów"
#: ../src/shell-app.c:621 #: ../src/shell-app.c:622
#, c-format #, c-format
msgid "Failed to launch '%s'" msgid "Failed to launch '%s'"
msgstr "Uruchomienie \"%s\" się nie powiodło" msgstr "Uruchomienie \"%s\" się nie powiodło"

296
po/sk.po
View File

@ -10,8 +10,8 @@ msgstr ""
"Project-Id-Version: gnome-shell\n" "Project-Id-Version: gnome-shell\n"
"Report-Msgid-Bugs-To: http://bugzilla.gnome.org/enter_bug.cgi?product=gnome-" "Report-Msgid-Bugs-To: http://bugzilla.gnome.org/enter_bug.cgi?product=gnome-"
"shell&keywords=I18N+L10N&component=general\n" "shell&keywords=I18N+L10N&component=general\n"
"POT-Creation-Date: 2012-10-18 16:51+0000\n" "POT-Creation-Date: 2012-10-27 16:22+0000\n"
"PO-Revision-Date: 2012-10-13 22:35+0100\n" "PO-Revision-Date: 2012-10-28 19:49+0000\n"
"Last-Translator: Dušan Kazik <prescott66@gmail.com>\n" "Last-Translator: Dušan Kazik <prescott66@gmail.com>\n"
"Language-Team: Slovak <gnome-sk-list@gnome.org>\n" "Language-Team: Slovak <gnome-sk-list@gnome.org>\n"
"Language: sk\n" "Language: sk\n"
@ -25,8 +25,6 @@ msgstr ""
msgid "Screenshots" msgid "Screenshots"
msgstr "Snímky obrazovky" msgstr "Snímky obrazovky"
# PM: inde dianie na obrazovke
# DK:presne taketo nieco som chcel povedat ale nevedel som ako
#: ../data/50-gnome-shell-screenshot.xml.in.h:2 #: ../data/50-gnome-shell-screenshot.xml.in.h:2
msgid "Record a screencast" msgid "Record a screencast"
msgstr "Zaznamenať dianie na obrazovke" msgstr "Zaznamenať dianie na obrazovke"
@ -37,20 +35,16 @@ msgstr "Systém"
#: ../data/50-gnome-shell-system.xml.in.h:2 #: ../data/50-gnome-shell-system.xml.in.h:2
msgid "Show the message tray" msgid "Show the message tray"
msgstr "Zobraz lištu správ" msgstr "Zobrazí lištu správ"
# tooltip # tooltip
#: ../data/50-gnome-shell-system.xml.in.h:3 #: ../data/50-gnome-shell-system.xml.in.h:3
#, fuzzy
#| msgid "Show Applications"
msgid "Show all applications" msgid "Show all applications"
msgstr "Zobrazí aplikácie" msgstr "Zobrazí všetky aplikácie"
#: ../data/50-gnome-shell-system.xml.in.h:4 #: ../data/50-gnome-shell-system.xml.in.h:4
#, fuzzy
#| msgid "Keybinding to open the application menu"
msgid "Open the application menu" msgid "Open the application menu"
msgstr "Klávesová skratka na otvorenie ponuky aplikácií" msgstr "Otvorí ponuku aplikácií"
#: ../data/gnome-shell.desktop.in.in.h:1 #: ../data/gnome-shell.desktop.in.in.h:1
msgid "GNOME Shell" msgid "GNOME Shell"
@ -85,13 +79,9 @@ msgstr ""
#: ../data/org.gnome.shell.gschema.xml.in.in.h:3 #: ../data/org.gnome.shell.gschema.xml.in.in.h:3
msgid "Uuids of extensions to enable" msgid "Uuids of extensions to enable"
msgstr "Uuid identifikátory rozšírení určených na povolenie" msgstr "Vlastnosť uuid rozšírení určených na povolenie"
# PM: nepáči sa mi konštrukcia viet, preklad vyznieva strojovo
# DK: uz lepsie?
# PM: lepšie ale nepáči sa mi org.gnome.Shell. mne sa vidí že to bude nejaký súbor a potom predložka na asi nebude dobre
#: ../data/org.gnome.shell.gschema.xml.in.in.h:4 #: ../data/org.gnome.shell.gschema.xml.in.in.h:4
#, fuzzy
msgid "" msgid ""
"GNOME Shell extensions have a uuid property; this key lists extensions which " "GNOME Shell extensions have a uuid property; this key lists extensions which "
"should be loaded. Any extension that wants to be loaded needs to be in this " "should be loaded. Any extension that wants to be loaded needs to be in this "
@ -101,7 +91,7 @@ msgstr ""
"Rozšírenia pre GNOME Shell majú vlastnosť uuid; tento kľúč obsahuje zoznam " "Rozšírenia pre GNOME Shell majú vlastnosť uuid; tento kľúč obsahuje zoznam "
"rozšírení, ktoré by mali byť načítané. Každé rozšírenie, ktoré je potrebné " "rozšírení, ktoré by mali byť načítané. Každé rozšírenie, ktoré je potrebné "
"načítať, musí byť v tomto zozname. Tento zoznam môžete upraviť aj ručne " "načítať, musí byť v tomto zozname. Tento zoznam môžete upraviť aj ručne "
"pomocou metód DBus EnableExtension a DisableExtension na org.gnome.Shell." "pomocou metód DBus EnableExtension a DisableExtension v org.gnome.Shell."
#: ../data/org.gnome.shell.gschema.xml.in.in.h:5 #: ../data/org.gnome.shell.gschema.xml.in.in.h:5
msgid "Whether to collect stats about applications usage" msgid "Whether to collect stats about applications usage"
@ -176,17 +166,15 @@ msgid "Keybinding to open the application menu."
msgstr "Klávesová skratka na otvorenie ponuky aplikácií." msgstr "Klávesová skratka na otvorenie ponuky aplikácií."
#: ../data/org.gnome.shell.gschema.xml.in.in.h:17 #: ../data/org.gnome.shell.gschema.xml.in.in.h:17
#, fuzzy
#| msgid "Keybinding to open the application menu"
msgid "Keybinding to open the \"Show Applications\" view" msgid "Keybinding to open the \"Show Applications\" view"
msgstr "Klávesová skratka na otvorenie ponuky aplikácií" msgstr "Klávesová skratka na otvorenie pohľadu „Zobraziť aplikácie“"
#: ../data/org.gnome.shell.gschema.xml.in.in.h:18 #: ../data/org.gnome.shell.gschema.xml.in.in.h:18
#, fuzzy
#| msgid "Keybinding to open the application menu."
msgid "" msgid ""
"Keybinding to open the \"Show Applications\" view of the Activities Overview." "Keybinding to open the \"Show Applications\" view of the Activities Overview."
msgstr "Klávesová skratka na otvorenie ponuky aplikácií." msgstr ""
"Klávesová skratka na otvorenie pohľadu „Zobraziť aplikácie“ v prehľade "
"aktivít."
#: ../data/org.gnome.shell.gschema.xml.in.in.h:19 #: ../data/org.gnome.shell.gschema.xml.in.in.h:19
msgid "Keybinding to toggle the visibility of the message tray" msgid "Keybinding to toggle the visibility of the message tray"
@ -211,7 +199,7 @@ msgstr "Ktorú klávesnicu používať"
#: ../data/org.gnome.shell.gschema.xml.in.in.h:24 #: ../data/org.gnome.shell.gschema.xml.in.in.h:24
msgid "The type of keyboard to use." msgid "The type of keyboard to use."
msgstr "Typ klávesnice, ktorý sa má používať." msgstr "Typ klávesnice, ktorá sa má používať."
#: ../data/org.gnome.shell.gschema.xml.in.in.h:25 #: ../data/org.gnome.shell.gschema.xml.in.in.h:25
msgid "Framerate used for recording screencasts." msgid "Framerate used for recording screencasts."
@ -273,6 +261,39 @@ msgstr ""
"základe aktuálneho dátumu a použije túto príponu. Pri nahrávaní do iného " "základe aktuálneho dátumu a použije túto príponu. Pri nahrávaní do iného "
"formátu kontajneru by mala byť zmenená." "formátu kontajneru by mala byť zmenená."
#: ../data/org.gnome.shell.gschema.xml.in.in.h:32
msgid "Attach modal dialog to the parent window"
msgstr "Pripojiť modálne dialógové okno k rodičovskému oknu"
#: ../data/org.gnome.shell.gschema.xml.in.in.h:33
msgid ""
"This key overrides the key in org.gnome.mutter when running GNOME Shell."
msgstr "Tento kľúč preváži kľúč v org.gnome.mutter po spustení GNOME Shell."
#: ../data/org.gnome.shell.gschema.xml.in.in.h:34
msgid "Arrangement of buttons on the titlebar"
msgstr "Usporiadanie tlačidiel na titulku okna"
#: ../data/org.gnome.shell.gschema.xml.in.in.h:35
msgid ""
"This key overrides the key in org.gnome.desktop.wm.preferences when running "
"GNOME Shell."
msgstr ""
"Tento kľúč preváži kľúč v org.gnome.desktop.wm.preferences po spustení GNOME "
"Shell."
#: ../data/org.gnome.shell.gschema.xml.in.in.h:36
msgid "Enable edge tiling when dropping windows on screen edges"
msgstr ""
#: ../data/org.gnome.shell.gschema.xml.in.in.h:37
msgid "Workspaces are managed dynamically"
msgstr "Pracovné priestory sú spravované dynamicky"
#: ../data/org.gnome.shell.gschema.xml.in.in.h:38
msgid "Workspaces only on primary monitor"
msgstr "Pracovné priestory sú iba na primárnom monitore"
#: ../js/extensionPrefs/main.js:124 #: ../js/extensionPrefs/main.js:124
#, c-format #, c-format
msgid "There was an error loading the preferences dialog for %s:" msgid "There was an error loading the preferences dialog for %s:"
@ -286,11 +307,11 @@ msgstr "Rozšírenie"
msgid "Select an extension to configure using the combobox above." msgid "Select an extension to configure using the combobox above."
msgstr "Použitím ponuky vyberte rozšírenie na nastavenie" msgstr "Použitím ponuky vyberte rozšírenie na nastavenie"
#: ../js/gdm/loginDialog.js:529 #: ../js/gdm/loginDialog.js:560
msgid "Session..." msgid "Session..."
msgstr "Relácia..." msgstr "Relácia..."
#: ../js/gdm/loginDialog.js:677 #: ../js/gdm/loginDialog.js:704
msgctxt "title" msgctxt "title"
msgid "Sign In" msgid "Sign In"
msgstr "Prihlásenie" msgstr "Prihlásenie"
@ -299,42 +320,42 @@ msgstr "Prihlásenie"
#. translators: this message is shown below the user list on the #. translators: this message is shown below the user list on the
#. login screen. It can be activated to reveal an entry for #. login screen. It can be activated to reveal an entry for
#. manually entering the username. #. manually entering the username.
#: ../js/gdm/loginDialog.js:736 #: ../js/gdm/loginDialog.js:763
msgid "Not listed?" msgid "Not listed?"
msgstr "Nie ste v zozname?" msgstr "Nie ste v zozname?"
#: ../js/gdm/loginDialog.js:889 ../js/ui/components/networkAgent.js:137 #: ../js/gdm/loginDialog.js:901 ../js/ui/components/networkAgent.js:137
#: ../js/ui/components/polkitAgent.js:162 ../js/ui/endSessionDialog.js:373 #: ../js/ui/components/polkitAgent.js:162 ../js/ui/endSessionDialog.js:373
#: ../js/ui/extensionDownloader.js:195 ../js/ui/shellMountOperation.js:396 #: ../js/ui/extensionDownloader.js:195 ../js/ui/shellMountOperation.js:396
#: ../js/ui/status/bluetooth.js:427 ../js/ui/unlockDialog.js:167 #: ../js/ui/status/bluetooth.js:427 ../js/ui/unlockDialog.js:168
msgid "Cancel" msgid "Cancel"
msgstr "Zrušiť" msgstr "Zrušiť"
#: ../js/gdm/loginDialog.js:894 #: ../js/gdm/loginDialog.js:906
msgctxt "button" msgctxt "button"
msgid "Sign In" msgid "Sign In"
msgstr "Prihlásiť sa" msgstr "Prihlásiť sa"
#: ../js/gdm/loginDialog.js:1215 #: ../js/gdm/loginDialog.js:1217
msgid "Login Window" msgid "Login Window"
msgstr "Prihlasovacie okno" msgstr "Prihlasovacie okno"
#. Translators: accessible name of the power menu in the login screen #. Translators: accessible name of the power menu in the login screen
#: ../js/gdm/powerMenu.js:37 #: ../js/gdm/powerMenu.js:36
msgid "Power" msgid "Power"
msgstr "Napájanie" msgstr "Napájanie"
#: ../js/gdm/powerMenu.js:95 ../js/ui/userMenu.js:655 ../js/ui/userMenu.js:659 #: ../js/gdm/powerMenu.js:93 ../js/ui/userMenu.js:663 ../js/ui/userMenu.js:667
#: ../js/ui/userMenu.js:770 #: ../js/ui/userMenu.js:778
msgid "Suspend" msgid "Suspend"
msgstr "Uspať" msgstr "Uspať"
#: ../js/gdm/powerMenu.js:100 #: ../js/gdm/powerMenu.js:98
msgid "Restart" msgid "Restart"
msgstr "Reštartovať" msgstr "Reštartovať"
#: ../js/gdm/powerMenu.js:105 ../js/ui/userMenu.js:657 #: ../js/gdm/powerMenu.js:103 ../js/ui/userMenu.js:665
#: ../js/ui/userMenu.js:659 ../js/ui/userMenu.js:769 #: ../js/ui/userMenu.js:667 ../js/ui/userMenu.js:777
msgid "Power Off" msgid "Power Off"
msgstr "Vypnúť" msgstr "Vypnúť"
@ -517,35 +538,35 @@ msgid "S"
msgstr "So" msgstr "So"
#. Translators: Text to show if there are no events #. Translators: Text to show if there are no events
#: ../js/ui/calendar.js:699 #: ../js/ui/calendar.js:700
msgid "Nothing Scheduled" msgid "Nothing Scheduled"
msgstr "Žiadne naplánované udalosti" msgstr "Žiadne naplánované udalosti"
#. Translators: Shown on calendar heading when selected day occurs on current year #. Translators: Shown on calendar heading when selected day occurs on current year
#: ../js/ui/calendar.js:715 #: ../js/ui/calendar.js:716
msgctxt "calendar heading" msgctxt "calendar heading"
msgid "%A, %B %d" msgid "%A, %B %d"
msgstr "%A, %e. %B" msgstr "%A, %e. %B"
#. Translators: Shown on calendar heading when selected day occurs on different year #. Translators: Shown on calendar heading when selected day occurs on different year
#: ../js/ui/calendar.js:718 #: ../js/ui/calendar.js:719
msgctxt "calendar heading" msgctxt "calendar heading"
msgid "%A, %B %d, %Y" msgid "%A, %B %d, %Y"
msgstr "%A, %e. %B %Y" msgstr "%A, %e. %B %Y"
#: ../js/ui/calendar.js:728 #: ../js/ui/calendar.js:729
msgid "Today" msgid "Today"
msgstr "Dnes" msgstr "Dnes"
#: ../js/ui/calendar.js:732 #: ../js/ui/calendar.js:733
msgid "Tomorrow" msgid "Tomorrow"
msgstr "Zajtra" msgstr "Zajtra"
#: ../js/ui/calendar.js:743 #: ../js/ui/calendar.js:744
msgid "This week" msgid "This week"
msgstr "Tento týždeň" msgstr "Tento týždeň"
#: ../js/ui/calendar.js:751 #: ../js/ui/calendar.js:752
msgid "Next week" msgid "Next week"
msgstr "Ďalší týždeň" msgstr "Ďalší týždeň"
@ -553,10 +574,11 @@ msgstr "Ďalší týždeň"
msgid "Removable Devices" msgid "Removable Devices"
msgstr "Vymeniteľné zariadenia" msgstr "Vymeniteľné zariadenia"
# DK: doplnil som slovo "programu", aby to znelo prirodzenejsie. priklad:po pripojeni USB kluca bolo zobrazene "Otvoriť pomocou Súbory"
#: ../js/ui/components/autorunManager.js:591 #: ../js/ui/components/autorunManager.js:591
#, c-format #, c-format
msgid "Open with %s" msgid "Open with %s"
msgstr "Otvoriť pomocou %s" msgstr "Otvoriť pomocou programu %s"
#: ../js/ui/components/autorunManager.js:617 #: ../js/ui/components/autorunManager.js:617
msgid "Eject" msgid "Eject"
@ -623,7 +645,7 @@ msgstr ""
#: ../js/ui/components/networkAgent.js:314 #: ../js/ui/components/networkAgent.js:314
msgid "Wired 802.1X authentication" msgid "Wired 802.1X authentication"
msgstr "Overenie totožnosti drôtovej 802.1X" msgstr "Overenie totožnosti k drôtovej sieti 802.1X"
#: ../js/ui/components/networkAgent.js:316 #: ../js/ui/components/networkAgent.js:316
msgid "Network name: " msgid "Network name: "
@ -631,7 +653,7 @@ msgstr "Názov siete: "
#: ../js/ui/components/networkAgent.js:321 #: ../js/ui/components/networkAgent.js:321
msgid "DSL authentication" msgid "DSL authentication"
msgstr "Overenie totožnosti DSL" msgstr "Overenie totožnosti k DSL"
#: ../js/ui/components/networkAgent.js:328 #: ../js/ui/components/networkAgent.js:328
msgid "PIN code required" msgid "PIN code required"
@ -639,7 +661,7 @@ msgstr "Požaduje sa kód PIN"
#: ../js/ui/components/networkAgent.js:329 #: ../js/ui/components/networkAgent.js:329
msgid "PIN code is needed for the mobile broadband device" msgid "PIN code is needed for the mobile broadband device"
msgstr "Pre zariadenie mobilnej siete je potrebný PIN kód" msgstr "Pre zariadenie mobilnej siete je potrebný kód PIN"
#: ../js/ui/components/networkAgent.js:330 #: ../js/ui/components/networkAgent.js:330
msgid "PIN: " msgid "PIN: "
@ -647,7 +669,7 @@ msgstr "PIN: "
#: ../js/ui/components/networkAgent.js:336 #: ../js/ui/components/networkAgent.js:336
msgid "Mobile broadband network password" msgid "Mobile broadband network password"
msgstr "Heslo pre mobilnú sieť" msgstr "Heslo k mobilnej sieti"
#: ../js/ui/components/networkAgent.js:337 #: ../js/ui/components/networkAgent.js:337
#, c-format #, c-format
@ -675,11 +697,12 @@ msgstr "Overiť totožnosť"
msgid "Sorry, that didn't work. Please try again." msgid "Sorry, that didn't work. Please try again."
msgstr "Prepáčte, ale nezabralo to. Skúste to, prosím, znova." msgstr "Prepáčte, ale nezabralo to. Skúste to, prosím, znova."
# %d je datum, %t je cas
#. Translators: this is a filename used for screencast recording #. Translators: this is a filename used for screencast recording
#: ../js/ui/components/recorder.js:44 #: ../js/ui/components/recorder.js:44
#, no-c-format #, no-c-format
msgid "Screencast from %d %t" msgid "Screencast from %d %t"
msgstr "Záznam videa obrazovky z %d %t" msgstr "Záznam videa obrazovky dňa %d o %t"
#. FIXME: We don't have a 'chat room' icon (bgo #653737) use #. FIXME: We don't have a 'chat room' icon (bgo #653737) use
#. system-users for now as Empathy does. #. system-users for now as Empathy does.
@ -714,44 +737,42 @@ msgid "Mute"
msgstr "Stlmiť" msgstr "Stlmiť"
#. 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 the word "Yesterday". i.e. "14:30 on Yesterday"
#: ../js/ui/components/telepathyClient.js:941 #: ../js/ui/components/telepathyClient.js:943
#, no-c-format #, no-c-format
msgid "<b>%H:%M</b> on Yesterday" msgid "<b>%H:%M</b> on Yesterday"
msgstr "" msgstr "včera o <b>%H:%M</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 string followed by a week day name. i.e. "14:30 on Monday
#: ../js/ui/components/telepathyClient.js:947 #: ../js/ui/components/telepathyClient.js:949
#, fuzzy, no-c-format #, no-c-format
#| msgid "Sent at <b>%X</b> on <b>%A</b>"
msgid "<b>%H:%M</b> on <b>%A</b>" msgid "<b>%H:%M</b> on <b>%A</b>"
msgstr "Čas odoslania: <b>%A</b>, <b>%R</b>" msgstr "v <b>%A</b> o <b>%H:%M</b>"
#. Translators: this is a time format in the style of "14:30 on Wednesday, May 25", #. 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 #. shown when you get a chat message in the same year
#: ../js/ui/components/telepathyClient.js:953 #: ../js/ui/components/telepathyClient.js:955
#, fuzzy, no-c-format #, no-c-format
#| msgid "Sent on <b>%A</b>, <b>%B %d</b>"
msgid "<b>%H:%M</b> on <b>%A</b>, <b>%B</b> <b>%d</b>" msgid "<b>%H:%M</b> on <b>%A</b>, <b>%B</b> <b>%d</b>"
msgstr "Čas odoslania: <b>%A</b>, <b>%e. %B</b>" msgstr "v <b>%A</b> o <b>%H:%M</b>, <b>%e.</b> <b>%B</b>"
#. Translators: this is a time format in the style of "14:30 on Wednesday, May 25, 2012", #. 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 #. shown when you get a chat message in a different year
#: ../js/ui/components/telepathyClient.js:958 #: ../js/ui/components/telepathyClient.js:960
#, fuzzy, no-c-format #, no-c-format
#| msgid "Sent on <b>%A</b>, <b>%B %d</b>, %Y"
msgid "<b>%H:%M</b> on <b>%A</b>, <b>%B</b> <b>%d</b>, %Y" msgid "<b>%H:%M</b> on <b>%A</b>, <b>%B</b> <b>%d</b>, %Y"
msgstr "Čas odoslania: <b>%A</b>, <b>%e. %B</b> %Y" msgstr "v <b>%A</b> o <b>%H:%M</b>, <b>%e.</b> <b>%B</b>, %Y"
#. Translators: this is the other person changing their old IM name to their new #. Translators: this is the other person changing their old IM name to their new
#. IM name. #. IM name.
#: ../js/ui/components/telepathyClient.js:986 #: ../js/ui/components/telepathyClient.js:988
#, c-format #, c-format
msgid "%s is now known as %s" msgid "%s is now known as %s"
msgstr "%s odteraz vystupuje ako %s" msgstr "Kontakt %s odteraz vystupuje ako %s"
#. translators: argument is a room name like #. translators: argument is a room name like
#. * room@jabber.org for example. #. * room@jabber.org for example.
#: ../js/ui/components/telepathyClient.js:1085 #: ../js/ui/components/telepathyClient.js:1087
#, c-format #, c-format
msgid "Invitation to %s" msgid "Invitation to %s"
msgstr "Pozvánka do %s" msgstr "Pozvánka do %s"
@ -759,42 +780,42 @@ msgstr "Pozvánka do %s"
#. translators: first argument is the name of a contact and the second #. 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 #. * one the name of a room. "Alice is inviting you to join room@jabber.org
#. * for example. #. * for example.
#: ../js/ui/components/telepathyClient.js:1093 #: ../js/ui/components/telepathyClient.js:1095
#, c-format #, c-format
msgid "%s is inviting you to join %s" msgid "%s is inviting you to join %s"
msgstr "%s vás pozýva aby ste sa pridali do %s" msgstr "Kontakt %s vás pozýva aby ste sa pridali do %s"
#: ../js/ui/components/telepathyClient.js:1095 #: ../js/ui/components/telepathyClient.js:1097
#: ../js/ui/components/telepathyClient.js:1174 #: ../js/ui/components/telepathyClient.js:1176
#: ../js/ui/components/telepathyClient.js:1237 #: ../js/ui/components/telepathyClient.js:1239
msgid "Decline" msgid "Decline"
msgstr "Odmietnuť" msgstr "Odmietnuť"
#: ../js/ui/components/telepathyClient.js:1096 #: ../js/ui/components/telepathyClient.js:1098
#: ../js/ui/components/telepathyClient.js:1175 #: ../js/ui/components/telepathyClient.js:1177
#: ../js/ui/components/telepathyClient.js:1238 #: ../js/ui/components/telepathyClient.js:1240
msgid "Accept" msgid "Accept"
msgstr "Prijať" msgstr "Prijať"
#. translators: argument is a contact name like Alice for example. #. translators: argument is a contact name like Alice for example.
#: ../js/ui/components/telepathyClient.js:1126 #: ../js/ui/components/telepathyClient.js:1128
#, c-format #, c-format
msgid "Video call from %s" msgid "Video call from %s"
msgstr "Videohovor od používateľa %s" msgstr "Videohovor od kontaktu %s"
#. translators: argument is a contact name like Alice for example. #. translators: argument is a contact name like Alice for example.
#: ../js/ui/components/telepathyClient.js:1129 #: ../js/ui/components/telepathyClient.js:1131
#, c-format #, c-format
msgid "Call from %s" msgid "Call from %s"
msgstr "Hovor od používateľa %s" msgstr "Hovor od kontaktu %s"
#: ../js/ui/components/telepathyClient.js:1134 #: ../js/ui/components/telepathyClient.js:1136
#: ../js/ui/status/bluetooth.js:346 #: ../js/ui/status/bluetooth.js:346
msgid "Reject" msgid "Reject"
msgstr "Odmietnuť" msgstr "Odmietnuť"
#. translators: this is a button label (verb), not a noun #. translators: this is a button label (verb), not a noun
#: ../js/ui/components/telepathyClient.js:1136 #: ../js/ui/components/telepathyClient.js:1138
msgid "Answer" msgid "Answer"
msgstr "Prijať hovor" msgstr "Prijať hovor"
@ -803,110 +824,111 @@ msgstr "Prijať hovor"
#. * file name. The string will be something #. * file name. The string will be something
#. * like: "Alice is sending you test.ogg" #. * like: "Alice is sending you test.ogg"
#. #.
#: ../js/ui/components/telepathyClient.js:1168 #: ../js/ui/components/telepathyClient.js:1170
#, c-format #, c-format
msgid "%s is sending you %s" msgid "%s is sending you %s"
msgstr "%s vám posiela %s" msgstr "Kontakt %s vám posiela %s"
#. To translators: The parameter is the contact's alias #. To translators: The parameter is the contact's alias
#: ../js/ui/components/telepathyClient.js:1203 #: ../js/ui/components/telepathyClient.js:1205
#, c-format #, c-format
msgid "%s would like permission to see when you are online" msgid "%s would like permission to see when you are online"
msgstr "%s by chcel získať oprávnenie vidieť, kedy ste pripojený" msgstr ""
"Kontakt %s by chcel získať oprávnenie vidieť, kedy ste pripojený"
#: ../js/ui/components/telepathyClient.js:1295 #: ../js/ui/components/telepathyClient.js:1297
msgid "Network error" msgid "Network error"
msgstr "Chyba siete" msgstr "Chyba siete"
#: ../js/ui/components/telepathyClient.js:1297 #: ../js/ui/components/telepathyClient.js:1299
msgid "Authentication failed" msgid "Authentication failed"
msgstr "Overenie totožnosti zlyhalo" msgstr "Overenie totožnosti zlyhalo"
#: ../js/ui/components/telepathyClient.js:1299 #: ../js/ui/components/telepathyClient.js:1301
msgid "Encryption error" msgid "Encryption error"
msgstr "Chyba šifrovania" msgstr "Chyba šifrovania"
#: ../js/ui/components/telepathyClient.js:1301 #: ../js/ui/components/telepathyClient.js:1303
msgid "Certificate not provided" msgid "Certificate not provided"
msgstr "Neposkytnutý certifikát" msgstr "Neposkytnutý certifikát"
#: ../js/ui/components/telepathyClient.js:1303 #: ../js/ui/components/telepathyClient.js:1305
msgid "Certificate untrusted" msgid "Certificate untrusted"
msgstr "Nedôveryhodný certifikát" msgstr "Nedôveryhodný certifikát"
#: ../js/ui/components/telepathyClient.js:1305 #: ../js/ui/components/telepathyClient.js:1307
msgid "Certificate expired" msgid "Certificate expired"
msgstr "Certifikát s ukončenou platnosťou" msgstr "Certifikát s ukončenou platnosťou"
#: ../js/ui/components/telepathyClient.js:1307 #: ../js/ui/components/telepathyClient.js:1309
msgid "Certificate not activated" msgid "Certificate not activated"
msgstr "Neaktivovaný certifikát" msgstr "Neaktivovaný certifikát"
#: ../js/ui/components/telepathyClient.js:1309 #: ../js/ui/components/telepathyClient.js:1311
msgid "Certificate hostname mismatch" msgid "Certificate hostname mismatch"
msgstr "Certifikát s nesúhlasným názvom hostiteľa" msgstr "Certifikát s nesúhlasným názvom hostiteľa"
#: ../js/ui/components/telepathyClient.js:1311 #: ../js/ui/components/telepathyClient.js:1313
msgid "Certificate fingerprint mismatch" msgid "Certificate fingerprint mismatch"
msgstr "Certifikát s nesúhlasným odtlačkom" msgstr "Certifikát s nesúhlasným odtlačkom"
#: ../js/ui/components/telepathyClient.js:1313 #: ../js/ui/components/telepathyClient.js:1315
msgid "Certificate self-signed" msgid "Certificate self-signed"
msgstr "Sebou podpísaný certifikát" msgstr "Sebou podpísaný certifikát"
#: ../js/ui/components/telepathyClient.js:1315 #: ../js/ui/components/telepathyClient.js:1317
msgid "Status is set to offline" msgid "Status is set to offline"
msgstr "Stav je nastavený na odhlásený" msgstr "Stav je nastavený na odhlásený"
#: ../js/ui/components/telepathyClient.js:1317 #: ../js/ui/components/telepathyClient.js:1319
msgid "Encryption is not available" msgid "Encryption is not available"
msgstr "Šifrovanie nie je dostupné" msgstr "Šifrovanie nie je dostupné"
#: ../js/ui/components/telepathyClient.js:1319 #: ../js/ui/components/telepathyClient.js:1321
msgid "Certificate is invalid" msgid "Certificate is invalid"
msgstr "Certifikát je neplatný" msgstr "Certifikát je neplatný"
#: ../js/ui/components/telepathyClient.js:1321 #: ../js/ui/components/telepathyClient.js:1323
msgid "Connection has been refused" msgid "Connection has been refused"
msgstr "Pripojenie bolo odmietnuté" msgstr "Pripojenie bolo odmietnuté"
#: ../js/ui/components/telepathyClient.js:1323 #: ../js/ui/components/telepathyClient.js:1325
msgid "Connection can't be established" msgid "Connection can't be established"
msgstr "Nedá sa nadviazať spojenie" msgstr "Nedá sa nadviazať spojenie"
#: ../js/ui/components/telepathyClient.js:1325 #: ../js/ui/components/telepathyClient.js:1327
msgid "Connection has been lost" msgid "Connection has been lost"
msgstr "Spojenie sa stratilo" msgstr "Spojenie sa stratilo"
#: ../js/ui/components/telepathyClient.js:1327 #: ../js/ui/components/telepathyClient.js:1329
msgid "This account is already connected to the server" msgid "This account is already connected to the server"
msgstr "Tento účet je už pripojený k serveru" msgstr "Tento účet je už pripojený k serveru"
#: ../js/ui/components/telepathyClient.js:1329 #: ../js/ui/components/telepathyClient.js:1331
msgid "" msgid ""
"Connection has been replaced by a new connection using the same resource" "Connection has been replaced by a new connection using the same resource"
msgstr "Pripojenie bolo nahradené novým, ktoré používa rovnaký zdroj" msgstr "Pripojenie bolo nahradené novým, ktoré používa rovnaký zdroj"
#: ../js/ui/components/telepathyClient.js:1331 #: ../js/ui/components/telepathyClient.js:1333
msgid "The account already exists on the server" msgid "The account already exists on the server"
msgstr "Účet na serveri už existuje" msgstr "Účet na serveri už existuje"
#: ../js/ui/components/telepathyClient.js:1333 #: ../js/ui/components/telepathyClient.js:1335
msgid "Server is currently too busy to handle the connection" msgid "Server is currently too busy to handle the connection"
msgstr "Server je momentálne príliš zaneprázdnený na zvládnutie pripojenia" msgstr "Server je momentálne príliš zaneprázdnený na zvládnutie pripojenia"
#: ../js/ui/components/telepathyClient.js:1335 #: ../js/ui/components/telepathyClient.js:1337
msgid "Certificate has been revoked" msgid "Certificate has been revoked"
msgstr "Certifikát bol zrušený" msgstr "Certifikát bol zrušený"
#: ../js/ui/components/telepathyClient.js:1337 #: ../js/ui/components/telepathyClient.js:1339
msgid "" msgid ""
"Certificate uses an insecure cipher algorithm or is cryptographically weak" "Certificate uses an insecure cipher algorithm or is cryptographically weak"
msgstr "" msgstr ""
"Šifrovací algoritmus používaný certifikátom nie je bezpečný alebo je " "Šifrovací algoritmus používaný certifikátom nie je bezpečný alebo je "
"kryptograficky slabý" "kryptograficky slabý"
#: ../js/ui/components/telepathyClient.js:1339 #: ../js/ui/components/telepathyClient.js:1341
msgid "" msgid ""
"The length of the server certificate, or the depth of the server certificate " "The length of the server certificate, or the depth of the server certificate "
"chain, exceed the limits imposed by the cryptography library" "chain, exceed the limits imposed by the cryptography library"
@ -914,26 +936,26 @@ msgstr ""
"Dĺžka certifikátu servera, alebo hĺbka reťazca certifikátu servera presahuje " "Dĺžka certifikátu servera, alebo hĺbka reťazca certifikátu servera presahuje "
"limit stanovený kryptografickou knižnicou." "limit stanovený kryptografickou knižnicou."
#: ../js/ui/components/telepathyClient.js:1341 #: ../js/ui/components/telepathyClient.js:1343
msgid "Internal error" msgid "Internal error"
msgstr "Vnútorná chyba" msgstr "Vnútorná chyba"
#. translators: argument is the account name, like #. translators: argument is the account name, like
#. * name@jabber.org for example. #. * name@jabber.org for example.
#: ../js/ui/components/telepathyClient.js:1351 #: ../js/ui/components/telepathyClient.js:1353
#, c-format #, c-format
msgid "Connection to %s failed" msgid "Connection to %s failed"
msgstr "Pripojenie k %s zlyhalo" msgstr "Pripojenie k %s zlyhalo"
#: ../js/ui/components/telepathyClient.js:1360 #: ../js/ui/components/telepathyClient.js:1362
msgid "Reconnect" msgid "Reconnect"
msgstr "Znovu sa pripojiť" msgstr "Znovu sa pripojiť"
#: ../js/ui/components/telepathyClient.js:1361 #: ../js/ui/components/telepathyClient.js:1363
msgid "Edit account" msgid "Edit account"
msgstr "Upraviť účet" msgstr "Upraviť účet"
#: ../js/ui/components/telepathyClient.js:1406 #: ../js/ui/components/telepathyClient.js:1408
msgid "Unknown reason" msgid "Unknown reason"
msgstr "Neznámy dôvod" msgstr "Neznámy dôvod"
@ -992,7 +1014,7 @@ msgstr[2] "Budete automaticky odhlásený o %d sekundy."
#: ../js/ui/endSessionDialog.js:74 #: ../js/ui/endSessionDialog.js:74
msgid "Logging out of the system." msgid "Logging out of the system."
msgstr "Odhlasuje sa zo systému." msgstr "Prebieha odhlásenie zo systému."
#: ../js/ui/endSessionDialog.js:76 #: ../js/ui/endSessionDialog.js:76
msgctxt "button" msgctxt "button"
@ -1120,21 +1142,21 @@ msgstr "Zobraziť zdroj"
msgid "Web Page" msgid "Web Page"
msgstr "Webová stránka" msgstr "Webová stránka"
#: ../js/ui/messageTray.js:1082 #: ../js/ui/messageTray.js:1083
msgid "Open" msgid "Open"
msgstr "Otvoriť" msgstr "Otvoriť"
#: ../js/ui/messageTray.js:1089 #: ../js/ui/messageTray.js:1090
msgid "Remove" msgid "Remove"
msgstr "Odstrániť" msgstr "Odstrániť"
# DK: zvazoval som pouzit "Panel správ" # DK: zvazoval som pouzit "Panel správ"
# neviem co bude vhodnejsie ako preklad "tray" # neviem co bude vhodnejsie ako preklad "tray"
#: ../js/ui/messageTray.js:1545 #: ../js/ui/messageTray.js:1534
msgid "Message Tray" msgid "Message Tray"
msgstr "Lišta správ" msgstr "Lišta správ"
#: ../js/ui/messageTray.js:2552 #: ../js/ui/messageTray.js:2557
msgid "System Information" msgid "System Information"
msgstr "Informácie o systéme" msgstr "Informácie o systéme"
@ -1175,7 +1197,7 @@ msgstr "Ukončiť"
msgid "Activities" msgid "Activities"
msgstr "Aktivity" msgstr "Aktivity"
#: ../js/ui/panel.js:965 #: ../js/ui/panel.js:966
msgid "Top Bar" msgid "Top Bar"
msgstr "Horná lišta" msgstr "Horná lišta"
@ -1197,11 +1219,11 @@ msgstr "Prosím, zadajte príkaz:"
# v ostatnych retazcoch je pouzite %e, tak to bude asi OK # v ostatnych retazcoch je pouzite %e, tak to bude asi OK
#. Translators: This is a time format for a date in #. Translators: This is a time format for a date in
#. long format #. long format
#: ../js/ui/screenShield.js:79 #: ../js/ui/screenShield.js:80
msgid "%A, %B %d" msgid "%A, %B %d"
msgstr "%A, %e. %B" msgstr "%A, %e. %B"
#: ../js/ui/screenShield.js:143 #: ../js/ui/screenShield.js:144
#, c-format #, c-format
msgid "%d new message" msgid "%d new message"
msgid_plural "%d new messages" msgid_plural "%d new messages"
@ -1209,13 +1231,13 @@ msgstr[0] "%d nových správ"
msgstr[1] "%d nová správa" msgstr[1] "%d nová správa"
msgstr[2] "%d nové správy" msgstr[2] "%d nové správy"
#: ../js/ui/screenShield.js:145 #: ../js/ui/screenShield.js:146
#, c-format #, c-format
msgid "%d new notification" msgid "%d new notification"
msgid_plural "%d new notifications" msgid_plural "%d new notifications"
msgstr[0] "%d nových upozornení" msgstr[0] "%d nových oznámení"
msgstr[1] "%d nové upozornenie" msgstr[1] "%d nové oznámenie"
msgstr[2] "%d nové upozornenia" msgstr[2] "%d nové oznámenia"
#: ../js/ui/searchDisplay.js:275 #: ../js/ui/searchDisplay.js:275
msgid "Searching..." msgid "Searching..."
@ -1249,13 +1271,13 @@ msgstr "Heslo"
msgid "Remember Password" msgid "Remember Password"
msgstr "Zapamätať heslo" msgstr "Zapamätať heslo"
#: ../js/ui/shellMountOperation.js:400 ../js/ui/unlockDialog.js:170 #: ../js/ui/shellMountOperation.js:400 ../js/ui/unlockDialog.js:171
msgid "Unlock" msgid "Unlock"
msgstr "Odblokovať" msgstr "Odblokovať"
#: ../js/ui/status/accessibility.js:39 #: ../js/ui/status/accessibility.js:39
msgid "Accessibility" msgid "Accessibility"
msgstr "Prístupnosť" msgstr "Zjednodušenie ovládania"
#: ../js/ui/status/accessibility.js:44 #: ../js/ui/status/accessibility.js:44
msgid "Zoom" msgid "Zoom"
@ -1537,7 +1559,7 @@ msgstr "Mobilné"
#: ../js/ui/status/network.js:1628 #: ../js/ui/status/network.js:1628
msgid "VPN Connections" msgid "VPN Connections"
msgstr "VPN pripojenia" msgstr "Pripojenia k VPN"
#: ../js/ui/status/network.js:1635 #: ../js/ui/status/network.js:1635
msgid "Network Settings" msgid "Network Settings"
@ -1669,7 +1691,7 @@ msgstr "Hlasitosť"
msgid "Microphone" msgid "Microphone"
msgstr "Mikrofón" msgstr "Mikrofón"
#: ../js/ui/unlockDialog.js:177 #: ../js/ui/unlockDialog.js:178
msgid "Log in as another user" msgid "Log in as another user"
msgstr "Prihlásiť ako iný používateľ" msgstr "Prihlásiť ako iný používateľ"
@ -1697,35 +1719,35 @@ msgstr "Nečinný"
msgid "Unavailable" msgid "Unavailable"
msgstr "Nedostupný" msgstr "Nedostupný"
#: ../js/ui/userMenu.js:735 #: ../js/ui/userMenu.js:743
msgid "Notifications" msgid "Notifications"
msgstr "Upozornenia" msgstr "Upozornenia"
#: ../js/ui/userMenu.js:743 #: ../js/ui/userMenu.js:751
msgid "System Settings" msgid "System Settings"
msgstr "Nastavenia systému" msgstr "Nastavenia systému"
#: ../js/ui/userMenu.js:751 #: ../js/ui/userMenu.js:759
msgid "Switch User" msgid "Switch User"
msgstr "Prepnúť používateľa" msgstr "Prepnúť používateľa"
#: ../js/ui/userMenu.js:756 #: ../js/ui/userMenu.js:764
msgid "Log Out" msgid "Log Out"
msgstr "Odhlásiť sa" msgstr "Odhlásiť sa"
#: ../js/ui/userMenu.js:761 #: ../js/ui/userMenu.js:769
msgid "Lock" msgid "Lock"
msgstr "Uzamknúť" msgstr "Uzamknúť"
#: ../js/ui/userMenu.js:776 #: ../js/ui/userMenu.js:784
msgid "Install Updates & Restart" msgid "Install Updates & Restart"
msgstr "Nainštalovať aktualizácie a reštartovať" msgstr "Nainštalovať aktualizácie a reštartovať"
#: ../js/ui/userMenu.js:794 #: ../js/ui/userMenu.js:802
msgid "Your chat status will be set to busy" msgid "Your chat status will be set to busy"
msgstr "Váš stav bude nastavený na zaneprázdnený" msgstr "Váš stav bude nastavený na zaneprázdnený"
#: ../js/ui/userMenu.js:795 #: ../js/ui/userMenu.js:803
msgid "" msgid ""
"Notifications are now disabled, including chat messages. Your online status " "Notifications are now disabled, including chat messages. Your online status "
"has been adjusted to let others know that you might not see their messages." "has been adjusted to let others know that you might not see their messages."

View File

@ -218,12 +218,12 @@ msgstr "يىغقۇچقا قوش"
#: ../js/ui/appFavorites.js:91 #: ../js/ui/appFavorites.js:91
#, c-format #, c-format
msgid "%s has been added to your favorites." msgid "%s has been added to your favorites."
msgstr "%s يىغقۇچىڭىزغا قوشۇلدى." msgstr "%s يىغقۇچىڭىزغا قوشۇلدى."
#: ../js/ui/appFavorites.js:122 #: ../js/ui/appFavorites.js:122
#, c-format #, c-format
msgid "%s has been removed from your favorites." msgid "%s has been removed from your favorites."
msgstr "%s يىغقۇچىڭىزدىن چىقىرىۋېتىلىدۇ." msgstr "%s يىغقۇچىڭىزدىن چىقىرىۋېتىلىدۇ."
#. Translators: Shown in calendar event list for all day events #. Translators: Shown in calendar event list for all day events
#. * Keep it short, best if you can use less then 10 characters #. * Keep it short, best if you can use less then 10 characters
@ -437,7 +437,7 @@ msgstr "يېقىنقى تۈرلەر"
#: ../js/ui/endSessionDialog.js:63 #: ../js/ui/endSessionDialog.js:63
#, c-format #, c-format
msgid "Log Out %s" msgid "Log Out %s"
msgstr "%s تىزىمدىن چىقىش" msgstr "%s تىزىمدىن چىقىش"
#: ../js/ui/endSessionDialog.js:64 ../js/ui/endSessionDialog.js:70 #: ../js/ui/endSessionDialog.js:64 ../js/ui/endSessionDialog.js:70
msgid "Log Out" msgid "Log Out"
@ -452,7 +452,7 @@ msgstr ""
#: ../js/ui/endSessionDialog.js:66 #: ../js/ui/endSessionDialog.js:66
#, c-format #, c-format
msgid "%s will be logged out automatically in %d seconds." msgid "%s will be logged out automatically in %d seconds."
msgstr "%s تىزىمدىن %d سېكۇنتتىن كېيىن ئۆزلۈكىدىن چىقىسىز." msgstr "%s تىزىمدىن %d سېكۇنتتىن كېيىن ئۆزلۈكىدىن چىقىسىز."
#: ../js/ui/endSessionDialog.js:67 #: ../js/ui/endSessionDialog.js:67
#, c-format #, c-format
@ -566,7 +566,7 @@ msgstr "سىزىقچە"
#: ../js/ui/panel.js:533 #: ../js/ui/panel.js:533
#, c-format #, c-format
msgid "Quit %s" msgid "Quit %s"
msgstr "%s چېكىن" msgstr "%s چېكىن"
#. Button on the left side of the panel. #. Button on the left side of the panel.
#. Translators: If there is no suitable word for "Activities" in your language, you can use the word for "Overview". #. Translators: If there is no suitable word for "Activities" in your language, you can use the word for "Overview".
@ -799,7 +799,7 @@ msgstr "رەت قىل"
#: ../js/ui/status/bluetooth.js:408 #: ../js/ui/status/bluetooth.js:408
#, c-format #, c-format
msgid "Pairing confirmation for %s" msgid "Pairing confirmation for %s"
msgstr "%s نىڭ جەزملىشىنى جۈپلەشتۈرۈۋاتىدۇ" msgstr "%s نىڭ جەزملىشىنى جۈپلەشتۈرۈۋاتىدۇ"
#: ../js/ui/status/bluetooth.js:414 ../js/ui/status/bluetooth.js:448 #: ../js/ui/status/bluetooth.js:414 ../js/ui/status/bluetooth.js:448
#, c-format #, c-format
@ -823,7 +823,7 @@ msgstr "ماسلاشمىدى"
#: ../js/ui/status/bluetooth.js:441 #: ../js/ui/status/bluetooth.js:441
#, c-format #, c-format
msgid "Pairing request for %s" msgid "Pairing request for %s"
msgstr "%s دىن كەلگەن جۈپلەش ئىلتىماسى" msgstr "%s دىن كەلگەن جۈپلەش ئىلتىماسى"
#: ../js/ui/status/bluetooth.js:449 #: ../js/ui/status/bluetooth.js:449
msgid "Please enter the PIN mentioned on the device." msgid "Please enter the PIN mentioned on the device."
@ -1074,22 +1074,22 @@ msgstr "مىكروفون"
#: ../js/ui/telepathyClient.js:335 #: ../js/ui/telepathyClient.js:335
#, c-format #, c-format
msgid "%s is online." msgid "%s is online."
msgstr "%s توردا." msgstr "%s توردا."
#: ../js/ui/telepathyClient.js:340 #: ../js/ui/telepathyClient.js:340
#, c-format #, c-format
msgid "%s is offline." msgid "%s is offline."
msgstr "%s توردا يوق." msgstr "%s توردا يوق."
#: ../js/ui/telepathyClient.js:343 #: ../js/ui/telepathyClient.js:343
#, c-format #, c-format
msgid "%s is away." msgid "%s is away."
msgstr "%s يوق." msgstr "%s يوق."
#: ../js/ui/telepathyClient.js:346 #: ../js/ui/telepathyClient.js:346
#, c-format #, c-format
msgid "%s is busy." msgid "%s is busy."
msgstr "%s ئالدىراش." msgstr "%s ئالدىراش."
#. Translators: this is a time format string followed by a date. #. Translators: this is a time format string followed by a date.
#. If applicable, replace %X with a strftime format valid for your #. If applicable, replace %X with a strftime format valid for your
@ -1114,7 +1114,7 @@ msgstr "ئىزدە"
#: ../js/ui/windowAttentionHandler.js:42 #: ../js/ui/windowAttentionHandler.js:42
#, c-format #, c-format
msgid "%s has finished starting" msgid "%s has finished starting"
msgstr "%s باشلاشنى تاماملىدى" msgstr "%s باشلاشنى تاماملىدى"
#: ../js/ui/windowAttentionHandler.js:44 #: ../js/ui/windowAttentionHandler.js:44
#, c-format #, c-format

View File

@ -31,7 +31,6 @@
#include <string.h> #include <string.h>
#define HANDLE_LIBICAL_MEMORY #define HANDLE_LIBICAL_MEMORY
#include <libecal/libecal.h> #include <libecal/libecal.h>
#include <libedataserverui/libedataserverui.h>
#undef CALENDAR_ENABLE_DEBUG #undef CALENDAR_ENABLE_DEBUG
#include "calendar-debug.h" #include "calendar-debug.h"

View File

@ -34,7 +34,6 @@
#include <unistd.h> #include <unistd.h>
#include <gio/gio.h> #include <gio/gio.h>
#include <gtk/gtk.h>
#define HANDLE_LIBICAL_MEMORY #define HANDLE_LIBICAL_MEMORY
#include <libecal/libecal.h> #include <libecal/libecal.h>
@ -985,9 +984,11 @@ on_name_lost (GDBusConnection *connection,
const gchar *name, const gchar *name,
gpointer user_data) gpointer user_data)
{ {
GMainLoop *main_loop = user_data;
g_print ("gnome-shell-calendar-server[%d]: Lost (or failed to acquire) the name " BUS_NAME " - exiting\n", g_print ("gnome-shell-calendar-server[%d]: Lost (or failed to acquire) the name " BUS_NAME " - exiting\n",
(gint) getpid ()); (gint) getpid ());
gtk_main_quit (); g_main_loop_quit (main_loop);
} }
static void static void
@ -1003,11 +1004,13 @@ stdin_channel_io_func (GIOChannel *source,
GIOCondition condition, GIOCondition condition,
gpointer data) gpointer data)
{ {
GMainLoop *main_loop = data;
if (condition & G_IO_HUP) if (condition & G_IO_HUP)
{ {
g_debug ("gnome-shell-calendar-server[%d]: Got HUP on stdin - exiting\n", g_debug ("gnome-shell-calendar-server[%d]: Got HUP on stdin - exiting\n",
(gint) getpid ()); (gint) getpid ());
gtk_main_quit (); g_main_loop_quit (main_loop);
} }
else else
{ {
@ -1022,6 +1025,7 @@ main (int argc,
{ {
GError *error; GError *error;
GOptionContext *opt_context; GOptionContext *opt_context;
GMainLoop *main_loop;
gint ret; gint ret;
guint name_owner_id; guint name_owner_id;
GIOChannel *stdin_channel; GIOChannel *stdin_channel;
@ -1031,9 +1035,7 @@ main (int argc,
name_owner_id = 0; name_owner_id = 0;
stdin_channel = NULL; stdin_channel = NULL;
/* We need to initialize GTK+ since evolution-data-server may decide to use g_type_init ();
* GTK+ to pop up a dialog box */
gtk_init (&argc, &argv);
introspection_data = g_dbus_node_info_new_for_xml (introspection_xml, NULL); introspection_data = g_dbus_node_info_new_for_xml (introspection_xml, NULL);
g_assert (introspection_data != NULL); g_assert (introspection_data != NULL);
@ -1048,11 +1050,15 @@ main (int argc,
goto out; goto out;
} }
main_loop = g_main_loop_new (NULL, FALSE);
stdin_channel = g_io_channel_unix_new (STDIN_FILENO); stdin_channel = g_io_channel_unix_new (STDIN_FILENO);
g_io_add_watch (stdin_channel, g_io_add_watch_full (stdin_channel,
G_IO_HUP, G_PRIORITY_DEFAULT,
stdin_channel_io_func, G_IO_HUP,
NULL); stdin_channel_io_func,
g_main_loop_ref (main_loop),
(GDestroyNotify) g_main_loop_unref);
name_owner_id = g_bus_own_name (G_BUS_TYPE_SESSION, name_owner_id = g_bus_own_name (G_BUS_TYPE_SESSION,
BUS_NAME, BUS_NAME,
@ -1061,10 +1067,12 @@ main (int argc,
on_bus_acquired, on_bus_acquired,
on_name_acquired, on_name_acquired,
on_name_lost, on_name_lost,
NULL, g_main_loop_ref (main_loop),
NULL); (GDestroyNotify) g_main_loop_unref);
gtk_main (); g_main_loop_run (main_loop);
g_main_loop_unref (main_loop);
ret = 0; ret = 0;

View File

@ -73,6 +73,7 @@ struct _ShellApp
char *window_id_string; char *window_id_string;
char *casefolded_name; char *casefolded_name;
char *casefolded_generic_name;
char *name_collation_key; char *name_collation_key;
char *casefolded_exec; char *casefolded_exec;
char **casefolded_keywords; char **casefolded_keywords;
@ -1310,6 +1311,7 @@ static void
shell_app_init_search_data (ShellApp *app) shell_app_init_search_data (ShellApp *app)
{ {
const char *name; const char *name;
const char *generic_name;
const char *exec; const char *exec;
const char * const *keywords; const char * const *keywords;
char *normalized_exec; char *normalized_exec;
@ -1319,6 +1321,12 @@ shell_app_init_search_data (ShellApp *app)
name = g_app_info_get_name (G_APP_INFO (appinfo)); name = g_app_info_get_name (G_APP_INFO (appinfo));
app->casefolded_name = shell_util_normalize_and_casefold (name); app->casefolded_name = shell_util_normalize_and_casefold (name);
generic_name = g_desktop_app_info_get_generic_name (appinfo);
if (generic_name)
app->casefolded_generic_name = shell_util_normalize_and_casefold (generic_name);
else
app->casefolded_generic_name = NULL;
exec = g_app_info_get_executable (G_APP_INFO (appinfo)); exec = g_app_info_get_executable (G_APP_INFO (appinfo));
normalized_exec = shell_util_normalize_and_casefold (exec); normalized_exec = shell_util_normalize_and_casefold (exec);
app->casefolded_exec = trim_exec_line (normalized_exec); app->casefolded_exec = trim_exec_line (normalized_exec);
@ -1388,6 +1396,18 @@ _shell_app_match_search_terms (ShellApp *app,
current_match = MATCH_SUBSTRING; current_match = MATCH_SUBSTRING;
} }
if (app->casefolded_generic_name)
{
p = strstr (app->casefolded_generic_name, term);
if (p != NULL)
{
if (p == app->casefolded_generic_name || *(p - 1) == ' ')
current_match = MATCH_PREFIX;
else if (current_match < MATCH_PREFIX)
current_match = MATCH_SUBSTRING;
}
}
if (app->casefolded_exec) if (app->casefolded_exec)
{ {
p = strstr (app->casefolded_exec, term); p = strstr (app->casefolded_exec, term);
@ -1497,6 +1517,7 @@ shell_app_finalize (GObject *object)
g_free (app->window_id_string); g_free (app->window_id_string);
g_free (app->casefolded_name); g_free (app->casefolded_name);
g_free (app->casefolded_generic_name);
g_free (app->name_collation_key); g_free (app->name_collation_key);
g_free (app->casefolded_exec); g_free (app->casefolded_exec);
g_strfreev (app->casefolded_keywords); g_strfreev (app->casefolded_keywords);

View File

@ -1693,43 +1693,3 @@ shell_global_get_session_mode (ShellGlobal *global)
return global->session_mode; return global->session_mode;
} }
/**
* shell_global_create_xrootpmap_texture:
* @global: The #ShellGlobal
*
* This returns the _XROOTPMAP_ID pixmap that gdm should have stuffed
* in the root window. The goal here is to allow a smooth fade between
* plymouth and the shell greeter. This is also a workaround for gjs not
* supporting raw xlib types.
*
* Returns: (transfer floating): A #ClutterActor that represents the
* _XROOTPMAP_ID pixmap property from the root window.
*/
ClutterActor *
shell_global_create_xrootpmap_texture (ShellGlobal *global)
{
Atom res_type;
int res_format;
unsigned long res_nitems, bytesafter;
unsigned char *data;
Pixmap root_pixmap_id = None;
g_return_val_if_fail (SHELL_IS_GLOBAL (global), NULL);
if (XGetWindowProperty (global->xdisplay,
DefaultRootWindow (global->xdisplay),
XInternAtom (global->xdisplay, "_XROOTPMAP_ID", False),
0, G_MAXLONG, False, XA_PIXMAP,
&res_type, &res_format, &res_nitems, &bytesafter, &data) == Success)
{
if (res_type == XA_PIXMAP && res_format == 32 && res_nitems == 1)
root_pixmap_id = * (Pixmap *) data;
XFree (data);
}
if (root_pixmap_id != None)
return clutter_x11_texture_pixmap_new_with_pixmap (root_pixmap_id);
else
return NULL;
}

View File

@ -136,8 +136,6 @@ void shell_global_reexec_self (ShellGlobal *global);
const char * shell_global_get_session_mode (ShellGlobal *global); const char * shell_global_get_session_mode (ShellGlobal *global);
ClutterActor * shell_global_create_xrootpmap_texture (ShellGlobal *global);
G_END_DECLS G_END_DECLS
#endif /* __SHELL_GLOBAL_H__ */ #endif /* __SHELL_GLOBAL_H__ */

View File

@ -11,6 +11,8 @@
#define GST_USE_UNSTABLE_API #define GST_USE_UNSTABLE_API
#include <gst/gst.h> #include <gst/gst.h>
#include <gtk/gtk.h>
#include "shell-recorder-src.h" #include "shell-recorder-src.h"
#include "shell-recorder.h" #include "shell-recorder.h"
#include "shell-screen-grabber.h" #include "shell-screen-grabber.h"
@ -65,7 +67,7 @@ struct _ShellRecorder {
int framerate; int framerate;
char *pipeline_description; char *pipeline_description;
char *filename; char *file_template;
/* We might have multiple pipelines that are finishing encoding /* We might have multiple pipelines that are finishing encoding
* to go along with the current pipeline where we are recording. * to go along with the current pipeline where we are recording.
@ -90,6 +92,7 @@ struct _RecorderPipeline
GstElement *pipeline; GstElement *pipeline;
GstElement *src; GstElement *src;
int outfile; int outfile;
char *filename;
}; };
static void recorder_set_stage (ShellRecorder *recorder, static void recorder_set_stage (ShellRecorder *recorder,
@ -98,8 +101,8 @@ static void recorder_set_framerate (ShellRecorder *recorder,
int framerate); int framerate);
static void recorder_set_pipeline (ShellRecorder *recorder, static void recorder_set_pipeline (ShellRecorder *recorder,
const char *pipeline); const char *pipeline);
static void recorder_set_filename (ShellRecorder *recorder, static void recorder_set_file_template (ShellRecorder *recorder,
const char *filename); const char *file_template);
static void recorder_pipeline_set_caps (RecorderPipeline *pipeline); static void recorder_pipeline_set_caps (RecorderPipeline *pipeline);
static void recorder_pipeline_closed (RecorderPipeline *pipeline); static void recorder_pipeline_closed (RecorderPipeline *pipeline);
@ -109,7 +112,7 @@ enum {
PROP_STAGE, PROP_STAGE,
PROP_FRAMERATE, PROP_FRAMERATE,
PROP_PIPELINE, PROP_PIPELINE,
PROP_FILENAME PROP_FILE_TEMPLATE
}; };
G_DEFINE_TYPE(ShellRecorder, shell_recorder, G_TYPE_OBJECT); G_DEFINE_TYPE(ShellRecorder, shell_recorder, G_TYPE_OBJECT);
@ -269,18 +272,6 @@ static void
shell_recorder_finalize (GObject *object) shell_recorder_finalize (GObject *object)
{ {
ShellRecorder *recorder = SHELL_RECORDER (object); ShellRecorder *recorder = SHELL_RECORDER (object);
GSList *l;
for (l = recorder->pipelines; l; l = l->next)
{
RecorderPipeline *pipeline = l->data;
/* Remove the back-reference. The pipeline will be freed
* when it finishes. (Or when the process exits, but that's
* out of our control.)
*/
pipeline->recorder = NULL;
}
if (recorder->update_memory_used_timeout) if (recorder->update_memory_used_timeout)
g_source_remove (recorder->update_memory_used_timeout); g_source_remove (recorder->update_memory_used_timeout);
@ -290,7 +281,7 @@ shell_recorder_finalize (GObject *object)
recorder_set_stage (recorder, NULL); recorder_set_stage (recorder, NULL);
recorder_set_pipeline (recorder, NULL); recorder_set_pipeline (recorder, NULL);
recorder_set_filename (recorder, NULL); recorder_set_file_template (recorder, NULL);
g_object_unref (recorder->grabber); g_object_unref (recorder->grabber);
@ -917,22 +908,22 @@ recorder_set_pipeline (ShellRecorder *recorder,
} }
static void static void
recorder_set_filename (ShellRecorder *recorder, recorder_set_file_template (ShellRecorder *recorder,
const char *filename) const char *file_template)
{ {
if (filename == recorder->filename || if (file_template == recorder->file_template ||
(filename && recorder->filename && strcmp (recorder->filename, filename) == 0)) (file_template && recorder->file_template && strcmp (recorder->file_template, file_template) == 0))
return; return;
if (recorder->current_pipeline) if (recorder->current_pipeline)
shell_recorder_close (recorder); shell_recorder_close (recorder);
if (recorder->filename) if (recorder->file_template)
g_free (recorder->filename); g_free (recorder->file_template);
recorder->filename = g_strdup (filename); recorder->file_template = g_strdup (file_template);
g_object_notify (G_OBJECT (recorder), "filename"); g_object_notify (G_OBJECT (recorder), "file-template");
} }
static void static void
@ -954,8 +945,8 @@ shell_recorder_set_property (GObject *object,
case PROP_PIPELINE: case PROP_PIPELINE:
recorder_set_pipeline (recorder, g_value_get_string (value)); recorder_set_pipeline (recorder, g_value_get_string (value));
break; break;
case PROP_FILENAME: case PROP_FILE_TEMPLATE:
recorder_set_filename (recorder, g_value_get_string (value)); recorder_set_file_template (recorder, g_value_get_string (value));
break; break;
default: default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
@ -982,8 +973,8 @@ shell_recorder_get_property (GObject *object,
case PROP_PIPELINE: case PROP_PIPELINE:
g_value_set_string (value, recorder->pipeline_description); g_value_set_string (value, recorder->pipeline_description);
break; break;
case PROP_FILENAME: case PROP_FILE_TEMPLATE:
g_value_set_string (value, recorder->filename); g_value_set_string (value, recorder->file_template);
break; break;
default: default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
@ -1027,9 +1018,9 @@ shell_recorder_class_init (ShellRecorderClass *klass)
G_PARAM_READWRITE)); G_PARAM_READWRITE));
g_object_class_install_property (gobject_class, g_object_class_install_property (gobject_class,
PROP_FILENAME, PROP_FILE_TEMPLATE,
g_param_spec_string ("filename", g_param_spec_string ("file-template",
"Filename", "File Template",
"The filename template to use for output files", "The filename template to use for output files",
NULL, NULL,
G_PARAM_READWRITE)); G_PARAM_READWRITE));
@ -1149,13 +1140,14 @@ get_absolute_path (char *maybe_relative)
* be opened. * be opened.
*/ */
static int static int
recorder_open_outfile (ShellRecorder *recorder) recorder_open_outfile (ShellRecorder *recorder,
char **outfilename)
{ {
const char *pattern; const char *pattern;
int flags; int flags;
int outfile = -1; int outfile = -1;
pattern = recorder->filename; pattern = recorder->file_template;
if (!pattern) if (!pattern)
return -1; return -1;
@ -1230,8 +1222,12 @@ recorder_open_outfile (ShellRecorder *recorder)
{ {
g_printerr ("Recording to %s\n", path); g_printerr ("Recording to %s\n", path);
if (outfilename != NULL)
*outfilename = path;
else
g_free (path);
g_string_free (filename, TRUE); g_string_free (filename, TRUE);
g_free (path);
goto out; goto out;
} }
@ -1269,7 +1265,8 @@ recorder_pipeline_add_sink (RecorderPipeline *pipeline)
return TRUE; return TRUE;
} }
pipeline->outfile = recorder_open_outfile (pipeline->recorder); pipeline->outfile = recorder_open_outfile (pipeline->recorder,
&pipeline->filename);
if (pipeline->outfile == -1) if (pipeline->outfile == -1)
goto out; goto out;
@ -1344,6 +1341,10 @@ recorder_pipeline_free (RecorderPipeline *pipeline)
if (pipeline->outfile != -1) if (pipeline->outfile != -1)
close (pipeline->outfile); close (pipeline->outfile);
g_free (pipeline->filename);
g_clear_object (&pipeline->recorder);
g_free (pipeline); g_free (pipeline);
} }
@ -1393,6 +1394,10 @@ recorder_pipeline_closed (RecorderPipeline *pipeline)
if (pipeline->recorder) if (pipeline->recorder)
{ {
GtkRecentManager *recent_manager;
GFile *file;
char *uri;
ShellRecorder *recorder = pipeline->recorder; ShellRecorder *recorder = pipeline->recorder;
if (pipeline == recorder->current_pipeline) if (pipeline == recorder->current_pipeline)
{ {
@ -1401,6 +1406,15 @@ recorder_pipeline_closed (RecorderPipeline *pipeline)
shell_recorder_close (recorder); shell_recorder_close (recorder);
} }
recent_manager = gtk_recent_manager_get_default ();
file = g_file_new_for_path (pipeline->filename);
uri = g_file_get_uri (file);
gtk_recent_manager_add_item (recent_manager,
uri);
g_free (uri);
g_object_unref (file);
recorder->pipelines = g_slist_remove (recorder->pipelines, pipeline); recorder->pipelines = g_slist_remove (recorder->pipelines, pipeline);
} }
@ -1452,7 +1466,7 @@ recorder_open_pipeline (ShellRecorder *recorder)
GstBus *bus; GstBus *bus;
pipeline = g_new0(RecorderPipeline, 1); pipeline = g_new0(RecorderPipeline, 1);
pipeline->recorder = recorder; pipeline->recorder = g_object_ref (recorder);
pipeline->outfile = - 1; pipeline->outfile = - 1;
pipeline_description = recorder->pipeline_description; pipeline_description = recorder->pipeline_description;
@ -1555,10 +1569,10 @@ shell_recorder_set_framerate (ShellRecorder *recorder,
} }
/** /**
* shell_recorder_set_filename: * shell_recorder_set_file_template:
* @recorder: the #ShellRecorder * @recorder: the #ShellRecorder
* @filename: the filename template to use for output files, * @file_template: the filename template to use for output files,
* or %NULL for the defalt value. * or %NULL for the defalt value.
* *
* Sets the filename that will be used when creating output * Sets the filename that will be used when creating output
* files. This is only used if the configured pipeline has an * files. This is only used if the configured pipeline has an
@ -1573,12 +1587,12 @@ shell_recorder_set_framerate (ShellRecorder *recorder,
* The default value is 'shell-%d%u-%c.ogg'. * The default value is 'shell-%d%u-%c.ogg'.
*/ */
void void
shell_recorder_set_filename (ShellRecorder *recorder, shell_recorder_set_file_template (ShellRecorder *recorder,
const char *filename) const char *file_template)
{ {
g_return_if_fail (SHELL_IS_RECORDER (recorder)); g_return_if_fail (SHELL_IS_RECORDER (recorder));
recorder_set_filename (recorder, filename); recorder_set_file_template (recorder, file_template);
} }
@ -1593,7 +1607,7 @@ shell_recorder_set_filename (ShellRecorder *recorder,
* should have an unconnected sink pad where the recorded * should have an unconnected sink pad where the recorded
* video is recorded. It will normally have a unconnected * video is recorded. It will normally have a unconnected
* source pad; output from that pad will be written into the * source pad; output from that pad will be written into the
* output file. (See shell_recorder_set_filename().) However * output file. (See shell_recorder_set_file_template().) However
* the pipeline can also take care of its own output - this * the pipeline can also take care of its own output - this
* might be used to send the output to an icecast server * might be used to send the output to an icecast server
* via shout2send or similar. * via shout2send or similar.

View File

@ -32,8 +32,8 @@ ShellRecorder *shell_recorder_new (ClutterStage *stage);
void shell_recorder_set_framerate (ShellRecorder *recorder, void shell_recorder_set_framerate (ShellRecorder *recorder,
int framerate); int framerate);
void shell_recorder_set_filename (ShellRecorder *recorder, void shell_recorder_set_file_template (ShellRecorder *recorder,
const char *filename); const char *file_template);
void shell_recorder_set_pipeline (ShellRecorder *recorder, void shell_recorder_set_pipeline (ShellRecorder *recorder,
const char *pipeline); const char *pipeline);
gboolean shell_recorder_record (ShellRecorder *recorder); gboolean shell_recorder_record (ShellRecorder *recorder);

View File

@ -3,6 +3,7 @@
#define GST_USE_UNSTABLE_API #define GST_USE_UNSTABLE_API
#include "shell-recorder.h" #include "shell-recorder.h"
#include <clutter/clutter.h> #include <clutter/clutter.h>
#include <gtk/gtk.h>
#include <gst/gst.h> #include <gst/gst.h>
/* Very simple test of the ShellRecorder class; shows some text strings /* Very simple test of the ShellRecorder class; shows some text strings
@ -11,23 +12,34 @@
static ShellRecorder *recorder = NULL; static ShellRecorder *recorder = NULL;
static gboolean static gboolean
stop_recording_timeout (gpointer data) stop_recording_timeout (ClutterActor *stage)
{ {
if (recorder) if (recorder)
{ {
shell_recorder_close (recorder); shell_recorder_close (recorder);
/* quit when the recorder finishes closing
*/
g_object_weak_ref (G_OBJECT (recorder),
(GWeakNotify)
clutter_actor_destroy,
stage);
g_object_unref (recorder); g_object_unref (recorder);
} }
else
clutter_main_quit (); {
clutter_actor_destroy (stage);
}
return FALSE; return FALSE;
} }
static void static void
on_animation_completed (ClutterAnimation *animation) on_animation_completed (ClutterAnimation *animation,
ClutterStage *stage)
{ {
g_timeout_add (1000, stop_recording_timeout, NULL); g_timeout_add (1000, (GSourceFunc) stop_recording_timeout, stage);
} }
static void static void
@ -35,7 +47,7 @@ on_stage_realized (ClutterActor *stage,
gpointer data) gpointer data)
{ {
recorder = shell_recorder_new (CLUTTER_STAGE (stage)); recorder = shell_recorder_new (CLUTTER_STAGE (stage));
shell_recorder_set_filename (recorder, "test-recorder.ogg"); shell_recorder_set_file_template (recorder, "test-recorder.ogg");
shell_recorder_record (recorder); shell_recorder_record (recorder);
} }
@ -46,6 +58,7 @@ int main (int argc, char **argv)
ClutterAnimation *animation; ClutterAnimation *animation;
ClutterColor red, green, blue; ClutterColor red, green, blue;
gtk_init (&argc, &argv);
gst_init (&argc, &argv); gst_init (&argc, &argv);
if (clutter_init (&argc, &argv) != CLUTTER_INIT_SUCCESS) if (clutter_init (&argc, &argv) != CLUTTER_INIT_SUCCESS)
return 1; return 1;
@ -69,7 +82,7 @@ int main (int argc, char **argv)
"y", 240.0, "y", 240.0,
NULL); NULL);
g_signal_connect (animation, "completed", g_signal_connect (animation, "completed",
G_CALLBACK (on_animation_completed), NULL); G_CALLBACK (on_animation_completed), stage);
text = g_object_new (CLUTTER_TYPE_TEXT, text = g_object_new (CLUTTER_TYPE_TEXT,
"text", "Blue", "text", "Blue",
@ -110,7 +123,5 @@ int main (int argc, char **argv)
clutter_main (); clutter_main ();
g_object_unref (stage);
return 0; return 0;
} }

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();

34
tests/interactive/test-title.js Executable file
View File

@ -0,0 +1,34 @@
#!/usr/bin/env gjs
const Gtk = imports.gi.Gtk;
const Mainloop = imports.mainloop;
function nextTitle() {
let length = Math.random() * 20;
let str = '';
for (let i = 0; i < length; i++) {
// 97 == 'a'
str += String.fromCharCode(97 + Math.random() * 26);
}
return str;
}
function main() {
Gtk.init(null);
let win = new Gtk.Window({ title: nextTitle() });
win.connect('destroy', Gtk.main_quit);
win.present();
Mainloop.timeout_add(5000, function() {
win.title = nextTitle();
return true;
});
Gtk.main();
}
main();