Compare commits

...

124 Commits

Author SHA1 Message Date
cad6f31c1a Bump version to 3.8.3
Update NEWS.
2013-06-07 21:46:20 +02:00
294f59103f window-switcher: Only show windows from current workspace by default
When adding the window switcher, we copied our default values from
the alternate-tab extension. Arguably it makes more sense to mimick
the old mutter/metacity behavior though, so change the default
accordingly.

https://bugzilla.gnome.org/show_bug.cgi?id=701214
2013-06-07 21:34:01 +02:00
f88f51dd99 osdWindow: Disable unredirection while showing the OSD
This allows OSDs to be visible even when displayed on top
of unredirected windows.

https://bugzilla.gnome.org/show_bug.cgi?id=701224
2013-06-07 21:22:03 +02:00
c1eaf97bc6 RemoteMenu: Avoid useless signal connections
If we are missing more than one action, every time action-added is
called, it calls modelChanged() again and re-connect signal for
all action still missing. This patch prevent from connecting signals
again when doing a refresh because a missing action is now available.
All necessary signals have already been connected.

https://bugzilla.gnome.org/show_bug.cgi?id=694612
2013-06-07 20:08:37 +02:00
1420f62dfa RemoteMenu: use detailed action-added signal
This avoid disconnecting all signals if we are waiting for
different actions to be added, leading to incomplete menu.
Previously if we were waiting for 2 different actions in 2
different sections, the first action-added signal would
disconnect the 2nd signal handler as well, so the model of
that section would not be updated when the 2nd action is added.

https://bugzilla.gnome.org/show_bug.cgi?id=694612
2013-06-07 20:08:37 +02:00
3ff194247a main: Use the correct schema for 'dynamic-workspaces'
We currently monitor the shell's override schema for changes to
the 'dynamic-workspaces' key, which ends up being the wrong
schema in classic mode. With the new ability to use mode-specific
overides, we can finally fix this.

https://bugzilla.gnome.org/show_bug.cgi?id=701717
2013-06-07 19:59:41 +02:00
36b1cd13c9 main: Pick up overridesSchema from sessionMode
This will allow the use of mode-specific defaults. For classic mode
we currently implement this with mini-extensions, but this may result
in confusing behavior when settings change due to extensions being
disabled during screen locks (not to mention that those mini-extensions
are hardly an elegant approach).

https://bugzilla.gnome.org/show_bug.cgi?id=701717
2013-06-07 19:59:39 +02:00
bcede26d77 main: Move pref overrides to JS
We will allow to use mode-specific overrides; in preparation for that,
move the code so that we only override preferences after initializing
the session mode.

https://bugzilla.gnome.org/show_bug.cgi?id=701717
2013-06-07 19:58:52 +02:00
fbf1ee8a01 update Simplified Chinese (zh_CN) translation 2013-06-06 11:44:18 +08:00
1360747c9e dnd: Use pushModal() to grab the keyboard
Currently we "only" grab the keyboard when starting a drag operation,
which does not impede keybindings to be processed. This is at best
not harmful (like workspace switching), but may have unintended effects
otherwise - for instance, the hot corner is disabled, so having the
corresponding keyboard shortcut still active is fairly odd (not to
mention that it leaves the system in a confused state).
Fix this by switching to pushModal()/popModal(), which will push a
dedicated keybinding mode for us.

https://bugzilla.gnome.org/show_bug.cgi?id=700877
2013-06-05 16:36:23 +02:00
1d95841da0 screenShield: Clear clipboard on lock
Currently the clipboard's contents may leak to unauthorized parties by
pasting into the unlock dialog's password entry and unmasking the entry.
Prevent this from happening by clearing the clipboard on lock.

https://bugzilla.gnome.org/show_bug.cgi?id=698922
2013-06-05 16:23:52 +02:00
494fcfecf8 osdWindow: Make sure the OSD is always our topmost chrome element
In particular this fixes the OSD showing up behind a modal dialog's
lightbox.

https://bugzilla.gnome.org/show_bug.cgi?id=701269
2013-06-05 15:36:12 +02:00
75705b45ef dash: Grow the empty dash during drag operations
When the dash does not contain any applications (either favorites
or running), it is currently impossable to add a favorite via DND.
Grow the dash slightly in that case to provide a drop target.

https://bugzilla.gnome.org/show_bug.cgi?id=684618
2013-06-05 14:54:45 +02:00
1ad1e48741 dash: Minor cleanup
https://bugzilla.gnome.org/show_bug.cgi?id=684618
2013-06-05 14:54:45 +02:00
ddb682e4fe dash: Use a single code path for clearing the drag placeholder
We currently only keep track of old placeholders when moving past
the dragged app's current favorite position, as this is the only
case where we need to worry about jitter. Still, moving it into
_clearDragPlaceholder() allows us to consolidate code paths, which
is a good thing ...

https://bugzilla.gnome.org/show_bug.cgi?id=684618
2013-06-05 14:54:45 +02:00
5216b77600 dash: Make sure _clearDragPlaceholder() resets _dragPlaceholderPos
The function currently only resets the placeholder position if
there is a placeholder; this is not necessarily true, as the
placeholder may be reset outside _clearDragPlaceholder().
If this happens, the placeholder will temporarily stop working
for the "old" position (and permanently if it's the only position).
Just reset the position unconditionally.

https://bugzilla.gnome.org/show_bug.cgi?id=684618
2013-06-05 14:28:25 +02:00
c93d91d80b Updated Traditional Chinese translation(Hong Kong and Taiwan) 2013-06-04 21:50:40 +08:00
f9e3467b70 appDisplay: Give more horizontal space to control buttons
Before, the text of those buttons were truncated when the text exceeded
the fixed width we had in the CSS.
Now, we give more horizontal space to the control buttons to match
the maximum text length of all buttons.

https://bugzilla.gnome.org/show_bug.cgi?id=696307
2013-06-04 13:53:42 +02:00
13bea1a01b Bump gvc submodule
As of commit 95a1b874d8, the submodule is supposed to be at
revision 3d6aac673b88ff, but commit 31774a7711 accidentally
reverted it back to the previously used revision.
2013-05-31 20:50:42 +02:00
76c930e471 build: Bump gcr requirement
https://bugzilla.gnome.org/show_bug.cgi?id=700972
2013-05-31 20:44:13 +02:00
9f6cd75170 shell-gtk-embed: Lower tray icon windows to the bottom of the stack
Otherwise they break the "top level window" detection used by the
unredirect code in mutter, causes game windows not to be unredirected
when tray icons are present.

https://bugzilla.gnome.org/show_bug.cgi?id=701224
2013-05-30 00:59:11 +02:00
c107882828 xdnd: Lower window activation timeout
The current one is perceived as too high by users, so try a shorter timeout.

https://bugzilla.gnome.org/show_bug.cgi?id=700150
2013-05-29 22:06:32 +02:00
d18e084cd5 Keyboard: clear currentSource after destruction
StLabel doesn't like that we set its properties after destructions,
and this would happen in currentInputSourceChanged() at the end,
when setting the ornament.
2013-05-25 20:39:33 +02:00
2eb779740c messageTray: Check if the clicked summary item has a right click menu
Commit e71129aa68 introduced the
possibility of having summary items without a right click menu so we
should check for one before trying to show it.

https://bugzilla.gnome.org/show_bug.cgi?id=700190
2013-05-24 23:57:47 +02:00
3ce20568d0 status/keyboard: Allow switching input source in the message tray
We still can't show a popup switcher in the message tray but we can at
least degrade gracefully and advance to the next input source.

https://bugzilla.gnome.org/show_bug.cgi?id=697009
2013-05-24 23:57:47 +02:00
d45ab6f15e status/keyboard: Switch input source on special modifiers accelerator
This simply mimics the X server's layout switching behavior by
advancing to the next input source and wrapping around.

https://bugzilla.gnome.org/show_bug.cgi?id=697008
2013-05-24 23:57:47 +02:00
cd7197e605 status/keyboard: Synchronize input source switching with key events
Currently we simply set the gsettings key when activating an input
source. This obviously introduces a time window, between the event that
activates the switch and when the switch is complete, under which key
events are being delivered to applications and interpreted according
to the previous input source.

The patches in bug 696996 introduce a DBus API in g-s-d that allows us
to know when an input source if effectively active. Using that and
freezing keyboard events in the X server until we hear back from g-s-d
we can ensure that events won't be misinterpreted after an input
source switch.

https://bugzilla.gnome.org/show_bug.cgi?id=697007
2013-05-24 23:57:47 +02:00
3f6c1aadef Depend on gcr-base instead of gcr pkg-config file
gnome-shell does not use the UI bits of the Gcr library

https://bugzilla.gnome.org/show_bug.cgi?id=700944
2013-05-24 11:18:17 +02:00
29e8290b65 docs: Include ShellKeyBindingMode in docs
https://bugzilla.gnome.org/show_bug.cgi?id=700900
2013-05-23 17:10:37 +02:00
3074e48405 popupMenu: Allow for an optional border for slider handle
While the default style works well will a solid handle, using both
border and fill color would be desirable in classic mode. Add the
necessary (optional) style properties to allow this.

https://bugzilla.gnome.org/show_bug.cgi?id=697917
2013-05-22 18:47:37 +02:00
12c2939b64 screenshot: Hide cursor while magnifier is active
As with the screen recorder, the magnifier already adds its own
copy of the system cursor, so we should not add it again. Just
as in the screen recorder case, we don't address the case where
the cursor should not be included in the screenshot, but the
magnifier adds it anyway.

https://bugzilla.gnome.org/show_bug.cgi?id=700488
2013-05-22 18:34:45 +02:00
c7eed59562 recorder: Hide cursor while magnifier is active
The magnifier adds its own copy of the system cursor to apply the
expected transformations, so we don't need to add it again in the
recorder; this avoids two different cursors showing up in recordings,
but doesn't address the case where the cursor should not be recorded
at all, but the magnifier adds it anyway.

https://bugzilla.gnome.org/show_bug.cgi?id=700488
2013-05-22 18:34:45 +02:00
73903400c5 screencast: Fix return value in case of invalid file template
If we are passed an invalid file template, ShellRecorder.record()
will return a %NULL filename; as the Screencast DBus interface
expects a string return value, we cannot return the value unmodified
in that case.

https://bugzilla.gnome.org/show_bug.cgi?id=700842
2013-05-22 17:24:04 +02:00
dc7cc9b517 userWidget: Fix leaking instances
UserWidget instances should be destroyed when the actor is. That's
what consumer code expects since the destroy() method is never called.

https://bugzilla.gnome.org/show_bug.cgi?id=700807
2013-05-21 21:55:21 +02:00
b18c239240 appDisplay: Also account for folder popup's close buttons
As the close button of folder popups overlaps at the top, it ends
up being cut off if the folder is located at the very top of the
view. Fix this glitch by taking the button's overlap into account
in that case.

https://bugzilla.gnome.org/show_bug.cgi?id=694371
2013-05-20 18:21:16 +02:00
3c66f1a4d9 appDisplay: Fix cut-off folders in All view
We already take care of growing the view if open folders overlap
at the bottom, however folder popups may still end up being cut
off when opening above the source icon - if the popup is high enough,
its y coordinate will be negative and therefore outside the parent's
allocation. To fix, we can either make sure that folders pop up below
their source icon in that case, or adjust the parent grid's position
as necessary while a folder is open. This implements the latter.

https://bugzilla.gnome.org/show_bug.cgi?id=694371
2013-05-20 18:21:16 +02:00
1dff5fb5b2 appDisplay: Expand AllView
If the view doesn't fill the available space, content should still
start at the top rather than the center - not least the positioning
code for folder popups assumes that, so set the appropriate expand
flags.

https://bugzilla.gnome.org/show_bug.cgi?id=694371
2013-05-20 18:21:16 +02:00
e2561d15b5 theme: polish the session chooser
The session chooser list has an embedded look which doesn't fit
well with the rest of the theme. Give it more of a flat appearance
and simplify the visuals.
https://bugzilla.gnome.org/show_bug.cgi?id=695742
2013-05-19 15:25:58 -04:00
326c3732b8 screenshot: Check for NULL window in screenshot_window()
screenshot_window() currently assumes a focus window, which will
result in a crash if that's not the case.

https://bugzilla.gnome.org/show_bug.cgi?id=700625
2013-05-19 15:32:56 +02:00
5dd020f2e2 recorder: Use workarea to position the recording icon
It looks a bit unpolished to overlap our own chrome with the recording
icon, which may happen when an existing adds UI at the bottom edge.
Fix this by using the primary monitor's workarea for the position rather
than the entire monitor.

https://bugzilla.gnome.org/show_bug.cgi?id=700409
2013-05-18 14:30:16 +02:00
b6edbd46b9 overview: Add focusSearch() method and export it over DBus
Some keyboard spot a dedicated search key, which gnome-settings-daemon
currently handles by spawning gnome-search-tool. It makes a lot of
sense to promote the Shell's integrated search feature instead, so
expose an appropriate DBus method g-s-d can use.

https://bugzilla.gnome.org/show_bug.cgi?id=700536
2013-05-17 18:28:47 +02:00
c330036fef Document --clutter-display in the man page
This is the sole option that was missing from the
man page.

https://bugzilla.gnome.org/show_bug.cgi?id=700339
2013-05-16 18:45:25 -04:00
d0a864b9b9 windowManager: Enable switch-to-workspace-n keybindings in overview
Those keybindings are unassigned by default, but that's not a valid
reason they shouldn't work like the related switch-up/down bindings.

https://bugzilla.gnome.org/show_bug.cgi?id=649977
2013-05-16 00:41:17 +02:00
9bed5b725e network: Fix stupid typo
There is no ACTIVE state in NetworkManager.ActionConnectionState,
it's ACTIVATED.

https://bugzilla.gnome.org/show_bug.cgi?id=700394
2013-05-15 17:48:21 +02:00
f374ecfc75 altTab: Always activate MRU window when activating an app
Commit 2499f2ed80 went back to using shell_app_activate() for
selecting an app, which favors windows on the current workspace;
this is the behavior we want for instance when activating a
launcher, but it's wrong for the alt-tab list - explicitly
request the first (e.g. MRU) window in that case.

https://bugzilla.gnome.org/show_bug.cgi?id=700356
2013-05-15 12:13:41 +02:00
dd8ca02425 PopupMenuManager: Fix child menus
Since commit c84dc6254d, popup menus are closed automatically
when another menu opens (to catch the case where a menu is opened
by keyboard shortcut, which wasn't handled before). However in the
case of child menus, both child and parent are expected to be visible,
so handle this case explicitly.

https://bugzilla.gnome.org/show_bug.cgi?id=699678
2013-05-14 19:09:09 +02:00
ff3f9bdd7d volume: Adjust to icon name changes
The headphone icon gained an audio- prefix, use that instead of
the old name.
2013-05-14 14:28:34 +02:00
fab02ae82f Bump version to 3.8.2
Update NEWS.
2013-05-14 01:33:19 +02:00
d43c5ec27a shellEntry: Set the input-purpose property for password entries
This way input methods can disable themselves automatically for
entries holding passwords.

https://bugzilla.gnome.org/show_bug.cgi?id=700043
2013-05-14 00:40:27 +02:00
f7de35b852 st-entry: add input purpose and hints
Add input-purpose and input-hints properties to StEntry,
and pass these on to StIMText.

https://bugzilla.gnome.org/show_bug.cgi?id=691392
2013-05-14 00:40:18 +02:00
cde0045851 st-im-text: add input purpose and hints
Add input-purpose and input-hints properties to StIMText,
and pass these on to GtkIMContext.

https://bugzilla.gnome.org/show_bug.cgi?id=691392
2013-05-14 00:40:15 +02:00
f844613292 st-im-text: remove undefined st_im_text_set_autoshow_im decl
https://bugzilla.gnome.org/show_bug.cgi?id=691392
2013-05-14 00:40:11 +02:00
ff2e44de53 status/keyboard: Stop destroying the IBusBus object
This is a singleton object inside libibus which means that if we
destroy it (e.g. because ibus-daemon got restarted) then, other
library users, like the ibus gtk+ IM module that we also use
in-process, will break.

https://bugzilla.gnome.org/show_bug.cgi?id=699189
2013-05-14 00:34:55 +02:00
17aa8e0488 polkitAgent: Allow retrying mistyped passwords
Don't hide the polkit agent window when someone mistypes their password.
Allow them to try again. The user can cancel at any point.

https://bugzilla.gnome.org/show_bug.cgi?id=684431
2013-05-13 20:08:34 +02:00
a33df9b046 appDisplay: Implement folder keynav and shortcuts
When opening an application folder, it should take key focus to
allow for keynav; also, Escape closing both folder and app picker
is unexpected, it should only close the popup.

https://bugzilla.gnome.org/show_bug.cgi?id=695314
2013-05-13 19:46:16 +02:00
c25f399f7c Updated Norwegian bokmål translation 2013-05-13 09:48:12 +02:00
bd47d07fbc ScreenShield: clear the lock screen early when deactivating
Upon popMode, MessageTray will try readding all notifications
to their rightful parent, so we must tell NotificationBox to
relinquish them before st_bin_set_child() fails (leaving a dangling
child pointer and crashing at the next allocation)

https://bugzilla.gnome.org/show_bug.cgi?id=698812
2013-05-12 20:20:36 +02:00
72282237e1 data: Fix typo in Screencast docs 2013-05-10 23:44:14 +02:00
dfb44aa51d Expose screencast functionality via DBus
Like screenshots, the screen recorder can be a useful tool in other cases
than being triggered by a keyboard shortcut. To account for that, export
a Screencast DBus API similar to the existing Screenshot interface.

https://bugzilla.gnome.org/show_bug.cgi?id=696247
2013-05-10 19:49:41 +02:00
5516cad087 sessionMode: Add 'allowScreencast' property
Our built-in screen recorder is implemented as a component, so it will
just be disabled when the session mode doesn't allow screencasting.
However we will expose screencasting functionality on DBus as well, and
while it makes sense to restrict its availablity to the same modes as
the existing recorder, exporting/unexporting the service depending on
the session mode is not very consumer friendly.
For that reason, add an additional 'allowScreencast' property that for now
mirrors the availability of the 'recorder' component.

https://bugzilla.gnome.org/show_bug.cgi?id=696247
2013-05-10 19:49:41 +02:00
ab60c31629 shell-recorder: Make drawing the cursor optional
As with screenshots, showing the cursor in a recording may not be
desirable, so add a property to control whether the cursor is drawn
or not.

https://bugzilla.gnome.org/show_bug.cgi?id=696247
2013-05-10 19:49:41 +02:00
52dd030087 shell-recorder: Support specifying the recorded area
Currently we will always record the entire screen. It has been requested
to support recording a specified area analogous to the screenshot API as
well, so add a set_area() method which allows this.

https://bugzilla.gnome.org/show_bug.cgi?id=696247
2013-05-10 19:49:41 +02:00
98240c2857 shell-recorder: Optionally return the filename of the recording
It is currently not always possible to predict the actual output filename
of a recording - the file-template does not necessarily use an absolute
path and may contain %d and %t escape sequences.
This is OK for fire-and-forget uses like the existing keyboard shortcut,
but we will soon expose the functionality on DBus and consumers of that
API might very well need to access the file after the recording. So do
the same as our screenshot API and add an optional (out) parameter to
record().

https://bugzilla.gnome.org/show_bug.cgi?id=696247
2013-05-10 19:49:41 +02:00
65bfd6c6d2 Don't put non-Shell windows in Ctrl+Alt+Tab if they wouldn't be visible
Metacity's Ctrl+Alt+Tab would include X11 windows
with hints like GDK_WINDOW_TYPE_HINT_DOCK and
GDK_WINDOW_TYPE_HINT_DESKTOP (there are more conditions, but that's a
good start). If we're in normal mode, those are visible and it's OK
to display those in the Ctrl+Alt+Tab order, but if we're in the lock
screen or the unlock dialog, they're not visible and it doesn't make
sense to focus them.

Bug: https://bugzilla.gnome.org/show_bug.cgi?id=699862
Signed-off-by: Simon McVittie <simon.mcvittie@collabora.co.uk>
Reviewed-by: Florian Müllner <fmuellner@gnome.org>
2013-05-09 19:31:08 +01:00
1034e33c35 modalDialog: Show spinner when working
Use the same UI concept from the login screen to show spinners when
the polkit or keyring dialogs are working

https://bugzilla.gnome.org/show_bug.cgi?id=684438
2013-05-09 06:41:07 +02:00
d7528b878c components: Allow cancelling of dialog between prompts
Some callers of the keyring prompt keep the dialog up while
processing the prompt. Allow the user to cancel the prompt
while in this state.

This is propagated to the caller, who can cancel the operation
in question when this occurs.

https://bugzilla.gnome.org/show_bug.cgi?id=682830
2013-05-09 05:55:15 +02:00
eb2e66c539 network: don't use active connections that are in invalid states
Only ACTIVE or ACTIVATING connections are important when deciding
what icon to show, don't fallback on any, possibly invalid or deactivating,
active connection object.

https://bugzilla.gnome.org/show_bug.cgi?id=676285
2013-05-09 00:05:36 +02:00
30e9a2a7d0 keyring: Fix button disabled when prompting for confirmation
https://bugzilla.gnome.org/show_bug.cgi?id=696304
2013-05-08 22:13:56 +02:00
e842694316 st-shadow: Fix offset shadow offscreen rendering
The shadows are currently rendered by painting the actor we want to
apply shadow on, in an offscreen buffer. The problem is that when this
actor has an allocation padding (ie allocation that isn't at 0x0
relatively to its parent), this padding is added within the offscreen
buffer and as a result the shadow rendering is truncated because the
offscreen buffer size is the size of the allocation box, not the
allocation box + padding.

This patch reposition the actor at 0x0 with rendering it by changing
the initial transformation matrix when rendering the actor offscreen.

https://bugzilla.gnome.org/show_bug.cgi?id=698301
2013-05-08 16:16:07 +01:00
b33d87a762 loginDialog: Adjust logoBin to modalDialog changes
With modalDialogs' backgroundStack using a BinLayout now, we need
to set approriate expand flags on the iconBin.

https://bugzilla.gnome.org/show_bug.cgi?id=699877
2013-05-08 00:09:53 +02:00
0ff3599d91 modalDialog: Replace Shell.Stack with layout manager
Commit e98eb57e3e added flags to expand the dialog's background
stack, which works fine with the current clutter-1.16 branch, but
breaks on clutter-1.14 (as shipped with GNOME 3.8).
Using an St.Widget with a Clutter.BinLayout fixes this, and is more
modern Clutter usage.

https://bugzilla.gnome.org/show_bug.cgi?id=699877
2013-05-08 00:09:53 +02:00
28d79a1235 osdWindow: Allow popup to grow if necessary
The popup currently has a fixed size based on monitor size. As a result,
the popup's content may overflow if its minimum size is larger than the
popup size. To prevent this, use min-width/min-height for the popup size
so that the popup can grow if necessary.

https://bugzilla.gnome.org/show_bug.cgi?id=696523
2013-05-07 21:35:47 +02:00
522d21154b loginDialog: Remove logo in upper left corner
With optional branding now being shown below the user list, we can
remove the unloved instance in the upper left corner ...

https://bugzilla.gnome.org/show_bug.cgi?id=694912
2013-05-07 20:52:04 +02:00
7c231916c1 loginDialog: (Optionally) show logo below user list
The optional logo on the login screen is currently shown in the
top bar, which is not only a rather unprominent position, it also
gives the wrong suggestion of a clickable element.
Newer designs call for the logo to be shown horizontally centered
at the bottom of the screen, so implement that instead.

https://bugzilla.gnome.org/show_bug.cgi?id=694912
2013-05-07 20:52:04 +02:00
a40bb67fc6 modalDialog: Always use a stack for the background
Currently a system modal dialog's actor hierarchy depends on whether
events should be blocked while the dialog is shown or not. Change
it to always contain a stack, to allow subclasses to add additional
background elements.

https://bugzilla.gnome.org/show_bug.cgi?id=694912
2013-05-07 20:52:04 +02:00
4c350b90c7 dateMenu: do not show "Open Calendar" button with no installed calendar application
https://bugzilla.gnome.org/show_bug.cgi?id=697725
2013-05-06 15:59:17 +01:00
47dee22b05 gdm: Fix regression where domain login hint not shown
Also only keep around realmd while we're actually using it, allow it
to quit if no other clients are active.

https://bugzilla.gnome.org/show_bug.cgi?id=698200
2013-05-03 21:55:45 +02:00
13c0e575f6 ctrlAltTab: Use a symbolic icon for desktop windows
The nautilus icon sticks out pretty badly among the symbolic
icons we use for other desktop components. This commit finds
windows of type DESKTOP, and uses the video-display-symbolic
icon for them.
https://bugzilla.gnome.org/show_bug.cgi?id=697914
2013-05-03 10:27:01 -04:00
ea8736b13a AppMenuButton: Improve handling of signals
If for some reason an extension needs to destroy the AppMenu object,
currently it is not possible to do this cleanly due to these signals
remaining connected.

https://bugzilla.gnome.org/show_bug.cgi?id=698531
2013-05-01 18:33:31 +10:00
303d53e7f5 StIcon: use g_signal_connect_object() for safety
Prevent a crash in case an icon is destroyed before the texture
finishes loading, and something else is keeping the texture alive
for any reason.

https://bugzilla.gnome.org/show_bug.cgi?id=696720
2013-04-29 00:26:51 +02:00
31295dfe83 Updated Lithuanian translation 2013-04-28 13:36:38 +03:00
69ea4553cb dateMenu: append .desktop to evolution strings
Since that is what the actual app_id's are.
2013-04-27 08:32:23 +10:00
0d8d77356e PopupMenuManager: Close active menu when another one opens
We already do this when navigating between menus via mouse or
keynav, but miss cases where a menu is opened by other means,
for instance via a keyboard shortcut.

https://bugzilla.gnome.org/show_bug.cgi?id=686756
2013-04-26 18:16:14 +02:00
8b78032248 panel: Change openAppMenu() to a toggle action
It makes sense to allow closing the app menu with the same shortcut
that is used to open it, so make it a toggle action and allow it
TOPBAR_POPUP mode.

https://bugzilla.gnome.org/show_bug.cgi?id=686756
2013-04-26 18:16:13 +02:00
ad277a563c panel: Add keybinding mode for top bar popups and use it
Allow some keybindings to still work while a top bar menu is open
by assigning it a keybinding mode.

https://bugzilla.gnome.org/show_bug.cgi?id=698938
2013-04-26 18:16:13 +02:00
db26fb201e popupMenu: Allow setting grabHelper params for PopupMenuManager
Currently all keybindings are disabled while some popup menu is open.
However some keybindings may still be useful in some cases, so expose
GrabHelper's modal params parameter to allow specifying a keybinding
mode for particular menus.

https://bugzilla.gnome.org/show_bug.cgi?id=698938
2013-04-26 18:16:13 +02:00
9f00be50d6 shellDBus: Fix Eval() return value when disabled
Eval() is expected to return a boolean success value and a string result.
However when the function is disabled (via the development-tools setting),
we return null for the latter which is not a valid string value.
Return an empty string instead.

https://bugzilla.gnome.org/show_bug.cgi?id=698959
2013-04-26 18:16:12 +02:00
77d21e53d0 backgroundMenu: Ignore releases when using long-press
Otherwise, a release from the long-press will be seen as a
button event that should close the menu.

https://bugzilla.gnome.org/show_bug.cgi?id=697203
2013-04-26 11:24:30 -04:00
ba0b4ba590 layout: Correct hot corner barriers in RTL layouts
https://bugzilla.gnome.org/show_bug.cgi?id=698884
2013-04-26 11:24:25 -04:00
b9fc7a3050 [l10n] Add Interlingua translation 2013-04-24 15:52:53 +02:00
aa053a906d [l10n] Updated Turkish translation 2013-04-20 00:48:22 +03:00
2cda0472bd Bump version to 3.8.1
Update NEWS.
2013-04-16 21:25:54 +02:00
4710753700 panel: Pick up spinner icon from CSS
In order to use a different spinner image in classic mode (or any
other mode specific style), get it from CSS rather than hardcoding
a particular image.

https://bugzilla.gnome.org/show_bug.cgi?id=693688
2013-04-16 19:10:40 +02:00
2b439ef209 theme-node: Add lookup_url/get_url() methods
Similar to the existing generic getter methods, add lookup functions
for URL properties like the standard background-image/border-image
properties.

https://bugzilla.gnome.org/show_bug.cgi?id=693688
2013-04-16 19:10:40 +02:00
2fc76e6d9e panel: Pass a full pathname to AnimatedIcon
For classic mode, we want to use a different styling for the spinner,
so we will pick up the image filename from CSS to make use of mode
specific styling. As the CSS will give us a full pathname, adapt the
API to take a full pathname instead of building it inside AnimatedIcon
from the passed basename.

https://bugzilla.gnome.org/show_bug.cgi?id=693688
2013-04-16 19:10:40 +02:00
ff544450a5 Revert "classic: Invert the spinner color"
This reverts commit f358bb1a96.
2013-04-15 18:40:00 -04:00
b4590da686 Revert "Add an OSD for sticky modifiers"
This reverts commit 96994721ef.
2013-04-15 18:39:52 -04:00
6c4be0311a Revert "Make it possible to always show the a11y status"
This reverts commit 6ce79c62eb.
2013-04-15 18:39:44 -04:00
4a2cdc20f0 Add networkAgent to initial-setup mode
We want to be able to set up e.g. a WEP connection on the
network page of gnome-initial-setup, so we need a network
agent in the session.
2013-04-15 18:05:57 -04:00
6ce79c62eb Make it possible to always show the a11y status
A switch for this is part of the redesign for the universal
access control-center panel.

https://bugzilla.gnome.org/show_bug.cgi?id=698001
2013-04-15 17:48:47 -04:00
96994721ef Add an OSD for sticky modifiers
This commit adds an OSD that displays which modifiers are
currently latched or locked. This is commonly used together
with sticky keys.
https://bugzilla.gnome.org/show_bug.cgi?id=647711
2013-04-15 17:48:47 -04:00
f358bb1a96 classic: Invert the spinner color
https://bugzilla.gnome.org/show_bug.cgi?id=693688
2013-04-15 17:48:47 -04:00
1bce210c51 messageTray: Don't show the context-menu when the tray isn't open
https://bugzilla.gnome.org/show_bug.cgi?id=697709
2013-04-15 12:49:30 -04:00
8a3c8d1b1c Add a note to POTFILES.in about the gvc submodule 2013-04-14 21:59:03 +02:00
08b224de1f Updated Vietnamese translation 2013-04-13 17:53:05 +10:00
86c92c37d2 st-im-text: Override ClutterText's cursor_event to set cursor position
This is both more efficient and accurate than doing it from the paint
vfunc.

https://bugzilla.gnome.org/show_bug.cgi?id=697722
2013-04-10 17:27:28 +02:00
07053c3df7 shellEntry: Remove close method
GrabHelper already takes care of putting the key focus back on the
widget that had it when the grab was established.

ShellEntry's close() has recently become harmful since it's now called
from the menu's destroy() method and that is called in the entry's
destroy handler which means that this._entry might no longer be valid
at close() time.

https://bugzilla.gnome.org/show_bug.cgi?id=697560
2013-04-08 21:02:03 +02:00
4fb33c9b09 dnd: Set the position and scale on the drag actor before it's reparented
We need to do this to ensure that it gets the correct scale, as otherwise
the transform that we retrieve will be incorrect.

https://bugzilla.gnome.org/show_bug.cgi?id=697504
2013-04-08 14:57:49 -04:00
5e6a25c3c2 dnd: Set the scale on the drag actor
The actor is the same as the drag actor in this case, but we tend to
set properties on the drag actor and get them from the actor elsewhere
in this codepath. Make this consistent.

https://bugzilla.gnome.org/show_bug.cgi?id=697504
2013-04-08 14:57:49 -04:00
e14ef4a294 theme: remove excessive padding from notification buttons
Set the button width manually and remove the huge horizontal
padding we had. This means that long button labels don't get cut
off.

https://bugzilla.gnome.org/show_bug.cgi?id=664411
2013-04-08 19:25:46 +02:00
8b659f0f4c St: support -st-natural-width/height CSS properties
It is sometimes desirable to specify the size of a box from CSS without
changing the minimum-width too.
This property implements that.

https://bugzilla.gnome.org/show_bug.cgi?id=664411
2013-04-08 19:25:45 +02:00
a6395c95d4 Small fix in Serbian translation 2013-04-08 15:29:57 +02:00
98e74dfd38 screenshield: Remove box-shadow
This causes very low performance in some situations (like multiscreen). Proper
fixes are too invasive at this point (3.8.1) so lets just remove the shadow
for now and add it back later once he have fixed it.

https://bugzilla.gnome.org/show_bug.cgi?id=697274
2013-04-07 22:06:46 +02:00
1d728186db recorder: Enable the keybinding for all modes
There's not really a good reason to restrict the screen recorder
to normal mode and overview, so allow it for all keybinding modes.

https://bugzilla.gnome.org/show_bug.cgi?id=696200
2013-04-07 21:13:30 +02:00
2499f2ed80 AppSwitcherPopup: Activate only the selected window if any
If there's an explicitly selected window thumbnail we should bring up
only that particular window instead of all the application's windows.

https://bugzilla.gnome.org/show_bug.cgi?id=697480
2013-04-07 21:05:38 +02:00
963905adcd runDialog: don't destroy on close
It's a singleton like the endSessionDialog

https://bugzilla.gnome.org/show_bug.cgi?id=697435
2013-04-06 11:10:30 -04:00
7c21ab0985 Revert "Revert "modalDialog: Destroy dialogs on close""
This reverts commit 007820b7c1.

(I only meant to revert that in my local branch)
2013-04-06 10:53:11 -04:00
77d3712261 popupMenu: close menu on destroy
This fixes a crash if a background menu is open
and the background changes.

https://bugzilla.gnome.org/show_bug.cgi?id=697432
2013-04-06 10:47:16 -04:00
0376f22d41 background: stop monitoring file after removing from cache
https://bugzilla.gnome.org/show_bug.cgi?id=697395
2013-04-06 10:45:53 -04:00
007820b7c1 Revert "modalDialog: Destroy dialogs on close"
This reverts commit 3dd6113a0a.
2013-04-06 10:28:47 -04:00
dc98711477 backgroundMenu: drop cursor object with rest of menu actors
https://bugzilla.gnome.org/show_bug.cgi?id=697395
2013-04-06 09:45:45 -04:00
e98c6ff31b background: when updating image remove old one from cache
We're removing the new content from the cache instead of the
old content.

This commit fixes that.

https://bugzilla.gnome.org/show_bug.cgi?id=697395
2013-04-06 09:44:51 -04:00
9eae74357a background: don't leak background objects during quick changes
We currently let some backgrounds "fall through the cracks" if
a bunch of change notifications come in at once.

This commit fixes that.

https://bugzilla.gnome.org/show_bug.cgi?id=697395
2013-04-06 09:44:50 -04:00
1ee88a2878 screenShield: Ensure we destroy background container widgets
We may accidentally leak a widget when monitors change while
locked otherwise. This is especially bad because we put a
box-shadow on this widget.

https://bugzilla.gnome.org/show_bug.cgi?id=697300
2013-04-04 19:16:49 -04:00
76 changed files with 5835 additions and 2975 deletions

97
NEWS
View File

@ -1,3 +1,100 @@
3.8.3
=====
* Fix child menu regression introduced in 3.8.2 [Florian; #699678]
* Fix alt-tab not always switching back to the previous window [Florian; #700356]
* Fix VPN network icon regression introduced in 3.8.2 [Florian; #700394]
* Allow switch-to-workspace-n keybindings in overview [Florian; #649977]
* Update man page [Matthias; #700339]
* Add FocusSearch DBus method [Florian; #700536]
* gdm: Update the session chooser style [Allan; #695742]
* Fix some app folders getting truncated at the top [Florian; #694371]
* Fix duplicate cursors in screenshots with magnification [Florian; #700488]
* popupMenu: Allow for an optional border for slider handle [Florian; #697917]
* Synchronize input source switching with key events [Rui; #697007]
* Switch input source on modifiers-only accelerator [Rui; #697008]
* Allow input source switching in message tray [Rui; #697009]
* Tweak timeout for activating windows during XDND [Adel; #700150]
* Fix fullscreen windows not being unredirected when legacy tray icons
are around [Adel; #701224]
* Fix ellipsization in control buttons in app picker [Carlos; #696307]
* Fix DND to empty dash [Florian; #684618]
* Fix OSD window appearing below system modal dialogs [Rui; #701269]
* Clear clipboard on screen lock to prevent information leak [Florian; #698922]
* Allow session mode specific overrides schema [Florian; #701717]
* Fix incomplete app menu if multiple actions only become available later
[Xavier; #694612]
* Fix showing the OSD when a fullscreen app is unredirected [Adel, #701224]
* window-switcher: Only show windows from current workspace by default
[Florian; #701214
* Misc bug fixes [Florian, Rui, Giovanni, Stef; #700409, #700625, #700807,
#700842, #700900, #700944, #700190, #700972, #700877]
Contributors:
Giovanni Campagna, Xavier Claessens, Matthias Clasen, Allan Day,
Adel Gadllah, Rui Matos, Florian Müllner, Carlos Soriano, Stef Walter
Translations:
Cheng-Chia Tseng [zh_HK, zh_TW], eternalhui [zh_CN]
3.8.2
=====
* Fix hotcorner regression in RTL locales [Jasper; #698884]
* Allow some keybindings to work while a top bar menu is open [Florian; #698938]
* Make open-app-menu keybinding a toggle action [Florian; #686756]
* ctrlAltTab: Use symbolic icons for desktop windows [Matthias; #697914]
* gdm: Fix regression where domain login hint not shown [Stef; #698200]
* Hide "Open Calendar" item when no calendar app is installed [Lionel; #697725]
* Update how branding appears on login screen [Florian; #694912, #699877]
* Allow OSD popups to grow if necessary [Marta; #696523]
* Fix offset of shadow offscreen rendering [Lionel; #698301]
* Fix insensitive button preventing empty keyring password [Stef; #696304]
* Allow cancelling keyring dialog between prompts [Stef; #682830]
* modalDialog: Show spinner while working [Stef; #684438]
* Provide a DBus API for screencasting [Florian; #696247]
* Implement app folder keynav and shortcuts [Florian; #695314]
* polkitAgent: Allow retrying after mistyped passwords [Stef; #684431]
* Add input purpose and hints to StEntry and StIMText [Daiki; #691392]
* Set input-purpose property for password entries [Rui; #700043]
* Misc fixes and cleanups [Jasper, Florian, Giovanni, Tim, Rui; #697203,
#698959, #696720, #698531, #676285, #698812, #699189]
Contributors:
Giovanni Campagna, Matthias Clasen, Lionel Landwerlin, Tim Lunn, Rui Matos,
Simon McVittie, Marta Milakovic, Florian Müllner, Jasper St. Pierre,
Daiki Ueno, Stef Walter
Translations:
Muhammet Kara [tr], Nik Kalach [ia], Žygimantas Beručka [lt],
Kjartan Maraas [nb]
3.8.1
=====
* Clip window group during startup animation [Jasper; #696323]
* Check for logind rather than systemd [Martin; #696252]
* Don't special-case last remote search provider position [Giovanni; #694974]
* Fix memory leaks [Ray, Jasper; ##697119, #697295, #697300, #697395]
* AppSwitcherPopup: Activate only the selected window if any [Rui; #697480]
* Enable screen recorder keybinding in all modes [Florian; #696200]
* Remove box-shadow from screen shield for performance reasons [Adel; #697274]
* Add support for -st-natural-width/height CSS properties [Giovanni; #664411]
* Remove excessive padding from notification buttons [Allan; #664411]
* Fix thumbnail dragging in overview [Jasper; #697504]
* theme-node: Add get_url()/lookup_url() methods [Florian; #693688]
* Misc bug fixes and cleanups [Jasper, Rui, Colin, David, Ray, Matthias:
#695859, #696259, #696585, #696436, #697432, #697435, #697560, #697722,
#697709]
Contributors:
Giovanni Campagna, Matthias Clasen, Allan Day, Adel Gadllah, David Gumberg,
Rui Matos, Florian Müllner, Martin Pitt, Jasper St. Pierre, Ray Strode,
Colin Walters
Translations:
Daniel Martinez [an], Bruce Cowan [en_GB], Khaled Hosny [ar],
Ihar Hrachyshka [be], Aron Xu [zh_CN], Wojciech Szczęsny [pl],
Inaki Larranaga Murgoitio [eu], Kjartan Maraas [nb],
Милош Поповић [sr, sr@latin], Trần Ngọc Quân [vi]
3.8.0.1
=======
* Background bug fixes [Ray; #696712]

View File

@ -1,5 +1,5 @@
AC_PREREQ(2.63)
AC_INIT([gnome-shell],[3.8.0.1],[https://bugzilla.gnome.org/enter_bug.cgi?product=gnome-shell],[gnome-shell])
AC_INIT([gnome-shell],[3.8.3],[https://bugzilla.gnome.org/enter_bug.cgi?product=gnome-shell],[gnome-shell])
AC_CONFIG_HEADERS([config.h])
AC_CONFIG_SRCDIR([src/shell-global.c])
@ -63,7 +63,7 @@ AM_CONDITIONAL(BUILD_RECORDER, $build_recorder)
CLUTTER_MIN_VERSION=1.13.4
GOBJECT_INTROSPECTION_MIN_VERSION=0.10.1
GJS_MIN_VERSION=1.35.4
MUTTER_MIN_VERSION=3.8.0
MUTTER_MIN_VERSION=3.8.3
GTK_MIN_VERSION=3.7.9
GIO_MIN_VERSION=2.35.0
LIBECAL_MIN_VERSION=3.5.3
@ -71,7 +71,7 @@ LIBEDATASERVER_MIN_VERSION=3.5.3
TELEPATHY_GLIB_MIN_VERSION=0.17.5
POLKIT_MIN_VERSION=0.100
STARTUP_NOTIFICATION_MIN_VERSION=0.11
GCR_MIN_VERSION=3.3.90
GCR_MIN_VERSION=3.7.5
GNOME_DESKTOP_REQUIRED_VERSION=3.7.90
GNOME_MENUS_REQUIRED_VERSION=3.5.3
NETWORKMANAGER_MIN_VERSION=0.9.6
@ -96,7 +96,7 @@ PKG_CHECK_MODULES(GNOME_SHELL, gio-unix-2.0 >= $GIO_MIN_VERSION
polkit-agent-1 >= $POLKIT_MIN_VERSION xfixes
libnm-glib libnm-util >= $NETWORKMANAGER_MIN_VERSION
libnm-gtk >= $NETWORKMANAGER_MIN_VERSION
libsecret-unstable gcr-3 >= $GCR_MIN_VERSION)
libsecret-unstable gcr-base-3 >= $GCR_MIN_VERSION)
PKG_CHECK_MODULES(GNOME_SHELL_JS, gio-2.0 gjs-internals-1.0 >= $GJS_MIN_VERSION)
PKG_CHECK_MODULES(ST, clutter-1.0 gtk+-3.0 libcroco-0.6 >= 0.6.8 x11)

View File

@ -15,6 +15,7 @@ desktop_DATA = gnome-shell.desktop gnome-shell-extension-prefs.desktop
introspectiondir = $(datadir)/dbus-1/interfaces
introspection_DATA = \
org.gnome.Shell.Screencast.xml \
org.gnome.Shell.Screenshot.xml \
org.gnome.ShellSearchProvider.xml \
org.gnome.ShellSearchProvider2.xml

View File

@ -0,0 +1,96 @@
<!DOCTYPE node PUBLIC
'-//freedesktop//DTD D-BUS Object Introspection 1.0//EN'
'http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd'>
<node>
<!--
org.gnome.Shell.Screencast:
@short_description: Screencast interface
The interface used to record screen contents.
-->
<interface name="org.gnome.Shell.Screencast">
<!--
Screencast:
@file_template: the template for the filename to use
@options: a dictionary of optional parameters
@success: whether the screencast was started successfully
@filename_used: the file where the screencast is being saved
Records a screencast of the whole screen and saves it
(by default) as webm video under a filename derived from
@file_template. The template is either a relative or absolute
filename which may contain some escape sequences - %d and %t
will be replaced by the start date and time of the recording.
If a relative name is used, the screencast will be saved in the
$XDG_VIDEOS_DIR if it exists, or the home directory otherwise.
The actual filename of the saved video is returned in @filename_used.
The set of optional parameters in @options currently consists of:
'draw-cursor'(b): whether the cursor should be included in the
recording (true)
'framerate'(i): the number of frames per second that should be
recorded if possible (30)
'pipeline'(s): the GStreamer pipeline used to encode recordings
in gst-launch format; if not specified, the
recorder will produce vp8 (webm) video (unset)
-->
<method name="Screencast">
<arg type="s" direction="in" name="file_template"/>
<arg type="a{sv}" direction="in" name="options"/>
<arg type="b" direction="in" name="flash"/>
<arg type="b" direction="out" name="success"/>
<arg type="s" direction="out" name="filename_used"/>
</method>
<!--
ScreencastArea:
@x: the X coordinate of the area to capture
@y: the Y coordinate of the area to capture
@width: the width of the area to capture
@height: the height of the area to capture
@file_template: the template for the filename to use
@options: a dictionary of optional parameters
@success: whether the screencast was started successfully
@filename_used: the file where the screencast is being saved
Records a screencast of the passed in area and saves it
(by default) as webm video under a filename derived from
@file_template. The template is either a relative or absolute
filename which may contain some escape sequences - %d and %t
will be replaced by the start date and time of the recording.
If a relative name is used, the screencast will be saved in the
$XDG_VIDEOS_DIR if it exists, or the home directory otherwise.
The actual filename of the saved video is returned in @filename_used.
The set of optional parameters in @options currently consists of:
'draw-cursor'(b): whether the cursor should be included in the
recording (true)
'framerate'(i): the number of frames per second that should be
recorded if possible (30)
'pipeline'(s): the GStreamer pipeline used to encode recordings
in gst-launch format; if not specified, the
recorder will produce vp8 (webm) video (unset)
-->
<method name="ScreencastArea">
<arg type="i" direction="in" name="x"/>
<arg type="i" direction="in" name="y"/>
<arg type="i" direction="in" name="width"/>
<arg type="i" direction="in" name="height"/>
<arg type="s" direction="in" name="file_template"/>
<arg type="a{sv}" direction="in" name="options"/>
<arg type="b" direction="out" name="success"/>
<arg type="s" direction="out" name="filename_used"/>
</method>
<!--
StopScreencast:
@success: whether stopping the recording was successful
Stop the recording started by either Screencast or ScreencastArea.
-->
<method name="StopScreencast">
<arg type="b" direction="out" name="success"/>
</method>
</interface>
</node>

View File

@ -207,7 +207,7 @@ value here is from the GsmPresenceStatus enumeration.</_summary>
</_description>
</key>
<key type="b" name="current-workspace-only">
<default>false</default>
<default>true</default>
<summary>Limit switcher to current workspace.</summary>
<description>
If true, only windows from the current workspace are shown in the switcher.

View File

@ -512,6 +512,7 @@ StScrollBar StButton#vhandle:active {
}
#appMenu {
spinner-image: url("process-working.svg");
spacing: 4px;
}
@ -799,6 +800,11 @@ StScrollBar StButton#vhandle:active {
height: 24px;
}
.empty-dash-drop-target {
width: 24px;
height: 24px;
}
/* Search Box */
#searchEntry {
@ -886,12 +892,11 @@ StScrollBar StButton#vhandle:active {
}
.app-view-controls {
width: 250px;
padding-bottom: 32px;
}
.app-view-control {
padding: 4px 16px;
padding: 4px 32px;
}
.search-display > StBoxLayout,
@ -1453,11 +1458,13 @@ StScrollBar StButton#vhandle:active {
}
.notification-button {
padding: 4px 42px 5px;
-st-natural-width: 140px;
padding: 4px 4px 5px;
}
.notification-button:focus {
padding: 3px 41px 4px;
-st-natural-width: 138px;
padding: 3px 4px 4px;
}
.notification-icon-button {
@ -2335,52 +2342,47 @@ StScrollBar StButton#vhandle:active {
width: 15em;
}
.login-dialog-session-list {
color: #ffffff;
font-size: 10.5pt;
.login-dialog-session-list,
.login-dialog-session-list-item {
color: #babdb6;
}
.login-dialog-session-list-button:focus,
.login-dialog-session-list-button:active,
.login-dialog-session-list-button:hover,
.login-dialog-session-list-item:focus,
.login-dialog-session-list-item:hover {
color: white;
}
.login-dialog-session-list-button {
padding: 4px;
}
.login-dialog-session-list-button:focus {
background-color: #4c4c4c;
}
.login-dialog-session-list-button:active {
background-color: #4c4c4c;
}
.login-dialog-session-list-button:hover {
font-weight: bold;
}
.login-dialog-session-list-scroll-view {
background-gradient-start: rgba(80,80,80,0.3);
background-gradient-end: rgba(80,80,80,0.7);
background-gradient-direction: vertical;
box-shadow: inset 0px 2px 4px rgba(0,0,0,0.9);
border-radius: 8px;
border: 1px solid rgba(80,80,80,1.0);
padding: .5em;
padding: 6px;
}
.login-dialog-session-list-item:focus {
background-color: #666666;
.login-dialog-session-list-item {
padding-bottom: 6px;
}
.login-dialog-session-list-triangle {
padding-right: .5em;
padding-right: 6px;
}
.login-dialog-session-list-item-box {
spacing: .25em;
padding-left: 6px;
spacing: 6px;
}
.login-dialog-session-list-item-dot {
width: .75em;
height: .75em;
width: 10px;
height: 10px;
}
.login-dialog-logo-bin {
padding: 24px 0px;
}
.login-dialog .modal-dialog-button-box {
@ -2445,7 +2447,6 @@ StScrollBar StButton#vhandle:active {
.screen-shield-background {
background: black;
box-shadow: 0px 4px 8px rgba(0,0,0,0.9);
}
#lockDialogGroup {

View File

@ -46,6 +46,7 @@
<xi:include href="doc-gen-org.gnome.Shell.SearchProvider.xml"/>
<xi:include href="doc-gen-org.gnome.Shell.SearchProvider2.xml"/>
<xi:include href="xml/shell-global.xml"/>
<xi:include href="xml/shell-keybinding-modes.xml"/>
<xi:include href="xml/shell-wm.xml"/>
<xi:include href="xml/shell-xfixes-cursor.xml"/>
<xi:include href="xml/shell-util.xml"/>

View File

@ -78,6 +78,7 @@ nobase_dist_js_DATA = \
ui/popupMenu.js \
ui/remoteSearch.js \
ui/runDialog.js \
ui/screencast.js \
ui/screenshot.js \
ui/screenShield.js \
ui/scripting.js \

View File

@ -28,6 +28,7 @@ const Mainloop = imports.mainloop;
const Meta = imports.gi.Meta;
const Lang = imports.lang;
const Pango = imports.gi.Pango;
const Realmd = imports.gdm.realmd;
const Signals = imports.signals;
const Shell = imports.gi.Shell;
const St = imports.gi.St;
@ -39,7 +40,6 @@ const GdmUtil = imports.gdm.util;
const Lightbox = imports.ui.lightbox;
const Main = imports.ui.main;
const ModalDialog = imports.ui.modalDialog;
const Panel = imports.ui.panel;
const PanelMenu = imports.ui.panelMenu;
const Tweener = imports.ui.tweener;
const UserMenu = imports.ui.userMenu;
@ -48,44 +48,10 @@ const UserWidget = imports.ui.userWidget;
const _FADE_ANIMATION_TIME = 0.25;
const _SCROLL_ANIMATION_TIME = 0.5;
const _TIMED_LOGIN_IDLE_THRESHOLD = 5.0;
const _LOGO_ICON_HEIGHT = 16;
const WORK_SPINNER_ICON_SIZE = 24;
const WORK_SPINNER_ANIMATION_DELAY = 1.0;
const WORK_SPINNER_ANIMATION_TIME = 0.3;
const _LOGO_ICON_HEIGHT = 48;
let _loginDialog = null;
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',
@ -552,6 +518,12 @@ const LoginDialog = new Lang.Class({
Lang.bind(this, this._updateBanner));
this._settings.connect('changed::' + GdmUtil.DISABLE_USER_LIST_KEY,
Lang.bind(this, this._updateDisableUserList));
this._settings.connect('changed::' + GdmUtil.LOGO_KEY,
Lang.bind(this, this._updateLogo));
this._textureCache = St.TextureCache.get_default();
this._textureCache.connect('texture-file-changed',
Lang.bind(this, this._updateLogoTexture));
this._userSelectionBox = new St.BoxLayout({ style_class: 'login-dialog-user-selection-box',
vertical: true });
@ -609,7 +581,6 @@ const LoginDialog = new Lang.Class({
this._promptBox.add(this._promptLoginHint);
this._signInButton = null;
this._workSpinner = null;
this._sessionList = new SessionList();
this._sessionList.connect('session-activated',
@ -644,6 +615,11 @@ const LoginDialog = new Lang.Class({
x_align: St.Align.START,
x_fill: true });
this._logoBin = new St.Bin({ style_class: 'login-dialog-logo-bin', y_expand: true });
this._logoBin.set_y_align(Clutter.ActorAlign.END);
this.backgroundStack.add_actor(this._logoBin);
this._updateLogo();
if (!this._userManager.is_loaded)
this._userManagerLoadedId = this._userManager.connect('notify::is-loaded',
Lang.bind(this, function() {
@ -690,6 +666,24 @@ const LoginDialog = new Lang.Class({
}
},
_updateLogoTexture: function(cache, uri) {
if (this._logoFileUri != uri)
return;
let icon = null;
if (this._logoFileUri)
icon = this._textureCache.load_uri_async(this._logoFileUri,
-1, _LOGO_ICON_HEIGHT);
this._logoBin.set_child(icon);
},
_updateLogo: function() {
let path = this._settings.get_string(GdmUtil.LOGO_KEY);
this._logoFileUri = path ? Gio.file_new_for_path(path).get_uri() : null;
this._updateLogoTexture(this._textureCache, this._logoFileUri);
},
_reset: function() {
this._userVerifier.clear();
@ -708,7 +702,7 @@ const LoginDialog = new Lang.Class({
this._promptEntry.text = '';
this._updateSensitivity(true);
this._setWorking(false);
this.setWorking(false);
},
_onDefaultSessionChanged: function(client, sessionId) {
@ -774,10 +768,6 @@ const LoginDialog = new Lang.Class({
},
_prepareDialog: function(forSecret, hold) {
this._workSpinner = new Panel.AnimatedIcon('process-working.svg', WORK_SPINNER_ICON_SIZE);
this._workSpinner.actor.opacity = 0;
this._workSpinner.actor.show();
this.buttonLayout.visible = true;
this.clearButtons();
@ -790,12 +780,11 @@ const LoginDialog = new Lang.Class({
y_fill: false,
x_align: St.Align.START,
y_align: St.Align.MIDDLE });
this.buttonLayout.add(this._workSpinner.actor,
{ expand: false,
x_fill: false,
y_fill: false,
x_align: St.Align.END,
y_align: St.Align.MIDDLE });
this.placeSpinner({ expand: false,
x_fill: false,
y_fill: false,
x_align: St.Align.END,
y_align: St.Align.MIDDLE });
this._signInButton = this.addButton({ action: Lang.bind(this, function() {
hold.release();
}),
@ -848,7 +837,7 @@ const LoginDialog = new Lang.Class({
this._promptEntryActivateId = 0;
}
this._setWorking(false);
this.setWorking(false);
this._promptBox.hide();
this._promptLoginHint.hide();
@ -861,36 +850,9 @@ const LoginDialog = new Lang.Class({
this._promptLoginHint.hide();
this.clearButtons();
this._workSpinner = null;
this._signInButton = null;
},
_setWorking: function(working) {
if (!this._workSpinner)
return;
if (working) {
this._workSpinner.play();
Tweener.addTween(this._workSpinner.actor,
{ opacity: 255,
delay: WORK_SPINNER_ANIMATION_DELAY,
time: WORK_SPINNER_ANIMATION_TIME,
transition: 'linear'
});
} else {
Tweener.addTween(this._workSpinner.actor,
{ opacity: 0,
time: WORK_SPINNER_ANIMATION_TIME,
transition: 'linear',
onCompleteScope: this,
onComplete: function() {
if (this._workSpinner)
this._workSpinner.stop();
}
});
}
},
_askQuestion: function(verifier, serviceName, question, passwordChar) {
this._promptLabel.set_text(question);
@ -905,7 +867,7 @@ const LoginDialog = new Lang.Class({
function() {
let text = this._promptEntry.get_text();
this._updateSensitivity(false);
this._setWorking(true);
this.setWorking(true);
this._userVerifier.answerQuery(serviceName, text);
}];
@ -913,17 +875,40 @@ const LoginDialog = new Lang.Class({
return batch.run();
},
_showRealmLoginHint: function(realmManager, hint) {
if (!hint)
return;
hint = hint.replace(/%U/g, 'user');
hint = hint.replace(/%D/g, 'DOMAIN');
hint = hint.replace(/%[^UD]/g, '');
// Translators: this message is shown below the username entry field
// to clue the user in on how to login to the local network realm
this._showLoginHint(null, _("(e.g., user or %s)").format(hint));
},
_askForUsernameAndLogIn: function() {
this._promptLabel.set_text(_("Username: "));
this._promptEntry.set_text('');
this._promptEntry.clutter_text.set_password_char('');
let realmManager = new Realmd.Manager();
let signalId = realmManager.connect('login-format-changed',
Lang.bind(this, this._showRealmLoginHint));
this._showRealmLoginHint(realmManager.loginFormat);
let tasks = [this._showPrompt,
function() {
let userName = this._promptEntry.get_text();
this._promptEntry.reactive = false;
return this._beginVerificationForUser(userName);
},
function() {
realmManager.disconnect(signalId)
realmManager.release();
}];
let batch = new Batch.ConsecutiveBatch(this, tasks);

View File

@ -63,7 +63,7 @@ const Manager = new Lang.Class({
Lang.bind(this, this._reloadRealms))
this._realms = {};
this._aggregateProvider.connect('g-properties-changed',
this._signalId = this._aggregateProvider.connect('g-properties-changed',
Lang.bind(this, function(proxy, properties) {
if ('Realms' in properties.deep_unpack())
this._reloadRealms();
@ -106,7 +106,7 @@ const Manager = new Lang.Class({
realm.connect('g-properties-changed',
Lang.bind(this, function(proxy, properties) {
if ('Configured' in properties.deep_unpack())
this._reloadRealm();
this._reloadRealm(realm);
}));
},
@ -134,6 +134,18 @@ const Manager = new Lang.Class({
this._updateLoginFormat();
return this._loginFormat;
},
release: function() {
Service(Gio.DBus.system,
'org.freedesktop.realmd',
'/org/freedesktop/realmd',
function(service) {
service.ReleaseRemote();
});
this._aggregateProvider.disconnect(this._signalId);
this._realms = { };
this._updateLoginFormat();
}
});
Signals.addSignalMethods(Manager.prototype)

View File

@ -9,7 +9,6 @@ const Signals = imports.signals;
const Batch = imports.gdm.batch;
const Fprint = imports.gdm.fingerprint;
const Realmd = imports.gdm.realmd;
const Main = imports.ui.main;
const Params = imports.misc.params;
const Tweener = imports.ui.tweener;
@ -117,7 +116,6 @@ const ShellUserVerifier = new Lang.Class({
this._settings = new Gio.Settings({ schema: LOGIN_SCREEN_SCHEMA });
this._fprintManager = new Fprint.FprintManager();
this._realmManager = new Realmd.Manager();
this._messageQueue = [];
this._messageQueueTimeoutId = 0;
this.hasPendingMessages = false;
@ -377,30 +375,11 @@ const ShellUserVerifier = new Lang.Class({
this._queueMessage(problem, 'login-dialog-message-warning');
},
_showRealmLoginHint: function() {
if (this._realmManager.loginFormat) {
let hint = this._realmManager.loginFormat;
hint = hint.replace(/%U/g, 'user');
hint = hint.replace(/%D/g, 'DOMAIN');
hint = hint.replace(/%[^UD]/g, '');
// Translators: this message is shown below the username entry field
// to clue the user in on how to login to the local network realm
this.emit('show-login-hint',
_("(e.g., user or %s)").format(hint));
}
},
_onInfoQuery: function(client, serviceName, question) {
// We only expect questions to come from the main auth service
if (serviceName != PASSWORD_SERVICE_NAME)
return;
this._showRealmLoginHint();
this._realmLoginHintSignalId = this._realmManager.connect('login-format-changed',
Lang.bind(this, this._showRealmLoginHint));
this.emit('ask-question', serviceName, question, '');
},
@ -476,11 +455,6 @@ const ShellUserVerifier = new Lang.Class({
}
this.emit('hide-login-hint');
if (this._realmLoginHintSignalId) {
this._realmManager.disconnect(this._realmLoginHintSignalId);
this._realmLoginHintSignalId = 0;
}
},
});
Signals.addSignalMethods(ShellUserVerifier.prototype);

View File

@ -233,8 +233,10 @@ const AppSwitcherPopup = new Lang.Class({
_finish : function(timestamp) {
let appIcon = this._items[this._selectedIndex];
let window = this._currentWindow > 0 ? this._currentWindow : 0;
appIcon.app.activate_window(appIcon.cachedWindows[window], timestamp);
if (this._currentWindow < 0)
appIcon.app.activate_window(appIcon.cachedWindows[0], timestamp);
else
Main.activateWindow(appIcon.cachedWindows[this._currentWindow], timestamp);
this.parent();
},

View File

@ -187,6 +187,9 @@ const AllView = new Lang.Class({
_init: function() {
this.parent();
this._grid.actor.y_align = Clutter.ActorAlign.START;
this._grid.actor.y_expand = true;
let box = new St.BoxLayout({ vertical: true });
this._stack = new St.Widget({ layout_manager: new AllViewLayout() });
this._stack.add_actor(this._grid.actor);
@ -276,8 +279,12 @@ const AllView = new Lang.Class({
this._eventBlocker.reactive = isOpen;
this._currentPopup = isOpen ? popup : null;
this._updateIconOpacities(isOpen);
if (isOpen)
if (isOpen) {
this._ensureIconVisible(popup.actor);
this._grid.actor.y = popup.parentOffset;
} else {
this._grid.actor.y = 0;
}
}));
},
@ -327,6 +334,42 @@ const Views = {
ALL: 1
};
const ControlsBoxLayout = Lang.Class({
Name: 'ControlsBoxLayout',
Extends: Clutter.BoxLayout,
/**
* Override the BoxLayout behavior to use the maximum preferred width of all
* buttons for each child
*/
vfunc_get_preferred_width: function(container, forHeight) {
let maxMinWidth = 0;
let maxNaturalWidth = 0;
for (let child = container.get_first_child();
child;
child = child.get_next_sibling()) {
let [minWidth, natWidth] = child.get_preferred_width(forHeight);
maxMinWidth = Math.max(maxMinWidth, minWidth);
maxNaturalWidth = Math.max(maxNaturalWidth, natWidth);
}
let childrenCount = container.get_n_children();
let totalSpacing = this.spacing * (childrenCount - 1);
return [maxMinWidth * childrenCount + totalSpacing,
maxNaturalWidth * childrenCount + totalSpacing];
},
vfunc_set_container: function(container) {
if(this._styleChangedId) {
this._container.disconnect(this._styleChangedId);
this._styleChangedId = 0;
}
if(container != null)
this._styleChangedId = container.connect('style-changed', Lang.bind(this,
function() { this.spacing = this._container.get_theme_node().get_length('spacing'); }));
this._container = container;
}
});
const AppDisplay = new Lang.Class({
Name: 'AppDisplay',
@ -367,9 +410,9 @@ const AppDisplay = new Lang.Class({
x_expand: true, y_expand: true });
this.actor.add(this._viewStack, { expand: true });
let layout = new Clutter.BoxLayout({ homogeneous: true });
this._controls = new St.Widget({ style_class: 'app-view-controls',
layout_manager: layout });
let layout = new ControlsBoxLayout({ homogeneous: true });
this._controls = new St.Widget({ style_class: 'app-view-controls' });
this._controls.set_layout_manager(layout);
this.actor.add(new St.Bin({ child: this._controls }));
@ -572,7 +615,11 @@ const FolderIcon = new Lang.Class({
// Position the popup above or below the source icon
if (side == St.Side.BOTTOM) {
this._popup.actor.show();
this._popup.actor.y = this.actor.y - this._popup.actor.height;
let closeButtonOffset = -this._popup.closeButton.translation_y;
let y = this.actor.y - this._popup.actor.height;
let yWithButton = y - closeButtonOffset;
this._popup.parentOffset = yWithButton < 0 ? -yWithButton : 0;
this._popup.actor.y = Math.max(y, closeButtonOffset);
this._popup.actor.hide();
} else {
this._popup.actor.y = this.actor.y + this.actor.height;
@ -595,6 +642,7 @@ const AppFolderPopup = new Lang.Class({
this._arrowSide = side;
this._isOpen = false;
this.parentOffset = 0;
this.actor = new St.Widget({ layout_manager: new Clutter.BinLayout(),
visible: false,
@ -618,17 +666,31 @@ const AppFolderPopup = new Lang.Class({
this.actor.add_actor(this._boxPointer.actor);
this._boxPointer.bin.set_child(this._view.actor);
let closeButton = Util.makeCloseButton();
closeButton.connect('clicked', Lang.bind(this, this.popdown));
this.actor.add_actor(closeButton);
this.closeButton = Util.makeCloseButton();
this.closeButton.connect('clicked', Lang.bind(this, this.popdown));
this.actor.add_actor(this.closeButton);
this._boxPointer.actor.bind_property('opacity', closeButton, 'opacity',
this._boxPointer.actor.bind_property('opacity', this.closeButton, 'opacity',
GObject.BindingFlags.SYNC_CREATE);
global.focus_manager.add_group(this.actor);
source.actor.connect('destroy', Lang.bind(this,
function() {
this.actor.destroy();
}));
this.actor.connect('key-press-event', Lang.bind(this, this._onKeyPress));
},
_onKeyPress: function(actor, event) {
if (!this._isOpen)
return false;
if (event.get_key_symbol() != Clutter.KEY_Escape)
return false;
this.popdown();
return true;
},
toggle: function() {
@ -643,6 +705,7 @@ const AppFolderPopup = new Lang.Class({
return;
this.actor.show();
this.actor.navigate_focus(null, Gtk.DirectionType.TAB_FORWARD, false);
this._boxPointer.setArrowActor(this._source.actor);
this._boxPointer.show(BoxPointer.PopupAnimation.FADE |

View File

@ -126,6 +126,11 @@ const BackgroundCache = new Lang.Class({
},
removeImageContent: function(content) {
let filename = content.get_filename();
if (filename && this._fileMonitors[filename])
delete this._fileMonitors[filename];
this._removeContent(this._images, content);
},
@ -426,7 +431,7 @@ const Background = new Lang.Class({
content.brightness = this._brightness;
content.vignette_sharpness = this._vignetteSharpness;
this._cache.removeImageContent(content);
this._cache.removeImageContent(this._images[index].content);
this._images[index].content = content;
this._watchCacheFile(filename);
},
@ -742,11 +747,15 @@ const BackgroundManager = new Lang.Class({
time: FADE_ANIMATION_TIME,
transition: 'easeOutQuad',
onComplete: Lang.bind(this, function() {
if (this.background == background) {
if (this._newBackground == newBackground) {
this.background = newBackground;
this._newBackground = null;
background.actor.destroy();
} else {
newBackground.actor.destroy();
}
background.actor.destroy();
this.emit('changed');
})
});

View File

@ -46,8 +46,10 @@ function addBackgroundMenu(actor) {
clickAction.connect('long-press', function(action, actor, state) {
if (state == Clutter.LongPressState.QUERY)
return action.get_button() == 1 && !actor._backgroundMenu.isOpen;
if (state == Clutter.LongPressState.ACTIVATE)
if (state == Clutter.LongPressState.ACTIVATE) {
openMenu();
actor._backgroundManager.ignoreRelease();
}
return true;
});
clickAction.connect('clicked', function(action) {
@ -60,5 +62,7 @@ function addBackgroundMenu(actor) {
actor._backgroundMenu.destroy();
actor._backgroundMenu = null;
actor._backgroundManager = null;
cursor.destroy();
});
}

View File

@ -25,7 +25,7 @@ const KeyringDialog = new Lang.Class({
this.prompt = new Shell.KeyringPrompt();
this.prompt.connect('show-password', Lang.bind(this, this._onShowPassword));
this.prompt.connect('show-confirm', Lang.bind(this, this._onShowConfirm));
this.prompt.connect('hide-prompt', Lang.bind(this, this._onHidePrompt));
this.prompt.connect('prompt-close', Lang.bind(this, this._onHidePrompt));
let mainContentBox = new St.BoxLayout({ style_class: 'prompt-dialog-main-layout',
vertical: false });
@ -63,11 +63,17 @@ const KeyringDialog = new Lang.Class({
this._cancelButton = this.addButton({ label: '',
action: Lang.bind(this, this._onCancelButton),
key: Clutter.Escape });
key: Clutter.Escape },
{ expand: true, x_fill: false, x_align: St.Align.START });
this.placeSpinner({ expand: false,
x_fill: false,
y_fill: false,
x_align: St.Align.END,
y_align: St.Align.MIDDLE });
this._continueButton = this.addButton({ label: '',
action: Lang.bind(this, this._onContinueButton),
default: true },
{ expand: true, x_fill: false, x_align: St.Align.END });
{ expand: false, x_fill: false, x_align: St.Align.END });
this.prompt.bind_property('cancel-label', this._cancelButton, 'label', GObject.BindingFlags.SYNC_CREATE);
this.prompt.bind_property('continue-label', this._continueButton, 'label', GObject.BindingFlags.SYNC_CREATE);
@ -143,11 +149,19 @@ const KeyringDialog = new Lang.Class({
},
_updateSensitivity: function(sensitive) {
this._passwordEntry.reactive = sensitive;
this._passwordEntry.clutter_text.editable = sensitive;
if (this._passwordEntry) {
this._passwordEntry.reactive = sensitive;
this._passwordEntry.clutter_text.editable = sensitive;
}
if (this._confirmEntry) {
this._confirmEntry.reactive = sensitive;
this._confirmEntry.clutter_text.editable = sensitive;
}
this._continueButton.can_focus = sensitive;
this._continueButton.reactive = sensitive;
this.setWorking(!sensitive);
},
_ensureOpen: function() {

View File

@ -31,7 +31,6 @@ const AuthenticationDialog = new Lang.Class({
this.message = message;
this.userNames = userNames;
this._wasDismissed = false;
this._completed = false;
let mainContentBox = new St.BoxLayout({ style_class: 'prompt-dialog-main-layout',
vertical: false });
@ -161,26 +160,32 @@ const AuthenticationDialog = new Lang.Class({
this._cancelButton = this.addButton({ label: _("Cancel"),
action: Lang.bind(this, this.cancel),
key: Clutter.Escape });
key: Clutter.Escape },
{ expand: true, x_fill: false, x_align: St.Align.START });
this.placeSpinner({ expand: false,
x_fill: false,
y_fill: false,
x_align: St.Align.END,
y_align: St.Align.MIDDLE });
this._okButton = this.addButton({ label: _("Authenticate"),
action: Lang.bind(this, this._onAuthenticateButtonPressed),
default: true },
{ expand: true, x_fill: false, x_align: St.Align.END });
{ expand: false, x_fill: false, x_align: St.Align.END });
this._doneEmitted = false;
this._identityToAuth = Polkit.UnixUser.new_for_name(userName);
this._cookie = cookie;
},
performAuthentication: function() {
this.destroySession();
this._session = new PolkitAgent.Session({ identity: this._identityToAuth,
cookie: this._cookie });
this._session.connect('completed', Lang.bind(this, this._onSessionCompleted));
this._session.connect('request', Lang.bind(this, this._onSessionRequest));
this._session.connect('show-error', Lang.bind(this, this._onSessionShowError));
this._session.connect('show-info', Lang.bind(this, this._onSessionShowInfo));
},
startAuthentication: function() {
this._session.initiate();
},
@ -202,14 +207,14 @@ const AuthenticationDialog = new Lang.Class({
log('polkitAuthenticationAgent: Failed to show modal dialog.' +
' Dismissing authentication request for action-id ' + this.actionId +
' cookie ' + this._cookie);
this._emitDone(false, true);
this._emitDone(true);
}
},
_emitDone: function(keepVisible, dismissed) {
_emitDone: function(dismissed) {
if (!this._doneEmitted) {
this._doneEmitted = true;
this.emit('done', keepVisible, dismissed);
this.emit('done', dismissed);
}
},
@ -219,6 +224,7 @@ const AuthenticationDialog = new Lang.Class({
this._okButton.can_focus = sensitive;
this._okButton.reactive = sensitive;
this.setWorking(!sensitive);
},
_onEntryActivate: function() {
@ -237,12 +243,16 @@ const AuthenticationDialog = new Lang.Class({
},
_onSessionCompleted: function(session, gainedAuthorization) {
if (this._completed)
if (this._completed || this._doneEmitted)
return;
this._completed = true;
if (!gainedAuthorization) {
/* Yay, all done */
if (gainedAuthorization) {
this._emitDone(false);
} else {
/* Unless we are showing an existing error message from the PAM
* module (the PAM module could be reporting the authentication
* error providing authentication-method specific information),
@ -258,8 +268,10 @@ const AuthenticationDialog = new Lang.Class({
this._infoMessageLabel.hide();
this._nullMessageLabel.hide();
}
/* Try and authenticate again */
this.performAuthentication();
}
this._emitDone(!gainedAuthorization, false);
},
_onSessionRequest: function(session, request, echo_on) {
@ -303,6 +315,7 @@ const AuthenticationDialog = new Lang.Class({
if (this._session) {
if (!this._completed)
this._session.cancel();
this._completed = false;
this._session = null;
}
},
@ -317,7 +330,7 @@ const AuthenticationDialog = new Lang.Class({
cancel: function() {
this._wasDismissed = true;
this.close(global.get_current_time());
this._emitDone(false, true);
this._emitDone(true);
},
});
Signals.addSignalMethods(AuthenticationDialog.prototype);
@ -327,7 +340,6 @@ const AuthenticationAgent = new Lang.Class({
_init: function() {
this._currentDialog = null;
this._isCompleting = false;
this._handle = null;
this._native = new Shell.PolkitAuthenticationAgent();
this._native.connect('initiate', Lang.bind(this, this._onInitiate));
@ -364,45 +376,24 @@ const AuthenticationAgent = new Lang.Class({
// discussion.
this._currentDialog.connect('done', Lang.bind(this, this._onDialogDone));
this._currentDialog.startAuthentication();
this._currentDialog.performAuthentication();
},
_onCancel: function(nativeAgent) {
this._completeRequest(false, false);
this._completeRequest(false);
},
_onDialogDone: function(dialog, keepVisible, dismissed) {
this._completeRequest(keepVisible, dismissed);
_onDialogDone: function(dialog, dismissed) {
this._completeRequest(dismissed);
},
_reallyCompleteRequest: function(dismissed) {
_completeRequest: function(dismissed) {
this._currentDialog.close();
this._currentDialog.destroySession();
this._currentDialog = null;
this._isCompleting = false;
this._native.complete(dismissed)
this._native.complete(dismissed);
},
_completeRequest: function(keepVisible, wasDismissed) {
if (this._isCompleting)
return;
this._isCompleting = true;
if (keepVisible) {
// Give the user 2 seconds to read 'Authentication Failure' before
// dismissing the dialog
Mainloop.timeout_add(2000,
Lang.bind(this,
function() {
this._reallyCompleteRequest(wasDismissed);
return false;
}));
} else {
this._reallyCompleteRequest(wasDismissed);
}
}
});
const Component = AuthenticationAgent;

View File

@ -20,8 +20,7 @@ const Recorder = new Lang.Class({
Main.wm.addKeybinding('toggle-recording',
this._bindingSettings,
Meta.KeyBindingFlags.NONE,
Shell.KeyBindingMode.NORMAL |
Shell.KeyBindingMode.OVERVIEW,
Shell.KeyBindingMode.ALL,
Lang.bind(this, this._toggleRecorder));
},

View File

@ -89,19 +89,25 @@ const CtrlAltTabManager = new Lang.Class({
let items = this._items.filter(function (item) { return item.proxy.mapped; });
// And add the windows metacity would show in its Ctrl-Alt-Tab list
if (!Main.overview.visible) {
if (Main.sessionMode.hasWindows && !Main.overview.visible) {
let screen = global.screen;
let display = screen.get_display();
let windows = display.get_tab_list(Meta.TabList.DOCKS, screen, screen.get_active_workspace ());
let windowTracker = Shell.WindowTracker.get_default();
let textureCache = St.TextureCache.get_default();
for (let i = 0; i < windows.length; i++) {
let icon;
let app = windowTracker.get_window_app(windows[i]);
if (app)
icon = app.create_icon_texture(POPUP_APPICON_SIZE);
else
icon = textureCache.bind_pixbuf_property(windows[i], 'icon');
let icon = null;
let iconName = null;
if (windows[i].get_window_type () == Meta.WindowType.DESKTOP) {
iconName = 'video-display-symbolic';
} else {
let app = windowTracker.get_window_app(windows[i]);
if (app)
icon = app.create_icon_texture(POPUP_APPICON_SIZE);
else
icon = textureCache.bind_pixbuf_property(windows[i], 'icon');
}
items.push({ name: windows[i].title,
proxy: windows[i].get_compositor_private(),
focusCallback: Lang.bind(windows[i],
@ -109,6 +115,7 @@ const CtrlAltTabManager = new Lang.Class({
Main.activateWindow(this, timestamp);
}),
iconActor: icon,
iconName: iconName,
sortGroup: SortGroup.MIDDLE });
}
}

View File

@ -326,6 +326,16 @@ const DragPlaceholderItem = new Lang.Class({
}
});
const EmptyDropTargetItem = new Lang.Class({
Name: 'EmptyDropTargetItem',
Extends: DashItemContainer,
_init: function() {
this.parent();
this.setChild(new St.Bin({ style_class: 'empty-dash-drop-target' }));
}
});
const DashActor = new Lang.Class({
Name: 'DashActor',
Extends: St.Widget,
@ -441,6 +451,12 @@ const Dash = new Lang.Class({
dragMotion: Lang.bind(this, this._onDragMotion)
};
DND.addDragMonitor(this._dragMonitor);
if (this._box.get_n_children() == 0) {
this._emptyDropTarget = new EmptyDropTargetItem();
this._box.insert_child_at_index(this._emptyDropTarget, 0);
this._emptyDropTarget.show(true);
}
},
_onDragCancelled: function() {
@ -457,6 +473,7 @@ const Dash = new Lang.Class({
_endDrag: function() {
this._clearDragPlaceholder();
this._clearEmptyDropTarget();
this._showAppsIcon.setDragApp(null);
DND.removeDragMonitor(this._dragMonitor);
},
@ -797,9 +814,21 @@ const Dash = new Lang.Class({
_clearDragPlaceholder: function() {
if (this._dragPlaceholder) {
this._animatingPlaceholdersCount++;
this._dragPlaceholder.animateOutAndDestroy();
this._dragPlaceholder.connect('destroy',
Lang.bind(this, function() {
this._animatingPlaceholdersCount--;
}));
this._dragPlaceholder = null;
this._dragPlaceholderPos = -1;
}
this._dragPlaceholderPos = -1;
},
_clearEmptyDropTarget: function() {
if (this._emptyDropTarget) {
this._emptyDropTarget.animateOutAndDestroy();
this._emptyDropTarget = null;
}
},
@ -827,23 +856,18 @@ const Dash = new Lang.Class({
numChildren--;
}
let pos = Math.floor(y * numChildren / boxHeight);
let pos;
if (!this._emptyDropTarget)
pos = Math.floor(y * numChildren / boxHeight);
else
pos = 0; // always insert at the top when dash is empty
if (pos != this._dragPlaceholderPos && pos <= numFavorites && this._animatingPlaceholdersCount == 0) {
this._dragPlaceholderPos = pos;
// Don't allow positioning before or after self
if (favPos != -1 && (pos == favPos || pos == favPos + 1)) {
if (this._dragPlaceholder) {
this._dragPlaceholder.animateOutAndDestroy();
this._animatingPlaceholdersCount++;
this._dragPlaceholder.connect('destroy',
Lang.bind(this, function() {
this._animatingPlaceholdersCount--;
}));
}
this._dragPlaceholder = null;
this._clearDragPlaceholder();
return DND.DragMotionResult.CONTINUE;
}
@ -868,9 +892,9 @@ const Dash = new Lang.Class({
// Remove the drag placeholder if we are not in the
// "favorites zone"
if (pos > numFavorites && this._dragPlaceholder) {
if (pos > numFavorites)
this._clearDragPlaceholder();
}
if (!this._dragPlaceholder)
return DND.DragMotionResult.NO_DROP;

View File

@ -100,7 +100,6 @@ const DateMenuButton = new Lang.Class({
Shell.AppSystem.get_default().connect('installed-changed',
Lang.bind(this, this._appInstalledChanged));
this._appInstalledChanged();
item = this.menu.addSettingsAction(_("Date & Time Settings"), 'gnome-datetime-panel.desktop');
if (item) {
@ -157,14 +156,16 @@ const DateMenuButton = new Lang.Class({
},
_appInstalledChanged: function() {
let app = Shell.AppSystem.get_default().lookup_app('gnome-clocks.desktop');
this._openClocksItem.actor.visible = app !== null;
this._calendarApp = undefined;
this._updateEventsVisibility();
},
_updateEventsVisibility: function() {
let visible = this._eventSource.hasCalendars;
this._openCalendarItem.actor.visible = visible;
this._openClocksItem.actor.visible = visible;
this._openCalendarItem.actor.visible = visible &&
(this._getCalendarApp() != null);
this._openClocksItem.actor.visible = visible &&
(this._getClockApp() != null);
this._separator.visible = visible;
if (visible) {
let alignment = 0.25;
@ -217,18 +218,34 @@ const DateMenuButton = new Lang.Class({
this._date.set_text(displayDate.toLocaleFormat(dateFormat));
},
_getCalendarApp: function() {
if (this._calendarApp !== undefined)
return this._calendarApp;
let apps = Gio.AppInfo.get_recommended_for_type('text/calendar');
if (apps && (apps.length > 0))
this._calendarApp = apps[0];
else
this._calendarApp = null;
return this._calendarApp;
},
_getClockApp: function() {
return Shell.AppSystem.get_default().lookup_app('gnome-clocks.desktop');
},
_onOpenCalendarActivate: function() {
this.menu.close();
let app = Gio.AppInfo.get_default_for_type('text/calendar', false);
if (app.get_id() == 'evolution')
app = Gio.DesktopAppInfo.new('evolution-calendar');
let app = this._getCalendarApp();
if (app.get_id() == 'evolution.desktop')
app = Gio.DesktopAppInfo.new('evolution-calendar.desktop');
app.launch([], global.create_app_launch_context());
},
_onOpenClocksActivate: function() {
this.menu.close();
let app = Shell.AppSystem.get_default().lookup_app('gnome-clocks.desktop');
let app = this._getClockApp();
app.activate();
}
});

View File

@ -149,16 +149,16 @@ const _Draggable = new Lang.Class({
_grabEvents: function() {
if (!this._eventsGrabbed) {
Clutter.grab_pointer(_getEventHandlerActor());
Clutter.grab_keyboard(_getEventHandlerActor());
this._eventsGrabbed = true;
this._eventsGrabbed = Main.pushModal(_getEventHandlerActor());
if (this._eventsGrabbed)
Clutter.grab_pointer(_getEventHandlerActor());
}
},
_ungrabEvents: function() {
if (this._eventsGrabbed) {
Clutter.ungrab_pointer();
Clutter.ungrab_keyboard();
Main.popModal(_getEventHandlerActor());
this._eventsGrabbed = false;
}
},
@ -291,19 +291,19 @@ const _Draggable = new Lang.Class({
this._dragOrigY = this._dragActor.y;
this._dragOrigScale = this._dragActor.scale_x;
this._dragActor.reparent(Main.uiGroup);
this._dragActor.raise_top();
Shell.util_set_hidden_from_pick(this._dragActor, true);
// Set the actor's scale such that it will keep the same
// transformed size when it's reparented to the uiGroup
let [scaledWidth, scaledHeight] = this.actor.get_transformed_size();
this._dragActor.set_scale(scaledWidth / this.actor.width,
scaledHeight / this.actor.height);
let [actorStageX, actorStageY] = this.actor.get_transformed_position();
this._dragOffsetX = actorStageX - this._dragStartX;
this._dragOffsetY = actorStageY - this._dragStartY;
// Set the actor's scale such that it will keep the same
// transformed size when it's reparented to the uiGroup
let [scaledWidth, scaledHeight] = this.actor.get_transformed_size();
this.actor.set_scale(scaledWidth / this.actor.width,
scaledHeight / this.actor.height);
this._dragActor.reparent(Main.uiGroup);
this._dragActor.raise_top();
Shell.util_set_hidden_from_pick(this._dragActor, true);
}
this._dragOrigOpacity = this._dragActor.opacity;

View File

@ -1092,12 +1092,21 @@ const HotCorner = new Lang.Class({
}
if (size > 0) {
this._verticalBarrier = new Meta.Barrier({ display: global.display,
x1: this._x, x2: this._x, y1: this._y, y2: this._y + size,
directions: Meta.BarrierDirection.POSITIVE_X });
this._horizontalBarrier = new Meta.Barrier({ display: global.display,
x1: this._x, x2: this._x + size, y1: this._y, y2: this._y,
directions: Meta.BarrierDirection.POSITIVE_Y });
if (Clutter.get_default_text_direction() == Clutter.TextDirection.RTL) {
this._verticalBarrier = new Meta.Barrier({ display: global.display,
x1: this._x, x2: this._x, y1: this._y, y2: this._y + size,
directions: Meta.BarrierDirection.NEGATIVE_X });
this._horizontalBarrier = new Meta.Barrier({ display: global.display,
x1: this._x - size, x2: this._x, y1: this._y, y2: this._y,
directions: Meta.BarrierDirection.POSITIVE_Y });
} else {
this._verticalBarrier = new Meta.Barrier({ display: global.display,
x1: this._x, x2: this._x, y1: this._y, y2: this._y + size,
directions: Meta.BarrierDirection.POSITIVE_X });
this._horizontalBarrier = new Meta.Barrier({ display: global.display,
x1: this._x, x2: this._x + size, y1: this._y, y2: this._y,
directions: Meta.BarrierDirection.POSITIVE_Y });
}
this._pressureBarrier.addBarrier(this._verticalBarrier);
this._pressureBarrier.addBarrier(this._horizontalBarrier);

View File

@ -38,7 +38,6 @@ const Magnifier = imports.ui.magnifier;
const XdndHandler = imports.ui.xdndHandler;
const Util = imports.misc.util;
const OVERRIDES_SCHEMA = 'org.gnome.shell.overrides';
const DEFAULT_BACKGROUND_COLOR = Clutter.Color.from_pixel(0x2e3436ff);
let componentManager = null;
@ -68,7 +67,7 @@ let layoutManager = null;
let _startDate;
let _defaultCssStylesheet = null;
let _cssStylesheet = null;
let _overridesSettings = null;
let _workspacesSettings = null;
function _sessionUpdated() {
_loadDefaultStylesheet();
@ -106,6 +105,7 @@ function start() {
function _sessionsLoaded() {
sessionMode.connect('updated', _sessionUpdated);
_initializePrefs();
_initializeUI();
shellDBusService = new ShellDBus.GnomeShell();
@ -114,6 +114,21 @@ function _sessionsLoaded() {
_sessionUpdated();
}
function _initializePrefs() {
let keys = new Gio.Settings({ schema: sessionMode.overridesSchema }).list_keys();
for (let i = 0; i < keys.length; i++)
Meta.prefs_override_preference_schema (keys[i], sessionMode.overridesSchema);
let workspacesSchema;
if (keys.indexOf('dynamic-workspaces') > -1)
workspacesSchema = sessionMode.overridesSchema;
else
workspacesSchema = 'org.gnome.mutter';
_workspacesSettings = new Gio.Settings({ schema: workspacesSchema });
_workspacesSettings.connect('changed::dynamic-workspaces', _queueCheckWorkspaces);
}
function _initializeUI() {
// Ensure ShellWindowTracker and ShellAppUsage are initialized; this will
// also initialize ShellAppSystem first. ShellAppSystem
@ -179,9 +194,6 @@ function _initializeUI() {
Scripting.runPerfScript(module, perfOutput);
}
_overridesSettings = new Gio.Settings({ schema: OVERRIDES_SCHEMA });
_overridesSettings.connect('changed::dynamic-workspaces', _queueCheckWorkspaces);
global.screen.connect('notify::n-workspaces', _nWorkspacesChanged);
global.screen.connect('window-entered-monitor', _windowEnteredMonitor);

View File

@ -1721,6 +1721,9 @@ const MessageTray = new Lang.Class({
this.actor.add_action(clickAction);
clickAction.connect('clicked', Lang.bind(this, function(action) {
if (this._trayState != State.SHOWN)
return;
let button = action.get_button();
if (button == 3)
this._openContextMenu();
@ -1731,7 +1734,7 @@ const MessageTray = new Lang.Class({
clickAction.connect('long-press', Lang.bind(this, function(action, actor, state) {
switch (state) {
case Clutter.LongPressState.QUERY:
return true;
return this._trayState == State.SHOWN;
case Clutter.LongPressState.ACTIVATE:
this._openContextMenu();
}
@ -2242,10 +2245,15 @@ const MessageTray = new Lang.Class({
let canShowSummaryBoxPointer = this._trayState == State.SHOWN;
// We only have sources with empty notification stacks for legacy tray icons. Currently, we never attempt
// to show notifications for legacy tray icons, but this would be necessary if we did.
let requestedNotificationStackIsEmpty = (this._clickedSummaryItemMouseButton == 1 && this._clickedSummaryItem.source.notifications.length == 0);
let wrongSummaryNotificationStack = (this._clickedSummaryItemMouseButton == 1 &&
let requestedNotificationStackIsEmpty = (haveClickedSummaryItem &&
this._clickedSummaryItemMouseButton == 1 &&
this._clickedSummaryItem.source.notifications.length == 0);
let wrongSummaryNotificationStack = (haveClickedSummaryItem &&
this._clickedSummaryItemMouseButton == 1 &&
this._summaryBoxPointer.bin.child != this._clickedSummaryItem.notificationStackWidget);
let wrongSummaryRightClickMenu = (this._clickedSummaryItemMouseButton == 3 &&
let wrongSummaryRightClickMenu = (haveClickedSummaryItem &&
this._clickedSummaryItemMouseButton == 3 &&
this._clickedSummaryItem.rightClickMenu != null &&
this._summaryBoxPointer.bin.child != this._clickedSummaryItem.rightClickMenu);
let wrongSummaryBoxPointer = (haveClickedSummaryItem &&
(wrongSummaryNotificationStack || wrongSummaryRightClickMenu));

View File

@ -22,6 +22,10 @@ const Tweener = imports.ui.tweener;
const OPEN_AND_CLOSE_TIME = 0.1;
const FADE_OUT_DIALOG_TIME = 1.0;
const WORK_SPINNER_ICON_SIZE = 24;
const WORK_SPINNER_ANIMATION_DELAY = 1.0;
const WORK_SPINNER_ANIMATION_TIME = 0.3;
const State = {
OPENED: 0,
CLOSED: 1,
@ -65,7 +69,9 @@ const ModalDialog = new Lang.Class({
this._group.connect('key-press-event', Lang.bind(this, this._onKeyPressEvent));
this._group.connect('key-release-event', Lang.bind(this, this._onKeyReleaseEvent));
this._backgroundBin = new St.Bin();
this.backgroundStack = new St.Widget({ layout_manager: new Clutter.BinLayout() });
this._backgroundBin = new St.Bin({ child: this.backgroundStack,
x_fill: true, y_fill: true });
this._monitorConstraint = new Layout.MonitorConstraint();
this._backgroundBin.add_constraint(this._monitorConstraint);
this._group.add_actor(this._backgroundBin);
@ -81,15 +87,10 @@ const ModalDialog = new Lang.Class({
{ inhibitEvents: true });
this._lightbox.highlight(this._backgroundBin);
let stack = new Shell.Stack();
this._backgroundBin.child = stack;
this._eventBlocker = new Clutter.Actor({ reactive: true });
stack.add_actor(this._eventBlocker);
stack.add_actor(this.dialogLayout);
} else {
this._backgroundBin.child = this.dialogLayout;
this.backgroundStack.add_actor(this._eventBlocker);
}
this.backgroundStack.add_actor(this.dialogLayout);
this.contentLayout = new St.BoxLayout({ vertical: true });
@ -110,6 +111,8 @@ const ModalDialog = new Lang.Class({
this._initialKeyFocus = this.dialogLayout;
this._initialKeyFocusDestroyId = 0;
this._savedKeyFocus = null;
this._workSpinner = null;
},
destroy: function() {
@ -183,6 +186,44 @@ const ModalDialog = new Lang.Class({
return button;
},
placeSpinner: function(layoutInfo) {
/* This is here because of recursive imports */
const Panel = imports.ui.panel;
let spinnerIcon = global.datadir + '/theme/process-working.svg';
this._workSpinner = new Panel.AnimatedIcon(spinnerIcon, WORK_SPINNER_ICON_SIZE);
this._workSpinner.actor.opacity = 0;
this._workSpinner.actor.show();
this.buttonLayout.add(this._workSpinner.actor, layoutInfo);
},
setWorking: function(working) {
if (!this._workSpinner)
return;
Tweener.removeTweens(this._workSpinner.actor);
if (working) {
this._workSpinner.play();
Tweener.addTween(this._workSpinner.actor,
{ opacity: 255,
delay: WORK_SPINNER_ANIMATION_DELAY,
time: WORK_SPINNER_ANIMATION_TIME,
transition: 'linear'
});
} else {
Tweener.addTween(this._workSpinner.actor,
{ opacity: 0,
time: WORK_SPINNER_ANIMATION_TIME,
transition: 'linear',
onCompleteScope: this,
onComplete: function() {
if (this._workSpinner)
this._workSpinner.stop();
}
});
}
},
_onKeyPressEvent: function(object, event) {
this._pressedKey = event.get_key_symbol();
},

View File

@ -8,6 +8,7 @@ const Layout = imports.ui.layout;
const Main = imports.ui.main;
const Mainloop = imports.mainloop;
const Tweener = imports.ui.tweener;
const Meta = imports.gi.Meta;
const HIDE_TIMEOUT = 1500;
const FADE_TIME = 0.1;
@ -71,6 +72,7 @@ const OsdWindow = new Lang.Class({
Name: 'OsdWindow',
_init: function() {
this._popupSize = 0;
this.actor = new St.Widget({ x_expand: true,
y_expand: true,
x_align: Clutter.ActorAlign.CENTER,
@ -80,6 +82,15 @@ const OsdWindow = new Lang.Class({
vertical: true });
this.actor.add_actor(this._box);
this._box.connect('style-changed', Lang.bind(this, this._onStyleChanged));
this._box.connect('notify::height', Lang.bind(this,
function() {
Meta.later_add(Meta.LaterType.BEFORE_REDRAW, Lang.bind(this,
function() {
this._box.width = this._box.height;
}));
}));
this._icon = new St.Icon();
this._box.add(this._icon, { expand: true });
@ -125,8 +136,10 @@ const OsdWindow = new Lang.Class({
return;
if (!this.actor.visible) {
Meta.disable_unredirect_for_screen(global.screen);
this.actor.show();
this.actor.opacity = 0;
this.actor.get_parent().set_child_above_sibling(this.actor, null);
Tweener.addTween(this.actor,
{ opacity: 255,
@ -161,6 +174,7 @@ const OsdWindow = new Lang.Class({
this.actor.hide();
this.setLabel(null);
this.setLevel(null);
Meta.enable_unredirect_for_screen(global.screen);
},
_monitorsChanged: function() {
@ -169,11 +183,25 @@ const OsdWindow = new Lang.Class({
let scalew = monitor.width / 640.0;
let scaleh = monitor.height / 480.0;
let scale = Math.min(scalew, scaleh);
let size = 110 * Math.max(1, scale);
this._popupSize = 110 * Math.max(1, scale);
this._box.set_size(size, size);
this._box.translation_y = monitor.height / 4;
this._icon.icon_size = this._popupSize / 2;
this._box.style_changed();
},
this._icon.icon_size = size / 2;
_onStyleChanged: function() {
let themeNode = this._box.get_theme_node();
let horizontalPadding = themeNode.get_horizontal_padding();
let verticalPadding = themeNode.get_vertical_padding();
let topBorder = themeNode.get_border_width(St.Side.TOP);
let bottomBorder = themeNode.get_border_width(St.Side.BOTTOM);
let leftBorder = themeNode.get_border_width(St.Side.LEFT);
let rightBorder = themeNode.get_border_width(St.Side.RIGHT);
let minWidth = this._popupSize - verticalPadding - leftBorder - rightBorder;
let minHeight = this._popupSize - horizontalPadding - topBorder - bottomBorder;
this._box.style = 'min-height: %dpx;'.format(Math.max(minWidth, minHeight));
}
});

View File

@ -31,7 +31,7 @@ const ANIMATION_TIME = 0.25;
// and don't want the shading animation to get cut off
const SHADE_ANIMATION_TIME = .20;
const DND_WINDOW_SWITCH_TIMEOUT = 1250;
const DND_WINDOW_SWITCH_TIMEOUT = 750;
const OVERVIEW_ACTIVATION_TIMEOUT = 0.5;
@ -499,6 +499,11 @@ const Overview = new Lang.Class({
this._animateVisible();
},
focusSearch: function() {
this.show();
this._searchEntry.grab_key_focus();
},
fadeInDesktop: function() {
this._desktopFade.opacity = 0;
this._desktopFade.show();

View File

@ -144,8 +144,8 @@ const AnimatedIcon = new Lang.Class({
Name: 'AnimatedIcon',
Extends: Animation,
_init: function(name, size) {
this.parent(global.datadir + '/theme/' + name, size, size, ANIMATED_ICON_UPDATE_TIMEOUT);
_init: function(filename, size) {
this.parent(filename, size, size, ANIMATED_ICON_UPDATE_TIMEOUT);
}
});
@ -258,6 +258,7 @@ const AppMenuButton = new Lang.Class({
this._actionGroupNotifyId = 0;
let bin = new St.Bin({ name: 'appMenu' });
bin.connect('style-changed', Lang.bind(this, this._onStyleChanged));
this.actor.add_actor(bin);
this.actor.bind_property("reactive", this.actor, "can-focus", 0);
@ -288,27 +289,25 @@ const AppMenuButton = new Lang.Class({
this._visible = !Main.overview.visible;
if (!this._visible)
this.actor.hide();
Main.overview.connect('hiding', Lang.bind(this, function () {
this._overviewHidingId = Main.overview.connect('hiding', Lang.bind(this, function () {
this.show();
}));
Main.overview.connect('showing', Lang.bind(this, function () {
this._overviewShowingId = Main.overview.connect('showing', Lang.bind(this, function () {
this.hide();
}));
this._stop = true;
this._spinner = new AnimatedIcon('process-working.svg',
PANEL_ICON_SIZE);
this._container.add_actor(this._spinner.actor);
this._spinner.actor.hide();
this._spinner.actor.lower_bottom();
this._spinner = null;
let tracker = Shell.WindowTracker.get_default();
let appSys = Shell.AppSystem.get_default();
tracker.connect('notify::focus-app', Lang.bind(this, this._focusAppChanged));
appSys.connect('app-state-changed', Lang.bind(this, this._onAppStateChanged));
global.window_manager.connect('switch-workspace', Lang.bind(this, this._sync));
this._focusAppNotifyId =
tracker.connect('notify::focus-app', Lang.bind(this, this._focusAppChanged));
this._appStateChangedSignalId =
appSys.connect('app-state-changed', Lang.bind(this, this._onAppStateChanged));
this._switchWorkspaceNotifyId =
global.window_manager.connect('switch-workspace', Lang.bind(this, this._sync));
this._sync();
},
@ -354,6 +353,18 @@ const AppMenuButton = new Lang.Class({
onCompleteScope: this });
},
_onStyleChanged: function(actor) {
let node = actor.get_theme_node();
let [success, icon] = node.lookup_url('spinner-image', false);
if (!success || this._spinnerIcon == icon)
return;
this._spinnerIcon = icon;
this._spinner = new AnimatedIcon(this._spinnerIcon, PANEL_ICON_SIZE);
this._container.add_actor(this._spinner.actor);
this._spinner.actor.hide();
this._spinner.actor.lower_bottom();
},
_onIconBoxStyleChanged: function() {
let node = this._iconBox.get_theme_node();
this._iconBottomClip = node.get_length('app-icon-bottom-clip');
@ -385,6 +396,10 @@ const AppMenuButton = new Lang.Class({
this._stop = true;
this.actor.reactive = true;
if (this._spinner == null)
return;
Tweener.addTween(this._spinner.actor,
{ opacity: 0,
time: SPINNER_ANIMATION_TIME,
@ -401,6 +416,10 @@ const AppMenuButton = new Lang.Class({
startAnimation: function() {
this._stop = false;
this.actor.reactive = false;
if (this._spinner == null)
return;
this._spinner.play();
this._spinner.actor.show();
},
@ -463,6 +482,9 @@ const AppMenuButton = new Lang.Class({
}
this._label.actor.allocate(childBox, flags);
if (this._spinner == null)
return;
if (direction == Clutter.TextDirection.LTR) {
childBox.x1 = Math.floor(iconWidth / 2) + this._label.actor.width;
childBox.x2 = childBox.x1 + this._spinner.actor.width;
@ -553,7 +575,8 @@ const AppMenuButton = new Lang.Class({
return;
}
this._spinner.actor.hide();
if (this._spinner)
this._spinner.actor.hide();
if (this._iconBox.child != null)
this._iconBox.child.destroy();
this._iconBox.hide();
@ -616,6 +639,33 @@ const AppMenuButton = new Lang.Class({
this.setMenu(menu);
this._menuManager.addMenu(menu);
},
destroy: function() {
if (this._appStateChangedSignalId > 0) {
let appSys = Shell.AppSystem.get_default();
appSys.disconnect(this._appStateChangedSignalId);
this._appStateChangedSignalId = 0;
}
if (this._focusAppNotifyId > 0) {
let tracker = Shell.WindowTracker.get_default();
tracker.disconnect(this._focusAppNotifyId);
this._focusAppNotifyId = 0;
}
if (this._overviewHidingId > 0) {
Main.overview.disconnect(this._overviewHidingId);
this._overviewHidingId = 0;
}
if (this._overviewShowingId > 0) {
Main.overview.disconnect(this._overviewShowingId);
this._overviewShowingId = 0;
}
if (this._switchWorkspaceNotifyId > 0) {
global.window_manager.disconnect(this._switchWorkspaceNotifyId);
this._switchWorkspaceNotifyId = 0;
}
this.parent();
}
});
@ -873,7 +923,6 @@ 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
@ -902,7 +951,7 @@ const Panel = new Lang.Class({
this.statusArea = {};
this.menuManager = new PopupMenu.PopupMenuManager(this);
this.menuManager = new PopupMenu.PopupMenuManager(this, { keybindingMode: Shell.KeyBindingMode.TOPBAR_POPUP });
this._leftBox = new St.BoxLayout({ name: 'panelLeft' });
this.actor.add_actor(this._leftBox);
@ -1056,17 +1105,18 @@ const Panel = new Lang.Class({
return true;
},
openAppMenu: function() {
toggleAppMenu: function() {
let indicator = this.statusArea.appMenu;
if (!indicator) // appMenu not supported by current session mode
return;
let menu = indicator.menu;
if (!indicator.actor.reactive || menu.isOpen)
if (!indicator.actor.reactive)
return;
menu.open();
menu.actor.navigate_focus(null, Gtk.DirectionType.TAB_FORWARD, false);
menu.toggle();
if (menu.isOpen)
menu.actor.navigate_focus(null, Gtk.DirectionType.TAB_FORWARD, false);
},
set boxOpacity(value) {

View File

@ -553,6 +553,10 @@ const PopupSliderMenuItem = new Lang.Class({
let handleRadius = themeNode.get_length('-slider-handle-radius');
let handleBorderWidth = themeNode.get_length('-slider-handle-border-width');
let [hasHandleColor, handleBorderColor] =
themeNode.lookup_color('-slider-handle-border-color', false);
let sliderWidth = width - 2 * handleRadius;
let sliderHeight = themeNode.get_length('-slider-height');
@ -604,7 +608,16 @@ const PopupSliderMenuItem = new Lang.Class({
color.blue / 255,
color.alpha / 255);
cr.arc(handleX, handleY, handleRadius, 0, 2 * Math.PI);
cr.fill();
cr.fillPreserve();
if (hasHandleColor && handleBorderWidth) {
cr.setSourceRGBA(
handleBorderColor.red / 255,
handleBorderColor.green / 255,
handleBorderColor.blue / 255,
handleBorderColor.alpha / 255);
cr.setLineWidth(handleBorderWidth);
cr.stroke();
}
cr.$dispose();
},
@ -1157,6 +1170,7 @@ const PopupMenuBase = new Lang.Class({
},
destroy: function() {
this.close();
this.removeAll();
this.actor.destroy();
@ -1812,6 +1826,8 @@ const RemoteMenu = new Lang.Class({
this._actionStateChangeId = this.actionGroup.connect('action-state-changed', Lang.bind(this, this._actionStateChanged));
this._actionEnableChangeId = this.actionGroup.connect('action-enabled-changed', Lang.bind(this, this._actionEnabledChanged));
this._skipSignalConnection = false;
},
destroy: function() {
@ -1859,7 +1875,7 @@ const RemoteMenu = new Lang.Class({
let action_id = model.get_item_attribute_value(index, Gio.MENU_ATTRIBUTE_ACTION, null).deep_unpack();
if (!this.actionGroup.has_action(action_id)) {
// the action may not be there yet, wait for action-added
return [null, false, 'action-added'];
return [null, false, 'action-added::' + action_id];
}
if (!this._actions[action_id])
@ -1896,7 +1912,7 @@ const RemoteMenu = new Lang.Class({
break;
default:
log('Action "%s" has state of type %s, which is not supported'.format(action_id, action.state.get_type_string()));
return [null, false, 'action-state-changed'];
return [null, false, 'action-state-changed::' + action_id];
}
} else {
target = model.get_item_attribute_value(index, Gio.MENU_ATTRIBUTE_TARGET, null);
@ -1972,13 +1988,16 @@ const RemoteMenu = new Lang.Class({
target.addMenuItem(separator, k+1);
k++;
}
} else if (changeSignal) {
} else if (changeSignal && !this._skipSignalConnection) {
let signalId = this.actionGroup.connect(changeSignal, Lang.bind(this, function(actionGroup, actionName) {
actionGroup.disconnect(signalId);
if (this._actions[actionName]) return;
// force a full update
/* force a full update but do not reconnect signals if other
* actions are missing */
this._skipSignalConnection = true;
this._modelChanged(model, 0, -1, model.get_n_items(), target);
this._skipSignalConnection = false;
}));
}
}
@ -2051,9 +2070,9 @@ const RemoteMenu = new Lang.Class({
const PopupMenuManager = new Lang.Class({
Name: 'PopupMenuManager',
_init: function(owner) {
_init: function(owner, grabParams) {
this._owner = owner;
this._grabHelper = new GrabHelper.GrabHelper(owner.actor);
this._grabHelper = new GrabHelper.GrabHelper(owner.actor, grabParams);
this._menus = [];
},
@ -2123,6 +2142,8 @@ const PopupMenuManager = new Lang.Class({
_onMenuOpenState: function(menu, open) {
if (open) {
if (this.activeMenu && !this.activeMenu.isChildMenu(menu))
this.activeMenu.close(BoxPointer.PopupAnimation.FADE);
this._grabHelper.grab({ actor: menu.actor, modal: true, focus: menu.sourceActor,
onUngrab: Lang.bind(this, this._closeMenu, menu) });
} else {
@ -2139,13 +2160,8 @@ const PopupMenuManager = new Lang.Class({
},
_changeMenu: function(newMenu) {
let oldMenu = this.activeMenu;
if (oldMenu) {
oldMenu.close(BoxPointer.PopupAnimation.FADE);
newMenu.open(BoxPointer.PopupAnimation.FADE);
} else {
newMenu.open(BoxPointer.PopupAnimation.FULL);
}
newMenu.open(this.activeMenu ? BoxPointer.PopupAnimation.FADE
: BoxPointer.PopupAnimation.FULL);
},
_onMenuSourceEnter: function(menu) {

View File

@ -35,7 +35,8 @@ const RunDialog = new Lang.Class({
Extends: ModalDialog.ModalDialog,
_init : function() {
this.parent({ styleClass: 'run-dialog' });
this.parent({ styleClass: 'run-dialog',
destroyOnClose: false });
this._lockdownSettings = new Gio.Settings({ schema: LOCKDOWN_SCHEMA });
this._terminalSettings = new Gio.Settings({ schema: TERMINAL_SCHEMA });

View File

@ -562,6 +562,7 @@ const ScreenShield = new Lang.Class({
this._bgManagers[i].destroy();
this._bgManagers = [];
this._backgroundGroup.destroy_all_children();
for (let i = 0; i < Main.layoutManager.monitors.length; i++)
this._createBackground(i);
@ -1114,6 +1115,9 @@ const ScreenShield = new Lang.Class({
deactivate: function(animate) {
this._hideLockScreen(animate, 0);
if (this._hasLockScreen)
this._clearLockScreen();
if (Main.sessionMode.currentMode == 'lock-screen')
Main.sessionMode.popMode('lock-screen');
if (Main.sessionMode.currentMode == 'unlock-dialog')
@ -1130,9 +1134,6 @@ const ScreenShield = new Lang.Class({
},
_completeDeactivate: function() {
if (this._hasLockScreen)
this._clearLockScreen();
if (this._dialog && !this._isGreeter) {
this._dialog.destroy();
this._dialog = null;
@ -1199,6 +1200,12 @@ const ScreenShield = new Lang.Class({
return;
}
// Clear the clipboard - otherwise, its contents may be leaked
// to unauthorized parties by pasting into the unlock dialog's
// password entry and unmasking the entry
St.Clipboard.get_default().set_text(St.ClipboardType.CLIPBOARD, '');
St.Clipboard.get_default().set_text(St.ClipboardType.PRIMARY, '');
this._isLocked = true;
this.activate(animate);

140
js/ui/screencast.js Normal file
View File

@ -0,0 +1,140 @@
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
const Gio = imports.gi.Gio;
const GLib = imports.gi.GLib;
const Lang = imports.lang;
const Shell = imports.gi.Shell;
const Hash = imports.misc.hash;
const Main = imports.ui.main;
const ScreencastIface = <interface name="org.gnome.Shell.Screencast">
<method name="Screencast">
<arg type="s" direction="in" name="file_template"/>
<arg type="a{sv}" direction="in" name="options"/>
<arg type="b" direction="out" name="success"/>
<arg type="s" direction="out" name="filename_used"/>
</method>
<method name="ScreencastArea">
<arg type="i" direction="in" name="x"/>
<arg type="i" direction="in" name="y"/>
<arg type="i" direction="in" name="width"/>
<arg type="i" direction="in" name="height"/>
<arg type="s" direction="in" name="file_template"/>
<arg type="a{sv}" direction="in" name="options"/>
<arg type="b" direction="out" name="success"/>
<arg type="s" direction="out" name="filename_used"/>
</method>
<method name="StopScreencast">
<arg type="b" direction="out" name="success"/>
</method>
</interface>;
const ScreencastService = new Lang.Class({
Name: 'ScreencastService',
_init: function() {
this._dbusImpl = Gio.DBusExportedObject.wrapJSObject(ScreencastIface, this);
this._dbusImpl.export(Gio.DBus.session, '/org/gnome/Shell/Screencast');
Gio.DBus.session.own_name('org.gnome.Shell.Screencast', Gio.BusNameOwnerFlags.REPLACE, null, null);
this._recorders = new Hash.Map();
Main.sessionMode.connect('updated',
Lang.bind(this, this._sessionModeChanged));
},
_ensureRecorderForSender: function(sender) {
let recorder = this._recorders.get(sender);
if (!recorder) {
recorder = new Shell.Recorder({ stage: global.stage });
recorder._watchNameId =
Gio.bus_watch_name(Gio.BusType.SESSION, sender, 0, null,
Lang.bind(this, this._onNameVanished));
this._recorders.set(sender, recorder);
}
return recorder;
},
_sessionModeChanged: function() {
if (Main.sessionMode.allowScreencast)
return;
for (let sender in this._recorders.keys())
this._recorders.delete(sender);
},
_onNameVanished: function(connection, name) {
this._stopRecordingForSender(name);
},
_stopRecordingForSender: function(sender) {
let recorder = this._recorders.get(sender);
if (!recorder)
return false;
Gio.bus_unwatch_name(recorder._watchNameId);
recorder.close();
this._recorders.delete(sender);
return true;
},
_applyOptionalParameters: function(recorder, options) {
for (let option in options)
options[option] = options[option].deep_unpack();
if (options['pipeline'])
recorder.set_pipeline(options['pipeline']);
if (options['framerate'])
recorder.set_framerate(options['framerate']);
if (options['draw-cursor'])
recorder.set_draw_cursor(options['draw-cursor']);
},
ScreencastAsync: function(params, invocation) {
let returnValue = [false, ''];
if (!Main.sessionMode.allowScreencast)
invocation.return_value(GLib.Variant.new('(bs)', returnValue));
let sender = invocation.get_sender();
let recorder = this._ensureRecorderForSender(sender);
if (!recorder.is_recording()) {
let [fileTemplate, options] = params;
recorder.set_file_template(fileTemplate);
this._applyOptionalParameters(recorder, options);
let [success, fileName] = recorder.record();
returnValue = [success, fileName ? fileName : ''];
}
invocation.return_value(GLib.Variant.new('(bs)', returnValue));
},
ScreencastAreaAsync: function(params, invocation) {
let returnValue = [false, ''];
if (!Main.sessionMode.allowScreencast)
invocation.return_value(GLib.Variant.new('(bs)', returnValue));
let sender = invocation.get_sender();
let recorder = this._ensureRecorderForSender(sender);
if (!recorder.is_recording()) {
let [x, y, width, height, fileTemplate, options] = params;
recorder.set_file_template(fileTemplate);
recorder.set_area(x, y, width, height);
this._applyOptionalParameters(recorder, options);
let [success, fileName] = recorder.record();
returnValue = [success, fileName ? fileName : ''];
}
invocation.return_value(GLib.Variant.new('(bs)', returnValue));
},
StopScreencastAsync: function(params, invocation) {
let success = this._stopRecordingForSender(invocation.get_sender());
invocation.return_value(GLib.Variant.new('(b)', [success]));
}
});

View File

@ -16,6 +16,7 @@ const _modes = {
'restrictive': {
parentMode: null,
stylesheetName: 'gnome-shell.css',
overridesSchema: 'org.gnome.shell.overrides',
hasOverview: false,
showCalendarEvents: false,
allowSettings: false,
@ -45,7 +46,7 @@ const _modes = {
unlockDialog: imports.gdm.loginDialog.LoginDialog,
components: ['polkitAgent'],
panel: {
left: ['logo'],
left: [],
center: ['dateMenu'],
right: ['a11yGreeter', 'display', 'keyboard',
'volume', 'battery', 'powerMenu']
@ -81,7 +82,7 @@ const _modes = {
'initial-setup': {
hasWindows: true,
isPrimary: true,
components: ['keyring'],
components: ['networkAgent', 'keyring'],
panel: {
left: [],
center: ['dateMenu'],
@ -195,6 +196,10 @@ const SessionMode = new Lang.Class({
return this._modeStack[this._modeStack.length - 1];
},
get allowScreencast() {
return this.components.indexOf('recorder') != -1;
},
_sync: function() {
let params = this._modes[this.currentMode];
let defaults;

View File

@ -12,6 +12,7 @@ const ExtensionDownloader = imports.ui.extensionDownloader;
const ExtensionUtils = imports.misc.extensionUtils;
const Hash = imports.misc.hash;
const Main = imports.ui.main;
const Screencast = imports.ui.screencast;
const Screenshot = imports.ui.screenshot;
const GnomeShellIface = <interface name="org.gnome.Shell">
@ -20,6 +21,7 @@ const GnomeShellIface = <interface name="org.gnome.Shell">
<arg type="b" direction="out" name="success" />
<arg type="s" direction="out" name="result" />
</method>
<method name="FocusSearch"/>
<method name="ShowOSD">
<arg type="a{sv}" direction="in" name="params"/>
</method>
@ -70,6 +72,7 @@ const GnomeShell = new Lang.Class({
this._dbusImpl.export(Gio.DBus.session, '/org/gnome/Shell');
this._extensionsService = new GnomeShellExtensions();
this._screencastService = new Screencast.ScreencastService();
this._screenshotService = new Screenshot.ScreenshotService();
this._grabbedAccelerators = new Hash.Map();
@ -97,7 +100,7 @@ const GnomeShell = new Lang.Class({
*/
Eval: function(code) {
if (!global.settings.get_boolean('development-tools'))
return [false, null];
return [false, ''];
let returnValue;
let success;
@ -114,6 +117,10 @@ const GnomeShell = new Lang.Class({
return [success, returnValue];
},
FocusSearch: function() {
Main.overview.focusSearch();
},
ShowOSD: function(params) {
for (let param in params)
params[param] = params[param].deep_unpack();

View File

@ -14,9 +14,7 @@ const EntryMenu = new Lang.Class({
Name: 'ShellEntryMenu',
Extends: PopupMenu.PopupMenu,
_init: function(entry, params) {
params = Params.parse (params, { isPassword: false });
_init: function(entry) {
this.parent(entry, 0, St.Side.TOP);
this.actor.add_style_class_name('entry-context-menu');
@ -37,8 +35,6 @@ const EntryMenu = new Lang.Class({
this._pasteItem = item;
this._passwordItem = null;
if (params.isPassword)
this._makePasswordItem();
Main.uiGroup.add_actor(this.actor);
this.actor.hide();
@ -53,19 +49,21 @@ const EntryMenu = new Lang.Class({
},
get isPassword() {
return this._passwordItem != null;
return this._passwordItem != null;
},
set isPassword(v) {
if (v == this.isPassword)
return;
if (v == this.isPassword)
return;
if (v)
this._makePasswordItem();
else {
this._passwordItem.destroy();
this._passwordItem = null;
}
if (v) {
this._makePasswordItem();
this._entry.input_purpose = Gtk.InputPurpose.PASSWORD;
} else {
this._passwordItem.destroy();
this._passwordItem = null;
this._entry.input_purpose = Gtk.InputPurpose.FREE_FORM;
}
},
open: function(animate) {
@ -82,11 +80,6 @@ const EntryMenu = new Lang.Class({
this.actor.grab_key_focus();
},
close: function(animate) {
this._entry.grab_key_focus();
this.parent(animate);
},
_updateCopyItem: function() {
let selection = this._entry.clutter_text.get_selection();
this._copyItem.setSensitive(!this._entry.clutter_text.password_char &&
@ -160,7 +153,10 @@ function addContextMenu(entry, params) {
if (entry.menu)
return;
entry.menu = new EntryMenu(entry, params);
params = Params.parse (params, { isPassword: false });
entry.menu = new EntryMenu(entry);
entry.menu.isPassword = params.isPassword;
entry._menuManager = new PopupMenu.PopupMenuManager({ actor: entry });
entry._menuManager.addMenu(entry.menu);

View File

@ -33,6 +33,33 @@ const KEY_INPUT_SOURCES = 'sources';
const INPUT_SOURCE_TYPE_XKB = 'xkb';
const INPUT_SOURCE_TYPE_IBUS = 'ibus';
// This is the longest we'll keep the keyboard frozen until an input
// source is active.
const MAX_INPUT_SOURCE_ACTIVATION_TIME = 4000; // ms
const BUS_NAME = 'org.gnome.SettingsDaemon.Keyboard';
const OBJECT_PATH = '/org/gnome/SettingsDaemon/Keyboard';
const KeyboardManagerInterface =
<interface name="org.gnome.SettingsDaemon.Keyboard">
<method name="SetInputSource">
<arg type="u" direction="in" />
</method>
</interface>;
const KeyboardManagerProxy = Gio.DBusProxy.makeProxyWrapper(KeyboardManagerInterface);
function releaseKeyboard() {
if (Main.modalCount > 0)
global.display.unfreeze_keyboard(global.get_current_time());
else
global.display.ungrab_keyboard(global.get_current_time());
}
function holdKeyboard() {
global.freeze_keyboard(global.get_current_time());
}
const IBusManager = new Lang.Class({
Name: 'IBusManager',
@ -45,26 +72,24 @@ const IBusManager = new Lang.Class({
this._readyCallback = readyCallback;
this._candidatePopup = new IBusCandidatePopup.CandidatePopup();
this._ibus = null;
this._panelService = null;
this._engines = {};
this._ready = false;
this._registerPropertiesId = 0;
this._currentEngineName = null;
this._nameWatcherId = Gio.DBus.session.watch_name(IBus.SERVICE_IBUS,
Gio.BusNameWatcherFlags.NONE,
Lang.bind(this, this._onNameAppeared),
Lang.bind(this, this._clear));
this._ibus = IBus.Bus.new_async();
this._ibus.connect('connected', Lang.bind(this, this._onConnected));
this._ibus.connect('disconnected', Lang.bind(this, this._clear));
// Need to set this to get 'global-engine-changed' emitions
this._ibus.set_watch_ibus_signal(true);
this._ibus.connect('global-engine-changed', Lang.bind(this, this._engineChanged));
},
_clear: function() {
if (this._panelService)
this._panelService.destroy();
if (this._ibus)
this._ibus.destroy();
this._ibus = null;
this._panelService = null;
this._candidatePopup.setPanelService(null);
this._engines = {};
@ -76,18 +101,12 @@ const IBusManager = new Lang.Class({
this._readyCallback(false);
},
_onNameAppeared: function() {
this._ibus = IBus.Bus.new_async();
this._ibus.connect('connected', Lang.bind(this, this._onConnected));
},
_onConnected: function() {
this._ibus.list_engines_async(-1, null, Lang.bind(this, this._initEngines));
this._ibus.request_name_async(IBus.SERVICE_PANEL,
IBus.BusNameFlag.REPLACE_EXISTING,
-1, null,
Lang.bind(this, this._initPanelService));
this._ibus.connect('disconnected', Lang.bind(this, this._clear));
},
_initEngines: function(ibus, result) {
@ -109,9 +128,6 @@ const IBusManager = new Lang.Class({
this._panelService = new IBus.PanelService({ connection: this._ibus.get_connection(),
object_path: IBus.PATH_PANEL });
this._candidatePopup.setPanelService(this._panelService);
// Need to set this to get 'global-engine-changed' emitions
this._ibus.set_watch_ibus_signal(true);
this._ibus.connect('global-engine-changed', Lang.bind(this, this._engineChanged));
this._panelService.connect('update-property', Lang.bind(this, this._updateProperty));
// If an engine is already active we need to get its properties
this._ibus.get_global_engine_async(-1, null, Lang.bind(this, function(i, result) {
@ -140,6 +156,9 @@ const IBusManager = new Lang.Class({
},
_engineChanged: function(bus, engineName) {
if (!this._ready)
return;
this._currentEngineName = engineName;
if (this._registerPropertiesId != 0)
@ -337,14 +356,14 @@ const InputSourceIndicator = new Lang.Class({
Main.wm.addKeybinding('switch-input-source',
new Gio.Settings({ schema: "org.gnome.desktop.wm.keybindings" }),
Meta.KeyBindingFlags.REVERSES,
Shell.KeyBindingMode.ALL & ~Shell.KeyBindingMode.MESSAGE_TRAY,
Shell.KeyBindingMode.ALL,
Lang.bind(this, this._switchInputSource));
this._keybindingActionBackward =
Main.wm.addKeybinding('switch-input-source-backward',
new Gio.Settings({ schema: "org.gnome.desktop.wm.keybindings" }),
Meta.KeyBindingFlags.REVERSES |
Meta.KeyBindingFlags.REVERSED,
Shell.KeyBindingMode.ALL & ~Shell.KeyBindingMode.MESSAGE_TRAY,
Shell.KeyBindingMode.ALL,
Lang.bind(this, this._switchInputSource));
this._settings = new Gio.Settings({ schema: DESKTOP_INPUT_SOURCES_SCHEMA });
this._settings.connect('changed::' + KEY_CURRENT_INPUT_SOURCE, Lang.bind(this, this._currentInputSourceChanged));
@ -364,6 +383,15 @@ const InputSourceIndicator = new Lang.Class({
this._ibusManager.connect('property-updated', Lang.bind(this, this._ibusPropertyUpdated));
this._inputSourcesChanged();
this._keyboardManager = new KeyboardManagerProxy(Gio.DBus.session, BUS_NAME, OBJECT_PATH,
function(proxy, error) {
if (error)
log(error.message);
});
this._keyboardManager.g_default_timeout = MAX_INPUT_SOURCE_ACTIVATION_TIME;
global.display.connect('modifiers-accelerator-activated', Lang.bind(this, this._modifiersSwitcher));
this.menu.addMenuItem(new PopupMenu.PopupSeparatorMenuItem());
this._showLayoutItem = this.menu.addAction(_("Show Keyboard Layout"), Lang.bind(this, this._showLayout));
@ -397,10 +425,43 @@ const InputSourceIndicator = new Lang.Class({
this._inputSourcesChanged();
},
_modifiersSwitcher: function() {
let sourceIndexes = Object.keys(this._inputSources);
if (sourceIndexes.length == 0) {
releaseKeyboard();
return true;
}
let is = this._currentSource;
if (!is)
is = this._inputSources[sourceIndexes[0]];
let nextIndex = is.index + 1;
if (nextIndex > sourceIndexes[sourceIndexes.length - 1])
nextIndex = 0;
while (!(is = this._inputSources[nextIndex]))
nextIndex += 1;
is.activate();
return true;
},
_switchInputSource: function(display, screen, window, binding) {
if (this._mruSources.length < 2)
return;
// HACK: Fall back on simple input source switching since we
// can't show a popup switcher while a GrabHelper grab is in
// effect without considerable work to consolidate the usage
// of pushModal/popModal and grabHelper. See
// https://bugzilla.gnome.org/show_bug.cgi?id=695143 .
if (Main.keybindingMode == Shell.KeyBindingMode.MESSAGE_TRAY ||
Main.keybindingMode == Shell.KeyBindingMode.TOPBAR_POPUP) {
this._modifiersSwitcher();
return;
}
let popup = new InputSourcePopup(this._mruSources, this._keybindingAction, this._keybindingActionBackward);
let modifiers = binding.get_modifiers();
let backwards = modifiers & Meta.VirtualModifier.SHIFT_MASK;
@ -459,6 +520,7 @@ const InputSourceIndicator = new Lang.Class({
this._inputSources = {};
this._ibusSources = {};
this._currentSource = null;
let inputSourcesByShortName = {};
@ -487,10 +549,8 @@ const InputSourceIndicator = new Lang.Class({
let is = new InputSource(type, id, displayName, shortName, i);
is.connect('activate', Lang.bind(this, function() {
if (this._currentSource && this._currentSource.index == is.index)
return;
this._settings.set_value(KEY_CURRENT_INPUT_SOURCE,
GLib.Variant.new_uint32(is.index));
holdKeyboard();
this._keyboardManager.SetInputSourceRemote(is.index, releaseKeyboard);
}));
if (!(is.shortName in inputSourcesByShortName))

View File

@ -2047,6 +2047,7 @@ const NMApplet = new Lang.Class({
let default_ip4 = null;
let default_ip6 = null;
let active_vpn = null;
let active_any = null;
for (let i = 0; i < this._activeConnections.length; i++) {
let a = this._activeConnections[i];
@ -2077,10 +2078,15 @@ const NMApplet = new Lang.Class({
if (a.default6)
default_ip6 = a;
if (a._type == 'vpn')
active_vpn = a;
else if (a.state == NetworkManager.ActiveConnectionState.ACTIVATING)
if (a.state == NetworkManager.ActiveConnectionState.ACTIVATING)
activating = a;
else if (a.state == NetworkManager.ActiveConnectionState.ACTIVATED)
active_any = a;
if (a._type == 'vpn' &&
(a.state == NetworkManager.ActiveConnectionState.ACTIVATING ||
a.state == NetworkManager.ActiveConnectionState.ACTIVATED))
active_vpn = a;
if (!a._primaryDevice) {
if (a._type != NetworkManager.SETTING_VPN_SETTING_NAME) {
@ -2108,7 +2114,7 @@ const NMApplet = new Lang.Class({
}
}
this._mainConnection = activating || default_ip4 || default_ip6 || this._activeConnections[0] || null;
this._mainConnection = activating || default_ip4 || default_ip6 || active_any || null;
this._vpnConnection = active_vpn;
},

View File

@ -307,7 +307,7 @@ const Indicator = new Lang.Class({
this._headphoneIcon.visible = value;
}));
this._headphoneIcon = this.addIcon(new Gio.ThemedIcon({ name: 'headphones-symbolic' }));
this._headphoneIcon = this.addIcon(new Gio.ThemedIcon({ name: 'audio-headphones-symbolic' }));
this._headphoneIcon.visible = false;
this.menu.addMenuItem(this._volumeMenu);

View File

@ -91,9 +91,6 @@ const UnlockDialog = new Lang.Class({
this._promptLoginHint.hide();
this.contentLayout.add_actor(this._promptLoginHint);
this._workSpinner = new Panel.AnimatedIcon('process-working.svg', LoginDialog.WORK_SPINNER_ICON_SIZE);
this._workSpinner.actor.opacity = 0;
this.allowCancel = false;
this.buttonLayout.visible = true;
this.addButton({ label: _("Cancel"),
@ -104,12 +101,11 @@ const UnlockDialog = new Lang.Class({
y_fill: false,
x_align: St.Align.START,
y_align: St.Align.MIDDLE });
this.buttonLayout.add(this._workSpinner.actor,
{ expand: false,
x_fill: false,
y_fill: false,
x_align: St.Align.END,
y_align: St.Align.MIDDLE });
this.placeSpinner({ expand: false,
x_fill: false,
y_fill: false,
x_align: St.Align.END,
y_align: St.Align.MIDDLE });
this._okButton = this.addButton({ label: _("Unlock"),
action: Lang.bind(this, this._doUnlock),
default: true },
@ -163,28 +159,6 @@ const UnlockDialog = new Lang.Class({
this._okButton.can_focus = sensitive;
},
_setWorking: function(working) {
if (working) {
this._workSpinner.play();
Tweener.addTween(this._workSpinner.actor,
{ opacity: 255,
delay: LoginDialog.WORK_SPINNER_ANIMATION_DELAY,
time: LoginDialog.WORK_SPINNER_ANIMATION_TIME,
transition: 'linear'
});
} else {
Tweener.addTween(this._workSpinner.actor,
{ opacity: 0,
time: LoginDialog.WORK_SPINNER_ANIMATION_TIME,
transition: 'linear',
onCompleteScope: this,
onComplete: function() {
this._workSpinner.stop();
}
});
}
},
_showMessage: function(userVerifier, message, styleClass) {
if (message) {
this._promptMessage.text = message;
@ -215,7 +189,7 @@ const UnlockDialog = new Lang.Class({
this._currentQuery = serviceName;
this._updateSensitivity(true);
this._setWorking(false);
this.setWorking(false);
},
_showLoginHint: function(verifier, message) {
@ -234,7 +208,7 @@ const UnlockDialog = new Lang.Class({
// the actual reply to GDM will be sent as soon as asked
this._firstQuestionAnswer = this._promptEntry.text;
this._updateSensitivity(false);
this._setWorking(true);
this.setWorking(true);
return;
}
@ -245,7 +219,7 @@ const UnlockDialog = new Lang.Class({
this._currentQuery = null;
this._updateSensitivity(false);
this._setWorking(true);
this.setWorking(true);
this._userVerifier.answerQuery(query, this._promptEntry.text);
},
@ -285,7 +259,7 @@ const UnlockDialog = new Lang.Class({
this._promptEntry.menu.isPassword = true;
this._updateSensitivity(false);
this._setWorking(false);
this.setWorking(false);
},
_escape: function() {

View File

@ -16,6 +16,7 @@ const UserWidget = new Lang.Class({
this.actor = new St.BoxLayout({ style_class: 'user-widget',
vertical: false });
this.actor.connect('destroy', Lang.bind(this, this._onDestroy));
this._avatar = new UserMenu.UserAvatarWidget(user);
this.actor.add(this._avatar.actor,
@ -36,7 +37,7 @@ const UserWidget = new Lang.Class({
this._updateUser();
},
destroy: function() {
_onDestroy: function() {
if (this._userLoadedId != 0) {
this._user.disconnect(this._userLoadedId);
this._userLoadedId = 0;
@ -46,8 +47,6 @@ const UserWidget = new Lang.Class({
this._user.disconnect(this._userChangedId);
this._userChangedId = 0;
}
this.actor.destroy();
},
_updateUser: function() {

View File

@ -136,6 +136,42 @@ const WindowManager = new Lang.Class({
Shell.KeyBindingMode.NORMAL |
Shell.KeyBindingMode.OVERVIEW,
Lang.bind(this, this._showWorkspaceSwitcher));
this.allowKeybinding('switch-to-workspace-1',
Shell.KeyBindingMode.NORMAL |
Shell.KeyBindingMode.OVERVIEW);
this.allowKeybinding('switch-to-workspace-2',
Shell.KeyBindingMode.NORMAL |
Shell.KeyBindingMode.OVERVIEW);
this.allowKeybinding('switch-to-workspace-3',
Shell.KeyBindingMode.NORMAL |
Shell.KeyBindingMode.OVERVIEW);
this.allowKeybinding('switch-to-workspace-4',
Shell.KeyBindingMode.NORMAL |
Shell.KeyBindingMode.OVERVIEW);
this.allowKeybinding('switch-to-workspace-5',
Shell.KeyBindingMode.NORMAL |
Shell.KeyBindingMode.OVERVIEW);
this.allowKeybinding('switch-to-workspace-6',
Shell.KeyBindingMode.NORMAL |
Shell.KeyBindingMode.OVERVIEW);
this.allowKeybinding('switch-to-workspace-7',
Shell.KeyBindingMode.NORMAL |
Shell.KeyBindingMode.OVERVIEW);
this.allowKeybinding('switch-to-workspace-8',
Shell.KeyBindingMode.NORMAL |
Shell.KeyBindingMode.OVERVIEW);
this.allowKeybinding('switch-to-workspace-9',
Shell.KeyBindingMode.NORMAL |
Shell.KeyBindingMode.OVERVIEW);
this.allowKeybinding('switch-to-workspace-10',
Shell.KeyBindingMode.NORMAL |
Shell.KeyBindingMode.OVERVIEW);
this.allowKeybinding('switch-to-workspace-11',
Shell.KeyBindingMode.NORMAL |
Shell.KeyBindingMode.OVERVIEW);
this.allowKeybinding('switch-to-workspace-12',
Shell.KeyBindingMode.NORMAL |
Shell.KeyBindingMode.OVERVIEW);
this.setCustomKeybindingHandler('switch-applications',
Shell.KeyBindingMode.NORMAL,
Lang.bind(this, this._startAppSwitcher));
@ -172,8 +208,9 @@ const WindowManager = new Lang.Class({
this.addKeybinding('open-application-menu',
new Gio.Settings({ schema: SHELL_KEYBINDINGS_SCHEMA }),
Meta.KeyBindingFlags.NONE,
Shell.KeyBindingMode.NORMAL,
Lang.bind(this, this._openAppMenu));
Shell.KeyBindingMode.NORMAL |
Shell.KeyBindingMode.TOPBAR_POPUP,
Lang.bind(this, this._toggleAppMenu));
Main.overview.connect('showing', Lang.bind(this, function() {
for (let i = 0; i < this._dimmedWindows.length; i++)
@ -679,8 +716,8 @@ const WindowManager = new Lang.Class({
Main.ctrlAltTabManager.popup(backwards, binding.get_name(), binding.get_mask());
},
_openAppMenu : function(display, screen, window, event, binding) {
Main.panel.openAppMenu();
_toggleAppMenu : function(display, screen, window, event, binding) {
Main.panel.toggleAppMenu();
},
_showWorkspaceSwitcher : function(display, screen, window, binding) {

View File

@ -125,6 +125,12 @@
<listitem><para>List possible modes and exit</para></listitem>
</varlistentry>
<varlistentry>
<term><option>--clutter-display=<replaceable>DISPLAY</replaceable></option></term>
<listitem><para>Clutter the option display (otherwise ignored)</para></listitem>
</varlistentry>
</variablelist>
</refsect1>

View File

@ -28,6 +28,7 @@ gu
he
hi
hu
ia
id
it
ja

View File

@ -55,6 +55,7 @@ js/ui/viewSelector.js
js/ui/wanda.js
js/ui/windowAttentionHandler.js
src/calendar-server/evolution-calendar.desktop.in.in
# Please do not remove this file from POTFILES.in. Run "git submodule init && git submodule update" to get it.
src/gvc/gvc-mixer-control.c
src/main.c
src/shell-app.c

1938
po/ia.po Normal file

File diff suppressed because it is too large Load Diff

View File

@ -461,7 +461,7 @@ msgstr "Nepavyko įvykdyti „%s“:"
#: ../js/ui/appDisplay.js:349
msgid "Frequent"
msgstr "Dažniausios"
msgstr "Dažnai naudojamos"
#: ../js/ui/appDisplay.js:356
msgid "All"
@ -1262,7 +1262,7 @@ msgstr "Apžvalga"
#. characters.
#: ../js/ui/overview.js:271
msgid "Type to search…"
msgstr "Rašykite ko ieškote…"
msgstr "Rašykite, ko ieškote…"
#: ../js/ui/panel.js:612
msgid "Quit"
@ -1299,7 +1299,7 @@ msgstr "Užverti"
#. long format
#: ../js/ui/screenShield.js:86
msgid "%A, %B %d"
msgstr "%A, %B %d"
msgstr "%A, %B %d d."
#: ../js/ui/screenShield.js:151
#, c-format

View File

@ -8,7 +8,7 @@ msgid ""
msgstr ""
"Project-Id-Version: gnome-shell 3.8.x\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2013-04-03 13:31+0200\n"
"POT-Creation-Date: 2013-05-13 09:47+0200\n"
"PO-Revision-Date: 2013-04-03 13:31+0200\n"
"Last-Translator: Kjartan Maraas <kmaraas@gnome.org>\n"
"Language-Team: Norwegian bokmål <i18n-nb@lister.ping.uio.no>\n"
@ -335,43 +335,50 @@ msgstr "Utvidelse"
msgid "Select an extension to configure using the combobox above."
msgstr "Velg en utvidelse som skal konfigureres med komboboksen over."
#: ../js/gdm/loginDialog.js:405
#: ../js/gdm/loginDialog.js:371
msgid "Session…"
msgstr "Økt …"
#. 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:630
#: ../js/gdm/loginDialog.js:601
msgid "Not listed?"
msgstr "Ikke listet?"
#: ../js/gdm/loginDialog.js:786 ../js/ui/components/networkAgent.js:137
#: ../js/ui/components/polkitAgent.js:162 ../js/ui/endSessionDialog.js:375
#: ../js/gdm/loginDialog.js:776 ../js/ui/components/networkAgent.js:137
#: ../js/ui/components/polkitAgent.js:162 ../js/ui/endSessionDialog.js:376
#: ../js/ui/extensionDownloader.js:195 ../js/ui/shellMountOperation.js:399
#: ../js/ui/status/bluetooth.js:415 ../js/ui/unlockDialog.js:99
#: ../js/ui/status/bluetooth.js:415 ../js/ui/unlockDialog.js:96
#: ../js/ui/userMenu.js:938
msgid "Cancel"
msgstr "Avbryt"
#: ../js/gdm/loginDialog.js:802
#: ../js/gdm/loginDialog.js:791
msgctxt "button"
msgid "Sign In"
msgstr "Logg inn"
#: ../js/gdm/loginDialog.js:802
#: ../js/gdm/loginDialog.js:791
msgid "Next"
msgstr "Neste"
#. Translators: this message is shown below the username entry field
#. to clue the user in on how to login to the local network realm
#: ../js/gdm/loginDialog.js:888
#, c-format
msgid "(e.g., user or %s)"
msgstr "(f.eks. bruker eller %s)"
#. TTLS and PEAP are actually much more complicated, but this complication
#. is not visible here since we only care about phase2 authentication
#. (and don't even care of which one)
#: ../js/gdm/loginDialog.js:917 ../js/ui/components/networkAgent.js:260
#: ../js/gdm/loginDialog.js:892 ../js/ui/components/networkAgent.js:260
#: ../js/ui/components/networkAgent.js:278
msgid "Username: "
msgstr "Brukernavn: "
#: ../js/gdm/loginDialog.js:1173
#: ../js/gdm/loginDialog.js:1158
msgid "Login Window"
msgstr "Innloggingsvindu"
@ -394,21 +401,16 @@ msgstr "Start på nytt"
msgid "Power Off"
msgstr "Slå av"
#: ../js/gdm/util.js:249
#: ../js/gdm/util.js:247
msgid "Authentication error"
msgstr "Autentiseringsfeil"
#. Translators: this message is shown below the password entry field
#. to indicate the user can swipe their finger instead
#: ../js/gdm/util.js:366
#: ../js/gdm/util.js:364
msgid "(or swipe finger)"
msgstr "(eller dra finger)"
#: ../js/gdm/util.js:391
#, c-format
msgid "(e.g., user or %s)"
msgstr "(f.eks. bruker eller %s)"
#: ../js/misc/util.js:97
msgid "Command not found"
msgstr "Kommando ikke funnet"
@ -632,11 +634,11 @@ msgstr "Åpne med %s"
msgid "Eject"
msgstr "Løs ut"
#: ../js/ui/components/keyring.js:82 ../js/ui/components/polkitAgent.js:268
#: ../js/ui/components/keyring.js:88 ../js/ui/components/polkitAgent.js:275
msgid "Password:"
msgstr "Passord:"
#: ../js/ui/components/keyring.js:101
#: ../js/ui/components/keyring.js:107
msgid "Type again:"
msgstr "Skriv på nytt:"
@ -724,7 +726,7 @@ msgstr "Autentisering kreves"
msgid "Administrator"
msgstr "Administrator"
#: ../js/ui/components/polkitAgent.js:165
#: ../js/ui/components/polkitAgent.js:171
msgid "Authenticate"
msgstr "Autentiser"
@ -732,12 +734,12 @@ msgstr "Autentiser"
#. * requested authentication was not gained; this can happen
#. * because of an authentication error (like invalid password),
#. * for instance.
#: ../js/ui/components/polkitAgent.js:256 ../js/ui/shellMountOperation.js:383
#: ../js/ui/components/polkitAgent.js:263 ../js/ui/shellMountOperation.js:383
msgid "Sorry, that didn't work. Please try again."
msgstr "Beklager, det virket ikke. Vennligst prøv igjen."
#. Translators: this is a filename used for screencast recording
#: ../js/ui/components/recorder.js:48
#: ../js/ui/components/recorder.js:47
#, no-c-format
msgid "Screencast from %d %t"
msgstr "Skjermvideo fra %d %t"
@ -1003,14 +1005,14 @@ msgstr "Åpne kalender"
msgid "Open Clocks"
msgstr "Åpne Klokker"
#: ../js/ui/dateMenu.js:105
#: ../js/ui/dateMenu.js:104
msgid "Date & Time Settings"
msgstr "Innstillinger for dato og klokkeslett"
#. 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:215
#: ../js/ui/dateMenu.js:216
msgid "%A %B %e, %Y"
msgstr "%a %e %B, %Y"
@ -1188,11 +1190,11 @@ msgstr "Innstillinger for varsling"
msgid "No Messages"
msgstr "Ingen meldinger"
#: ../js/ui/messageTray.js:1782
#: ../js/ui/messageTray.js:1785
msgid "Message Tray"
msgstr "Meldingstrau"
#: ../js/ui/messageTray.js:2810
#: ../js/ui/messageTray.js:2813
msgid "System Information"
msgstr "Systeminformasjon"
@ -1224,17 +1226,17 @@ msgstr "Oversikt"
msgid "Type to search…"
msgstr "Skriv for å søke …"
#: ../js/ui/panel.js:612
#: ../js/ui/panel.js:635
msgid "Quit"
msgstr "Avslutt"
#. Translators: If there is no suitable word for "Activities"
#. in your language, you can use the word for "Overview".
#: ../js/ui/panel.js:636
#: ../js/ui/panel.js:686
msgid "Activities"
msgstr "Aktiviteter"
#: ../js/ui/panel.js:933
#: ../js/ui/panel.js:982
msgid "Top Bar"
msgstr "Topp-panel"
@ -1247,11 +1249,11 @@ msgstr "Topp-panel"
msgid "toggle-switch-us"
msgstr "toggle-switch-intl"
#: ../js/ui/runDialog.js:73
#: ../js/ui/runDialog.js:74
msgid "Enter a Command"
msgstr "Oppgi en kommando"
#: ../js/ui/runDialog.js:109
#: ../js/ui/runDialog.js:110
msgid "Close"
msgstr "Lukk"
@ -1272,7 +1274,7 @@ msgstr[1] "%d nye varslinger"
msgid "Lock"
msgstr "Lås"
#: ../js/ui/screenShield.js:640
#: ../js/ui/screenShield.js:641
msgid "GNOME needs to lock the screen"
msgstr "GNOME må låse skjermen"
@ -1283,11 +1285,11 @@ msgstr "GNOME må låse skjermen"
#.
#. XXX: another option is to kick the user into the gdm login
#. screen, where we're not affected by grabs
#: ../js/ui/screenShield.js:761 ../js/ui/screenShield.js:1197
#: ../js/ui/screenShield.js:762 ../js/ui/screenShield.js:1198
msgid "Unable to lock"
msgstr "Kan ikke låse"
#: ../js/ui/screenShield.js:762 ../js/ui/screenShield.js:1198
#: ../js/ui/screenShield.js:763 ../js/ui/screenShield.js:1199
msgid "Lock was blocked by an application"
msgstr "Låsing ble stoppet av et program"
@ -1307,11 +1309,11 @@ msgstr "Kopier"
msgid "Paste"
msgstr "Lim inn"
#: ../js/ui/shellEntry.js:106
#: ../js/ui/shellEntry.js:101
msgid "Show Text"
msgstr "Vis tekst"
#: ../js/ui/shellEntry.js:108
#: ../js/ui/shellEntry.js:103
msgid "Hide Text"
msgstr "Skjul tekst"
@ -1323,7 +1325,7 @@ msgstr "Passord"
msgid "Remember Password"
msgstr "Husk passord"
#: ../js/ui/shellMountOperation.js:403 ../js/ui/unlockDialog.js:113
#: ../js/ui/shellMountOperation.js:403 ../js/ui/unlockDialog.js:109
msgid "Unlock"
msgstr "Lås opp"
@ -1614,7 +1616,7 @@ msgstr "Tilkobling feilet"
msgid "Activation of network connection failed"
msgstr "Aktivering av nettverkstilkobling feilet"
#: ../js/ui/status/network.js:2276
#: ../js/ui/status/network.js:2282
msgid "Networking is disabled"
msgstr "Nettverk er slått av"
@ -1728,11 +1730,11 @@ msgstr "Volum"
msgid "Microphone"
msgstr "Mikrofon"
#: ../js/ui/unlockDialog.js:124
#: ../js/ui/unlockDialog.js:120
msgid "Log in as another user"
msgstr "Logg inn som en annen bruker"
#: ../js/ui/unlockDialog.js:145
#: ../js/ui/unlockDialog.js:141
msgid "Unlock Window"
msgstr "Lås opp vindu"
@ -1885,11 +1887,11 @@ msgstr "Vis mulige modi"
msgid "Failed to launch '%s'"
msgstr "Klarte ikke å starte «%s»"
#: ../src/shell-keyring-prompt.c:708
#: ../src/shell-keyring-prompt.c:714
msgid "Passwords do not match."
msgstr "Passordene er ikke like."
#: ../src/shell-keyring-prompt.c:716
#: ../src/shell-keyring-prompt.c:722
msgid "Password cannot be blank"
msgstr "Passordet kan ikke være tomt"

163
po/sr.po
View File

@ -8,7 +8,7 @@ msgstr ""
"Project-Id-Version: gnome-shell master\n"
"Report-Msgid-Bugs-To: http://bugzilla.gnome.org/enter_bug.cgi?product=gnome-"
"shell&keywords=I18N+L10N&component=general\n"
"POT-Creation-Date: 2013-03-04 08:38+0000\n"
"POT-Creation-Date: 2013-03-31 01:48+0000\n"
"PO-Revision-Date: 2013-03-08 20:26+0200\n"
"Last-Translator: Мирослав Николић <miroslavnikolic@rocketmail.com>\n"
"Language-Team: Serbian <gnom@prevod.org>\n"
@ -16,8 +16,8 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=4; plural=n==1? 3 : n%10==1 && n%100!=11 ? 0 : "
"n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n"
"Plural-Forms: nplurals=4; plural=n==1? 3 : n%10==1 && n%100!=11 ? 0 : n"
"%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n"
"X-Project-Style: gnome\n"
#: ../data/50-gnome-shell-screenshot.xml.in.h:1
@ -365,53 +365,52 @@ msgid "Select an extension to configure using the combobox above."
msgstr "Изаберите проширење за подешавање користећи прозорче за избор."
#: ../js/gdm/loginDialog.js:405
#| msgid "Session..."
msgid "Session…"
msgstr "Сесија…"
#. translators: this message is shown below the user list on the
#. login screen. It can be activated to reveal an entry for
#. manually entering the username.
#: ../js/gdm/loginDialog.js:629
#: ../js/gdm/loginDialog.js:630
msgid "Not listed?"
msgstr "Није на списку?"
#: ../js/gdm/loginDialog.js:783 ../js/ui/components/networkAgent.js:137
#: ../js/gdm/loginDialog.js:786 ../js/ui/components/networkAgent.js:137
#: ../js/ui/components/polkitAgent.js:162 ../js/ui/endSessionDialog.js:375
#: ../js/ui/extensionDownloader.js:195 ../js/ui/shellMountOperation.js:399
#: ../js/ui/status/bluetooth.js:415 ../js/ui/unlockDialog.js:126
#: ../js/ui/userMenu.js:934
#: ../js/ui/status/bluetooth.js:415 ../js/ui/unlockDialog.js:99
#: ../js/ui/userMenu.js:938
msgid "Cancel"
msgstr "Откажи"
#: ../js/gdm/loginDialog.js:799
#: ../js/gdm/loginDialog.js:802
msgctxt "button"
msgid "Sign In"
msgstr "Пријави ме"
#: ../js/gdm/loginDialog.js:799
#: ../js/gdm/loginDialog.js:802
msgid "Next"
msgstr "Даље"
#. TTLS and PEAP are actually much more complicated, but this complication
#. is not visible here since we only care about phase2 authentication
#. (and don't even care of which one)
#: ../js/gdm/loginDialog.js:904 ../js/ui/components/networkAgent.js:260
#: ../js/gdm/loginDialog.js:917 ../js/ui/components/networkAgent.js:260
#: ../js/ui/components/networkAgent.js:278
msgid "Username: "
msgstr "Корисничко име: "
#: ../js/gdm/loginDialog.js:1157
#: ../js/gdm/loginDialog.js:1173
msgid "Login Window"
msgstr "Прозор за пријављивање"
#. Translators: accessible name of the power menu in the login screen
#: ../js/gdm/powerMenu.js:36
msgid "Power"
msgstr "Угаси"
msgstr "Напајање"
#: ../js/gdm/powerMenu.js:93 ../js/ui/userMenu.js:695 ../js/ui/userMenu.js:699
#: ../js/ui/userMenu.js:815
#: ../js/gdm/powerMenu.js:93 ../js/ui/userMenu.js:696 ../js/ui/userMenu.js:700
#: ../js/ui/userMenu.js:816
msgid "Suspend"
msgstr "Обустави"
@ -419,58 +418,58 @@ msgstr "Обустави"
msgid "Restart"
msgstr "Поново покрени"
#: ../js/gdm/powerMenu.js:103 ../js/ui/userMenu.js:697
#: ../js/ui/userMenu.js:699 ../js/ui/userMenu.js:814 ../js/ui/userMenu.js:938
#: ../js/gdm/powerMenu.js:103 ../js/ui/userMenu.js:698
#: ../js/ui/userMenu.js:700 ../js/ui/userMenu.js:815 ../js/ui/userMenu.js:942
msgid "Power Off"
msgstr "Угаси"
msgstr "Искључи"
#: ../js/gdm/util.js:182
#: ../js/gdm/util.js:249
msgid "Authentication error"
msgstr "Грешка потврђивања идентитета"
#. Translators: this message is shown below the password entry field
#. to indicate the user can swipe their finger instead
#: ../js/gdm/util.js:299
#: ../js/gdm/util.js:366
msgid "(or swipe finger)"
msgstr "(или лупите прст)"
#: ../js/gdm/util.js:324
#: ../js/gdm/util.js:391
#, c-format
msgid "(e.g., user or %s)"
msgstr "(нпр., корисник или %s)"
#: ../js/misc/util.js:94
#: ../js/misc/util.js:97
msgid "Command not found"
msgstr "Наредба није нађена"
#. Replace "Error invoking GLib.shell_parse_argv: " with
#. something nicer
#: ../js/misc/util.js:127
#: ../js/misc/util.js:130
msgid "Could not parse command:"
msgstr "Не могу да обрадим наредбу:"
#: ../js/misc/util.js:135
#: ../js/misc/util.js:138
#, c-format
msgid "Execution of '%s' failed:"
msgstr "Није успело покретање „%s“:"
#: ../js/ui/appDisplay.js:348
#: ../js/ui/appDisplay.js:349
msgid "Frequent"
msgstr "Често"
#: ../js/ui/appDisplay.js:355
#: ../js/ui/appDisplay.js:356
msgid "All"
msgstr "Све"
#: ../js/ui/appDisplay.js:913
#: ../js/ui/appDisplay.js:914
msgid "New Window"
msgstr "Нови прозор"
#: ../js/ui/appDisplay.js:916 ../js/ui/dash.js:284
#: ../js/ui/appDisplay.js:917 ../js/ui/dash.js:284
msgid "Remove from Favorites"
msgstr "Уклони из омиљених"
#: ../js/ui/appDisplay.js:917
#: ../js/ui/appDisplay.js:918
msgid "Add to Favorites"
msgstr "Додај у омиљене"
@ -484,7 +483,7 @@ msgstr "„%s“ је додат међу омиљене."
msgid "%s has been removed from your favorites."
msgstr "„%s“ је уклоњен из омиљених."
#: ../js/ui/backgroundMenu.js:19 ../js/ui/userMenu.js:788
#: ../js/ui/backgroundMenu.js:19 ../js/ui/userMenu.js:789
msgid "Settings"
msgstr "Подешавања"
@ -507,7 +506,7 @@ msgctxt "event list time"
msgid "%H\\u2236%M"
msgstr "%H\\u2236%M"
#. Transators: Shown in calendar event list, if 12h format,
#. Translators: Shown in calendar event list, if 12h format,
#. \u2236 is a ratio character, similar to : and \u2009 is
#. a thin space
#: ../js/ui/calendar.js:77
@ -609,35 +608,35 @@ msgid "S"
msgstr "Суб"
#. Translators: Text to show if there are no events
#: ../js/ui/calendar.js:692
#: ../js/ui/calendar.js:720
msgid "Nothing Scheduled"
msgstr "Ништа планирано"
#. Translators: Shown on calendar heading when selected day occurs on current year
#: ../js/ui/calendar.js:708
#: ../js/ui/calendar.js:736
msgctxt "calendar heading"
msgid "%A, %B %d"
msgstr "%A, %B %d"
#. Translators: Shown on calendar heading when selected day occurs on different year
#: ../js/ui/calendar.js:711
#: ../js/ui/calendar.js:739
msgctxt "calendar heading"
msgid "%A, %B %d, %Y"
msgstr "%A, %B %d, %Y"
#: ../js/ui/calendar.js:721
#: ../js/ui/calendar.js:749
msgid "Today"
msgstr "Данас"
#: ../js/ui/calendar.js:725
#: ../js/ui/calendar.js:753
msgid "Tomorrow"
msgstr "Сутра"
#: ../js/ui/calendar.js:736
#: ../js/ui/calendar.js:764
msgid "This week"
msgstr "Ове недеље"
#: ../js/ui/calendar.js:744
#: ../js/ui/calendar.js:772
msgid "Next week"
msgstr "Следеће недеље"
@ -653,12 +652,12 @@ msgstr "Спољни уређај је искључен"
msgid "Removable Devices"
msgstr "Уклоњиви уређаји"
#: ../js/ui/components/autorunManager.js:593
#: ../js/ui/components/autorunManager.js:594
#, c-format
msgid "Open with %s"
msgstr "Отвори програмом %s"
#: ../js/ui/components/autorunManager.js:619
#: ../js/ui/components/autorunManager.js:620
msgid "Eject"
msgstr "Избаци"
@ -1038,7 +1037,7 @@ msgstr "Подешавања датума и времена"
#. 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:205
#: ../js/ui/dateMenu.js:215
msgid "%A %B %e, %Y"
msgstr "%A, %e. %b., %R"
@ -1213,7 +1212,6 @@ msgid "Remove"
msgstr "Уклони"
#: ../js/ui/messageTray.js:1501
#| msgid "No Messages"
msgid "Clear Messages"
msgstr "Очисти поруке"
@ -1221,15 +1219,15 @@ msgstr "Очисти поруке"
msgid "Notification Settings"
msgstr "Поставке обавештења"
#: ../js/ui/messageTray.js:1707
#: ../js/ui/messageTray.js:1709
msgid "No Messages"
msgstr "Нема порука"
#: ../js/ui/messageTray.js:1787
#: ../js/ui/messageTray.js:1782
msgid "Message Tray"
msgstr "Фиока порука"
#: ../js/ui/messageTray.js:2864
#: ../js/ui/messageTray.js:2810
msgid "System Information"
msgstr "Подаци о систему"
@ -1238,7 +1236,7 @@ msgctxt "program"
msgid "Unknown"
msgstr "Непознат"
#: ../js/ui/overviewControls.js:460 ../js/ui/screenShield.js:153
#: ../js/ui/overviewControls.js:463 ../js/ui/screenShield.js:149
#, c-format
msgid "%d new message"
msgid_plural "%d new messages"
@ -1247,7 +1245,7 @@ msgstr[1] "%d нове поруке"
msgstr[2] "%d нових порука"
msgstr[3] "Једна нова порука"
#: ../js/ui/overview.js:82
#: ../js/ui/overview.js:84
msgid "Undo"
msgstr "Опозови"
@ -1259,22 +1257,21 @@ msgstr "Преглед"
#. in the search entry when no search is
#. active; it should not exceed ~30
#. characters.
#: ../js/ui/overview.js:284
#| msgid "Type to search..."
#: ../js/ui/overview.js:271
msgid "Type to search…"
msgstr "Упишите текст за претрагу…"
#: ../js/ui/panel.js:613
#: ../js/ui/panel.js:612
msgid "Quit"
msgstr "Изађи"
#. Translators: If there is no suitable word for "Activities"
#. in your language, you can use the word for "Overview".
#: ../js/ui/panel.js:642
#: ../js/ui/panel.js:636
msgid "Activities"
msgstr "Активности"
#: ../js/ui/panel.js:983
#: ../js/ui/panel.js:933
msgid "Top Bar"
msgstr "Горња трака"
@ -1287,21 +1284,21 @@ msgstr "Горња трака"
msgid "toggle-switch-us"
msgstr "toggle-switch-intl"
#: ../js/ui/runDialog.js:205
#: ../js/ui/runDialog.js:73
msgid "Enter a Command"
msgstr "Унесите наредбу"
#: ../js/ui/runDialog.js:241
#: ../js/ui/runDialog.js:109
msgid "Close"
msgstr "Затвори"
#. Translators: This is a time format for a date in
#. long format
#: ../js/ui/screenShield.js:90
#: ../js/ui/screenShield.js:86
msgid "%A, %B %d"
msgstr "%A, %d. %B"
#: ../js/ui/screenShield.js:155
#: ../js/ui/screenShield.js:151
#, c-format
msgid "%d new notification"
msgid_plural "%d new notifications"
@ -1310,11 +1307,11 @@ msgstr[1] "%d нова обавештења"
msgstr[2] "%d нових обавештења"
msgstr[3] "Једно ново обавештење"
#: ../js/ui/screenShield.js:442 ../js/ui/userMenu.js:806
#: ../js/ui/screenShield.js:438 ../js/ui/userMenu.js:807
msgid "Lock"
msgstr "Закључај"
#: ../js/ui/screenShield.js:639
#: ../js/ui/screenShield.js:640
msgid "GNOME needs to lock the screen"
msgstr "Гном мора да закључа екран"
@ -1325,21 +1322,19 @@ msgstr "Гном мора да закључа екран"
#.
#. XXX: another option is to kick the user into the gdm login
#. screen, where we're not affected by grabs
#: ../js/ui/screenShield.js:758 ../js/ui/screenShield.js:1169
#| msgid "Unable to connect to %s"
#: ../js/ui/screenShield.js:761 ../js/ui/screenShield.js:1197
msgid "Unable to lock"
msgstr "Не могу да закључам"
#: ../js/ui/screenShield.js:759 ../js/ui/screenShield.js:1170
#: ../js/ui/screenShield.js:762 ../js/ui/screenShield.js:1198
msgid "Lock was blocked by an application"
msgstr "Неки програм је блокирао закључавање"
#: ../js/ui/searchDisplay.js:431
#| msgid "Searching..."
#: ../js/ui/searchDisplay.js:453
msgid "Searching…"
msgstr "Тражим…"
#: ../js/ui/searchDisplay.js:475
#: ../js/ui/searchDisplay.js:497
msgid "No results."
msgstr "Нема одговарајућих резултата."
@ -1351,11 +1346,11 @@ msgstr "Умножи"
msgid "Paste"
msgstr "Убаци"
#: ../js/ui/shellEntry.js:105
#: ../js/ui/shellEntry.js:106
msgid "Show Text"
msgstr "Прикажи текст"
#: ../js/ui/shellEntry.js:107
#: ../js/ui/shellEntry.js:108
msgid "Hide Text"
msgstr "Сакриј текст"
@ -1367,7 +1362,7 @@ msgstr "Лозинка"
msgid "Remember Password"
msgstr "Запамти лозинку"
#: ../js/ui/shellMountOperation.js:403 ../js/ui/unlockDialog.js:140
#: ../js/ui/shellMountOperation.js:403 ../js/ui/unlockDialog.js:113
msgid "Unlock"
msgstr "Откључај"
@ -1431,12 +1426,10 @@ msgid "Visibility"
msgstr "Видљивост"
#: ../js/ui/status/bluetooth.js:59
#| msgid "Send Files to Device..."
msgid "Send Files to Device…"
msgstr "Пошаљи датотеке на уређај…"
#: ../js/ui/status/bluetooth.js:60
#| msgid "Set Up a New Device..."
msgid "Set Up a New Device…"
msgstr "Подеси нови уређај…"
@ -1463,7 +1456,6 @@ msgid "connecting..."
msgstr "повезујем се..."
#: ../js/ui/status/bluetooth.js:239
#| msgid "Send Files..."
msgid "Send Files…"
msgstr "Пошаљи датотеке…"
@ -1676,7 +1668,6 @@ msgstr "Подешавања напајања"
#. 0 is reported when UPower does not have enough data
#. to estimate battery life
#: ../js/ui/status/power.js:99
#| msgid "Estimating..."
msgid "Estimating…"
msgstr "Приближно…"
@ -1784,11 +1775,11 @@ msgstr "Јачина звука"
msgid "Microphone"
msgstr "Микрофон"
#: ../js/ui/unlockDialog.js:151
#: ../js/ui/unlockDialog.js:124
msgid "Log in as another user"
msgstr "Пријавите се као други корсник"
#: ../js/ui/unlockDialog.js:177
#: ../js/ui/unlockDialog.js:145
msgid "Unlock Window"
msgstr "Откључај прозор"
@ -1816,27 +1807,27 @@ msgstr "Мирује"
msgid "Offline"
msgstr "Ван мреже"
#: ../js/ui/userMenu.js:780
#: ../js/ui/userMenu.js:781
msgid "Notifications"
msgstr "Обавештења"
#: ../js/ui/userMenu.js:796
#: ../js/ui/userMenu.js:797
msgid "Switch User"
msgstr "Промени корисника"
#: ../js/ui/userMenu.js:801
#: ../js/ui/userMenu.js:802
msgid "Log Out"
msgstr "Одјави ме"
#: ../js/ui/userMenu.js:821
#: ../js/ui/userMenu.js:822
msgid "Install Updates & Restart"
msgstr "Инсталирај ажурирања и поново покрени"
#: ../js/ui/userMenu.js:839
#: ../js/ui/userMenu.js:840
msgid "Your chat status will be set to busy"
msgstr "Ваше стање ћаскања ће бити постављено на заузето"
#: ../js/ui/userMenu.js:840
#: ../js/ui/userMenu.js:841
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."
@ -1845,20 +1836,22 @@ msgstr ""
"мрежи је подешено тако да ће остали знати да ви не можете видети њихове "
"поруке."
#: ../js/ui/userMenu.js:886
#: ../js/ui/userMenu.js:888
msgid "Other users are logged in."
msgstr "Други корисници су пријављени."
#: ../js/ui/userMenu.js:891
#: ../js/ui/userMenu.js:893
msgid "Shutting down might cause them to lose unsaved work."
msgstr "Искључивање може да доведе до тога да изгубе несачувани рад."
#: ../js/ui/userMenu.js:918
#. Translators: Remote here refers to a remote session, like a ssh login
#: ../js/ui/userMenu.js:921
#, c-format
msgid "%s (remote)"
msgstr "%s (удаљено)"
#: ../js/ui/userMenu.js:920
#. Translators: Console here refers to a tty like a VT console
#: ../js/ui/userMenu.js:924
#, c-format
msgid "%s (console)"
msgstr "%s (љуска)"
@ -1871,7 +1864,7 @@ msgstr "Програми"
msgid "Search"
msgstr "Тражи"
#: ../js/ui/wanda.js:92
#: ../js/ui/wanda.js:77
#, c-format
msgid ""
"Sorry, no wisdom for you today:\n"
@ -1880,7 +1873,7 @@ msgstr ""
"Извините, данас за вас нема мудрости:\n"
"%s"
#: ../js/ui/wanda.js:96
#: ../js/ui/wanda.js:81
#, c-format
msgid "%s the Oracle says"
msgstr "Пророк је рекао %s"

View File

@ -8,7 +8,7 @@ msgstr ""
"Project-Id-Version: gnome-shell master\n"
"Report-Msgid-Bugs-To: http://bugzilla.gnome.org/enter_bug.cgi?product=gnome-"
"shell&keywords=I18N+L10N&component=general\n"
"POT-Creation-Date: 2013-03-04 08:38+0000\n"
"POT-Creation-Date: 2013-03-31 01:48+0000\n"
"PO-Revision-Date: 2013-03-08 20:26+0200\n"
"Last-Translator: Miroslav Nikolić <miroslavnikolic@rocketmail.com>\n"
"Language-Team: Serbian <gnom@prevod.org>\n"
@ -16,8 +16,8 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=4; plural=n==1? 3 : n%10==1 && n%100!=11 ? 0 : "
"n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n"
"Plural-Forms: nplurals=4; plural=n==1? 3 : n%10==1 && n%100!=11 ? 0 : n"
"%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n"
"X-Project-Style: gnome\n"
#: ../data/50-gnome-shell-screenshot.xml.in.h:1
@ -365,53 +365,52 @@ msgid "Select an extension to configure using the combobox above."
msgstr "Izaberite proširenje za podešavanje koristeći prozorče za izbor."
#: ../js/gdm/loginDialog.js:405
#| msgid "Session..."
msgid "Session…"
msgstr "Sesija…"
#. 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:629
#: ../js/gdm/loginDialog.js:630
msgid "Not listed?"
msgstr "Nije na spisku?"
#: ../js/gdm/loginDialog.js:783 ../js/ui/components/networkAgent.js:137
#: ../js/gdm/loginDialog.js:786 ../js/ui/components/networkAgent.js:137
#: ../js/ui/components/polkitAgent.js:162 ../js/ui/endSessionDialog.js:375
#: ../js/ui/extensionDownloader.js:195 ../js/ui/shellMountOperation.js:399
#: ../js/ui/status/bluetooth.js:415 ../js/ui/unlockDialog.js:126
#: ../js/ui/userMenu.js:934
#: ../js/ui/status/bluetooth.js:415 ../js/ui/unlockDialog.js:99
#: ../js/ui/userMenu.js:938
msgid "Cancel"
msgstr "Otkaži"
#: ../js/gdm/loginDialog.js:799
#: ../js/gdm/loginDialog.js:802
msgctxt "button"
msgid "Sign In"
msgstr "Prijavi me"
#: ../js/gdm/loginDialog.js:799
#: ../js/gdm/loginDialog.js:802
msgid "Next"
msgstr "Dalje"
#. TTLS and PEAP are actually much more complicated, but this complication
#. is not visible here since we only care about phase2 authentication
#. (and don't even care of which one)
#: ../js/gdm/loginDialog.js:904 ../js/ui/components/networkAgent.js:260
#: ../js/gdm/loginDialog.js:917 ../js/ui/components/networkAgent.js:260
#: ../js/ui/components/networkAgent.js:278
msgid "Username: "
msgstr "Korisničko ime: "
#: ../js/gdm/loginDialog.js:1157
#: ../js/gdm/loginDialog.js:1173
msgid "Login Window"
msgstr "Prozor za prijavljivanje"
#. Translators: accessible name of the power menu in the login screen
#: ../js/gdm/powerMenu.js:36
msgid "Power"
msgstr "Ugasi"
msgstr "Napajanje"
#: ../js/gdm/powerMenu.js:93 ../js/ui/userMenu.js:695 ../js/ui/userMenu.js:699
#: ../js/ui/userMenu.js:815
#: ../js/gdm/powerMenu.js:93 ../js/ui/userMenu.js:696 ../js/ui/userMenu.js:700
#: ../js/ui/userMenu.js:816
msgid "Suspend"
msgstr "Obustavi"
@ -419,58 +418,58 @@ msgstr "Obustavi"
msgid "Restart"
msgstr "Ponovo pokreni"
#: ../js/gdm/powerMenu.js:103 ../js/ui/userMenu.js:697
#: ../js/ui/userMenu.js:699 ../js/ui/userMenu.js:814 ../js/ui/userMenu.js:938
#: ../js/gdm/powerMenu.js:103 ../js/ui/userMenu.js:698
#: ../js/ui/userMenu.js:700 ../js/ui/userMenu.js:815 ../js/ui/userMenu.js:942
msgid "Power Off"
msgstr "Ugasi"
msgstr "Isključi"
#: ../js/gdm/util.js:182
#: ../js/gdm/util.js:249
msgid "Authentication error"
msgstr "Greška potvrđivanja identiteta"
#. Translators: this message is shown below the password entry field
#. to indicate the user can swipe their finger instead
#: ../js/gdm/util.js:299
#: ../js/gdm/util.js:366
msgid "(or swipe finger)"
msgstr "(ili lupite prst)"
#: ../js/gdm/util.js:324
#: ../js/gdm/util.js:391
#, c-format
msgid "(e.g., user or %s)"
msgstr "(npr., korisnik ili %s)"
#: ../js/misc/util.js:94
#: ../js/misc/util.js:97
msgid "Command not found"
msgstr "Naredba nije nađena"
#. Replace "Error invoking GLib.shell_parse_argv: " with
#. something nicer
#: ../js/misc/util.js:127
#: ../js/misc/util.js:130
msgid "Could not parse command:"
msgstr "Ne mogu da obradim naredbu:"
#: ../js/misc/util.js:135
#: ../js/misc/util.js:138
#, c-format
msgid "Execution of '%s' failed:"
msgstr "Nije uspelo pokretanje „%s“:"
#: ../js/ui/appDisplay.js:348
#: ../js/ui/appDisplay.js:349
msgid "Frequent"
msgstr "Često"
#: ../js/ui/appDisplay.js:355
#: ../js/ui/appDisplay.js:356
msgid "All"
msgstr "Sve"
#: ../js/ui/appDisplay.js:913
#: ../js/ui/appDisplay.js:914
msgid "New Window"
msgstr "Novi prozor"
#: ../js/ui/appDisplay.js:916 ../js/ui/dash.js:284
#: ../js/ui/appDisplay.js:917 ../js/ui/dash.js:284
msgid "Remove from Favorites"
msgstr "Ukloni iz omiljenih"
#: ../js/ui/appDisplay.js:917
#: ../js/ui/appDisplay.js:918
msgid "Add to Favorites"
msgstr "Dodaj u omiljene"
@ -484,7 +483,7 @@ msgstr "„%s“ je dodat među omiljene."
msgid "%s has been removed from your favorites."
msgstr "„%s“ je uklonjen iz omiljenih."
#: ../js/ui/backgroundMenu.js:19 ../js/ui/userMenu.js:788
#: ../js/ui/backgroundMenu.js:19 ../js/ui/userMenu.js:789
msgid "Settings"
msgstr "Podešavanja"
@ -507,7 +506,7 @@ msgctxt "event list time"
msgid "%H\\u2236%M"
msgstr "%H\\u2236%M"
#. Transators: Shown in calendar event list, if 12h format,
#. Translators: Shown in calendar event list, if 12h format,
#. \u2236 is a ratio character, similar to : and \u2009 is
#. a thin space
#: ../js/ui/calendar.js:77
@ -609,35 +608,35 @@ msgid "S"
msgstr "Sub"
#. Translators: Text to show if there are no events
#: ../js/ui/calendar.js:692
#: ../js/ui/calendar.js:720
msgid "Nothing Scheduled"
msgstr "Ništa planirano"
#. Translators: Shown on calendar heading when selected day occurs on current year
#: ../js/ui/calendar.js:708
#: ../js/ui/calendar.js:736
msgctxt "calendar heading"
msgid "%A, %B %d"
msgstr "%A, %B %d"
#. Translators: Shown on calendar heading when selected day occurs on different year
#: ../js/ui/calendar.js:711
#: ../js/ui/calendar.js:739
msgctxt "calendar heading"
msgid "%A, %B %d, %Y"
msgstr "%A, %B %d, %Y"
#: ../js/ui/calendar.js:721
#: ../js/ui/calendar.js:749
msgid "Today"
msgstr "Danas"
#: ../js/ui/calendar.js:725
#: ../js/ui/calendar.js:753
msgid "Tomorrow"
msgstr "Sutra"
#: ../js/ui/calendar.js:736
#: ../js/ui/calendar.js:764
msgid "This week"
msgstr "Ove nedelje"
#: ../js/ui/calendar.js:744
#: ../js/ui/calendar.js:772
msgid "Next week"
msgstr "Sledeće nedelje"
@ -653,12 +652,12 @@ msgstr "Spoljni uređaj je isključen"
msgid "Removable Devices"
msgstr "Uklonjivi uređaji"
#: ../js/ui/components/autorunManager.js:593
#: ../js/ui/components/autorunManager.js:594
#, c-format
msgid "Open with %s"
msgstr "Otvori programom %s"
#: ../js/ui/components/autorunManager.js:619
#: ../js/ui/components/autorunManager.js:620
msgid "Eject"
msgstr "Izbaci"
@ -1038,7 +1037,7 @@ msgstr "Podešavanja datuma i vremena"
#. 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:205
#: ../js/ui/dateMenu.js:215
msgid "%A %B %e, %Y"
msgstr "%A, %e. %b., %R"
@ -1213,7 +1212,6 @@ msgid "Remove"
msgstr "Ukloni"
#: ../js/ui/messageTray.js:1501
#| msgid "No Messages"
msgid "Clear Messages"
msgstr "Očisti poruke"
@ -1221,15 +1219,15 @@ msgstr "Očisti poruke"
msgid "Notification Settings"
msgstr "Postavke obaveštenja"
#: ../js/ui/messageTray.js:1707
#: ../js/ui/messageTray.js:1709
msgid "No Messages"
msgstr "Nema poruka"
#: ../js/ui/messageTray.js:1787
#: ../js/ui/messageTray.js:1782
msgid "Message Tray"
msgstr "Fioka poruka"
#: ../js/ui/messageTray.js:2864
#: ../js/ui/messageTray.js:2810
msgid "System Information"
msgstr "Podaci o sistemu"
@ -1238,7 +1236,7 @@ msgctxt "program"
msgid "Unknown"
msgstr "Nepoznat"
#: ../js/ui/overviewControls.js:460 ../js/ui/screenShield.js:153
#: ../js/ui/overviewControls.js:463 ../js/ui/screenShield.js:149
#, c-format
msgid "%d new message"
msgid_plural "%d new messages"
@ -1247,7 +1245,7 @@ msgstr[1] "%d nove poruke"
msgstr[2] "%d novih poruka"
msgstr[3] "Jedna nova poruka"
#: ../js/ui/overview.js:82
#: ../js/ui/overview.js:84
msgid "Undo"
msgstr "Opozovi"
@ -1259,22 +1257,21 @@ msgstr "Pregled"
#. in the search entry when no search is
#. active; it should not exceed ~30
#. characters.
#: ../js/ui/overview.js:284
#| msgid "Type to search..."
#: ../js/ui/overview.js:271
msgid "Type to search…"
msgstr "Upišite tekst za pretragu…"
#: ../js/ui/panel.js:613
#: ../js/ui/panel.js:612
msgid "Quit"
msgstr "Izađi"
#. Translators: If there is no suitable word for "Activities"
#. in your language, you can use the word for "Overview".
#: ../js/ui/panel.js:642
#: ../js/ui/panel.js:636
msgid "Activities"
msgstr "Aktivnosti"
#: ../js/ui/panel.js:983
#: ../js/ui/panel.js:933
msgid "Top Bar"
msgstr "Gornja traka"
@ -1287,21 +1284,21 @@ msgstr "Gornja traka"
msgid "toggle-switch-us"
msgstr "toggle-switch-intl"
#: ../js/ui/runDialog.js:205
#: ../js/ui/runDialog.js:73
msgid "Enter a Command"
msgstr "Unesite naredbu"
#: ../js/ui/runDialog.js:241
#: ../js/ui/runDialog.js:109
msgid "Close"
msgstr "Zatvori"
#. Translators: This is a time format for a date in
#. long format
#: ../js/ui/screenShield.js:90
#: ../js/ui/screenShield.js:86
msgid "%A, %B %d"
msgstr "%A, %d. %B"
#: ../js/ui/screenShield.js:155
#: ../js/ui/screenShield.js:151
#, c-format
msgid "%d new notification"
msgid_plural "%d new notifications"
@ -1310,11 +1307,11 @@ msgstr[1] "%d nova obaveštenja"
msgstr[2] "%d novih obaveštenja"
msgstr[3] "Jedno novo obaveštenje"
#: ../js/ui/screenShield.js:442 ../js/ui/userMenu.js:806
#: ../js/ui/screenShield.js:438 ../js/ui/userMenu.js:807
msgid "Lock"
msgstr "Zaključaj"
#: ../js/ui/screenShield.js:639
#: ../js/ui/screenShield.js:640
msgid "GNOME needs to lock the screen"
msgstr "Gnom mora da zaključa ekran"
@ -1325,21 +1322,19 @@ msgstr "Gnom mora da zaključa ekran"
#.
#. XXX: another option is to kick the user into the gdm login
#. screen, where we're not affected by grabs
#: ../js/ui/screenShield.js:758 ../js/ui/screenShield.js:1169
#| msgid "Unable to connect to %s"
#: ../js/ui/screenShield.js:761 ../js/ui/screenShield.js:1197
msgid "Unable to lock"
msgstr "Ne mogu da zaključam"
#: ../js/ui/screenShield.js:759 ../js/ui/screenShield.js:1170
#: ../js/ui/screenShield.js:762 ../js/ui/screenShield.js:1198
msgid "Lock was blocked by an application"
msgstr "Neki program je blokirao zaključavanje"
#: ../js/ui/searchDisplay.js:431
#| msgid "Searching..."
#: ../js/ui/searchDisplay.js:453
msgid "Searching…"
msgstr "Tražim…"
#: ../js/ui/searchDisplay.js:475
#: ../js/ui/searchDisplay.js:497
msgid "No results."
msgstr "Nema odgovarajućih rezultata."
@ -1351,11 +1346,11 @@ msgstr "Umnoži"
msgid "Paste"
msgstr "Ubaci"
#: ../js/ui/shellEntry.js:105
#: ../js/ui/shellEntry.js:106
msgid "Show Text"
msgstr "Prikaži tekst"
#: ../js/ui/shellEntry.js:107
#: ../js/ui/shellEntry.js:108
msgid "Hide Text"
msgstr "Sakrij tekst"
@ -1367,7 +1362,7 @@ msgstr "Lozinka"
msgid "Remember Password"
msgstr "Zapamti lozinku"
#: ../js/ui/shellMountOperation.js:403 ../js/ui/unlockDialog.js:140
#: ../js/ui/shellMountOperation.js:403 ../js/ui/unlockDialog.js:113
msgid "Unlock"
msgstr "Otključaj"
@ -1431,12 +1426,10 @@ msgid "Visibility"
msgstr "Vidljivost"
#: ../js/ui/status/bluetooth.js:59
#| msgid "Send Files to Device..."
msgid "Send Files to Device…"
msgstr "Pošalji datoteke na uređaj…"
#: ../js/ui/status/bluetooth.js:60
#| msgid "Set Up a New Device..."
msgid "Set Up a New Device…"
msgstr "Podesi novi uređaj…"
@ -1463,7 +1456,6 @@ msgid "connecting..."
msgstr "povezujem se..."
#: ../js/ui/status/bluetooth.js:239
#| msgid "Send Files..."
msgid "Send Files…"
msgstr "Pošalji datoteke…"
@ -1676,7 +1668,6 @@ msgstr "Podešavanja napajanja"
#. 0 is reported when UPower does not have enough data
#. to estimate battery life
#: ../js/ui/status/power.js:99
#| msgid "Estimating..."
msgid "Estimating…"
msgstr "Približno…"
@ -1784,11 +1775,11 @@ msgstr "Jačina zvuka"
msgid "Microphone"
msgstr "Mikrofon"
#: ../js/ui/unlockDialog.js:151
#: ../js/ui/unlockDialog.js:124
msgid "Log in as another user"
msgstr "Prijavite se kao drugi korsnik"
#: ../js/ui/unlockDialog.js:177
#: ../js/ui/unlockDialog.js:145
msgid "Unlock Window"
msgstr "Otključaj prozor"
@ -1816,27 +1807,27 @@ msgstr "Miruje"
msgid "Offline"
msgstr "Van mreže"
#: ../js/ui/userMenu.js:780
#: ../js/ui/userMenu.js:781
msgid "Notifications"
msgstr "Obaveštenja"
#: ../js/ui/userMenu.js:796
#: ../js/ui/userMenu.js:797
msgid "Switch User"
msgstr "Promeni korisnika"
#: ../js/ui/userMenu.js:801
#: ../js/ui/userMenu.js:802
msgid "Log Out"
msgstr "Odjavi me"
#: ../js/ui/userMenu.js:821
#: ../js/ui/userMenu.js:822
msgid "Install Updates & Restart"
msgstr "Instaliraj ažuriranja i ponovo pokreni"
#: ../js/ui/userMenu.js:839
#: ../js/ui/userMenu.js:840
msgid "Your chat status will be set to busy"
msgstr "Vaše stanje ćaskanja će biti postavljeno na zauzeto"
#: ../js/ui/userMenu.js:840
#: ../js/ui/userMenu.js:841
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."
@ -1845,20 +1836,22 @@ msgstr ""
"mreži je podešeno tako da će ostali znati da vi ne možete videti njihove "
"poruke."
#: ../js/ui/userMenu.js:886
#: ../js/ui/userMenu.js:888
msgid "Other users are logged in."
msgstr "Drugi korisnici su prijavljeni."
#: ../js/ui/userMenu.js:891
#: ../js/ui/userMenu.js:893
msgid "Shutting down might cause them to lose unsaved work."
msgstr "Isključivanje može da dovede do toga da izgube nesačuvani rad."
#: ../js/ui/userMenu.js:918
#. Translators: Remote here refers to a remote session, like a ssh login
#: ../js/ui/userMenu.js:921
#, c-format
msgid "%s (remote)"
msgstr "%s (udaljeno)"
#: ../js/ui/userMenu.js:920
#. Translators: Console here refers to a tty like a VT console
#: ../js/ui/userMenu.js:924
#, c-format
msgid "%s (console)"
msgstr "%s (ljuska)"
@ -1871,7 +1864,7 @@ msgstr "Programi"
msgid "Search"
msgstr "Traži"
#: ../js/ui/wanda.js:92
#: ../js/ui/wanda.js:77
#, c-format
msgid ""
"Sorry, no wisdom for you today:\n"
@ -1880,7 +1873,7 @@ msgstr ""
"Izvinite, danas za vas nema mudrosti:\n"
"%s"
#: ../js/ui/wanda.js:96
#: ../js/ui/wanda.js:81
#, c-format
msgid "%s the Oracle says"
msgstr "Prorok je rekao %s"

2602
po/tr.po

File diff suppressed because it is too large Load Diff

442
po/vi.po
View File

@ -1,18 +1,19 @@
# Vietnamese translation for gnome-shell.
# Copyright (C) 2010 GNOME i18n Project for Vietnamese.
# Copyright (C) 2013 GNOME i18n Project for Vietnamese.
# This file is distributed under the same license as the gnome-shell package.
# Nguyễn Thái Ngọc Duy <pclouds@gmail.com>, 2010-2013.
# Ngô Chin <ndtrung4419@gmail.com>, 2011.
# Trần Ngọc Quân <vnwildman@gmail.com>, 2013.
#
msgid ""
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: 2013-03-02 23:02+0000\n"
"PO-Revision-Date: 2013-03-03 11:13+0700\n"
"Last-Translator: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>\n"
"Language-Team: Vietnamese <vi-VN@googlegroups.com>\n"
"POT-Creation-Date: 2013-03-23 11:49+0000\n"
"PO-Revision-Date: 2013-04-13 17:51+1000\n"
"Last-Translator: Trần Ngọc Quân <vnwildman@gmail.com>\n"
"Language-Team: Vietnamese <translation-team-vi@lists.sourceforge.net>\n"
"Language: vi\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
@ -49,7 +50,7 @@ msgstr "Mở trình đơn ứng dụng"
#: ../data/gnome-shell.desktop.in.in.h:1
msgid "GNOME Shell"
msgstr "GNOME Shell"
msgstr "Hệ vỏ GNOME"
#: ../data/gnome-shell.desktop.in.in.h:2
msgid "Window management and application launching"
@ -58,11 +59,11 @@ msgstr "Quản lý cửa sổ và chạy ứng dụng"
#: ../data/gnome-shell-extension-prefs.desktop.in.in.h:1
#: ../js/extensionPrefs/main.js:153
msgid "GNOME Shell Extension Preferences"
msgstr "Tuỳ thích phần mở rộng GNOME Shell"
msgstr "Cá nhân hóa phần mở rộng hệ vỏ GNOME"
#: ../data/gnome-shell-extension-prefs.desktop.in.in.h:2
msgid "Configure GNOME Shell Extensions"
msgstr "Cấu hình phần mở rộng GNOME Shell"
msgstr "Cấu hình phần mở rộng Hệ vỏ GNOME"
#: ../data/org.gnome.shell.gschema.xml.in.in.h:1
msgid "Enable internal tools useful for developers and testers from Alt-F2"
@ -87,7 +88,7 @@ msgid ""
"list. You can also manipulate this list with the EnableExtension and "
"DisableExtension DBus methods on org.gnome.Shell."
msgstr ""
"Phần mở rộng GNOME Shell có thuộc tính uuid. Khoá này liệt kê danh sách phần "
"Phần mở rộng Hệ vỏ GNOME có thuộc tính uuid; khóa này liệt kê danh sách phần "
"mở rộng nên nạp. Bất kỳ phần mở rộng nào muốn nạp phải nằm trong danh sách "
"này. Bạn có thể thao tác trên danh sách này với phương thức DBus "
"EnableExtension và DisableExtension trên org.gnome.Shell."
@ -120,13 +121,15 @@ msgstr ""
#: ../data/org.gnome.shell.gschema.xml.in.in.h:9
msgid "List of categories that should be displayed as folders"
msgstr ""
msgstr "Liệt kê các các-ta-lốc mà nó có thể hiển thị như một thư mục"
#: ../data/org.gnome.shell.gschema.xml.in.in.h:10
msgid ""
"Each category name in this list will be represented as folder in the "
"application view, rather than being displayed inline in the main view."
msgstr ""
"Mỗi tên các-ta-lốc trong danh sách này sẽ được xuất hiện như là một thư mục "
"trong trình bày ứng dụng, thay vì hiển thị cùng dòng trong trình bày chính. "
#: ../data/org.gnome.shell.gschema.xml.in.in.h:11
msgid "History for command (Alt-F2) dialog"
@ -154,18 +157,22 @@ msgstr ""
#: ../data/org.gnome.shell.gschema.xml.in.in.h:15
msgid "Always show the 'Log out' menuitem in the user menu."
msgstr "Luôn hiện mục \"Đăng xuất\" trên trình đơn người dùng."
msgstr "Luôn hiện mục Đăng xuất trên trình đơn người dùng."
#: ../data/org.gnome.shell.gschema.xml.in.in.h:16
msgid ""
"This key overrides the automatic hiding of the 'Log out' menuitem in single-"
"user, single-session situations."
msgstr ""
"Khóa này sẽ đè lên việc tự động ẩn trình đơn 'Đăng xuất' ở chế độ đơn-người-"
"dùng, đơn-phiên-làm-việc. "
#: ../data/org.gnome.shell.gschema.xml.in.in.h:17
msgid ""
"Whether to remember password for mounting encrypted or remote filesystems"
msgstr ""
"Hoặc là ghi nhớ mật khẩu dành cho việc gắn hệ thống tập tin đã mã hóa hoặc "
"hệ thống tập tin trên máy chủ"
#: ../data/org.gnome.shell.gschema.xml.in.in.h:18
msgid ""
@ -174,6 +181,10 @@ msgid ""
"'Remember Password' checkbox will be present. This key sets the default "
"state of the checkbox."
msgstr ""
"Hệ vỏ sẽ yêu cầu mật khẩu khi có thư mục được mã hóa hay hệ thống tập tin "
"máy mạng được gắn. Nếu mật khẩu có thể ghi lại để dùng trong lần sau, hộp "
"dấu kiểm “Nhớ mật khẩu” sẽ xuất hiện. Khóa này đặt trạng thái mặc định cho "
"hộp dấu kiểm."
#: ../data/org.gnome.shell.gschema.xml.in.in.h:19
msgid "Show the week date in the calendar"
@ -226,27 +237,27 @@ msgstr "Phím chạy hoặc ngừng trình thu màn hình."
#: ../data/org.gnome.shell.gschema.xml.in.in.h:31
msgid "Which keyboard to use"
msgstr "Loại bàn phím cần dùng"
msgstr "Bàn phím cần dùng"
#: ../data/org.gnome.shell.gschema.xml.in.in.h:32
msgid "The type of keyboard to use."
msgstr "Loại bàn phím cần dùng."
msgstr "Kiểu bàn phím cần dùng."
#: ../data/org.gnome.shell.gschema.xml.in.in.h:33
msgid "Framerate used for recording screencasts."
msgstr "Tốc độ khung dùng lưu screencast."
msgstr "Tốc độ khung hình sẽ dùng khi ghi screencast."
#: ../data/org.gnome.shell.gschema.xml.in.in.h:34
msgid ""
"The framerate of the resulting screencast recordered by GNOME Shell's "
"screencast recorder in frames-per-second."
msgstr ""
"Tốc độ khung của screencast lưu bởi bộ thu GNOME Shell theo số khung mỗi "
"giây."
"Tốc độ khung hình của screencast được ghi bởi bộ thu Hệ vỏ GNOME tính theo "
"số khung mỗi giây."
#: ../data/org.gnome.shell.gschema.xml.in.in.h:35
msgid "The gstreamer pipeline used to encode the screencast"
msgstr "Ống dẫn gstreamer để thu screencast"
msgstr "Ống dẫn gstreamer dùng để thu screencast"
#: ../data/org.gnome.shell.gschema.xml.in.in.h:37
#, no-c-format
@ -267,9 +278,9 @@ msgstr ""
"source pad không kết nối; đầu ra từ pad sẽ được ghi vào tập tin kết quả. Tuy "
"nhiên ống dẫn có thể tự lưu đầu ra riêng - có thể hữu dụng để gửi kết quả "
"đến máy chủ icecast thông qua shout2send hoặc tương tự. Nếu bỏ chọn hoặc đặt "
"giá trị rỗng, ống dẫn mặc định sẽ được dùng, hiện thời là 'vp8enc "
"giá trị rỗng, ống dẫn mặc định sẽ được dùng, hiện thời là vp8enc "
"min_quantizer=13 max_quantizer=13 cpu-used=5 deadline=1000000 threads=%T ! "
"queue ! webmmux' và lưu ở dạng WEBM dùng VP8 codec. %T được dùng để thế chỗ "
"queue ! webmmux và lưu ở dạng WEBM dùng VP8 codec. %T được dùng để thế chỗ "
"cho số thread dự đoán tối ưu cho hệ thống."
#: ../data/org.gnome.shell.gschema.xml.in.in.h:38
@ -296,25 +307,31 @@ msgid ""
"are 'thumbnail-only' (shows a thumbnail of the window), 'app-icon-"
"only' (shows only the application icon) or 'both'."
msgstr ""
"Cấu hình về cách hiển thị các cửa sổ ở bảng chuyển đổi. Các kiểu có thể là "
"'thumbnail-only' (hiển thị ảnh thu nhỏ của cửa sổ), 'app-icon-only' (chỉ "
"hiển thị biểu tượng của ứng dụng) hoặc 'both' (cả hai)."
#: ../data/org.gnome.shell.gschema.xml.in.in.h:42
msgid "Attach modal dialog to the parent window"
msgstr ""
msgstr "Gắn hộp thoại dạng modal vào cửa sổ mẹ"
#: ../data/org.gnome.shell.gschema.xml.in.in.h:43
msgid ""
"This key overrides the key in org.gnome.mutter when running GNOME Shell."
msgstr ""
"Khóa này sẽ đè lên khóa có trong org.gnome.mutter khi chạy hệ vỏ GNOME."
#: ../data/org.gnome.shell.gschema.xml.in.in.h:44
msgid "Arrangement of buttons on the titlebar"
msgstr ""
msgstr "Sắp đặt các nút trên thanh tiêu đề"
#: ../data/org.gnome.shell.gschema.xml.in.in.h:45
msgid ""
"This key overrides the key in org.gnome.desktop.wm.preferences when running "
"GNOME Shell."
msgstr ""
"Khóa này đè lên khóa có trong org.gnome.desktop.wm.preferences khi chạy hệ "
"vỏ GNOME."
#: ../data/org.gnome.shell.gschema.xml.in.in.h:46
msgid "Enable edge tiling when dropping windows on screen edges"
@ -348,46 +365,46 @@ msgstr "Phiên làm việc…"
#. 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:629
#: ../js/gdm/loginDialog.js:630
msgid "Not listed?"
msgstr "Không có trong danh sách?"
#: ../js/gdm/loginDialog.js:783 ../js/ui/components/networkAgent.js:137
#: ../js/gdm/loginDialog.js:786 ../js/ui/components/networkAgent.js:137
#: ../js/ui/components/polkitAgent.js:162 ../js/ui/endSessionDialog.js:375
#: ../js/ui/extensionDownloader.js:195 ../js/ui/shellMountOperation.js:399
#: ../js/ui/status/bluetooth.js:415 ../js/ui/unlockDialog.js:126
#: ../js/ui/userMenu.js:932
#: ../js/ui/status/bluetooth.js:415 ../js/ui/unlockDialog.js:99
#: ../js/ui/userMenu.js:938
msgid "Cancel"
msgstr "Thôi"
#: ../js/gdm/loginDialog.js:799
#: ../js/gdm/loginDialog.js:802
msgctxt "button"
msgid "Sign In"
msgstr "Đăng nhập"
#: ../js/gdm/loginDialog.js:799
#: ../js/gdm/loginDialog.js:802
msgid "Next"
msgstr "Tới"
msgstr "Kế tiếp"
#. TTLS and PEAP are actually much more complicated, but this complication
#. is not visible here since we only care about phase2 authentication
#. (and don't even care of which one)
#: ../js/gdm/loginDialog.js:904 ../js/ui/components/networkAgent.js:260
#: ../js/gdm/loginDialog.js:917 ../js/ui/components/networkAgent.js:260
#: ../js/ui/components/networkAgent.js:278
msgid "Username: "
msgstr "Tên người dùng: "
msgstr "Tài khoản: "
#: ../js/gdm/loginDialog.js:1157
#: ../js/gdm/loginDialog.js:1173
msgid "Login Window"
msgstr "Cửa sổ đặt nhập"
msgstr "Cửa sổ đăng nhập"
#. Translators: accessible name of the power menu in the login screen
#: ../js/gdm/powerMenu.js:36
msgid "Power"
msgstr "Nguồn"
#: ../js/gdm/powerMenu.js:93 ../js/ui/userMenu.js:694 ../js/ui/userMenu.js:698
#: ../js/ui/userMenu.js:814
#: ../js/gdm/powerMenu.js:93 ../js/ui/userMenu.js:696 ../js/ui/userMenu.js:700
#: ../js/ui/userMenu.js:816
msgid "Suspend"
msgstr "Ngưng"
@ -395,58 +412,58 @@ msgstr "Ngưng"
msgid "Restart"
msgstr "Khởi động lại"
#: ../js/gdm/powerMenu.js:103 ../js/ui/userMenu.js:696
#: ../js/ui/userMenu.js:698 ../js/ui/userMenu.js:813 ../js/ui/userMenu.js:936
#: ../js/gdm/powerMenu.js:103 ../js/ui/userMenu.js:698
#: ../js/ui/userMenu.js:700 ../js/ui/userMenu.js:815 ../js/ui/userMenu.js:942
msgid "Power Off"
msgstr "Tắt máy"
#: ../js/gdm/util.js:182
#: ../js/gdm/util.js:249
msgid "Authentication error"
msgstr "Lỗi xác thực"
#. Translators: this message is shown below the password entry field
#. to indicate the user can swipe their finger instead
#: ../js/gdm/util.js:299
#: ../js/gdm/util.js:366
msgid "(or swipe finger)"
msgstr "(hoặc quẹt ngón tay)"
#: ../js/gdm/util.js:324
#: ../js/gdm/util.js:391
#, c-format
msgid "(e.g., user or %s)"
msgstr "(ví dụ người dùng hoặc %s)"
msgstr "(ví dụ: tài khoản hoặc %s)"
#: ../js/misc/util.js:94
#: ../js/misc/util.js:97
msgid "Command not found"
msgstr "Không tìm thấy lệnh"
#. Replace "Error invoking GLib.shell_parse_argv: " with
#. something nicer
#: ../js/misc/util.js:127
#: ../js/misc/util.js:130
msgid "Could not parse command:"
msgstr "Không thể phân tích lệnh:"
#: ../js/misc/util.js:135
#: ../js/misc/util.js:138
#, c-format
msgid "Execution of '%s' failed:"
msgstr "Lỗi thực hiện '%s':"
msgstr "Lỗi thực hiện %s:"
#: ../js/ui/appDisplay.js:348
#: ../js/ui/appDisplay.js:349
msgid "Frequent"
msgstr "Thường dùng"
#: ../js/ui/appDisplay.js:355
#: ../js/ui/appDisplay.js:356
msgid "All"
msgstr "Tất cả"
#: ../js/ui/appDisplay.js:913
#: ../js/ui/appDisplay.js:914
msgid "New Window"
msgstr "Cửa sổ mới"
#: ../js/ui/appDisplay.js:916 ../js/ui/dash.js:284
#: ../js/ui/appDisplay.js:917 ../js/ui/dash.js:284
msgid "Remove from Favorites"
msgstr "Bỏ đánh dấu ưa thích"
#: ../js/ui/appDisplay.js:917
#: ../js/ui/appDisplay.js:918
msgid "Add to Favorites"
msgstr "Đánh dấu ưa thích"
@ -460,13 +477,13 @@ msgstr "Đã được đánh dấu ưa thích cho %s."
msgid "%s has been removed from your favorites."
msgstr "Đã bỏ đánh dấu ưa thích cho %s"
#: ../js/ui/backgroundMenu.js:19 ../js/ui/userMenu.js:787
#: ../js/ui/backgroundMenu.js:19 ../js/ui/userMenu.js:789
msgid "Settings"
msgstr "Thiết lập"
msgstr "Cài đặt"
#: ../js/ui/backgroundMenu.js:21
msgid "Change Background…"
msgstr "Thay đổi nền…"
msgstr "Đổi ảnh nền…"
#. Translators: Shown in calendar event list for all day events
#. * Keep it short, best if you can use less then 10 characters
@ -585,35 +602,35 @@ msgid "S"
msgstr "T7"
#. Translators: Text to show if there are no events
#: ../js/ui/calendar.js:692
#: ../js/ui/calendar.js:720
msgid "Nothing Scheduled"
msgstr "Không có lịch hẹn"
#. Translators: Shown on calendar heading when selected day occurs on current year
#: ../js/ui/calendar.js:708
#: ../js/ui/calendar.js:736
msgctxt "calendar heading"
msgid "%A, %B %d"
msgstr "%A, %d %B"
#. Translators: Shown on calendar heading when selected day occurs on different year
#: ../js/ui/calendar.js:711
#: ../js/ui/calendar.js:739
msgctxt "calendar heading"
msgid "%A, %B %d, %Y"
msgstr "%A, %d %B %Y"
#: ../js/ui/calendar.js:721
#: ../js/ui/calendar.js:749
msgid "Today"
msgstr "Hôm nay"
#: ../js/ui/calendar.js:725
#: ../js/ui/calendar.js:753
msgid "Tomorrow"
msgstr "Ngày mai"
#: ../js/ui/calendar.js:736
#: ../js/ui/calendar.js:764
msgid "This week"
msgstr "Tuần này"
#: ../js/ui/calendar.js:744
#: ../js/ui/calendar.js:772
msgid "Next week"
msgstr "Tuần tới"
@ -629,12 +646,12 @@ msgstr "Ổ ngoài đã ngắt kết nối"
msgid "Removable Devices"
msgstr "Thiết bị di động"
#: ../js/ui/components/autorunManager.js:593
#: ../js/ui/components/autorunManager.js:594
#, c-format
msgid "Open with %s"
msgstr "Mở bằng %s"
#: ../js/ui/components/autorunManager.js:619
#: ../js/ui/components/autorunManager.js:620
msgid "Eject"
msgstr "Đẩy ra"
@ -685,7 +702,7 @@ msgstr "Mạng không dây cần xác thực"
msgid ""
"Passwords or encryption keys are required to access the wireless network "
"'%s'."
msgstr "Cần mật mã hoặc khoá mã để truy cập mạng không dây '%s'"
msgstr "Cần mật mã hoặc khoá mã để truy cập mạng không dây %s"
#: ../js/ui/components/networkAgent.js:314
msgid "Wired 802.1X authentication"
@ -718,7 +735,7 @@ msgstr "Mật khẩu mạng băng thông rộng"
#: ../js/ui/components/networkAgent.js:337
#, c-format
msgid "A password is required to connect to '%s'."
msgstr "Cần mật khẩu để kết nối đến '%s'."
msgstr "Cần mật khẩu để kết nối đến %s."
#: ../js/ui/components/polkitAgent.js:55
msgid "Authentication Required"
@ -772,7 +789,7 @@ msgstr "Ngừng im lặng"
#: ../js/ui/components/telepathyClient.js:480
msgid "Mute"
msgstr "Im lặng"
msgstr "Câm"
#. Translators: this is the word "Yesterday" followed by a time string. i.e. "Yesterday, 14:30"
#: ../js/ui/components/telepathyClient.js:942
@ -983,7 +1000,7 @@ msgstr "Xem tài khoản"
msgid "Unknown reason"
msgstr "Lý do không biết"
#: ../js/ui/ctrlAltTab.js:29 ../js/ui/viewSelector.js:97
#: ../js/ui/ctrlAltTab.js:29 ../js/ui/viewSelector.js:96
msgid "Windows"
msgstr "Cửa sổ"
@ -1012,7 +1029,7 @@ msgstr "Thiết lập ngày giờ"
#. 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:205
#: ../js/ui/dateMenu.js:215
msgid "%A %B %e, %Y"
msgstr "%A %e %B, %Y"
@ -1108,7 +1125,7 @@ msgstr "Cài đặt"
#: ../js/ui/extensionDownloader.js:204
#, c-format
msgid "Download and install '%s' from extensions.gnome.org?"
msgstr "Tải và cài đặt '%s' từ extensions.gnome.org chứ?"
msgstr "Tải và cài đặt %s từ extensions.gnome.org chứ?"
#: ../js/ui/keyboard.js:619 ../js/ui/status/keyboard.js:314
#: ../js/ui/status/power.js:211
@ -1137,9 +1154,7 @@ msgstr "Hiện lỗi"
msgid "Enabled"
msgstr "Bật"
#. translators:
#. * The device has been disabled
#: ../js/ui/lookingGlass.js:769 ../src/gvc/gvc-mixer-control.c:1830
#: ../js/ui/lookingGlass.js:769
msgid "Disabled"
msgstr "Tắt"
@ -1179,15 +1194,15 @@ msgstr "Xoá thông báo"
msgid "Notification Settings"
msgstr "Thiết lập thông báo"
#: ../js/ui/messageTray.js:1707
#: ../js/ui/messageTray.js:1709
msgid "No Messages"
msgstr "Không có thông báo"
#: ../js/ui/messageTray.js:1787
#: ../js/ui/messageTray.js:1782
msgid "Message Tray"
msgstr "Khay thông báo"
#: ../js/ui/messageTray.js:2864
#: ../js/ui/messageTray.js:2810
msgid "System Information"
msgstr "Thông tin hệ thống"
@ -1196,13 +1211,13 @@ msgctxt "program"
msgid "Unknown"
msgstr "Không biết"
#: ../js/ui/overviewControls.js:460 ../js/ui/screenShield.js:153
#: ../js/ui/overviewControls.js:463 ../js/ui/screenShield.js:149
#, c-format
msgid "%d new message"
msgid_plural "%d new messages"
msgstr[0] "%d tin nhắn mới"
#: ../js/ui/overview.js:82
#: ../js/ui/overview.js:84
msgid "Undo"
msgstr "Hoàn lại"
@ -1214,21 +1229,21 @@ msgstr "Tổng quan"
#. in the search entry when no search is
#. active; it should not exceed ~30
#. characters.
#: ../js/ui/overview.js:284
#: ../js/ui/overview.js:271
msgid "Type to search…"
msgstr "Nhập để tìm…"
#: ../js/ui/panel.js:613
#: ../js/ui/panel.js:612
msgid "Quit"
msgstr "Thoát"
#. Translators: If there is no suitable word for "Activities"
#. in your language, you can use the word for "Overview".
#: ../js/ui/panel.js:642
#: ../js/ui/panel.js:636
msgid "Activities"
msgstr "Hoạt động"
#: ../js/ui/panel.js:983
#: ../js/ui/panel.js:933
msgid "Top Bar"
msgstr "Thanh đỉnh"
@ -1241,31 +1256,31 @@ msgstr "Thanh đỉnh"
msgid "toggle-switch-us"
msgstr "toggle-switch-intl"
#: ../js/ui/runDialog.js:205
#: ../js/ui/runDialog.js:73
msgid "Enter a Command"
msgstr "Nhập lệnh"
#: ../js/ui/runDialog.js:241
#: ../js/ui/runDialog.js:109
msgid "Close"
msgstr "Đóng"
#. Translators: This is a time format for a date in
#. long format
#: ../js/ui/screenShield.js:90
#: ../js/ui/screenShield.js:86
msgid "%A, %B %d"
msgstr "%A, %d %B"
#: ../js/ui/screenShield.js:155
#: ../js/ui/screenShield.js:151
#, c-format
msgid "%d new notification"
msgid_plural "%d new notifications"
msgstr[0] "%d thông báo mới"
#: ../js/ui/screenShield.js:442 ../js/ui/userMenu.js:805
#: ../js/ui/screenShield.js:438 ../js/ui/userMenu.js:807
msgid "Lock"
msgstr "Khoá"
#: ../js/ui/screenShield.js:639
#: ../js/ui/screenShield.js:637
msgid "GNOME needs to lock the screen"
msgstr "GNOME cần khoá màn hình"
@ -1276,19 +1291,19 @@ msgstr "GNOME cần khoá màn hình"
#.
#. XXX: another option is to kick the user into the gdm login
#. screen, where we're not affected by grabs
#: ../js/ui/screenShield.js:758 ../js/ui/screenShield.js:1169
#: ../js/ui/screenShield.js:758 ../js/ui/screenShield.js:1194
msgid "Unable to lock"
msgstr "Không thể khoá"
#: ../js/ui/screenShield.js:759 ../js/ui/screenShield.js:1170
#: ../js/ui/screenShield.js:759 ../js/ui/screenShield.js:1195
msgid "Lock was blocked by an application"
msgstr "Một ứng dụng đã ngăn cản khoá"
#: ../js/ui/searchDisplay.js:431
#: ../js/ui/searchDisplay.js:453
msgid "Searching…"
msgstr "Đang tìm…"
#: ../js/ui/searchDisplay.js:475
#: ../js/ui/searchDisplay.js:497
msgid "No results."
msgstr "Không có kết quả."
@ -1300,11 +1315,11 @@ msgstr "Chép"
msgid "Paste"
msgstr "Dán"
#: ../js/ui/shellEntry.js:105
#: ../js/ui/shellEntry.js:106
msgid "Show Text"
msgstr "Hiện chữ"
#: ../js/ui/shellEntry.js:107
#: ../js/ui/shellEntry.js:108
msgid "Hide Text"
msgstr "Ẩn chữ"
@ -1316,7 +1331,7 @@ msgstr "Mật khẩu"
msgid "Remember Password"
msgstr "Nhớ mật khẩu"
#: ../js/ui/shellMountOperation.js:403 ../js/ui/unlockDialog.js:140
#: ../js/ui/shellMountOperation.js:403 ../js/ui/unlockDialog.js:113
msgid "Unlock"
msgstr "Bỏ khoá"
@ -1433,7 +1448,7 @@ msgstr "Yêu cầu cấp quyền từ %s"
#: ../js/ui/status/bluetooth.js:328
#, c-format
msgid "Device %s wants access to the service '%s'"
msgstr "Thiết bị %s muốn truy cập dịch vụ '%s'"
msgstr "Thiết bị %s muốn truy cập dịch vụ %s"
#: ../js/ui/status/bluetooth.js:330
msgid "Always grant access"
@ -1461,7 +1476,7 @@ msgstr "Thiết bị %s muốn kết nối với máy tính này"
#: ../js/ui/status/bluetooth.js:366
#, c-format
msgid "Please confirm whether the PIN '%06d' matches the one on the device."
msgstr "Vui lòng xác nhận PIN '%06d' khớp với số trên thiết bị."
msgstr "Vui lòng xác nhận PIN %06d khớp với số trên thiết bị."
#. Translators: this is the verb, not the noun
#: ../js/ui/status/bluetooth.js:369
@ -1717,59 +1732,59 @@ msgstr "Âm lượng"
msgid "Microphone"
msgstr "Micrô"
#: ../js/ui/unlockDialog.js:151
#: ../js/ui/unlockDialog.js:124
msgid "Log in as another user"
msgstr "Đăng nhập người dùng khác"
#: ../js/ui/unlockDialog.js:177
#: ../js/ui/unlockDialog.js:145
msgid "Unlock Window"
msgstr "Bỏ khoá cửa sổ"
#: ../js/ui/userMenu.js:192
#: ../js/ui/userMenu.js:193
msgid "Available"
msgstr "Có mặt"
#: ../js/ui/userMenu.js:195
#: ../js/ui/userMenu.js:196
msgid "Busy"
msgstr "Bận"
#: ../js/ui/userMenu.js:198
#: ../js/ui/userMenu.js:199
msgid "Invisible"
msgstr "Giấu mặt"
#: ../js/ui/userMenu.js:201
#: ../js/ui/userMenu.js:202
msgid "Away"
msgstr "Vắng mặt"
#: ../js/ui/userMenu.js:204
#: ../js/ui/userMenu.js:205
msgid "Idle"
msgstr "Nhàn rỗi"
#: ../js/ui/userMenu.js:207
#: ../js/ui/userMenu.js:208
msgid "Offline"
msgstr "Ngoại tuyến"
#: ../js/ui/userMenu.js:779
#: ../js/ui/userMenu.js:781
msgid "Notifications"
msgstr "Thông báo"
#: ../js/ui/userMenu.js:795
#: ../js/ui/userMenu.js:797
msgid "Switch User"
msgstr "Chuyển người dùng"
#: ../js/ui/userMenu.js:800
#: ../js/ui/userMenu.js:802
msgid "Log Out"
msgstr "Đăng xuất"
#: ../js/ui/userMenu.js:820
#: ../js/ui/userMenu.js:822
msgid "Install Updates & Restart"
msgstr "Cài đặt bản cập nhật và khởi động lại"
#: ../js/ui/userMenu.js:838
#: ../js/ui/userMenu.js:840
msgid "Your chat status will be set to busy"
msgstr "Trạng thái nhắn tin của bạn sẽ được đặt là bận"
#: ../js/ui/userMenu.js:839
#: ../js/ui/userMenu.js:841
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."
@ -1777,33 +1792,35 @@ msgstr ""
"Thông báo đã bị tắt, bao gồm tin nhắn. Trạng thái trực tuyến của bạn đã được "
"điều chỉnh để mọi người biết bạn sẽ không xem tin nhắn họ gửi đến."
#: ../js/ui/userMenu.js:885
#: ../js/ui/userMenu.js:888
msgid "Other users are logged in."
msgstr "Người dùng khác đang đăng nhập."
#: ../js/ui/userMenu.js:890
#: ../js/ui/userMenu.js:893
msgid "Shutting down might cause them to lose unsaved work."
msgstr "Tắt sẽ làm mất những kết quả chưa được lưu."
#: ../js/ui/userMenu.js:916
#. Translators: Remote here refers to a remote session, like a ssh login
#: ../js/ui/userMenu.js:921
#, c-format
msgid "%s (remote)"
msgstr "%s (ở xa)"
#: ../js/ui/userMenu.js:918
#. Translators: Console here refers to a tty like a VT console
#: ../js/ui/userMenu.js:924
#, c-format
msgid "%s (console)"
msgstr "%s (console)"
#: ../js/ui/viewSelector.js:101
#: ../js/ui/viewSelector.js:100
msgid "Applications"
msgstr "Ứng dụng"
#: ../js/ui/viewSelector.js:105
#: ../js/ui/viewSelector.js:104
msgid "Search"
msgstr "Tìm"
#: ../js/ui/wanda.js:92
#: ../js/ui/wanda.js:77
#, c-format
msgid ""
"Sorry, no wisdom for you today:\n"
@ -1812,7 +1829,7 @@ msgstr ""
"Rất tiếc, không có lời thông thái nào hôm nay:\n"
"%s"
#: ../js/ui/wanda.js:96
#: ../js/ui/wanda.js:81
#, c-format
msgid "%s the Oracle says"
msgstr "Nhà tiên tri %s nói"
@ -1820,32 +1837,12 @@ msgstr "Nhà tiên tri %s nói"
#: ../js/ui/windowAttentionHandler.js:19
#, c-format
msgid "'%s' is ready"
msgstr "'%s' đã sẵn sàng"
msgstr "%s đã sẵn sàng"
#: ../src/calendar-server/evolution-calendar.desktop.in.in.h:1
msgid "Evolution Calendar"
msgstr "Lịch Evolution"
#. translators:
#. * The number of sound outputs on a particular device
#: ../src/gvc/gvc-mixer-control.c:1837
#, c-format
msgid "%u Output"
msgid_plural "%u Outputs"
msgstr[0] "%u đầu ra"
#. translators:
#. * The number of sound inputs on a particular device
#: ../src/gvc/gvc-mixer-control.c:1847
#, c-format
msgid "%u Input"
msgid_plural "%u Inputs"
msgstr[0] "%u đầu vào"
#: ../src/gvc/gvc-mixer-control.c:2371
msgid "System Sounds"
msgstr "Âm thanh hệ thống"
#: ../src/main.c:347
msgid "Print version"
msgstr "In phiên bản"
@ -1856,7 +1853,7 @@ msgstr "Chể độ dùng bởi GDM cho màn hình đăng nhập"
#: ../src/main.c:359
msgid "Use a specific mode, e.g. \"gdm\" for login screen"
msgstr "Dùng chế độ đặc biệt, ví dụ \"gdm\" cho màn hình đăng nhập"
msgstr "Dùng chế độ đặc biệt, ví dụ gdm cho màn hình đăng nhập"
#: ../src/main.c:365
msgid "List possible modes"
@ -1865,7 +1862,7 @@ msgstr "Danh sách chế độ"
#: ../src/shell-app.c:622
#, c-format
msgid "Failed to launch '%s'"
msgstr "Lỗi chạy '%s'"
msgstr "Lỗi chạy %s"
#: ../src/shell-keyring-prompt.c:708
msgid "Passwords do not match."
@ -1879,6 +1876,17 @@ msgstr "Mật khẩu không thể không có"
msgid "Authentication dialog was dismissed by the user"
msgstr "Hộp thoại xác thực bị người dùng bỏ qua"
#~ msgid "%u Output"
#~ msgid_plural "%u Outputs"
#~ msgstr[0] "%u đầu ra"
#~ msgid "%u Input"
#~ msgid_plural "%u Inputs"
#~ msgstr[0] "%u đầu vào"
#~ msgid "System Sounds"
#~ msgstr "Âm thanh hệ thống"
#~ msgctxt "title"
#~ msgid "Sign In"
#~ msgstr "Đăng nhập"
@ -1910,7 +1918,7 @@ msgstr "Hộp thoại xác thực bị người dùng bỏ qua"
#~ msgstr "%l:%M %p"
#~ msgid "Failed to unmount '%s'"
#~ msgstr "Lỗi bỏ gắn kết '%s'"
#~ msgstr "Lỗi bỏ gắn kết %s"
#~ msgid "Retry"
#~ msgstr "Thử lại"
@ -1925,7 +1933,7 @@ msgstr "Hộp thoại xác thực bị người dùng bỏ qua"
#~ msgstr "Lỗi duyệt tập tin"
#~ msgid "The requested device cannot be browsed, error is '%s'"
#~ msgstr "Không thể duyệt thiết bị yêu cầu , lỗi là '%s'"
#~ msgstr "Không thể duyệt thiết bị yêu cầu , lỗi là %s"
#~ msgid "Wireless"
#~ msgstr "Mạng không dây"
@ -2070,155 +2078,3 @@ msgstr "Hộp thoại xác thực bị người dùng bỏ qua"
#~ msgid "Show password"
#~ msgstr "Hiện mật khẩu"
#~| msgid "If true, display seconds in time."
#~ msgid "If true, display onscreen keyboard."
#~ msgstr "Nếu đúng (true), hiện bàn phím màn hình."
#~| msgid "Screen Keyboard"
#~ msgid "Show the onscreen keyboard"
#~ msgstr "Hiện bàn phím màn hình"
#~ msgid "%s has finished starting"
#~ msgstr "%s đã hoàn tất khởi chạy"
#~ msgid "Uuids of extensions to disable"
#~ msgstr "UUID của phần mở rộng cần tắt"
#~ msgid "You're now connected to mobile broadband connection '%s'"
#~ msgstr "Đã nối mạng '%s' (băng thông rộng)"
#~ msgid "You're now connected to wireless network '%s'"
#~ msgstr "Đã nối mạng '%s' (không dây)"
#~ msgid "You're now connected to wired network '%s'"
#~ msgstr "Đã nối mạng '%s' (dây)"
#~ msgid "You're now connected to VPN network '%s'"
#~ msgstr "Đã nối mạng VPN '%s'"
#~ msgid "Localization Settings"
#~ msgstr "Thiết lập bản địa hoá"
#~ msgid "Less than a minute ago"
#~ msgstr "Chưa đến một phút"
#~ msgid "%d minute ago"
#~ msgid_plural "%d minutes ago"
#~ msgstr[0] "%d phút trước"
#~ msgid "%d hour ago"
#~ msgid_plural "%d hours ago"
#~ msgstr[0] "%d giờ trước"
#~ msgid "%d day ago"
#~ msgid_plural "%d days ago"
#~ msgstr[0] "%d ngày trước"
#~ msgid "%d week ago"
#~ msgid_plural "%d weeks ago"
#~ msgstr[0] "%d tuần trước"
#~ msgid "Shut Down"
#~ msgstr "Tắt máy"
#~ msgid "Click Shut Down to quit these applications and shut down the system."
#~ msgstr "Nhấn Tắt máy để thoát những ứng dụng này và tắt hệ thống."
#~ msgid "The system will shut down automatically in %d seconds."
#~ msgstr "Hệ thống sẽ tự động tắt sau %d giây."
#~ msgid "Shutting down the system."
#~ msgstr "Tắt hệ thống."
#~ msgid "Confirm"
#~ msgstr "Xác nhận"
#~ msgid "Clip the crosshairs at the center"
#~ msgstr "Cắt lưới chéo ở giữa"
#~ msgid "Color of the crosshairs"
#~ msgstr "Màu lưới chéo"
#~ msgid ""
#~ "Determines the length of the vertical and horizontal lines that make up "
#~ "the crosshairs."
#~ msgstr "Xác định độ dài và rộng của những dòng tạo nên lưới chéo."
#~ msgid ""
#~ "Determines the transparency of the crosshairs, from fully opaque to fully "
#~ "transparent."
#~ msgstr "Xác định độ trong suốt của lưới chéo, từ đặc đến trong suốt."
#~ msgid "Enable lens mode"
#~ msgstr "Bật chế độ gương"
#~ msgid "Show or hide crosshairs"
#~ msgstr "Hiện hoặc ẩn lưới chéo"
#~ msgid "Show or hide the magnifier"
#~ msgstr "Hiện hoặc ẩn kính lúp"
#~ msgid "Thickness of the crosshairs"
#~ msgstr "Độ dày lưới chéo"
#~ msgid ""
#~ "Width of the vertical and horizontal lines that make up the crosshairs."
#~ msgstr "Độ rộng của đường dọc/ngang hình thành dấu gạch chéo."
#~ msgid "PREFERENCES"
#~ msgstr "TUỲ THÍCH"
#~ msgid "Shut Down..."
#~ msgstr "Tắt máy..."
#~ msgid "Search your computer"
#~ msgstr "Tìm trong máy"
#~ msgid "Customize the panel clock"
#~ msgstr "Tuỳ biến đồng hồ"
#~ msgid "Clock Format"
#~ msgstr "Dạng đồng hồ"
#~| msgid "System Preferences..."
#~ msgid "Clock Preferences"
#~ msgstr "Thiết lập đồng hồ"
#~ msgid "Panel Display"
#~ msgstr "Khung hiển thị"
#~ msgid "Show seco_nds"
#~ msgstr "Hiện _giây"
#~ msgid "_12 hour format"
#~ msgstr "Dạng _12 giờ"
#~ msgid "_24 hour format"
#~ msgstr "Dạng _24 giờ"
#~| msgid "System Preferences..."
#~ msgid "Preferences"
#~ msgstr "Thiết lập"
#~ msgid ""
#~ "Can't add a new workspace because maximum workspaces limit has been "
#~ "reached."
#~ msgstr ""
#~ "Không thể thêm vùng làm việc mới vì đã đạt giới hạn số vùng làm việc tối "
#~ "đa."
#~ msgid "Can't remove the first workspace."
#~ msgstr "Không thể bỏ vùng làm việc đầu tiên."
#~ msgid "Drag here to add favorites"
#~ msgstr "Kéo vào đây để thêm vào danh mục ưa thích"
#~ msgid "Find..."
#~ msgstr "Tìm"
#~ msgid "Sidebar"
#~ msgstr "Thanh bên"
#~ msgid "Recent Documents"
#~ msgstr "Tài liệu gần đây"

File diff suppressed because it is too large Load Diff

View File

@ -9,15 +9,16 @@ msgstr ""
"Project-Id-Version: gnome-shell 3.3.90\n"
"Report-Msgid-Bugs-To: http://bugzilla.gnome.org/enter_bug.cgi?product=gnome-"
"shell&keywords=I18N+L10N&component=general\n"
"POT-Creation-Date: 2013-03-04 08:38+0000\n"
"PO-Revision-Date: 2013-03-06 19:06+0800\n"
"Last-Translator: Chao-Hsiung Liao <j_h_liau@yahoo.com.tw>\n"
"POT-Creation-Date: 2013-05-31 18:55+0000\n"
"PO-Revision-Date: 2013-06-04 21:50+0800\n"
"Last-Translator: Cheng-Chia Tseng <pswo10680@gmail.com>\n"
"Language-Team: Chinese (Hong Kong) <community@linuxhall.org>\n"
"Language: \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=1; plural=0;\n"
"X-Generator: Poedit 1.5.3\n"
"X-Generator: Poedit 1.5.4\n"
#: ../data/50-gnome-shell-screenshot.xml.in.h:1
msgid "Screenshots"
@ -313,44 +314,50 @@ msgstr "擴充功能"
msgid "Select an extension to configure using the combobox above."
msgstr "使用上面的組合方塊選擇要設定的擴充功能。"
#: ../js/gdm/loginDialog.js:405
#| msgid "Session..."
#: ../js/gdm/loginDialog.js:371
msgid "Session…"
msgstr "作業階段…"
#. translators: this message is shown below the user list on the
#. login screen. It can be activated to reveal an entry for
#. manually entering the username.
#: ../js/gdm/loginDialog.js:629
#: ../js/gdm/loginDialog.js:601
msgid "Not listed?"
msgstr "沒有列出來?"
#: ../js/gdm/loginDialog.js:783 ../js/ui/components/networkAgent.js:137
#: ../js/ui/components/polkitAgent.js:162 ../js/ui/endSessionDialog.js:375
#: ../js/gdm/loginDialog.js:776 ../js/ui/components/networkAgent.js:137
#: ../js/ui/components/polkitAgent.js:161 ../js/ui/endSessionDialog.js:376
#: ../js/ui/extensionDownloader.js:195 ../js/ui/shellMountOperation.js:399
#: ../js/ui/status/bluetooth.js:415 ../js/ui/unlockDialog.js:126
#: ../js/ui/userMenu.js:934
#: ../js/ui/status/bluetooth.js:415 ../js/ui/unlockDialog.js:96
#: ../js/ui/userMenu.js:938
msgid "Cancel"
msgstr "取消"
#: ../js/gdm/loginDialog.js:799
#: ../js/gdm/loginDialog.js:791
msgctxt "button"
msgid "Sign In"
msgstr "登入"
#: ../js/gdm/loginDialog.js:799
#: ../js/gdm/loginDialog.js:791
msgid "Next"
msgstr "下一個"
#. Translators: this message is shown below the username entry field
#. to clue the user in on how to login to the local network realm
#: ../js/gdm/loginDialog.js:888
#, c-format
msgid "(e.g., user or %s)"
msgstr "(例如: user 或 %s)"
#. TTLS and PEAP are actually much more complicated, but this complication
#. is not visible here since we only care about phase2 authentication
#. (and don't even care of which one)
#: ../js/gdm/loginDialog.js:904 ../js/ui/components/networkAgent.js:260
#: ../js/gdm/loginDialog.js:892 ../js/ui/components/networkAgent.js:260
#: ../js/ui/components/networkAgent.js:278
msgid "Username: "
msgstr "使用者名稱:"
#: ../js/gdm/loginDialog.js:1157
#: ../js/gdm/loginDialog.js:1158
msgid "Login Window"
msgstr "登入視窗"
@ -359,8 +366,8 @@ msgstr "登入視窗"
msgid "Power"
msgstr "電源"
#: ../js/gdm/powerMenu.js:93 ../js/ui/userMenu.js:695 ../js/ui/userMenu.js:699
#: ../js/ui/userMenu.js:815
#: ../js/gdm/powerMenu.js:93 ../js/ui/userMenu.js:696 ../js/ui/userMenu.js:700
#: ../js/ui/userMenu.js:816
msgid "Suspend"
msgstr "暫停"
@ -368,58 +375,53 @@ msgstr "暫停"
msgid "Restart"
msgstr "重新啟動"
#: ../js/gdm/powerMenu.js:103 ../js/ui/userMenu.js:697
#: ../js/ui/userMenu.js:699 ../js/ui/userMenu.js:814 ../js/ui/userMenu.js:938
#: ../js/gdm/powerMenu.js:103 ../js/ui/userMenu.js:698
#: ../js/ui/userMenu.js:700 ../js/ui/userMenu.js:815 ../js/ui/userMenu.js:942
msgid "Power Off"
msgstr "關閉電源"
#: ../js/gdm/util.js:182
#: ../js/gdm/util.js:247
msgid "Authentication error"
msgstr "驗證錯誤"
#. Translators: this message is shown below the password entry field
#. to indicate the user can swipe their finger instead
#: ../js/gdm/util.js:299
#: ../js/gdm/util.js:364
msgid "(or swipe finger)"
msgstr "(或是滑過手指)"
#: ../js/gdm/util.js:324
#, c-format
msgid "(e.g., user or %s)"
msgstr "(例如: user 或 %s)"
#: ../js/misc/util.js:94
#: ../js/misc/util.js:97
msgid "Command not found"
msgstr "找不到指令"
#. Replace "Error invoking GLib.shell_parse_argv: " with
#. something nicer
#: ../js/misc/util.js:127
#: ../js/misc/util.js:130
msgid "Could not parse command:"
msgstr "無法分析指令:"
#: ../js/misc/util.js:135
#: ../js/misc/util.js:138
#, c-format
msgid "Execution of '%s' failed:"
msgstr "執行「%s」失敗"
#: ../js/ui/appDisplay.js:348
#: ../js/ui/appDisplay.js:356
msgid "Frequent"
msgstr "頻率"
msgstr "常用"
#: ../js/ui/appDisplay.js:355
#: ../js/ui/appDisplay.js:363
msgid "All"
msgstr "全部"
#: ../js/ui/appDisplay.js:913
#: ../js/ui/appDisplay.js:941
msgid "New Window"
msgstr "新視窗"
#: ../js/ui/appDisplay.js:916 ../js/ui/dash.js:284
#: ../js/ui/appDisplay.js:944 ../js/ui/dash.js:284
msgid "Remove from Favorites"
msgstr "自喜好中移除"
#: ../js/ui/appDisplay.js:917
#: ../js/ui/appDisplay.js:945
msgid "Add to Favorites"
msgstr "加入喜好"
@ -433,7 +435,7 @@ msgstr "%s 已加入你的喜好中。"
msgid "%s has been removed from your favorites."
msgstr "%s 已經從你的喜好中移除。"
#: ../js/ui/backgroundMenu.js:19 ../js/ui/userMenu.js:788
#: ../js/ui/backgroundMenu.js:19 ../js/ui/userMenu.js:789
msgid "Settings"
msgstr "設定值"
@ -456,7 +458,7 @@ msgctxt "event list time"
msgid "%H\\u2236%M"
msgstr "%H\\u2236%M"
#. Transators: Shown in calendar event list, if 12h format,
#. Translators: Shown in calendar event list, if 12h format,
#. \u2236 is a ratio character, similar to : and \u2009 is
#. a thin space
#: ../js/ui/calendar.js:77
@ -558,35 +560,35 @@ msgid "S"
msgstr "六"
#. Translators: Text to show if there are no events
#: ../js/ui/calendar.js:692
#: ../js/ui/calendar.js:720
msgid "Nothing Scheduled"
msgstr "沒有預訂行程"
#. Translators: Shown on calendar heading when selected day occurs on current year
#: ../js/ui/calendar.js:708
#: ../js/ui/calendar.js:736
msgctxt "calendar heading"
msgid "%A, %B %d"
msgstr "%m月%d日%A"
#. Translators: Shown on calendar heading when selected day occurs on different year
#: ../js/ui/calendar.js:711
#: ../js/ui/calendar.js:739
msgctxt "calendar heading"
msgid "%A, %B %d, %Y"
msgstr "%Y年%m月%d日%A"
#: ../js/ui/calendar.js:721
#: ../js/ui/calendar.js:749
msgid "Today"
msgstr "今天"
#: ../js/ui/calendar.js:725
#: ../js/ui/calendar.js:753
msgid "Tomorrow"
msgstr "明天"
#: ../js/ui/calendar.js:736
#: ../js/ui/calendar.js:764
msgid "This week"
msgstr "本週"
#: ../js/ui/calendar.js:744
#: ../js/ui/calendar.js:772
msgid "Next week"
msgstr "下週"
@ -602,20 +604,20 @@ msgstr "外部裝置已拔除"
msgid "Removable Devices"
msgstr "可移除式裝置"
#: ../js/ui/components/autorunManager.js:593
#: ../js/ui/components/autorunManager.js:594
#, c-format
msgid "Open with %s"
msgstr "用 %s 開啟"
#: ../js/ui/components/autorunManager.js:619
#: ../js/ui/components/autorunManager.js:620
msgid "Eject"
msgstr "退出"
#: ../js/ui/components/keyring.js:82 ../js/ui/components/polkitAgent.js:268
#: ../js/ui/components/keyring.js:88 ../js/ui/components/polkitAgent.js:280
msgid "Password:"
msgstr "密碼: "
#: ../js/ui/components/keyring.js:101
#: ../js/ui/components/keyring.js:107
msgid "Type again:"
msgstr "再輸入一次:"
@ -693,15 +695,15 @@ msgstr "流動寬頻網絡密碼"
msgid "A password is required to connect to '%s'."
msgstr "連線至「%s」需要密碼。"
#: ../js/ui/components/polkitAgent.js:55
#: ../js/ui/components/polkitAgent.js:54
msgid "Authentication Required"
msgstr "要求驗證"
#: ../js/ui/components/polkitAgent.js:93
#: ../js/ui/components/polkitAgent.js:92
msgid "Administrator"
msgstr "系統管理員"
#: ../js/ui/components/polkitAgent.js:165
#: ../js/ui/components/polkitAgent.js:170
msgid "Authenticate"
msgstr "驗證"
@ -709,12 +711,12 @@ msgstr "驗證"
#. * requested authentication was not gained; this can happen
#. * because of an authentication error (like invalid password),
#. * for instance.
#: ../js/ui/components/polkitAgent.js:256 ../js/ui/shellMountOperation.js:383
#: ../js/ui/components/polkitAgent.js:266 ../js/ui/shellMountOperation.js:383
msgid "Sorry, that didn't work. Please try again."
msgstr "抱歉,那樣無法運作。請再試一次。"
#. Translators: this is a filename used for screencast recording
#: ../js/ui/components/recorder.js:48
#: ../js/ui/components/recorder.js:47
#, no-c-format
msgid "Screencast from %d %t"
msgstr "Screencast from %d %t"
@ -976,14 +978,14 @@ msgstr "開啟行事曆"
msgid "Open Clocks"
msgstr "開啟時鐘"
#: ../js/ui/dateMenu.js:105
#: ../js/ui/dateMenu.js:104
msgid "Date & Time Settings"
msgstr "日期與時刻設定值"
#. 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:205
#: ../js/ui/dateMenu.js:216
msgid "%A %B %e, %Y"
msgstr "%Y年%m月%e日%A"
@ -1080,7 +1082,7 @@ msgstr "安裝"
msgid "Download and install '%s' from extensions.gnome.org?"
msgstr "是否從 extensions.gnome.org 下載並安裝「%s」"
#: ../js/ui/keyboard.js:619 ../js/ui/status/keyboard.js:314
#: ../js/ui/keyboard.js:619 ../js/ui/status/keyboard.js:333
#: ../js/ui/status/power.js:211
msgid "Keyboard"
msgstr "鍵盤"
@ -1142,7 +1144,6 @@ msgid "Remove"
msgstr "移除"
#: ../js/ui/messageTray.js:1501
#| msgid "No Messages"
msgid "Clear Messages"
msgstr "清除訊息"
@ -1150,15 +1151,15 @@ msgstr "清除訊息"
msgid "Notification Settings"
msgstr "通知設定值"
#: ../js/ui/messageTray.js:1707
#: ../js/ui/messageTray.js:1709
msgid "No Messages"
msgstr "沒有訊息"
#: ../js/ui/messageTray.js:1787
#: ../js/ui/messageTray.js:1785
msgid "Message Tray"
msgstr "訊息匣"
#: ../js/ui/messageTray.js:2864
#: ../js/ui/messageTray.js:2818
msgid "System Information"
msgstr "系統資訊"
@ -1167,13 +1168,13 @@ msgctxt "program"
msgid "Unknown"
msgstr "不明"
#: ../js/ui/overviewControls.js:460 ../js/ui/screenShield.js:153
#: ../js/ui/overviewControls.js:463 ../js/ui/screenShield.js:149
#, c-format
msgid "%d new message"
msgid_plural "%d new messages"
msgstr[0] "%d 個新訊息"
#: ../js/ui/overview.js:82
#: ../js/ui/overview.js:84
msgid "Undo"
msgstr "復原"
@ -1185,22 +1186,21 @@ msgstr "概覽"
#. in the search entry when no search is
#. active; it should not exceed ~30
#. characters.
#: ../js/ui/overview.js:284
#| msgid "Type to search..."
#: ../js/ui/overview.js:271
msgid "Type to search…"
msgstr "輸入以搜尋…"
#: ../js/ui/panel.js:613
#: ../js/ui/panel.js:635
msgid "Quit"
msgstr "結束"
#. Translators: If there is no suitable word for "Activities"
#. in your language, you can use the word for "Overview".
#: ../js/ui/panel.js:642
#: ../js/ui/panel.js:686
msgid "Activities"
msgstr "概覽 "
#: ../js/ui/panel.js:983
#: ../js/ui/panel.js:982
msgid "Top Bar"
msgstr "頂端列"
@ -1209,35 +1209,35 @@ msgstr "頂端列"
#. "ON" and "OFF") or "toggle-switch-intl" (for toggle
#. switches containing "◯" and "|"). Other values will
#. simply result in invisible toggle switches.
#: ../js/ui/popupMenu.js:727
#: ../js/ui/popupMenu.js:740
msgid "toggle-switch-us"
msgstr "toggle-switch-us"
#: ../js/ui/runDialog.js:205
#: ../js/ui/runDialog.js:74
msgid "Enter a Command"
msgstr "請輸入指令"
#: ../js/ui/runDialog.js:241
#: ../js/ui/runDialog.js:110
msgid "Close"
msgstr "關閉"
#. Translators: This is a time format for a date in
#. long format
#: ../js/ui/screenShield.js:90
#: ../js/ui/screenShield.js:86
msgid "%A, %B %d"
msgstr "%m月%d日%A"
#: ../js/ui/screenShield.js:155
#: ../js/ui/screenShield.js:151
#, c-format
msgid "%d new notification"
msgid_plural "%d new notifications"
msgstr[0] "%d 個新通知"
#: ../js/ui/screenShield.js:442 ../js/ui/userMenu.js:806
#: ../js/ui/screenShield.js:438 ../js/ui/userMenu.js:807
msgid "Lock"
msgstr "鎖定"
#: ../js/ui/screenShield.js:639
#: ../js/ui/screenShield.js:641
msgid "GNOME needs to lock the screen"
msgstr "GNOME 需要鎖定螢幕"
@ -1248,37 +1248,35 @@ msgstr "GNOME 需要鎖定螢幕"
#.
#. XXX: another option is to kick the user into the gdm login
#. screen, where we're not affected by grabs
#: ../js/ui/screenShield.js:758 ../js/ui/screenShield.js:1169
#| msgid "Unable to connect to %s"
#: ../js/ui/screenShield.js:762 ../js/ui/screenShield.js:1198
msgid "Unable to lock"
msgstr "無法鎖定"
#: ../js/ui/screenShield.js:759 ../js/ui/screenShield.js:1170
#: ../js/ui/screenShield.js:763 ../js/ui/screenShield.js:1199
msgid "Lock was blocked by an application"
msgstr "鎖定被應用程式阻擋"
#: ../js/ui/searchDisplay.js:431
#| msgid "Searching..."
#: ../js/ui/searchDisplay.js:453
msgid "Searching…"
msgstr "搜尋…"
#: ../js/ui/searchDisplay.js:475
#: ../js/ui/searchDisplay.js:497
msgid "No results."
msgstr "沒有結果。"
#: ../js/ui/shellEntry.js:29
#: ../js/ui/shellEntry.js:27
msgid "Copy"
msgstr "複製"
#: ../js/ui/shellEntry.js:34
#: ../js/ui/shellEntry.js:32
msgid "Paste"
msgstr "貼上"
#: ../js/ui/shellEntry.js:105
#: ../js/ui/shellEntry.js:99
msgid "Show Text"
msgstr "顯示文字"
#: ../js/ui/shellEntry.js:107
#: ../js/ui/shellEntry.js:101
msgid "Hide Text"
msgstr "隱藏文字"
@ -1290,7 +1288,7 @@ msgstr "密碼"
msgid "Remember Password"
msgstr "記住密碼"
#: ../js/ui/shellMountOperation.js:403 ../js/ui/unlockDialog.js:140
#: ../js/ui/shellMountOperation.js:403 ../js/ui/unlockDialog.js:109
msgid "Unlock"
msgstr "解鎖"
@ -1354,12 +1352,10 @@ msgid "Visibility"
msgstr "顯示狀態"
#: ../js/ui/status/bluetooth.js:59
#| msgid "Send Files to Device..."
msgid "Send Files to Device…"
msgstr "傳送檔案到裝置…"
#: ../js/ui/status/bluetooth.js:60
#| msgid "Set Up a New Device..."
msgid "Set Up a New Device…"
msgstr "設定新的裝置…"
@ -1386,7 +1382,6 @@ msgid "connecting..."
msgstr "連線中…"
#: ../js/ui/status/bluetooth.js:239
#| msgid "Send Files..."
msgid "Send Files…"
msgstr "傳送檔案…"
@ -1462,11 +1457,11 @@ msgstr "請輸入裝置所提及的 PIN。"
msgid "OK"
msgstr "確定"
#: ../js/ui/status/keyboard.js:368
#: ../js/ui/status/keyboard.js:396
msgid "Show Keyboard Layout"
msgstr "顯示鍵盤配置"
#: ../js/ui/status/keyboard.js:373
#: ../js/ui/status/keyboard.js:401
msgid "Region & Language Settings"
msgstr "地區和語言設定值"
@ -1584,7 +1579,7 @@ msgstr "連線失敗"
msgid "Activation of network connection failed"
msgstr "啟動網絡連線失敗"
#: ../js/ui/status/network.js:2276
#: ../js/ui/status/network.js:2282
msgid "Networking is disabled"
msgstr "網絡已停用"
@ -1599,7 +1594,6 @@ msgstr "電源設定值"
#. 0 is reported when UPower does not have enough data
#. to estimate battery life
#: ../js/ui/status/power.js:99
#| msgid "Estimating..."
msgid "Estimating…"
msgstr "評估中…"
@ -1695,11 +1689,11 @@ msgstr "音量"
msgid "Microphone"
msgstr "麥克風"
#: ../js/ui/unlockDialog.js:151
#: ../js/ui/unlockDialog.js:120
msgid "Log in as another user"
msgstr "以另一個使用者身分登入"
#: ../js/ui/unlockDialog.js:177
#: ../js/ui/unlockDialog.js:141
msgid "Unlock Window"
msgstr "解鎖視窗"
@ -1727,46 +1721,48 @@ msgstr "閒置"
msgid "Offline"
msgstr "離線"
#: ../js/ui/userMenu.js:780
#: ../js/ui/userMenu.js:781
msgid "Notifications"
msgstr "通知"
#: ../js/ui/userMenu.js:796
#: ../js/ui/userMenu.js:797
msgid "Switch User"
msgstr "切換使用者"
#: ../js/ui/userMenu.js:801
#: ../js/ui/userMenu.js:802
msgid "Log Out"
msgstr "登出"
#: ../js/ui/userMenu.js:821
#: ../js/ui/userMenu.js:822
msgid "Install Updates & Restart"
msgstr "安裝更新 & 重新啟動"
#: ../js/ui/userMenu.js:839
#: ../js/ui/userMenu.js:840
msgid "Your chat status will be set to busy"
msgstr "你的聊天狀態會設為忙碌"
#: ../js/ui/userMenu.js:840
#: ../js/ui/userMenu.js:841
msgid ""
"Notifications are now disabled, including chat messages. Your online status "
"has been adjusted to let others know that you might not see their messages."
msgstr "通知現在已被停用,包含聊天訊息。你的上線狀態也調整為讓其他人知道你沒時間看他們的訊息。"
#: ../js/ui/userMenu.js:886
#: ../js/ui/userMenu.js:888
msgid "Other users are logged in."
msgstr "其他使用者已登入。"
#: ../js/ui/userMenu.js:891
#: ../js/ui/userMenu.js:893
msgid "Shutting down might cause them to lose unsaved work."
msgstr "關機可能使它們失去未儲存的工作。"
#: ../js/ui/userMenu.js:918
#. Translators: Remote here refers to a remote session, like a ssh login
#: ../js/ui/userMenu.js:921
#, c-format
msgid "%s (remote)"
msgstr "%s (遠端)"
#: ../js/ui/userMenu.js:920
#. Translators: Console here refers to a tty like a VT console
#: ../js/ui/userMenu.js:924
#, c-format
msgid "%s (console)"
msgstr "%s (主控臺)"
@ -1779,7 +1775,7 @@ msgstr "應用程式"
msgid "Search"
msgstr "搜尋"
#: ../js/ui/wanda.js:92
#: ../js/ui/wanda.js:77
#, c-format
msgid ""
"Sorry, no wisdom for you today:\n"
@ -1788,7 +1784,7 @@ msgstr ""
"抱歉,今天可能有些問題:\n"
"%s"
#: ../js/ui/wanda.js:96
#: ../js/ui/wanda.js:81
#, c-format
msgid "%s the Oracle says"
msgstr "%s Oracle 說:"
@ -1818,7 +1814,7 @@ msgid "%u Input"
msgid_plural "%u Inputs"
msgstr[0] "%u 輸入"
#: ../src/gvc/gvc-mixer-control.c:2371
#: ../src/gvc/gvc-mixer-control.c:2373
msgid "System Sounds"
msgstr "系統音效"
@ -1843,11 +1839,11 @@ msgstr "列出可能的模式"
msgid "Failed to launch '%s'"
msgstr "無法啟動「%s」"
#: ../src/shell-keyring-prompt.c:708
#: ../src/shell-keyring-prompt.c:714
msgid "Passwords do not match."
msgstr "密碼不相符。"
#: ../src/shell-keyring-prompt.c:716
#: ../src/shell-keyring-prompt.c:722
msgid "Password cannot be blank"
msgstr "密碼不能為空白"

View File

@ -9,15 +9,16 @@ msgstr ""
"Project-Id-Version: gnome-shell 3.3.90\n"
"Report-Msgid-Bugs-To: http://bugzilla.gnome.org/enter_bug.cgi?product=gnome-"
"shell&keywords=I18N+L10N&component=general\n"
"POT-Creation-Date: 2013-03-04 08:38+0000\n"
"PO-Revision-Date: 2013-03-05 19:49+0800\n"
"Last-Translator: Chao-Hsiung Liao <j_h_liau@yahoo.com.tw>\n"
"POT-Creation-Date: 2013-05-31 18:55+0000\n"
"PO-Revision-Date: 2013-04-27 00:04+0800\n"
"Last-Translator: Cheng-Chia Tseng <pswo10680@gmail.com>\n"
"Language-Team: Chinese (Taiwan) <zh-l10n@lists.linux.org.tw>\n"
"Language: \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=1; plural=0;\n"
"X-Generator: Poedit 1.5.3\n"
"X-Generator: Poedit 1.5.4\n"
#: ../data/50-gnome-shell-screenshot.xml.in.h:1
msgid "Screenshots"
@ -343,44 +344,50 @@ msgstr "擴充功能"
msgid "Select an extension to configure using the combobox above."
msgstr "使用上面的組合方塊選擇要設定的擴充功能。"
#: ../js/gdm/loginDialog.js:405
#| msgid "Session..."
#: ../js/gdm/loginDialog.js:371
msgid "Session…"
msgstr "作業階段…"
#. translators: this message is shown below the user list on the
#. login screen. It can be activated to reveal an entry for
#. manually entering the username.
#: ../js/gdm/loginDialog.js:629
#: ../js/gdm/loginDialog.js:601
msgid "Not listed?"
msgstr "沒有列出來?"
#: ../js/gdm/loginDialog.js:783 ../js/ui/components/networkAgent.js:137
#: ../js/ui/components/polkitAgent.js:162 ../js/ui/endSessionDialog.js:375
#: ../js/gdm/loginDialog.js:776 ../js/ui/components/networkAgent.js:137
#: ../js/ui/components/polkitAgent.js:161 ../js/ui/endSessionDialog.js:376
#: ../js/ui/extensionDownloader.js:195 ../js/ui/shellMountOperation.js:399
#: ../js/ui/status/bluetooth.js:415 ../js/ui/unlockDialog.js:126
#: ../js/ui/userMenu.js:934
#: ../js/ui/status/bluetooth.js:415 ../js/ui/unlockDialog.js:96
#: ../js/ui/userMenu.js:938
msgid "Cancel"
msgstr "取消"
#: ../js/gdm/loginDialog.js:799
#: ../js/gdm/loginDialog.js:791
msgctxt "button"
msgid "Sign In"
msgstr "登入"
#: ../js/gdm/loginDialog.js:799
#: ../js/gdm/loginDialog.js:791
msgid "Next"
msgstr "下一個"
#. Translators: this message is shown below the username entry field
#. to clue the user in on how to login to the local network realm
#: ../js/gdm/loginDialog.js:888
#, c-format
msgid "(e.g., user or %s)"
msgstr "(例如: user 或 %s)"
#. TTLS and PEAP are actually much more complicated, but this complication
#. is not visible here since we only care about phase2 authentication
#. (and don't even care of which one)
#: ../js/gdm/loginDialog.js:904 ../js/ui/components/networkAgent.js:260
#: ../js/gdm/loginDialog.js:892 ../js/ui/components/networkAgent.js:260
#: ../js/ui/components/networkAgent.js:278
msgid "Username: "
msgstr "使用者名稱:"
#: ../js/gdm/loginDialog.js:1157
#: ../js/gdm/loginDialog.js:1158
msgid "Login Window"
msgstr "登入視窗"
@ -389,8 +396,8 @@ msgstr "登入視窗"
msgid "Power"
msgstr "電源"
#: ../js/gdm/powerMenu.js:93 ../js/ui/userMenu.js:695 ../js/ui/userMenu.js:699
#: ../js/ui/userMenu.js:815
#: ../js/gdm/powerMenu.js:93 ../js/ui/userMenu.js:696 ../js/ui/userMenu.js:700
#: ../js/ui/userMenu.js:816
msgid "Suspend"
msgstr "暫停"
@ -398,58 +405,53 @@ msgstr "暫停"
msgid "Restart"
msgstr "重新啟動"
#: ../js/gdm/powerMenu.js:103 ../js/ui/userMenu.js:697
#: ../js/ui/userMenu.js:699 ../js/ui/userMenu.js:814 ../js/ui/userMenu.js:938
#: ../js/gdm/powerMenu.js:103 ../js/ui/userMenu.js:698
#: ../js/ui/userMenu.js:700 ../js/ui/userMenu.js:815 ../js/ui/userMenu.js:942
msgid "Power Off"
msgstr "關閉電源"
#: ../js/gdm/util.js:182
#: ../js/gdm/util.js:247
msgid "Authentication error"
msgstr "驗證錯誤"
#. Translators: this message is shown below the password entry field
#. to indicate the user can swipe their finger instead
#: ../js/gdm/util.js:299
#: ../js/gdm/util.js:364
msgid "(or swipe finger)"
msgstr "(或是滑過手指)"
#: ../js/gdm/util.js:324
#, c-format
msgid "(e.g., user or %s)"
msgstr "(例如: user 或 %s)"
#: ../js/misc/util.js:94
#: ../js/misc/util.js:97
msgid "Command not found"
msgstr "找不到指令"
#. Replace "Error invoking GLib.shell_parse_argv: " with
#. something nicer
#: ../js/misc/util.js:127
#: ../js/misc/util.js:130
msgid "Could not parse command:"
msgstr "無法分析指令:"
#: ../js/misc/util.js:135
#: ../js/misc/util.js:138
#, c-format
msgid "Execution of '%s' failed:"
msgstr "執行「%s」失敗"
#: ../js/ui/appDisplay.js:348
#: ../js/ui/appDisplay.js:356
msgid "Frequent"
msgstr "頻率"
msgstr "常用"
#: ../js/ui/appDisplay.js:355
#: ../js/ui/appDisplay.js:363
msgid "All"
msgstr "全部"
#: ../js/ui/appDisplay.js:913
#: ../js/ui/appDisplay.js:941
msgid "New Window"
msgstr "新視窗"
#: ../js/ui/appDisplay.js:916 ../js/ui/dash.js:284
#: ../js/ui/appDisplay.js:944 ../js/ui/dash.js:284
msgid "Remove from Favorites"
msgstr "自喜好中移除"
#: ../js/ui/appDisplay.js:917
#: ../js/ui/appDisplay.js:945
msgid "Add to Favorites"
msgstr "加入喜好"
@ -463,7 +465,7 @@ msgstr "%s 已加入您的喜好中。"
msgid "%s has been removed from your favorites."
msgstr "%s 已經從您的喜好中移除。"
#: ../js/ui/backgroundMenu.js:19 ../js/ui/userMenu.js:788
#: ../js/ui/backgroundMenu.js:19 ../js/ui/userMenu.js:789
msgid "Settings"
msgstr "設定值"
@ -486,7 +488,7 @@ msgctxt "event list time"
msgid "%H\\u2236%M"
msgstr "%H\\u2236%M"
#. Transators: Shown in calendar event list, if 12h format,
#. Translators: Shown in calendar event list, if 12h format,
#. \u2236 is a ratio character, similar to : and \u2009 is
#. a thin space
#: ../js/ui/calendar.js:77
@ -588,35 +590,35 @@ msgid "S"
msgstr "六"
#. Translators: Text to show if there are no events
#: ../js/ui/calendar.js:692
#: ../js/ui/calendar.js:720
msgid "Nothing Scheduled"
msgstr "沒有預訂行程"
#. Translators: Shown on calendar heading when selected day occurs on current year
#: ../js/ui/calendar.js:708
#: ../js/ui/calendar.js:736
msgctxt "calendar heading"
msgid "%A, %B %d"
msgstr "%m月%d日%A"
#. Translators: Shown on calendar heading when selected day occurs on different year
#: ../js/ui/calendar.js:711
#: ../js/ui/calendar.js:739
msgctxt "calendar heading"
msgid "%A, %B %d, %Y"
msgstr "%Y年%m月%d日%A"
#: ../js/ui/calendar.js:721
#: ../js/ui/calendar.js:749
msgid "Today"
msgstr "今天"
#: ../js/ui/calendar.js:725
#: ../js/ui/calendar.js:753
msgid "Tomorrow"
msgstr "明天"
#: ../js/ui/calendar.js:736
#: ../js/ui/calendar.js:764
msgid "This week"
msgstr "本週"
#: ../js/ui/calendar.js:744
#: ../js/ui/calendar.js:772
msgid "Next week"
msgstr "下週"
@ -632,20 +634,20 @@ msgstr "外部裝置已拔除"
msgid "Removable Devices"
msgstr "可移除式裝置"
#: ../js/ui/components/autorunManager.js:593
#: ../js/ui/components/autorunManager.js:594
#, c-format
msgid "Open with %s"
msgstr "用 %s 開啟"
#: ../js/ui/components/autorunManager.js:619
#: ../js/ui/components/autorunManager.js:620
msgid "Eject"
msgstr "退出"
#: ../js/ui/components/keyring.js:82 ../js/ui/components/polkitAgent.js:268
#: ../js/ui/components/keyring.js:88 ../js/ui/components/polkitAgent.js:280
msgid "Password:"
msgstr "密碼: "
#: ../js/ui/components/keyring.js:101
#: ../js/ui/components/keyring.js:107
msgid "Type again:"
msgstr "再輸入一次:"
@ -723,15 +725,15 @@ msgstr "行動寬頻網路密碼"
msgid "A password is required to connect to '%s'."
msgstr "連線至「%s」需要密碼。"
#: ../js/ui/components/polkitAgent.js:55
#: ../js/ui/components/polkitAgent.js:54
msgid "Authentication Required"
msgstr "要求驗證"
#: ../js/ui/components/polkitAgent.js:93
#: ../js/ui/components/polkitAgent.js:92
msgid "Administrator"
msgstr "系統管理員"
#: ../js/ui/components/polkitAgent.js:165
#: ../js/ui/components/polkitAgent.js:170
msgid "Authenticate"
msgstr "驗證"
@ -739,12 +741,12 @@ msgstr "驗證"
#. * requested authentication was not gained; this can happen
#. * because of an authentication error (like invalid password),
#. * for instance.
#: ../js/ui/components/polkitAgent.js:256 ../js/ui/shellMountOperation.js:383
#: ../js/ui/components/polkitAgent.js:266 ../js/ui/shellMountOperation.js:383
msgid "Sorry, that didn't work. Please try again."
msgstr "抱歉,那樣無法運作。請再試一次。"
#. Translators: this is a filename used for screencast recording
#: ../js/ui/components/recorder.js:48
#: ../js/ui/components/recorder.js:47
#, no-c-format
msgid "Screencast from %d %t"
msgstr "Screencast from %d %t"
@ -1006,14 +1008,14 @@ msgstr "開啟行事曆"
msgid "Open Clocks"
msgstr "開啟時鐘"
#: ../js/ui/dateMenu.js:105
#: ../js/ui/dateMenu.js:104
msgid "Date & Time Settings"
msgstr "日期與時刻設定值"
#. 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:205
#: ../js/ui/dateMenu.js:216
msgid "%A %B %e, %Y"
msgstr "%Y年%m月%e日%A"
@ -1110,7 +1112,7 @@ msgstr "安裝"
msgid "Download and install '%s' from extensions.gnome.org?"
msgstr "是否從 extensions.gnome.org 下載並安裝「%s」"
#: ../js/ui/keyboard.js:619 ../js/ui/status/keyboard.js:314
#: ../js/ui/keyboard.js:619 ../js/ui/status/keyboard.js:333
#: ../js/ui/status/power.js:211
msgid "Keyboard"
msgstr "鍵盤"
@ -1172,7 +1174,6 @@ msgid "Remove"
msgstr "移除"
#: ../js/ui/messageTray.js:1501
#| msgid "No Messages"
msgid "Clear Messages"
msgstr "清除訊息"
@ -1180,15 +1181,15 @@ msgstr "清除訊息"
msgid "Notification Settings"
msgstr "通知設定值"
#: ../js/ui/messageTray.js:1707
#: ../js/ui/messageTray.js:1709
msgid "No Messages"
msgstr "沒有訊息"
#: ../js/ui/messageTray.js:1787
#: ../js/ui/messageTray.js:1785
msgid "Message Tray"
msgstr "訊息匣"
#: ../js/ui/messageTray.js:2864
#: ../js/ui/messageTray.js:2818
msgid "System Information"
msgstr "系統資訊"
@ -1197,13 +1198,13 @@ msgctxt "program"
msgid "Unknown"
msgstr "不明"
#: ../js/ui/overviewControls.js:460 ../js/ui/screenShield.js:153
#: ../js/ui/overviewControls.js:463 ../js/ui/screenShield.js:149
#, c-format
msgid "%d new message"
msgid_plural "%d new messages"
msgstr[0] "%d 個新訊息"
#: ../js/ui/overview.js:82
#: ../js/ui/overview.js:84
msgid "Undo"
msgstr "復原"
@ -1215,22 +1216,21 @@ msgstr "概覽"
#. in the search entry when no search is
#. active; it should not exceed ~30
#. characters.
#: ../js/ui/overview.js:284
#| msgid "Type to search..."
#: ../js/ui/overview.js:271
msgid "Type to search…"
msgstr "輸入以搜尋…"
#: ../js/ui/panel.js:613
#: ../js/ui/panel.js:635
msgid "Quit"
msgstr "結束"
#. Translators: If there is no suitable word for "Activities"
#. in your language, you can use the word for "Overview".
#: ../js/ui/panel.js:642
#: ../js/ui/panel.js:686
msgid "Activities"
msgstr "概覽 "
#: ../js/ui/panel.js:983
#: ../js/ui/panel.js:982
msgid "Top Bar"
msgstr "頂端列"
@ -1239,35 +1239,35 @@ msgstr "頂端列"
#. "ON" and "OFF") or "toggle-switch-intl" (for toggle
#. switches containing "◯" and "|"). Other values will
#. simply result in invisible toggle switches.
#: ../js/ui/popupMenu.js:727
#: ../js/ui/popupMenu.js:740
msgid "toggle-switch-us"
msgstr "toggle-switch-us"
#: ../js/ui/runDialog.js:205
#: ../js/ui/runDialog.js:74
msgid "Enter a Command"
msgstr "請輸入指令"
#: ../js/ui/runDialog.js:241
#: ../js/ui/runDialog.js:110
msgid "Close"
msgstr "關閉"
#. Translators: This is a time format for a date in
#. long format
#: ../js/ui/screenShield.js:90
#: ../js/ui/screenShield.js:86
msgid "%A, %B %d"
msgstr "%m月%d日%A"
#: ../js/ui/screenShield.js:155
#: ../js/ui/screenShield.js:151
#, c-format
msgid "%d new notification"
msgid_plural "%d new notifications"
msgstr[0] "%d 個新通知"
#: ../js/ui/screenShield.js:442 ../js/ui/userMenu.js:806
#: ../js/ui/screenShield.js:438 ../js/ui/userMenu.js:807
msgid "Lock"
msgstr "鎖定"
#: ../js/ui/screenShield.js:639
#: ../js/ui/screenShield.js:641
msgid "GNOME needs to lock the screen"
msgstr "GNOME 需要鎖定螢幕"
@ -1278,37 +1278,35 @@ msgstr "GNOME 需要鎖定螢幕"
#.
#. XXX: another option is to kick the user into the gdm login
#. screen, where we're not affected by grabs
#: ../js/ui/screenShield.js:758 ../js/ui/screenShield.js:1169
#| msgid "Unable to connect to %s"
#: ../js/ui/screenShield.js:762 ../js/ui/screenShield.js:1198
msgid "Unable to lock"
msgstr "無法鎖定"
#: ../js/ui/screenShield.js:759 ../js/ui/screenShield.js:1170
#: ../js/ui/screenShield.js:763 ../js/ui/screenShield.js:1199
msgid "Lock was blocked by an application"
msgstr "鎖定被應用程式阻擋"
#: ../js/ui/searchDisplay.js:431
#| msgid "Searching..."
#: ../js/ui/searchDisplay.js:453
msgid "Searching…"
msgstr "搜尋…"
#: ../js/ui/searchDisplay.js:475
#: ../js/ui/searchDisplay.js:497
msgid "No results."
msgstr "沒有結果。"
#: ../js/ui/shellEntry.js:29
#: ../js/ui/shellEntry.js:27
msgid "Copy"
msgstr "複製"
#: ../js/ui/shellEntry.js:34
#: ../js/ui/shellEntry.js:32
msgid "Paste"
msgstr "貼上"
#: ../js/ui/shellEntry.js:105
#: ../js/ui/shellEntry.js:99
msgid "Show Text"
msgstr "顯示文字"
#: ../js/ui/shellEntry.js:107
#: ../js/ui/shellEntry.js:101
msgid "Hide Text"
msgstr "隱藏文字"
@ -1320,7 +1318,7 @@ msgstr "密碼"
msgid "Remember Password"
msgstr "記住密碼"
#: ../js/ui/shellMountOperation.js:403 ../js/ui/unlockDialog.js:140
#: ../js/ui/shellMountOperation.js:403 ../js/ui/unlockDialog.js:109
msgid "Unlock"
msgstr "解鎖"
@ -1384,12 +1382,10 @@ msgid "Visibility"
msgstr "顯示狀態"
#: ../js/ui/status/bluetooth.js:59
#| msgid "Send Files to Device..."
msgid "Send Files to Device…"
msgstr "傳送檔案到裝置…"
#: ../js/ui/status/bluetooth.js:60
#| msgid "Set Up a New Device..."
msgid "Set Up a New Device…"
msgstr "設定新的裝置…"
@ -1416,7 +1412,6 @@ msgid "connecting..."
msgstr "連線中…"
#: ../js/ui/status/bluetooth.js:239
#| msgid "Send Files..."
msgid "Send Files…"
msgstr "傳送檔案…"
@ -1492,11 +1487,11 @@ msgstr "請輸入裝置所提及的 PIN。"
msgid "OK"
msgstr "確定"
#: ../js/ui/status/keyboard.js:368
#: ../js/ui/status/keyboard.js:396
msgid "Show Keyboard Layout"
msgstr "顯示鍵盤配置"
#: ../js/ui/status/keyboard.js:373
#: ../js/ui/status/keyboard.js:401
msgid "Region & Language Settings"
msgstr "地區和語言設定值"
@ -1614,7 +1609,7 @@ msgstr "連線失敗"
msgid "Activation of network connection failed"
msgstr "啟動網路連線失敗"
#: ../js/ui/status/network.js:2276
#: ../js/ui/status/network.js:2282
msgid "Networking is disabled"
msgstr "網路已停用"
@ -1629,7 +1624,6 @@ msgstr "電源設定值"
#. 0 is reported when UPower does not have enough data
#. to estimate battery life
#: ../js/ui/status/power.js:99
#| msgid "Estimating..."
msgid "Estimating…"
msgstr "評估中…"
@ -1725,11 +1719,11 @@ msgstr "音量"
msgid "Microphone"
msgstr "麥克風"
#: ../js/ui/unlockDialog.js:151
#: ../js/ui/unlockDialog.js:120
msgid "Log in as another user"
msgstr "以另一個使用者身分登入"
#: ../js/ui/unlockDialog.js:177
#: ../js/ui/unlockDialog.js:141
msgid "Unlock Window"
msgstr "解鎖視窗"
@ -1757,27 +1751,27 @@ msgstr "閒置"
msgid "Offline"
msgstr "離線"
#: ../js/ui/userMenu.js:780
#: ../js/ui/userMenu.js:781
msgid "Notifications"
msgstr "通知"
#: ../js/ui/userMenu.js:796
#: ../js/ui/userMenu.js:797
msgid "Switch User"
msgstr "切換使用者"
#: ../js/ui/userMenu.js:801
#: ../js/ui/userMenu.js:802
msgid "Log Out"
msgstr "登出"
#: ../js/ui/userMenu.js:821
#: ../js/ui/userMenu.js:822
msgid "Install Updates & Restart"
msgstr "安裝更新 & 重新啟動"
#: ../js/ui/userMenu.js:839
#: ../js/ui/userMenu.js:840
msgid "Your chat status will be set to busy"
msgstr "您的聊天狀態會設為忙碌"
#: ../js/ui/userMenu.js:840
#: ../js/ui/userMenu.js:841
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."
@ -1785,20 +1779,22 @@ msgstr ""
"通知現在已被停用,包含聊天訊息。您的上線狀態也調整為讓其他人知道您沒時間看他"
"們的訊息。"
#: ../js/ui/userMenu.js:886
#: ../js/ui/userMenu.js:888
msgid "Other users are logged in."
msgstr "其他使用者已登入。"
#: ../js/ui/userMenu.js:891
#: ../js/ui/userMenu.js:893
msgid "Shutting down might cause them to lose unsaved work."
msgstr "關機可能使它們失去未儲存的工作。"
#: ../js/ui/userMenu.js:918
#. Translators: Remote here refers to a remote session, like a ssh login
#: ../js/ui/userMenu.js:921
#, c-format
msgid "%s (remote)"
msgstr "%s (遠端)"
#: ../js/ui/userMenu.js:920
#. Translators: Console here refers to a tty like a VT console
#: ../js/ui/userMenu.js:924
#, c-format
msgid "%s (console)"
msgstr "%s (主控臺)"
@ -1811,7 +1807,7 @@ msgstr "應用程式"
msgid "Search"
msgstr "搜尋"
#: ../js/ui/wanda.js:92
#: ../js/ui/wanda.js:77
#, c-format
msgid ""
"Sorry, no wisdom for you today:\n"
@ -1820,7 +1816,7 @@ msgstr ""
"抱歉,今天可能有些問題:\n"
"%s"
#: ../js/ui/wanda.js:96
#: ../js/ui/wanda.js:81
#, c-format
msgid "%s the Oracle says"
msgstr "%s Oracle 說:"
@ -1850,7 +1846,7 @@ msgid "%u Input"
msgid_plural "%u Inputs"
msgstr[0] "%u 輸入"
#: ../src/gvc/gvc-mixer-control.c:2371
#: ../src/gvc/gvc-mixer-control.c:2373
msgid "System Sounds"
msgstr "系統音效"
@ -1875,11 +1871,11 @@ msgstr "列出可能的模式"
msgid "Failed to launch '%s'"
msgstr "無法啟動「%s」"
#: ../src/shell-keyring-prompt.c:708
#: ../src/shell-keyring-prompt.c:714
msgid "Passwords do not match."
msgstr "密碼不相符。"
#: ../src/shell-keyring-prompt.c:716
#: ../src/shell-keyring-prompt.c:722
msgid "Password cannot be blank"
msgstr "密碼不能為空白"

Submodule src/gvc updated: 03894efbcd...3d6aac673b

View File

@ -36,8 +36,6 @@ extern GType gnome_shell_plugin_get_type (void);
#define SHELL_DBUS_SERVICE "org.gnome.Shell"
#define MAGNIFIER_DBUS_SERVICE "org.gnome.Magnifier"
#define OVERRIDES_SCHEMA "org.gnome.shell.overrides"
#define WM_NAME "GNOME Shell"
#define GNOME_WM_KEYBINDINGS "Mutter,GNOME Shell"
@ -166,23 +164,6 @@ shell_dbus_init (gboolean replace)
g_object_unref (session);
}
static void
shell_prefs_init (void)
{
meta_prefs_override_preference_schema ("attach-modal-dialogs",
OVERRIDES_SCHEMA);
meta_prefs_override_preference_schema ("dynamic-workspaces",
OVERRIDES_SCHEMA);
meta_prefs_override_preference_schema ("workspaces-only-on-primary",
OVERRIDES_SCHEMA);
meta_prefs_override_preference_schema ("button-layout",
OVERRIDES_SCHEMA);
meta_prefs_override_preference_schema ("edge-tiling",
OVERRIDES_SCHEMA);
meta_prefs_override_preference_schema ("focus-change-on-pointer-rest",
OVERRIDES_SCHEMA);
}
static void
shell_introspection_init (void)
{
@ -409,7 +390,6 @@ main (int argc, char **argv)
shell_dbus_init (meta_get_replace_current_wm ());
shell_a11y_init ();
shell_perf_log_init ();
shell_prefs_init ();
shell_introspection_init ();
shell_fonts_init ();

View File

@ -1009,6 +1009,13 @@ shell_global_end_modal (ShellGlobal *global,
meta_plugin_end_modal (global->plugin, timestamp);
}
void
shell_global_freeze_keyboard (ShellGlobal *global,
guint32 timestamp)
{
meta_display_freeze_keyboard (global->meta_display, global->stage_xwindow, timestamp);
}
/* Code to close all file descriptors before we exec; copied from gspawn.c in GLib.
*
* Authors: Padraig O'Briain, Matthias Clasen, Lennart Poettering

View File

@ -44,6 +44,8 @@ gboolean shell_global_begin_modal (ShellGlobal *global,
MetaModalOptions options);
void shell_global_end_modal (ShellGlobal *global,
guint32 timestamp);
void shell_global_freeze_keyboard (ShellGlobal *global,
guint32 timestamp);
typedef enum {
SHELL_STAGE_INPUT_MODE_NONREACTIVE,

View File

@ -106,6 +106,8 @@ shell_gtk_embed_window_created_cb (MetaDisplay *display,
0, 0 /* offset x/y */);
cairo_region_destroy (empty_region);
gdk_window_lower (gdk_window);
/* Now that we've found the window we don't need to listen for
new windows anymore */
g_signal_handler_disconnect (display,

View File

@ -15,6 +15,8 @@
* @SHELL_KEYBINDING_MODE_SYSTEM_MODAL: allow keybinding when a system modal
* dialog (e.g. authentification or session dialogs) is open
* @SHELL_KEYBINDING_MODE_LOOKING_GLASS: allow keybinding in looking glass
* @SHELL_KEYBINDING_MODE_TOPBAR_POPUP: allow keybinding while a top bar menu
* is open
* @SHELL_KEYBINDING_MODE_ALL: always allow keybinding
*
* Controls in which GNOME Shell states a keybinding should be handled.
@ -29,6 +31,7 @@ typedef enum {
SHELL_KEYBINDING_MODE_MESSAGE_TRAY = 1 << 5,
SHELL_KEYBINDING_MODE_SYSTEM_MODAL = 1 << 6,
SHELL_KEYBINDING_MODE_LOOKING_GLASS = 1 << 7,
SHELL_KEYBINDING_MODE_TOPBAR_POPUP = 1 << 8,
SHELL_KEYBINDING_MODE_ALL = ~0,
} ShellKeyBindingMode;

View File

@ -100,7 +100,6 @@ G_DEFINE_TYPE_WITH_CODE (ShellKeyringPrompt, shell_keyring_prompt, G_TYPE_OBJECT
enum {
SIGNAL_SHOW_PASSWORD,
SIGNAL_SHOW_CONFIRM,
SIGNAL_HIDE_PROMPT,
SIGNAL_LAST
};
@ -258,10 +257,8 @@ shell_keyring_prompt_dispose (GObject *obj)
{
ShellKeyringPrompt *self = SHELL_KEYRING_PROMPT (obj);
if (self->shown) {
self->shown = FALSE;
g_signal_emit (self, signals[SIGNAL_HIDE_PROMPT], 0);
}
if (self->shown)
gcr_prompt_close (GCR_PROMPT (self));
if (self->async_result)
shell_keyring_prompt_cancel (self);
@ -384,11 +381,6 @@ shell_keyring_prompt_class_init (ShellKeyringPromptClass *klass)
0, 0, NULL, NULL,
g_cclosure_marshal_VOID__VOID,
G_TYPE_NONE, 0);
signals[SIGNAL_HIDE_PROMPT] = g_signal_new ("hide-prompt", G_TYPE_FROM_CLASS (klass),
0, 0, NULL, NULL,
g_cclosure_marshal_VOID__VOID,
G_TYPE_NONE, 0);
}
static void
@ -482,6 +474,19 @@ shell_keyring_prompt_confirm_finish (GcrPrompt *prompt,
return self->last_reply;
}
static void
shell_keyring_prompt_close (GcrPrompt *prompt)
{
ShellKeyringPrompt *self = SHELL_KEYRING_PROMPT (prompt);
/*
* We expect keyring.js to connect to this signal and do the
* actual work of closing the prompt.
*/
self->shown = FALSE;
}
static void
shell_keyring_prompt_iface (GcrPromptIface *iface)
{
@ -489,6 +494,7 @@ shell_keyring_prompt_iface (GcrPromptIface *iface)
iface->prompt_password_finish = shell_keyring_prompt_password_finish;
iface->prompt_confirm_async = shell_keyring_prompt_confirm_async;
iface->prompt_confirm_finish = shell_keyring_prompt_confirm_finish;
iface->prompt_close = shell_keyring_prompt_close;
}
/**
@ -746,9 +752,19 @@ shell_keyring_prompt_cancel (ShellKeyringPrompt *self)
GSimpleAsyncResult *res;
g_return_if_fail (SHELL_IS_KEYRING_PROMPT (self));
g_return_if_fail (self->mode != PROMPTING_NONE);
g_return_if_fail (self->async_result != NULL);
/*
* If cancelled while not prompting, we should just close the prompt,
* the user wants it to go away.
*/
if (self->mode == PROMPTING_NONE)
{
if (self->shown)
gcr_prompt_close (GCR_PROMPT (self));
return;
}
g_return_if_fail (self->async_result != NULL);
self->last_reply = GCR_PROMPT_REPLY_CANCEL;
res = self->async_result;

View File

@ -25,6 +25,9 @@
/* This is also hard-coded in mutter and GDK */
#define VIRTUAL_CORE_POINTER_ID 2
#define A11Y_APPS_SCHEMA "org.gnome.desktop.a11y.applications"
#define MAGNIFIER_ACTIVE_KEY "screen-magnifier-enabled"
typedef enum {
RECORDER_STATE_CLOSED,
RECORDER_STATE_RECORDING
@ -50,6 +53,8 @@ struct _ShellRecorder {
RecorderState state;
ClutterStage *stage;
gboolean custom_area;
cairo_rectangle_int_t area;
int stage_width;
int stage_height;
@ -66,6 +71,8 @@ struct _ShellRecorder {
CoglHandle recording_icon; /* icon shown while playing */
GSettings *a11y_settings;
gboolean draw_cursor;
cairo_surface_t *cursor_image;
int cursor_hot_x;
int cursor_hot_y;
@ -110,6 +117,8 @@ static void recorder_set_pipeline (ShellRecorder *recorder,
const char *pipeline);
static void recorder_set_file_template (ShellRecorder *recorder,
const char *file_template);
static void recorder_set_draw_cursor (ShellRecorder *recorder,
gboolean draw_cursor);
static void recorder_pipeline_set_caps (RecorderPipeline *pipeline);
static void recorder_pipeline_closed (RecorderPipeline *pipeline);
@ -119,7 +128,8 @@ enum {
PROP_STAGE,
PROP_FRAMERATE,
PROP_PIPELINE,
PROP_FILE_TEMPLATE
PROP_FILE_TEMPLATE,
PROP_DRAW_CURSOR
};
G_DEFINE_TYPE(ShellRecorder, shell_recorder, G_TYPE_OBJECT);
@ -271,8 +281,11 @@ shell_recorder_init (ShellRecorder *recorder)
recorder->recording_icon = create_recording_icon ();
recorder->memory_target = get_memory_target();
recorder->a11y_settings = g_settings_new (A11Y_APPS_SCHEMA);
recorder->state = RECORDER_STATE_CLOSED;
recorder->framerate = DEFAULT_FRAMES_PER_SECOND;
recorder->draw_cursor = TRUE;
}
static void
@ -292,6 +305,8 @@ shell_recorder_finalize (GObject *object)
cogl_handle_unref (recorder->recording_icon);
g_clear_object (&recorder->a11y_settings);
G_OBJECT_CLASS (shell_recorder_parent_class)->finalize (object);
}
@ -429,10 +444,10 @@ recorder_draw_cursor (ShellRecorder *recorder,
/* We don't show a cursor unless the hot spot is in the frame; this
* means that sometimes we aren't going to draw a cursor even when
* there is a little bit overlapping within the stage */
if (recorder->pointer_x < 0 ||
recorder->pointer_y < 0 ||
recorder->pointer_x >= recorder->stage_width ||
recorder->pointer_y >= recorder->stage_height)
if (recorder->pointer_x < recorder->area.x ||
recorder->pointer_y < recorder->area.y ||
recorder->pointer_x >= recorder->area.x + recorder->area.width ||
recorder->pointer_y >= recorder->area.y + recorder->area.height)
return;
if (!recorder->cursor_image)
@ -444,15 +459,15 @@ recorder_draw_cursor (ShellRecorder *recorder,
gst_buffer_map (buffer, &info, GST_MAP_WRITE);
surface = cairo_image_surface_create_for_data (info.data,
CAIRO_FORMAT_ARGB32,
recorder->stage_width,
recorder->stage_height,
recorder->stage_width * 4);
recorder->area.width,
recorder->area.height,
recorder->area.width * 4);
cr = cairo_create (surface);
cairo_set_source_surface (cr,
recorder->cursor_image,
recorder->pointer_x - recorder->cursor_hot_x,
recorder->pointer_y - recorder->cursor_hot_y);
recorder->pointer_x - recorder->cursor_hot_x - recorder->area.x,
recorder->pointer_y - recorder->cursor_hot_y - recorder->area.y);
cairo_paint (cr);
cairo_destroy (cr);
@ -470,7 +485,7 @@ recorder_draw_buffer_meter (ShellRecorder *recorder)
GdkRectangle primary_monitor;
float rects[16];
gdk_screen_get_monitor_geometry (recorder->gdk_screen,
gdk_screen_get_monitor_workarea (recorder->gdk_screen,
gdk_screen_get_primary_monitor (recorder->gdk_screen),
&primary_monitor);
@ -555,12 +570,13 @@ recorder_record_frame (ShellRecorder *recorder)
recorder->last_frame_time = now;
size = recorder->stage_width * recorder->stage_height * 4;
size = recorder->area.width * recorder->area.height * 4;
data = g_malloc (recorder->stage_width * 4 * recorder->stage_height);
cogl_read_pixels (0, 0, /* x/y */
recorder->stage_width,
recorder->stage_height,
data = g_malloc (recorder->area.width * 4 * recorder->area.height);
cogl_read_pixels (recorder->area.x,
recorder->area.y,
recorder->area.width,
recorder->area.height,
COGL_READ_PIXELS_COLOR_BUFFER,
CLUTTER_CAIRO_FORMAT_ARGB32,
data);
@ -572,7 +588,9 @@ recorder_record_frame (ShellRecorder *recorder)
GST_BUFFER_PTS(buffer) = now - recorder->start_time;
recorder_draw_cursor (recorder, buffer);
if (recorder->draw_cursor &&
!g_settings_get_boolean (recorder->a11y_settings, MAGNIFIER_ACTIVE_KEY))
recorder_draw_cursor (recorder, buffer);
shell_recorder_src_add_buffer (SHELL_RECORDER_SRC (recorder->current_pipeline->src), buffer);
gst_buffer_unref (buffer);
@ -593,7 +611,7 @@ recorder_on_stage_paint (ClutterActor *actor,
{
GdkRectangle primary_monitor;
gdk_screen_get_monitor_geometry (recorder->gdk_screen,
gdk_screen_get_monitor_workarea (recorder->gdk_screen,
gdk_screen_get_primary_monitor (recorder->gdk_screen),
&primary_monitor);
if (!recorder->only_paint)
@ -616,6 +634,14 @@ recorder_update_size (ShellRecorder *recorder)
clutter_actor_get_allocation_box (CLUTTER_ACTOR (recorder->stage), &allocation);
recorder->stage_width = (int)(0.5 + allocation.x2 - allocation.x1);
recorder->stage_height = (int)(0.5 + allocation.y2 - allocation.y1);
if (!recorder->custom_area)
{
recorder->area.x = 0;
recorder->area.y = 0;
recorder->area.width = recorder->stage_width;
recorder->area.height = recorder->stage_height;
}
}
static void
@ -1006,6 +1032,18 @@ recorder_set_file_template (ShellRecorder *recorder,
g_object_notify (G_OBJECT (recorder), "file-template");
}
static void
recorder_set_draw_cursor (ShellRecorder *recorder,
gboolean draw_cursor)
{
if (draw_cursor == recorder->draw_cursor)
return;
recorder->draw_cursor = draw_cursor;
g_object_notify (G_OBJECT (recorder), "draw-cursor");
}
static void
shell_recorder_set_property (GObject *object,
guint prop_id,
@ -1028,6 +1066,9 @@ shell_recorder_set_property (GObject *object,
case PROP_FILE_TEMPLATE:
recorder_set_file_template (recorder, g_value_get_string (value));
break;
case PROP_DRAW_CURSOR:
recorder_set_draw_cursor (recorder, g_value_get_boolean (value));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
@ -1056,6 +1097,9 @@ shell_recorder_get_property (GObject *object,
case PROP_FILE_TEMPLATE:
g_value_set_string (value, recorder->file_template);
break;
case PROP_DRAW_CURSOR:
g_value_set_boolean (value, recorder->draw_cursor);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
@ -1104,6 +1148,14 @@ shell_recorder_class_init (ShellRecorderClass *klass)
"The filename template to use for output files",
NULL,
G_PARAM_READWRITE));
g_object_class_install_property (gobject_class,
PROP_DRAW_CURSOR,
g_param_spec_boolean ("draw-cursor",
"Draw Cursor",
"Whether to record the cursor",
TRUE,
G_PARAM_READWRITE));
}
/* Sets the GstCaps (video format, in this case) on the stream
@ -1126,8 +1178,8 @@ recorder_pipeline_set_caps (RecorderPipeline *pipeline)
"bpp", G_TYPE_INT, 32,
"depth", G_TYPE_INT, 24,
"framerate", GST_TYPE_FRACTION, pipeline->recorder->framerate, 1,
"width", G_TYPE_INT, pipeline->recorder->stage_width,
"height", G_TYPE_INT, pipeline->recorder->stage_height,
"width", G_TYPE_INT, pipeline->recorder->area.width,
"height", G_TYPE_INT, pipeline->recorder->area.height,
NULL);
g_object_set (pipeline->src, "caps", caps, NULL);
gst_caps_unref (caps);
@ -1678,6 +1730,15 @@ shell_recorder_set_file_template (ShellRecorder *recorder,
}
void
shell_recorder_set_draw_cursor (ShellRecorder *recorder,
gboolean draw_cursor)
{
g_return_if_fail (SHELL_IS_RECORDER (recorder));
recorder_set_draw_cursor (recorder, draw_cursor);
}
/**
* shell_recorder_set_pipeline:
* @recorder: the #ShellRecorder
@ -1705,9 +1766,35 @@ shell_recorder_set_pipeline (ShellRecorder *recorder,
recorder_set_pipeline (recorder, pipeline);
}
void
shell_recorder_set_area (ShellRecorder *recorder,
int x,
int y,
int width,
int height)
{
g_return_if_fail (SHELL_IS_RECORDER (recorder));
recorder->custom_area = TRUE;
recorder->area.x = CLAMP (x, 0, recorder->stage_width);
recorder->area.y = CLAMP (y, 0, recorder->stage_height);
recorder->area.width = CLAMP (width,
0, recorder->stage_width - recorder->area.x);
recorder->area.height = CLAMP (height,
0, recorder->stage_height - recorder->area.y);
/* This breaks the recording but tweaking the GStreamer pipeline a bit
* might make it work, at least if the codec can handle a stream where
* the frame size changes in the middle.
*/
if (recorder->current_pipeline)
recorder_pipeline_set_caps (recorder->current_pipeline);
}
/**
* shell_recorder_record:
* @recorder: the #ShellRecorder
* @filename_used: (out) (allow-none): actual filename used for recording
*
* Starts recording, Starting the recording may fail if the output file
* cannot be opened, or if the output stream cannot be created
@ -1724,7 +1811,8 @@ shell_recorder_set_pipeline (ShellRecorder *recorder,
* Return value: %TRUE if recording was succesfully started
*/
gboolean
shell_recorder_record (ShellRecorder *recorder)
shell_recorder_record (ShellRecorder *recorder,
char **filename_used)
{
g_return_val_if_fail (SHELL_IS_RECORDER (recorder), FALSE);
g_return_val_if_fail (recorder->stage != NULL, FALSE);
@ -1733,6 +1821,9 @@ shell_recorder_record (ShellRecorder *recorder)
if (!recorder_open_pipeline (recorder))
return FALSE;
if (filename_used)
*filename_used = g_strdup (recorder->current_pipeline->filename);
recorder_connect_stage_callbacks (recorder);
recorder->start_time = get_wall_time();

View File

@ -36,7 +36,15 @@ 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);
void shell_recorder_set_draw_cursor (ShellRecorder *recorder,
gboolean draw_cursor);
void shell_recorder_set_area (ShellRecorder *recorder,
int x,
int y,
int width,
int height);
gboolean shell_recorder_record (ShellRecorder *recorder,
char **filename_used);
void shell_recorder_close (ShellRecorder *recorder);
void shell_recorder_pause (ShellRecorder *recorder);
gboolean shell_recorder_is_recording (ShellRecorder *recorder);

View File

@ -15,6 +15,9 @@
#include "shell-global.h"
#include "shell-screenshot.h"
#define A11Y_APPS_SCHEMA "org.gnome.desktop.a11y.applications"
#define MAGNIFIER_ACTIVE_KEY "screen-magnifier-enabled"
struct _ShellScreenshotClass
{
GObjectClass parent_class;
@ -304,6 +307,7 @@ grab_screenshot (ClutterActor *stage,
MetaScreen *screen = shell_global_get_screen (screenshot_data->screenshot->global);
int width, height;
GSimpleAsyncResult *result;
GSettings *settings;
meta_screen_get_size (screen, &width, &height);
@ -352,8 +356,11 @@ grab_screenshot (ClutterActor *stage,
screenshot_data->screenshot_area.width = width;
screenshot_data->screenshot_area.height = height;
if (screenshot_data->include_cursor)
settings = g_settings_new (A11Y_APPS_SCHEMA);
if (screenshot_data->include_cursor &&
!g_settings_get_boolean (settings, MAGNIFIER_ACTIVE_KEY))
_draw_cursor_image (screenshot_data->image, screenshot_data->screenshot_area);
g_object_unref (settings);
g_signal_handlers_disconnect_by_func (stage, (void *)grab_screenshot, (gpointer)screenshot_data);
@ -476,6 +483,7 @@ shell_screenshot_screenshot_window (ShellScreenshot *screenshot,
ShellScreenshotCallback callback)
{
GSimpleAsyncResult *result;
GSettings *settings;
_screenshot_data *screenshot_data = g_new0 (_screenshot_data, 1);
@ -492,6 +500,17 @@ shell_screenshot_screenshot_window (ShellScreenshot *screenshot,
screenshot_data->filename = g_strdup (filename);
screenshot_data->callback = callback;
if (!window)
{
screenshot_data->filename_used = g_strdup ("");
result = g_simple_async_result_new (NULL, on_screenshot_written, (gpointer)screenshot_data, shell_screenshot_screenshot_window);
g_simple_async_result_set_op_res_gboolean (result, FALSE);
g_simple_async_result_complete (result);
g_object_unref (result);
return;
}
window_actor = CLUTTER_ACTOR (meta_window_get_compositor_private (window));
clutter_actor_get_position (window_actor, &actor_x, &actor_y);
@ -522,8 +541,10 @@ shell_screenshot_screenshot_window (ShellScreenshot *screenshot,
stex = META_SHAPED_TEXTURE (meta_window_actor_get_texture (META_WINDOW_ACTOR (window_actor)));
screenshot_data->image = meta_shaped_texture_get_image (stex, &clip);
if (include_cursor)
settings = g_settings_new (A11Y_APPS_SCHEMA);
if (include_cursor && !g_settings_get_boolean (settings, MAGNIFIER_ACTIVE_KEY))
_draw_cursor_image (screenshot_data->image, screenshot_data->screenshot_area);
g_object_unref (settings);
result = g_simple_async_result_new (NULL, on_screenshot_written, (gpointer)screenshot_data, shell_screenshot_screenshot_window);
g_simple_async_result_run_in_thread (result, write_screenshot_thread, G_PRIORITY_DEFAULT, NULL);

View File

@ -82,6 +82,8 @@ enum
PROP_CLUTTER_TEXT,
PROP_HINT_TEXT,
PROP_TEXT,
PROP_INPUT_PURPOSE,
PROP_INPUT_HINTS,
};
/* signals */
@ -136,6 +138,14 @@ st_entry_set_property (GObject *gobject,
st_entry_set_text (entry, g_value_get_string (value));
break;
case PROP_INPUT_PURPOSE:
st_entry_set_input_purpose (entry, g_value_get_enum (value));
break;
case PROP_INPUT_HINTS:
st_entry_set_input_hints (entry, g_value_get_flags (value));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec);
break;
@ -164,6 +174,14 @@ st_entry_get_property (GObject *gobject,
g_value_set_string (value, clutter_text_get_text (CLUTTER_TEXT (priv->entry)));
break;
case PROP_INPUT_PURPOSE:
g_value_set_enum (value, st_im_text_get_input_purpose (ST_IM_TEXT (priv->entry)));
break;
case PROP_INPUT_HINTS:
g_value_set_flags (value, st_im_text_get_input_hints (ST_IM_TEXT (priv->entry)));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec);
break;
@ -759,6 +777,26 @@ st_entry_class_init (StEntryClass *klass)
NULL, G_PARAM_READWRITE);
g_object_class_install_property (gobject_class, PROP_TEXT, pspec);
pspec = g_param_spec_enum ("input-purpose",
"Purpose",
"Purpose of the text field",
GTK_TYPE_INPUT_PURPOSE,
GTK_INPUT_PURPOSE_FREE_FORM,
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
g_object_class_install_property (gobject_class,
PROP_INPUT_PURPOSE,
pspec);
pspec = g_param_spec_flags ("input-hints",
"hints",
"Hints for the text field behaviour",
GTK_TYPE_INPUT_HINTS,
GTK_INPUT_HINT_NONE,
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
g_object_class_install_property (gobject_class,
PROP_INPUT_HINTS,
pspec);
/* signals */
/**
* StEntry::primary-icon-clicked:
@ -966,6 +1004,87 @@ st_entry_get_hint_text (StEntry *entry)
return entry->priv->hint;
}
/**
* st_entry_set_input_purpose:
* @entry: a #StEntry
* @purpose: the purpose
*
* Sets the #StEntry:input-purpose property which
* can be used by on-screen keyboards and other input
* methods to adjust their behaviour.
*/
void
st_entry_set_input_purpose (StEntry *entry,
GtkInputPurpose purpose)
{
StIMText *imtext;
g_return_if_fail (ST_IS_ENTRY (entry));
imtext = ST_IM_TEXT (entry->priv->entry);
if (st_im_text_get_input_purpose (imtext) != purpose)
{
st_im_text_set_input_purpose (imtext, purpose);
g_object_notify (G_OBJECT (entry), "input-purpose");
}
}
/**
* st_entry_get_input_purpose:
* @entry: a #StEntry
*
* Gets the value of the #StEntry:input-purpose property.
*/
GtkInputPurpose
st_entry_get_input_purpose (StEntry *entry)
{
g_return_val_if_fail (ST_IS_ENTRY (entry), GTK_INPUT_PURPOSE_FREE_FORM);
return st_im_text_get_input_purpose (ST_IM_TEXT (entry->priv->entry));
}
/**
* st_entry_set_input_hints:
* @entry: a #StEntry
* @hints: the hints
*
* Sets the #StEntry:input-hints property, which
* allows input methods to fine-tune their behaviour.
*/
void
st_entry_set_input_hints (StEntry *entry,
GtkInputHints hints)
{
StIMText *imtext;
g_return_if_fail (ST_IS_ENTRY (entry));
imtext = ST_IM_TEXT (entry->priv->entry);
if (st_im_text_get_input_hints (imtext) != hints)
{
st_im_text_set_input_hints (imtext, hints);
g_object_notify (G_OBJECT (entry), "input-hints");
}
}
/**
* st_entry_get_input_hints:
* @entry: a #StEntry
*
* Gets the value of the #StEntry:input-hints property.
*/
GtkInputHints
st_entry_get_input_hints (StEntry *entry)
{
g_return_val_if_fail (ST_IS_ENTRY (entry), GTK_INPUT_HINT_NONE);
return st_im_text_get_input_hints (ST_IM_TEXT (entry->priv->entry));
}
static gboolean
_st_entry_icon_press_cb (ClutterActor *actor,
ClutterButtonEvent *event,

View File

@ -64,20 +64,27 @@ struct _StEntryClass
GType st_entry_get_type (void) G_GNUC_CONST;
StWidget * st_entry_new (const gchar *text);
const gchar * st_entry_get_text (StEntry *entry);
void st_entry_set_text (StEntry *entry,
const gchar *text);
ClutterActor* st_entry_get_clutter_text (StEntry *entry);
StWidget *st_entry_new (const gchar *text);
const gchar *st_entry_get_text (StEntry *entry);
void st_entry_set_text (StEntry *entry,
const gchar *text);
ClutterActor *st_entry_get_clutter_text (StEntry *entry);
void st_entry_set_hint_text (StEntry *entry,
const gchar *text);
const gchar * st_entry_get_hint_text (StEntry *entry);
void st_entry_set_hint_text (StEntry *entry,
const gchar *text);
const gchar *st_entry_get_hint_text (StEntry *entry);
void st_entry_set_primary_icon (StEntry *entry,
ClutterActor *icon);
void st_entry_set_secondary_icon (StEntry *entry,
ClutterActor *icon);
void st_entry_set_input_purpose (StEntry *entry,
GtkInputPurpose purpose);
GtkInputPurpose st_entry_get_input_purpose (StEntry *entry);
void st_entry_set_input_hints (StEntry *entry,
GtkInputHints hints);
GtkInputHints st_entry_get_input_hints (StEntry *entry);
void st_entry_set_primary_icon (StEntry *entry,
ClutterActor *icon);
void st_entry_set_secondary_icon (StEntry *entry,
ClutterActor *icon);
G_END_DECLS

View File

@ -249,11 +249,6 @@ st_icon_paint (ClutterActor *actor)
clutter_actor_get_allocation_box (priv->icon_texture, &allocation);
clutter_actor_box_get_size (&allocation, &width, &height);
allocation.x1 = (width - priv->shadow_width) / 2;
allocation.y1 = (height - priv->shadow_height) / 2;
allocation.x2 = allocation.x1 + priv->shadow_width;
allocation.y2 = allocation.y1 + priv->shadow_height;
_st_paint_shadow_with_opacity (priv->shadow_spec,
priv->shadow_material,
&allocation,
@ -410,8 +405,8 @@ st_icon_finish_update (StIcon *icon)
st_icon_update_shadow_material (icon);
/* "pixbuf-change" is actually a misnomer for "texture-changed" */
g_signal_connect (priv->icon_texture, "pixbuf-change",
G_CALLBACK (on_pixbuf_changed), icon);
g_signal_connect_object (priv->icon_texture, "pixbuf-change",
G_CALLBACK (on_pixbuf_changed), icon, 0);
}
}
@ -469,7 +464,7 @@ st_icon_update (StIcon *icon)
else
{
/* Will be shown when fully loaded */
priv->opacity_handler_id = g_signal_connect (priv->pending_texture, "notify::opacity", G_CALLBACK (opacity_changed_cb), icon);
priv->opacity_handler_id = g_signal_connect_object (priv->pending_texture, "notify::opacity", G_CALLBACK (opacity_changed_cb), icon, 0);
}
}
else if (priv->icon_texture)

View File

@ -50,6 +50,15 @@
#include "st-im-text.h"
/* properties */
enum
{
PROP_0,
PROP_INPUT_PURPOSE,
PROP_INPUT_HINTS,
};
#define ST_IM_TEXT_GET_PRIVATE(obj) \
(G_TYPE_INSTANCE_GET_PRIVATE ((obj), ST_TYPE_IM_TEXT, StIMTextPrivate))
@ -74,27 +83,24 @@ st_im_text_dispose (GObject *object)
}
static void
update_im_cursor_location (StIMText *self)
st_im_text_cursor_event (ClutterText *self,
const ClutterGeometry *geometry)
{
StIMTextPrivate *priv = self->priv;
ClutterText *clutter_text = CLUTTER_TEXT (self);
gint position;
gfloat cursor_x, cursor_y, cursor_height;
StIMTextPrivate *priv = ST_IM_TEXT (self)->priv;
gfloat actor_x, actor_y;
GdkRectangle area;
position = clutter_text_get_cursor_position (clutter_text);
clutter_text_position_to_coords (clutter_text, position,
&cursor_x, &cursor_y, &cursor_height);
clutter_actor_get_transformed_position (CLUTTER_ACTOR (self), &actor_x, &actor_y);
area.x = (int)(0.5 + cursor_x + actor_x);
area.y = (int)(0.5 + cursor_y + actor_y);
area.width = 0;
area.height = (int)(0.5 + cursor_height);
area.x = (int)(0.5 + geometry->x + actor_x);
area.y = (int)(0.5 + geometry->y + actor_y);
area.width = geometry->width;
area.height = geometry->height;
gtk_im_context_set_cursor_location (priv->im_context, &area);
if (CLUTTER_TEXT_CLASS (st_im_text_parent_class)->cursor_event)
CLUTTER_TEXT_CLASS (st_im_text_parent_class)->cursor_event (self, geometry);
}
static void
@ -190,20 +196,6 @@ reset_im_context (StIMText *self)
}
}
static void
st_im_text_paint (ClutterActor *actor)
{
StIMText *self = ST_IM_TEXT (actor);
ClutterText *clutter_text = CLUTTER_TEXT (actor);
/* This updates the cursor position as a side-effect */
if (CLUTTER_ACTOR_CLASS (st_im_text_parent_class)->paint)
CLUTTER_ACTOR_CLASS (st_im_text_parent_class)->paint (actor);
if (clutter_text_get_editable (clutter_text))
update_im_cursor_location (self);
}
static gboolean
st_im_text_get_paint_volume (ClutterActor *self,
ClutterPaintVolume *volume)
@ -421,17 +413,68 @@ st_im_text_key_focus_out (ClutterActor *actor)
CLUTTER_ACTOR_CLASS (st_im_text_parent_class)->key_focus_out (actor);
}
static void
st_im_text_set_property (GObject *gobject,
guint prop_id,
const GValue *value,
GParamSpec *pspec)
{
StIMText *imtext = ST_IM_TEXT (gobject);
switch (prop_id)
{
case PROP_INPUT_PURPOSE:
st_im_text_set_input_purpose (imtext, g_value_get_enum (value));
break;
case PROP_INPUT_HINTS:
st_im_text_set_input_hints (imtext, g_value_get_flags (value));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec);
break;
}
}
static void
st_im_text_get_property (GObject *gobject,
guint prop_id,
GValue *value,
GParamSpec *pspec)
{
StIMText *imtext = ST_IM_TEXT (gobject);
switch (prop_id)
{
case PROP_INPUT_PURPOSE:
g_value_set_enum (value, st_im_text_get_input_purpose (imtext));
break;
case PROP_INPUT_HINTS:
g_value_set_flags (value, st_im_text_get_input_hints (imtext));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec);
break;
}
}
static void
st_im_text_class_init (StIMTextClass *klass)
{
GObjectClass *object_class = G_OBJECT_CLASS (klass);
ClutterActorClass *actor_class = CLUTTER_ACTOR_CLASS (klass);
ClutterTextClass *text_class = CLUTTER_TEXT_CLASS (klass);
GParamSpec *pspec;
g_type_class_add_private (klass, sizeof (StIMTextPrivate));
object_class->dispose = st_im_text_dispose;
object_class->set_property = st_im_text_set_property;
object_class->get_property = st_im_text_get_property;
actor_class->paint = st_im_text_paint;
actor_class->get_paint_volume = st_im_text_get_paint_volume;
actor_class->realize = st_im_text_realize;
actor_class->unrealize = st_im_text_unrealize;
@ -440,6 +483,28 @@ st_im_text_class_init (StIMTextClass *klass)
actor_class->captured_event = st_im_text_captured_event;
actor_class->key_focus_in = st_im_text_key_focus_in;
actor_class->key_focus_out = st_im_text_key_focus_out;
text_class->cursor_event = st_im_text_cursor_event;
pspec = g_param_spec_enum ("input-purpose",
"Purpose",
"Purpose of the text field",
GTK_TYPE_INPUT_PURPOSE,
GTK_INPUT_PURPOSE_FREE_FORM,
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
g_object_class_install_property (object_class,
PROP_INPUT_PURPOSE,
pspec);
pspec = g_param_spec_flags ("input-hints",
"hints",
"Hints for the text field behaviour",
GTK_TYPE_INPUT_HINTS,
GTK_INPUT_HINT_NONE,
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
g_object_class_install_property (object_class,
PROP_INPUT_HINTS,
pspec);
}
static void
@ -475,3 +540,96 @@ st_im_text_new (const gchar *text)
"text", text,
NULL);
}
/**
* st_im_text_set_input_purpose:
* @imtext: a #StIMText
* @purpose: the purpose
*
* Sets the #StIMText:input-purpose property which
* can be used by on-screen keyboards and other input
* methods to adjust their behaviour.
*/
void
st_im_text_set_input_purpose (StIMText *imtext,
GtkInputPurpose purpose)
{
g_return_if_fail (ST_IS_IM_TEXT (imtext));
if (st_im_text_get_input_purpose (imtext) != purpose)
{
g_object_set (G_OBJECT (imtext->priv->im_context),
"input-purpose", purpose,
NULL);
g_object_get (G_OBJECT (imtext->priv->im_context),
"input-purpose", &purpose,
NULL);
g_object_notify (G_OBJECT (imtext), "input-purpose");
}
}
/**
* st_im_text_get_input_purpose:
* @imtext: a #StIMText
*
* Gets the value of the #StIMText:input-purpose property.
*/
GtkInputPurpose
st_im_text_get_input_purpose (StIMText *imtext)
{
GtkInputPurpose purpose;
g_return_val_if_fail (ST_IS_IM_TEXT (imtext), GTK_INPUT_PURPOSE_FREE_FORM);
g_object_get (G_OBJECT (imtext->priv->im_context),
"input-purpose", &purpose,
NULL);
return purpose;
}
/**
* st_im_text_set_input_hints:
* @imtext: a #StIMText
* @hints: the hints
*
* Sets the #StIMText:input-hints property, which
* allows input methods to fine-tune their behaviour.
*/
void
st_im_text_set_input_hints (StIMText *imtext,
GtkInputHints hints)
{
g_return_if_fail (ST_IS_IM_TEXT (imtext));
if (st_im_text_get_input_hints (imtext) != hints)
{
g_object_set (G_OBJECT (imtext->priv->im_context),
"input-hints", hints,
NULL);
g_object_notify (G_OBJECT (imtext), "input-hints");
}
}
/**
* st_im_text_get_input_hints:
* @imtext: a #StIMText
*
* Gets the value of the #StIMText:input-hints property.
*/
GtkInputHints
st_im_text_get_input_hints (StIMText *imtext)
{
GtkInputHints hints;
g_return_val_if_fail (ST_IS_IM_TEXT (imtext), GTK_INPUT_HINT_NONE);
g_object_get (G_OBJECT (imtext->priv->im_context),
"input-hints", &hints,
NULL);
return hints;
}

View File

@ -60,9 +60,13 @@ struct _StIMTextClass
GType st_im_text_get_type (void) G_GNUC_CONST;
ClutterActor *st_im_text_new (const gchar *text);
void st_im_text_set_autoshow_im (StIMText *self,
gboolean autoshow);
ClutterActor *st_im_text_new (const gchar *text);
void st_im_text_set_input_purpose (StIMText *imtext,
GtkInputPurpose purpose);
GtkInputPurpose st_im_text_get_input_purpose (StIMText *imtext);
void st_im_text_set_input_hints (StIMText *imtext,
GtkInputHints hints);
GtkInputHints st_im_text_get_input_hints (StIMText *imtext);
G_END_DECLS

View File

@ -218,10 +218,6 @@ st_label_paint (ClutterActor *actor)
clutter_actor_get_allocation_box (priv->label, &allocation);
clutter_actor_box_get_size (&allocation, &width, &height);
allocation.x1 = allocation.y1 = 0;
allocation.x2 = width;
allocation.y2 = height;
if (priv->text_shadow_material == COGL_INVALID_HANDLE ||
width != priv->shadow_width ||
height != priv->shadow_height)

View File

@ -511,6 +511,7 @@ _st_create_shadow_material_from_actor (StShadow *shadow_spec,
cogl_color_set_from_4ub (&clear_color, 0, 0, 0, 0);
cogl_push_framebuffer (offscreen);
cogl_clear (&clear_color, COGL_BUFFER_BIT_COLOR);
cogl_translate (-box.x1, -box.y1, 0);
cogl_ortho (0, width, height, 0, 0, 1.0);
clutter_actor_paint (actor);
cogl_pop_framebuffer ();

View File

@ -292,11 +292,6 @@ st_shadow_helper_paint (StShadowHelper *helper,
clutter_actor_box_get_size (actor_box, &width, &height);
allocation.x1 = (width - helper->width) / 2;
allocation.y1 = (height - helper->height) / 2;
allocation.x2 = allocation.x1 + helper->width;
allocation.y2 = allocation.y1 + helper->height;
_st_paint_shadow_with_opacity (helper->shadow,
helper->material,
&allocation,

View File

@ -879,6 +879,101 @@ st_theme_node_get_double (StThemeNode *node,
}
}
/**
* st_theme_node_lookup_url:
* @node: a #StThemeNode
* @property_name: The name of the string property
* @inherit: if %TRUE, if a value is not found for the property on the
* node, then it will be looked up on the parent node, and then on the
* parent's parent, and so forth. Note that if the property has a
* value of 'inherit' it will be inherited even if %FALSE is passed
* in for @inherit; this only affects the default behavior for inheritance.
* @value: (out): location to store the newly allocated value that was
* determined. If the property is not found, the value in this location
* will not be changed.
*
* Looks up a property containing a single URL value.
*
* See also st_theme_node_get_url(), which provides a simpler API.
*
* Return value: %TRUE if the property was found in the properties for this
* theme node (or in the properties of parent nodes when inheriting.)
*/
gboolean
st_theme_node_lookup_url (StThemeNode *node,
const char *property_name,
gboolean inherit,
char **value)
{
gboolean result = FALSE;
int i;
ensure_properties (node);
for (i = node->n_properties - 1; i >= 0; i--)
{
CRDeclaration *decl = node->properties[i];
if (strcmp (decl->property->stryng->str, property_name) == 0)
{
CRTerm *term = decl->value;
CRStyleSheet *base_stylesheet;
GFile *file;
if (term->type != TERM_URI && term->type != TERM_STRING)
continue;
if (decl->parent_statement != NULL)
base_stylesheet = decl->parent_statement->parent_sheet;
else
base_stylesheet = NULL;
file = _st_theme_resolve_url (node->theme,
base_stylesheet,
decl->value->content.str->stryng->str);
*value = g_file_get_path (file);
g_object_unref (file);
result = TRUE;
break;
}
}
if (!result && inherit && node->parent_node)
result = st_theme_node_lookup_url (node->parent_node, property_name, inherit, value);
return result;
}
/*
* st_theme_node_get_url:
* @node: a #StThemeNode
* @property_name: The name of the string property
*
* Looks up a property containing a single URL value.
*
* See also st_theme_node_lookup_url(), which provides more options,
* and lets you handle the case where the theme does not specify the
* indicated value.
*
* Return value: the newly allocated value if found.
* If @property_name is not found, a warning will be logged and %NULL
* will be returned.
*/
char *
st_theme_node_get_url (StThemeNode *node,
const char *property_name)
{
char *value;
if (st_theme_node_lookup_url (node, property_name, FALSE, &value))
return value;
else
{
g_warning ("Did not find string property '%s'", property_name);
return NULL;
}
}
static const PangoFontDescription *
get_parent_font (StThemeNode *node)
{
@ -1554,6 +1649,7 @@ void
_st_theme_node_ensure_geometry (StThemeNode *node)
{
int i, j;
int width, height;
if (node->geometry_computed)
return;
@ -1571,6 +1667,8 @@ _st_theme_node_ensure_geometry (StThemeNode *node)
node->outline_width = 0;
node->outline_color = TRANSPARENT_COLOR;
width = -1;
height = -1;
node->width = -1;
node->height = -1;
node->min_width = -1;
@ -1590,8 +1688,12 @@ _st_theme_node_ensure_geometry (StThemeNode *node)
else if (g_str_has_prefix (property_name, "padding"))
do_padding_property (node, decl);
else if (strcmp (property_name, "width") == 0)
do_size_property (node, decl, &node->width);
do_size_property (node, decl, &width);
else if (strcmp (property_name, "height") == 0)
do_size_property (node, decl, &height);
else if (strcmp (property_name, "-st-natural-width") == 0)
do_size_property (node, decl, &node->width);
else if (strcmp (property_name, "-st-natural-height") == 0)
do_size_property (node, decl, &node->height);
else if (strcmp (property_name, "min-width") == 0)
do_size_property (node, decl, &node->min_width);
@ -1603,29 +1705,43 @@ _st_theme_node_ensure_geometry (StThemeNode *node)
do_size_property (node, decl, &node->max_height);
}
if (node->width != -1)
/*
* Setting width sets max-width, min-width and -st-natural-width,
* unless one of them is set individually.
* Setting min-width sets natural width too, so that the minimum
* width reported by get_preferred_width() is always not greater
* than the natural width.
* The natural width in node->width is actually a lower bound, the
* actor is allowed to request something greater than that, but
* not greater than max-width.
* We don't need to clamp node->width to be less than max_width,
* that's done by adjust_preferred_width.
*/
if (width != -1)
{
if (node->width == -1)
node->width = width;
if (node->min_width == -1)
node->min_width = node->width;
else if (node->width < node->min_width)
node->width = node->min_width;
node->min_width = width;
if (node->max_width == -1)
node->max_width = node->width;
else if (node->width > node->max_width)
node->width = node->max_width;
node->max_width = width;
}
if (node->height != -1)
if (node->width < node->min_width)
node->width = node->min_width;
if (height != -1)
{
if (node->height == -1)
node->height = height;
if (node->min_height == -1)
node->min_height = node->height;
else if (node->height < node->min_height)
node->height = node->min_height;
node->min_height = height;
if (node->max_height == -1)
node->max_height = node->height;
else if (node->height > node->max_height)
node->height = node->max_height;
node->max_height = height;
}
if (node->height < node->min_height)
node->height = node->min_height;
}
int
@ -3425,7 +3541,7 @@ st_theme_node_adjust_preferred_width (StThemeNode *node,
if (natural_width_p)
{
if (node->width != -1)
*natural_width_p = node->width;
*natural_width_p = MAX (*natural_width_p, node->width);
if (node->max_width != -1)
*natural_width_p = MIN (*natural_width_p, node->max_width);
*natural_width_p += width_inc;
@ -3491,7 +3607,7 @@ st_theme_node_adjust_preferred_height (StThemeNode *node,
if (natural_height_p)
{
if (node->height != -1)
*natural_height_p = node->height;
*natural_height_p = MAX (*natural_height_p, node->height);
if (node->max_height != -1)
*natural_height_p = MIN (*natural_height_p, node->max_height);
*natural_height_p += height_inc;

View File

@ -142,6 +142,10 @@ gboolean st_theme_node_lookup_shadow (StThemeNode *node,
const char *property_name,
gboolean inherit,
StShadow **shadow);
gboolean st_theme_node_lookup_url (StThemeNode *node,
const char *property_name,
gboolean inherit,
char **value);
/* Easier-to-use variants of the above, for application-level use */
void st_theme_node_get_color (StThemeNode *node,
@ -153,6 +157,8 @@ gdouble st_theme_node_get_length (StThemeNode *node,
const char *property_name);
StShadow *st_theme_node_get_shadow (StThemeNode *node,
const char *property_name);
char *st_theme_node_get_url (StThemeNode *node,
const char *property_name);
/* Specific getters for particular properties: cached
*/

View File

@ -48,7 +48,7 @@ on_stage_realized (ClutterActor *stage,
{
recorder = shell_recorder_new (CLUTTER_STAGE (stage));
shell_recorder_set_file_template (recorder, "test-recorder.webm");
shell_recorder_record (recorder);
shell_recorder_record (recorder, NULL);
}
int main (int argc, char **argv)