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
AC_MSG_RESULT(yes)
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)
else
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
polkit-agent-1 >= $POLKIT_MIN_VERSION xfixes
libnm-glib libnm-util gnome-keyring-1
gcr-3 >= $GCR_MIN_VERSION
gnome-desktop-3.0 >= $GNOME_DESKTOP_REQUIRED_VERSION)
gcr-3 >= $GCR_MIN_VERSION)
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_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_LIBS)

View File

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

View File

@ -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
value here is from the GsmPresenceStatus enumeration.</_summary>
</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="recorder" schema="org.gnome.shell.recorder"/>
<child name="keybindings" schema="org.gnome.shell.keybindings"/>

View File

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

View File

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

View File

@ -39,13 +39,14 @@ const GdmUtil = imports.gdm.util;
const Lightbox = imports.ui.lightbox;
const Main = imports.ui.main;
const ModalDialog = imports.ui.modalDialog;
const PanelMenu = imports.ui.panelMenu;
const Tweener = imports.ui.tweener;
const UserMenu = imports.ui.userMenu;
const _RESIZE_ANIMATION_TIME = 0.25;
const _SCROLL_ANIMATION_TIME = 0.5;
const _TIMED_LOGIN_IDLE_THRESHOLD = 5.0;
const _LOGO_ICON_NAME_SIZE = 48;
const _LOGO_ICON_HEIGHT = 16;
let _loginDialog = null;
@ -82,6 +83,36 @@ function _smoothlyResizeActor(actor, width, height) {
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({
Name: 'UserListItem',
@ -659,17 +690,11 @@ const LoginDialog = new Lang.Class({
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,
Lang.bind(this, this._updateBanner));
this._settings.connect('changed::' + GdmUtil.BANNER_MESSAGE_TEXT_KEY,
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',
text: '' });
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() {
let enabled = this._settings.get_boolean(GdmUtil.BANNER_MESSAGE_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,
new Batch.ConcurrentBatch(this, [this._fadeInTitleLabel,
this._fadeInNotListedButton,
this._fadeInLogo]),
this._fadeInNotListedButton]),
function() {
this._sessionList.close();
@ -829,9 +839,13 @@ const LoginDialog = new Lang.Class({
},
_showMessage: function(userVerifier, message, styleClass) {
this._promptMessage.text = message;
this._promptMessage.styleClass = styleClass;
GdmUtil.fadeInActor(this._promptMessage);
if (message) {
this._promptMessage.text = message;
this._promptMessage.styleClass = styleClass;
GdmUtil.fadeInActor(this._promptMessage);
} else {
GdmUtil.fadeOutActor(this._promptMessage);
}
},
_showLoginHint: function(verifier, message) {
@ -1089,8 +1103,7 @@ const LoginDialog = new Lang.Class({
},
new Batch.ConcurrentBatch(this, [this._fadeOutTitleLabel,
this._fadeOutNotListedButton,
this._fadeOutLogo]),
this._fadeOutNotListedButton]),
function() {
let hold = new Batch.Hold();
@ -1103,14 +1116,6 @@ const LoginDialog = new Lang.Class({
batch.run();
},
_fadeInLogo: function() {
return GdmUtil.fadeInActor(this._logoBox);
},
_fadeOutLogo: function() {
return GdmUtil.fadeOutActor(this._logoBox);
},
_fadeInBanner: function() {
return GdmUtil.fadeInActor(this._bannerLabel);
},
@ -1159,8 +1164,7 @@ const LoginDialog = new Lang.Class({
},
new Batch.ConcurrentBatch(this, [this._fadeOutTitleLabel,
this._fadeOutNotListedButton,
this._fadeOutLogo]),
this._fadeOutNotListedButton]),
function() {
return this._userList.shrinkToNaturalHeight();

View File

@ -125,6 +125,9 @@ const ShellUserVerifier = new Lang.Class({
},
answerQuery: function(serviceName, answer) {
// Clear any previous message
this.emit('show-message', null, 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
// go back to the welcome screen.
this._failCounter++;
let canRetry = retry && this._userName &&
this._failCounter < this._settings.get_int(ALLOWED_FAILURES_KEY);
if (canRetry) {
this._failCounter++;
this.clear();
this.begin(this._userName, new Batch.Hold());
} else {

View File

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

View File

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

View File

@ -270,8 +270,9 @@ const DBusEventSource = new Lang.Class({
this._loadEvents(false);
},
_onEventsReceived: function([appointments]) {
_onEventsReceived: function(results, error) {
let newEvents = [];
let appointments = results ? results[0] : null;
if (appointments != null) {
for (let n = 0; n < appointments.length; 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) {
this._shellDialog.close(global.get_current_time());
this._shellDialog.destroy();
@ -599,6 +602,16 @@ const NetworkAgent = new Lang.Class({
},
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();
},
@ -622,7 +635,7 @@ const NetworkAgent = new Lang.Class({
this._dialogs[requestId].destroy();
delete this._dialogs[requestId];
} else if (this._vpnRequests[requestId]) {
this._vpnRequests[requestId].cancel();
this._vpnRequests[requestId].cancel(false);
delete this._vpnRequests[requestId];
}
},

View File

@ -41,7 +41,7 @@ const Recorder = new Lang.Class({
recorder.set_framerate(this._recorderSettings.get_int('framerate'));
/* Translators: this is a filename used for screencast recording */
// 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');
if (!pipeline.match(/^\s*$/))

View File

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

View File

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

View File

@ -104,7 +104,7 @@ const LayoutManager = new Lang.Class({
this.primaryMonitor = null;
this.primaryIndex = -1;
this._hotCorners = [];
this._rootPixmap = null;
this._background = null;
this._leftPanelBarrier = 0;
this._rightPanelBarrier = 0;
this._trayBarrier = 0;
@ -333,30 +333,30 @@ const LayoutManager = new Lang.Class({
// to the greeter. Otherwise, we'll just animate the panel,
// as usual.
if (Main.sessionMode.isGreeter) {
this._rootPixmap = global.create_xrootpmap_texture();
if (this._rootPixmap != null) {
Main.uiGroup.add_actor(this._rootPixmap);
Tweener.addTween(this._rootPixmap,
this._background = Meta.BackgroundActor.new_for_screen(global.screen);
if (this._background != null) {
Main.uiGroup.add_actor(this._background);
Tweener.addTween(this._background,
{ opacity: 0,
time: PLYMOUTH_TRANSITION_TIME,
transition: 'linear',
onComplete: this._fadeRootpmapComplete,
onComplete: this._fadeBackgroundComplete,
onCompleteScope: this });
plymouthTransitionRunning = true;
}
}
if (!plymouthTransitionRunning)
this._fadeRootpmapComplete();
this._fadeBackgroundComplete();
},
_fadeRootpmapComplete: function() {
_fadeBackgroundComplete: function() {
// Don't animate the strut
this._chrome.freezeUpdateRegions();
if (this._rootPixmap != null) {
this._rootPixmap.destroy();
this._rootPixmap = null;
if (this._background != null) {
this._background.destroy();
this._background = null;
}
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._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',
vscrollbar_policy: source.isChat ? Gtk.PolicyType.NEVER : Gtk.PolicyType.AUTOMATIC,
hscrollbar_policy: Gtk.PolicyType.NEVER });
@ -1251,7 +1245,9 @@ const SummaryItem = new Lang.Class({
vertical: true });
this.notificationStackView.add_actor(this.notificationStack);
this.notificationStackWidget.add_actor(this.notificationStackView);
this.notificationStackWidget.add_actor(this._closeButton);
this.closeButton = makeCloseButton();
this.notificationStackWidget.add_actor(this.closeButton);
this._stackedNotifications = [];
this._oldMaxScrollAdjustment = 0;
@ -1268,14 +1264,6 @@ const SummaryItem = new Lang.Class({
global.focus_manager.add_group(this.rightClickMenu);
},
get closeButtonVisible() {
return this._closeButton.visible;
},
set closeButtonVisible(v) {
this._closeButton.visible = v;
},
_onKeyPress: function(actor, event) {
if (event.get_key_symbol() == Clutter.KEY_Up) {
actor.emit('clicked', 1);
@ -1510,7 +1498,7 @@ const MessageTray = new Lang.Class({
this._overviewVisible = true;
this._grabHelper.ungrab(); // drop modal grab if necessary
this.actor.add_style_pseudo_class('overview');
this._updateState();
this.show();
}));
Main.overview.connect('hiding', Lang.bind(this,
function() {
@ -1603,12 +1591,9 @@ const MessageTray = new Lang.Class({
_onCloseClicked: function() {
if (this._notificationState == State.SHOWN) {
this._closeButton.hide();
this._notificationClosed = true;
this._notification.emit('done-displaying');
if (!this._notification.resident)
this._notification.destroy();
this._updateState();
this._notificationClosed = false;
}
},
@ -1751,6 +1736,11 @@ const MessageTray = new Lang.Class({
this._updateState();
},
show: function() {
this._traySummoned = true;
this._updateState();
},
_onNotify: function(source, notification) {
if (this._summaryBoxPointerItem && this._summaryBoxPointerItem.source == source) {
if (this._summaryBoxPointerState == State.HIDING) {
@ -1993,7 +1983,7 @@ const MessageTray = new Lang.Class({
}
// Summary
let summarySummoned = this._pointerInSummary || this._overviewVisible || this._traySummoned;
let summarySummoned = this._pointerInSummary || this._traySummoned;
let summaryPinned = this._pointerInTray || summarySummoned || this._locked;
let summaryHovered = this._pointerInTray || this._pointerInSummary;
@ -2001,7 +1991,7 @@ const MessageTray = new Lang.Class({
this._notificationState == State.SHOWN);
let notificationsDone = !notificationsVisible && !notificationsPending;
let summaryOptionalInOverview = this._overviewVisible && !this._locked && !summaryHovered;
let summaryOptionalInOverview = !this._locked && !summaryHovered;
let mustHideSummary = (notificationsPending && (notificationUrgent || summaryOptionalInOverview))
|| notificationsVisible || !Main.sessionMode.hasNotifications;
@ -2101,9 +2091,8 @@ const MessageTray = new Lang.Class({
transition: 'easeOutQuad'
});
if (this._overviewVisible) {
if (!this._overviewVisible)
this._lightbox.show();
}
return true;
},
@ -2141,6 +2130,10 @@ const MessageTray = new Lang.Class({
},
_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,
{ y: 0,
time: ANIMATION_TIME,
@ -2420,7 +2413,10 @@ const MessageTray = new Lang.Class({
this._notificationQueue = newQueue;
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();
} else if (this._clickedSummaryItemMouseButton == 3) {
this._summaryBoxPointer.bin.child = this._clickedSummaryItem.rightClickMenu;
@ -2530,6 +2526,8 @@ const MessageTray = new Lang.Class({
this._summaryBoxPointer.bin.child = null;
this._summaryBoxPointerItem.disconnect(this._summaryBoxPointerContentUpdatedId);
this._summaryBoxPointerContentUpdatedId = 0;
this._summaryBoxPointerItem.closeButton.disconnect(this._summaryBoxPointerCloseClickedId);
this._summaryBoxPointerCloseClickedId = 0;
this._summaryBoxPointerItem.source.disconnect(this._sourceDoneDisplayingId);
this._summaryBoxPointerDoneDisplayingId = 0;

View File

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

View File

@ -15,6 +15,7 @@ const Signals = imports.signals;
const Atk = imports.gi.Atk;
const CenterLayout = imports.ui.centerLayout;
const Config = imports.misc.config;
const CtrlAltTab = imports.ui.ctrlAltTab;
const DND = imports.ui.dnd;
@ -247,6 +248,10 @@ const AppMenuButton = new Lang.Class({
this._container.connect('get-preferred-height', Lang.bind(this, this._getContentPreferredHeight));
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.connect('style-changed',
Lang.bind(this, this._onIconBoxStyleChanged));
@ -332,6 +337,15 @@ const AppMenuButton = new Lang.Class({
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() {
let allocation = this._iconBox.allocation;
if (this._iconBottomClip > 0)
@ -901,6 +915,7 @@ const PANEL_ITEM_IMPLEMENTATIONS = {
'volume': imports.ui.status.volume.Indicator,
'battery': imports.ui.status.power.Indicator,
'lockScreen': imports.ui.status.lockScreenMenu.Indicator,
'logo': imports.gdm.loginDialog.LogoMenuButton,
'keyboard': imports.ui.status.keyboard.InputSourceIndicator,
'powerMenu': imports.gdm.powerMenu.PowerMenuButton,
'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');
}
const PanelLayout = new Lang.Class({
Name: 'PanelLayout',
Extends: CenterLayout.CenterLayout,
vfunc_allocate: function(container, box, flags) {
this.parent(container, box, flags);
let availWidth = box.x2 - box.x1;
let availHeight = box.y2 - box.y1;
let [left, center, right, leftCorner, rightCorner] = container.get_children();
let childBox = new Clutter.ActorBox();
let cornerMinWidth, cornerMinHeight;
let cornerWidth, cornerHeight;
[cornerMinWidth, cornerWidth] = leftCorner.get_preferred_width(-1);
[cornerMinHeight, cornerHeight] = leftCorner.get_preferred_height(-1);
childBox.x1 = 0;
childBox.x2 = cornerWidth;
childBox.y1 = availHeight;
childBox.y2 = availHeight + cornerHeight;
leftCorner.allocate(childBox, flags);
[cornerMinWidth, cornerWidth] = rightCorner.get_preferred_width(-1);
[cornerMinHeight, cornerHeight] = rightCorner.get_preferred_height(-1);
childBox.x1 = availWidth - cornerWidth;
childBox.x2 = availWidth;
childBox.y1 = availHeight;
childBox.y2 = availHeight + cornerHeight;
rightCorner.allocate(childBox, flags);
}
});
const Panel = new Lang.Class({
Name: 'Panel',
_init : function() {
this.actor = new Shell.GenericContainer({ name: 'panel',
reactive: true });
this.actor = new St.Widget({ name: 'panel',
reactive: true,
layoutManager: new PanelLayout() });
this.actor._delegate = this;
this.statusArea = {};
@ -947,7 +997,6 @@ const Panel = new Lang.Class({
this._leftCorner = new PanelCorner(this._rightBox, St.Side.LEFT);
else
this._leftCorner = new PanelCorner(this._leftBox, St.Side.LEFT);
this.actor.add_actor(this._leftCorner.actor);
if (this.actor.get_text_direction() == Clutter.TextDirection.RTL)
@ -956,9 +1005,6 @@ const Panel = new Lang.Class({
this._rightCorner = new PanelCorner(this._rightBox, St.Side.RIGHT);
this.actor.add_actor(this._rightCorner.actor);
this.actor.connect('get-preferred-width', Lang.bind(this, this._getPreferredWidth));
this.actor.connect('get-preferred-height', Lang.bind(this, this._getPreferredHeight));
this.actor.connect('allocate', Lang.bind(this, this._allocate));
this.actor.connect('button-press-event', Lang.bind(this, this._onButtonPress));
Main.layoutManager.panelBox.add(this.actor);
@ -969,83 +1015,6 @@ const Panel = new Lang.Class({
this._updatePanel();
},
_getPreferredWidth: function(actor, forHeight, alloc) {
alloc.min_size = -1;
alloc.natural_size = Main.layoutManager.primaryMonitor.width;
},
_getPreferredHeight: function(actor, forWidth, alloc) {
// We don't need to implement this; it's forced by the CSS
alloc.min_size = -1;
alloc.natural_size = -1;
},
_allocate: function(actor, box, flags) {
let allocWidth = box.x2 - box.x1;
let allocHeight = box.y2 - box.y1;
let [leftMinWidth, leftNaturalWidth] = this._leftBox.get_preferred_width(-1);
let [centerMinWidth, centerNaturalWidth] = this._centerBox.get_preferred_width(-1);
let [rightMinWidth, rightNaturalWidth] = this._rightBox.get_preferred_width(-1);
let sideWidth, centerWidth;
centerWidth = centerNaturalWidth;
sideWidth = (allocWidth - centerWidth) / 2;
let childBox = new Clutter.ActorBox();
childBox.y1 = 0;
childBox.y2 = allocHeight;
if (this.actor.get_text_direction() == Clutter.TextDirection.RTL) {
childBox.x1 = allocWidth - Math.min(Math.floor(sideWidth),
leftNaturalWidth);
childBox.x2 = allocWidth;
} else {
childBox.x1 = 0;
childBox.x2 = Math.min(Math.floor(sideWidth),
leftNaturalWidth);
}
this._leftBox.allocate(childBox, flags);
childBox.x1 = Math.ceil(sideWidth);
childBox.y1 = 0;
childBox.x2 = childBox.x1 + centerWidth;
childBox.y2 = allocHeight;
this._centerBox.allocate(childBox, flags);
childBox.y1 = 0;
childBox.y2 = allocHeight;
if (this.actor.get_text_direction() == Clutter.TextDirection.RTL) {
childBox.x1 = 0;
childBox.x2 = Math.min(Math.floor(sideWidth),
rightNaturalWidth);
} else {
childBox.x1 = allocWidth - Math.min(Math.floor(sideWidth),
rightNaturalWidth);
childBox.x2 = allocWidth;
}
this._rightBox.allocate(childBox, flags);
let cornerMinWidth, cornerMinHeight;
let cornerWidth, cornerHeight;
[cornerMinWidth, cornerWidth] = this._leftCorner.actor.get_preferred_width(-1);
[cornerMinHeight, cornerHeight] = this._leftCorner.actor.get_preferred_height(-1);
childBox.x1 = 0;
childBox.x2 = cornerWidth;
childBox.y1 = allocHeight;
childBox.y2 = allocHeight + cornerHeight;
this._leftCorner.actor.allocate(childBox, flags);
[cornerMinWidth, cornerWidth] = this._rightCorner.actor.get_preferred_width(-1);
[cornerMinHeight, cornerHeight] = this._rightCorner.actor.get_preferred_height(-1);
childBox.x1 = allocWidth - cornerWidth;
childBox.x2 = allocWidth;
childBox.y1 = allocHeight;
childBox.y2 = allocHeight + cornerHeight;
this._rightCorner.actor.allocate(childBox, flags);
},
_onButtonPress: function(actor, event) {
if (event.get_source() != actor)
return false;

View File

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

View File

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

View File

@ -27,6 +27,9 @@ const SearchProviderIface = <interface name="org.gnome.Shell.SearchProvider">
<method name="ActivateResult">
<arg type="s" direction="in" />
</method>
<method name="LaunchSearch">
<arg type="as" direction="in" />
</method>
</interface>;
var SearchProviderProxy = Gio.DBusProxy.makeProxyWrapper(SearchProviderIface);
@ -112,6 +115,7 @@ const RemoteSearchProvider = new Lang.Class({
this.parent(title.toUpperCase());
this._cancellable = new Gio.Cancellable();
this.icon = icon;
},
createIcon: function(size, meta) {
@ -126,9 +130,7 @@ const RemoteSearchProvider = new Lang.Class({
width, height, rowStride, size);
}
// Ugh, but we want to fall back to something ...
return new St.Icon({ icon_name: 'text-x-generic',
icon_size: size });
return null;
},
_getResultsFinished: function(results, error) {
@ -196,6 +198,10 @@ const RemoteSearchProvider = new Lang.Class({
activateResult: function(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',
text: _("Please enter a command:") });
text: _("Enter a Command") });
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);
entry.label_actor = label;
@ -236,6 +237,10 @@ const RunDialog = new Lang.Class({
this._errorBox.hide();
this.setButtons([{ action: Lang.bind(this, this.close),
label: _("Close"),
key: Clutter.Escape }]);
this._pathCompleter = new Gio.FilenameCompleter();
this._commandCompleter = new CommandCompleter();
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();
if (symbol == Clutter.Return || symbol == Clutter.KP_Enter) {
this.popModal();
if (e.get_state() & Clutter.ModifierType.CONTROL_MASK)
this._run(o.get_text(), true);
else
this._run(o.get_text(), false);
if (!this._commandError)
this._run(o.get_text(),
e.get_state() & Clutter.ModifierType.CONTROL_MASK);
if (!this._commandError ||
!this.pushModal())
this.close();
else {
if (!this.pushModal())
this.close();
}
return true;
}
if (symbol == Clutter.Escape) {
this.close();
return true;
}
if (symbol == Clutter.slash) {

View File

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

View File

@ -163,6 +163,16 @@ const SearchProvider = new Lang.Class({
*/
activateResult: function(id) {
throw new Error('Not implemented');
},
/**
* launchSearch:
* @terms: Current search terms
*
* Called when the user clicks the provider icon.
*/
launchSearch: function(terms) {
throw new Error('Not implemented');
}
});
Signals.addSignalMethods(SearchProvider.prototype);
@ -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);

View File

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

View File

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

View File

@ -233,20 +233,11 @@ const NMWirelessSectionTitleMenuItem = new Lang.Class({
}
});
const NMDevice = new Lang.Class({
Name: 'NMDevice',
const NMConnectionBased = new Lang.Class({
Name: 'NMConnectionBased',
Abstract: true,
_init: function(client, device, 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;
_init: function(connections) {
this._connections = [ ];
for (let i = 0; i < connections.length; i++) {
if (!connections[i].get_uuid())
@ -264,26 +255,115 @@ const NMDevice = new Lang.Class({
this._connections.push(obj);
}
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._activeConnectionItem = null;
this._autoConnectionItem = null;
this._overflowItem = null;
if (this.device) {
this.statusItem = new PopupMenu.PopupSwitchMenuItem(this._getDescription(), this.connected, { style_class: 'popup-subtitle-menu-item' });
this._statusChanged = this.statusItem.connect('toggled', Lang.bind(this, function(item, state) {
let ok;
if (state)
ok = this.activate();
else
ok = this.deactivate();
this.statusItem = new PopupMenu.PopupSwitchMenuItem(this._getDescription(), this.connected, { style_class: 'popup-subtitle-menu-item' });
this._statusChanged = this.statusItem.connect('toggled', Lang.bind(this, function(item, state) {
let ok;
if (state)
ok = this.activate();
else
ok = this.deactivate();
if (!ok)
item.setToggleState(!state);
}));
if (!ok)
item.setToggleState(!state);
}));
this._updateStatusItem();
}
this._updateStatusItem();
this.section = new PopupMenu.PopupMenuSection();
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;
},
clearActiveConnection: function(activeConnection) {
this.setActiveConnection(null);
},
setActiveConnection: function(activeConnection) {
if (activeConnection == this._activeConnection)
// nothing to do
@ -369,80 +453,13 @@ const NMDevice = new Lang.Class({
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) {
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) {
// 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() {
@ -500,15 +517,6 @@ const NMDevice = new Lang.Class({
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() {
this._clearSection();
Main.queueDeferredWork(this._deferredWorkId);
@ -652,8 +660,6 @@ const NMDevice = new Lang.Class({
return out;
}
});
Signals.addSignalMethods(NMDevice.prototype);
const NMDeviceWired = new Lang.Class({
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({
Name: 'NMDeviceWireless',
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({
Name: 'NMApplet',
Extends: PanelMenu.SystemStatusButton,
@ -1622,15 +1684,9 @@ const NMApplet = new Lang.Class({
this.menu.addMenuItem(this._devices.wwan.section);
this.menu.addMenuItem(new PopupMenu.PopupSeparatorMenuItem());
this._devices.vpn = {
section: new PopupMenu.PopupMenuSection(),
device: this._makeWrapperDevice(NMDeviceVPN, null),
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._vpnSection = new NMVPNSection(this._client, this._connections);
this._vpnSection.connect('activation-failed', Lang.bind(this, this._onActivationFailed));
this.menu.addMenuItem(this._vpnSection.section);
this.menu.addMenuItem(new PopupMenu.PopupSeparatorMenuItem());
this.menu.addSettingsAction(_("Network Settings"), 'gnome-network-panel.desktop');
@ -1699,18 +1755,6 @@ const NMApplet = new Lang.Class({
},
_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 item = this._devices[category].item;
let section = this._devices[category].section;
@ -1758,17 +1802,20 @@ const NMApplet = new Lang.Class({
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) {
let wrapper = new wrapperClass(this._client, device, this._connections);
wrapper._activationFailedId = wrapper.connect('activation-failed', Lang.bind(this, 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);
}));
wrapper._activationFailedId = wrapper.connect('activation-failed',
Lang.bind(this, this._onActivationFailed));
wrapper._deviceStateChangedId = wrapper.connect('state-changed', Lang.bind(this, function(dev) {
this._syncSectionTitle(dev.category);
}));
@ -1851,7 +1898,7 @@ const NMApplet = new Lang.Class({
for (let i = 0; i < closedConnections.length; i++) {
let active = closedConnections[i];
if (active._primaryDevice) {
active._primaryDevice.setActiveConnection(null);
active._primaryDevice.clearActiveConnection(active);
active._primaryDevice = null;
}
if (active._inited) {
@ -1918,7 +1965,7 @@ const NMApplet = new Lang.Class({
}
}
} else
a._primaryDevice = this._devices.vpn.device
a._primaryDevice = this._vpnSection;
if (a._primaryDevice)
a._primaryDevice.setActiveConnection(a);
@ -2000,8 +2047,7 @@ const NMApplet = new Lang.Class({
let section = connection._section;
if (section == NMConnectionCategory.VPN) {
this._devices.vpn.device.removeConnection(connection);
this._syncSectionTitle(section);
this._vpnSection.removeConnection(connection);
} else if (section != NMConnectionCategory.INVALID) {
let devices = this._devices[section].devices;
for (let i = 0; i < devices.length; i++)
@ -2024,8 +2070,7 @@ const NMApplet = new Lang.Class({
if (section == NMConnectionCategory.INVALID)
return;
if (section == NMConnectionCategory.VPN) {
this._devices.vpn.device.checkConnection(connection);
this._syncSectionTitle(section);
this._vpnSection.checkConnection(connection);
} else {
let devices = this._devices[section].devices;
for (let i = 0; i < devices.length; i++) {
@ -2051,7 +2096,6 @@ const NMApplet = new Lang.Class({
this._syncSectionTitle(NMConnectionCategory.WIRED);
this._syncSectionTitle(NMConnectionCategory.WIRELESS);
this._syncSectionTitle(NMConnectionCategory.WWAN);
this._syncSectionTitle(NMConnectionCategory.VPN);
},
_syncNMState: function() {

View File

@ -208,9 +208,13 @@ const UnlockDialog = new Lang.Class({
},
_showMessage: function(userVerifier, message, styleClass) {
this._promptMessage.text = message;
this._promptMessage.styleClass = styleClass;
GdmUtil.fadeInActor(this._promptMessage);
if (message) {
this._promptMessage.text = message;
this._promptMessage.styleClass = styleClass;
GdmUtil.fadeInActor(this._promptMessage);
} else {
GdmUtil.fadeOutActor(this._promptMessage);
}
},
_onAskQuestion: function(verifier, serviceName, question, passwordChar) {
@ -278,6 +282,7 @@ const UnlockDialog = new Lang.Class({
this._currentQuery = null;
this._firstQuestion = true;
this._promptEntry.text = '';
this._promptEntry.clutter_text.set_password_char('\u25cf');
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_LOG_OUT_KEY = 'disable-log-out';
const LOCK_ENABLED_KEY = 'lock-enabled';
const ALWAYS_SHOW_LOG_OUT_KEY = 'always-show-log-out';
const DIALOG_ICON_SIZE = 64;
@ -187,7 +188,7 @@ const IMStatusChooserItem = new Lang.Class({
item = new IMStatusItem(_("Idle"), 'user-idle-symbolic');
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.connect('active-item-changed',
@ -616,10 +617,13 @@ const UserMenuButton = new Lang.Class({
_updateLogout: function() {
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 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() {

View File

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

View File

@ -159,6 +159,24 @@ const WindowClone = new Lang.Class({
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) {
this._stackAbove = actor;
if (this.inDrag || this._zooming)
@ -435,6 +453,11 @@ const WindowOverlay = new Lang.Class({
this._updateCaptionId = metaWindow.connect('notify::title',
Lang.bind(this, function(w) {
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' });
@ -501,6 +524,11 @@ const WindowOverlay = new Lang.Class({
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
* @cloneY: y position of windowClone
@ -538,9 +566,8 @@ const WindowOverlay = new Lang.Class({
else
button.set_position(Math.floor(buttonX), Math.floor(buttonY));
if (!title.fullWidth)
title.fullWidth = title.width;
let titleWidth = Math.min(title.fullWidth, cloneWidth);
let [titleMinWidth, titleNatWidth] = title.get_preferred_width(-1);
let titleWidth = Math.max(titleMinWidth, Math.min(titleNatWidth, cloneWidth));
let titleX = cloneX + (cloneWidth - titleWidth) / 2;
let titleY = cloneY + cloneHeight + title._spacing;
@ -1046,6 +1073,9 @@ const Workspace = new Lang.Class({
* ANIMATE - Indicates that we need animate changing position.
*/
positionWindows: function(flags) {
if (this.leavingOverview)
return;
this._positionWindowsFlags |= flags;
if (this._positionWindowsId > 0)

View File

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

View File

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

View File

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

View File

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

244
po/pl.po
View File

@ -11,8 +11,8 @@ msgid ""
msgstr ""
"Project-Id-Version: gnome-shell\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2012-09-25 15:12+0200\n"
"PO-Revision-Date: 2012-09-25 15:13+0200\n"
"POT-Creation-Date: 2012-10-31 19:12+0100\n"
"PO-Revision-Date: 2012-10-31 19:13+0100\n"
"Last-Translator: Piotr Drąg <piotrdrag@gmail.com>\n"
"Language-Team: Polish <gnomepl@aviary.pl>\n"
"Language: pl\n"
@ -142,62 +142,74 @@ msgstr ""
"użytkownika. Wartość pochodzi ze spisu GsmPresenceStatus."
#: ../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"
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."
msgstr ""
"Jeśli jest ustawione na \"true\", to wyświetla w kalendarzu dzień tygodnia w "
"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"
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."
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"
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."
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"
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."
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"
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."
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."
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 ""
"The framerate of the resulting screencast recordered by GNOME Shell's "
"screencast recorder in frames-per-second."
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"
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
msgid ""
"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 "
"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"
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 ""
"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 "
@ -252,11 +264,11 @@ msgstr ""
"Proszę wybrać rozszerzenie do skonfigurowania używając powyższego pola "
"wyboru."
#: ../js/gdm/loginDialog.js:528
#: ../js/gdm/loginDialog.js:529
msgid "Session..."
msgstr "Sesja..."
#: ../js/gdm/loginDialog.js:676
#: ../js/gdm/loginDialog.js:677
msgctxt "title"
msgid "Sign In"
msgstr "Proszę się zalogować"
@ -264,23 +276,23 @@ msgstr "Proszę się zalogować"
#. translators: this message is shown below the user list on the
#. login screen. It can be activated to reveal an entry for
#. manually entering the username.
#: ../js/gdm/loginDialog.js:743
#: ../js/gdm/loginDialog.js:736
msgid "Not listed?"
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/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"
msgstr "Anuluj"
#: ../js/gdm/loginDialog.js:901
#: ../js/gdm/loginDialog.js:894
msgctxt "button"
msgid "Sign In"
msgstr "Zaloguj"
#: ../js/gdm/loginDialog.js:1240
#: ../js/gdm/loginDialog.js:1215
msgid "Login Window"
msgstr "Okno logowania"
@ -289,8 +301,8 @@ msgstr "Okno logowania"
msgid "Power"
msgstr "Zasilanie"
#: ../js/gdm/powerMenu.js:89 ../js/ui/userMenu.js:663 ../js/ui/userMenu.js:667
#: ../js/ui/userMenu.js:778
#: ../js/gdm/powerMenu.js:89 ../js/ui/userMenu.js:664 ../js/ui/userMenu.js:668
#: ../js/ui/userMenu.js:779
msgid "Suspend"
msgstr "Uśpij"
@ -298,8 +310,8 @@ msgstr "Uśpij"
msgid "Restart"
msgstr "Uruchom ponownie"
#: ../js/gdm/powerMenu.js:99 ../js/ui/userMenu.js:665 ../js/ui/userMenu.js:667
#: ../js/ui/userMenu.js:777
#: ../js/gdm/powerMenu.js:99 ../js/ui/userMenu.js:666 ../js/ui/userMenu.js:668
#: ../js/ui/userMenu.js:778
msgid "Power Off"
msgstr "Wyłącz komputer"
@ -350,7 +362,7 @@ msgstr "Ustawienia"
msgid "New Window"
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"
msgstr "Usuń z ulubionych"
@ -514,16 +526,16 @@ msgstr "Ten tydzień"
msgid "Next week"
msgstr "Następny tydzień"
#: ../js/ui/components/autorunManager.js:278
#: ../js/ui/components/autorunManager.js:297
msgid "Removable Devices"
msgstr "Urządzenia wymienne"
#: ../js/ui/components/autorunManager.js:575
#: ../js/ui/components/autorunManager.js:594
#, c-format
msgid "Open with %s"
msgstr "Otwórz za pomocą %s"
#: ../js/ui/components/autorunManager.js:601
#: ../js/ui/components/autorunManager.js:620
msgid "Eject"
msgstr "Wysuń"
@ -680,35 +692,35 @@ msgstr "Wycisz"
#. Translators: this is a time format string followed by a date.
#. If applicable, replace %X with a strftime format valid for your
#. locale, without seconds.
#: ../js/ui/components/telepathyClient.js:948
#: ../js/ui/components/telepathyClient.js:950
#, no-c-format
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>"
#. Translators: this is a time format in the style of "Wednesday, May 25",
#. shown when you get a chat message in the same year.
#: ../js/ui/components/telepathyClient.js:954
#: ../js/ui/components/telepathyClient.js:956
#, no-c-format
msgid "Sent on <b>%A</b>, <b>%B %d</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",
#. 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
msgid "Sent on <b>%A</b>, <b>%B %d</b>, %Y"
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
#. IM name.
#: ../js/ui/components/telepathyClient.js:988
#: ../js/ui/components/telepathyClient.js:990
#, c-format
msgid "%s is now known as %s"
msgstr "Użytkownik %s jest teraz znany jako %s"
#. translators: argument is a room name like
#. * room@jabber.org for example.
#: ../js/ui/components/telepathyClient.js:1088
#: ../js/ui/components/telepathyClient.js:1090
#, c-format
msgid "Invitation to %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
#. * one the name of a room. "Alice is inviting you to join room@jabber.org
#. * for example.
#: ../js/ui/components/telepathyClient.js:1096
#: ../js/ui/components/telepathyClient.js:1098
#, c-format
msgid "%s is inviting you to join %s"
msgstr "Użytkownik %s zaprasza do dołączenia do pokoju %s"
#: ../js/ui/components/telepathyClient.js:1098
#: ../js/ui/components/telepathyClient.js:1177
#: ../js/ui/components/telepathyClient.js:1240
#: ../js/ui/components/telepathyClient.js:1100
#: ../js/ui/components/telepathyClient.js:1179
#: ../js/ui/components/telepathyClient.js:1242
msgid "Decline"
msgstr "Odmów"
#: ../js/ui/components/telepathyClient.js:1099
#: ../js/ui/components/telepathyClient.js:1178
#: ../js/ui/components/telepathyClient.js:1241
#: ../js/ui/components/telepathyClient.js:1101
#: ../js/ui/components/telepathyClient.js:1180
#: ../js/ui/components/telepathyClient.js:1243
msgid "Accept"
msgstr "Zaakceptuj"
#. translators: argument is a contact name like Alice for example.
#: ../js/ui/components/telepathyClient.js:1129
#: ../js/ui/components/telepathyClient.js:1131
#, c-format
msgid "Video call from %s"
msgstr "Wideorozmowa z użytkownikiem %s"
#. translators: argument is a contact name like Alice for example.
#: ../js/ui/components/telepathyClient.js:1132
#: ../js/ui/components/telepathyClient.js:1134
#, c-format
msgid "Call from %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
msgid "Reject"
msgstr "Odrzuć"
#. translators: this is a button label (verb), not a noun
#: ../js/ui/components/telepathyClient.js:1139
#: ../js/ui/components/telepathyClient.js:1141
msgid "Answer"
msgstr "Odbierz"
@ -760,111 +772,111 @@ msgstr "Odbierz"
#. * file name. The string will be something
#. * like: "Alice is sending you test.ogg"
#.
#: ../js/ui/components/telepathyClient.js:1171
#: ../js/ui/components/telepathyClient.js:1173
#, c-format
msgid "%s is sending you %s"
msgstr "Użytkownik %s przysyła plik %s"
#. To translators: The parameter is the contact's alias
#: ../js/ui/components/telepathyClient.js:1206
#: ../js/ui/components/telepathyClient.js:1208
#, c-format
msgid "%s would like permission to see when you are online"
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"
msgstr "Błąd sieci"
#: ../js/ui/components/telepathyClient.js:1300
#: ../js/ui/components/telepathyClient.js:1302
msgid "Authentication failed"
msgstr "Uwierzytelnienie się nie powiodło"
#: ../js/ui/components/telepathyClient.js:1302
#: ../js/ui/components/telepathyClient.js:1304
msgid "Encryption error"
msgstr "Błąd szyfrowania"
#: ../js/ui/components/telepathyClient.js:1304
#: ../js/ui/components/telepathyClient.js:1306
msgid "Certificate not provided"
msgstr "Nie podano certyfikatu"
#: ../js/ui/components/telepathyClient.js:1306
#: ../js/ui/components/telepathyClient.js:1308
msgid "Certificate untrusted"
msgstr "Certyfikat jest niezaufany"
#: ../js/ui/components/telepathyClient.js:1308
#: ../js/ui/components/telepathyClient.js:1310
msgid "Certificate expired"
msgstr "Certyfikat wygasł"
#: ../js/ui/components/telepathyClient.js:1310
#: ../js/ui/components/telepathyClient.js:1312
msgid "Certificate not activated"
msgstr "Certyfikat nie został aktywowany"
#: ../js/ui/components/telepathyClient.js:1312
#: ../js/ui/components/telepathyClient.js:1314
msgid "Certificate hostname mismatch"
msgstr "Nazwa komputera certyfikatu się nie zgadza"
#: ../js/ui/components/telepathyClient.js:1314
#: ../js/ui/components/telepathyClient.js:1316
msgid "Certificate fingerprint mismatch"
msgstr "Odcisk palca certyfikatu się nie zgadza"
#: ../js/ui/components/telepathyClient.js:1316
#: ../js/ui/components/telepathyClient.js:1318
msgid "Certificate self-signed"
msgstr "Certyfikat został samodzielnie podpisany"
#: ../js/ui/components/telepathyClient.js:1318
#: ../js/ui/components/telepathyClient.js:1320
msgid "Status is set to offline"
msgstr "Stan jest ustawiony na offline"
#: ../js/ui/components/telepathyClient.js:1320
#: ../js/ui/components/telepathyClient.js:1322
msgid "Encryption is not available"
msgstr "Szyfrowanie jest niedostępne"
#: ../js/ui/components/telepathyClient.js:1322
#: ../js/ui/components/telepathyClient.js:1324
msgid "Certificate is invalid"
msgstr "Certyfikat jest nieprawidłowy"
#: ../js/ui/components/telepathyClient.js:1324
#: ../js/ui/components/telepathyClient.js:1326
msgid "Connection has been refused"
msgstr "Odrzucono połączenie"
#: ../js/ui/components/telepathyClient.js:1326
#: ../js/ui/components/telepathyClient.js:1328
msgid "Connection can't be established"
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"
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"
msgstr "To konto jest już połączone z serwerem"
#: ../js/ui/components/telepathyClient.js:1332
#: ../js/ui/components/telepathyClient.js:1334
msgid ""
"Connection has been replaced by a new connection using the same resource"
msgstr ""
"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"
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"
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"
msgstr "Certyfikat został unieważniony"
#: ../js/ui/components/telepathyClient.js:1340
#: ../js/ui/components/telepathyClient.js:1342
msgid ""
"Certificate uses an insecure cipher algorithm or is cryptographically weak"
msgstr ""
"Certyfikat używa niezabezpieczonego algorytmu szyfrowania lub jest "
"kryptograficznie słaby"
#: ../js/ui/components/telepathyClient.js:1342
#: ../js/ui/components/telepathyClient.js:1344
msgid ""
"The length of the server certificate, or the depth of the server certificate "
"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 "
"ograniczenia nałożone przez bibliotekę kryptograficzną"
#: ../js/ui/components/telepathyClient.js:1344
#: ../js/ui/components/telepathyClient.js:1346
msgid "Internal error"
msgstr "Błąd wewnętrzny"
#. translators: argument is the account name, like
#. * name@jabber.org for example.
#: ../js/ui/components/telepathyClient.js:1354
#: ../js/ui/components/telepathyClient.js:1356
#, c-format
msgid "Connection to %s failed"
msgstr "Połączenie z kontem %s się nie powiodło"
#: ../js/ui/components/telepathyClient.js:1363
#: ../js/ui/components/telepathyClient.js:1365
msgid "Reconnect"
msgstr "Połącz ponownie"
#: ../js/ui/components/telepathyClient.js:1364
#: ../js/ui/components/telepathyClient.js:1366
msgid "Edit account"
msgstr "Modyfikuj konto"
#: ../js/ui/components/telepathyClient.js:1409
#: ../js/ui/components/telepathyClient.js:1411
msgid "Unknown reason"
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"
msgstr "Wyświetl programy"
@ -903,14 +915,14 @@ msgstr "Wyświetl programy"
msgid "Date and Time Settings"
msgstr "Ustawienia daty i czasu"
#: ../js/ui/dateMenu.js:109
#: ../js/ui/dateMenu.js:111
msgid "Open Calendar"
msgstr "Otwórz kalendarz"
#. Translators: This is the date format to use when the calendar popup is
#. * shown - it is shown just below the time in the shell (e.g. "Tue 9:29 AM").
#.
#: ../js/ui/dateMenu.js:175
#: ../js/ui/dateMenu.js:201
msgid "%A %B %e, %Y"
msgstr "%A, %e %B %Y"
@ -1075,23 +1087,23 @@ msgstr "Wyświetl źródło"
msgid "Web Page"
msgstr "Strona WWW"
#: ../js/ui/messageTray.js:1081
#: ../js/ui/messageTray.js:1084
msgid "Open"
msgstr "Otwórz"
#: ../js/ui/messageTray.js:1088
#: ../js/ui/messageTray.js:1091
msgid "Remove"
msgstr "Usuń"
#: ../js/ui/messageTray.js:2088
#: ../js/ui/messageTray.js:1543
msgid "Message Tray"
msgstr "Obszar powiadamiania"
#: ../js/ui/messageTray.js:2551
#: ../js/ui/messageTray.js:2549
msgid "System Information"
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"
msgid "Unknown"
msgstr "Nieznany"
@ -1147,7 +1159,7 @@ msgstr "Proszę wprowadzić polecenie:"
#. Translators: This is a time format for a date in
#. long format
#: ../js/ui/screenShield.js:79
#: ../js/ui/screenShield.js:80
msgid "%A, %B %d"
msgstr "%A, %e %B"
@ -1199,7 +1211,7 @@ msgstr "Hasło"
msgid "Remember Password"
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"
msgstr "Odblokuj"
@ -1614,67 +1626,63 @@ msgstr "Głośność"
msgid "Microphone"
msgstr "Mikrofon"
#: ../js/ui/unlockDialog.js:176
#: ../js/ui/unlockDialog.js:177
msgid "Log in as another user"
msgstr "Zaloguj jako inny użytkownik"
#: ../js/ui/userMenu.js:180
#: ../js/ui/userMenu.js:181
msgid "Available"
msgstr "Dostępny"
#: ../js/ui/userMenu.js:183
#: ../js/ui/userMenu.js:184
msgid "Busy"
msgstr "Zajęty"
#: ../js/ui/userMenu.js:186
#: ../js/ui/userMenu.js:187
msgid "Invisible"
msgstr "Niewidoczny"
#: ../js/ui/userMenu.js:189
#: ../js/ui/userMenu.js:190
msgid "Away"
msgstr "Nieobecny"
#: ../js/ui/userMenu.js:192
#: ../js/ui/userMenu.js:193
msgid "Idle"
msgstr "Bezczynny"
#: ../js/ui/userMenu.js:195
#: ../js/ui/userMenu.js:196
msgid "Unavailable"
msgstr "Niedostępny"
#: ../js/ui/userMenu.js:618 ../js/ui/userMenu.js:759
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
#: ../js/ui/userMenu.js:744
msgid "Notifications"
msgstr "Powiadomienia"
#: ../js/ui/userMenu.js:751
#: ../js/ui/userMenu.js:752
msgid "System Settings"
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"
msgstr "Wyloguj się"
#: ../js/ui/userMenu.js:769
#: ../js/ui/userMenu.js:770
msgid "Lock"
msgstr "Zablokuj ekran"
#: ../js/ui/userMenu.js:784
#: ../js/ui/userMenu.js:785
msgid "Install Updates & Restart"
msgstr "Zaktualizuj i uruchom ponownie"
#: ../js/ui/userMenu.js:802
#: ../js/ui/userMenu.js:803
msgid "Your chat status will be set to busy"
msgstr "Stan komunikatora zostanie ustawiony na \"zajęty\""
#: ../js/ui/userMenu.js:803
#: ../js/ui/userMenu.js:804
msgid ""
"Notifications are now disabled, including chat messages. Your online status "
"has been adjusted to let others know that you might not see their messages."
@ -1696,7 +1704,7 @@ msgstr "Programy"
msgid "Search"
msgstr "Wyszukiwanie"
#: ../js/ui/wanda.js:119
#: ../js/ui/wanda.js:117
#, c-format
msgid ""
"Sorry, no wisdom for you today:\n"
@ -1705,12 +1713,12 @@ msgstr ""
"Nic mądrego na dzisiaj:\n"
"%s"
#: ../js/ui/wanda.js:123
#: ../js/ui/wanda.js:121
#, c-format
msgid "%s the Oracle says"
msgstr "Wyrocznia %s przemawia"
#: ../js/ui/wanda.js:164
#: ../js/ui/wanda.js:162
msgid "Your favorite Easter Egg"
msgstr "Twój ulubiony żart"
@ -1747,23 +1755,23 @@ msgstr[2] "%u wejść"
msgid "System Sounds"
msgstr "Dźwięki systemowe"
#: ../src/main.c:330
#: ../src/main.c:332
msgid "Print version"
msgstr "Wyświetla wersję"
#: ../src/main.c:336
#: ../src/main.c:338
msgid "Mode used by GDM for login screen"
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"
msgstr "Używa podanego trybu, np. \"gdm\" dla ekranu logowania"
#: ../src/main.c:348
#: ../src/main.c:350
msgid "List possible modes"
msgstr "Wyświetla listę możliwych trybów"
#: ../src/shell-app.c:621
#: ../src/shell-app.c:622
#, c-format
msgid "Failed to launch '%s'"
msgstr "Uruchomienie \"%s\" się nie powiodło"

296
po/sk.po
View File

@ -10,8 +10,8 @@ msgstr ""
"Project-Id-Version: gnome-shell\n"
"Report-Msgid-Bugs-To: http://bugzilla.gnome.org/enter_bug.cgi?product=gnome-"
"shell&keywords=I18N+L10N&component=general\n"
"POT-Creation-Date: 2012-10-18 16:51+0000\n"
"PO-Revision-Date: 2012-10-13 22:35+0100\n"
"POT-Creation-Date: 2012-10-27 16:22+0000\n"
"PO-Revision-Date: 2012-10-28 19:49+0000\n"
"Last-Translator: Dušan Kazik <prescott66@gmail.com>\n"
"Language-Team: Slovak <gnome-sk-list@gnome.org>\n"
"Language: sk\n"
@ -25,8 +25,6 @@ msgstr ""
msgid "Screenshots"
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
msgid "Record a screencast"
msgstr "Zaznamenať dianie na obrazovke"
@ -37,20 +35,16 @@ msgstr "Systém"
#: ../data/50-gnome-shell-system.xml.in.h:2
msgid "Show the message tray"
msgstr "Zobraz lištu správ"
msgstr "Zobrazí lištu správ"
# tooltip
#: ../data/50-gnome-shell-system.xml.in.h:3
#, fuzzy
#| msgid "Show Applications"
msgid "Show all applications"
msgstr "Zobrazí aplikácie"
msgstr "Zobrazí všetky aplikácie"
#: ../data/50-gnome-shell-system.xml.in.h:4
#, fuzzy
#| msgid "Keybinding to 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
msgid "GNOME Shell"
@ -85,13 +79,9 @@ msgstr ""
#: ../data/org.gnome.shell.gschema.xml.in.in.h:3
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
#, fuzzy
msgid ""
"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 "
@ -101,7 +91,7 @@ msgstr ""
"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é "
"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
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í."
#: ../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"
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
#, fuzzy
#| msgid "Keybinding to open the application menu."
msgid ""
"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
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
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
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 "
"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
#, c-format
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."
msgstr "Použitím ponuky vyberte rozšírenie na nastavenie"
#: ../js/gdm/loginDialog.js:529
#: ../js/gdm/loginDialog.js:560
msgid "Session..."
msgstr "Relácia..."
#: ../js/gdm/loginDialog.js:677
#: ../js/gdm/loginDialog.js:704
msgctxt "title"
msgid "Sign In"
msgstr "Prihlásenie"
@ -299,42 +320,42 @@ msgstr "Prihlásenie"
#. translators: this message is shown below the user list on the
#. login screen. It can be activated to reveal an entry for
#. manually entering the username.
#: ../js/gdm/loginDialog.js:736
#: ../js/gdm/loginDialog.js:763
msgid "Not listed?"
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/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"
msgstr "Zrušiť"
#: ../js/gdm/loginDialog.js:894
#: ../js/gdm/loginDialog.js:906
msgctxt "button"
msgid "Sign In"
msgstr "Prihlásiť sa"
#: ../js/gdm/loginDialog.js:1215
#: ../js/gdm/loginDialog.js:1217
msgid "Login Window"
msgstr "Prihlasovacie okno"
#. Translators: accessible name of the power menu in the login screen
#: ../js/gdm/powerMenu.js:37
#: ../js/gdm/powerMenu.js:36
msgid "Power"
msgstr "Napájanie"
#: ../js/gdm/powerMenu.js:95 ../js/ui/userMenu.js:655 ../js/ui/userMenu.js:659
#: ../js/ui/userMenu.js:770
#: ../js/gdm/powerMenu.js:93 ../js/ui/userMenu.js:663 ../js/ui/userMenu.js:667
#: ../js/ui/userMenu.js:778
msgid "Suspend"
msgstr "Uspať"
#: ../js/gdm/powerMenu.js:100
#: ../js/gdm/powerMenu.js:98
msgid "Restart"
msgstr "Reštartovať"
#: ../js/gdm/powerMenu.js:105 ../js/ui/userMenu.js:657
#: ../js/ui/userMenu.js:659 ../js/ui/userMenu.js:769
#: ../js/gdm/powerMenu.js:103 ../js/ui/userMenu.js:665
#: ../js/ui/userMenu.js:667 ../js/ui/userMenu.js:777
msgid "Power Off"
msgstr "Vypnúť"
@ -517,35 +538,35 @@ msgid "S"
msgstr "So"
#. Translators: Text to show if there are no events
#: ../js/ui/calendar.js:699
#: ../js/ui/calendar.js:700
msgid "Nothing Scheduled"
msgstr "Žiadne naplánované udalosti"
#. 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"
msgid "%A, %B %d"
msgstr "%A, %e. %B"
#. 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"
msgid "%A, %B %d, %Y"
msgstr "%A, %e. %B %Y"
#: ../js/ui/calendar.js:728
#: ../js/ui/calendar.js:729
msgid "Today"
msgstr "Dnes"
#: ../js/ui/calendar.js:732
#: ../js/ui/calendar.js:733
msgid "Tomorrow"
msgstr "Zajtra"
#: ../js/ui/calendar.js:743
#: ../js/ui/calendar.js:744
msgid "This week"
msgstr "Tento týždeň"
#: ../js/ui/calendar.js:751
#: ../js/ui/calendar.js:752
msgid "Next week"
msgstr "Ďalší týždeň"
@ -553,10 +574,11 @@ msgstr "Ďalší týždeň"
msgid "Removable Devices"
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
#, c-format
msgid "Open with %s"
msgstr "Otvoriť pomocou %s"
msgstr "Otvoriť pomocou programu %s"
#: ../js/ui/components/autorunManager.js:617
msgid "Eject"
@ -623,7 +645,7 @@ msgstr ""
#: ../js/ui/components/networkAgent.js:314
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
msgid "Network name: "
@ -631,7 +653,7 @@ msgstr "Názov siete: "
#: ../js/ui/components/networkAgent.js:321
msgid "DSL authentication"
msgstr "Overenie totožnosti DSL"
msgstr "Overenie totožnosti k DSL"
#: ../js/ui/components/networkAgent.js:328
msgid "PIN code required"
@ -639,7 +661,7 @@ msgstr "Požaduje sa kód PIN"
#: ../js/ui/components/networkAgent.js:329
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
msgid "PIN: "
@ -647,7 +669,7 @@ msgstr "PIN: "
#: ../js/ui/components/networkAgent.js:336
msgid "Mobile broadband network password"
msgstr "Heslo pre mobilnú sieť"
msgstr "Heslo k mobilnej sieti"
#: ../js/ui/components/networkAgent.js:337
#, c-format
@ -675,11 +697,12 @@ msgstr "Overiť totožnosť"
msgid "Sorry, that didn't work. Please try again."
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
#: ../js/ui/components/recorder.js:44
#, no-c-format
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
#. system-users for now as Empathy does.
@ -714,44 +737,42 @@ msgid "Mute"
msgstr "Stlmiť"
#. 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
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
#: ../js/ui/components/telepathyClient.js:947
#, fuzzy, no-c-format
#| msgid "Sent at <b>%X</b> on <b>%A</b>"
#: ../js/ui/components/telepathyClient.js:949
#, no-c-format
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",
#. shown when you get a chat message in the same year
#: ../js/ui/components/telepathyClient.js:953
#, fuzzy, no-c-format
#| msgid "Sent on <b>%A</b>, <b>%B %d</b>"
#: ../js/ui/components/telepathyClient.js:955
#, no-c-format
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",
#. shown when you get a chat message in a different year
#: ../js/ui/components/telepathyClient.js:958
#, fuzzy, no-c-format
#| msgid "Sent on <b>%A</b>, <b>%B %d</b>, %Y"
#: ../js/ui/components/telepathyClient.js:960
#, no-c-format
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
#. IM name.
#: ../js/ui/components/telepathyClient.js:986
#: ../js/ui/components/telepathyClient.js:988
#, c-format
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
#. * room@jabber.org for example.
#: ../js/ui/components/telepathyClient.js:1085
#: ../js/ui/components/telepathyClient.js:1087
#, c-format
msgid "Invitation to %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
#. * one the name of a room. "Alice is inviting you to join room@jabber.org
#. * for example.
#: ../js/ui/components/telepathyClient.js:1093
#: ../js/ui/components/telepathyClient.js:1095
#, c-format
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:1174
#: ../js/ui/components/telepathyClient.js:1237
#: ../js/ui/components/telepathyClient.js:1097
#: ../js/ui/components/telepathyClient.js:1176
#: ../js/ui/components/telepathyClient.js:1239
msgid "Decline"
msgstr "Odmietnuť"
#: ../js/ui/components/telepathyClient.js:1096
#: ../js/ui/components/telepathyClient.js:1175
#: ../js/ui/components/telepathyClient.js:1238
#: ../js/ui/components/telepathyClient.js:1098
#: ../js/ui/components/telepathyClient.js:1177
#: ../js/ui/components/telepathyClient.js:1240
msgid "Accept"
msgstr "Prijať"
#. translators: argument is a contact name like Alice for example.
#: ../js/ui/components/telepathyClient.js:1126
#: ../js/ui/components/telepathyClient.js:1128
#, c-format
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.
#: ../js/ui/components/telepathyClient.js:1129
#: ../js/ui/components/telepathyClient.js:1131
#, c-format
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
msgid "Reject"
msgstr "Odmietnuť"
#. translators: this is a button label (verb), not a noun
#: ../js/ui/components/telepathyClient.js:1136
#: ../js/ui/components/telepathyClient.js:1138
msgid "Answer"
msgstr "Prijať hovor"
@ -803,110 +824,111 @@ msgstr "Prijať hovor"
#. * file name. The string will be something
#. * like: "Alice is sending you test.ogg"
#.
#: ../js/ui/components/telepathyClient.js:1168
#: ../js/ui/components/telepathyClient.js:1170
#, c-format
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
#: ../js/ui/components/telepathyClient.js:1203
#: ../js/ui/components/telepathyClient.js:1205
#, c-format
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"
msgstr "Chyba siete"
#: ../js/ui/components/telepathyClient.js:1297
#: ../js/ui/components/telepathyClient.js:1299
msgid "Authentication failed"
msgstr "Overenie totožnosti zlyhalo"
#: ../js/ui/components/telepathyClient.js:1299
#: ../js/ui/components/telepathyClient.js:1301
msgid "Encryption error"
msgstr "Chyba šifrovania"
#: ../js/ui/components/telepathyClient.js:1301
#: ../js/ui/components/telepathyClient.js:1303
msgid "Certificate not provided"
msgstr "Neposkytnutý certifikát"
#: ../js/ui/components/telepathyClient.js:1303
#: ../js/ui/components/telepathyClient.js:1305
msgid "Certificate untrusted"
msgstr "Nedôveryhodný certifikát"
#: ../js/ui/components/telepathyClient.js:1305
#: ../js/ui/components/telepathyClient.js:1307
msgid "Certificate expired"
msgstr "Certifikát s ukončenou platnosťou"
#: ../js/ui/components/telepathyClient.js:1307
#: ../js/ui/components/telepathyClient.js:1309
msgid "Certificate not activated"
msgstr "Neaktivovaný certifikát"
#: ../js/ui/components/telepathyClient.js:1309
#: ../js/ui/components/telepathyClient.js:1311
msgid "Certificate hostname mismatch"
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"
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"
msgstr "Sebou podpísaný certifikát"
#: ../js/ui/components/telepathyClient.js:1315
#: ../js/ui/components/telepathyClient.js:1317
msgid "Status is set to offline"
msgstr "Stav je nastavený na odhlásený"
#: ../js/ui/components/telepathyClient.js:1317
#: ../js/ui/components/telepathyClient.js:1319
msgid "Encryption is not available"
msgstr "Šifrovanie nie je dostupné"
#: ../js/ui/components/telepathyClient.js:1319
#: ../js/ui/components/telepathyClient.js:1321
msgid "Certificate is invalid"
msgstr "Certifikát je neplatný"
#: ../js/ui/components/telepathyClient.js:1321
#: ../js/ui/components/telepathyClient.js:1323
msgid "Connection has been refused"
msgstr "Pripojenie bolo odmietnuté"
#: ../js/ui/components/telepathyClient.js:1323
#: ../js/ui/components/telepathyClient.js:1325
msgid "Connection can't be established"
msgstr "Nedá sa nadviazať spojenie"
#: ../js/ui/components/telepathyClient.js:1325
#: ../js/ui/components/telepathyClient.js:1327
msgid "Connection has been lost"
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"
msgstr "Tento účet je už pripojený k serveru"
#: ../js/ui/components/telepathyClient.js:1329
#: ../js/ui/components/telepathyClient.js:1331
msgid ""
"Connection has been replaced by a new connection using the same resource"
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"
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"
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"
msgstr "Certifikát bol zrušený"
#: ../js/ui/components/telepathyClient.js:1337
#: ../js/ui/components/telepathyClient.js:1339
msgid ""
"Certificate uses an insecure cipher algorithm or is cryptographically weak"
msgstr ""
"Šifrovací algoritmus používaný certifikátom nie je bezpečný alebo je "
"kryptograficky slabý"
#: ../js/ui/components/telepathyClient.js:1339
#: ../js/ui/components/telepathyClient.js:1341
msgid ""
"The length of the server certificate, or the depth of the server certificate "
"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 "
"limit stanovený kryptografickou knižnicou."
#: ../js/ui/components/telepathyClient.js:1341
#: ../js/ui/components/telepathyClient.js:1343
msgid "Internal error"
msgstr "Vnútorná chyba"
#. translators: argument is the account name, like
#. * name@jabber.org for example.
#: ../js/ui/components/telepathyClient.js:1351
#: ../js/ui/components/telepathyClient.js:1353
#, c-format
msgid "Connection to %s failed"
msgstr "Pripojenie k %s zlyhalo"
#: ../js/ui/components/telepathyClient.js:1360
#: ../js/ui/components/telepathyClient.js:1362
msgid "Reconnect"
msgstr "Znovu sa pripojiť"
#: ../js/ui/components/telepathyClient.js:1361
#: ../js/ui/components/telepathyClient.js:1363
msgid "Edit account"
msgstr "Upraviť účet"
#: ../js/ui/components/telepathyClient.js:1406
#: ../js/ui/components/telepathyClient.js:1408
msgid "Unknown reason"
msgstr "Neznámy dôvod"
@ -992,7 +1014,7 @@ msgstr[2] "Budete automaticky odhlásený o %d sekundy."
#: ../js/ui/endSessionDialog.js:74
msgid "Logging out of the system."
msgstr "Odhlasuje sa zo systému."
msgstr "Prebieha odhlásenie zo systému."
#: ../js/ui/endSessionDialog.js:76
msgctxt "button"
@ -1120,21 +1142,21 @@ msgstr "Zobraziť zdroj"
msgid "Web Page"
msgstr "Webová stránka"
#: ../js/ui/messageTray.js:1082
#: ../js/ui/messageTray.js:1083
msgid "Open"
msgstr "Otvoriť"
#: ../js/ui/messageTray.js:1089
#: ../js/ui/messageTray.js:1090
msgid "Remove"
msgstr "Odstrániť"
# DK: zvazoval som pouzit "Panel správ"
# neviem co bude vhodnejsie ako preklad "tray"
#: ../js/ui/messageTray.js:1545
#: ../js/ui/messageTray.js:1534
msgid "Message Tray"
msgstr "Lišta správ"
#: ../js/ui/messageTray.js:2552
#: ../js/ui/messageTray.js:2557
msgid "System Information"
msgstr "Informácie o systéme"
@ -1175,7 +1197,7 @@ msgstr "Ukončiť"
msgid "Activities"
msgstr "Aktivity"
#: ../js/ui/panel.js:965
#: ../js/ui/panel.js:966
msgid "Top Bar"
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
#. Translators: This is a time format for a date in
#. long format
#: ../js/ui/screenShield.js:79
#: ../js/ui/screenShield.js:80
msgid "%A, %B %d"
msgstr "%A, %e. %B"
#: ../js/ui/screenShield.js:143
#: ../js/ui/screenShield.js:144
#, c-format
msgid "%d new message"
msgid_plural "%d new messages"
@ -1209,13 +1231,13 @@ msgstr[0] "%d nových správ"
msgstr[1] "%d nová správa"
msgstr[2] "%d nové správy"
#: ../js/ui/screenShield.js:145
#: ../js/ui/screenShield.js:146
#, c-format
msgid "%d new notification"
msgid_plural "%d new notifications"
msgstr[0] "%d nových upozornení"
msgstr[1] "%d nové upozornenie"
msgstr[2] "%d nové upozornenia"
msgstr[0] "%d nových oznámení"
msgstr[1] "%d nové oznámenie"
msgstr[2] "%d nové oznámenia"
#: ../js/ui/searchDisplay.js:275
msgid "Searching..."
@ -1249,13 +1271,13 @@ msgstr "Heslo"
msgid "Remember Password"
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"
msgstr "Odblokovať"
#: ../js/ui/status/accessibility.js:39
msgid "Accessibility"
msgstr "Prístupnosť"
msgstr "Zjednodušenie ovládania"
#: ../js/ui/status/accessibility.js:44
msgid "Zoom"
@ -1537,7 +1559,7 @@ msgstr "Mobilné"
#: ../js/ui/status/network.js:1628
msgid "VPN Connections"
msgstr "VPN pripojenia"
msgstr "Pripojenia k VPN"
#: ../js/ui/status/network.js:1635
msgid "Network Settings"
@ -1669,7 +1691,7 @@ msgstr "Hlasitosť"
msgid "Microphone"
msgstr "Mikrofón"
#: ../js/ui/unlockDialog.js:177
#: ../js/ui/unlockDialog.js:178
msgid "Log in as another user"
msgstr "Prihlásiť ako iný používateľ"
@ -1697,35 +1719,35 @@ msgstr "Nečinný"
msgid "Unavailable"
msgstr "Nedostupný"
#: ../js/ui/userMenu.js:735
#: ../js/ui/userMenu.js:743
msgid "Notifications"
msgstr "Upozornenia"
#: ../js/ui/userMenu.js:743
#: ../js/ui/userMenu.js:751
msgid "System Settings"
msgstr "Nastavenia systému"
#: ../js/ui/userMenu.js:751
#: ../js/ui/userMenu.js:759
msgid "Switch User"
msgstr "Prepnúť používateľa"
#: ../js/ui/userMenu.js:756
#: ../js/ui/userMenu.js:764
msgid "Log Out"
msgstr "Odhlásiť sa"
#: ../js/ui/userMenu.js:761
#: ../js/ui/userMenu.js:769
msgid "Lock"
msgstr "Uzamknúť"
#: ../js/ui/userMenu.js:776
#: ../js/ui/userMenu.js:784
msgid "Install Updates & Restart"
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"
msgstr "Váš stav bude nastavený na zaneprázdnený"
#: ../js/ui/userMenu.js:795
#: ../js/ui/userMenu.js:803
msgid ""
"Notifications are now disabled, including chat messages. Your online status "
"has been adjusted to let others know that you might not see their messages."

View File

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

View File

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

View File

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

View File

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

View File

@ -1693,43 +1693,3 @@ shell_global_get_session_mode (ShellGlobal *global)
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);
ClutterActor * shell_global_create_xrootpmap_texture (ShellGlobal *global);
G_END_DECLS
#endif /* __SHELL_GLOBAL_H__ */

View File

@ -11,6 +11,8 @@
#define GST_USE_UNSTABLE_API
#include <gst/gst.h>
#include <gtk/gtk.h>
#include "shell-recorder-src.h"
#include "shell-recorder.h"
#include "shell-screen-grabber.h"
@ -65,7 +67,7 @@ struct _ShellRecorder {
int framerate;
char *pipeline_description;
char *filename;
char *file_template;
/* We might have multiple pipelines that are finishing encoding
* to go along with the current pipeline where we are recording.
@ -90,6 +92,7 @@ struct _RecorderPipeline
GstElement *pipeline;
GstElement *src;
int outfile;
char *filename;
};
static void recorder_set_stage (ShellRecorder *recorder,
@ -98,8 +101,8 @@ static void recorder_set_framerate (ShellRecorder *recorder,
int framerate);
static void recorder_set_pipeline (ShellRecorder *recorder,
const char *pipeline);
static void recorder_set_filename (ShellRecorder *recorder,
const char *filename);
static void recorder_set_file_template (ShellRecorder *recorder,
const char *file_template);
static void recorder_pipeline_set_caps (RecorderPipeline *pipeline);
static void recorder_pipeline_closed (RecorderPipeline *pipeline);
@ -109,7 +112,7 @@ enum {
PROP_STAGE,
PROP_FRAMERATE,
PROP_PIPELINE,
PROP_FILENAME
PROP_FILE_TEMPLATE
};
G_DEFINE_TYPE(ShellRecorder, shell_recorder, G_TYPE_OBJECT);
@ -269,18 +272,6 @@ static void
shell_recorder_finalize (GObject *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)
g_source_remove (recorder->update_memory_used_timeout);
@ -290,7 +281,7 @@ shell_recorder_finalize (GObject *object)
recorder_set_stage (recorder, NULL);
recorder_set_pipeline (recorder, NULL);
recorder_set_filename (recorder, NULL);
recorder_set_file_template (recorder, NULL);
g_object_unref (recorder->grabber);
@ -917,22 +908,22 @@ recorder_set_pipeline (ShellRecorder *recorder,
}
static void
recorder_set_filename (ShellRecorder *recorder,
const char *filename)
recorder_set_file_template (ShellRecorder *recorder,
const char *file_template)
{
if (filename == recorder->filename ||
(filename && recorder->filename && strcmp (recorder->filename, filename) == 0))
if (file_template == recorder->file_template ||
(file_template && recorder->file_template && strcmp (recorder->file_template, file_template) == 0))
return;
if (recorder->current_pipeline)
shell_recorder_close (recorder);
if (recorder->filename)
g_free (recorder->filename);
if (recorder->file_template)
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
@ -954,8 +945,8 @@ shell_recorder_set_property (GObject *object,
case PROP_PIPELINE:
recorder_set_pipeline (recorder, g_value_get_string (value));
break;
case PROP_FILENAME:
recorder_set_filename (recorder, g_value_get_string (value));
case PROP_FILE_TEMPLATE:
recorder_set_file_template (recorder, g_value_get_string (value));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
@ -982,8 +973,8 @@ shell_recorder_get_property (GObject *object,
case PROP_PIPELINE:
g_value_set_string (value, recorder->pipeline_description);
break;
case PROP_FILENAME:
g_value_set_string (value, recorder->filename);
case PROP_FILE_TEMPLATE:
g_value_set_string (value, recorder->file_template);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
@ -1027,9 +1018,9 @@ shell_recorder_class_init (ShellRecorderClass *klass)
G_PARAM_READWRITE));
g_object_class_install_property (gobject_class,
PROP_FILENAME,
g_param_spec_string ("filename",
"Filename",
PROP_FILE_TEMPLATE,
g_param_spec_string ("file-template",
"File Template",
"The filename template to use for output files",
NULL,
G_PARAM_READWRITE));
@ -1149,13 +1140,14 @@ get_absolute_path (char *maybe_relative)
* be opened.
*/
static int
recorder_open_outfile (ShellRecorder *recorder)
recorder_open_outfile (ShellRecorder *recorder,
char **outfilename)
{
const char *pattern;
int flags;
int outfile = -1;
pattern = recorder->filename;
pattern = recorder->file_template;
if (!pattern)
return -1;
@ -1230,8 +1222,12 @@ recorder_open_outfile (ShellRecorder *recorder)
{
g_printerr ("Recording to %s\n", path);
if (outfilename != NULL)
*outfilename = path;
else
g_free (path);
g_string_free (filename, TRUE);
g_free (path);
goto out;
}
@ -1269,7 +1265,8 @@ recorder_pipeline_add_sink (RecorderPipeline *pipeline)
return TRUE;
}
pipeline->outfile = recorder_open_outfile (pipeline->recorder);
pipeline->outfile = recorder_open_outfile (pipeline->recorder,
&pipeline->filename);
if (pipeline->outfile == -1)
goto out;
@ -1344,6 +1341,10 @@ recorder_pipeline_free (RecorderPipeline *pipeline)
if (pipeline->outfile != -1)
close (pipeline->outfile);
g_free (pipeline->filename);
g_clear_object (&pipeline->recorder);
g_free (pipeline);
}
@ -1393,6 +1394,10 @@ recorder_pipeline_closed (RecorderPipeline *pipeline)
if (pipeline->recorder)
{
GtkRecentManager *recent_manager;
GFile *file;
char *uri;
ShellRecorder *recorder = pipeline->recorder;
if (pipeline == recorder->current_pipeline)
{
@ -1401,6 +1406,15 @@ recorder_pipeline_closed (RecorderPipeline *pipeline)
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);
}
@ -1452,7 +1466,7 @@ recorder_open_pipeline (ShellRecorder *recorder)
GstBus *bus;
pipeline = g_new0(RecorderPipeline, 1);
pipeline->recorder = recorder;
pipeline->recorder = g_object_ref (recorder);
pipeline->outfile = - 1;
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
* @filename: the filename template to use for output files,
* or %NULL for the defalt value.
* @file_template: the filename template to use for output files,
* or %NULL for the defalt value.
*
* Sets the filename that will be used when creating output
* 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'.
*/
void
shell_recorder_set_filename (ShellRecorder *recorder,
const char *filename)
shell_recorder_set_file_template (ShellRecorder *recorder,
const char *file_template)
{
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
* video is recorded. It will normally have a unconnected
* 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
* might be used to send the output to an icecast server
* via shout2send or similar.

View File

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

View File

@ -3,6 +3,7 @@
#define GST_USE_UNSTABLE_API
#include "shell-recorder.h"
#include <clutter/clutter.h>
#include <gtk/gtk.h>
#include <gst/gst.h>
/* Very simple test of the ShellRecorder class; shows some text strings
@ -11,23 +12,34 @@
static ShellRecorder *recorder = NULL;
static gboolean
stop_recording_timeout (gpointer data)
stop_recording_timeout (ClutterActor *stage)
{
if (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);
}
clutter_main_quit ();
else
{
clutter_actor_destroy (stage);
}
return FALSE;
}
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
@ -35,7 +47,7 @@ on_stage_realized (ClutterActor *stage,
gpointer data)
{
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);
}
@ -46,6 +58,7 @@ int main (int argc, char **argv)
ClutterAnimation *animation;
ClutterColor red, green, blue;
gtk_init (&argc, &argv);
gst_init (&argc, &argv);
if (clutter_init (&argc, &argv) != CLUTTER_INIT_SUCCESS)
return 1;
@ -69,7 +82,7 @@ int main (int argc, char **argv)
"y", 240.0,
NULL);
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", "Blue",
@ -110,7 +123,5 @@ int main (int argc, char **argv)
clutter_main ();
g_object_unref (stage);
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();