Compare commits

...

379 Commits

Author SHA1 Message Date
d6c3868a7c Bump version to 3.0.0 2011-04-04 17:29:04 -04:00
a73f02ac23 Add NEWS file with 3.0 contributors 2011-04-04 17:23:58 -04:00
7e9594456b Require and build against Mutter 3.0 2011-04-04 17:21:16 -04:00
d25418ba04 popup-sub-menu: Adjust scrollbar style
Slightly adjust the style, so that scrollbars in submenus look
slightly less disconnected from the scrolled content.

https://bugzilla.gnome.org/show_bug.cgi?id=646001
2011-04-04 15:54:26 -04:00
a7df1a3d77 popup-menu: Tweak submenu style
Tone down the background color and use an inset shadow to give the
subsection some depth.

Expander menu item is always highlighted when open.

https://bugzilla.gnome.org/show_bug.cgi?id=646001
2011-04-04 15:53:12 -04:00
50951d15ea popupMenu: make submenus scrollable if needed
Right now, the network menu will overflow the screen if More...
is selected with many access points. As a short-term workaround
for this, add a scrollbar for submenus of panel dropdown menus
if they would cause the toplevel menu to overflow the screen.

- Put the actors in a PopupSubMenu in a StScrollView so we get
  a scrollbar if the allocated space is smaller than the height
  of the menu. Expand animation is turned off in the scrolled case
  to avoid weirdness.
- When we pop up a panel menu, set a max-height style property
  on the panel menu to limit it to the height of the screen.
- Hack event handling while the scrollbar is dragged to make
  the scrollbar work properly.

https://bugzilla.gnome.org/show_bug.cgi?id=646001
2011-04-04 15:46:46 -04:00
30076884ae Updated Latvian translation. 2011-04-04 19:57:01 +03:00
1eff22a90b Updated Japanese translation 2011-04-04 23:17:08 +09:00
41bdbc203d Updated Traditional Chinese translation(Hong Kong and Taiwan) 2011-04-04 22:08:33 +08:00
7932585656 network: fix alignment of secure vs insecure wireless icons
Since the icon area is end-aligned, the signal strength icon for
insecure networks was ending up aligned with the lock icon for secure
networks. Fix that by always including a _secureIcon, but having it be
blank for the insecure networks.

https://bugzilla.gnome.org/show_bug.cgi?id=646121
2011-04-04 09:30:53 -04:00
68bf4e7b70 Updated Japanese translation 2011-04-04 22:28:24 +09:00
92f09a60f6 Add shell_get_file_contents_utf8_sync(), use it instead of gio temporarily
Adding correct annotations to Gio.File.load_contents revealed that gjs
doesn't actually support array+length combinations.  For 3.0 this would
be invasive to fix, so add a method to ShellGlobal which does what
we need.

https://bugzilla.gnome.org/show_bug.cgi?id=646333
2011-04-04 09:08:33 -04:00
d19f2bb6d2 Updated Traditional Chinese translation(Hong Kong and Taiwan) 2011-04-04 20:55:10 +08:00
b06dce5bf8 Updated Japanese translation 2011-04-04 21:31:01 +09:00
82e2ab89c5 Fix expand animation for submenus
Figuring out the size of an unmapped actor is not completely
reliable because styles aren't fully assigned until an actor
is mapped. So show the submenu before computing the size we
want to tween to.

https://bugzilla.gnome.org/show_bug.cgi?id=645949
2011-04-04 08:23:37 -04:00
db198b183c New Bengali translation 2011-04-04 16:37:51 +06:00
90bab650e2 Update Czech translation 2011-04-04 04:19:53 +02:00
fa1cc556f9 Updated Dutch translation by Wouter Bolsterlee 2011-04-04 01:12:51 +02:00
69b23b0e48 [l10n]Fixes on Catalan translation 2011-04-03 23:19:44 +02:00
af69945e5b end-session-dialog: Show default icon if user icon is unset
If the user has not configured a user icon, the logout dialog will
display an empty rectangle. Show a default picture instead.

https://bugzilla.gnome.org/show_bug.cgi?id=646032
2011-04-03 22:48:37 +02:00
f36f7644c8 [l10n] Updated German translation, umlauts fixed 2011-04-03 21:08:58 +02:00
20f1457d15 NetworkStatus: ignore invalid and unsupported connection types
Some connection types (like wimax) are not supported by the menu, and
should be ignored instead of throwing exceptions. Also, NetworkManager
had a bug that sent connections with invalid settings. This should not
happen, but in case it does, we will not blow up, but just log a warning
and continue silently.

https://bugzilla.gnome.org/show_bug.cgi?id=646355
2011-04-03 14:24:58 +02:00
38bcd52065 NetworkMenu: keep the connection list visible when connecting...
When a device is connecting, we can continue showing available
connections and access points, as well as the active one with the dot.
(Hiding was a remnant of when the device status was on a different
menu item than the title)

https://bugzilla.gnome.org/show_bug.cgi?id=646381
2011-04-03 14:22:27 +02:00
38219fec99 Updated Italian translation 2011-04-03 10:35:14 +02:00
6c3300bc2f network: fix logic bug in checking whether to activate or deactive
A cosmetic change recommended in review of the patch to fix the
VPN Connections switch ended up introducing a logic error that
made the switch not work properly. Fix.

https://bugzilla.gnome.org/show_bug.cgi?id=646380
2011-04-02 21:58:45 -04:00
d1a110d4ca NetworkMenu: fix VPN connection state
It was always reporting true, even if disconnected. At the same time,
add a signal that is emitted when state changes and update the UI
accordingly.
In the future (with another libnm-glib API break) we should use the
NMVPNConnection object to track the connection state, so that we can
show if we're connecting or we need authentication.

https://bugzilla.gnome.org/show_bug.cgi?id=646380
2011-04-02 20:40:12 +02:00
5b61485143 NetworkMenu: fix parameters to _findConnection
NMDevice._findConnection expects an uuid as parameter, but
checkConnection was passing a NMConnection object. This caused
exists to be always false, thus the connection was added again every
time the 'updated' signal was emitted.

https://bugzilla.gnome.org/show_bug.cgi?id=645702
2011-04-02 20:35:46 +02:00
6b95a357eb gnome-shell.css: fix multiple calendar layout issues
Specifying absolute pixel widths for fields breaks under both font
scaling and translation.

Change all px lengths in the calendar to corresponding pt values, to
fix the layout under larger/smaller font sizes.

Change all "width" specifications to "min-width", for languages with
longer translations. This completely breaks the layout if any field
exceeds the min-width of its column, but that is preferable to
ellipsizing. Needs to be redone using St.Table or the like for 3.0.1.

Also add padding to the right of the calendar popup to match the
padding on the left, since the lack of it becomes more obvious in
layouts where the actual width exceeds the minimum width.

https://bugzilla.gnome.org/show_bug.cgi?id=645693
2011-04-02 07:31:55 -04:00
60bdc726ce Updated Korean translation 2011-04-02 19:58:17 +09:00
429f809b71 search-display: Fix getDragActorSource()/getDragActor()
The 'icon' property in search results' meta info has been replaced
by a 'createIcon' property, adjust to this change.

https://bugzilla.gnome.org/show_bug.cgi?id=645990
2011-04-02 11:13:45 +02:00
9396d736f2 notificationDaemon: only ignore 'chat' and 'presence' notifications from Empathy (#645932) 2011-04-02 00:05:10 +02:00
cc9b812466 Updated Lithuanian translation. 2011-04-01 22:30:15 +02:00
5b0f2dc0cf [jhbuild] Clutter moved to git.gnome.org
Use this new git repository.
2011-04-01 17:21:52 +02:00
7ffea1606d [jhbuild] Build libxklavier 5.1 from tarball
We had to get it from CVS waiting for 5.1 to be released,
but now we can use the same tarball as the GNOME moduleset.

Stop installing CVS since libxklavier was the only module using it.

https://bugzilla.gnome.org/show_bug.cgi?id=646416
2011-04-01 15:38:30 +02:00
342bc1e72d [jhbuild] glib-networking depends on gsettings-desktop-schemas
This missing dependency is only noticeable when you remove the
whole $prefix and build everything from scratch, since schemas
are already present in existing installs.

https://bugzilla.gnome.org/show_bug.cgi?id=646416
2011-04-01 15:38:30 +02:00
0127eb5892 Updated Gujarati Translations 2011-04-01 17:23:55 +05:30
39023269d6 Updated Hungarian translation 2011-04-01 13:44:58 +02:00
35e3cd97fe hindi updated 2011-04-01 14:52:29 +05:30
a63a171ec3 Updated Norwegian bokmål translation 2011-04-01 09:45:14 +02:00
7f1763f32f Updated Basque language 2011-04-01 09:43:36 +02:00
2d6326815c Added Basque language 2011-04-01 09:27:53 +02:00
ee4c8cca8c Updated Tamil translation 2011-04-01 12:17:10 +05:30
2104e0f411 build: Add gconf dependency to libgweather 2011-03-31 20:04:33 +02:00
84e69f57ea Updated Serbian translation 2011-03-31 11:07:58 +02:00
aba43125f3 [l10n] Updated Estonian translation 2011-03-31 09:37:56 +03:00
de5fc58fcb Updated Danish translation 2011-03-30 22:40:47 +02:00
4831dde3fb Updated translation for Afrikaans (af) 2011-03-30 19:10:32 +02:00
b5cbfc5e7a Updated British English translation 2011-03-30 14:56:02 +01:00
1124d164ec Updated Japanese translation. 2011-03-30 21:49:55 +09:00
9d9391bd95 Updated Portuguese translation 2011-03-29 23:53:24 +01:00
0121d74b92 Update translation for Afrikaans (af) 2011-03-29 23:41:13 +02:00
f81af32963 Update Simplified Chinese translation. 2011-03-30 00:38:46 +08:00
8f5198821e Bump version to 2.91.93 2011-03-28 23:19:36 -04:00
96c2b5ef32 MessageTray: don't forward click on sources with notifications
When a source has an associated tray icon, we would forward all clicks
to the X11 window, meaning that the summary notification could not
be opened. Instead, restore normal event flow for clicks, when the
source has notifications in the queue.

https://bugzilla.gnome.org/show_bug.cgi?id=645753
2011-03-28 23:05:56 -04:00
c5eb324cf0 Fix problem with app menu showing when leaving overview
Since the opacity of the application menu is controlled by
it's _targetIsCurrent flag, we need to respect that when entering
and leaving the overview.

https://bugzilla.gnome.org/show_bug.cgi?id=645734
2011-03-28 23:05:55 -04:00
f117d9bfd3 telepathyClient: give a separate style to TpLogger messages
Sometimes, log messages are hard to differentiate from normal,
unread recent messages, so give a separate style to messages
retrieved from the TelepathyLogger service.

https://bugzilla.gnome.org/show_bug.cgi?id=645609
2011-03-28 23:05:55 -04:00
b470736246 telepathyClient: Do a better job with old chat timestamps
If we have a date that's not within the last week, it's really
confusing to display it as "Sent at 9:23 on Tuesday". Steal
some strings from calendar.js for displaying older dates to
avoid a string-freeze break.

https://bugzilla.gnome.org/show_bug.cgi?id=645609
2011-03-28 23:05:55 -04:00
b2a2a00cd8 telepathyClient: insert a timestamp between log messages and pending messages
This will give a visual break, giving a bit of clarity when a message
is received from a new contact.

https://bugzilla.gnome.org/show_bug.cgi?id=645609
2011-03-28 23:05:55 -04:00
659130856c Hide summary box pointer without animating if it is empty
This ensures that we don't show a small black blob fading away
when the user clicks on the notification and it is removed.

Set HIDING state right away in _hideSummaryBoxPointer() so that
it is only called once. Update this._pointerInTray when the tray
is unlocked, so that we are not dependent on escapeTray() being
triggered by 'done-displaying-content' signal.

https://bugzilla.gnome.org/show_bug.cgi?id=645697
2011-03-28 22:40:38 -04:00
9a21008177 Make sure notification has all the content when it is expanded
Use Meta.later_add() with BEFORE_REDRAW rather than Mainloop.idle_add()
to add the banner body so that the notification body is reliably added
after the first frame is drawn. This is important for notifications that
are expanded right away, such as the summary notifications that
were not shown as banners because the user was in the Busy mode or was
interacting with the summary. Otherwise, these notifications were sometimes
shown with an ellipsized banner and were only getting full content when
they were done animating.

Only add expanded content and signal the change once. Previously, we
used to signal the change numerous times and processing this signal was
holding up processing other things, such as the user moving the mouse
away from the notification so that the notification collapses.

https://bugzilla.gnome.org/show_bug.cgi?id=645719
2011-03-28 22:40:17 -04:00
8f58bc5b19 [l10n]Updated Catalan translation 2011-03-29 00:29:34 +02:00
3a0220a875 Updated Danish translation 2011-03-28 23:40:46 +02:00
9f438d0ec6 Panel: sync primary hotcorner hover with Activities button
Since the hotcorner is a reactive actor, and it is over the Activities
button, hovering on it results in a leave-event for the button.
This is not noticeable when opening the overview, as the button is
correctly prelighted, but it is when closing, if you keep the mouse
near the hot corner, as the button is kept in normal state, despite
the mouse being over it.

https://bugzilla.gnome.org/show_bug.cgi?id=645751
2011-03-28 22:15:04 +02:00
22c22e0d7a boxPointer: Use the anchor point to fix problems with allocations
Instead of setting the x/y position of the box pointer, which results
in a long change of workarounds for limitations of the Clutter
layout system, set the anchor point instead, which takes the
positioning out of the layout system.

The position is computed as a combination of the position computed
from the allocation and the box pointer's size, and an offset that
we tween when animating showing and hiding the box pointer.

https://bugzilla.gnome.org/show_bug.cgi?id=645744
2011-03-28 15:27:10 -04:00
bc48bd5f4a boxPointer: use shell_util_get_transformed_allocation()
Using ClutterActor.get_transformed_size() can produce bugs if we
happen to position the box pointer when the source actor has a
relayout queued. Use our newly added reliable utility function
instead.

https://bugzilla.gnome.org/show_bug.cgi?id=645744
2011-03-28 15:27:10 -04:00
905c4bb4a5 Add shell_util_get_transformed_allocation()
Add a function that gets the current allocation of an actor
transformed into stage coordinates. This avoids a misfeature of
clutter_actor_get_transformed_size() where when a size request is
queued (even if it won't eventually change the size), the returned
value is the transformed size request rather than the last allocation.

https://bugzilla.gnome.org/show_bug.cgi?id=645744
2011-03-28 15:27:10 -04:00
94bfaf6896 Updated Polish translation 2011-03-28 20:22:07 +02:00
25b743b03c message-tray: Fix dismissing notifications
Commit 31b12635d1 fixed links in notifications again, but blocked
clicks on normal labels getting through to the notification. Fix
this, so that both links and dismissing notifications work again.

https://bugzilla.gnome.org/show_bug.cgi?id=645839
2011-03-28 19:46:11 +02:00
8da4e6ce5e Updated Indonesian translation 2011-03-28 23:16:23 +07:00
cedd297ba6 hindi added and translated and lingua upodated 2011-03-28 14:18:59 +05:30
b6e0c5e0ea Added mr to LINGUAS
Added Marathi Translations
2011-03-28 10:56:54 +05:30
bf3f7d0dc4 Update Simplified Chinese translation. 2011-03-28 12:53:51 +08:00
7b42a84422 Updated Latvian translation. 2011-03-28 01:10:16 +03:00
8b7c065706 Updated Brazilian Portuguese translation. 2011-03-27 17:45:38 -04:00
c6a4b3d9b0 Updated French translation 2011-03-27 20:46:53 +02:00
0ef32f2b8d Updated Galician translations 2011-03-27 20:33:17 +02:00
f7fdcb7bf1 Added UG translation 2011-03-27 19:56:53 +02:00
848d36ff39 Uploaded Ukranian 2011-03-27 18:27:33 +03:00
07ce3e7cdf [l10n] Updated German translation 2011-03-27 16:42:46 +02:00
cfec145ae2 Use the description for GNOME shell instead of Mutter 2011-03-27 15:55:37 +02:00
641d7a4ea4 polkit: Add translator comment
Add a translator comment for the "Sorry, that didn't work. Please try
again." string, as suggested by several people; this should help
translators what "that" refers to.
2011-03-27 10:41:54 +05:30
da0650fda6 Updated Bulgarian translation 2011-03-27 08:03:48 +03:00
6724133927 update tranlation for Punjabi by A S Alam 2011-03-27 10:03:13 +05:30
c0ded8ef5f Updated Russian translation 2011-03-26 23:41:48 +03:00
7382de51dc Updated Dutch translation by Wouter Bolsterlee 2011-03-26 20:43:15 +01:00
96a1121e6b Update Simplified Chinese translation. 2011-03-27 03:39:01 +08:00
323bbb0692 Updated Slovenian translation 2011-03-26 20:31:54 +01:00
59e235623a Updated Arabic translation 2011-03-26 17:30:39 +02:00
40dc85d975 Add description to DOAP file 2011-03-26 13:24:44 +01:00
6006a42cbb Update Simplified Chinese translation. 2011-03-26 19:08:04 +08:00
c2e0278bd9 Updated Vietnamese translation 2011-03-26 13:58:45 +07:00
c1ba920c86 BluetoothStatus: depend more on libgnome-bluetooth-applet
Ensure that a dependency is generated even when using --as-needed,
by adding a fake function that calls into the library.

https://bugzilla.gnome.org/show_bug.cgi?id=639324

Was accidentally removed, as part of the switch to building
a gnome-shell binary, reapplying the original patch. - Owen

https://bugzilla.gnome.org/show_bug.cgi?id=645596
2011-03-25 21:39:22 -04:00
7b997e9374 statusIconDispatcher: fix trailing comma
Fix a trailing comma in object initializer introduced in
the last patch.
2011-03-25 21:24:42 -04:00
dfb97c1ed7 statusIconDispatcher: add ibus-ui-gtk to standard implementations
As a stop-gap measure until we have a native input method tray icon,
add ibus-ui-gtk to STANDARD_TRAY_ICON_IMPLEMENTATIONS so that the IBus
status icon shows up in the status area rather than in the message
tray. The message tray location doesn't work for the function of
showing the current input method when switching between windows or
changing input methods.

https://bugzilla.gnome.org/show_bug.cgi?id=641531
2011-03-25 21:20:36 -04:00
fc49fb2f4f Improve checks for XFixes pointer barriers
Instead of checking on version (which doesn't work when protocol
and libraries are out of sync), just check for the functions we
need.

https://bugzilla.gnome.org/show_bug.cgi?id=645630
2011-03-25 21:13:57 -04:00
63078fba5b NetworkStatus: Adapt to nm_client_activate_connection api change
It now takes a connection directly instead of the object path associated
with a connection.
2011-03-25 20:38:55 -04:00
b0176546c2 NetworkStatus: fix vpn indicator
It looks like a part of the code wasn't updated to reflect
a variable name change.
2011-03-25 20:37:29 -04:00
a234ba91a4 Updated Hebrew translation. 2011-03-26 00:56:07 +02:00
526d11809f network: add security icons to WEP/WPA wireless networks
https://bugzilla.gnome.org/show_bug.cgi?id=645647
2011-03-25 18:55:40 -04:00
3bbdecc6b3 popupMenu: round spacing to an integer
StThemeNode.get_length() doesn't necessarily return an integer pixel
value, and our code produces non-integer positions in that case. So
round the spacing.

https://bugzilla.gnome.org/show_bug.cgi?id=645647
2011-03-25 18:55:40 -04:00
00fc4a2eb7 gnome-shell.css: fix padding/alignment of menu toggle switches
We do not support scaling background-images, so setting the
toggle-switch size to anything other than the natural size of the
image just results in it getting padding, which makes it look
improperly aligned.

https://bugzilla.gnome.org/show_bug.cgi?id=645647
2011-03-25 18:55:06 -04:00
924b31233b popupMenu: fix relayout after submenu open/close
Because of the GtkSizeGroup-like trickiness we're doing with
PopupMenuItems, we need to force Clutter to discard its cached size
requests for them any time the menu itself changes size.

https://bugzilla.gnome.org/show_bug.cgi?id=645647
2011-03-25 18:55:06 -04:00
475161f716 boxpointer: reposition after a size change
If the BoxPointer changes size (eg, when opening the "More" section of
the network menu), reposition it to make sure it's still aligned
correctly and still completely on-screen.

This is not the right fix for this problem (and causes the menu to be
drawn in the wrong position for one frame). The right fix would
involve a ClutterConstraint, but that would be more invasive, and can
happen post-3.0.0.

https://bugzilla.gnome.org/show_bug.cgi?id=645647
2011-03-25 18:55:06 -04:00
31b12635d1 messageTray: fix clicking on links again
The change to make Notification an StButton (06d2c0af, bug 642978)
broke links, because the link actor would ignore the
button-press-event, allowing the notification actor to receive it and
get a pointer grab, and so the link actor would never see the
button-release-event. Fix that by accepting and discarding the
button-press-event.

https://bugzilla.gnome.org/show_bug.cgi?id=645613
2011-03-25 18:49:27 -04:00
d2de0865bf telepathyClient: fix duplicate copy of first message in a chat
The chat-history-fill-in code had logic to avoid appending two
messages when a message appeared in both the log and the pending
messages. But it wasn't working because of an incorrect object field
name.

Additionally, the code was previously keeping the copy of the message
from the log, and suppressing the copy from pending. But that meant
that once the previous bug was fixed, it would think it had only shown
old messages, and so it would create a source but not notify it. So
fix it to suppress the log message and show the pending message.

https://bugzilla.gnome.org/show_bug.cgi?id=645612
2011-03-25 18:47:01 -04:00
9b4dbd0e83 Updated Swedish translation 2011-03-25 22:15:24 +01:00
4577cd7497 Updated Spanish translation 2011-03-25 21:36:39 +01:00
4ebf07c725 NetworkStatus: hide the only connection for wired devices
For wired devices (actually, ethernet devices), hide the connection
list when there is only one connection (either automatic or stored).
The device can be operated with the associated switch.
2011-03-25 20:58:37 +01:00
da852a94bd NetworkStatus: show "firmware missing" when firmware is not available
Since device state Unavailable is generic and has substates, instead
of using an hack for carrier, introduce some code that checks both
for carrier and firmware-missing when in that device state, and updates
the UI accordingly.
2011-03-25 20:58:37 +01:00
9b51ff7241 Updated Spanish translation 2011-03-25 19:11:59 +01:00
aa0137e7ce Use /org/gnome as starting path for schemas 2011-03-25 12:53:03 -04:00
3889ae7627 Updated Brazilian Portuguese translation 2011-03-25 11:54:56 -03:00
c97a8602a1 ShellAppSystem: Only search gnomecc.menu for preferences
settings.menu was removed in gnome-menus commit
b68bcd27f44ce2c494f6e3cd9695890b9c02af04; gnomecc.menu is the intended
replacement.

(On Red Hat Linux derived systems, settings.menu continues to exist)

https://bugzilla.gnome.org/show_bug.cgi?id=645063
2011-03-25 10:35:38 -04:00
affc9f9058 Updated Korean translation 2011-03-25 21:57:01 +09:00
1582819259 update tranlation for Punjabi by A S Alam 2011-03-25 08:17:30 +05:30
05e8ae33dc Uploaded Ukranian 2011-03-25 00:19:36 +02:00
219d5fb66b Updated Swedish translation 2011-03-24 23:04:46 +01:00
92ff57c0ea Updated Swedish translation 2011-03-24 23:04:46 +01:00
5233429b6f Updated Italian translation 2011-03-24 22:58:22 +01:00
475cf7179e Add gettext macro to message to enable translation. 2011-03-25 02:16:10 +08:00
f608c65962 Updated Vietnamese translation 2011-03-25 00:31:36 +07:00
6cf0a35b4c po/vi.po: import from damned lies 2011-03-25 00:21:48 +07:00
bac006ebc1 Updated French translation 2011-03-24 13:56:49 +01:00
be5f74e37f Updated French Translation
Contributed by :
Cyril Arnaud, Frédéric Peters, Bruno Brouard
2011-03-24 13:54:58 +01:00
5c29bff23d Updated Galician translations 2011-03-24 09:51:53 +01:00
68968d2b40 Update Simplified Chinese translation. 2011-03-24 16:09:59 +08:00
038f4e8bde Updated Norwegian bokmål translation 2011-03-24 09:03:20 +01:00
f8874fec0f Add file to POTFILES.in 2011-03-24 09:03:19 +01:00
ee6693e6e3 Don't translate empty string 2011-03-24 09:03:19 +01:00
bfba97647e Mark strings for translation in the right way 2011-03-24 09:03:19 +01:00
82d5194afe Updated Swedish translation 2011-03-24 08:04:06 +01:00
bf449b9f61 Updated Italian translation 2011-03-24 01:13:58 +01:00
9530048867 NotificationDaemon: fix typo in dealing with TrayIcon
Source was failing to determine if it was a tray icon, destroying
itself when the associated application was closed.

https://bugzilla.gnome.org/show_bug.cgi?id=645625
2011-03-23 22:58:28 +01:00
090d54516e main: Allow replacement of org.gnome.Shell name
This was an oversight in the previous commit; if we don't
do this, then we just can't --replace.

https://bugzilla.gnome.org/show_bug.cgi?id=645593
2011-03-23 17:23:47 -04:00
c91b716a63 main: Use --replace semantics for org.gnome.Shell DBus name
Previously (because I suck) we were ignoring the return value of
RequestName, and so we'd totally ignore the fact that we failed
to acquire the DBus name.

Make this consistent by using meta_get_replace_current_wm() and
if we're in --replace, actually replace immediately.

https://bugzilla.gnome.org/show_bug.cgi?id=645593
2011-03-23 16:13:51 -04:00
80cdb0dc4e Updated Spanish translation 2011-03-23 20:36:13 +01:00
aaa6b54673 Updated Spanish translation 2011-03-23 18:49:19 +01:00
a3b61ec8c8 Complete Simplified Chinese translation. 2011-03-23 23:58:48 +08:00
6c41d6b66a Updated Bengali India Translation 2011-03-23 20:58:20 +05:30
1838ab1412 Uploaded Ukranian 2011-03-23 16:10:44 +02:00
72e8d38586 Update Simplified Chinese translation. 2011-03-23 21:39:20 +08:00
9259e2221d Added Bengali India file, translation to start 2011-03-23 12:36:36 +05:30
42ea979b06 Added Bengali India to the list of languages 2011-03-23 12:35:13 +05:30
46824adb97 Added Bengali India file, translation to start 2011-03-23 12:35:00 +05:30
3758f4952e Bump version to 2.91.92 2011-03-22 18:52:39 -04:00
8fdbbe78f4 MessageTray: keep notification focused through update()
If a notification was updated while one of its widgets was focused,
it would lose the grab when that widget was destroyed. Fix that by
moving the focus to a safe place before destroying the old widgets.

https://bugzilla.gnome.org/show_bug.cgi?id=643687
2011-03-22 18:20:33 -04:00
5a86b0f9e3 MessageTray: never show summary and a new notification at the same time
We want to minimize focus stealing from the user. If a non-urgent notification
comes in while the user is interacting with the tray, we add it to the tray
and only show it after the user is done interacting with the tray. If an
urgent notification comes in while the user is interacting with the tray,
we hide the tray and show the urgent notification.

https://bugzilla.gnome.org/show_bug.cgi?id=636838
2011-03-22 18:18:11 -04:00
604722b775 MessageTray: use single scrollbar for summary notification stacks
We want to allow the user to scroll through all notifications from
source by using a single scrollbar. We suppress the individual
scrollbars inside the notifications.

As one exception, we keep the original scrollbar for chat notifications
because it has a distinct look, ending above the text entry box.

https://bugzilla.gnome.org/show_bug.cgi?id=611611
2011-03-22 18:18:11 -04:00
812812d817 MessageTray: show multiple notifications per source
Add an ability to show multple notifications per source, so that
the user doesn't miss seeing any notifications.

https://bugzilla.gnome.org/show_bug.cgi?id=611611
2011-03-22 18:18:11 -04:00
f07fe0a8e7 Updated Slovenian translation 2011-03-22 22:05:03 +01:00
1d7cef5bfe workspace-thumbnails: Add a subtle border to indicator
As windows' content tends to use mostly light colors/white, the
thumbnail indicator is hard to spot for workspaces with maximized
windows on it. To improve its visibility in these cases, add a
subtle dark border in addition to the white outline.
2011-03-22 21:38:56 +01:00
34b12e6a6a Updated Galician translations 2011-03-22 21:18:27 +01:00
eb6ba563bd Updated Spanish translation 2011-03-22 20:58:02 +01:00
281b2e9b0e St: Fix blur radius computation to correspond to current CSS draft
The next draft of the CSS Backgrounds and Borders module will actually
define when the blur radius means. Fix our code to use that definition
(2 * standard deviation) rather than using the 1.9 * that we extracted
from what Mozilla was doing.

https://bugzilla.gnome.org/show_bug.cgi?id=632506
2011-03-22 15:53:49 -04:00
5437629e89 Updated Spanish translation 2011-03-22 20:33:20 +01:00
e1df2f8ff5 Updated Arabic translation 2011-03-22 20:59:20 +02:00
12fad6f05f Fix ripple animation for RTL locales
The animation was invisible because it was going out of screen, also
add a mirrored version of the image to the theme.

https://bugzilla.gnome.org/show_bug.cgi?id=584662
2011-03-22 19:35:21 +01:00
4208078750 st-texture-cache: Fix stretched images
Some functions in StTextureCache enforce square ClutterTextures,
even in cases where the underlying CoglTexture has a different
width:height ratio.
Add padding in those cases to keep the resulting image from being
stretched.

https://bugzilla.gnome.org/show_bug.cgi?id=643866
2011-03-22 19:35:21 +01:00
dba02f8f08 endSessionDialog: make shutdown dialog work like latest mock ups
This commit adds a restart button to the shutdown dialog and changes
the terminology from Shut Down to Power Off.  This brings things in
line with the latest mockups here:

http://live.gnome.org/GnomeShell/Design/Whiteboards/SystemStopRestart

https://bugzilla.gnome.org/show_bug.cgi?id=641375
2011-03-22 14:22:55 -04:00
35e410fe96 endSessionDialog: clean up appearance
This commit lines up the app list with the description,
adds spacing between controls of the dialog, and increases
the wrap width of the text.

https://bugzilla.gnome.org/show_bug.cgi?id=641375
2011-03-22 14:22:55 -04:00
7dcd2313d8 endSessionDialog: hide app list when there are no apps
We don't want its padding to show up when it shouldn't
be visible.

https://bugzilla.gnome.org/show_bug.cgi?id=641375
2011-03-22 14:22:55 -04:00
40750f2dc6 Updated Russian translation 2011-03-22 21:18:55 +03:00
85c007431b endSessionDialog: emit Closed signal when dialog disappears
The session manager needs to keep its internal state for the
dialog in sync with ours.

https://bugzilla.gnome.org/show_bug.cgi?id=645485
2011-03-22 14:15:00 -04:00
cbd187369e PopupMenu: invert the menu when in RTL locales
Change the way menu items allocate their contents to take text
direction into account, so they're fully reversed in RTL locales,
and St.Align.START / END are respected.

https://bugzilla.gnome.org/show_bug.cgi?id=645524
2011-03-22 18:26:18 +01:00
d20d89a0b9 endSessionDialog: prelight inhibiting app items
This commit makes it more obvious that apps in the end session
dialog inhibitors list are clickable.  It does this by rendering
the text for the apps in a low intensity white under normal
conditions, but a high intesnity white on hover.

https://bugzilla.gnome.org/show_bug.cgi?id=645491
2011-03-22 13:04:41 -04:00
80eb37ef60 Constrain tooltips to monitors
Use st_tooltip_set_constrain_func() to set a function that constrains
tooltips to be on the same monitor as the original tip area.

https://bugzilla.gnome.org/show_bug.cgi?id=645547
2011-03-22 12:38:26 -04:00
d19cdc206b StTooltip: Add the ability to set a hook to constrain the tooltip
If, for example, the stage is divided into multiple monitors, we
might want to constrain tooltips so they don't cross monitor boundaries.
Add a function to set a per-stage callback to constrain tooltips.

https://bugzilla.gnome.org/show_bug.cgi?id=645547
2011-03-22 12:38:26 -04:00
02078255ea appDisplay: show hover and tooltip while the menu is up
While we have menu for an app icon open, we want to show the prelight
for the item instead of removing the prelight when the user mouses
away from the item and into the menu, and if there's a tooltip
(like for the dash), we want to show the tooltip immediately when
the menu is popped up.

https://bugzilla.gnome.org/show_bug.cgi?id=642871
2011-03-22 12:38:25 -04:00
bea2d40f79 popupMenu: Add the ability to block sending events to the source actor
It can be useful to avoid sending enter/leave events to the source actor
of a menu: this would be the case when the source actor isn't a menu item
that should participate in menu navigation but rather is some object
(like an app icon) that we want to indicate corresponds to the menu.

https://bugzilla.gnome.org/show_bug.cgi?id=642871
2011-03-22 12:38:25 -04:00
a5d3259cfe StTooltip: use a timeout like GtkTooltip
Instead of showing tooltips immediately on hover, wait until a timeout
after the last motion (timeout is given by the gtk-tooltip-timeout
GtkSetting.)

https://bugzilla.gnome.org/show_bug.cgi?id=642871
2011-03-22 12:38:25 -04:00
4a93ce703e dash: Show tooltips on hover
As dash items no longer show application names, display names as
tooltips on hover.

https://bugzilla.gnome.org/show_bug.cgi?id=642871
2011-03-22 12:37:14 -04:00
661ea906d9 css: Adjust tooltip style
Update the tooltip style to match current mockups.

https://bugzilla.gnome.org/show_bug.cgi?id=642871
2011-03-22 12:37:14 -04:00
b382b4cb94 build: Bump vala to 0.11.7 to fix dep. on dconf 2011-03-22 11:07:00 -05:00
087e86fb32 StTooltip: fix various warnings and use Clutter API correctly
Use ClutterContainer functions for adding the tooltip instead of
calling clutter_actor_set_parent behind the stage's back, and do
it inside st_widget_show_tooltip (which is a normal method) instead
of overriding st_tooltip_show, which is a vfunc and it is called
internally by Clutter, therefore it is limited in what it can safely
do.
Also, instead of positioning the tooltip with clutter_actor_set_position,
modify the anchor point when the associated widget moves, so that
only a redraw is queued.

https://bugzilla.gnome.org/show_bug.cgi?id=635100
2011-03-22 16:13:38 +01:00
afffa76c17 Make St aware of the UI group.
Inside the Shell, all the UI (including chrome, the overview, and
the actual windows) is not a child of the stage but of a special
ClutterGroup, which is cloned inside the magnifier.
Add function for setting this special actor so that actors added by
St are visible in the magnifier. Nothing yet uses this, but the
tooltip will soon.

https://bugzilla.gnome.org/show_bug.cgi?id=635100
2011-03-22 16:09:23 +01:00
69ca18f36b Updated Arabic translation 2011-03-22 15:04:15 +02:00
f84c62f0be Fix overview sizing when exiting via thumbnails
We need to update WorkspacesView._ZoomOut before calling
_updateWorkspacesGeometry() in show(), as otherwise the old
value is kept. This was a problem if we previously left the
overview zoomed out.
2011-03-22 12:50:14 +01:00
90c554ad42 Updated Traditional Chinese translation(Hong Kong and Taiwan) 2011-03-22 19:43:17 +08:00
e2cb6cc4da st-texture-cache: Request large thumbnails
As of commit 34ce17c4b3, search results use large icons, or thumbnails
when available. To keep the amount of upscaling for the latter as small
as possible, request a large thumbnail size.

https://bugzilla.gnome.org/show_bug.cgi?id=645493
2011-03-22 11:42:07 +01:00
02da366cc2 [l10n] Updated Estonian translation 2011-03-22 10:25:46 +02:00
54e3a54489 Transition the ShellApp state when ready.
shell_app_state_transition emits a signal, so invoke it only when
ready, or signal handlers will see an object which is in an invalid
state.

https://bugzilla.gnome.org/show_bug.cgi?id=632501
2011-03-21 22:42:25 -04:00
8798ec653d NotificationDaemon: don't notify for resident notifications when application is focused
The applications have to have a way of keeping resident notifications
updated without unnecessarily notifying the user with the information
the user is already seeing in the application window.

https://bugzilla.gnome.org/show_bug.cgi?id=630847
2011-03-21 21:58:29 -04:00
d1ffd3cf35 MessageTray: style summary sources
Make summary sources look more clickable and highlight them when selected.
Highlighting the fully expanded summary source when selected matches the
highlighting in the top bar items and teaches the user that any part of the
expanded summary source can be clicked.

Based on the initial patches by Florian Müllner and Jonathan Strander.

https://bugzilla.gnome.org/show_bug.cgi?id=644788
2011-03-21 21:50:27 -04:00
133b854f1b modalDialog: constrain container to the size of the stage
The lightbox will be sized to the size of its parent container,
so we need to make the parent container reliably the size of the
stage, instead of letting it be auto-sized to the size of its contents.

https://bugzilla.gnome.org/show_bug.cgi?id=644889
2011-03-21 21:18:37 -04:00
33125e78c8 Alt-F2: Avoid running programs multiple times
Returning true from the event handler seems to avoid getting
duplicate return events; these duplicate events likely are
getting generated by IBus.

https://bugzilla.gnome.org/show_bug.cgi?id=644509
2011-03-21 20:50:08 -04:00
4118bf1a5e Updated Italian translation 2011-03-22 01:36:58 +01:00
8282db456b Use the new meta_window_move_to_monitor function
https://bugzilla.gnome.org/show_bug.cgi?id=645032
2011-03-22 00:58:56 +01:00
7b5eacf671 Updated Galician translations 2011-03-22 00:53:01 +01:00
12bd374477 searchDisplay: don't create useless SearchResult's
average constructing time for 1 SearchResult is 3 ms.
It give > 400 result on query like 'a' (on my machine).
https://bugzilla.gnome.org/show_bug.cgi?id=645313
2011-03-22 02:50:32 +03:00
9ef4cc0ab9 iconGrid: remove unused variable in _computeLayout
https://bugzilla.gnome.org/show_bug.cgi?id=645313
2011-03-22 02:50:25 +03:00
528fc9bc47 XDND: Allow workspace switching using the thumbnails
Currently activating a window on a different workspace requires very
long drag distances, which is very inconvenient to use.

Fix that by allowing switching workspaces using the thumbnails which is
consistent with window and launcher dnd and much easier to use.

https://bugzilla.gnome.org/show_bug.cgi?id=643945
2011-03-22 00:05:17 +01:00
c58b8498b3 st: Add more error checking to shadow-related code
The additional error checks should catch quite some warnings (e.g.
when trying to create a shadow for a 0-width actor).
2011-03-21 23:25:42 +01:00
c81c564941 overview: Don't pick for every overlay
Don't do an individual hover fixup for every window overlay, instead
just use the new global.sync_hover() to fix up hovers once we have
finished showing the overview.

Based on a patch from Adel Gadllah <adel.gadllah@gmail.com>

https://bugzilla.gnome.org/show_bug.cgi?id=638613
2011-03-21 17:45:51 -04:00
b16de0e374 Fix workspaces accumulating on each restart.
Main._nWorkspacesChanged was racing with Main._checkWorkspaces.
If _checkWorkspaces won the race, _workspaces was uninitialized.
Because of this, _checkWorkspaces only noticed workspaces
with windows on them, leading it to believe the last workspace wasn't
empty, and added a new, empty workspace.

https://bugzilla.gnome.org/show_bug.cgi?id=645343
2011-03-21 17:45:00 -04:00
d38f41a459 dnd: If needed, destroy _dragActor in _cancelDrag
In the case where the original actor is destroyed, we don't
show a snap back animation, so we need to destroy drag actor
as we would do in _onAnimationComplete.

https://bugzilla.gnome.org/show_bug.cgi?id=640781
2011-03-21 17:39:42 -04:00
30346884fe Update terminology from "panel" to "top bar" when Ctrl+Alt+Tab is pressed.
This is the term recommended for use by the Documentation Team.
2011-03-21 17:17:27 -04:00
1518dc9b60 Add pointer barriers to panel and message tray
If you have XFixes 5 (and corresponding xserver support) then we
add barriers on the panel and in the message tray corner so that
its easy to reach the corners even when there are monitors to the
sides of the primary monitor.

https://bugzilla.gnome.org/show_bug.cgi?id=622655
2011-03-21 21:03:19 +01:00
fd3f2289c3 gnome-shell.desktop: Set autorestart flag
This is the last ditch 3.0 plan for error handling.
See https://bugzilla.gnome.org/show_bug.cgi?id=645251

https://bugzilla.gnome.org/show_bug.cgi?id=645451
2011-03-21 15:57:49 -04:00
22bfd4f7c3 notificationDaemon: handle trayicon clicks in the overview
If the user clicks a trayicon in the overview, drop out of the
overview before passing the click on to the icon. (We have to actually
wait for the overview animation to complete, in case the icon wants to
get a pointer grab, which it would not be able to do with the overview
active.)

https://bugzilla.gnome.org/show_bug.cgi?id=641853
2011-03-21 14:58:10 -04:00
2782011ce8 shell-global: try to resync the pointer state after grabs
If the pointer moves on or off the stage while another process has a
grab, we will lose track of it. One example of this is that if you use
a popup menu from a message tray trayicon, the tray will stay up after
the menu goes away, because the shell never saw the pointer leave it.

Add a new method shell_global_sync_pointer() that causes clutter to
recheck what actor is under the pointer and generate leave/enter
events if appropriate.

Of course, we can't actually tell for sure when another process has a
grab, so we need a heuristic of when to call this. Currently we call
it from Chrome._windowsRestacked(), which is not really the right
thing at all, but does fix the menu-from-trayicon case...

https://bugzilla.gnome.org/show_bug.cgi?id=630842
2011-03-21 14:56:53 -04:00
7f17fcfafc messageTray: forward clicks on trayicon SummaryItems to the icon
If the user clicks on the title of a trayicon's SummaryItem, forward
that click to the trayicon. Also adjust
gnome_shell_plugin_xevent_filter() so that if the trayicon takes a
grab as a result of this, we don't hide the message tray.

https://bugzilla.gnome.org/show_bug.cgi?id=630842
2011-03-21 14:56:53 -04:00
a40daa3c22 runDialog: popModal before running the command
If you run a command from Alt+F2 that tries to get a server grab (eg,
xmag), it will fail if it starts up before the run dialog is finished
hiding.

Additionally, the run dialog currently stays focused while it is
fading out, potentially stealing keystrokes (or causing the user to
accidentally launch two copies of a program).

Change ModalDialog.close() to call popModal() immediately

Add a ModalDialog.popModal method, and call that before running the
RunDialog command. If the command succeeds, close the dialog as
before. If it fails, call ModalDialog.pushModal() to put things back
to normal before displaying the error.

https://bugzilla.gnome.org/show_bug.cgi?id=644857
2011-03-21 14:26:08 -04:00
1e366aa56e altTab: popModal before fading out
This lets the user start typing in the newly-selected window right
away, without any characters possibly getting eaten during the
animation.

https://bugzilla.gnome.org/show_bug.cgi?id=644857
2011-03-21 14:26:08 -04:00
bad8dbc2d2 modalDialog: grab focus immediately, not after fade-in
If the user types Alt+F2 and then immediately starts typing, some keys
can get lost. Fix that by grabbing focus sooner.

https://bugzilla.gnome.org/show_bug.cgi?id=644857
2011-03-21 14:26:08 -04:00
d0dd37fe94 appDisplay: use get_allocation_box() in _ensureIconVisible
When right-clicking on an AppWellIcon, the icon will become focused,
which (presumably via style-changed) invalidates its current
allocation, causing "icon.y" to return 0 until it has been
reallocated, messing up our idea of where in the AppDisplay the icon
is. Work around this by calling get_allocation_box() instead.

https://bugzilla.gnome.org/show_bug.cgi?id=645162
2011-03-21 14:26:07 -04:00
b2df3fcd1d Always show the workspace thumbnails if there is a monitor to the right
If there is a monitor to the right it is very easy to overshot the
expanding thumbnails and enter the next monitor. So, in that case
we just always show it.

https://bugzilla.gnome.org/show_bug.cgi?id=641877
2011-03-21 18:48:57 +01:00
96f89ce4ae message-tray: allocate the entire size to the icon
Specify x-fill and y-fill true for the bin that contains the status
icon so the status icon will always be sized to our specified icon
size (24x24). This prevents pathological behavior for legacy status
icons embedded in the tray where an initial allocation at 1x1 before
they had content would "stick", and the icon would permanently
end up 1x1.

https://bugzilla.gnome.org/show_bug.cgi?id=634820
2011-03-21 11:17:29 -04:00
e886a3d891 StButton: fix handling of Space/Enter -> click
StButton was mistakenly considering any Space/Enter KEY_RELEASE to be
a click, when in fact it should only count as a click if it also got
the corresponding KEY_PRESS as well. This meant that when typing in a
chat notification, any Space/Enter keypress would dismiss the
notification, since the StEntry would take the PRESS event but ignore
the RELEASE, allowing it to propagate to the notification itself,
which would treat it as a click.

https://bugzilla.gnome.org/show_bug.cgi?id=645243
2011-03-21 10:18:46 -04:00
0eaf141ae4 user-status: Honor lockdown settings
Right now, the user status menu always contains actions to logout
and lock the screen, and the user switching action only depends on
the technical availability of the functionality.
All those items should honor the lockdown settings defined in
org.gnome.desktop.lockdown.

https://bugzilla.gnome.org/show_bug.cgi?id=645335
2011-03-21 15:02:10 +01:00
291ef07cf3 run-dialog: Honor lockdown settings
org.gnome.desktop.lockdown has a setting to prevent the use of the
Alt-F2 run dialog. Honor this setting.

https://bugzilla.gnome.org/show_bug.cgi?id=645335
2011-03-21 15:00:32 +01:00
b9066ac997 Updated Lithuanian translation. 2011-03-21 14:26:19 +01:00
206f4604a4 gnome-shell: fix restart after rebuild
Alt+F2 restart was failing after a rebuild when running from the
source tree because it would try to restart
".libs/lt-gnome-shell-real", which didn't exist yet. Fix this by using
"libtool --mode=execute" at build time to regenerate that file.

https://bugzilla.gnome.org/show_bug.cgi?id=645390
2011-03-21 09:20:23 -04:00
adbc1d97a0 StThemeNode: support border-image: none
Treat border-image: none as a valid specification that overwrites any
previously specified border image.

https://bugzilla.gnome.org/show_bug.cgi?id=644788
2011-03-21 09:16:32 -04:00
70ae700461 Only add hot corner for primary and "top left" monitors
To avoid having hot corners that accidentally trigger when e.g. trying
to hit the panel on the primary monitor we add hot corners only to
monitors that are "naturally" top left (top right for RTL).

For instance, we'd like a hot corner here:

corner -> +-------------
          |            |
+---------+            |
|=========|            |
|         |            |
|         |            |
|         |            |
+---------+------------+

But not here:

          unexpected hot corner
          ↓
+---------+-------+
|=========|       |
|         |       |
|         +-------+
+---------+

https://bugzilla.gnome.org/show_bug.cgi?id=645116
2011-03-21 10:32:30 +01:00
b81ad3ed39 Updated Portuguese translation 2011-03-20 23:52:36 +00:00
77cdb17cee ShellAppSystem: dynamically generate known_vendor_prefixes
It create prefix based on desktop file's id and desktop file's path and vendor_prefix.
https://bugzilla.gnome.org/show_bug.cgi?id=620464
2011-03-20 23:39:38 +03:00
d4e329b76d Updated Galician translations 2011-03-20 18:54:54 +01:00
fb24585dd8 Don't use italic for status items in menus
https://bugzilla.gnome.org/show_bug.cgi?id=645276
2011-03-20 12:23:58 -04:00
bd5efd5968 Added Latvian translation. 2011-03-20 15:35:24 +02:00
650f35c1f3 Util: use the right function name when reporting errors.
It's Main.notifyError, not Main.notifyProblem.

https://bugzilla.gnome.org/show_bug.cgi?id=645248
2011-03-19 19:57:08 +01:00
14e65168c9 Updated Polish translation 2011-03-19 16:19:43 +01:00
f00c47c21a Updated Indonesian translation 2011-03-19 22:12:28 +07:00
547d105b2e Updated Korean translation 2011-03-19 23:23:32 +09:00
de671103ca Updated Serbian translation 2011-03-19 12:37:28 +01:00
2c48efa3fd dash: Handle cancelled drags
If a drag was cancelled, do animations like size changes or zooming
out the remove target in parallel with the snapback animation.

https://bugzilla.gnome.org/show_bug.cgi?id=644324
2011-03-19 11:16:10 +01:00
7f35b2dc43 workspaces-view: Zoom out early on canceled item drags
Start the zoom at the same time as the snapback animation, as it's
already done for window snapbacks.

https://bugzilla.gnome.org/show_bug.cgi?id=644324
2011-03-19 11:16:10 +01:00
6ae914da2f overview: Handle drag-cancelled signal for items
Allow handling the drag-cancelled signal for non-window items, just
like the handling for windows instroduced in commit a80e88e33.

https://bugzilla.gnome.org/show_bug.cgi?id=644324
2011-03-19 11:16:10 +01:00
06ea78af1b view-selector: Don't fade in the initially selected tab
The fade effect when switching tabs should only be applied when
switching from a previously selected tab, not when selecting the
initial one - otherwise, the window previews are faded in the first
time the overview is shown.

https://bugzilla.gnome.org/show_bug.cgi?id=644389
2011-03-19 11:16:09 +01:00
2ea12a7699 Updated Hungarian translation 2011-03-19 02:47:36 +01:00
8ab25de6c6 Fix user visible typo: s/estabilished/established/
The affected translations are also modified to not cause any
inconvenience for translators.
2011-03-19 01:16:16 +01:00
e0424a7017 Updated Dutch translation by Wouter Bolsterlee 2011-03-19 01:14:43 +01:00
f259162d64 workspacesView: Fix graphical glitches with windows appearing for a split-second
When we were knocking off workspace height to fix the ratio problems, we
weren't adding spacing in between workspaces, so they smooshed up against
each other whenever we took height off, causing them to be visible.
2011-03-18 23:21:43 +01:00
6bb5cdeb2f Updated Spanish translation 2011-03-18 20:01:08 +01:00
384c30b6fd Updated Slovenian translation 2011-03-18 18:45:54 +01:00
67a75d4439 Update Simplified Chinese translation. 2011-03-18 18:34:54 +08:00
0d963df7b3 status: use Shell.AppSystem to launch settings panels
Different methos are being used to launch the control-center panels of each
status icon. Standarize on Shell.AppSystem.
This also fixes the network icon using a non-existant Util.spawnDesktop()
method.

Bug #645091
2011-03-17 23:26:14 -05:00
99efde5673 Switch Clutter module to http git checkout
It apparently is unlikely that anongit access will be restored
to clutter-project.org. We'll update the moduleset again when
alternate hosting is found.
2011-03-17 23:03:18 -04:00
c8ff699c4b Updated Romanian translation 2011-03-18 00:20:27 +01:00
0718a888d0 Updated Romanian translation 2011-03-18 00:18:56 +01:00
b7be4df603 panel: Hide spinner when switching apps
Commit fcfd17e was overzealous when simplifying the previous spinner
animation, as a result the spinner now stays around when switching
to another application while the animation is ongoing.
2011-03-17 22:06:34 +01:00
8bece0b49e Updated Arabic translation 2011-03-17 22:55:07 +02:00
47d6edc3c8 Updated Spanish translation 2011-03-17 20:20:09 +01:00
26bb56396d Updated Spanish translation 2011-03-17 20:06:18 +01:00
dd99ed73a9 Fallback to using a generic when requested image isn't found
Use a type specific generic image when the requested icon
can't be loaded instead of using an empty texture.

https://bugzilla.gnome.org/show_bug.cgi?id=644668
2011-03-17 14:02:04 -04:00
36ce460a39 Uploaded Ukranian 2011-03-17 18:59:08 +02:00
e92c845dfd Updated Italian translation 2011-03-17 16:03:27 +01:00
492263c2e9 Link against libmutter.
https://bugzilla.gnome.org/show_bug.cgi?id=644565
2011-03-17 15:26:51 +01:00
0c99f66547 Handle workspaces going empty due to windows changing monitors
If a workspace becomes empty due to a window changing to/from the
primary monitor, but not changing its original workspace then we
were not noticing this. This can happen for instance if you drag
a thumbnail window to a non-primary window.

https://bugzilla.gnome.org/show_bug.cgi?id=609258
2011-03-17 14:13:55 +01:00
df440496ee Constrain zoomed overview windows to the current monitor
Additionally, the constraint to not overlap the panel should only happen
on the primary monitor.

https://bugzilla.gnome.org/show_bug.cgi?id=609258
2011-03-17 14:13:55 +01:00
09f2028d6a overview: hidden workspace thumbnails should not stick out on other monitor
We clip the entire WorkspacesDisplay to its allocation to avoid things
like the WorkspaceThumbnails sticking out of the primary monitor into
another monitor.

https://bugzilla.gnome.org/show_bug.cgi?id=609258
2011-03-17 14:13:55 +01:00
05736ba0a1 Always reserve space in all workspaces on a drag
We used to do this only on automatic workspace switch, but that
doesn't work for the multiple monitors case where we want to reserve
space on the extra monitors.

https://bugzilla.gnome.org/show_bug.cgi?id=609258
2011-03-17 14:13:55 +01:00
e5f05bc9d8 Add workspaces on non-primary monitors
We create a Workspace with a null metaWorkspace for each
non-primary monitor, showing the windows on these monitors.
These are saved in WorkspaceView.extraWorkspaces.

https://bugzilla.gnome.org/show_bug.cgi?id=609258
2011-03-17 14:13:55 +01:00
cdd1209b55 Only show windows from the primary monitor on the overview workspace
This means a bunch of windows will not be visible at all in the overview.
Those will be added back with per-screen workspaces on the non-primary
monitors.

https://bugzilla.gnome.org/show_bug.cgi?id=609258
2011-03-17 14:13:55 +01:00
0e6458a630 Only show windows from the primary monitor in the workspace thumbnails
Also, if windows are dropped on the thumbnail, move them to the primary
monitor.

https://bugzilla.gnome.org/show_bug.cgi?id=609258
2011-03-17 14:13:55 +01:00
a1a068a377 Only show the primary monitor region in the workspace thumbnails
Make the thumbnail the size of the primary monitor and only show
the windows from that area.

https://bugzilla.gnome.org/show_bug.cgi?id=609258
2011-03-17 14:13:55 +01:00
2c5657e8a9 Enable the workspaces_only_on_primary feature of mutter
https://bugzilla.gnome.org/show_bug.cgi?id=609258
2011-03-17 14:13:55 +01:00
87fbd715a3 Updated Norwegian bokmål translation 2011-03-17 09:44:09 +01:00
fc8cba9598 Updated Hebrew translation. 2011-03-17 00:38:02 +02:00
147725bf7a gnome-shell.modules: Add a gtk3 dep for libgweather 2011-03-16 18:01:40 -04:00
06d2c0af35 messageTray: dismiss notifications on click, not button-release-event
Notification was connecting to button-release-event to decide when to
be dismissed, which caused problems with widgets inside the
notification that reacted to button-press-event but not
button-release-event. Fix this by wrapping the Notification's table in
an StButton and connecting to 'click'.

https://bugzilla.gnome.org/show_bug.cgi?id=642978
2011-03-16 15:55:37 -04:00
708f1a97dd Move the font color CSS rule from .workspaces-view to .window-caption
This is needed once we start seeing window captions outside the
workspaces view (for other monitors).

https://bugzilla.gnome.org/show_bug.cgi?id=609258
2011-03-16 20:33:25 +01:00
d8bd9f5a66 Add and export shell_global_get_primary_monitor_index
https://bugzilla.gnome.org/show_bug.cgi?id=609258
2011-03-16 20:33:25 +01:00
079953c3ee Switch to using the mutter primary monitor APIs
https://bugzilla.gnome.org/show_bug.cgi?id=609258
2011-03-16 20:30:58 +01:00
fea8b6da2f Remove broken ShellAppSystem API and all consumers
In commit 9bd22dc0, I introduced an API to load an arbitrary
.desktop file, not necessarily from the menu path.  It turns
out this function was broken because it created ShellApp instances
that were *different* from ones that were cached normally.

As far as I can tell, we didn't initially use it.  Then later
Util.spawnDesktop was created which used this function.

Remove this broken function and all callers; if we're loading
.desktop files from *outside* the menu path, we can look at
readding.

This patch also kills off Util.spawnDesktop in favor of callers
talking to ShellAppSystem directly, now that the latter reports
errors.

https://bugzilla.gnome.org/show_bug.cgi?id=644402
2011-03-16 15:07:22 -04:00
4bf1df0894 ShellApp: Report error when we fail to run an app
https://bugzilla.gnome.org/show_bug.cgi?id=644402
2011-03-16 15:07:22 -04:00
b4f16c4df8 Add shell_global_report_error()
Move the "system notification error" handling out of
util.js, and add it to ShellGlobal so we can start
calling it from across the codebase better (including
C).

https://bugzilla.gnome.org/show_bug.cgi?id=644402
2011-03-16 15:07:21 -04:00
61282737c5 Updated Galician translations 2011-03-16 19:56:26 +01:00
d8c2290099 Prelight panel items on hover
In order to give feedback when the user hovers
over items on the panel, we should prelight them.

https://bugzilla.gnome.org/show_bug.cgi?id=609576
2011-03-16 19:52:54 +01:00
830ab599df Updated Spanish translation 2011-03-16 19:30:11 +01:00
0de5c5e8a3 Updated Hungarian translation 2011-03-16 19:01:40 +01:00
c6170ed751 windowManager: fix up accounting of dimmed windows
Simplify the accounting of which windows we should dim by checking
the current state of windows rather than trying to track changes,
and by keeping a list of dimmed windows rather than a list of windows
with a dimmed parent. Remove windows from the list of dimmed windows
when they are destroyed.

This should fix problems where destroyed windows could end up in
the list of dimmed windows.

https://bugzilla.gnome.org/show_bug.cgi?id=644167
2011-03-16 12:31:06 -04:00
2ea762cfc9 Updated Italian transaltion 2011-03-16 17:04:19 +01:00
2646741297 Updated Arabic translation 2011-03-16 17:46:23 +02:00
f5df5faf71 Update Simplified Chinese translation. 2011-03-16 23:28:57 +08:00
cab9a580e8 gnome-shell-jhbuild: Adjust GI_TYPELIB_PATH for NM inclusion
When jhbuilding, we use a jhbuilt gobject-introspection, so the
default typelib path is the jhbuild prefix, not /usr. So if we are
using NetworkManager from packages, we need to adjust GI_TYPELIB_PATH
to include it.

https://bugzilla.gnome.org/show_bug.cgi?id=621707
2011-03-16 11:04:33 -04:00
c8ac3fd4f5 Status area: add NetworkManager indicator
Adds an implementation of nm-applet in javascript. Uses the new
introspection from NetworkManager, and temporarily requires
nm-applet to be running for the secret service.
Features a renewed interface, with each device controllable through
a switch, which if toggled off disconnects, and if toggled on
connects to the most recently used valid connection. More esoteric
features like creation of ad-hoc networks have been moved to the
control center panel.

https://bugzilla.gnome.org/show_bug.cgi?id=621707
2011-03-16 15:59:34 +01:00
7f67c34b39 Bluetooth: fix updating the device list
Inside the inner loop, use the inner iterator, not that of the outer
loop. At the same time, refactor the code to rely less on private
properties appended to foreign objects.

https://bugzilla.gnome.org/show_bug.cgi?id=644858
2011-03-16 15:29:37 +01:00
e27293edbc messageTray: fix summary area wobbling
Due to accumulation of rounding errors, the left edge of the summary area
could wobble by a few pixels during animations. Fix that.

https://bugzilla.gnome.org/show_bug.cgi?id=636930
2011-03-16 09:47:07 -04:00
8d57c5052c Updated Arabic translation 2011-03-16 14:53:53 +02:00
1314559833 polkit: drop gdmuser naming workaround
The polkit authentication dialog contains logic for
falling back to dispalying a user's username if that
user has no real name.

This logic is no longer needed because gdmuser does it
internally now.

https://bugzilla.gnome.org/show_bug.cgi?id=644765
2011-03-15 15:50:26 -04:00
735397aa89 gdm: fix empty real name check
gdm_user_get_real_name() checks for an empty real
name and automatically falls back to username if
real name is NULL.  It doesn't automatically fall
back to username if real name is empty, however.

This commit makes it fall back for both cases.

https://bugzilla.gnome.org/show_bug.cgi?id=644765
2011-03-15 15:49:15 -04:00
c0d0c792e1 StContainer: Account for floating-point imprecision when sorting actors
When we compare the boxes for two actors, they may appear to overlap
by a small amount because of floating-point imprecision. Allow for
up to 0.1 pixel overlap when determining what children are in the
focus direction from the currently focused actor.

https://bugzilla.gnome.org/show_bug.cgi?id=644134
2011-03-15 15:41:07 -04:00
43020b20b7 ShellWindowTracker: don't create ShellApps for non-interesting windows
If a process does not have any "interesting" windows, then it can't be
considered a running app. (Previously we were calling
get_app_for_window() before ruling out non-interesting windows, which
ended up calling _shell_app_new_for_window(), which would add the
window to the ShellApp directly, bypassing the is_interesting check.)

https://bugzilla.gnome.org/show_bug.cgi?id=642221
2011-03-15 15:37:08 -04:00
0a3d80b86e accessibility: remove Screen Reader and Screen Keyboard entries
These are not 100% ready for 3.0 (though they are still available from
the control panel).

https://bugzilla.gnome.org/show_bug.cgi?id=639762
2011-03-15 15:36:09 -04:00
a9505d0426 workspaceView: Make sure to scale the workspace proportionally
Commit 0207f1f29b landed a new
way of zooming, but was causing all sorts of window positioning
weirdness because the positions were supposed to be working against
a proportional workspace.

https://bugzilla.gnome.org/show_bug.cgi?id=644542
2011-03-15 13:28:38 -04:00
4d804c2a29 telepathyClient: remove alias-change messages, to unbreak string freeze
https://bugzilla.gnome.org/show_bug.cgi?id=642793
2011-03-15 13:12:15 -04:00
e8eec2d357 Use points for font sizes
Do a basic job of converting font sizes from pixels to points, so they
will scale will the global GNOME scale factor. Some other sizes that are
clearly related to the font sizes are changed to ems, but no comprehensive
attempt is made to get rid of px units.

https://bugzilla.gnome.org/show_bug.cgi?id=636868
2011-03-15 12:01:40 -04:00
971e3f679f Updated Slovenian translation 2011-03-15 16:13:05 +01:00
7c90f078e7 Updated Slovenian translation 2011-03-15 16:09:30 +01:00
5957bd1abb Updated Galician translations 2011-03-15 15:26:21 +01:00
b16380e7e5 Updated Galician translations 2011-03-15 15:26:21 +01:00
b72a32c70d Updated Hungarian translation 2011-03-15 14:44:00 +01:00
90f15b3c5a dateMenu: open calendar specifically when opening evolution
https://bugzilla.gnome.org/show_bug.cgi?id=641504
2011-03-15 09:13:09 -04:00
44bbf26cb2 gnome-shell.modules: add --disable-Werror to telepathy-logger
It does not currently build error-free with gcc 4.6.
2011-03-15 08:41:02 -04:00
fcfd17e973 app-menu: Simplify startup animation
During application startup, we used to display a rotating spinner
which also moved from left to right, revealing the application title.
The result looks rather busy, so remove the horizontal movement.

https://bugzilla.gnome.org/show_bug.cgi?id=640782
2011-03-15 13:27:44 +01:00
73853cf147 .gitignore: add gnome-shell-perf-helper 2011-03-15 08:27:04 -04:00
ddbc263da2 [l10n] Updated Estonian translation 2011-03-15 13:42:27 +02:00
982d8a0dc0 build: Fix TelepathyLogger version requirement
We are supposed to require the 0.2 gir file not 1.0.
2011-03-15 00:15:26 +01:00
5a269db9d5 telepathyClient: Add messages from TelepathyLogger
This allows users to see chat history from other contacts with
the inline message tray replies.

https://bugzilla.gnome.org/show_bug.cgi?id=643377
2011-03-14 18:49:31 -04:00
525da01a62 shell-global: Add wrappers for TelepathyLogger
gjs can't support more than one callback in the same function,
so work around this with yet another shell-global wrapper.

https://bugzilla.gnome.org/show_bug.cgi?id=643377
2011-03-14 18:49:31 -04:00
12df10b2d0 Require a recent TelepathyLogger
We require a TelepathyLogger version with gobject-introspection support.

https://bugzilla.gnome.org/show_bug.cgi?id=643377
2011-03-14 18:48:18 -04:00
e6aee5d7ea telepathyClient: Add support for the ACTION message type
This message type is usually supported by the '/me' command
in IRC and IM clients.

https://bugzilla.gnome.org/show_bug.cgi?id=642793
2011-03-14 18:48:18 -04:00
6ff69da0de telepathyClient: Add support for aliases on the self-contact
Upgrade the connection's self contact to allow aliases, so that we
don't show the internal telepathy identifier anywhere user-visible.

https://bugzilla.gnome.org/show_bug.cgi?id=642793
2011-03-14 18:48:18 -04:00
ebcb87c163 shell-global: Add shell_get_self_contact_features
This is another workaround for the lack of gjs supporting array
arguments, this time wrapping tp_connection_upgrade_contacts to
add new features to the connection's self contact.

https://bugzilla.gnome.org/show_bug.cgi?id=642793
2011-03-14 18:48:18 -04:00
79d9df9bb1 telepathyClient: Add history navigation to entry
This adds a non-saving history to each notification entry,
like runDialog and lookingGlass.

https://bugzilla.gnome.org/show_bug.cgi?id=642793
2011-03-14 18:42:55 -04:00
8c40c2086a telepathyClient: Add alias change notifiers
Update the Source title when an contact's alias changes, and
also also add a minor meta message like the current timestamps.

Updating the alias of a 'presenced' contact will overwrite the
current title, and it will also not update the summary item title
right now due to limitations of the message tray.

https://bugzilla.gnome.org/show_bug.cgi?id=642793
2011-03-14 18:42:55 -04:00
f4a000cb59 telepathyClient: Re-open existing chat sources on Shell restart
This allows users to continue a chat they were having after
the shell is restarted.

https://bugzilla.gnome.org/show_bug.cgi?id=642793
2011-03-14 18:42:55 -04:00
4029202635 messageTray: Add Source.pushNotification method
This allows clients to make minor adjustments to their notification
content without triggering a new popup.

https://bugzilla.gnome.org/show_bug.cgi?id=642793
2011-03-14 18:42:55 -04:00
29d473f2fa XDND: Fix dragMonitor leak in WorkspacesDisplay
WorkspacesDisplay removes its dragMonitor in _dragEnd, but
this was never called in when a xdnd drag ended causing
dragMonitors to stack up and handling events multiple times.

Fix that by making sure that _dragEnd is called when xdnd ends.

https://bugzilla.gnome.org/show_bug.cgi?id=644642
2011-03-14 22:03:33 +01:00
7ad89dc46b Work around Spidermonkey problem with Unicode date formats
Monkey-patch Date.prototype.toLocaleFormat() with a version that uses
g_date_time_format() since the Spidermonkey built-in can't handle
format strings with Unicode characters.

https://bugzilla.gnome.org/show_bug.cgi?id=643350
2011-03-14 15:33:44 -04:00
4b2d6f8a99 clock: update every second
If we don't update every second, we may show the wrong time for up to
a minute on 1. resume; or 2. when changing the time; or 3. when
changing the timezone. This is both annoying and and leads to people
thinking that the tool for changing the time / timezone is broken.

https://bugzilla.gnome.org/show_bug.cgi?id=635840

Signed-off-by: David Zeuthen <davidz@redhat.com>
2011-03-14 14:36:24 -04:00
9b55de1c6b polkit: Make dialogs look more like the mockups
The mockups are here

 https://live.gnome.org/GnomeShell/Design/Whiteboards/AuthorizationDialog

Detailed changes

 - Don't use an icon for root
 - For root, show Administrator in red
 - Nuke icons for info and error messages
 - Make error messages yellow
 - Use 10pt size for error and message labels, not 12px
 - Don't make the dialog change size when (single-line) error/info
   messages appear
 - Spacing fixes
 - Show "Sorry, that didn't work. Please try again" if authentication fails
 - Don't cancel the PolkitAgentSession if the session has already completed

https://bugzilla.gnome.org/show_bug.cgi?id=644737

Signed-off-by: David Zeuthen <davidz@redhat.com>
2011-03-14 15:18:03 -03:00
8b45211a8f gnome-shell.modules: patch libcanberra to not use gtk_quit_add()
Add patch from the main GNOME 3 moduleset to make libcanberra
work properly with GTK+ 3.
2011-03-14 13:55:49 -04:00
f079501cff placeDisplay: Remove network places
It hasn't existed in nautilus for a while now, and we don't
have places at all.

https://bugzilla.gnome.org/show_bug.cgi?id=644402
2011-03-14 10:37:19 -04:00
e375e1789b popupMenu: don't include hidden items in the width computation
https://bugzilla.gnome.org/show_bug.cgi?id=621707
2011-03-14 09:28:06 -04:00
30d2cfdf56 Updated Korean translation 2011-03-14 10:40:23 +09:00
44d61e6857 Remove use of G_CONST_RETURN macro.
This is going to be deprecated.

https://bugzilla.gnome.org/show_bug.cgi?id=644632
2011-03-13 22:03:47 +01:00
3466829766 popupMenu: Restyle the slider to use a color for the 'active' area
In the mockups the slider does not have an uniform color but uses
one color (shade of blue) to indicate the current value and one
to indicate "the rest" (shade of grey).

So adjust the slider to look like that to be closer to the look
in the mockups and thus to the design.

https://bugzilla.gnome.org/show_bug.cgi?id=644600
2011-03-13 19:33:03 +01:00
d3703516d9 Fix handling of clutter_init() failures
clutter_init() fails under normal circumstances like
being unable to open a display connection, so it shouldn't
be handled with g_error() producing a core dump.

Clutter consistently produces an error message when
clutter_init() fails, so we don't need to print out any
error message.

https://bugzilla.gnome.org/show_bug.cgi?id=643910
2011-03-13 14:29:47 -04:00
bdebaa986b Silence -Werror for other clutter_init callers 2011-03-13 14:16:54 -04:00
c2d400846b test-theme: Pacify -Werror for clutter_init 2011-03-13 14:11:33 -04:00
034e147910 l10n: Updated Greek translation 2011-03-13 19:14:24 +02:00
25015c9c3a BluetoothStatus: don't pass NaNs to native functions
GJS complains when a NaN is passed in place of an integer, and
parseInt returns that from non numeric string. Pass a sentinel
that cancels the operation in that case.

https://bugzilla.gnome.org/show_bug.cgi?id=642978
2011-03-13 17:05:33 +01:00
43cf60f563 StScrollViewFade: Fix GLSL shader to work on r300 hardware
The number instructions in a shader is limited to 64 on r300 hardware,
the fade shader in StScrollViewFade was ending up using 97 instructions
which is way over the limit.

So refactor the shader to use less instructions by precomputing as many
values as possible outside of the conditionals. The resulting shader
ends up using 34 instructions which is well within the hardware limits.

https://bugzilla.gnome.org/show_bug.cgi?id=644589
2011-03-13 16:29:18 +01:00
057348763b StTextureCache: generate icon names in the right order
GThemedIcon expects the first name to be the most specific, and
will thus prefer it to later ones. We thus need to order the names
from the longer to the shorter.

https://bugzilla.gnome.org/show_bug.cgi?id=621707
2011-03-13 14:46:42 +01:00
7230452e23 Updated Romanian translation 2011-03-13 01:31:36 +01:00
438317c1e9 Updated Romanian translation 2011-03-13 01:31:02 +01:00
cfe719c962 Updated Romanian translation 2011-03-13 01:25:15 +01:00
44e2d88628 Updated Romanian translation 2011-03-13 01:19:11 +01:00
6e50e77709 Updated Romanian translation 2011-03-13 00:32:01 +01:00
02ed28d68d Updated Dutch translation by Wouter Bolsterlee 2011-03-12 23:53:15 +01:00
73274e201b Status Menu: use Gnome Session DBus for shutdown and logout
Around 2.91.90, gnome-session-save was renamed to gnome-session-quit.
This commit restores compatibility with the older gnome-session, for
those testing under GNOME 2.32 or below, by calling the DBus methods
directly.

https://bugzilla.gnome.org/show_bug.cgi?id=644591
2011-03-12 21:37:39 +01:00
f6fc88cc2d perf: Add metrics for switching to the applications view
Measure how long it takes to switch from the workspaces view to the
windows view the first time and the second time.

https://bugzilla.gnome.org/show_bug.cgi?id=644266
2011-03-11 19:25:40 -05:00
d16acc43d9 viewSelector: allow programmatically switching to tabs
Add the idea of an 'id' for a tab, and add a public switchTab method
so you can switch to 'applications' or 'windows'. This will be useful
for performance tests that test tab switching performance.

https://bugzilla.gnome.org/show_bug.cgi?id=644266
2011-03-11 19:25:40 -05:00
239aa7b8d5 perf: Add metrics for different window configurations
Add metrics:
 overviewFps5Windows
 overviewFps10Windows
 overviewFps5Maximzed
 overviewFps10Maximized
 overviewFps5Alpha
 overviewFps10Alpha

To have more numbers to show how performance varies with different
numbers of windows and different types of windows (maximized,
with an alpha channel.)

https://bugzilla.gnome.org/show_bug.cgi?id=644265
2011-03-11 19:25:40 -05:00
44a1bc5396 scripting.js: small cleanups
- Fix missing trailing semicolons
- Catch when something results in metrics not being to avoid
  hard-to-debug JSON parse errors.

https://bugzilla.gnome.org/show_bug.cgi?id=644265
2011-03-11 19:21:07 -05:00
821583acae Use gnome-shell-perf-helper to control windows during perf tests
* Run gnome-shell-perf-helper during performance tests
* Use MUTTER_WM_CLASS_FILTER to omit all other windows
* Add new Scripting methods: createTestWindow,
  waitTestWindows, destroyTestWindows
* Create a single 640x480 test window for testing overview
  animation performance.

https://bugzilla.gnome.org/show_bug.cgi?id=644265
2011-03-11 19:21:07 -05:00
c6a2814881 gnome-shell-perf-helper: add server for creating test windows
Add a small D-Bus server program that the performance tests can
use to create well-specificed sets of windows.

https://bugzilla.gnome.org/show_bug.cgi?id=644265
2011-03-11 19:21:07 -05:00
1954a02352 gnome-shell-jhbuild: Fix race condition when launching DConf manually
We need to connect to the NameOwnerChanged signal before we execute the
DConf binary. Refactor things so that we connect to the signal when
we first get the bus object. Split the code for waiting for a D-Bus
name into a wait_for_dbus_name() function for latter reuse.

https://bugzilla.gnome.org/show_bug.cgi?id=644265
2011-03-11 19:21:06 -05:00
8a28022a6b Don't show the overview unless removing the workspace
Don't enter the overview at startup, or when we we remove the
last window on the first workspace, but only when we remove a
workspace and there are windows on the other workspaces.

https://bugzilla.gnome.org/show_bug.cgi?id=644541
2011-03-11 19:21:06 -05:00
43a243b24a CSS: Remove a left-over from an earlier relayout iteration 2011-03-11 21:29:23 +01:00
7c937c8704 gvc: Fix missing introspection
It's all Bastien's fault
2011-03-11 17:50:49 +00:00
bdd1f82777 volume: Use constants from GVC
Instead of defining our own.

https://bugzilla.gnome.org/show_bug.cgi?id=644511
2011-03-11 16:29:59 +00:00
cbb8876815 gvc: Fix introspection building 2011-03-11 16:29:40 +00:00
f8cdaaae30 gvc: Update from gnome-control-center
https://bugzilla.gnome.org/show_bug.cgi?id=644511
2011-03-11 16:29:40 +00:00
74314bacd7 Remove DYNAMIC_MOZJS_HACK bits
Not used anymore now that gnome-shell is a real ELF binary with an
rpath.
2011-03-11 10:30:33 -05:00
04473f607b gnome-shell-jhbuild: exit 1 if gnome-shell-real failed
We need to be propagating the failure exit code so that
gnome-session knows something went wrong.
2011-03-11 10:30:33 -05:00
88958270cb New translation for Afrikaans (af) 2011-03-11 12:39:00 +02:00
856f7ecee9 Updated Italian translation 2011-03-11 01:57:01 +01:00
9f5584a157 Uploaded Ukranian 2011-03-10 20:20:27 +02:00
eda8a94d5b Updated Spanish translation 2011-03-10 19:14:39 +01:00
5956b13588 Updated Hebrew translation. 2011-03-10 18:45:10 +02:00
162d029c81 statusMenu: Lock screen before suspending
We need to lock the screen before suspending the system
to prevent unauthorized access to the system / account.

https://bugzilla.gnome.org/show_bug.cgi?id=643357
2011-03-09 21:59:50 +01:00
7f3920dbb7 statusMenu: Use the screensaver's dbus interface directly
Use the dbus interface instead of calling gnome-screensaver-command.

https://bugzilla.gnome.org/show_bug.cgi?id=643357
2011-03-09 21:59:26 +01:00
6d07c3a1df Updated Polish translation 2011-03-09 21:48:39 +01:00
a0a83428cf telepathyClient: Pin the scrollbar to the bottom
When new messages come in we want to scroll down so that the user
sees the incoming messages. The current implementation does not work
because it relies on a synchronous allocation hack which does not work
for unmapped notifications.

Fix that by connecting to adjustment::changed and scroll whenever the
adjustment changes which equals "new messages", "new timestamp" or
"presense change", but don't interference with the user's scroll actions
i.e when the user scrolls back to read something don't scroll to the bottom.

https://bugzilla.gnome.org/show_bug.cgi?id=614977
2011-03-09 19:38:17 +01:00
dc2cae07b2 notification: Remove scrollTo hack
Remove the hack from Notification.scrollTo because it is unreliable,
the caller should make sure to call scrollTo when it will actually
have the desired effect.

https://bugzilla.gnome.org/show_bug.cgi?id=614977
2011-03-09 19:38:16 +01:00
f8b44cd30e Updated Spanish translation 2011-03-09 19:38:10 +01:00
c3eca3d754 Updated Spanish translation 2011-03-09 19:37:05 +01:00
1ea005f6a6 Updated Slovenian translation 2011-03-09 17:40:12 +01:00
16a675b7ce Bail early from check over all permutations
If we're already doing worse than the best so far there is
no need to continue checking this particular permutation.

https://bugzilla.gnome.org/show_bug.cgi?id=609258
2011-03-09 10:45:21 +01:00
df2f939f3a Start the workspace zoom out immediately on dnd cancel.
This means the snap-back animation happens at the same time as the zoom,
which looks much better.

https://bugzilla.gnome.org/show_bug.cgi?id=643786
2011-03-09 10:36:09 +01:00
5743224817 Don't rearrange dragged window when repositioning windows
If we're dragging a window around and we need to reposition the windows,
due to e.g. the sliding in of the thumbnails or some other reason, then we
need to consider the original position of the dragged window, rather than
the currend drag position. Otherwise we will unnecessarily rearrange the
other windows for instance on snap-back if you moved the dragged window
past some other window.

https://bugzilla.gnome.org/show_bug.cgi?id=643786
2011-03-09 10:36:09 +01:00
a80e88e33e dnd: Add a drag-cancelled signal
This lets us start the workspace zoom out animation right when the
snapback starts, rather than waiting for the snapback to finish.

https://bugzilla.gnome.org/show_bug.cgi?id=643786
2011-03-09 10:36:09 +01:00
0207f1f29b Restructure the way we handle positioning zooming in Workspace
We currently show the workspace in the overview in a rectangle
with the same aspect ratio as the screen. Originally this was
probably done since it showed the desktop, but we don't do this
anymore, and the positioning of the windows in the overview is
strictly a grid, so its not in any way related to monitor geometry.
Additionally, in the multihead case the screen aspect ratio is
very different from the overview monitor geometry, so a lot of
space is lost.

So, instead we just fill the entire inner rectangle of the overview
with the workspace. However, the way the zoom into and out of the
workspace right now is by scaling the workspace so that it covers
the entire monitor. This cannot really work anymore when the workspace
is a different aspect ratio. Furthermore the coordinates of the
window clone actors are of two very different types in the "original
window" case and the "window in a slot case". One is screen relative,
the other is workspace relative. This makes it very hard to compute
the cost of window motion distance in computeWindowMotion.

In order to handle this we change the way workspace actor positioning
and scaling work. All workspace window clone actors are stored in
true screen coordingates, both the original window positions and the
in-a-slot ones. Global scaling of the workspace is never done, we
just reposition everything in both the initial zoom and when the
controls appear from the side.

There is one issue in the initial and final animations, which is that
the clip region we normally have for the workspacesView will limit the
animation of the clones to/from the original positions, so we disable
the clip region during these animations.

https://bugzilla.gnome.org/show_bug.cgi?id=643786
2011-03-09 10:36:02 +01:00
72120bb87f dnd: Avoid division by zero, etc for zero-size actors
When rescaling due to a possible parent actor resize avoid problems
if the parent width is zero.

https://bugzilla.gnome.org/show_bug.cgi?id=643786
2011-03-09 10:27:36 +01:00
7eaca86bf1 updated kn translations 2011-03-09 09:39:58 +05:30
db5f72c868 Updated Arabic translation 2011-03-09 01:12:50 +02:00
69d6ae4141 panel: prevent blink of current app indicator
If new current app is null, show animation of disappearing old.
https://bugzilla.gnome.org/show_bug.cgi?id=615099
2011-03-09 01:53:32 +03:00
edabafc0fc gnome-shell.modules: update the git repository for telepathy-glib
Telepathy repositories moved to freedesktop.org:
http://lists.freedesktop.org/archives/telepathy/2011-February/005291.html

https://bugzilla.gnome.org/show_bug.cgi?id=644239
2011-03-08 16:14:20 -05:00
e9f2aa6010 Updated British English translation 2011-03-08 19:53:18 +00:00
e054dd7813 autoWorkspaces: Merge empty workspaces with the always empty one
When closing a workspace due to the last window on that workspace
closing, switch to the overview and show the always empty workspace
rather then just going to the adjacent workspace.

Based on a patch from Adel Gadllah <adel.gadllah@gmail.com>.

https://bugzilla.gnome.org/show_bug.cgi?id=642188
2011-03-08 19:46:51 +01:00
76d788a186 windowManager: Add mechanism to block animations
Add an API to allow blocking animations in situations where
they aren't desireable.

https://bugzilla.gnome.org/show_bug.cgi?id=642188
2011-03-08 19:46:46 +01:00
3944df1bd2 altTab: fix incorrect positioning with multiple monitors
Calculate the position of the alt-tab popup correctly when primary.x != 0.
This was accidentally broken by 614176b269
https://bugzilla.gnome.org/show_bug.cgi?id=644206
2011-03-08 20:21:07 +03:00
49f6280645 src: add more stuff to gnome_shell_real_LDADD
to work with libtools that are more strict about not allowing
transitive dependencies
2011-03-08 11:47:14 -05:00
84eb66d5aa StContainer: simplify focus navigation
When navigating from a non-immediate descendant of a container, we
were attempting to use clutter_actor_get_transformed_position() to get
the exact position of that actor relative to the container, but this
did not really make sense, since we would be using the position of
the intermediate container when navigating back.

https://bugzilla.gnome.org/show_bug.cgi?id=644134
2011-03-08 09:36:55 -05:00
026fc531ba StTextureCache: never return fullcolor icons for ST_ICON_SYMBOLIC
g_themed_icon_new_with_default_fallbacks() does not do what we want
with symbolic icons; if the user's icon theme is not "gnome", then it
will end up preferring a non-symbolic icon from the higher-level theme
over a symbolic icon from gnome-icon-theme-symbolic.

If the shell requests a symbolic icon, and there is only a
non-symbolic icon available, that should be considered a programmer
error, just like requesting a non-existent icon name. So change the
code to only look up "-symbolic" names when drawing an
ST_ICON_SYMBOLIC icon.

https://bugzilla.gnome.org/show_bug.cgi?id=644142
2011-03-08 09:36:55 -05:00
8d14df0ced Updated Norwegian bokmål translation 2011-03-08 15:29:51 +01:00
f27547dcff l10n: Updated Greek translation for gnome-shell 2011-03-08 15:00:59 +02:00
155 changed files with 42798 additions and 13238 deletions

4
.gitignore vendored
View File

@ -7,7 +7,6 @@ ChangeLog
INSTALL
Makefile
Makefile.in
NEWS
aclocal.m4
autom4te.cache
config.h
@ -44,8 +43,9 @@ src/calendar-server/org.gnome.Shell.CalendarServer.service
src/gnome-shell
src/gnome-shell-calendar-server
src/gnome-shell-extension-tool
src/gnome-shell-real
src/gnome-shell-jhbuild
src/gnome-shell-perf-helper
src/gnome-shell-real
src/run-js-test
src/test-recorder
src/test-recorder.ogg

63
NEWS Normal file
View File

@ -0,0 +1,63 @@
Contributors to GNOME Shell 3.0
===============================
Code:
Josh Adams, Kiyoshi Aman, Nuno Araujo, Emmanuele Bassi, Dirk-Jan C. Binnema,
Wouter Bolsterlee, Raphael Bosshard, Milan Bouchet-Valat, Christina Boumpouka,
Mathieu Bridon, Alban Browaeys, Phil Bull, Micro Cai, Giovanni Campagna,
Cosimo Cecchi, Tor-björn Claesson, Matthias Clasen, Jason D. Clinton,
Frederic Crozat, Guillaume Desmottes, Sander Dijkhuis, Neha Doijode,
Maxim Ermilov, Diego Escalante Urrelo, Luca Ferretti, Steve Frécinaux,
Takao Fujiwara, Adel Gadllah, Vadim Girlin, Nick Glynn, Guido Günther,
Leon Handreke, Lex Hider, Richard Hughes, Javier Jardón, Abderrahim Kitouni,
Andre Klapper, Alexander Larsson, Nickolas Lloyd, Ryan Lortie, Kjartan Maraas,
Koop Mast, Rui Matos, Jonathan Matthew, William Jon McCann, Morten Mjelva,
Federico Mena Quintero, Florian Müllner, Jon Nettleton, Hellyna Ng,
Discardi Nicola, Carlos Martín Nieto, Bastien Nocera, Bill Nottingham,
Matt Novenstern, Marc-Antoine Perennou, Neil Perry, Frédéric Péters,
Alejandro Piñeiro, Siegfried-Angel Gevatter Pujals, "res", Neil Roberts,
"Sardem FF7", Florian Scandella, Joseph Scheuhammer, Christian Schramm,
Gustavo Noronha Silva, Jasper St. Pierre, Eric Springer, Jakub Steiner,
Jonathan Strander, Ray Strode, Owen Taylor, Rico Tzschichholz,
Sergey V. Udaltsov, Daiki Ueno, Vincent Untz, Marcelo Jorge Vieira,
Mads Villadsen, Colin Walters, Dan Winship, William Wolf, Thomas Wood,
Pierre Yager, David Zeuthen, Marina Zhurakhinskaya
Design:
Allan Day, William Jon McCann, Jeremy Perry, Jakub Steiner
2008 Boston GNOME design hackfest participants (especially Neil J. Patel
for turning the resulting sketches into our first mockups.)
Everybody on irc.gnome.org:#gnome-design
Translations:
Friedel Wolff (af), Khaled Hosny (ar), Ivaylo Valkov (bg), Jamil Ahmed (bn)
Runa Bhattacharjee (bn_IN), Gil Forcada, Siegfried-Angel Gevatter Pujals,
Jordi Serratosa (ca), Andre Klapper, Petr Kovar (cs), Kenneth Nielsen,
Kris Thomsen (da), Mario Blättermann, Hendrik Brandt, Christian Kirbach,
Hendrik Richter, Wolfgang Stöggl (de), Michael Kotsarinis, Kostas Papadimas,
Jennie Petoumenou, Sterios Prosiniklis, Fotis Tsamis, Simos Xenitellis (el),
Bruce Cowan, Philip Withnall (en_GB), Jorge Gonzalez, Daniel Mustieles (es),
Mattias Põldaru, Ivar Smolin (et), Inaki Larranaga Murgoitio (eu),
Mahyar Moghimi (fa), Timo Jyrinki (fi), Cyril Arnaud, Bruno Brouard,
Pablo Martin-Gomez, Claude Paroz, Frédéric Peters (fr), Seán de Búrca (ga)
Francisco Diéguez, Antón Méixome (gl), Sweta Kothari (gu), Liel Fridman,
Yaron Shahrabani (he), Rajesh Ranjan (hi), Gabor Kelemen (hu), Milo Casagrande,
Luca Ferretti (it), Dirgita, Andika Triwidada (id), Takayuki KUSANO,
Takayoshi OKANO, Kiyotaka NISHIBORI, Futoshi NISHIO (ja), Shankar Prasad (kn),
Young-Ho Cha, Changwoo Ryu (ko), Žygimantas Beručka, Gintautas Miliauskas (lt),
Rudolfs Mazurs (lv), Sandeep Shedmake (mr), Kjartan Maraas (nb),
Wouter Bolsterlee, Sander Dijkhuis, Reinout van Schouwen (nl),
Torstein Winterseth (nn), A S Alam (pa), Tomasz Dominikowski, Piotr Drąg (pl),
Duarte Loreto (pt), Felipe Borges, Rodrigo Padula de Oliveira,
Rodrigo L. M. Flores, Amanda Magalhães, Og B. Maciel, Gabriel F. Vilar,
Jonh Wendell (pt_BR), Lucian Adrian Grijincu, Daniel Șerbănescu (ro),
Sergey V. Kovylov, Andrey Korzinev, Yuri Myasoedov, Marina Zhurakhinskaya (ru),
Daniel Nylander (se), Matej Urbančič, Andrej Žnidaršič (sl),
Miloš Popović (sr, sr@latin), Miroslav Nikolić (sr), Tirumurti Vasudevan (ta),
Sira Nokyoongtong (th), Baris Cicek (tr), Abduxukur Abdurixit,
Gheyret T. Kenji (ug), Maxim V. Dziumanenko, Daniel Korostil (uk),
Nguyễn Thái Ngọc Duy (vi), Jessica Ban, 'jiero', Wei Li, YunQiang Su, Ray Wang,
Aron Xu (zh_CN), Chao-Hsiung Liao (zh_HK, zh_TW)

View File

@ -1,5 +1,5 @@
AC_PREREQ(2.63)
AC_INIT([gnome-shell],[2.91.91],[https://bugzilla.gnome.org/enter_bug.cgi?product=gnome-shell],[gnome-shell])
AC_INIT([gnome-shell],[3.0.0],[https://bugzilla.gnome.org/enter_bug.cgi?product=gnome-shell],[gnome-shell])
AC_CONFIG_HEADERS([config.h])
AC_CONFIG_SRCDIR([src/shell-global.c])
@ -52,8 +52,8 @@ AC_MSG_CHECKING([for GStreamer (needed for recording functionality)])
if $PKG_CONFIG --exists gstreamer-0.10 '>=' $GSTREAMER_MIN_VERSION ; then
AC_MSG_RESULT(yes)
build_recorder=true
recorder_modules="gstreamer-0.10 gstreamer-base-0.10 xfixes x11"
PKG_CHECK_MODULES(TEST_SHELL_RECORDER, $recorder_modules clutter-1.0)
recorder_modules="gstreamer-0.10 gstreamer-base-0.10 x11"
PKG_CHECK_MODULES(TEST_SHELL_RECORDER, $recorder_modules clutter-1.0 xfixes)
else
AC_MSG_RESULT(no)
fi
@ -63,7 +63,7 @@ AM_CONDITIONAL(BUILD_RECORDER, $build_recorder)
CLUTTER_MIN_VERSION=1.5.15
GOBJECT_INTROSPECTION_MIN_VERSION=0.10.1
GJS_MIN_VERSION=0.7.11
MUTTER_MIN_VERSION=2.91.91
MUTTER_MIN_VERSION=3.0.0
GTK_MIN_VERSION=3.0.0
GIO_MIN_VERSION=2.25.9
LIBECAL_MIN_VERSION=2.32.0
@ -71,13 +71,14 @@ LIBEDATASERVER_MIN_VERSION=1.2.0
LIBEDATASERVERUI2_MIN_VERSION=1.2.0
LIBEDATASERVERUI3_MIN_VERSION=2.91.6
TELEPATHY_GLIB_MIN_VERSION=0.13.12
TELEPATHY_LOGGER_MIN_VERSION=0.2.4
POLKIT_MIN_VERSION=0.100
# Collect more than 20 libraries for a prize!
PKG_CHECK_MODULES(GNOME_SHELL, gio-2.0 >= $GIO_MIN_VERSION
gio-unix-2.0 dbus-glib-1 libxml-2.0
gtk+-3.0 >= $GTK_MIN_VERSION
libmutter-wm >= $MUTTER_MIN_VERSION
libmutter >= $MUTTER_MIN_VERSION
gjs-internals-1.0 >= $GJS_MIN_VERSION
libgnome-menu $recorder_modules gconf-2.0
gdk-x11-3.0
@ -87,20 +88,31 @@ PKG_CHECK_MODULES(GNOME_SHELL, gio-2.0 >= $GIO_MIN_VERSION
gobject-introspection-1.0 >= $GOBJECT_INTROSPECTION_MIN_VERSION
libcanberra
telepathy-glib >= $TELEPATHY_GLIB_MIN_VERSION
polkit-agent-1 >= $POLKIT_MIN_VERSION)
telepathy-logger-0.2 >= $TELEPATHY_LOGGER_MIN_VERSION
polkit-agent-1 >= $POLKIT_MIN_VERSION xfixes)
PKG_CHECK_MODULES(SHELL_PERF_HELPER, gtk+-3.0 gio-2.0)
GJS_VERSION=`$PKG_CONFIG --modversion gjs-internals-1.0`
AC_DEFINE_UNQUOTED([GJS_VERSION], ["$GJS_VERSION"], [The version of GJS we're linking to])
AC_SUBST([GJS_VERSION], ["$GJS_VERSION"])
GOBJECT_INTROSPECTION_CHECK([$GOBJECT_INTROSPECTION_MIN_VERSION])
JHBUILD_TYPELIBDIR="$INTROSPECTION_TYPELIBDIR"
# NM is the only typelib we use that we don't jhbuild
PKG_CHECK_EXISTS([libnm-glib >= 0.8.995],
[NM_TYPELIBDIR=`$PKG_CONFIG --variable=libdir libnm-glib`/girepository-1.0
if test "$INTROSPECTION_TYPELIBDIR" != "$NM_TYPELIBDIR"; then
JHBUILD_TYPELIBDIR="$JHBUILD_TYPELIBDIR:$NM_TYPELIBDIR"
fi])
AC_SUBST(JHBUILD_TYPELIBDIR)
saved_CFLAGS=$CFLAGS
saved_LIBS=$LIBS
CFLAGS=$GNOME_SHELL_CFLAGS
LIBS=$GNOME_SHELL_LIBS
# sn_startup_sequence_get_application_id, we can replace with a version check later
AC_CHECK_FUNCS(JS_NewGlobalObject sn_startup_sequence_get_application_id)
AC_CHECK_FUNCS(JS_NewGlobalObject sn_startup_sequence_get_application_id XFixesCreatePointerBarrier)
CFLAGS=$saved_CFLAGS
LIBS=$saved_LIBS
@ -134,8 +146,8 @@ PKG_CHECK_MODULES(CALENDAR_SERVER, libecal-1.2 >= $LIBECAL_MIN_VERSION libedatas
AC_SUBST(CALENDAR_SERVER_CFLAGS)
AC_SUBST(CALENDAR_SERVER_LIBS)
MUTTER_GIR_DIR=`$PKG_CONFIG --variable=girdir libmutter-wm`
MUTTER_TYPELIB_DIR=`$PKG_CONFIG --variable=typelibdir libmutter-wm`
MUTTER_GIR_DIR=`$PKG_CONFIG --variable=girdir libmutter`
MUTTER_TYPELIB_DIR=`$PKG_CONFIG --variable=typelibdir libmutter`
AC_SUBST(MUTTER_GIR_DIR)
AC_SUBST(MUTTER_TYPELIB_DIR)
@ -190,20 +202,6 @@ AC_ARG_ENABLE(jhbuild-wrapper-script,
AS_HELP_STRING([--jhbuild-wrapper-script=yes],[Make "gnome-shell" script work for jhbuild]),,enable_jhbuild_wrapper_script=no)
AM_CONDITIONAL(USE_JHBUILD_WRAPPER_SCRIPT, test "x$enable_jhbuild_wrapper_script" = xyes)
AC_MSG_CHECKING([for Ubuntu])
if test -f /etc/ubuntu_version; then
enable_dynamic_mozjs_hack_default=yes
AC_MSG_RESULT([yes])
else
enable_dynamic_mozjs_hack_default=no
AC_MSG_RESULT([no])
fi
AC_ARG_ENABLE(dynamic-mozjs-hack,
AS_HELP_STRING([--dynamic-mozjs-hack=no],[Look for libmozjs.so using pkg-config]),,enable_dynamic_mozjs_hack=$enable_dynamic_mozjs_hack_default)
ENABLE_DYNAMIC_MOZJS_HACK=$enable_dynamic_mozjs_hack
AC_SUBST(ENABLE_DYNAMIC_MOZJS_HACK)
AC_CONFIG_FILES([
Makefile
data/Makefile

View File

@ -24,7 +24,8 @@ dist_theme_DATA = \
theme/calendar-today.svg \
theme/close-window.svg \
theme/close.svg \
theme/corner-ripple.png \
theme/corner-ripple-ltr.png \
theme/corner-ripple-rtl.png \
theme/dash-placeholder.svg \
theme/filter-selected-ltr.svg \
theme/filter-selected-rtl.svg \
@ -49,6 +50,7 @@ dist_theme_DATA = \
theme/separator-white.png \
theme/single-view-active.svg \
theme/single-view.svg \
theme/source-button-border.svg \
theme/toggle-off-us.svg \
theme/toggle-off-intl.svg \
theme/toggle-on-us.svg \

View File

@ -13,3 +13,4 @@ NoDisplay=true
X-GNOME-Autostart-Phase=WindowManager
X-GNOME-Provides=panel;windowmanager;
X-GNOME-Autostart-Notify=true
X-GNOME-AutoRestart=true

View File

@ -81,5 +81,20 @@
</locale>
</schema>
<schema>
<key>/schemas/desktop/gnome/shell/windows/workspaces_only_on_primary</key>
<applyto>/desktop/gnome/shell/windows/workspaces_only_on_primary</applyto>
<owner>gnome-shell</owner>
<type>bool</type>
<default>true</default>
<locale name="C">
<short>Workspaces only on primary monitor</short>
<long>
This key overrides /apps/mutter/general/workspaces_only_on_primary when
running GNOME Shell.
</long>
</locale>
</schema>
</schemalist>
</gconfschemafile>

View File

@ -1,5 +1,5 @@
<schemalist>
<schema id="org.gnome.shell" path="/apps/gnome-shell/"
<schema id="org.gnome.shell" path="/org/gnome/shell/"
gettext-domain="@GETTEXT_PACKAGE@">
<key name="development-tools" type="b">
<default>true</default>
@ -54,7 +54,7 @@
<child name="recorder" schema="org.gnome.shell.recorder"/>
</schema>
<schema id="org.gnome.shell.calendar" path="/apps/gnome-shell/calendar/"
<schema id="org.gnome.shell.calendar" path="/org/gnome/shell/calendar/"
gettext-domain="@GETTEXT_PACKAGE@">
<key name="show-weekdate" type="b">
<default>false</default>
@ -65,7 +65,7 @@
</key>
</schema>
<schema id="org.gnome.shell.clock" path="/apps/gnome-shell/clock/"
<schema id="org.gnome.shell.clock" path="/org/gnome/shell/clock/"
gettext-domain="@GETTEXT_PACKAGE@">
<key name="show-seconds" type="b">
<default>false</default>
@ -83,7 +83,7 @@
</key>
</schema>
<schema id="org.gnome.shell.recorder" path="/apps/gnome-shell/recorder/"
<schema id="org.gnome.shell.recorder" path="/org/gnome/shell/recorder/"
gettext-domain="@GETTEXT_PACKAGE@">
<key name="framerate" type="i">
<default>15</default>

View File

Before

Width:  |  Height:  |  Size: 2.4 KiB

After

Width:  |  Height:  |  Size: 2.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 KiB

View File

@ -34,13 +34,6 @@ stage {
color: rgba(0,0,0,0.5);
}
.label-real-shadow {
background-gradient-direction: horizontal;
background-gradient-start: rgba(0, 0, 0, 0);
background-gradient-end: rgba(0, 0, 0, 255);
width: 10px;
}
StScrollBar
{
padding: 0px;
@ -82,10 +75,10 @@ StScrollBar StButton#vhandle:hover
}
StTooltip StLabel {
border: 1px solid rgba(79,111,173,1);
border: 1px solid rgba(255,255,255,0.6);
border-radius: 5px;
padding: 4px;
background-color: rgba(79,111,173,0.9);
padding: 2px 12px;
background-color: rgba(0,0,0,0.9);
color: #ffffff;
font-size: 0.8em;
font-weight: normal;
@ -105,12 +98,40 @@ StTooltip StLabel {
.popup-menu {
color: #ffffff;
font-size: 14px;
font-size: 10.5pt;
min-width: 200px;
}
.popup-submenu-menu-item:open {
background-color: #4c4c4c;
}
.popup-sub-menu {
background-color: #606060;
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);
}
.popup-sub-menu .popup-menu-item:ltr {
padding-right: 0em;
}
.popup-sub-menu .popup-menu-item:rtl {
padding-left: 0em;
}
.popup-sub-menu StScrollBar {
padding: 4px;
}
.popup-sub-menu StScrollBar StBin#trough {
border-width: 0px;
}
.popup-sub-menu StScrollBar StBin#vhandle {
background-color: #4c4c4c;
border-width: 0px;
}
/* The remaining popup-menu sizing is all done in ems, so that if you
@ -150,6 +171,8 @@ StTooltip StLabel {
-slider-height: 0.3em;
-slider-background-color: #333333;
-slider-border-color: #5f5f5f;
-slider-active-background-color: #76b0ec;
-slider-active-border-color: #1f6dbc;
-slider-border-width: 1px;
-slider-handle-radius: 0.5em;
}
@ -158,14 +181,22 @@ StTooltip StLabel {
spacing: .5em;
}
.popup-inactive-menu-item {
color: #999;
}
.popup-subtitle-menu-item {
font-weight: bold;
}
.popup-menu-icon {
icon-size: 1.14em;
}
/* Switches (to be used in menus) */
.toggle-switch {
width: 4.5em;
height: 1.5em;
width: 65px;
height: 22px;
}
.toggle-switch-us {
@ -182,12 +213,18 @@ StTooltip StLabel {
background-image: url("toggle-on-intl.svg");
}
.nm-menu-item-icons {
spacing: .5em;
}
/* Panel */
#panel {
color: #ffffff;
background-color: black;
border-image: url("panel-border.svg") 1;
font-size: 10.5pt;
height: 1.86em;
}
#panelLeft, #panelCenter, #panelRight {
@ -247,12 +284,16 @@ StTooltip StLabel {
.panel-button {
padding: 0px 12px;
font-size: 14px;
font-weight: bold;
color: #ccc;
transition-duration: 100;
}
.panel-button:hover {
color: white;
text-shadow: black 0px 2px 2px;
}
.panel-button:active,
.panel-button:checked,
.panel-button:focus {
@ -315,7 +356,7 @@ StTooltip StLabel {
background-color: rgba(0,0,0,0.6);
}
.workspaces-view {
.window-caption {
color: white;
spacing: 25px;
}
@ -344,13 +385,14 @@ StTooltip StLabel {
.workspace-thumbnail-indicator {
outline: 2px solid white;
border: 1px solid #888;
}
.window-caption {
background: rgba(0,0,0,0.8);
border: 1px solid rgba(128,128,128,0.40);
border-radius: 10px;
font-size: 12px;
font-size: 9pt;
padding: 2px 8px;
-shell-caption-spacing: 4px;
}
@ -370,7 +412,7 @@ StTooltip StLabel {
#dash {
color: #5f5f5f;
font-size: 12px;
font-size: 9pt;
padding: 4px 0px;
background-color: rgba(0, 0, 0, 0.5);
border: 1px solid rgba(128, 128, 128, 0.4);
@ -396,12 +438,12 @@ StTooltip StLabel {
}
#viewSelector {
spacing: 16px;
font-size: 16px;
spacing: 1em;
font-size: 12pt;
}
#viewSelectorTabBar {
padding: 16px;
padding: 1em;
}
#searchArea {
@ -449,8 +491,8 @@ StTooltip StLabel {
.view-tab-title {
color: #888a85;
font-weight: bold;
padding: 0px 12px;
height: 24px;
padding: 0px 0.75em;
height: 1.5em;
}
.view-tab-title:hover {
@ -460,17 +502,7 @@ StTooltip StLabel {
.view-tab-title:selected {
color: #000000;
background-color: #c2c7cd;
border-radius: 4px;
height: 24px;
}
.view-tab-boxpointer {
-arrow-border-radius: 9px;
-arrow-background-color: rgba(0,0,0,0.5);
-arrow-border-width: 2px;
-arrow-border-color: rgba(255,255,255,0.5);
-arrow-base: 30px;
-arrow-rise: 15px;
border-radius: 0.25em;
}
#searchResults {
@ -533,7 +565,7 @@ StTooltip StLabel {
.dash-search-button-label {
color: #cccccc;
font-size: 16px;
font-size: 12pt;
}
/* Apps */
@ -558,9 +590,9 @@ StTooltip StLabel {
}
.app-filter {
font-size: 14px;
font-size: 10.5pt;
font-weight: bold;
height: 40px;
height: 2.85em;
color: #aaa;
width: 200px;
}
@ -603,7 +635,7 @@ StTooltip StLabel {
border-radius: 4px;
padding: 3px;
border: 1px rgba(0,0,0,0);
font-size: 10px;
font-size: 7.5pt;
color: white;
transition-duration: 100;
text-align: center;
@ -633,7 +665,7 @@ StTooltip StLabel {
}
.app-well-menu {
font-size: 12px
font-size: 9pt;
}
/* LookingGlass */
@ -761,7 +793,7 @@ StTooltip StLabel {
#calendarArea {
/* this is the width of the entire popup */
width: 600px;
min-width: 600px;
}
.calendar-vertical-separator {
@ -789,7 +821,7 @@ StTooltip StLabel {
.calendar-month-label {
color: #666666;
font-size: 10px;
font-size: 7.5pt;
padding: 2px;
font-weight: bold;
}
@ -832,16 +864,16 @@ StTooltip StLabel {
.datemenu-date-label {
padding: .4em 1.75em;
font-size: 14px;
font-size: 10.5pt;
color: #cccccc;
font-weight: bold;
}
.calendar-day-base {
font-size: 10px;
font-size: 7.5pt;
text-align: center;
width: 24px;
height: 24px;
width: 2.4em;
height: 2.4em;
}
.calendar-day-base:hover {
@ -899,11 +931,13 @@ StTooltip StLabel {
}
.events-header-vbox {
spacing: 8px;
spacing: 6pt;
padding-right: 1.75em;
}
.events-header {
height: 40px;
.events-header-vbox:rtl {
padding-right: 0em;
padding-left: 1.75em;
}
.events-header-hbox {
@ -911,7 +945,7 @@ StTooltip StLabel {
}
.events-day-header {
font-size: 12px;
font-size: 9pt;
font-weight: bold;
color: rgba(153, 153, 153, 1.0);
padding-left: 0.3em;
@ -923,7 +957,7 @@ StTooltip StLabel {
}
.events-day-dayname {
font-size: 12px;
font-size: 9pt;
color: rgba(153, 153, 153, 1.0);
text-align: left;
}
@ -933,7 +967,7 @@ StTooltip StLabel {
}
.events-day-time {
font-size: 12px;
font-size: 9pt;
color: #fff;
text-align: right;
}
@ -943,22 +977,22 @@ StTooltip StLabel {
}
.events-day-task {
font-size: 12px;
font-size: 9pt;
color: rgba(153, 153, 153, 1.0);
}
.events-day-name-box {
width: 20px;
min-width: 15pt;
}
.events-time-box {
width: 70px;
padding-right: 8px;
min-width: 53pt;
padding-right: 6pt;
}
.events-time-box:rtl {
padding-right: 0px;
padding-left: 8px;
padding-left: 6pt;
}
.events-event-box {
@ -972,13 +1006,13 @@ StTooltip StLabel {
#message-tray {
background-gradient-direction: vertical;
background-gradient-start: rgba(0,0,0,0.01);
background-gradient-end: rgba(0,0,0,0.95);
background-gradient-end: rgba(0,0,0,0.82);
height: 36px;
color: white;
}
#notification {
font-size: 16px;
font-size: 12pt;
border-radius: 5px 5px 0px 0px;
background: rgba(0,0,0,0.9);
padding: 8px 8px 4px 8px;
@ -1007,11 +1041,29 @@ StTooltip StLabel {
}
.summary-boxpointer #summary-right-click-menu {
font-size: 14px;
font-size: 10.5pt;
padding-top: 12px;
padding-bottom: 12px;
}
#summary-notification-stack-scrollview {
max-height: 18em;
padding-top: 6px;
padding-bottom: 6px;
}
#summary-notification-stack-scrollview > .top-shadow, #summary-notification-stack-scrollview > .bottom-shadow {
height: 1em;
}
#summary-notification-stack-scrollview:ltr {
padding-right: 8px;
}
#summary-notification-stack-scrollview:rtl {
padding-left: 8px;
}
#notification-scrollview {
max-height: 10em;
}
@ -1078,6 +1130,10 @@ StTooltip StLabel {
icon-size: 36px;
}
.chat-log-message {
color: #888888;
}
.chat-received {
background-gradient-direction: horizontal;
background-gradient-start: rgba(255, 255, 255, 0.2);
@ -1109,7 +1165,7 @@ StTooltip StLabel {
.chat-meta-message {
padding-left: 4px;
border-radius: 4px;
font-size: 14px;
font-size: 10.5pt;
color: #bbbbbb;
}
@ -1158,14 +1214,32 @@ StTooltip StLabel {
padding: 2px 4px 0px 0px;
}
.summary-source-button {
color: #fff;
text-shadow: black 0px 2px 2px;
}
.summary-source-button:ltr {
padding-left: 4px;
padding-right: 16px;
padding-right: 12px;
}
.summary-source-button:selected .summary-source {
background-image: url("panel-button-highlight-narrow.svg");
border-image: url("source-button-border.svg") 10 10 0 1;
}
.summary-source-button:expanded:selected .summary-source {
background-image: none;
border-image: none;
}
.summary-source-button:expanded:selected {
background-image: url("panel-button-highlight-wide.svg");
border-image: url("source-button-border.svg") 10 10 0 1;
}
.summary-source-button:rtl {
padding-right: 4px;
padding-left: 16px;
padding-left: 12px;
}
.summary-source-button:last-child:ltr {
@ -1176,8 +1250,13 @@ StTooltip StLabel {
padding-left: 12px;
}
.summary-source {
padding-right: 4px;
padding-left: 4px;
}
.source-title {
font-size: 12px;
font-size: 9pt;
font-weight: bold;
padding-left: 4px;
}
@ -1199,7 +1278,7 @@ StTooltip StLabel {
border-radius: 24px;
padding: 20px;
font-size: 12px;
font-size: 9pt;
color: white;
}
@ -1258,7 +1337,11 @@ StTooltip StLabel {
.ripple-box {
width: 52px;
height: 52px;
background-image: url("corner-ripple.png");
background-image: url("corner-ripple-ltr.png");
}
.ripple-box:rtl {
background-image: url("corner-ripple-rtl.png");
}
.switcher-arrow {
@ -1328,10 +1411,14 @@ StTooltip StLabel {
padding-top: 30px;
}
.modal-dialog-button-box {
spacing: 21px;
}
.modal-dialog-button {
border: 1px solid #8b8b8b;
border-radius: 18px;
font-size: 14px;
font-size: 10.5pt;
margin-left: 10px;
margin-right: 10px;
@ -1364,12 +1451,12 @@ StTooltip StLabel {
/* Run Dialog */
.run-dialog-label {
font-size: 12px;
font-size: 9pt;
color: white;
}
.run-dialog-error-label {
font-size: 12px;
font-size: 9pt;
color: white;
}
@ -1379,9 +1466,9 @@ StTooltip StLabel {
}
.run-dialog-entry {
font-size: 14px;
font-size: 10.5pt;
font-weight: bold;
width: 320px;
width: 23em;
color: white;
}
@ -1399,6 +1486,10 @@ StTooltip StLabel {
}
/* End Session Dialog */
.end-session-dialog {
spacing: 42px;
}
.end-session-dialog-subject {
font-size: 12pt;
font-weight: bold;
@ -1417,13 +1508,11 @@ StTooltip StLabel {
font-size: 10pt;
color: white;
padding-left: 17px;
padding-right: 40px;
width: 16em;
width: 28em;
}
.end-session-dialog-description:rtl {
padding-right: 17px;
padding-left: 40px;
}
.end-session-dialog-logout-icon {
@ -1442,16 +1531,23 @@ StTooltip StLabel {
font-size: 10pt;
max-height: 200px;
padding-top: 42px;
padding-bottom: 42px;
padding-left: 17px;
padding-left: 49px;
padding-right: 32px;
}
.end-session-dialog-app-list:rtl {
padding-right: 17px;
padding-right: 49px;
padding-left: 32px;
}
.end-session-dialog-app-list-item {
color: #ccc;
}
.end-session-dialog-app-list-item:hover {
color: white;
}
.end-session-dialog-app-list-item:ltr {
padding-right: 1em;
}
@ -1484,12 +1580,12 @@ StTooltip StLabel {
}
.polkit-dialog-main-layout {
spacing: 10px;
spacing: 24px;
padding: 10px;
}
.polkit-dialog-message-layout {
spacing: 10px;
spacing: 16px;
}
.polkit-dialog-headline {
@ -1513,6 +1609,10 @@ StTooltip StLabel {
padding-right: 10px;
}
.polkit-dialog-user-root-label {
color: #ff0000;
}
.polkit-dialog-password-label:ltr {
padding-right: 0.5em;
}
@ -1528,33 +1628,21 @@ StTooltip StLabel {
}
.polkit-dialog-error-label {
font-size: 12px;
color: white;
}
.polkit-dialog-error-box {
padding-top: 15px;
spacing: 5px;
}
.polkit-dialog-checking-label {
font-size: 12px;
color: white;
}
.polkit-dialog-checking-box {
padding-top: 15px;
spacing: 5px;
font-size: 10pt;
color: #ffff00;
padding-bottom: 8px;
}
.polkit-dialog-info-label {
font-size: 12px;
color: white;
font-size: 10pt;
padding-bottom: 8px;
}
.polkit-dialog-info-box {
padding-top: 15px;
spacing: 5px;
/* intentionally left transparent to avoid dialog changing size */
.polkit-dialog-null-label {
font-size: 10pt;
color: rgba(0,0,0,0);
padding-bottom: 8px;
}

View File

@ -0,0 +1,74 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="21"
height="10"
id="svg2"
version="1.1"
inkscape:version="0.48.0 r9654"
sodipodi:docname="source-button-border.svg">
<defs
id="defs4" />
<sodipodi:namedview
id="base"
pagecolor="#000000"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="0"
inkscape:pageshadow="2"
inkscape:zoom="44.8"
inkscape:cx="8.704132"
inkscape:cy="5.7029946"
inkscape:document-units="px"
inkscape:current-layer="layer1"
showgrid="true"
showguides="true"
inkscape:guide-bbox="true"
inkscape:window-width="1600"
inkscape:window-height="1145"
inkscape:window-x="0"
inkscape:window-y="26"
inkscape:window-maximized="1"
guidetolerance="10000"
objecttolerance="10000">
<inkscape:grid
type="xygrid"
id="grid3792"
empspacing="10"
visible="true"
enabled="true"
snapvisiblegridlinesonly="true" />
</sodipodi:namedview>
<metadata
id="metadata7">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title></dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<g
inkscape:label="Layer 1"
inkscape:groupmode="layer"
id="layer1">
<rect
style="opacity:0.8;fill:#ffffff;fill-opacity:1;stroke-width:0.43599999;stroke-miterlimit:4;stroke-dasharray:none"
id="rect3796"
width="19"
height="2"
x="1"
y="8" />
</g>
</svg>

After

Width:  |  Height:  |  Size: 2.0 KiB

View File

@ -6,6 +6,22 @@
<name xml:lang="en">GNOME Shell</name>
<shortdesc xml:lang="en">Next generation GNOME desktop shell</shortdesc>
<description>GNOME Shell provides core user interface functions for the GNOME 3
desktop, like switching to windows and launching applications.
GNOME Shell takes advantage of the capabilities of modern graphics
hardware and introduces innovative user interface concepts to
provide a visually attractive and easy to use experience.
Tarball releases are provided largely for distributions to build
packages. If you are interested in building GNOME Shell from source,
we would recommend building from version control using the build
script described at:
http://live.gnome.org/GnomeShell
Not only will that give you the very latest version of this rapidly
changing project, it will be much easier than get GNOME Shell and
its dependencies to build from tarballs.</description>
<!--
<homepage rdf:resource="http://live.gnome.org/GnomeShell" />
-->

View File

@ -8,6 +8,7 @@ nobase_dist_js_DATA = \
misc/format.js \
misc/gnomeSession.js \
misc/history.js \
misc/modemManager.js \
misc/params.js \
misc/util.js \
perf/core.js \
@ -50,6 +51,7 @@ nobase_dist_js_DATA = \
ui/statusMenu.js \
ui/status/accessibility.js \
ui/status/keyboard.js \
ui/status/network.js \
ui/status/power.js \
ui/status/volume.js \
ui/status/bluetooth.js \

View File

@ -102,3 +102,24 @@ Inhibitor.prototype = {
};
DBus.proxifyPrototype(Inhibitor.prototype, InhibitorIface);
Signals.addSignalMethods(Inhibitor.prototype);
// Not the full interface, only the methods we use
const SessionManagerIface = {
name: 'org.gnome.SessionManager',
methods: [
{ name: 'Logout', inSignature: 'u', outSignature: '' },
{ name: 'Shutdown', inSignature: '', outSignature: '' }
]
};
function SessionManager() {
this._init();
}
SessionManager.prototype = {
_init: function() {
DBus.session.proxifyObject(this, 'org.gnome.SessionManager', '/org/gnome/SessionManager');
}
};
DBus.proxifyPrototype(SessionManager.prototype, SessionManagerIface);

225
js/misc/modemManager.js Normal file
View File

@ -0,0 +1,225 @@
// -*- mode: js2; indent-tabs-mode: nil; js2-basic-offset: 4 -*-
const DBus = imports.dbus;
const Lang = imports.lang;
const Shell = imports.gi.Shell;
const Signals = imports.signals;
// The following are not the complete interfaces, just the methods we need
// (or may need in the future)
const ModemGsmNetworkInterface = {
name: 'org.freedesktop.ModemManager.Modem.Gsm.Network',
methods: [
{ name: 'GetRegistrationInfo', inSignature: '', outSignature: 'uss' },
{ name: 'GetSignalQuality', inSignature: '', outSignature: 'u' }
],
properties: [
{ name: 'AccessTechnology', signature: 'u', access: 'read' }
],
signals: [
{ name: 'SignalQuality', inSignature: 'u' },
{ name: 'RegistrationInfo', inSignature: 'uss' }
]
};
const ModemGsmNetworkProxy = DBus.makeProxyClass(ModemGsmNetworkInterface);
const ModemCdmaInterface = {
name: 'org.freedesktop.ModemManager.Modem.Cdma',
methods: [
{ name: 'GetSignalQuality', inSignature: '', outSignature: 'u' },
{ name: 'GetServingSystem', inSignature: '', outSignature: 'usu' }
],
signals: [
{ name: 'SignalQuality', inSignature: 'u' }
]
};
const ModemCdmaProxy = DBus.makeProxyClass(ModemCdmaInterface);
let _providersTable;
function _getProvidersTable() {
if (_providersTable)
return _providersTable;
let [providers, countryCodes] = Shell.mobile_providers_parse();
return _providersTable = providers;
}
function ModemGsm() {
this._init.apply(this, arguments);
}
ModemGsm.prototype = {
_init: function(path) {
this._proxy = new ModemGsmNetworkProxy(DBus.system, 'org.freedesktop.ModemManager', path);
this.signal_quality = 0;
this.operator_name = null;
// Code is duplicated because the function have different signatures
this._proxy.connect('SignalQuality', Lang.bind(this, function(proxy, quality) {
this.signal_quality = quality;
this.emit('notify::signal-quality');
}));
this._proxy.connect('RegistrationInfo', Lang.bind(this, function(proxy, status, code, name) {
this.operator_name = this._findOperatorName(name, code);
this.emit('notify::operator-name');
}));
this._proxy.GetRegistrationInfoRemote(Lang.bind(this, function(result, err) {
if (err) {
log(err);
return;
}
let [status, code, name] = result;
this.operator_name = this._findOperatorName(name, code);
this.emit('notify::operator-name');
}));
this._proxy.GetSignalQualityRemote(Lang.bind(this, function(result, err) {
if (err) {
// it will return an error if the device is not connected
this.signal_quality = 0;
} else {
let [quality] = result;
this.signal_quality = quality;
}
this.emit('notify::signal-quality');
}));
},
_findOperatorName: function(name, opCode) {
if (name.length != 0 && (name.length > 6 || name.length < 5)) {
// this looks like a valid name, i.e. not an MCCMNC (that some
// devices return when not yet connected
return name;
}
if (isNaN(parseInt(name))) {
// name is definitely not a MCCMNC, so it may be a name
// after all; return that
return name;
}
let needle;
if (name.length == 0 && opCode)
needle = opCode;
else if (name.length == 6 || name.length == 5)
needle = name;
else // nothing to search
return null;
return this._findProviderForMCCMNC(needle);
},
_findProviderForMCCMNC: function(needle) {
let table = _getProvidersTable();
let needlemcc = needle.substring(0, 3);
let needlemnc = needle.substring(3, needle.length);
let name2, name3;
for (let iter in table) {
let providers = table[iter];
// Search through each country's providers
for (let i = 0; i < providers.length; i++) {
let provider = providers[i];
// Search through MCC/MNC list
let list = provider.get_gsm_mcc_mnc();
for (let j = 0; j < list.length; j++) {
let mccmnc = list[j];
// Match both 2-digit and 3-digit MNC; prefer a
// 3-digit match if found, otherwise a 2-digit one.
if (mccmnc.mcc != needlemcc)
continue; // MCC was wrong
if (!name3 && needle.length == 6 && needlemnc == mccmnc.mnc)
name3 = provider.name;
if (!name2 && needlemnc.substring(0, 2) == mccmnc.mnc.substring(0, 2))
name2 = provider.name;
if (name2 && name3)
break;
}
}
}
return name3 || name2 || null;
}
}
Signals.addSignalMethods(ModemGsm.prototype);
function ModemCdma() {
this._init.apply(this, arguments);
}
ModemCdma.prototype = {
_init: function(path) {
this._proxy = new ModemCdmaProxy(DBus.system, 'org.freedesktop.ModemManager', path);
this.signal_quality = 0;
this.operator_name = null;
this._proxy.connect('SignalQuality', Lang.bind(this, function(proxy, quality) {
this.signal_quality = quality;
this.emit('notify::signal-quality');
// receiving this signal means the device got activated
// and we can finally call GetServingSystem
if (this.operator_name == null)
this._refreshServingSystem();
}));
this._proxy.GetSignalQualityRemote(Lang.bind(this, function(result, err) {
if (err) {
// it will return an error if the device is not connected
this.signal_quality = 0;
} else {
let [quality] = result;
this.signal_quality = quality;
}
this.emit('notify::signal-quality');
}));
},
_refreshServingSystem: function() {
this._proxy.GetServingSystemRemote(Lang.bind(this, function(result, err) {
if (err) {
// it will return an error if the device is not connected
this.operator_name = null;
} else {
let [bandClass, band, id] = result;
if (name.length > 0)
this.operator_name = this._findProviderForSid(id);
else
this.operator_name = null;
}
this.emit('notify::operator-name');
}));
},
_findProviderForSid: function(sid) {
if (sid == 0)
return null;
let table = _getProvidersTable();
// Search through each country
for (let iter in table) {
let providers = table[iter];
// Search through each country's providers
for (let i = 0; i < providers.length; i++) {
let provider = providers[i];
let cdma_sid = provider.get_cdma_sid();
// Search through CDMA SID list
for (let j = 0; j < cdma_sid.length; j++) {
if (cdma_sid[j] == sid)
return provider.name;
}
}
}
return null;
}
};
Signals.addSignalMethods(ModemCdma.prototype);

View File

@ -6,7 +6,6 @@ const GLib = imports.gi.GLib;
const Shell = imports.gi.Shell;
const Main = imports.ui.main;
const MessageTray = imports.ui.messageTray;
const Gettext = imports.gettext.domain('gnome-shell');
const _ = Gettext.gettext;
@ -56,20 +55,6 @@ function spawnCommandLine(command_line) {
}
}
// spawnDesktop:
// @id: a desktop file ID
//
// Spawns the desktop file identified by @id using startup notification,
// etc, handling any errors that occur when trying to find or start
// the program.
function spawnDesktop(id) {
try {
trySpawnDesktop(id);
} catch (err) {
_handleSpawnError(id, err);
}
}
// trySpawn:
// @argv: an argv array
//
@ -117,41 +102,9 @@ function trySpawnCommandLine(command_line) {
trySpawn(argv);
}
// trySpawnDesktop:
// @id: a desktop file ID
//
// Spawns the desktop file identified by @id using startup notification.
// On error, throws an exception.
function trySpawnDesktop(id) {
let app;
// shell_app_system_load_from_desktop_file() will end up returning
// a stupid error message if the desktop file doesn't exist, but
// that's the only case it returns an error for, so we just
// substitute our own error in instead
try {
app = Shell.AppSystem.get_default().load_from_desktop_file(id + '.desktop');
} catch (err) {
throw new Error(_("No such application"));
}
try {
app.launch();
} catch(err) {
// see trySpawn
err.message = err.message.replace(/.*\((.+)\)/, '$1');
throw err;
}
}
function _handleSpawnError(command, err) {
let title = _("Execution of '%s' failed:").format(command);
let source = new MessageTray.SystemNotificationSource();
Main.messageTray.add(source);
let notification = new MessageTray.Notification(source, title, err.message);
notification.setTransient(true);
source.notify(notification);
Main.notifyError(title, err.message);
}
// killall:
@ -178,3 +131,83 @@ function killall(processName) {
logError(e, 'Failed to kill ' + processName);
}
}
// This was ported from network-manager-applet
// Copyright 2007 - 2011 Red Hat, Inc.
// Author: Dan Williams <dcbw@redhat.com>
const _IGNORED_WORDS = [
'Semiconductor',
'Components',
'Corporation',
'Communications',
'Company',
'Corp.',
'Corp',
'Co.',
'Inc.',
'Inc',
'Incorporated',
'Ltd.',
'Limited.',
'Intel?',
'chipset',
'adapter',
'[hex]',
'NDIS',
'Module'
];
const _IGNORED_PHRASES = [
'Multiprotocol MAC/baseband processor',
'Wireless LAN Controller',
'Wireless LAN Adapter',
'Wireless Adapter',
'Network Connection',
'Wireless Cardbus Adapter',
'Wireless CardBus Adapter',
'54 Mbps Wireless PC Card',
'Wireless PC Card',
'Wireless PC',
'PC Card with XJACK(r) Antenna',
'Wireless cardbus',
'Wireless LAN PC Card',
'Technology Group Ltd.',
'Communication S.p.A.',
'Business Mobile Networks BV',
'Mobile Broadband Minicard Composite Device',
'Mobile Communications AB',
'(PC-Suite Mode)'
];
function fixupPCIDescription(desc) {
desc.replace(/[_,]/, ' ');
/* Attempt to shorten ID by ignoring certain phrases */
for (let i = 0; i < _IGNORED_PHRASES.length; i++) {
let item = _IGNORED_PHRASES[i];
let pos = desc.indexOf(item);
if (pos != -1) {
let before = desc.substring(0, pos);
let after = desc.substring(pos + item.length, desc.length);
desc = before + after;
}
}
/* Attmept to shorten ID by ignoring certain individual words */
let words = desc.split(' ');
let out = [ ];
for (let i = 0; i < words; i++) {
let item = words[i];
// skip empty items (that come out from consecutive spaces)
if (item.length == 0)
continue;
if (_IGNORED_WORDS.indexOf(item) == -1) {
out.push(item);
}
}
return out.join(' ');
}

View File

@ -21,26 +21,77 @@ let METRICS = {
overviewFpsSubsequent:
{ description: "Frames rate when going to the overview, second time",
units: "frames / s" },
overviewFps5Windows:
{ description: "Frames rate when going to the overview, 5 windows open",
units: "frames / s" },
overviewFps10Windows:
{ description: "Frames rate when going to the overview, 10 windows open",
units: "frames / s" },
overviewFps5Maximized:
{ description: "Frames rate when going to the overview, 5 maximized windows open",
units: "frames / s" },
overviewFps10Maximized:
{ description: "Frames rate when going to the overview, 10 maximized windows open",
units: "frames / s" },
overviewFps5Alpha:
{ description: "Frames rate when going to the overview, 5 alpha-transparent windows open",
units: "frames / s" },
overviewFps10Alpha:
{ description: "Frames rate when going to the overview, 10 alpha-transparent windows open",
units: "frames / s" },
usedAfterOverview:
{ description: "Malloc'ed bytes after the overview is shown once",
units: "B" },
leakedAfterOverview:
{ description: "Additional malloc'ed bytes the second time the overview is shown",
units: "B" }
units: "B" },
applicationsShowTimeFirst:
{ description: "Time to switch to applications view, first time",
units: "us" },
applicationsShowTimeSubsequent:
{ description: "Time to switch to applications view, second time",
units: "us"}
};
let WINDOW_CONFIGS = [
{ width: 640, height: 480, alpha: false, maximized: false, count: 1, metric: 'overviewFpsSubsequent' },
{ width: 640, height: 480, alpha: false, maximized: false, count: 5, metric: 'overviewFps5Windows' },
{ width: 640, height: 480, alpha: false, maximized: false, count: 10, metric: 'overviewFps10Windows' },
{ width: 640, height: 480, alpha: false, maximized: true, count: 5, metric: 'overviewFps5Maximized' },
{ width: 640, height: 480, alpha: false, maximized: true, count: 10, metric: 'overviewFps10Maximized' },
{ width: 640, height: 480, alpha: true, maximized: false, count: 5, metric: 'overviewFps5Alpha' },
{ width: 640, height: 480, alpha: true, maximized: false, count: 10, metric: 'overviewFps10Alpha' }
];
function run() {
Scripting.defineScriptEvent("overviewShowStart", "Starting to show the overview");
Scripting.defineScriptEvent("overviewShowDone", "Overview finished showing");
Scripting.defineScriptEvent("afterShowHide", "After a show/hide cycle for the overview");
Scripting.defineScriptEvent("applicationsShowStart", "Starting to switch to applications view");
Scripting.defineScriptEvent("applicationsShowDone", "Done switching to applications view");
Main.overview.connect('shown', function() {
Scripting.scriptEvent('overviewShowDone');
});
yield Scripting.sleep(1000);
yield Scripting.waitLeisure();
for (let i = 0; i < 2; i++) {
for (let i = 0; i < 2 * WINDOW_CONFIGS.length; i++) {
// We go to the overview twice for each configuration; the first time
// to calculate the mipmaps for the windows, the second time to get
// a clean set of numbers.
if ((i % 2) == 0) {
let config = WINDOW_CONFIGS[i / 2];
yield Scripting.destroyTestWindows();
for (let k = 0; k < config.count; k++)
yield Scripting.createTestWindow(config.width, config.height, config.alpha, config.maximized);
yield Scripting.waitTestWindows();
yield Scripting.sleep(1000);
yield Scripting.waitLeisure();
}
Scripting.scriptEvent('overviewShowStart');
Main.overview.show();
@ -53,6 +104,21 @@ function run() {
Scripting.collectStatistics();
Scripting.scriptEvent('afterShowHide');
}
yield Scripting.destroyTestWindows();
yield Scripting.sleep(1000);
Main.overview.show();
yield Scripting.waitLeisure();
for (let i = 0; i < 2; i++) {
Scripting.scriptEvent('applicationsShowStart');
Main.overview.viewSelector.switchTab('applications');
yield Scripting.waitLeisure();
Scripting.scriptEvent('applicationsShowDone');
Main.overview.viewSelector.switchTab('windows');
yield Scripting.waitLeisure();
}
}
let showingOverview = false;
@ -64,6 +130,8 @@ let mallocUsedSize = 0;
let overviewShowCount = 0;
let firstOverviewUsedSize;
let haveSwapComplete = false;
let applicationsShowStart;
let applicationsShowCount = 0;
function script_overviewShowStart(time) {
showingOverview = true;
@ -79,6 +147,18 @@ function script_overviewShowDone(time) {
finishedShowingOverview = true;
}
function script_applicationsShowStart(time) {
applicationsShowStart = time;
}
function script_applicationsShowDone(time) {
applicationsShowCount++;
if (applicationsShowCount == 1)
METRICS.applicationsShowTimeFirst.value = time - applicationsShowStart;
else
METRICS.applicationsShowTimeSubsequent.value = time - applicationsShowStart;
}
function script_afterShowHide(time) {
if (overviewShowCount == 1) {
METRICS.usedAfterOverview.value = mallocUsedSize;
@ -113,9 +193,15 @@ function _frameDone(time) {
if (overviewShowCount == 1) {
METRICS.overviewLatencyFirst.value = overviewLatency;
METRICS.overviewFpsFirst.value = fps;
} else {
} else if (overviewShowCount == 2) {
METRICS.overviewLatencySubsequent.value = overviewLatency;
METRICS.overviewFpsSubsequent.value = fps;
}
// Other than overviewFpsFirst, we collect FPS metrics the second
// we show each window configuration. overviewShowCount is 1,2,3...
if (overviewShowCount % 2 == 0) {
let config = WINDOW_CONFIGS[(overviewShowCount / 2) - 1];
METRICS[config.metric].value = fps;
}
}
}

View File

@ -87,7 +87,7 @@ AltTabPopup.prototype = {
let [childMinHeight, childNaturalHeight] = this._appSwitcher.actor.get_preferred_height(primary.width - hPadding);
let [childMinWidth, childNaturalWidth] = this._appSwitcher.actor.get_preferred_width(childNaturalHeight);
childBox.x1 = Math.max(primary.x + leftPadding, primary.x + Math.floor((primary.width - childNaturalWidth) / 2));
childBox.x2 = Math.min(primary.width - hPadding, childBox.x1 + childNaturalWidth);
childBox.x2 = Math.min(primary.x + primary.width - hPadding, childBox.x1 + childNaturalWidth);
childBox.y1 = primary.y + Math.floor((primary.height - childNaturalHeight) / 2);
childBox.y2 = childBox.y1 + childNaturalHeight;
this._appSwitcher.actor.allocate(childBox, flags);
@ -376,7 +376,15 @@ AltTabPopup.prototype = {
this.destroy();
},
_popModal: function() {
if (this._haveModal) {
Main.popModal(this.actor);
this._haveModal = false;
}
},
destroy : function() {
this._popModal();
if (this.actor.visible) {
Tweener.addTween(this.actor,
{ opacity: 0,
@ -392,8 +400,7 @@ AltTabPopup.prototype = {
},
_onDestroy : function() {
if (this._haveModal)
Main.popModal(this.actor);
this._popModal();
if (this._thumbnails)
this._destroyThumbnails();

View File

@ -86,10 +86,14 @@ AlphabeticalView.prototype = {
if (vfade)
offset = vfade.fade_offset;
if (icon.y < value + offset)
value = Math.max(0, icon.y - offset);
else if (icon.y + icon.height > value + pageSize - offset)
value = Math.min(upper, icon.y + icon.height + offset - pageSize);
// If this gets called as part of a right-click, the actor
// will be needs_allocation, and so "icon.y" would return 0
let box = icon.get_allocation_box();
if (box.y1 < value + offset)
value = Math.max(0, box.y1 - offset);
else if (box.y2 > value + pageSize - offset)
value = Math.min(upper, box.y2 + offset - pageSize);
else
return;
@ -412,6 +416,10 @@ AppWellIcon.prototype = {
this._removeMenuTimeout();
Main.overview.beginItemDrag(this);
}));
this._draggable.connect('drag-cancelled', Lang.bind(this,
function () {
Main.overview.cancelledItemDrag(this);
}));
this._draggable.connect('drag-end', Lang.bind(this,
function () {
Main.overview.endItemDrag(this);
@ -505,6 +513,8 @@ AppWellIcon.prototype = {
this._menuManager.addMenu(this._menu);
}
this.actor.set_hover(true);
this.actor.show_tooltip();
this._menu.popup();
return false;
@ -568,6 +578,9 @@ AppIconMenu.prototype = {
PopupMenu.PopupMenu.prototype._init.call(this, source.actor, 0.5, side, 0);
// We want to keep the item hovered while the menu is up
this.blockSourceEvents = true;
this._source = source;
this.connect('activate', Lang.bind(this, this._onActivate));

View File

@ -2,6 +2,7 @@
const Clutter = imports.gi.Clutter;
const Lang = imports.lang;
const Meta = imports.gi.Meta;
const St = imports.gi.St;
const Shell = imports.gi.Shell;
@ -40,80 +41,80 @@ BoxPointer.prototype = {
this._border.connect('repaint', Lang.bind(this, this._drawBorder));
this._container.add_actor(this._border);
this.bin.raise(this._border);
this._xOffset = 0;
this._yOffset = 0;
this._xPosition = 0;
this._yPosition = 0;
},
show: function(animate, onComplete) {
let x = this.actor.x;
let y = this.actor.y;
let themeNode = this.actor.get_theme_node();
let rise = themeNode.get_length('-arrow-rise');
this.actor.opacity = 0;
this.opacity = 0;
this.actor.show();
if (animate) {
switch (this._arrowSide) {
case St.Side.TOP:
this.actor.y -= rise;
this.yOffset = -rise;
break;
case St.Side.BOTTOM:
this.actor.y += rise;
this.yOffset = rise;
break;
case St.Side.LEFT:
this.actor.x -= rise;
this.xOffset = -rise;
break;
case St.Side.RIGHT:
this.actor.x += rise;
this.xOffset = rise;
break;
}
}
Tweener.addTween(this.actor, { opacity: 255,
x: x,
y: y,
transition: "linear",
onComplete: onComplete,
time: POPUP_ANIMATION_TIME });
Tweener.addTween(this, { opacity: 255,
xOffset: 0,
yOffset: 0,
transition: "linear",
onComplete: onComplete,
time: POPUP_ANIMATION_TIME });
},
hide: function(animate, onComplete) {
let x = this.actor.x;
let y = this.actor.y;
let originalX = this.actor.x;
let originalY = this.actor.y;
let xOffset = 0;
let yOffset = 0;
let themeNode = this.actor.get_theme_node();
let rise = themeNode.get_length('-arrow-rise');
if (animate) {
switch (this._arrowSide) {
case St.Side.TOP:
y += rise;
yOffset = rise;
break;
case St.Side.BOTTOM:
y -= rise;
yOffset = -rise;
break;
case St.Side.LEFT:
x += rise;
xOffset = rise;
break;
case St.Side.RIGHT:
x -= rise;
xOffset = -rise;
break;
}
}
Tweener.addTween(this.actor, { opacity: 0,
x: x,
y: y,
transition: "linear",
time: POPUP_ANIMATION_TIME,
onComplete: Lang.bind(this, function () {
this.actor.hide();
this.actor.x = originalX;
this.actor.y = originalY;
if (onComplete)
onComplete();
})
});
Tweener.addTween(this, { opacity: 0,
xOffset: xOffset,
yOffset: yOffset,
transition: "linear",
time: POPUP_ANIMATION_TIME,
onComplete: Lang.bind(this, function () {
this.actor.hide();
this.xOffset = 0;
this.yOffset = 0;
if (onComplete)
onComplete();
})
});
},
_adjustAllocationForArrow: function(isWidth, alloc) {
@ -176,6 +177,9 @@ BoxPointer.prototype = {
break;
}
this.bin.allocate(childBox, flags);
if (this._sourceActor && this._sourceActor.mapped)
this._reposition(this._sourceActor, this._gap, this._alignment);
},
_drawBorder: function(area) {
@ -306,13 +310,20 @@ BoxPointer.prototype = {
// so that we can query the correct size.
this.actor.show();
this._sourceActor = sourceActor;
this._gap = gap;
this._alignment = alignment;
this._reposition(sourceActor, gap, alignment);
},
_reposition: function(sourceActor, gap, alignment) {
// Position correctly relative to the sourceActor
let sourceNode = sourceActor.get_theme_node();
let sourceContentBox = sourceNode.get_content_box(sourceActor.get_allocation_box());
let [sourceX, sourceY] = sourceActor.get_transformed_position();
let [sourceWidth, sourceHeight] = sourceActor.get_transformed_size();
let sourceCenterX = sourceX + sourceContentBox.x1 + (sourceContentBox.x2 - sourceContentBox.x1) / 2;
let sourceCenterY = sourceY + sourceContentBox.y1 + (sourceContentBox.y2 - sourceContentBox.y1) / 2;
let sourceAllocation = Shell.util_get_transformed_allocation(sourceActor);
let sourceCenterX = sourceAllocation.x1 + sourceContentBox.x1 + (sourceContentBox.x2 - sourceContentBox.x1) / 2;
let sourceCenterY = sourceAllocation.y1 + sourceContentBox.y1 + (sourceContentBox.y2 - sourceContentBox.y1) / 2;
let [minWidth, minHeight, natWidth, natHeight] = this.actor.get_preferred_size();
// We also want to keep it onscreen, and separated from the
@ -330,16 +341,16 @@ BoxPointer.prototype = {
switch (this._arrowSide) {
case St.Side.TOP:
resY = sourceY + sourceHeight + gap;
resY = sourceAllocation.y2 + gap;
break;
case St.Side.BOTTOM:
resY = sourceY - natHeight - gap;
resY = sourceAllocation.y1 - natHeight - gap;
break;
case St.Side.LEFT:
resX = sourceX + sourceWidth + gap;
resX = sourceAllocation.x2 + gap;
break;
case St.Side.RIGHT:
resX = sourceX - natWidth - gap;
resX = sourceAllocation.x1 - natWidth - gap;
break;
}
@ -373,9 +384,9 @@ BoxPointer.prototype = {
parent = parent.get_parent();
}
// Actually set the position
this.actor.x = Math.floor(x);
this.actor.y = Math.floor(y);
this._xPosition = Math.floor(x);
this._yPosition = Math.floor(y);
this._shiftActor();
},
// @origin: Coordinate specifying middle of the arrow, along
@ -386,5 +397,42 @@ BoxPointer.prototype = {
this._arrowOrigin = origin;
this._border.queue_repaint();
}
},
_shiftActor : function() {
// Since the position of the BoxPointer depends on the allocated size
// of the BoxPointer and the position of the source actor, trying
// to position the BoxPoiner via the x/y properties will result in
// allocation loops and warnings. Instead we do the positioning via
// the anchor point, which is independent of allocation, and leave
// x == y == 0.
this.actor.set_anchor_point(-(this._xPosition + this._xOffset),
-(this._yPosition + this._yOffset));
},
set xOffset(offset) {
this._xOffset = offset;
this._shiftActor();
},
get xOffset() {
return this._xOffset;
},
set yOffset(offset) {
this._yOffset = offset;
this._shiftActor();
},
get yOffset() {
return this._yOffset;
},
set opacity(opacity) {
this.actor.opacity = opacity;
},
get opacity() {
return this.actor.opacity;
}
};

View File

@ -36,8 +36,8 @@ Chrome.prototype = {
this._trackedActors = [];
global.gdk_screen.connect('monitors-changed',
Lang.bind(this, this._monitorsChanged));
global.screen.connect('monitors-changed',
Lang.bind(this, this._monitorsChanged));
global.screen.connect('restacked',
Lang.bind(this, this._windowsRestacked));
@ -335,6 +335,11 @@ Chrome.prototype = {
this._updateVisibility();
this._queueUpdateRegions();
}
// Figure out where the pointer is in case we lost track of
// it during a grab. (In particular, if a trayicon popup menu
// is dismissed, see if we need to close the message tray.)
global.sync_pointer();
},
_updateRegions: function() {

View File

@ -281,6 +281,7 @@ CtrlAltTabPopup.prototype = {
},
_onDestroy : function() {
this._popModal();
if (this._keyPressEventId)
this.actor.disconnect(this._keyPressEventId);
if (this._keyReleaseEventId)

View File

@ -283,20 +283,37 @@ Dash.prototype = {
Lang.bind(this, this._onDragBegin));
Main.overview.connect('item-drag-end',
Lang.bind(this, this._onDragEnd));
Main.overview.connect('item-drag-cancelled',
Lang.bind(this, this._onDragCancelled));
Main.overview.connect('window-drag-begin',
Lang.bind(this, this._onDragBegin));
Main.overview.connect('window-drag-cancelled',
Lang.bind(this, this._onDragCancelled));
Main.overview.connect('window-drag-end',
Lang.bind(this, this._onDragEnd));
},
_onDragBegin: function() {
this._dragCancelled = false;
this._dragMonitor = {
dragMotion: Lang.bind(this, this._onDragMotion)
};
DND.addDragMonitor(this._dragMonitor);
},
_onDragCancelled: function() {
this._dragCancelled = true;
this._endDrag();
},
_onDragEnd: function() {
if (this._dragCancelled)
return;
this._endDrag();
},
_endDrag: function() {
this._clearDragPlaceholder();
if (this._favRemoveTarget) {
this._favRemoveTarget.actor.hide();
@ -372,6 +389,8 @@ Dash.prototype = {
Lang.bind(this, function() {
display.actor.opacity = 255;
}));
display.actor.set_tooltip_text(app.get_name());
let item = new DashItemContainer();
item.setChild(display.actor);

View File

@ -185,21 +185,6 @@ DateMenuButton.prototype = {
}
let displayDate = new Date();
let msecRemaining;
if (showSeconds) {
msecRemaining = 1000 - displayDate.getMilliseconds();
if (msecRemaining < 50) {
displayDate.setSeconds(displayDate.getSeconds() + 1);
msecRemaining += 1000;
}
} else {
msecRemaining = 60000 - (1000 * displayDate.getSeconds() +
displayDate.getMilliseconds());
if (msecRemaining < 500) {
displayDate.setMinutes(displayDate.getMinutes() + 1);
msecRemaining += 60000;
}
}
this._clock.set_text(displayDate.toLocaleFormat(clockFormat));
@ -209,19 +194,19 @@ DateMenuButton.prototype = {
dateFormat = _("%A %B %e, %Y");
this._date.set_text(displayDate.toLocaleFormat(dateFormat));
Mainloop.timeout_add(msecRemaining, Lang.bind(this, this._updateClockAndDate));
Mainloop.timeout_add_seconds(1, Lang.bind(this, this._updateClockAndDate));
return false;
},
_onPreferencesActivate: function() {
this.menu.close();
Util.spawnDesktop('gnome-datetime-panel');
let app = Shell.AppSystem.get_default().get_app('gnome-datetime-panel.desktop');
app.activate(-1);
},
_onOpenCalendarActivate: function() {
this.menu.close();
// TODO: pass '-c calendar' (to force the calendar at startup)
// TODO: pass the selected day
Util.spawnDesktop('evolution');
},
Util.spawn(['evolution', '-c', 'calendar']);
}
};

View File

@ -480,7 +480,9 @@ _Draggable.prototype = {
let [parentX, parentY] = this._dragOrigParent.get_transformed_position();
let [parentWidth, parentHeight] = this._dragOrigParent.get_size();
let [parentScaledWidth, parentScaledHeight] = this._dragOrigParent.get_transformed_size();
let parentScale = parentScaledWidth / parentWidth;
let parentScale = 1.0;
if (parentWidth != 0)
parentScale = parentScaledWidth / parentWidth;
x = parentX + parentScale * this._dragOrigX;
y = parentY + parentScale * this._dragOrigY;
@ -496,6 +498,7 @@ _Draggable.prototype = {
},
_cancelDrag: function(eventTime) {
this.emit('drag-cancelled', eventTime);
this._dragInProgress = false;
let [snapBackX, snapBackY, snapBackScale] = this._getRestoreLocation();
@ -504,6 +507,9 @@ _Draggable.prototype = {
if (!this._buttonDown)
this._dragComplete();
this.emit('drag-end', eventTime, false);
if (!this._dragOrigParent)
this._dragActor.destroy();
return;
}

View File

@ -66,16 +66,20 @@ const logoutDialogContent = {
uninhibitedDescriptionWithUser: _("%s will be logged out automatically in %d seconds."),
uninhibitedDescription: _("You will be logged out automatically in %d seconds."),
endDescription: _("Logging out of the system."),
confirmButtonText: _("Log Out"),
confirmButtons: [{ signal: 'ConfirmedLogout',
label: _("Log Out") }],
iconStyleClass: 'end-session-dialog-logout-icon'
};
const shutdownDialogContent = {
subject: _("Shut Down"),
inhibitedDescription: _("Click Shut Down to quit these applications and shut down the system."),
uninhibitedDescription: _("The system will shut down automatically in %d seconds."),
endDescription: _("Shutting down the system."),
confirmButtonText: _("Shut Down"),
subject: _("Power Off"),
inhibitedDescription: _("Click Power Off to quit these applications and power off the system."),
uninhibitedDescription: _("The system will power off automatically in %d seconds."),
endDescription: _("Powering off the system."),
confirmButtons: [{ signal: 'ConfirmedReboot',
label: _("Restart") },
{ signal: 'ConfirmedShutdown',
label: _("Power Off") }],
iconName: 'system-shutdown',
iconStyleClass: 'end-session-dialog-shutdown-icon'
};
@ -85,7 +89,8 @@ const restartDialogContent = {
inhibitedDescription: _("Click Restart to quit these applications and restart the system."),
uninhibitedDescription: _("The system will restart automatically in %d seconds."),
endDescription: _("Restarting the system."),
confirmButtonText: _("Restart"),
confirmButtons: [{ signal: 'ConfirmedReboot',
label: _("Restart") }],
iconName: 'system-shutdown',
iconStyleClass: 'end-session-dialog-shutdown-icon'
};
@ -233,7 +238,7 @@ EndSessionDialog.prototype = {
__proto__: ModalDialog.ModalDialog.prototype,
_init: function() {
ModalDialog.ModalDialog.prototype._init.call(this);
ModalDialog.ModalDialog.prototype._init.call(this, { styleClass: 'end-session-dialog' });
this._user = Gdm.UserManager.ref_default().get_user(GLib.get_user_name());
@ -288,12 +293,26 @@ EndSessionDialog.prototype = {
this.contentLayout.add(scrollView,
{ x_fill: true,
y_fill: true });
scrollView.hide();
this._applicationList = new St.BoxLayout({ vertical: true });
scrollView.add_actor(this._applicationList,
{ x_fill: true,
y_fill: true,
x_align: St.Align.START,
y_align: St.Align.MIDDLE });
this._applicationList.connect('actor-added',
Lang.bind(this, function() {
if (this._applicationList.get_children().length == 1)
scrollView.show();
}));
this._applicationList.connect('actor-removed',
Lang.bind(this, function() {
if (this._applicationList.get_children().length == 0)
scrollView.hide();
}));
},
_onDestroy: function() {
@ -347,8 +366,10 @@ EndSessionDialog.prototype = {
if (this._user.is_loaded && !dialogContent.iconName) {
let iconFile = this._user.get_icon_file();
this._setIconFromFile(iconFile, dialogContent.iconStyleClass);
if (GLib.file_test(iconFile, GLib.FileTest.EXISTS))
this._setIconFromFile(iconFile, dialogContent.iconStyleClass);
else
this._setIconFromName('avatar-default', dialogContent.iconStyleClass);
} else if (dialogContent.iconName) {
this._setIconFromName(dialogContent.iconName,
dialogContent.iconStyleClass);
@ -392,18 +413,27 @@ EndSessionDialog.prototype = {
return;
let dialogContent = DialogContent[this._type];
let confirmButtonText = _("Confirm");
let buttons = [{ action: Lang.bind(this, this.cancel),
label: _("Cancel"),
key: Clutter.Escape }];
if (dialogContent.confirmButtonText)
confirmButtonText = dialogContent.confirmButtonText;
for (let i = 0; i < dialogContent.confirmButtons.length; i++) {
let signal = dialogContent.confirmButtons[i].signal;
let label = dialogContent.confirmButtons[i].label;
buttons.push({ action: Lang.bind(this, function() {
this._confirm(signal);
}),
label: label });
}
this.setButtons([{ label: _("Cancel"),
action: Lang.bind(this, this.cancel),
key: Clutter.Escape
},
{ label: confirmButtonText,
action: Lang.bind(this, this._confirm)
}]);
this.setButtons(buttons);
},
close: function() {
ModalDialog.ModalDialog.prototype.close.call(this);
DBus.session.emit_signal('/org/gnome/SessionManager/EndSessionDialog',
'org.gnome.SessionManager.EndSessionDialog',
'Closed', '', []);
},
cancel: function() {
@ -414,12 +444,12 @@ EndSessionDialog.prototype = {
this.close(global.get_current_time());
},
_confirm: function() {
_confirm: function(signal) {
this._fadeOutDialog();
this._stopTimer();
DBus.session.emit_signal('/org/gnome/SessionManager/EndSessionDialog',
'org.gnome.SessionManager.EndSessionDialog',
'Confirmed', '', []);
signal, '', []);
},
_onOpened: function() {
@ -434,7 +464,11 @@ EndSessionDialog.prototype = {
time: this._secondsLeft,
transition: 'linear',
onUpdate: Lang.bind(this, this._updateContent),
onComplete: Lang.bind(this, this._confirm),
onComplete: Lang.bind(this, function() {
let dialogContent = DialogContent[this._type];
let button = dialogContent.confirmButtons[dialogContent.confirmButtons.length - 1];
this._confirm(button.signal);
}),
});
},

View File

@ -64,6 +64,11 @@ function init() {
Tweener.init();
String.prototype.format = Format.format;
// Work around https://bugzilla.mozilla.org/show_bug.cgi?id=508783
Date.prototype.toLocaleFormat = function(format) {
return Shell.util_format_date(format, this.getTime());
};
// Set the default direction for St widgets (this needs to be done before any use of St)
if (Gettext_gtk30.gettext('default:LTR') == 'default:RTL') {
St.Widget.set_default_direction(St.TextDirection.RTL);

View File

@ -67,7 +67,13 @@ function loadExtension(dir, enabled, type) {
return;
}
let [success, metadataContents, len, etag] = metadataFile.load_contents(null);
let metadataContents;
try {
metadataContents = Shell.get_file_contents_utf8_sync(metadataFile.get_path());
} catch (e) {
global.logError(baseErrorString + 'Failed to load metadata.json: ' + e);
return;
}
let meta;
try {
meta = JSON.parse(metadataContents);

View File

@ -281,8 +281,11 @@ IconGrid.prototype = {
}
},
childrenInRow: function(rowWidth) {
return this._computeLayout(rowWidth)[0];
},
_computeLayout: function (forWidth) {
let children = this._grid.get_children();
let nColumns = 0;
let usedWidth = 0;
while ((this._colLimit == null || nColumns < this._colLimit) &&

View File

@ -86,6 +86,9 @@ function start() {
global.logError = _logError;
global.log = _logDebug;
// Chain up async errors reported from C
global.connect('notify-error', function (global, msg, detail) { notifyError(msg, detail); });
Gio.DesktopAppInfo.set_desktop_env('GNOME');
shellDBusService = new ShellDBus.GnomeShell();
@ -133,6 +136,7 @@ function start() {
// Set up stage hierarchy to group all UI actors under one container.
uiGroup = new Clutter.Group();
St.set_ui_root(global.stage, uiGroup);
global.window_group.reparent(uiGroup);
global.overlay_group.reparent(uiGroup);
global.stage.add_actor(uiGroup);
@ -189,7 +193,7 @@ function start() {
// Attempt to become a PolicyKit authentication agent
PolkitAuthenticationAgent.init()
global.gdk_screen.connect('monitors-changed', _relayout);
global.screen.connect('monitors-changed', _relayout);
ExtensionSystem.init();
ExtensionSystem.loadExtensions();
@ -216,7 +220,11 @@ function start() {
}
global.screen.connect('notify::n-workspaces', _nWorkspacesChanged);
Mainloop.idle_add(_nWorkspacesChanged);
global.screen.connect('window-entered-monitor', _windowEnteredMonitor);
global.screen.connect('window-left-monitor', _windowLeftMonitor);
_nWorkspacesChanged();
}
let _workspaces = [];
@ -262,12 +270,32 @@ function _checkWorkspaces() {
emptyWorkspaces.push(false);
}
let activeWorkspaceIndex = global.screen.get_active_workspace_index();
let removingCurrentWorkspace = (emptyWorkspaces[activeWorkspaceIndex] &&
activeWorkspaceIndex < emptyWorkspaces.length - 1);
// Don't enter the overview when removing multiple empty workspaces at startup
let showOverview = (removingCurrentWorkspace &&
!emptyWorkspaces.every(function(x) { return x; }));
if (removingCurrentWorkspace) {
// "Merge" the empty workspace we are removing with the one at the end
wm.blockAnimations();
}
// Delete other empty workspaces; do it from the end to avoid index changes
for (i = emptyWorkspaces.length - 2; i >= 0; i--) {
if (emptyWorkspaces[i])
global.screen.remove_workspace(_workspaces[i], global.get_current_time());
}
if (removingCurrentWorkspace) {
global.screen.get_workspace_by_index(global.screen.n_workspaces - 1).activate(global.get_current_time());
wm.unblockAnimations();
if (!overview.visible && showOverview)
overview.show();
}
_checkWorkspacesId = 0;
return false;
}
@ -283,6 +311,20 @@ function _windowRemoved(workspace, window) {
});
}
function _windowLeftMonitor(metaScreen, monitorIndex, metaWin) {
// If the window left the primary monitor, that
// might make that workspace empty
if (monitorIndex == global.get_primary_monitor_index())
_queueCheckWorkspaces();
}
function _windowEnteredMonitor(metaScreen, monitorIndex, metaWin) {
// If the window entered the primary monitor, that
// might make that workspace non-empty
if (monitorIndex == global.get_primary_monitor_index())
_queueCheckWorkspaces();
}
function _queueCheckWorkspaces() {
if (_checkWorkspacesId == 0)
_checkWorkspacesId = Meta.later_add(Meta.LaterType.BEFORE_REDRAW, _checkWorkspaces);
@ -375,6 +417,27 @@ function loadTheme() {
themeContext.set_theme (theme);
}
/**
* notifyError:
* @msg: An error message
* @details: Additional information
*
* See shell_global_notify_problem().
*/
function notifyError(msg, details) {
// Also print to stderr so it's logged somewhere
if (details)
log("error: " + msg + ": " + details);
else
log("error: " + msg)
let source = new MessageTray.SystemNotificationSource();
messageTray.add(source);
let notification = new MessageTray.Notification(source, msg, details);
notification.setTransient(true);
source.notify(notification);
}
/**
* _log:
* @category: string message type ('info', 'error')
@ -418,28 +481,67 @@ function _getAndClearErrorStack() {
function _relayout() {
let monitors = global.get_monitors();
if (monitors.length != hotCorners.length) {
// destroy old corners
for (let i = 0; i < hotCorners.length; i++)
hotCorners[i].destroy();
hotCorners = [];
for (let i = 0; i < monitors.length; i++)
hotCorners[i] = new Panel.HotCorner();
}
// destroy old corners
for (let i = 0; i < hotCorners.length; i++)
hotCorners[i].destroy();
hotCorners = [];
let primary = global.get_primary_monitor();
for (let i = 0; i < monitors.length; i++) {
let monitor = monitors[i];
let corner = hotCorners[i];
let isPrimary = (monitor.x == primary.x &&
monitor.y == primary.y &&
monitor.width == primary.width &&
monitor.height == primary.height);
let cornerX = monitor.x;
let cornerY = monitor.y;
if (St.Widget.get_default_direction() == St.TextDirection.RTL)
corner.actor.set_position(monitor.x + monitor.width, monitor.y);
cornerX += monitor.width;
let haveTopLeftCorner = true;
/* Check if we have a top left (right for RTL) corner.
* I.e. if there is no monitor directly above or to the left(right) */
let besideX;
if (St.Widget.get_default_direction() == St.TextDirection.RTL)
besideX = monitor.x + 1;
else
corner.actor.set_position(monitor.x, monitor.y);
besideX = cornerX - 1;
let besideY = cornerY;
let aboveX = cornerX;
let aboveY = cornerY - 1;
for (let j = 0; j < monitors.length; j++) {
if (i == j)
continue;
let otherMonitor = monitors[j];
if (besideX >= otherMonitor.x &&
besideX < otherMonitor.x + otherMonitor.width &&
besideY >= otherMonitor.y &&
besideY < otherMonitor.y + otherMonitor.height) {
haveTopLeftCorner = false;
break;
}
if (aboveX >= otherMonitor.x &&
aboveX < otherMonitor.x + otherMonitor.width &&
aboveY >= otherMonitor.y &&
aboveY < otherMonitor.y + otherMonitor.height) {
haveTopLeftCorner = false;
break;
}
}
/* We only want hot corners where there is a natural top-left
* corner, and on the primary monitor */
if (!isPrimary && !haveTopLeftCorner)
continue;
let corner = new Panel.HotCorner(isPrimary ? panel.button : null);
hotCorners.push(corner);
corner.actor.set_position(cornerX, cornerY);
if (isPrimary)
panel.setHotCorner(corner);
}

View File

@ -108,6 +108,12 @@ URLHighlighter.prototype = {
}
this.setMarkup(text, allowMarkup);
this.actor.connect('button-press-event', Lang.bind(this, function(actor, event) {
// Keep Notification.actor from seeing this and taking
// a pointer grab, which would block our button-release-event
// handler, if an URL is clicked
return this._findUrlAtPos(event) != -1;
}));
this.actor.connect('button-release-event', Lang.bind(this, function (actor, event) {
let urlId = this._findUrlAtPos(event);
if (urlId != -1) {
@ -406,24 +412,23 @@ Notification.prototype = {
this._bannerBodyMarkup = false;
this._titleFitsInBannerMode = true;
this._spacing = 0;
this._scrollPolicy = Gtk.PolicyType.AUTOMATIC;
source.connect('destroy', Lang.bind(this,
// Avoid passing 'source' as an argument to this.destroy()
function () {
this.destroy();
function (source, reason) {
this.destroy(reason);
}));
this.actor = new St.Table({ name: 'notification',
reactive: true });
this.actor.connect('style-changed', Lang.bind(this, this._styleChanged));
this.actor.connect('button-release-event', Lang.bind(this,
function (actor, event) {
if (!this._actionArea ||
!this._actionArea.contains(event.get_source()))
this._onClicked();
}));
this.actor = new St.Button();
this.actor._delegate = this;
this.actor.connect('clicked', Lang.bind(this, this._onClicked));
this.actor.connect('destroy', Lang.bind(this, this._onDestroy));
this._table = new St.Table({ name: 'notification',
reactive: true });
this._table.connect('style-changed', Lang.bind(this, this._styleChanged));
this.actor.set_child(this._table);
this._buttonFocusManager = St.FocusManager.get_for_stage(global.stage);
// The first line should have the title, followed by the
@ -435,10 +440,10 @@ Notification.prototype = {
this._bannerBox.connect('get-preferred-width', Lang.bind(this, this._bannerBoxGetPreferredWidth));
this._bannerBox.connect('get-preferred-height', Lang.bind(this, this._bannerBoxGetPreferredHeight));
this._bannerBox.connect('allocate', Lang.bind(this, this._bannerBoxAllocate));
this.actor.add(this._bannerBox, { row: 0,
col: 1,
y_expand: false,
y_fill: false });
this._table.add(this._bannerBox, { row: 0,
col: 1,
y_expand: false,
y_fill: false });
this._titleLabel = new St.Label();
this._bannerBox.add_actor(this._titleLabel);
@ -468,31 +473,39 @@ Notification.prototype = {
this._customContent = params.customContent;
let oldFocus = global.stage.key_focus;
if (this._icon)
this._icon.destroy();
// We always clear the content area if we don't have custom
// content because it might contain the @banner that didn't
// fit in the banner mode.
if (this._scrollArea && (!this._customContent || params.clear)) {
if (oldFocus && this._scrollArea.contains(oldFocus))
this.actor.grab_key_focus();
this._scrollArea.destroy();
this._scrollArea = null;
this._contentArea = null;
}
if (this._actionArea && params.clear) {
if (oldFocus && this._actionArea.contains(oldFocus))
this.actor.grab_key_focus();
this._actionArea.destroy();
this._actionArea = null;
this._buttonBox = null;
}
if (!this._scrollArea && !this._actionArea)
this.actor.remove_style_class_name('multi-line-notification');
this._table.remove_style_class_name('multi-line-notification');
this._icon = params.icon || this.source.createNotificationIcon();
this.actor.add(this._icon, { row: 0,
col: 0,
x_expand: false,
y_expand: false,
y_fill: false,
y_align: St.Align.START });
this._table.add(this._icon, { row: 0,
col: 0,
x_expand: false,
y_expand: false,
y_fill: false,
y_align: St.Align.START });
title = title ? _fixMarkup(title.replace(/\n/g, ' '), params.titleMarkup) : '';
this._titleLabel.clutter_text.set_markup('<b>' + title + '</b>');
@ -518,25 +531,38 @@ Notification.prototype = {
this._updated();
},
setIconVisible: function(visible) {
this._icon.visible = visible;
},
enableScrolling: function(enableScrolling) {
this._scrollPolicy = enableScrolling ? Gtk.PolicyType.AUTOMATIC : Gtk.PolicyType.NEVER;
if (this._scrollArea)
this._scrollArea.vscrollbar_policy = this._scrollPolicy;
},
_createScrollArea: function() {
this._table.add_style_class_name('multi-line-notification');
this._scrollArea = new St.ScrollView({ name: 'notification-scrollview',
vscrollbar_policy: this._scrollPolicy,
hscrollbar_policy: Gtk.PolicyType.NEVER,
vfade: true });
this._table.add(this._scrollArea, { row: 1, col: 1 });
this._contentArea = new St.BoxLayout({ name: 'notification-body',
vertical: true });
this._scrollArea.add_actor(this._contentArea);
// If we know the notification will be expandable, we need to add
// the banner text to the body as the first element.
this._addBannerBody();
},
// addActor:
// @actor: actor to add to the body of the notification
//
// Appends @actor to the notification's body
addActor: function(actor, style) {
if (!this._scrollArea) {
this.actor.add_style_class_name('multi-line-notification');
this._scrollArea = new St.ScrollView({ name: 'notification-scrollview',
vscrollbar_policy: Gtk.PolicyType.AUTOMATIC,
hscrollbar_policy: Gtk.PolicyType.NEVER,
vfade: true });
this.actor.add(this._scrollArea, { row: 1,
col: 1 });
this._contentArea = new St.BoxLayout({ name: 'notification-body',
vertical: true });
this._scrollArea.add_actor(this._contentArea);
// If we know the notification will be expandable, we need to add
// the banner text to the body as the first element.
this._addBannerBody();
this._createScrollArea();
}
this._contentArea.add(actor, style ? style : {});
@ -571,11 +597,6 @@ Notification.prototype = {
//
// Scrolls the content area (if scrollable) to the indicated edge
scrollTo: function(side) {
// Hack to force a relayout, since the caller probably
// just added or removed something to scrollArea, and
// the adjustment needs to reflect that.
global.stage.get_actor_at_pos(Clutter.PickMode.REACTIVE, 0, 0);
let adjustment = this._scrollArea.vscroll.adjustment;
if (side == St.Side.TOP)
adjustment.value = adjustment.lower;
@ -605,8 +626,8 @@ Notification.prototype = {
props.row = 2;
props.col = 1;
this.actor.add_style_class_name('multi-line-notification');
this.actor.add(this._actionArea, props);
this._table.add_style_class_name('multi-line-notification');
this._table.add(this._actionArea, props);
this._updated();
},
@ -667,7 +688,7 @@ Notification.prototype = {
},
_styleChanged: function() {
this._spacing = this.actor.get_theme_node().get_length('spacing-columns');
this._spacing = this._table.get_theme_node().get_length('spacing-columns');
},
_bannerBoxGetPreferredWidth: function(actor, forHeight, alloc) {
@ -712,22 +733,29 @@ Notification.prototype = {
// Make _bannerLabel visible if the entire notification
// fits on one line, or if the notification is currently
// unexpanded and only showing one line anyway.
if (!this.expanded || (bannerFits && this.actor.row_count == 1))
if (!this.expanded || (bannerFits && this._table.row_count == 1))
this._bannerLabel.opacity = 255;
}
// If the banner doesn't fully fit in the banner box, we possibly need to add the
// banner to the body. We can't do that from here though since that will force a
// relayout, so we add it to the main loop.
if (!bannerFits)
Mainloop.idle_add(Lang.bind(this,
function() {
if (!bannerFits && this._canExpandContent())
Meta.later_add(Meta.LaterType.BEFORE_REDRAW,
Lang.bind(this,
function() {
if (this._canExpandContent()) {
this._addBannerBody();
if (!this._titleFitsInBannerMode)
this.actor.add_style_class_name('multi-line-notification');
this._table.add_style_class_name('multi-line-notification');
this._updated();
return false;
}));
}
return false;
}));
},
_canExpandContent: function() {
return this._bannerBodyText ||
(!this._titleFitsInBannerMode && !this._table.has_style_class_name('multi-line-notification'));
},
_updated: function() {
@ -745,7 +773,7 @@ Notification.prototype = {
this._titleLabel.clutter_text.line_wrap = true;
this._titleLabel.clutter_text.line_wrap_mode = Pango.WrapMode.WORD_CHAR;
this._titleLabel.clutter_text.ellipsize = Pango.EllipsizeMode.NONE;
} else if (this.actor.row_count > 1 && this._bannerLabel.opacity != 0) {
} else if (this._table.row_count > 1 && this._bannerLabel.opacity != 0) {
// We always hide the banner if the notification has additional content.
//
// We don't need to wrap the banner that doesn't fit the way we wrap the
@ -810,6 +838,7 @@ Notification.prototype = {
destroy: function(reason) {
this._destroyedReason = reason;
this.actor.destroy();
this.actor._delegate = null;
}
};
Signals.addSignalMethods(Notification.prototype);
@ -824,9 +853,13 @@ Source.prototype = {
_init: function(title) {
this.title = title;
this._iconBin = new St.Bin({ width: this.ICON_SIZE,
height: this.ICON_SIZE });
height: this.ICON_SIZE,
x_fill: true,
y_fill: true });
this.isTransient = false;
this.isChat = false;
this.notifications = [];
},
setTransient: function(isTransient) {
@ -846,30 +879,40 @@ Source.prototype = {
return this._iconBin;
},
notify: function(notification) {
if (this.notification) {
this.notification.disconnect(this._notificationClickedId);
this.notification.disconnect(this._notificationDestroyedId);
pushNotification: function(notification) {
if (this.notifications.indexOf(notification) < 0) {
this.notifications.push(notification);
this.emit('notification-added', notification);
}
this.notification = notification;
this._notificationClickedId = notification.connect('clicked', Lang.bind(this, this.open));
this._notificationDestroyedId = notification.connect('destroy', Lang.bind(this,
notification.connect('clicked', Lang.bind(this, this.open));
notification.connect('destroy', Lang.bind(this,
function () {
if (this.notification == notification) {
this.notification = null;
this._notificationDestroyedId = 0;
this._notificationClickedId = 0;
this._notificationRemoved();
}
}));
let index = this.notifications.indexOf(notification);
if (index < 0)
return;
this.notifications.splice(index, 1);
if (this.notifications.length == 0)
this._lastNotificationRemoved();
}));
},
notify: function(notification) {
this.pushNotification(notification);
this.emit('notify', notification);
},
destroy: function() {
this.emit('destroy');
destroy: function(reason) {
this.emit('destroy', reason);
},
// A subclass can redefine this to "steal" clicks from the
// summaryitem; Use Clutter.get_current_event() to get the
// details, return true to prevent the default handling from
// ocurring.
handleSummaryClick: function() {
return false;
},
//// Protected methods ////
@ -885,8 +928,14 @@ Source.prototype = {
open: function(notification) {
},
destroyNonResidentNotifications: function() {
for (let i = this.notifications.length - 1; i >= 0; i--)
if (!this.notifications[i].resident)
this.notifications[i].destroy();
},
// Default implementation is to destroy this source, but subclasses can override
_notificationRemoved: function() {
_lastNotificationRemoved: function() {
this.destroy();
}
};
@ -899,8 +948,12 @@ function SummaryItem(source) {
SummaryItem.prototype = {
_init: function(source) {
this.source = source;
this.source.connect('notification-added', Lang.bind(this, this._notificationAddedToSource));
this.actor = new St.Button({ style_class: 'summary-source-button',
y_fill: true,
reactive: true,
button_mask: St.ButtonMask.ONE | St.ButtonMask.TWO | St.ButtonMask.THREE,
track_hover: true });
this._sourceBox = new St.BoxLayout({ style_class: 'summary-source' });
@ -915,9 +968,30 @@ SummaryItem.prototype = {
this._sourceTitleBin.child = this._sourceTitle;
this._sourceTitleBin.width = 0;
this._sourceBox.add_actor(this._sourceIcon);
this._sourceBox.add_actor(this._sourceTitleBin, { expand: true });
this._sourceBox.add(this._sourceIcon, { y_fill: false });
this._sourceBox.add(this._sourceTitleBin, { expand: true, y_fill: false });
this.actor.child = this._sourceBox;
this.notificationStackView = new St.ScrollView({ name: source.isChat ? '' : 'summary-notification-stack-scrollview',
vscrollbar_policy: source.isChat ? Gtk.PolicyType.NEVER : Gtk.PolicyType.AUTOMATIC,
hscrollbar_policy: Gtk.PolicyType.NEVER,
vfade: true });
this.notificationStack = new St.BoxLayout({ name: 'summary-notification-stack',
vertical: true });
this.notificationStackView.add_actor(this.notificationStack);
this._notificationExpandedIds = [];
this._notificationDoneDisplayingIds = [];
this._notificationDestroyedIds = [];
this._oldMaxScrollAdjustment = 0;
this.notificationStackView.vscroll.adjustment.connect('changed', Lang.bind(this, function(adjustment) {
let currentValue = adjustment.value + adjustment.page_size;
if (currentValue == this._oldMaxScrollAdjustment)
this.scrollTo(St.Side.BOTTOM);
this._oldMaxScrollAdjustment = adjustment.upper;
}));
this.rightClickMenu = new St.BoxLayout({ name: 'summary-right-click-menu',
vertical: true });
@ -926,14 +1000,14 @@ SummaryItem.prototype = {
item = new PopupMenu.PopupMenuItem(_("Open"));
item.connect('activate', Lang.bind(this, function() {
source.open();
this.emit('right-click-menu-done-displaying');
this.emit('done-displaying-content');
}));
this.rightClickMenu.add(item.actor);
item = new PopupMenu.PopupMenuItem(_("Remove"));
item.connect('activate', Lang.bind(this, function() {
source.destroy();
this.emit('right-click-menu-done-displaying');
this.emit('done-displaying-content');
}));
this.rightClickMenu.add(item.actor);
@ -963,6 +1037,87 @@ SummaryItem.prototype = {
setEllipsization: function(mode) {
this._sourceTitle.clutter_text.ellipsize = mode;
},
prepareNotificationStackForShowing: function() {
if (this.notificationStack.get_children().length > 0)
return;
for (let i = 0; i < this.source.notifications.length; i++) {
this._appendNotificationToStack(this.source.notifications[i]);
}
},
doneShowingNotificationStack: function() {
let notificationActors = this.notificationStack.get_children();
for (let i = 0; i < notificationActors.length; i++) {
notificationActors[i]._delegate.collapseCompleted();
notificationActors[i]._delegate.disconnect(this._notificationExpandedIds[i]);
notificationActors[i]._delegate.disconnect(this._notificationDoneDisplayingIds[i]);
notificationActors[i]._delegate.disconnect(this._notificationDestroyedIds[i]);
this.notificationStack.remove_actor(notificationActors[i]);
notificationActors[i]._delegate.setIconVisible(true);
notificationActors[i]._delegate.enableScrolling(true);
}
this._notificationExpandedIds = [];
this._notificationDoneDisplayingIds = [];
this._notificationDestroyedIds = [];
},
_notificationAddedToSource: function(source, notification) {
if (this.notificationStack.mapped)
this._appendNotificationToStack(notification);
},
_appendNotificationToStack: function(notification) {
let notificationExpandedId = notification.connect('expanded', Lang.bind(this, this._contentUpdated));
this._notificationExpandedIds.push(notificationExpandedId);
let notificationDoneDisplayingId = notification.connect('done-displaying', Lang.bind(this, this._notificationDoneDisplaying));
this._notificationDoneDisplayingIds.push(notificationDoneDisplayingId);
let notificationDestroyedId = notification.connect('destroy', Lang.bind(this, this._notificationDestroyed));
this._notificationDestroyedIds.push(notificationDestroyedId);
if (!this.source.isChat)
notification.enableScrolling(false);
if (this.notificationStack.get_children().length > 0)
notification.setIconVisible(false);
this.notificationStack.add(notification.actor);
notification.expand(false);
},
// scrollTo:
// @side: St.Side.TOP or St.Side.BOTTOM
//
// Scrolls the notifiction stack to the indicated edge
scrollTo: function(side) {
let adjustment = this.notificationStackView.vscroll.adjustment;
if (side == St.Side.TOP)
adjustment.value = adjustment.lower;
else if (side == St.Side.BOTTOM)
adjustment.value = adjustment.upper;
},
_contentUpdated: function() {
this.emit('content-updated');
},
_notificationDoneDisplaying: function() {
this.emit('done-displaying-content');
},
_notificationDestroyed: function(notification) {
let index = this.notificationStack.get_children().indexOf(notification.actor);
if (index >= 0) {
notification.disconnect(this._notificationExpandedIds[index]);
this._notificationExpandedIds.splice(index, 1);
notification.disconnect(this._notificationDoneDisplayingIds[index]);
this._notificationDoneDisplayingIds.splice(index, 1);
notification.disconnect(this._notificationDestroyedIds[index]);
this._notificationDestroyedIds.splice(index, 1);
this.notificationStack.remove_actor(notification.actor);
this._contentUpdated();
}
if (this.notificationStack.get_children().length > 0)
this.notificationStack.get_children()[0]._delegate.setIconVisible(true);
}
};
Signals.addSignalMethods(SummaryItem.prototype);
@ -1011,14 +1166,15 @@ MessageTray.prototype = {
this._summaryBoxPointer.actor.lower_bottom();
this._summaryBoxPointer.actor.hide();
this._summaryNotification = null;
this._summaryNotificationClickedId = 0;
this._summaryRightClickMenuClickedId = 0;
this._summaryBoxPointerItem = null;
this._summaryBoxPointerContentUpdatedId = 0;
this._summaryBoxPointerDoneDisplayingId = 0;
this._clickedSummaryItem = null;
this._clickedSummaryItemMouseButton = -1;
this._clickedSummaryItemAllocationChangedId = 0;
this._expandedSummaryItem = null;
this._summaryItemTitleWidth = 0;
this._pointerBarrier = 0;
// To simplify the summary item animation code, we pretend
// that there's an invisible SummaryItem to the left of the
@ -1053,18 +1209,17 @@ MessageTray.prototype = {
this._notificationTimeoutId = 0;
this._notificationExpandedId = 0;
this._summaryBoxPointerState = State.HIDDEN;
this._summaryNotificationTimeoutId = 0;
this._summaryNotificationExpandedId = 0;
this._summaryBoxPointerTimeoutId = 0;
this._overviewVisible = Main.overview.visible;
this._notificationRemoved = false;
this._reNotifyWithSummaryNotificationAfterHide = false;
this._reNotifyAfterHideNotification = null;
Main.chrome.addActor(this.actor, { affectsStruts: false,
visibleInOverview: true });
Main.chrome.trackActor(this._notificationBin);
Main.chrome.trackActor(this._summaryBoxPointer.actor);
global.gdk_screen.connect('monitors-changed', Lang.bind(this, this._setSizePosition));
global.screen.connect('monitors-changed', Lang.bind(this, this._setSizePosition));
this._setSizePosition();
@ -1108,6 +1263,15 @@ MessageTray.prototype = {
this._notificationBin.width = primary.width;
this._summaryBin.x = 0;
this._summaryBin.width = primary.width;
if (this._pointerBarrier)
global.destroy_pointer_barrier(this._pointerBarrier);
this._pointerBarrier =
global.create_pointer_barrier(primary.x + primary.width, primary.y + primary.height - this.actor.height,
primary.x + primary.width, primary.y + primary.height,
4 /* BarrierNegativeX */);
},
contains: function(source) {
@ -1163,9 +1327,9 @@ MessageTray.prototype = {
this._onSummaryItemHoverChanged(summaryItem);
}));
summaryItem.actor.connect('button-press-event', Lang.bind(this,
function (actor, event) {
this._onSummaryItemClicked(summaryItem, event);
summaryItem.actor.connect('clicked', Lang.bind(this,
function (actor, button) {
this._onSummaryItemClicked(summaryItem, button);
}));
source.connect('destroy', Lang.bind(this, this._onSourceDestroy));
@ -1229,13 +1393,6 @@ MessageTray.prototype = {
if (needUpdate);
this._updateState();
// remove all notifications with this source from the queue
let newNotificationQueue = [];
for (let i = this._notificationQueue.length - 1; i >= 0; i--) {
if (this._notificationQueue[i].source == source)
this._notificationQueue[i].destroy();
}
},
_onNotificationDestroy: function(notification) {
@ -1260,18 +1417,23 @@ MessageTray.prototype = {
if (!this._locked)
return;
this._locked = false;
this._pointerInTray = this.actor.hover && !this._summaryBoxPointer.bin.hover;
this._updateState();
},
_onNotify: function(source, notification) {
if (notification == this._summaryNotification) {
if (!this._summaryNotificationExpandedId)
// We must be in the process of hiding the summary notification.
// If the summary notification is updated while it is being
// hidden, we show the update as a new notification. However,
// we must first wait till the hide is complete and the
// notification actor is not part of the stage.
this._reNotifyWithSummaryNotificationAfterHide = true;
if (this._summaryBoxPointerItem && this._summaryBoxPointerItem.source == source) {
if (this._summaryBoxPointerState == State.HIDING)
// We are in the process of hiding the summary box pointer.
// If there is an update for one of the notifications or
// a new notification to be added to the notification stack
// while it is in the process of being hidden, we show it as
// a new notification. However, we first wait till the hide
// is complete. This is especially important if one of the
// notifications in the stack was updated because we will
// need to be able to re-parent its actor to a different
// part of the stage.
this._reNotifyAfterHideNotification = notification;
return;
}
@ -1310,12 +1472,18 @@ MessageTray.prototype = {
// Turn off ellipsization for the previously expanded item that is
// collapsing and for the item that is expanding because it looks
// better that way.
if (this._expandedSummaryItem)
if (this._expandedSummaryItem) {
// Ideally, we would remove 'expanded' pseudo class when the item
// is done collapsing, but we don't track when that happens.
this._expandedSummaryItem.actor.remove_style_pseudo_class('expanded');
this._expandedSummaryItem.setEllipsization(Pango.EllipsizeMode.NONE);
}
this._expandedSummaryItem = summaryItem;
if (this._expandedSummaryItem)
if (this._expandedSummaryItem) {
this._expandedSummaryItem.actor.add_style_pseudo_class('expanded');
this._expandedSummaryItem.setEllipsization(Pango.EllipsizeMode.NONE);
}
// We tween on a "_expandedSummaryItemTitleWidth" pseudo-property
// that represents the current title width of the
@ -1337,6 +1505,8 @@ MessageTray.prototype = {
},
set _expandedSummaryItemTitleWidth(expansion) {
expansion = Math.round(expansion);
// Expand the expanding item to its new width
if (this._expandedSummaryItem)
this._expandedSummaryItem.setTitleWidth(expansion);
@ -1367,11 +1537,32 @@ MessageTray.prototype = {
if (this._summaryItems[i] == this._expandedSummaryItem)
continue;
let width = this._summaryItems[i].getTitleWidth();
this._summaryItems[i].setTitleWidth(width * shrinkage);
let oldWidth = this._summaryItems[i].getTitleWidth();
let newWidth = Math.floor(oldWidth * shrinkage);
excess -= newWidth;
this._summaryItems[i].setTitleWidth(newWidth);
}
if (this._expandedSummaryItem) {
let oldWidth = this._imaginarySummaryItemTitleWidth;
let newWidth = Math.floor(oldWidth * shrinkage);
excess -= newWidth;
this._imaginarySummaryItemTitleWidth = newWidth;
}
// If the tray as a whole is fully-expanded, make sure the
// left edge doesn't wobble during animation due to rounding.
if (this._imaginarySummaryItemTitleWidth == 0 && excess != 0) {
for (let i = 0; i < this._summaryItems.length; i++) {
if (this._summaryItems[i] == this._expandedSummaryItem)
continue;
let oldWidth = this._summaryItems[i].getTitleWidth();
if (oldWidth != 0) {
this._summaryItems[i].setTitleWidth (oldWidth + excess);
break;
}
}
}
if (this._expandedSummaryItem)
this._imaginarySummaryItemTitleWidth *= shrinkage;
},
_expandSummaryItemCompleted: function() {
@ -1379,13 +1570,14 @@ MessageTray.prototype = {
this._expandedSummaryItem.setEllipsization(Pango.EllipsizeMode.END);
},
_onSummaryItemClicked: function(summaryItem, event) {
let clickedButton = event.get_button();
if (!this._clickedSummaryItem ||
this._clickedSummaryItem != summaryItem ||
this._clickedSummaryItemMouseButton != clickedButton) {
_onSummaryItemClicked: function(summaryItem, button) {
if (summaryItem.source.handleSummaryClick())
this._unsetClickedSummaryItem();
else if (!this._clickedSummaryItem ||
this._clickedSummaryItem != summaryItem ||
this._clickedSummaryItemMouseButton != button) {
this._clickedSummaryItem = summaryItem;
this._clickedSummaryItemMouseButton = clickedButton;
this._clickedSummaryItemMouseButton = button;
} else {
this._unsetClickedSummaryItem();
}
@ -1521,14 +1713,15 @@ MessageTray.prototype = {
// at the present time.
_updateState: function() {
// Notifications
let notificationsPending = this._notificationQueue.length > 0 &&
(!this._busy || this._notificationQueue[0].urgency == Urgency.CRITICAL);
let notificationUrgent = this._notificationQueue.length > 0 && this._notificationQueue[0].urgency == Urgency.CRITICAL;
let notificationsPending = this._notificationQueue.length > 0 && (!this._busy || notificationUrgent);
let notificationPinned = this._pointerInTray && !this._pointerInSummary && !this._notificationRemoved;
let notificationExpanded = this._notificationBin.y < 0;
let notificationExpired = (this._notificationTimeoutId == 0 && !(this._notification && this._notification.urgency == Urgency.CRITICAL) && !this._pointerInTray && !this._locked) || this._notificationRemoved;
let canShowNotification = notificationsPending && this._summaryState == State.HIDDEN;
if (this._notificationState == State.HIDDEN) {
if (notificationsPending)
if (canShowNotification)
this._showNotification();
} else if (this._notificationState == State.SHOWN) {
if (notificationExpired)
@ -1550,7 +1743,11 @@ MessageTray.prototype = {
this._notificationState == State.SHOWN);
let notificationsDone = !notificationsVisible && !notificationsPending;
if (this._summaryState == State.HIDDEN) {
let summaryOptionalInOverview = this._overviewVisible && !this._locked && !summaryHovered;
let mustHideSummary = (notificationsPending && (notificationUrgent || summaryOptionalInOverview))
|| notificationsVisible;
if (this._summaryState == State.HIDDEN && !mustHideSummary) {
if (this._backFromAway) {
// Immediately set this to false, so that we don't schedule a timeout later
this._backFromAway = false;
@ -1562,7 +1759,7 @@ MessageTray.prototype = {
this._showSummary(0);
}
} else if (this._summaryState == State.SHOWN) {
if (!summaryPinned)
if (!summaryPinned || mustHideSummary)
this._hideSummary();
else if (summaryVisibleWithNoHover && !summaryNotificationIsForExpandedSummaryItem)
// If we are hiding the summary, we'll collapse the expanded summary item when we are done
@ -1577,18 +1774,21 @@ MessageTray.prototype = {
let summarySourceIsMainNotificationSource = (haveClickedSummaryItem && this._notification &&
this._clickedSummaryItem.source == this._notification.source);
let canShowSummaryBoxPointer = this._summaryState == State.SHOWN;
let wrongSummaryNotification = (this._clickedSummaryItemMouseButton == 1 &&
this._summaryNotification != this._clickedSummaryItem.source.notification);
// 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 &&
this._summaryBoxPointer.bin.child != this._clickedSummaryItem.notificationStackView);
let wrongSummaryRightClickMenu = (this._clickedSummaryItemMouseButton == 3 &&
this._summaryBoxPointer.bin.child != this._clickedSummaryItem.rightClickMenu);
let wrongSummaryBoxPointer = (haveClickedSummaryItem &&
(wrongSummaryNotification || wrongSummaryRightClickMenu));
(wrongSummaryNotificationStack || wrongSummaryRightClickMenu));
if (this._summaryBoxPointerState == State.HIDDEN) {
if (haveClickedSummaryItem && !summarySourceIsMainNotificationSource && canShowSummaryBoxPointer)
if (haveClickedSummaryItem && !summarySourceIsMainNotificationSource && canShowSummaryBoxPointer && !requestedNotificationStackIsEmpty)
this._showSummaryBoxPointer();
} else if (this._summaryBoxPointerState == State.SHOWN) {
if (!haveClickedSummaryItem || !canShowSummaryBoxPointer || wrongSummaryBoxPointer)
if (!haveClickedSummaryItem || !canShowSummaryBoxPointer || wrongSummaryBoxPointer || mustHideSummary)
this._hideSummaryBoxPointer();
}
@ -1843,38 +2043,33 @@ MessageTray.prototype = {
},
_hideSummaryCompleted: function() {
this._expandedSummaryItem = null;
this._expandedSummaryItemTitleWidth = this._summaryItemTitleWidth;
this._setExpandedSummaryItem(null);
},
_showSummaryBoxPointer: function() {
this._summaryBoxPointerItem = this._clickedSummaryItem;
this._summaryBoxPointerContentUpdatedId = this._summaryBoxPointerItem.connect('content-updated',
Lang.bind(this, this._adjustSummaryBoxPointerPosition));
this._summaryBoxPointerDoneDisplayingId = this._summaryBoxPointerItem.connect('done-displaying-content',
Lang.bind(this, this._escapeTray));
if (this._clickedSummaryItemMouseButton == 1) {
let clickedSummaryItemNotification = this._clickedSummaryItem.source.notification;
let index = this._notificationQueue.indexOf(clickedSummaryItemNotification);
if (index != -1)
this._notificationQueue.splice(index, 1);
this._summaryNotification = clickedSummaryItemNotification;
this._summaryNotificationClickedId = this._summaryNotification.connect('done-displaying',
Lang.bind(this, this._escapeTray));
this._summaryBoxPointer.bin.child = this._summaryNotification.actor;
if (!this._summaryNotificationExpandedId)
this._summaryNotificationExpandedId = this._summaryNotification.connect('expanded',
Lang.bind(this, this._onSummaryBoxPointerExpanded));
this._summaryNotification.expand(false);
this._notificationQueue = this._notificationQueue.filter( Lang.bind(this,
function(notification) {
return this._summaryBoxPointerItem.source != notification.source;
}));
this._summaryBoxPointerItem.prepareNotificationStackForShowing();
this._summaryBoxPointer.bin.child = this._summaryBoxPointerItem.notificationStackView;
this._summaryBoxPointerItem.scrollTo(St.Side.BOTTOM);
} else if (this._clickedSummaryItemMouseButton == 3) {
this._summaryRightClickMenuClickedId = this._clickedSummaryItem.connect('right-click-menu-done-displaying',
Lang.bind(this, this._escapeTray));
this._summaryBoxPointer.bin.child = this._clickedSummaryItem.rightClickMenu;
}
this._focusGrabber.grabFocus(this._summaryBoxPointer.bin.child);
this._clickedSummaryItemAllocationChangedId =
this._clickedSummaryItem.actor.connect('allocation-changed',
Lang.bind(this, this._adjustSummaryBoxPointerPosition));
// _clickedSummaryItem.actor can change absolute postiion without changing allocation
// _clickedSummaryItem.actor can change absolute position without changing allocation
this._summaryMotionId = this._summary.connect('allocation-changed',
Lang.bind(this, this._adjustSummaryBoxPointerPosition));
@ -1883,6 +2078,7 @@ MessageTray.prototype = {
this._adjustSummaryBoxPointerPosition();
this._summaryBoxPointerState = State.SHOWING;
this._clickedSummaryItem.actor.add_style_pseudo_class('selected');
this._summaryBoxPointer.show(true, Lang.bind(this, function() {
this._summaryBoxPointerState = State.SHOWN;
}));
@ -1904,49 +2100,54 @@ MessageTray.prototype = {
this._summaryMotionId = 0;
}
if (this._summaryRightClickMenuClickedId) {
this._clickedSummaryItem.disconnect(this._summaryRightClickMenuClickedId);
this._summaryRightClickMenuClickedId = 0;
}
if (this._clickedSummaryItem)
this._clickedSummaryItem.actor.remove_style_pseudo_class('selected');
this._clickedSummaryItem = null;
this._clickedSummaryItemMouseButton = -1;
},
_onSummaryBoxPointerExpanded: function() {
this._adjustSummaryBoxPointerPosition();
},
_hideSummaryBoxPointer: function() {
if (this._summaryNotificationExpandedId) {
this._summaryNotification.disconnect(this._summaryNotificationExpandedId);
this._summaryNotificationExpandedId = 0;
}
this._summaryBoxPointerState = State.HIDING;
// Unset this._clickedSummaryItem if we are no longer showing the summary
if (this._summaryState != State.SHOWN)
this._unsetClickedSummaryItem();
this._focusGrabber.ungrabFocus();
this._summaryBoxPointerState = State.HIDING;
this._summaryBoxPointer.hide(true, Lang.bind(this, this._hideSummaryBoxPointerCompleted));
if (this._summaryBoxPointerItem.source.notifications.length == 0) {
this._summaryBoxPointer.actor.hide();
this._hideSummaryBoxPointerCompleted();
} else {
this._summaryBoxPointer.hide(true, Lang.bind(this, this._hideSummaryBoxPointerCompleted));
}
},
_hideSummaryBoxPointerCompleted: function() {
let doneShowingNotificationStack = (this._summaryBoxPointer.bin.child == this._summaryBoxPointerItem.notificationStackView);
this._summaryBoxPointerState = State.HIDDEN;
this._summaryBoxPointer.bin.child = null;
if (this._summaryNotification != null) {
this._summaryNotification.collapseCompleted();
this._summaryNotification.disconnect(this._summaryNotificationClickedId);
this._summaryNotificationClickedId = 0;
let summaryNotification = this._summaryNotification;
this._summaryNotification = null;
if (summaryNotification.isTransient && !this._reNotifyWithSummaryNotificationAfterHide)
summaryNotification.destroy(NotificationDestroyedReason.EXPIRED);
if (this._reNotifyWithSummaryNotificationAfterHide) {
this._onNotify(summaryNotification.source, summaryNotification);
this._reNotifyWithSummaryNotificationAfterHide = false;
this._summaryBoxPointerItem.disconnect(this._summaryBoxPointerContentUpdatedId);
this._summaryBoxPointerContentUpdatedId = 0;
this._summaryBoxPointerItem.disconnect(this._summaryBoxPointerDoneDisplayingId);
this._summaryBoxPointerDoneDisplayingId = 0;
let sourceNotificationStackDoneShowing = null;
if (doneShowingNotificationStack) {
this._summaryBoxPointerItem.doneShowingNotificationStack();
sourceNotificationStackDoneShowing = this._summaryBoxPointerItem.source;
}
this._summaryBoxPointerItem = null;
if (sourceNotificationStackDoneShowing) {
if (sourceNotificationStackDoneShowing.isTransient && !this._reNotifyAfterHideNotification)
sourceNotificationStackDoneShowing.destroy(NotificationDestroyedReason.EXPIRED);
if (this._reNotifyAfterHideNotification) {
this._onNotify(this._reNotifyAfterHideNotification.source, this._reNotifyAfterHideNotification);
this._reNotifyAfterHideNotification = null;
}
}
if (this._clickedSummaryItem)
this._updateState();
}

View File

@ -39,13 +39,20 @@ ModalDialog.prototype = {
params = Params.parse(params, { styleClass: null });
this.state = State.CLOSED;
this._hasModal = false;
this._group = new St.Group({ visible: false,
x: 0,
y: 0 });
Main.uiGroup.add_actor(this._group);
let constraint = new Clutter.BindConstraint({ source: global.stage,
coordinate: Clutter.BindCoordinate.POSITION | Clutter.BindCoordinate.SIZE });
this._group.add_constraint(constraint);
global.focus_manager.add_group(this._group);
this._initialKeyFocus = this._group;
this._savedKeyFocus = null;
this._group.connect('destroy', Lang.bind(this, this._onGroupDestroy));
@ -60,12 +67,18 @@ ModalDialog.prototype = {
this._group.add_actor(this._backgroundBin);
this._lightbox.highlight(this._backgroundBin);
this._backgroundStack = new Shell.Stack();
this._backgroundBin.child = this._backgroundStack;
this._eventBlocker = new Clutter.Group({ reactive: true });
this._backgroundStack.add_actor(this._eventBlocker);
this._dialogLayout = new St.BoxLayout({ style_class: 'modal-dialog',
vertical: true });
if (params.styleClass != null) {
this._dialogLayout.add_style_class_name(params.styleClass);
}
this._backgroundBin.child = this._dialogLayout;
this._backgroundStack.add_actor(this._dialogLayout);
this.contentLayout = new St.BoxLayout({ vertical: true });
this._dialogLayout.add(this.contentLayout,
@ -74,8 +87,9 @@ ModalDialog.prototype = {
x_align: St.Align.MIDDLE,
y_align: St.Align.START });
this._buttonLayout = new St.BoxLayout({ opacity: 220,
vertical: false });
this._buttonLayout = new St.BoxLayout({ style_class: 'modal-dialog-button-box',
opacity: 220,
vertical: false });
this._dialogLayout.add(this._buttonLayout,
{ expand: true,
x_align: St.Align.MIDDLE,
@ -154,22 +168,23 @@ ModalDialog.prototype = {
transition: 'easeOutQuad',
onComplete: Lang.bind(this,
function() {
this._initialKeyFocus.grab_key_focus();
this.state = State.OPENED;
this.emit('opened');
}),
})
});
},
setInitialKeyFocus: function(actor) {
this._initialKeyFocus = actor;
},
open: function(timestamp) {
if (this.state == State.OPENED || this.state == State.OPENING)
return true;
if (!Main.pushModal(this._group, timestamp))
if (!this.pushModal(timestamp))
return false;
global.stage.set_key_focus(this._group);
this._fadeOpen();
return true;
},
@ -178,14 +193,8 @@ ModalDialog.prototype = {
if (this.state == State.CLOSED || this.state == State.CLOSING)
return;
let needsPopModal;
if (this.state == State.OPENED || this.state == State.OPENING)
needsPopModal = true;
else
needsPopModal = false;
this.state = State.CLOSING;
this.popModal(timestamp);
Tweener.addTween(this._group,
{ opacity: 0,
@ -195,13 +204,46 @@ ModalDialog.prototype = {
function() {
this.state = State.CLOSED;
this._group.hide();
if (needsPopModal)
Main.popModal(this._group, timestamp);
})
});
},
// Drop modal status without closing the dialog; this makes the
// dialog insensitive as well, so it needs to be followed shortly
// by either a close() or a pushModal()
popModal: function(timestamp) {
if (!this._hasModal)
return;
let focus = global.stage.key_focus;
if (focus && this._group.contains(focus))
this._savedKeyFocus = focus;
else
this._savedKeyFocus = null;
Main.popModal(this._group, timestamp);
global.gdk_screen.get_display().sync();
this._hasModal = false;
this._eventBlocker.raise_top();
},
pushModal: function (timestamp) {
if (this._hasModal)
return true;
if (!Main.pushModal(this._group, timestamp))
return false;
this._hasModal = true;
if (this._savedKeyFocus) {
this._savedKeyFocus.grab_key_focus();
this._savedKeyFocus = null;
} else
this._initialKeyFocus.grab_key_focus();
this._eventBlocker.lower_bottom();
return true;
},
// This method is like close, but fades the dialog out much slower,
// and leaves the lightbox in place. Once in the faded out state,
// the dialog can be brought back by an open call, or the lightbox
@ -220,6 +262,7 @@ ModalDialog.prototype = {
if (this.state == State.FADED_OUT)
return;
this.popModal(timestamp);
Tweener.addTween(this._dialogLayout,
{ opacity: 0,
time: FADE_OUT_DIALOG_TIME,
@ -227,7 +270,6 @@ ModalDialog.prototype = {
onComplete: Lang.bind(this,
function() {
this.state = State.FADED_OUT;
Main.popModal(this._group, timestamp);
})
});
}

View File

@ -1,5 +1,6 @@
/* -*- mode: js2; js2-basic-offset: 4; indent-tabs-mode: nil -*- */
const Clutter = imports.gi.Clutter;
const DBus = imports.dbus;
const GLib = imports.gi.GLib;
const Lang = imports.lang;
@ -188,9 +189,11 @@ NotificationDaemon.prototype = {
actions, hints, timeout) {
let id;
// Filter out notifications from Empathy, since we
// Filter out chat and presence notifications from Empathy, since we
// handle that information from telepathyClient.js
if (appName == 'Empathy') {
if (appName == 'Empathy' && (hints['category'] == 'im.received' ||
hints['category'] == 'presence.online' ||
hints['category'] == 'presence.offline')) {
// Ignore replacesId since we already sent back a
// NotificationClosed for that id.
id = nextNotificationId++;
@ -345,7 +348,7 @@ NotificationDaemon.prototype = {
notification.setTransient(hints['transient'] == true);
let sourceIconActor = source.useNotificationIcon ? this._iconForNotificationData(icon, hints, source.ICON_SIZE) : null;
source.notify(notification, sourceIconActor);
source.processNotification(notification, sourceIconActor);
},
CloseNotification: function(id) {
@ -389,8 +392,7 @@ NotificationDaemon.prototype = {
for (let id in this._sources) {
let source = this._sources[id];
if (source.app == tracker.focus_app) {
if (source.notification && !source.notification.resident)
source.notification.destroy();
source.destroyNonResidentNotifications();
return;
}
}
@ -441,15 +443,51 @@ Source.prototype = {
this.title = this.app.get_name();
else
this.useNotificationIcon = true;
this._isTrayIcon = false;
this._trayIcon = null;
},
notify: function(notification, icon) {
processNotification: function(notification, icon) {
if (!this.app)
this._setApp();
if (!this.app && icon)
this._setSummaryIcon(icon);
MessageTray.Source.prototype.notify.call(this, notification);
let tracker = Shell.WindowTracker.get_default();
if (notification.resident && this.app && tracker.focus_app == this.app)
this.pushNotification(notification);
else
this.notify(notification);
},
handleSummaryClick: function() {
if (!this._trayIcon)
return false;
let event = Clutter.get_current_event();
if (event.type() != Clutter.EventType.BUTTON_RELEASE)
return false;
// Left clicks are passed through only where there aren't unacknowledged
// notifications, so it possible to open them in summary mode; right
// clicks are always forwarded, as the right click menu is not useful for
// tray icons
if (event.get_button() == 1 &&
this.notifications.length > 0)
return false;
if (Main.overview.visible) {
// We can't just connect to Main.overview's 'hidden' signal,
// because it's emitted *before* it calls popModal()...
let id = global.connect('notify::stage-input-mode', Lang.bind(this,
function () {
global.disconnect(id);
this._trayIcon.click(event);
}));
Main.overview.hide();
} else {
this._trayIcon.click(event);
}
return true;
},
_setApp: function() {
@ -466,7 +504,7 @@ Source.prototype = {
// Only override the icon if we were previously using
// notification-based icons (ie, not a trayicon) or if it was unset before
if (!this._isTrayIcon) {
if (!this._trayIcon) {
this.useNotificationIcon = false;
this._setSummaryIcon(this.app.create_icon_texture (this.ICON_SIZE));
}
@ -475,25 +513,29 @@ Source.prototype = {
setTrayIcon: function(icon) {
this._setSummaryIcon(icon);
this.useNotificationIcon = false;
this._isTrayIcon = true;
this._trayIcon = icon;
},
open: function(notification) {
this.destroyNonResidentNotifications();
this.openApp();
},
_notificationRemoved: function() {
if (!this._isTrayIcon)
_lastNotificationRemoved: function() {
if (!this._trayIcon)
this.destroy();
},
_appStateChanged: function() {
// Destroy notification sources when their apps exit.
// The app exiting would normally result in a tray icon being removed,
// so it should be ok to destroy the source associated with a tray icon
// here too, however we just let that happen through the code path
// associated with the tray icon being removed.
if (!this._isTrayIcon && this.app.get_state() == Shell.AppState.STOPPED)
// so the associated source would be destroyed through the code path
// that handles the tray icon being removed. We should not destroy
// the source associated with a tray icon when the application state
// is Shell.AppState.STOPPED because running applications that have
// no open windows would also have that state. This is often the case
// for applications that use tray icons.
if (!this._trayIcon && this.app.get_state() == Shell.AppState.STOPPED)
this.destroy();
},

View File

@ -24,6 +24,7 @@ const PlaceDisplay = imports.ui.placeDisplay;
const Tweener = imports.ui.tweener;
const ViewSelector = imports.ui.viewSelector;
const WorkspacesView = imports.ui.workspacesView;
const WorkspaceThumbnail = imports.ui.workspaceThumbnail;
// Time for initial animation going into Overview mode
const ANIMATION_TIME = 0.25;
@ -74,11 +75,13 @@ ShellInfo.prototype = {
Main.messageTray.add(this._source);
}
let notification = this._source.notification;
if (notification == null)
let notification = null;
if (this._source.notifications.length == 0) {
notification = new MessageTray.Notification(this._source, text, null);
else
} else {
notification = this._source.notifications[0];
notification.update(text, null, { clear: true });
}
notification.setTransient(true);
@ -180,10 +183,10 @@ Overview.prototype = {
this._group.add_actor(this.viewSelector.actor);
this._workspacesDisplay = new WorkspacesView.WorkspacesDisplay();
this.viewSelector.addViewTab(_("Windows"), this._workspacesDisplay.actor, 'text-x-generic');
this.viewSelector.addViewTab('windows', _("Windows"), this._workspacesDisplay.actor, 'text-x-generic');
let appView = new AppDisplay.AllAppDisplay();
this.viewSelector.addViewTab(_("Applications"), appView.actor, 'system-run');
this.viewSelector.addViewTab('applications', _("Applications"), appView.actor, 'system-run');
// Default search providers
this.viewSelector.addSearchProvider(new AppDisplay.AppSearchProvider());
@ -220,6 +223,7 @@ Overview.prototype = {
this._resetWindowSwitchTimeout();
this._lastHoveredWindow = null;
DND.removeMonitor(this._dragMonitor);
this.endItemDrag();
},
_resetWindowSwitchTimeout: function() {
@ -242,7 +246,8 @@ Overview.prototype = {
_onDragMotion: function(dragEvent) {
let targetIsWindow = dragEvent.targetActor &&
dragEvent.targetActor._delegate &&
dragEvent.targetActor._delegate.metaWindow;
dragEvent.targetActor._delegate.metaWindow &&
!(dragEvent.targetActor._delegate instanceof WorkspaceThumbnail.WindowClone);
this._windowSwitchTimestamp = global.get_current_time();
@ -438,7 +443,7 @@ Overview.prototype = {
let primary = global.get_primary_monitor();
let rtl = (St.Widget.get_default_direction () == St.TextDirection.RTL);
let contentY = Panel.PANEL_HEIGHT;
let contentY = Main.panel.actor.height;
let contentHeight = primary.height - contentY - Main.messageTray.actor.height;
this._group.set_position(primary.x, primary.y);
@ -473,6 +478,10 @@ Overview.prototype = {
this.emit('item-drag-begin');
},
cancelledItemDrag: function(source) {
this.emit('item-drag-cancelled');
},
endItemDrag: function(source) {
this.emit('item-drag-end');
},
@ -481,35 +490,14 @@ Overview.prototype = {
this.emit('window-drag-begin');
},
cancelledWindowDrag: function(source) {
this.emit('window-drag-cancelled');
},
endWindowDrag: function(source) {
this.emit('window-drag-end');
},
// Returns the scale the Overview has when we just start zooming out
// to overview mode. That is, when just the active workspace is showing.
getZoomedInScale : function() {
return 1 / this.workspaces.getScale();
},
// Returns the position the Overview has when we just start zooming out
// to overview mode. That is, when just the active workspace is showing.
getZoomedInPosition : function() {
let [posX, posY] = this.workspaces.getActiveWorkspacePosition();
let scale = this.getZoomedInScale();
return [- posX * scale, - posY * scale];
},
// Returns the current scale of the Overview.
getScale : function() {
return this.workspaces.actor.scaleX;
},
// Returns the current position of the Overview.
getPosition : function() {
return [this.workspaces.actor.x, this.workspaces.actor.y];
},
// show:
//
// Animates the overview visible and grabs mouse and keyboard input
@ -563,30 +551,13 @@ Overview.prototype = {
});
}
// Create a zoom out effect. First scale the workspaces view up and
// position it so that the active workspace fills up the whole screen,
// then transform it to its normal dimensions and position.
// The opposite transition is used in hide().
this.workspaces.actor.scaleX = this.workspaces.actor.scaleY = this.getZoomedInScale();
[this.workspaces.actor.x, this.workspaces.actor.y] = this.getZoomedInPosition();
let primary = global.get_primary_monitor();
Tweener.addTween(this.workspaces.actor,
{ x: primary.x - this._group.x,
y: primary.y - this._group.y,
scaleX: 1,
scaleY: 1,
transition: 'easeOutQuad',
time: ANIMATION_TIME,
onComplete: this._showDone,
onCompleteScope: this
});
// Make the other elements fade in.
this._group.opacity = 0;
Tweener.addTween(this._group,
{ opacity: 255,
transition: 'easeOutQuad',
time: ANIMATION_TIME
time: ANIMATION_TIME,
onComplete: this._showDone,
onCompleteScope: this
});
this._coverPane.raise_top();
@ -698,27 +669,13 @@ Overview.prototype = {
this.workspaces.hide();
// Create a zoom in effect by transforming the workspaces view so that
// the active workspace fills up the whole screen. The opposite
// transition is used in show().
let scale = this.getZoomedInScale();
let [posX, posY] = this.getZoomedInPosition();
Tweener.addTween(this.workspaces.actor,
{ x: posX,
y: posY,
scaleX: scale,
scaleY: scale,
transition: 'easeOutQuad',
time: ANIMATION_TIME,
onComplete: this._hideDone,
onCompleteScope: this
});
// Make other elements fade out.
Tweener.addTween(this._group,
{ opacity: 0,
transition: 'easeOutQuad',
time: ANIMATION_TIME
time: ANIMATION_TIME,
onComplete: this._hideDone,
onCompleteScope: this
});
this._coverPane.raise_top();
@ -737,6 +694,7 @@ Overview.prototype = {
this._animateNotVisible();
this._syncInputMode();
global.sync_pointer();
},
_hideDone: function() {

View File

@ -22,8 +22,6 @@ const DateMenu = imports.ui.dateMenu;
const Main = imports.ui.main;
const Tweener = imports.ui.tweener;
const PANEL_HEIGHT = 26;
const PANEL_ICON_SIZE = 24;
const STARTUP_ANIMATION_TIME = 0.2;
@ -33,8 +31,7 @@ const HOT_CORNER_ACTIVATION_TIMEOUT = 0.5;
const BUTTON_DND_ACTIVATION_TIMEOUT = 250;
const ANIMATED_ICON_UPDATE_TIMEOUT = 100;
const SPINNER_UPDATE_TIMEOUT = 130;
const SPINNER_SPEED = 0.02;
const SPINNER_ANIMATION_TIME = 0.2;
const STANDARD_TRAY_ICON_ORDER = ['a11y', 'display', 'keyboard', 'volume', 'bluetooth', 'network', 'battery'];
const STANDARD_TRAY_ICON_SHELL_IMPLEMENTATION = {
@ -47,6 +44,12 @@ const STANDARD_TRAY_ICON_SHELL_IMPLEMENTATION = {
if (Config.HAVE_BLUETOOTH)
STANDARD_TRAY_ICON_SHELL_IMPLEMENTATION['bluetooth'] = imports.ui.status.bluetooth.Indicator;
try {
STANDARD_TRAY_ICON_SHELL_IMPLEMENTATION['network'] = imports.ui.status.network.NMApplet;
} catch(e) {
log('NMApplet is not supported. It is possible that your NetworkManager version is too old');
}
// To make sure the panel corners blend nicely with the panel,
// we draw background and borders the same way, e.g. drawing
// them as filled shapes from the outside inwards instead of
@ -244,6 +247,10 @@ AppMenuButton.prototype = {
let bin = new St.Bin({ name: 'appMenu' });
this.actor.set_child(bin);
this.actor.reactive = false;
this._targetIsCurrent = false;
this._container = new Shell.GenericContainer();
bin.set_child(this._container);
this._container.connect('get-preferred-width', Lang.bind(this, this._getContentPreferredWidth));
@ -271,20 +278,13 @@ AppMenuButton.prototype = {
this.hide();
}));
this._updateId = 0;
this._animationStep = 0;
this._clipWidth = PANEL_ICON_SIZE;
this._direction = SPINNER_SPEED;
this._stop = true;
this._spinner = new AnimatedIcon('process-working.svg',
PANEL_ICON_SIZE);
this._container.add_actor(this._spinner.actor);
this._spinner.actor.lower_bottom();
this._shadow = new St.Bin({ style_class: 'label-real-shadow' });
this._shadow.hide();
this._container.add_actor(this._shadow);
let tracker = Shell.WindowTracker.get_default();
tracker.connect('notify::focus-app', Lang.bind(this, this._sync));
tracker.connect('app-state-changed', Lang.bind(this, this._onAppStateChanged));
@ -300,6 +300,10 @@ AppMenuButton.prototype = {
this._visible = true;
this.actor.show();
if (!this._targetIsCurrent)
return;
Tweener.removeTweens(this.actor);
Tweener.addTween(this.actor,
{ opacity: 255,
@ -312,6 +316,11 @@ AppMenuButton.prototype = {
return;
this._visible = false;
if (!this._targetIsCurrent) {
this.actor.hide();
return;
}
Tweener.removeTweens(this.actor);
Tweener.addTween(this.actor,
{ opacity: 0,
@ -334,62 +343,26 @@ AppMenuButton.prototype = {
this._iconBox.remove_clip();
},
_stopAnimation: function(animate) {
this._label.actor.remove_clip();
if (this._updateId) {
this._shadow.hide();
if (animate) {
Tweener.addTween(this._spinner.actor,
{ opacity: 0,
time: 0.2,
transition: "easeOutQuad",
onCompleteScope: this,
onComplete: function() {
this._spinner.actor.opacity = 255;
this._spinner.actor.hide();
}
});
}
Mainloop.source_remove(this._updateId);
this._updateId = 0;
}
if (!animate)
this._spinner.actor.hide();
},
stopAnimation: function() {
this._direction = SPINNER_SPEED * 3;
this._stop = true;
},
if (this._stop)
return;
_update: function() {
this._animationStep += this._direction;
if (this._animationStep > 1 && this._stop) {
this._animationStep = 1;
this._stopAnimation(true);
return false;
}
if (this._animationStep > 1)
this._animationStep = 1;
this._clipWidth = this._label.actor.width - (this._label.actor.width - PANEL_ICON_SIZE) * (1 - this._animationStep);
if (this.actor.get_direction() == St.TextDirection.LTR) {
this._label.actor.set_clip(0, 0, this._clipWidth + this._shadow.width, this.actor.height);
} else {
this._label.actor.set_clip(this._label.actor.width - this._clipWidth, 0, this._clipWidth, this.actor.height);
}
this._container.queue_relayout();
return true;
this._stop = true;
Tweener.addTween(this._spinner.actor,
{ opacity: 0,
time: SPINNER_ANIMATION_TIME,
transition: "easeOutQuad",
onCompleteScope: this,
onComplete: function() {
this._spinner.actor.opacity = 255;
this._spinner.actor.hide();
}
});
},
startAnimation: function() {
this._direction = SPINNER_SPEED;
this._stopAnimation(false);
this._animationStep = 0;
this._update();
this._stop = false;
this._updateId = Mainloop.timeout_add(SPINNER_UPDATE_TIMEOUT, Lang.bind(this, this._update));
this._spinner.actor.show();
this._shadow.show();
},
_getContentPreferredWidth: function(actor, forHeight, alloc) {
@ -451,18 +424,13 @@ AppMenuButton.prototype = {
this._label.actor.allocate(childBox, flags);
if (direction == St.TextDirection.LTR) {
childBox.x1 = Math.floor(iconWidth / 2) + this._clipWidth + this._shadow.width;
childBox.x1 = Math.floor(iconWidth / 2) + this._label.actor.width;
childBox.x2 = childBox.x1 + this._spinner.actor.width;
childBox.y1 = box.y1;
childBox.y2 = box.y2 - 1;
this._spinner.actor.allocate(childBox, flags);
childBox.x1 = Math.floor(iconWidth / 2) + this._clipWidth + 2;
childBox.x2 = childBox.x1 + this._shadow.width;
childBox.y1 = box.y1;
childBox.y2 = box.y2 - 1;
this._shadow.allocate(childBox, flags);
} else {
childBox.x1 = this._label.actor.width - this._clipWidth - this._spinner.actor.width;
childBox.x1 = -this._spinner.actor.width;
childBox.x2 = childBox.x1 + this._spinner.actor.width;
childBox.y1 = box.y1;
childBox.y2 = box.y2 - 1;
@ -501,13 +469,6 @@ AppMenuButton.prototype = {
lastStartedApp = this._startingApps[i];
let focusedApp = tracker.focus_app;
let targetApp = focusedApp != null ? focusedApp : lastStartedApp;
if (targetApp == this._targetApp) {
if (targetApp && targetApp.get_state() != Shell.AppState.STARTING)
this.stopAnimation();
return;
}
this._stopAnimation();
if (!focusedApp) {
// If the app has just lost focus to the panel, pretend
@ -517,27 +478,56 @@ AppMenuButton.prototype = {
return;
}
let targetApp = focusedApp != null ? focusedApp : lastStartedApp;
if (targetApp == null) {
if (!this._targetIsCurrent)
return;
this.actor.reactive = false;
this._targetIsCurrent = false;
Tweener.removeTweens(this.actor);
Tweener.addTween(this.actor, { opacity: 0,
time: Overview.ANIMATION_TIME,
transition: 'easeOutQuad' });
return;
}
if (!this._targetIsCurrent) {
this.actor.reactive = true;
this._targetIsCurrent = true;
Tweener.removeTweens(this.actor);
Tweener.addTween(this.actor, { opacity: 255,
time: Overview.ANIMATION_TIME,
transition: 'easeOutQuad' });
}
if (targetApp == this._targetApp) {
if (targetApp && targetApp.get_state() != Shell.AppState.STARTING)
this.stopAnimation();
return;
}
this._spinner.actor.hide();
if (this._iconBox.child != null)
this._iconBox.child.destroy();
this._iconBox.hide();
this._label.setText('');
this.actor.reactive = false;
this._targetApp = targetApp;
if (targetApp != null) {
let icon = targetApp.get_faded_icon(2 * PANEL_ICON_SIZE);
let icon = targetApp.get_faded_icon(2 * PANEL_ICON_SIZE);
this._label.setText(targetApp.get_name());
// TODO - _quit() doesn't really work on apps in state STARTING yet
this._quitMenu.label.set_text(_("Quit %s").format(targetApp.get_name()));
this._label.setText(targetApp.get_name());
// TODO - _quit() doesn't really work on apps in state STARTING yet
this._quitMenu.label.set_text(_("Quit %s").format(targetApp.get_name()));
this.actor.reactive = true;
this._iconBox.set_child(icon);
this._iconBox.show();
this._iconBox.set_child(icon);
this._iconBox.show();
if (targetApp.get_state() == Shell.AppState.STARTING)
this.startAnimation();
}
if (targetApp.get_state() == Shell.AppState.STARTING)
this.startAnimation();
this.emit('changed');
}
@ -641,12 +631,17 @@ PanelCorner.prototype = {
* This class manages the "hot corner" that can toggle switching to
* overview.
*/
function HotCorner() {
this._init();
function HotCorner(button) {
this._init(button);
}
HotCorner.prototype = {
_init : function() {
_init : function(button) {
// This is the activities button associated with this hot corner,
// if this is on the primary monitor (or null with the corner is
// on a different monitor)
this._button = button;
// We use this flag to mark the case where the user has entered the
// hot corner and has not left both the hot corner and a surrounding
// guard area (the "environs"). This avoids triggering the hot corner
@ -673,6 +668,8 @@ HotCorner.prototype = {
this._activationTime = 0;
this.actor.connect('enter-event',
Lang.bind(this, this._onEnvironsEntered));
this.actor.connect('leave-event',
Lang.bind(this, this._onEnvironsLeft));
// Clicking on the hot corner environs should result in the same bahavior
@ -725,6 +722,8 @@ HotCorner.prototype = {
x: x,
y: y });
ripple._opacity = startOpacity;
if (ripple.get_direction() == St.TextDirection.RTL)
ripple.set_anchor_point_from_gravity(Clutter.Gravity.NORTH_EAST);
Tweener.addTween(ripple, { _opacity: finalOpacity,
scale_x: finalScale,
scale_y: finalScale,
@ -747,6 +746,11 @@ HotCorner.prototype = {
this._addRipple(0.35, 1.0, 0.0, 0.3, 1, 0.0);
},
_onEnvironsEntered : function() {
if (this._button)
this._button.hover = true;
},
_onCornerEntered : function() {
if (!this._entered) {
this._entered = true;
@ -774,6 +778,9 @@ HotCorner.prototype = {
},
_onEnvironsLeft : function(actor, event) {
if (this._button)
this._button.hover = false;
if (event.get_related() != this._corner)
this._entered = false;
return false;
@ -808,6 +815,8 @@ Panel.prototype = {
this.actor.remove_style_class_name('in-overview');
}));
this._leftPointerBarrier = 0;
this._rightPointerBarrier = 0;
this._menus = new PopupMenu.PopupMenuManager(this);
this._leftBox = new St.BoxLayout({ name: 'panelLeft' });
@ -991,7 +1000,7 @@ Panel.prototype = {
affectsStruts: false,
affectsInputRegion: false });
Main.ctrlAltTabManager.addGroup(this.actor, _("Panel"), 'start-here',
Main.ctrlAltTabManager.addGroup(this.actor, _("Top Bar"), 'start-here',
{ sortGroup: CtrlAltTab.SortGroup.TOP });
},
@ -1068,7 +1077,21 @@ Panel.prototype = {
let primary = global.get_primary_monitor();
this.actor.set_position(primary.x, primary.y);
this.actor.set_size(primary.width, PANEL_HEIGHT);
this.actor.set_size(primary.width, -1);
if (this._leftPointerBarrier)
global.destroy_pointer_barrier(this._leftPointerBarrier);
if (this._rightPointerBarrier)
global.destroy_pointer_barrier(this._rightPointerBarrier);
this._leftPointerBarrier =
global.create_pointer_barrier(primary.x, primary.y,
primary.x, primary.y + this.actor.height,
1 /* BarrierPositiveX */);
this._rightPointerBarrier =
global.create_pointer_barrier(primary.x + primary.width, primary.y,
primary.x + primary.width, primary.y + this.actor.height,
4 /* BarrierNegativeX */);
this._leftCorner.relayout();
this._rightCorner.relayout();

View File

@ -32,6 +32,15 @@ Button.prototype = {
},
_onButtonPress: function(actor, event) {
if (!this.menu.isOpen) {
// Setting the max-height won't do any good if the minimum height of the
// menu is higher then the screen; it's useful if part of the menu is
// scrollable so the minimum height is smaller than the natural height
let monitor = global.get_primary_monitor();
this.menu.actor.style = ('max-height: ' +
Math.round(monitor.height - Main.panel.actor.height) +
'px;');
}
this.menu.toggle();
},

View File

@ -176,37 +176,8 @@ PlacesManager.prototype = {
Util.spawn(['nautilus-connect-server']);
});
let networkApp = null;
try {
networkApp = Shell.AppSystem.get_default().load_from_desktop_file('gnome-network-scheme.desktop');
} catch(e) {
try {
networkApp = Shell.AppSystem.get_default().load_from_desktop_file('network-scheme.desktop');
} catch(e) {
log('Cannot create "Network" item, .desktop file not found or corrupt.');
}
}
if (networkApp != null) {
this._network = new PlaceInfo('special:network', networkApp.get_name(),
function(size) {
return networkApp.create_icon_texture(size);
},
function (params) {
params = Params.parse(params, { workspace: null,
timestamp: 0 });
networkApp.launch_full(params.timestamp, [],
params.workspace ? params.workspace.index() : -1);
});
}
this._defaultPlaces.push(this._home);
this._defaultPlaces.push(this._desktopMenu);
if (this._network)
this._defaultPlaces.push(this._network);
this._defaultPlaces.push(this._connect);
/*

View File

@ -49,6 +49,8 @@ AuthenticationDialog.prototype = {
this.actionId = actionId;
this.message = message;
this.userNames = userNames;
this._wasDismissed = false;
this._completed = false;
let mainContentBox = new St.BoxLayout({ style_class: 'polkit-dialog-main-layout',
vertical: false });
@ -69,7 +71,7 @@ AuthenticationDialog.prototype = {
{ y_align: St.Align.START });
this._subjectLabel = new St.Label({ style_class: 'polkit-dialog-headline',
text: _('Authentication Required') });
text: _("Authentication Required") });
messageBox.add(this._subjectLabel,
{ y_fill: false,
@ -100,32 +102,35 @@ AuthenticationDialog.prototype = {
Lang.bind(this, this._onUserChanged));
// Special case 'root'
if (userName == 'root')
userRealName = _('Administrator');
let userIsRoot = false;
if (userName == 'root') {
userIsRoot = true;
userRealName = _("Administrator");
}
// Work around Gdm.UserManager returning an empty string for the real name
if (userRealName.length == 0)
userRealName = userName;
let userBox = new St.BoxLayout({ style_class: 'polkit-dialog-user-layout',
vertical: false });
messageBox.add(userBox);
this._userIcon = new St.Icon();
this._userIcon.hide();
userBox.add(this._userIcon,
{ x_fill: true,
y_fill: false,
x_align: St.Align.END,
y_align: St.Align.START });
let userLabel = new St.Label(({ style_class: 'polkit-dialog-user-label',
text: userRealName }));
userBox.add(userLabel,
{ x_fill: true,
y_fill: false,
x_align: St.Align.END,
y_align: St.Align.MIDDLE });
if (userIsRoot) {
let userLabel = new St.Label(({ style_class: 'polkit-dialog-user-root-label',
text: userRealName }));
messageBox.add(userLabel);
} else {
let userBox = new St.BoxLayout({ style_class: 'polkit-dialog-user-layout',
vertical: false });
messageBox.add(userBox);
this._userIcon = new St.Icon();
this._userIcon.hide();
userBox.add(this._userIcon,
{ x_fill: true,
y_fill: false,
x_align: St.Align.END,
y_align: St.Align.START });
let userLabel = new St.Label(({ style_class: 'polkit-dialog-user-label',
text: userRealName }));
userBox.add(userLabel,
{ x_fill: true,
y_fill: false,
x_align: St.Align.END,
y_align: St.Align.MIDDLE });
}
this._onUserChanged();
@ -134,45 +139,41 @@ AuthenticationDialog.prototype = {
this._passwordLabel = new St.Label(({ style_class: 'polkit-dialog-password-label' }));
this._passwordBox.add(this._passwordLabel);
this._passwordEntry = new St.Entry({ style_class: 'polkit-dialog-password-entry',
text: _(''),
text: "",
can_focus: true});
this._passwordEntry.clutter_text.connect('activate', Lang.bind(this, this._onEntryActivate));
this._passwordBox.add(this._passwordEntry,
{expand: true });
this._passwordBox.hide();
this._errorBox = new St.BoxLayout({ style_class: 'polkit-dialog-error-box' });
messageBox.add(this._errorBox);
let errorIcon = new St.Icon({ icon_name: 'dialog-error',
icon_size: 24,
style_class: 'polkit-dialog-error-icon' });
this._errorBox.add(errorIcon, { y_align: St.Align.MIDDLE });
this._errorMessage = new St.Label({ style_class: 'polkit-dialog-error-label' });
this._errorMessage.clutter_text.ellipsize = Pango.EllipsizeMode.NONE;
this._errorMessage.clutter_text.line_wrap = true;
this._errorBox.add(this._errorMessage, { expand: true,
y_align: St.Align.MIDDLE,
y_fill: true });
this._errorBox.hide();
this._errorMessageLabel = new St.Label({ style_class: 'polkit-dialog-error-label' });
this._errorMessageLabel.clutter_text.ellipsize = Pango.EllipsizeMode.NONE;
this._errorMessageLabel.clutter_text.line_wrap = true;
messageBox.add(this._errorMessageLabel);
this._errorMessageLabel.hide();
this._infoBox = new St.BoxLayout({ style_class: 'polkit-dialog-info-box' });
messageBox.add(this._infoBox);
let infoIcon = new St.Icon({ icon_name: 'dialog-information',
icon_size: 24,
style_class: 'polkit-dialog-info-icon' });
this._infoBox.add(infoIcon, { y_align: St.Align.MIDDLE });
this._infoMessage = new St.Label({ style_class: 'polkit-dialog-info-label'});
this._infoMessage.clutter_text.line_wrap = true;
this._infoBox.add(this._infoMessage, { expand: true,
y_align: St.Align.MIDDLE,
y_fill: true });
this._infoBox.hide();
this._infoMessageLabel = new St.Label({ style_class: 'polkit-dialog-info-label' });
this._infoMessageLabel.clutter_text.ellipsize = Pango.EllipsizeMode.NONE;
this._infoMessageLabel.clutter_text.line_wrap = true;
messageBox.add(this._infoMessageLabel);
this._infoMessageLabel.hide();
this.setButtons([{ label: _('Cancel'),
/* text is intentionally non-blank otherwise the height is not the same as for
* infoMessage and errorMessageLabel - but it is still invisible because
* gnome-shell.css sets the color to be transparent
*/
this._nullMessageLabel = new St.Label({ style_class: 'polkit-dialog-null-label',
text: 'abc'});
this._nullMessageLabel.clutter_text.ellipsize = Pango.EllipsizeMode.NONE;
this._nullMessageLabel.clutter_text.line_wrap = true;
messageBox.add(this._nullMessageLabel);
this._nullMessageLabel.show();
this.setButtons([{ label: _("Cancel"),
action: Lang.bind(this, this.cancel),
key: Clutter.Escape
},
{ label: _('Authenticate'),
{ label: _("Authenticate"),
action: Lang.bind(this, this._onAuthenticateButtonPressed)
}]);
@ -234,8 +235,9 @@ AuthenticationDialog.prototype = {
this._session.response(response);
// When the user responds, dismiss already shown info and
// error texts (if any)
this._errorBox.hide();
this._infoBox.hide();
this._errorMessageLabel.hide();
this._infoMessageLabel.hide();
this._nullMessageLabel.show();
},
_onAuthenticateButtonPressed: function() {
@ -243,14 +245,35 @@ AuthenticationDialog.prototype = {
},
_onSessionCompleted: function(session, gainedAuthorization) {
this._passwordBox.hide();
if (this._completed)
return;
this._completed = true;
if (!gainedAuthorization) {
/* 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),
* show "Sorry, that didn't work. Please try again."
*/
if (!this._errorMessageLabel.visible && !this._wasDismissed) {
/* Translators: "that didn't work" refers to the fact that the
* requested authentication was not gained; this can happen
* because of an authentication error (like invalid password),
* for instance. */
this._errorMessageLabel.set_text(_("Sorry, that didn\'t work. Please try again."));
this._errorMessageLabel.show();
this._infoMessageLabel.hide();
this._nullMessageLabel.hide();
}
}
this._emitDone(!gainedAuthorization, false);
},
_onSessionRequest: function(session, request, echo_on) {
// Cheap localization trick
if (request == 'Password:')
this._passwordLabel.set_text(_('Password:'));
this._passwordLabel.set_text(_("Password:"));
else
this._passwordLabel.set_text(request);
@ -267,41 +290,49 @@ AuthenticationDialog.prototype = {
_onSessionShowError: function(session, text) {
this._passwordEntry.set_text('');
this._errorMessage.set_text(text);
this._errorBox.show();
this._errorMessageLabel.set_text(text);
this._errorMessageLabel.show();
this._infoMessageLabel.hide();
this._nullMessageLabel.hide();
this._ensureOpen();
},
_onSessionShowInfo: function(session, text) {
this._passwordEntry.set_text('');
this._infoMessage.set_text(text);
this._infoBox.show();
this._infoMessageLabel.set_text(text);
this._infoMessageLabel.show();
this._errorMessageLabel.hide();
this._nullMessageLabel.hide();
this._ensureOpen();
},
destroySession: function() {
if (this._session) {
this._session.cancel();
if (!this._completed)
this._session.cancel();
this._session = null;
}
},
_onUserChanged: function() {
if (this._user.is_loaded) {
let iconFileName = this._user.get_icon_file();
let iconFile = Gio.file_new_for_path(iconFileName);
let icon;
if (iconFile.query_exists(null)) {
icon = new Gio.FileIcon({file: iconFile});
} else {
icon = new Gio.ThemedIcon({name: 'avatar-default'});
if (this._userIcon) {
let iconFileName = this._user.get_icon_file();
let iconFile = Gio.file_new_for_path(iconFileName);
let icon;
if (iconFile.query_exists(null)) {
icon = new Gio.FileIcon({file: iconFile});
} else {
icon = new Gio.ThemedIcon({name: 'avatar-default'});
}
this._userIcon.set_gicon (icon);
this._userIcon.show();
}
this._userIcon.set_gicon (icon);
this._userIcon.show();
}
},
cancel: function() {
this._wasDismissed = true;
this.close(global.get_current_time());
this._emitDone(false, true);
},

View File

@ -61,7 +61,7 @@ PopupBaseMenuItem.prototype = {
},
_onStyleChanged: function (actor) {
this._spacing = actor.get_theme_node().get_length('spacing');
this._spacing = Math.round(actor.get_theme_node().get_length('spacing'));
},
_onButtonReleaseEvent: function (actor, event) {
@ -173,6 +173,8 @@ PopupBaseMenuItem.prototype = {
cr.fill();
},
// This returns column widths in logical order (i.e. from the dot
// to the image), not in visual order (left to right)
getColumnWidths: function() {
let widths = [];
for (let i = 0, col = 0; i < this._children.length; i++) {
@ -224,19 +226,36 @@ PopupBaseMenuItem.prototype = {
_allocate: function(actor, box, flags) {
let height = box.y2 - box.y1;
let direction = this.actor.get_direction();
if (this._dot) {
// The dot is placed outside box
// one quarter of padding from the border of the container
// (so 3/4 from the inner border)
// (padding is box.x1)
let dotBox = new Clutter.ActorBox();
let dotWidth = Math.round(box.x1 / 2);
dotBox.x1 = Math.round(box.x1 / 4);
dotBox.x2 = dotBox.x1 + dotWidth;
if (direction == St.TextDirection.LTR) {
dotBox.x1 = Math.round(box.x1 / 4);
dotBox.x2 = dotBox.x1 + dotWidth;
} else {
dotBox.x2 = box.x2 + 3 * Math.round(box.x1 / 4);
dotBox.x1 = dotBox.x2 - dotWidth;
}
dotBox.y1 = Math.round(box.y1 + (height - dotWidth) / 2);
dotBox.y2 = dotBox.y1 + dotWidth;
this._dot.allocate(dotBox, flags);
}
let x = box.x1;
let x;
if (direction == St.TextDirection.LTR)
x = box.x1;
else
x = box.x2;
// if direction is ltr, x is the right edge of the last added
// actor, and it's constantly increasing, whereas if rtl, x is
// the left edge and it decreases
for (let i = 0, col = 0; i < this._children.length; i++) {
let child = this._children[i];
let childBox = new Clutter.ActorBox();
@ -244,9 +263,12 @@ PopupBaseMenuItem.prototype = {
let [minWidth, naturalWidth] = child.actor.get_preferred_width(-1);
let availWidth, extraWidth;
if (this._columnWidths) {
if (child.span == -1)
availWidth = box.x2 - x;
else {
if (child.span == -1) {
if (direction == St.TextDirection.LTR)
availWidth = box.x2 - x;
else
availWidth = x - box.x1;
} else {
availWidth = 0;
for (let j = 0; j < child.span; j++)
availWidth += this._columnWidths[col++];
@ -257,18 +279,36 @@ PopupBaseMenuItem.prototype = {
extraWidth = 0;
}
if (child.expand) {
childBox.x1 = x;
childBox.x2 = x + availWidth;
} else if (child.align === St.Align.CENTER) {
childBox.x1 = x + Math.round(extraWidth / 2);
childBox.x2 = childBox.x1 + naturalWidth;
} else if (child.align === St.Align.END) {
childBox.x2 = x + availWidth;
childBox.x1 = childBox.x2 - naturalWidth;
if (direction == St.TextDirection.LTR) {
if (child.expand) {
childBox.x1 = x;
childBox.x2 = x + availWidth;
} else if (child.align === St.Align.CENTER) {
childBox.x1 = x + Math.round(extraWidth / 2);
childBox.x2 = childBox.x1 + naturalWidth;
} else if (child.align === St.Align.END) {
childBox.x2 = x + availWidth;
childBox.x1 = childBox.x2 - naturalWidth;
} else {
childBox.x1 = x;
childBox.x2 = x + naturalWidth;
}
} else {
childBox.x1 = x;
childBox.x2 = x + naturalWidth;
if (child.expand) {
childBox.x1 = x - availWidth;
childBox.x2 = x;
} else if (child.align === St.Align.CENTER) {
childBox.x1 = x - Math.round(extraWidth / 2);
childBox.x2 = childBox.x1 + naturalWidth;
} else if (child.align === St.Align.END) {
// align to the left
childBox.x1 = x - availWidth;
childBox.x2 = childBox.x1 + naturalWidth;
} else {
// align to the right
childBox.x2 = x;
childBox.x1 = x - naturalWidth;
}
}
let [minHeight, naturalHeight] = child.actor.get_preferred_height(-1);
@ -277,7 +317,10 @@ PopupBaseMenuItem.prototype = {
child.actor.allocate(childBox, flags);
x += availWidth + this._spacing;
if (direction == St.TextDirection.LTR)
x += availWidth + this._spacing;
else
x -= availWidth + this._spacing;
}
}
};
@ -485,12 +528,30 @@ PopupSliderMenuItem.prototype = {
let sliderBorderColor = themeNode.get_color('-slider-border-color');
let sliderColor = themeNode.get_color('-slider-background-color');
let sliderActiveBorderColor = themeNode.get_color('-slider-active-border-color');
let sliderActiveColor = themeNode.get_color('-slider-active-background-color');
cr.setSourceRGBA (
sliderActiveColor.red / 255,
sliderActiveColor.green / 255,
sliderActiveColor.blue / 255,
sliderActiveColor.alpha / 255);
cr.rectangle(handleRadius, (height - sliderHeight) / 2, sliderWidth * this._value, sliderHeight);
cr.fillPreserve();
cr.setSourceRGBA (
sliderActiveBorderColor.red / 255,
sliderActiveBorderColor.green / 255,
sliderActiveBorderColor.blue / 255,
sliderActiveBorderColor.alpha / 255);
cr.setLineWidth(sliderBorderWidth);
cr.stroke();
cr.setSourceRGBA (
sliderColor.red / 255,
sliderColor.green / 255,
sliderColor.blue / 255,
sliderColor.alpha / 255);
cr.rectangle(handleRadius, (height - sliderHeight) / 2, sliderWidth, sliderHeight);
cr.rectangle(handleRadius + sliderWidth * this._value, (height - sliderHeight) / 2, sliderWidth * (1 - this._value), sliderHeight);
cr.fillPreserve();
cr.setSourceRGBA (
sliderBorderColor.red / 255,
@ -704,8 +765,18 @@ PopupMenuBase.prototype = {
} else {
this.box = new St.BoxLayout({ vertical: true });
}
this.box.connect_after('queue-relayout', Lang.bind(this, this._menuQueueRelayout));
this.isOpen = false;
// If set, we don't send events (including crossing events) to the source actor
// for the menu which causes its prelight state to freeze
this.blockSourceEvents = false;
// Can be set while a menu is up to let all events through without special
// menu handling useful for scrollbars in menus, and probably not otherwise.
this.passEvents = false;
this._activeMenuItem = null;
},
@ -806,6 +877,8 @@ PopupMenuBase.prototype = {
let columnWidths = [];
let items = this.box.get_children();
for (let i = 0; i < items.length; i++) {
if (!items[i].visible)
continue;
if (items[i]._delegate instanceof PopupBaseMenuItem || items[i]._delegate instanceof PopupMenuBase) {
let itemColumnWidths = items[i]._delegate.getColumnWidths();
for (let j = 0; j < itemColumnWidths.length; j++) {
@ -825,6 +898,16 @@ PopupMenuBase.prototype = {
}
},
// Because of the above column-width funniness, we need to do a
// queue-relayout on every item whenever the menu itself changes
// size, to force clutter to drop its cached size requests. (The
// menuitems will in turn call queue_relayout on their parent, the
// menu, but that call will be a no-op since the menu already
// has a relayout queued, so we won't get stuck in a loop.
_menuQueueRelayout: function() {
this.box.get_children().map(function (actor) { actor.queue_relayout(); });
},
addActor: function(actor) {
this.box.add(actor);
},
@ -959,45 +1042,109 @@ PopupSubMenu.prototype = {
__proto__: PopupMenuBase.prototype,
_init: function(sourceActor, sourceArrow) {
PopupMenuBase.prototype._init.call(this, sourceActor, 'popup-sub-menu');
PopupMenuBase.prototype._init.call(this, sourceActor);
this._arrow = sourceArrow;
this._arrow.rotation_center_z_gravity = Clutter.Gravity.CENTER;
this.actor = this.box;
// Since a function of a submenu might be to provide a "More.." expander
// with long content, we make it scrollable - the scrollbar will only take
// effect if a CSS max-height is set on the top menu.
this.actor = new St.ScrollView({ style_class: 'popup-sub-menu',
hscrollbar_policy: Gtk.PolicyType.NEVER,
vscrollbar_policy: Gtk.PolicyType.NEVER });
// StScrollbar plays dirty tricks with events, calling
// clutter_set_motion_events_enabled (FALSE) during the scroll; this
// confuses our event tracking, so we just turn it off during the
// scroll.
let vscroll = this.actor.get_vscroll_bar();
vscroll.connect('scroll-start',
Lang.bind(this, function() {
let topMenu = this._getTopMenu();
if (topMenu)
topMenu.passEvents = true;
}));
vscroll.connect('scroll-stop',
Lang.bind(this, function() {
let topMenu = this._getTopMenu();
if (topMenu)
topMenu.passEvents = false;
}));
this.actor.add_actor(this.box);
this.actor._delegate = this;
this.actor.clip_to_allocation = true;
this.actor.connect('key-press-event', Lang.bind(this, this._onKeyPressEvent));
this.actor.hide();
},
_getTopMenu: function() {
let actor = this.actor.get_parent();
while (actor) {
if (actor._delegate && actor._delegate instanceof PopupMenu)
return actor._delegate;
actor = actor.get_parent();
}
return null;
},
_needsScrollbar: function() {
let topMenu = this._getTopMenu();
let [topMinHeight, topNaturalHeight] = topMenu.actor.get_preferred_height(-1);
let topThemeNode = topMenu.actor.get_theme_node();
let topMaxHeight = topThemeNode.get_max_height();
return topMaxHeight >= 0 && topNaturalHeight >= topMaxHeight;
},
open: function(animate) {
if (this.isOpen)
return;
this.isOpen = true;
// we don't implement the !animate case because that doesn't
// currently get used...
let [naturalHeight, minHeight] = this.actor.get_preferred_height(-1);
this.actor.height = 0;
this.actor.show();
this.actor._arrow_rotation = this._arrow.rotation_angle_z;
Tweener.addTween(this.actor,
{ _arrow_rotation: 90,
height: naturalHeight,
time: 0.25,
onUpdateScope: this,
onUpdate: function() {
this._arrow.rotation_angle_z = this.actor._arrow_rotation;
},
onCompleteScope: this,
onComplete: function() {
this.actor.set_height(-1);
this.emit('open-state-changed', true);
}
});
let needsScrollbar = this._needsScrollbar();
// St.ScrollView always requests space horizontally for a possible vertical
// scrollbar if in AUTOMATIC mode. Doing better would require implementation
// of width-for-height in St.BoxLayout and St.ScrollView. This looks bad
// when we *don't* need it, so turn off the scrollbar when that's true.
// Dynamic changes in whether we need it aren't handled properly.
this.actor.vscrollbar_policy =
needsScrollbar ? Gtk.PolicyType.AUTOMATIC : Gtk.PolicyType.NEVER;
// It looks funny if we animate with a scrollbar (at what point is
// the scrollbar added?) so just skip that case
if (animate && needsScrollbar)
animate = false;
if (animate) {
let [minHeight, naturalHeight] = this.actor.get_preferred_height(-1);
this.actor.height = 0;
this.actor._arrow_rotation = this._arrow.rotation_angle_z;
Tweener.addTween(this.actor,
{ _arrow_rotation: 90,
height: naturalHeight,
time: 0.25,
onUpdateScope: this,
onUpdate: function() {
this._arrow.rotation_angle_z = this.actor._arrow_rotation;
},
onCompleteScope: this,
onComplete: function() {
this.actor.set_height(-1);
this.emit('open-state-changed', true);
}
});
} else {
this._arrow.rotation_angle_z = 90;
this.emit('open-state-changed', true);
}
},
close: function(animate) {
@ -1009,6 +1156,9 @@ PopupSubMenu.prototype = {
if (this._activeMenuItem)
this._activeMenuItem.setActive(false);
if (animate && this._needsScrollbar())
animate = false;
if (animate) {
this.actor._arrow_rotation = this._arrow.rotation_angle_z;
Tweener.addTween(this.actor,
@ -1311,14 +1461,20 @@ PopupMenuManager.prototype = {
return this._activeMenuContains(event.get_source());
},
_eventIsOnAnyMenuSource: function(event) {
_shouldBlockEvent: function(event) {
let src = event.get_source();
if (this._activeMenu != null && this._activeMenu.actor.contains(src))
return false;
for (let i = 0; i < this._menus.length; i++) {
let menu = this._menus[i].menu;
if (menu.sourceActor && menu.sourceActor.contains(src))
return true;
if (menu.sourceActor && !menu.blockSourceEvents && menu.sourceActor.contains(src)) {
return false;
}
}
return false;
return true;
},
_findMenu: function(item) {
@ -1338,8 +1494,12 @@ PopupMenuManager.prototype = {
this._owner.menuEventFilter(event))
return true;
if (this._activeMenu != null && this._activeMenu.passEvents)
return false;
let activeMenuContains = this._eventIsOnActiveMenu(event);
let eventType = event.type();
if (eventType == Clutter.EventType.BUTTON_RELEASE) {
if (activeMenuContains) {
return false;
@ -1350,7 +1510,7 @@ PopupMenuManager.prototype = {
} else if (eventType == Clutter.EventType.BUTTON_PRESS && !activeMenuContains) {
this._closeMenu();
return true;
} else if (activeMenuContains || this._eventIsOnAnyMenuSource(event)) {
} else if (!this._shouldBlockEvent(event)) {
return false;
}

View File

@ -22,6 +22,9 @@ const MAX_FILE_DELETED_BEFORE_INVALID = 10;
const HISTORY_KEY = 'command-history';
const LOCKDOWN_SCHEMA = 'org.gnome.desktop.lockdown';
const DISABLE_COMMAND_LINE_KEY = 'disable-command-line';
const DIALOG_GROW_TIME = 0.1;
function CommandCompleter() {
@ -167,6 +170,7 @@ __proto__: ModalDialog.ModalDialog.prototype,
_init : function() {
ModalDialog.ModalDialog.prototype._init.call(this, { styleClass: 'run-dialog' });
this._lockdownSettings = new Gio.Settings({ schema: LOCKDOWN_SCHEMA });
global.settings.connect('changed::development-tools', Lang.bind(this, function () {
this._enableInternalCommands = global.settings.get_boolean('development-tools');
}));
@ -206,10 +210,7 @@ __proto__: ModalDialog.ModalDialog.prototype,
this._entryText = entry.clutter_text;
this.contentLayout.add(entry, { y_align: St.Align.START });
this.connect('opened',
Lang.bind(this, function() {
this._entryText.grab_key_focus();
}));
this.setInitialKeyFocus(this._entryText);
this._errorBox = new St.BoxLayout({ style_class: 'run-dialog-error-box' });
@ -239,15 +240,21 @@ __proto__: ModalDialog.ModalDialog.prototype,
this._entryText.connect('key-press-event', Lang.bind(this, function(o, e) {
let symbol = e.get_key_symbol();
if (symbol == Clutter.Return || symbol == Clutter.KP_Enter) {
this.popModal();
if (Shell.get_event_state(e) & Clutter.ModifierType.CONTROL_MASK)
this._run(o.get_text(), true);
else
this._run(o.get_text(), false);
if (!this._commandError)
this.close(global.get_current_time());
this.close();
else {
if (!this.pushModal())
this.close();
}
return true;
}
if (symbol == Clutter.Escape) {
this.close(global.get_current_time());
this.close();
return true;
}
if (symbol == Clutter.slash) {
@ -353,6 +360,9 @@ __proto__: ModalDialog.ModalDialog.prototype,
this._entryText.set_text('');
this._commandError = false;
if (this._lockdownSettings.get_boolean(DISABLE_COMMAND_LINE_KEY))
return;
ModalDialog.ModalDialog.prototype.open.call(this);
},

View File

@ -1,5 +1,6 @@
/* -*- mode: js2; js2-basic-offset: 4; indent-tabs-mode: nil -*- */
const DBus = imports.dbus;
const Gio = imports.gi.Gio;
const Mainloop = imports.mainloop;
@ -68,6 +69,104 @@ function waitLeisure() {
};
}
const PerfHelperIface = {
name: 'org.gnome.Shell.PerfHelper',
methods: [{ name: 'CreateWindow', inSignature: 'iibb', outSignature: '' },
{ name: 'WaitWindows', inSignature: '', outSignature: '' },
{ name: 'DestroyWindows', inSignature: '', outSignature: ''}]
};
const PerfHelper = function () {
this._init();
};
PerfHelper.prototype = {
_init: function() {
DBus.session.proxifyObject(this, 'org.gnome.Shell.PerfHelper', '/org/gnome/Shell/PerfHelper');
}
};
DBus.proxifyPrototype(PerfHelper.prototype, PerfHelperIface);
let _perfHelper = null;
function _getPerfHelper() {
if (_perfHelper == null)
_perfHelper = new PerfHelper();
return _perfHelper;
}
/**
* createTestWindow:
* @width: width of window, in pixels
* @height: height of window, in pixels
* @alpha: whether the window should be alpha transparent
* @maximized: whethe the window should be created maximized
*
* Creates a window using gnome-shell-perf-helper for testing purposes.
* While this function can be used with yield in an automation
* script to pause until the D-Bus call to the helper process returns,
* because of the normal X asynchronous mapping process, to actually wait
* until the window has been mapped and exposed, use waitTestWindows().
*/
function createTestWindow(width, height, alpha, maximized) {
let cb;
let perfHelper = _getPerfHelper();
perfHelper.CreateWindowRemote(width, height, alpha, maximized,
function(result, excp) {
if (cb)
cb();
});
return function(callback) {
cb = callback;
};
}
/**
* waitTestWindows:
*
* Used within an automation script to pause until all windows previously
* created with createTestWindow have been mapped and exposed.
*/
function waitTestWindows() {
let cb;
let perfHelper = _getPerfHelper();
perfHelper.WaitWindowsRemote(function(result, excp) {
if (cb)
cb();
});
return function(callback) {
cb = callback;
};
}
/**
* destroyTestWindows:
*
* Destroys all windows previously created with createTestWindow().
* While this function can be used with yield in an automation
* script to pause until the D-Bus call to the helper process returns,
* this doesn't guarantee that Mutter has actually finished the destroy
* process because of normal X asynchronicity.
*/
function destroyTestWindows() {
let cb;
let perfHelper = _getPerfHelper();
perfHelper.DestroyWindowsRemote(function(result, excp) {
if (cb)
cb();
});
return function(callback) {
cb = callback;
};
}
/**
* defineScriptEvent
* @name: The event will be called script.<name>
@ -147,8 +246,8 @@ function _collect(scriptModule, outputFile) {
Shell.write_string_to_stream(out, '"events":\n');
Shell.PerfLog.get_default().dump_events(out);
let monitors = global.get_monitors()
let primary = global.get_primary_monitor()
let monitors = global.get_monitors();
let primary = global.get_primary_monitor();
Shell.write_string_to_stream(out, ',\n"monitors":\n[');
for (let i = 0; i < monitors.length; i++) {
let monitor = monitors[i];
@ -167,7 +266,21 @@ function _collect(scriptModule, outputFile) {
Shell.write_string_to_stream(out, ',\n"metrics":\n[ ');
let first = true;
for (let name in scriptModule.METRICS) {
let metric = scriptModule.METRICS[name];
let metric = scriptModule.METRICS[name];
// Extra checks here because JSON.stringify generates
// invalid JSON for undefined values
if (metric.description == null) {
log("Error: No description found for metric " + name);
continue;
}
if (metric.units == null) {
log("Error: No units found for metric " + name);
continue;
}
if (metric.value == null) {
log("Error: No value found for metric " + name);
continue;
}
if (!first)
Shell.write_string_to_stream(out, ',\n ');

View File

@ -274,24 +274,18 @@ OpenSearchSystem.prototype = {
},
_addProvider: function(fileName) {
let file = Gio.file_new_for_path(global.datadir + '/search_providers/' + fileName);
let source = '';
file.load_contents_async(null, Lang.bind(this, function (obj, res) {
let [success, source] = file.load_contents_finish(res);
if (source) {
let [success, name, url, langs, icon_uri] = global.parse_search_provider(source);
let provider ={ name: name,
url: url,
id: this._providers.length,
icon_uri: icon_uri,
langs: langs };
if (this._checkSupportedProviderLanguage(provider)) {
this._providers.push(provider);
this.emit('changed');
}
}
}));
let path = global.datadir + '/search_providers/' + fileName;
let source = Shell.get_file_contents_utf8_sync(path);
let [success, name, url, langs, icon_uri] = global.parse_search_provider(source);
let provider ={ name: name,
url: url,
id: this._providers.length,
icon_uri: icon_uri,
langs: langs };
if (this._checkSupportedProviderLanguage(provider)) {
this._providers.push(provider);
this.emit('changed');
}
},
_refresh: function() {

View File

@ -5,6 +5,7 @@ const Lang = imports.lang;
const Gettext = imports.gettext.domain('gnome-shell');
const _ = Gettext.gettext;
const Gtk = imports.gi.Gtk;
const Meta = imports.gi.Meta;
const St = imports.gi.St;
const DND = imports.ui.dnd;
@ -49,6 +50,10 @@ SearchResult.prototype = {
Lang.bind(this, function() {
Main.overview.beginItemDrag(this);
}));
draggable.connect('drag-cancelled',
Lang.bind(this, function() {
Main.overview.cancelledItemDrag(this);
}));
draggable.connect('drag-end',
Lang.bind(this, function() {
Main.overview.endItemDrag(this);
@ -72,11 +77,12 @@ SearchResult.prototype = {
},
getDragActorSource: function() {
return this.metaInfo['icon'];
// not exactly right, but alignment problems are hard to notice
return this._content;
},
getDragActor: function(stageX, stageY) {
return new Clutter.Clone({ source: this.metaInfo['icon'] });
return this.metaInfo['createIcon'](Main.overview.dash.iconSize);
},
shellWorkspaceLaunch: function(params) {
@ -100,8 +106,30 @@ GridSearchResults.prototype = {
this._grid = new IconGrid.IconGrid({ rowLimit: MAX_SEARCH_RESULTS_ROWS,
xAlign: St.Align.START });
this.actor = new St.Bin({ x_align: St.Align.START });
this.actor.set_child(this._grid.actor);
this.selectionIndex = -1;
this._width = 0;
this.actor.connect('notify::width', Lang.bind(this, function() {
this._width = this.actor.width;
Meta.later_add(Meta.LaterType.BEFORE_REDRAW, Lang.bind(this, function() {
this._tryAddResults();
}));
}));
this._notDisplayedResult = [];
this._terms = [];
},
_tryAddResults: function() {
let canDisplay = this._grid.childrenInRow(this._width) * MAX_SEARCH_RESULTS_ROWS
- this._grid.visibleItemsCount();
for (let i = Math.min(this._notDisplayedResult.length, canDisplay); i > 0; i--) {
let result = this._notDisplayedResult.shift();
let meta = this.provider.getResultMeta(result);
let display = new SearchResult(this.provider, meta, this._terms);
this._grid.addItem(display.actor);
}
},
getVisibleResultCount: function() {
@ -109,15 +137,15 @@ GridSearchResults.prototype = {
},
renderResults: function(results, terms) {
for (let i = 0; i < results.length; i++) {
let result = results[i];
let meta = this.provider.getResultMeta(result);
let display = new SearchResult(this.provider, meta, terms);
this._grid.addItem(display.actor);
}
// copy the lists
this._notDisplayedResult = results.slice(0);
this._terms = terms.slice(0);
this._tryAddResults();
},
clear: function () {
this._terms = [];
this._notDisplayedResult = [];
this._grid.removeAll();
this.selectionIndex = -1;
},

View File

@ -66,13 +66,13 @@ ATIndicator.prototype = {
let textZoom = this._buildFontItem();
this.menu.addMenuItem(textZoom);
let screenReader = this._buildItem(_("Screen Reader"), APPLICATIONS_SCHEMA,
'screen-reader-enabled');
this.menu.addMenuItem(screenReader);
// let screenReader = this._buildItem(_("Screen Reader"), APPLICATIONS_SCHEMA,
// 'screen-reader-enabled');
// this.menu.addMenuItem(screenReader);
let screenKeyboard = this._buildItem(_("Screen Keyboard"), APPLICATIONS_SCHEMA,
'screen-keyboard-enabled');
this.menu.addMenuItem(screenKeyboard);
// let screenKeyboard = this._buildItem(_("Screen Keyboard"), APPLICATIONS_SCHEMA,
// 'screen-keyboard-enabled');
// this.menu.addMenuItem(screenKeyboard);
let visualBell = this._buildItemGConf(_("Visual Alerts"), client, KEY_VISUAL_BELL);
this.menu.addMenuItem(visualBell);
@ -91,7 +91,8 @@ ATIndicator.prototype = {
this.menu.addMenuItem(new PopupMenu.PopupSeparatorMenuItem());
this.menu.addAction(_("Universal Access Settings"), function() {
Util.spawnDesktop('gnome-universal-access-panel');
let app = Shell.AppSystem.get_default().get_app('gnome-universal-access-panel.desktop');
app.activate(-1);
});
},

View File

@ -93,7 +93,8 @@ Indicator.prototype = {
this._updateFullMenu();
this.menu.addAction(_("Bluetooth Settings"), function() {
GLib.spawn_command_line_async('gnome-control-center bluetooth');
let app = Shell.AppSystem.get_default().get_app('bluetooth-properties.desktop');
app.activate(-1);
});
this._applet.connect('pincode-request', Lang.bind(this, this._pinRequest));
@ -136,6 +137,7 @@ Indicator.prototype = {
_updateDevices: function() {
let devices = this._applet.get_devices();
let newlist = [ ];
for (let i = 0; i < this._deviceItems.length; i++) {
let item = this._deviceItems[i];
let destroy = true;
@ -143,26 +145,20 @@ Indicator.prototype = {
// we need to deep compare because BluetoothSimpleDevice is a boxed type
// (but we take advantage of that, because _skip will disappear the next
// time get_devices() is called)
if (this._deviceCompare(item._device, devices[i])) {
item.label.text = devices[i].alias;
devices[i]._skip = true;
if (this._deviceCompare(item._device, devices[j])) {
item.label.text = devices[j].alias;
devices[j]._skip = true;
destroy = false;
break;
}
}
if (destroy) {
if (destroy)
item.destroy();
item._destroyed = true;
}
}
let newlist = [ ];
for (let i = 0; i < this._deviceItems.length; i++) {
let item = this._deviceItems[i];
if (!item._destroyed)
else
newlist.push(item);
}
this._deviceItems = newlist;
this._deviceItems = newlist;
this._hasDevices = newlist.length > 0;
for (let i = 0; i < devices.length; i++) {
let d = devices[i];
@ -471,9 +467,15 @@ PinNotification.prototype = {
this.connect('action-invoked', Lang.bind(this, function(self, action) {
if (action == 'ok') {
if (this._numeric)
this._applet.agent_reply_passkey(this._devicePath, parseInt(this._entry.text));
else
if (this._numeric) {
let num = parseInt(this._entry.text);
if (isNaN(num)) {
// user reply was empty, or was invalid
// cancel the operation
num = -1;
}
this._applet.agent_reply_passkey(this._devicePath, num);
} else
this._applet.agent_reply_pincode(this._devicePath, this._entry.text);
} else {
if (this._numeric)

View File

@ -74,7 +74,8 @@ XKBIndicator.prototype = {
Util.spawn(['gkbd-keyboard-display', '-g', String(this._config.get_current_group() + 1)]);
}));
this.menu.addAction(_("Localization Settings"), function() {
Util.spawn(['gnome-control-center', 'region']);
let app = Shell.AppSystem.get_default().get_app('gnome-region-panel.desktop');
app.activate(-1);
});
},

2138
js/ui/status/network.js Normal file

File diff suppressed because it is too large Load Diff

View File

@ -83,7 +83,8 @@ Indicator.prototype = {
this.menu.addMenuItem(new PopupMenu.PopupSeparatorMenuItem());
this.menu.addAction(_("Power Settings"),function() {
Util.spawnDesktop('gnome-power-panel');
let app = Shell.AppSystem.get_default().get_app('gnome-power-panel.desktop');
app.activate(-1);
});
this._proxy.connect('Changed', Lang.bind(this, this._devicesChanged));

View File

@ -16,7 +16,6 @@ const Util = imports.misc.util;
const Gettext = imports.gettext.domain('gnome-shell');
const _ = Gettext.gettext;
const VOLUME_MAX = 65536.0; /* PA_VOLUME_NORM */
const VOLUME_ADJUSTMENT_STEP = 0.05; /* Volume adjustment step in % */
const VOLUME_NOTIFY_ID = 1;
@ -37,6 +36,8 @@ Indicator.prototype = {
this._control.connect('default-source-changed', Lang.bind(this, this._readInput));
this._control.connect('stream-added', Lang.bind(this, this._maybeShowInput));
this._control.connect('stream-removed', Lang.bind(this, this._maybeShowInput));
this._volumeMax = this._control.get_vol_max_norm();
this._volumeMaxAmplified = this._control.get_vol_max_amplified();
this._output = null;
this._outputVolumeId = 0;
@ -63,7 +64,8 @@ Indicator.prototype = {
this.menu.addMenuItem(new PopupMenu.PopupSeparatorMenuItem());
this.menu.addAction(_("Sound Settings"), function() {
Util.spawnDesktop('gnome-sound-panel');
let app = Shell.AppSystem.get_default().get_app('gnome-sound-panel.desktop');
app.activate(-1);
});
this.actor.connect('scroll-event', Lang.bind(this, this._onScrollEvent));
@ -72,9 +74,9 @@ Indicator.prototype = {
_getMaxVolume: function(property) {
if (this[property].get_can_decibel())
return (VOLUME_MAX * 1.5);
return this._volumeMaxAmplified;
else
return VOLUME_MAX;
return this._volumeMax;
},
_onScrollEvent: function(actor, event) {

View File

@ -19,7 +19,8 @@ const STANDARD_TRAY_ICON_IMPLEMENTATIONS = {
'a11y-keyboard': 'a11y',
'kbd-scrolllock': 'keyboard',
'kbd-numlock': 'keyboard',
'kbd-capslock': 'keyboard'
'kbd-capslock': 'keyboard',
'ibus-ui-gtk': 'input-method'
};
function StatusIconDispatcher() {

View File

@ -1,6 +1,8 @@
/* -*- mode: js2; js2-basic-offset: 4; indent-tabs-mode: nil -*- */
const Gdm = imports.gi.Gdm;
const DBus = imports.dbus;
const Gio = imports.gi.Gio;
const GLib = imports.gi.GLib;
const Lang = imports.lang;
const Shell = imports.gi.Shell;
@ -16,6 +18,21 @@ const PanelMenu = imports.ui.panelMenu;
const PopupMenu = imports.ui.popupMenu;
const Util = imports.misc.util;
const BUS_NAME = 'org.gnome.ScreenSaver';
const OBJECT_PATH = '/org/gnome/ScreenSaver';
const LOCKDOWN_SCHEMA = 'org.gnome.desktop.lockdown';
const DISABLE_USER_SWITCH_KEY = 'disable-user-switching';
const DISABLE_LOCK_SCREEN_KEY = 'disable-lock-screen';
const DISABLE_LOG_OUT_KEY = 'disable-log-out';
const ScreenSaverInterface = {
name: BUS_NAME,
methods: [ { name: 'Lock', inSignature: '' } ]
};
let ScreenSaverProxy = DBus.makeProxyClass(ScreenSaverInterface);
// Adapted from gdm/gui/user-switch-applet/applet.c
//
// Copyright (C) 2004-2005 James M. Cape <jcape@ignore-your.tv>.
@ -33,17 +50,20 @@ StatusMenuButton.prototype = {
let box = new St.BoxLayout({ name: 'panelStatusMenu' });
this.actor.set_child(box);
this._lockdownSettings = new Gio.Settings({ schema: LOCKDOWN_SCHEMA });
this._gdm = Gdm.UserManager.ref_default();
this._gdm.queue_load();
this._user = this._gdm.get_user(GLib.get_user_name());
this._presence = new GnomeSession.Presence();
this._presenceItems = {};
this._session = new GnomeSession.SessionManager();
this._account_mgr = Tp.AccountManager.dup()
this._upClient = new UPowerGlib.Client();
this._screenSaverProxy = new ScreenSaverProxy(DBus.session, BUS_NAME, OBJECT_PATH);
this.actor.connect('destroy', Lang.bind(this, this._onDestroy));
this._iconBox = new St.Bin();
@ -67,6 +87,15 @@ StatusMenuButton.prototype = {
this._gdm.connect('notify::is-loaded', Lang.bind(this, this._updateSwitchUser));
this._gdm.connect('user-added', Lang.bind(this, this._updateSwitchUser));
this._gdm.connect('user-removed', Lang.bind(this, this._updateSwitchUser));
this._lockdownSettings.connect('changed::' + DISABLE_USER_SWITCH_KEY,
Lang.bind(this, this._updateSwitchUser));
this._lockdownSettings.connect('changed::' + DISABLE_LOG_OUT_KEY,
Lang.bind(this, this._updateLogout));
this._lockdownSettings.connect('changed::' + DISABLE_LOCK_SCREEN_KEY,
Lang.bind(this, this._updateLockScreen));
this._updateSwitchUser();
this._updateLogout();
this._updateLockScreen();
this._upClient.connect('notify::can-suspend', Lang.bind(this, this._updateSuspendOrPowerOff));
},
@ -83,11 +112,41 @@ StatusMenuButton.prototype = {
this._name.set_text("");
},
_updateSessionSeparator: function() {
let showSeparator = this._loginScreenItem.actor.visible ||
this._logoutItem.actor.visible ||
this._lockScreenItem.actor.visible;
if (showSeparator)
this._sessionSeparator.actor.show();
else
this._sessionSeparator.actor.hide();
},
_updateSwitchUser: function() {
if (this._gdm.can_switch ())
let allowSwitch = !this._lockdownSettings.get_boolean(DISABLE_USER_SWITCH_KEY);
if (allowSwitch && this._gdm.can_switch ())
this._loginScreenItem.actor.show();
else
this._loginScreenItem.actor.hide();
this._updateSessionSeparator();
},
_updateLogout: function() {
let allowLogout = !this._lockdownSettings.get_boolean(DISABLE_LOG_OUT_KEY);
if (allowLogout)
this._logoutItem.actor.show();
else
this._logoutItem.actor.hide();
this._updateSessionSeparator();
},
_updateLockScreen: function() {
let allowLockScreen = !this._lockdownSettings.get_boolean(DISABLE_LOCK_SCREEN_KEY);
if (allowLockScreen)
this._lockScreenItem.actor.show();
else
this._lockScreenItem.actor.hide();
this._updateSessionSeparator();
},
_updateSuspendOrPowerOff: function() {
@ -101,7 +160,7 @@ StatusMenuButton.prototype = {
if (!this._haveSuspend) {
this._suspendOrPowerOffItem.updateText(_("Power Off..."), null);
} else {
this._suspendOrPowerOffItem.updateText(_("Suspend"), ("Power Off..."));
this._suspendOrPowerOffItem.updateText(_("Suspend"), _("Power Off..."));
}
},
@ -149,6 +208,7 @@ StatusMenuButton.prototype = {
item = new PopupMenu.PopupMenuItem(_("Lock Screen"));
item.connect('activate', Lang.bind(this, this._onLockScreenActivate));
this.menu.addMenuItem(item);
this._lockScreenItem = item;
item = new PopupMenu.PopupMenuItem(_("Switch User"));
item.connect('activate', Lang.bind(this, this._onLoginScreenActivate));
@ -158,9 +218,11 @@ StatusMenuButton.prototype = {
item = new PopupMenu.PopupMenuItem(_("Log Out..."));
item.connect('activate', Lang.bind(this, this._onQuitSessionActivate));
this.menu.addMenuItem(item);
this._logoutItem = item;
item = new PopupMenu.PopupSeparatorMenuItem();
this.menu.addMenuItem(item);
this._sessionSeparator = item;
item = new PopupMenu.PopupAlternatingMenuItem(_("Suspend"),
_("Power Off..."));
@ -178,17 +240,19 @@ StatusMenuButton.prototype = {
_onMyAccountActivate: function() {
Main.overview.hide();
Util.spawnDesktop('gnome-user-accounts-panel');
let app = Shell.AppSystem.get_default().get_app('gnome-user-accounts-panel.desktop');
app.activate(-1);
},
_onPreferencesActivate: function() {
Main.overview.hide();
Util.spawnDesktop('gnome-control-center');
let app = Shell.AppSystem.get_default().get_app('gnome-control-center.desktop');
app.activate(-1);
},
_onLockScreenActivate: function() {
Main.overview.hide();
Util.spawn(['gnome-screensaver-command', '--lock']);
this._screenSaverProxy.LockRemote();
},
_onLoginScreenActivate: function() {
@ -199,7 +263,7 @@ StatusMenuButton.prototype = {
_onQuitSessionActivate: function() {
Main.overview.hide();
Util.spawn(['gnome-session-quit', '--logout']);
this._session.LogoutRemote(0);
},
_onSuspendOrPowerOffActivate: function() {
@ -207,9 +271,11 @@ StatusMenuButton.prototype = {
if (this._haveSuspend &&
this._suspendOrPowerOffItem.state == PopupMenu.PopupAlternatingMenuItemState.DEFAULT) {
this._upClient.suspend_sync(null);
this._screenSaverProxy.LockRemote(Lang.bind(this, function() {
this._upClient.suspend_sync(null);
}));
} else {
Util.spawn(['gnome-session-quit', '--power-off']);
this._session.ShutdownRemote();
}
},

View File

@ -7,10 +7,13 @@ const Mainloop = imports.mainloop;
const Shell = imports.gi.Shell;
const Signals = imports.signals;
const St = imports.gi.St;
const Tpl = imports.gi.TelepathyLogger;
const Tp = imports.gi.TelepathyGLib;
const Gettext = imports.gettext.domain('gnome-shell');
const _ = Gettext.gettext;
const C_ = Gettext.pgettext;
const History = imports.misc.history;
const Main = imports.ui.main;
const MessageTray = imports.ui.messageTray;
@ -21,6 +24,9 @@ const SCROLLBACK_RECENT_TIME = 15 * 60; // 15 minutes
const SCROLLBACK_RECENT_LENGTH = 20;
const SCROLLBACK_IDLE_LENGTH = 5;
// See Source._displayPendingMessages
const SCROLLBACK_HISTORY_LINES = 10;
const NotificationDirection = {
SENT: 'chat-sent',
RECEIVED: 'chat-received'
@ -35,6 +41,31 @@ let contactFeatures = [Tp.ContactFeature.ALIAS,
// lets us see messages even if they belong to another app (eg,
// Empathy).
function makeMessageFromTpMessage(tpMessage, direction) {
let [text, flags] = tpMessage.to_text();
return {
messageType: tpMessage.get_message_type(),
text: text,
sender: tpMessage.sender.alias,
timestamp: tpMessage.get_received_timestamp(),
direction: direction
};
}
function makeMessageFromTplEvent(event) {
let sent = event.get_sender().get_entity_type() == Tpl.EntityType.SELF;
let direction = sent ? NotificationDirection.SENT : NotificationDirection.RECEIVED;
return {
messageType: event.get_message_type(),
text: event.get_message(),
sender: event.get_sender().get_alias(),
timestamp: event.get_timestamp(),
direction: direction
};
}
function Client() {
this._init();
};
@ -67,7 +98,22 @@ Client.prototype = {
_observeChannels: function(observer, account, conn, channels,
dispatchOp, requests, context) {
let connPath = conn.get_object_path();
// If the self_contact doesn't have the ALIAS, make sure
// to fetch it before trying to grab the channels.
let self_contact = conn.get_self_contact();
if (self_contact.has_feature(Tp.ContactFeature.ALIAS)) {
this._finishObserveChannels(account, conn, channels, context);
} else {
Shell.get_self_contact_features(conn,
contactFeatures.length, contactFeatures,
Lang.bind(this, function() {
this._finishObserveChannels(account, conn, channels, context);
}));
context.delay();
}
},
_finishObserveChannels: function(account, conn, channels, context) {
let len = channels.length;
for (let i = 0; i < len; i++) {
let channel = channels[i];
@ -90,7 +136,6 @@ Client.prototype = {
}), null);
}
// Allow dbus method to return
context.accept();
},
@ -116,7 +161,7 @@ Source.prototype = {
__proto__: MessageTray.Source.prototype,
_init: function(account, conn, channel, contact) {
MessageTray.Source.prototype._init.call(this, channel.get_identifier());
MessageTray.Source.prototype._init.call(this, contact.get_alias());
this.isChat = true;
@ -127,8 +172,6 @@ Source.prototype = {
this._channel = channel;
this._closedId = this._channel.connect('invalidated', Lang.bind(this, this._channelClosed));
this._updateAlias();
this._notification = new Notification(this);
this._notification.setUrgency(MessageTray.Urgency.HIGH);
@ -143,11 +186,18 @@ Source.prototype = {
this._notifyAvatarId = this._contact.connect('notify::avatar-file', Lang.bind(this, this._updateAvatarIcon));
this._presenceChangedId = this._contact.connect('presence-changed', Lang.bind(this, this._presenceChanged));
this._displayPendingMessages();
// Add ourselves as a source.
Main.messageTray.add(this);
this.pushNotification(this._notification);
this._getLogMessages();
},
_updateAlias: function() {
let oldAlias = this.title;
this.title = this._contact.get_alias();
this._notification.appendAliasChange(oldAlias, this.title);
this.pushNotification(this._notification);
},
createNotificationIcon: function() {
@ -183,13 +233,52 @@ Source.prototype = {
req.ensure_channel_async('', null, null);
},
_displayPendingMessages: function() {
let msgs = this._channel.get_pending_messages();
_getLogMessages: function() {
let logManager = Tpl.LogManager.dup_singleton();
let entity = Tpl.Entity.new_from_tp_contact(this._contact, Tpl.EntityType.CONTACT);
Shell.get_contact_events(logManager,
this._account, entity,
SCROLLBACK_HISTORY_LINES,
Lang.bind(this, this._displayPendingMessages));
},
for (let i = 0; i < msgs.length; i++) {
let msg = msgs[i];
this._messageReceived(this._channel, msg);
_displayPendingMessages: function(logManager, result) {
let [success, events] = logManager.get_filtered_events_finish(result);
let logMessages = events.map(makeMessageFromTplEvent);
let pendingTpMessages = this._channel.get_pending_messages();
let pendingMessages = pendingTpMessages.map(function (tpMessage) { return makeMessageFromTpMessage(tpMessage, NotificationDirection.RECEIVED); });
let showTimestamp = false;
for (let i = 0; i < logMessages.length; i++) {
let logMessage = logMessages[i];
let isPending = false;
// Skip any log messages that are also in pendingMessages
for (let j = 0; j < pendingMessages.length; j++) {
let pending = pendingMessages[j];
if (logMessage.timestamp == pending.timestamp && logMessage.text == pending.text) {
isPending = true;
break;
}
}
if (!isPending) {
showTimestamp = true;
this._notification.appendMessage(logMessage, true, ['chat-log-message']);
}
}
if (showTimestamp)
this._notification.appendTimestamp();
for (let i = 0; i < pendingMessages.length; i++)
this._notification.appendMessage(pendingMessages[i], true);
if (pendingMessages.length > 0)
this.notify();
},
_channelClosed: function() {
@ -205,25 +294,32 @@ Source.prototype = {
},
_messageReceived: function(channel, message) {
this._notification.appendMessage(message, NotificationDirection.RECEIVED);
message = makeMessageFromTpMessage(message, NotificationDirection.RECEIVED);
this._notification.appendMessage(message);
this.notify();
},
// This is called for both messages we send from
// our client and other clients as well.
_messageSent: function(channel, message, flags, token) {
this._notification.appendMessage(message, NotificationDirection.SENT);
message = makeMessageFromTpMessage(message, NotificationDirection.SENT);
this._notification.appendMessage(message);
},
notify: function() {
if (!Main.messageTray.contains(this))
Main.messageTray.add(this);
MessageTray.Source.prototype.notify.call(this, this._notification);
},
respond: function(text) {
let msg = Tp.ClientMessage.new_text(Tp.ChannelTextMessageType.NORMAL, text);
let type;
if (text.slice(0, 4) == '/me ') {
type = Tp.ChannelTextMessageType.ACTION;
text = text.slice(4);
} else {
type = Tp.ChannelTextMessageType.NORMAL;
}
let msg = Tp.ClientMessage.new_text(type, text);
this._channel.send_message_async(msg, 0, null);
},
@ -279,19 +375,52 @@ Notification.prototype = {
this._responseEntry.clutter_text.connect('activate', Lang.bind(this, this._onEntryActivated));
this.setActionArea(this._responseEntry);
this._oldMaxScrollAdjustment = 0;
this._createScrollArea();
this._scrollArea.vscroll.adjustment.connect('changed', Lang.bind(this, function(adjustment) {
let currentValue = adjustment.value + adjustment.page_size;
if (currentValue == this._oldMaxScrollAdjustment)
this.scrollTo(St.Side.BOTTOM);
this._oldMaxScrollAdjustment = adjustment.upper;
}));
this._inputHistory = new History.HistoryManager({ entry: this._responseEntry.clutter_text });
this._history = [];
this._timestampTimeoutId = 0;
},
appendMessage: function(message, direction) {
let [text, flags] = message.to_text();
let timestamp = message.get_received_timestamp();
/**
* appendMessage:
* @message: An object with the properties:
* text: the body of the message,
* messageType: a #Tp.ChannelTextMessageType,
* sender: the name of the sender,
* timestamp: the time the message was sent
* direction: a #NotificationDirection
*
* @noTimestamp: Whether to add a timestamp. If %true, no timestamp
* will be added, regardless of the difference since the
* last timestamp
* @styles: A list of CSS class names.
*/
appendMessage: function(message, noTimestamp, styles) {
let messageBody = GLib.markup_escape_text(message.text, -1);
styles = styles || [];
styles.push(message.direction);
this.update(this.source.title, text, { customContent: true });
this._append(text, direction, timestamp);
if (message.messageType == Tp.ChannelTextMessageType.ACTION) {
let senderAlias = GLib.markup_escape_text(message.sender, -1);
messageBody = '<i>%s</i> %s'.format(senderAlias, messageBody);
styles.push('chat-action');
}
this.update(this.source.title, messageBody, { customContent: true, bannerMarkup: true });
this._append(messageBody, styles, message.timestamp, noTimestamp);
},
_append: function(text, style, timestamp) {
_append: function(text, styles, timestamp, noTimestamp) {
let currentTime = (Date.now() / 1000);
if (!timestamp)
timestamp = currentTime;
@ -303,20 +432,22 @@ Notification.prototype = {
if (this._timestampTimeoutId)
Mainloop.source_remove(this._timestampTimeoutId);
let body = this.addBody(text);
body.add_style_class_name(style);
this.scrollTo(St.Side.BOTTOM);
let body = this.addBody(text, true);
for (let i = 0; i < styles.length; i ++)
body.add_style_class_name(styles[i]);
this._history.unshift({ actor: body, time: timestamp, realMessage: true });
if (timestamp < currentTime - SCROLLBACK_IMMEDIATE_TIME)
this._appendTimestamp();
else
// Schedule a new timestamp in SCROLLBACK_IMMEDIATE_TIME
// from the timestamp of the message.
this._timestampTimeoutId = Mainloop.timeout_add_seconds(
SCROLLBACK_IMMEDIATE_TIME - (currentTime - timestamp),
Lang.bind(this, this._appendTimestamp));
if (!noTimestamp) {
if (timestamp < currentTime - SCROLLBACK_IMMEDIATE_TIME)
this.appendTimestamp();
else
// Schedule a new timestamp in SCROLLBACK_IMMEDIATE_TIME
// from the timestamp of the message.
this._timestampTimeoutId = Mainloop.timeout_add_seconds(
SCROLLBACK_IMMEDIATE_TIME - (currentTime - timestamp),
Lang.bind(this, this.appendTimestamp));
}
if (this._history.length > 1) {
// Keep the scrollback from growing too long. If the most
@ -337,15 +468,39 @@ Notification.prototype = {
}
},
_appendTimestamp: function() {
_formatTimestamp: function(date) {
let now = new Date();
var daysAgo = (now.getTime() - date.getTime()) / (24 * 60 * 60 * 1000);
// Show a week day and time if date is in the last week
if (daysAgo < 1 || (daysAgo < 7 && now.getDay() != date.getDay())) {
/* Translators: this is a time format string followed by a date.
If applicable, replace %X with a strftime format valid for your
locale, without seconds. */
// xgettext:no-c-format
format = _("Sent at %X on %A");
// FIXME: The next two are stolen from calendar.js with the comment to avoid
// a string-freeze break. They should be replaced with better strings
// with 'Sent at', appropriate context and appropriate translator comment.
} else if (date.getYear() == now.getYear()) {
/* Translators: Shown on calendar heading when selected day occurs on current year */
format = C_("calendar heading", "%A, %B %d");
} else {
/* Translators: Shown on calendar heading when selected day occurs on different year */
format = C_("calendar heading", "%A, %B %d, %Y");
}
return date.toLocaleFormat(format);
},
appendTimestamp: function() {
let lastMessageTime = this._history[0].time;
let lastMessageDate = new Date(lastMessageTime * 1000);
/* Translators: this is a time format string followed by a date.
If applicable, replace %X with a strftime format valid for your
locale, without seconds. */
// xgettext:no-c-format
let timeLabel = this.addBody(lastMessageDate.toLocaleFormat(_("Sent at %X on %A")), false, { expand: true, x_fill: false, x_align: St.Align.END });
let timeLabel = this.addBody(this._formatTimestamp(lastMessageDate), false, { expand: true, x_fill: false, x_align: St.Align.END });
timeLabel.add_style_class_name('chat-meta-message');
this._history.unshift({ actor: timeLabel, time: lastMessageTime, realMessage: false });
@ -363,11 +518,28 @@ Notification.prototype = {
this._history.unshift({ actor: label, time: (Date.now() / 1000), realMessage: false});
},
appendAliasChange: function(oldAlias, newAlias) {
// FIXME: uncomment this after 3.0 string freeze ends
// oldAlias = GLib.markup_escape_text(oldAlias, -1);
// newAlias = GLib.markup_escape_text(newAlias, -1);
// /* Translators: this is the other person changing their old IM name to their new
// IM name. */
// let message = '<i>' + _("%s is now known as %s").format(oldAlias, newAlias) + '</i>';
// let label = this.addBody(message, true);
// label.add_style_class_name('chat-meta-message');
// this._history.unshift({ actor: label, time: (Date.now() / 1000), realMessage: false });
// this.update(newAlias, null, { customContent: true });
},
_onEntryActivated: function() {
let text = this._responseEntry.get_text();
if (text == '')
return;
this._inputHistory.addItem(text);
// Telepathy sends out the Sent signal for us.
// see Source._messageSent
this._responseEntry.set_text('');

View File

@ -41,11 +41,14 @@ BaseTab.prototype = {
this.visible = false;
},
show: function() {
show: function(animate) {
this.visible = true;
this.page.opacity = 0;
this.page.show();
if (!animate)
return;
this.page.opacity = 0;
Tweener.addTween(this.page,
{ opacity: 255,
time: 0.1,
@ -77,14 +80,16 @@ BaseTab.prototype = {
Signals.addSignalMethods(BaseTab.prototype);
function ViewTab(label, pageActor, a11yIcon) {
this._init(label, pageActor, a11yIcon);
function ViewTab(id, label, pageActor, a11yIcon) {
this._init(id, label, pageActor, a11yIcon);
}
ViewTab.prototype = {
__proto__: BaseTab.prototype,
_init: function(label, pageActor, a11yIcon) {
_init: function(id, label, pageActor, a11yIcon) {
this.id = id;
let titleActor = new St.Button({ label: label,
style_class: 'view-tab-title' });
titleActor.connect('clicked', Lang.bind(this, this._activate));
@ -383,14 +388,16 @@ ViewSelector.prototype = {
}));
},
addViewTab: function(title, pageActor, a11yIcon) {
let viewTab = new ViewTab(title, pageActor, a11yIcon);
addViewTab: function(id, title, pageActor, a11yIcon) {
let viewTab = new ViewTab(id, title, pageActor, a11yIcon);
this._tabs.push(viewTab);
this._tabBox.add(viewTab.title);
this._addTab(viewTab);
},
_switchTab: function(tab) {
let firstSwitch = this._activeTab == null;
if (this._activeTab && this._activeTab.visible) {
if (this._activeTab == tab)
return;
@ -406,11 +413,13 @@ ViewSelector.prototype = {
}
}
// Only fade when switching between tabs,
// not when setting the initially selected one.
if (!tab.visible)
tab.show();
tab.show(!firstSwitch);
// Pull a Meg Ryan:
if (Main.overview && Main.overview.workspaces) {
if (!firstSwitch && Main.overview.workspaces) {
if (tab != this._tabs[0]) {
Tweener.addTween(Main.overview.workspaces.actor,
{ opacity: 0,
@ -433,6 +442,14 @@ ViewSelector.prototype = {
}
},
switchTab: function(id) {
for (let i = 0; i < this._tabs.length; i++)
if (this._tabs[i].id == id) {
this._switchTab(this._tabs[i]);
break;
}
},
_switchDefaultTab: function() {
if (this._tabs.length > 0)
this._switchTab(this._tabs[0]);

View File

@ -93,6 +93,8 @@ WindowManager.prototype = {
this._dimmedWindows = [];
this._animationBlockCount = 0;
this._switchData = null;
this._shellwm.connect('kill-switch-workspace', Lang.bind(this, this._switchWorkspaceDone));
this._shellwm.connect('kill-window-effects', Lang.bind(this, function (shellwm, actor) {
@ -121,11 +123,11 @@ WindowManager.prototype = {
Main.overview.connect('showing', Lang.bind(this, function() {
for (let i = 0; i < this._dimmedWindows.length; i++)
this._undimParentWindow(this._dimmedWindows[i], true);
this._undimWindow(this._dimmedWindows[i], true);
}));
Main.overview.connect('hiding', Lang.bind(this, function() {
for (let i = 0; i < this._dimmedWindows.length; i++)
this._dimParentWindow(this._dimmedWindows[i], true);
this._dimWindow(this._dimmedWindows[i], true);
}));
},
@ -139,8 +141,16 @@ WindowManager.prototype = {
this._shellwm.connect('keybinding::' + keybinding, handler);
},
blockAnimations: function() {
this._animationBlockCount++;
},
unblockAnimations: function() {
this._animationBlockCount = Math.max(0, this._animationBlockCount - 1);
},
_shouldAnimate : function(actor) {
if (Main.overview.visible)
if (Main.overview.visible || this._animationsBlocked > 0)
return false;
if (actor && (actor.meta_window.get_window_type() != Meta.WindowType.NORMAL))
return false;
@ -224,41 +234,39 @@ WindowManager.prototype = {
_unmaximizeWindowDone : function(shellwm, actor) {
},
_parentHasOtherAttachedDialog: function(parent, self) {
_hasAttachedDialogs: function(window, ignoreWindow) {
var count = 0;
parent.foreach_transient(function(win) {
if (win.get_window_type() == Meta.WindowType.MODAL_DIALOG && win != self)
window.foreach_transient(function(win) {
if (win != ignoreWindow && win.get_window_type() == Meta.WindowType.MODAL_DIALOG)
count++;
return false;
});
return count != 0;
},
_markParentWindowAsDimmable: function(actor, animate) {
if (Meta.prefs_get_attach_modal_dialogs()) {
this._dimmedWindows.push(actor);
if (this._shouldAnimate())
this._dimParentWindow(actor, animate);
_checkDimming: function(window, ignoreWindow) {
let shouldDim = Meta.prefs_get_attach_modal_dialogs() && this._hasAttachedDialogs(window, ignoreWindow);
if (shouldDim && !window._dimmed) {
window._dimmed = true;
this._dimmedWindows.push(window);
if (!Main.overview.visible)
this._dimWindow(window, true);
} else if (!shouldDim && window._dimmed) {
window._dimmed = false;
this._dimmedWindows = this._dimmedWindows.filter(function(win) {
return win != window;
});
if (!Main.overview.visible)
this._undimWindow(window, true);
}
},
_unmarkParentWindowAsDimmable: function(actor, animate) {
if (!Main.overview.visible)
this._undimParentWindow(actor, true);
this._dimmedWindows = this._dimmedWindows.filter(function(win) {
return win != actor;
});
},
_dimParentWindow: function(actor, animate) {
let meta = actor.get_meta_window();
let parent = meta.get_transient_for();
if (!parent)
_dimWindow: function(window, animate) {
let actor = window.get_compositor_private();
if (!actor)
return;
let parentActor = parent.get_compositor_private();
if (!parentActor || this._parentHasOtherAttachedDialog(parent, meta))
return;
let texture = parentActor.get_texture();
let texture = actor.get_texture();
if (animate)
Tweener.addTween(getWindowDimmer(texture),
{ dimFraction: 1.0,
@ -269,15 +277,11 @@ WindowManager.prototype = {
getWindowDimmer(texture).dimFraction = 1.0;
},
_undimParentWindow: function(actor, animate) {
let meta = actor.get_meta_window();
let parent = meta.get_transient_for();
if (!parent)
_undimWindow: function(window, animate) {
let actor = window.get_compositor_private();
if (!actor)
return;
let parentActor = parent.get_compositor_private();
if (!parentActor || this._parentHasOtherAttachedDialog(parent, meta))
return;
let texture = parentActor.get_texture();
let texture = actor.get_texture();
if (animate)
Tweener.addTween(getWindowDimmer(texture),
{ dimFraction: 0.0,
@ -294,17 +298,19 @@ WindowManager.prototype = {
let type = actor.meta_window.get_window_type();
if (type == actor._windowType)
return;
if (type == Meta.WindowType.MODAL_DIALOG)
this._markParentWindowAsDimmable(actor, true);
else if (actor._windowType == Meta.WindowType.MODAL_DIALOG)
this._unmarkParentWindowAsDimmable(actor, true);
if (type == Meta.WindowType.MODAL_DIALOG ||
actor._windowType == Meta.WindowType.MODAL_DIALOG) {
let parent = actor.get_meta_window().get_transient_for();
if (parent)
this._checkDimming(parent);
}
actor._windowType = type;
}));
if (actor.meta_window.get_window_type() == Meta.WindowType.MODAL_DIALOG
&& Meta.prefs_get_attach_modal_dialogs()
&& actor.get_meta_window().get_transient_for()) {
this._markParentWindowAsDimmable(actor, true);
this._checkDimming(actor.get_meta_window().get_transient_for());
if (this._shouldAnimate()) {
actor.set_scale(1.0, 0.0);
actor.show();
@ -364,14 +370,20 @@ WindowManager.prototype = {
},
_destroyWindow : function(shellwm, actor) {
let parent = actor.meta_window.get_transient_for();
let window = actor.meta_window;
let parent = window.get_transient_for();
if (actor._notifyWindowTypeSignalId) {
actor.meta_window.disconnect(actor._notifyWindowTypeSignalId);
window.disconnect(actor._notifyWindowTypeSignalId);
actor._notifyWindowTypeSignalId = 0;
}
while (actor.meta_window.get_window_type() == Meta.WindowType.MODAL_DIALOG
if (window._dimmed) {
this._dimmedWindows = this._dimmedWindows.filter(function(win) {
return win != window;
});
}
while (window.get_window_type() == Meta.WindowType.MODAL_DIALOG
&& parent) {
this._unmarkParentWindowAsDimmable(actor, true);
this._checkDimming(parent, window);
if (!Meta.prefs_get_attach_modal_dialogs()
|| !this._shouldAnimate())
break;

View File

@ -125,6 +125,7 @@ WindowClone.prototype = {
dragActorMaxSize: WINDOW_DND_SIZE,
dragActorOpacity: DRAGGING_WINDOW_OPACITY });
this._draggable.connect('drag-begin', Lang.bind(this, this._onDragBegin));
this._draggable.connect('drag-cancelled', Lang.bind(this, this._onDragCancelled));
this._draggable.connect('drag-end', Lang.bind(this, this._onDragEnd));
this.inDrag = false;
@ -220,8 +221,15 @@ WindowClone.prototype = {
let [width, height] = this.actor.get_transformed_size();
this.actor.x = _clamp(this.actor.x, 0, global.screen_width - width);
this.actor.y = _clamp(this.actor.y, Panel.PANEL_HEIGHT, global.screen_height - height);
let monitorIndex = this.metaWindow.get_monitor();
let availArea = global.get_monitors()[monitorIndex];
if (monitorIndex == global.get_primary_monitor_index()) {
availArea.y += Main.panel.actor.height;
availArea.height -= Main.panel.actor.height;
}
this.actor.x = _clamp(this.actor.x, availArea.x, availArea.x + availArea.width - width);
this.actor.y = _clamp(this.actor.y, availArea.y, availArea.y + availArea.height - height);
},
_zoomStart : function () {
@ -288,10 +296,16 @@ WindowClone.prototype = {
},
_onDragBegin : function (draggable, time) {
[this.dragOrigX, this.dragOrigY] = this.actor.get_position();
this.dragOrigScale = this.actor.scale_x;
this.inDrag = true;
this.emit('drag-begin');
},
_onDragCancelled : function (draggable, time) {
this.emit('drag-cancelled');
},
_onDragEnd : function (draggable, time, snapback) {
this.inDrag = false;
@ -327,6 +341,7 @@ WindowOverlay.prototype = {
this._windowClone = windowClone;
this._parentActor = parentActor;
this._hidden = false;
let title = new St.Label({ style_class: 'window-caption',
text: metaWindow.title });
@ -372,23 +387,19 @@ WindowOverlay.prototype = {
},
hide: function() {
this._hidden = true;
this.closeButton.hide();
this.title.hide();
},
show: function() {
let [x, y, mask] = global.get_pointer();
let actor = global.stage.get_actor_at_pos(Clutter.PickMode.REACTIVE,
x, y);
if (actor == this._windowClone.actor) {
this.closeButton.show();
}
this._hidden = false;
this.title.show();
},
fadeIn: function() {
this.show();
this.title.opacity = 0;
this.title.show();
this._parentActor.raise_top();
Tweener.addTween(this.title,
{ opacity: 255,
@ -480,6 +491,12 @@ WindowOverlay.prototype = {
},
_onEnter: function() {
// We might get enter events on the clone while the overlay is
// hidden, e.g. during animations, we ignore these events,
// as the close button will be shown as needed when the overlays
// are shown again
if (this._hidden)
return;
this._parentActor.raise_top();
this.closeButton.show();
this.emit('show-close-button');
@ -520,44 +537,45 @@ WindowOverlay.prototype = {
Signals.addSignalMethods(WindowOverlay.prototype);
const WindowPositionFlags = {
ZOOM: 1 << 0,
INITIAL: 1 << 0,
ANIMATE: 1 << 1
};
/**
* @metaWorkspace: a #Meta.Workspace
* @metaWorkspace: a #Meta.Workspace, or null
*/
function Workspace(metaWorkspace) {
this._init(metaWorkspace);
function Workspace(metaWorkspace, monitorIndex) {
this._init(metaWorkspace, monitorIndex);
}
Workspace.prototype = {
_init : function(metaWorkspace) {
_init : function(metaWorkspace, monitorIndex) {
// When dragging a window, we use this slot for reserve space.
this._reservedSlot = null;
this.metaWorkspace = metaWorkspace;
this._x = 0;
this._y = 0;
this._width = 0;
this._height = 0;
this.monitorIndex = monitorIndex;
this._monitor = global.get_monitors()[this.monitorIndex];
this._windowOverlaysGroup = new Clutter.Group();
// Without this the drop area will be overlapped.
this._windowOverlaysGroup.set_size(0, 0);
this.actor = new Clutter.Group();
this.actor._delegate = this;
this.actor.set_size(0, 0);
this._dropRect = new Clutter.Rectangle({ opacity: 0 });
this._dropRect._delegate = this;
this.actor.add_actor(this._dropRect);
this.actor.add_actor(this._windowOverlaysGroup);
this.actor.connect('destroy', Lang.bind(this, this._onDestroy));
// Items in _windowOverlaysGroup should not be scaled, so we don't
// add them to this.actor, but to its parent whenever it changes
this.actor.connect('parent-set', Lang.bind(this, this._onParentSet));
// Auto-sizing is unreliable in the presence of ClutterClone, so rather than
// implicitly counting on the workspace actor to be sized to the size of the
// included desktop actor clone, set the size explicitly to the screen size.
// See http://bugzilla.openedhand.com/show_bug.cgi?id=1755
this.actor.width = global.screen_width;
this.actor.height = global.screen_height;
this.scale = 1.0;
let windows = Main.getWindowActorsForWorkspace(this.metaWorkspace.index());
let windows = global.get_window_actors().filter(this._isMyWindow, this);
// Create clones for windows that should be
// visible in the Overview
@ -570,15 +588,37 @@ Workspace.prototype = {
}
// Track window changes
this._windowAddedId = this.metaWorkspace.connect('window-added',
Lang.bind(this, this._windowAdded));
this._windowRemovedId = this.metaWorkspace.connect('window-removed',
Lang.bind(this, this._windowRemoved));
if (this.metaWorkspace) {
this._windowAddedId = this.metaWorkspace.connect('window-added',
Lang.bind(this, this._windowAdded));
this._windowRemovedId = this.metaWorkspace.connect('window-removed',
Lang.bind(this, this._windowRemoved));
}
this._windowEnteredMonitorId = global.screen.connect('window-entered-monitor',
Lang.bind(this, this._windowEnteredMonitor));
this._windowLeftMonitorId = global.screen.connect('window-left-monitor',
Lang.bind(this, this._windowLeftMonitor));
this._repositionWindowsId = 0;
this.leavingOverview = false;
},
setGeometry: function(x, y, width, height) {
this._x = x;
this._y = y;
this._width = width;
this._height = height;
// This is sometimes called during allocation, so we do this later
Meta.later_add(Meta.LaterType.BEFORE_REDRAW, Lang.bind(this,
function () {
this._dropRect.set_position(x, y);
this._dropRect.set_size(width, height);
return false;
}));
},
_lookupIndex: function (metaWindow) {
for (let i = 0; i < this._windows.length; i++) {
if (this._windows[i].metaWindow == metaWindow) {
@ -588,17 +628,6 @@ Workspace.prototype = {
return -1;
},
_onParentSet: function(actor, old_parent) {
let new_parent = this.actor.get_parent();
if (new_parent == null)
return;
if (old_parent)
this._windowOverlaysGroup.reparent(new_parent);
else
new_parent.add_actor(this._windowOverlaysGroup);
},
containsMetaWindow: function (metaWindow) {
return this._lookupIndex(metaWindow) >= 0;
},
@ -677,10 +706,20 @@ Workspace.prototype = {
let xDelta, yDelta, distanceSquared;
let actorWidth, actorHeight;
actorWidth = actor.width * actor.scale_x;
actorHeight = actor.height * actor.scale_y;
xDelta = actor.x + actorWidth / 2.0 - xCenter * global.screen_width;
yDelta = actor.y + actorHeight / 2.0 - yCenter * global.screen_height;
let x = actor.x;
let y = actor.y;
let scale = actor.scale_x;
if (actor._delegate.inDrag) {
x = actor._delegate.dragOrigX;
y = actor._delegate.dragOrigY;
scale = actor._delegate.dragOrigScale;
}
actorWidth = actor.width * scale;
actorHeight = actor.height * scale;
xDelta = x + actorWidth / 2.0 - xCenter * this._width - this._x;
yDelta = y + actorHeight / 2.0 - yCenter * this._height - this._y;
distanceSquared = xDelta * xDelta + yDelta * yDelta;
return distanceSquared;
@ -705,6 +744,12 @@ Workspace.prototype = {
let delta = this._computeWindowMotion(cloneActor, slot);
motion += delta;
// Bail out early if we're already larger than the
// previous best
if (minimumMotionPermutation != null &&
motion > minimumMotion)
continue;
}
if (minimumMotionPermutation == null || motion < minimumMotion) {
@ -765,38 +810,35 @@ Workspace.prototype = {
},
/**
* _getSlotRelativeGeometry:
* _getSlotGeometry:
* @slot: A layout slot
*
* Returns: the workspace-relative [x, y, width, height]
* Returns: the screen-relative [x, y, width, height]
* of a given window layout slot.
*/
_getSlotRelativeGeometry: function(slot) {
_getSlotGeometry: function(slot) {
let [xCenter, yCenter, fraction] = slot;
let width = global.screen_width * fraction;
let height = global.screen_height * fraction;
let width = this._width * fraction;
let height = this._height * fraction;
let x = xCenter * global.screen_width - width / 2;
let y = yCenter * global.screen_height - height / 2;
let x = this._x + xCenter * this._width - width / 2 ;
let y = this._y + yCenter * this._height - height / 2;
return [x, y, width, height];
},
/**
* _computeWindowRelativeLayout:
* _computeWindowLayout:
* @metaWindow: A #MetaWindow
* @slot: A layout slot
*
* Given a window and slot to fit it in, compute its
* workspace-relative [x, y, scale] where scale applies
* screen-relative [x, y, scale] where scale applies
* to both X and Y directions.
*/
_computeWindowRelativeLayout: function(metaWindow, slot) {
let [xCenter, yCenter, fraction] = slot;
let [x, y, width, height] = this._getSlotRelativeGeometry(slot);
xCenter = xCenter * global.screen_width;
_computeWindowLayout: function(metaWindow, slot) {
let [x, y, width, height] = this._getSlotGeometry(slot);
let rect = metaWindow.get_outer_rect();
let buttonOuterHeight, captionHeight;
@ -804,23 +846,19 @@ Workspace.prototype = {
if (this._windowOverlays[0]) {
[buttonOuterHeight, captionHeight] = this._windowOverlays[0].chromeHeights();
buttonOuterWidth = this._windowOverlays[0].chromeWidth() / this.scale;
buttonOuterWidth = this._windowOverlays[0].chromeWidth();
} else
[buttonOuterHeight, captionHeight] = [0, 0];
buttonOuterHeight /= this.scale;
captionHeight /= this.scale;
let desiredWidth = global.screen_width * fraction;
let desiredHeight = global.screen_height * fraction;
let scale = Math.min((desiredWidth - buttonOuterWidth) / rect.width,
(desiredHeight - buttonOuterHeight - captionHeight) / rect.height,
1.0 / this.scale);
let scale = Math.min((width - buttonOuterWidth) / rect.width,
(height - buttonOuterHeight - captionHeight) / rect.height,
1.0);
x = Math.floor(xCenter - 0.5 * scale * rect.width);
x = Math.floor(x + (width - scale * rect.width) / 2);
// We want to center the window in case we have just one
if (metaWindow.get_workspace().n_windows == 1)
y = Math.floor(yCenter * global.screen_height - 0.5 * scale * rect.height);
y = Math.floor(y + (height - scale * rect.height) / 2);
else
y = Math.floor(y + height - rect.height * scale - captionHeight);
@ -846,7 +884,7 @@ Workspace.prototype = {
/**
* positionWindows:
* @flags:
* ZOOM - workspace is moving at the same time and we need to take that into account.
* INITIAL - this is the initial positioning of the windows.
* ANIMATE - Indicates that we need animate changing position.
*/
positionWindows : function(flags) {
@ -859,7 +897,7 @@ Workspace.prototype = {
if (this._reservedSlot)
clones.push(this._reservedSlot);
let workspaceZooming = flags & WindowPositionFlags.ZOOM;
let initialPositioning = flags & WindowPositionFlags.INITIAL;
let animate = flags & WindowPositionFlags.ANIMATE;
// Start the animations
@ -867,7 +905,7 @@ Workspace.prototype = {
clones = this._orderWindowsByMotionAndStartup(clones, slots);
let currentWorkspace = global.screen.get_active_workspace();
let isOnCurrentWorkspace = this.metaWorkspace == currentWorkspace;
let isOnCurrentWorkspace = this.metaWorkspace == null || this.metaWorkspace == currentWorkspace;
for (let i = 0; i < clones.length; i++) {
let slot = slots[i];
@ -881,7 +919,7 @@ Workspace.prototype = {
if (clone.inDrag)
continue;
let [x, y, scale] = this._computeWindowRelativeLayout(metaWindow, slot);
let [x, y, scale] = this._computeWindowLayout(metaWindow, slot);
if (overlay)
overlay.hide();
@ -890,7 +928,7 @@ Workspace.prototype = {
/* Hidden windows should fade in and grow
* therefore we need to resize them now so they
* can be scaled up later */
if (workspaceZooming) {
if (initialPositioning) {
clone.actor.opacity = 0;
clone.actor.scale_x = 0;
clone.actor.scale_y = 0;
@ -911,7 +949,6 @@ Workspace.prototype = {
y: y,
scale_x: scale,
scale_y: scale,
workspace_relative: workspaceZooming ? this : null,
time: Overview.ANIMATION_TIME,
transition: 'easeOutQuad',
onComplete: Lang.bind(this, function() {
@ -934,7 +971,7 @@ Workspace.prototype = {
let clone = clones[i];
let metaWindow = clone.metaWindow;
if (i == 0) {
clone.setStackAbove(null);
clone.setStackAbove(this._dropRect);
} else {
let previousClone = clones[i - 1];
clone.setStackAbove(previousClone.actor);
@ -954,10 +991,8 @@ Workspace.prototype = {
// be after the workspace animation finishes.
let [cloneX, cloneY] = clone.actor.get_position();
let [cloneWidth, cloneHeight] = clone.actor.get_size();
cloneX = this.x + this.scale * cloneX;
cloneY = this.y + this.scale * cloneY;
cloneWidth = this.scale * clone.actor.scale_x * cloneWidth;
cloneHeight = this.scale * clone.actor.scale_y * cloneHeight;
cloneWidth = clone.actor.scale_x * cloneWidth;
cloneHeight = clone.actor.scale_y * cloneHeight;
if (overlay) {
overlay.updatePositions(cloneX, cloneY, cloneWidth, cloneHeight);
@ -973,7 +1008,8 @@ Workspace.prototype = {
for (let i = 0; i < this._windows.length; i++) {
let clone = this._windows[i];
let overlay = this._windowOverlays[i];
this._showWindowOverlay(clone, overlay, this.metaWorkspace == currentWorkspace);
this._showWindowOverlay(clone, overlay,
this.metaWorkspace == null || this.metaWorkspace == currentWorkspace);
}
},
@ -982,12 +1018,10 @@ Workspace.prototype = {
return true;
let [x, y, mask] = global.get_pointer();
let wsWidth = this.actor.width * this.scale;
let wsHeight = this.actor.height * this.scale;
let pointerHasMoved = (this._cursorX != x && this._cursorY != y);
let inWorkspace = (this.x < x && x < this.x + wsWidth &&
this.y < y && y < this.y + wsHeight);
let inWorkspace = (this._x < x && x < this._x + this._width &&
this._y < y && y < this._y + this._height);
if (pointerHasMoved && inWorkspace) {
// store current cursor position
@ -1012,7 +1046,7 @@ Workspace.prototype = {
this._windowOverlaysGroup.hide();
},
_windowRemoved : function(metaWorkspace, metaWin) {
_doRemoveWindow : function(metaWin) {
let win = metaWin.get_compositor_private();
// find the position of the window in our list
@ -1021,6 +1055,10 @@ Workspace.prototype = {
if (index == -1)
return;
// Check if window still should be here
if (win && this._isMyWindow(win))
return;
let clone = this._windows[index];
this._windows.splice(index, 1);
@ -1064,7 +1102,7 @@ Workspace.prototype = {
Lang.bind(this, this._delayedWindowRepositioning));
},
_windowAdded : function(metaWorkspace, metaWin) {
_doAddWindow : function(metaWin) {
if (this.leavingOverview)
return;
@ -1076,30 +1114,62 @@ Workspace.prototype = {
Mainloop.idle_add(Lang.bind(this,
function () {
if (this.actor && metaWin.get_compositor_private())
this._windowAdded(metaWorkspace, metaWin);
this._doAddWindow(metaWin);
return false;
}));
return;
}
if (!this._isOverviewWindow(win))
// We might have the window in our list already if it was on all workspaces and
// now was moved to this workspace
if (this._lookupIndex (metaWin) != -1)
return;
if (!this._isMyWindow(win) || !this._isOverviewWindow(win))
return;
let clone = this._addWindowClone(win);
if (win._overviewHint) {
let x = (win._overviewHint.x - this.actor.x) / this.scale;
let y = (win._overviewHint.y - this.actor.y) / this.scale;
let scale = win._overviewHint.scale / this.scale;
let x = win._overviewHint.x - this.actor.x;
let y = win._overviewHint.y - this.actor.y;
let scale = win._overviewHint.scale;
delete win._overviewHint;
clone.actor.set_position (x, y);
clone.actor.set_scale (scale, scale);
} else {
// Position new windows at the top corner of the workspace rather
// than where they were placed for real to avoid the window
// being clipped to the workspaceView. Its not really more
// natural for the window to suddenly appear in the overview
// on some seemingly random location anyway.
clone.actor.set_position (this._x, this._y);
}
this.positionWindows(WindowPositionFlags.ANIMATE);
},
_windowAdded : function(metaWorkspace, metaWin) {
this._doAddWindow(metaWin);
},
_windowRemoved : function(metaWorkspace, metaWin) {
this._doRemoveWindow(metaWin);
},
_windowEnteredMonitor : function(metaScreen, monitorIndex, metaWin) {
if (monitorIndex == this.monitorIndex) {
this._doAddWindow(metaWin);
}
},
_windowLeftMonitor : function(metaScreen, monitorIndex, metaWin) {
if (monitorIndex == this.monitorIndex) {
this._doRemoveWindow(metaWin);
}
},
// check for maximized windows on the workspace
hasMaximizedWindows: function() {
for (let i = 0; i < this._windows.length; i++) {
@ -1114,14 +1184,11 @@ Workspace.prototype = {
// Animate the full-screen to Overview transition.
zoomToOverview : function() {
this.actor.set_position(this.x, this.y);
this.actor.set_scale(this.scale, this.scale);
// Position and scale the windows.
if (Main.overview.animationInProgress)
this.positionWindows(WindowPositionFlags.ANIMATE | WindowPositionFlags.ZOOM);
this.positionWindows(WindowPositionFlags.ANIMATE | WindowPositionFlags.INITIAL);
else
this.positionWindows(WindowPositionFlags.ZOOM);
this.positionWindows(WindowPositionFlags.INITIAL);
},
// Animates the return from Overview mode
@ -1139,7 +1206,7 @@ Workspace.prototype = {
this._overviewHiddenId = Main.overview.connect('hidden', Lang.bind(this,
this._doneLeavingOverview));
if (this._metaWorkspace == currentWorkspace)
if (this.metaWorkspace != null && this.metaWorkspace != currentWorkspace)
return;
// Position and scale the windows.
@ -1154,7 +1221,6 @@ Workspace.prototype = {
y: clone.origY,
scale_x: 1.0,
scale_y: 1.0,
workspace_relative: this,
time: Overview.ANIMATION_TIME,
opacity: 255,
transition: 'easeOutQuad'
@ -1165,7 +1231,6 @@ Workspace.prototype = {
{ scale_x: 0,
scale_y: 0,
opacity: 0,
workspace_relative: this,
time: Overview.ANIMATION_TIME,
transition: 'easeOutQuad'
});
@ -1185,8 +1250,12 @@ Workspace.prototype = {
}
Tweener.removeTweens(actor);
this.metaWorkspace.disconnect(this._windowAddedId);
this.metaWorkspace.disconnect(this._windowRemovedId);
if (this.metaWorkspace) {
this.metaWorkspace.disconnect(this._windowAddedId);
this.metaWorkspace.disconnect(this._windowRemovedId);
}
global.screen.disconnect(this._windowEnteredMonitorId);
global.screen.disconnect(this._windowLeftMonitorId);
if (this._repositionWindowsId > 0)
Mainloop.source_remove(this._repositionWindowsId);
@ -1205,9 +1274,10 @@ Workspace.prototype = {
this.leavingOverview = false;
},
// Tests if @win belongs to this workspaces
// Tests if @win belongs to this workspaces and monitor
_isMyWindow : function (win) {
return Main.isWindowActorDisplayedOnWorkspace(win, this.metaWorkspace.index());
return (this.metaWorkspace == null || Main.isWindowActorDisplayedOnWorkspace(win, this.metaWorkspace.index())) &&
(!win.get_meta_window() || win.get_meta_window().get_monitor() == this.monitorIndex);
},
// Tests if @win should be shown in the Overview
@ -1228,6 +1298,10 @@ Workspace.prototype = {
Main.overview.beginWindowDrag();
overlay.hide();
}));
clone.connect('drag-cancelled',
Lang.bind(this, function(clone) {
Main.overview.cancelledWindowDrag();
}));
clone.connect('drag-end',
Lang.bind(this, function(clone) {
Main.overview.endWindowDrag();
@ -1291,8 +1365,10 @@ Workspace.prototype = {
},
_onCloneSelected : function (clone, time) {
Main.activateWindow(clone.metaWindow, time,
this.metaWorkspace.index());
let wsIndex = undefined;
if (this.metaWorkspace)
wsIndex = this.metaWorkspace.index();
Main.activateWindow(clone.metaWindow, time, wsIndex);
},
// Draggable target interface
@ -1320,7 +1396,15 @@ Workspace.prototype = {
};
let metaWindow = win.get_meta_window();
metaWindow.change_workspace_by_index(this.metaWorkspace.index(),
// We need to move the window before changing the workspace, because
// the move itself could cause a workspace change if the window enters
// the primary monitor
if (metaWindow.get_monitor() != this.monitorIndex)
metaWindow.move_to_monitor(this.monitorIndex);
let index = this.metaWorkspace ? this.metaWorkspace.index() : global.screen.get_active_workspace_index();
metaWindow.change_workspace_by_index(index,
false, // don't create workspace
time);
return true;
@ -1335,56 +1419,3 @@ Workspace.prototype = {
};
Signals.addSignalMethods(Workspace.prototype);
// Create a SpecialPropertyModifier to let us move windows in a
// straight line on the screen even though their containing workspace
// is also moving.
Tweener.registerSpecialPropertyModifier('workspace_relative', _workspaceRelativeModifier, _workspaceRelativeGet);
function _workspaceRelativeModifier(workspace) {
let [startX, startY] = Main.overview.getPosition();
let overviewPosX, overviewPosY, overviewScale;
if (!workspace)
return [];
if (workspace.leavingOverview) {
let [zoomedInX, zoomedInY] = Main.overview.getZoomedInPosition();
overviewPosX = { begin: startX, end: zoomedInX };
overviewPosY = { begin: startY, end: zoomedInY };
overviewScale = { begin: Main.overview.getScale(),
end: Main.overview.getZoomedInScale() };
} else {
overviewPosX = { begin: startX, end: 0 };
overviewPosY = { begin: startY, end: 0 };
overviewScale = { begin: Main.overview.getScale(), end: 1 };
}
return [ { name: 'x',
parameters: { workspacePos: workspace.x,
overviewPos: overviewPosX,
overviewScale: overviewScale } },
{ name: 'y',
parameters: { workspacePos: workspace.y,
overviewPos: overviewPosY,
overviewScale: overviewScale } }
];
}
function _workspaceRelativeGet(begin, end, time, params) {
let curOverviewPos = (1 - time) * params.overviewPos.begin +
time * params.overviewPos.end;
let curOverviewScale = (1 - time) * params.overviewScale.begin +
time * params.overviewScale.end;
// Calculate the screen position of the window.
let screen = (1 - time) *
((begin + params.workspacePos) * params.overviewScale.begin +
params.overviewPos.begin) +
time *
((end + params.workspacePos) * params.overviewScale.end +
params.overviewPos.end);
// Return the workspace coordinates.
return (screen - curOverviewPos) / curOverviewScale - params.workspacePos;
}

View File

@ -146,6 +146,7 @@ function WorkspaceThumbnail(metaWorkspace) {
WorkspaceThumbnail.prototype = {
_init : function(metaWorkspace) {
this.metaWorkspace = metaWorkspace;
this.monitorIndex = global.get_primary_monitor_index();
this.actor = new St.Group({ reactive: true,
clip_to_allocation: true,
@ -169,7 +170,8 @@ WorkspaceThumbnail.prototype = {
this._background = new Clutter.Clone({ source: global.background_actor });
this._contents.add_actor(this._background);
this.setPorthole(0, 0, global.screen_width, global.screen_height);
let monitor = global.get_primary_monitor();
this.setPorthole(monitor.x, monitor.y, monitor.width, monitor.height);
let windows = global.get_window_actors().filter(this._isMyWindow, this);
@ -186,6 +188,10 @@ WorkspaceThumbnail.prototype = {
Lang.bind(this, this._windowAdded));
this._windowRemovedId = this.metaWorkspace.connect('window-removed',
Lang.bind(this, this._windowRemoved));
this._windowEnteredMonitorId = global.screen.connect('window-entered-monitor',
Lang.bind(this, this._windowEnteredMonitor));
this._windowLeftMonitorId = global.screen.connect('window-left-monitor',
Lang.bind(this, this._windowLeftMonitor));
this.state = ThumbnailState.NORMAL;
this._slidePosition = 0; // Fully slid in
@ -193,6 +199,8 @@ WorkspaceThumbnail.prototype = {
},
setPorthole: function(x, y, width, height) {
this._portholeX = x;
this._portholeY = y;
this.actor.set_size(width, height);
this._contents.set_position(-x, -y);
},
@ -239,7 +247,7 @@ WorkspaceThumbnail.prototype = {
return this._collapseFraction;
},
_windowRemoved : function(metaWorkspace, metaWin) {
_doRemoveWindow : function(metaWin) {
let win = metaWin.get_compositor_private();
// find the position of the window in our list
@ -248,12 +256,16 @@ WorkspaceThumbnail.prototype = {
if (index == -1)
return;
// Check if window still should be here
if (win && this._isMyWindow(win))
return;
let clone = this._windows[index];
this._windows.splice(index, 1);
clone.destroy();
},
_windowAdded : function(metaWorkspace, metaWin) {
_doAddWindow : function(metaWin) {
if (this.leavingOverview)
return;
@ -265,18 +277,43 @@ WorkspaceThumbnail.prototype = {
Mainloop.idle_add(Lang.bind(this,
function () {
if (this.actor && metaWin.get_compositor_private())
this._windowAdded(metaWorkspace, metaWin);
this._doAddWindow(metaWin);
return false;
}));
return;
}
if (!this._isOverviewWindow(win))
// We might have the window in our list already if it was on all workspaces and
// now was moved to this workspace
if (this._lookupIndex (metaWin) != -1)
return;
if (!this._isMyWindow(win) || !this._isOverviewWindow(win))
return;
let clone = this._addWindowClone(win);
},
_windowAdded : function(metaWorkspace, metaWin) {
this._doAddWindow(metaWin);
},
_windowRemoved : function(metaWorkspace, metaWin) {
this._doRemoveWindow(metaWin);
},
_windowEnteredMonitor : function(metaScreen, monitorIndex, metaWin) {
if (monitorIndex == this.monitorIndex) {
this._doAddWindow(metaWin);
}
},
_windowLeftMonitor : function(metaScreen, monitorIndex, metaWin) {
if (monitorIndex == this.monitorIndex) {
this._doRemoveWindow(metaWin);
}
},
destroy : function() {
this.actor.destroy();
},
@ -284,15 +321,17 @@ WorkspaceThumbnail.prototype = {
_onDestroy: function(actor) {
this.metaWorkspace.disconnect(this._windowAddedId);
this.metaWorkspace.disconnect(this._windowRemovedId);
global.screen.disconnect(this._windowEnteredMonitorId);
global.screen.disconnect(this._windowLeftMonitorId);
this._windows = [];
this.actor = null;
},
// Tests if @win belongs to this workspaces
// Tests if @win belongs to this workspace and monitor
_isMyWindow : function (win) {
return win.get_workspace() == this.metaWorkspace.index() ||
(win.get_meta_window() && win.get_meta_window().is_on_all_workspaces());
return Main.isWindowActorDisplayedOnWorkspace(win, this.metaWorkspace.index()) &&
(!win.get_meta_window() || win.get_meta_window().get_monitor() == this.monitorIndex);
},
// Tests if @win should be shown in the Overview
@ -340,6 +379,11 @@ WorkspaceThumbnail.prototype = {
// Draggable target interface
handleDragOver : function(source, actor, x, y, time) {
if (source == Main.xdndHandler) {
this.metaWorkspace.activate(time);
return DND.DragMotionResult.CONTINUE;
}
if (this.state > ThumbnailState.NORMAL)
return DND.DragMotionResult.CONTINUE;
@ -361,6 +405,13 @@ WorkspaceThumbnail.prototype = {
return false;
let metaWindow = win.get_meta_window();
// We need to move the window before changing the workspace, because
// the move itself could cause a workspace change if the window enters
// the primary monitor
if (metaWindow.get_monitor() != this.monitorIndex)
metaWindow.move_to_monitor(this.monitorIndex);
metaWindow.change_workspace_by_index(this.metaWorkspace.index(),
false, // don't create workspace
time);
@ -442,11 +493,12 @@ ThumbnailsBox.prototype = {
// The "porthole" is the portion of the screen that we show in the workspaces
let panelHeight = Main.panel.actor.height;
let monitor = global.get_primary_monitor();
this._porthole = {
x: 0,
y: panelHeight,
width: global.screen_width,
height: global.screen_height - panelHeight
x: monitor.x,
y: monitor.y + panelHeight,
width: monitor.width,
height: monitor.height - panelHeight
};
this.addThumbnails(0, global.screen.n_workspaces);

View File

@ -25,14 +25,13 @@ const MAX_WORKSPACES = 16;
const CONTROLS_POP_IN_TIME = 0.1;
function WorkspacesView(width, height, x, y, workspaces) {
this._init(width, height, x, y, workspaces);
function WorkspacesView(workspaces) {
this._init(workspaces);
}
WorkspacesView.prototype = {
_init: function(width, height, x, y, workspaces) {
_init: function(workspaces) {
this.actor = new St.Group({ style_class: 'workspaces-view' });
this.actor.set_clip(x, y, width, height);
// The actor itself isn't a drop target, so we don't want to pick on its area
this.actor.set_size(0, 0);
@ -43,19 +42,17 @@ WorkspacesView.prototype = {
function() {
let node = this.actor.get_theme_node();
this._spacing = node.get_length('spacing');
this._computeWorkspacePositions();
this._updateWorkspaceActors(false);
}));
this.actor.connect('notify::mapped',
Lang.bind(this, this._onMappedChanged));
this._width = width;
this._height = height;
this._x = x;
this._y = y;
this._zoomScale = 1.0;
this._width = 0;
this._height = 0;
this._x = 0;
this._y = 0;
this._workspaceRatioSpacing = 0;
this._spacing = 0;
this._activeWorkspaceX = 0; // x offset of active ws while dragging
this._activeWorkspaceY = 0; // y offset of active ws while dragging
this._lostWorkspaces = [];
this._animating = false; // tweening
this._scrolling = false; // swipe-scrolling
@ -71,6 +68,18 @@ WorkspacesView.prototype = {
this._workspaces[w].actor.reparent(this.actor);
this._workspaces[activeWorkspaceIndex].actor.raise_top();
this._extraWorkspaces = [];
let monitors = global.get_monitors();
let m = 0;
for (let i = 0; i < monitors.length; i++) {
if (i == global.get_primary_monitor_index())
continue;
let ws = new Workspace.Workspace(null, i);
this._extraWorkspaces[m++] = ws;
ws.setGeometry(monitors[i].x, monitors[i].y, monitors[i].width, monitors[i].height);
global.overlay_group.add_actor(ws.actor);
}
// Position/scale the desktop windows and their children after the
// workspaces have been created. This cannot be done first because
// window movement depends on the Workspaces object being accessible
@ -80,6 +89,13 @@ WorkspacesView.prototype = {
Lang.bind(this, function() {
for (let w = 0; w < this._workspaces.length; w++)
this._workspaces[w].zoomToOverview();
for (let w = 0; w < this._extraWorkspaces.length; w++)
this._extraWorkspaces[w].zoomToOverview();
}));
this._overviewShownId =
Main.overview.connect('shown',
Lang.bind(this, function() {
this.actor.set_clip(this._x, this._y, this._width, this._height);
}));
this._scrollAdjustment = new St.Adjustment({ value: activeWorkspaceIndex,
@ -109,30 +125,18 @@ WorkspacesView.prototype = {
this._swipeScrollEndId = 0;
},
setZoomScale: function(zoomScale) {
if (zoomScale == this._zoomScale)
return;
setGeometry: function(x, y, width, height, spacing) {
if (this._x == x && this._y == y &&
this._width == width && this._height == height)
return;
this._width = width;
this._height = height;
this._x = x;
this._y = y;
this._workspaceRatioSpacing = spacing;
this._zoomScale = zoomScale;
if (this._zoomOut) {
// If we are already zoomed out, then we have to reposition.
// Note that when shown initially zoomOut is false, so we
// won't trigger this.
// setZoomScale can be invoked when the workspaces view is
// reallocated. Since we just want to animate things to the
// new position it seems OK to call updateWorkspaceActors
// immediately - adding a tween doesn't immediately cause
// a new allocation. But hide/show of the window overlays we
// do around animation does, so we need to do it later.
// This can be removed when we fix things to not hide/show
// the window overlay.
Meta.later_add(Meta.LaterType.BEFORE_REDRAW,
Lang.bind(this, function() {
this._computeWorkspacePositions();
this._updateWorkspaceActors(true);
}));
}
for (let i = 0; i < this._workspaces.length; i++)
this._workspaces[i].setGeometry(x, y, width, height);
},
_lookupWorkspaceForMetaWindow: function (metaWindow) {
@ -154,101 +158,41 @@ WorkspacesView.prototype = {
activeWorkspace.actor.raise_top();
this.actor.remove_clip(this._x, this._y, this._width, this._height);
for (let w = 0; w < this._workspaces.length; w++)
this._workspaces[w].zoomFromOverview();
for (let w = 0; w < this._extraWorkspaces.length; w++)
this._extraWorkspaces[w].zoomFromOverview();
},
destroy: function() {
this.actor.destroy();
},
getScale: function() {
return this._workspaces[0].scale;
},
syncStacking: function(stackIndices) {
for (let i = 0; i < this._workspaces.length; i++)
this._workspaces[i].syncStacking(stackIndices);
for (let i = 0; i < this._extraWorkspaces.length; i++)
this._extraWorkspaces[i].syncStacking(stackIndices);
},
// Get the grid position of the active workspace.
getActiveWorkspacePosition: function() {
let activeWorkspaceIndex = global.screen.get_active_workspace_index();
let activeWorkspace = this._workspaces[activeWorkspaceIndex];
return [activeWorkspace.x, activeWorkspace.y];
},
zoomOut: function() {
if (this._zoomOut)
return;
this._zoomOut = true;
this._computeWorkspacePositions();
this._updateWorkspaceActors(true);
},
zoomIn: function() {
if (!this._zoomOut)
return;
this._zoomOut = false;
this._computeWorkspacePositions();
this._updateWorkspaceActors(true);
},
// Compute the position, scale and opacity of the workspaces, but don't
// actually change the actors to match
_computeWorkspacePositions: function() {
let active = global.screen.get_active_workspace_index();
let zoomScale = this._zoomOut ? this._zoomScale : 1;
let scale = zoomScale * this._width / global.screen_width;
let _width = this._workspaces[0].actor.width * scale;
let _height = this._workspaces[0].actor.height * scale;
this._activeWorkspaceX = (this._width - _width) / 2;
this._activeWorkspaceY = (this._height - _height) / 2;
for (let w = 0; w < this._workspaces.length; w++) {
let workspace = this._workspaces[w];
workspace.opacity = (this._inDrag && w != active) ? 200 : 255;
workspace.scale = scale;
workspace.x = this._x + this._activeWorkspaceX;
// We adjust the center because the zoomScale is to leave space for
// the expanded workspace control so we want to zoom to either the
// left part of the area or the right part of the area
let offset = 0.5 * (1 - this._zoomScale) * this._width;
let rtl = (St.Widget.get_default_direction () == St.TextDirection.RTL);
if (this._zoomOut)
workspace.x += rtl ? offset : - offset;
// We divide by zoomScale so that adjacent workspaces are always offscreen
// except when we are switching between workspaces
workspace.y = this._y + this._activeWorkspaceY
+ (w - active) * (_height + this._spacing) / zoomScale;
}
updateWindowPositions: function() {
for (let w = 0; w < this._workspaces.length; w++)
this._workspaces[w].positionWindows(Workspace.WindowPositionFlags.ANIMATE);
},
_scrollToActive: function(showAnimation) {
let active = global.screen.get_active_workspace_index();
this._computeWorkspacePositions();
this._updateWorkspaceActors(showAnimation);
this._updateScrollAdjustment(active, showAnimation);
},
// Update workspace actors parameters to the values calculated in
// _computeWorkspacePositions()
// Update workspace actors parameters
// @showAnimation: iff %true, transition between states
_updateWorkspaceActors: function(showAnimation) {
let active = global.screen.get_active_workspace_index();
let targetWorkspaceNewY = this._y + this._activeWorkspaceY;
let targetWorkspaceCurrentY = this._workspaces[active].y;
let dy = targetWorkspaceNewY - targetWorkspaceCurrentY;
this._animating = showAnimation;
@ -257,14 +201,12 @@ WorkspacesView.prototype = {
Tweener.removeTweens(workspace.actor);
workspace.y += dy;
let opacity = (this._inDrag && w != active) ? 200 : 255;
let y = (w - active) * (this._height + this._spacing + this._workspaceRatioSpacing);
if (showAnimation) {
let params = { x: workspace.x,
y: workspace.y,
scale_x: workspace.scale,
scale_y: workspace.scale,
opacity: workspace.opacity,
let params = { y: y,
opacity: opacity,
time: WORKSPACE_SWITCH_TIME,
transition: 'easeOutQuad'
};
@ -281,9 +223,8 @@ WorkspacesView.prototype = {
}
Tweener.addTween(workspace.actor, params);
} else {
workspace.actor.set_scale(workspace.scale, workspace.scale);
workspace.actor.set_position(workspace.x, workspace.y);
workspace.actor.opacity = workspace.opacity;
workspace.actor.set_position(0, y);
workspace.actor.opacity = opacity;
if (w == 0)
this._updateVisibility();
}
@ -294,7 +235,6 @@ WorkspacesView.prototype = {
Tweener.removeTweens(workspace.actor);
workspace.y += dy;
workspace.actor.show();
workspace.hideWindowsOverlays();
@ -338,7 +278,6 @@ WorkspacesView.prototype = {
this._lostWorkspaces[l].destroy();
this._lostWorkspaces = [];
this._computeWorkspacePositions();
this._updateWorkspaceActors(false);
},
@ -380,7 +319,6 @@ WorkspacesView.prototype = {
for (let w = oldNumWorkspaces; w < newNumWorkspaces; w++)
this.actor.add_actor(this._workspaces[w].actor);
this._computeWorkspacePositions();
this._updateWorkspaceActors(false);
} else {
this._lostWorkspaces = lostWorkspaces;
@ -397,10 +335,16 @@ WorkspacesView.prototype = {
},
_onDestroy: function() {
for (let i = 0; i < this._extraWorkspaces.length; i++)
this._extraWorkspaces[i].destroy();
this._scrollAdjustment.run_dispose();
Main.overview.disconnect(this._overviewShowingId);
Main.overview.disconnect(this._overviewShownId);
global.window_manager.disconnect(this._switchWorkspaceNotifyId);
if (this._inDrag)
this._dragEnd();
if (this._timeoutId) {
Mainloop.source_remove(this._timeoutId);
this._timeoutId = 0;
@ -443,6 +387,7 @@ WorkspacesView.prototype = {
return;
this._inDrag = true;
this._firstDragMotion = true;
this._dragMonitor = {
dragMotion: Lang.bind(this, this._onDragMotion)
@ -454,6 +399,14 @@ WorkspacesView.prototype = {
if (Main.overview.animationInProgress)
return DND.DragMotionResult.CONTINUE;
if (this._firstDragMotion) {
this._firstDragMotion = false;
for (let i = 0; i < this._workspaces.length; i++)
this._workspaces[i].setReservedSlot(dragEvent.dragActor._delegate);
for (let i = 0; i < this._extraWorkspaces.length; i++)
this._extraWorkspaces[i].setReservedSlot(dragEvent.dragActor._delegate);
}
let primary = global.get_primary_monitor();
let activeWorkspaceIndex = global.screen.get_active_workspace_index();
@ -467,7 +420,6 @@ WorkspacesView.prototype = {
let switchTop = (dragEvent.y <= topEdge && topWorkspace);
if (switchTop && this._dragOverLastY != topEdge) {
topWorkspace.metaWorkspace.activate(global.get_current_time());
topWorkspace.setReservedSlot(dragEvent.dragActor._delegate);
this._dragOverLastY = topEdge;
return DND.DragMotionResult.CONTINUE;
@ -476,7 +428,6 @@ WorkspacesView.prototype = {
let switchBottom = (dragEvent.y >= bottomEdge && bottomWorkspace);
if (switchBottom && this._dragOverLastY != bottomEdge) {
bottomWorkspace.metaWorkspace.activate(global.get_current_time());
bottomWorkspace.setReservedSlot(dragEvent.dragActor._delegate);
this._dragOverLastY = bottomEdge;
return DND.DragMotionResult.CONTINUE;
@ -511,7 +462,6 @@ WorkspacesView.prototype = {
this._timeoutId = Mainloop.timeout_add_seconds(1,
Lang.bind(this, function() {
hoverWorkspace.metaWorkspace.activate(global.get_current_time());
hoverWorkspace.setReservedSlot(dragEvent.dragActor._delegate);
return false;
}));
} else {
@ -534,6 +484,8 @@ WorkspacesView.prototype = {
for (let i = 0; i < this._workspaces.length; i++)
this._workspaces[i].setReservedSlot(null);
for (let i = 0; i < this._extraWorkspaces.length; i++)
this._extraWorkspaces[i].setReservedSlot(null);
},
_swipeScrollBegin: function() {
@ -557,12 +509,6 @@ WorkspacesView.prototype = {
Main.overview.hide();
}
if (result == Overview.SwipeScrollResult.SWIPE)
// The active workspace has changed; while swipe-scrolling
// has already taken care of the positioning, the cached
// positions need to be updated
this._computeWorkspacePositions();
// Make sure title captions etc are shown as necessary
this._updateVisibility();
},
@ -590,7 +536,7 @@ WorkspacesView.prototype = {
return;
let currentY = firstWorkspaceY;
let newY = this._y - adj.value / (adj.upper - 1) * workspacesHeight;
let newY = - adj.value / (adj.upper - 1) * workspacesHeight;
let dy = newY - currentY;
@ -618,6 +564,7 @@ WorkspacesDisplay.prototype = {
this.actor.connect('get-preferred-width', Lang.bind(this, this._getPreferredWidth));
this.actor.connect('get-preferred-height', Lang.bind(this, this._getPreferredHeight));
this.actor.connect('allocate', Lang.bind(this, this._allocate));
this.actor.set_clip_to_allocation(true);
let controls = new St.Bin({ style_class: 'workspace-controls',
request_mode: Clutter.RequestMode.WIDTH_FOR_HEIGHT,
@ -633,6 +580,8 @@ WorkspacesDisplay.prototype = {
controls.connect('scroll-event',
Lang.bind(this, this._onScrollEvent));
this._monitorIndex = global.get_primary_monitor_index();
this._monitor = global.get_monitors()[this._monitorIndex];
this._thumbnailsBox = new WorkspaceThumbnail.ThumbnailsBox();
controls.add_actor(this._thumbnailsBox.actor);
@ -640,65 +589,53 @@ WorkspacesDisplay.prototype = {
this.workspacesView = null;
this._inDrag = false;
this._cancelledDrag = false;
this._alwaysZoomOut = false;
this._zoomOut = false;
this._zoomFraction = 0;
this._updateAlwaysZoom();
global.screen.connect('monitors-changed', Lang.bind(this, this._updateAlwaysZoom));
Main.xdndHandler.connect('drag-begin', Lang.bind(this, function(){
this._alwaysZoomOut = true;
}));
Main.xdndHandler.connect('drag-end', Lang.bind(this, function(){
this._alwaysZoomOut = false;
this._updateAlwaysZoom();
}));
this._nWorkspacesNotifyId = 0;
this._switchWorkspaceNotifyId = 0;
this._itemDragBeginId = 0;
this._itemDragCancelledId = 0;
this._itemDragEndId = 0;
this._windowDragBeginId = 0;
this._windowDragCancelledId = 0;
this._windowDragEndId = 0;
},
show: function() {
this._zoomOut = this._alwaysZoomOut;
this._zoomFraction = this._alwaysZoomOut ? 1 : 0;
this._updateZoom();
this._controls.show();
this._thumbnailsBox.show();
this._workspaces = [];
for (let i = 0; i < global.screen.n_workspaces; i++) {
let metaWorkspace = global.screen.get_workspace_by_index(i);
this._workspaces[i] = new Workspace.Workspace(metaWorkspace);
this._workspaces[i] = new Workspace.Workspace(metaWorkspace, this._monitorIndex);
}
let rtl = (St.Widget.get_default_direction () == St.TextDirection.RTL);
let totalAllocation = this.actor.allocation;
let totalWidth = totalAllocation.x2 - totalAllocation.x1;
let totalHeight = totalAllocation.y2 - totalAllocation.y1;
let controlsVisible = this._controls.get_theme_node().get_length('visible-width');
totalWidth -= controlsVisible;
// Workspaces expect to have the same ratio as the screen, so take
// this into account when fitting the workspace into the available space
let width, height;
let totalRatio = totalWidth / totalHeight;
let wsRatio = global.screen_width / global.screen_height;
if (wsRatio > totalRatio) {
width = totalWidth;
height = Math.floor(totalWidth / wsRatio);
} else {
width = Math.floor(totalHeight * wsRatio);
height = totalHeight;
}
// Position workspaces in the available space
let [x, y] = this.actor.get_transformed_position();
x = Math.floor(x + Math.abs(totalWidth - width) / 2);
y = Math.floor(y + Math.abs(totalHeight - height) / 2);
if (rtl)
x += controlsVisible;
let newView = new WorkspacesView(width, height, x, y, this._workspaces);
this._updateZoomScale();
if (this.workspacesView)
this.workspacesView.destroy();
this.workspacesView = newView;
this.workspacesView = new WorkspacesView(this._workspaces);
this._updateWorkspacesGeometry();
this._nWorkspacesNotifyId =
global.screen.connect('notify::n-workspaces',
@ -711,20 +648,23 @@ WorkspacesDisplay.prototype = {
if (this._itemDragBeginId == 0)
this._itemDragBeginId = Main.overview.connect('item-drag-begin',
Lang.bind(this, this._dragBegin));
if (this._itemDragCancelledId == 0)
this._itemDragCancelledId = Main.overview.connect('item-drag-cancelled',
Lang.bind(this, this._dragCancelled));
if (this._itemDragEndId == 0)
this._itemDragEndId = Main.overview.connect('item-drag-end',
Lang.bind(this, this._dragEnd));
if (this._windowDragBeginId == 0)
this._windowDragBeginId = Main.overview.connect('window-drag-begin',
Lang.bind(this, this._dragBegin));
if (this._windowDragCancelledId == 0)
this._windowDragCancelledId = Main.overview.connect('window-drag-cancelled',
Lang.bind(this, this._dragCancelled));
if (this._windowDragEndId == 0)
this._windowDragEndId = Main.overview.connect('window-drag-end',
Lang.bind(this, this._dragEnd));
this._onRestacked();
this._zoomOut = false;
this._zoomFraction = 0;
this._updateZoom();
},
hide: function() {
@ -743,7 +683,11 @@ WorkspacesDisplay.prototype = {
Main.overview.disconnect(this._itemDragBeginId);
this._itemDragBeginId = 0;
}
if (this._itemEndBeginId > 0) {
if (this._itemDragCancelledId > 0) {
Main.overview.disconnect(this._itemDragCancelledId);
this._itemDragCancelledId = 0;
}
if (this._itemDragEndId > 0) {
Main.overview.disconnect(this._itemDragEndId);
this._itemDragEndId = 0;
}
@ -751,6 +695,10 @@ WorkspacesDisplay.prototype = {
Main.overview.disconnect(this._windowDragBeginId);
this._windowDragBeginId = 0;
}
if (this._windowDragCancelledId > 0) {
Main.overview.disconnect(this._windowDragCancelledId);
this._windowDragCancelledId = 0;
}
if (this._windowDragEndId > 0) {
Main.overview.disconnect(this._windowDragEndId);
this._windowDragEndId = 0;
@ -774,6 +722,23 @@ WorkspacesDisplay.prototype = {
return this._zoomFraction;
},
_updateAlwaysZoom: function() {
this._alwaysZoomOut = false;
let monitors = global.get_monitors();
let primary = global.get_primary_monitor();
/* Look for any monitor to the right of the primary, if there is
* one, we always keep zoom out, otherwise its hard to reach
* the thumbnail area without passing into the next monitor. */
for (let i = 0; i < monitors.length; i++) {
if (monitors[i].x >= primary.x + primary.width) {
this._alwaysZoomOut = true;
break;
}
}
},
_getPreferredWidth: function (actor, forHeight, alloc) {
// pass through the call in case the child needs it, but report 0x0
this._controls.get_preferred_width(forHeight);
@ -809,22 +774,41 @@ WorkspacesDisplay.prototype = {
childBox.y2 = box.y2- box.y1;
this._controls.allocate(childBox, flags);
this._updateZoomScale();
this._updateWorkspacesGeometry();
},
_updateZoomScale: function() {
_updateWorkspacesGeometry: function() {
if (!this.workspacesView)
return;
let totalAllocation = this.actor.allocation;
let totalWidth = totalAllocation.x2 - totalAllocation.x1;
let totalHeight = totalAllocation.y2 - totalAllocation.y1;
let fullWidth = this.actor.allocation.x2 - this.actor.allocation.x1;
let fullHeight = this.actor.allocation.y2 - this.actor.allocation.y1;
let [controlsMin, controlsNatural] = this._controls.get_preferred_width(totalHeight);
let width = fullWidth;
let height = fullHeight;
let [controlsMin, controlsNatural] = this._controls.get_preferred_width(height);
let controlsVisible = this._controls.get_theme_node().get_length('visible-width');
let zoomScale = (totalWidth - controlsNatural) / (totalWidth - controlsVisible);
this.workspacesView.setZoomScale(zoomScale);
let [x, y] = this.actor.get_transformed_position();
let rtl = (St.Widget.get_default_direction () == St.TextDirection.RTL);
if (this._zoomOut) {
width -= controlsNatural;
if (rtl)
x += controlsNatural;
} else {
width -= controlsVisible;
if (rtl)
x += controlsVisible;
}
height = (fullHeight / fullWidth) * width;
let difference = fullHeight - height;
y += difference / 2;
this.workspacesView.setGeometry(x, y, width, height, difference);
},
_onRestacked: function() {
@ -853,7 +837,7 @@ WorkspacesDisplay.prototype = {
// Assume workspaces are only added at the end
for (let w = oldNumWorkspaces; w < newNumWorkspaces; w++) {
let metaWorkspace = global.screen.get_workspace_by_index(w);
this._workspaces[w] = new Workspace.Workspace(metaWorkspace);
this._workspaces[w] = new Workspace.Workspace(metaWorkspace, this._monitorIndex);
}
this._thumbnailsBox.addThumbnails(oldNumWorkspaces, newNumWorkspaces - oldNumWorkspaces);
@ -890,9 +874,10 @@ WorkspacesDisplay.prototype = {
if (Main.overview.animationInProgress)
return;
let shouldZoom = this._controls.hover || this._inDrag;
let shouldZoom = this._alwaysZoomOut || this._controls.hover || (this._inDrag && !this._cancelledDrag);
if (shouldZoom != this._zoomOut) {
this._zoomOut = shouldZoom;
this._updateWorkspacesGeometry();
if (!this.workspacesView)
return;
@ -902,10 +887,7 @@ WorkspacesDisplay.prototype = {
time: WORKSPACE_SWITCH_TIME,
transition: 'easeOutQuad' });
if (shouldZoom)
this.workspacesView.zoomOut();
else
this.workspacesView.zoomIn();
this.workspacesView.updateWindowPositions();
}
},
@ -915,6 +897,12 @@ WorkspacesDisplay.prototype = {
_dragBegin: function() {
this._inDrag = true;
this._cancelledDrag = false;
this._updateZoom();
},
_dragCancelled: function() {
this._cancelledDrag = true;
this._updateZoom();
},

View File

@ -1,5 +1,8 @@
af
ar
bg
bn
bn_IN
ca
cs
da
@ -8,6 +11,7 @@ el
en_GB
es
et
eu
fa
fi
fr
@ -15,6 +19,7 @@ ga
gl
gu
he
hi
hu
id
it
@ -22,6 +27,8 @@ ja
ko
kn
lt
lv
mr
nb
nl
nn

View File

@ -13,6 +13,7 @@ js/ui/messageTray.js
js/ui/overview.js
js/ui/panel.js
js/ui/placeDisplay.js
js/ui/polkitAuthenticationAgent.js
js/ui/popupMenu.js
js/ui/runDialog.js
js/ui/searchDisplay.js
@ -20,6 +21,7 @@ js/ui/statusMenu.js
js/ui/status/accessibility.js
js/ui/status/bluetooth.js
js/ui/status/keyboard.js
js/ui/status/network.js
js/ui/status/power.js
js/ui/status/volume.js
js/ui/telepathyClient.js
@ -29,8 +31,10 @@ js/ui/workspacesView.js
src/gvc/gvc-mixer-control.c
src/gdmuser/gdm-user.c
src/main.c
src/shell-app.c
src/shell-app-system.c
src/shell-global.c
src/shell-mobile-providers.c
src/shell-polkit-authentication-agent.c
src/shell-util.c

1102
po/af.po Normal file

File diff suppressed because it is too large Load Diff

522
po/ar.po

File diff suppressed because it is too large Load Diff

471
po/bg.po
View File

@ -7,8 +7,8 @@ msgid ""
msgstr ""
"Project-Id-Version: gnome-shell master\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2011-03-05 23:07+0200\n"
"PO-Revision-Date: 2011-03-05 23:07+0200\n"
"POT-Creation-Date: 2011-03-27 08:03+0300\n"
"PO-Revision-Date: 2011-03-27 08:03+0300\n"
"Last-Translator: Ivaylo Valkov <ivaylo@e-valkov.org>\n"
"Language-Team: Bulgarian <dict@fsa-bg.org>\n"
"Language: bg\n"
@ -174,47 +174,43 @@ msgstr "Дали да се събира статистика за използв
msgid "disabled OpenSearch providers"
msgstr "изключени доставчици на OpenSearch"
#: ../js/misc/util.js:86
#: ../js/misc/util.js:71
msgid "Command not found"
msgstr "Командата не беше открита"
#. Replace "Error invoking GLib.shell_parse_argv: " with
#. something nicer
#: ../js/misc/util.js:113
#: ../js/misc/util.js:98
msgid "Could not parse command:"
msgstr "Неуспех при анализиране на командата:"
#: ../js/misc/util.js:135
msgid "No such application"
msgstr "Няма такава програма"
#: ../js/misc/util.js:148
#: ../js/misc/util.js:106
#, c-format
msgid "Execution of '%s' failed:"
msgstr "Неуспешно изпълнение на „%s“:"
#. Translators: Filter to display all applications
#: ../js/ui/appDisplay.js:195
#: ../js/ui/appDisplay.js:230
msgid "All"
msgstr "Всички"
#: ../js/ui/appDisplay.js:285
#: ../js/ui/appDisplay.js:328
msgid "APPLICATIONS"
msgstr "ПРОГРАМИ"
#: ../js/ui/appDisplay.js:311
#: ../js/ui/appDisplay.js:354
msgid "SETTINGS"
msgstr "НАСТРОЙКИ"
#: ../js/ui/appDisplay.js:565
#: ../js/ui/appDisplay.js:625
msgid "New Window"
msgstr "Нов прозорец"
#: ../js/ui/appDisplay.js:568
#: ../js/ui/appDisplay.js:628
msgid "Remove from Favorites"
msgstr "Премахване от „Любими“"
#: ../js/ui/appDisplay.js:569
#: ../js/ui/appDisplay.js:629
msgid "Add to Favorites"
msgstr "Добавяне в „Любими“"
@ -244,7 +240,6 @@ msgstr "%H:%M"
#. Transators: Shown in calendar event list, if 12h format
#: ../js/ui/calendar.js:78
#, fuzzy
msgctxt "event list time"
msgid "%l:%M %p"
msgstr "%l:%M %p"
@ -349,14 +344,12 @@ msgstr "Няма нищо запланувано"
#. Translators: Shown on calendar heading when selected day occurs on current year
#: ../js/ui/calendar.js:720
#, fuzzy
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:723
#, fuzzy
msgctxt "calendar heading"
msgid "%A, %B %d, %Y"
msgstr "%A, %B, %d, %Y"
@ -377,7 +370,7 @@ msgstr "Тази седмица"
msgid "Next week"
msgstr "Следващата седмица"
#: ../js/ui/dash.js:174
#: ../js/ui/dash.js:174 ../js/ui/messageTray.js:1000
msgid "Remove"
msgstr "Премахване"
@ -385,55 +378,54 @@ msgstr "Премахване"
msgid "Date and Time Settings"
msgstr "Настройки на датата и времето"
#: ../js/ui/dateMenu.js:110
#: ../js/ui/dateMenu.js:111
msgid "Open Calendar"
msgstr "Отваряне на календара"
#. Translators: This is the time format with date used
#. in 24-hour mode.
#: ../js/ui/dateMenu.js:162
#: ../js/ui/dateMenu.js:164
msgid "%a %b %e, %R:%S"
msgstr "%a, %e %b, %R:%S"
#: ../js/ui/dateMenu.js:163
#: ../js/ui/dateMenu.js:165
msgid "%a %b %e, %R"
msgstr "%a, %e %b, %R"
#. Translators: This is the time format without date used
#. in 24-hour mode.
#: ../js/ui/dateMenu.js:167
#: ../js/ui/dateMenu.js:169
msgid "%a %R:%S"
msgstr "%a, %R:%S"
#: ../js/ui/dateMenu.js:168
#: ../js/ui/dateMenu.js:170
msgid "%a %R"
msgstr "%a, %R"
#. Translators: This is a time format with date used
#. for AM/PM.
#: ../js/ui/dateMenu.js:175
#: ../js/ui/dateMenu.js:177
msgid "%a %b %e, %l:%M:%S %p"
msgstr "%a, %e %b, %l:%M:%S %p"
#: ../js/ui/dateMenu.js:176
#: ../js/ui/dateMenu.js:178
msgid "%a %b %e, %l:%M %p"
msgstr "%a, %e %b, %l:%M %p"
#. Translators: This is a time format without date used
#. for AM/PM.
#: ../js/ui/dateMenu.js:180
#: ../js/ui/dateMenu.js:182
msgid "%a %l:%M:%S %p"
msgstr "%a %l:%M:%S %p"
#: ../js/ui/dateMenu.js:181
#: ../js/ui/dateMenu.js:183
msgid "%a %l:%M %p"
msgstr "%a, %H:%M"
#. 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:207
#, fuzzy
#: ../js/ui/dateMenu.js:194
msgid "%A %B %e, %Y"
msgstr "%A %B %e, %Y"
@ -446,7 +438,7 @@ msgstr "СКОРО ОТВАРЯНИ"
msgid "Log Out %s"
msgstr "Изход на „%s“"
#: ../js/ui/endSessionDialog.js:64 ../js/ui/endSessionDialog.js:69
#: ../js/ui/endSessionDialog.js:64 ../js/ui/endSessionDialog.js:70
msgid "Log Out"
msgstr "Изход"
@ -469,49 +461,47 @@ msgstr "Ще излезете от системата автоматично с
msgid "Logging out of the system."
msgstr "Излизане от системата."
#: ../js/ui/endSessionDialog.js:74 ../js/ui/endSessionDialog.js:78
msgid "Shut Down"
msgstr "Изключване на компютъра"
#: ../js/ui/endSessionDialog.js:75
msgid "Click Shut Down to quit these applications and shut down the system."
msgstr ""
"Натиснете „Изключване на системата“, за да спрете тези програми и да "
"изключите системата."
#: ../js/ui/endSessionDialog.js:75 ../js/ui/endSessionDialog.js:82
msgid "Power Off"
msgstr "Изключване"
#: ../js/ui/endSessionDialog.js:76
#, c-format
msgid "The system will shut down automatically in %d seconds."
msgstr "Системата ще се изключи автоматично след %d секунди."
msgid "Click Power Off to quit these applications and power off the system."
msgstr ""
"Натиснете „Изключване“, за да спрете тези програми и да излезете от "
"системата."
#: ../js/ui/endSessionDialog.js:77
msgid "Shutting down the system."
#, c-format
msgid "The system will power off automatically in %d seconds."
msgstr "Системата ще се изключи автоматично след %d секунди."
#: ../js/ui/endSessionDialog.js:78
msgid "Powering off the system."
msgstr "Изключване на системата."
#: ../js/ui/endSessionDialog.js:84 ../js/ui/endSessionDialog.js:88
#: ../js/ui/endSessionDialog.js:80 ../js/ui/endSessionDialog.js:88
#: ../js/ui/endSessionDialog.js:93
msgid "Restart"
msgstr "Рестартиране"
#: ../js/ui/endSessionDialog.js:85
#: ../js/ui/endSessionDialog.js:89
msgid "Click Restart to quit these applications and restart the system."
msgstr ""
"Натиснете „Рестартиране“, за да спрете тези програми и да рестартирате "
"системата."
#: ../js/ui/endSessionDialog.js:86
#: ../js/ui/endSessionDialog.js:90
#, c-format
msgid "The system will restart automatically in %d seconds."
msgstr "Системата ще се рестартира автоматично след %d секунди."
#: ../js/ui/endSessionDialog.js:87
#: ../js/ui/endSessionDialog.js:91
msgid "Restarting the system."
msgstr "Рестартиране на системата."
#: ../js/ui/endSessionDialog.js:395
msgid "Confirm"
msgstr "Потвърждаване"
#: ../js/ui/endSessionDialog.js:400 ../js/ui/status/bluetooth.js:470
#: ../js/ui/endSessionDialog.js:415 ../js/ui/polkitAuthenticationAgent.js:172
#: ../js/ui/status/bluetooth.js:466
msgid "Cancel"
msgstr "Отказване"
@ -525,7 +515,7 @@ msgstr "Включено"
#. translators:
#. * The device has been disabled
#: ../js/ui/lookingGlass.js:627 ../src/gvc/gvc-mixer-control.c:1087
#: ../js/ui/lookingGlass.js:627 ../src/gvc/gvc-mixer-control.c:1091
msgid "Disabled"
msgstr "Изключено"
@ -545,34 +535,48 @@ msgstr "Преглед на изходния код"
msgid "Web Page"
msgstr "Домашна страница"
#: ../js/ui/messageTray.js:1907
#: ../js/ui/messageTray.js:993
msgid "Open"
msgstr "Отваряне"
#: ../js/ui/messageTray.js:2151
msgid "System Information"
msgstr "Информация за системата"
#: ../js/ui/overview.js:88
#: ../js/ui/overview.js:91
msgid "Undo"
msgstr "Отмяна"
#: ../js/ui/overview.js:183
#: ../js/ui/overview.js:186
msgid "Windows"
msgstr "Прозорци"
#: ../js/ui/overview.js:186
#: ../js/ui/overview.js:189
msgid "Applications"
msgstr "Програми"
#. Translators: this is the name of the dock/favorites area on
#. the left of the overview
#: ../js/ui/overview.js:205
msgid "Dash"
msgstr "Най-ползвани"
#. TODO - _quit() doesn't really work on apps in state STARTING yet
#: ../js/ui/panel.js:531
#: ../js/ui/panel.js:515
#, c-format
msgid "Quit %s"
msgstr "Спиране на програмата „%s“"
#. Button on the left side of the panel.
#. Translators: If there is no suitable word for "Activities" in your language, you can use the word for "Overview".
#: ../js/ui/panel.js:892
#: ../js/ui/panel.js:878
msgid "Activities"
msgstr "Дейности"
#: ../js/ui/panel.js:979
msgid "Top Bar"
msgstr "Горна лента"
#: ../js/ui/placeDisplay.js:122
#, c-format
msgid "Failed to unmount '%s'"
@ -586,65 +590,85 @@ msgstr "Повторен опит"
msgid "Connect to..."
msgstr "Свързване към…"
#: ../js/ui/placeDisplay.js:409
#: ../js/ui/placeDisplay.js:380
msgid "PLACES & DEVICES"
msgstr "МЕСТА И УСТРОЙСТВА"
#: ../js/ui/polkitAuthenticationAgent.js:74
msgid "Authentication Required"
msgstr "Необходимо е удостоверяване"
#: ../js/ui/polkitAuthenticationAgent.js:108
msgid "Administrator"
msgstr "Администратор"
#: ../js/ui/polkitAuthenticationAgent.js:176
msgid "Authenticate"
msgstr "Удостоверяване"
#: ../js/ui/polkitAuthenticationAgent.js:260
msgid "Sorry, that didn't work. Please try again."
msgstr "Действието не беше успешно. Опитайте отново."
#: ../js/ui/polkitAuthenticationAgent.js:272
msgid "Password:"
msgstr "Парола:"
#. Translators: this MUST be either "toggle-switch-us"
#. (for toggle switches containing the English words
#. "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:612
#: ../js/ui/popupMenu.js:679
msgid "toggle-switch-us"
msgstr "toggle-switch-intl"
#: ../js/ui/runDialog.js:201
#: ../js/ui/runDialog.js:205
msgid "Please enter a command:"
msgstr "Въведете команда:"
#: ../js/ui/searchDisplay.js:283
#: ../js/ui/searchDisplay.js:310
msgid "Searching..."
msgstr "Търсене…"
#: ../js/ui/searchDisplay.js:297
#: ../js/ui/searchDisplay.js:324
msgid "No matching results."
msgstr "Няма съвпадения."
#: ../js/ui/statusMenu.js:102 ../js/ui/statusMenu.js:166
#: ../js/ui/statusMenu.js:161 ../js/ui/statusMenu.js:163
#: ../js/ui/statusMenu.js:228
msgid "Power Off..."
msgstr "Изключване..."
#: ../js/ui/statusMenu.js:104 ../js/ui/statusMenu.js:165
#: ../js/ui/statusMenu.js:163 ../js/ui/statusMenu.js:227
msgid "Suspend"
msgstr "Приспиване"
#: ../js/ui/statusMenu.js:125
#: ../js/ui/statusMenu.js:184
msgid "Available"
msgstr "На линия"
#: ../js/ui/statusMenu.js:130
#, fuzzy
#: ../js/ui/statusMenu.js:189
msgid "Busy"
msgstr "Правя нещо друго"
#: ../js/ui/statusMenu.js:138
#: ../js/ui/statusMenu.js:197
msgid "My Account"
msgstr "Моята регистрация"
#: ../js/ui/statusMenu.js:142
#: ../js/ui/statusMenu.js:201
msgid "System Settings"
msgstr "Настройки на системата"
#: ../js/ui/statusMenu.js:149
#: ../js/ui/statusMenu.js:208
msgid "Lock Screen"
msgstr "Заключване на екрана"
#: ../js/ui/statusMenu.js:153
#: ../js/ui/statusMenu.js:213
msgid "Switch User"
msgstr "Смяна на потребител"
#: ../js/ui/statusMenu.js:158
#: ../js/ui/statusMenu.js:218
msgid "Log Out..."
msgstr "Изход…"
@ -652,14 +676,12 @@ msgstr "Изход…"
msgid "Zoom"
msgstr "Увеличаване"
#: ../js/ui/status/accessibility.js:69
msgid "Screen Reader"
msgstr "Четец на екрана"
#: ../js/ui/status/accessibility.js:73
msgid "Screen Keyboard"
msgstr "Екранна клавиатура"
#. let screenReader = this._buildItem(_("Screen Reader"), APPLICATIONS_SCHEMA,
#. 'screen-reader-enabled');
#. this.menu.addMenuItem(screenReader);
#. let screenKeyboard = this._buildItem(_("Screen Keyboard"), APPLICATIONS_SCHEMA,
#. 'screen-keyboard-enabled');
#. this.menu.addMenuItem(screenKeyboard);
#: ../js/ui/status/accessibility.js:77
msgid "Visual Alerts"
msgstr "Визуална помощ"
@ -684,17 +706,17 @@ msgstr "Клавиши за мишка"
msgid "Universal Access Settings"
msgstr "Настройки на универсалния достъп"
#: ../js/ui/status/accessibility.js:145
#: ../js/ui/status/accessibility.js:146
msgid "High Contrast"
msgstr "Висок контраст"
#: ../js/ui/status/accessibility.js:182
#: ../js/ui/status/accessibility.js:183
msgid "Large Text"
msgstr "Едър текст"
#: ../js/ui/status/bluetooth.js:42 ../js/ui/status/bluetooth.js:241
#: ../js/ui/status/bluetooth.js:337 ../js/ui/status/bluetooth.js:371
#: ../js/ui/status/bluetooth.js:411 ../js/ui/status/bluetooth.js:444
#: ../js/ui/status/bluetooth.js:42 ../js/ui/status/bluetooth.js:237
#: ../js/ui/status/bluetooth.js:333 ../js/ui/status/bluetooth.js:367
#: ../js/ui/status/bluetooth.js:407 ../js/ui/status/bluetooth.js:440
msgid "Bluetooth"
msgstr "Bluetooth"
@ -714,94 +736,94 @@ msgstr "Добавяне на ново устройство..."
msgid "Bluetooth Settings"
msgstr "Настройки на Bluetooth"
#: ../js/ui/status/bluetooth.js:192
#: ../js/ui/status/bluetooth.js:188
msgid "Connection"
msgstr "Свързване"
#: ../js/ui/status/bluetooth.js:228
#: ../js/ui/status/bluetooth.js:224
msgid "Send Files..."
msgstr "Изпращане на файлове..."
#: ../js/ui/status/bluetooth.js:233
#: ../js/ui/status/bluetooth.js:229
msgid "Browse Files..."
msgstr "Разглеждане на файлове..."
#: ../js/ui/status/bluetooth.js:242
#: ../js/ui/status/bluetooth.js:238
msgid "Error browsing device"
msgstr "Грешка при разглеждане на устройството"
#: ../js/ui/status/bluetooth.js:243
#: ../js/ui/status/bluetooth.js:239
#, c-format
msgid "The requested device cannot be browsed, error is '%s'"
msgstr "Заявеното устройство не може да бъде разгледано. Грешката е „%s“"
#: ../js/ui/status/bluetooth.js:251
#: ../js/ui/status/bluetooth.js:247
msgid "Keyboard Settings"
msgstr "Настройка на клавиатурата"
#: ../js/ui/status/bluetooth.js:256
#: ../js/ui/status/bluetooth.js:252
msgid "Mouse Settings"
msgstr "Настройки на мишката"
#: ../js/ui/status/bluetooth.js:263 ../js/ui/status/volume.js:65
#: ../js/ui/status/bluetooth.js:259 ../js/ui/status/volume.js:66
msgid "Sound Settings"
msgstr "Настройки на звука"
#: ../js/ui/status/bluetooth.js:372
#: ../js/ui/status/bluetooth.js:368
#, c-format
msgid "Authorization request from %s"
msgstr "Заявка за упълномощаване от „%s“"
#: ../js/ui/status/bluetooth.js:378
#: ../js/ui/status/bluetooth.js:374
#, c-format
msgid "Device %s wants access to the service '%s'"
msgstr "Устройството %s иска достъп до услугата „%s“"
#: ../js/ui/status/bluetooth.js:380
#: ../js/ui/status/bluetooth.js:376
msgid "Always grant access"
msgstr "Винаги позволяване на достъп"
#: ../js/ui/status/bluetooth.js:381
#: ../js/ui/status/bluetooth.js:377
msgid "Grant this time only"
msgstr "Позволяване само този път"
#: ../js/ui/status/bluetooth.js:382
#: ../js/ui/status/bluetooth.js:378
msgid "Reject"
msgstr "Отхвърляне"
#: ../js/ui/status/bluetooth.js:412
#: ../js/ui/status/bluetooth.js:408
#, c-format
msgid "Pairing confirmation for %s"
msgstr "Потвърждение за сдвояване с „%s“"
#: ../js/ui/status/bluetooth.js:418 ../js/ui/status/bluetooth.js:452
#: ../js/ui/status/bluetooth.js:414 ../js/ui/status/bluetooth.js:448
#, c-format
msgid "Device %s wants to pair with this computer"
msgstr "Устройството %s иска да се сдвои с този компютър"
#: ../js/ui/status/bluetooth.js:419
#: ../js/ui/status/bluetooth.js:415
#, c-format
msgid "Please confirm whether the PIN '%s' matches the one on the device."
msgstr "Потвърдете дали кодът „%s“ съвпада с този на устройството."
#: ../js/ui/status/bluetooth.js:421
#: ../js/ui/status/bluetooth.js:417
msgid "Matches"
msgstr "Съвпадения"
#: ../js/ui/status/bluetooth.js:422
#: ../js/ui/status/bluetooth.js:418
msgid "Does not match"
msgstr "Няма съвпадения"
#: ../js/ui/status/bluetooth.js:445
#: ../js/ui/status/bluetooth.js:441
#, c-format
msgid "Pairing request for %s"
msgstr "Запитване за свързване с „%s“"
#: ../js/ui/status/bluetooth.js:453
#: ../js/ui/status/bluetooth.js:449
msgid "Please enter the PIN mentioned on the device."
msgstr "Въведете кода на устройството %s."
#: ../js/ui/status/bluetooth.js:469
#: ../js/ui/status/bluetooth.js:465
msgid "OK"
msgstr "Добре"
@ -813,17 +835,153 @@ msgstr "Показване клавиатурната подредба…"
msgid "Localization Settings"
msgstr "Настройка на локализацията"
#: ../js/ui/status/network.js:104 ../js/ui/status/network.js:1454
msgid "<unknown>"
msgstr "<неизвестно>"
#. Translators: this indicates that wireless or wwan is disabled by hardware killswitch
#: ../js/ui/status/network.js:311
msgid "disabled"
msgstr "изключено"
#: ../js/ui/status/network.js:494
msgid "connecting..."
msgstr "свързване…"
#. Translators: this is for network connections that require some kind of key or password
#: ../js/ui/status/network.js:497
msgid "authentication required"
msgstr "изисква се удостоверяване"
#. Translators: this is for devices that require some kind of firmware or kernel
#. module, which is missing
#: ../js/ui/status/network.js:507
msgid "firmware missing"
msgstr "липсва фърмуер"
#. Translators: this is for wired network devices that are physically disconnected
#: ../js/ui/status/network.js:514
msgid "cable unplugged"
msgstr "кабелът е изваден"
#. Translators: this is for a network device that cannot be activated (for example it
#. is disabled by rfkill, or it has no coverage
#: ../js/ui/status/network.js:519
msgid "unavailable"
msgstr "недостъпно"
#: ../js/ui/status/network.js:521
msgid "connection failed"
msgstr "връзката е неуспешна"
#. TRANSLATORS: this is the indication that a connection for another logged in user is active,
#. and we cannot access its settings (including the name)
#: ../js/ui/status/network.js:602 ../js/ui/status/network.js:1402
msgid "Connected (private)"
msgstr "Връзката е осъществена (няма налични данни)"
#: ../js/ui/status/network.js:683
msgid "Auto Ethernet"
msgstr "Автоматична мрежа по Ethernet"
#: ../js/ui/status/network.js:758
msgid "Auto broadband"
msgstr "Автоматична широколентова мрежа"
#: ../js/ui/status/network.js:761
msgid "Auto dial-up"
msgstr "Автоматична мрежа през модем"
#. TRANSLATORS: this the automatic wireless connection name (including the network name)
#: ../js/ui/status/network.js:904 ../js/ui/status/network.js:1414
#, c-format
msgid "Auto %s"
msgstr "Автоматична мрежа към „%s“"
#: ../js/ui/status/network.js:906
msgid "Auto bluetooth"
msgstr "Автоматична мрежа по Bluetooth"
#: ../js/ui/status/network.js:1416
msgid "Auto wireless"
msgstr "Автоматична безжична мрежа"
#: ../js/ui/status/network.js:1474
msgid "More..."
msgstr "Повече…"
#: ../js/ui/status/network.js:1497
msgid "Enable networking"
msgstr "Включване на мрежата"
#: ../js/ui/status/network.js:1509
msgid "Wired"
msgstr "Жична"
#: ../js/ui/status/network.js:1520
msgid "Wireless"
msgstr "Безжична"
#: ../js/ui/status/network.js:1530
msgid "Mobile broadband"
msgstr "Мобилна широколентова"
#: ../js/ui/status/network.js:1540
msgid "VPN Connections"
msgstr "Връзки към ВЧМ"
#: ../js/ui/status/network.js:1549
msgid "Network Settings"
msgstr "Настройки на мрежата"
#: ../js/ui/status/network.js:1844
#, c-format
msgid "You're now connected to mobile broadband connection '%s'"
msgstr "Връзката в момента е към мобилната широколентова мрежа „%s“"
#: ../js/ui/status/network.js:1848
#, c-format
msgid "You're now connected to wireless network '%s'"
msgstr "Връзката в момента е към безжичната мрежа „%s“"
#: ../js/ui/status/network.js:1852
#, c-format
msgid "You're now connected to wired network '%s'"
msgstr "Връзката в момента е към жичната мрежа „%s“"
#: ../js/ui/status/network.js:1856
#, c-format
msgid "You're now connected to VPN network '%s'"
msgstr "Връзката в момента е към ВЧМ „%s“"
#: ../js/ui/status/network.js:1861
#, c-format
msgid "You're now connected to '%s'"
msgstr "Връзката в момента е към „%s“"
#: ../js/ui/status/network.js:1869
msgid "Connection established"
msgstr "Връзката е осъществена"
#: ../js/ui/status/network.js:1991
msgid "Networking is disabled"
msgstr "Мрежата е изключена"
#: ../js/ui/status/network.js:2116
msgid "Network Manager"
msgstr "Управление на мрежата"
#: ../js/ui/status/power.js:85
msgid "Power Settings"
msgstr "Настройка на захранването"
#. 0 is reported when UPower does not have enough data
#. to estimate battery life
#: ../js/ui/status/power.js:110
#: ../js/ui/status/power.js:111
msgid "Estimating..."
msgstr "Приблизително времето…"
#: ../js/ui/status/power.js:117
#: ../js/ui/status/power.js:118
#, c-format
msgid "%d hour remaining"
msgid_plural "%d hours remaining"
@ -831,110 +989,110 @@ msgstr[0] "Остава %d час"
msgstr[1] "Остават %d часа"
#. TRANSLATORS: this is a time string, as in "%d hours %d minutes remaining"
#: ../js/ui/status/power.js:120
#: ../js/ui/status/power.js:121
#, c-format
msgid "%d %s %d %s remaining"
msgstr "Остават %d %s и %d %s"
#: ../js/ui/status/power.js:122
#: ../js/ui/status/power.js:123
msgid "hour"
msgid_plural "hours"
msgstr[0] "час"
msgstr[1] "часа"
#: ../js/ui/status/power.js:122
#: ../js/ui/status/power.js:123
msgid "minute"
msgid_plural "minutes"
msgstr[0] "минута"
msgstr[1] "минути"
#: ../js/ui/status/power.js:125
#: ../js/ui/status/power.js:126
#, c-format
msgid "%d minute remaining"
msgid_plural "%d minutes remaining"
msgstr[0] "остават %d минути"
msgstr[1] "остават %d минути"
#: ../js/ui/status/power.js:227
#: ../js/ui/status/power.js:228
msgid "AC adapter"
msgstr "Адаптер за ел. мрежа"
#: ../js/ui/status/power.js:229
#: ../js/ui/status/power.js:230
msgid "Laptop battery"
msgstr "Батерия на преносим компютър"
#: ../js/ui/status/power.js:231
#: ../js/ui/status/power.js:232
msgid "UPS"
msgstr "Непрекъсваемо токозахранване"
#: ../js/ui/status/power.js:233
#: ../js/ui/status/power.js:234
msgid "Monitor"
msgstr "Монитор"
#: ../js/ui/status/power.js:235
#: ../js/ui/status/power.js:236
msgid "Mouse"
msgstr "Мишка"
#: ../js/ui/status/power.js:237
#: ../js/ui/status/power.js:238
msgid "Keyboard"
msgstr "Клавиатура"
#: ../js/ui/status/power.js:239
#: ../js/ui/status/power.js:240
msgid "PDA"
msgstr "Цифров помощник"
#: ../js/ui/status/power.js:241
#: ../js/ui/status/power.js:242
msgid "Cell phone"
msgstr "Мобилен телефон"
#: ../js/ui/status/power.js:243
#: ../js/ui/status/power.js:244
msgid "Media player"
msgstr "Музикално устройство"
#: ../js/ui/status/power.js:245
#: ../js/ui/status/power.js:246
msgid "Tablet"
msgstr "Таблет"
#: ../js/ui/status/power.js:247
#: ../js/ui/status/power.js:248
msgid "Computer"
msgstr "Компютър"
#: ../js/ui/status/power.js:249 ../src/shell-app-system.c:1013
#: ../js/ui/status/power.js:250 ../src/shell-app-system.c:1088
msgid "Unknown"
msgstr "Неизвестно"
#: ../js/ui/status/volume.js:44
#: ../js/ui/status/volume.js:45
msgid "Volume"
msgstr "Сила на звука"
#: ../js/ui/status/volume.js:57
#: ../js/ui/status/volume.js:58
msgid "Microphone"
msgstr "Микрофон"
#: ../js/ui/telepathyClient.js:239
#: ../js/ui/telepathyClient.js:331
#, c-format
msgid "%s is online."
msgstr "%s е на линия."
#: ../js/ui/telepathyClient.js:244
#: ../js/ui/telepathyClient.js:336
#, c-format
msgid "%s is offline."
msgstr "%s не е на линия."
#: ../js/ui/telepathyClient.js:247
#: ../js/ui/telepathyClient.js:339
#, c-format
msgid "%s is away."
msgstr "%s отсъства."
#: ../js/ui/telepathyClient.js:250
#, fuzzy, c-format
#: ../js/ui/telepathyClient.js:342
#, c-format
msgid "%s is busy."
msgstr "%s прави нещо друго."
#. Translators: this is a time format string followed by a date.
#. If applicable, replace %X with a strftime format valid for your
#. locale, without seconds.
#: ../js/ui/telepathyClient.js:348
#: ../js/ui/telepathyClient.js:473
#, no-c-format
msgid "Sent at %X on %A"
msgstr "Изпратено на %2$A в %1$X"
@ -943,10 +1101,14 @@ msgstr "Изпратено на %2$A в %1$X"
#. in the search entry when no search is
#. active; it should not exceed ~30
#. characters.
#: ../js/ui/viewSelector.js:103
#: ../js/ui/viewSelector.js:122
msgid "Type to search..."
msgstr "Търсене на написаното…"
#: ../js/ui/viewSelector.js:142 ../src/shell-util.c:250
msgid "Search"
msgstr "Търсене"
#: ../js/ui/windowAttentionHandler.js:42
#, c-format
msgid "%s has finished starting"
@ -959,7 +1121,7 @@ msgstr "Програмата „%s“ е готова за употреба"
#. translators:
#. * The number of sound outputs on a particular device
#: ../src/gvc/gvc-mixer-control.c:1094
#: ../src/gvc/gvc-mixer-control.c:1098
#, c-format
msgid "%u Output"
msgid_plural "%u Outputs"
@ -968,49 +1130,66 @@ msgstr[1] "%u изхода"
#. translators:
#. * The number of sound inputs on a particular device
#: ../src/gvc/gvc-mixer-control.c:1104
#: ../src/gvc/gvc-mixer-control.c:1108
#, c-format
msgid "%u Input"
msgid_plural "%u Inputs"
msgstr[0] "%u вход"
msgstr[1] "%u входа"
#: ../src/gvc/gvc-mixer-control.c:1402
#: ../src/gvc/gvc-mixer-control.c:1406
msgid "System Sounds"
msgstr "Системни звуци"
#: ../src/shell-global.c:1298
#: ../src/main.c:446
msgid "Print version"
msgstr "Показване на версията"
#: ../src/shell-app.c:454
#, c-format
msgid "Failed to launch '%s'"
msgstr "Неуспех при стартиране на „%s“"
#: ../src/shell-global.c:1395
msgid "Less than a minute ago"
msgstr "Преди по-малко от минута"
#: ../src/shell-global.c:1302
#: ../src/shell-global.c:1399
#, c-format
msgid "%d minute ago"
msgid_plural "%d minutes ago"
msgstr[0] "преди %d минута"
msgstr[1] "преди %d минути"
#: ../src/shell-global.c:1307
#: ../src/shell-global.c:1404
#, c-format
msgid "%d hour ago"
msgid_plural "%d hours ago"
msgstr[0] "преди %d час"
msgstr[1] "преди %d часа"
#: ../src/shell-global.c:1312
#: ../src/shell-global.c:1409
#, c-format
msgid "%d day ago"
msgid_plural "%d days ago"
msgstr[0] "преди %d ден"
msgstr[1] "преди %d дни"
#: ../src/shell-global.c:1317
#: ../src/shell-global.c:1414
#, c-format
msgid "%d week ago"
msgid_plural "%d weeks ago"
msgstr[0] "преди %d седмица"
msgstr[1] "преди %d седмици"
#: ../src/shell-mobile-providers.c:80
msgid "United Kingdom"
msgstr "Великобритания"
#: ../src/shell-mobile-providers.c:526
msgid "Default"
msgstr "Стандартно"
#: ../src/shell-polkit-authentication-agent.c:334
msgid "Authentication dialog was dismissed by the user"
msgstr "Прозорецът за упълномощаване беше затворен от потребителя"
@ -1025,10 +1204,6 @@ msgstr "Домашна папка"
msgid "File System"
msgstr "Файлова система"
#: ../src/shell-util.c:250
msgid "Search"
msgstr "Търсене"
#. Translators: the first string is the name of a gvfs
#. * method, and the second string is a path. For
#. * example, "Trash: some-directory". It means that the

1202
po/bn.po Normal file

File diff suppressed because it is too large Load Diff

1189
po/bn_IN.po Normal file

File diff suppressed because it is too large Load Diff

501
po/ca.po
View File

@ -8,8 +8,8 @@ msgid ""
msgstr ""
"Project-Id-Version: HEAD\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2011-03-06 18:36+0100\n"
"PO-Revision-Date: 2011-03-06 18:36+0100\n"
"POT-Creation-Date: 2011-03-29 00:29+0200\n"
"PO-Revision-Date: 2011-04-03 23:19+0200\n"
"Last-Translator: Gil Forcada <gilforcada@guifi.net>\n"
"Language-Team: Catalan <tradgnome@softcatala.org>\n"
"Language: ca\n"
@ -62,7 +62,7 @@ msgstr "Historial de les ordres utilitzades en el diàleg de l'Alt+F2"
#: ../data/org.gnome.shell.gschema.xml.in.h:7
msgid "History for the looking glass dialog"
msgstr "Historial del diàleg de l'Alt+F2"
msgstr "Historial del depurador del GNOME Shell"
#: ../data/org.gnome.shell.gschema.xml.in.h:8
msgid "If true, display date in the clock, in addition to time."
@ -71,7 +71,7 @@ msgstr ""
#: ../data/org.gnome.shell.gschema.xml.in.h:9
msgid "If true, display seconds in time."
msgstr "Si és «true» (cert) es mostren el segons."
msgstr "Si és «true» (cert) es mostren els segons."
#: ../data/org.gnome.shell.gschema.xml.in.h:10
msgid "If true, display the ISO week date in the calendar."
@ -106,7 +106,7 @@ msgstr ""
"s'estableix a un valor nul, s'utilitzarà el conducte predeterminat que ara "
"mateix és «videorate ! vp8enc quality=10 speed=2 threads=%T ! queue ! "
"webmmux» que enregistra amb el format WEBM amb el còdec VP8. El %T és una "
"variable per a estimar el nombre de fils d'execució paral·lels òptims del "
"variable per estimar el nombre de fils d'execució paral·lels òptims del "
"sistema."
#: ../data/org.gnome.shell.gschema.xml.in.h:14
@ -161,7 +161,7 @@ msgstr ""
"El GNOME Shell normalment fa un seguiment de les aplicacions actives per tal "
"de mostrar les més utilitzades (per exemple en els llançadors). Tot i que "
"les dades es mantindran en privat, podeu inhabilitar-ho per motius de "
"privacitat. Tingueu en compte que si ho inhabiliteu no es suprimiran les "
"privadesa. Tingueu en compte que si ho inhabiliteu no es suprimiran les "
"dades ja recollides."
#: ../data/org.gnome.shell.gschema.xml.in.h:22
@ -176,47 +176,43 @@ msgstr "Si s'han de recollir estadístiques d'ús de les aplicacions"
msgid "disabled OpenSearch providers"
msgstr "inhabilita els proveïdors d'OpenSearch"
#: ../js/misc/util.js:86
#: ../js/misc/util.js:71
msgid "Command not found"
msgstr "No s'ha trobat l'ordre"
#. Replace "Error invoking GLib.shell_parse_argv: " with
#. something nicer
#: ../js/misc/util.js:113
#: ../js/misc/util.js:98
msgid "Could not parse command:"
msgstr "No s'ha pogut analitzar l'ordre:"
#: ../js/misc/util.js:135
msgid "No such application"
msgstr "No hi ha cap aplicació"
#: ../js/misc/util.js:148
#: ../js/misc/util.js:106
#, c-format
msgid "Execution of '%s' failed:"
msgstr "No s'ha pogut executar «%s»:"
#. Translators: Filter to display all applications
#: ../js/ui/appDisplay.js:195
#: ../js/ui/appDisplay.js:230
msgid "All"
msgstr "Totes"
#: ../js/ui/appDisplay.js:285
#: ../js/ui/appDisplay.js:328
msgid "APPLICATIONS"
msgstr "APLICACIONS"
#: ../js/ui/appDisplay.js:311
#: ../js/ui/appDisplay.js:354
msgid "SETTINGS"
msgstr "CONFIGURACIÓ"
#: ../js/ui/appDisplay.js:565
#: ../js/ui/appDisplay.js:625
msgid "New Window"
msgstr "Finestra nova"
#: ../js/ui/appDisplay.js:568
#: ../js/ui/appDisplay.js:628
msgid "Remove from Favorites"
msgstr "Suprimeix dels preferits"
#: ../js/ui/appDisplay.js:569
#: ../js/ui/appDisplay.js:629
msgid "Add to Favorites"
msgstr "Afegeix als preferits"
@ -376,7 +372,7 @@ msgstr "Aquesta setmana"
msgid "Next week"
msgstr "La setmana que ve"
#: ../js/ui/dash.js:174
#: ../js/ui/dash.js:174 ../js/ui/messageTray.js:1000
msgid "Remove"
msgstr "Suprimeix"
@ -384,54 +380,54 @@ msgstr "Suprimeix"
msgid "Date and Time Settings"
msgstr "Configuració de la data i l'hora"
#: ../js/ui/dateMenu.js:110
#: ../js/ui/dateMenu.js:111
msgid "Open Calendar"
msgstr "Obre el calendari"
#. Translators: This is the time format with date used
#. in 24-hour mode.
#: ../js/ui/dateMenu.js:162
#: ../js/ui/dateMenu.js:164
msgid "%a %b %e, %R:%S"
msgstr "%a %d de %b, %R:%S"
#: ../js/ui/dateMenu.js:163
#: ../js/ui/dateMenu.js:165
msgid "%a %b %e, %R"
msgstr "%a %d de %b, %R"
#. Translators: This is the time format without date used
#. in 24-hour mode.
#: ../js/ui/dateMenu.js:167
#: ../js/ui/dateMenu.js:169
msgid "%a %R:%S"
msgstr "%a %R:%S"
#: ../js/ui/dateMenu.js:168
#: ../js/ui/dateMenu.js:170
msgid "%a %R"
msgstr "%a %R"
#. Translators: This is a time format with date used
#. for AM/PM.
#: ../js/ui/dateMenu.js:175
#: ../js/ui/dateMenu.js:177
msgid "%a %b %e, %l:%M:%S %p"
msgstr "%a %d de %b, %l:%M:%S %p"
#: ../js/ui/dateMenu.js:176
#: ../js/ui/dateMenu.js:178
msgid "%a %b %e, %l:%M %p"
msgstr "%a %d de %b, %l:%M %p"
#. Translators: This is a time format without date used
#. for AM/PM.
#: ../js/ui/dateMenu.js:180
#: ../js/ui/dateMenu.js:182
msgid "%a %l:%M:%S %p"
msgstr "%a %l:%M:%S %p"
#: ../js/ui/dateMenu.js:181
#: ../js/ui/dateMenu.js:183
msgid "%a %l:%M %p"
msgstr "%a %l:%M %p"
#. 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:207
#: ../js/ui/dateMenu.js:194
msgid "%A %B %e, %Y"
msgstr "%A %d de %B, %Y"
@ -444,7 +440,7 @@ msgstr "DOCUMENTS RECENTS"
msgid "Log Out %s"
msgstr "Surt %s"
#: ../js/ui/endSessionDialog.js:64 ../js/ui/endSessionDialog.js:69
#: ../js/ui/endSessionDialog.js:64 ../js/ui/endSessionDialog.js:70
msgid "Log Out"
msgstr "Surt"
@ -466,46 +462,44 @@ msgstr "Sortireu automàticament d'aquí %d segons."
msgid "Logging out of the system."
msgstr "S'està sortint de la sessió."
#: ../js/ui/endSessionDialog.js:74 ../js/ui/endSessionDialog.js:78
msgid "Shut Down"
msgstr "Atura"
#: ../js/ui/endSessionDialog.js:75
msgid "Click Shut Down to quit these applications and shut down the system."
msgstr "Feu clic a «Atura» per tancar les aplicacions i apagar l'ordinador."
#: ../js/ui/endSessionDialog.js:75 ../js/ui/endSessionDialog.js:82
msgid "Power Off"
msgstr "Apaga"
#: ../js/ui/endSessionDialog.js:76
#, c-format
msgid "The system will shut down automatically in %d seconds."
msgstr "S'apagarà l'ordinador automàticament d'aquí %d segons."
msgid "Click Power Off to quit these applications and power off the system."
msgstr "Feu clic a «Apaga» per tancar les aplicacions i apagar l'ordinador."
#: ../js/ui/endSessionDialog.js:77
msgid "Shutting down the system."
#, c-format
msgid "The system will power off automatically in %d seconds."
msgstr "S'apagarà l'ordinador automàticament d'aquí %d segons."
#: ../js/ui/endSessionDialog.js:78
msgid "Powering off the system."
msgstr "S'està apagant l'ordinador."
#: ../js/ui/endSessionDialog.js:84 ../js/ui/endSessionDialog.js:88
#: ../js/ui/endSessionDialog.js:80 ../js/ui/endSessionDialog.js:88
#: ../js/ui/endSessionDialog.js:93
msgid "Restart"
msgstr "Reinicia"
#: ../js/ui/endSessionDialog.js:85
#: ../js/ui/endSessionDialog.js:89
msgid "Click Restart to quit these applications and restart the system."
msgstr ""
"Feu clic a «Reinicia» per tancar les aplicacions i reiniciar l'ordinador."
#: ../js/ui/endSessionDialog.js:86
#: ../js/ui/endSessionDialog.js:90
#, c-format
msgid "The system will restart automatically in %d seconds."
msgstr "Es reiniciarà l'ordinador automàticament d'aquí %d segons."
#: ../js/ui/endSessionDialog.js:87
#: ../js/ui/endSessionDialog.js:91
msgid "Restarting the system."
msgstr "S'està reiniciant l'ordinador."
#: ../js/ui/endSessionDialog.js:395
msgid "Confirm"
msgstr "D'acord"
#: ../js/ui/endSessionDialog.js:400 ../js/ui/status/bluetooth.js:470
#: ../js/ui/endSessionDialog.js:415 ../js/ui/polkitAuthenticationAgent.js:172
#: ../js/ui/status/bluetooth.js:466
msgid "Cancel"
msgstr "Cancel·la"
@ -519,7 +513,7 @@ msgstr "Habilitat"
#. translators:
#. * The device has been disabled
#: ../js/ui/lookingGlass.js:627 ../src/gvc/gvc-mixer-control.c:1087
#: ../js/ui/lookingGlass.js:627 ../src/gvc/gvc-mixer-control.c:1091
msgid "Disabled"
msgstr "Inhabilitat"
@ -539,34 +533,48 @@ msgstr "Visualitza el font"
msgid "Web Page"
msgstr "Pàgina web"
#: ../js/ui/messageTray.js:1907
#: ../js/ui/messageTray.js:993
msgid "Open"
msgstr "Obre"
#: ../js/ui/messageTray.js:2151
msgid "System Information"
msgstr "Informació de l'ordinador"
#: ../js/ui/overview.js:88
#: ../js/ui/overview.js:91
msgid "Undo"
msgstr "Desfés"
#: ../js/ui/overview.js:183
#: ../js/ui/overview.js:186
msgid "Windows"
msgstr "Finestres"
#: ../js/ui/overview.js:186
#: ../js/ui/overview.js:189
msgid "Applications"
msgstr "Aplicacions"
#. Translators: this is the name of the dock/favorites area on
#. the left of the overview
#: ../js/ui/overview.js:205
msgid "Dash"
msgstr "Quadre d'aplicacions"
#. TODO - _quit() doesn't really work on apps in state STARTING yet
#: ../js/ui/panel.js:531
#: ../js/ui/panel.js:515
#, c-format
msgid "Quit %s"
msgstr "Tanca %s"
#. Button on the left side of the panel.
#. Translators: If there is no suitable word for "Activities" in your language, you can use the word for "Overview".
#: ../js/ui/panel.js:892
#: ../js/ui/panel.js:893
msgid "Activities"
msgstr "Activitats"
#: ../js/ui/panel.js:994
msgid "Top Bar"
msgstr "Barra superior"
#: ../js/ui/placeDisplay.js:122
#, c-format
msgid "Failed to unmount '%s'"
@ -580,64 +588,89 @@ msgstr "Torna-ho a intentar"
msgid "Connect to..."
msgstr "Connecta a..."
#: ../js/ui/placeDisplay.js:409
#: ../js/ui/placeDisplay.js:380
msgid "PLACES & DEVICES"
msgstr "LLOCS I DISPOSITIUS"
#: ../js/ui/polkitAuthenticationAgent.js:74
msgid "Authentication Required"
msgstr "Cal autenticació"
#: ../js/ui/polkitAuthenticationAgent.js:108
msgid "Administrator"
msgstr "Administrador"
#: ../js/ui/polkitAuthenticationAgent.js:176
msgid "Authenticate"
msgstr "Autentica"
#. Translators: "that didn't work" refers to the fact that the
#. * requested authentication was not gained; this can happen
#. * because of an authentication error (like invalid password),
#. * for instance.
#: ../js/ui/polkitAuthenticationAgent.js:264
msgid "Sorry, that didn't work. Please try again."
msgstr "No ha funcionat. Torneu-ho a provar."
#: ../js/ui/polkitAuthenticationAgent.js:276
msgid "Password:"
msgstr "Contrasenya:"
#. Translators: this MUST be either "toggle-switch-us"
#. (for toggle switches containing the English words
#. "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:612
#: ../js/ui/popupMenu.js:679
msgid "toggle-switch-us"
msgstr "toggle-switch-intl"
#: ../js/ui/runDialog.js:201
#: ../js/ui/runDialog.js:205
msgid "Please enter a command:"
msgstr "Introduïu una ordre:"
#: ../js/ui/searchDisplay.js:283
#: ../js/ui/searchDisplay.js:310
msgid "Searching..."
msgstr "S'està cercant..."
#: ../js/ui/searchDisplay.js:297
#: ../js/ui/searchDisplay.js:324
msgid "No matching results."
msgstr "No s'ha trobat cap coincidència."
#: ../js/ui/statusMenu.js:102 ../js/ui/statusMenu.js:166
#: ../js/ui/statusMenu.js:161 ../js/ui/statusMenu.js:163
#: ../js/ui/statusMenu.js:228
msgid "Power Off..."
msgstr "Apaga..."
#: ../js/ui/statusMenu.js:104 ../js/ui/statusMenu.js:165
#: ../js/ui/statusMenu.js:163 ../js/ui/statusMenu.js:227
msgid "Suspend"
msgstr "Atura temporalment"
#: ../js/ui/statusMenu.js:125
#: ../js/ui/statusMenu.js:184
msgid "Available"
msgstr "Disponible"
#: ../js/ui/statusMenu.js:130
#: ../js/ui/statusMenu.js:189
msgid "Busy"
msgstr "Ocupat"
#: ../js/ui/statusMenu.js:138
#: ../js/ui/statusMenu.js:197
msgid "My Account"
msgstr "El meu compte"
#: ../js/ui/statusMenu.js:142
#: ../js/ui/statusMenu.js:201
msgid "System Settings"
msgstr "Paràmetres de l'ordinador"
#: ../js/ui/statusMenu.js:149
#: ../js/ui/statusMenu.js:208
msgid "Lock Screen"
msgstr "Bloca la pantalla"
#: ../js/ui/statusMenu.js:153
#: ../js/ui/statusMenu.js:213
msgid "Switch User"
msgstr "Canvia d'usuari"
#: ../js/ui/statusMenu.js:158
#: ../js/ui/statusMenu.js:218
msgid "Log Out..."
msgstr "Surt..."
@ -645,14 +678,12 @@ msgstr "Surt..."
msgid "Zoom"
msgstr "Amplia"
#: ../js/ui/status/accessibility.js:69
msgid "Screen Reader"
msgstr "Lector de pantalla"
#: ../js/ui/status/accessibility.js:73
msgid "Screen Keyboard"
msgstr "Teclat en pantalla"
#. let screenReader = this._buildItem(_("Screen Reader"), APPLICATIONS_SCHEMA,
#. 'screen-reader-enabled');
#. this.menu.addMenuItem(screenReader);
#. let screenKeyboard = this._buildItem(_("Screen Keyboard"), APPLICATIONS_SCHEMA,
#. 'screen-keyboard-enabled');
#. this.menu.addMenuItem(screenKeyboard);
#: ../js/ui/status/accessibility.js:77
msgid "Visual Alerts"
msgstr "Avisos visuals"
@ -677,17 +708,17 @@ msgstr "Tecles del ratolí"
msgid "Universal Access Settings"
msgstr "Paràmetres d'accés universal"
#: ../js/ui/status/accessibility.js:145
#: ../js/ui/status/accessibility.js:146
msgid "High Contrast"
msgstr "Alt contrast"
#: ../js/ui/status/accessibility.js:182
#: ../js/ui/status/accessibility.js:183
msgid "Large Text"
msgstr "Text gran"
#: ../js/ui/status/bluetooth.js:42 ../js/ui/status/bluetooth.js:241
#: ../js/ui/status/bluetooth.js:337 ../js/ui/status/bluetooth.js:371
#: ../js/ui/status/bluetooth.js:411 ../js/ui/status/bluetooth.js:444
#: ../js/ui/status/bluetooth.js:42 ../js/ui/status/bluetooth.js:237
#: ../js/ui/status/bluetooth.js:333 ../js/ui/status/bluetooth.js:367
#: ../js/ui/status/bluetooth.js:407 ../js/ui/status/bluetooth.js:440
msgid "Bluetooth"
msgstr "Bluetooth"
@ -707,94 +738,94 @@ msgstr "Establiu un dispositiu nou..."
msgid "Bluetooth Settings"
msgstr "Paràmetres del Bluetooth"
#: ../js/ui/status/bluetooth.js:192
#: ../js/ui/status/bluetooth.js:188
msgid "Connection"
msgstr "Connexió"
#: ../js/ui/status/bluetooth.js:228
#: ../js/ui/status/bluetooth.js:224
msgid "Send Files..."
msgstr "Envia fitxers..."
#: ../js/ui/status/bluetooth.js:233
#: ../js/ui/status/bluetooth.js:229
msgid "Browse Files..."
msgstr "Navega pels fitxers..."
#: ../js/ui/status/bluetooth.js:242
#: ../js/ui/status/bluetooth.js:238
msgid "Error browsing device"
msgstr "S'ha produït un error en navegar pel dispositiu"
#: ../js/ui/status/bluetooth.js:243
#: ../js/ui/status/bluetooth.js:239
#, c-format
msgid "The requested device cannot be browsed, error is '%s'"
msgstr "No es pot navegar pel dispositiu degut a l'error «%s»"
#: ../js/ui/status/bluetooth.js:251
#: ../js/ui/status/bluetooth.js:247
msgid "Keyboard Settings"
msgstr "Paràmetres del teclat"
#: ../js/ui/status/bluetooth.js:256
#: ../js/ui/status/bluetooth.js:252
msgid "Mouse Settings"
msgstr "Paràmetres del ratolí"
#: ../js/ui/status/bluetooth.js:263 ../js/ui/status/volume.js:65
#: ../js/ui/status/bluetooth.js:259 ../js/ui/status/volume.js:66
msgid "Sound Settings"
msgstr "Paràmetres de so"
#: ../js/ui/status/bluetooth.js:372
#: ../js/ui/status/bluetooth.js:368
#, c-format
msgid "Authorization request from %s"
msgstr "Hi ha una petició d'autorització des de %s"
#: ../js/ui/status/bluetooth.js:378
#: ../js/ui/status/bluetooth.js:374
#, c-format
msgid "Device %s wants access to the service '%s'"
msgstr "El dispositiu %s vol accedir al servei «%s»"
#: ../js/ui/status/bluetooth.js:380
#: ../js/ui/status/bluetooth.js:376
msgid "Always grant access"
msgstr "Permet l'accés sempre"
#: ../js/ui/status/bluetooth.js:381
#: ../js/ui/status/bluetooth.js:377
msgid "Grant this time only"
msgstr "Permete-ho només ara"
msgstr "Permet-ho només ara"
#: ../js/ui/status/bluetooth.js:382
#: ../js/ui/status/bluetooth.js:378
msgid "Reject"
msgstr "Rebutja"
#: ../js/ui/status/bluetooth.js:412
#: ../js/ui/status/bluetooth.js:408
#, c-format
msgid "Pairing confirmation for %s"
msgstr "Confirmació d'aparellament per %s"
#: ../js/ui/status/bluetooth.js:418 ../js/ui/status/bluetooth.js:452
#: ../js/ui/status/bluetooth.js:414 ../js/ui/status/bluetooth.js:448
#, c-format
msgid "Device %s wants to pair with this computer"
msgstr "El dispositiu %s vol aparellar-se amb aquest ordinador"
#: ../js/ui/status/bluetooth.js:419
#: ../js/ui/status/bluetooth.js:415
#, c-format
msgid "Please confirm whether the PIN '%s' matches the one on the device."
msgstr "Confirmeu que el PIN «%s» coincideix amb el que hi ha al dispositiu."
#: ../js/ui/status/bluetooth.js:421
#: ../js/ui/status/bluetooth.js:417
msgid "Matches"
msgstr "Coincideix"
#: ../js/ui/status/bluetooth.js:422
#: ../js/ui/status/bluetooth.js:418
msgid "Does not match"
msgstr "No coincideix"
#: ../js/ui/status/bluetooth.js:445
#: ../js/ui/status/bluetooth.js:441
#, c-format
msgid "Pairing request for %s"
msgstr "Teniu una sol·licitud d'aparellament amb %s"
#: ../js/ui/status/bluetooth.js:453
#: ../js/ui/status/bluetooth.js:449
msgid "Please enter the PIN mentioned on the device."
msgstr "Introduïu el PIN que es mostra al dispositiu."
#: ../js/ui/status/bluetooth.js:469
#: ../js/ui/status/bluetooth.js:465
msgid "OK"
msgstr "D'acord"
@ -806,17 +837,153 @@ msgstr "Mostra la disposició del teclat..."
msgid "Localization Settings"
msgstr "Paràmetres de localització"
#: ../js/ui/status/network.js:104 ../js/ui/status/network.js:1454
msgid "<unknown>"
msgstr "<desconegut>"
#. Translators: this indicates that wireless or wwan is disabled by hardware killswitch
#: ../js/ui/status/network.js:311
msgid "disabled"
msgstr "inhabilitada"
#: ../js/ui/status/network.js:494
msgid "connecting..."
msgstr "s'està connectant..."
#. Translators: this is for network connections that require some kind of key or password
#: ../js/ui/status/network.js:497
msgid "authentication required"
msgstr "cal autenticació"
#. Translators: this is for devices that require some kind of firmware or kernel
#. module, which is missing
#: ../js/ui/status/network.js:507
msgid "firmware missing"
msgstr "manca el microprogramari"
#. Translators: this is for wired network devices that are physically disconnected
#: ../js/ui/status/network.js:514
msgid "cable unplugged"
msgstr "s'ha desconnectat el cable"
#. Translators: this is for a network device that cannot be activated (for example it
#. is disabled by rfkill, or it has no coverage
#: ../js/ui/status/network.js:519
msgid "unavailable"
msgstr "no disponible"
#: ../js/ui/status/network.js:521
msgid "connection failed"
msgstr "ha fallat la connexió"
#. TRANSLATORS: this is the indication that a connection for another logged in user is active,
#. and we cannot access its settings (including the name)
#: ../js/ui/status/network.js:602 ../js/ui/status/network.js:1402
msgid "Connected (private)"
msgstr "Connectat (privat)"
#: ../js/ui/status/network.js:683
msgid "Auto Ethernet"
msgstr "Ethernet automàtic"
#: ../js/ui/status/network.js:758
msgid "Auto broadband"
msgstr "Banda ampla automàtica"
#: ../js/ui/status/network.js:761
msgid "Auto dial-up"
msgstr "Marcatge directe automàtic"
#. TRANSLATORS: this the automatic wireless connection name (including the network name)
#: ../js/ui/status/network.js:904 ../js/ui/status/network.js:1414
#, c-format
msgid "Auto %s"
msgstr "%s automàtic"
#: ../js/ui/status/network.js:906
msgid "Auto bluetooth"
msgstr "Bluetooth automàtic"
#: ../js/ui/status/network.js:1416
msgid "Auto wireless"
msgstr "Sense fil automàtic"
#: ../js/ui/status/network.js:1474
msgid "More..."
msgstr "Més..."
#: ../js/ui/status/network.js:1497
msgid "Enable networking"
msgstr "Habilita la xarxa"
#: ../js/ui/status/network.js:1509
msgid "Wired"
msgstr "Amb fil"
#: ../js/ui/status/network.js:1520
msgid "Wireless"
msgstr "Sense fil"
#: ../js/ui/status/network.js:1530
msgid "Mobile broadband"
msgstr "Ampla de banda mòbil"
#: ../js/ui/status/network.js:1540
msgid "VPN Connections"
msgstr "Connexions VPN"
#: ../js/ui/status/network.js:1549
msgid "Network Settings"
msgstr "Paràmetres de xarxa"
#: ../js/ui/status/network.js:1844
#, c-format
msgid "You're now connected to mobile broadband connection '%s'"
msgstr "Us acabeu de connectar amb la connexió de banda ampla mòbil «%s»"
#: ../js/ui/status/network.js:1848
#, c-format
msgid "You're now connected to wireless network '%s'"
msgstr "Us acabeu de connectar a la xarxa sense fil «%s»"
#: ../js/ui/status/network.js:1852
#, c-format
msgid "You're now connected to wired network '%s'"
msgstr "Us acabeu de connectar a la xarxa amb fil «%s»"
#: ../js/ui/status/network.js:1856
#, c-format
msgid "You're now connected to VPN network '%s'"
msgstr "Us acabeu de connectar a la xarxa VPN «%s»"
#: ../js/ui/status/network.js:1861
#, c-format
msgid "You're now connected to '%s'"
msgstr "Us acabeu de connectar a «%s»"
#: ../js/ui/status/network.js:1869
msgid "Connection established"
msgstr "S'ha establert la connexió"
#: ../js/ui/status/network.js:1991
msgid "Networking is disabled"
msgstr "S'ha inhabilitat la xarxa"
#: ../js/ui/status/network.js:2116
msgid "Network Manager"
msgstr "Gestor de connexions de xarxa"
#: ../js/ui/status/power.js:85
msgid "Power Settings"
msgstr "Paràmetres d'energia"
#. 0 is reported when UPower does not have enough data
#. to estimate battery life
#: ../js/ui/status/power.js:110
#: ../js/ui/status/power.js:111
msgid "Estimating..."
msgstr "S'està estimant la durada..."
#: ../js/ui/status/power.js:117
#: ../js/ui/status/power.js:118
#, c-format
msgid "%d hour remaining"
msgid_plural "%d hours remaining"
@ -824,102 +991,102 @@ msgstr[0] "Queda %d hora"
msgstr[1] "Queden %d hores"
#. TRANSLATORS: this is a time string, as in "%d hours %d minutes remaining"
#: ../js/ui/status/power.js:120
#: ../js/ui/status/power.js:121
#, c-format
msgid "%d %s %d %s remaining"
msgstr "Queden %d %s %d %s"
#: ../js/ui/status/power.js:122
#: ../js/ui/status/power.js:123
msgid "hour"
msgid_plural "hours"
msgstr[0] "hora"
msgstr[1] "hores"
#: ../js/ui/status/power.js:122
#: ../js/ui/status/power.js:123
msgid "minute"
msgid_plural "minutes"
msgstr[0] "minut"
msgstr[1] "minuts"
#: ../js/ui/status/power.js:125
#: ../js/ui/status/power.js:126
#, c-format
msgid "%d minute remaining"
msgid_plural "%d minutes remaining"
msgstr[0] "Queda %d minut"
msgstr[1] "Queden %d minuts"
#: ../js/ui/status/power.js:227
#: ../js/ui/status/power.js:228
msgid "AC adapter"
msgstr "Adaptador de corrent"
#: ../js/ui/status/power.js:229
#: ../js/ui/status/power.js:230
msgid "Laptop battery"
msgstr "Bateria del portàtil"
#: ../js/ui/status/power.js:231
#: ../js/ui/status/power.js:232
msgid "UPS"
msgstr "SAI"
#: ../js/ui/status/power.js:233
#: ../js/ui/status/power.js:234
msgid "Monitor"
msgstr "Pantalla"
#: ../js/ui/status/power.js:235
#: ../js/ui/status/power.js:236
msgid "Mouse"
msgstr "Ratolí"
#: ../js/ui/status/power.js:237
#: ../js/ui/status/power.js:238
msgid "Keyboard"
msgstr "Teclat"
#: ../js/ui/status/power.js:239
#: ../js/ui/status/power.js:240
msgid "PDA"
msgstr "PDA"
#: ../js/ui/status/power.js:241
#: ../js/ui/status/power.js:242
msgid "Cell phone"
msgstr "Telèfon mòbil"
#: ../js/ui/status/power.js:243
#: ../js/ui/status/power.js:244
msgid "Media player"
msgstr "Reproductor multimèdia"
#: ../js/ui/status/power.js:245
#: ../js/ui/status/power.js:246
msgid "Tablet"
msgstr "Tauleta"
#: ../js/ui/status/power.js:247
#: ../js/ui/status/power.js:248
msgid "Computer"
msgstr "Ordinador"
#: ../js/ui/status/power.js:249 ../src/shell-app-system.c:1013
#: ../js/ui/status/power.js:250 ../src/shell-app-system.c:1088
msgid "Unknown"
msgstr "Desconegut"
#: ../js/ui/status/volume.js:44
#: ../js/ui/status/volume.js:45
msgid "Volume"
msgstr "Volum"
#: ../js/ui/status/volume.js:57
#: ../js/ui/status/volume.js:58
msgid "Microphone"
msgstr "Micròfon"
#: ../js/ui/telepathyClient.js:239
#: ../js/ui/telepathyClient.js:331
#, c-format
msgid "%s is online."
msgstr "%s és en línia."
#: ../js/ui/telepathyClient.js:244
#: ../js/ui/telepathyClient.js:336
#, c-format
msgid "%s is offline."
msgstr "%s no hi és."
#: ../js/ui/telepathyClient.js:247
#: ../js/ui/telepathyClient.js:339
#, c-format
msgid "%s is away."
msgstr "%s és lluny."
#: ../js/ui/telepathyClient.js:250
#: ../js/ui/telepathyClient.js:342
#, c-format
msgid "%s is busy."
msgstr "%s està ocupat."
@ -927,7 +1094,7 @@ msgstr "%s està ocupat."
#. Translators: this is a time format string followed by a date.
#. If applicable, replace %X with a strftime format valid for your
#. locale, without seconds.
#: ../js/ui/telepathyClient.js:348
#: ../js/ui/telepathyClient.js:473
#, no-c-format
msgid "Sent at %X on %A"
msgstr "Enviat a les %X del %A"
@ -936,10 +1103,14 @@ msgstr "Enviat a les %X del %A"
#. in the search entry when no search is
#. active; it should not exceed ~30
#. characters.
#: ../js/ui/viewSelector.js:103
#: ../js/ui/viewSelector.js:122
msgid "Type to search..."
msgstr "Teclegeu per cercar..."
#: ../js/ui/viewSelector.js:142 ../src/shell-util.c:250
msgid "Search"
msgstr "Cerca"
#: ../js/ui/windowAttentionHandler.js:42
#, c-format
msgid "%s has finished starting"
@ -952,7 +1123,7 @@ msgstr "«%s» ja està apunt"
#. translators:
#. * The number of sound outputs on a particular device
#: ../src/gvc/gvc-mixer-control.c:1094
#: ../src/gvc/gvc-mixer-control.c:1098
#, c-format
msgid "%u Output"
msgid_plural "%u Outputs"
@ -961,49 +1132,66 @@ msgstr[1] "%u sortides"
#. translators:
#. * The number of sound inputs on a particular device
#: ../src/gvc/gvc-mixer-control.c:1104
#: ../src/gvc/gvc-mixer-control.c:1108
#, c-format
msgid "%u Input"
msgid_plural "%u Inputs"
msgstr[0] "%u entrada"
msgstr[1] "%u entrades"
#: ../src/gvc/gvc-mixer-control.c:1402
#: ../src/gvc/gvc-mixer-control.c:1406
msgid "System Sounds"
msgstr "Sons del sistema"
#: ../src/shell-global.c:1298
#: ../src/main.c:446
msgid "Print version"
msgstr "Mostra la versió"
#: ../src/shell-app.c:454
#, c-format
msgid "Failed to launch '%s'"
msgstr "No s'ha pogut iniciar «%s»"
#: ../src/shell-global.c:1395
msgid "Less than a minute ago"
msgstr "Fa menys d'un minut"
#: ../src/shell-global.c:1302
#: ../src/shell-global.c:1399
#, c-format
msgid "%d minute ago"
msgid_plural "%d minutes ago"
msgstr[0] "Fa %d minut"
msgstr[1] "Fa %d minuts"
#: ../src/shell-global.c:1307
#: ../src/shell-global.c:1404
#, c-format
msgid "%d hour ago"
msgid_plural "%d hours ago"
msgstr[0] "Fa %d hora"
msgstr[1] "Fa %d hores"
#: ../src/shell-global.c:1312
#: ../src/shell-global.c:1409
#, c-format
msgid "%d day ago"
msgid_plural "%d days ago"
msgstr[0] "Fa %d dia"
msgstr[1] "Fa %d dies"
#: ../src/shell-global.c:1317
#: ../src/shell-global.c:1414
#, c-format
msgid "%d week ago"
msgid_plural "%d weeks ago"
msgstr[0] "Fa %d setmana"
msgstr[1] "Fa %d setmanes"
#: ../src/shell-mobile-providers.c:80
msgid "United Kingdom"
msgstr "Regne Unit"
#: ../src/shell-mobile-providers.c:526
msgid "Default"
msgstr "Predeterminat"
#: ../src/shell-polkit-authentication-agent.c:334
msgid "Authentication dialog was dismissed by the user"
msgstr "L'usuari ha descartat el diàleg d'autenticació"
@ -1018,10 +1206,6 @@ msgstr "Carpeta d'inici"
msgid "File System"
msgstr "Sistema de fitxers"
#: ../src/shell-util.c:250
msgid "Search"
msgstr "Cerca"
#. Translators: the first string is the name of a gvfs
#. * method, and the second string is a path. For
#. * example, "Trash: some-directory". It means that the
@ -1032,6 +1216,33 @@ msgstr "Cerca"
msgid "%1$s: %2$s"
msgstr "%1$s: %2$s"
#~ msgid "Shut Down"
#~ msgstr "Atura"
#~ msgid "Click Shut Down to quit these applications and shut down the system."
#~ msgstr "Feu clic a «Atura» per tancar les aplicacions i apagar l'ordinador."
#~ msgid "The system will shut down automatically in %d seconds."
#~ msgstr "S'apagarà l'ordinador automàticament d'aquí %d segons."
#~ msgid "Shutting down the system."
#~ msgstr "S'està apagant l'ordinador."
#~ msgid "Confirm"
#~ msgstr "D'acord"
#~ msgid "Panel"
#~ msgstr "Quadre"
#~ msgid "No such application"
#~ msgstr "No hi ha cap aplicació"
#~ msgid "Screen Reader"
#~ msgstr "Lector de pantalla"
#~ msgid "Screen Keyboard"
#~ msgstr "Teclat en pantalla"
#~ msgid "PREFERENCES"
#~ msgstr "PREFERÈNCIES"

683
po/cs.po

File diff suppressed because it is too large Load Diff

1317
po/da.po

File diff suppressed because it is too large Load Diff

1223
po/de.po

File diff suppressed because it is too large Load Diff

824
po/el.po

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

533
po/es.po

File diff suppressed because it is too large Load Diff

550
po/et.po
View File

@ -12,21 +12,21 @@ msgid ""
msgstr ""
"Project-Id-Version: gnome-shell MASTER\n"
"Report-Msgid-Bugs-To: http://bugzilla.gnome.org/enter_bug.cgi?product=gnome-"
"shell&component=general\n"
"POT-Creation-Date: 2011-02-04 22:28+0000\n"
"PO-Revision-Date: 2011-02-06 08:43+0200\n"
"Last-Translator: Ivar Smolin <okul@linux.ee>\n"
"shell&keywords=I18N+L10N&component=general\n"
"POT-Creation-Date: 2011-03-30 17:13+0000\n"
"PO-Revision-Date: 2011-03-30 23:56+0300\n"
"Last-Translator: Mattias Põldaru <mahfiaz@gmail.com>\n"
"Language-Team: Estonian <gnome-et@linux.ee>\n"
"Language: et\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Language: et\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
"X-Poedit-Language: Estonian\n"
"X-Poedit-Country: Estonia\n"
msgid "GNOME Shell"
msgstr "GNOME kest"
msgstr "GNOME Shell"
msgid "Window management and application launching"
msgstr "Aknahaldur ja rakenduste käivitaja"
@ -58,6 +58,10 @@ msgstr ""
msgid "History for command (Alt-F2) dialog"
msgstr "Käsudialoogi (Alt-F2) ajalugu"
# suurendusklaasidialoog? miks ka mitte :)
msgid "History for the looking glass dialog"
msgstr "Otsingudialoogi ajalugu"
msgid "If true, display date in the clock, in addition to time."
msgstr "Kui määratud, siis kuvatakse kellaaja kõrval ka kuupäeva."
@ -83,6 +87,16 @@ msgid ""
"records to WEBM using the VP8 codec. %T is used as a placeholder for a guess "
"at the optimal thread count on the system."
msgstr ""
"Määrab GStreameri toru, mida kasutatakse lindistuste kodeerimiseks. See peab "
"vastama gst-launch'i süntaksile. Torul peaks olema vaba plokk (pad), kuhu "
"lindistatav video salvestatakse. Tavaliselt on vaba plokk olemas; selle "
"ploki väljund kirjutatakse väljundfaili. Toru võib hoolitseda ka enda "
"väljundi eest - seda võib kasutada väljundi saatmiseks icecast serverisse "
"shout2send või sarnase tehnoloogia abil. Kui see on määramata või väärtus on "
"tühi, kasutatakse vaikimisi toru. See on praegu 'videorate ! vp8enc "
"quality=10 speed=2 threads=%T ! queue ! webmmux' ning lindistab WEBM "
"vormingusse VP8 koodekiga. %T asendatakse süsteemi oletatava optimaalseima "
"lõimede (thread) arvuga."
msgid "Show date in clock"
msgstr "Kell näitab kuupäeva"
@ -96,7 +110,7 @@ msgstr "Kellaaega näidatakse sekunditega"
msgid ""
"The applications corresponding to these identifiers will be displayed in the "
"favorites area."
msgstr ""
msgstr "Nendele tunnustele vastavaid rakendusi kuvatakse lemmikutes."
msgid ""
"The filename for recorded screencasts will be a unique filename based on the "
@ -112,9 +126,10 @@ msgid ""
"The framerate of the resulting screencast recordered by GNOME Shell's "
"screencast recorder in frames-per-second."
msgstr ""
"GNOME Shelli lindistatava ekraanivideo kaadrisagedus (kaadrit sekundis)."
msgid "The gstreamer pipeline used to encode the screencast"
msgstr ""
msgstr "GStreameri toru, mida ekraanivideo kodeerimiseks kasutatakse"
msgid ""
"The shell normally monitors active applications in order to present the most "
@ -122,125 +137,19 @@ msgid ""
"want to disable this for privacy reasons. Please note that doing so won't "
"remove already saved data."
msgstr ""
"Shell tavaliselt seirab aktiivseid rakendusi, et näidata enamkasutatavaid "
"(näiteks käivitajaid). Kuigi neid andmeid hoitakse privaatselt, võid "
"privaatsuse suurendamiseks selle keelata. Selle keelamine siiski ei eemalda "
"juba salvestatud andmeid."
msgid "Uuids of extensions to disable"
msgstr "Keelatavate laienduste UUID-d"
msgid "Whether to collect stats about applications usage"
msgstr ""
msgstr "Kas rakenduste kasutuse kohta kogutakse andmeid"
msgid "disabled OpenSearch providers"
msgstr ""
msgid "Clip the crosshairs at the center"
msgstr "Niitristi keskel on auk"
msgid "Color of the crosshairs"
msgstr "Niitristi värvus"
msgid ""
"Determines the length of the vertical and horizontal lines that make up the "
"crosshairs."
msgstr ""
msgid ""
"Determines the position of the magnified mouse image within the magnified "
"view and how it reacts to system mouse movement. The values are - none: no "
"mouse tracking; - centered: the mouse image is displayed at the center of "
"the zoom region (which also represents the point under the system mouse) and "
"the magnified contents are scrolled as the system mouse moves; - "
"proportional: the position of the magnified mouse in the zoom region is "
"proportionally the same as the position of the system mouse on screen; - "
"push: when the magnified mouse intersects a boundary of the zoom region, the "
"contents are scrolled into view."
msgstr ""
msgid ""
"Determines the transparency of the crosshairs, from fully opaque to fully "
"transparent."
msgstr ""
"Määrab niitristi läbipaistvuse, alates täiesti läbipaistmatust kuni täiesti "
"läbipaistvani."
msgid ""
"Determines whether the crosshairs intersect the magnified mouse sprite, or "
"are clipped such that the ends of the horizontal and vertical lines surround "
"the mouse image."
msgstr ""
"Määrab, kas niitrist kattub suurendatud hiire pildiga või on keskelt ära "
"lõigatud nii, et jooned ümbritsevad hiirekursori pilti."
msgid "Enable lens mode"
msgstr "Läätsede režiimi lubamine"
msgid ""
"Enables/disables display of crosshairs centered on the magnified mouse "
"sprite."
msgstr "Lubab/keelab niitristi kuvamise suurendatud hiirekursori kohal."
msgid ""
"For centered mouse tracking, when the system pointer is at or near the edge "
"of the screen, the magnified contents continue to scroll such that the "
"screen edge moves into the magnified view."
msgstr ""
msgid "Length of the crosshairs"
msgstr "Niitristi pikkus"
msgid "Magnification factor"
msgstr "Suurendustegur"
msgid "Mouse Tracking Mode"
msgstr "Hiire jälitamise režiim"
msgid "Opacity of the crosshairs"
msgstr "Niitristi läbipaistvus"
msgid "Screen position"
msgstr "Ekraani asukoht"
msgid "Scroll magnified contents beyond the edges of the desktop"
msgstr "Suurendusklaas võib liikuda töölauapiiridest väljapoole"
msgid "Show or hide crosshairs"
msgstr "Niitristi kuvamine või peitmine"
msgid "Show or hide the magnifier"
msgstr "Suurendusklaasi kuvamine või peitmine"
msgid "Show or hide the magnifier and all of its zoom regions."
msgstr ""
"Suurendusklaasi ja selle kõigi suurenduspiirkondade kuvamine või peitmine."
msgid ""
"The color of the the vertical and horizontal lines that make up the "
"crosshairs."
msgstr "Niitristi püst- ja rõhtjoone värvus."
msgid ""
"The magnified view either fills the entire screen, or occupies the top-half, "
"bottom-half, left-half, or right-half of the screen."
msgstr ""
"Suurendatud vaade täidab kas kogu ekraani või täidab ülemise, alumise, "
"vasaku või parema ekraanipoole."
msgid ""
"The power of the magnification. A value of 1.0 means no magnification. A "
"value of 2.0 doubles the size."
msgstr "Suurendustegur. 1,0 tähendab originaalsuurust. 2,0 muudab kaks korda."
msgid "Thickness of the crosshairs"
msgstr "Niitristi paksus"
msgid ""
"Whether the magnified view should be centered over the location of the "
"system mouse and move with it."
msgstr ""
"Kas suurendatud vaate keskkoht peaks asetsema süsteemi hiire kohal ning "
"liikuma sellega kaasa."
msgid "Width of the vertical and horizontal lines that make up the crosshairs."
msgstr "Niitristi moodustavate püst- ja rõhtjoone laius"
msgstr "keelatud OpenSearch pakkujad"
msgid "Command not found"
msgstr "Käsku ei leitud"
@ -250,9 +159,6 @@ msgstr "Käsku ei leitud"
msgid "Could not parse command:"
msgstr "Käsku pole võimalik analüüsida:"
msgid "No such application"
msgstr "Sellist rakendust ei ole"
#, c-format
msgid "Execution of '%s' failed:"
msgstr "'%s' käivitamine nurjus:"
@ -264,8 +170,8 @@ msgstr "Kõik"
msgid "APPLICATIONS"
msgstr "Rakendused"
msgid "PREFERENCES"
msgstr "Eelistused"
msgid "SETTINGS"
msgstr "Seaded"
msgid "New Window"
msgstr "Uus aken"
@ -382,7 +288,7 @@ msgstr "L"
#. Translators: Text to show if there are no events
msgid "Nothing Scheduled"
msgstr ""
msgstr "Ühtegi sündmust pole plaanitud"
#. Translators: Shown on calendar heading when selected day occurs on current year
msgctxt "calendar heading"
@ -465,6 +371,8 @@ msgstr "Logi välja"
msgid "Click Log Out to quit these applications and log out of the system."
msgstr ""
"Nende rakenduste sulgemiseks ja süsteemist väljalogimiseks klõpsa nupule "
"Logi välja."
#, c-format
msgid "%s will be logged out automatically in %d seconds."
@ -477,17 +385,19 @@ msgstr "Sind logitakse %d sekundi pärast automaatselt välja."
msgid "Logging out of the system."
msgstr "Süsteemist väljalogimine"
msgid "Shut Down"
msgid "Power Off"
msgstr "Lülita välja"
msgid "Click Shut Down to quit these applications and shut down the system."
msgid "Click Power Off to quit these applications and power off the system."
msgstr ""
"Nende rakenduste sulgemiseks ja süsteemi väljalülitamiseks klõpsa nupule "
"Lülita välja."
#, c-format
msgid "The system will shut down automatically in %d seconds."
msgid "The system will power off automatically in %d seconds."
msgstr "%d sekundi pärast lülitub süsteem automaatselt välja."
msgid "Shutting down the system."
msgid "Powering off the system."
msgstr "Süsteemi väljalülitamine."
msgid "Restart"
@ -505,9 +415,6 @@ msgstr "Süsteem taaskäivitatakse automaatselt %d sekundi pärast."
msgid "Restarting the system."
msgstr "Süsteemi taaskäivitamine."
msgid "Confirm"
msgstr "Kinnita"
msgid "Cancel"
msgstr "Katkesta"
@ -534,6 +441,9 @@ msgstr "Kuva lähtekoodi"
msgid "Web Page"
msgstr "Veebileht"
msgid "Open"
msgstr "Ava"
msgid "System Information"
msgstr "Süsteemi andmed"
@ -546,6 +456,11 @@ msgstr "Aknad"
msgid "Applications"
msgstr "Rakendused"
#. Translators: this is the name of the dock/favorites area on
#. the left of the overview
msgid "Dash"
msgstr "Dokk"
#. TODO - _quit() doesn't really work on apps in state STARTING yet
#, c-format
msgid "Quit %s"
@ -556,6 +471,9 @@ msgstr "Lõpeta %s"
msgid "Activities"
msgstr "Tegevused"
msgid "Top Bar"
msgstr "Ülemine riba"
#, c-format
msgid "Failed to unmount '%s'"
msgstr "'%s' lahtihaakimine nurjus"
@ -569,6 +487,25 @@ msgstr "Ühendumine..."
msgid "PLACES & DEVICES"
msgstr "Asukohad ja seadmed"
msgid "Authentication Required"
msgstr "Vajalik on autentimine"
msgid "Administrator"
msgstr "Administraator"
msgid "Authenticate"
msgstr "Autendi"
#. Translators: "that didn't work" refers to the fact that the
#. * requested authentication was not gained; this can happen
#. * because of an authentication error (like invalid password),
#. * for instance.
msgid "Sorry, that didn't work. Please try again."
msgstr "Kahjuks see ei sobinud. Palun proovi uuesti."
msgid "Password:"
msgstr "Parool:"
#. Translators: this MUST be either "toggle-switch-us"
#. (for toggle switches containing the English words
#. "ON" and "OFF") or "toggle-switch-intl" (for toggle
@ -580,6 +517,18 @@ msgstr "toggle-switch-intl"
msgid "Please enter a command:"
msgstr "Palun sisesta käsk:"
msgid "Searching..."
msgstr "Otsimine..."
msgid "No matching results."
msgstr "Tulemused puuduvad."
msgid "Power Off..."
msgstr "Lülita välja..."
msgid "Suspend"
msgstr "Uinak"
msgid "Available"
msgstr "Saadaval"
@ -601,24 +550,15 @@ msgstr "Vaheta kasutajat"
msgid "Log Out..."
msgstr "Logi välja..."
#. This is temporarily removed, see
#. http://bugzilla.gnome.org/show_bug.cgi?id=636680
#. for details.
#. item = new PopupMenu.PopupMenuItem(_("Suspend..."));
#. item.connect('activate', Lang.bind(this, this._onShutDownActivate));
#. this.menu.addMenuItem(item);
msgid "Shut Down..."
msgstr "Lülita välja..."
msgid "Zoom"
msgstr ""
msgid "Screen Reader"
msgstr "Ekraanilugeja"
msgid "Screen Keyboard"
msgstr "Ekraaniklaviatuur"
msgstr "Suurendus"
#. let screenReader = this._buildItem(_("Screen Reader"), APPLICATIONS_SCHEMA,
#. 'screen-reader-enabled');
#. this.menu.addMenuItem(screenReader);
#. let screenKeyboard = this._buildItem(_("Screen Keyboard"), APPLICATIONS_SCHEMA,
#. 'screen-keyboard-enabled');
#. this.menu.addMenuItem(screenKeyboard);
msgid "Visual Alerts"
msgstr "Visuaalsed märguanded"
@ -638,10 +578,10 @@ msgid "Universal Access Settings"
msgstr "Universaalse ligipääsu sätted"
msgid "High Contrast"
msgstr ""
msgstr "Kõrgkontrastne"
msgid "Large Text"
msgstr ""
msgstr "Suur tekst"
msgid "Bluetooth"
msgstr "Bluetooth"
@ -653,7 +593,7 @@ msgid "Send Files to Device..."
msgstr "Failide saatmine seadmesse..."
msgid "Setup a New Device..."
msgstr ""
msgstr "Uue seadme häälestamine..."
msgid "Bluetooth Settings"
msgstr "Bluetoothi sätted"
@ -672,7 +612,7 @@ msgstr "Viga seadme sirvimisel"
#, c-format
msgid "The requested device cannot be browsed, error is '%s'"
msgstr ""
msgstr "Küsitud seadet pole võimalik sirvida, viga on '%s'"
msgid "Keyboard Settings"
msgstr "Klaviatuurisätted"
@ -683,9 +623,6 @@ msgstr "Hiiresätted"
msgid "Sound Settings"
msgstr "Helisätted"
msgid "Bluetooth Agent"
msgstr "Bluetoothi agent"
#, c-format
msgid "Authorization request from %s"
msgstr "Autoriseerimise päring seadmelt %s"
@ -731,12 +668,126 @@ msgstr "Palun sisesta seadme poolt öeldav PIN-kood."
msgid "OK"
msgstr "Olgu"
msgid "Show Keyboard Layout..."
msgstr "Klaviatuuripaigutuse kuvamine..."
msgid "Localization Settings"
msgstr "Lokaliseerimissätted"
msgid "<unknown>"
msgstr "<tundmatu>"
#. Translators: this indicates that wireless or wwan is disabled by hardware killswitch
msgid "disabled"
msgstr "keelatud"
msgid "connecting..."
msgstr "ühendumine..."
#. Translators: this is for network connections that require some kind of key or password
msgid "authentication required"
msgstr "vajalik on autentimine"
#. Translators: this is for devices that require some kind of firmware or kernel
#. module, which is missing
msgid "firmware missing"
msgstr "püsivara puudub"
#. Translators: this is for wired network devices that are physically disconnected
msgid "cable unplugged"
msgstr "juhe eemaldatud"
#. Translators: this is for a network device that cannot be activated (for example it
#. is disabled by rfkill, or it has no coverage
msgid "unavailable"
msgstr "pole saadaval"
msgid "connection failed"
msgstr "ühendumine nurjus"
#. TRANSLATORS: this is the indication that a connection for another logged in user is active,
#. and we cannot access its settings (including the name)
msgid "Connected (private)"
msgstr "Ühendatud (privaatne)"
msgid "Auto Ethernet"
msgstr "Automaatne ethernet"
msgid "Auto broadband"
msgstr "Automaatne lairibaühendus"
msgid "Auto dial-up"
msgstr "Automaatne sissehelistamine"
#. TRANSLATORS: this the automatic wireless connection name (including the network name)
#, c-format
msgid "Auto %s"
msgstr "Automaatne %s"
msgid "Auto bluetooth"
msgstr "Automaatne bluetooth"
msgid "Auto wireless"
msgstr "Automaatne juhtmeta ühendus"
msgid "More..."
msgstr "Veel..."
msgid "Enable networking"
msgstr "Luba võrguühendused"
msgid "Wired"
msgstr "Juhtmega"
msgid "Wireless"
msgstr "Juhtmeta"
msgid "Mobile broadband"
msgstr "Mobiiliühendus"
msgid "VPN Connections"
msgstr "VPN-ühendused"
msgid "Network Settings"
msgstr "Võrgusätted"
#, c-format
msgid "You're now connected to mobile broadband connection '%s'"
msgstr "Loodi mobiiliühendus '%s'"
#, c-format
msgid "You're now connected to wireless network '%s'"
msgstr "Loodi ühendus juhtmeta võrguga '%s'"
#, c-format
msgid "You're now connected to wired network '%s'"
msgstr "Loodi ühendus juhtmega võrguga '%s'"
#, c-format
msgid "You're now connected to VPN network '%s'"
msgstr "Loodi ühendus VPN-võrguga '%s'"
#, c-format
msgid "You're now connected to '%s'"
msgstr "Loodi võrguühendus '%s' kaudu"
msgid "Connection established"
msgstr "Ühendus loodud"
msgid "Networking is disabled"
msgstr "Võrguühendused on keelatud"
msgid "Network Manager"
msgstr "Võrguhaldur"
msgid "Power Settings"
msgstr "Toitesätted..."
#. 0 is reported when UPower does not have enough data
#. to estimate battery life
msgid "Estimating..."
msgstr "Andmete kogumine..."
#, c-format
msgid "%d hour remaining"
msgid_plural "%d hours remaining"
@ -829,8 +880,15 @@ msgstr "%s on hõivatud."
msgid "Sent at %X on %A"
msgstr "Saadetud: %a, kell %X"
msgid "Search your computer"
msgstr ""
#. Translators: this is the text displayed
#. in the search entry when no search is
#. active; it should not exceed ~30
#. characters.
msgid "Type to search..."
msgstr "Otsing..."
msgid "Search"
msgstr "Otsing"
#, c-format
msgid "%s has finished starting"
@ -840,32 +898,32 @@ msgstr "%s läks käima"
msgid "'%s' is ready"
msgstr "'%s' on valmis"
msgid ""
"Can't add a new workspace because maximum workspaces limit has been reached."
msgstr "Pole võimalik uut tööala lisada, kuna tööalade piir on saavutatud."
msgid "Can't remove the first workspace."
msgstr "Esimest tööala pole võimalik eemaldada."
#. translators:
#. * The number of sound outputs on a particular device
#, c-format
msgid "%u Output"
msgid_plural "%u Outputs"
msgstr[0] ""
msgstr[1] ""
msgstr[0] "%u väljund"
msgstr[1] "%u väljundit"
#. translators:
#. * The number of sound inputs on a particular device
#, c-format
msgid "%u Input"
msgid_plural "%u Inputs"
msgstr[0] ""
msgstr[1] ""
msgstr[0] "%u sisend"
msgstr[1] "%u sisendit"
msgid "System Sounds"
msgstr "Süsteemi helid"
msgid "Print version"
msgstr "Printimise versioon"
#, c-format
msgid "Failed to launch '%s'"
msgstr "'%s' käivitamine nurjus"
msgid "Less than a minute ago"
msgstr "Vähem kui minuti eest"
@ -893,6 +951,15 @@ msgid_plural "%d weeks ago"
msgstr[0] "%d nädal tagasi"
msgstr[1] "%d nädalat tagasi"
msgid "United Kingdom"
msgstr "Suurbritannia"
msgid "Default"
msgstr "Vaikimisi"
msgid "Authentication dialog was dismissed by the user"
msgstr "Kasutaja katkestas autentimisdialoogi"
msgid "Home Folder"
msgstr "Kodukaust"
@ -901,9 +968,6 @@ msgstr "Kodukaust"
msgid "File System"
msgstr "Failisüsteem"
msgid "Search"
msgstr "Otsing"
#. Translators: the first string is the name of a gvfs
#. * method, and the second string is a path. For
#. * example, "Trash: some-directory". It means that the
@ -913,8 +977,140 @@ msgstr "Otsing"
msgid "%1$s: %2$s"
msgstr "%1$s: %2$s"
#~ msgid "Suspend..."
#~ msgstr "Peata..."
#~ msgid "Shut Down"
#~ msgstr "Lülita välja"
#~ msgid "Click Shut Down to quit these applications and shut down the system."
#~ msgstr ""
#~ "Nende rakenduste sulgemiseks ja süsteemi väljalülitamiseks klõpsa nupule "
#~ "Logi välja."
#~ msgid "The system will shut down automatically in %d seconds."
#~ msgstr "%d sekundi pärast lülitub süsteem automaatselt välja."
#~ msgid "Shutting down the system."
#~ msgstr "Süsteemi väljalülitamine."
#~ msgid "Confirm"
#~ msgstr "Kinnita"
#~ msgid "Panel"
#~ msgstr "Paneel"
#~ msgid "No such application"
#~ msgstr "Sellist rakendust ei ole"
#~ msgid "Screen Reader"
#~ msgstr "Ekraanilugeja"
#~ msgid "Screen Keyboard"
#~ msgstr "Ekraaniklaviatuur"
#~ msgid "Clip the crosshairs at the center"
#~ msgstr "Niitristi keskel on auk"
#~ msgid "Color of the crosshairs"
#~ msgstr "Niitristi värvus"
#~ msgid ""
#~ "Determines the transparency of the crosshairs, from fully opaque to fully "
#~ "transparent."
#~ msgstr ""
#~ "Määrab niitristi läbipaistvuse, alates täiesti läbipaistmatust kuni "
#~ "täiesti läbipaistvani."
#~ msgid ""
#~ "Determines whether the crosshairs intersect the magnified mouse sprite, "
#~ "or are clipped such that the ends of the horizontal and vertical lines "
#~ "surround the mouse image."
#~ msgstr ""
#~ "Määrab, kas niitrist kattub suurendatud hiire pildiga või on keskelt ära "
#~ "lõigatud nii, et jooned ümbritsevad hiirekursori pilti."
#~ msgid "Enable lens mode"
#~ msgstr "Läätsede režiimi lubamine"
#~ msgid ""
#~ "Enables/disables display of crosshairs centered on the magnified mouse "
#~ "sprite."
#~ msgstr "Lubab/keelab niitristi kuvamise suurendatud hiirekursori kohal."
#~ msgid "Length of the crosshairs"
#~ msgstr "Niitristi pikkus"
#~ msgid "Magnification factor"
#~ msgstr "Suurendustegur"
#~ msgid "Mouse Tracking Mode"
#~ msgstr "Hiire jälitamise režiim"
#~ msgid "Opacity of the crosshairs"
#~ msgstr "Niitristi läbipaistvus"
#~ msgid "Screen position"
#~ msgstr "Ekraani asukoht"
#~ msgid "Scroll magnified contents beyond the edges of the desktop"
#~ msgstr "Suurendusklaas võib liikuda töölauapiiridest väljapoole"
#~ msgid "Show or hide crosshairs"
#~ msgstr "Niitristi kuvamine või peitmine"
#~ msgid "Show or hide the magnifier"
#~ msgstr "Suurendusklaasi kuvamine või peitmine"
#~ msgid "Show or hide the magnifier and all of its zoom regions."
#~ msgstr ""
#~ "Suurendusklaasi ja selle kõigi suurenduspiirkondade kuvamine või peitmine."
#~ msgid ""
#~ "The color of the the vertical and horizontal lines that make up the "
#~ "crosshairs."
#~ msgstr "Niitristi püst- ja rõhtjoone värvus."
#~ msgid ""
#~ "The magnified view either fills the entire screen, or occupies the top-"
#~ "half, bottom-half, left-half, or right-half of the screen."
#~ msgstr ""
#~ "Suurendatud vaade täidab kas kogu ekraani või täidab ülemise, alumise, "
#~ "vasaku või parema ekraanipoole."
#~ msgid ""
#~ "The power of the magnification. A value of 1.0 means no magnification. A "
#~ "value of 2.0 doubles the size."
#~ msgstr ""
#~ "Suurendustegur. 1,0 tähendab originaalsuurust. 2,0 muudab kaks korda."
#~ msgid "Thickness of the crosshairs"
#~ msgstr "Niitristi paksus"
#~ msgid ""
#~ "Whether the magnified view should be centered over the location of the "
#~ "system mouse and move with it."
#~ msgstr ""
#~ "Kas suurendatud vaate keskkoht peaks asetsema süsteemi hiire kohal ning "
#~ "liikuma sellega kaasa."
#~ msgid ""
#~ "Width of the vertical and horizontal lines that make up the crosshairs."
#~ msgstr "Niitristi moodustavate püst- ja rõhtjoone laius"
#~ msgid "PREFERENCES"
#~ msgstr "Eelistused"
#~ msgid "Shut Down..."
#~ msgstr "Lülita välja..."
#~ msgid "Bluetooth Agent"
#~ msgstr "Bluetoothi agent"
#~ msgid ""
#~ "Can't add a new workspace because maximum workspaces limit has been "
#~ "reached."
#~ msgstr "Pole võimalik uut tööala lisada, kuna tööalade piir on saavutatud."
#~ msgid "Can't remove the first workspace."
#~ msgstr "Esimest tööala pole võimalik eemaldada."
#~ msgid "Clock"
#~ msgstr "Kell"
@ -958,11 +1154,5 @@ msgstr "%1$s: %2$s"
#~ msgid "Find"
#~ msgstr "Otsi"
#~ msgid "Searching..."
#~ msgstr "Otsimine..."
#~ msgid "No matching results."
#~ msgstr "Tulemused puuduvad."
#~ msgid "Invisible"
#~ msgstr "Nähtamatu"

1232
po/eu.po Normal file

File diff suppressed because it is too large Load Diff

1170
po/fr.po

File diff suppressed because it is too large Load Diff

990
po/gl.po

File diff suppressed because it is too large Load Diff

801
po/gu.po

File diff suppressed because it is too large Load Diff

520
po/he.po

File diff suppressed because it is too large Load Diff

1185
po/hi.po Normal file

File diff suppressed because it is too large Load Diff

559
po/hu.po

File diff suppressed because it is too large Load Diff

1190
po/id.po

File diff suppressed because it is too large Load Diff

555
po/it.po

File diff suppressed because it is too large Load Diff

1486
po/ja.po

File diff suppressed because it is too large Load Diff

View File

@ -9,7 +9,7 @@ msgstr ""
"Report-Msgid-Bugs-To: http://bugzilla.gnome.org/enter_bug."
"cgi?product=gnome-shell&component=general\n"
"POT-Creation-Date: 2011-02-21 01:21+0000\n"
"PO-Revision-Date: 2011-03-04 17:37+0530\n"
"PO-Revision-Date: 2011-03-09 09:36+0530\n"
"Last-Translator: Shankar Prasad <svenkate@redhat.com>\n"
"Language-Team: Kannada <kn@li.org>\n"
"MIME-Version: 1.0\n"
@ -112,6 +112,7 @@ msgid ""
"The applications corresponding to these identifiers will be displayed in the "
"favorites area."
msgstr ""
"ಈ ಐಡೆಂಟಿಫಯರುಗಳಿಗೆ ಅನುಗುಣವಾದ ಅನ್ವಯಗಳನ್ನು ಮೆಚ್ಚಿನವುಗಳ ಜಾಗದಲ್ಲಿ ತೋರಿಸಲಾಗುತ್ತದೆ."
#: ../data/org.gnome.shell.gschema.xml.in.h:18
msgid ""
@ -119,12 +120,17 @@ msgid ""
"current date, and use this extension. It should be changed when recording to "
"a different container format."
msgstr ""
"ರೆಕಾರ್ಡು ಮಾಡಲಾದ ಸ್ಕ್ರೀನ್‌ಕ್ಯಾಸ್ಟುಗಳಿಗಾಗಿನ ಕಡತದ ಹೆಸರು ಪ್ರಸಕ್ತ ದಿನಾಂಕದ "
"ಆಧರಿತವಾದ ಒಂದು ವಿಶೇಷವಾದ ಕಡತದ ಹೆಸರಾಗಿರುತ್ತದೆ, ಹಾಗು ಈ ವಿಸ್ತರಣೆಯನ್ನು ಬಳಸುತ್ತದೆ. "
"ಬೇರೊಂದು ಕಂಟೈನರ್ ಶೈಲಿಗೆ ರೆಕಾರ್ಡ್ ಮಾಡುವಾಗ ಇದನ್ನು ಬದಲಾಯಿಸಬೇಕಾಗುತ್ತದೆ."
#: ../data/org.gnome.shell.gschema.xml.in.h:19
msgid ""
"The framerate of the resulting screencast recordered by GNOME Shell's "
"screencast recorder in frames-per-second."
msgstr ""
"ಪ್ರತಿ ಸೆಕೆಂಡಿನ ಫ್ರೇಮ್‌ಗಳಲ್ಲಿನ GNOME ಶೆಲ್‌ನ ಸ್ಕ್ರೀನ್‌ಕ್ಯಾಸ್ಟ್‍ ರೆಕಾರ್ಡರಿನಿಂದ "
"ರೆಕಾರ್ಡು ಮಾಡಲಾದ ಸ್ಕ್ರೀನ್‌ಕ್ಯಾಸ್ಟಿನ ಫ್ರೇಮ್‌ದರ. "
#: ../data/org.gnome.shell.gschema.xml.in.h:20
msgid "The gstreamer pipeline used to encode the screencast"
@ -658,7 +664,7 @@ msgstr "ಜಾಗತಿಕ ನಿಲುಕಣೆ ಸಿದ್ಧತೆಗಳು"
#: ../js/ui/status/accessibility.js:164
msgid "High Contrast"
msgstr ""
msgstr "ಅತಿ ಹೆಚ್ಚು ವೈದೃಶ್ಯ"
#: ../js/ui/status/accessibility.js:206
msgid "Large Text"
@ -767,7 +773,7 @@ msgstr "ತಾಳೆಯಾಗುತ್ತಿಲ್ಲ"
#: ../js/ui/status/bluetooth.js:445
#, c-format
msgid "Pairing request for %s"
msgstr ""
msgstr "%s ಗಾಗಿ ಪೇರಿಂಗ್ ಮನವಿ"
#: ../js/ui/status/bluetooth.js:453
msgid "Please enter the PIN mentioned on the device."
@ -912,7 +918,7 @@ msgstr "ಹುಡುಕಲು ನಮೂದಿಸು..."
#: ../js/ui/windowAttentionHandler.js:43
#, c-format
msgid "%s has finished starting"
msgstr ""
msgstr "ಆರಂಭಗೊಳಿಸುವುದನ್ನು %s ಪೂರ್ಣಗೊಳಿಸಿದ್ದಾರೆ"
#: ../js/ui/windowAttentionHandler.js:45
#, c-format
@ -925,8 +931,8 @@ msgstr "'%s' ಸಿದ್ಧಗೊಂಡಿದೆ"
#, c-format
msgid "%u Output"
msgid_plural "%u Outputs"
msgstr[0] ""
msgstr[1] ""
msgstr[0] "%u ಔಟ್‌ಪುಟ್"
msgstr[1] "%u ಔಟ್‌ಪುಟ್‌ಗಳು"
#. translators:
#. * The number of sound inputs on a particular device
@ -934,8 +940,8 @@ msgstr[1] ""
#, c-format
msgid "%u Input"
msgid_plural "%u Inputs"
msgstr[0] ""
msgstr[1] ""
msgstr[0] "%u ಇನ್‌ಪುಟ್"
msgstr[1] "%u ಇನ್‌ಪುಟ್‌ಗಳು"
#: ../src/gvc/gvc-mixer-control.c:1402
msgid "System Sounds"
@ -943,7 +949,7 @@ msgstr "ವ್ಯವಸ್ಥೆಯ ಧ್ವನಿಗಳು"
#: ../src/shell-global.c:1363
msgid "Less than a minute ago"
msgstr ""
msgstr "ಒಂದು ನಿಮಿಷಕ್ಕೂ ಹಿಂದೆ"
#: ../src/shell-global.c:1367
#, c-format

588
po/ko.po

File diff suppressed because it is too large Load Diff

1289
po/lt.po

File diff suppressed because it is too large Load Diff

1244
po/lv.po Normal file

File diff suppressed because it is too large Load Diff

1197
po/mr.po Normal file

File diff suppressed because it is too large Load Diff

475
po/nb.po
View File

@ -8,8 +8,8 @@ msgid ""
msgstr ""
"Project-Id-Version: gnome-shell 2.91.x\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2011-03-06 13:39+0100\n"
"PO-Revision-Date: 2011-03-06 13:40+0100\n"
"POT-Creation-Date: 2011-04-01 09:43+0200\n"
"PO-Revision-Date: 2011-04-01 09:45+0200\n"
"Last-Translator: Kjartan Maraas <kmaraas@gnome.org>\n"
"Language-Team: Norwegian Bokmål <i18n-nb@lister.ping.uio.no>\n"
"Language: \n"
@ -55,7 +55,7 @@ msgstr ""
#: ../data/org.gnome.shell.gschema.xml.in.h:6
msgid "History for command (Alt-F2) dialog"
msgstr ""
msgstr "Historikk for kommandodialog (Alt-F2)"
#: ../data/org.gnome.shell.gschema.xml.in.h:7
msgid "History for the looking glass dialog"
@ -67,7 +67,7 @@ msgstr ""
#: ../data/org.gnome.shell.gschema.xml.in.h:9
msgid "If true, display seconds in time."
msgstr ""
msgstr "Viser sekunder i klokken hvis «true»."
#: ../data/org.gnome.shell.gschema.xml.in.h:10
msgid "If true, display the ISO week date in the calendar."
@ -145,49 +145,45 @@ msgstr "Om det skal samles statistikk om bruk av programmer"
#: ../data/org.gnome.shell.gschema.xml.in.h:24
msgid "disabled OpenSearch providers"
msgstr ""
msgstr "OpenSearch tilbydere slått av"
#: ../js/misc/util.js:86
#: ../js/misc/util.js:71
msgid "Command not found"
msgstr "Kommando ikke funnet"
#. Replace "Error invoking GLib.shell_parse_argv: " with
#. something nicer
#: ../js/misc/util.js:113
#: ../js/misc/util.js:98
msgid "Could not parse command:"
msgstr "Klarte ikke å lese kommando:"
#: ../js/misc/util.js:135
msgid "No such application"
msgstr "Programmet finnes ikke"
#: ../js/misc/util.js:148
#: ../js/misc/util.js:106
#, c-format
msgid "Execution of '%s' failed:"
msgstr "Kjøring av «%s» feilet:"
#. Translators: Filter to display all applications
#: ../js/ui/appDisplay.js:195
#: ../js/ui/appDisplay.js:230
msgid "All"
msgstr "Alle"
#: ../js/ui/appDisplay.js:285
#: ../js/ui/appDisplay.js:328
msgid "APPLICATIONS"
msgstr "PROGRAMMER"
#: ../js/ui/appDisplay.js:311
#: ../js/ui/appDisplay.js:354
msgid "SETTINGS"
msgstr "INNSTILLINGER"
#: ../js/ui/appDisplay.js:565
#: ../js/ui/appDisplay.js:625
msgid "New Window"
msgstr "Nytt vindu"
#: ../js/ui/appDisplay.js:568
#: ../js/ui/appDisplay.js:628
msgid "Remove from Favorites"
msgstr "Fjern fra favoritter"
#: ../js/ui/appDisplay.js:569
#: ../js/ui/appDisplay.js:629
msgid "Add to Favorites"
msgstr "Legg til i favoritter"
@ -320,13 +316,13 @@ msgid "Nothing Scheduled"
msgstr "Ingenting planlagt"
#. Translators: Shown on calendar heading when selected day occurs on current year
#: ../js/ui/calendar.js:720
#: ../js/ui/calendar.js:720 ../js/ui/telepathyClient.js:490
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:723
#: ../js/ui/calendar.js:723 ../js/ui/telepathyClient.js:493
msgctxt "calendar heading"
msgid "%A, %B %d, %Y"
msgstr "%A %B %d, %Y"
@ -347,7 +343,7 @@ msgstr "Denne uken"
msgid "Next week"
msgstr "Neste uke"
#: ../js/ui/dash.js:174
#: ../js/ui/dash.js:174 ../js/ui/messageTray.js:1007
msgid "Remove"
msgstr "Fjern"
@ -355,54 +351,54 @@ msgstr "Fjern"
msgid "Date and Time Settings"
msgstr "Innstillinger for dato og klokkeslett"
#: ../js/ui/dateMenu.js:110
#: ../js/ui/dateMenu.js:111
msgid "Open Calendar"
msgstr "Åpne kalender"
#. Translators: This is the time format with date used
#. in 24-hour mode.
#: ../js/ui/dateMenu.js:162
#: ../js/ui/dateMenu.js:164
msgid "%a %b %e, %R:%S"
msgstr "%a %e %b, %R.%S"
#: ../js/ui/dateMenu.js:163
#: ../js/ui/dateMenu.js:165
msgid "%a %b %e, %R"
msgstr "%a %e %b, %R"
#. Translators: This is the time format without date used
#. in 24-hour mode.
#: ../js/ui/dateMenu.js:167
#: ../js/ui/dateMenu.js:169
msgid "%a %R:%S"
msgstr "%a %R.%S"
#: ../js/ui/dateMenu.js:168
#: ../js/ui/dateMenu.js:170
msgid "%a %R"
msgstr "%a %R"
#. Translators: This is a time format with date used
#. for AM/PM.
#: ../js/ui/dateMenu.js:175
#: ../js/ui/dateMenu.js:177
msgid "%a %b %e, %l:%M:%S %p"
msgstr "%a %e %b, %l.%M.%S %p"
#: ../js/ui/dateMenu.js:176
#: ../js/ui/dateMenu.js:178
msgid "%a %b %e, %l:%M %p"
msgstr "%a %e %b, %l.%M %p"
#. Translators: This is a time format without date used
#. for AM/PM.
#: ../js/ui/dateMenu.js:180
#: ../js/ui/dateMenu.js:182
msgid "%a %l:%M:%S %p"
msgstr "%a %l.%M.%S %p"
#: ../js/ui/dateMenu.js:181
#: ../js/ui/dateMenu.js:183
msgid "%a %l:%M %p"
msgstr "%a %l.%M %p"
#. 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:207
#: ../js/ui/dateMenu.js:194
msgid "%A %B %e, %Y"
msgstr "%a %e %B, %Y"
@ -415,7 +411,7 @@ msgstr "SISTE OPPFØRINGER"
msgid "Log Out %s"
msgstr "Logg ut %s"
#: ../js/ui/endSessionDialog.js:64 ../js/ui/endSessionDialog.js:69
#: ../js/ui/endSessionDialog.js:64 ../js/ui/endSessionDialog.js:70
msgid "Log Out"
msgstr "Logg ut"
@ -438,47 +434,46 @@ msgstr "Du vil bli logget ut automatisk om %d sekunder."
msgid "Logging out of the system."
msgstr "Logger ut av systemet"
#: ../js/ui/endSessionDialog.js:74 ../js/ui/endSessionDialog.js:78
msgid "Shut Down"
msgstr "Avslutt"
#: ../js/ui/endSessionDialog.js:75
msgid "Click Shut Down to quit these applications and shut down the system."
msgstr "Klikk Avslutt for å avslutte disse programmene og stenge ned systemet."
#: ../js/ui/endSessionDialog.js:75 ../js/ui/endSessionDialog.js:82
msgid "Power Off"
msgstr "Slå av"
#: ../js/ui/endSessionDialog.js:76
#, c-format
msgid "The system will shut down automatically in %d seconds."
msgstr "Systemet vil ss av automatisk om %d sekunder."
msgid "Click Power Off to quit these applications and power off the system."
msgstr ""
"Klikk «Slå av» for å avslutte disse programmene og logge ut av systemet."
#: ../js/ui/endSessionDialog.js:77
msgid "Shutting down the system."
#, c-format
msgid "The system will power off automatically in %d seconds."
msgstr "Systemet vil slås av automatisk om %d sekunder."
#: ../js/ui/endSessionDialog.js:78
msgid "Powering off the system."
msgstr "Slår av systemet."
#: ../js/ui/endSessionDialog.js:84 ../js/ui/endSessionDialog.js:88
#: ../js/ui/endSessionDialog.js:80 ../js/ui/endSessionDialog.js:88
#: ../js/ui/endSessionDialog.js:93
msgid "Restart"
msgstr "Start på nytt"
#: ../js/ui/endSessionDialog.js:85
#: ../js/ui/endSessionDialog.js:89
msgid "Click Restart to quit these applications and restart the system."
msgstr ""
"Klikk Start på nytt for å avslutte disse programmene og starte systemet på "
"nytt."
#: ../js/ui/endSessionDialog.js:86
#: ../js/ui/endSessionDialog.js:90
#, c-format
msgid "The system will restart automatically in %d seconds."
msgstr "Systemet vil starte på nytt automatisk om %d sekunder."
#: ../js/ui/endSessionDialog.js:87
#: ../js/ui/endSessionDialog.js:91
msgid "Restarting the system."
msgstr "Starter systemet på nytt."
#: ../js/ui/endSessionDialog.js:395
msgid "Confirm"
msgstr "Bekreft"
#: ../js/ui/endSessionDialog.js:400 ../js/ui/status/bluetooth.js:470
#: ../js/ui/endSessionDialog.js:415 ../js/ui/polkitAuthenticationAgent.js:172
#: ../js/ui/status/bluetooth.js:466
msgid "Cancel"
msgstr "Avbryt"
@ -492,7 +487,7 @@ msgstr "Aktivert"
#. translators:
#. * The device has been disabled
#: ../js/ui/lookingGlass.js:627 ../src/gvc/gvc-mixer-control.c:1087
#: ../js/ui/lookingGlass.js:627 ../src/gvc/gvc-mixer-control.c:1091
msgid "Disabled"
msgstr "Deaktivert"
@ -512,34 +507,48 @@ msgstr "Vis kildekode"
msgid "Web Page"
msgstr "Nettside"
#: ../js/ui/messageTray.js:1907
#: ../js/ui/messageTray.js:1000
msgid "Open"
msgstr "Åpne"
#: ../js/ui/messageTray.js:2164
msgid "System Information"
msgstr "Systeminformasjon"
#: ../js/ui/overview.js:88
#: ../js/ui/overview.js:91
msgid "Undo"
msgstr "Angre"
#: ../js/ui/overview.js:183
#: ../js/ui/overview.js:186
msgid "Windows"
msgstr "Vinduer"
#: ../js/ui/overview.js:186
#: ../js/ui/overview.js:189
msgid "Applications"
msgstr "Programmer"
#. Translators: this is the name of the dock/favorites area on
#. the left of the overview
#: ../js/ui/overview.js:205
msgid "Dash"
msgstr "Favoritter"
#. TODO - _quit() doesn't really work on apps in state STARTING yet
#: ../js/ui/panel.js:531
#: ../js/ui/panel.js:524
#, c-format
msgid "Quit %s"
msgstr "Avslutt %s"
#. Button on the left side of the panel.
#. Translators: If there is no suitable word for "Activities" in your language, you can use the word for "Overview".
#: ../js/ui/panel.js:892
#: ../js/ui/panel.js:902
msgid "Activities"
msgstr "Aktiviteter"
#: ../js/ui/panel.js:1003
msgid "Top Bar"
msgstr "Topp-panel"
#: ../js/ui/placeDisplay.js:122
#, c-format
msgid "Failed to unmount '%s'"
@ -553,64 +562,89 @@ msgstr "Prøv igjen"
msgid "Connect to..."
msgstr "Koble til …"
#: ../js/ui/placeDisplay.js:409
#: ../js/ui/placeDisplay.js:380
msgid "PLACES & DEVICES"
msgstr "STEDER & ENHETER"
#: ../js/ui/polkitAuthenticationAgent.js:74
msgid "Authentication Required"
msgstr "Autentisering kreves"
#: ../js/ui/polkitAuthenticationAgent.js:108
msgid "Administrator"
msgstr "Administrator"
#: ../js/ui/polkitAuthenticationAgent.js:176
msgid "Authenticate"
msgstr "Autentiser"
#. Translators: "that didn't work" refers to the fact that the
#. * requested authentication was not gained; this can happen
#. * because of an authentication error (like invalid password),
#. * for instance.
#: ../js/ui/polkitAuthenticationAgent.js:264
msgid "Sorry, that didn't work. Please try again."
msgstr "Beklager, det virket ikke. Vennligst prøv igjen."
#: ../js/ui/polkitAuthenticationAgent.js:276
msgid "Password:"
msgstr "Passord:"
#. Translators: this MUST be either "toggle-switch-us"
#. (for toggle switches containing the English words
#. "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:612
#: ../js/ui/popupMenu.js:679
msgid "toggle-switch-us"
msgstr "toggle-switch-intl"
#: ../js/ui/runDialog.js:201
#: ../js/ui/runDialog.js:205
msgid "Please enter a command:"
msgstr "Oppgi en kommando:"
#: ../js/ui/searchDisplay.js:283
#: ../js/ui/searchDisplay.js:310
msgid "Searching..."
msgstr "Søker …"
#: ../js/ui/searchDisplay.js:297
#: ../js/ui/searchDisplay.js:324
msgid "No matching results."
msgstr "Ingen treff."
#: ../js/ui/statusMenu.js:102 ../js/ui/statusMenu.js:166
#: ../js/ui/statusMenu.js:161 ../js/ui/statusMenu.js:163
#: ../js/ui/statusMenu.js:228
msgid "Power Off..."
msgstr "Slå av …"
#: ../js/ui/statusMenu.js:104 ../js/ui/statusMenu.js:165
#: ../js/ui/statusMenu.js:163 ../js/ui/statusMenu.js:227
msgid "Suspend"
msgstr "Hvilemodus"
#: ../js/ui/statusMenu.js:125
#: ../js/ui/statusMenu.js:184
msgid "Available"
msgstr "Tilgjengelig"
#: ../js/ui/statusMenu.js:130
#: ../js/ui/statusMenu.js:189
msgid "Busy"
msgstr "Opptatt"
#: ../js/ui/statusMenu.js:138
#: ../js/ui/statusMenu.js:197
msgid "My Account"
msgstr "Min konto"
#: ../js/ui/statusMenu.js:142
#: ../js/ui/statusMenu.js:201
msgid "System Settings"
msgstr "Systeminnstillinger"
#: ../js/ui/statusMenu.js:149
#: ../js/ui/statusMenu.js:208
msgid "Lock Screen"
msgstr "Lås skjerm"
#: ../js/ui/statusMenu.js:153
#: ../js/ui/statusMenu.js:213
msgid "Switch User"
msgstr "Bytt bruker"
#: ../js/ui/statusMenu.js:158
#: ../js/ui/statusMenu.js:218
msgid "Log Out..."
msgstr "Logg ut …"
@ -618,14 +652,12 @@ msgstr "Logg ut …"
msgid "Zoom"
msgstr "Zoom"
#: ../js/ui/status/accessibility.js:69
msgid "Screen Reader"
msgstr "Skjermleser"
#: ../js/ui/status/accessibility.js:73
msgid "Screen Keyboard"
msgstr "Tastatur på skjermen"
#. let screenReader = this._buildItem(_("Screen Reader"), APPLICATIONS_SCHEMA,
#. 'screen-reader-enabled');
#. this.menu.addMenuItem(screenReader);
#. let screenKeyboard = this._buildItem(_("Screen Keyboard"), APPLICATIONS_SCHEMA,
#. 'screen-keyboard-enabled');
#. this.menu.addMenuItem(screenKeyboard);
#: ../js/ui/status/accessibility.js:77
msgid "Visual Alerts"
msgstr "Synlig varsling"
@ -650,17 +682,17 @@ msgstr "Mustaster"
msgid "Universal Access Settings"
msgstr "Innstillinger for tilgjengelighet"
#: ../js/ui/status/accessibility.js:145
#: ../js/ui/status/accessibility.js:146
msgid "High Contrast"
msgstr "Høy kontrast"
#: ../js/ui/status/accessibility.js:182
#: ../js/ui/status/accessibility.js:183
msgid "Large Text"
msgstr "Stor tekst"
#: ../js/ui/status/bluetooth.js:42 ../js/ui/status/bluetooth.js:241
#: ../js/ui/status/bluetooth.js:337 ../js/ui/status/bluetooth.js:371
#: ../js/ui/status/bluetooth.js:411 ../js/ui/status/bluetooth.js:444
#: ../js/ui/status/bluetooth.js:42 ../js/ui/status/bluetooth.js:237
#: ../js/ui/status/bluetooth.js:333 ../js/ui/status/bluetooth.js:367
#: ../js/ui/status/bluetooth.js:407 ../js/ui/status/bluetooth.js:440
msgid "Bluetooth"
msgstr "Bluetooth"
@ -680,94 +712,94 @@ msgstr "Sett opp en ny enhet …"
msgid "Bluetooth Settings"
msgstr "Innstillinger for Bluetooth"
#: ../js/ui/status/bluetooth.js:192
#: ../js/ui/status/bluetooth.js:188
msgid "Connection"
msgstr "Tilkobling"
#: ../js/ui/status/bluetooth.js:228
#: ../js/ui/status/bluetooth.js:224
msgid "Send Files..."
msgstr "Send filer …"
#: ../js/ui/status/bluetooth.js:233
#: ../js/ui/status/bluetooth.js:229
msgid "Browse Files..."
msgstr "Bla gjennom filer …"
#: ../js/ui/status/bluetooth.js:242
#: ../js/ui/status/bluetooth.js:238
msgid "Error browsing device"
msgstr "Feil under lesing av enhet"
#: ../js/ui/status/bluetooth.js:243
#: ../js/ui/status/bluetooth.js:239
#, c-format
msgid "The requested device cannot be browsed, error is '%s'"
msgstr "Kan ikke bla gjennom forespurt enhet. Feilen er «%s»"
#: ../js/ui/status/bluetooth.js:251
#: ../js/ui/status/bluetooth.js:247
msgid "Keyboard Settings"
msgstr "Innstillinger for tastatur"
#: ../js/ui/status/bluetooth.js:256
#: ../js/ui/status/bluetooth.js:252
msgid "Mouse Settings"
msgstr "Innstillinger for mus"
#: ../js/ui/status/bluetooth.js:263 ../js/ui/status/volume.js:65
#: ../js/ui/status/bluetooth.js:259 ../js/ui/status/volume.js:66
msgid "Sound Settings"
msgstr "Innstillinger for lyd"
#: ../js/ui/status/bluetooth.js:372
#: ../js/ui/status/bluetooth.js:368
#, c-format
msgid "Authorization request from %s"
msgstr "Forespørsel om autorisering fra %s"
#: ../js/ui/status/bluetooth.js:378
#: ../js/ui/status/bluetooth.js:374
#, c-format
msgid "Device %s wants access to the service '%s'"
msgstr "Enhet %s vil ha tilgang til tjenesten «%s»"
#: ../js/ui/status/bluetooth.js:380
#: ../js/ui/status/bluetooth.js:376
msgid "Always grant access"
msgstr "Alltid gi tilgang"
#: ../js/ui/status/bluetooth.js:381
#: ../js/ui/status/bluetooth.js:377
msgid "Grant this time only"
msgstr "Gi tilgang kun denne ene gangen"
#: ../js/ui/status/bluetooth.js:382
#: ../js/ui/status/bluetooth.js:378
msgid "Reject"
msgstr "Avvis"
#: ../js/ui/status/bluetooth.js:412
#: ../js/ui/status/bluetooth.js:408
#, c-format
msgid "Pairing confirmation for %s"
msgstr "Bekreftelse for tilkobling for %s"
#: ../js/ui/status/bluetooth.js:418 ../js/ui/status/bluetooth.js:452
#: ../js/ui/status/bluetooth.js:414 ../js/ui/status/bluetooth.js:448
#, c-format
msgid "Device %s wants to pair with this computer"
msgstr "Enhet %s vil koble seg sammen med denne datamaskinen"
#: ../js/ui/status/bluetooth.js:419
#: ../js/ui/status/bluetooth.js:415
#, c-format
msgid "Please confirm whether the PIN '%s' matches the one on the device."
msgstr "Vennligst bekreft om PIN «%s» er lik den som brukes på enheten."
#: ../js/ui/status/bluetooth.js:421
#: ../js/ui/status/bluetooth.js:417
msgid "Matches"
msgstr "Stemmer overens"
#: ../js/ui/status/bluetooth.js:422
#: ../js/ui/status/bluetooth.js:418
msgid "Does not match"
msgstr "Stemmer ikke overens"
#: ../js/ui/status/bluetooth.js:445
#: ../js/ui/status/bluetooth.js:441
#, c-format
msgid "Pairing request for %s"
msgstr "Forespørsel om tilkobling for %s"
#: ../js/ui/status/bluetooth.js:453
#: ../js/ui/status/bluetooth.js:449
msgid "Please enter the PIN mentioned on the device."
msgstr "Vennligst oppgi PIN som oppgitt på enheten."
#: ../js/ui/status/bluetooth.js:469
#: ../js/ui/status/bluetooth.js:465
msgid "OK"
msgstr "OK"
@ -779,17 +811,153 @@ msgstr "Vis tastaturutforming …"
msgid "Localization Settings"
msgstr "Innstillinger for lokalisering"
#: ../js/ui/status/network.js:104 ../js/ui/status/network.js:1454
msgid "<unknown>"
msgstr "<ukjent>"
#. Translators: this indicates that wireless or wwan is disabled by hardware killswitch
#: ../js/ui/status/network.js:311
msgid "disabled"
msgstr "slått av"
#: ../js/ui/status/network.js:494
msgid "connecting..."
msgstr "kobler til …"
#. Translators: this is for network connections that require some kind of key or password
#: ../js/ui/status/network.js:497
msgid "authentication required"
msgstr "autentisering kreves"
#. Translators: this is for devices that require some kind of firmware or kernel
#. module, which is missing
#: ../js/ui/status/network.js:507
msgid "firmware missing"
msgstr "fastvare mangler"
#. Translators: this is for wired network devices that are physically disconnected
#: ../js/ui/status/network.js:514
msgid "cable unplugged"
msgstr "kabel koblet fra"
#. Translators: this is for a network device that cannot be activated (for example it
#. is disabled by rfkill, or it has no coverage
#: ../js/ui/status/network.js:519
msgid "unavailable"
msgstr "ikke tilgjengelig"
#: ../js/ui/status/network.js:521
msgid "connection failed"
msgstr "tilkobling feilet"
#. TRANSLATORS: this is the indication that a connection for another logged in user is active,
#. and we cannot access its settings (including the name)
#: ../js/ui/status/network.js:602 ../js/ui/status/network.js:1402
msgid "Connected (private)"
msgstr "Tilkoblet (privat)"
#: ../js/ui/status/network.js:683
msgid "Auto Ethernet"
msgstr "Automatisk Ethernet"
#: ../js/ui/status/network.js:758
msgid "Auto broadband"
msgstr "Automatisk bredbånd"
#: ../js/ui/status/network.js:761
msgid "Auto dial-up"
msgstr "Automatisk oppringt"
#. TRANSLATORS: this the automatic wireless connection name (including the network name)
#: ../js/ui/status/network.js:904 ../js/ui/status/network.js:1414
#, c-format
msgid "Auto %s"
msgstr "Automatisk %s"
#: ../js/ui/status/network.js:906
msgid "Auto bluetooth"
msgstr "Automatisk Bluetooth"
#: ../js/ui/status/network.js:1416
msgid "Auto wireless"
msgstr "Automatisk trådløst"
#: ../js/ui/status/network.js:1474
msgid "More..."
msgstr "Mer …"
#: ../js/ui/status/network.js:1497
msgid "Enable networking"
msgstr "Slå på nettverk"
#: ../js/ui/status/network.js:1509
msgid "Wired"
msgstr "Kablet"
#: ../js/ui/status/network.js:1520
msgid "Wireless"
msgstr "Trådløst"
#: ../js/ui/status/network.js:1530
msgid "Mobile broadband"
msgstr "Mobilt bredbånd"
#: ../js/ui/status/network.js:1540
msgid "VPN Connections"
msgstr "VPN-tilkoblinger"
#: ../js/ui/status/network.js:1549
msgid "Network Settings"
msgstr "Innstillinger for nettverk"
#: ../js/ui/status/network.js:1844
#, c-format
msgid "You're now connected to mobile broadband connection '%s'"
msgstr "Du er nå koblet til mobil bredbåndstilkobling «%s»"
#: ../js/ui/status/network.js:1848
#, c-format
msgid "You're now connected to wireless network '%s'"
msgstr "Du er nå koblet til trådløst nettverk «%s»"
#: ../js/ui/status/network.js:1852
#, c-format
msgid "You're now connected to wired network '%s'"
msgstr "Du er nå koblet til kablet nettverk «%s»"
#: ../js/ui/status/network.js:1856
#, c-format
msgid "You're now connected to VPN network '%s'"
msgstr "Du er nå koblet til virtuelt privat nettverk «%s»"
#: ../js/ui/status/network.js:1861
#, c-format
msgid "You're now connected to '%s'"
msgstr "Du er nå koblet til «%s»"
#: ../js/ui/status/network.js:1869
msgid "Connection established"
msgstr "Tilkobling etablert"
#: ../js/ui/status/network.js:1991
msgid "Networking is disabled"
msgstr "Nettverk er slått av"
#: ../js/ui/status/network.js:2116
msgid "Network Manager"
msgstr "Nettverkshåndtering"
#: ../js/ui/status/power.js:85
msgid "Power Settings"
msgstr "Innstillinger for strøm"
#. 0 is reported when UPower does not have enough data
#. to estimate battery life
#: ../js/ui/status/power.js:110
#: ../js/ui/status/power.js:111
msgid "Estimating..."
msgstr "Estimerer …"
#: ../js/ui/status/power.js:117
#: ../js/ui/status/power.js:118
#, c-format
msgid "%d hour remaining"
msgid_plural "%d hours remaining"
@ -797,102 +965,102 @@ msgstr[0] "%d time gjenstår"
msgstr[1] "%d timer gjenstår"
#. TRANSLATORS: this is a time string, as in "%d hours %d minutes remaining"
#: ../js/ui/status/power.js:120
#: ../js/ui/status/power.js:121
#, c-format
msgid "%d %s %d %s remaining"
msgstr "%d %s %d %s gjenstår"
#: ../js/ui/status/power.js:122
#: ../js/ui/status/power.js:123
msgid "hour"
msgid_plural "hours"
msgstr[0] "time"
msgstr[1] "timer"
#: ../js/ui/status/power.js:122
#: ../js/ui/status/power.js:123
msgid "minute"
msgid_plural "minutes"
msgstr[0] "minutt"
msgstr[1] "minutter"
#: ../js/ui/status/power.js:125
#: ../js/ui/status/power.js:126
#, c-format
msgid "%d minute remaining"
msgid_plural "%d minutes remaining"
msgstr[0] "%d minutt gjenstår"
msgstr[1] "%d minutter gjenstår"
#: ../js/ui/status/power.js:227
#: ../js/ui/status/power.js:228
msgid "AC adapter"
msgstr "Strømadapter"
#: ../js/ui/status/power.js:229
#: ../js/ui/status/power.js:230
msgid "Laptop battery"
msgstr "Batteri på bærbar"
#: ../js/ui/status/power.js:231
#: ../js/ui/status/power.js:232
msgid "UPS"
msgstr "UPS"
#: ../js/ui/status/power.js:233
#: ../js/ui/status/power.js:234
msgid "Monitor"
msgstr "Skjerm"
#: ../js/ui/status/power.js:235
#: ../js/ui/status/power.js:236
msgid "Mouse"
msgstr "Mus"
#: ../js/ui/status/power.js:237
#: ../js/ui/status/power.js:238
msgid "Keyboard"
msgstr "Tastatur"
#: ../js/ui/status/power.js:239
#: ../js/ui/status/power.js:240
msgid "PDA"
msgstr "PDA"
#: ../js/ui/status/power.js:241
#: ../js/ui/status/power.js:242
msgid "Cell phone"
msgstr "Mobiltelefon"
#: ../js/ui/status/power.js:243
#: ../js/ui/status/power.js:244
msgid "Media player"
msgstr "Medieavspiller"
#: ../js/ui/status/power.js:245
#: ../js/ui/status/power.js:246
msgid "Tablet"
msgstr "Nettbrett"
#: ../js/ui/status/power.js:247
#: ../js/ui/status/power.js:248
msgid "Computer"
msgstr "Datamaskin"
#: ../js/ui/status/power.js:249 ../src/shell-app-system.c:1013
#: ../js/ui/status/power.js:250 ../src/shell-app-system.c:1088
msgid "Unknown"
msgstr "Ukjent"
#: ../js/ui/status/volume.js:44
#: ../js/ui/status/volume.js:45
msgid "Volume"
msgstr "Volum"
#: ../js/ui/status/volume.js:57
#: ../js/ui/status/volume.js:58
msgid "Microphone"
msgstr "Mikrofon"
#: ../js/ui/telepathyClient.js:239
#: ../js/ui/telepathyClient.js:335
#, c-format
msgid "%s is online."
msgstr "%s er tilkoblet."
#: ../js/ui/telepathyClient.js:244
#: ../js/ui/telepathyClient.js:340
#, c-format
msgid "%s is offline."
msgstr "%s er frakoblet."
#: ../js/ui/telepathyClient.js:247
#: ../js/ui/telepathyClient.js:343
#, c-format
msgid "%s is away."
msgstr "«%s» er borte."
#: ../js/ui/telepathyClient.js:250
#: ../js/ui/telepathyClient.js:346
#, c-format
msgid "%s is busy."
msgstr "%s er opptatt."
@ -900,7 +1068,7 @@ msgstr "%s er opptatt."
#. Translators: this is a time format string followed by a date.
#. If applicable, replace %X with a strftime format valid for your
#. locale, without seconds.
#: ../js/ui/telepathyClient.js:348
#: ../js/ui/telepathyClient.js:482
#, no-c-format
msgid "Sent at %X on %A"
msgstr "Sendt %X på %A"
@ -909,10 +1077,14 @@ msgstr "Sendt %X på %A"
#. in the search entry when no search is
#. active; it should not exceed ~30
#. characters.
#: ../js/ui/viewSelector.js:103
#: ../js/ui/viewSelector.js:122
msgid "Type to search..."
msgstr "Skriv for å søke …"
#: ../js/ui/viewSelector.js:142 ../src/shell-util.c:250
msgid "Search"
msgstr "Søk"
#: ../js/ui/windowAttentionHandler.js:42
#, c-format
msgid "%s has finished starting"
@ -925,7 +1097,7 @@ msgstr "«%s» er klar"
#. translators:
#. * The number of sound outputs on a particular device
#: ../src/gvc/gvc-mixer-control.c:1094
#: ../src/gvc/gvc-mixer-control.c:1098
#, c-format
msgid "%u Output"
msgid_plural "%u Outputs"
@ -934,49 +1106,66 @@ msgstr[1] "%u utganger"
#. translators:
#. * The number of sound inputs on a particular device
#: ../src/gvc/gvc-mixer-control.c:1104
#: ../src/gvc/gvc-mixer-control.c:1108
#, c-format
msgid "%u Input"
msgid_plural "%u Inputs"
msgstr[0] "%u inngang"
msgstr[1] "%u innganger"
#: ../src/gvc/gvc-mixer-control.c:1402
#: ../src/gvc/gvc-mixer-control.c:1406
msgid "System Sounds"
msgstr "Systemlyder"
#: ../src/shell-global.c:1298
#: ../src/main.c:446
msgid "Print version"
msgstr "Skriv ut versjon"
#: ../src/shell-app.c:454
#, c-format
msgid "Failed to launch '%s'"
msgstr "Klarte ikke å starte «%s»"
#: ../src/shell-global.c:1395
msgid "Less than a minute ago"
msgstr "Mindre enn ett minutt siden"
#: ../src/shell-global.c:1302
#: ../src/shell-global.c:1399
#, c-format
msgid "%d minute ago"
msgid_plural "%d minutes ago"
msgstr[0] "%d minutt siden"
msgstr[1] "%d minutter siden"
#: ../src/shell-global.c:1307
#: ../src/shell-global.c:1404
#, c-format
msgid "%d hour ago"
msgid_plural "%d hours ago"
msgstr[0] "%d time siden"
msgstr[1] "%d timer siden"
#: ../src/shell-global.c:1312
#: ../src/shell-global.c:1409
#, c-format
msgid "%d day ago"
msgid_plural "%d days ago"
msgstr[0] "%d dag siden"
msgstr[1] "%d dager siden"
#: ../src/shell-global.c:1317
#: ../src/shell-global.c:1414
#, c-format
msgid "%d week ago"
msgid_plural "%d weeks ago"
msgstr[0] "%d uke siden"
msgstr[1] "%d uker siden"
#: ../src/shell-mobile-providers.c:80
msgid "United Kingdom"
msgstr "England"
#: ../src/shell-mobile-providers.c:526
msgid "Default"
msgstr "Forvalg"
#: ../src/shell-polkit-authentication-agent.c:334
msgid "Authentication dialog was dismissed by the user"
msgstr "Autentiseringsdialogen ble lukket av brukeren"
@ -991,10 +1180,6 @@ msgstr "Hjemmemappe"
msgid "File System"
msgstr "Filsystem"
#: ../src/shell-util.c:250
msgid "Search"
msgstr "Søk"
#. Translators: the first string is the name of a gvfs
#. * method, and the second string is a path. For
#. * example, "Trash: some-directory". It means that the

699
po/nl.po

File diff suppressed because it is too large Load Diff

479
po/pa.po
View File

@ -6,9 +6,9 @@ msgid ""
msgstr ""
"Project-Id-Version: gnome-shell master\n"
"Report-Msgid-Bugs-To: http://bugzilla.gnome.org/enter_bug."
"cgi?product=gnome-shell&component=general\n"
"POT-Creation-Date: 2011-03-07 16:15+0000\n"
"PO-Revision-Date: 2011-03-08 08:27+0530\n"
"cgi?product=gnome-shell&keywords=I18N+L10N&component=general\n"
"POT-Creation-Date: 2011-03-25 20:20+0000\n"
"PO-Revision-Date: 2011-03-27 10:02+0530\n"
"Last-Translator: A S Alam <aalam@users.sf.net>\n"
"Language-Team: Punjabi/Panjabi <punjabi-users@lists.sf.net>\n"
"MIME-Version: 1.0\n"
@ -92,6 +92,20 @@ msgid ""
"records to WEBM using the VP8 codec. %T is used as a placeholder for a guess "
"at the optimal thread count on the system."
msgstr ""
"ਰਿਕਾਰਡਿੰਗ ਇੰਕੋਡ ਕਰਨ ਲਈ ਜੀਸਟੀਮਰ ਪਾਇਪਲਾਈਨ ਸੈੱਟ ਕਰੋ। ਇਹ gst-launch ਲਈ ਵਰਤਿਆ "
"ਜਾਂਦਾ ਸੰਟੈਕਸ ਵਰਤਦਾ ਹੈ। ਪਾਇਪਲਾਈਨ ਲਈ ਸਿੰਕ ਪੈਡ ਲਈ ਕੁਨੈਕਟ ਨਹੀਂ ਹੋਣਾ ਚਾਹੀਦਾ ਹੈ, "
"ਜਿੱਥੇ "
"ਰਿਕਾਰਡ ਹੋਣ ਵਾਲੀ ਵਿਡੀਓ ਰਿਕਾਰਡ ਕੀਤੀ ਜਾ ਰਹੀ ਹੈ। ਇਹ ਆਮ ਤੌਰ ਉੱਤੇ ਨਾ-ਕੁਨੈਕਟ ਕੀਤਾ "
"ਸਰੋਤ ਪੈਡ ਹੋਵੇਗਾ, ਉਸ ਪੈਡ ਤੋਂ ਆਉਟਪੁੱਟ ਨੂੰ ਆਉਟਪੁੱਟ ਫਾਇਲ ਵਿੱਚ ਲਿਖਿਆ ਜਾਵੇਗਾ। ਪਰ "
"ਪਾਈਪਲਾਈਨ ਖੁਦ ਦੀ ਆਉਟਪੁੱਟ ਦਾ ਧਿਆਨ ਵੀ ਰੱਖ ਸਕਦੀ ਹੈ - ਇਸ ਨਾਲ ਆਉਟਪੁੱਟ ਨੂੰ "
"icecast ਸਰਵਰ ਉੱਤੇ shout2send ਜਾਂ ਕਿਸੇ ਹੋਰ ਰਾਹੀਂ ਵੀ ਭੇਜਿਆ ਜਾ ਸਕਦਾ ਹੈ। ਜਦੋਂ "
"ਅਣ-ਸੈੱਟ "
"ਕੀਤਾ ਜਾਂ ਖਾਲੀ ਮੁੱਲ ਨਾਲ ਸੈੱਟ ਕੀਤਾ ਤਾਂ, ਡਿਫਾਲਟ ਪਾਈਪਲਾਈਨ ਵਰਤਿਆ ਜਾਂਦਾ ਹੈ। ਇਸ ਇਸ "
"ਵੇਲੇ "
"'videorate ! vp8enc quality=10 speed=2 threads=%T ! queue ! webmmux' ਹੈ ਅਤੇ "
"VP8 codec ਦੀ ਵਰਤੋਂ ਕਰਕੇ WEBM ਨਾਲ ਰਿਕਾਰਡ ਕੀਤਾ ਜਾਂਦਾ ਹੈ। %T ਸਿਸਟਮ ਉੱਤੇ ਢੁੱਕਵੀ "
"ਥਰਿੱਡ "
"ਗਿਣਤੀ ਦਾ ਅੰਦਾਜ਼ਾ ਲਗਾਉਣ ਲਈ ਵਰਤਿਆ ਜਾਂਦਾ ਹੈ।"
#: ../data/org.gnome.shell.gschema.xml.in.h:14
msgid "Show date in clock"
@ -164,47 +178,43 @@ msgstr "ਐਪਲੀਕੇਸ਼ਨ ਵਰਤੋਂ ਬਾਰੇ ਅੰਕੜੇ
msgid "disabled OpenSearch providers"
msgstr "ਓਪਨਸਰਚ ਉਪਲੱਬਧ ਕਰਵਾਉਣ ਵਾਲੇ ਬੰਦ ਹਨ"
#: ../js/misc/util.js:86
#: ../js/misc/util.js:71
msgid "Command not found"
msgstr "ਕਮਾਂਡ ਨਹੀਂ ਲੱਭੀ"
#. Replace "Error invoking GLib.shell_parse_argv: " with
#. something nicer
#: ../js/misc/util.js:113
#: ../js/misc/util.js:98
msgid "Could not parse command:"
msgstr "ਕਮਾਂਡ ਪਾਰਸ ਨਹੀਂ ਕੀਤੀ ਜਾ ਸਕੀ:"
#: ../js/misc/util.js:135
msgid "No such application"
msgstr "ਇੰਞ ਦੀ ਕੋਈ ਐਪਲੀਕੇਸ਼ਨ ਨਹੀਂ ਹੈ"
#: ../js/misc/util.js:148
#: ../js/misc/util.js:106
#, c-format
msgid "Execution of '%s' failed:"
msgstr "'%s' ਚਲਾਉਣ ਲਈ ਫੇਲ੍ਹ:"
#. Translators: Filter to display all applications
#: ../js/ui/appDisplay.js:226
#: ../js/ui/appDisplay.js:230
msgid "All"
msgstr "ਸਭ"
#: ../js/ui/appDisplay.js:324
#: ../js/ui/appDisplay.js:328
msgid "APPLICATIONS"
msgstr "ਐਪਲੀਕੇਸ਼ਨ"
#: ../js/ui/appDisplay.js:350
#: ../js/ui/appDisplay.js:354
msgid "SETTINGS"
msgstr "ਸੈਟਿੰਗ"
#: ../js/ui/appDisplay.js:612
#: ../js/ui/appDisplay.js:625
msgid "New Window"
msgstr "ਨਵੀਂ ਵਿੰਡੋ"
#: ../js/ui/appDisplay.js:615
#: ../js/ui/appDisplay.js:628
msgid "Remove from Favorites"
msgstr "ਪਸੰਦ ਵਿੱਚੋਂ ਹਟਾਓ"
#: ../js/ui/appDisplay.js:616
#: ../js/ui/appDisplay.js:629
msgid "Add to Favorites"
msgstr "ਪਸੰਦ 'ਚ ਸ਼ਾਮਲ ਕਰੋ"
@ -364,7 +374,7 @@ msgstr "ਇਹ ਹਫ਼ਤਾ"
msgid "Next week"
msgstr "ਹਫ਼ਤਾ ਅੱਗੇ"
#: ../js/ui/dash.js:174 ../js/ui/messageTray.js:933
#: ../js/ui/dash.js:174 ../js/ui/messageTray.js:994
msgid "Remove"
msgstr "ਹਟਾਓ"
@ -419,7 +429,7 @@ msgstr "%a %l:%M %p"
#. 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:209
#: ../js/ui/dateMenu.js:194
msgid "%A %B %e, %Y"
msgstr "%A, %e %B %Y"
@ -432,7 +442,7 @@ msgstr "ਤਾਜ਼ਾ ਆਈਟਮਾਂ"
msgid "Log Out %s"
msgstr "%s ਲਾਗਆਉਟ"
#: ../js/ui/endSessionDialog.js:64 ../js/ui/endSessionDialog.js:69
#: ../js/ui/endSessionDialog.js:64 ../js/ui/endSessionDialog.js:70
msgid "Log Out"
msgstr "ਲਾਗਆਉਟ"
@ -455,46 +465,44 @@ msgstr "ਤੁਹਾਨੂੰ %d ਸਕਿੰਟਾਂ ਵਿੱਚ ਆਟੋਮ
msgid "Logging out of the system."
msgstr "ਸਿਸਟਮ ਲਾਗ ਕੀਤਾ ਜਾ ਰਿਹਾ ਹੈ।"
#: ../js/ui/endSessionDialog.js:74 ../js/ui/endSessionDialog.js:78
msgid "Shut Down"
#: ../js/ui/endSessionDialog.js:75 ../js/ui/endSessionDialog.js:82
msgid "Power Off"
msgstr "ਬੰਦ ਕਰੋ"
#: ../js/ui/endSessionDialog.js:75
msgid "Click Shut Down to quit these applications and shut down the system."
msgstr "ਇਹ ਐਪਲੀਕੇਸ਼ਨ ਬੰਦ ਕਰਕੇ ਸਿਸਟਮ ਨੂੰ ਬੰਦ ਕਰਨ ਲਈ ਬੰਦ ਕਰੋ ਨੂੰ ਕਲਿੱਕ ਕਰੋ।"
#: ../js/ui/endSessionDialog.js:76
#, c-format
msgid "The system will shut down automatically in %d seconds."
msgstr "ਸਿਸਟਮ ਨੂੰ ਆਟੋਮੈਟਿਕ ਹੀ %d ਸਕਿੰਟਾਂ ਵਿੱਚ ਬੰਦ ਕੀਤਾ ਜਾਵੇਗਾ।"
msgid "Click Power Off to quit these applications and power off the system."
msgstr "ਇਹ ਐਪਲੀਕੇਸ਼ਨਾਂ ਬੰਦ ਕਰਨ ਅਤੇ ਸਿਸਟਮ ਨੂੰ ਬੰਦ ਕਰਨ ਲਈ ਬੰਦ ਕਰੋ ਨੂੰ ਕਲਿੱਕ ਕਰੋ।"
#: ../js/ui/endSessionDialog.js:77
msgid "Shutting down the system."
#, c-format
msgid "The system will power off automatically in %d seconds."
msgstr "ਸਿਸਟਮ ਨੂੰ ਆਟੋਮੈਟਿਕ ਹੀ %d ਸਕਿੰਟਾਂ ਵਿੱਚ ਬੰਦ ਹੋ ਜਾਵੇਗਾ।"
#: ../js/ui/endSessionDialog.js:78
msgid "Powering off the system."
msgstr "ਸਿਸਟਮ ਬੰਦ ਕੀਤਾ ਜਾ ਰਿਹਾ ਹੈ।"
#: ../js/ui/endSessionDialog.js:84 ../js/ui/endSessionDialog.js:88
#: ../js/ui/endSessionDialog.js:80 ../js/ui/endSessionDialog.js:88
#: ../js/ui/endSessionDialog.js:93
msgid "Restart"
msgstr "ਮੁੜ-ਚਾਲੂ ਕਰੋ"
#: ../js/ui/endSessionDialog.js:85
#: ../js/ui/endSessionDialog.js:89
msgid "Click Restart to quit these applications and restart the system."
msgstr ""
"ਇਹ ਐਪਲੀਕੇਸ਼ਨ ਬੰਦ ਕਰਨ ਤੇ ਸਿਸਟਮ ਨੂੰ ਮੁੜ-ਚਾਲੂ ਕਰਨ ਲਈ ਮੁੜ-ਚਾਲੂ ਕਰੋ ਨੂੰ ਕਲਿੱਕ ਕਰੋ।"
#: ../js/ui/endSessionDialog.js:86
#: ../js/ui/endSessionDialog.js:90
#, c-format
msgid "The system will restart automatically in %d seconds."
msgstr "ਸਿਸਟਮ ਨੂੰ ਆਟੋਮੈਟਿਕ ਹੀ %d ਸਕਿੰਟਾਂ ਵਿੱਚ ਮੁੜ-ਚਾਲੂ ਕੀਤਾ ਜਾ ਜਾਵੇਗਾ।"
#: ../js/ui/endSessionDialog.js:87
#: ../js/ui/endSessionDialog.js:91
msgid "Restarting the system."
msgstr "ਸਿਸਟਮ ਮੁੜ-ਚਾਲੂ ਕੀਤਾ ਜਾ ਰਿਹਾ ਹੈ।"
#: ../js/ui/endSessionDialog.js:395
msgid "Confirm"
msgstr "ਪੁਸ਼ਟੀ"
#: ../js/ui/endSessionDialog.js:400 ../js/ui/status/bluetooth.js:470
#: ../js/ui/endSessionDialog.js:415 ../js/ui/polkitAuthenticationAgent.js:172
#: ../js/ui/status/bluetooth.js:466
msgid "Cancel"
msgstr "ਰੱਦ ਕਰੋ"
@ -508,7 +516,7 @@ msgstr "ਚਾਲੂ ਹੈ"
#. translators:
#. * The device has been disabled
#: ../js/ui/lookingGlass.js:627 ../src/gvc/gvc-mixer-control.c:1087
#: ../js/ui/lookingGlass.js:627 ../src/gvc/gvc-mixer-control.c:1091
msgid "Disabled"
msgstr "ਬੰਦ ਹੈ"
@ -528,48 +536,47 @@ msgstr "ਸਰੋਤ ਵੇਖੋ"
msgid "Web Page"
msgstr "ਵੈੱਬ ਪੇਜ਼"
#: ../js/ui/messageTray.js:926
#: ../js/ui/messageTray.js:987
msgid "Open"
msgstr "ਖੋਲ੍ਹੋ"
#: ../js/ui/messageTray.js:1963
#: ../js/ui/messageTray.js:2145
msgid "System Information"
msgstr "ਸਿਸਟਮ ਜਾਣਕਾਰੀ"
#: ../js/ui/overview.js:88
#: ../js/ui/overview.js:91
msgid "Undo"
msgstr "ਵਾਪਸ"
#: ../js/ui/overview.js:183
#: ../js/ui/overview.js:186
msgid "Windows"
msgstr "ਵਿੰਡੋ"
#: ../js/ui/overview.js:186
#: ../js/ui/overview.js:189
msgid "Applications"
msgstr "ਐਪਲੀਕੇਸ਼ਨ"
#. Translators: this is the name of the dock/favorites area on
#. the left of the overview
#: ../js/ui/overview.js:202
#: ../js/ui/overview.js:205
msgid "Dash"
msgstr "ਡੈਸ਼"
#. TODO - _quit() doesn't really work on apps in state STARTING yet
#: ../js/ui/panel.js:532
#: ../js/ui/panel.js:515
#, c-format
msgid "Quit %s"
msgstr "%s ਬੰਦ ਕਰੋ"
#. Button on the left side of the panel.
#. Translators: If there is no suitable word for "Activities" in your language, you can use the word for "Overview".
#: ../js/ui/panel.js:893
#: ../js/ui/panel.js:878
msgid "Activities"
msgstr "ਸਰਗਰਮੀਆਂ"
#: ../js/ui/panel.js:994
#| msgid "Cancel"
msgid "Panel"
msgstr "ਪੈਨਲ"
#: ../js/ui/panel.js:979
msgid "Top Bar"
msgstr "ਉੱਤਲੀ ਪੱਟੀ"
#: ../js/ui/placeDisplay.js:122
#, c-format
@ -584,64 +591,85 @@ msgstr "ਮੁੜ-ਕੋਸ਼ਿਸ਼"
msgid "Connect to..."
msgstr "...ਨਾਲ ਕੁਨੈਕਟ ਕਰੋ"
#: ../js/ui/placeDisplay.js:409
#: ../js/ui/placeDisplay.js:380
msgid "PLACES & DEVICES"
msgstr "ਥਾਵਾਂ ਤੇ ਜੰਤਰ"
#: ../js/ui/polkitAuthenticationAgent.js:74
msgid "Authentication Required"
msgstr "ਪਰਮਾਣਕਿਤਾ ਚਾਹੀਦੀ ਹੈ"
#: ../js/ui/polkitAuthenticationAgent.js:108
msgid "Administrator"
msgstr "ਪਰਸ਼ਾਸ਼ਕ"
#: ../js/ui/polkitAuthenticationAgent.js:176
msgid "Authenticate"
msgstr "ਪਰਮਾਣਕਿਤਾ"
#: ../js/ui/polkitAuthenticationAgent.js:260
msgid "Sorry, that didn't work. Please try again."
msgstr "ਅਫਸੋਸ, ਉਹ ਕੰਮ ਨਹੀਂ ਕਰਦਾ। ਫੇਰ ਕੋਸ਼ਿਸ਼ ਕਰੋ ਜੀ।"
#: ../js/ui/polkitAuthenticationAgent.js:272
msgid "Password:"
msgstr "ਪਾਸਵਰਡ:"
#. Translators: this MUST be either "toggle-switch-us"
#. (for toggle switches containing the English words
#. "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:618
#: ../js/ui/popupMenu.js:679
msgid "toggle-switch-us"
msgstr "toggle-switch-us"
#: ../js/ui/runDialog.js:201
#: ../js/ui/runDialog.js:205
msgid "Please enter a command:"
msgstr "ਕਮਾਂਡ ਦਿਓ ਜੀ:"
#: ../js/ui/searchDisplay.js:283
#: ../js/ui/searchDisplay.js:310
msgid "Searching..."
msgstr "ਖੋਜ ਜਾਰੀ ਹੈ..."
#: ../js/ui/searchDisplay.js:297
#: ../js/ui/searchDisplay.js:324
msgid "No matching results."
msgstr "ਕੋਈ ਨਤੀਜਾ ਨਹੀਂ ਲੱਭਿਆ।"
#: ../js/ui/statusMenu.js:102 ../js/ui/statusMenu.js:166
#: ../js/ui/statusMenu.js:161 ../js/ui/statusMenu.js:163
#: ../js/ui/statusMenu.js:228
msgid "Power Off..."
msgstr "...ਬੰਦ ਕਰੋ"
#: ../js/ui/statusMenu.js:104 ../js/ui/statusMenu.js:165
#: ../js/ui/statusMenu.js:163 ../js/ui/statusMenu.js:227
msgid "Suspend"
msgstr "ਸਸਪੈਂਡ"
#: ../js/ui/statusMenu.js:125
#: ../js/ui/statusMenu.js:184
msgid "Available"
msgstr "ਉਪਲੱਬਧ"
#: ../js/ui/statusMenu.js:130
#: ../js/ui/statusMenu.js:189
msgid "Busy"
msgstr "ਰੁਝਿਆ"
#: ../js/ui/statusMenu.js:138
#: ../js/ui/statusMenu.js:197
msgid "My Account"
msgstr "ਮੇਰਾ ਅਕਾਊਂਟ"
#: ../js/ui/statusMenu.js:142
#: ../js/ui/statusMenu.js:201
msgid "System Settings"
msgstr "ਸਿਸਟਮ ਸੈਟਿੰਗ"
#: ../js/ui/statusMenu.js:149
#: ../js/ui/statusMenu.js:208
msgid "Lock Screen"
msgstr "ਸਕਰੀਨ ਲਾਕ ਕਰੋ"
#: ../js/ui/statusMenu.js:153
#: ../js/ui/statusMenu.js:213
msgid "Switch User"
msgstr "ਯੂਜ਼ਰ ਬਦਲੋ"
#: ../js/ui/statusMenu.js:158
#: ../js/ui/statusMenu.js:218
msgid "Log Out..."
msgstr "...ਲਾਗਆਉਟ"
@ -649,14 +677,12 @@ msgstr "...ਲਾਗਆਉਟ"
msgid "Zoom"
msgstr "ਜ਼ੂਮ"
#: ../js/ui/status/accessibility.js:69
msgid "Screen Reader"
msgstr "ਸਕਰੀਨ ਰੀਡਰ"
#: ../js/ui/status/accessibility.js:73
msgid "Screen Keyboard"
msgstr "ਸਕਰੀਨ ਕੀਬੋਰਡ"
#. let screenReader = this._buildItem(_("Screen Reader"), APPLICATIONS_SCHEMA,
#. 'screen-reader-enabled');
#. this.menu.addMenuItem(screenReader);
#. let screenKeyboard = this._buildItem(_("Screen Keyboard"), APPLICATIONS_SCHEMA,
#. 'screen-keyboard-enabled');
#. this.menu.addMenuItem(screenKeyboard);
#: ../js/ui/status/accessibility.js:77
msgid "Visual Alerts"
msgstr "ਦਿੱਖ ਚੇਤਾਵਨੀ"
@ -681,17 +707,17 @@ msgstr "ਮਾਊਸ ਸਵਿੱਚਾਂ"
msgid "Universal Access Settings"
msgstr "ਯੂਨੀਵਰਸਲ ਅਸੈੱਸ ਸੈਟਿੰਗ"
#: ../js/ui/status/accessibility.js:145
#: ../js/ui/status/accessibility.js:146
msgid "High Contrast"
msgstr "ਵੱਧ ਕਨਟਰਾਸਟ"
#: ../js/ui/status/accessibility.js:182
#: ../js/ui/status/accessibility.js:183
msgid "Large Text"
msgstr "ਵੱਡੇ ਅੱਖਰ"
#: ../js/ui/status/bluetooth.js:42 ../js/ui/status/bluetooth.js:241
#: ../js/ui/status/bluetooth.js:337 ../js/ui/status/bluetooth.js:371
#: ../js/ui/status/bluetooth.js:411 ../js/ui/status/bluetooth.js:444
#: ../js/ui/status/bluetooth.js:42 ../js/ui/status/bluetooth.js:237
#: ../js/ui/status/bluetooth.js:333 ../js/ui/status/bluetooth.js:367
#: ../js/ui/status/bluetooth.js:407 ../js/ui/status/bluetooth.js:440
msgid "Bluetooth"
msgstr "ਬਲਿਊਟੁੱਥ"
@ -711,94 +737,94 @@ msgstr "...ਨਵਾਂ ਜੰਤਰ ਸੈਟਅੱਪ"
msgid "Bluetooth Settings"
msgstr "ਬਲਿਊਟੁੱਥ ਸੈਟਿੰਗ"
#: ../js/ui/status/bluetooth.js:192
#: ../js/ui/status/bluetooth.js:188
msgid "Connection"
msgstr "ਕੁਨੈਕਸ਼ਨ"
#: ../js/ui/status/bluetooth.js:228
#: ../js/ui/status/bluetooth.js:224
msgid "Send Files..."
msgstr "...ਫਾਇਲਾਂ ਭੇਜੋ"
#: ../js/ui/status/bluetooth.js:233
#: ../js/ui/status/bluetooth.js:229
msgid "Browse Files..."
msgstr "...ਫਾਇਲਾਂ ਦੀ ਝਲਕ"
#: ../js/ui/status/bluetooth.js:242
#: ../js/ui/status/bluetooth.js:238
msgid "Error browsing device"
msgstr "ਜੰਤਰ ਬਰਾਊਜ਼ ਕਰਨ ਲਈ ਗਲਤੀ"
#: ../js/ui/status/bluetooth.js:243
#: ../js/ui/status/bluetooth.js:239
#, c-format
msgid "The requested device cannot be browsed, error is '%s'"
msgstr "ਮੰਗ ਕੀਤੇ ਗਏ ਜੰਤਰ ਨੂੰ ਬਰਾਊਜ਼ ਨਹੀਂ ਕੀਤਾ ਜਾ ਸਕਦਾ, ਗਲਤੀ ਸੀ '%s'"
#: ../js/ui/status/bluetooth.js:251
#: ../js/ui/status/bluetooth.js:247
msgid "Keyboard Settings"
msgstr "ਕੀਬੋਰਡ ਸੈਟਿੰਗ"
#: ../js/ui/status/bluetooth.js:256
#: ../js/ui/status/bluetooth.js:252
msgid "Mouse Settings"
msgstr "ਮਾਊਸ ਸੈਟਿੰਗ"
#: ../js/ui/status/bluetooth.js:263 ../js/ui/status/volume.js:65
#: ../js/ui/status/bluetooth.js:259 ../js/ui/status/volume.js:66
msgid "Sound Settings"
msgstr "ਸਾਊਂਡ ਸੈਟਿੰਗ"
#: ../js/ui/status/bluetooth.js:372
#: ../js/ui/status/bluetooth.js:368
#, c-format
msgid "Authorization request from %s"
msgstr "'%s' ਤੋਂ ਪਰਮਾਣਕਿਤਾ ਮੰਗ"
#: ../js/ui/status/bluetooth.js:378
#: ../js/ui/status/bluetooth.js:374
#, c-format
msgid "Device %s wants access to the service '%s'"
msgstr "ਜੰਤਰ %s ਸਰਵਿਸ '%s' ਨੂੰ ਵਰਤਣੀ ਚਾਹੁੰਦਾ ਹੈ।"
#: ../js/ui/status/bluetooth.js:380
#: ../js/ui/status/bluetooth.js:376
msgid "Always grant access"
msgstr "ਹਮੇਸ਼ਾ ਪਹੁੰਚ ਮਨਜ਼ੂਰ"
#: ../js/ui/status/bluetooth.js:381
#: ../js/ui/status/bluetooth.js:377
msgid "Grant this time only"
msgstr "ਕੇਵਲ ਇਸ ਸਮੇਂ ਹੀ ਮਨਜ਼ੂਰ"
#: ../js/ui/status/bluetooth.js:382
#: ../js/ui/status/bluetooth.js:378
msgid "Reject"
msgstr "ਨਾ-ਮਨਜ਼ੂਰ"
#: ../js/ui/status/bluetooth.js:412
#: ../js/ui/status/bluetooth.js:408
#, c-format
msgid "Pairing confirmation for %s"
msgstr "%s ਲਈ ਪੇਅਰ ਕਰਨ ਦੀ ਪੁਸ਼ਟੀ"
#: ../js/ui/status/bluetooth.js:418 ../js/ui/status/bluetooth.js:452
#: ../js/ui/status/bluetooth.js:414 ../js/ui/status/bluetooth.js:448
#, c-format
msgid "Device %s wants to pair with this computer"
msgstr "ਜੰਤਰ %s ਇਸ ਕੰਪਿਊਟਰ ਨਾਲ ਪੇਅਰ ਹੋਣਾ ਚਾਹੁੰਦਾ ਹੈ"
#: ../js/ui/status/bluetooth.js:419
#: ../js/ui/status/bluetooth.js:415
#, c-format
msgid "Please confirm whether the PIN '%s' matches the one on the device."
msgstr "ਪੁਸ਼ਟੀ ਕਰੋ ਜੀ ਕਿ ਪਿੰਨ '%s' ਜੰਤਰ ਉੱਤੇ ਮੌਜੂਦ ਪਿੰਨ ਨਾਲ ਮਿਲਦਾ ਹੈ।"
#: ../js/ui/status/bluetooth.js:421
#: ../js/ui/status/bluetooth.js:417
msgid "Matches"
msgstr "ਮਿਲਦਾ ਹੈ"
#: ../js/ui/status/bluetooth.js:422
#: ../js/ui/status/bluetooth.js:418
msgid "Does not match"
msgstr "ਮਿਲਦਾ ਨਹੀਂ ਹੈ"
#: ../js/ui/status/bluetooth.js:445
#: ../js/ui/status/bluetooth.js:441
#, c-format
msgid "Pairing request for %s"
msgstr "%s ਲਈ ਪੇਅਰ ਕਰਨ ਦੀ ਮੰਗ"
#: ../js/ui/status/bluetooth.js:453
#: ../js/ui/status/bluetooth.js:449
msgid "Please enter the PIN mentioned on the device."
msgstr "ਜੰਤਰ ਉੱਤੇ ਦਿੱਤਾ ਗਿਆ ਪਿੰਨ ਦਿਉ ਜੀ।"
#: ../js/ui/status/bluetooth.js:469
#: ../js/ui/status/bluetooth.js:465
msgid "OK"
msgstr "ਠੀਕ ਹੈ"
@ -810,17 +836,153 @@ msgstr "...ਕੀਬੋਰਡ ਲੇਆਉਟ ਵੇਖੋ"
msgid "Localization Settings"
msgstr "ਲੋਕਲਾਈਜ਼ੇਸ਼ਨ ਸੈਟਿੰਗ"
#: ../js/ui/status/network.js:102 ../js/ui/status/network.js:1437
msgid "<unknown>"
msgstr "<ਅਣਜਾਣ>"
#. Translators: this indicates that wireless or wwan is disabled by hardware killswitch
#: ../js/ui/status/network.js:295
msgid "disabled"
msgstr "ਬੰਦ ਹੈ"
#: ../js/ui/status/network.js:478
msgid "connecting..."
msgstr "ਕੁਨੈਕਟ ਕੀਤਾ ਜਾ ਰਿਹਾ ਹੈ..."
#. Translators: this is for network connections that require some kind of key or password
#: ../js/ui/status/network.js:481
msgid "authentication required"
msgstr "ਪਰਮਾਣਕਿਤਾ ਚਾਹੀਦੀ ਹੈ"
#. Translators: this is for devices that require some kind of firmware or kernel
#. module, which is missing
#: ../js/ui/status/network.js:491
msgid "firmware missing"
msgstr "ਫਿਰਮਵੇਅਰ ਮੌਜੂਦ ਨਹੀਂ ਹੈ"
#. Translators: this is for wired network devices that are physically disconnected
#: ../js/ui/status/network.js:498
msgid "cable unplugged"
msgstr "ਕੇਬਲ ਕੱਢੀ ਹੋਈ ਹੈ"
#. Translators: this is for a network device that cannot be activated (for example it
#. is disabled by rfkill, or it has no coverage
#: ../js/ui/status/network.js:503
msgid "unavailable"
msgstr "ਨਾ-ਉਪਲੱਬਧ"
#: ../js/ui/status/network.js:505
msgid "connection failed"
msgstr "ਕੁਨੈਕਸ਼ਨ ਫੇਲ੍ਹ ਹੈ"
#. TRANSLATORS: this is the indication that a connection for another logged in user is active,
#. and we cannot access its settings (including the name)
#: ../js/ui/status/network.js:585 ../js/ui/status/network.js:1385
msgid "Connected (private)"
msgstr "ਕੁਨੈਕਟ ਹੈ (ਪ੍ਰਾਈਵੇਟ)"
#: ../js/ui/status/network.js:666
msgid "Auto Ethernet"
msgstr "ਆਟੋ ਈਥਰਨੈੱਟ"
#: ../js/ui/status/network.js:741
msgid "Auto broadband"
msgstr "ਆਟੋ ਬਰਾਡਬੈਂਡ"
#: ../js/ui/status/network.js:744
msgid "Auto dial-up"
msgstr "ਆਟੋ ਡਾਇਲ-ਅੱਪ"
#. TRANSLATORS: this the automatic wireless connection name (including the network name)
#: ../js/ui/status/network.js:887 ../js/ui/status/network.js:1397
#, c-format
msgid "Auto %s"
msgstr "ਆਟੋ %s"
#: ../js/ui/status/network.js:889
msgid "Auto bluetooth"
msgstr "ਆਟੋ ਬਲਿਊਟੁੱਥ"
#: ../js/ui/status/network.js:1399
msgid "Auto wireless"
msgstr "ਆਟੋ ਬੇਤਾਰ"
#: ../js/ui/status/network.js:1457
msgid "More..."
msgstr "ਹੋਰ..."
#: ../js/ui/status/network.js:1480
msgid "Enable networking"
msgstr "ਨੈੱਟਵਰਕਿੰਗ ਚਾਲੂ ਹੈ"
#: ../js/ui/status/network.js:1492
msgid "Wired"
msgstr "ਤਾਰ"
#: ../js/ui/status/network.js:1503
msgid "Wireless"
msgstr "ਬੇਤਾਰ"
#: ../js/ui/status/network.js:1513
msgid "Mobile broadband"
msgstr "ਮੋਬਾਇਲ ਬਰਾਡਬੈਂਡ"
#: ../js/ui/status/network.js:1523
msgid "VPN Connections"
msgstr "VPN ਕੁਨੈਕਸ਼ਨ"
#: ../js/ui/status/network.js:1532
msgid "Network Settings"
msgstr "ਨੈੱਟਵਰਕ ਸੈਟਿੰਗ"
#: ../js/ui/status/network.js:1827
#, c-format
msgid "You're now connected to mobile broadband connection '%s'"
msgstr "ਹੁਣ ਤੁਸੀਂ ਮੋਬਾਇਲ ਬਰਾਡਬੈਂਡ ਨੈੱਟਵਰਕ '%s' ਨਾਲ ਕੁਨੈਕਟ ਹੋ ਗਏ ਹੋ"
#: ../js/ui/status/network.js:1831
#, c-format
msgid "You're now connected to wireless network '%s'"
msgstr "ਹੁਣ ਤੁਸੀਂ ਬੇਤਾਰ ਨੈੱਟਵਰਕ '%s' ਨਾਲ ਕੁਨੈਕਟ ਹੋ ਗਏ ਹੋ"
#: ../js/ui/status/network.js:1835
#, c-format
msgid "You're now connected to wired network '%s'"
msgstr "ਹੁਣ ਤੁਸੀਂ ਤਾਰ ਵਾਲੇ ਨੈੱਟਵਰਕ '%s' ਨਾਲ ਕੁਨੈਕਟ ਹੋ ਗਏ ਹੋ"
#: ../js/ui/status/network.js:1839
#, c-format
msgid "You're now connected to VPN network '%s'"
msgstr "ਤੁਸੀਂ ਹੁਣ VPN ਨੈੱਟਵਰਕ '%s' ਨਾਲ ਕੁਨੈਕਟ ਹੋ ਚੁੱਕੇ ਹੋ"
#: ../js/ui/status/network.js:1844
#, c-format
msgid "You're now connected to '%s'"
msgstr "ਤੁਸੀਂ ਹੁਣ '%s' ਨਾਲ ਕੁਨੈਕਟ ਹੋ"
#: ../js/ui/status/network.js:1852
msgid "Connection established"
msgstr "ਕੁਨੈਕਸ਼ਨ ਬਣਾਇਆ ਗਿਆ"
#: ../js/ui/status/network.js:1974
msgid "Networking is disabled"
msgstr "ਨੈੱਟਵਰਕਿੰਗ ਬੰਦ ਹੈ"
#: ../js/ui/status/network.js:2099
msgid "Network Manager"
msgstr "ਨੈੱਟਵਰਕ ਮੈਨੇਜਰ"
#: ../js/ui/status/power.js:85
msgid "Power Settings"
msgstr "ਪਾਵਰ ਸੈਟਿੰਗ"
#. 0 is reported when UPower does not have enough data
#. to estimate battery life
#: ../js/ui/status/power.js:110
#: ../js/ui/status/power.js:111
msgid "Estimating..."
msgstr "...ਅਨੁਮਾਨ ਲਾਇਆ ਜਾ ਰਿਹਾ ਹੈ"
#: ../js/ui/status/power.js:117
#: ../js/ui/status/power.js:118
#, c-format
msgid "%d hour remaining"
msgid_plural "%d hours remaining"
@ -828,102 +990,102 @@ msgstr[0] "%d ਘੰਟਾ ਬਾਕੀ"
msgstr[1] "%d ਘੰਟੇ ਬਾਕੀ"
#. TRANSLATORS: this is a time string, as in "%d hours %d minutes remaining"
#: ../js/ui/status/power.js:120
#: ../js/ui/status/power.js:121
#, c-format
msgid "%d %s %d %s remaining"
msgstr "%d %s %d %s ਬਾਕੀ"
#: ../js/ui/status/power.js:122
#: ../js/ui/status/power.js:123
msgid "hour"
msgid_plural "hours"
msgstr[0] "ਘੰਟਾ"
msgstr[1] "ਘੰਟੇ"
#: ../js/ui/status/power.js:122
#: ../js/ui/status/power.js:123
msgid "minute"
msgid_plural "minutes"
msgstr[0] "ਮਿੰਟ"
msgstr[1] "ਮਿੰਟ"
#: ../js/ui/status/power.js:125
#: ../js/ui/status/power.js:126
#, c-format
msgid "%d minute remaining"
msgid_plural "%d minutes remaining"
msgstr[0] "%d ਮਿੰਟ ਬਾਕੀ"
msgstr[1] "%d ਮਿੰਟ ਬਾਕੀ"
#: ../js/ui/status/power.js:227
#: ../js/ui/status/power.js:228
msgid "AC adapter"
msgstr "AC ਐਡਪਟਰ"
#: ../js/ui/status/power.js:229
#: ../js/ui/status/power.js:230
msgid "Laptop battery"
msgstr "ਲੈਪਟਾਪ ਬੈਟਰੀ"
#: ../js/ui/status/power.js:231
#: ../js/ui/status/power.js:232
msgid "UPS"
msgstr "UPS"
#: ../js/ui/status/power.js:233
#: ../js/ui/status/power.js:234
msgid "Monitor"
msgstr "ਮਾਨੀਟਰ"
#: ../js/ui/status/power.js:235
#: ../js/ui/status/power.js:236
msgid "Mouse"
msgstr "ਮਾਊਸ"
#: ../js/ui/status/power.js:237
#: ../js/ui/status/power.js:238
msgid "Keyboard"
msgstr "ਕੀਬੋਰਡ"
#: ../js/ui/status/power.js:239
#: ../js/ui/status/power.js:240
msgid "PDA"
msgstr "PDA"
#: ../js/ui/status/power.js:241
#: ../js/ui/status/power.js:242
msgid "Cell phone"
msgstr "ਸੈੱਲ ਫੋਨ"
#: ../js/ui/status/power.js:243
#: ../js/ui/status/power.js:244
msgid "Media player"
msgstr "ਮੀਡਿਆ ਪਲੇਅਰ"
#: ../js/ui/status/power.js:245
#: ../js/ui/status/power.js:246
msgid "Tablet"
msgstr "ਟੇਬਲੇਟ"
#: ../js/ui/status/power.js:247
#: ../js/ui/status/power.js:248
msgid "Computer"
msgstr "ਕੰਪਿਊਟਰ"
#: ../js/ui/status/power.js:249 ../src/shell-app-system.c:1013
#: ../js/ui/status/power.js:250 ../src/shell-app-system.c:1088
msgid "Unknown"
msgstr "ਅਣਜਾਣ"
#: ../js/ui/status/volume.js:44
#: ../js/ui/status/volume.js:45
msgid "Volume"
msgstr "ਆਵਾਜ਼"
#: ../js/ui/status/volume.js:57
#: ../js/ui/status/volume.js:58
msgid "Microphone"
msgstr "ਮਾਈਕਰੋਫੋਨ"
#: ../js/ui/telepathyClient.js:239
#: ../js/ui/telepathyClient.js:332
#, c-format
msgid "%s is online."
msgstr "%s ਆਨਲਾਈਨ ਹੈ।"
#: ../js/ui/telepathyClient.js:244
#: ../js/ui/telepathyClient.js:337
#, c-format
msgid "%s is offline."
msgstr "%s ਆਫਲਾਈਨ ਹੈ।"
#: ../js/ui/telepathyClient.js:247
#: ../js/ui/telepathyClient.js:340
#, c-format
msgid "%s is away."
msgstr "%s ਦੂਰ ਹੈ।"
#: ../js/ui/telepathyClient.js:250
#: ../js/ui/telepathyClient.js:343
#, c-format
msgid "%s is busy."
msgstr "%s ਰੁੱਝਿਆ/ਰੁੱਝੀ ਹੈ।"
@ -931,7 +1093,7 @@ msgstr "%s ਰੁੱਝਿਆ/ਰੁੱਝੀ ਹੈ।"
#. Translators: this is a time format string followed by a date.
#. If applicable, replace %X with a strftime format valid for your
#. locale, without seconds.
#: ../js/ui/telepathyClient.js:348
#: ../js/ui/telepathyClient.js:474
#, no-c-format
msgid "Sent at %X on %A"
msgstr "%2$A ਨੂੰ %1$X ਵਜੇ ਭੇਜਿਆ"
@ -940,11 +1102,11 @@ msgstr "%2$A ਨੂੰ %1$X ਵਜੇ ਭੇਜਿਆ"
#. in the search entry when no search is
#. active; it should not exceed ~30
#. characters.
#: ../js/ui/viewSelector.js:117
#: ../js/ui/viewSelector.js:122
msgid "Type to search..."
msgstr "...ਲੱਭਣ ਲਈ ਲਿਖੋ"
#: ../js/ui/viewSelector.js:137 ../src/shell-util.c:250
#: ../js/ui/viewSelector.js:142 ../src/shell-util.c:250
msgid "Search"
msgstr "ਖੋਜ"
@ -960,7 +1122,7 @@ msgstr "'%s' ਤਿਆਰ ਹੈ"
#. translators:
#. * The number of sound outputs on a particular device
#: ../src/gvc/gvc-mixer-control.c:1094
#: ../src/gvc/gvc-mixer-control.c:1098
#, c-format
msgid "%u Output"
msgid_plural "%u Outputs"
@ -969,51 +1131,67 @@ msgstr[1] "%u ਆਉਟਪੁੱਟ"
#. translators:
#. * The number of sound inputs on a particular device
#: ../src/gvc/gvc-mixer-control.c:1104
#: ../src/gvc/gvc-mixer-control.c:1108
#, c-format
msgid "%u Input"
msgid_plural "%u Inputs"
msgstr[0] "%u ਇੰਪੁੱਟ"
msgstr[1] "%u ਇੰਪੁੱਟ"
#: ../src/gvc/gvc-mixer-control.c:1402
#: ../src/gvc/gvc-mixer-control.c:1406
msgid "System Sounds"
msgstr "ਸਿਸਟਮ ਸਾਊਂਡ"
#: ../src/shell-global.c:1298
#: ../src/main.c:446
msgid "Print version"
msgstr "ਵਰਜਨ ਛਾਪੋ"
#: ../src/shell-app.c:454
#, c-format
msgid "Failed to launch '%s'"
msgstr "'%s' ਚਲਾਉਣ ਲਈ ਫੇਲ੍ਹ"
#: ../src/shell-global.c:1395
msgid "Less than a minute ago"
msgstr "ਇੱਕ ਮਿੰਟ ਤੋਂ ਘੱਟ ਚਿਰ ਪਹਿਲਾਂ"
#: ../src/shell-global.c:1302
#: ../src/shell-global.c:1399
#, c-format
msgid "%d minute ago"
msgid_plural "%d minutes ago"
msgstr[0] "%d ਮਿੰਟ ਪਹਿਲਾਂ"
msgstr[1] "%d ਮਿੰਟ ਪਹਿਲਾਂ"
#: ../src/shell-global.c:1307
#: ../src/shell-global.c:1404
#, c-format
msgid "%d hour ago"
msgid_plural "%d hours ago"
msgstr[0] "%d ਘੰਟਾ ਪਹਿਲਾਂ"
msgstr[1] "%d ਘੰਟੇ ਪਹਿਲਾਂ"
#: ../src/shell-global.c:1312
#: ../src/shell-global.c:1409
#, c-format
msgid "%d day ago"
msgid_plural "%d days ago"
msgstr[0] "%d ਦਿਨ ਪਹਿਲਾਂ"
msgstr[1] "%d ਦਿਨ ਪਹਿਲਾਂ"
#: ../src/shell-global.c:1317
#: ../src/shell-global.c:1414
#, c-format
msgid "%d week ago"
msgid_plural "%d weeks ago"
msgstr[0] "%d ਹਫ਼ਤਾ ਪਹਿਲਾਂ"
msgstr[1] "%d ਹਫ਼ਤੇ ਪਹਿਲਾਂ"
#: ../src/shell-mobile-providers.c:80
msgid "United Kingdom"
msgstr "ਬਰਤਾਨੀਆ"
#: ../src/shell-mobile-providers.c:526
msgid "Default"
msgstr "ਡਿਫਾਲਟ"
#: ../src/shell-polkit-authentication-agent.c:334
#| msgid "Authentation dialog was dismissed by the user"
msgid "Authentication dialog was dismissed by the user"
msgstr "ਪਰਮਾਣਕਿਤਾ ਡਾਈਲਾਗ ਯੂਜ਼ਰ ਵਲੋਂ ਰੱਦ ਕੀਤਾ"
@ -1037,6 +1215,34 @@ msgstr "ਫਾਇਲ ਸਿਸਟਮ"
msgid "%1$s: %2$s"
msgstr "%1$s: %2$s"
#~ msgid "No such application"
#~ msgstr "ਇੰਞ ਦੀ ਕੋਈ ਐਪਲੀਕੇਸ਼ਨ ਨਹੀਂ ਹੈ"
#~ msgid "Shut Down"
#~ msgstr "ਬੰਦ ਕਰੋ"
#~ msgid "Click Shut Down to quit these applications and shut down the system."
#~ msgstr "ਇਹ ਐਪਲੀਕੇਸ਼ਨ ਬੰਦ ਕਰਕੇ ਸਿਸਟਮ ਨੂੰ ਬੰਦ ਕਰਨ ਲਈ ਬੰਦ ਕਰੋ ਨੂੰ ਕਲਿੱਕ ਕਰੋ।"
#~ msgid "The system will shut down automatically in %d seconds."
#~ msgstr "ਸਿਸਟਮ ਨੂੰ ਆਟੋਮੈਟਿਕ ਹੀ %d ਸਕਿੰਟਾਂ ਵਿੱਚ ਬੰਦ ਕੀਤਾ ਜਾਵੇਗਾ।"
#~ msgid "Shutting down the system."
#~ msgstr "ਸਿਸਟਮ ਬੰਦ ਕੀਤਾ ਜਾ ਰਿਹਾ ਹੈ।"
#~ msgid "Confirm"
#~ msgstr "ਪੁਸ਼ਟੀ"
#~| msgid "Cancel"
#~ msgid "Panel"
#~ msgstr "ਪੈਨਲ"
#~ msgid "Screen Reader"
#~ msgstr "ਸਕਰੀਨ ਰੀਡਰ"
#~ msgid "Screen Keyboard"
#~ msgstr "ਸਕਰੀਨ ਕੀਬੋਰਡ"
#~ msgid "PREFERENCES"
#~ msgstr "ਪਸੰਦ"
@ -1246,9 +1452,6 @@ msgstr "%1$s: %2$s"
#~ msgid "Frequent"
#~ msgstr "ਅਕਸਰ"
#~ msgid "More"
#~ msgstr "ਹੋਰ"
#~ msgid "(see all)"
#~ msgstr "(ਸਭ ਵੇਖੋ)"

1159
po/pl.po

File diff suppressed because it is too large Load Diff

1297
po/pt.po

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

1595
po/ro.po

File diff suppressed because it is too large Load Diff

1228
po/ru.po

File diff suppressed because it is too large Load Diff

834
po/sl.po

File diff suppressed because it is too large Load Diff

1359
po/sr.po

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

1245
po/sv.po

File diff suppressed because it is too large Load Diff

1484
po/ta.po

File diff suppressed because it is too large Load Diff

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