Compare commits

...

153 Commits
3.4.2 ... 3.5.2

Author SHA1 Message Date
06febdce22 Bump version to 3.5.2
Update NEWS
Require Mutter 3.5.2
2012-06-05 22:08:07 +02:00
c31d9d5e3d a11y: do not expose a label text if 'hidden' style class is used
https://bugzilla.gnome.org/show_bug.cgi?id=675341
2012-06-05 18:12:41 +02:00
cda8a545f1 css: add a 'hidden' style class
Used for elements that are not supposed to be shown.

https://bugzilla.gnome.org/show_bug.cgi?id=675341
2012-06-05 18:12:41 +02:00
f850e92524 popupMenu: do not overflow the currentItems
Do not overflow currentItems array. If the Menu section is filled
via model items-changed callback the position in the model passed to
the RemoteMenu _modelChanged can be a to be added asynchronously
action-added. Thus the item does not yet exists in the currentItems.

https://bugzilla.gnome.org/show_bug.cgi?id=676447
2012-06-05 16:28:40 +02:00
cc9d53e038 popupMenu: bypass changeSignal callback if action is already handled
https://bugzilla.gnome.org/show_bug.cgi?id=676447
2012-06-05 16:28:40 +02:00
7b048fc092 endSessionDialog: Factor out _updateDescription from _updateContent
_startTimer adds a tweener to implement the description countdown, which
updates the entire content on each iteration, including the icon. This
causes a significant impact on performance, especially when accessibility
is enabled, as it causes a flood of AtkObject:state-change:showing events.
As the countdown only affects the description, factor out _updateDescription
and use it in _startTimer, and only do a full update of all contents when
necessary.

https://bugzilla.gnome.org/show_bug.cgi?id=674210
2012-06-05 15:57:18 +02:00
4ba4a501fd Updated Spanish translation 2012-06-03 17:57:30 +02:00
2b2cce6896 Updated Galician translations 2012-06-03 15:02:43 +02:00
c1f51a7bf3 searchDisplay: Use the rowLimit we pass to the IconGrid
When displaying children, we need to make sure that we use the rowLimit
property that we pass to iconGrid, rather than assuming that it's
always MAX_SEARCH_RESULTS_ROWS in case some subclass (in an extension maybe)
wants to do something different.

https://bugzilla.gnome.org/show_bug.cgi?id=675527
2012-06-03 01:32:29 -04:00
465556f0d8 Updated Galician translations 2012-06-03 02:39:58 +02:00
db7ac5208a Patch for bug https://bugzilla.gnome.org/show_bug.cgi?id=673630 2012-06-02 15:45:55 +03:00
cfcd1bc014 Updated Hebrew translation. 2012-06-02 12:45:45 +03:00
e63f7e8779 userMenu: Indicate progress on status changes
Depending on the number of accounts, the type or simply the network,
there may be a noticable lag between setting the status and the actual
status change.
Use the new user-status-pending icon to indicate progress.

https://bugzilla.gnome.org/show_bug.cgi?id=659067
2012-06-01 19:53:44 -04:00
7911154bad NetworkMenu: show notifications for failed VPN connections
Refactor NMDeviceVPN to be more like the other NMDevices, including
having a valid getSectionTitle() and emitting signals when the
underlying connection changes state.
Use the existing notification infrastructure to hook these signals
to actual notifications (including some code consolidation).

https://bugzilla.gnome.org/show_bug.cgi?id=676330
2012-06-01 22:39:43 +02:00
ec0730f3e5 status/keyboard: Port to the new input sources settings
https://bugzilla.gnome.org/show_bug.cgi?id=641531
2012-06-01 22:18:59 +02:00
76005f5adf workspacesDisplay: Connect to 'notify::n-workspaces' early
Currently we only connect to the 'notify::n-workspaces' signal the
first time the overview is shown, which means we will miss any
changes to the workspace layout in the meanwhile.
In particular, the decision of whether the workspace switcher should be
shown is taken before the dynamic workspace handling takes over, and is
thus based entirely on the value of the num-workspaces user preference
rather than the actual number of workspaces.
Just connect the signal in _init() (with the nice side-effect to make it
explicit that the signal handler won't ever be disconnected).

https://bugzilla.gnome.org/show_bug.cgi?id=673198
2012-06-01 17:34:48 +02:00
94493cde35 a11y: setting the proper role/label_actor for SearchResult.content
role/label_actor should be used for the actor that will receive
the focus. In some cases it was also (wrongly) set on the
container, so using an AT like Orca, it exposed both.

https://bugzilla.gnome.org/show_bug.cgi?id=672242
2012-06-01 16:10:07 +02:00
a1f68720e5 telepathyClient: Remove C-based TelepathyLogger wrapper
gjs has matured enough to the point where we don't need this

https://bugzilla.gnome.org/show_bug.cgi?id=676850
2012-06-01 08:59:59 -04:00
022376dd56 Added contexts to various Unknown strings
Fixes bug https://bugzilla.gnome.org/show_bug.cgi?id=659968
2012-06-01 14:44:40 +02:00
934e5aacab notificationDaemon.js: convert the hints dict at the beginning of the function
It's used right away to discard some Empathy notifications.

This regression has been introduced during the 3.4 cycle when 'hints' has been
turned to a GVariant.

https://bugzilla.gnome.org/show_bug.cgi?id=675370
2012-06-01 09:40:32 +02:00
35b142f23f NetworkMenu: fix updating connection lists
Ensure that the UI is updated when a connection changes name or id,
even if it was already known by a device.
Also, use less private properties on NMConnection objects, as they
can become stale and cause problems.

https://bugzilla.gnome.org/show_bug.cgi?id=677097
2012-05-31 20:50:02 +02:00
41c3795a7b Add an initial-setup mode
Use the newly introduced kiosk mode functionality, and define an
'initial-setup' mode that is suitable for
https://live.gnome.org/GnomeOS/Design/Whiteboards/InitialSetup

https://bugzilla.gnome.org/show_bug.cgi?id=676697
2012-05-31 09:52:14 -04:00
95d7099133 [l10n] Update Japanese translation 2012-05-31 18:12:53 +09:00
33dc9abb9b Updated Norwegian bokmål translation 2012-05-30 14:19:28 +02:00
5e4edac14d browser-plugin: Fix Opera support
Opera now tries to call NP_SetWindow without trying to check
if it's a NULL pointer or not.

https://bugzilla.gnome.org/show_bug.cgi?id=672192
2012-05-29 18:57:05 -04:00
cb5ae92986 sessionMode: Add 'input-method' to status icons in user mode
We now drop all status icons that are not explicitly enabled, which
breaks the ibus icon. Add it to the list of allowed icons until we
merge it with the keyboard one.

https://bugzilla.gnome.org/show_bug.cgi?id=677058
2012-05-29 22:06:03 +02:00
ebbd295ebe panel: Refuse to add (legacy) status icons not part of the session mode
If a session mode does not use certain status items, we don't want their
fallback implementation to show up either, so filter them out.

https://bugzilla.gnome.org/show_bug.cgi?id=677058
2012-05-29 22:06:03 +02:00
65d23fb9a3 extensionUtils: Support subdirectories in getCurrentExtension
Some extensions may have complex layouts with multiple subdirectories.
Currently, getCurrentExtension doesn't support this, as it uses a regex
and assume's that the last path's component's parent is all that's needed.
Fix this.

https://bugzilla.gnome.org/show_bug.cgi?id=677001
2012-05-29 14:36:16 -04:00
ad6d986172 browser-plugin: Fix enable/disable
This code was broken at the last minute, and an accidentally stale plugin
copy kept it untested.

https://bugzilla.gnome.org/show_bug.cgi?id=676837
2012-05-29 14:36:16 -04:00
985641cc2e Updated Slovenian translation 2012-05-29 09:08:02 +02:00
de0a714081 Updated Lithuanian translation 2012-05-26 23:12:17 +03:00
3f942302d1 extensionSystem: Show an icon in the install dialog
https://bugzilla.gnome.org/show_bug.cgi?id=676837
2012-05-25 18:25:51 -04:00
96396163cf extensionSystem: Replace Shell.write_soup_message_to_stream with GBytes usage
https://bugzilla.gnome.org/show_bug.cgi?id=676837
2012-05-25 18:25:51 -04:00
0c736c4561 extensionSystem: Use Gio.File.new_tmp
https://bugzilla.gnome.org/show_bug.cgi?id=676837
2012-05-25 18:25:51 -04:00
33ad9d1035 extensionSystem: Clean up
https://bugzilla.gnome.org/show_bug.cgi?id=676837
2012-05-25 18:25:51 -04:00
d57658d059 extensionSystem: Remove custom CA file handling
libsoup (well, glib-networking) now handles this automatically

https://bugzilla.gnome.org/show_bug.cgi?id=676837
2012-05-25 18:25:51 -04:00
031206cf1f extensionSystem: Remove now-unused version_tag, clean up other code as well
https://bugzilla.gnome.org/show_bug.cgi?id=676837
2012-05-25 18:25:51 -04:00
12c7cc278d shellDBus: Remove now unused DisableExtension/EnableExtension
These methods were initially introduced when I was planning on having
an explicit DisableExtension/EnableExtension, instead of hooking up
a gsettings notify. This behavior was changed at the last minute, but
the methods were kept to avoid having to change the browser-plugin.

Consumers of this API should just set the GSettings key directly
instead now.

https://bugzilla.gnome.org/show_bug.cgi?id=676837
2012-05-25 18:25:51 -04:00
9d3750b9b8 browser-plugin: Set the 'enabled-extensions' GSettings key directly
This way, we won't have to shuttle over DBus if we want to set an extension's
status outside of a GNOME Shell session.

https://bugzilla.gnome.org/show_bug.cgi?id=676837
2012-05-25 18:25:51 -04:00
ba4b9f229e telepathyClient: fix isChat
As part of commit 9e1a2cf the parent _init was moved before the isChat
was set to true. As the parent set it to false isChat is never true
since this commit.

https://bugzilla.gnome.org/show_bug.cgi?id=676806
2012-05-25 13:14:43 -04:00
850fe98cbb Updated Hebrew translation. 2012-05-25 10:39:30 +03:00
8a9e3e0df2 Switch string formatting to the one inside gjs
https://bugzilla.gnome.org/show_bug.cgi?id=675479
2012-05-24 15:38:44 -04:00
a277569d31 Revert "main: Make sure that --mode parameter is valid"
This reverts commit a7a46bbe1c.

Conflicts:

	js/ui/sessionMode.js
2012-05-24 19:34:06 +02:00
7ed9516884 Updated Spanish translation 2012-05-23 14:19:24 +02:00
ecff2fa2b7 main: Add a --list-modes command line option
Add a command line option to list available modes, i.e. possible
arguments for the --mode switch.

https://bugzilla.gnome.org/show_bug.cgi?id=676156
2012-05-22 19:42:29 +02:00
e49b94658c Remove SessionType type
SessionType has now completely been replaced by the finer-grained
session-mode, so remove the remaining type definition.

https://bugzilla.gnome.org/show_bug.cgi?id=676156
2012-05-22 19:42:28 +02:00
e4f1572a3a sessionMode: Add statusArea property
Add a sessionMode.statusArea property, which specifies both the order
and shell implementation of the status area items for the mode.

https://bugzilla.gnome.org/show_bug.cgi?id=676156
2012-05-22 19:42:28 +02:00
b5b13322d8 sessionMode: Add extraStylesheet property
Add a sessionMode.extraStylesheet property, which may be used for
mode-specific style information.

https://bugzilla.gnome.org/show_bug.cgi?id=676156
2012-05-22 19:42:28 +02:00
c25e7f3c41 sessionMode: Add createSession() hook
Add a sessionMode.createSession() hook, which is executed during
startup to setup mode-specific stuff.

https://bugzilla.gnome.org/show_bug.cgi?id=676156
2012-05-22 19:42:28 +02:00
f6a2c92bfa main: Remove _initUserSession()
In Shell.SessionType.USER mode, two separate setup functions were
used during startup. With the new feature-based checks, the second
one is now almost empty, so move its remaining code into the first
function and remove it.

https://bugzilla.gnome.org/show_bug.cgi?id=676156
2012-05-22 19:42:28 +02:00
ed17418101 sessionMode: Add hasWorkspaces property
Add a sessionMode.hasWorkspaces property, which determines whether
the concept of workspaces should be exposed in the interface or not.

https://bugzilla.gnome.org/show_bug.cgi?id=676156
2012-05-22 19:42:28 +02:00
5264f39209 sessionMode: Add hasRunDialog property
Add a sessionMode.hasRunDialog property, which determines whether
the keyboard shortcut to access the run dialog should be active
or not.

https://bugzilla.gnome.org/show_bug.cgi?id=676156
2012-05-22 19:42:28 +02:00
de69c719fb sessionMode: Add allowKeybindingsWhenModal property
Add a sessionMode.allowKeybindingsWhenModal property, which determines
whether keybindings should still be handled while a modal dialog is
up or not.

https://bugzilla.gnome.org/show_bug.cgi?id=676156
2012-05-22 19:42:28 +02:00
ab3173487d sessionMode: Add allowExtensions property
Add a sessionMode.allowExtensions property, which determines whether
installed and enabled extensions should be loaded or ignored.

https://bugzilla.gnome.org/show_bug.cgi?id=676156
2012-05-22 19:42:28 +02:00
a3fcb8c284 sessionMode: Add allowSettings property
Add a sessionMode.allowSettings property, which determines whether
menus in the top bar should allow access to System Settings or not.

https://bugzilla.gnome.org/show_bug.cgi?id=676156
2012-05-22 19:42:28 +02:00
ba92cfa064 sessionMode: Add showCalendarEvents property
Add a sessionMode.showCalendarEvents property, which determines
whether the calendar menu should contain an events section or not.

https://bugzilla.gnome.org/show_bug.cgi?id=676156
2012-05-22 19:42:28 +02:00
6bee51ed33 sessionMode: Add hasAppMenu property
Add a sessionMode.hasAppMenu property, which determines whether
the top bar should contain a menu for the active application or
not.

https://bugzilla.gnome.org/show_bug.cgi?id=676156
2012-05-22 19:42:28 +02:00
122bca49ea sessionMode: Add hasOverview property
Add a sessionMode.hasOverview property, which determines whether
the mode should give access to the overview or not.

https://bugzilla.gnome.org/show_bug.cgi?id=676156
2012-05-22 19:42:28 +02:00
19318a1eeb global: Remove session_type property
ShellGlobal:session-type is now unsed, remove it.

https://bugzilla.gnome.org/show_bug.cgi?id=676156
2012-05-22 19:42:28 +02:00
a7a46bbe1c main: Make sure that --mode parameter is valid
Instead of falling back to a set of default values or crashing the
window manager when an invalid mode is specified, check the value
of the ShellGlobal:session-mode property before taking over as WM
and make a clean exit if it cannot be resolved to an existent mode.

https://bugzilla.gnome.org/show_bug.cgi?id=676156
2012-05-22 19:42:27 +02:00
3d26224180 Delegate mode information to a dedicated object
Rather than accessing global.session_type / global.session_mode
all over the place, delegate mode information to a dedicated
sessionMode object. While not very useful for now, we will replace
checks for a particular mode with checks for particular properties
that sessionMode defines based on global.session_mode.

https://bugzilla.gnome.org/show_bug.cgi?id=676156
2012-05-22 19:42:27 +02:00
940ddb104c global: Add session-mode property
Add a session-mode property on ShellGlobal which corresponds to the
new --mode switch. Make the existing ShellGlobal:session-type property
readonly and base it on ShellGlobal:session-mode to avoid conflicts.

https://bugzilla.gnome.org/show_bug.cgi?id=676156
2012-05-22 19:42:27 +02:00
5617f91281 main: Add generic --mode switch
We are going to need "special" modes other than GDM, for instance
for the initial setup[0]. Rather than adding one command line switch
per mode (and logic to deal with multiple switches being given at
the same time), add a generic --mode switch to specify the mode as
string.

[0] https://live.gnome.org/GnomeOS/Design/Whiteboards/InitialSetup

https://bugzilla.gnome.org/show_bug.cgi?id=676156
2012-05-22 19:42:27 +02:00
a9a863aab4 Updated Spanish translation 2012-05-22 10:46:27 +02:00
ca26347dea userMenu: Offer "Switch Session" item on multi-session systems
Since commit 518282e169, we hide both "Switch User" and "Log out"
on single-user systems. However, if there is more than one session
available, users may still want to get back to the login manager
to change sessions.
Add both "Log out" and "Switch Session" items in that case.

https://bugzilla.gnome.org/show_bug.cgi?id=675802
2012-05-22 07:36:36 +02:00
41a14e808e Updated Spanish translation 2012-05-21 13:57:39 +02:00
6452501275 Updated Galician translations 2012-05-20 18:14:15 +02:00
b61ada72cc shell-app: Raise windows in reverse order to preserve the stacking
ShellApp keeps track of windows sorted by most recently used first
which means that when raising windows we need to start from the end of
the list to finish with the correct stacking order.

This patch just makes the code agree with the comment which was
already there.

https://bugzilla.gnome.org/show_bug.cgi?id=676371
2012-05-19 17:32:12 +02:00
ace42d845c Updated Korean translation 2012-05-19 22:58:08 +09:00
850b6f28e5 main: Add prototype for _shell_link_to_shell_js()
It's pointless to have a prototype for a dummy function, but at
least on F17, gcc's -Werror includes -Wmissing-prototypes ...

https://bugzilla.gnome.org/show_bug.cgi?id=676347
2012-05-19 02:41:07 +02:00
3c81e9f0e7 Prevent the link to libgnome-shell-js.so from being removed
Add a dummy call to shell_js_add_extension_importer() to ensure that the
link to libgnome-shell-js.so is not removed when using -Wl,--as-needed,
which is the default on many distros.

https://bugzilla.gnome.org/show_bug.cgi?id=670477
2012-05-18 18:30:51 -04:00
e20ea19f34 Link the gnome-shell binary to libgnome-shell-js.so
Depending on the exact linker options and versions, rpath's written
into the binary may, or may not, be honored by dlopen(). Work around
this by simply linking the gnome-shell binary to gnome-shell-js, since
then dlopen() doesn't need to search paths.

https://bugzilla.gnome.org/show_bug.cgi?id=670477
2012-05-18 18:29:02 -04:00
ce041a3190 js: Don't use global.log*
These are "deprecated", and are just references to the gjs logging functoins

https://bugzilla.gnome.org/show_bug.cgi?id=675790
2012-05-18 14:09:00 -04:00
3a01aaf7fb extensionSystem: Don't spam stdout with "Loaded extension"
https://bugzilla.gnome.org/show_bug.cgi?id=675790
2012-05-18 14:09:00 -04:00
ec4a2aae95 notificationDaemon: Fix copy-paste typo
Since this line was introduced in 7458d3e, "Approve file transfer channels",
it's quite obvious that the line was meant to filter out transfer channel
notifications.

https://bugzilla.gnome.org/show_bug.cgi?id=676175
2012-05-18 14:08:12 -04:00
de8a66d4ce st: Remove our own font DPI resolution implementation
Clutter has had clutter_backend_get_resolution for a little while.

https://bugzilla.gnome.org/show_bug.cgi?id=672807
2012-05-18 13:57:12 -04:00
dc3d3acb3b global: Remove XSettings font handling code
Clutter now has its own XSettings implementation, ClutterSettings, which
handles this automatically now.

https://bugzilla.gnome.org/show_bug.cgi?id=672807
2012-05-18 13:57:12 -04:00
48d6eb168f bluetooth: Enforce a PIN length of 6 digits
Bluetooth PINs are required to have 6 digits, so enforce that
condition by making the PIN request notification's confirm
button insensitive unless the entered PIN has the correct length.

https://bugzilla.gnome.org/show_bug.cgi?id=651251
2012-05-18 17:41:19 +02:00
6190d6c962 messageTray: Allow to make notification buttons insensitive
The availability of a notification action may depend on conditions,
so add a method to control the sensitivity of buttons which have
been added with addButton().

https://bugzilla.gnome.org/show_bug.cgi?id=651251
2012-05-18 17:39:50 +02:00
76616dc98c bluetooth: zero-pad PIN
Bluetooth PINs always consist of 6 digits, so make sure to add
leading zeros as necessary.

https://bugzilla.gnome.org/show_bug.cgi?id=651251
2012-05-18 17:39:50 +02:00
82c2f5221d panel: Check for appMenu button's reactivity before opening
When the appMenu is not available, for instance when no windows are
open (on the current workspace), we make its actor unreactive to
"hide" it from keynav. However the menu can still be triggered
erroneously when using the corresponding keyboard shortcut, so
add a check for the actor's reactivity there as well.

https://bugzilla.gnome.org/show_bug.cgi?id=676316
2012-05-18 17:38:06 +02:00
a3bbb7be14 [l10n] Updated Indonesian translation 2012-05-17 22:19:18 +07:00
9e1a2cfeac Start using MessageTray.Source directly instead of having to subclass it
For most subclasses, this is a direct swap -- a lot of the time, the
constructor was a blank class that override createNotificationIcon,
and called _setSummaryIcon in _init.

https://bugzilla.gnome.org/show_bug.cgi?id=661236
2012-05-17 08:32:22 -04:00
c6fabe504a messageTray: Make Source usable without subclassing
Rather than ask most users of Source to subclass it to simply set their icon,
just allow them to create a new instance and add it without any complex magic.

https://bugzilla.gnome.org/show_bug.cgi?id=661236
2012-05-17 08:32:22 -04:00
61a17d7fab Magnifier: Add brightness and contrast functionality
Added clutter effects class that does lightness inversion.
Modified the magnifier to use this inversion effect.

https://bugzilla.gnome.org/show_bug.cgi?id=639851
2012-05-16 18:59:33 -04:00
865cfa5211 Magnifier: Add brightness and contrast functionality
Modified the magnifier to use the CluttterBrightnessContrastEffect
for changing overall brightness and/or contrast of a ZoomRegion.

https://bugzilla.gnome.org/show_bug.cgi?id=639851
2012-05-16 18:59:32 -04:00
e2b857adae Updated Japanese translation. 2012-05-15 00:53:03 +09:00
f3924ccd91 l10n: Updated Italian translation 2012-05-12 20:09:29 +02:00
86e3e59530 Updated Galician translations 2012-05-11 11:31:43 +02:00
02e4726ba6 util: Don't double-fork when spawning from Alt-F2
This breaks polkit.

See http://bugzilla.redhat.com//show_bug.cgi?id=819275

https://bugzilla.gnome.org/show_bug.cgi?id=675789
2012-05-10 15:05:05 -04:00
66e470e073 Updated Spanish translation 2012-05-10 18:06:54 +02:00
afaa5c24d6 userMenu: Update to latest mockups
Technically those are minor changes, but people will love us anyway:

  - change the default of the <alt>ernative to "Power Off"
  - remove "Online Accounts" item
  - regroup the remaining items
  - remove ellipses from labels

https://bugzilla.gnome.org/show_bug.cgi?id=675802
2012-05-10 15:54:37 +02:00
518282e169 userMenu: Hide "Log out" item on single user machines
Ignoring remote logins, the "Log out" action is meaningless for
single user setups. Do not show it in that case.

https://bugzilla.gnome.org/show_bug.cgi?id=675802
2012-05-10 15:54:37 +02:00
d955adbbad userMenu: More show()/hide() refactoring
Here's one show()/hide() sequence left out in commit 723a1c843 ...
2012-05-10 15:54:37 +02:00
83d3225e57 userMenu: Fix 'Lock' lockdown setting
Oops, embarrassing typo ...

https://bugzilla.gnome.org/show_bug.cgi?id=675802
2012-05-10 15:23:13 +02:00
6fa45975bf Updated Marathi Translations 2012-05-10 10:02:04 +05:30
e6087efb40 NetworkAgent: disallow multiple requests for the same connection/setting
It doesn't make sense to have multiple requests for the same
connection/setting combination at the same time, since we would be
asking the user twice for the same password. Instead, report cancellation
to NetworkManager if this happens.
Note that does make sense to have multiple requests in sequence though
(they could have different flags), but this is not affected.

https://bugzilla.gnome.org/show_bug.cgi?id=674961
2012-05-07 22:06:26 +02:00
4ce2f80a2f searchDisplay: Remove the sync search completed code path
Now that all searches are async we can remove the code path for the
SearchSystem::search-completed signal which is no longer useful.

This patch ends up fixing the status text not being updated for when
there are no results.

https://bugzilla.gnome.org/show_bug.cgi?id=675328
2012-05-07 21:45:45 +02:00
0862d1c804 searchDisplay: Remove a couple of no longer used variables
https://bugzilla.gnome.org/show_bug.cgi?id=675328
2012-05-07 21:45:42 +02:00
333e380340 search: Remove the ability to add synchronous search providers
As shown in the previous commits, synchronous search is easily implemented
by the asynchronous search API. The only reason we still have a
synchronous search API is of historical reasons. Well, we're not a museum,
and git log can keep our fossils safe if need be....

https://bugzilla.gnome.org/show_bug.cgi?id=675328
2012-05-07 15:29:46 -03:00
58f77a19ed search: Port all search providers over to the async API
https://bugzilla.gnome.org/show_bug.cgi?id=675328
2012-05-07 15:29:32 -03:00
f2d883dab2 placeDisplay: Create our own PlacesManager
Since we don't have a section showing off the available places somewhere,
we don't need a global PlacesManager.

https://bugzilla.gnome.org/show_bug.cgi?id=675328
2012-05-07 15:29:20 -03:00
7ba8c7c2b5 search: Remove unused MUTLIPLE_* match types
https://bugzilla.gnome.org/show_bug.cgi?id=675328
2012-05-07 15:21:24 -03:00
0bf6c93faa search: Allow synchronous searches to be defined with the async API
To allow this to happen, we need to make sure that we don't overwrite the
previousResults when calling the async method. Note that this is a bug of
some sort, we were already using this synchronous style when a remote
search failed.

https://bugzilla.gnome.org/show_bug.cgi?id=675328
2012-05-07 15:21:24 -03:00
b9f0158278 placeDisplay: use new bookmark file location
GTK+ 3.5 is placing the bookmarks file in
$XDG_CONFIG_HOME/gtk-3.0/bookmarks. Adapt to that change.

https://bugzilla.gnome.org/show_bug.cgi?id=675443
2012-05-07 08:21:59 -04:00
25ee41f344 theme: use a smaller border-radius for top bar
- plays better with window decorations and maximized windows
- https://bugzilla.gnome.org/show_bug.cgi?id=672430
2012-05-07 10:36:28 +02:00
5436634829 a11y: Using the proper label_actor for date menu on top panel
On the code two labels are created. One is used on the date menu
itself, and the other for the menu icon at the top panel. The wrong
label was used as the label_actor for the top panel menu icon.

https://bugzilla.gnome.org/show_bug.cgi?id=675307
2012-05-03 20:47:11 +02:00
915524e1ab main: Close the recorder instead of pausing it
Pausing means that we will continue to use the same output file when
the keybinding is activated again. While useful to record a single
video in chunks, it doesn't seem to be how most users understand the
keybinding. Closing the recorder will close the file and create a new
one the next time the keybinding is pressed.

https://bugzilla.gnome.org/show_bug.cgi?id=675128
2012-05-03 09:27:53 +02:00
d579cd1605 test-recorder: Create the recorder only after the stage is realized
The recorder needs the stage's XID so it can only be created after the
stage is realized.

https://bugzilla.gnome.org/show_bug.cgi?id=675301
2012-05-03 09:27:53 +02:00
cb5941ec55 test-recorder: Explicitly make the clutter API coordinates doubles
That's what clutter expects and it would crash otherwise.

https://bugzilla.gnome.org/show_bug.cgi?id=675301
2012-05-03 09:27:53 +02:00
a5ac183d86 network: Fix an accidental copy-paste error
Logic swap accidentally introduced in commit 723a1c843.

https://bugzilla.gnome.org/show_bug.cgi?id=672272
2012-05-02 16:31:29 -04:00
a36de92bb9 gactionmuxer: Fix list_actions
The code there before was just completely wrong

https://bugzilla.gnome.org/show_bug.cgi?id=673177
2012-05-02 16:26:07 -04:00
01f9d551f1 messageTray: Fix scroll bugginess in summary items
Two nested scroll views were fighing with each other. The reason isn't
particularly important and has to do with some silliness involving
StAdjustment. The visible effect was that scrolling up and down when
in a summary item view would appear to be glitchy, and sometimes not
work at all.

To fix, make sure that the scroll view we don't care about is disabled
when in a summary mode.

https://bugzilla.gnome.org/show_bug.cgi?id=661615
2012-05-02 16:04:46 -04:00
399df66b18 messageTray: notification should be a style class name, not a global name
There have been multiple notifications ever since we had a notification stack
per source, so the idea of one notification being on screen at a time has long
been dead.

https://bugzilla.gnome.org/show_bug.cgi?id=661615
2012-05-02 16:04:05 -04:00
723a1c843a Refactor show()/hide() sequences
We seem to have a lot of code that does something along the lines of:

    if (condition)
        actor.show();
    else
        actor.hide();

ClutterActor already has such a thing for exactly this purpose: the 'visible'
property. Use it instead of the mess above.

https://bugzilla.gnome.org/show_bug.cgi?id=672272
2012-05-02 12:43:58 -04:00
e333263fd6 gdm: don't fail if fprintd unavailable
fingerprint support is optional so we shouldn't try to start
fprintd upfront and croak if it fails.

https://bugzilla.gnome.org/show_bug.cgi?id=675006
2012-05-02 11:44:29 -04:00
507df9eea1 gnome-shell-plugin: Remove useless dispose/finalize handlers
https://bugzilla.gnome.org/show_bug.cgi?id=672807
2012-05-02 10:20:22 -04:00
a9a3687ea0 st-bin: Remove unnecessary foreach implementation
https://bugzilla.gnome.org/show_bug.cgi?id=672807
2012-05-02 10:20:22 -04:00
f05c649c61 Updated Greek translation 2012-05-02 13:53:42 +03:00
a2dfba1842 l10n: Updated Italian translation 2012-04-30 15:34:24 +02:00
c199da4dfa Updated Norwegian bokmål translation 2012-04-30 11:13:44 +02:00
ee9033e12f gitignore: Update to ignore calendar schemas 2012-04-29 19:20:04 -04:00
54788d750e searchDisplay: Reset the keyboard focus after displaying async results
We hide the content around displaying new search results to prevent
flickering, unfortunately, one side effect of hiding an actor is
losing key focus if it currently is on the that actor or any
child. This could happen in the case of async results showing up after
the user had moved focus to the search results.

This patch works around that issue by saving the key focus and
resetting it back after displaying the new async results.

https://bugzilla.gnome.org/show_bug.cgi?id=675078
2012-04-30 01:10:08 +02:00
78e894c6f2 lookingGlass: Remove the "Errors" tab
We already have one too many logging systems. Remove the errors tab
and make global.log/global.logError point to window.log/window.logError
instead.

https://bugzilla.gnome.org/show_bug.cgi?id=675104
2012-04-29 17:12:07 -04:00
32107ba8b5 environment: Allow window.log to take multiple arguments
https://bugzilla.gnome.org/show_bug.cgi?id=675104
2012-04-29 17:12:05 -04:00
6122f65e7a NetworkMenu: use network-offline while loading
network-error is partially red and thus can be distracting at
login. Use network-offline instead.

https://bugzilla.gnome.org/show_bug.cgi?id=674426
2012-04-29 18:40:03 +02:00
43fd29f9bf Revert "popupMenu: Fix RemoteMenu items with boolean state action"
This reverts commit 7293ddb22c.
2012-04-29 10:38:52 +02:00
54c624b356 Updated Brazilian Portuguese translation 2012-04-28 10:46:58 -03:00
8c33adfd29 dash: Destroy tooltip label when item is removed 2012-04-27 15:50:48 -04:00
2e8881b77c notificationDaemon: Match app based on WM_CLASS
Most tray applets won't have an associated window in the same PID. We
need to fall back to the WM_CLASS in this case.

https://bugzilla.gnome.org/show_bug.cgi?id=673761
2012-04-27 15:49:18 -04:00
64aa729edd jhbuild wrapper: Clean up environment variable logic
Lots of things here were unused. First, we don't need to calculate
the js_dir when not running from the source tree, which makes the
branch mostly empty, meaning we can merge the two branches.
2012-04-27 15:48:53 -04:00
ccf95b738d jhbuild wrapper: Re-set typelib path to the src dir
This allows us running uninstalled. While we're at it, though, remove
JHBUILD_TYPELIBDIR. jhbuild shell should add its own stuff to GI_TYPELIB_PATH,
and we don't want to half reimplement jhbuild. The wrapper script should be
solely for the case of running from the source directory, and not care about
jhbuild at all.
2012-04-27 15:48:53 -04:00
b2847fedd3 jhbuild wrapper: Don't crash if we can't start the shell
If start_shell throws an exception for whatever reason, the finally
handler will run before shell has been set, leading to a "referencing
an undefined local variable" error.
2012-04-27 15:48:53 -04:00
8befcb9bba shell-network-agent: don't crash if a request isn't found
If a request isn't found in shell_network_agent_set_password() or
shell_network_agent_respond(), then g_return_if_fail() rather than
crashing. OTOH, if a request is not found in
shell_network_agent_cancel_get_secrets(), then just ignore it
silently, since that could legitimately happen.

https://bugzilla.gnome.org/show_bug.cgi?id=674961
2012-04-27 15:47:53 -04:00
988fc52303 Updated Galician translations 2012-04-27 17:07:47 +02:00
7293ddb22c popupMenu: Fix RemoteMenu items with boolean state action
Stateful actions are expected to pass their state when activated,
but we currently only do this for actions with a string state.

https://bugzilla.gnome.org/show_bug.cgi?id=674932
2012-04-27 12:30:16 +02:00
f23c118e81 Updated Hebrew translation. 2012-04-26 15:30:48 +03:00
f68b3be35a data: Add Evolution calendar settings gschema to EXTRA_DIST
3d95e7bb11 forgot to add this
gschema file to dist
2012-04-26 08:40:01 +02:00
3d95e7bb11 Mirror Evolution calendar settings into our own schema
Right now, we are hard-depending on the presence of Evolution by
using its settings schemas. This is likely to be unpopular, and
also causes instability if someone happens not to have Evolution
installed, so install a schema that has the same data path as
the Evolution schema, but a different name and install that
for the keys we need.

To avoid a string-freeze break, we rely on the translations in
Evolution - if Evolution isn't installed, the key descriptions
will be untranslated in dconf-editor.

https://bugzilla.gnome.org/show_bug.cgi?id=674424
2012-04-25 14:39:02 -04:00
337c484f01 Updated Korean translation 2012-04-26 01:08:27 +09:00
5d98e2bf04 st-theme-node-drawing: Don't use GL types
This swaps a use of GLfloat for a regular float. Cogl might stop
including a GL header in its public headers soon so this would fix a
compilation error.

https://bugzilla.gnome.org/show_bug.cgi?id=672711
2012-04-25 15:47:04 +01:00
6f300d0cc6 Updated Spanish translation 2012-04-25 12:17:17 +02:00
3422e1dca7 popupMenu: make sure to break the grab when the slider is not visible
Otherwise the grab will persist for example after closing the PopupMenu
with Escape.

https://bugzilla.gnome.org/show_bug.cgi?id=672713
2012-04-24 22:37:19 +02:00
963c6ae567 workspace: Use the position hints when available also for the window overlay
Otherwise when dropping a window in the current workspace the overlay will
appear from the top left corner.

https://bugzilla.gnome.org/show_bug.cgi?id=674323
2012-04-24 22:37:19 +02:00
6304169926 workspace: hide the overlay for a zoomed window when exiting the overivew
Otherwise it remains visible until the overview animation is completed.

https://bugzilla.gnome.org/show_bug.cgi?id=674323
2012-04-24 22:37:19 +02:00
221afde55e jhbuild wrapper: clean up imports
Final commit in the series, remove imports that were only used
by moved or deleted functionality.
2012-04-24 21:20:49 +02:00
0ae87270ad jhbuild wrapper: don't try to "restore GNOME"
If run under jhbuild, gnome-shell is in PATH, so trying to restore
is just running it again, likely failing in the same way (with the
additional problem of detaching the shell from the terminal). Also,
this is using deprecated GConf keys, and deprecated pygobject
bindings.
2012-04-24 21:20:49 +02:00
9d33baec70 jhbuild wrapper: don't set unneeded environment variables
The jhbuild wrapper is expected to be run through jhbuild run, or
in the uninstalled case inside a jhbuild shell, so there should
be no need to set XDG_DATA_DIRS and friends.
2012-04-24 21:20:49 +02:00
0f37b22cdb jhbuild wrapper: don't muck with session activated services
dconf-daemon is available since 2.32, so there is no need to
start it manually (and in fact, it should not be running normally).
Similarly, notify-osd and notification-daemon should not be
dbus activated, but rather autostarted by gnome-session, and
therefore not running in a gnome-shell session.
2012-04-24 21:20:49 +02:00
47afd87e84 jhbuild wrapper: move performance measurement to a separate tool
Introduce a new gnome-shell-perf-tool, which can be used instead
of the old gnome-shell-jhbuild wrapper to gather data about gnome-shell
performance and submit to shell-perf.gnome.org. This runs the
shell with no extra setup beyond the WM_CLASS filter, so it can
be used for a jhbuild setup or for an installed shell.
2012-04-24 21:20:49 +02:00
700c06023e st: Clean up scroll event code
Currently the scroll event code only handles scroll events if the
adjustment's value is within the "lower" and "upper" limits. The
likely intent was to pass events to a parent scroll view when
reaching the bounds (uh, nested scroll views!), but apparently
we never made use of this, as the upper bound is actually wrong
(an adjustment's maximum value is upper - page_size, not upper).
Just handle all scroll events unconditionally and rely on the
bound checks in StAdjustment.

https://bugzilla.gnome.org/show_bug.cgi?id=672413
2012-04-24 20:45:01 +02:00
4fea5b5ca3 main: Move 'toggle-recording' binding into the shell
The keybinding to toggle the screen recorder was implemented as a
signal on MetaScreen, as keybindings could only be defined in mutter
core. As this is no longer the case, we can move the binding into the
shell where it belongs.

https://bugzilla.gnome.org/show_bug.cgi?id=674377
2012-04-24 17:37:44 +02:00
521bddc1cc [l10n] Update Japanese translation
Fix a typo
2012-04-21 22:42:20 +09:00
101 changed files with 5764 additions and 5144 deletions

3
.gitignore vendored
View File

@ -23,6 +23,8 @@ data/gnome-shell-extension-prefs.desktop.in
data/gschemas.compiled
data/org.gnome.shell.gschema.xml
data/org.gnome.shell.gschema.valid
data/org.gnome.shell.evolution.calendar.gschema.xml
data/org.gnome.shell.evolution.calendar.gschema.valid
docs/reference/*/*.args
docs/reference/*/*.bak
docs/reference/*/*.hierarchy
@ -68,6 +70,7 @@ src/gnome-shell-extension-prefs
src/gnome-shell-hotplug-sniffer
src/gnome-shell-jhbuild
src/gnome-shell-perf-helper
src/gnome-shell-perf-tool
src/gnome-shell-real
src/hotplug-sniffer/org.gnome.Shell.HotplugSniffer.service
src/run-js-test

71
NEWS
View File

@ -1,3 +1,74 @@
3.5.2
=====
* main: Move 'toggle-recording' binding into the shell [Florian; #674377]
* popupMenu: make sure to break the grab when the slider is not visible
[Stefano; #672713]
* st-theme-node-drawing: Don't use GL types [Neil; #672711]
* Mirror Evolution calendar settings into our own schema [Owen; #674424]
* shell-network-agent: don't crash if a request isn't found [Dan; #674961]
* notificationDaemon: Match app based on WM_CLASS [Jasper; #673761]
* NetworkMenu: use network-offline while loading [Giovanni; #674426]
* lookingGlass: Remove the Errors tab [Jasper; #675104]
* searchDisplay: Reset keyboard focus after displaying async results
[Rui; #675078]
* gdm: don't fail if fprintd is unavailable [Ray; #675006]
* messageTray: Fix scrolling up [Jasper; #661615]
* main: Close the recorder instead of pausing it [Rui; #675128]
* Accessibility [Alejandro]
- Use the proper label_actor for date menu on top panel [#675307]
- Set the proper role/label_actor for SearchResult.content [#672242]
- do not expose a label text if 'hidden' style class is used [#675341]
* Magnifier: Add brightness and contrast functionality [Joseph; #639851]
* theme: use a smaller border-radius for top bar [Jakub; #672430]
* placeDisplay: use new bookmark file location [Matthias; #675443]
* port all synchronous search providers to the async API [Jasper, Rui; #675328]
* NetworkAgent: disallow multiple requests for the same connection/setting
[Giovanni; #674961]
* userMenu: Update to latest mockups [Florian; #675802]
* util: Don't double-fork when spawning from Alt-F2 [Colin; #675789]
* messageTray: Make Source usable without subclassing [Jasper; #661236]
* panel: Check for appMenu button's reactivity before opening [Florian; #676316]
* Fix formatting of bluetooth passkey [Florian; #651251]
* notificationDaemon: Filter out file-transfer notifications [Jasper; #676175]
* Don't use global.log() [Jasper; #675790]
* Fix broken extension loading in some distributions [Owen, Alexandre; #670477]
* shell-app: Raise windows in reverse order to preserve the stacking
[Rui; #676371]
* Generalize gdm-mode [Florian; #676156]
* Switch string formatting to the one inside gjs [Jasper; #675479]
* extensionUtils: Support subdirectories in getCurrentExtension
[Jasper; #677001]
* panel: Refuse to add (legacy) status icons not part of the session mode
[Florian; #677058]
* Add an initial-setup mode [Matthias; #676697]
* status/keyboard: Port to the new input sources settings [Rui; #641531]
* NetworkMenu: show notifications for failed VPN connections [Giovanni; #676330]
* userMenu: Indicate progress on status changes [Florian; #659067]
* recorder: Honor "disable-save-to-disk" lockdown key [Rūdolfs; #673630]
* searchDisplay: Use the rowLimit we pass to the IconGrid [Christian; #675527]
* endSessionDialog: Factor out _updateDescription from _updateContent
[Alejandro; #674210]
* Fix empathy's appMenu freezing the shell [Alban; #676447]
* Code cleanups [Florian, Giovanni, Jasper; #672807, #672413, #676837, #676850,
#672272]
* Misc bug fixes [Alban, Florian, Giovanni, Guillaume, Jasper, Piotr, Rico,
Ron, Rui, Stefano; #659968, #672192, #673177, #673198, #674323, #675301,
#675370, #676347, #676806, #677097]
Contributors:
Alban Browaeys, Giovanni Campagna, Matthias Clasen, Guillaume Desmottes,
Piotr Drąg, Stefano Facchini, Rui Matos, Rūdolfs Mazurs, Florian Müllner,
Alejandro Piñeiro, Neil Roberts, Alexandre Rostovtsev, Joseph Scheuhammer,
Jakub Steiner, Jasper St. Pierre, Ray Strode, Owen Taylor, Rico Tzschichholz,
Colin Walters, Dan Winship, Ron Yorston
Translations:
OKANO Takayoshi [ja], Daniel Mustieles [es], Changwoo Ryu [ko],
Yaron Shahrabani [he], Fran Diéguez [gl], Jonh Wendell [pt_BR],
Kjartan Maraas [nb], Luca Ferretti [it], Tom Tryfonidis [el],
Sandeep Sheshrao Shedmake [mr], Takanori MATSUURA [ja], Dirgita [id],
Mantas Kriaučiūnas [lt], Matej Urbančič [sl], Jiro Matsuzawa [ja]
3.4.1
=====
* Fix crash that occurred when an icon theme change caused unexpected

View File

@ -41,7 +41,7 @@
"It can be used only by extensions.gnome.org"
#define PLUGIN_MIME_STRING "application/x-gnome-shell-integration::Gnome Shell Integration Dummy Content-Type";
#define PLUGIN_API_VERSION 3
#define PLUGIN_API_VERSION 4
typedef struct {
GDBusProxy *proxy;
@ -163,6 +163,7 @@ NP_Initialize(NPNetscapeFuncs *pfuncs, NPPluginFuncs *plugin)
plugin->newp = NPP_New;
plugin->destroy = NPP_Destroy;
plugin->getvalue = NPP_GetValue;
plugin->setwindow = NPP_SetWindow;
return NPERR_NO_ERROR;
}
@ -267,6 +268,7 @@ typedef struct {
NPObject parent;
NPP instance;
GDBusProxy *proxy;
GSettings *settings;
NPObject *listener;
NPObject *restart_listener;
gint signal_id;
@ -323,6 +325,9 @@ on_shell_appeared (GDBusConnection *connection,
}
}
#define SHELL_SCHEMA "org.gnome.shell"
#define ENABLED_EXTENSIONS_KEY "enabled-extensions"
static NPObject *
plugin_object_allocate (NPP instance,
NPClass *klass)
@ -332,6 +337,7 @@ plugin_object_allocate (NPP instance,
obj->instance = instance;
obj->proxy = g_object_ref (data->proxy);
obj->settings = g_settings_new (SHELL_SCHEMA);
obj->signal_id = g_signal_connect (obj->proxy, "g-signal",
G_CALLBACK (on_shell_signal), obj);
@ -492,7 +498,61 @@ plugin_enable_extension (PluginObject *obj,
NPString uuid,
gboolean enabled)
{
gboolean ret;
gchar *uuid_str = g_strndup (uuid.UTF8Characters, uuid.UTF8Length);
gsize length;
gchar **uuids;
const gchar **new_uuids;
if (!uuid_is_valid (uuid_str))
{
g_free (uuid_str);
return FALSE;
}
uuids = g_settings_get_strv (obj->settings, ENABLED_EXTENSIONS_KEY);
length = g_strv_length (uuids);
if (enabled)
{
new_uuids = g_new (const gchar *, length + 2); /* New key, NULL */
memcpy (new_uuids, uuids, length * sizeof (*new_uuids));
new_uuids[length] = uuid_str;
new_uuids[length + 1] = NULL;
}
else
{
gsize i = 0, j = 0;
new_uuids = g_new (const gchar *, length);
for (i = 0; i < length; i ++)
{
if (g_str_equal (uuids[i], uuid_str))
continue;
new_uuids[j] = uuids[i];
j++;
}
new_uuids[j] = NULL;
}
ret = g_settings_set_strv (obj->settings,
ENABLED_EXTENSIONS_KEY,
new_uuids);
g_strfreev (uuids);
g_free (new_uuids);
g_free (uuid_str);
return ret;
}
static gboolean
plugin_install_extension (PluginObject *obj,
NPString uuid)
{
gchar *uuid_str = g_strndup (uuid.UTF8Characters, uuid.UTF8Length);
if (!uuid_is_valid (uuid_str))
{
g_free (uuid_str);
@ -500,7 +560,7 @@ plugin_enable_extension (PluginObject *obj,
}
g_dbus_proxy_call (obj->proxy,
(enabled ? "EnableExtension" : "DisableExtension"),
"InstallRemoteExtension",
g_variant_new ("(s)", uuid_str),
G_DBUS_CALL_FLAGS_NONE,
-1, /* timeout */
@ -513,40 +573,6 @@ plugin_enable_extension (PluginObject *obj,
return TRUE;
}
static gboolean
plugin_install_extension (PluginObject *obj,
NPString uuid,
NPString version_tag)
{
gchar *uuid_str = g_strndup (uuid.UTF8Characters, uuid.UTF8Length);
gchar *version_tag_str;
if (!uuid_is_valid (uuid_str))
{
g_free (uuid_str);
return FALSE;
}
version_tag_str = g_strndup (version_tag.UTF8Characters,
version_tag.UTF8Length);
g_dbus_proxy_call (obj->proxy,
"InstallRemoteExtension",
g_variant_new ("(ss)",
uuid_str,
version_tag_str),
G_DBUS_CALL_FLAGS_NONE,
-1, /* timeout */
NULL, /* cancellable */
NULL, /* callback */
NULL /* user_data */);
g_free (uuid_str);
g_free (version_tag_str);
return TRUE;
}
static gboolean
plugin_uninstall_extension (PluginObject *obj,
NPString uuid,
@ -771,11 +797,9 @@ plugin_object_invoke (NPObject *npobj,
else if (name == install_extension_id)
{
if (!NPVARIANT_IS_STRING(args[0])) return FALSE;
if (!NPVARIANT_IS_STRING(args[1])) return FALSE;
return plugin_install_extension (obj,
NPVARIANT_TO_STRING(args[0]),
NPVARIANT_TO_STRING(args[1]));
NPVARIANT_TO_STRING(args[0]));
}
else if (name == uninstall_extension_id)
{
@ -946,3 +970,12 @@ NPP_GetValue(NPP instance,
return NPERR_NO_ERROR;
}
/* Opera tries to call NPP_SetWindow without checking the
* NULL pointer beforehand. */
NPError
NPP_SetWindow(NPP instance,
NPWindow *window)
{
return NPERR_NO_ERROR;
}

View File

@ -1,5 +1,5 @@
AC_PREREQ(2.63)
AC_INIT([gnome-shell],[3.4.1],[https://bugzilla.gnome.org/enter_bug.cgi?product=gnome-shell],[gnome-shell])
AC_INIT([gnome-shell],[3.5.2],[https://bugzilla.gnome.org/enter_bug.cgi?product=gnome-shell],[gnome-shell])
AC_CONFIG_HEADERS([config.h])
AC_CONFIG_SRCDIR([src/shell-global.c])
@ -63,7 +63,7 @@ AM_CONDITIONAL(BUILD_RECORDER, $build_recorder)
CLUTTER_MIN_VERSION=1.9.16
GOBJECT_INTROSPECTION_MIN_VERSION=0.10.1
GJS_MIN_VERSION=1.29.18
MUTTER_MIN_VERSION=3.4.1
MUTTER_MIN_VERSION=3.5.2
FOLKS_MIN_VERSION=0.5.2
GTK_MIN_VERSION=3.3.9
GIO_MIN_VERSION=2.31.6
@ -75,6 +75,7 @@ TELEPATHY_LOGGER_MIN_VERSION=0.2.4
POLKIT_MIN_VERSION=0.100
STARTUP_NOTIFICATION_MIN_VERSION=0.11
GCR_MIN_VERSION=3.3.90
GNOME_DESKTOP_REQUIRED_VERSION=3.5.1
# Collect more than 20 libraries for a prize!
PKG_CHECK_MODULES(GNOME_SHELL, gio-unix-2.0 >= $GIO_MIN_VERSION
@ -95,7 +96,8 @@ PKG_CHECK_MODULES(GNOME_SHELL, gio-unix-2.0 >= $GIO_MIN_VERSION
telepathy-logger-0.2 >= $TELEPATHY_LOGGER_MIN_VERSION
polkit-agent-1 >= $POLKIT_MIN_VERSION xfixes
libnm-glib libnm-util gnome-keyring-1
gcr-3 >= $GCR_MIN_VERSION)
gcr-3 >= $GCR_MIN_VERSION
gnome-desktop-3.0 >= $GNOME_DESKTOP_REQUIRED_VERSION)
PKG_CHECK_MODULES(SHELL_PERF_HELPER, gtk+-3.0 gio-2.0)
@ -108,8 +110,6 @@ AC_DEFINE_UNQUOTED([GJS_VERSION], ["$GJS_VERSION"], [The version of GJS we're li
AC_SUBST([GJS_VERSION], ["$GJS_VERSION"])
GOBJECT_INTROSPECTION_CHECK([$GOBJECT_INTROSPECTION_MIN_VERSION])
JHBUILD_TYPELIBDIR="$INTROSPECTION_TYPELIBDIR"
AC_SUBST(JHBUILD_TYPELIBDIR)
saved_CFLAGS=$CFLAGS
saved_LIBS=$LIBS
@ -123,7 +123,7 @@ PKG_CHECK_MODULES(GNOME_SHELL_JS, gio-2.0 gjs-internals-1.0 >= $GJS_MIN_VERSION)
PKG_CHECK_MODULES(ST, clutter-1.0 gtk+-3.0 libcroco-0.6 >= 0.6.2 x11)
PKG_CHECK_MODULES(TRAY, gtk+-3.0)
PKG_CHECK_MODULES(GVC, libpulse libpulse-mainloop-glib gobject-2.0)
PKG_CHECK_MODULES(DESKTOP_SCHEMAS, gsettings-desktop-schemas >= 0.1.7)
PKG_CHECK_MODULES(DESKTOP_SCHEMAS, gsettings-desktop-schemas >= 3.5.1)
AC_MSG_CHECKING([for bluetooth support])
PKG_CHECK_EXISTS([gnome-bluetooth-1.0 >= 3.1.0],
@ -239,31 +239,6 @@ AC_ARG_ENABLE(jhbuild-wrapper-script,
AS_HELP_STRING([--enable-jhbuild-wrapper-script],[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([location of system Certificate Authority list])
AC_ARG_WITH(ca-certificates,
[AC_HELP_STRING([--with-ca-certificates=@<:@path@:>@],
[path to system Certificate Authority list])])
if test "$with_ca_certificates" = "no"; then
AC_MSG_RESULT([disabled])
else
if test -z "$with_ca_certificates"; then
for f in /etc/pki/tls/certs/ca-bundle.crt \
/etc/ssl/certs/ca-certificates.crt; do
if test -f "$f"; then
with_ca_certificates="$f"
fi
done
if test -z "$with_ca_certificates"; then
AC_MSG_ERROR([could not find. Use --with-ca-certificates=path to set, or --without-ca-certificates to disable])
fi
fi
AC_MSG_RESULT($with_ca_certificates)
AC_DEFINE_UNQUOTED(SHELL_SYSTEM_CA_FILE, ["$with_ca_certificates"], [The system TLS CA list])
fi
AC_SUBST(SHELL_SYSTEM_CA_FILE,["$with_ca_certificates"])
BROWSER_PLUGIN_DIR="${BROWSER_PLUGIN_DIR:-"\${libdir}/mozilla/plugins"}"
AC_ARG_VAR([BROWSER_PLUGIN_DIR],[Where to install the plugin to])

View File

@ -53,7 +53,7 @@ dist_theme_DATA = \
theme/ws-switch-arrow-up.svg \
theme/ws-switch-arrow-down.svg
gsettings_SCHEMAS = org.gnome.shell.gschema.xml
gsettings_SCHEMAS = org.gnome.shell.gschema.xml org.gnome.shell.evolution.calendar.gschema.xml
@INTLTOOL_XML_NOMERGE_RULE@
@GSETTINGS_RULES@
@ -80,6 +80,7 @@ EXTRA_DIST = \
$(menu_DATA) \
$(shaders_DATA) \
$(convert_DATA) \
org.gnome.shell.evolution.calendar.gschema.xml.in \
org.gnome.shell.gschema.xml.in
CLEANFILES = \

View File

@ -0,0 +1,21 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- NOTE: This schema is a GNOME 3.4 workaround - it uses the same path
as org.gnome.evolution.calendar, but avoids us requiring Evolution
be installed. In GNOME 3.6 the selected state will become a flag
on the calendar. Because the translations are in Evolution,
this is untranslated and in POTFILES.skip.
-->
<schemalist>
<schema path="/org/gnome/evolution/calendar/" id="org.gnome.shell.evolution.calendar" gettext-domain="evolution">
<key type="as" name="selected-calendars">
<default>[]</default>
<summary>List of selected calendars</summary>
<description>List of calendars to load</description>
</key>
<key type="as" name="selected-tasks">
<default>[]</default>
<summary>List of selected task lists</summary>
<description>List of task lists to load</description>
</key>
</schema>
</schemalist>

View File

@ -88,6 +88,13 @@ value here is from the GsmPresenceStatus enumeration.</_summary>
Keybinding to open the application menu.
</_description>
</key>
<key name="toggle-recording" type="as">
<default><![CDATA[['<Control><Shift><Alt>r']]]></default>
<_summary>Keybinding to toggle the screen recorder</_summary>
<_description>
Keybinding to start/stop the builtin screen recorder.
</_description>
</key>
</schema>
<schema id="org.gnome.shell.keyboard" path="/org/gnome/shell/keyboard/"

View File

@ -328,6 +328,11 @@ StScrollBar StButton#vhandle:hover
background-gradient-end: rgba(255, 255, 255, 0.2);
}
.notification-icon-button:insensitive,
.notification-button:insensitive {
color: #9f9f9f;
}
/* Panel */
#panel {
@ -357,7 +362,7 @@ StScrollBar StButton#vhandle:hover
}
.panel-corner {
-panel-corner-radius: 10px;
-panel-corner-radius: 6px;
-panel-corner-background-color: black;
-panel-corner-border-width: 2px;
-panel-corner-border-color: transparent;
@ -409,7 +414,7 @@ StScrollBar StButton#vhandle:hover
.panel-button:active,
.panel-button:overview,
.panel-button:focus {
border-image: url("panel-button-border.svg") 10 10 0 2;
border-image: url("panel-button-border.svg") 6 10 0 2;
background-image: url("panel-button-highlight-wide.svg");
color: white;
text-shadow: black 0px 2px 2px;
@ -1203,7 +1208,8 @@ StScrollBar StButton#vhandle:hover
height: 36px;
}
#notification {
.notification {
font-size: 11pt;
border-radius: 10px 10px 0px 0px;
background: rgba(0,0,0,0.8);
padding: 8px 8px 4px 8px;
@ -1212,7 +1218,7 @@ StScrollBar StButton#vhandle:hover
width: 34em;
}
#notification.multi-line-notification {
.notification.multi-line-notification {
padding-bottom: 8px;
}
@ -1234,7 +1240,7 @@ StScrollBar StButton#vhandle:hover
color: white;
}
.summary-boxpointer #notification {
.summary-boxpointer .notification {
border-radius: 9px;
background: rgba(0,0,0,0) !important;
padding-bottom: 12px;
@ -1251,10 +1257,6 @@ StScrollBar StButton#vhandle:hover
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;
}
@ -1263,28 +1265,24 @@ StScrollBar StButton#vhandle:hover
padding-left: 8px;
}
#notification-scrollview {
.notification-scrollview {
max-height: 10em;
-st-vfade-offset: 24px;
}
#notification-scrollview > .top-shadow, #notification-scrollview > .bottom-shadow {
height: 1em;
}
#notification-scrollview:ltr > StScrollBar {
.notification-scrollview:ltr > StScrollBar {
padding-left: 6px;
}
#notification-scrollview:rtl > StScrollBar {
.notification-scrollview:rtl > StScrollBar {
padding-right: 6px;
}
#notification-body {
.notification-body {
spacing: 5px;
}
#notification-actions {
.notification-actions {
spacing: 10px;
}
@ -1411,7 +1409,7 @@ StScrollBar StButton#vhandle:hover
font-style: italic;
}
#notification StEntry {
.notification StEntry {
padding: 4px;
border-radius: 4px;
color: #a8a8a8;
@ -1427,7 +1425,7 @@ StScrollBar StButton#vhandle:hover
caret-size: 1px;
}
#notification StEntry:focus {
.notification StEntry:focus {
border: 1px solid #8b8b8b;
color: #333333;
background-gradient-direction: vertical;
@ -1950,10 +1948,12 @@ StScrollBar StButton#vhandle:hover
padding-bottom: 8px;
}
/* intentionally left transparent to avoid dialog changing size */
.hidden {
color: rgba(0,0,0,0);
}
.prompt-dialog-null-label {
font-size: 10pt;
color: rgba(0,0,0,0);
padding-bottom: 8px;
}

View File

@ -9,7 +9,7 @@
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"
width="17"
height="10"
id="svg2"
version="1.1"
@ -66,9 +66,9 @@
<rect
style="opacity:0.8;fill:#ffffff;fill-opacity:1;stroke-width:0.43599999;stroke-miterlimit:4;stroke-dasharray:none"
id="rect3796"
width="3"
width="7"
height="2"
x="9"
x="5"
y="8" />
</g>
</svg>

Before

Width:  |  Height:  |  Size: 2.0 KiB

After

Width:  |  Height:  |  Size: 2.0 KiB

View File

@ -28,7 +28,6 @@ nobase_dist_js_DATA = \
misc/config.js \
misc/extensionUtils.js \
misc/fileUtils.js \
misc/format.js \
misc/gnomeSession.js \
misc/history.js \
misc/jsParse.js \
@ -67,6 +66,7 @@ nobase_dist_js_DATA = \
ui/messageTray.js \
ui/modalDialog.js \
ui/networkAgent.js \
ui/sessionMode.js \
ui/shellEntry.js \
ui/shellMountOperation.js \
ui/notificationDaemon.js \

View File

@ -6,11 +6,11 @@ const GObject = imports.gi.GObject;
const Gio = imports.gi.Gio;
const Gtk = imports.gi.Gtk;
const Pango = imports.gi.Pango;
const Format = imports.format;
const _ = Gettext.gettext;
const Config = imports.misc.config;
const Format = imports.misc.format;
const ExtensionUtils = imports.misc.extensionUtils;
@ -210,7 +210,7 @@ const Application = new Lang.Class({
try {
extension = ExtensionUtils.createExtensionObject(uuid, dir, type);
} catch(e) {
global.logError('' + e);
logError(e, 'Could not create extensions object');
return;
}
@ -257,7 +257,7 @@ function initEnvironment() {
},
logError: function(s) {
global.log('ERROR: ' + s);
log('ERROR: ' + s);
},
userdatadir: GLib.build_filenamev([GLib.get_user_data_dir(), 'gnome-shell'])

View File

@ -11,10 +11,17 @@ const FprintManagerIface = <interface name='net.reactivated.Fprint.Manager'>
</method>
</interface>;
const FprintManagerProxy = Gio.DBusProxy.makeProxyWrapper(FprintManagerIface);
const FprintManagerInfo = Gio.DBusInterfaceInfo.new_for_xml(FprintManagerIface);
function FprintManager() {
return new FprintManagerProxy(Gio.DBus.system,
'net.reactivated.Fprint',
'/net/reactivated/Fprint/Manager');
};
var self = new Gio.DBusProxy({ g_connection: Gio.DBus.system,
g_interface_name: FprintManagerInfo.name,
g_interface_info: FprintManagerInfo,
g_name: 'net.reactivated.Fprint',
g_object_path: '/net/reactivated/Fprint/Manager',
g_flags: (Gio.DBusProxyFlags.DO_NOT_AUTO_START |
Gio.DBusProxyFlags.DO_NOT_LOAD_PROPERTIES) });
self.init(null);
return self;
}

View File

@ -60,10 +60,8 @@ const PowerMenuButton = new Lang.Class({
},
_updateVisibility: function() {
if (!this._haveSuspend && !this._haveShutdown && !this._haveRestart)
this.actor.hide();
else
this.actor.show();
let shouldBeVisible = (this._haveSuspend || this._haveShutdown || this._haveRestart);
this.actor.visible = shouldBeVisible;
},
_updateHaveShutdown: function() {
@ -76,11 +74,7 @@ const PowerMenuButton = new Lang.Class({
else
this._haveShutdown = false;
if (this._haveShutdown)
this._powerOffItem.actor.show();
else
this._powerOffItem.actor.hide();
this._powerOffItem.actor.visible = this._haveShutdown;
this._updateVisibility();
}));
} else {
@ -91,12 +85,7 @@ const PowerMenuButton = new Lang.Class({
else
this._haveShutdown = false;
if (this._haveShutdown) {
this._powerOffItem.actor.show();
} else {
this._powerOffItem.actor.hide();
}
this._powerOffItem.actor.visible = this._haveShutdown;
this._updateVisibility();
}));
}
@ -112,11 +101,7 @@ const PowerMenuButton = new Lang.Class({
else
this._haveRestart = false;
if (this._haveRestart)
this._restartItem.actor.show();
else
this._restartItem.actor.hide();
this._restartItem.actor.visible = this._haveRestart;
this._updateVisibility();
}));
} else {
@ -127,12 +112,7 @@ const PowerMenuButton = new Lang.Class({
else
this._haveRestart = false;
if (this._haveRestart) {
this._restartItem.actor.show();
} else {
this._restartItem.actor.hide();
}
this._restartItem.actor.visible = this._haveRestart;
this._updateVisibility();
}));
}
@ -140,12 +120,7 @@ const PowerMenuButton = new Lang.Class({
_updateHaveSuspend: function() {
this._haveSuspend = this._upClient.get_can_suspend();
if (this._haveSuspend)
this._suspendItem.actor.show();
else
this._suspendItem.actor.hide();
this._suspendItem.actor.visible = this._haveSuspend;
this._updateVisibility();
},

View File

@ -8,8 +8,6 @@ const PACKAGE_VERSION = '@PACKAGE_VERSION@';
const GJS_VERSION = '@GJS_VERSION@';
/* 1 if gnome-bluetooth is available, 0 otherwise */
const HAVE_BLUETOOTH = @HAVE_BLUETOOTH@;
/* The system TLS CA list */
const SHELL_SYSTEM_CA_FILE = '@SHELL_SYSTEM_CA_FILE@';
/* gettext package */
const GETTEXT_PACKAGE = '@GETTEXT_PACKAGE@';
/* locale dir */

View File

@ -40,13 +40,18 @@ function getCurrentExtension() {
throw new Error('Could not find current extension');
let path = match[1];
let uuid = GLib.path_get_basename(GLib.path_get_dirname(path));
let file = Gio.File.new_for_path(path);
let extension = extensions[uuid];
if (extension === undefined)
throw new Error('Could not find current extension');
// Walk up the directory tree, looking for an extesion with
// the same UUID as a directory name.
while (file != null) {
let extension = extensions[file.get_basename()];
if (extension !== undefined)
return extension;
file = file.get_parent();
}
return extension;
throw new Error('Could not find current extension');
}
/**
@ -120,7 +125,7 @@ function createExtensionObject(uuid, dir, type) {
// Encourage people to add this
if (!meta.url) {
global.log('Warning: Missing "url" property in metadata.json');
log('Warning: Missing "url" property in %s/metadata.json'.format(uuid));
}
if (uuid != meta.uuid) {
@ -157,7 +162,7 @@ function init() {
if (!userExtensionsDir.query_exists(null))
userExtensionsDir.make_directory_with_parents(null);
} catch (e) {
global.logError('' + e);
logError(e, 'Could not create extensions directory');
}
}
@ -167,7 +172,7 @@ function scanExtensionsInDirectory(callback, dir, type) {
try {
fileEnum = dir.enumerate_children('standard::*', Gio.FileQueryInfoFlags.NONE, null);
} catch(e) {
global.logError('' + e);
logError(e, 'Could not enumerate extensions directory');
return;
}

View File

@ -1,71 +0,0 @@
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
const ShellJS = imports.gi.ShellJS;
/*
* This function is intended to extend the String object and provide
* an String.format API for string formatting.
* It has to be set up using String.prototype.format = Format.format;
* Usage:
* "somestring %s %d".format('hello', 5);
* It supports %s, %d, %x and %f, for %f it also support precisions like
* "%.2f".format(1.526). All specifiers can be prefixed with a minimum
* field width, e.g. "%5s".format("foo"). Unless the width is prefixed
* with '0', the formatted string will be padded with spaces.
*/
function format() {
let str = this;
let i = 0;
let args = arguments;
return str.replace(/%(I+)?([0-9]+)?(?:\.([0-9]+))?(.)/g, function (str, flagsGroup, widthGroup, precisionGroup, genericGroup) {
if (precisionGroup != '' && genericGroup != 'f')
throw new Error("Precision can only be specified for 'f'");
let hasAlternativeIntFlag = (flagsGroup.indexOf('I') != -1);
if (hasAlternativeIntFlag && genericGroup != 'd')
throw new Error("Alternative output digits can only be specfied for 'd'");
let fillChar = (widthGroup[0] == '0') ? '0' : ' ';
let width = parseInt(widthGroup, 10) || 0;
function fillWidth(s, c, w) {
let fill = '';
for (let i = 0; i < w; i++)
fill += c;
return fill.substr(s.length) + s;
}
let s = '';
switch (genericGroup) {
case '%':
return '%';
break;
case 's':
s = args[i++].toString();
break;
case 'd':
let intV = parseInt(args[i++]);
if (hasAlternativeIntFlag)
s = ShellJS.format_int_alternative_output(intV);
else
s = intV.toString();
break;
case 'x':
s = parseInt(args[i++]).toString(16);
break;
case 'f':
if (precisionGroup == '')
s = parseFloat(args[i++]).toString();
else
s = parseFloat(args[i++]).toFixed(parseInt(precisionGroup));
break;
default:
throw new Error('Unsupported conversion character %' + genericGroup);
}
return fillWidth(s, fillChar, width);
});
}

View File

@ -83,10 +83,11 @@ function spawnCommandLine(command_line) {
// this will throw an error.
function trySpawn(argv)
{
var success, pid;
try {
GLib.spawn_async(null, argv, null,
GLib.SpawnFlags.SEARCH_PATH,
null, null);
[success, pid] = GLib.spawn_async(null, argv, null,
GLib.SpawnFlags.SEARCH_PATH | GLib.SpawnFlags.DO_NOT_REAP_CHILD,
null, null);
} catch (err) {
if (err.code == GLib.SpawnError.G_SPAWN_ERROR_NOENT) {
err.message = _("Command not found");
@ -101,6 +102,10 @@ function trySpawn(argv)
throw err;
}
// Dummy child watch; we don't want to double-fork internally
// because then we lose the parent-child relationship, which
// can break polkit. See https://bugzilla.redhat.com//show_bug.cgi?id=819275
GLib.child_watch_add(GLib.PRIORITY_DEFAULT, pid, function () {}, null);
}
// trySpawnCommandLine:

View File

@ -312,11 +312,10 @@ const AppSearchProvider = new Lang.Class({
_init: function() {
this.parent(_("APPLICATIONS"));
this._appSys = Shell.AppSystem.get_default();
},
getResultMetas: function(apps) {
getResultMetas: function(apps, callback) {
let metas = [];
for (let i = 0; i < apps.length; i++) {
let app = apps[i];
@ -327,15 +326,15 @@ const AppSearchProvider = new Lang.Class({
}
});
}
return metas;
callback(metas);
},
getInitialResultSet: function(terms) {
return this._appSys.initial_search(terms);
this.searchSystem.pushResults(this, this._appSys.initial_search(terms));
},
getSubsearchResultSet: function(previousResults, terms) {
return this._appSys.subsearch(previousResults, terms);
this.searchSystem.pushResults(this, this._appSys.subsearch(previousResults, terms));
},
activateResult: function(app, params) {
@ -378,7 +377,7 @@ const SettingsSearchProvider = new Lang.Class({
this._gnomecc = this._appSys.lookup_app('gnome-control-center.desktop');
},
getResultMetas: function(prefs) {
getResultMetas: function(prefs, callback) {
let metas = [];
for (let i = 0; i < prefs.length; i++) {
let pref = prefs[i];
@ -389,15 +388,15 @@ const SettingsSearchProvider = new Lang.Class({
}
});
}
return metas;
callback(metas);
},
getInitialResultSet: function(terms) {
return this._appSys.search_settings(terms);
this.searchSystem.pushResults(this, this._appSys.search_settings(terms));
},
getSubsearchResultSet: function(previousResults, terms) {
return this._appSys.search_settings(terms);
this.searchSystem.pushResults(this, this._appSys.search_settings(terms));
},
activateResult: function(pref, params) {

View File

@ -262,12 +262,11 @@ const AutorunResidentSource = new Lang.Class({
Extends: MessageTray.Source,
_init: function() {
this.parent(_("Removable Devices"));
this.parent(_("Removable Devices"), 'media-removable', St.IconType.FULLCOLOR);
this._mounts = [];
this._notification = new AutorunResidentNotification(this);
this._setSummaryIcon(this.createNotificationIcon());
},
addMount: function(mount, apps) {
@ -310,12 +309,6 @@ const AutorunResidentSource = new Lang.Class({
Main.messageTray.add(this);
this.pushNotification(this._notification);
}
},
createNotificationIcon: function() {
return new St.Icon ({ icon_name: 'media-removable',
icon_type: St.IconType.FULLCOLOR,
icon_size: this.ICON_SIZE });
}
});
@ -500,11 +493,11 @@ const AutorunTransientSource = new Lang.Class({
Extends: MessageTray.Source,
_init: function(mount, apps) {
this.parent(mount.get_name());
this.mount = mount;
this.apps = apps;
this.parent(mount.get_name());
this._notification = new AutorunTransientNotification(this);
this._setSummaryIcon(this.createNotificationIcon());

View File

@ -63,7 +63,7 @@ const Contact = new Lang.Class({
this.individual.full_name ||
this.individual.nickname ||
email ||
_("Unknown");
C_("contact", "Unknown");
let aliasLabel = new St.Label({ text: aliasText,
style_class: 'contact-details-alias' });
details.add(aliasLabel, { x_fill: true,
@ -154,7 +154,7 @@ const ContactSearchProvider = new Lang.Class({
this._contactSys = Shell.ContactSystem.get_default();
},
getResultMetas: function(ids) {
getResultMetas: function(ids, callback) {
let metas = [];
for (let i = 0; i < ids.length; i++) {
let contact = new Contact(ids[i]);
@ -165,15 +165,15 @@ const ContactSearchProvider = new Lang.Class({
}
});
}
return metas;
callback(metas);
},
getInitialResultSet: function(terms) {
return this._contactSys.initial_search(terms);
this.searchSystem.pushResults(this, this._contactSys.initial_search(terms));
},
getSubsearchResultSet: function(previousResults, terms) {
return this._contactSys.subsearch(previousResults, terms);
this.searchSystem.pushResults(this, this._contactSys.subsearch(previousResults, terms));
},
createResultActor: function(resultMeta, terms) {

View File

@ -168,7 +168,17 @@ const DashItemContainer = new Lang.Class({
});
},
destroy: function() {
if (this.label)
this.label.destroy();
this.actor.destroy();
},
animateOutAndDestroy: function() {
if (this.label)
this.label.destroy();
if (this.child == null) {
this.actor.destroy();
return;
@ -691,7 +701,7 @@ const Dash = new Lang.Class({
if (Main.overview.visible)
item.animateOutAndDestroy();
else
item.actor.destroy();
item.destroy();
}
this._adjustIconSize();

View File

@ -45,9 +45,7 @@ const DateMenuButton = new Lang.Class({
Name: 'DateMenuButton',
Extends: PanelMenu.Button,
_init: function(params) {
params = Params.parse(params, { showEvents: true });
_init: function() {
let item;
let hbox;
let vbox;
@ -75,11 +73,11 @@ const DateMenuButton = new Lang.Class({
// Date
this._date = new St.Label();
this.actor.label_actor = this._date;
this.actor.label_actor = this._clock;
this._date.style_class = 'datemenu-date-label';
vbox.add(this._date);
if (params.showEvents) {
if (Main.sessionMode.showCalendarEvents) {
this._eventSource = new Calendar.DBusEventSource();
this._eventList = new Calendar.EventsList(this._eventSource);
} else {
@ -110,7 +108,7 @@ const DateMenuButton = new Lang.Class({
item.actor.reparent(vbox);
}
if (params.showEvents) {
if (Main.sessionMode.showCalendarEvents) {
// Add vertical separator
item = new St.DrawingArea({ style_class: 'calendar-vertical-separator',

View File

@ -342,7 +342,7 @@ const EndSessionDialog = new Lang.Class({
}
},
_updateContent: function() {
_updateDescription: function() {
if (this.state != ModalDialog.State.OPENING &&
this.state != ModalDialog.State.OPENED)
return;
@ -352,17 +352,6 @@ const EndSessionDialog = new Lang.Class({
let subject = dialogContent.subject;
let description;
if (this._user.is_loaded && !dialogContent.iconName) {
let iconFile = this._user.get_icon_file();
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);
}
if (this._inhibitors.length > 0) {
this._stopTimer();
description = dialogContent.inhibitedDescription;
@ -395,6 +384,27 @@ const EndSessionDialog = new Lang.Class({
_setLabelText(this._descriptionLabel, description);
},
_updateContent: function() {
if (this.state != ModalDialog.State.OPENING &&
this.state != ModalDialog.State.OPENED)
return;
let dialogContent = DialogContent[this._type];
if (this._user.is_loaded && !dialogContent.iconName) {
let iconFile = this._user.get_icon_file();
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);
}
this._updateDescription();
},
_updateButtons: function() {
let dialogContent = DialogContent[this._type];
let buttons = [{ action: Lang.bind(this, this.cancel),
@ -441,7 +451,7 @@ const EndSessionDialog = new Lang.Class({
{ _secondsLeft: 0,
time: this._secondsLeft,
transition: 'linear',
onUpdate: Lang.bind(this, this._updateContent),
onUpdate: Lang.bind(this, this._updateDescription),
onComplete: Lang.bind(this, function() {
let dialogContent = DialogContent[this._type];
let button = dialogContent.confirmButtons[dialogContent.confirmButtons.length - 1];

View File

@ -39,11 +39,19 @@ function _patchContainerClass(containerClass) {
};
}
function _makeLoggingFunc(func) {
return function() {
return func([].join.call(arguments, ', '));
};
}
function init() {
// Add some bindings to the global JS namespace; (gjs keeps the web
// browser convention of having that namespace be called 'window'.)
window.global = Shell.Global.get();
window.log = _makeLoggingFunc(window.log);
window._ = Gettext.gettext;
window.C_ = Gettext.pgettext;
window.ngettext = Gettext.ngettext;
@ -82,7 +90,7 @@ function init() {
}
// OK, now things are initialized enough that we can import shell JS
const Format = imports.misc.format;
const Format = imports.format;
const Tweener = imports.ui.tweener;
Tweener.init();

View File

@ -34,24 +34,11 @@ const REPOSITORY_URL_BASE = 'https://extensions.gnome.org';
const REPOSITORY_URL_DOWNLOAD = REPOSITORY_URL_BASE + '/download-extension/%s.shell-extension.zip';
const REPOSITORY_URL_INFO = REPOSITORY_URL_BASE + '/extension-info/';
const _httpSession = new Soup.SessionAsync();
const _httpSession = new Soup.SessionAsync({ ssl_use_system_ca_file: true });
// The unfortunate state of gjs, gobject-introspection and libsoup
// means that I have to do a hack to add a feature.
// See: https://bugzilla.gnome.org/show_bug.cgi?id=655189 for context.
if (Soup.Session.prototype.add_feature != null)
Soup.Session.prototype.add_feature.call(_httpSession, new Soup.ProxyResolverDefault());
function _getCertFile() {
let localCert = GLib.build_filenamev([global.userdatadir, 'extensions.gnome.org.crt']);
if (GLib.file_test(localCert, GLib.FileTest.EXISTS))
return localCert;
else
return Config.SHELL_SYSTEM_CA_FILE;
}
_httpSession.ssl_ca_file = _getCertFile();
// _httpSession.add_feature(new Soup.ProxyResolverDefault());
Soup.Session.prototype.add_feature.call(_httpSession, new Soup.ProxyResolverDefault());
// Arrays of uuids
var enabledExtensions;
@ -69,18 +56,16 @@ const disconnect = Lang.bind(_signals, _signals.disconnect);
const ENABLED_EXTENSIONS_KEY = 'enabled-extensions';
function installExtensionFromUUID(uuid, version_tag) {
function installExtensionFromUUID(uuid) {
let params = { uuid: uuid,
version_tag: version_tag,
shell_version: Config.PACKAGE_VERSION,
api_version: API_VERSION.toString() };
shell_version: Config.PACKAGE_VERSION };
let message = Soup.form_request_new_from_hash('GET', REPOSITORY_URL_INFO, params);
_httpSession.queue_message(message,
function(session, message) {
let info = JSON.parse(message.response_body.data);
let dialog = new InstallExtensionDialog(uuid, version_tag, info.name);
let dialog = new InstallExtensionDialog(uuid, info);
dialog.open(global.get_current_time());
});
}
@ -115,21 +100,13 @@ function gotExtensionZipFile(session, message, uuid) {
return;
}
// FIXME: use a GFile mkstemp-type method once one exists
let fd, tmpzip;
try {
[fd, tmpzip] = GLib.file_open_tmp('XXXXXX.shell-extension.zip');
} catch (e) {
logExtensionError(uuid, 'tempfile: ' + e.toString());
return;
}
let stream = new Gio.UnixOutputStream({ fd: fd });
let [file, stream] = Gio.File.new_tmp('XXXXXX.shell-extension.zip');
let dir = ExtensionUtils.userExtensionsDir.get_child(uuid);
Shell.write_soup_message_to_stream(stream, message);
let contents = message.response_body.flatten().as_bytes();
stream.output_stream.write_bytes(contents, null);
stream.close(null);
let [success, pid] = GLib.spawn_async(null,
['unzip', '-uod', dir.get_path(), '--', tmpzip],
['unzip', '-uod', dir.get_path(), '--', file.get_path()],
null,
GLib.SpawnFlags.SEARCH_PATH | GLib.SpawnFlags.DO_NOT_REAP_CHILD,
null);
@ -237,7 +214,7 @@ function logExtensionError(uuid, message, state) {
extension.errors = [];
extension.errors.push(message);
global.logError('Extension "%s" had error: %s'.format(uuid, message));
log('Extension "%s" had error: %s'.format(uuid, message));
state = state || ExtensionState.ERROR;
_signals.emit('extension-state-changed', { uuid: uuid,
error: message,
@ -249,7 +226,7 @@ function loadExtension(dir, type, enabled) {
let extension;
if (ExtensionUtils.extensions[uuid] != undefined) {
global.logError('Extension "%s" is already loaded'.format(uuid));
log('Extension "%s" is already loaded'.format(uuid));
return;
}
@ -278,7 +255,6 @@ function loadExtension(dir, type, enabled) {
}
_signals.emit('extension-state-changed', extension);
global.log('Loaded extension ' + uuid);
}
function initExtension(uuid) {
@ -390,12 +366,11 @@ const InstallExtensionDialog = new Lang.Class({
Name: 'InstallExtensionDialog',
Extends: ModalDialog.ModalDialog,
_init: function(uuid, version_tag, name) {
_init: function(uuid, info) {
this.parent({ styleClass: 'extension-dialog' });
this._uuid = uuid;
this._version_tag = version_tag;
this._name = name;
this._info = info;
this.setButtons([{ label: _("Cancel"),
action: Lang.bind(this, this._onCancelButtonPressed),
@ -405,13 +380,17 @@ const InstallExtensionDialog = new Lang.Class({
action: Lang.bind(this, this._onInstallButtonPressed)
}]);
let message = _("Download and install '%s' from extensions.gnome.org?").format(name);
let message = _("Download and install '%s' from extensions.gnome.org?").format(info.name);
this._descriptionLabel = new St.Label({ text: message });
let box = new St.BoxLayout();
this.contentLayout.add(box);
this.contentLayout.add(this._descriptionLabel,
{ y_fill: true,
y_align: St.Align.START });
let gicon = new Gio.FileIcon({ file: Gio.File.new_for_uri(REPOSITORY_URL_BASE + info.icon) })
let icon = new St.Icon({ gicon: gicon });
box.add(icon);
let label = new St.Label({ text: message });
box.add(label);
},
_onCancelButtonPressed: function(button, event) {
@ -435,9 +414,7 @@ const InstallExtensionDialog = new Lang.Class({
_signals.emit('extension-state-changed', state);
let params = { version_tag: this._version_tag,
shell_version: Config.PACKAGE_VERSION,
api_version: API_VERSION.toString() };
let params = { shell_version: Config.PACKAGE_VERSION };
let url = REPOSITORY_URL_DOWNLOAD.format(this._uuid);
let message = Soup.form_request_new_from_hash('GET', url, params);

View File

@ -282,6 +282,10 @@ const IconGrid = new Lang.Class({
return this._computeLayout(rowWidth)[0];
},
getRowLimit: function() {
return this._rowLimit;
},
_computeLayout: function (forWidth) {
let nColumns = 0;
let usedWidth = 0;

View File

@ -541,16 +541,8 @@ const KeyboardSource = new Lang.Class({
Extends: MessageTray.Source,
_init: function(keyboard) {
this.parent(_("Keyboard"));
this._keyboard = keyboard;
this._setSummaryIcon(this.createNotificationIcon());
},
createNotificationIcon: function() {
return new St.Icon({ icon_name: 'input-keyboard',
icon_type: St.IconType.SYMBOLIC,
icon_size: this.ICON_SIZE });
this.parent(_("Keyboard"), 'input-keyboard', St.IconType.SYMBOLIC);
},
handleSummaryClick: function() {

View File

@ -634,45 +634,6 @@ const Inspector = new Lang.Class({
Signals.addSignalMethods(Inspector.prototype);
const ErrorLog = new Lang.Class({
Name: 'ErrorLog',
_init: function() {
this.actor = new St.BoxLayout();
this.text = new St.Label();
this.actor.add(this.text);
// We need to override StLabel's default ellipsization when
// using line_wrap; otherwise ClutterText's layout is going
// to constrain both the width and height, which prevents
// scrolling.
this.text.clutter_text.ellipsize = Pango.EllipsizeMode.NONE;
this.text.clutter_text.line_wrap = true;
this.actor.connect('notify::mapped', Lang.bind(this, this._renderText));
},
_formatTime: function(d){
function pad(n) { return n < 10 ? '0' + n : n; }
return d.getUTCFullYear()+'-'
+ pad(d.getUTCMonth()+1)+'-'
+ pad(d.getUTCDate())+'T'
+ pad(d.getUTCHours())+':'
+ pad(d.getUTCMinutes())+':'
+ pad(d.getUTCSeconds())+'Z';
},
_renderText: function() {
if (!this.actor.mapped)
return;
let text = this.text.text;
let stack = Main._getAndClearErrorStack();
for (let i = 0; i < stack.length; i++) {
let logItem = stack[i];
text += logItem.category + ' t=' + this._formatTime(new Date(logItem.timestamp)) + ' ' + logItem.message + '\n';
}
this.text.text = text;
}
});
const Memory = new Lang.Class({
Name: 'Memory',
@ -947,9 +908,6 @@ const LookingGlass = new Lang.Class({
}));
notebook.appendPage('Windows', this._windowList.actor);
this._errorLog = new ErrorLog();
notebook.appendPage('Errors', this._errorLog.actor);
this._memory = new Memory();
notebook.appendPage('Memory', this._memory.actor);

View File

@ -16,6 +16,7 @@ const Params = imports.misc.params;
const MOUSE_POLL_FREQUENCY = 50;
const CROSSHAIRS_CLIP_SIZE = [100, 100];
const NO_CHANGE = 0.0;
// Settings
const APPLICATIONS_SCHEMA = 'org.gnome.desktop.a11y.applications';
@ -24,6 +25,13 @@ const SHOW_KEY = 'screen-magnifier-enabled';
const MAGNIFIER_SCHEMA = 'org.gnome.desktop.a11y.magnifier';
const SCREEN_POSITION_KEY = 'screen-position';
const MAG_FACTOR_KEY = 'mag-factor';
const INVERT_LIGHTNESS_KEY = 'invert-lightness';
const BRIGHT_RED_KEY = 'brightness-red';
const BRIGHT_GREEN_KEY = 'brightness-green';
const BRIGHT_BLUE_KEY = 'brightness-blue';
const CONTRAST_RED_KEY = 'contrast-red';
const CONTRAST_GREEN_KEY = 'contrast-green';
const CONTRAST_BLUE_KEY = 'contrast-blue';
const LENS_MODE_KEY = 'lens-mode';
const CLAMP_MODE_KEY = 'scroll-at-edges';
const MOUSE_TRACKING_KEY = 'mouse-tracking';
@ -443,6 +451,21 @@ const Magnifier = new Lang.Class({
aPref = this._settings.get_enum(MOUSE_TRACKING_KEY);
if (aPref)
zoomRegion.setMouseTrackingMode(aPref);
aPref = this._settings.get_boolean(INVERT_LIGHTNESS_KEY);
if (aPref)
zoomRegion.setInvertLightness(aPref);
let bc = {};
bc.r = this._settings.get_double(BRIGHT_RED_KEY);
bc.g = this._settings.get_double(BRIGHT_GREEN_KEY);
bc.b = this._settings.get_double(BRIGHT_BLUE_KEY);
zoomRegion.setBrightness(bc);
bc.r = this._settings.get_double(CONTRAST_RED_KEY);
bc.g = this._settings.get_double(CONTRAST_GREEN_KEY);
bc.b = this._settings.get_double(CONTRAST_BLUE_KEY);
zoomRegion.setContrast(bc);
}
let showCrosshairs = this._settings.get_boolean(SHOW_CROSS_HAIRS_KEY);
@ -465,6 +488,23 @@ const Magnifier = new Lang.Class({
this._settings.connect('changed::' + MOUSE_TRACKING_KEY,
Lang.bind(this, this._updateMouseTrackingMode));
this._settings.connect('changed::' + INVERT_LIGHTNESS_KEY,
Lang.bind(this, this._updateInvertLightness));
this._settings.connect('changed::' + BRIGHT_RED_KEY,
Lang.bind(this, this._updateBrightness));
this._settings.connect('changed::' + BRIGHT_GREEN_KEY,
Lang.bind(this, this._updateBrightness));
this._settings.connect('changed::' + BRIGHT_BLUE_KEY,
Lang.bind(this, this._updateBrightness));
this._settings.connect('changed::' + CONTRAST_RED_KEY,
Lang.bind(this, this._updateContrast));
this._settings.connect('changed::' + CONTRAST_GREEN_KEY,
Lang.bind(this, this._updateContrast));
this._settings.connect('changed::' + CONTRAST_BLUE_KEY,
Lang.bind(this, this._updateContrast));
this._settings.connect('changed::' + SHOW_CROSS_HAIRS_KEY,
Lang.bind(this, function() {
this.setCrosshairsVisible(this._settings.get_boolean(SHOW_CROSS_HAIRS_KEY));
@ -540,7 +580,38 @@ const Magnifier = new Lang.Class({
this._settings.get_enum(MOUSE_TRACKING_KEY)
);
}
}
},
_updateInvertLightness: function() {
// Applies only to the first zoom region.
if (this._zoomRegions.length) {
this._zoomRegions[0].setInvertLightness(
this._settings.get_boolean(INVERT_LIGHTNESS_KEY)
);
}
},
_updateBrightness: function() {
// Applies only to the first zoom region.
if (this._zoomRegions.length) {
let brightness = {};
brightness.r = this._settings.get_double(BRIGHT_RED_KEY);
brightness.g = this._settings.get_double(BRIGHT_GREEN_KEY);
brightness.b = this._settings.get_double(BRIGHT_BLUE_KEY);
this._zoomRegions[0].setBrightness(brightness);
}
},
_updateContrast: function() {
// Applies only to the first zoom region.
if (this._zoomRegions.length) {
let contrast = {};
contrast.r = this._settings.get_double(CONTRAST_RED_KEY);
contrast.g = this._settings.get_double(CONTRAST_GREEN_KEY);
contrast.b = this._settings.get_double(CONTRAST_BLUE_KEY);
this._zoomRegions[0].setContrast(contrast);
}
},
});
Signals.addSignalMethods(Magnifier.prototype);
@ -554,6 +625,9 @@ const ZoomRegion = new Lang.Class({
this._clampScrollingAtEdges = false;
this._lensMode = false;
this._screenPosition = GDesktopEnums.MagnifierScreenPosition.FULL_SCREEN;
this._invertLightness = false;
this._brightness = { r: NO_CHANGE, g: NO_CHANGE, b: NO_CHANGE };
this._contrast = { r: NO_CHANGE, g: NO_CHANGE, b: NO_CHANGE };
this._magView = null;
this._background = null;
@ -879,6 +953,86 @@ const ZoomRegion = new Lang.Class({
}
},
/**
* setInvertLightness:
* Set whether to invert the lightness of the magnified view.
* @flag Boolean to either invert brightness (true), or not (false).
*/
setInvertLightness: function(flag) {
this._invertLightness = flag;
if (this._magShaderEffects)
this._magShaderEffects.setInvertLightness(this._invertLightness);
},
/**
* getInvertLightness:
* Retrieve whether the lightness is inverted.
* @return Boolean indicating inversion (true), or not (false).
*/
getInvertLightness: function() {
return this._invertLightness;
},
/**
* setBrightness:
* Alter the brightness of the magnified view.
* @brightness Object containing the contrast for the red, green,
* and blue channels. Values of 0.0 represent "standard"
* brightness (no change), whereas values less or greater than
* 0.0 indicate decreased or incresaed brightness, respectively.
*/
setBrightness: function(brightness) {
this._brightness.r = brightness.r;
this._brightness.g = brightness.g;
this._brightness.b = brightness.b;
if (this._magShaderEffects)
this._magShaderEffects.setBrightness(this._brightness);
},
/**
* getBrightness:
* Retrive the current brightness of the Zoom Region.
* @return Object containing the brightness change for the red, green,
* and blue channels.
*/
getBrightness: function() {
let brightness = {};
brightness.r = this._brightness.r;
brightness.g = this._brightness.g;
brightness.b = this._brightness.b;
return brightness;
},
/**
* setContrast:
* Alter the contrast of the magnified view.
* @contrast Object containing the contrast for the red, green,
* and blue channels. Values of 0.0 represent "standard"
* contrast (no change), whereas values less or greater than
* 0.0 indicate decreased or incresaed contrast, respectively.
*/
setContrast: function(contrast) {
this._contrast.r = contrast.r;
this._contrast.g = contrast.g;
this._contrast.b = contrast.b;
if (this._magShaderEffects)
this._magShaderEffects.setContrast(this._contrast);
},
/**
* getContrast:
* Retreive the contrast of the magnified view.
* @return Object containing the contrast for the red, green,
* and blue channels.
*/
getContrast: function() {
let contrast = {};
contrast.r = this._contrast.r;
contrast.g = this._contrast.g;
contrast.b = this._contrast.b;
return contrast;
},
//// Private methods ////
_createActors: function() {
@ -917,6 +1071,12 @@ const ZoomRegion = new Lang.Class({
this._crossHairsActor = this._crossHairs.addToZoomRegion(this, this._mouseActor);
else
this._crossHairsActor = null;
// Contrast and brightness effects.
this._magShaderEffects = new MagShaderEffects(this._uiGroupClone);
this._magShaderEffects.setInvertLightness(this._invertLightness);
this._magShaderEffects.setBrightness(this._brightness);
this._magShaderEffects.setContrast(this._contrast);
},
_destroyActors: function() {
@ -925,6 +1085,8 @@ const ZoomRegion = new Lang.Class({
if (this._crossHairs)
this._crossHairs.removeFromParent(this._crossHairsActor);
this._magShaderEffects.destroyEffects();
this._magShaderEffects = null;
this._magView.destroy();
this._magView = null;
this._background = null;
@ -1228,10 +1390,7 @@ const Crosshairs = new Lang.Class({
crosshairsActor = new Clutter.Clone({ source: this._actor });
this._clones.push(crosshairsActor);
}
if (this._actor.visible)
crosshairsActor.show();
else
crosshairsActor.hide();
crosshairsActor.visible = this._actor.visible;
container.add_actor(crosshairsActor);
container.raise_child(magnifiedMouse, crosshairsActor);
@ -1436,3 +1595,133 @@ const Crosshairs = new Lang.Class({
this._vertBottomHair.set_position((groupWidth - thickness) / 2, bottom);
}
});
const MagShaderEffects = new Lang.Class({
Name: 'MagShaderEffects',
_init: function(uiGroupClone) {
this._inverse = new Shell.InvertLightnessEffect();
this._brightnessContrast = new Clutter.BrightnessContrastEffect();
this._inverse.set_enabled(false);
this._brightnessContrast.set_enabled(false);
this._magView = uiGroupClone;
this._magView.add_effect(this._inverse);
this._magView.add_effect(this._brightnessContrast);
},
/**
* destroyEffects:
* Remove contrast and brightness effects from the magnified view, and
* lose the reference to the actor they were applied to. Don't use this
* object after calling this.
*/
destroyEffects: function() {
this._magView.clear_effects();
this._brightnessContrast = null;
this._inverse = null;
this._magView = null;
},
/**
* setInvertLightness:
* Enable/disable invert lightness effect.
* @invertFlag: Enabled flag.
*/
setInvertLightness: function(invertFlag) {
this._inverse.set_enabled(invertFlag);
},
/**
* getInvertLightness:
* Report whether the inversion effect is enabled.
* @return: Boolean.
*/
getInvertLightness: function() {
return this._inverse.get_enabled();
},
/**
* setBrightness:
* Set the brightness of the magnified view.
* @brightness: Object containing the brightness for the red, green,
* and blue channels. Values of 0.0 represent "standard"
* brightness (no change), whereas values less or greater than
* 0.0 indicate decreased or incresaed brightness,
* respectively.
*/
setBrightness: function(brightness) {
let bRed = brightness.r;
let bGreen = brightness.g;
let bBlue = brightness.b;
this._brightnessContrast.set_brightness_full(bRed, bGreen, bBlue);
// Enable the effect if the brightness OR contrast change are such that
// it modifies the brightness and/or contrast.
let [cRed, cGreen, cBlue] = this._brightnessContrast.get_contrast();
this._brightnessContrast.set_enabled(
(bRed != NO_CHANGE || bGreen != NO_CHANGE || bBlue != NO_CHANGE ||
cRed != NO_CHANGE || cGreen != NO_CHANGE || cBlue != NO_CHANGE)
);
},
/**
* getBrightness:
* Retrieve current brightness of the magnified view.
* @return: Object containing the brightness for the red, green,
* and blue channels. Values of 0.0 represent "standard"
* brightness (no change), whereas values less or greater than
* 0.0 indicate decreased or incresaed brightness, respectively.
*/
getBrightness: function() {
let result = {};
let [bRed, bGreen, bBlue] = this._brightnessContrast.get_brightness();
result.r = bRed;
result.g = bGreen;
result.b = bBlue;
return result;
},
/**
* Set the contrast of the magnified view.
* @contrast: Object containing the contrast for the red, green,
* and blue channels. Values of 0.0 represent "standard"
* contrast (no change), whereas values less or greater than
* 0.0 indicate decreased or incresaed contrast, respectively.
*/
setContrast: function(contrast) {
let cRed = contrast.r;
let cGreen = contrast.g;
let cBlue = contrast.b;
this._brightnessContrast.set_contrast_full(cRed, cGreen, cBlue);
// Enable the effect if the contrast OR brightness change are such that
// it modifies the brightness and/or contrast.
// should be able to use Clutter.color_equal(), but that complains of
// a null first argument.
let [bRed, bGreen, bBlue] = this._brightnessContrast.get_brightness();
this._brightnessContrast.set_enabled(
cRed != NO_CHANGE || cGreen != NO_CHANGE || cBlue != NO_CHANGE ||
bRed != NO_CHANGE || bGreen != NO_CHANGE || bBlue != NO_CHANGE
);
},
/**
* Retrieve current contrast of the magnified view.
* @return: Object containing the contrast for the red, green,
* and blue channels. Values of 0.0 represent "standard"
* contrast (no change), whereas values less or greater than
* 0.0 indicate decreased or incresaed contrast, respectively.
*/
getContrast: function() {
let resutl = {};
let [cRed, cGreen, cBlue] = this._brightnessContrast.get_contrast();
result.r = cRed;
result.g = cGreen;
result.b = cBlue;
return result;
}
});

View File

@ -30,6 +30,7 @@ const NetworkAgent = imports.ui.networkAgent;
const NotificationDaemon = imports.ui.notificationDaemon;
const WindowAttentionHandler = imports.ui.windowAttentionHandler;
const Scripting = imports.ui.scripting;
const SessionMode = imports.ui.sessionMode;
const ShellDBus = imports.ui.shellDBus;
const TelepathyClient = imports.ui.telepathyClient;
const WindowManager = imports.ui.windowManager;
@ -46,7 +47,6 @@ let automountManager = null;
let autorunManager = null;
let panel = null;
let hotCorners = [];
let placesManager = null;
let overview = null;
let runDialog = null;
let lookingGlass = null;
@ -57,6 +57,7 @@ let windowAttentionHandler = null;
let telepathyClient = null;
let ctrlAltTabManager = null;
let recorder = null;
let sessionMode = null;
let shellDBusService = null;
let modalCount = 0;
let modalActorFocusStack = [];
@ -67,28 +68,27 @@ let statusIconDispatcher = null;
let keyboard = null;
let layoutManager = null;
let networkAgent = null;
let _errorLogStack = [];
let _startDate;
let _defaultCssStylesheet = null;
let _cssStylesheet = null;
let _gdmCssStylesheet = null;
let _overridesSettings = null;
let background = null;
function _createUserSession() {
function createUserSession() {
// Load the calendar server. Note that we are careful about
// not loading any events until the user presses the clock
global.launch_calendar_server();
placesManager = new PlaceDisplay.PlacesManager();
telepathyClient = new TelepathyClient.Client();
automountManager = new AutomountManager.AutomountManager();
autorunManager = new AutorunManager.AutorunManager();
networkAgent = new NetworkAgent.NetworkAgent();
_initRecorder();
}
function _createGDMSession() {
function createGDMSession() {
// We do this this here instead of at the top to prevent GDM
// related code from getting loaded in normal user sessions
const LoginDialog = imports.gdm.loginDialog;
@ -99,18 +99,26 @@ function _createGDMSession() {
});
}
function createInitialSetupSession() {
networkAgent = new NetworkAgent.NetworkAgent();
}
function _initRecorder() {
let recorderSettings = new Gio.Settings({ schema: 'org.gnome.shell.recorder' });
let desktopLockdownSettings = new Gio.Settings({ schema: 'org.gnome.desktop.lockdown' });
let bindingSettings = new Gio.Settings({ schema: 'org.gnome.shell.keybindings' });
global.screen.connect('toggle-recording', function() {
global.display.add_keybinding('toggle-recording',
bindingSettings,
Meta.KeyBindingFlags.NONE, function() {
if (recorder == null) {
recorder = new Shell.Recorder({ stage: global.stage });
}
if (recorder.is_recording()) {
recorder.pause();
recorder.close();
Meta.enable_unredirect_for_screen(global.screen);
} else {
} else if (!desktopLockdownSettings.get_boolean('disable-save-to-disk')) {
// read the parameters from GSettings always in case they have changed
recorder.set_framerate(recorderSettings.get_int('framerate'));
/* Translators: this is a filename used for screencast recording */
@ -129,38 +137,17 @@ function _initRecorder() {
});
}
function _initUserSession() {
_initRecorder();
global.screen.override_workspace_layout(Meta.ScreenCorner.TOPLEFT, false, -1, 1);
ExtensionSystem.init();
ExtensionSystem.loadExtensions();
Meta.keybindings_set_custom_handler('panel-run-dialog', function() {
getRunDialog().open();
});
Meta.keybindings_set_custom_handler('panel-main-menu', function () {
overview.toggle();
});
global.display.connect('overlay-key', Lang.bind(overview, overview.toggle));
}
function start() {
// Monkey patch utility functions into the global proxy;
// This is easier and faster than indirecting down into global
// if we want to call back up into JS.
global.logError = _logError;
global.log = _logDebug;
// These are here so we don't break compatibility.
global.logError = window.log;
global.log = window.log;
// Chain up async errors reported from C
global.connect('notify-error', function (global, msg, detail) { notifyError(msg, detail); });
Gio.DesktopAppInfo.set_desktop_env('GNOME');
sessionMode = new SessionMode.SessionMode();
shellDBusService = new ShellDBus.GnomeShell();
// Ensure ShellWindowTracker and ShellAppUsage are initialized; this will
@ -183,7 +170,6 @@ function start() {
global.stage.no_clear_hint = true;
_defaultCssStylesheet = global.datadir + '/theme/gnome-shell.css';
_gdmCssStylesheet = global.datadir + '/theme/gdm.css';
loadTheme();
// Set up stage hierarchy to group all UI actors under one container.
@ -211,8 +197,7 @@ function start() {
layoutManager = new Layout.LayoutManager();
xdndHandler = new XdndHandler.XdndHandler();
ctrlAltTabManager = new CtrlAltTab.CtrlAltTabManager();
// This overview object is just a stub for non-user sessions
overview = new Overview.Overview({ isDummy: global.session_type != Shell.SessionType.USER });
overview = new Overview.Overview();
magnifier = new Magnifier.Magnifier();
statusIconDispatcher = new StatusIconDispatcher.StatusIconDispatcher();
panel = new Panel.Panel();
@ -222,10 +207,7 @@ function start() {
notificationDaemon = new NotificationDaemon.NotificationDaemon();
windowAttentionHandler = new WindowAttentionHandler.WindowAttentionHandler();
if (global.session_type == Shell.SessionType.USER)
_createUserSession();
else if (global.session_type == Shell.SessionType.GDM)
_createGDMSession();
sessionMode.createSession();
panel.startStatusArea();
@ -233,8 +215,30 @@ function start() {
keyboard.init();
overview.init();
if (global.session_type == Shell.SessionType.USER)
_initUserSession();
if (sessionMode.hasWorkspaces)
global.screen.override_workspace_layout(Meta.ScreenCorner.TOPLEFT,
false, -1, 1);
if (sessionMode.allowExtensions) {
ExtensionSystem.init();
ExtensionSystem.loadExtensions();
}
if (sessionMode.hasRunDialog) {
Meta.keybindings_set_custom_handler('panel-run-dialog', function() {
getRunDialog().open();
});
}
if (sessionMode.hasOverview) {
Meta.keybindings_set_custom_handler('panel-main-menu', function () {
overview.toggle();
});
global.display.connect('overlay-key',
Lang.bind(overview, overview.toggle));
}
statusIconDispatcher.start(messageTray.actor);
// Provide the bus object for gnome-session to
@ -251,7 +255,6 @@ function start() {
global.stage.connect('captured-event', _globalKeyPressHandler);
_log('info', 'loaded at ' + _startDate);
log('GNOME Shell started at ' + _startDate);
let perfModuleName = GLib.getenv("SHELL_PERF_MODULE");
@ -494,8 +497,8 @@ function loadTheme() {
let theme = new St.Theme ({ application_stylesheet: cssStylesheet });
if (global.session_type == Shell.SessionType.GDM)
theme.load_stylesheet(_gdmCssStylesheet);
if (sessionMode.extraStylesheet)
theme.load_stylesheet(sessionMode.extraStylesheet);
if (previousTheme) {
let customStylesheets = previousTheme.get_custom_stylesheets();
@ -537,59 +540,6 @@ function notifyError(msg, details) {
notify(msg, details);
}
/**
* _log:
* @category: string message type ('info', 'error')
* @msg: A message string
* ...: Any further arguments are converted into JSON notation,
* and appended to the log message, separated by spaces.
*
* Log a message into the LookingGlass error
* stream. This is primarily intended for use by the
* extension system as well as debugging.
*/
function _log(category, msg) {
let text = msg;
if (arguments.length > 2) {
text += ': ';
for (let i = 2; i < arguments.length; i++) {
text += JSON.stringify(arguments[i]);
if (i < arguments.length - 1)
text += ' ';
}
}
_errorLogStack.push({timestamp: new Date().getTime(),
category: category,
message: text });
}
function _logError(msg) {
return _log('error', msg);
}
function _logDebug(msg) {
return _log('debug', msg);
}
// Used by the error display in lookingGlass.js
function _getAndClearErrorStack() {
let errors = _errorLogStack;
_errorLogStack = [];
return errors;
}
function logStackTrace(msg) {
try {
throw new Error();
} catch (e) {
// e.stack must have at least two lines, with the first being
// logStackTrace() (which we strip off), and the second being
// our caller.
let trace = e.stack.substr(e.stack.indexOf('\n') + 1);
log(msg ? (msg + '\n' + trace) : trace);
}
}
function isWindowActorDisplayedOnWorkspace(win, workspaceIndex) {
return win.get_workspace() == workspaceIndex ||
(win.get_meta_window() && win.get_meta_window().is_on_all_workspaces());
@ -612,6 +562,11 @@ function _globalKeyPressHandler(actor, event) {
if (event.type() != Clutter.EventType.KEY_PRESS)
return false;
if (!sessionMode.allowKeybindingsWhenModal) {
if (modalCount > (overview.visible ? 1 : 0))
return false;
}
let symbol = event.get_key_symbol();
let keyCode = event.get_key_code();
let ignoredModifiers = global.display.get_ignored_modifier_mask();
@ -620,11 +575,6 @@ function _globalKeyPressHandler(actor, event) {
// This relies on the fact that Clutter.ModifierType is the same as Gdk.ModifierType
let action = global.display.get_keybinding_action(keyCode, modifierState);
// Other bindings are only available to the user session when the overview is up and
// no modal dialog is present.
if (global.session_type == Shell.SessionType.USER && (!overview.visible || modalCount > 1))
return false;
// This isn't a Meta.KeyBindingAction yet
if (symbol == Clutter.Super_L || symbol == Clutter.Super_R) {
overview.hide();
@ -637,28 +587,39 @@ function _globalKeyPressHandler(actor, event) {
return true;
}
// None of the other bindings are relevant outside of the user's session
if (global.session_type != Shell.SessionType.USER)
return false;
switch (action) {
// left/right would effectively act as synonyms for up/down if we enabled them;
// but that could be considered confusing; we also disable them in the main view.
//
// case Meta.KeyBindingAction.WORKSPACE_LEFT:
// if (!sessionMode.hasWorkspaces)
// return false;
//
// wm.actionMoveWorkspaceLeft();
// return true;
// case Meta.KeyBindingAction.WORKSPACE_RIGHT:
// if (!sessionMode.hasWorkspaces)
// return false;
//
// wm.actionMoveWorkspaceRight();
// return true;
case Meta.KeyBindingAction.WORKSPACE_UP:
if (!sessionMode.hasWorkspaces)
return false;
wm.actionMoveWorkspaceUp();
return true;
case Meta.KeyBindingAction.WORKSPACE_DOWN:
if (!sessionMode.hasWorkspaces)
return false;
wm.actionMoveWorkspaceDown();
return true;
case Meta.KeyBindingAction.PANEL_RUN_DIALOG:
case Meta.KeyBindingAction.COMMAND_2:
if (!sessionMode.hasRunDialog)
return false;
getRunDialog().open();
return true;
case Meta.KeyBindingAction.PANEL_MAIN_MENU:
@ -931,7 +892,8 @@ function initializeDeferredWork(actor, callback, props) {
function queueDeferredWork(workId) {
let data = _deferredWorkData[workId];
if (!data) {
global.logError('invalid work id ', workId);
let message = 'Invalid work id %d'.format(workId);
logError(new Error(message), message);
return;
}
if (_deferredWorkQueue.indexOf(workId) < 0)

View File

@ -441,7 +441,7 @@ const Notification = new Lang.Class({
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',
this._table = new St.Table({ style_class: 'notification',
reactive: true });
this._table.connect('style-changed', Lang.bind(this, this._styleChanged));
this.actor.set_child(this._table);
@ -586,19 +586,21 @@ const Notification = new Lang.Class({
enableScrolling: function(enableScrolling) {
this._scrollPolicy = enableScrolling ? Gtk.PolicyType.AUTOMATIC : Gtk.PolicyType.NEVER;
if (this._scrollArea)
if (this._scrollArea) {
this._scrollArea.vscrollbar_policy = this._scrollPolicy;
this._scrollArea.enable_mouse_scrolling = enableScrolling;
}
},
_createScrollArea: function() {
this._table.add_style_class_name('multi-line-notification');
this._scrollArea = new St.ScrollView({ name: 'notification-scrollview',
this._scrollArea = new St.ScrollView({ style_class: 'notification-scrollview',
vscrollbar_policy: this._scrollPolicy,
hscrollbar_policy: Gtk.PolicyType.NEVER });
this._table.add(this._scrollArea, { row: 1,
col: 2 });
this._updateLastColumnSettings();
this._contentArea = new St.BoxLayout({ name: 'notification-body',
this._contentArea = new St.BoxLayout({ style_class: 'notification-body',
vertical: true });
this._scrollArea.add_actor(this._contentArea);
// If we know the notification will be expandable, we need to add
@ -734,7 +736,7 @@ const Notification = new Lang.Class({
addButton: function(id, label) {
if (!this._buttonBox) {
let box = new St.BoxLayout({ name: 'notification-actions' });
let box = new St.BoxLayout({ style_class: 'notification-actions' });
this.setActionArea(box, { x_expand: false,
y_expand: false,
x_fill: false,
@ -744,6 +746,7 @@ const Notification = new Lang.Class({
}
let button = new St.Button({ can_focus: true });
button._actionId = id;
if (this._useActionIcons && Gtk.IconTheme.get_default().has_icon(id)) {
button.add_style_class_name('notification-icon-button');
@ -763,6 +766,31 @@ const Notification = new Lang.Class({
this.updated();
},
// setButtonSensitive:
// @id: the action ID
// @sensitive: whether the button should be sensitive
//
// If the notification contains a button with action ID @id,
// its sensitivity will be set to @sensitive. Insensitive
// buttons cannot be clicked.
setButtonSensitive: function(id, sensitive) {
if (!this._buttonBox)
return;
let button = this._buttonBox.get_children().filter(function(b) {
return b._actionId == id;
})[0];
if (!button || button.reactive == sensitive)
return;
button.reactive = sensitive;
if (sensitive)
button.remove_style_pseudo_class('insensitive');
else
button.add_style_pseudo_class('insensitive');
},
setUrgency: function(urgency) {
this.urgency = urgency;
},
@ -958,8 +986,10 @@ const Source = new Lang.Class({
ICON_SIZE: 24,
_init: function(title) {
_init: function(title, iconName, iconType) {
this.title = title;
this.iconName = iconName;
this.iconType = iconType;
this.actor = new Shell.GenericContainer();
this.actor.connect('get-preferred-width', Lang.bind(this, this._getPreferredWidth));
@ -989,6 +1019,8 @@ const Source = new Lang.Class({
this.isMuted = false;
this.notifications = [];
this._setSummaryIcon(this.createNotificationIcon());
},
_getPreferredWidth: function (actor, forHeight, alloc) {
@ -1059,10 +1091,12 @@ const Source = new Lang.Class({
},
// Called to create a new icon actor (of size this.ICON_SIZE).
// Must be overridden by the subclass if you do not pass icons
// explicitly to the Notification() constructor.
// Provides a sane default implementation, override if you need
// something more fancy.
createNotificationIcon: function() {
throw new Error('no implementation of createNotificationIcon in ' + this);
return new St.Icon({ icon_name: this.iconName,
icon_type: this.iconType,
icon_size: this.ICON_SIZE });
},
// Unlike createNotificationIcon, this always returns the same actor;
@ -1113,16 +1147,14 @@ const Source = new Lang.Class({
},
//// Protected methods ////
// The subclass must call this at least once to set the summary icon.
_setSummaryIcon: function(icon) {
if (this._iconBin.child)
this._iconBin.child.destroy();
this._iconBin.child = icon;
},
// Default implementation is to do nothing, but subclasses can override
open: function(notification) {
this.emit('opened', notification);
},
destroyNonResidentNotifications: function() {
@ -2487,15 +2519,7 @@ const SystemNotificationSource = new Lang.Class({
Extends: Source,
_init: function() {
this.parent(_("System Information"));
this._setSummaryIcon(this.createNotificationIcon());
},
createNotificationIcon: function() {
return new St.Icon({ icon_name: 'dialog-information',
icon_type: St.IconType.SYMBOLIC,
icon_size: this.ICON_SIZE });
this.parent(_("System Information"), 'dialog-information', St.IconType.SYMBOLIC);
},
open: function() {

View File

@ -221,12 +221,19 @@ const NotificationDaemon = new Lang.Class({
let [appName, replacesId, icon, summary, body, actions, hints, timeout] = params;
let id;
for (let hint in hints) {
// unpack the variants
hints[hint] = hints[hint].deep_unpack();
}
hints = Params.parse(hints, { urgency: Urgency.NORMAL }, true);
// Filter out chat, presence, calls and invitation notifications from
// Empathy, since we handle that information from telepathyClient.js
if (appName == 'Empathy' && (hints['category'] == 'im.received' ||
hints['category'] == 'x-empathy.im.room-invitation' ||
hints['category'] == 'x-empathy.call.incoming' ||
hints['category'] == 'x-empathy.call.incoming"' ||
hints['category'] == 'x-empathy.transfer.incoming' ||
hints['category'] == 'x-empathy.im.subscription-request' ||
hints['category'] == 'presence.online' ||
hints['category'] == 'presence.offline')) {
@ -249,13 +256,6 @@ const NotificationDaemon = new Lang.Class({
}
}
for (let hint in hints) {
// unpack the variants
hints[hint] = hints[hint].deep_unpack();
}
hints = Params.parse(hints, { urgency: Urgency.NORMAL }, true);
// Be compatible with the various hints for image data and image path
// 'image-data' and 'image-path' are the latest name of these hints, introduced in 1.2
@ -483,7 +483,7 @@ const NotificationDaemon = new Lang.Class({
},
_onTrayIconAdded: function(o, icon) {
let source = this._getSource(icon.title || icon.wm_class || _("Unknown"), icon.pid, null, null, icon);
let source = this._getSource(icon.title || icon.wm_class || C_("program", "Unknown"), icon.pid, null, null, icon);
},
_onTrayIconRemoved: function(o, icon) {
@ -578,11 +578,27 @@ const Source = new Lang.Class({
return true;
},
_getApp: function() {
let app;
app = Shell.WindowTracker.get_default().get_app_from_pid(this.pid);
if (app != null)
return app;
if (this.trayIcon) {
app = Shell.AppSystem.get_default().lookup_wmclass(this.trayIcon.wmclass);
if (app != null)
return app;
}
return null;
},
_setApp: function() {
if (this.app)
return;
this.app = Shell.WindowTracker.get_default().get_app_from_pid(this.pid);
this.app = this._getApp();
if (!this.app)
return;
@ -622,5 +638,10 @@ const Source = new Lang.Class({
}
this.parent();
},
createNotificationIcon: function() {
// We set the summary icon ourselves.
return null;
}
});

View File

@ -99,10 +99,8 @@ const ShellInfo = new Lang.Class({
const Overview = new Lang.Class({
Name: 'Overview',
_init : function(params) {
params = Params.parse(params, { isDummy: false });
this.isDummy = params.isDummy;
_init : function() {
this.isDummy = !Main.sessionMode.hasOverview;
// We only have an overview in user sessions, so
// create a dummy overview in other cases

View File

@ -14,7 +14,6 @@ const St = imports.gi.St;
const Signals = imports.signals;
const Atk = imports.gi.Atk;
const Config = imports.misc.config;
const CtrlAltTab = imports.ui.ctrlAltTab;
const DND = imports.ui.dnd;
const Layout = imports.ui.layout;
@ -32,33 +31,6 @@ const BUTTON_DND_ACTIVATION_TIMEOUT = 250;
const ANIMATED_ICON_UPDATE_TIMEOUT = 100;
const SPINNER_ANIMATION_TIME = 0.2;
const STANDARD_STATUS_AREA_ORDER = ['a11y', 'keyboard', 'volume', 'bluetooth', 'network', 'battery', 'userMenu'];
const STANDARD_STATUS_AREA_SHELL_IMPLEMENTATION = {
'a11y': imports.ui.status.accessibility.ATIndicator,
'volume': imports.ui.status.volume.Indicator,
'battery': imports.ui.status.power.Indicator,
'keyboard': imports.ui.status.keyboard.XKBIndicator,
'userMenu': imports.ui.userMenu.UserMenuButton
};
if (Config.HAVE_BLUETOOTH)
STANDARD_STATUS_AREA_SHELL_IMPLEMENTATION['bluetooth'] = imports.ui.status.bluetooth.Indicator;
try {
STANDARD_STATUS_AREA_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');
}
const GDM_STATUS_AREA_ORDER = ['a11y', 'display', 'keyboard', 'volume', 'battery', 'powerMenu'];
const GDM_STATUS_AREA_SHELL_IMPLEMENTATION = {
'a11y': imports.ui.status.accessibility.ATIndicator,
'volume': imports.ui.status.volume.Indicator,
'battery': imports.ui.status.power.Indicator,
'keyboard': imports.ui.status.keyboard.XKBIndicator,
'powerMenu': imports.gdm.powerMenu.PowerMenuButton
};
// 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
@ -962,7 +934,7 @@ const Panel = new Lang.Class({
this.actor.connect('button-press-event', Lang.bind(this, this._onButtonPress));
/* Button on the left side of the panel. */
if (global.session_type == Shell.SessionType.USER) {
if (Main.sessionMode.hasOverview) {
this._activitiesButton = new ActivitiesButton();
this._activities = this._activitiesButton.actor;
this._leftBox.add(this._activities);
@ -970,28 +942,19 @@ const Panel = new Lang.Class({
// The activities button has a pretend menu, so as to integrate
// more cleanly with the rest of the panel
this._menus.addMenu(this._activitiesButton.menu);
}
if (Main.sessionMode.hasAppMenu) {
this._appMenu = new AppMenuButton(this._menus);
this._leftBox.add(this._appMenu.actor);
}
/* center */
if (global.session_type == Shell.SessionType.USER)
this._dateMenu = new DateMenu.DateMenuButton({ showEvents: true });
else
this._dateMenu = new DateMenu.DateMenuButton({ showEvents: false });
this._dateMenu = new DateMenu.DateMenuButton();
this._centerBox.add(this._dateMenu.actor, { y_fill: true });
this._menus.addMenu(this._dateMenu.menu);
/* right */
if (global.session_type == Shell.SessionType.GDM) {
this._status_area_order = GDM_STATUS_AREA_ORDER;
this._status_area_shell_implementation = GDM_STATUS_AREA_SHELL_IMPLEMENTATION;
} else {
this._status_area_order = STANDARD_STATUS_AREA_ORDER;
this._status_area_shell_implementation = STANDARD_STATUS_AREA_SHELL_IMPLEMENTATION;
}
Main.statusIconDispatcher.connect('status-icon-added', Lang.bind(this, this._onTrayIconAdded));
Main.statusIconDispatcher.connect('status-icon-removed', Lang.bind(this, this._onTrayIconRemoved));
@ -1115,17 +1078,17 @@ const Panel = new Lang.Class({
openAppMenu: function() {
let menu = this._appMenu.menu;
if (Main.overview.visible || menu.isOpen)
return;
if (!this._appMenu.actor.reactive || menu.isOpen)
return;
menu.open();
menu.actor.navigate_focus(null, Gtk.DirectionType.TAB_FORWARD, false);
},
startStatusArea: function() {
for (let i = 0; i < this._status_area_order.length; i++) {
let role = this._status_area_order[i];
let constructor = this._status_area_shell_implementation[role];
for (let i = 0; i < Main.sessionMode.statusArea.order.length; i++) {
let role = Main.sessionMode.statusArea.order[i];
let constructor = Main.sessionMode.statusArea.implementation[role];
if (!constructor) {
// This icon is not implemented (this is a bug)
continue;
@ -1175,18 +1138,21 @@ const Panel = new Lang.Class({
},
_onTrayIconAdded: function(o, icon, role) {
if (this._status_area_shell_implementation[role]) {
if (Main.sessionMode.statusArea.implementation[role]) {
// This icon is legacy, and replaced by a Shell version
// Hide it
return;
}
if (Main.sessionMode.statusArea.order.indexOf(role) == -1)
return;
icon.height = PANEL_ICON_SIZE;
let buttonBox = new PanelMenu.ButtonBox();
let box = buttonBox.actor;
box.add_actor(icon);
this._insertStatusItem(box, this._status_area_order.indexOf(role));
this._insertStatusItem(box, Main.sessionMode.statusArea.order.indexOf(role));
},
_onTrayIconRemoved: function(o, icon) {

View File

@ -189,7 +189,7 @@ const PlacesManager = new Lang.Class({
this._volumeMonitor.connect('drive-changed', Lang.bind(this, this._updateDevices));
this._updateDevices();
this._bookmarksPath = GLib.build_filenamev([GLib.get_home_dir(), '.gtk-bookmarks']);
this._bookmarksPath = GLib.build_filenamev([GLib.get_user_config_dir(), 'gtk-3.0', 'bookmarks']);
this._bookmarksFile = Gio.file_new_for_path(this._bookmarksPath);
this._monitor = this._bookmarksFile.monitor_file(Gio.FileMonitorFlags.NONE, null);
this._bookmarkTimeoutId = 0;
@ -365,12 +365,13 @@ const PlaceSearchProvider = new Lang.Class({
_init: function() {
this.parent(_("PLACES & DEVICES"));
this.placesManager = new PlacesManager();
},
getResultMetas: function(resultIds) {
getResultMetas: function(resultIds, callback) {
let metas = [];
for (let i = 0; i < resultIds.length; i++) {
let placeInfo = Main.placesManager.lookupPlaceById(resultIds[i]);
let placeInfo = this.placesManager.lookupPlaceById(resultIds[i]);
if (!placeInfo)
metas.push(null);
else
@ -381,24 +382,22 @@ const PlaceSearchProvider = new Lang.Class({
}
});
}
return metas;
callback(metas);
},
activateResult: function(id, params) {
let placeInfo = Main.placesManager.lookupPlaceById(id);
let placeInfo = this.placesManager.lookupPlaceById(id);
placeInfo.launch(params);
},
_compareResultMeta: function (idA, idB) {
let infoA = Main.placesManager.lookupPlaceById(idA);
let infoB = Main.placesManager.lookupPlaceById(idB);
let infoA = this.placesManager.lookupPlaceById(idA);
let infoB = this.placesManager.lookupPlaceById(idB);
return infoA.name.localeCompare(infoB.name);
},
_searchPlaces: function(places, terms) {
let multiplePrefixResults = [];
let prefixResults = [];
let multipleSubstringResults = [];
let substringResults = [];
terms = terms.map(String.toLowerCase);
@ -406,29 +405,26 @@ const PlaceSearchProvider = new Lang.Class({
for (let i = 0; i < places.length; i++) {
let place = places[i];
let mtype = place.matchTerms(terms);
if (mtype == Search.MatchType.MULTIPLE_PREFIX)
multiplePrefixResults.push(place.id);
else if (mtype == Search.MatchType.PREFIX)
if (mtype == Search.MatchType.PREFIX)
prefixResults.push(place.id);
else if (mtype == Search.MatchType.MULTIPLE_SUBSTRING)
multipleSubstringResults.push(place.id);
else if (mtype == Search.MatchType.SUBSTRING)
substringResults.push(place.id);
}
multiplePrefixResults.sort(this._compareResultMeta);
prefixResults.sort(this._compareResultMeta);
multipleSubstringResults.sort(this._compareResultMeta);
substringResults.sort(this._compareResultMeta);
return multiplePrefixResults.concat(prefixResults.concat(multipleSubstringResults.concat(substringResults)));
prefixResults.sort(Lang.bind(this, this._compareResultMeta));
substringResults.sort(Lang.bind(this, this._compareResultMeta));
this.searchSystem.pushResults(this, prefixResults.concat(substringResults));
},
getInitialResultSet: function(terms) {
let places = Main.placesManager.getAllPlaces();
return this._searchPlaces(places, terms);
let places = this.placesManager.getAllPlaces();
this._searchPlaces(places, terms);
},
getSubsearchResultSet: function(previousResults, terms) {
let places = previousResults.map(function (id) { return Main.placesManager.lookupPlaceById(id); });
return this._searchPlaces(places, terms);
let places = previousResults.map(Lang.bind(this, function(id) {
return this.placesManager.lookupPlaceById(id);
}));
this._searchPlaces(places, terms);
}
});

View File

@ -167,6 +167,7 @@ const AuthenticationDialog = new Lang.Class({
*/
this._nullMessageLabel = new St.Label({ style_class: 'prompt-dialog-null-label',
text: 'abc'});
this._nullMessageLabel.add_style_class_name('hidden');
this._nullMessageLabel.clutter_text.ellipsize = Pango.EllipsizeMode.NONE;
this._nullMessageLabel.clutter_text.line_wrap = true;
messageBox.add(this._nullMessageLabel);

View File

@ -546,6 +546,10 @@ const PopupSliderMenuItem = new Lang.Class({
this._slider.connect('repaint', Lang.bind(this, this._sliderRepaint));
this.actor.connect('button-press-event', Lang.bind(this, this._startDragging));
this.actor.connect('scroll-event', Lang.bind(this, this._onScrollEvent));
this.actor.connect('notify::mapped', Lang.bind(this, function() {
if (!this.actor.mapped)
this._endDragging();
}));
this._releaseId = this._motionId = 0;
this._dragging = false;
@ -884,8 +888,7 @@ const PopupMenuBase = new Lang.Class({
},
addSettingsAction: function(title, desktopFile) {
// Don't allow user settings to get edited unless we're in a user session
if (global.session_type != Shell.SessionType.USER)
if (!Main.sessionMode.allowSettings)
return null;
let menuItem = this.addAction(title, function() {
@ -1917,7 +1920,7 @@ const RemoteMenu = new Lang.Class({
while (k0 < currentItems.length && currentItems[k0]._ignored)
k0++;
// find the right menu item matching the model item
for (j0 = 0; j0 < position; j0++, k0++) {
for (j0 = 0; k0 < currentItems.length && j0 < position; j0++, k0++) {
if (currentItems[k0]._ignored)
k0++;
}
@ -1927,7 +1930,7 @@ const RemoteMenu = new Lang.Class({
for (k = k0; k < currentItems.length; k++)
currentItems[k].destroy();
} else {
for (j = j0, k = k0; j < j0 + removed; j++, k++) {
for (j = j0, k = k0; k < currentItems.length && j < j0 + removed; j++, k++) {
currentItems[k].destroy();
if (currentItems[k]._ignored)
@ -1958,8 +1961,9 @@ const RemoteMenu = new Lang.Class({
k++;
}
} else if (changeSignal) {
let signalId = this.actionGroup.connect(changeSignal, Lang.bind(this, function() {
this.actionGroup.disconnect(signalId);
let signalId = this.actionGroup.connect(changeSignal, Lang.bind(this, function(actionGroup, actionName) {
actionGroup.disconnect(signalId);
if (this._actions[actionName]) return;
// force a full update
this._modelChanged(model, 0, -1, model.get_n_items(), target);

View File

@ -91,7 +91,6 @@ const RemoteSearchProvider = new Lang.Class({
dbusName, dbusPath);
this.parent(title.toUpperCase());
this.async = true;
this._cancellable = new Gio.Cancellable();
},
@ -120,7 +119,7 @@ const RemoteSearchProvider = new Lang.Class({
this.searchSystem.pushResults(this, results[0]);
},
getInitialResultSetAsync: function(terms) {
getInitialResultSet: function(terms) {
this._cancellable.cancel();
this._cancellable.reset();
try {
@ -133,7 +132,7 @@ const RemoteSearchProvider = new Lang.Class({
}
},
getSubsearchResultSetAsync: function(previousResults, newTerms) {
getSubsearchResultSet: function(previousResults, newTerms) {
this._cancellable.cancel();
this._cancellable.reset();
try {
@ -164,7 +163,7 @@ const RemoteSearchProvider = new Lang.Class({
callback(resultMetas);
},
getResultMetasAsync: function(ids, callback) {
getResultMetas: function(ids, callback) {
this._cancellable.cancel();
this._cancellable.reset();
try {

View File

@ -18,9 +18,7 @@ const DISABLED_OPEN_SEARCH_PROVIDERS_KEY = 'disabled-open-search-providers';
const MatchType = {
NONE: 0,
SUBSTRING: 1,
MULTIPLE_SUBSTRING: 2,
PREFIX: 3,
MULTIPLE_PREFIX: 4
PREFIX: 2
};
const SearchResultDisplay = new Lang.Class({
@ -72,11 +70,8 @@ const SearchResultDisplay = new Lang.Class({
* Subclass this object to add a new result type
* to the search system, then call registerProvider()
* in SearchSystem with an instance.
* By default, search is synchronous and uses the
* Search is asynchronous and uses the
* getInitialResultSet()/getSubsearchResultSet() methods.
* For asynchronous search, set the async property to true
* and implement getInitialResultSetAsync()/getSubsearchResultSetAsync()
* instead.
*/
const SearchProvider = new Lang.Class({
Name: 'SearchProvider',
@ -84,7 +79,6 @@ const SearchProvider = new Lang.Class({
_init: function(title) {
this.title = title;
this.searchSystem = null;
this.async = false;
},
/**
@ -95,7 +89,7 @@ const SearchProvider = new Lang.Class({
* therefore a single term of length one or two), or when
* a new term is added.
*
* Should return an array of result identifier strings representing
* Should "return" an array of result identifier strings representing
* items which match the given search terms. This
* is expected to be a substring match on the metadata for a given
* item. Ordering of returned results is up to the discretion of the provider,
@ -105,6 +99,9 @@ const SearchProvider = new Lang.Class({
* description) before single matches
* * Put items which match on a prefix before non-prefix substring matches
*
* We say "return" above, but in order to make the query asynchronous, use
* this.searchSystem.pushResults();. The return value should be ignored.
*
* This function should be fast; do not perform unindexed full-text searches
* or network queries.
*/
@ -112,18 +109,6 @@ const SearchProvider = new Lang.Class({
throw new Error('Not implemented');
},
/**
* getInitialResultSetAsync:
* @terms: Array of search terms, treated as logical AND
*
* Like getInitialResultSet(), but the method should return immediately
* without a return value - use SearchSystem.pushResults() when the
* corresponding results are ready.
*/
getInitialResultSetAsync: function(terms) {
throw new Error('Not implemented');
},
/**
* getSubsearchResultSet:
* @previousResults: Array of item identifiers
@ -136,46 +121,23 @@ const SearchProvider = new Lang.Class({
*
* This allows search providers to only search through the previous
* result set, rather than possibly performing a full re-query.
*
* Similar to getInitialResultSet, the return value for this will
* be ignored; use this.searchSystem.pushResults();.
*/
getSubsearchResultSet: function(previousResults, newTerms) {
throw new Error('Not implemented');
},
/**
* getSubsearchResultSetAsync:
* @previousResults: Array of item identifiers
* @newTerms: Updated search terms
*
* Like getSubsearchResultSet(), but the method should return immediately
* without a return value - use SearchSystem.pushResults() when the
* corresponding results are ready.
*/
getSubsearchResultSetAsync: function(previousResults, newTerms) {
throw new Error('Not implemented');
},
/**
* getResultMetas:
* @ids: Result identifier strings
*
* Return an array of objects with 'id', 'name', (both strings) and
* Call callback with array of objects with 'id', 'name', (both strings) and
* 'createIcon' (function(size) returning a Clutter.Texture) properties
* with the same number of members as @ids
*/
getResultMetas: function(ids) {
throw new Error('Not implemented');
},
/**
* getResultMetasAsync:
* @ids: Result identifier strings
* @callback: callback to pass the results to when ready
*
* Like getResultMetas(), but the method should return immediately
* without a return value - pass the results to the provided @callback
* when ready.
*/
getResultMetasAsync: function(ids, callback) {
getResultMetas: function(ids, callback) {
throw new Error('Not implemented');
},
@ -379,42 +341,33 @@ const SearchSystem = new Lang.Class({
}
}
let previousResultsArr = this._previousResults;
let results = [];
this._previousTerms = terms;
this._previousResults = results;
if (isSubSearch) {
for (let i = 0; i < this._providers.length; i++) {
let [provider, previousResults] = this._previousResults[i];
let [provider, previousResults] = previousResultsArr[i];
try {
if (provider.async) {
provider.getSubsearchResultSetAsync(previousResults, terms);
results.push([provider, []]);
} else {
let providerResults = provider.getSubsearchResultSet(previousResults, terms);
results.push([provider, providerResults]);
}
results.push([provider, []]);
provider.getSubsearchResultSet(previousResults, terms);
} catch (error) {
global.log ('A ' + error.name + ' has occured in ' + provider.title + ': ' + error.message);
log('A ' + error.name + ' has occured in ' + provider.title + ': ' + error.message);
}
}
} else {
for (let i = 0; i < this._providers.length; i++) {
let provider = this._providers[i];
try {
if (provider.async) {
provider.getInitialResultSetAsync(terms);
results.push([provider, []]);
} else {
let providerResults = provider.getInitialResultSet(terms);
results.push([provider, providerResults]);
}
results.push([provider, []]);
provider.getInitialResultSet(terms);
} catch (error) {
global.log ('A ' + error.name + ' has occured in ' + provider.title + ': ' + error.message);
log('A ' + error.name + ' has occured in ' + provider.title + ': ' + error.message);
}
}
}
this._previousTerms = terms;
this._previousResults = results;
this.emit('search-completed', results);
},
});
Signals.addSignalMethods(SearchSystem.prototype);

View File

@ -5,6 +5,7 @@ const Lang = imports.lang;
const Gtk = imports.gi.Gtk;
const Meta = imports.gi.Meta;
const St = imports.gi.St;
const Atk = imports.gi.Atk;
const DND = imports.ui.dnd;
const IconGrid = imports.ui.iconGrid;
@ -33,12 +34,13 @@ const SearchResult = new Lang.Class({
content = new St.Bin({ style_class: 'search-result-content',
reactive: true,
can_focus: true,
track_hover: true });
track_hover: true,
accessible_role: Atk.Role.PUSH_BUTTON });
let icon = new IconGrid.BaseIcon(this.metaInfo['name'],
{ createIcon: this.metaInfo['createIcon'] });
content.set_child(icon.actor);
this._dragActorSource = icon.icon;
this.actor.label_actor = icon.label;
content.label_actor = icon.label;
} else {
if (content._delegate && content._delegate.getDragActorSource)
this._dragActorSource = content._delegate.getDragActorSource();
@ -119,13 +121,7 @@ const GridSearchResults = new Lang.Class({
if (results.length == 0)
return;
if (provider.async) {
provider.getResultMetasAsync(results,
Lang.bind(this, this.renderResults));
} else {
let metas = provider.getResultMetas(results);
this.renderResults(metas);
}
provider.getResultMetas(results, Lang.bind(this, this.renderResults));
}));
}));
this._notDisplayedResult = [];
@ -135,7 +131,7 @@ const GridSearchResults = new Lang.Class({
getResultsForDisplay: function() {
let alreadyVisible = this._pendingClear ? 0 : this._grid.visibleItemsCount();
let canDisplay = this._grid.childrenInRow(this._width) * MAX_SEARCH_RESULTS_ROWS
let canDisplay = this._grid.childrenInRow(this._width) * this._grid.getRowLimit()
- alreadyVisible;
let numResults = Math.min(this._notDisplayedResult.length, canDisplay);
@ -179,8 +175,7 @@ const SearchResults = new Lang.Class({
_init: function(searchSystem, openSearchSystem) {
this._searchSystem = searchSystem;
this._searchSystem.connect('search-updated', Lang.bind(this, this._updateCurrentResults));
this._searchSystem.connect('search-completed', Lang.bind(this, this._updateResults));
this._searchSystem.connect('search-updated', Lang.bind(this, this._updateResults));
this._openSearchSystem = openSearchSystem;
this.actor = new St.BoxLayout({ name: 'searchResults',
@ -214,10 +209,8 @@ const SearchResults = new Lang.Class({
this._content.add(this._statusText);
this._providers = this._searchSystem.getProviders();
this._providerMeta = [];
this._providerMetaResults = {};
for (let i = 0; i < this._providers.length; i++) {
this.createProviderMeta(this._providers[i]);
this._providerMetaResults[this.providers[i].title] = [];
}
this._searchProvidersBox = new St.BoxLayout({ style_class: 'search-providers-box' });
this.actor.add(this._searchProvidersBox);
@ -290,8 +283,7 @@ const SearchResults = new Lang.Class({
this._providerMeta.push({ provider: provider,
actor: providerBox,
resultDisplay: resultDisplay,
hasPendingResults: false });
resultDisplay: resultDisplay });
this._content.add(providerBox);
},
@ -307,7 +299,6 @@ const SearchResults = new Lang.Class({
},
_clearDisplay: function() {
this._visibleResultsCount = 0;
for (let i = 0; i < this._providerMeta.length; i++) {
let meta = this._providerMeta[i];
meta.resultDisplay.clear();
@ -335,6 +326,8 @@ const SearchResults = new Lang.Class({
doSearch: function (searchString) {
this._searchSystem.updateSearch(searchString);
let terms = this._searchSystem.getTerms();
this._openSearchSystem.setSearchTerms(terms);
},
_metaForProvider: function(provider) {
@ -346,8 +339,6 @@ const SearchResults = new Lang.Class({
for (let i = 0; i < this._providerMeta.length; i++) {
let meta = this._providerMeta[i];
if (meta.hasPendingResults)
return;
if (!meta.actor.visible)
continue;
@ -372,71 +363,57 @@ const SearchResults = new Lang.Class({
}
},
_updateCurrentResults: function(searchSystem, results) {
let terms = searchSystem.getTerms();
let [provider, providerResults] = results;
let meta = this._metaForProvider(provider);
meta.hasPendingResults = false;
this._updateProviderResults(provider, providerResults, terms);
},
_updateStatusText: function () {
let haveResults = false;
_updateProviderResults: function(provider, providerResults, terms) {
let meta = this._metaForProvider(provider);
if (providerResults.length == 0) {
this._clearDisplayForProvider(provider);
meta.resultDisplay.setResults([], []);
} else {
this._providerMetaResults[provider.title] = providerResults;
meta.resultDisplay.setResults(providerResults, terms);
let results = meta.resultDisplay.getResultsForDisplay();
if (provider.async) {
provider.getResultMetasAsync(results, Lang.bind(this,
function(metas) {
this._clearDisplayForProvider(provider);
meta.actor.show();
this._content.hide();
meta.resultDisplay.renderResults(metas);
this._maybeSetInitialSelection();
this._content.show();
}));
} else {
let metas = provider.getResultMetas(results);
this._clearDisplayForProvider(provider);
meta.actor.show();
meta.resultDisplay.renderResults(metas);
for (let i = 0; i < this._providerMeta.length; ++i)
if (this._providerMeta[i].resultDisplay.getFirstResult()) {
haveResults = true;
break;
}
}
this._maybeSetInitialSelection();
},
_updateResults: function(searchSystem, results) {
if (results.length == 0) {
if (!haveResults) {
this._statusText.set_text(_("No matching results."));
this._statusText.show();
} else {
this._statusText.hide();
}
},
_updateResults: function(searchSystem, results) {
let terms = searchSystem.getTerms();
this._openSearchSystem.setSearchTerms(terms);
let [provider, providerResults] = results;
let meta = this._metaForProvider(provider);
// To avoid CSS transitions causing flickering when the first search
// result stays the same, we hide the content while filling in the
// results.
this._content.hide();
if (providerResults.length == 0) {
this._clearDisplayForProvider(provider);
meta.resultDisplay.setResults([], []);
this._maybeSetInitialSelection();
this._updateStatusText();
} else {
meta.resultDisplay.setResults(providerResults, terms);
let results = meta.resultDisplay.getResultsForDisplay();
for (let i = 0; i < results.length; i++) {
let [provider, providerResults] = results[i];
let meta = this._metaForProvider(provider);
meta.hasPendingResults = provider.async;
if (!meta.hasPendingResults)
this._updateProviderResults(provider, providerResults, terms);
provider.getResultMetas(results, Lang.bind(this, function(metas) {
this._clearDisplayForProvider(provider);
meta.actor.show();
// Hiding drops the key focus if we have it
let focus = global.stage.get_key_focus();
// To avoid CSS transitions causing flickering when
// the first search result stays the same, we hide the
// content while filling in the results.
this._content.hide();
meta.resultDisplay.renderResults(metas);
this._maybeSetInitialSelection();
this._updateStatusText();
this._content.show();
if (this._content.contains(focus))
global.stage.set_key_focus(focus);
}));
}
this._content.show();
return true;
},
activateDefault: function() {

124
js/ui/sessionMode.js Normal file
View File

@ -0,0 +1,124 @@
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
const Lang = imports.lang;
const Config = imports.misc.config;
const Main = imports.ui.main;
const Params = imports.misc.params;
const STANDARD_STATUS_AREA_SHELL_IMPLEMENTATION = {
'a11y': imports.ui.status.accessibility.ATIndicator,
'volume': imports.ui.status.volume.Indicator,
'battery': imports.ui.status.power.Indicator,
'keyboard': imports.ui.status.keyboard.InputSourceIndicator,
'userMenu': imports.ui.userMenu.UserMenuButton
};
if (Config.HAVE_BLUETOOTH)
STANDARD_STATUS_AREA_SHELL_IMPLEMENTATION['bluetooth'] =
imports.ui.status.bluetooth.Indicator;
try {
STANDARD_STATUS_AREA_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');
}
const DEFAULT_MODE = 'user';
const _modes = {
'gdm': { hasOverview: false,
hasAppMenu: false,
showCalendarEvents: false,
allowSettings: false,
allowExtensions: false,
allowKeybindingsWhenModal: true,
hasRunDialog: false,
hasWorkspaces: false,
createSession: Main.createGDMSession,
extraStylesheet: global.datadir + '/theme/gdm.css',
statusArea: {
order: [
'a11y', 'display', 'keyboard',
'volume', 'battery', 'powerMenu'
],
implementation: {
'a11y': imports.ui.status.accessibility.ATIndicator,
'volume': imports.ui.status.volume.Indicator,
'battery': imports.ui.status.power.Indicator,
'keyboard': imports.ui.status.keyboard.InputSourceIndicator,
'powerMenu': imports.gdm.powerMenu.PowerMenuButton
}
}
},
'initial-setup': { hasOverview: false,
hasAppMenu: false,
showCalendarEvents: false,
allowSettings: false,
allowExtensions: false,
allowKeybindingsWhenModal: false,
hasRunDialog: false,
hasWorkspaces: false,
createSession: Main.createInitialSetupSession,
extraStylesheet: null,
statusArea: {
order: [
'a11y', 'keyboard', 'volume'
],
implementation: {
'a11y': imports.ui.status.accessibility.ATIndicator,
'keyboard': imports.ui.status.keyboard.XKBIndicator,
'volume': imports.ui.status.volume.Indicator
}
}
},
'user': { hasOverview: true,
hasAppMenu: true,
showCalendarEvents: true,
allowSettings: true,
allowExtensions: true,
allowKeybindingsWhenModal: false,
hasRunDialog: true,
hasWorkspaces: true,
createSession: Main.createUserSession,
extraStylesheet: null,
statusArea: {
order: [
'input-method', 'a11y', 'keyboard', 'volume', 'bluetooth',
'network', 'battery', 'userMenu'
],
implementation: STANDARD_STATUS_AREA_SHELL_IMPLEMENTATION
}
}
};
function listModes() {
let modes = Object.getOwnPropertyNames(_modes);
for (let i = 0; i < modes.length; i++)
print(modes[i]);
}
const SessionMode = new Lang.Class({
Name: 'SessionMode',
_init: function() {
let params = _modes[global.session_mode];
params = Params.parse(params, _modes[DEFAULT_MODE]);
this._createSession = params.createSession;
delete params.createSession;
Lang.copyProperties(params, this);
},
createSession: function() {
if (this._createSession)
this._createSession();
}
});

View File

@ -56,15 +56,8 @@ const GnomeShellIface = <interface name="org.gnome.Shell">
<arg type="i" direction="in" name="width"/>
<arg type="i" direction="in" name="height"/>
</method>
<method name="EnableExtension">
<arg type="s" direction="in" name="uuid"/>
</method>
<method name="DisableExtension">
<arg type="s" direction="in" name="uuid"/>
</method>
<method name="InstallRemoteExtension">
<arg type="s" direction="in" name="uuid"/>
<arg type="s" direction="in" name="version"/>
</method>
<method name="UninstallExtension">
<arg type="s" direction="in" name="uuid"/>
@ -260,22 +253,8 @@ const GnomeShell = new Lang.Class({
return extension.errors;
},
EnableExtension: function(uuid) {
let enabledExtensions = global.settings.get_strv(ExtensionSystem.ENABLED_EXTENSIONS_KEY);
if (enabledExtensions.indexOf(uuid) == -1)
enabledExtensions.push(uuid);
global.settings.set_strv(ExtensionSystem.ENABLED_EXTENSIONS_KEY, enabledExtensions);
},
DisableExtension: function(uuid) {
let enabledExtensions = global.settings.get_strv(ExtensionSystem.ENABLED_EXTENSIONS_KEY);
while (enabledExtensions.indexOf(uuid) != -1)
enabledExtensions.splice(enabledExtensions.indexOf(uuid), 1);
global.settings.set_strv(ExtensionSystem.ENABLED_EXTENSIONS_KEY, enabledExtensions);
},
InstallRemoteExtension: function(uuid, version_tag) {
ExtensionSystem.installExtensionFromUUID(uuid, version_tag);
InstallRemoteExtension: function(uuid) {
ExtensionSystem.installExtensionFromUUID(uuid);
},
UninstallExtension: function(uuid) {

View File

@ -243,6 +243,7 @@ const ShellMountPasswordSource = new Lang.Class({
this.parent(strings[0]);
this._notification = new ShellMountPasswordNotification(this, strings, icon, reaskPassword);
this._setSummaryIcon(icon);
// add ourselves as a source, and popup the notification
Main.messageTray.add(this);

View File

@ -106,10 +106,7 @@ const Indicator = new Lang.Class({
/* TRANSLATORS: this means that bluetooth was disabled by hardware rfkill */
this._killswitch.setStatus(_("hardware disabled"));
if (has_adapter)
this.actor.show();
else
this.actor.hide();
this.actor.visible = has_adapter;
if (on) {
this._discoverable.actor.show();
@ -308,7 +305,7 @@ const Indicator = new Lang.Class({
_ensureSource: function() {
if (!this._source) {
this._source = new Source();
this._source = new MessageTray.Source(_("Bluetooth"), 'bluetooth-active', St.IconType.SYMBOLIC);
Main.messageTray.add(this._source);
}
},
@ -333,35 +330,6 @@ const Indicator = new Lang.Class({
}
});
const Source = new Lang.Class({
Name: 'BluetoothSource',
Extends: MessageTray.Source,
_init: function() {
this.parent(_("Bluetooth"));
this._setSummaryIcon(this.createNotificationIcon());
},
notify: function(notification) {
this._private_destroyId = notification.connect('destroy', Lang.bind(this, function(notification) {
if (this.notification == notification) {
// the destroyed notification is the last for this source
this.notification.disconnect(this._private_destroyId);
this.destroy();
}
}));
this.parent(notification);
},
createNotificationIcon: function() {
return new St.Icon({ icon_name: 'bluetooth-active',
icon_type: St.IconType.SYMBOLIC,
icon_size: this.ICON_SIZE });
}
});
const AuthNotification = new Lang.Class({
Name: 'AuthNotification',
Extends: MessageTray.Notification,
@ -412,7 +380,7 @@ const ConfirmNotification = new Lang.Class({
this._applet = applet;
this._devicePath = device_path;
this.addBody(_("Device %s wants to pair with this computer").format(long_name));
this.addBody(_("Please confirm whether the PIN '%s' matches the one on the device.").format(pin));
this.addBody(_("Please confirm whether the PIN '%06d' matches the one on the device.").format(pin));
this.addButton('matches', _("Matches"));
this.addButton('does-not-match', _("Does not match"));
@ -448,7 +416,8 @@ const PinNotification = new Lang.Class({
this._entry.connect('key-release-event', Lang.bind(this, function(entry, event) {
let key = event.get_key_symbol();
if (key == Clutter.KEY_Return) {
this.emit('action-invoked', 'ok');
if (this._canActivateOkButton())
this.emit('action-invoked', 'ok');
return true;
} else if (key == Clutter.KEY_Escape) {
this.emit('action-invoked', 'cancel');
@ -461,6 +430,12 @@ const PinNotification = new Lang.Class({
this.addButton('ok', _("OK"));
this.addButton('cancel', _("Cancel"));
this.setButtonSensitive('ok', this._canActivateOkButton());
this._entry.clutter_text.connect('text-changed', Lang.bind(this,
function() {
this.setButtonSensitive('ok', this._canActivateOkButton());
}));
this.connect('action-invoked', Lang.bind(this, function(self, action) {
if (action == 'ok') {
if (this._numeric) {
@ -483,6 +458,11 @@ const PinNotification = new Lang.Class({
}));
},
_canActivateOkButton: function() {
// PINs have a fixed length of 6
return this._entry.clutter_text.text.length == 6;
},
grabFocus: function(lockTray) {
this.parent(lockTray);
global.stage.set_key_focus(this._entry);

View File

@ -2,9 +2,9 @@
const Clutter = imports.gi.Clutter;
const GdkPixbuf = imports.gi.GdkPixbuf;
const Gkbd = imports.gi.Gkbd;
const Gio = imports.gi.Gio;
const GLib = imports.gi.GLib;
const GnomeDesktop = imports.gi.GnomeDesktop;
const Lang = imports.lang;
const Shell = imports.gi.Shell;
const St = imports.gi.St;
@ -14,30 +14,28 @@ const PopupMenu = imports.ui.popupMenu;
const PanelMenu = imports.ui.panelMenu;
const Util = imports.misc.util;
const DESKTOP_INPUT_SOURCES_SCHEMA = 'org.gnome.desktop.input-sources';
const KEY_CURRENT_INPUT_SOURCE = 'current';
const KEY_INPUT_SOURCES = 'sources';
const INPUT_SOURCE_TYPE_XKB = 'xkb';
const LayoutMenuItem = new Lang.Class({
Name: 'LayoutMenuItem',
Extends: PopupMenu.PopupBaseMenuItem,
_init: function(config, id, indicator, long_name) {
_init: function(displayName, shortName) {
this.parent();
this._config = config;
this._id = id;
this.label = new St.Label({ text: long_name });
this.indicator = indicator;
this.label = new St.Label({ text: displayName });
this.indicator = new St.Label({ text: shortName });
this.addActor(this.label);
this.addActor(this.indicator);
},
activate: function(event) {
this.parent(event);
this._config.lock_group(this._id);
}
});
const XKBIndicator = new Lang.Class({
Name: 'XKBIndicator',
const InputSourceIndicator = new Lang.Class({
Name: 'InputSourceIndicator',
Extends: PanelMenu.Button,
_init: function() {
@ -50,122 +48,144 @@ const XKBIndicator = new Lang.Class({
this.actor.add_actor(this._container);
this.actor.add_style_class_name('panel-status-button');
this._iconActor = new St.Icon({ icon_name: 'keyboard', icon_type: St.IconType.SYMBOLIC, style_class: 'system-status-icon' });
this._container.add_actor(this._iconActor);
this._labelActors = [ ];
this._layoutItems = [ ];
this._labelActors = {};
this._layoutItems = {};
this._showFlags = false;
this._config = Gkbd.Configuration.get();
this._config.connect('changed', Lang.bind(this, this._syncConfig));
this._config.connect('group-changed', Lang.bind(this, this._syncGroup));
this._config.start_listen();
this._settings = new Gio.Settings({ schema: DESKTOP_INPUT_SOURCES_SCHEMA });
this._settings.connect('changed::' + KEY_CURRENT_INPUT_SOURCE, Lang.bind(this, this._currentInputSourceChanged));
this._settings.connect('changed::' + KEY_INPUT_SOURCES, Lang.bind(this, this._inputSourcesChanged));
this._syncConfig();
this._currentSourceIndex = this._settings.get_uint(KEY_CURRENT_INPUT_SOURCE);
this._xkbInfo = new GnomeDesktop.XkbInfo();
if (global.session_type == Shell.SessionType.USER) {
this._inputSourcesChanged();
// re-using "allowSettings" for the keyboard layout is a bit shady,
// but at least for now it is used as "allow popping up windows
// from shell menus"; we can always add a separate sessionMode
// option if need arises.
if (Main.sessionMode.allowSettings) {
this.menu.addMenuItem(new PopupMenu.PopupSeparatorMenuItem());
this.menu.addAction(_("Show Keyboard Layout"), Lang.bind(this, function() {
Main.overview.hide();
Util.spawn(['gkbd-keyboard-display', '-g', String(this._config.get_current_group() + 1)]);
}));
this.menu.addAction(_("Show Keyboard Layout"), Lang.bind(this, this._showLayout));
}
this.menu.addSettingsAction(_("Region and Language Settings"), 'gnome-region-panel.desktop');
},
_adjustGroupNames: function(names) {
// Disambiguate duplicate names with a subscript
// This is O(N^2) to avoid sorting names
// but N <= 4 so who cares?
_currentInputSourceChanged: function() {
let nVisibleSources = Object.keys(this._layoutItems).length;
if (nVisibleSources < 2)
return;
for (let i = 0; i < names.length; i++) {
let name = names[i];
let cnt = 0;
for (let j = i + 1; j < names.length; j++) {
if (names[j] == name) {
cnt++;
// U+2081 SUBSCRIPT ONE
names[j] = name + String.fromCharCode(0x2081 + cnt);
}
}
if (cnt != 0)
names[i] = name + '\u2081';
let nSources = this._settings.get_value(KEY_INPUT_SOURCES).n_children();
let newCurrentSourceIndex = this._settings.get_uint(KEY_CURRENT_INPUT_SOURCE);
if (newCurrentSourceIndex >= nSources)
return;
if (!this._layoutItems[newCurrentSourceIndex]) {
// This source index is invalid as we weren't able to
// build a menu item for it, so we hide ourselves since we
// can't fix it here. *shrug*
this.menu.close();
this.actor.hide();
return;
} else {
this.actor.show();
}
return names;
if (this._layoutItems[this._currentSourceIndex]) {
this._layoutItems[this._currentSourceIndex].setShowDot(false);
this._container.set_skip_paint(this._labelActors[this._currentSourceIndex], true);
}
this._layoutItems[newCurrentSourceIndex].setShowDot(true);
this._container.set_skip_paint(this._labelActors[newCurrentSourceIndex], false);
this._currentSourceIndex = newCurrentSourceIndex;
},
_syncConfig: function() {
this._showFlags = this._config.if_flags_shown();
if (this._showFlags) {
this._container.set_skip_paint(this._iconActor, false);
} else {
this._container.set_skip_paint(this._iconActor, true);
_inputSourcesChanged: function() {
let sources = this._settings.get_value(KEY_INPUT_SOURCES);
let nSources = sources.n_children();
for (let i in this._layoutItems)
this._layoutItems[i].destroy();
for (let i in this._labelActors)
this._labelActors[i].destroy();
this._layoutItems = {};
this._labelActors = {};
let infos = [];
let infosByShortName = {};
for (let i = 0; i < nSources; i++) {
let [type, id] = sources.get_child_value(i).deep_unpack();
if (type != INPUT_SOURCE_TYPE_XKB)
continue;
let info = {};
[info.exists, info.displayName, info.shortName, , ] =
this._xkbInfo.get_layout_info(id);
if (!info.exists)
continue;
info.sourceIndex = i;
if (!(info.shortName in infosByShortName))
infosByShortName[info.shortName] = [];
infosByShortName[info.shortName].push(info);
infos.push(info);
}
let groups = this._config.get_group_names();
if (groups.length > 1) {
if (infos.length > 1) {
this.actor.show();
} else {
this.menu.close();
this.actor.hide();
}
for (let i = 0; i < this._layoutItems.length; i++)
this._layoutItems[i].destroy();
for (let i = 0; i < infos.length; i++) {
let info = infos[i];
if (infosByShortName[info.shortName].length > 1) {
let sub = infosByShortName[info.shortName].indexOf(info) + 1;
info.shortName += String.fromCharCode(0x2080 + sub);
}
for (let i = 0; i < this._labelActors.length; i++)
this._labelActors[i].destroy();
let short_names = this._adjustGroupNames(this._config.get_short_group_names());
this._selectedLayout = null;
this._layoutItems = [ ];
this._selectedLabel = null;
this._labelActors = [ ];
for (let i = 0; i < groups.length; i++) {
let icon_name = this._config.get_group_name(i);
let actor;
if (this._showFlags)
actor = new St.Icon({ icon_name: icon_name, icon_type: St.IconType.SYMBOLIC, style_class: 'popup-menu-icon' });
else
actor = new St.Label({ text: short_names[i] });
let item = new LayoutMenuItem(this._config, i, actor, groups[i]);
item._short_group_name = short_names[i];
item._icon_name = icon_name;
this._layoutItems.push(item);
let item = new LayoutMenuItem(info.displayName, info.shortName);
this._layoutItems[info.sourceIndex] = item;
this.menu.addMenuItem(item, i);
item.connect('activate', Lang.bind(this, function() {
this._settings.set_value(KEY_CURRENT_INPUT_SOURCE,
GLib.Variant.new_uint32(info.sourceIndex));
}));
let shortLabel = new St.Label({ text: short_names[i] });
this._labelActors.push(shortLabel);
let shortLabel = new St.Label({ text: info.shortName });
this._labelActors[info.sourceIndex] = shortLabel;
this._container.add_actor(shortLabel);
this._container.set_skip_paint(shortLabel, true);
}
this._syncGroup();
this._currentInputSourceChanged();
},
_syncGroup: function() {
let selected = this._config.get_current_group();
_showLayout: function() {
Main.overview.hide();
if (this._selectedLayout) {
this._selectedLayout.setShowDot(false);
this._selectedLayout = null;
}
let sources = this._settings.get_value(KEY_INPUT_SOURCES);
let current = this._settings.get_uint(KEY_CURRENT_INPUT_SOURCE);
let id = sources.get_child_value(current).deep_unpack()[1];
let [, , , xkbLayout, xkbVariant] = this._xkbInfo.get_layout_info(id);
if (this._selectedLabel) {
this._container.set_skip_paint(this._selectedLabel, true);
this._selectedLabel = null;
}
if (!xkbLayout || xkbLayout.length == 0)
return;
let item = this._layoutItems[selected];
item.setShowDot(true);
let description = xkbLayout;
if (xkbVariant.length > 0)
description = description + '\t' + xkbVariant;
this._iconActor.icon_name = item._icon_name;
this._selectedLabel = this._labelActors[selected];
this._container.set_skip_paint(this._selectedLabel, this._showFlags);
this._selectedLayout = item;
Util.spawn(['gkbd-keyboard-display', '-l', description]);
},
_containerGetPreferredWidth: function(container, for_height, alloc) {
@ -173,15 +193,11 @@ const XKBIndicator = new Lang.Class({
// for the height of all children, but we ignore the results
// for those we don't actually display.
let max_min_width = 0, max_natural_width = 0;
if (this._showFlags)
[max_min_width, max_natural_width] = this._iconActor.get_preferred_width(for_height);
for (let i = 0; i < this._labelActors.length; i++) {
for (let i in this._labelActors) {
let [min_width, natural_width] = this._labelActors[i].get_preferred_width(for_height);
if (!this._showFlags) {
max_min_width = Math.max(max_min_width, min_width);
max_natural_width = Math.max(max_natural_width, natural_width);
}
max_min_width = Math.max(max_min_width, min_width);
max_natural_width = Math.max(max_natural_width, natural_width);
}
alloc.min_size = max_min_width;
@ -190,15 +206,11 @@ const XKBIndicator = new Lang.Class({
_containerGetPreferredHeight: function(container, for_width, alloc) {
let max_min_height = 0, max_natural_height = 0;
if (this._showFlags)
[max_min_height, max_natural_height] = this._iconActor.get_preferred_height(for_width);
for (let i = 0; i < this._labelActors.length; i++) {
for (let i in this._labelActors) {
let [min_height, natural_height] = this._labelActors[i].get_preferred_height(for_width);
if (!this._showFlags) {
max_min_height = Math.max(max_min_height, min_height);
max_natural_height = Math.max(max_natural_height, natural_height);
}
max_min_height = Math.max(max_min_height, min_height);
max_natural_height = Math.max(max_natural_height, natural_height);
}
alloc.min_size = max_min_height;
@ -212,8 +224,7 @@ const XKBIndicator = new Lang.Class({
box.y2 -= box.y1;
box.y1 = 0;
this._iconActor.allocate_align_fill(box, 0.5, 0, false, false, flags);
for (let i = 0; i < this._labelActors.length; i++)
for (let i in this._labelActors)
this._labelActors[i].allocate_align_fill(box, 0.5, 0, false, false, flags);
}
});

View File

@ -304,9 +304,10 @@ const NMDevice = new Lang.Class({
// record the connection
let obj = {
connection: connections[i],
name: connections[i]._name,
uuid: connections[i]._uuid,
name: connections[i].get_id(),
uuid: connections[i].get_uuid(),
timestamp: connections[i]._timestamp,
item: null,
};
this._connections.push(obj);
}
@ -401,48 +402,46 @@ const NMDevice = new Lang.Class({
},
checkConnection: function(connection) {
let pos = this._findConnection(connection._uuid);
let pos = this._findConnection(connection.get_uuid());
let exists = pos != -1;
let valid = this.connectionValid(connection);
let similar = false;
if (exists) {
let existing = this._connections[pos];
if (exists && !valid)
this.removeConnection(connection);
else if (!exists && valid)
this.addConnection(connection);
else if (exists && valid) {
// propagate changes and update the UI
if (this._connections[pos].timestamp != connection._timestamp) {
this._connections[pos].timestamp = connection._timestamp;
this._connections.sort(this._connectionSortFunction);
this._clearSection();
this._queueCreateSection();
}
// Check if connection changed name or id
similar = existing.name == connection.get_id() &&
existing.timestamp == connection._timestamp;
}
if (exists && valid && similar) {
// Nothing to do
return;
}
if (exists)
this.removeConnection(connection);
if (valid)
this.addConnection(connection);
},
addConnection: function(connection) {
// record the connection
let obj = {
connection: connection,
name: connection._name,
uuid: connection._uuid,
name: connection.get_id(),
uuid: connection.get_uuid(),
timestamp: connection._timestamp,
item: null,
};
this._connections.push(obj);
this._connections.sort(this._connectionSortFunction);
Util.insertSorted(this._connections, obj, this._connectionSortFunction);
this._clearSection();
this._queueCreateSection();
},
removeConnection: function(connection) {
if (!connection._uuid) {
log('Cannot remove a connection without an UUID');
return;
}
let pos = this._findConnection(connection._uuid);
let pos = this._findConnection(connection.get_uuid());
if (pos == -1) {
// this connection was never added, nothing to do here
return;
@ -707,18 +706,15 @@ const NMDeviceWired = new Lang.Class({
// the device
// we can do it here because addConnection and removeConnection
// both call _createSection at some point
if (this._connections.length <= 1)
this.section.actor.hide();
else
this.section.actor.show();
this.section.actor.visible = this._connections.length > 1;
},
_createAutomaticConnection: function() {
let connection = new NetworkManager.Connection();
connection._uuid = NetworkManager.utils_uuid_generate();
let uuid = NetworkManager.utils_uuid_generate();
connection.add_setting(new NetworkManager.SettingWired());
connection.add_setting(new NetworkManager.SettingConnection({
uuid: connection._uuid,
uuid: uuid,
id: this._autoConnectionName,
type: NetworkManager.SETTING_WIRED_SETTING_NAME,
autoconnect: true
@ -862,10 +858,10 @@ const NMDeviceBluetooth = new Lang.Class({
_createAutomaticConnection: function() {
let connection = new NetworkManager.Connection;
connection._uuid = NetworkManager.utils_uuid_generate();
let uuid = NetworkManager.utils_uuid_generate();
connection.add_setting(new NetworkManager.SettingBluetooth);
connection.add_setting(new NetworkManager.SettingConnection({
uuid: connection._uuid,
uuid: uuid,
id: this._autoConnectionName,
type: NetworkManager.SETTING_BLUETOOTH_SETTING_NAME,
autoconnect: false
@ -900,12 +896,12 @@ const NMDeviceVPN = new Lang.Class({
Name: 'NMDeviceVPN',
Extends: NMDevice,
_init: function(client) {
_init: function(client, device, connections) {
// Disable autoconnections
this._autoConnectionName = null;
this.category = NMConnectionCategory.VPN;
this.parent(client, null, [ ]);
this.parent(client, null, connections);
},
connectionValid: function(connection) {
@ -917,13 +913,24 @@ const NMDeviceVPN = new Lang.Class({
},
get connected() {
return !!this._activeConnection;
if (!this._activeConnection)
return false;
return this._activeConnection.vpn_state == NetworkManager.VPNConnectionState.ACTIVATED;
},
setActiveConnection: function(activeConnection) {
if (this._stateChangeId)
this._activeConnection.disconnect(this._stateChangeId);
this._stateChangeId = 0;
this.parent(activeConnection);
this.emit('active-connection-changed');
if (this._activeConnection)
this._stateChangeId = this._activeConnection.connect('vpn-state-changed',
Lang.bind(this, this._connectionStateChanged));
this.emit('state-changed');
},
_shouldShowConnectionList: function() {
@ -936,7 +943,39 @@ const NMDeviceVPN = new Lang.Class({
},
getStatusLabel: function() {
return null;
if (!this._activeConnection) // Same as DISCONNECTED
return null;
switch(this._activeConnection.vpn_state) {
case NetworkManager.VPNConnectionState.DISCONNECTED:
case NetworkManager.VPNConnectionState.ACTIVATED:
return null;
case NetworkManager.VPNConnectionState.PREPARE:
case NetworkManager.VPNConnectionState.CONNECT:
case NetworkManager.VPNConnectionState.IP_CONFIG_GET:
return _("connecting...");
case NetworkManager.VPNConnectionState.NEED_AUTH:
/* Translators: this is for network connections that require some kind of key or password */
return _("authentication required");
case NetworkManager.VPNConnectionState.FAILED:
return _("connection failed");
default:
log('VPN connection state invalid, is %d'.format(this.device.state));
return 'invalid';
}
},
_connectionStateChanged: function(connection, newstate, reason) {
if (newstate == NetworkManager.VPNConnectionState.FAILED) {
// FIXME: if we ever want to show something based on reason,
// we need to convert from NetworkManager.VPNConnectionStateReason
// to NetworkManager.DeviceStateReason
this.emit('activation-failed', reason);
}
// Differently from real NMDevices, there is no need to queue
// an update of the menu section, contents wouldn't change anyway
this.emit('state-changed');
}
});
@ -1038,13 +1077,8 @@ const NMDeviceWireless = new Lang.Class({
},
setEnabled: function(enabled) {
if (enabled) {
this.statusItem.actor.show();
this.section.actor.show();
} else {
this.statusItem.actor.hide();
this.section.actor.hide();
}
this.statusItem.actor.visible = enabled;
this.section.actor.visible = enabled;
},
activate: function() {
@ -1331,9 +1365,7 @@ const NMDeviceWireless = new Lang.Class({
},
removeConnection: function(connection) {
if (!connection._uuid)
return;
let pos = this._findConnection(connection._uuid);
let pos = this._findConnection(connection.get_uuid());
if (pos == -1) {
// removing connection that was never added
return;
@ -1347,7 +1379,7 @@ const NMDeviceWireless = new Lang.Class({
let apObj = this._networks[i];
let connections = apObj.connections;
for (let k = 0; k < connections.length; k++) {
if (connections[k]._uuid == connection._uuid) {
if (connections[k].get_uuid() == connection.get_uuid()) {
// remove the connection from the access point group
connections.splice(k);
forceupdate = forceupdate || connections.length == 0;
@ -1363,7 +1395,7 @@ const NMDeviceWireless = new Lang.Class({
forceupdate = true;
} else {
for (let j = 0; j < items.length; j++) {
if (items[j]._connection._uuid == connection._uuid) {
if (items[j]._connection.get_uuid() == connection.get_uuid()) {
items[j].destroy();
break;
}
@ -1390,8 +1422,8 @@ const NMDeviceWireless = new Lang.Class({
// record the connection
let obj = {
connection: connection,
name: connection._name,
uuid: connection._uuid,
name: connection.get_id(),
uuid: connection.get_uuid(),
};
this._connections.push(obj);
@ -1538,7 +1570,7 @@ const NMApplet = new Lang.Class({
Extends: PanelMenu.SystemStatusButton,
_init: function() {
this.parent('network-error', _("Network"));
this.parent('network-offline', _("Network"));
this._client = NMClient.Client.new();
@ -1552,6 +1584,15 @@ const NMApplet = new Lang.Class({
this.menu.addMenuItem(this._statusSection);
this.menu.addMenuItem(new PopupMenu.PopupSeparatorMenuItem());
this._activeConnections = [ ];
this._connections = [ ];
this._mainConnection = null;
this._activeAccessPointUpdateId = 0;
this._activeAccessPoint = null;
this._mobileUpdateId = 0;
this._mobileUpdateDevice = null;
this._devices = { };
this._devices.wired = {
@ -1587,13 +1628,9 @@ const NMApplet = new Lang.Class({
this._devices.vpn = {
section: new PopupMenu.PopupMenuSection(),
device: new NMDeviceVPN(this._client),
device: this._makeWrapperDevice(NMDeviceVPN, null),
item: new NMWiredSectionTitleMenuItem(_("VPN Connections"))
};
this._devices.vpn.device.connect('active-connection-changed', Lang.bind(this, function() {
this._devices.vpn.item.updateForDevice(this._devices.vpn.device);
}));
this._devices.vpn.item.updateForDevice(this._devices.vpn.device);
this._devices.vpn.section.addMenuItem(this._devices.vpn.item);
this._devices.vpn.section.addMenuItem(this._devices.vpn.device.section);
this._devices.vpn.section.actor.hide();
@ -1601,15 +1638,6 @@ const NMApplet = new Lang.Class({
this.menu.addMenuItem(new PopupMenu.PopupSeparatorMenuItem());
this.menu.addSettingsAction(_("Network Settings"), 'gnome-network-panel.desktop');
this._activeConnections = [ ];
this._connections = [ ];
this._mainConnection = null;
this._activeAccessPointUpdateId = 0;
this._activeAccessPoint = null;
this._mobileUpdateId = 0;
this._mobileUpdateDevice = null;
// Device types
this._dtypes = { };
this._dtypes[NetworkManager.DeviceType.ETHERNET] = NMDeviceWired;
@ -1652,7 +1680,10 @@ const NMApplet = new Lang.Class({
_ensureSource: function() {
if (!this._source) {
this._source = new NMMessageTraySource();
this._source = new MessageTray.Source(_("Network Manager"),
'network-transmit-receive',
St.IconType.SYMBOLIC);
this._source.connect('destroy', Lang.bind(this, function() {
this._source = null;
}));
@ -1673,6 +1704,18 @@ const NMApplet = new Lang.Class({
},
_syncSectionTitle: function(category) {
if (category == NMConnectionCategory.VPN) {
// Special case VPN: it's only one device (and a fake one
// actually), and we don't show it if empty
let device = this._devices.vpn.device;
let section = this._devices.vpn.section;
let item = this._devices.vpn.item;
section.actor.visible = !device.empty;
item.updateForDevice(device);
return;
}
let devices = this._devices[category].devices;
let item = this._devices[category].item;
let section = this._devices[category].section;
@ -1723,6 +1766,29 @@ const NMApplet = new Lang.Class({
this._source.notify(device._notification);
},
_makeWrapperDevice: function(wrapperClass, device) {
let wrapper = new wrapperClass(this._client, device, this._connections);
wrapper._activationFailedId = wrapper.connect('activation-failed', Lang.bind(this, function(device, reason) {
// XXX: nm-applet has no special text depending on reason
// but I'm not sure of this generic message
this._notifyForDevice(device, 'network-error',
_("Connection failed"),
_("Activation of network connection failed"),
MessageTray.Urgency.HIGH);
}));
wrapper._deviceStateChangedId = wrapper.connect('state-changed', Lang.bind(this, function(dev) {
this._syncSectionTitle(dev.category);
}));
wrapper._destroyId = wrapper.connect('destroy', function(wrapper) {
wrapper.disconnect(wrapper._activationFailedId);
wrapper.disconnect(wrapper._deviceStateChangedId);
wrapper.disconnect(wrapper._destroyId);
});
return wrapper;
},
_deviceAdded: function(client, device) {
if (device._delegate) {
// already seen, not adding again
@ -1730,24 +1796,8 @@ const NMApplet = new Lang.Class({
}
let wrapperClass = this._dtypes[device.get_device_type()];
if (wrapperClass) {
let wrapper = new wrapperClass(this._client, device, this._connections);
let wrapper = this._makeWrapperDevice(wrapperClass, device);
wrapper._activationFailedId = wrapper.connect('activation-failed', Lang.bind(this, function(device, reason) {
// XXX: nm-applet has no special text depending on reason
// but I'm not sure of this generic message
this._notifyForDevice(device, 'network-error',
_("Connection failed"),
_("Activation of network connection failed"),
MessageTray.Urgency.HIGH);
}));
wrapper._deviceStateChangedId = wrapper.connect('state-changed', Lang.bind(this, function(dev) {
this._syncSectionTitle(dev.category);
}));
wrapper._destroyId = wrapper.connect('destroy', function(wrapper) {
wrapper.disconnect(wrapper._activationFailedId);
wrapper.disconnect(wrapper._deviceStateChangedId);
wrapper.disconnect(wrapper._destroyId);
});
let section = this._devices[wrapper.category].section;
let devices = this._devices[wrapper.category].devices;
@ -1883,7 +1933,7 @@ const NMApplet = new Lang.Class({
let connections = this._settings.list_connections();
for (let i = 0; i < connections.length; i++) {
let connection = connections[i];
if (connection._uuid) {
if (connection._updatedId) {
// connection was already seen (for example because NetworkManager was restarted)
continue;
}
@ -1896,7 +1946,7 @@ const NMApplet = new Lang.Class({
},
_newConnection: function(settings, connection) {
if (connection._uuid) {
if (connection._updatedId) {
// connection was already seen
return;
}
@ -1919,35 +1969,31 @@ const NMApplet = new Lang.Class({
if (section == NMConnectionCategory.VPN) {
this._devices.vpn.device.removeConnection(connection);
if (this._devices.vpn.device.empty)
this._devices.vpn.section.actor.hide();
this._syncSectionTitle(section);
} else if (section != NMConnectionCategory.INVALID) {
let devices = this._devices[section].devices;
for (let i = 0; i < devices.length; i++)
devices[i].removeConnection(connection);
}
connection._uuid = null;
connection.disconnect(connection._removedId);
connection.disconnect(connection._updatedId);
connection._removedId = connection._updatedId = 0;
},
_updateConnection: function(connection) {
let connectionSettings = connection.get_setting_by_name(NetworkManager.SETTING_CONNECTION_SETTING_NAME);
connection._type = connectionSettings.type;
connection._section = this._ctypes[connection._type] || NMConnectionCategory.INVALID;
connection._name = connectionSettings.id;
connection._uuid = connectionSettings.uuid;
connection._timestamp = connectionSettings.timestamp;
let section = connection._section;
if (connection._section == NMConnectionCategory.INVALID)
if (section == NMConnectionCategory.INVALID)
return;
if (section == NMConnectionCategory.VPN) {
this._devices.vpn.device.checkConnection(connection);
this._devices.vpn.section.actor.show();
this._syncSectionTitle(section);
} else {
let devices = this._devices[section].devices;
for (let i = 0; i < devices.length; i++) {
@ -1970,12 +2016,10 @@ const NMApplet = new Lang.Class({
this._statusSection.actor.hide();
this._syncSectionTitle('wired');
this._syncSectionTitle('wireless');
this._syncSectionTitle('wwan');
if (!this._devices.vpn.device.empty)
this._devices.vpn.section.actor.show();
this._syncSectionTitle(NMConnectionCategory.WIRED);
this._syncSectionTitle(NMConnectionCategory.WIRELESS);
this._syncSectionTitle(NMConnectionCategory.WWAN);
this._syncSectionTitle(NMConnectionCategory.VPN);
},
_syncNMState: function() {
@ -2108,18 +2152,3 @@ const NMApplet = new Lang.Class({
}
}
});
const NMMessageTraySource = new Lang.Class({
Name: 'NMMessageTraySource',
Extends: MessageTray.Source,
_init: function() {
this.parent(_("Network Manager"));
let icon = new St.Icon({ icon_name: 'network-transmit-receive',
icon_type: St.IconType.SYMBOLIC,
icon_size: this.ICON_SIZE
});
this._setSummaryIcon(icon);
}
});

View File

@ -212,7 +212,7 @@ const DeviceItem = new Lang.Class({
case UPDeviceType.COMPUTER:
return _("Computer");
default:
return _("Unknown");
return C_("device", "Unknown");
}
}
});

View File

@ -149,13 +149,9 @@ const Indicator = new Lang.Class({
}
}
}
if (showInput) {
this._inputTitle.actor.show();
this._inputSlider.actor.show();
} else {
this._inputTitle.actor.hide();
this._inputSlider.actor.hide();
}
this._inputTitle.actor.visible = showInput;
this._inputSlider.actor.visible = showInput;
},
_volumeToIcon: function(volume) {

View File

@ -365,8 +365,9 @@ const Client = new Lang.Class({
_ensureSubscriptionSource: function() {
if (this._subscriptionSource == null) {
this._subscriptionSource = new MultiNotificationSource(
_("Subscription request"), 'gtk-dialog-question');
this._subscriptionSource = new MessageTray.Source(_("Subscription request"),
'gtk-dialog-question',
St.IconType.FULLCOLOR);
Main.messageTray.add(this._subscriptionSource);
this._subscriptionSource.connect('destroy', Lang.bind(this, function () {
this._subscriptionSource = null;
@ -401,8 +402,9 @@ const Client = new Lang.Class({
_ensureAccountSource: function() {
if (this._accountSource == null) {
this._accountSource = new MultiNotificationSource(
_("Connection error"), 'gtk-dialog-error');
this._accountSource = new MessageTray.Source(_("Connection error"),
'gtk-dialog-error',
St.IconType.FULLCOLOR);
Main.messageTray.add(this._accountSource);
this._accountSource.connect('destroy', Lang.bind(this, function () {
this._accountSource = null;
@ -418,14 +420,13 @@ const ChatSource = new Lang.Class({
Extends: MessageTray.Source,
_init: function(account, conn, channel, contact, client) {
this.parent(contact.get_alias());
this.isChat = true;
this._account = account;
this._contact = contact;
this._client = client;
this.parent(contact.get_alias());
this.isChat = true;
this._pendingMessages = [];
this._conn = conn;
@ -446,8 +447,6 @@ const ChatSource = new Lang.Class({
this._receivedId = this._channel.connect('message-received', Lang.bind(this, this._messageReceived));
this._pendingId = this._channel.connect('pending-message-removed', Lang.bind(this, this._pendingRemoved));
this._setSummaryIcon(this.createNotificationIcon());
this._notifyAliasId = this._contact.connect('notify::alias', Lang.bind(this, this._updateAlias));
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));
@ -510,10 +509,10 @@ const ChatSource = new Lang.Class({
_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));
logManager.get_filtered_events_async(this._account, entity,
Tpl.EventTypeMask.TEXT, SCROLLBACK_HISTORY_LINES,
null, Lang.bind(this, this._displayPendingMessages));
},
_displayPendingMessages: function(logManager, result) {
@ -1002,10 +1001,9 @@ const ApproverSource = new Lang.Class({
Extends: MessageTray.Source,
_init: function(dispatchOp, text, gicon) {
this.parent(text);
this._gicon = gicon;
this._setSummaryIcon(this.createNotificationIcon());
this.parent(text);
this._dispatchOp = dispatchOp;
@ -1028,7 +1026,6 @@ const ApproverSource = new Lang.Class({
createNotificationIcon: function() {
return new St.Icon({ gicon: this._gicon,
icon_type: St.IconType.FULLCOLOR,
icon_size: this.ICON_SIZE });
}
});
@ -1151,40 +1148,6 @@ const FileTransferNotification = new Lang.Class({
}
});
// A notification source that can embed multiple notifications
const MultiNotificationSource = new Lang.Class({
Name: 'MultiNotificationSource',
Extends: MessageTray.Source,
_init: function(title, icon) {
this.parent(title);
this._icon = icon;
this._setSummaryIcon(this.createNotificationIcon());
this._nbNotifications = 0;
},
notify: function(notification) {
this.parent(notification);
this._nbNotifications += 1;
// Display the source while there is at least one notification
notification.connect('destroy', Lang.bind(this, function () {
this._nbNotifications -= 1;
if (this._nbNotifications == 0)
this.destroy();
}));
},
createNotificationIcon: function() {
return new St.Icon({ gicon: Gio.icon_new_for_string(this._icon),
icon_type: St.IconType.FULLCOLOR,
icon_size: this.ICON_SIZE });
}
});
// Subscription request
const SubscriptionRequestNotification = new Lang.Class({
Name: 'SubscriptionRequestNotification',

View File

@ -1,6 +1,7 @@
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
const AccountsService = imports.gi.AccountsService;
const GdmGreeter = imports.gi.GdmGreeter;
const Gio = imports.gi.Gio;
const GLib = imports.gi.GLib;
const Lang = imports.lang;
@ -473,13 +474,22 @@ const UserMenuButton = new Lang.Class({
style_class: 'popup-menu-icon' });
this._idleIcon = new St.Icon({ icon_name: 'user-idle',
style_class: 'popup-menu-icon' });
this._pendingIcon = new St.Icon({ icon_name: 'user-status-pending',
style_class: 'popup-menu-icon' });
this._accountMgr.connect('most-available-presence-changed',
Lang.bind(this, this._updatePresenceIcon));
this._accountMgr.connect('account-enabled',
Lang.bind(this, this._onAccountEnabled));
this._accountMgr.connect('account-disabled',
Lang.bind(this, this._onAccountDisabled));
this._accountMgr.connect('account-removed',
Lang.bind(this, this._onAccountDisabled));
this._accountMgr.prepare_async(null, Lang.bind(this,
function(mgr) {
let [presence, s, msg] = mgr.get_most_available_presence();
this._updatePresenceIcon(mgr, presence, s, msg);
this._setupAccounts();
}));
this._name = new St.Label();
@ -497,13 +507,13 @@ const UserMenuButton = new Lang.Class({
}));
this._userManager.connect('notify::is-loaded',
Lang.bind(this, this._updateSwitchUser));
Lang.bind(this, this._updateMultiUser));
this._userManager.connect('notify::has-multiple-users',
Lang.bind(this, this._updateSwitchUser));
Lang.bind(this, this._updateMultiUser));
this._userManager.connect('user-added',
Lang.bind(this, this._updateSwitchUser));
Lang.bind(this, this._updateMultiUser));
this._userManager.connect('user-removed',
Lang.bind(this, this._updateSwitchUser));
Lang.bind(this, this._updateMultiUser));
this._lockdownSettings.connect('changed::' + DISABLE_USER_SWITCH_KEY,
Lang.bind(this, this._updateSwitchUser));
this._lockdownSettings.connect('changed::' + DISABLE_LOG_OUT_KEY,
@ -542,30 +552,32 @@ const UserMenuButton = new Lang.Class({
this._name.set_text("");
},
_updateMultiUser: function() {
this._updateSwitchUser();
this._updateLogout();
},
_updateSwitchUser: function() {
let allowSwitch = !this._lockdownSettings.get_boolean(DISABLE_USER_SWITCH_KEY);
if (allowSwitch &&
this._userManager.can_switch() &&
this._userManager.has_multiple_users)
this._loginScreenItem.actor.show();
else
this._loginScreenItem.actor.hide();
let multiUser = this._userManager.can_switch() && this._userManager.has_multiple_users;
let multiSession = GdmGreeter.get_session_ids().length > 1;
this._loginScreenItem.label.set_text(multiUser ? _("Switch User")
: _("Switch Session"));
this._loginScreenItem.actor.visible = allowSwitch && (multiUser || multiSession);
},
_updateLogout: function() {
let allowLogout = !this._lockdownSettings.get_boolean(DISABLE_LOG_OUT_KEY);
if (allowLogout)
this._logoutItem.actor.show();
else
this._logoutItem.actor.hide();
let multiUser = this._userManager.has_multiple_users;
let multiSession = GdmGreeter.get_session_ids().length > 1;
this._logoutItem.actor.visible = allowLogout && (multiUser || multiSession);
},
_updateLockScreen: function() {
let allowLockScreen = !this._lockdownSettings.get_boolean(DISABLE_LOCK_SCREEN_KEY);
if (allowLockScreen)
this._lockScreenItem.actor.show();
else
this._lockScreenItem.actor.hide();
this._lockScreenItem.actor.visible = allowLockScreen;
},
_updateHaveShutdown: function() {
@ -584,19 +596,16 @@ const UserMenuButton = new Lang.Class({
if (!this._suspendOrPowerOffItem)
return;
if (!this._haveShutdown && !this._haveSuspend)
this._suspendOrPowerOffItem.actor.hide();
else
this._suspendOrPowerOffItem.actor.show();
this._suspendOrPowerOffItem.actor.visible = this._haveShutdown || this._haveSuspend;
// If we can't suspend show Power Off... instead
// If we can't power off show Suspend instead
// and disable the alt key
if (!this._haveSuspend) {
this._suspendOrPowerOffItem.updateText(_("Power Off..."), null);
} else if (!this._haveShutdown) {
if (!this._haveShutdown) {
this._suspendOrPowerOffItem.updateText(_("Suspend"), null);
} else if (!this._haveSuspend) {
this._suspendOrPowerOffItem.updateText(_("Power Off"), null);
} else {
this._suspendOrPowerOffItem.updateText(_("Suspend"), _("Power Off..."));
this._suspendOrPowerOffItem.updateText(_("Power Off"), _("Suspend"));
}
},
@ -620,11 +629,52 @@ const UserMenuButton = new Lang.Class({
this._iconBox.child = this._offlineIcon;
},
_setupAccounts: function() {
let accounts = this._accountMgr.get_valid_accounts();
for (let i = 0; i < accounts.length; i++) {
accounts[i]._changingId = accounts[i].connect('notify::connection-status',
Lang.bind(this, this._updateChangingPresence));
}
this._updateChangingPresence();
},
_onAccountEnabled: function(accountMgr, account) {
if (!account._changingId)
account._changingId = account.connect('notify::connection-status',
Lang.bind(this, this._updateChangingPresence));
this._updateChangingPresence();
},
_onAccountDisabled: function(accountMgr, account) {
account.disconnect(account._changingId);
account._changingId = 0;
this._updateChangingPresence();
},
_updateChangingPresence: function() {
let accounts = this._accountMgr.get_valid_accounts();
let changing = false;
for (let i = 0; i < accounts.length; i++) {
if (accounts[i].connection_status == Tp.ConnectionStatus.CONNECTING) {
changing = true;
break;
}
}
if (changing) {
this._iconBox.child = this._pendingIcon;
} else {
let [presence, s, msg] = this._accountMgr.get_most_available_presence();
this._updatePresenceIcon(this._accountMgr, presence, s, msg);
}
},
_createSubMenu: function() {
let item;
item = new IMStatusChooserItem();
item.connect('activate', Lang.bind(this, this._onMyAccountActivate));
if (Main.sessionMode.allowSettings)
item.connect('activate', Lang.bind(this, this._onMyAccountActivate));
this.menu.addMenuItem(item);
this._statusChooser = item;
@ -636,28 +686,28 @@ const UserMenuButton = new Lang.Class({
item = new PopupMenu.PopupSeparatorMenuItem();
this.menu.addMenuItem(item);
item = new PopupMenu.PopupMenuItem(_("Online Accounts"));
item.connect('activate', Lang.bind(this, this._onOnlineAccountsActivate));
this.menu.addMenuItem(item);
if (Main.sessionMode.allowSettings) {
item = new PopupMenu.PopupMenuItem(_("System Settings"));
item.connect('activate', Lang.bind(this, this._onPreferencesActivate));
this.menu.addMenuItem(item);
}
item = new PopupMenu.PopupMenuItem(_("System Settings"));
item.connect('activate', Lang.bind(this, this._onPreferencesActivate));
item = new PopupMenu.PopupAlternatingMenuItem(_("Power Off"),
_("Suspend"));
this.menu.addMenuItem(item);
item.connect('activate', Lang.bind(this, this._onSuspendOrPowerOffActivate));
this._suspendOrPowerOffItem = item;
this._updateSuspendOrPowerOff();
item = new PopupMenu.PopupSeparatorMenuItem();
this.menu.addMenuItem(item);
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));
this.menu.addMenuItem(item);
this._loginScreenItem = item;
item = new PopupMenu.PopupMenuItem(_("Log Out..."));
item = new PopupMenu.PopupMenuItem(_("Log Out"));
item.connect('activate', Lang.bind(this, this._onQuitSessionActivate));
this.menu.addMenuItem(item);
this._logoutItem = item;
@ -665,12 +715,10 @@ const UserMenuButton = new Lang.Class({
item = new PopupMenu.PopupSeparatorMenuItem();
this.menu.addMenuItem(item);
item = new PopupMenu.PopupAlternatingMenuItem(_("Suspend"),
_("Power Off..."));
item = new PopupMenu.PopupMenuItem(_("Lock"));
item.connect('activate', Lang.bind(this, this._onLockScreenActivate));
this.menu.addMenuItem(item);
this._suspendOrPowerOffItem = item;
item.connect('activate', Lang.bind(this, this._onSuspendOrPowerOffActivate));
this._updateSuspendOrPowerOff();
this._lockScreenItem = item;
},
_updatePresenceStatus: function(item, event) {
@ -698,12 +746,6 @@ const UserMenuButton = new Lang.Class({
app.activate();
},
_onOnlineAccountsActivate: function() {
Main.overview.hide();
let app = Shell.AppSystem.get_default().lookup_setting('gnome-online-accounts-panel.desktop');
app.activate(-1);
},
_onPreferencesActivate: function() {
Main.overview.hide();
let app = Shell.AppSystem.get_default().lookup_app('gnome-control-center.desktop');
@ -732,14 +774,14 @@ const UserMenuButton = new Lang.Class({
_onSuspendOrPowerOffActivate: function() {
Main.overview.hide();
if (this._haveSuspend &&
if (this._haveShutdown &&
this._suspendOrPowerOffItem.state == PopupMenu.PopupAlternatingMenuItemState.DEFAULT) {
this._session.ShutdownRemote();
} else {
// Ensure we only suspend after locking the screen
this._screenSaverProxy.LockRemote(Lang.bind(this, function() {
this._upClient.suspend_sync(null);
}));
} else {
this._session.ShutdownRemote();
}
}
});

View File

@ -168,34 +168,35 @@ const WandaSearchProvider = new Lang.Class({
this.parent(_("Your favorite Easter Egg"));
},
getResultMetas: function(fish) {
return [{ 'id': fish[0], // there may be many fish in the sea, but
// only one which speaks the truth!
'name': capitalize(fish[0]),
'createIcon': function(iconSize) {
// for DND only (maybe could be improved)
// DON'T use St.Icon here, it crashes the shell
// (dnd.js code assumes it can query the actor size
// without parenting it, while StWidget accesses
// StThemeNode in get_preferred_width/height, which
// triggers an assertion failure)
return St.TextureCache.get_default().load_icon_name(null,
'face-smile',
St.IconType.FULLCOLOR,
iconSize);
}
}];
getResultMetas: function(fish, callback) {
callback([{ 'id': fish[0], // there may be many fish in the sea, but
// only one which speaks the truth!
'name': capitalize(fish[0]),
'createIcon': function(iconSize) {
// for DND only (maybe could be improved)
// DON'T use St.Icon here, it crashes the shell
// (dnd.js code assumes it can query the actor size
// without parenting it, while StWidget accesses
// StThemeNode in get_preferred_width/height, which
// triggers an assertion failure)
return St.TextureCache.get_default().load_icon_name(null,
'face-smile',
St.IconType.FULLCOLOR,
iconSize);
}
}]);
},
getInitialResultSet: function(terms) {
if (terms.join(' ') == MAGIC_FISH_KEY) {
return [ FISH_NAME ];
this.searchSystem.pushResults(this, [ FISH_NAME ]);
} else {
this.searchSystem.pushResults(this, []);
}
return [];
},
getSubsearchResultSet: function(previousResults, terms) {
return this.getInitialResultSet(terms);
this.getInitialResultSet(terms);
},
activateResult: function(fish, params) {

View File

@ -53,10 +53,10 @@ const Source = new Lang.Class({
Extends: MessageTray.Source,
_init: function(app, window) {
this.parent(app.get_name());
this._window = window;
this._app = app;
this._setSummaryIcon(this.createNotificationIcon());
this.parent(app.get_name());
this.signalIDs = [];
this.signalIDs.push(this._window.connect('notify::demands-attention', Lang.bind(this, function() { this.destroy(); })));

View File

@ -1134,7 +1134,6 @@ const Workspace = new Lang.Class({
_hideAllOverlays: function() {
for (let i = 0; i < this._windows.length; i++) {
let clone = this._windows[i];
Tweener.removeTweens(clone.actor);
let overlay = this._windowOverlays[i];
if (overlay)
overlay.hide();
@ -1252,7 +1251,7 @@ const Workspace = new Lang.Class({
if (!this._isMyWindow(win) || !this._isOverviewWindow(win))
return;
let clone = this._addWindowClone(win);
let [clone, overlay] = this._addWindowClone(win);
if (win._overviewHint) {
let x = win._overviewHint.x - this.actor.x;
@ -1262,6 +1261,7 @@ const Workspace = new Lang.Class({
clone.actor.set_position (x, y);
clone.actor.set_scale (scale, scale);
this._updateWindowOverlayPositions(clone, overlay, x, y, scale, false);
} else {
// Position new windows at the top corner of the workspace rather
// than where they were placed for real to avoid the window
@ -1321,7 +1321,10 @@ const Workspace = new Lang.Class({
this.leavingOverview = true;
this._hideAllOverlays();
for (let i = 0; i < this._windows.length; i++) {
let clone = this._windows[i];
Tweener.removeTweens(clone.actor);
}
if (this._repositionWindowsId > 0) {
Mainloop.source_remove(this._repositionWindowsId);
@ -1361,6 +1364,7 @@ const Workspace = new Lang.Class({
}
}
this._hideAllOverlays();
},
destroy : function() {
@ -1451,7 +1455,7 @@ const Workspace = new Lang.Class({
this._windows.push(clone);
this._windowOverlays.push(overlay);
return clone;
return [clone, overlay];
},
_onShowOverlayClose: function (windowOverlay) {

View File

@ -529,9 +529,11 @@ const WorkspacesDisplay = new Lang.Class({
this._updateAlwaysZoom();
}));
global.screen.connect('notify::n-workspaces',
Lang.bind(this, this._workspacesChanged));
this._switchWorkspaceNotifyId = 0;
this._nWorkspacesChangedId = 0;
this._itemDragBeginId = 0;
this._itemDragCancelledId = 0;
this._itemDragEndId = 0;
@ -570,9 +572,6 @@ const WorkspacesDisplay = new Lang.Class({
global.screen.connect('restacked',
Lang.bind(this, this._onRestacked));
if (this._nWorkspacesChangedId == 0)
this._nWorkspacesChangedId = global.screen.connect('notify::n-workspaces',
Lang.bind(this, this._workspacesChanged));
if (this._itemDragBeginId == 0)
this._itemDragBeginId = Main.overview.connect('item-drag-begin',
Lang.bind(this, this._dragBegin));
@ -844,10 +843,7 @@ const WorkspacesDisplay = new Lang.Class({
if (!primaryView)
return;
primaryView.actor.opacity = opacity;
if (opacity == 0)
primaryView.actor.hide();
else
primaryView.actor.show();
primaryView.actor.visible = opacity != 0;
}));
}));
},
@ -928,19 +924,16 @@ const WorkspacesDisplay = new Lang.Class({
},
_workspacesChanged: function() {
let oldNumWorkspaces = this._workspaces[0].length;
let newNumWorkspaces = global.screen.n_workspaces;
let active = global.screen.get_active_workspace_index();
if (oldNumWorkspaces == newNumWorkspaces)
return;
this._updateAlwaysZoom();
this._updateZoom();
if (this._workspacesViews == null)
return;
let oldNumWorkspaces = this._workspaces[0].length;
let newNumWorkspaces = global.screen.n_workspaces;
let active = global.screen.get_active_workspace_index();
let lostWorkspaces = [];
if (newNumWorkspaces > oldNumWorkspaces) {
let monitors = Main.layoutManager.monitors;

View File

@ -1,2 +1,3 @@
data/gnome-shell.desktop.in
data/gnome-shell-extension-prefs.desktop.in
data/org.gnome.shell.evolution.calendar.gschema.xml.in

746
po/el.po

File diff suppressed because it is too large Load Diff

492
po/es.po

File diff suppressed because it is too large Load Diff

488
po/gl.po

File diff suppressed because it is too large Load Diff

673
po/he.po

File diff suppressed because it is too large Load Diff

1179
po/id.po

File diff suppressed because it is too large Load Diff

454
po/it.po

File diff suppressed because it is too large Load Diff

608
po/ja.po

File diff suppressed because it is too large Load Diff

303
po/ko.po
View File

@ -1,14 +1,19 @@
# This file is distributed under the same license as the gnome-shell package.
# Young-Ho Cha <ganadist@gmail.com>, 2009.
# Changwoo Ryu <cwryu@debian.org>, 2011-2012.
# Seong-ho Cho <darkcircle.0426@gmail.com>, 2012.
# Changwoo Ryu <cwryu@debian.org>, 2011-2012.
#
#
# 주의 사항:
# - 이 프로그램의 이름인 shell은 "셸"이라고 쓰고, "쉘"이라고 하지 않음.
# - instance messanger 또는 IM은 메신저라고 번역
#
msgid ""
msgstr ""
"Project-Id-Version: gnome-shell\n"
"Report-Msgid-Bugs-To: http://bugzilla.gnome.org/enter_bug.cgi?product=gnome-shell&keywords=I18N+L10N&component=general\n"
"POT-Creation-Date: 2012-03-19 14:09+0000\n"
"PO-Revision-Date: 2012-03-27 01:36+0900\n"
"POT-Creation-Date: 2012-04-19 21:14+0000\n"
"PO-Revision-Date: 2012-05-19 22:57+0900\n"
"Last-Translator: Changwoo Ryu <cwryu@debian.org>\n"
"Language-Team: GNOME Korea <gnome-kr@googlegroups.com>\n"
"MIME-Version: 1.0\n"
@ -23,31 +28,30 @@ msgstr "그놈 셸"
#: ../data/gnome-shell.desktop.in.in.h:2
msgid "Window management and application launching"
msgstr "창 관리 프로그램 시작"
msgstr "창 관리 프로그램 실행"
#: ../data/gnome-shell-extension-prefs.desktop.in.in.h:1
#: ../js/extensionPrefs/main.js:153
msgid "GNOME Shell Extension Preferences"
msgstr "그놈 확장 기본 설정"
msgstr "그놈 확장 기본 설정"
#: ../data/gnome-shell-extension-prefs.desktop.in.in.h:2
msgid "Configure GNOME Shell Extensions"
msgstr "그놈 확장을 설정합니다"
msgstr "그놈 확장을 설정합니다"
#: ../data/org.gnome.shell.gschema.xml.in.h:1
msgid "Enable internal tools useful for developers and testers from Alt-F2"
msgstr "Alt-F2를 이용해 개발 및 테스트용 내부 프로그램 사용 가능"
msgstr "Alt-F2에서 개발 및 테스트용 내부 기능 사용 가능"
#: ../data/org.gnome.shell.gschema.xml.in.h:2
msgid ""
"Allows access to internal debugging and monitoring tools using the Alt-F2 "
"dialog."
msgstr ""
"Alt-F2 대화 상자를 사용할 때 내부 디버깅 및 감시 도구에 접근을 허용합니다."
msgstr "Alt-F2 대화 상자에서 내부 디버깅 및 감시 기능에 접근을 허용합니다."
#: ../data/org.gnome.shell.gschema.xml.in.h:3
msgid "Uuids of extensions to enable"
msgstr "사용할 확장 기능의 UUID"
msgstr "사용할 확장의 UUID 목록"
#: ../data/org.gnome.shell.gschema.xml.in.h:4
msgid ""
@ -55,14 +59,11 @@ msgid ""
"should be loaded. Any extension that wants to be loaded needs to be in this "
"list. You can also manipulate this list with the EnableExtension and "
"DisableExtension DBus methods on org.gnome.Shell."
msgstr ""
"그놈 셸 확장에 UUID 속성이 있으며 이 키는 불러올 확장을 나열합니다. 불러오려"
"는 확장은 이 목록에 있을 필요가 있습니다. 또한 이 목록을 org.gnome.Shell에 있"
"는 EnableExtension과 DisableExtension DBus 메서드로 조작할 수 있습니다."
msgstr "그놈 셸 확장에는 UUID 속성이 있습니다. 이 키는 읽어들일 확장의 UUID를 나열합니다. 읽어들이려는 확장은 모두 이 목록에 들어 있어야 합니다. EnableExtension 및 DisableExtension D-버스 메소드를 이용해 이 목록을 조작할 수도 있습니다."
#: ../data/org.gnome.shell.gschema.xml.in.h:5
msgid "Whether to collect stats about applications usage"
msgstr "프로그램 사용 통계를 저장할지 여부"
msgstr "프로그램 사용 통계를 수집할지 여부"
#: ../data/org.gnome.shell.gschema.xml.in.h:6
msgid ""
@ -70,11 +71,7 @@ msgid ""
"used ones (e.g. in launchers). While this data will be kept private, you may "
"want to disable this for privacy reasons. Please note that doing so won't "
"remove already saved data."
msgstr ""
"셸에서는 최근에 사용한 프로그램을 (실행 메뉴 등에서) 표시하는 목적으로, 현재 "
"사용 중인 프로그램을 감시합니다. 이 데이터는 비공개 데이터이지만 사생활 문제"
"가 걱정된다면 이 기능을 끌 수도 있습니다. 단 이 기능을 사용하지 않더라도 이"
"미 저장된 데이터를 제거하지는 않습니다."
msgstr "셸에서는 최근에 사용한 프로그램을(실행 메뉴 등에서) 표시하는 목적으로, 현재 사용 중인 프로그램을 감시합니다. 이 데이터는 비공개 데이터이지만 사생활 문제가 걱정된다면 이 기능을 끌 수도 있습니다. 단 이 기능을 사용하지 않더라도 이미 저장된 데이터를 제거하지는 않습니다."
#: ../data/org.gnome.shell.gschema.xml.in.h:7
msgid "List of desktop file IDs for favorite applications"
@ -84,35 +81,31 @@ msgstr "즐겨찾기 프로그램의 데스크톱 파일 ID 목록"
msgid ""
"The applications corresponding to these identifiers will be displayed in the "
"favorites area."
msgstr " ID에 해당하는 프로그램은 즐겨찾기 영역에 표시됩니다."
msgstr "여기 들어 있는 ID에 해당하는 프로그램은 즐겨찾기 영역에 표시됩니다."
#: ../data/org.gnome.shell.gschema.xml.in.h:9
msgid "disabled OpenSearch providers"
msgstr "OpenSearch 서비스 사용하지 않음"
msgstr "사용하지 않는 OpenSearch 서비스"
#: ../data/org.gnome.shell.gschema.xml.in.h:10
msgid "History for command (Alt-F2) dialog"
msgstr "명령어 (Alt-F2) 대화 상자에 명령어 기록 기능"
msgstr "명령어 대화 상자에(Alt-F2) 기록 기능"
#: ../data/org.gnome.shell.gschema.xml.in.h:11
msgid "History for the looking glass dialog"
msgstr "돋보기 대화 창의 기록"
msgstr "돋보기 대화 상자에 기록 기능"
#: ../data/org.gnome.shell.gschema.xml.in.h:12
msgid ""
"Internally used to store the last IM presence explicitly set by the user. "
"The value here is from the TpConnectionPresenceType enumeration."
msgstr ""
"사용자가 명시적으로 설정한 최근 IM 존재를 저장하기 위해 내부적으로 사용했습니"
"다. 이 값은 TpConnectionPresenceType 열거상수로부터 왔습니다."
msgstr "사용자가 직접 설정한 메신저 상태를 저장하는데 내부적으로 사용. 여기에 사용하는 값은 TpConnectionPresenceType 열거 상수 값입니다."
#: ../data/org.gnome.shell.gschema.xml.in.h:13
msgid ""
"Internally used to store the last session presence status for the user. The "
"value here is from the GsmPresenceStatus enumeration."
msgstr ""
"사용자를 위한 최근 세션 존재 상태를 저장하기 위해 내부적으로 사용합니다. 이 "
"값은 GsmPresenceStatus 열거상수로부터 왔습니다."
msgstr "사용자의 최근 세션 상태를 저장하는데 내부적으로 사용. 여기에 사용하는 값은 GsmPresenceStatus 열거 상수 값입니다."
#: ../data/org.gnome.shell.gschema.xml.in.h:14
msgid "Show the week date in the calendar"
@ -123,45 +116,52 @@ msgid "If true, display the ISO week date in the calendar."
msgstr "참이면 달력에 ISO 요일을 표시합니다."
#: ../data/org.gnome.shell.gschema.xml.in.h:16
msgid "Keybinding to open the application menu"
msgstr "프로그램 메뉴를 여는 키 바인딩"
#: ../data/org.gnome.shell.gschema.xml.in.h:17
msgid "Keybinding to open the application menu."
msgstr "프로그램 메뉴를 여는 키 바인딩."
#: ../data/org.gnome.shell.gschema.xml.in.h:18
msgid "Which keyboard to use"
msgstr "사용할 키보드"
#: ../data/org.gnome.shell.gschema.xml.in.h:17
#: ../data/org.gnome.shell.gschema.xml.in.h:19
msgid "The type of keyboard to use."
msgstr "사용할 키보드의 종류."
#: ../data/org.gnome.shell.gschema.xml.in.h:18
#: ../data/org.gnome.shell.gschema.xml.in.h:20
msgid "Show time with seconds"
msgstr "시각에 초 표시"
#: ../data/org.gnome.shell.gschema.xml.in.h:19
#: ../data/org.gnome.shell.gschema.xml.in.h:21
msgid "If true, display seconds in time."
msgstr "참이면 시각에 초를 표시합니다."
#: ../data/org.gnome.shell.gschema.xml.in.h:20
#: ../data/org.gnome.shell.gschema.xml.in.h:22
msgid "Show date in clock"
msgstr "시계에 날짜 표시"
#: ../data/org.gnome.shell.gschema.xml.in.h:21
#: ../data/org.gnome.shell.gschema.xml.in.h:23
msgid "If true, display date in the clock, in addition to time."
msgstr "참이면 시계에 날짜를 시각과 같이 표시합니다."
#: ../data/org.gnome.shell.gschema.xml.in.h:22
#: ../data/org.gnome.shell.gschema.xml.in.h:24
msgid "Framerate used for recording screencasts."
msgstr "스크린 방송 녹화에 사용할 프레임수."
#: ../data/org.gnome.shell.gschema.xml.in.h:23
#: ../data/org.gnome.shell.gschema.xml.in.h:25
msgid ""
"The framerate of the resulting screencast recordered by GNOME Shell's "
"screencast recorder in frames-per-second."
msgstr ""
"그놈 셸의 스크린 방송의 녹화 결과물에 사용할 프레임수, 초당 프레임 수 단위."
msgstr "그놈 셸의 스크린 방송의 녹화 결과물에 사용할 프레임수, 초당 프레임수 단위."
#: ../data/org.gnome.shell.gschema.xml.in.h:24
#: ../data/org.gnome.shell.gschema.xml.in.h:26
msgid "The gstreamer pipeline used to encode the screencast"
msgstr "스크린 방송 인코딩에 사용할 gstreamer 파이프라인"
#: ../data/org.gnome.shell.gschema.xml.in.h:26
#: ../data/org.gnome.shell.gschema.xml.in.h:28
#, no-c-format
msgid ""
"Sets the GStreamer pipeline used to encode recordings. It follows the syntax "
@ -174,29 +174,18 @@ msgid ""
"'vp8enc quality=8 speed=6 threads=%T ! queue ! webmmux' and records to WEBM "
"using the VP8 codec. %T is used as a placeholder for a guess at the optimal "
"thread count on the system."
msgstr ""
"녹화 인코딩에 사용할 GStreamer 파이프라인을 지정합니다. gst-launch에 사용하"
"는 문법을 따릅니다. 파이프라인은 녹화한 영상이 있는 싱크 패드를 연결하지 않"
"은 상태여야 합니다. 보통 소스 패드와 연결하지 않았을 것입니다. 이 패드의 출력"
"은 출력 파일에 기록할 것입니다. 그러나 파이프라인은 이 출력을 다룰 수 있기도 "
"합니다 - 아마 shout2send와 같은 것을 통해 icecast 서버로 출력을 보내는데 사용"
"할지도 모릅니다. 만약 설정을 취소하거나 빈 값으로 설정한다면, 기본 파이프라인"
"을 사용할 것입니다. 이것은 현재 'vp8enc quality=8 speed=6 threads=%T ! "
"queue ! webmmux' 이며 VP8 코덱을 사용하여 WEBM으로 녹화합니다. %T는 시스템 상"
"의 최적의 스레드 수를 추측하기 위해 대체기호로 사용합니다."
msgstr "녹화 인코딩에 사용할 GStreamer 파이프라인을 지정합니다. gst-launch 프로그램에 사용하는 문법을 따릅니다. 녹화한 영상이 입력되는 싱크 패드는 이 파이프라인에 연결하지 않은 상태여야 합니다. 보통은 소스 패드도 연결하지 않고, 소스 패드의 출력을 출력 파일에 기록합니다. 하지만 파이프라인에서 이 출력을 처리할 수도 있습니다. shout2send 같은 프로그램을 이용해 아이스캐스트 서버로 출력을 보내거나 하는 용도로 사용할 수 있습니다. 설정을 취소하거나 빈 값으로 설정하면, 기본 파이프라인을 사용합니다. 기본 파이프라인은 'vp8enc quality=8 speed=6 threads=%T ! queue ! webmmux'이고 VP8 코덱을 사용해 WEBM 형식으로 녹화합니다. '%T' 기호는 시스템에서 최적으로 생각되는 스레드 수로 대체됩니다."
#: ../data/org.gnome.shell.gschema.xml.in.h:27
#: ../data/org.gnome.shell.gschema.xml.in.h:29
msgid "File extension used for storing the screencast"
msgstr "스크린 방송 저장 사용할 파일 확장자"
msgstr "스크린 방송 저장할 때 사용할 파일 확장자"
#: ../data/org.gnome.shell.gschema.xml.in.h:28
#: ../data/org.gnome.shell.gschema.xml.in.h:30
msgid ""
"The filename for recorded screencasts will be a unique filename based on the "
"current date, and use this extension. It should be changed when recording to "
"a different container format."
msgstr ""
"스크린 방송 녹화 파일 이름은 현재 날짜와 이 확장자를 사용해서 결정됩니다. 녹"
"화할 때 다른 형식으로 바꿀 수도 있습니다."
msgstr "녹화한 스크린 방송 영상 파일은, 현재 날짜와 여기서 설정하는 확장자를 붙여 파일 이름을 만듭니다. 다른 컨테이너 형식으로 녹화하려면 이 값을 바꿔야 합니다."
#: ../js/extensionPrefs/main.js:125
#, c-format
@ -209,42 +198,42 @@ msgstr "<b>확장</b>"
#: ../js/extensionPrefs/main.js:189
msgid "Select an extension to configure using the combobox above."
msgstr "위의 콤보상자를 사용하여 설정할 확장을 선택하십시오."
msgstr "위의 콤보상자를 사용 설정할 확장을 선택하십시오."
#: ../js/gdm/loginDialog.js:624
#: ../js/gdm/loginDialog.js:627
msgid "Session..."
msgstr "세션..."
#: ../js/gdm/loginDialog.js:786
#: ../js/gdm/loginDialog.js:789
msgctxt "title"
msgid "Sign In"
msgstr "로그인"
#. Translators: this message is shown below the password entry field
#. to indicate the user can swipe their finger instead
#: ../js/gdm/loginDialog.js:831
#: ../js/gdm/loginDialog.js:834
msgid "(or swipe finger)"
msgstr "(또는 지문을 문지르십시오)"
#. translators: this message is shown below the user list on the
#. login screen. It can be activated to reveal an entry for
#. manually entering the username.
#: ../js/gdm/loginDialog.js:852
#: ../js/gdm/loginDialog.js:855
msgid "Not listed?"
msgstr "목록에 없습니까?"
#: ../js/gdm/loginDialog.js:1020 ../js/ui/endSessionDialog.js:401
#: ../js/ui/extensionSystem.js:399 ../js/ui/networkAgent.js:153
#: ../js/gdm/loginDialog.js:1023 ../js/ui/endSessionDialog.js:401
#: ../js/ui/extensionSystem.js:400 ../js/ui/networkAgent.js:153
#: ../js/ui/polkitAuthenticationAgent.js:175 ../js/ui/status/bluetooth.js:462
msgid "Cancel"
msgstr "취소"
#: ../js/gdm/loginDialog.js:1025
#: ../js/gdm/loginDialog.js:1028
msgctxt "button"
msgid "Sign In"
msgstr "로그인"
#: ../js/gdm/loginDialog.js:1377
#: ../js/gdm/loginDialog.js:1380
msgid "Login Window"
msgstr "로그인 창"
@ -638,11 +627,11 @@ msgstr[0] "시스템이 %d초 뒤에 자동으로 다시 시작합니다."
msgid "Restarting the system."
msgstr "시스템을 다시 시작합니다."
#: ../js/ui/extensionSystem.js:403
#: ../js/ui/extensionSystem.js:404
msgid "Install"
msgstr "설치"
#: ../js/ui/extensionSystem.js:407
#: ../js/ui/extensionSystem.js:408
#, c-format
msgid "Download and install '%s' from extensions.gnome.org?"
msgstr ""
@ -652,7 +641,8 @@ msgstr ""
msgid "tray"
msgstr "트레이"
#: ../js/ui/keyboard.js:544 ../js/ui/status/power.js:203
#: ../js/ui/keyboard.js:544 ../js/ui/status/keyboard.js:44
#: ../js/ui/status/power.js:203
msgid "Keyboard"
msgstr "키보드"
@ -664,59 +654,60 @@ msgstr "암호:"
msgid "Type again:"
msgstr "다시 입력하십시오:"
#: ../js/ui/lookingGlass.js:725
#: ../js/ui/lookingGlass.js:732
msgid "No extensions installed"
msgstr "확장 기능을 설치하지 않았습니다"
msgstr "확장을 설치하지 않았습니다"
#. Translators: argument is an extension UUID.
#: ../js/ui/lookingGlass.js:779
#: ../js/ui/lookingGlass.js:786
#, c-format
msgid "%s has not emitted any errors."
msgstr "%s이(가) 발생한 에러가 없습니다."
msgstr "%s에서 발생한 에러가 없습니다."
#: ../js/ui/lookingGlass.js:785
#: ../js/ui/lookingGlass.js:792
msgid "Hide Errors"
msgstr "오류 숨기기"
#: ../js/ui/lookingGlass.js:789 ../js/ui/lookingGlass.js:840
#: ../js/ui/lookingGlass.js:796 ../js/ui/lookingGlass.js:847
msgid "Show Errors"
msgstr "오류 보이기"
#: ../js/ui/lookingGlass.js:798
#: ../js/ui/lookingGlass.js:805
msgid "Enabled"
msgstr "사용"
#. translators:
#. * The device has been disabled
#: ../js/ui/lookingGlass.js:801 ../src/gvc/gvc-mixer-control.c:1093
#: ../js/ui/lookingGlass.js:808 ../src/gvc/gvc-mixer-control.c:1082
msgid "Disabled"
msgstr "사용 않음"
#: ../js/ui/lookingGlass.js:803
#: ../js/ui/lookingGlass.js:810
msgid "Error"
msgstr "오류"
#: ../js/ui/lookingGlass.js:805
#: ../js/ui/lookingGlass.js:812
msgid "Out of date"
msgstr "오래 된 버전"
#: ../js/ui/lookingGlass.js:807
#: ../js/ui/lookingGlass.js:814
msgid "Downloading"
msgstr "다운로드 중"
#: ../js/ui/lookingGlass.js:828
#: ../js/ui/lookingGlass.js:835
msgid "View Source"
msgstr "소스 보기"
#: ../js/ui/lookingGlass.js:834
#: ../js/ui/lookingGlass.js:841
msgid "Web Page"
msgstr "웹페이지"
# 주의: 파일이름, %d %t는 날짜와 시각, 이상하게 번역하지 말 것
#. Translators: this is a filename used for screencast recording
#: ../js/ui/main.js:118
#, no-c-format
msgid "Screencast from %d %t"
msgstr "%d %t의 스크린캐스트"
msgstr "스크린 방송, %d %t"
#: ../js/ui/messageTray.js:1200
msgid "Open"
@ -835,17 +826,17 @@ msgstr "프로그램"
msgid "Dash"
msgstr "대시보드"
#: ../js/ui/panel.js:591
#: ../js/ui/panel.js:592
msgid "Quit"
msgstr "끝내기"
#. Translators: If there is no suitable word for "Activities"
#. in your language, you can use the word for "Overview".
#: ../js/ui/panel.js:623
#: ../js/ui/panel.js:624
msgid "Activities"
msgstr "현재 활동"
#: ../js/ui/panel.js:998
#: ../js/ui/panel.js:999
msgid "Top Bar"
msgstr "위 막대"
@ -899,11 +890,11 @@ msgstr "toggle-switch-intl"
msgid "Please enter a command:"
msgstr "명령을 입력하십시오:"
#: ../js/ui/searchDisplay.js:331
#: ../js/ui/searchDisplay.js:332
msgid "Searching..."
msgstr "검색하는 중..."
#: ../js/ui/searchDisplay.js:413
#: ../js/ui/searchDisplay.js:415
msgid "No matching results."
msgstr "일치하는 결과가 없습니다."
@ -921,7 +912,7 @@ msgstr "텍스트 보이기"
#: ../js/ui/shellEntry.js:79
msgid "Hide Text"
msgstr "글자 숨기기"
msgstr "텍스트 숨기기"
#: ../js/ui/shellMountOperation.js:271
msgid "Wrong password, please try again"
@ -1061,7 +1052,7 @@ msgstr "항상 접근 허용"
msgid "Grant this time only"
msgstr "이번에만 허용"
#: ../js/ui/status/bluetooth.js:382 ../js/ui/telepathyClient.js:1091
#: ../js/ui/status/bluetooth.js:382 ../js/ui/telepathyClient.js:1093
msgid "Reject"
msgstr "거부"
@ -1127,7 +1118,7 @@ msgstr "관리되지 않음"
#. Translators: this is for network connections that require some kind of key or password
#: ../js/ui/status/network.js:500
msgid "authentication required"
msgstr "인증 필요합니다"
msgstr "인증 필요"
#. Translators: this is for devices that require some kind of firmware or kernel
#. module, which is missing
@ -1138,7 +1129,7 @@ msgstr "펌웨어 없음"
#. Translators: this is for wired network devices that are physically disconnected
#: ../js/ui/status/network.js:517
msgid "cable unplugged"
msgstr "케이블 분리되었습니다"
msgstr "케이블 분리"
#. Translators: this is for a network device that cannot be activated (for example it
#. is disabled by rfkill, or it has no coverage
@ -1148,7 +1139,7 @@ msgstr "사용 불가"
#: ../js/ui/status/network.js:524
msgid "connection failed"
msgstr "연결 실패했습니다"
msgstr "연결 실패"
#: ../js/ui/status/network.js:585 ../js/ui/status/network.js:1505
msgid "More..."
@ -1158,7 +1149,7 @@ msgstr "더 보기..."
#. and we cannot access its settings (including the name)
#: ../js/ui/status/network.js:621 ../js/ui/status/network.js:1440
msgid "Connected (private)"
msgstr "연결됨 (개인)"
msgstr "연결됨(개인)"
#: ../js/ui/status/network.js:696
msgid "Auto Ethernet"
@ -1375,35 +1366,35 @@ 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:887
#: ../js/ui/telepathyClient.js:889
#, no-c-format
msgid "Sent at <b>%X</b> on <b>%A</b>"
msgstr "보낸 때: <b>%A</b> <b>%H시 %M분</b>"
#. Translators: this is a time format in the style of "Wednesday, May 25",
#. shown when you get a chat message in the same year.
#: ../js/ui/telepathyClient.js:893
#: ../js/ui/telepathyClient.js:895
#, no-c-format
msgid "Sent on <b>%A</b>, <b>%B %d</b>"
msgstr "보낸 때: <b>%B %d일</b> <b>%A</b>"
#. Translators: this is a time format in the style of "Wednesday, May 25, 2012",
#. shown when you get a chat message in a different year.
#: ../js/ui/telepathyClient.js:898
#: ../js/ui/telepathyClient.js:900
#, no-c-format
msgid "Sent on <b>%A</b>, <b>%B %d</b>, %Y"
msgstr "보낸 때: %Y년 <b>%B %d일</b> <b>%A</b>"
#. Translators: this is the other person changing their old IM name to their new
#. IM name.
#: ../js/ui/telepathyClient.js:940
#: ../js/ui/telepathyClient.js:942
#, c-format
msgid "%s is now known as %s"
msgstr "%s의 대화명이 이제 %s입니다"
#. translators: argument is a room name like
#. * room@jabber.org for example.
#: ../js/ui/telepathyClient.js:1042
#: ../js/ui/telepathyClient.js:1044
#, c-format
msgid "Invitation to %s"
msgstr "%s에 초대"
@ -1411,35 +1402,35 @@ msgstr "%s에 초대"
#. translators: first argument is the name of a contact and the second
#. * one the name of a room. "Alice is inviting you to join room@jabber.org
#. * for example.
#: ../js/ui/telepathyClient.js:1050
#: ../js/ui/telepathyClient.js:1052
#, c-format
msgid "%s is inviting you to join %s"
msgstr "%s 님이 %s에 입장하도록 초대합니다"
#: ../js/ui/telepathyClient.js:1052 ../js/ui/telepathyClient.js:1131
#: ../js/ui/telepathyClient.js:1229
#: ../js/ui/telepathyClient.js:1054 ../js/ui/telepathyClient.js:1133
#: ../js/ui/telepathyClient.js:1231
msgid "Decline"
msgstr "거부"
#: ../js/ui/telepathyClient.js:1053 ../js/ui/telepathyClient.js:1132
#: ../js/ui/telepathyClient.js:1230
#: ../js/ui/telepathyClient.js:1055 ../js/ui/telepathyClient.js:1134
#: ../js/ui/telepathyClient.js:1232
msgid "Accept"
msgstr "허용"
#. translators: argument is a contact name like Alice for example.
#: ../js/ui/telepathyClient.js:1083
#: ../js/ui/telepathyClient.js:1085
#, c-format
msgid "Video call from %s"
msgstr "%s에서 영상 호출"
#. translators: argument is a contact name like Alice for example.
#: ../js/ui/telepathyClient.js:1086
#: ../js/ui/telepathyClient.js:1088
#, c-format
msgid "Call from %s"
msgstr "%s에서 호출"
#. translators: this is a button label (verb), not a noun
#: ../js/ui/telepathyClient.js:1093
#: ../js/ui/telepathyClient.js:1095
msgid "Answer"
msgstr "응답"
@ -1448,108 +1439,108 @@ msgstr "응답"
#. * file name. The string will be something
#. * like: "Alice is sending you test.ogg"
#.
#: ../js/ui/telepathyClient.js:1125
#: ../js/ui/telepathyClient.js:1127
#, c-format
msgid "%s is sending you %s"
msgstr "%s님이 %s 파일을 보냅니다"
#. To translators: The parameter is the contact's alias
#: ../js/ui/telepathyClient.js:1194
#: ../js/ui/telepathyClient.js:1196
#, c-format
msgid "%s would like permission to see when you are online"
msgstr "연결 상태인지 알 수 있는 권한을 %s님이 요청합니다"
#: ../js/ui/telepathyClient.js:1287
#: ../js/ui/telepathyClient.js:1289
msgid "Network error"
msgstr "네트워크 오류"
#: ../js/ui/telepathyClient.js:1289
#: ../js/ui/telepathyClient.js:1291
msgid "Authentication failed"
msgstr "인증이 실패했습니다"
#: ../js/ui/telepathyClient.js:1291
#: ../js/ui/telepathyClient.js:1293
msgid "Encryption error"
msgstr "암호화 오류"
#: ../js/ui/telepathyClient.js:1293
#: ../js/ui/telepathyClient.js:1295
msgid "Certificate not provided"
msgstr "인증서가 없습니다"
#: ../js/ui/telepathyClient.js:1295
#: ../js/ui/telepathyClient.js:1297
msgid "Certificate untrusted"
msgstr "인증서를 신뢰할 수 없습니다"
#: ../js/ui/telepathyClient.js:1297
#: ../js/ui/telepathyClient.js:1299
msgid "Certificate expired"
msgstr "인증서가 만료되었습니다"
#: ../js/ui/telepathyClient.js:1299
#: ../js/ui/telepathyClient.js:1301
msgid "Certificate not activated"
msgstr "인증서를 활성화하지 않았습니다"
#: ../js/ui/telepathyClient.js:1301
#: ../js/ui/telepathyClient.js:1303
msgid "Certificate hostname mismatch"
msgstr "인증서 호스트 이름이 맞지 않습니다"
#: ../js/ui/telepathyClient.js:1303
#: ../js/ui/telepathyClient.js:1305
msgid "Certificate fingerprint mismatch"
msgstr "인증서 핑거프린트가 맞지 않습니다"
#: ../js/ui/telepathyClient.js:1305
#: ../js/ui/telepathyClient.js:1307
msgid "Certificate self-signed"
msgstr "인증서가 자기 서명한 인증서입니다"
#: ../js/ui/telepathyClient.js:1307
#: ../js/ui/telepathyClient.js:1309
msgid "Status is set to offline"
msgstr "상태를 오프라인으로 설정"
#: ../js/ui/telepathyClient.js:1309
#: ../js/ui/telepathyClient.js:1311
msgid "Encryption is not available"
msgstr "암호화를 사용할 수 없습니다"
#: ../js/ui/telepathyClient.js:1311
#: ../js/ui/telepathyClient.js:1313
msgid "Certificate is invalid"
msgstr "인증서가 올바르지 않습니다"
#: ../js/ui/telepathyClient.js:1313
#: ../js/ui/telepathyClient.js:1315
msgid "Connection has been refused"
msgstr "연결이 거부되었습니다"
#: ../js/ui/telepathyClient.js:1315
#: ../js/ui/telepathyClient.js:1317
msgid "Connection can't be established"
msgstr "연결할 수 없습니다"
#: ../js/ui/telepathyClient.js:1317
#: ../js/ui/telepathyClient.js:1319
msgid "Connection has been lost"
msgstr "연결이 끊어졌습니다"
#: ../js/ui/telepathyClient.js:1319
msgid "This account is already connected to the server"
msgstr "이미 서버에 이 계정을 연결했습니다"
#: ../js/ui/telepathyClient.js:1321
msgid "This account is already connected to the server"
msgstr "이 계정은 이미 서버에 연결했습니다"
#: ../js/ui/telepathyClient.js:1323
msgid ""
"Connection has been replaced by a new connection using the same resource"
msgstr "같은 자원을 사용하는 새로운 연결로 바꾸었습니다"
#: ../js/ui/telepathyClient.js:1323
#: ../js/ui/telepathyClient.js:1325
msgid "The account already exists on the server"
msgstr "계정이 이미 서버에 있습니다"
#: ../js/ui/telepathyClient.js:1325
#: ../js/ui/telepathyClient.js:1327
msgid "Server is currently too busy to handle the connection"
msgstr "서버가 처리할 작업이 많아 연결을 처리할 수 없습니다"
#: ../js/ui/telepathyClient.js:1327
#: ../js/ui/telepathyClient.js:1329
msgid "Certificate has been revoked"
msgstr "인증서를 철회했습니다"
#: ../js/ui/telepathyClient.js:1329
#: ../js/ui/telepathyClient.js:1331
msgid ""
"Certificate uses an insecure cipher algorithm or is cryptographically weak"
msgstr "인증서가 보안에 취약한 알고리즘을 사용하거나 암호화 기능이 취약합니다."
#: ../js/ui/telepathyClient.js:1331
#: ../js/ui/telepathyClient.js:1333
msgid ""
"The length of the server certificate, or the depth of the server certificate "
"chain, exceed the limits imposed by the cryptography library"
@ -1557,26 +1548,26 @@ msgstr ""
"서버 인증서의 길이, 또는 서버 인증서 체인의 단계가 암호화 라이브러리의 제한"
"을 넘어갑니다."
#: ../js/ui/telepathyClient.js:1333
#: ../js/ui/telepathyClient.js:1335
msgid "Internal error"
msgstr "내부 오류"
#. translators: argument is the account name, like
#. * name@jabber.org for example.
#: ../js/ui/telepathyClient.js:1343
#: ../js/ui/telepathyClient.js:1345
#, c-format
msgid "Connection to %s failed"
msgstr "%s에 연결이 실패했습니다"
#: ../js/ui/telepathyClient.js:1352
#: ../js/ui/telepathyClient.js:1354
msgid "Reconnect"
msgstr "다시 연결"
#: ../js/ui/telepathyClient.js:1353
#: ../js/ui/telepathyClient.js:1355
msgid "Edit account"
msgstr "계정 편집"
#: ../js/ui/telepathyClient.js:1399
#: ../js/ui/telepathyClient.js:1401
msgid "Unknown reason"
msgstr "알 수 없는 이유"
@ -1650,7 +1641,7 @@ msgid ""
"Sorry, no wisdom for you today:\n"
"%s"
msgstr ""
"죄송하지만, 오늘 조언해 줄 것이 없습니다:\n"
"죄송합니다. 오늘 조언할 내용이 없습니다:\n"
"%s"
# 원래 "신탁"이지만 한국인이 이해하기 쉽게 맞게 변경.
@ -1670,7 +1661,7 @@ msgstr "'%s' 프로그램이 준비되었습니다"
#. translators:
#. * The number of sound outputs on a particular device
#: ../src/gvc/gvc-mixer-control.c:1100
#: ../src/gvc/gvc-mixer-control.c:1089
#, c-format
msgid "%u Output"
msgid_plural "%u Outputs"
@ -1678,13 +1669,13 @@ msgstr[0] "%u개 출력"
#. translators:
#. * The number of sound inputs on a particular device
#: ../src/gvc/gvc-mixer-control.c:1110
#: ../src/gvc/gvc-mixer-control.c:1099
#, c-format
msgid "%u Input"
msgid_plural "%u Inputs"
msgstr[0] "%u개 입력"
#: ../src/gvc/gvc-mixer-control.c:1408
#: ../src/gvc/gvc-mixer-control.c:1397
msgid "System Sounds"
msgstr "시스템 소리"
@ -1708,7 +1699,7 @@ msgstr "암호가 일치하지 않습니다."
#: ../src/shell-keyring-prompt.c:716
msgid "Password cannot be blank"
msgstr "암호는 비울 수 없습니다"
msgstr "빈 암호를 쓸 수 없습니다"
#: ../src/shell-mobile-providers.c:80
msgid "United Kingdom"
@ -1744,27 +1735,3 @@ msgstr "파일 시스템"
#, c-format
msgid "%1$s: %2$s"
msgstr "%s: %s"
#~ msgid "RECENT ITEMS"
#~ msgstr "최근 항목"
#~ msgid "Show password"
#~ msgstr "암호 표시"
#~ msgid "Home Folder"
#~ msgstr "내 폴더"
#~ msgid "%s has finished starting"
#~ msgstr "%s 프로그램이 시작했습니다"
#~ msgid "If true, display onscreen keyboard."
#~ msgstr "참이면 화면 키보드를 표시합니다."
#~ msgid "Show the onscreen keyboard"
#~ msgstr "화면 키보드 표시"
#~ msgid "Connectivity lost"
#~ msgstr "연결 끊어짐"
#~ msgid "You're no longer connected to the network"
#~ msgstr "이제 네트워크에 연결되어 있지 않습니다"

159
po/lt.po
View File

@ -3,19 +3,20 @@
# This file is distributed under the same license as the gnome-shell package.
# Žygimantas Beručka <zygis@gnome.org>, 2010, 2011, 2012.
# Algimantas Margevičius <gymka@mail.ru>, 2011.
# Mantas Kriaučiūnas <mantas@akl.lt>, 2012.
msgid ""
msgstr ""
"Project-Id-Version: gnome-shell master\n"
"Report-Msgid-Bugs-To: http://bugzilla.gnome.org/enter_bug.cgi?product=gnome-"
"shell&keywords=I18N+L10N&component=general\n"
"POT-Creation-Date: 2012-03-30 17:59+0000\n"
"POT-Creation-Date: 2012-05-19 13:58+0000\n"
"PO-Revision-Date: 2012-04-05 15:14+0300\n"
"Last-Translator: Žygimantas Beručka <zygis@gnome.org>\n"
"Last-Translator: Mantas Kriaučiūnas <mantas@akl.lt>\n"
"Language-Team: Lithuanian\n"
"Language: lt\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Language: lt\n"
"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && (n%"
"100<10 || n%100>=20) ? 1 : 2);\n"
"X-Generator: Virtaal 0.7.0\n"
@ -23,7 +24,7 @@ msgstr ""
#: ../data/gnome-shell.desktop.in.in.h:1
msgid "GNOME Shell"
msgstr "GNOME Shell"
msgstr "GNOME Shell aplinka"
#: ../data/gnome-shell.desktop.in.in.h:2
msgid "Window management and application launching"
@ -79,10 +80,11 @@ msgid ""
"want to disable this for privacy reasons. Please note that doing so won't "
"remove already saved data."
msgstr ""
"Apvalkalas paprastai stebi aktyvias programas siekiant pateikti dažniausiai "
"naudojamas (pvz., leistukuose). Nors šie duomenys konfidencialiai saugomi, "
"jei norite, saugumo sumetimais galite šią funkciją išjungti. Atminkite, kad "
"tai padarius jau įrašyti duomenys jau nebus įrašyti."
"Įprastai GNOME aplinka stebi aktyvias programas siekiant pateikti "
"dažniausiai naudojamas (pvz., leistukuose). Nors šie duomenys "
"konfidencialiai saugomi, jei norite, saugumo sumetimais galite šią funkciją "
"išjungti. Atminkite, kad išjungus šią funkciją anksčiau įrašyti duomenys "
"nebus pašalinti."
#: ../data/org.gnome.shell.gschema.xml.in.h:7
msgid "List of desktop file IDs for favorite applications"
@ -222,7 +224,7 @@ msgstr ""
#: ../js/extensionPrefs/main.js:125
#, c-format
msgid "There was an error loading the preferences dialog for %s:"
msgstr "Kilo klaida įkeliant %s nustatymų dialogą:"
msgstr "Įvyko klaida įkeliant %s nustatymų dialogą:"
#: ../js/extensionPrefs/main.js:165
msgid "<b>Extension</b>"
@ -232,40 +234,40 @@ msgstr "<b>Plėtinys</b>"
msgid "Select an extension to configure using the combobox above."
msgstr "Išskleidžiamajame sąraše pasirinkite konfigūruotiną plėtinį."
#: ../js/gdm/loginDialog.js:624
#: ../js/gdm/loginDialog.js:627
msgid "Session..."
msgstr "Seansas..."
#: ../js/gdm/loginDialog.js:786
#: ../js/gdm/loginDialog.js:789
msgctxt "title"
msgid "Sign In"
msgstr "Prisijungti"
#. Translators: this message is shown below the password entry field
#. to indicate the user can swipe their finger instead
#: ../js/gdm/loginDialog.js:831
#: ../js/gdm/loginDialog.js:834
msgid "(or swipe finger)"
msgstr "(arba perbraukite pirštu)"
#. translators: this message is shown below the user list on the
#. login screen. It can be activated to reveal an entry for
#. manually entering the username.
#: ../js/gdm/loginDialog.js:852
#: ../js/gdm/loginDialog.js:855
msgid "Not listed?"
msgstr "Nėra sąraše?"
#: ../js/gdm/loginDialog.js:1020 ../js/ui/endSessionDialog.js:401
#: ../js/ui/extensionSystem.js:399 ../js/ui/networkAgent.js:153
#: ../js/gdm/loginDialog.js:1023 ../js/ui/endSessionDialog.js:401
#: ../js/ui/extensionSystem.js:400 ../js/ui/networkAgent.js:153
#: ../js/ui/polkitAuthenticationAgent.js:175 ../js/ui/status/bluetooth.js:462
msgid "Cancel"
msgstr "Atšaukti"
msgstr "Atsisakyti"
#: ../js/gdm/loginDialog.js:1025
#: ../js/gdm/loginDialog.js:1028
msgctxt "button"
msgid "Sign In"
msgstr "Prisijungti"
#: ../js/gdm/loginDialog.js:1377
#: ../js/gdm/loginDialog.js:1380
msgid "Login Window"
msgstr "Prisijungimo langas"
@ -673,11 +675,11 @@ msgstr[2] "Sistema bus paleista iš naujo po %d sekundžių."
msgid "Restarting the system."
msgstr "Sistema paleidžiama iš naujo."
#: ../js/ui/extensionSystem.js:403
#: ../js/ui/extensionSystem.js:404
msgid "Install"
msgstr "Įdiegti"
#: ../js/ui/extensionSystem.js:407
#: ../js/ui/extensionSystem.js:408
#, c-format
msgid "Download and install '%s' from extensions.gnome.org?"
msgstr "Atsiųsti ir įdiegti „%s“ iš extensions.gnome.org?"
@ -686,7 +688,8 @@ msgstr "Atsiųsti ir įdiegti „%s“ iš extensions.gnome.org?"
msgid "tray"
msgstr "dėklas"
#: ../js/ui/keyboard.js:544 ../js/ui/status/power.js:203
#: ../js/ui/keyboard.js:544 ../js/ui/status/keyboard.js:44
#: ../js/ui/status/power.js:203
msgid "Keyboard"
msgstr "Klaviatūra"
@ -722,7 +725,7 @@ msgstr "Įjungta"
#. translators:
#. * The device has been disabled
#: ../js/ui/lookingGlass.js:808 ../src/gvc/gvc-mixer-control.c:1093
#: ../js/ui/lookingGlass.js:808 ../src/gvc/gvc-mixer-control.c:1082
msgid "Disabled"
msgstr "Išjungta"
@ -939,7 +942,7 @@ msgstr "Įveskite komandą:"
msgid "Searching..."
msgstr "Ieškoma..."
#: ../js/ui/searchDisplay.js:414
#: ../js/ui/searchDisplay.js:415
msgid "No matching results."
msgstr "Nerasta atitikmenų."
@ -1097,7 +1100,7 @@ msgstr "Visada leisti prieigą"
msgid "Grant this time only"
msgstr "Leisti tik šį kartą"
#: ../js/ui/status/bluetooth.js:382 ../js/ui/telepathyClient.js:1091
#: ../js/ui/status/bluetooth.js:382 ../js/ui/telepathyClient.js:1093
msgid "Reject"
msgstr "Atmesti"
@ -1174,7 +1177,7 @@ msgstr "Trūksta integruotos programinės įrangos (firmware)"
#. Translators: this is for wired network devices that are physically disconnected
#: ../js/ui/status/network.js:517
msgid "cable unplugged"
msgstr "kabelis neįjungtas"
msgstr "atjungtas laidas"
#. Translators: this is for a network device that cannot be activated (for example it
#. is disabled by rfkill, or it has no coverage
@ -1188,7 +1191,7 @@ msgstr "nepavyko prisijungti"
#: ../js/ui/status/network.js:585 ../js/ui/status/network.js:1505
msgid "More..."
msgstr "Daugiau..."
msgstr "Rodyti daugiau tinklų..."
#. TRANSLATORS: this is the indication that a connection for another logged in user is active,
#. and we cannot access its settings (including the name)
@ -1385,7 +1388,7 @@ msgstr "Skambutis"
#. We got the TpContact
#: ../js/ui/telepathyClient.js:287
msgid "File Transfer"
msgstr "Failo perdavimas"
msgstr "Failo persiuntimas"
#: ../js/ui/telepathyClient.js:369
msgid "Subscription request"
@ -1418,35 +1421,35 @@ msgstr "%s yra užsiėmęs (-usi)."
#. 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:887
#: ../js/ui/telepathyClient.js:889
#, no-c-format
msgid "Sent at <b>%X</b> on <b>%A</b>"
msgstr "Išsiųsta <b>%X</b> <b>%A</b>"
#. Translators: this is a time format in the style of "Wednesday, May 25",
#. shown when you get a chat message in the same year.
#: ../js/ui/telepathyClient.js:893
#: ../js/ui/telepathyClient.js:895
#, no-c-format
msgid "Sent on <b>%A</b>, <b>%B %d</b>"
msgstr "Išsiųsta <b>%B %d</b>, <b>%A</b>"
#. Translators: this is a time format in the style of "Wednesday, May 25, 2012",
#. shown when you get a chat message in a different year.
#: ../js/ui/telepathyClient.js:898
#: ../js/ui/telepathyClient.js:900
#, no-c-format
msgid "Sent on <b>%A</b>, <b>%B %d</b>, %Y"
msgstr "Išsiųsta %Y <b>%B %d</b>, <b>%A</b>"
#. Translators: this is the other person changing their old IM name to their new
#. IM name.
#: ../js/ui/telepathyClient.js:940
#: ../js/ui/telepathyClient.js:942
#, c-format
msgid "%s is now known as %s"
msgstr "%s nuo šiol vadinasi %s"
#. translators: argument is a room name like
#. * room@jabber.org for example.
#: ../js/ui/telepathyClient.js:1042
#: ../js/ui/telepathyClient.js:1044
#, c-format
msgid "Invitation to %s"
msgstr "Kvietimas į %s"
@ -1454,35 +1457,35 @@ msgstr "Kvietimas į %s"
#. translators: first argument is the name of a contact and the second
#. * one the name of a room. "Alice is inviting you to join room@jabber.org
#. * for example.
#: ../js/ui/telepathyClient.js:1050
#: ../js/ui/telepathyClient.js:1052
#, c-format
msgid "%s is inviting you to join %s"
msgstr "%s jus kviečia prisijungti prie %s"
#: ../js/ui/telepathyClient.js:1052 ../js/ui/telepathyClient.js:1131
#: ../js/ui/telepathyClient.js:1229
#: ../js/ui/telepathyClient.js:1054 ../js/ui/telepathyClient.js:1133
#: ../js/ui/telepathyClient.js:1231
msgid "Decline"
msgstr "Atmesti"
#: ../js/ui/telepathyClient.js:1053 ../js/ui/telepathyClient.js:1132
#: ../js/ui/telepathyClient.js:1230
#: ../js/ui/telepathyClient.js:1055 ../js/ui/telepathyClient.js:1134
#: ../js/ui/telepathyClient.js:1232
msgid "Accept"
msgstr "Priimti"
#. translators: argument is a contact name like Alice for example.
#: ../js/ui/telepathyClient.js:1083
#: ../js/ui/telepathyClient.js:1085
#, c-format
msgid "Video call from %s"
msgstr "Vaizdo skambutis nuo %s"
#. translators: argument is a contact name like Alice for example.
#: ../js/ui/telepathyClient.js:1086
#: ../js/ui/telepathyClient.js:1088
#, c-format
msgid "Call from %s"
msgstr "Skambutis nuo %s"
#. translators: this is a button label (verb), not a noun
#: ../js/ui/telepathyClient.js:1093
#: ../js/ui/telepathyClient.js:1095
msgid "Answer"
msgstr "Atsiliepti"
@ -1491,110 +1494,110 @@ msgstr "Atsiliepti"
#. * file name. The string will be something
#. * like: "Alice is sending you test.ogg"
#.
#: ../js/ui/telepathyClient.js:1125
#: ../js/ui/telepathyClient.js:1127
#, c-format
msgid "%s is sending you %s"
msgstr "%s jums siunčia %s"
#. To translators: The parameter is the contact's alias
#: ../js/ui/telepathyClient.js:1194
#: ../js/ui/telepathyClient.js:1196
#, c-format
msgid "%s would like permission to see when you are online"
msgstr "%s pageidauja matyti, kai esate prisijungę prie interneto"
#: ../js/ui/telepathyClient.js:1287
#: ../js/ui/telepathyClient.js:1289
msgid "Network error"
msgstr "Tinklo klaida"
#: ../js/ui/telepathyClient.js:1289
#: ../js/ui/telepathyClient.js:1291
msgid "Authentication failed"
msgstr "Nepavyko patvirtinti tapatybės"
#: ../js/ui/telepathyClient.js:1291
#: ../js/ui/telepathyClient.js:1293
msgid "Encryption error"
msgstr "Šifravimo klaida"
#: ../js/ui/telepathyClient.js:1293
#: ../js/ui/telepathyClient.js:1295
msgid "Certificate not provided"
msgstr "Liudijimas nepateiktas"
#: ../js/ui/telepathyClient.js:1295
#: ../js/ui/telepathyClient.js:1297
msgid "Certificate untrusted"
msgstr "Liudijimas nepatikimas"
#: ../js/ui/telepathyClient.js:1297
#: ../js/ui/telepathyClient.js:1299
msgid "Certificate expired"
msgstr "Liudijimo galiojimas pasibaigęs"
#: ../js/ui/telepathyClient.js:1299
#: ../js/ui/telepathyClient.js:1301
msgid "Certificate not activated"
msgstr "Liudijimas neaktyvuotas"
#: ../js/ui/telepathyClient.js:1301
#: ../js/ui/telepathyClient.js:1303
msgid "Certificate hostname mismatch"
msgstr "Liudijimo serverio vardo nesutapimas"
#: ../js/ui/telepathyClient.js:1303
#: ../js/ui/telepathyClient.js:1305
msgid "Certificate fingerprint mismatch"
msgstr "Liudijimo piršto atspaudo nesutapimas"
#: ../js/ui/telepathyClient.js:1305
#: ../js/ui/telepathyClient.js:1307
msgid "Certificate self-signed"
msgstr "Liudijimas pačių pasirašytas"
#: ../js/ui/telepathyClient.js:1307
#: ../js/ui/telepathyClient.js:1309
msgid "Status is set to offline"
msgstr "Nustatyta atsijungimo būsena"
#: ../js/ui/telepathyClient.js:1309
#: ../js/ui/telepathyClient.js:1311
msgid "Encryption is not available"
msgstr "Šifravimas negalimas"
#: ../js/ui/telepathyClient.js:1311
#: ../js/ui/telepathyClient.js:1313
msgid "Certificate is invalid"
msgstr "Liudijimas netinkamas"
#: ../js/ui/telepathyClient.js:1313
#: ../js/ui/telepathyClient.js:1315
msgid "Connection has been refused"
msgstr "Ryšys atmestas"
#: ../js/ui/telepathyClient.js:1315
#: ../js/ui/telepathyClient.js:1317
msgid "Connection can't be established"
msgstr "Nepavyko užmegzti ryšio"
#: ../js/ui/telepathyClient.js:1317
#: ../js/ui/telepathyClient.js:1319
msgid "Connection has been lost"
msgstr "Ryšys nutrūko"
#: ../js/ui/telepathyClient.js:1319
#: ../js/ui/telepathyClient.js:1321
msgid "This account is already connected to the server"
msgstr "Ši paskyra jau prijungta prie serverio"
#: ../js/ui/telepathyClient.js:1321
#: ../js/ui/telepathyClient.js:1323
msgid ""
"Connection has been replaced by a new connection using the same resource"
msgstr "Ryšys pakeistas nauju ryšiu naudojant tą patį išteklių"
#: ../js/ui/telepathyClient.js:1323
#: ../js/ui/telepathyClient.js:1325
msgid "The account already exists on the server"
msgstr "Tokia paskyra serveryje jau yra"
#: ../js/ui/telepathyClient.js:1325
#: ../js/ui/telepathyClient.js:1327
msgid "Server is currently too busy to handle the connection"
msgstr "Šiuo metu serveris per daug užimtas šiai užklausai apdoroti"
#: ../js/ui/telepathyClient.js:1327
#: ../js/ui/telepathyClient.js:1329
msgid "Certificate has been revoked"
msgstr "Liudijimas atšauktas"
#: ../js/ui/telepathyClient.js:1329
#: ../js/ui/telepathyClient.js:1331
msgid ""
"Certificate uses an insecure cipher algorithm or is cryptographically weak"
msgstr ""
"Liudijimui naudojamas nesaugus šifravimo algoritmas arba jis kriptografiškai "
"silpnas"
#: ../js/ui/telepathyClient.js:1331
#: ../js/ui/telepathyClient.js:1333
msgid ""
"The length of the server certificate, or the depth of the server certificate "
"chain, exceed the limits imposed by the cryptography library"
@ -1602,26 +1605,26 @@ msgstr ""
"Serverio liudijimo ilgis arba liudijimų eilės dydis viršija kriptografijos "
"bibliotekos apribojimus"
#: ../js/ui/telepathyClient.js:1333
#: ../js/ui/telepathyClient.js:1335
msgid "Internal error"
msgstr "Vidinė klaida"
#. translators: argument is the account name, like
#. * name@jabber.org for example.
#: ../js/ui/telepathyClient.js:1343
#: ../js/ui/telepathyClient.js:1345
#, c-format
msgid "Connection to %s failed"
msgstr "Nepavyko prisijungti prie %s"
#: ../js/ui/telepathyClient.js:1352
#: ../js/ui/telepathyClient.js:1354
msgid "Reconnect"
msgstr "Prisijungti iš naujo"
#: ../js/ui/telepathyClient.js:1353
#: ../js/ui/telepathyClient.js:1355
msgid "Edit account"
msgstr "Taisyti paskyrą"
#: ../js/ui/telepathyClient.js:1399
#: ../js/ui/telepathyClient.js:1401
msgid "Unknown reason"
msgstr "Nežinoma priežastis"
@ -1647,7 +1650,7 @@ msgstr "Pranešimai"
#: ../js/ui/userMenu.js:639
msgid "Online Accounts"
msgstr "Tinklo paskyros"
msgstr "Interneto paskyros"
#: ../js/ui/userMenu.js:643
msgid "System Settings"
@ -1706,7 +1709,7 @@ msgstr "Orakulė sako %s"
#: ../js/ui/wanda.js:168
msgid "Your favorite Easter Egg"
msgstr "Jūsų mėgstamiausias lykinis kiaušinis"
msgstr "Jūsų mėgstamiausias Velykinis kiaušinis"
#: ../js/ui/windowAttentionHandler.js:19
#, c-format
@ -1715,7 +1718,7 @@ msgstr "„%s“ yra pasirengusi"
#. translators:
#. * The number of sound outputs on a particular device
#: ../src/gvc/gvc-mixer-control.c:1100
#: ../src/gvc/gvc-mixer-control.c:1089
#, c-format
msgid "%u Output"
msgid_plural "%u Outputs"
@ -1725,7 +1728,7 @@ msgstr[2] "%u išvestys"
#. translators:
#. * The number of sound inputs on a particular device
#: ../src/gvc/gvc-mixer-control.c:1110
#: ../src/gvc/gvc-mixer-control.c:1099
#, c-format
msgid "%u Input"
msgid_plural "%u Inputs"
@ -1733,15 +1736,15 @@ msgstr[0] "%u įvestis"
msgstr[1] "%u įvestys"
msgstr[2] "%u įvestys"
#: ../src/gvc/gvc-mixer-control.c:1408
#: ../src/gvc/gvc-mixer-control.c:1397
msgid "System Sounds"
msgstr "Sistemos garsai"
#: ../src/main.c:255
#: ../src/main.c:256
msgid "Print version"
msgstr "Išvesti versijos numerį"
#: ../src/main.c:261
#: ../src/main.c:262
msgid "Mode used by GDM for login screen"
msgstr "Veiksena, naudojama GDM prisijungimo ekrane"
@ -1774,7 +1777,7 @@ msgstr "Naudotojas užvėrė tapatybės patvirtinimo dialogą"
#. * nautilus
#: ../src/shell-util.c:97
msgid "Home"
msgstr "Namai"
msgstr "Namų aplankas"
#. Translators: this is the same string as the one found in
#. * nautilus

278
po/mr.po
View File

@ -8,8 +8,8 @@ msgstr ""
"Project-Id-Version: mr\n"
"Report-Msgid-Bugs-To: http://bugzilla.gnome.org/enter_bug.cgi?product=gnome-"
"shell&keywords=I18N+L10N&component=general\n"
"POT-Creation-Date: 2012-03-30 17:59+0000\n"
"PO-Revision-Date: 2012-04-02 11:33+0530\n"
"POT-Creation-Date: 2012-04-24 15:39+0000\n"
"PO-Revision-Date: 2012-05-10 09:57+0530\n"
"Last-Translator: Sandeep Shedmake <sshedmak@redhat.com>\n"
"Language-Team: Marathi <fedora-trans-mr@redhat.com>\n"
"MIME-Version: 1.0\n"
@ -47,7 +47,6 @@ msgid ""
msgstr "आंतरिक डिबगिंग व Alt-F2 संवादचा वापर करून निंयत्रणकरीता प्रवेश देतो."
#: ../data/org.gnome.shell.gschema.xml.in.h:3
#| msgid "Uuids of extensions to disable"
msgid "Uuids of extensions to enable"
msgstr "सुरू करण्याजोगी एक्सटेंशन्स्चे Uuids"
@ -59,10 +58,10 @@ msgid ""
"DisableExtension DBus methods on org.gnome.Shell."
msgstr ""
"GNOME शेल एक्सटेंशन्सकडे uuid गुणधर्म असते; हि कि एक्सटेंशन्स् दाखवते ज्यास "
"लोड करणे आवश्यक आहे. "
"लोड करण्याजोगी कोणत्याहि एक्सटेंशला सूचीत असणे आवश्यक आहे. "
"org.gnome.Shell वरील EnableExtension व DisableExtension DBus मेथडससह या सूचीत "
"बदल करणे शक्य आहे."
"लोड करणे आवश्यक "
"आहे. लोड करण्याजोगी कोणत्याहि एक्सटेंशला सूचीत असणे आवश्यक आहे. org.gnome."
"Shell वरील "
"EnableExtension व DisableExtension DBus मेथडससह या सूचीत बदल करणे शक्य आहे."
#: ../data/org.gnome.shell.gschema.xml.in.h:5
msgid "Whether to collect stats about applications usage"
@ -110,7 +109,8 @@ msgid ""
"The value here is from the TpConnectionPresenceType enumeration."
msgstr ""
"वापरकर्तातर्फे ठरवलेले शेवटचे IM हाजेरी साठवण्याकरीता आंतरिकपणे वापरले जाते. "
"येथील मूल्य TpConnectionPresenceType एन्युमरेशनपासूनचे आहे."
"येथील मूल्य "
"TpConnectionPresenceType एन्युमरेशनपासूनचे आहे."
#: ../data/org.gnome.shell.gschema.xml.in.h:13
msgid ""
@ -118,8 +118,8 @@ msgid ""
"value here is from the GsmPresenceStatus enumeration."
msgstr ""
"वापरकर्तातर्फे ठरवलेले शेवटचे सत्र हाजेरी साठवण्याकरीता आंतरिकपणे वापरले जाते."
" "
"येथील मूल्य GsmPresenceStatus एन्युमरेशनपासूनचे आहे."
" येथील मूल्य "
"GsmPresenceStatus एन्युमरेशनपासूनचे आहे."
#: ../data/org.gnome.shell.gschema.xml.in.h:14
msgid "Show the week date in the calendar"
@ -138,34 +138,44 @@ msgid "Keybinding to open the application menu."
msgstr "ॲप्लिकेशन मेन्यु उघडण्यासाठी किबाइंडिंग."
#: ../data/org.gnome.shell.gschema.xml.in.h:18
#| msgid "Keybinding to open the application menu"
msgid "Keybinding to toggle the screen recorder"
msgstr "स्क्रीन रेकॉर्डरमधील बदलसाठी किबाइंडिंग"
#: ../data/org.gnome.shell.gschema.xml.in.h:19
#| msgid "Keybinding to open the application menu."
msgid "Keybinding to start/stop the builtin screen recorder."
msgstr "बिल्टइन स्क्रीन रेकॉर्डर सुरू किंवा थांबवण्यासाठी किबाइंडिंग."
#: ../data/org.gnome.shell.gschema.xml.in.h:20
msgid "Which keyboard to use"
msgstr "कुठले किबोर्ड वापरायचे"
#: ../data/org.gnome.shell.gschema.xml.in.h:19
#: ../data/org.gnome.shell.gschema.xml.in.h:21
msgid "The type of keyboard to use."
msgstr "वापरण्याजोगी किबोर्डचे प्रकार."
#: ../data/org.gnome.shell.gschema.xml.in.h:20
#: ../data/org.gnome.shell.gschema.xml.in.h:22
msgid "Show time with seconds"
msgstr "सेकंदात वेळ दाखवा"
#: ../data/org.gnome.shell.gschema.xml.in.h:21
#: ../data/org.gnome.shell.gschema.xml.in.h:23
msgid "If true, display seconds in time."
msgstr "खरे असल्यास, वेळेत सेकंद दाखवा."
#: ../data/org.gnome.shell.gschema.xml.in.h:22
#: ../data/org.gnome.shell.gschema.xml.in.h:24
msgid "Show date in clock"
msgstr "घड्याळात दिनांक दाखवा"
#: ../data/org.gnome.shell.gschema.xml.in.h:23
#: ../data/org.gnome.shell.gschema.xml.in.h:25
msgid "If true, display date in the clock, in addition to time."
msgstr "खरे असल्यास,वेळेबरोबर तारीख पण घड्याळात दाखवा."
#: ../data/org.gnome.shell.gschema.xml.in.h:24
#: ../data/org.gnome.shell.gschema.xml.in.h:26
msgid "Framerate used for recording screencasts."
msgstr "स्क्रिनकास्ट्स् रेकॉर्ड करण्यासाठी वापरलेले फ्रेमरेट."
#: ../data/org.gnome.shell.gschema.xml.in.h:25
#: ../data/org.gnome.shell.gschema.xml.in.h:27
msgid ""
"The framerate of the resulting screencast recordered by GNOME Shell's "
"screencast recorder in frames-per-second."
@ -174,24 +184,12 @@ msgstr ""
"केलेल्या परिणामक "
"सक्रीनकास्टचा फ्रेमरेट."
#: ../data/org.gnome.shell.gschema.xml.in.h:26
#: ../data/org.gnome.shell.gschema.xml.in.h:28
msgid "The gstreamer pipeline used to encode the screencast"
msgstr "स्क्रीनकास्ट एंकोड करण्यासाठी वापरलेले gstreamer पाइपलाइन"
#: ../data/org.gnome.shell.gschema.xml.in.h:28
#: ../data/org.gnome.shell.gschema.xml.in.h:30
#, no-c-format
#| msgid ""
#| "Sets the GStreamer pipeline used to encode recordings. It follows the "
#| "syntax used for gst-launch. The pipeline should have an unconnected sink "
#| "pad where the recorded video is recorded. It will normally have a "
#| "unconnected source pad; output from that pad will be written into the "
#| "output file. However the pipeline can also take care of its own output - "
#| "this might be used to send the output to an icecast server via shout2send "
#| "or similar. When unset or set to an empty value, the default pipeline "
#| "will be used. This is currently 'videorate ! vp8enc quality=10 speed=2 "
#| "threads=%T ! queue ! webmmux' and records to WEBM using the VP8 codec. %T "
#| "is used as a placeholder for a guess at the optimal thread count on the "
#| "system."
msgid ""
"Sets the GStreamer pipeline used to encode recordings. It follows the syntax "
"used for gst-launch. The pipeline should have an unconnected sink pad where "
@ -205,21 +203,26 @@ msgid ""
"thread count on the system."
msgstr ""
"रेकॉर्डिंग्स् एंकोड करण्यासाठी GStreamer पाइपलाइन ठरवतो. gst-launch सुरू "
"करण्यासाठी मांडणीचा वापर करतो. पाइपलाइनमध्ये जोडणी अशक्य सिंक पॅड असायला हवे "
"जेथे रेकॉर्डेड व्हिडीओ रेकॉर्ड केले जाते. सहसा जोडणी अशक्य स्रोत पॅड असते; "
"पॅडपासूनचे आऊटपुट, आऊटपुट फाइलमध्ये लिहले जाते. तरी पाइपलाइन स्वतःच्या "
"आऊटपुटची काळजी घेतो - याचा वापर shout2send किंवा समानतर्फे icecast "
"सर्व्हरकरीता आऊटपुट पाठवण्याकरीता केला जातो. रिकामे मूल्यकरीता सेट अशक्य "
"किंवा शक्य केल्यावर, मूळ पाइपलाइनचा वापर केला जातो. हे सध्या 'vp8enc "
"quality=8 speed=6 threads=%T ! queue ! webmmux' आहे व VP8 कोडेकचा वापर करून "
"WEBM करीता रेकॉर्डिंग करतो. %T चा वापर प्रणालीवरील कमाल थ्रेड गणणा "
"ओळखण्यासाठी प्लेसहोल्डर म्हणून केला जातो."
"करण्यासाठी "
"मांडणीचा वापर करतो. पाइपलाइनमध्ये जोडणी अशक्य सिंक पॅड असायला हवे जेथे "
"रेकॉर्डेड व्हिडीओ "
"रेकॉर्ड केले जाते. सहसा जोडणी अशक्य स्रोत पॅड असते; पॅडपासूनचे आऊटपुट, आऊटपुट "
"फाइलमध्ये लिहले "
"जाते. तरी पाइपलाइन स्वतःच्या आऊटपुटची काळजी घेतो - याचा वापर shout2send किंवा "
"समानतर्फे icecast सर्व्हरकरीता आऊटपुट पाठवण्याकरीता केला जातो. रिकामे "
"मूल्यकरीता सेट "
"अशक्य किंवा शक्य केल्यावर, मूळ पाइपलाइनचा वापर केला जातो. हे सध्या 'vp8enc "
"quality=8 "
"speed=6 threads=%T ! queue ! webmmux' आहे व VP8 कोडेकचा वापर करून WEBM करीता "
"रेकॉर्डिंग करतो. %T चा वापर प्रणालीवरील कमाल थ्रेड गणणा ओळखण्यासाठी "
"प्लेसहोल्डर म्हणून "
"केला जातो."
#: ../data/org.gnome.shell.gschema.xml.in.h:29
#: ../data/org.gnome.shell.gschema.xml.in.h:31
msgid "File extension used for storing the screencast"
msgstr "स्क्रिनकास्ट साठवण्याकरीता वापरलेले फाइल एक्सटेंशन"
#: ../data/org.gnome.shell.gschema.xml.in.h:30
#: ../data/org.gnome.shell.gschema.xml.in.h:32
msgid ""
"The filename for recorded screencasts will be a unique filename based on the "
"current date, and use this extension. It should be changed when recording to "
@ -243,42 +246,40 @@ msgstr "<b>एक्सटेंशन</b>"
msgid "Select an extension to configure using the combobox above."
msgstr "वरील कॉम्बोबॉक्सचा वापर करून संरचनाकरीता एक्सटेंशनचा वापर करा."
#: ../js/gdm/loginDialog.js:624
#| msgid "Searching..."
#: ../js/gdm/loginDialog.js:627
msgid "Session..."
msgstr "सत्र..."
#: ../js/gdm/loginDialog.js:786
#: ../js/gdm/loginDialog.js:789
msgctxt "title"
msgid "Sign In"
msgstr "प्रवेश करा"
#. Translators: this message is shown below the password entry field
#. to indicate the user can swipe their finger instead
#: ../js/gdm/loginDialog.js:831
#: ../js/gdm/loginDialog.js:834
msgid "(or swipe finger)"
msgstr "(किंवा बोट फिरवा)"
#. translators: this message is shown below the user list on the
#. login screen. It can be activated to reveal an entry for
#. manually entering the username.
#: ../js/gdm/loginDialog.js:852
#: ../js/gdm/loginDialog.js:855
msgid "Not listed?"
msgstr "सूचीत नाही?"
#: ../js/gdm/loginDialog.js:1020 ../js/ui/endSessionDialog.js:401
#: ../js/ui/extensionSystem.js:399 ../js/ui/networkAgent.js:153
#: ../js/gdm/loginDialog.js:1023 ../js/ui/endSessionDialog.js:401
#: ../js/ui/extensionSystem.js:400 ../js/ui/networkAgent.js:153
#: ../js/ui/polkitAuthenticationAgent.js:175 ../js/ui/status/bluetooth.js:462
msgid "Cancel"
msgstr "रद्द करा"
#: ../js/gdm/loginDialog.js:1025
#: ../js/gdm/loginDialog.js:1028
msgctxt "button"
msgid "Sign In"
msgstr "प्रवेश करा"
#: ../js/gdm/loginDialog.js:1377
#| msgid "New Window"
#: ../js/gdm/loginDialog.js:1380
msgid "Login Window"
msgstr "प्रवेश पटल"
@ -355,7 +356,6 @@ msgid "Open with %s"
msgstr "%s सह उघडा"
#: ../js/ui/autorunManager.js:586
#| msgid "Reject"
msgid "Eject"
msgstr "बाहेर काढा"
@ -591,13 +591,11 @@ msgstr "%A %B %e, %Y"
#: ../js/ui/endSessionDialog.js:61
#, c-format
#| msgid "Log Out %s"
msgctxt "title"
msgid "Log Out %s"
msgstr "%s पासून बाहेर पडा"
#: ../js/ui/endSessionDialog.js:62
#| msgid "Log Out"
msgctxt "title"
msgid "Log Out"
msgstr "बाहेर पडा"
@ -609,7 +607,6 @@ msgstr ""
#: ../js/ui/endSessionDialog.js:65
#, c-format
#| msgid "%s will be logged out automatically in %d seconds."
msgid "%s will be logged out automatically in %d second."
msgid_plural "%s will be logged out automatically in %d seconds."
msgstr[0] "%s स्वयं, %d सेकंदात बाहेर पडेल."
@ -617,7 +614,6 @@ msgstr[1] "%s स्वयं, %d सेकंदात बाहेर पड
#: ../js/ui/endSessionDialog.js:70
#, c-format
#| msgid "You will be logged out automatically in %d seconds."
msgid "You will be logged out automatically in %d second."
msgid_plural "You will be logged out automatically in %d seconds."
msgstr[0] "%d सेकंदात तुम्ही स्वयं बाहेर पडाल."
@ -628,13 +624,11 @@ msgid "Logging out of the system."
msgstr "प्रणालीतून बाहेर पडत आहे."
#: ../js/ui/endSessionDialog.js:76
#| msgid "Log Out"
msgctxt "button"
msgid "Log Out"
msgstr "बाहेर पडा"
#: ../js/ui/endSessionDialog.js:81
#| msgid "Power Off"
msgctxt "title"
msgid "Power Off"
msgstr "बंद करा"
@ -645,7 +639,6 @@ msgstr "ॲप्लिकेशन्स् बंद करण्यासा
#: ../js/ui/endSessionDialog.js:84
#, c-format
#| msgid "The system will power off automatically in %d seconds."
msgid "The system will power off automatically in %d second."
msgid_plural "The system will power off automatically in %d seconds."
msgstr[0] "प्रणाली स्वयं %d सेकंदात बंद होईल."
@ -656,19 +649,16 @@ msgid "Powering off the system."
msgstr "प्रणाली बंद करत आहे."
#: ../js/ui/endSessionDialog.js:90 ../js/ui/endSessionDialog.js:107
#| msgid "Restart"
msgctxt "button"
msgid "Restart"
msgstr "पुनः सुरू करा"
#: ../js/ui/endSessionDialog.js:92
#| msgid "Power Off"
msgctxt "button"
msgid "Power Off"
msgstr "बंद करा"
#: ../js/ui/endSessionDialog.js:98
#| msgid "Restart"
msgctxt "title"
msgid "Restart"
msgstr "पुनः सुरू करा"
@ -680,7 +670,6 @@ msgstr ""
#: ../js/ui/endSessionDialog.js:101
#, c-format
#| msgid "The system will restart automatically in %d seconds."
msgid "The system will restart automatically in %d second."
msgid_plural "The system will restart automatically in %d seconds."
msgstr[0] "प्रणाली स्वयं %d सेकंदात पुनः सुरू होईल."
@ -690,21 +679,21 @@ msgstr[1] "प्रणाली स्वयं %d सेकंदामध्
msgid "Restarting the system."
msgstr "प्रणाली पुनःसुरू करत आहे."
#: ../js/ui/extensionSystem.js:403
#: ../js/ui/extensionSystem.js:404
msgid "Install"
msgstr "प्रतिष्ठापीत करा"
#: ../js/ui/extensionSystem.js:407
#: ../js/ui/extensionSystem.js:408
#, c-format
msgid "Download and install '%s' from extensions.gnome.org?"
msgstr " extensions.gnome.org पासून '%s' डाऊनलोड व प्रतिष्ठापीत करा?"
#: ../js/ui/keyboard.js:327
#| msgid "Retry"
msgid "tray"
msgstr "ट्रे"
#: ../js/ui/keyboard.js:544 ../js/ui/status/power.js:203
#: ../js/ui/keyboard.js:544 ../js/ui/status/keyboard.js:44
#: ../js/ui/status/power.js:203
msgid "Keyboard"
msgstr "कळफलक"
@ -727,12 +716,10 @@ msgid "%s has not emitted any errors."
msgstr "%s ने कोणत्याहि त्रुटी दाखवले नाही."
#: ../js/ui/lookingGlass.js:792
#| msgid "Error"
msgid "Hide Errors"
msgstr "त्रुटी लपवा"
#: ../js/ui/lookingGlass.js:796 ../js/ui/lookingGlass.js:847
#| msgid "Error"
msgid "Show Errors"
msgstr "त्रुटी दाखवा"
@ -742,7 +729,7 @@ msgstr "सुरू केले"
#. translators:
#. * The device has been disabled
#: ../js/ui/lookingGlass.js:808 ../src/gvc/gvc-mixer-control.c:1093
#: ../js/ui/lookingGlass.js:808 ../src/gvc/gvc-mixer-control.c:1082
msgid "Disabled"
msgstr "बंद केले"
@ -767,7 +754,7 @@ msgid "Web Page"
msgstr "वेब पृष्ठ"
#. Translators: this is a filename used for screencast recording
#: ../js/ui/main.js:118
#: ../js/ui/main.js:121
#, no-c-format
msgid "Screencast from %d %t"
msgstr "%d %t पासून स्क्रीनकास्ट"
@ -777,22 +764,18 @@ msgid "Open"
msgstr "उघडा"
#: ../js/ui/messageTray.js:1217
#| msgid "minute"
#| msgid_plural "minutes"
msgid "Unmute"
msgstr "ंद करणे अशक्य करा"
msgstr "ंद करणे अशक्य करा"
#: ../js/ui/messageTray.js:1217
#| msgid "Mouse"
msgid "Mute"
msgstr "ंद करा"
msgstr "ंद करा"
#: ../js/ui/messageTray.js:2490
msgid "System Information"
msgstr "प्रणाली माहिती"
#: ../js/ui/networkAgent.js:148
#| msgid "Connection"
msgid "Connect"
msgstr "जोडणी करा"
@ -800,7 +783,6 @@ msgstr "जोडणी करा"
#: ../js/ui/networkAgent.js:243 ../js/ui/networkAgent.js:255
#: ../js/ui/networkAgent.js:282 ../js/ui/networkAgent.js:302
#: ../js/ui/networkAgent.js:312
#| msgid "Password:"
msgid "Password: "
msgstr "पासवर्ड: "
@ -829,7 +811,6 @@ msgid "Service: "
msgstr "सर्व्हिस: "
#: ../js/ui/networkAgent.js:329
#| msgid "Authentication Required"
msgid "Authentication required by wireless network"
msgstr "वायरलेस नेटवर्कतर्फे आवश्यक ओळखपटवणे"
@ -845,12 +826,10 @@ msgid "Wired 802.1X authentication"
msgstr "वायर्ड 802.1X ओळखपटवणे"
#: ../js/ui/networkAgent.js:336
#| msgid "Network Manager"
msgid "Network name: "
msgstr "नेटवर्क नाव: "
#: ../js/ui/networkAgent.js:341
#| msgid "authentication required"
msgid "DSL authentication"
msgstr "DSL ओळख पटवणे"
@ -867,13 +846,11 @@ msgid "PIN: "
msgstr "PIN: "
#: ../js/ui/networkAgent.js:356
#| msgid "Mobile broadband"
msgid "Mobile broadband network password"
msgstr "मोबाईल ब्रॉडबँड नेटवर्क पासवर्ड"
#: ../js/ui/networkAgent.js:357
#, c-format
#| msgid "You're now connected to '%s'"
msgid "A password is required to connect to '%s'."
msgstr "'%s' सह जोडणीकरीता पासवर्ड आवश्यक आहे."
@ -900,7 +877,6 @@ msgid "Dash"
msgstr "डॅश"
#: ../js/ui/panel.js:592
#| msgid "Quit %s"
msgid "Quit"
msgstr "बाहेर पडा"
@ -968,7 +944,7 @@ msgstr "कृपया आदेश द्या:"
msgid "Searching..."
msgstr "शोधत आहे..."
#: ../js/ui/searchDisplay.js:414
#: ../js/ui/searchDisplay.js:415
msgid "No matching results."
msgstr "जुळवण्याजोगी परिणाम आढळले नाही."
@ -985,7 +961,6 @@ msgid "Show Text"
msgstr "मजकूर दाखवा"
#: ../js/ui/shellEntry.js:79
#| msgid "Large Text"
msgid "Hide Text"
msgstr "मजकूर लपवा"
@ -994,7 +969,6 @@ msgid "Wrong password, please try again"
msgstr "चुकिचा पासवर्ड, कृपया पुनः प्रयत्न करा"
#: ../js/ui/status/accessibility.js:47
#| msgid "Visibility"
msgid "Accessibility"
msgstr "ॲक्सेसिबिलिटि"
@ -1006,7 +980,6 @@ msgstr "झूम"
#. 'screen-reader-enabled');
#. this.menu.addMenuItem(screenReader);
#: ../js/ui/status/accessibility.js:63
#| msgid "Keyboard"
msgid "Screen Keyboard"
msgstr "स्क्रीन किबोर्ड"
@ -1058,7 +1031,6 @@ msgid "Send Files to Device..."
msgstr "फाइल्स्ना साधनावर पाठवा..."
#: ../js/ui/status/bluetooth.js:63
#| msgid "Setup a New Device..."
msgid "Set up a New Device..."
msgstr "नविन साधनची मांडणी करा..."
@ -1068,7 +1040,6 @@ msgstr "ब्ल्यूटूथ सेटिंग्स्"
#. TRANSLATORS: this means that bluetooth was disabled by hardware rfkill
#: ../js/ui/status/bluetooth.js:107 ../js/ui/status/network.js:256
#| msgid "disabled"
msgid "hardware disabled"
msgstr "हार्डवेअर बंद केले"
@ -1077,7 +1048,6 @@ msgid "Connection"
msgstr "जोडणी"
#: ../js/ui/status/bluetooth.js:214 ../js/ui/status/network.js:491
#| msgid "connecting..."
msgid "disconnecting..."
msgstr "जोडणी खंडीत करत आहे..."
@ -1132,7 +1102,7 @@ msgstr "नेहमी प्रवेश द्या"
msgid "Grant this time only"
msgstr "फक्त याचवेळी मान्य करा"
#: ../js/ui/status/bluetooth.js:382 ../js/ui/telepathyClient.js:1091
#: ../js/ui/status/bluetooth.js:382 ../js/ui/telepathyClient.js:1093
msgid "Reject"
msgstr "नकारा"
@ -1173,12 +1143,10 @@ msgid "OK"
msgstr "ठीक आहे"
#: ../js/ui/status/keyboard.js:68
#| msgid "Show Keyboard Layout..."
msgid "Show Keyboard Layout"
msgstr "किबोर्ड लेआऊट दाखवा"
#: ../js/ui/status/keyboard.js:73
#| msgid "Date and Time Settings"
msgid "Region and Language Settings"
msgstr "क्षेत्र व भाषा सेटिंग्स्"
@ -1260,7 +1228,6 @@ msgid "Auto wireless"
msgstr "स्वयं वायरलेस्"
#: ../js/ui/status/network.js:1541
#| msgid "Network Manager"
msgid "Network"
msgstr "नेटवर्क"
@ -1289,12 +1256,10 @@ msgid "Network Settings"
msgstr "जाळं संयोजना"
#: ../js/ui/status/network.js:1739
#| msgid "connection failed"
msgid "Connection failed"
msgstr "जोडणी अपयशी"
#: ../js/ui/status/network.js:1740
#| msgid "connection failed"
msgid "Activation of network connection failed"
msgstr "नेटवर्क जोडणी सुरू करणे अपयशी"
@ -1415,7 +1380,6 @@ msgstr "आमंत्रण"
#. We got the TpContact
#: ../js/ui/telepathyClient.js:271
#| msgid "Cancel"
msgid "Call"
msgstr "कॉल"
@ -1425,12 +1389,10 @@ msgid "File Transfer"
msgstr "फाइल स्थानांतरन"
#: ../js/ui/telepathyClient.js:369
#| msgid "Authorization request from %s"
msgid "Subscription request"
msgstr "सबस्क्रिप्शन विनंती"
#: ../js/ui/telepathyClient.js:405
#| msgid "Connection"
msgid "Connection error"
msgstr "जोडणी त्रुटी"
@ -1457,36 +1419,35 @@ 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:887
#: ../js/ui/telepathyClient.js:889
#, no-c-format
#| msgid "Sent at %X on %A"
msgid "Sent at <b>%X</b> on <b>%A</b>"
msgstr "<b>%X</b> वेळी, <b>%A</b> ला पाठवले"
#. Translators: this is a time format in the style of "Wednesday, May 25",
#. shown when you get a chat message in the same year.
#: ../js/ui/telepathyClient.js:893
#: ../js/ui/telepathyClient.js:895
#, no-c-format
msgid "Sent on <b>%A</b>, <b>%B %d</b>"
msgstr "<b>%A</b> वेळी, <b>%B %d</b> ला पाठवले"
#. Translators: this is a time format in the style of "Wednesday, May 25, 2012",
#. shown when you get a chat message in a different year.
#: ../js/ui/telepathyClient.js:898
#: ../js/ui/telepathyClient.js:900
#, no-c-format
msgid "Sent on <b>%A</b>, <b>%B %d</b>, %Y"
msgstr "<b>%A</b>, <b>%B %d</b>, %Y वेळी पाठवले"
#. Translators: this is the other person changing their old IM name to their new
#. IM name.
#: ../js/ui/telepathyClient.js:940
#: ../js/ui/telepathyClient.js:942
#, c-format
msgid "%s is now known as %s"
msgstr "%s ला %s म्हणून ओळखले जाते"
#. translators: argument is a room name like
#. * room@jabber.org for example.
#: ../js/ui/telepathyClient.js:1042
#: ../js/ui/telepathyClient.js:1044
#, c-format
msgid "Invitation to %s"
msgstr "%s करीता आमंत्रण"
@ -1494,35 +1455,35 @@ msgstr "%s करीता आमंत्रण"
#. translators: first argument is the name of a contact and the second
#. * one the name of a room. "Alice is inviting you to join room@jabber.org
#. * for example.
#: ../js/ui/telepathyClient.js:1050
#: ../js/ui/telepathyClient.js:1052
#, c-format
msgid "%s is inviting you to join %s"
msgstr "%s तुम्हाला %s सह जोडणीकरीता आमंत्रण देत आहे"
#: ../js/ui/telepathyClient.js:1052 ../js/ui/telepathyClient.js:1131
#: ../js/ui/telepathyClient.js:1229
#: ../js/ui/telepathyClient.js:1054 ../js/ui/telepathyClient.js:1133
#: ../js/ui/telepathyClient.js:1231
msgid "Decline"
msgstr "नकारा"
#: ../js/ui/telepathyClient.js:1053 ../js/ui/telepathyClient.js:1132
#: ../js/ui/telepathyClient.js:1230
#: ../js/ui/telepathyClient.js:1055 ../js/ui/telepathyClient.js:1134
#: ../js/ui/telepathyClient.js:1232
msgid "Accept"
msgstr "स्वीकारा"
#. translators: argument is a contact name like Alice for example.
#: ../js/ui/telepathyClient.js:1083
#: ../js/ui/telepathyClient.js:1085
#, c-format
msgid "Video call from %s"
msgstr "%s पासून व्हिडीओ कॉल्स्"
#. translators: argument is a contact name like Alice for example.
#: ../js/ui/telepathyClient.js:1086
#: ../js/ui/telepathyClient.js:1088
#, c-format
msgid "Call from %s"
msgstr "%s पासून कॉल"
#. translators: this is a button label (verb), not a noun
#: ../js/ui/telepathyClient.js:1093
#: ../js/ui/telepathyClient.js:1095
msgid "Answer"
msgstr "उत्तर"
@ -1531,147 +1492,138 @@ msgstr "उत्तर"
#. * file name. The string will be something
#. * like: "Alice is sending you test.ogg"
#.
#: ../js/ui/telepathyClient.js:1125
#: ../js/ui/telepathyClient.js:1127
#, c-format
msgid "%s is sending you %s"
msgstr "%s तुम्हाला %s पाठवत आहे"
#. To translators: The parameter is the contact's alias
#: ../js/ui/telepathyClient.js:1194
#: ../js/ui/telepathyClient.js:1196
#, c-format
msgid "%s would like permission to see when you are online"
msgstr "ऑनलाइन असल्यावर %s परवानगी दृष्यास्पद करायची"
#: ../js/ui/telepathyClient.js:1287
#| msgid "Network Manager"
#: ../js/ui/telepathyClient.js:1289
msgid "Network error"
msgstr "नेटवर्क त्रुटी"
#: ../js/ui/telepathyClient.js:1289
#| msgid "Authentication Required"
#: ../js/ui/telepathyClient.js:1291
msgid "Authentication failed"
msgstr "ओळख पटवणे अपयशी"
#: ../js/ui/telepathyClient.js:1291
#: ../js/ui/telepathyClient.js:1293
msgid "Encryption error"
msgstr "एंक्रिप्शन त्रुटी"
#: ../js/ui/telepathyClient.js:1293
#: ../js/ui/telepathyClient.js:1295
msgid "Certificate not provided"
msgstr "प्रमाणपत्र पुरवले नाही"
#: ../js/ui/telepathyClient.js:1295
#: ../js/ui/telepathyClient.js:1297
msgid "Certificate untrusted"
msgstr "प्रमाणपत्र अविश्वासर्ह आहे"
#: ../js/ui/telepathyClient.js:1297
#: ../js/ui/telepathyClient.js:1299
msgid "Certificate expired"
msgstr "प्रमाणपत्राची वेळसमाप्ति"
#: ../js/ui/telepathyClient.js:1299
#: ../js/ui/telepathyClient.js:1301
msgid "Certificate not activated"
msgstr "प्रमाणपत्र सुरू केले नाही"
#: ../js/ui/telepathyClient.js:1301
#: ../js/ui/telepathyClient.js:1303
msgid "Certificate hostname mismatch"
msgstr "प्रमाणपत्र यजमाननाव जुळत नाही"
#: ../js/ui/telepathyClient.js:1303
#: ../js/ui/telepathyClient.js:1305
msgid "Certificate fingerprint mismatch"
msgstr "प्रमाणपत्र फिंग्ररप्रिंट जुळत नाही"
#: ../js/ui/telepathyClient.js:1305
#: ../js/ui/telepathyClient.js:1307
msgid "Certificate self-signed"
msgstr "प्रमाणपत्र स्वयं स्वाक्षरि"
#: ../js/ui/telepathyClient.js:1307
#| msgid "%s is offline."
#: ../js/ui/telepathyClient.js:1309
msgid "Status is set to offline"
msgstr "स्थिती ऑफलाइनकरीता ठरवली आहे"
#: ../js/ui/telepathyClient.js:1309
#: ../js/ui/telepathyClient.js:1311
msgid "Encryption is not available"
msgstr "एंक्रिप्शन अनुपलब्ध"
#: ../js/ui/telepathyClient.js:1311
#: ../js/ui/telepathyClient.js:1313
msgid "Certificate is invalid"
msgstr "प्रमाणपत्र अवैध आहे"
#: ../js/ui/telepathyClient.js:1313
#| msgid "Connection established"
#: ../js/ui/telepathyClient.js:1315
msgid "Connection has been refused"
msgstr "जोडणी नकारली गेली"
#: ../js/ui/telepathyClient.js:1315
#| msgid "Connection established"
#: ../js/ui/telepathyClient.js:1317
msgid "Connection can't be established"
msgstr "जोडणी स्थापीत करणे अशक्य"
#: ../js/ui/telepathyClient.js:1317
#| msgid "Connection established"
#: ../js/ui/telepathyClient.js:1319
msgid "Connection has been lost"
msgstr "जोडणी खंडीत झाली"
#: ../js/ui/telepathyClient.js:1319
#: ../js/ui/telepathyClient.js:1321
msgid "This account is already connected to the server"
msgstr "हे खाते आधिपासूनच सर्व्हरसह जुळले आहे"
#: ../js/ui/telepathyClient.js:1321
#: ../js/ui/telepathyClient.js:1323
msgid ""
"Connection has been replaced by a new connection using the same resource"
msgstr "समान स्रोतचा वापर करून जोडणीला नविन जोडणीसह बदलाबदल केले आहे"
#: ../js/ui/telepathyClient.js:1323
#: ../js/ui/telepathyClient.js:1325
msgid "The account already exists on the server"
msgstr "खाते आधिपासूनच सर्व्हरवर अस्तित्वात आहे"
#: ../js/ui/telepathyClient.js:1325
#: ../js/ui/telepathyClient.js:1327
msgid "Server is currently too busy to handle the connection"
msgstr "जोडणी हाताळण्यासाठी सर्व्हर सध्या खूप व्यस्थ आहे"
#: ../js/ui/telepathyClient.js:1327
#: ../js/ui/telepathyClient.js:1329
msgid "Certificate has been revoked"
msgstr "प्रमाणपत्र रद्द केले"
#: ../js/ui/telepathyClient.js:1329
#: ../js/ui/telepathyClient.js:1331
msgid ""
"Certificate uses an insecure cipher algorithm or is cryptographically weak"
msgstr ""
"प्रमाणपत्र असुरक्षित सिफर अल्गोरिदमचा वापर करते किंवा क्रिप्टोग्राफिकरित्या "
"खूप कमजोर आहे"
#: ../js/ui/telepathyClient.js:1331
#: ../js/ui/telepathyClient.js:1333
msgid ""
"The length of the server certificate, or the depth of the server certificate "
"chain, exceed the limits imposed by the cryptography library"
msgstr ""
"सर्व्हर प्रमाणपत्राची लांबी, किंवा सर्व्हर प्रमाणपत्र चैनचे गांभीर्य, "
"क्रिप्टोग्राफि लाइब्ररितर्फे लादलेल्या मर्यादापेक्षा जास्त आहे"
"क्रिप्टोग्राफि "
"लाइब्ररितर्फे लादलेल्या मर्यादापेक्षा जास्त आहे"
#: ../js/ui/telepathyClient.js:1333
#: ../js/ui/telepathyClient.js:1335
msgid "Internal error"
msgstr "आंतरिक त्रुटी"
#. translators: argument is the account name, like
#. * name@jabber.org for example.
#: ../js/ui/telepathyClient.js:1343
#: ../js/ui/telepathyClient.js:1345
#, c-format
#| msgid "connection failed"
msgid "Connection to %s failed"
msgstr "%s सह जोडणी अपयशी"
#: ../js/ui/telepathyClient.js:1352
#| msgid "Reject"
#: ../js/ui/telepathyClient.js:1354
msgid "Reconnect"
msgstr "पुनःजोडणी करा"
#: ../js/ui/telepathyClient.js:1353
#| msgid "My Account"
#: ../js/ui/telepathyClient.js:1355
msgid "Edit account"
msgstr "खाते संपादित करा"
#: ../js/ui/telepathyClient.js:1399
#| msgid "Unknown"
#: ../js/ui/telepathyClient.js:1401
msgid "Unknown reason"
msgstr "अपरिचीत कारण"
@ -1684,7 +1636,6 @@ msgid "Idle"
msgstr "रिकामे"
#: ../js/ui/userMenu.js:144
#| msgid "unavailable"
msgid "Unavailable"
msgstr "अनुपलब्ध"
@ -1693,12 +1644,10 @@ msgid "Power Off..."
msgstr "बंद करा..."
#: ../js/ui/userMenu.js:631
#| msgid "Applications"
msgid "Notifications"
msgstr "सूचना"
#: ../js/ui/userMenu.js:639
#| msgid "My Account"
msgid "Online Accounts"
msgstr "ऑनलाइन खाते"
@ -1728,7 +1677,8 @@ msgid ""
"has been adjusted to let others know that you might not see their messages."
msgstr ""
"सूचना आता बंद केले आहे, चॅट संदेश समाविष्टीत. इतरांना तुमचे संदेश दिसणार नाही "
"हे कळवण्यासाठी ऑनलाइन स्थिती सुस्थीत केली आहे."
"हे कळवण्यासाठी "
"ऑनलाइन स्थिती सुस्थीत केली आहे."
#. Translators: this is the text displayed
#. in the search entry when no search is
@ -1767,7 +1717,7 @@ msgstr "'%s' सज्ज आहे"
#. translators:
#. * The number of sound outputs on a particular device
#: ../src/gvc/gvc-mixer-control.c:1100
#: ../src/gvc/gvc-mixer-control.c:1089
#, c-format
msgid "%u Output"
msgid_plural "%u Outputs"
@ -1776,14 +1726,14 @@ msgstr[1] "%u आऊटपुट"
#. translators:
#. * The number of sound inputs on a particular device
#: ../src/gvc/gvc-mixer-control.c:1110
#: ../src/gvc/gvc-mixer-control.c:1099
#, c-format
msgid "%u Input"
msgid_plural "%u Inputs"
msgstr[0] "%u इंपुट"
msgstr[1] "%u इंपुट"
#: ../src/gvc/gvc-mixer-control.c:1408
#: ../src/gvc/gvc-mixer-control.c:1397
msgid "System Sounds"
msgstr "प्रणाली आवाज"
@ -1801,7 +1751,6 @@ msgid "Failed to launch '%s'"
msgstr "'%s' सुरू करण्यास अपयशी"
#: ../src/shell-keyring-prompt.c:708
#| msgid "Does not match"
msgid "Passwords do not match."
msgstr "पासवर्डस् जुळत नाही."
@ -1824,7 +1773,6 @@ msgstr "ओळख पटवा संवाद वापरकर्त्या
#. Translators: this is the same string as the one found in
#. * nautilus
#: ../src/shell-util.c:97
#| msgid "Volume"
msgid "Home"
msgstr "होम"

424
po/nb.po

File diff suppressed because it is too large Load Diff

View File

@ -14,15 +14,15 @@ msgid ""
msgstr ""
"Project-Id-Version: \n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2012-03-21 21:00-0300\n"
"PO-Revision-Date: 2012-03-13 11:54-0300\n"
"POT-Creation-Date: 2012-04-28 10:45-0300\n"
"PO-Revision-Date: 2012-04-28 10:45-0300\n"
"Last-Translator: Jonh Wendell <jwendell@gnome.org>\n"
"Language-Team: Brazilian Portuguese <gnome-pt_br-list@gnome.org>\n"
"Language: pt_BR\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n!=1);\n"
"Plural-Forms: nplurals=2; plural=(n > 1);\n"
#: ../data/gnome-shell.desktop.in.in.h:1
msgid "GNOME Shell"
@ -114,11 +114,19 @@ msgstr ""
"valor usado aqui vem da enumeração GsmPresenceStatus."
#: ../data/org.gnome.shell.gschema.xml.in.h:13
msgid "Keybinding to open the application menu"
msgstr "Atalho de teclado para abrir o menu aplicativo"
#: ../data/org.gnome.shell.gschema.xml.in.h:14
msgid "Keybinding to open the application menu."
msgstr "Atalho de teclado para abrir o menu aplicativo."
#: ../data/org.gnome.shell.gschema.xml.in.h:15
msgid "List of desktop file IDs for favorite applications"
msgstr ""
"Lista dos IDs de arquivo de área de trabalho para os aplicativos favoritos"
#: ../data/org.gnome.shell.gschema.xml.in.h:15
#: ../data/org.gnome.shell.gschema.xml.in.h:17
#, no-c-format
msgid ""
"Sets the GStreamer pipeline used to encode recordings. It follows the syntax "
@ -144,19 +152,19 @@ msgstr ""
"usando o codec VP8. %T é usado como uma tentativa de descobrir a melhor "
"quantidade de threads a serem usadas."
#: ../data/org.gnome.shell.gschema.xml.in.h:16
#: ../data/org.gnome.shell.gschema.xml.in.h:18
msgid "Show date in clock"
msgstr "Mostrar data no relógio"
#: ../data/org.gnome.shell.gschema.xml.in.h:17
#: ../data/org.gnome.shell.gschema.xml.in.h:19
msgid "Show the week date in the calendar"
msgstr "Mostrar o número da semana no calendário"
#: ../data/org.gnome.shell.gschema.xml.in.h:18
#: ../data/org.gnome.shell.gschema.xml.in.h:20
msgid "Show time with seconds"
msgstr "Mostrar horário com segundos"
#: ../data/org.gnome.shell.gschema.xml.in.h:19
#: ../data/org.gnome.shell.gschema.xml.in.h:21
msgid ""
"The applications corresponding to these identifiers will be displayed in the "
"favorites area."
@ -164,7 +172,7 @@ msgstr ""
"Os aplicativos correspondentes a estes identificadores serão exibidos na "
"área de favoritos."
#: ../data/org.gnome.shell.gschema.xml.in.h:20
#: ../data/org.gnome.shell.gschema.xml.in.h:22
msgid ""
"The filename for recorded screencasts will be a unique filename based on the "
"current date, and use this extension. It should be changed when recording to "
@ -174,7 +182,7 @@ msgstr ""
"baseado na data atual e usará esta extensão. Ele deve ser alterado ao gravar "
"para um contêiner de formato diferente."
#: ../data/org.gnome.shell.gschema.xml.in.h:21
#: ../data/org.gnome.shell.gschema.xml.in.h:23
msgid ""
"The framerate of the resulting screencast recordered by GNOME Shell's "
"screencast recorder in frames-per-second."
@ -182,11 +190,11 @@ msgstr ""
"A taxa de quadros do screencast resultante do gravador de screencasts do "
"GNOME Shell em quadros por segundo."
#: ../data/org.gnome.shell.gschema.xml.in.h:22
#: ../data/org.gnome.shell.gschema.xml.in.h:24
msgid "The gstreamer pipeline used to encode the screencast"
msgstr "A fila de processamento gstreamer usada para codificar o screencast"
#: ../data/org.gnome.shell.gschema.xml.in.h:23
#: ../data/org.gnome.shell.gschema.xml.in.h:25
msgid ""
"The shell normally monitors active applications in order to present the most "
"used ones (e.g. in launchers). While this data will be kept private, you may "
@ -198,23 +206,23 @@ msgstr ""
"segurança, você pode querer desabilitá-los por razões de privacidade. Por "
"favor, note que ao fazer isso não removerá os dados já salvos."
#: ../data/org.gnome.shell.gschema.xml.in.h:24
#: ../data/org.gnome.shell.gschema.xml.in.h:26
msgid "The type of keyboard to use."
msgstr "O tipo do teclado para usar."
#: ../data/org.gnome.shell.gschema.xml.in.h:25
#: ../data/org.gnome.shell.gschema.xml.in.h:27
msgid "Uuids of extensions to enable"
msgstr "Uuids das extensões para habilitar"
#: ../data/org.gnome.shell.gschema.xml.in.h:26
#: ../data/org.gnome.shell.gschema.xml.in.h:28
msgid "Whether to collect stats about applications usage"
msgstr "Quando coletar dados sobre uso de aplicativos"
#: ../data/org.gnome.shell.gschema.xml.in.h:27
#: ../data/org.gnome.shell.gschema.xml.in.h:29
msgid "Which keyboard to use"
msgstr "Qual teclado usar"
#: ../data/org.gnome.shell.gschema.xml.in.h:28
#: ../data/org.gnome.shell.gschema.xml.in.h:30
msgid "disabled OpenSearch providers"
msgstr "Provedores OpenSearch desabilitados"
@ -231,40 +239,40 @@ msgstr "<b>Extensão</b>"
msgid "Select an extension to configure using the combobox above."
msgstr "Escolha uma extensão para configurar usando a caixa acima."
#: ../js/gdm/loginDialog.js:624
#: ../js/gdm/loginDialog.js:627
msgid "Session..."
msgstr "Sessão..."
#: ../js/gdm/loginDialog.js:786
#: ../js/gdm/loginDialog.js:789
msgctxt "title"
msgid "Sign In"
msgstr "Iniciar sessão"
#. Translators: this message is shown below the password entry field
#. to indicate the user can swipe their finger instead
#: ../js/gdm/loginDialog.js:831
#: ../js/gdm/loginDialog.js:834
msgid "(or swipe finger)"
msgstr "(ou deslize o dedo)"
#. translators: this message is shown below the user list on the
#. login screen. It can be activated to reveal an entry for
#. manually entering the username.
#: ../js/gdm/loginDialog.js:852
#: ../js/gdm/loginDialog.js:855
msgid "Not listed?"
msgstr "Não listado?"
#: ../js/gdm/loginDialog.js:1020 ../js/ui/endSessionDialog.js:401
#: ../js/ui/extensionSystem.js:399 ../js/ui/networkAgent.js:153
#: ../js/gdm/loginDialog.js:1023 ../js/ui/endSessionDialog.js:401
#: ../js/ui/extensionSystem.js:400 ../js/ui/networkAgent.js:153
#: ../js/ui/polkitAuthenticationAgent.js:175 ../js/ui/status/bluetooth.js:462
msgid "Cancel"
msgstr "Cancelar"
#: ../js/gdm/loginDialog.js:1025
#: ../js/gdm/loginDialog.js:1028
msgctxt "button"
msgid "Sign In"
msgstr "Entrar"
#: ../js/gdm/loginDialog.js:1377
#: ../js/gdm/loginDialog.js:1380
msgid "Login Window"
msgstr "Janela de sessão"
@ -663,11 +671,11 @@ msgstr[1] "O sistema será reiniciado automaticamente em %d segundos."
msgid "Restarting the system."
msgstr "Reiniciando o sistema."
#: ../js/ui/extensionSystem.js:403
#: ../js/ui/extensionSystem.js:404
msgid "Install"
msgstr "Instalar"
#: ../js/ui/extensionSystem.js:407
#: ../js/ui/extensionSystem.js:408
#, c-format
msgid "Download and install '%s' from extensions.gnome.org?"
msgstr "Baixar e instalar \"%s\" de extensions.gnome.org?"
@ -676,7 +684,8 @@ msgstr "Baixar e instalar \"%s\" de extensions.gnome.org?"
msgid "tray"
msgstr "bandeja"
#: ../js/ui/keyboard.js:544 ../js/ui/status/power.js:203
#: ../js/ui/keyboard.js:544 ../js/ui/status/keyboard.js:44
#: ../js/ui/status/power.js:203
msgid "Keyboard"
msgstr "Teclado"
@ -688,51 +697,51 @@ msgstr "Senha:"
msgid "Type again:"
msgstr "Digite novamente:"
#: ../js/ui/lookingGlass.js:725
#: ../js/ui/lookingGlass.js:732
msgid "No extensions installed"
msgstr "Nenhuma extensão instalada"
#. Translators: argument is an extension UUID.
#: ../js/ui/lookingGlass.js:779
#: ../js/ui/lookingGlass.js:786
#, c-format
msgid "%s has not emitted any errors."
msgstr "%s não produziu nenhum erro."
#: ../js/ui/lookingGlass.js:785
#: ../js/ui/lookingGlass.js:792
msgid "Hide Errors"
msgstr "Mostrar erros"
#: ../js/ui/lookingGlass.js:789 ../js/ui/lookingGlass.js:840
#: ../js/ui/lookingGlass.js:796 ../js/ui/lookingGlass.js:847
msgid "Show Errors"
msgstr "Esconder erros"
#: ../js/ui/lookingGlass.js:798
#: ../js/ui/lookingGlass.js:805
msgid "Enabled"
msgstr "Habilitada"
#. translators:
#. * The device has been disabled
#: ../js/ui/lookingGlass.js:801 ../src/gvc/gvc-mixer-control.c:1093
#: ../js/ui/lookingGlass.js:808 ../src/gvc/gvc-mixer-control.c:1082
msgid "Disabled"
msgstr "Desabilitada"
#: ../js/ui/lookingGlass.js:803
#: ../js/ui/lookingGlass.js:810
msgid "Error"
msgstr "Erro"
#: ../js/ui/lookingGlass.js:805
#: ../js/ui/lookingGlass.js:812
msgid "Out of date"
msgstr "Obsoleta"
#: ../js/ui/lookingGlass.js:807
#: ../js/ui/lookingGlass.js:814
msgid "Downloading"
msgstr "Baixando"
#: ../js/ui/lookingGlass.js:828
#: ../js/ui/lookingGlass.js:835
msgid "View Source"
msgstr "Ver fonte"
#: ../js/ui/lookingGlass.js:834
#: ../js/ui/lookingGlass.js:841
msgid "Web Page"
msgstr "Página web"
@ -861,17 +870,17 @@ msgstr "Aplicativos"
msgid "Dash"
msgstr "Dash"
#: ../js/ui/panel.js:591
#: ../js/ui/panel.js:592
msgid "Quit"
msgstr "Sair"
#. Translators: If there is no suitable word for "Activities"
#. in your language, you can use the word for "Overview".
#: ../js/ui/panel.js:623
#: ../js/ui/panel.js:624
msgid "Activities"
msgstr "Atividades"
#: ../js/ui/panel.js:998
#: ../js/ui/panel.js:999
msgid "Top Bar"
msgstr "Barra superior"
@ -929,7 +938,7 @@ msgstr "Por favor, digite um comando:"
msgid "Searching..."
msgstr "Pesquisando..."
#: ../js/ui/searchDisplay.js:414
#: ../js/ui/searchDisplay.js:415
msgid "No matching results."
msgstr "Nenhum resultado encontrado."
@ -1087,7 +1096,7 @@ msgstr "Sempre permitir acesso"
msgid "Grant this time only"
msgstr "Permitir apenas desta vez"
#: ../js/ui/status/bluetooth.js:382 ../js/ui/telepathyClient.js:1091
#: ../js/ui/status/bluetooth.js:382 ../js/ui/telepathyClient.js:1093
msgid "Reject"
msgstr "Rejeitar"
@ -1404,35 +1413,35 @@ msgstr "%s está ocupado."
#. 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:887
#: ../js/ui/telepathyClient.js:889
#, no-c-format
msgid "Sent at <b>%X</b> on <b>%A</b>"
msgstr "Enviado <b>%A</b>, <b>%X</b>"
#. Translators: this is a time format in the style of "Wednesday, May 25",
#. shown when you get a chat message in the same year.
#: ../js/ui/telepathyClient.js:893
#: ../js/ui/telepathyClient.js:895
#, no-c-format
msgid "Sent on <b>%A</b>, <b>%B %d</b>"
msgstr "Enviado <b>%A</b>, <b>%d de %B</b>"
#. Translators: this is a time format in the style of "Wednesday, May 25, 2012",
#. shown when you get a chat message in a different year.
#: ../js/ui/telepathyClient.js:898
#: ../js/ui/telepathyClient.js:900
#, no-c-format
msgid "Sent on <b>%A</b>, <b>%B %d</b>, %Y"
msgstr "Enviado <b>%A</b>, <b>%d de %B</b> de %Y"
#. Translators: this is the other person changing their old IM name to their new
#. IM name.
#: ../js/ui/telepathyClient.js:940
#: ../js/ui/telepathyClient.js:942
#, c-format
msgid "%s is now known as %s"
msgstr "%s agora é conhecido como %s"
#. translators: argument is a room name like
#. * room@jabber.org for example.
#: ../js/ui/telepathyClient.js:1042
#: ../js/ui/telepathyClient.js:1044
#, c-format
msgid "Invitation to %s"
msgstr "Convite para %s"
@ -1440,35 +1449,35 @@ msgstr "Convite para %s"
#. translators: first argument is the name of a contact and the second
#. * one the name of a room. "Alice is inviting you to join room@jabber.org
#. * for example.
#: ../js/ui/telepathyClient.js:1050
#: ../js/ui/telepathyClient.js:1052
#, c-format
msgid "%s is inviting you to join %s"
msgstr "%s está convidando você para entrar em %s"
#: ../js/ui/telepathyClient.js:1052 ../js/ui/telepathyClient.js:1131
#: ../js/ui/telepathyClient.js:1229
#: ../js/ui/telepathyClient.js:1054 ../js/ui/telepathyClient.js:1133
#: ../js/ui/telepathyClient.js:1231
msgid "Decline"
msgstr "Recusar"
#: ../js/ui/telepathyClient.js:1053 ../js/ui/telepathyClient.js:1132
#: ../js/ui/telepathyClient.js:1230
#: ../js/ui/telepathyClient.js:1055 ../js/ui/telepathyClient.js:1134
#: ../js/ui/telepathyClient.js:1232
msgid "Accept"
msgstr "Aceitar"
#. translators: argument is a contact name like Alice for example.
#: ../js/ui/telepathyClient.js:1083
#: ../js/ui/telepathyClient.js:1085
#, c-format
msgid "Video call from %s"
msgstr "Vídeo-chamada de %s"
#. translators: argument is a contact name like Alice for example.
#: ../js/ui/telepathyClient.js:1086
#: ../js/ui/telepathyClient.js:1088
#, c-format
msgid "Call from %s"
msgstr "Chamada de %s"
#. translators: this is a button label (verb), not a noun
#: ../js/ui/telepathyClient.js:1093
#: ../js/ui/telepathyClient.js:1095
msgid "Answer"
msgstr "Atender"
@ -1477,110 +1486,110 @@ msgstr "Atender"
#. * file name. The string will be something
#. * like: "Alice is sending you test.ogg"
#.
#: ../js/ui/telepathyClient.js:1125
#: ../js/ui/telepathyClient.js:1127
#, c-format
msgid "%s is sending you %s"
msgstr "%s está enviando %s"
#. To translators: The parameter is the contact's alias
#: ../js/ui/telepathyClient.js:1194
#: ../js/ui/telepathyClient.js:1196
#, c-format
msgid "%s would like permission to see when you are online"
msgstr "%s quer permissão para vê-lo quando conectado"
#: ../js/ui/telepathyClient.js:1287
#: ../js/ui/telepathyClient.js:1289
msgid "Network error"
msgstr "Erro de rede"
#: ../js/ui/telepathyClient.js:1289
#: ../js/ui/telepathyClient.js:1291
msgid "Authentication failed"
msgstr "Falha de autenticação"
#: ../js/ui/telepathyClient.js:1291
#: ../js/ui/telepathyClient.js:1293
msgid "Encryption error"
msgstr "Erro de criptografia"
#: ../js/ui/telepathyClient.js:1293
#: ../js/ui/telepathyClient.js:1295
msgid "Certificate not provided"
msgstr "Certificado não fornecido"
#: ../js/ui/telepathyClient.js:1295
#: ../js/ui/telepathyClient.js:1297
msgid "Certificate untrusted"
msgstr "Certificado não confiável"
#: ../js/ui/telepathyClient.js:1297
#: ../js/ui/telepathyClient.js:1299
msgid "Certificate expired"
msgstr "Certificado expirado"
#: ../js/ui/telepathyClient.js:1299
#: ../js/ui/telepathyClient.js:1301
msgid "Certificate not activated"
msgstr "Certificado não ativado"
#: ../js/ui/telepathyClient.js:1301
#: ../js/ui/telepathyClient.js:1303
msgid "Certificate hostname mismatch"
msgstr "Máquina do certificado não confere"
#: ../js/ui/telepathyClient.js:1303
#: ../js/ui/telepathyClient.js:1305
msgid "Certificate fingerprint mismatch"
msgstr "Impressão digital do certificado não confere"
#: ../js/ui/telepathyClient.js:1305
#: ../js/ui/telepathyClient.js:1307
msgid "Certificate self-signed"
msgstr "Certificado auto-assinado"
#: ../js/ui/telepathyClient.js:1307
#: ../js/ui/telepathyClient.js:1309
msgid "Status is set to offline"
msgstr "O status está definido como desconectado."
#: ../js/ui/telepathyClient.js:1309
#: ../js/ui/telepathyClient.js:1311
msgid "Encryption is not available"
msgstr "Criptografia não disponível"
#: ../js/ui/telepathyClient.js:1311
#: ../js/ui/telepathyClient.js:1313
msgid "Certificate is invalid"
msgstr "O certificado é inválido"
#: ../js/ui/telepathyClient.js:1313
#: ../js/ui/telepathyClient.js:1315
msgid "Connection has been refused"
msgstr "A conexão foi recusada"
#: ../js/ui/telepathyClient.js:1315
#: ../js/ui/telepathyClient.js:1317
msgid "Connection can't be established"
msgstr "A conexão não pode ser estabelecida"
#: ../js/ui/telepathyClient.js:1317
#: ../js/ui/telepathyClient.js:1319
msgid "Connection has been lost"
msgstr "Conexão perdida"
#: ../js/ui/telepathyClient.js:1319
#: ../js/ui/telepathyClient.js:1321
msgid "This account is already connected to the server"
msgstr "Esta conta já está conectada ao servidor"
#: ../js/ui/telepathyClient.js:1321
#: ../js/ui/telepathyClient.js:1323
msgid ""
"Connection has been replaced by a new connection using the same resource"
msgstr "A conexão foi substituída por uma nova conexão usando o mesmo recurso"
#: ../js/ui/telepathyClient.js:1323
#: ../js/ui/telepathyClient.js:1325
msgid "The account already exists on the server"
msgstr "A conta já existe no servidor"
#: ../js/ui/telepathyClient.js:1325
#: ../js/ui/telepathyClient.js:1327
msgid "Server is currently too busy to handle the connection"
msgstr "O servidor está atualmente muito ocupado para controlar a conexão"
#: ../js/ui/telepathyClient.js:1327
#: ../js/ui/telepathyClient.js:1329
msgid "Certificate has been revoked"
msgstr "O certificado foi revogado"
#: ../js/ui/telepathyClient.js:1329
#: ../js/ui/telepathyClient.js:1331
msgid ""
"Certificate uses an insecure cipher algorithm or is cryptographically weak"
msgstr ""
"O certificado usa um algoritmo de cifragem inseguro ou é criptograficamente "
"fraco"
#: ../js/ui/telepathyClient.js:1331
#: ../js/ui/telepathyClient.js:1333
msgid ""
"The length of the server certificate, or the depth of the server certificate "
"chain, exceed the limits imposed by the cryptography library"
@ -1588,26 +1597,26 @@ msgstr ""
"O comprimento do certificado do servidor, ou a profundidade da cadeia do "
"certificado excedeu os limites impostos pela biblioteca de criptografia"
#: ../js/ui/telepathyClient.js:1333
#: ../js/ui/telepathyClient.js:1335
msgid "Internal error"
msgstr "Erro interno"
#. translators: argument is the account name, like
#. * name@jabber.org for example.
#: ../js/ui/telepathyClient.js:1343
#: ../js/ui/telepathyClient.js:1345
#, c-format
msgid "Connection to %s failed"
msgstr "A conexão com %s falhou"
#: ../js/ui/telepathyClient.js:1352
#: ../js/ui/telepathyClient.js:1354
msgid "Reconnect"
msgstr "Reconectar"
#: ../js/ui/telepathyClient.js:1353
#: ../js/ui/telepathyClient.js:1355
msgid "Edit account"
msgstr "Editar conta"
#: ../js/ui/telepathyClient.js:1399
#: ../js/ui/telepathyClient.js:1401
msgid "Unknown reason"
msgstr "Razão desconhecida"
@ -1701,7 +1710,7 @@ msgstr "\"%s\" está pronto"
#. translators:
#. * The number of sound outputs on a particular device
#: ../src/gvc/gvc-mixer-control.c:1100
#: ../src/gvc/gvc-mixer-control.c:1089
#, c-format
msgid "%u Output"
msgid_plural "%u Outputs"
@ -1710,14 +1719,14 @@ msgstr[1] "%u saídas"
#. translators:
#. * The number of sound inputs on a particular device
#: ../src/gvc/gvc-mixer-control.c:1110
#: ../src/gvc/gvc-mixer-control.c:1099
#, c-format
msgid "%u Input"
msgid_plural "%u Inputs"
msgstr[0] "%u entrada"
msgstr[1] "%u entradas"
#: ../src/gvc/gvc-mixer-control.c:1408
#: ../src/gvc/gvc-mixer-control.c:1397
msgid "System Sounds"
msgstr "Sons do sistema"

483
po/sl.po

File diff suppressed because it is too large Load Diff

View File

@ -27,8 +27,10 @@ CLEANFILES += $(service_DATA)
CLEANFILES += $(gir_DATA) $(typelib_DATA)
bin_SCRIPTS += gnome-shell-extension-tool gnome-shell-extension-prefs
EXTRA_DIST += gnome-shell-extension-tool.in gnome-shell-extension-prefs.in
bin_SCRIPTS += gnome-shell-extension-tool gnome-shell-extension-prefs \
gnome-shell-perf-tool
EXTRA_DIST += gnome-shell-extension-tool.in gnome-shell-extension-prefs.in \
gnome-shell-perf-tool.in
bin_PROGRAMS = gnome-shell-real
if USE_JHBUILD_WRAPPER_SCRIPT
@ -53,7 +55,6 @@ generated_script_substitutions = \
-e "s|@libexecdir[@]|$(libexecdir)|g" \
-e "s|@libdir[@]|$(libdir)|g" \
-e "s|@pkglibdir[@]|$(pkglibdir)|g" \
-e "s|@JHBUILD_TYPELIBDIR[@]|$(JHBUILD_TYPELIBDIR)|g" \
-e "s|@pkgdatadir[@]|$(pkgdatadir)|g" \
-e "s|@PYTHON[@]|$(PYTHON)|g" \
-e "s|@VERSION[@]|$(VERSION)|g" \
@ -71,6 +72,9 @@ gnome-shell-extension-tool: gnome-shell-extension-tool.in Makefile
gnome-shell-extension-prefs: gnome-shell-extension-prefs.in Makefile
$(AM_V_GEN) sed $(generated_script_substitutions) $< > $@.tmp && mv $@.tmp $@ && chmod a+x $@
gnome-shell-perf-tool: gnome-shell-perf-tool.in Makefile
$(AM_V_GEN) sed $(generated_script_substitutions) $< > $@.tmp && mv $@.tmp $@ && chmod a+x $@
CLEANFILES += gnome-shell $(bin_SCRIPTS)
include Makefile-st.am
@ -89,7 +93,8 @@ gnome_shell_cflags = \
-DGNOME_SHELL_LIBEXECDIR=\"$(libexecdir)\" \
-DGNOME_SHELL_DATADIR=\"$(pkgdatadir)\" \
-DGNOME_SHELL_PKGLIBDIR=\"$(pkglibdir)\" \
-DJSDIR=\"$(pkgdatadir)/js\"
-DJSDIR=\"$(pkgdatadir)/js\" \
-DMUTTER_TYPELIB_DIR=\"$(MUTTER_TYPELIB_DIR)\"
privlibdir = $(pkglibdir)
privlib_LTLIBRARIES = libgnome-shell.la libgnome-shell-js.la
@ -110,6 +115,7 @@ shell_public_headers_h = \
shell-gtk-embed.h \
shell-global.h \
shell-idle-monitor.h \
shell-invert-lightness-effect.h \
shell-mobile-providers.h \
shell-mount-operation.h \
shell-network-agent.h \
@ -157,6 +163,7 @@ libgnome_shell_la_SOURCES = \
shell-gtk-embed.c \
shell-global.c \
shell-idle-monitor.c \
shell-invert-lightness-effect.c \
shell-keyring-prompt.h \
shell-keyring-prompt.c \
shell-mobile-providers.c \
@ -187,7 +194,7 @@ libgnome_shell_la_gir_sources = \
gnome_shell_real_SOURCES = \
main.c
gnome_shell_real_CPPFLAGS = $(gnome_shell_cflags)
gnome_shell_real_LDADD = libgnome-shell.la $(libgnome_shell_la_LIBADD)
gnome_shell_real_LDADD = libgnome-shell.la libgnome-shell-js.la $(libgnome_shell_la_LIBADD)
gnome_shell_real_DEPENDENCIES = libgnome-shell.la
EXTRA_DIST += test-gapplication.js

View File

@ -52,7 +52,10 @@
#define CALENDAR_SOURCES_APPOINTMENT_SOURCES_KEY CALENDAR_SOURCES_EVO_DIR "/calendar/sources"
#define CALENDAR_SOURCES_TASK_SOURCES_KEY CALENDAR_SOURCES_EVO_DIR "/tasks/sources"
#define CALENDAR_SELECTED_SOURCES_SCHEMA "org.gnome.evolution.calendar"
/* org.gnome.shell.evolution.calendar has the same data behind it
* as org.gnome.evolution.calendar, but is a small schema we install
* ourselves */
#define CALENDAR_SELECTED_SOURCES_SCHEMA "org.gnome.shell.evolution.calendar"
#define CALENDAR_SOURCES_SELECTED_APPOINTMENT_SOURCES_KEY "selected-calendars"
#define CALENDAR_SOURCES_SELECTED_TASK_SOURCES_KEY "selected-tasks"

View File

@ -94,8 +94,20 @@ static gchar **
g_action_muxer_list_actions (GActionGroup *action_group)
{
GActionMuxer *muxer = G_ACTION_MUXER (action_group);
GHashTableIter iter;
gchar *key;
gchar **keys;
gsize i;
return (gchar **) muxer->groups;
keys = g_new (gchar *, g_hash_table_size (muxer->actions) + 1);
i = 0;
g_hash_table_iter_init (&iter, muxer->actions);
while (g_hash_table_iter_next (&iter, (gpointer *) &key, NULL))
keys[i++] = g_strdup (key);
keys[i] = NULL;
return keys;
}
static Group *

View File

@ -1,30 +1,13 @@
#!@PYTHON@
# -*- mode: Python; indent-tabs-mode: nil; -*-
import atexit
import datetime
import dbus
from dbus.mainloop.glib import DBusGMainLoop
import gobject
try:
import json
except ImportError:
try:
import simplejson as json
except ImportError:
json = None
import optparse
import os
import random
import re
import shutil
import signal
import subprocess
import sys
import tempfile
import termios
import time
import errno
def show_version(option, opt_str, value, parser):
print "GNOME Shell @VERSION@"
@ -79,168 +62,24 @@ def get_running_session_environs():
result[key] = environs[key]
return result
_bus = None
_bus_iface = None
_name_owner_changed_hook = None
def on_name_owner_changed(name, prev_owner, new_owner):
if _name_owner_changed_hook:
_name_owner_changed_hook(name, prev_owner, new_owner)
def get_bus():
global _bus
if _bus is None:
dbus_loop = DBusGMainLoop()
_bus = dbus.SessionBus(mainloop=dbus_loop)
return _bus
def get_bus_iface():
global _bus_iface
if _bus_iface is None:
bus = get_bus()
bus_proxy = bus.get_object('org.freedesktop.DBus', '/org/freedesktop/DBus')
_bus_iface = dbus.Interface(bus_proxy, 'org.freedesktop.DBus')
_bus_iface.connect_to_signal('NameOwnerChanged', on_name_owner_changed)
return _bus_iface
def wait_for_dbus_name(wait_name):
global _name_owner_changed_hook
bus_iface = get_bus_iface()
loop = gobject.MainLoop()
def on_name_owner_changed(name, prev_owner, new_owner):
if not (name == wait_name and new_owner != ''):
return
loop.quit()
return
_name_owner_changed_hook = on_name_owner_changed
def on_timeout():
print "\nFailed to start %s: timed out" % (wait_name,)
sys.exit(1)
gobject.timeout_add_seconds(7, on_timeout)
loop.run()
_name_owner_changed_hook = None
def start_dconf_await_service():
DCONF_NAME = 'ca.desrt.dconf'
bus = get_bus()
get_bus_iface() # connect to NameOwnerChanged signal
# See if the service is already running or normal D-Bus activation works
need_manual_activate = False
try:
dconf_proxy = bus.get_object(DCONF_NAME, '/')
dconf_proxy.Ping(dbus_interface='org.freedesktop.DBus.Peer')
except dbus.exceptions.DBusException, e:
if e.get_dbus_name() == 'org.freedesktop.DBus.Error.ServiceUnknown':
need_manual_activate = True
else:
raise e
if not need_manual_activate:
return
# At this point, it looks like we just have a jhbuild install
# of dconf, not known to the session dbus-daemon, so we start
# it manually and wait for it to join the bus
print "Starting dconf-service... ",
sys.stdout.flush()
# dconf is linked without libtool, so unlike other GNOME modules,
# won't have an embedded rpath for its library directory.
env = dict(os.environ)
if 'LD_LIBRARY_PATH' in env and env['LD_LIBRARY_PATH']:
ld_library_path = '@libdir@:' + env['LD_LIBRARY_PATH']
else:
ld_library_path = '@libdir@'
env['LD_LIBRARY_PATH'] = ld_library_path
dconf_path = os.path.join('@libexecdir@', 'dconf-service')
try:
subprocess.Popen([dconf_path, '--keep-alive'], env=env)
except OSError, e:
print "\nFailed to start %s: %s" % (dconf_path, e)
sys.exit(1)
wait_for_dbus_name (DCONF_NAME)
PERF_HELPER_NAME = "org.gnome.Shell.PerfHelper"
PERF_HELPER_IFACE = "org.gnome.Shell.PerfHelper"
PERF_HELPER_PATH = "/org/gnome/Shell/PerfHelper"
def start_perf_helper():
get_bus_iface() # connect to NameOwnerChanged signal
def start_shell():
self_dir = os.path.dirname(os.path.abspath(sys.argv[0]))
running_from_source_tree = os.path.exists(os.path.join(self_dir, 'gnome-shell-jhbuild.in'))
if running_from_source_tree:
perf_helper_path = os.path.join(self_dir, "gnome-shell-perf-helper")
else:
perf_helper_path = "@libexecdir@/gnome-shell-perf-helper"
subprocess.Popen([perf_helper_path])
wait_for_dbus_name (PERF_HELPER_NAME)
def stop_perf_helper():
bus = get_bus()
proxy = bus.get_object(PERF_HELPER_NAME, PERF_HELPER_PATH)
proxy.Exit(dbus_interface=PERF_HELPER_IFACE)
def start_shell(perf_output=None):
self_dir = os.path.dirname(os.path.abspath(sys.argv[0]))
if os.path.exists(os.path.join(self_dir, 'gnome-shell-jhbuild.in')):
running_from_source_tree = True
top_dir = os.path.dirname(self_dir)
typelib_dir = '@JHBUILD_TYPELIBDIR@:' + os.path.join(top_dir, "src")
js_dir = os.path.join(top_dir, "js")
data_dir = os.path.join(top_dir, "data")
else:
running_from_source_tree = False
js_dir = os.path.join('@pkgdatadir@', 'js')
typelib_dir = '@JHBUILD_TYPELIBDIR@'
if os.environ.has_key('GI_TYPELIB_PATH'):
typelib_dir = typelib_dir + ":" + os.environ.get('GI_TYPELIB_PATH')
# Set up environment
env = dict(os.environ)
# TODO: Fix this, since nothing prevents it from propagating to child
# processes. Why is it even here?
env.update({'GNOME_DISABLE_CRASH_DIALOG' : '1'})
# This stuff should really should only happen when running
# uninstalled, i.e. it should be in the conditional
# below. Otherwise it's just a bad reimplementation of "jhbuild
# run". See bug #642084
env.update({'GNOME_SHELL_JS' : js_dir,
'PATH' : '@bindir@:' + os.environ.get('PATH', ''),
'GI_TYPELIB_PATH' : typelib_dir,
'XDG_CONFIG_DIRS' : '@sysconfdir@/xdg:' + (os.environ.get('XDG_CONFIG_DIRS') or '/etc/xdg'),
'XDG_DATA_DIRS' : '@datadir@:' + (os.environ.get('XDG_DATA_DIRS') or '/usr/local/share:/usr/share')})
if running_from_source_tree:
env.update({'GNOME_SHELL_BINDIR' : self_dir,
'GNOME_SHELL_DATADIR' : data_dir,
'GSETTINGS_SCHEMA_DIR' : data_dir })
else:
# This is just broken to set in the installed case; see bug #642084
env.update({'GSETTINGS_SCHEMA_DIR' : os.path.join('@datadir@', 'glib-2.0', 'schemas')})
top_dir = os.path.dirname(self_dir)
# Also plain broken to set in the normal installed case
jhbuild_gconf_source = os.path.join('@sysconfdir@', 'gconf/2/path.jhbuild')
if os.path.exists(jhbuild_gconf_source):
env['GCONF_DEFAULT_SOURCE_PATH'] = jhbuild_gconf_source
typelib_dir = os.path.join(top_dir, "src")
if 'GI_TYPELIB_PATH' in os.environ:
typelib_dir += ':%s' % (os.environ['GI_TYPELIB_PATH'],)
if options.perf is not None:
env['SHELL_PERF_MODULE'] = options.perf
env['MUTTER_WM_CLASS_FILTER'] = 'Gnome-shell-perf-helper'
if perf_output is not None:
env['SHELL_PERF_OUTPUT'] = perf_output
env.update({'GNOME_SHELL_JS' : os.path.join(top_dir, "js"),
'GNOME_SHELL_BINDIR' : self_dir,
'GI_TYPELIB_PATH' : typelib_dir,
'GNOME_SHELL_DATADIR' : os.path.join(top_dir, "data"),
'GSETTINGS_SCHEMA_DIR' : os.path.join(top_dir, "data") })
args = []
if options.debug:
@ -256,22 +95,7 @@ def start_shell(perf_output=None):
args.append('--sync')
return subprocess.Popen(args, env=env)
def _killall(processname):
subprocess.call(['pkill', '-u', '%d' % (os.getuid(), ),
'-f', r'^([^ ]*/)?' + re.escape(processname) + '($| )'])
def ensure_desktop_infrastructure_state():
# This is a collection of random hacks necessary to make sure
# that we can run in jhbuild scenarios or when dynamically
# replacing GNOME 2.
start_dconf_await_service()
# We need to terminate notification-daemon
_killall('notification-daemon')
_killall('notify-osd')
def run_shell(perf_output=None):
def run_shell():
if options.debug:
# Record initial terminal state so we can reset it to that
# later, in case we kill gdb at a bad time
@ -282,8 +106,9 @@ def run_shell(perf_output=None):
if options.verbose:
print "Starting shell"
shell = None
try:
shell = start_shell(perf_output=perf_output)
shell = start_shell()
# Wait for shell to exit
if options.verbose:
@ -317,248 +142,6 @@ def run_shell(perf_output=None):
return normal_exit
def upload_performance_report(report_text):
# Local imports to avoid impacting gnome-shell startup time
import base64
from ConfigParser import RawConfigParser
import hashlib
import hmac
import httplib
import urlparse
import urllib
try:
config_home = os.environ['XDG_CONFIG_HOME']
except KeyError:
config_home = None
if not config_home:
config_home = os.path.expanduser("~/.config")
config_file = os.path.join(config_home, "gnome-shell/perf.ini")
try:
config = RawConfigParser()
f = open(config_file)
config.readfp(f)
f.close()
base_url = config.get('upload', 'url')
system_name = config.get('upload', 'name')
secret_key = config.get('upload', 'key')
except Exception, e:
print "Can't read upload configuration from %s: %s" % (config_file, str(e))
sys.exit(1)
# Determine host, port and upload URL from provided data, we're
# a bit extra-careful about normalization since the URL is part
# of the signature.
split = urlparse.urlsplit(base_url)
scheme = split[0].lower()
netloc = split[1]
base_path = split[2]
m = re.match(r'^(.*?)(?::(\d+))?$', netloc)
if m.group(2):
host, port = m.group(1), int(m.group(2))
else:
host, port = m.group(1), None
if scheme != "http":
print "'%s' is not a HTTP URL" % base_url
sys.exit(1)
if port is None:
port = 80
if base_path.endswith('/'):
base_path = base_path[:-1]
if port == 80:
normalized_base = "%s://%s%s" % (scheme, host, base_path)
else:
normalized_base = "%s://%s:%d%s" % (scheme, host, port, base_path)
upload_url = normalized_base + '/system/%s/upload' % system_name
upload_path = urlparse.urlsplit(upload_url)[2] # path portion
# Create signature based on upload URL and the report data
signature_data = 'POST&' + upload_url + "&&"
h = hmac.new(secret_key, digestmod=hashlib.sha1)
h.update(signature_data)
h.update(report_text)
signature = urllib.quote(base64.b64encode(h.digest()), "~")
headers = {
'User-Agent': 'gnome-shell',
'Content-Type': 'application/json',
'X-Shell-Signature': 'HMAC-SHA1 ' + signature
};
connection = httplib.HTTPConnection(host, port)
connection.request('POST', upload_path, report_text, headers)
response = connection.getresponse()
if response.status == 200:
print "Performance report upload succeeded"
else:
print "Performance report upload failed with status %d" % response.status
print response.read()
def run_performance_test():
iters = options.perf_iters
if options.perf_warmup:
iters += 1
logs = []
metric_summaries = {}
start_perf_helper()
for i in xrange(0, iters):
# We create an empty temporary file that the shell will overwrite
# with the contents.
handle, output_file = tempfile.mkstemp(".json", "gnome-shell-perf.")
os.close(handle)
# Run the performance test and collect the output as JSON
normal_exit = False
try:
normal_exit = run_shell(perf_output=output_file)
except:
stop_perf_helper()
raise
finally:
if not normal_exit:
os.remove(output_file)
if not normal_exit:
stop_perf_helper()
return False
try:
f = open(output_file)
output = json.load(f)
f.close()
except:
stop_perf_helper()
raise
finally:
os.remove(output_file)
# Grab the event definitions and monitor layout the first time around
if i == 0:
events = output['events']
monitors = output['monitors']
if options.perf_warmup and i == 0:
continue
for metric in output['metrics']:
name = metric['name']
if not name in metric_summaries:
summary = {}
summary['description'] = metric['description']
summary['units'] = metric['units']
summary['values'] = []
metric_summaries[name] = summary
else:
summary = metric_summaries[name]
summary['values'].append(metric['value'])
logs.append(output['log'])
stop_perf_helper()
if options.perf_output or options.perf_upload:
# Write a complete report, formatted as JSON. The Javascript/C code that
# generates the individual reports we are summarizing here is very careful
# to format them nicely, but we just dump out a compressed no-whitespace
# version here for simplicity. Using json.dump(indent=0) doesn't real
# improve the readability of the output much.
report = {
'date': datetime.datetime.utcnow().isoformat() + 'Z',
'events': events,
'monitors': monitors,
'metrics': metric_summaries,
'logs': logs
}
# Add the Git revision if available
self_dir = os.path.dirname(os.path.abspath(sys.argv[0]))
if os.path.exists(os.path.join(self_dir, 'gnome-shell-jhbuild.in')):
top_dir = os.path.dirname(self_dir)
git_dir = os.path.join(top_dir, '.git')
if os.path.exists(git_dir):
env = dict(os.environ)
env['GIT_DIR'] = git_dir
revision = subprocess.Popen(['git', 'rev-parse', 'HEAD'],
env=env,
stdout=subprocess.PIPE).communicate()[0].strip()
report['revision'] = revision
if options.perf_output:
f = open(options.perf_output, 'w')
json.dump(report, f)
f.close()
if options.perf_upload:
upload_performance_report(json.dumps(report))
else:
# Write a human readable summary
print '------------------------------------------------------------';
for metric in sorted(metric_summaries.keys()):
summary = metric_summaries[metric]
print "#", summary['description']
print metric, ", ".join((str(x) for x in summary['values']))
print '------------------------------------------------------------';
return True
def restore_gnome():
# Do imports lazily to save time and memory
import gio
import gconf
# We don't want to start the new gnome-panel in the current
# directory; $HOME is better for stuff launched from it
os.chdir(os.path.expanduser("~"))
def launch_component(gconf_path):
client = gconf.client_get_default()
component = client.get_string(gconf_path)
if component == None or component == "":
return False
# See gnome-session/gsm-util.c:gsm_util_find_desktop_file_for_app_name()
# The one difference is that we don't search the autostart directories,
# and just search normal application search path. (Gio doesnt' know
# how to search the autostart dirs, so we'd have to do that ourselves.)
appinfo = None
try:
appinfo = gio.unix.DesktopAppInfo(component + ".desktop")
except:
try:
appinfo = gio.unix.DesktopAppInfo("gnome-" + component + ".desktop")
except:
pass
if appinfo:
appinfo.launch()
return True
return False
# GNOME2 fallback
wm = launch_component("/desktop/gnome/session/required_components/windowmanager")
panel = launch_component("/desktop/gnome/session/required_components/panel")
if not wm and not panel: # Probably GNOME3
subprocess.Popen(['gnome-shell'])
# Main program
parser = optparse.OptionParser()
@ -570,17 +153,6 @@ parser.add_option("", "--debug-command", metavar="COMMAND",
help="Command to use for debugging (defaults to 'gdb --args')")
parser.add_option("-v", "--verbose", action="store_true")
parser.add_option("", "--sync", action="store_true")
parser.add_option("", "--perf", metavar="PERF_MODULE",
help="Specify the name of a performance module to run")
parser.add_option("", "--perf-iters", type="int", metavar="ITERS",
help="Numbers of iterations of performance module to run",
default=1)
parser.add_option("", "--perf-warmup", action="store_true",
help="Run a dry run before performance tests")
parser.add_option("", "--perf-output", metavar="OUTPUT_FILE",
help="Output file to write performance report")
parser.add_option("", "--perf-upload", action="store_true",
help="Upload performance report to server")
parser.add_option("", "--version", action="callback", callback=show_version,
help="Display version and exit")
@ -590,10 +162,6 @@ if args:
parser.print_usage()
sys.exit(1)
if options.perf and json is None:
print 'The Python simplejson module is required for performance tests'
sys.exit(1)
# Handle ssh logins
if 'DISPLAY' not in os.environ:
running_env = get_running_session_environs()
@ -604,21 +172,7 @@ if options.debug_command:
elif options.debug:
options.debug_command = "gdb --args"
# We only respawn the previous environment on abnormal exit;
# for a clean exit, we assume that gnome-shell was replaced with
# something else.
normal_exit = False
try:
if options.perf:
normal_exit = run_performance_test()
else:
ensure_desktop_infrastructure_state()
normal_exit = run_shell()
finally:
if options.replace and (options.perf or not normal_exit):
restore_gnome()
normal_exit = run_shell()
if normal_exit:
sys.exit(0)
else:

View File

@ -0,0 +1,310 @@
#!@PYTHON@
# -*- mode: Python; indent-tabs-mode: nil; -*-
import datetime
from gi.repository import GLib, GObject, Gio
try:
import json
except ImportError:
import simplejson as json
import optparse
import os
import re
import subprocess
import sys
import tempfile
import base64
from ConfigParser import RawConfigParser
import hashlib
import hmac
import httplib
import urlparse
import urllib
def show_version(option, opt_str, value, parser):
print "GNOME Shell Performance Test @VERSION@"
sys.exit()
def wait_for_dbus_name(wait_name):
loop = GLib.MainLoop()
def on_name_appeared(connection, name, name_owner, *args):
if not (name == wait_name and new_owner != ''):
return
loop.quit()
return
watch_id = Gio.bus_watch_name(Gio.BusType.SESSION,
wait_name,
Gio.BusNameWatcherFlags.NONE,
on_name_appeared,
None)
def on_timeout():
print "\nFailed to start %s: timed out" % (wait_name,)
sys.exit(1)
GLib.timeout_add_seconds(7, on_timeout)
loop.run()
Gio.bus_unwatch_name(watch_id)
PERF_HELPER_NAME = "org.gnome.Shell.PerfHelper"
PERF_HELPER_IFACE = "org.gnome.Shell.PerfHelper"
PERF_HELPER_PATH = "/org/gnome/Shell/PerfHelper"
def start_perf_helper():
self_dir = os.path.dirname(os.path.abspath(sys.argv[0]))
perf_helper_path = "@libexecdir@/gnome-shell-perf-helper"
subprocess.Popen([perf_helper_path])
wait_for_dbus_name (PERF_HELPER_NAME)
def stop_perf_helper():
proxy = Gio.DBusProxy(g_bus_type=Gio.BusType.SESSION,
g_name=PERF_HELPER_NAME,
g_interface=PERF_HELPER_IFACE,
g_object_path=PERF_HELPER_PATH)
proxy.Exit()
def start_shell(extra_args, perf_output=None):
# Set up environment
env = dict(os.environ)
env['SHELL_PERF_MODULE'] = options.perf
env['MUTTER_WM_CLASS_FILTER'] = 'Gnome-shell-perf-helper'
if perf_output is not None:
env['SHELL_PERF_OUTPUT'] = perf_output
self_dir = os.path.dirname(os.path.abspath(sys.argv[0]))
args.append(os.path.join(self_dir, 'gnome-shell'))
# pass on any additional arguments
args += extra_args
return subprocess.Popen(args, env=env)
def run_shell(args, perf_output=None):
# we do no additional supervision of gnome-shell,
# beyond that of wait
# in particular, we don't kill the shell upon
# receving a KeyboardInterrupt, as we expect to be
# in the same process group
shell = start_shell(extra_args, perf_output=perf_output)
shell.wait()
return shell.returncode == 0
def upload_performance_report(report_text):
try:
config_home = os.environ['XDG_CONFIG_HOME']
except KeyError:
config_home = None
if not config_home:
config_home = os.path.expanduser("~/.config")
config_file = os.path.join(config_home, "gnome-shell/perf.ini")
try:
config = RawConfigParser()
f = open(config_file)
config.readfp(f)
f.close()
base_url = config.get('upload', 'url')
system_name = config.get('upload', 'name')
secret_key = config.get('upload', 'key')
except Exception, e:
print "Can't read upload configuration from %s: %s" % (config_file, str(e))
sys.exit(1)
# Determine host, port and upload URL from provided data, we're
# a bit extra-careful about normalization since the URL is part
# of the signature.
split = urlparse.urlsplit(base_url)
scheme = split[0].lower()
netloc = split[1]
base_path = split[2]
m = re.match(r'^(.*?)(?::(\d+))?$', netloc)
if m.group(2):
host, port = m.group(1), int(m.group(2))
else:
host, port = m.group(1), None
if scheme != "http":
print "'%s' is not a HTTP URL" % base_url
sys.exit(1)
if port is None:
port = 80
if base_path.endswith('/'):
base_path = base_path[:-1]
if port == 80:
normalized_base = "%s://%s%s" % (scheme, host, base_path)
else:
normalized_base = "%s://%s:%d%s" % (scheme, host, port, base_path)
upload_url = normalized_base + '/system/%s/upload' % system_name
upload_path = urlparse.urlsplit(upload_url)[2] # path portion
# Create signature based on upload URL and the report data
signature_data = 'POST&' + upload_url + "&&"
h = hmac.new(secret_key, digestmod=hashlib.sha1)
h.update(signature_data)
h.update(report_text)
signature = urllib.quote(base64.b64encode(h.digest()), "~")
headers = {
'User-Agent': 'gnome-shell-performance-tool/@VERSION@',
'Content-Type': 'application/json',
'X-Shell-Signature': 'HMAC-SHA1 ' + signature
};
connection = httplib.HTTPConnection(host, port)
connection.request('POST', upload_path, report_text, headers)
response = connection.getresponse()
if response.status == 200:
print "Performance report upload succeeded"
else:
print "Performance report upload failed with status %d" % response.status
print response.read()
def run_performance_test(args):
iters = options.perf_iters
if options.perf_warmup:
iters += 1
logs = []
metric_summaries = {}
start_perf_helper()
for i in xrange(0, iters):
# We create an empty temporary file that the shell will overwrite
# with the contents.
handle, output_file = tempfile.mkstemp(".json", "gnome-shell-perf.")
os.close(handle)
# Run the performance test and collect the output as JSON
normal_exit = False
try:
normal_exit = run_shell(args, perf_output=output_file)
except:
stop_perf_helper()
raise
finally:
if not normal_exit:
os.remove(output_file)
if not normal_exit:
stop_perf_helper()
return False
try:
f = open(output_file)
output = json.load(f)
f.close()
except:
stop_perf_helper()
raise
finally:
os.remove(output_file)
# Grab the event definitions and monitor layout the first time around
if i == 0:
events = output['events']
monitors = output['monitors']
if options.perf_warmup and i == 0:
continue
for metric in output['metrics']:
name = metric['name']
if not name in metric_summaries:
summary = {}
summary['description'] = metric['description']
summary['units'] = metric['units']
summary['values'] = []
metric_summaries[name] = summary
else:
summary = metric_summaries[name]
summary['values'].append(metric['value'])
logs.append(output['log'])
stop_perf_helper()
if options.perf_output or options.perf_upload:
# Write a complete report, formatted as JSON. The Javascript/C code that
# generates the individual reports we are summarizing here is very careful
# to format them nicely, but we just dump out a compressed no-whitespace
# version here for simplicity. Using json.dump(indent=0) doesn't real
# improve the readability of the output much.
report = {
'date': datetime.datetime.utcnow().isoformat() + 'Z',
'events': events,
'monitors': monitors,
'metrics': metric_summaries,
'logs': logs
}
# Add the Git revision if available
self_dir = os.path.dirname(os.path.abspath(sys.argv[0]))
if os.path.exists(os.path.join(self_dir, 'gnome-shell-jhbuild.in')):
top_dir = os.path.dirname(self_dir)
git_dir = os.path.join(top_dir, '.git')
if os.path.exists(git_dir):
env = dict(os.environ)
env['GIT_DIR'] = git_dir
revision = subprocess.Popen(['git', 'rev-parse', 'HEAD'],
env=env,
stdout=subprocess.PIPE).communicate()[0].strip()
report['revision'] = revision
if options.perf_output:
f = open(options.perf_output, 'w')
json.dump(report, f)
f.close()
if options.perf_upload:
upload_performance_report(json.dumps(report))
else:
# Write a human readable summary
print '------------------------------------------------------------';
for metric in sorted(metric_summaries.keys()):
summary = metric_summaries[metric]
print "#", summary['description']
print metric, ", ".join((str(x) for x in summary['values']))
print '------------------------------------------------------------';
return True
# Main program
parser = optparse.OptionParser()
parser.add_option("", "--perf", metavar="PERF_MODULE",
help="Specify the name of a performance module to run")
parser.add_option("", "--perf-iters", type="int", metavar="ITERS",
help="Numbers of iterations of performance module to run",
default=1)
parser.add_option("", "--perf-warmup", action="store_true",
help="Run a dry run before performance tests")
parser.add_option("", "--perf-output", metavar="OUTPUT_FILE",
help="Output file to write performance report")
parser.add_option("", "--perf-upload", action="store_true",
help="Upload performance report to server")
parser.add_option("", "--version", action="callback", callback=show_version,
help="Display version and exit")
options, args = parser.parse_args()
normal_exit = run_performance_test(args)
if normal_exit:
sys.exit(0)
else:
sys.exit(1)

View File

@ -40,9 +40,6 @@
#include "shell-perf-log.h"
#include "shell-wm-private.h"
static void gnome_shell_plugin_dispose (GObject *object);
static void gnome_shell_plugin_finalize (GObject *object);
static void gnome_shell_plugin_start (MetaPlugin *plugin);
static void gnome_shell_plugin_minimize (MetaPlugin *plugin,
MetaWindowActor *actor);
@ -115,12 +112,8 @@ G_DEFINE_TYPE (GnomeShellPlugin, gnome_shell_plugin, META_TYPE_PLUGIN)
static void
gnome_shell_plugin_class_init (GnomeShellPluginClass *klass)
{
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
MetaPluginClass *plugin_class = META_PLUGIN_CLASS (klass);
gobject_class->dispose = gnome_shell_plugin_dispose;
gobject_class->finalize = gnome_shell_plugin_finalize;
plugin_class->start = gnome_shell_plugin_start;
plugin_class->map = gnome_shell_plugin_map;
plugin_class->minimize = gnome_shell_plugin_minimize;
@ -202,18 +195,6 @@ gnome_shell_plugin_start (MetaPlugin *plugin)
}
}
static void
gnome_shell_plugin_dispose (GObject *object)
{
G_OBJECT_CLASS(gnome_shell_plugin_parent_class)->dispose (object);
}
static void
gnome_shell_plugin_finalize (GObject *object)
{
G_OBJECT_CLASS(gnome_shell_plugin_parent_class)->finalize (object);
}
static ShellWM *
get_shell_wm (void)
{

View File

@ -24,9 +24,12 @@
#include "shell-a11y.h"
#include "shell-global.h"
#include "shell-global-private.h"
#include "shell-js.h"
#include "shell-perf-log.h"
#include "st.h"
#include <jsapi.h>
extern GType gnome_shell_plugin_get_type (void);
#define SHELL_DBUS_SERVICE "org.gnome.Shell"
@ -35,6 +38,7 @@ extern GType gnome_shell_plugin_get_type (void);
#define OVERRIDES_SCHEMA "org.gnome.shell.overrides"
static gboolean is_gdm_mode = FALSE;
static char *session_mode = NULL;
#define DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER 1
#define DBUS_REQUEST_NAME_REPLY_ALREADY_OWNER 4
@ -173,6 +177,18 @@ shell_prefs_init (void)
OVERRIDES_SCHEMA);
}
static void
shell_introspection_init (void)
{
g_irepository_prepend_search_path (MUTTER_TYPELIB_DIR);
g_irepository_prepend_search_path (GNOME_SHELL_PKGLIBDIR);
#if HAVE_BLUETOOTH
g_irepository_prepend_search_path (BLUETOOTH_DIR);
#endif
}
static void
malloc_statistics_callback (ShellPerfLog *perf_log,
gpointer data)
@ -238,6 +254,48 @@ default_log_handler (const char *log_domain,
g_log_default_handler (log_domain, log_level, message, data);
}
static void
shut_up (const char *domain,
GLogLevelFlags level,
const char *message,
gpointer user_data)
{
}
static gboolean
list_modes (const char *option_name,
const char *value,
gpointer data,
GError **error)
{
ShellGlobal *global;
GjsContext *context;
const char *script;
int status;
/* Many of our imports require global to be set, so rather than
* tayloring our imports carefully here to avoid that dependency,
* we just set it.
* ShellGlobal has some GTK+ dependencies, so initialize GTK+; we
* don't really care if it fails though (e.g. when running from a tty),
* so we mute all warnings */
g_log_set_default_handler (shut_up, NULL);
gtk_init_check (NULL, NULL);
_shell_global_init (NULL);
global = shell_global_get ();
context = _shell_global_get_gjs_context (global);
shell_introspection_init ();
script = "imports.ui.environment.init();"
"imports.ui.sessionMode.listModes();";
if (!gjs_context_eval (context, script, -1, "<main>", &status, NULL))
g_message ("Retrieving list of available modes failed.");
exit (status);
}
static gboolean
print_version (const gchar *option_name,
const gchar *value,
@ -256,11 +314,23 @@ GOptionEntry gnome_shell_options[] = {
NULL
},
{
"gdm-mode", 0, 0, G_OPTION_ARG_NONE,
"gdm-mode", 0, G_OPTION_FLAG_HIDDEN, G_OPTION_ARG_NONE,
&is_gdm_mode,
N_("Mode used by GDM for login screen"),
NULL
},
{
"mode", 0, 0, G_OPTION_ARG_STRING,
&session_mode,
N_("Use a specific mode, e.g. \"gdm\" for login screen"),
"MODE"
},
{
"list-modes", 0, G_OPTION_FLAG_NO_ARG, G_OPTION_ARG_CALLBACK,
list_modes,
N_("List possible modes"),
NULL
},
{ NULL }
};
@ -269,7 +339,6 @@ main (int argc, char **argv)
{
GOptionContext *ctx;
GError *error = NULL;
ShellSessionType session_type;
int ecode;
TpDebugSender *sender;
@ -308,11 +377,7 @@ main (int argc, char **argv)
shell_a11y_init ();
shell_perf_log_init ();
shell_prefs_init ();
g_irepository_prepend_search_path (GNOME_SHELL_PKGLIBDIR);
#if HAVE_BLUETOOTH
g_irepository_prepend_search_path (BLUETOOTH_DIR);
#endif
shell_introspection_init ();
/* Turn on telepathy-glib debugging but filter it out in
* default_log_handler. This handler also exposes all the logs over D-Bus
@ -323,12 +388,10 @@ main (int argc, char **argv)
g_log_set_default_handler (default_log_handler, sender);
/* Initialize the global object */
if (is_gdm_mode)
session_type = SHELL_SESSION_GDM;
else
session_type = SHELL_SESSION_USER;
if (session_mode == NULL)
session_mode = is_gdm_mode ? "gdm" : "user";
_shell_global_init ("session-type", session_type, NULL);
_shell_global_init ("session-mode", session_mode, NULL);
ecode = meta_run ();
@ -342,3 +405,17 @@ main (int argc, char **argv)
return ecode;
}
/* HACK:
Add a dummy function that calls into libgnome-shell-js.so to ensure it's
linked to /usr/bin/gnome-shell even when linking with --as-needed.
This function is never actually called.
https://bugzilla.gnome.org/show_bug.cgi?id=670477
*/
void _shell_link_to_shell_js (void);
void
_shell_link_to_shell_js (void)
{
shell_js_add_extension_importer (NULL, NULL, NULL, NULL);
}

View File

@ -608,6 +608,42 @@ shell_app_system_lookup_heuristic_basename (ShellAppSystem *system,
return NULL;
}
/**
* shell_app_system_lookup_wmclass:
* @system: a #ShellAppSystem
* @wmclass: A WM_CLASS value
*
* Find a valid application corresponding to a WM_CLASS value.
*
* Returns: (transfer none): A #ShellApp for @wmclass
*/
ShellApp *
shell_app_system_lookup_wmclass (ShellAppSystem *system,
const char *wmclass)
{
char *canonicalized;
char *desktop_file;
ShellApp *app;
if (wmclass == NULL)
return NULL;
canonicalized = g_ascii_strdown (wmclass, -1);
/* This handles "Fedora Eclipse", probably others.
* Note g_strdelimit is modify-in-place. */
g_strdelimit (canonicalized, " ", '-');
desktop_file = g_strconcat (canonicalized, ".desktop", NULL);
app = shell_app_system_lookup_heuristic_basename (system, desktop_file);
g_free (canonicalized);
g_free (desktop_file);
return app;
}
/**
* shell_app_system_get_all:
* @system:

View File

@ -49,7 +49,8 @@ ShellApp *shell_app_system_lookup_app_for_path (ShellAppSystem *
const char *desktop_path);
ShellApp *shell_app_system_lookup_heuristic_basename (ShellAppSystem *system,
const char *id);
ShellApp *shell_app_system_lookup_wmclass (ShellAppSystem *system,
const char *wmclass);
GSList *shell_app_system_get_all (ShellAppSystem *system);

View File

@ -371,7 +371,7 @@ shell_app_get_name (ShellApp *app)
name = meta_window_get_wm_class (window);
if (!name)
name = _("Unknown");
name = C_("program", "Unknown");
return name;
}
}
@ -493,7 +493,7 @@ shell_app_activate_window (ShellApp *app,
return;
else
{
GSList *iter;
GSList *windows_reversed, *iter;
ShellGlobal *global = shell_global_get ();
MetaScreen *screen = shell_global_get_screen (global);
MetaDisplay *display = meta_screen_get_display (screen);
@ -511,13 +511,16 @@ shell_app_activate_window (ShellApp *app,
/* Now raise all the other windows for the app that are on
* the same workspace, in reverse order to preserve the stacking.
*/
for (iter = windows; iter; iter = iter->next)
windows_reversed = g_slist_copy (windows);
windows_reversed = g_slist_reverse (windows_reversed);
for (iter = windows_reversed; iter; iter = iter->next)
{
MetaWindow *other_window = iter->data;
if (other_window != window)
meta_window_raise (other_window);
}
g_slist_free (windows_reversed);
/* If we have a transient that the user's interacted with more recently than
* the window, pick that.

View File

@ -16,7 +16,4 @@ GjsContext *_shell_global_get_gjs_context (ShellGlobal *global);
gboolean _shell_global_check_xdnd_event (ShellGlobal *global,
XEvent *xev);
void _shell_global_set_session_type (ShellGlobal *global,
ShellSessionType session_type);
#endif /* __SHELL_GLOBAL_PRIVATE_H__ */

View File

@ -59,7 +59,7 @@ struct _ShellGlobal {
MetaScreen *meta_screen;
GdkScreen *gdk_screen;
ShellSessionType session_type;
char *session_mode;
/* We use this window to get a notification from GTK+ when
* a widget in our process does a GTK+ grab. See
@ -97,7 +97,7 @@ struct _ShellGlobal {
enum {
PROP_0,
PROP_SESSION_TYPE,
PROP_SESSION_MODE,
PROP_OVERLAY_GROUP,
PROP_SCREEN,
PROP_GDK_SCREEN,
@ -143,8 +143,9 @@ shell_global_set_property(GObject *object,
case PROP_STAGE_INPUT_MODE:
shell_global_set_stage_input_mode (global, g_value_get_enum (value));
break;
case PROP_SESSION_TYPE:
global->session_type = g_value_get_enum (value);
case PROP_SESSION_MODE:
g_clear_pointer (&global->session_mode, g_free);
global->session_mode = g_ascii_strdown (g_value_get_string (value), -1);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
@ -162,8 +163,8 @@ shell_global_get_property(GObject *object,
switch (prop_id)
{
case PROP_SESSION_TYPE:
g_value_set_enum (value, shell_global_get_session_type (global));
case PROP_SESSION_MODE:
g_value_set_string (value, shell_global_get_session_mode (global));
break;
case PROP_OVERLAY_GROUP:
g_value_set_object (value, meta_get_overlay_group_for_screen (global->meta_screen));
@ -343,13 +344,12 @@ shell_global_class_init (ShellGlobalClass *klass)
G_TYPE_STRING);
g_object_class_install_property (gobject_class,
PROP_SESSION_TYPE,
g_param_spec_enum ("session-type",
"Session Type",
"The type of session",
SHELL_TYPE_SESSION_TYPE,
SHELL_SESSION_USER,
G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
PROP_SESSION_MODE,
g_param_spec_string ("session-mode",
"Session Mode",
"The session mode to use",
"user",
G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
g_object_class_install_property (gobject_class,
PROP_OVERLAY_GROUP,
g_param_spec_object ("overlay-group",
@ -805,90 +805,9 @@ global_stage_after_paint (ClutterStage *stage,
"clutter.stagePaintDone");
}
static void
update_font_options (GtkSettings *settings,
ClutterStage *stage)
{
StThemeContext *context;
ClutterBackend *backend;
gint dpi;
gint hinting;
gchar *hint_style_str;
cairo_hint_style_t hint_style = CAIRO_HINT_STYLE_NONE;
gint antialias;
cairo_antialias_t antialias_mode = CAIRO_ANTIALIAS_NONE;
cairo_font_options_t *options;
g_object_get (settings,
"gtk-xft-dpi", &dpi,
"gtk-xft-antialias", &antialias,
"gtk-xft-hinting", &hinting,
"gtk-xft-hintstyle", &hint_style_str,
NULL);
context = st_theme_context_get_for_stage (stage);
if (dpi != -1)
/* GTK stores resolution as 1024 * dots/inch */
st_theme_context_set_resolution (context, dpi / 1024);
else
st_theme_context_set_default_resolution (context);
/* Clutter (as of 0.9) passes comprehensively wrong font options
* override whatever set_font_flags() did above.
*
* http://bugzilla.openedhand.com/show_bug.cgi?id=1456
*/
backend = clutter_get_default_backend ();
options = cairo_font_options_create ();
cairo_font_options_set_hint_metrics (options, CAIRO_HINT_METRICS_ON);
if (hinting >= 0 && !hinting)
{
hint_style = CAIRO_HINT_STYLE_NONE;
}
else if (hint_style_str)
{
if (strcmp (hint_style_str, "hintnone") == 0)
hint_style = CAIRO_HINT_STYLE_NONE;
else if (strcmp (hint_style_str, "hintslight") == 0)
hint_style = CAIRO_HINT_STYLE_SLIGHT;
else if (strcmp (hint_style_str, "hintmedium") == 0)
hint_style = CAIRO_HINT_STYLE_MEDIUM;
else if (strcmp (hint_style_str, "hintfull") == 0)
hint_style = CAIRO_HINT_STYLE_FULL;
}
g_free (hint_style_str);
cairo_font_options_set_hint_style (options, hint_style);
/* We don't want to turn on subpixel anti-aliasing; since Clutter
* doesn't currently have the code to support ARGB masks,
* generating them then squashing them back to A8 is pointless.
*/
antialias_mode = (antialias < 0 || antialias) ? CAIRO_ANTIALIAS_GRAY
: CAIRO_ANTIALIAS_NONE;
cairo_font_options_set_antialias (options, antialias_mode);
clutter_backend_set_font_options (backend, options);
cairo_font_options_destroy (options);
}
static void
settings_notify_cb (GtkSettings *settings,
GParamSpec *pspec,
gpointer data)
{
update_font_options (settings, CLUTTER_STAGE (data));
}
static void
shell_fonts_init (ClutterStage *stage)
{
GtkSettings *settings;
CoglPangoFontMap *fontmap;
/* Disable text mipmapping; it causes problems on pre-GEM Intel
@ -898,19 +817,6 @@ shell_fonts_init (ClutterStage *stage)
*/
fontmap = COGL_PANGO_FONT_MAP (clutter_get_font_map ());
cogl_pango_font_map_set_use_mipmapping (fontmap, FALSE);
settings = gtk_settings_get_default ();
g_object_connect (settings,
"signal::notify::gtk-xft-dpi",
G_CALLBACK (settings_notify_cb), stage,
"signal::notify::gtk-xft-antialias",
G_CALLBACK (settings_notify_cb), stage,
"signal::notify::gtk-xft-hinting",
G_CALLBACK (settings_notify_cb), stage,
"signal::notify::gtk-xft-hintstyle",
G_CALLBACK (settings_notify_cb), stage,
NULL);
update_font_options (settings, stage);
}
/* This is an IBus workaround. The flow of events with IBus is that every time
@ -1870,31 +1776,10 @@ shell_global_launch_calendar_server (ShellGlobal *global)
g_free (calendar_server_exe);
}
/**
* shell_global_get_session_type:
* @global: The #ShellGlobal.
*
* Gets the type of session gnome-shell provides.
*
* The type determines what UI elements are displayed,
* what keybindings work, and generally how the shell
* behaves.
*
* A session type of #SHELL_SESSION_USER means gnome-shell
* will enable the activities overview, status menu, run dialog,
* etc. This is the default.
*
* A session type of #SHELL_SESSION_GDM means gnome-shell
* will enable a login dialog and run in a more confined
* way. This type is suitable for the display manager.
*
* Returns: the type of session gnome-shell is providing.
*/
ShellSessionType
shell_global_get_session_type (ShellGlobal *global)
const char *
shell_global_get_session_mode (ShellGlobal *global)
{
g_return_val_if_fail (SHELL_IS_GLOBAL (global),
SHELL_SESSION_USER);
g_return_val_if_fail (SHELL_IS_GLOBAL (global), "user");
return global->session_type;
return global->session_mode;
}

View File

@ -141,12 +141,7 @@ void shell_global_reexec_self (ShellGlobal *global);
void shell_global_launch_calendar_server (ShellGlobal *global);
typedef enum {
SHELL_SESSION_USER,
SHELL_SESSION_GDM
} ShellSessionType;
ShellSessionType shell_global_get_session_type (ShellGlobal *global);
const char * shell_global_get_session_mode (ShellGlobal *global);
G_END_DECLS

View File

@ -0,0 +1,214 @@
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
/*
* Copyright (C) 2010-2012 Inclusive Design Research Centre, OCAD University.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
*
* Author:
* Joseph Scheuhammer <clown@alum.mit.edu>
*/
/**
* SECTION:shell-invert-lightness-effect
* @short_description: A colorization effect where lightness is inverted but
* color is not.
* @see_also: #ClutterEffect, #ClutterOffscreenEffect
*
* #ShellInvertLightnessEffect is a sub-class of #ClutterEffect that enhances
* the appearance of a clutter actor. Specifically it inverts the lightness
* of a #ClutterActor (e.g., darker colors become lighter, white becomes black,
* and white, black).
*/
#define SHELL_INVERT_LIGHTNESS_EFFECT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), SHELL_TYPE_INVERT_LIGHTNESS_EFFECT, ShellInvertLightnessEffectClass))
#define SHELL_IS_INVERT_EFFECT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), SHELL_TYPE_INVERT_LIGHTNESS_EFFECT))
#define SHELL_INVERT_LIGHTNESS_EFFECT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), SHELL_TYPE_INVERT_LIGHTNESS_EFFEC, ShellInvertLightnessEffectClass))
#define CLUTTER_ENABLE_EXPERIMENTAL_API
#include "shell-invert-lightness-effect.h"
#include <cogl/cogl.h>
struct _ShellInvertLightnessEffect
{
ClutterOffscreenEffect parent_instance;
gint tex_width;
gint tex_height;
CoglPipeline *pipeline;
};
struct _ShellInvertLightnessEffectClass
{
ClutterOffscreenEffectClass parent_class;
CoglPipeline *base_pipeline;
};
/* Lightness inversion in GLSL.
*/
static const gchar *invert_lightness_source =
"cogl_texel = texture2D (cogl_sampler, cogl_tex_coord.st);\n"
"vec3 effect = vec3 (cogl_texel);\n"
"\n"
"float maxColor = max (cogl_texel.r, max (cogl_texel.g, cogl_texel.b));\n"
"float minColor = min (cogl_texel.r, min (cogl_texel.g, cogl_texel.b));\n"
"float lightness = (maxColor + minColor) / 2.0;\n"
"\n"
"float delta = (1.0 - lightness) - lightness;\n"
"effect.rgb = (effect.rgb + delta);\n"
"\n"
"cogl_texel = vec4 (effect, cogl_texel.a);\n";
G_DEFINE_TYPE (ShellInvertLightnessEffect,
shell_invert_lightness_effect,
CLUTTER_TYPE_OFFSCREEN_EFFECT);
static gboolean
shell_invert_lightness_effect_pre_paint (ClutterEffect *effect)
{
ShellInvertLightnessEffect *self = SHELL_INVERT_LIGHTNESS_EFFECT (effect);
ClutterEffectClass *parent_class;
if (!clutter_actor_meta_get_enabled (CLUTTER_ACTOR_META (effect)))
return FALSE;
if (!clutter_feature_available (CLUTTER_FEATURE_SHADERS_GLSL))
{
/* if we don't have support for GLSL shaders then we
* forcibly disable the ActorMeta
*/
g_warning ("Unable to use the ShellInvertLightnessEffect: the "
"graphics hardware or the current GL driver does not "
"implement support for the GLSL shading language.");
clutter_actor_meta_set_enabled (CLUTTER_ACTOR_META (self), FALSE);
return FALSE;
}
parent_class =
CLUTTER_EFFECT_CLASS (shell_invert_lightness_effect_parent_class);
if (parent_class->pre_paint (effect))
{
ClutterOffscreenEffect *offscreen_effect =
CLUTTER_OFFSCREEN_EFFECT (effect);
CoglHandle texture;
texture = clutter_offscreen_effect_get_texture (offscreen_effect);
self->tex_width = cogl_texture_get_width (texture);
self->tex_height = cogl_texture_get_height (texture);
cogl_pipeline_set_layer_texture (self->pipeline, 0, texture);
return TRUE;
}
else
return FALSE;
}
static void
shell_invert_lightness_effect_paint_target (ClutterOffscreenEffect *effect)
{
ShellInvertLightnessEffect *self = SHELL_INVERT_LIGHTNESS_EFFECT (effect);
ClutterActor *actor;
guint8 paint_opacity;
actor = clutter_actor_meta_get_actor (CLUTTER_ACTOR_META (effect));
paint_opacity = clutter_actor_get_paint_opacity (actor);
cogl_pipeline_set_color4ub (self->pipeline,
paint_opacity,
paint_opacity,
paint_opacity,
paint_opacity);
cogl_push_source (self->pipeline);
cogl_rectangle (0, 0, self->tex_width, self->tex_height);
cogl_pop_source ();
}
static void
shell_invert_lightness_effect_dispose (GObject *gobject)
{
ShellInvertLightnessEffect *self = SHELL_INVERT_LIGHTNESS_EFFECT (gobject);
if (self->pipeline != NULL)
{
cogl_object_unref (self->pipeline);
self->pipeline = NULL;
}
G_OBJECT_CLASS (shell_invert_lightness_effect_parent_class)->dispose (gobject);
}
static void
shell_invert_lightness_effect_class_init (ShellInvertLightnessEffectClass *klass)
{
ClutterEffectClass *effect_class = CLUTTER_EFFECT_CLASS (klass);
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
ClutterOffscreenEffectClass *offscreen_class;
offscreen_class = CLUTTER_OFFSCREEN_EFFECT_CLASS (klass);
offscreen_class->paint_target = shell_invert_lightness_effect_paint_target;
effect_class->pre_paint = shell_invert_lightness_effect_pre_paint;
gobject_class->dispose = shell_invert_lightness_effect_dispose;
}
static void
shell_invert_lightness_effect_init (ShellInvertLightnessEffect *self)
{
ShellInvertLightnessEffectClass *klass;
klass = SHELL_INVERT_LIGHTNESS_EFFECT_GET_CLASS (self);
if (G_UNLIKELY (klass->base_pipeline == NULL))
{
CoglSnippet *snippet;
CoglContext *ctx =
clutter_backend_get_cogl_context (clutter_get_default_backend ());
klass->base_pipeline = cogl_pipeline_new (ctx);
snippet = cogl_snippet_new (COGL_SNIPPET_HOOK_TEXTURE_LOOKUP,
NULL,
NULL);
cogl_snippet_set_replace (snippet, invert_lightness_source);
cogl_pipeline_add_layer_snippet (klass->base_pipeline, 0, snippet);
cogl_object_unref (snippet);
cogl_pipeline_set_layer_null_texture (klass->base_pipeline,
0, /* layer number */
COGL_TEXTURE_TYPE_2D);
}
self->pipeline = cogl_pipeline_copy (klass->base_pipeline);
}
/**
* shell_invert_lightness_effect_new:
*
* Creates a new #ShellInvertLightnessEffect to be used with
* clutter_actor_add_effect()
*
* Return value: (transfer full): the newly created
* #ShellInvertLightnessEffect or %NULL. Use g_object_unref() when done.
*/
ClutterEffect *
shell_invert_lightness_effect_new (void)
{
return g_object_new (SHELL_TYPE_INVERT_LIGHTNESS_EFFECT, NULL);
}

View File

@ -0,0 +1,42 @@
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
/*
* Copyright © 2010-2012 Inclusive Design Research Centre, OCAD University.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
*
* Author:
* Joseph Scheuhammer <clown@alum.mit.edu>
*/
#ifndef __SHELL_INVERT_LIGHTNESS_EFFECT_H__
#define __SHELL_INVERT_LIGHTNESS_EFFECT_H__
#define COGL_ENABLE_EXPERIMENTAL_API
#include <clutter/clutter.h>
G_BEGIN_DECLS
#define SHELL_TYPE_INVERT_LIGHTNESS_EFFECT (shell_invert_lightness_effect_get_type ())
#define SHELL_INVERT_LIGHTNESS_EFFECT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), SHELL_TYPE_INVERT_LIGHTNESS_EFFECT, ShellInvertLightnessEffect))
#define SHELL_IS_INVERT_LIGHTNESS_EFFECT(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SHELL_TYPE_INVERT_LIGHTNESS_EFFECT))
typedef struct _ShellInvertLightnessEffect ShellInvertLightnessEffect;
typedef struct _ShellInvertLightnessEffectClass ShellInvertLightnessEffectClass;
GType shell_invert_lightness_effect_get_type (void) G_GNUC_CONST;
ClutterEffect *shell_invert_lightness_effect_new (void);
G_END_DECLS
#endif /* __SHELL_INVERT_LIGHTNESS_EFFECT_H__ */

View File

@ -79,15 +79,3 @@ shell_js_add_extension_importer (const char *target_object_script,
JS_EndRequest (context);
return ret;
}
/**
* shell_js_format_int_alternative_output:
* @intval:
*
* Returns: (transfer full):
*/
gchar *
shell_js_format_int_alternative_output (gint intval)
{
return g_strdup_printf ("%Id", intval);
}

View File

@ -11,8 +11,6 @@ gboolean shell_js_add_extension_importer (const char *target_object_script,
const char *directory,
GError **error);
gchar *shell_js_format_int_alternative_output (gint intval);
G_BEGIN_DECLS
#endif /* __SHELL_JS_H__ */

View File

@ -76,6 +76,26 @@ shell_agent_request_free (gpointer data)
g_slice_free (ShellAgentRequest, request);
}
static void
shell_agent_request_cancel (ShellAgentRequest *request)
{
GError *error;
ShellNetworkAgent *self;
self = request->self;
error = g_error_new (NM_SECRET_AGENT_ERROR,
NM_SECRET_AGENT_ERROR_AGENT_CANCELED,
"Canceled by NetworkManager");
request->callback (NM_SECRET_AGENT (self), request->connection,
NULL, error, request->callback_data);
g_signal_emit (self, signals[SIGNAL_CANCEL_REQUEST], 0, request->request_id);
g_hash_table_remove (self->priv->requests, request->request_id);
g_error_free (error);
}
static void
shell_network_agent_init (ShellNetworkAgent *agent)
{
@ -341,6 +361,17 @@ shell_network_agent_get_secrets (NMSecretAgent *agent,
ShellAgentRequest *request;
NMSettingConnection *setting_connection;
const char *connection_type;
char *request_id;
request_id = g_strdup_printf ("%s/%s", connection_path, setting_name);
if ((request = g_hash_table_lookup (self->priv->requests, request_id)) != NULL)
{
/* We already have a request pending for this (connection, setting)
* Cancel it before starting the new one.
* This will also free the request structure and associated resources.
*/
shell_agent_request_cancel (request);
}
setting_connection = nm_connection_get_setting_connection (connection);
connection_type = nm_setting_connection_get_connection_type (setting_connection);
@ -371,7 +402,7 @@ shell_network_agent_get_secrets (NMSecretAgent *agent,
else
request->vpn_entries = NULL;
request->request_id = g_strdup_printf ("%s/%s", connection_path, setting_name);
request->request_id = request_id;
g_hash_table_replace (self->priv->requests, request->request_id, request);
if ((flags & NM_SECRET_AGENT_GET_SECRETS_FLAG_REQUEST_NEW) ||
@ -409,6 +440,7 @@ shell_network_agent_set_password (ShellNetworkAgent *self,
priv = self->priv;
request = g_hash_table_lookup (priv->requests, request_id);
g_return_if_fail (request != NULL);
if (!request->is_vpn)
{
@ -438,6 +470,7 @@ shell_network_agent_respond (ShellNetworkAgent *self,
priv = self->priv;
request = g_hash_table_lookup (priv->requests, request_id);
g_return_if_fail (request != NULL);
if (response == SHELL_NETWORK_AGENT_USER_CANCELED)
{
@ -488,20 +521,22 @@ shell_network_agent_cancel_get_secrets (NMSecretAgent *agent,
{
ShellNetworkAgent *self = SHELL_NETWORK_AGENT (agent);
ShellNetworkAgentPrivate *priv = self->priv;
gchar *request_id;
ShellAgentRequest *request;
gchar *request_id = g_strdup_printf ("%s/%s", connection_path, setting_name);
ShellAgentRequest *request = g_hash_table_lookup (priv->requests, request_id);
GError *error = g_error_new (NM_SECRET_AGENT_ERROR,
NM_SECRET_AGENT_ERROR_AGENT_CANCELED,
"Canceled by NetworkManager");
request->callback (agent, request->connection, NULL, error, request->callback_data);
g_signal_emit (self, signals[SIGNAL_CANCEL_REQUEST], 0, request_id);
g_hash_table_remove (priv->requests, request_id);
request_id = g_strdup_printf ("%s/%s", connection_path, setting_name);
request = g_hash_table_lookup (priv->requests, request_id);
g_free (request_id);
g_error_free (error);
if (!request)
{
/* We've already sent the result, but the caller cancelled the
* operation before receiving that result.
*/
return;
}
shell_agent_request_cancel (request);
}
/************************* saving of secrets ****************************************/

View File

@ -330,34 +330,6 @@ shell_tp_client_grab_contact_list_changed (ShellTpClient *self,
/* Telepathy utility functions */
/**
* shell_get_contact_events:
* @log_manager: A #TplLogManager
* @account: A #TpAccount
* @entity: A #TplEntity
* @num_events: The number of events to retrieve
* @callback: (scope async): User callback to run when the contact is ready
*
* Wrap tpl_log_manager_get_filtered_events_async because gjs cannot support
* multiple callbacks in the same function call.
*/
void
shell_get_contact_events (TplLogManager *log_manager,
TpAccount *account,
TplEntity *entity,
guint num_events,
GAsyncReadyCallback callback)
{
tpl_log_manager_get_filtered_events_async (log_manager,
account,
entity,
TPL_EVENT_MASK_TEXT,
num_events,
NULL, NULL,
callback, NULL);
}
/* gjs doesn't allow us to craft a GError so we need a C wrapper */
void
shell_decline_dispatch_op (TpAddDispatchOperationContext *context,

View File

@ -7,7 +7,6 @@
#include <glib-object.h>
#include <telepathy-glib/telepathy-glib.h>
#include <telepathy-logger/telepathy-logger.h>
G_BEGIN_DECLS
@ -103,12 +102,6 @@ void shell_tp_client_grab_contact_list_changed (ShellTpClient *self,
/* Telepathy utility functions */
void shell_get_contact_events (TplLogManager *log_manager,
TpAccount *account,
TplEntity *entity,
guint num_events,
GAsyncReadyCallback callback);
void shell_decline_dispatch_op (TpAddDispatchOperationContext *context,
const gchar *message);

View File

@ -592,29 +592,6 @@ shell_util_get_week_start ()
return week_start;
}
/**
* shell_write_soup_message_to_stream:
* @stream: a #GOutputStream
* @message: a #SoupMessage
* @error: location to store GError
*
* Write a string to a GOutputStream as binary data. This is a
* workaround for the lack of proper binary strings in GJS.
*/
void
shell_write_soup_message_to_stream (GOutputStream *stream,
SoupMessage *message,
GError **error)
{
SoupMessageBody *body;
body = message->response_body;
g_output_stream_write_all (stream,
body->data, body->length,
NULL, NULL, error);
}
/**
* shell_write_string_to_stream:
* @stream: a #GOutputStream

View File

@ -25,10 +25,6 @@ char *shell_util_normalize_and_casefold (const char *str);
char *shell_util_format_date (const char *format,
gint64 time_ms);
void shell_write_soup_message_to_stream (GOutputStream *stream,
SoupMessage *message,
GError **error);
gboolean shell_write_string_to_stream (GOutputStream *stream,
const char *str,
GError **error);

View File

@ -126,30 +126,6 @@ shell_window_tracker_class_init (ShellWindowTrackerClass *klass)
G_TYPE_NONE, 0);
}
/**
* get_appid_from_window:
*
* Turn the WM_CLASS property into our best guess at a .desktop file id.
*/
static char *
get_appid_from_window (MetaWindow *window)
{
const char *wmclass;
char *appid_guess;
wmclass = meta_window_get_wm_class (window);
if (!wmclass)
return NULL;
appid_guess = g_ascii_strdown (wmclass, -1);
/* This handles "Fedora Eclipse", probably others.
* Note g_strdelimit is modify-in-place. */
g_strdelimit (appid_guess, " ", '-');
return appid_guess;
}
/**
* shell_window_tracker_is_window_interesting:
*
@ -201,40 +177,6 @@ shell_window_tracker_is_window_interesting (MetaWindow *window)
return TRUE;
}
/**
* get_app_from_window_wmclass:
*
* Looks only at the given window, and attempts to determine
* an application based on WM_CLASS. If one can't be determined,
* return %NULL.
*
* Return value: (transfer full): A newly-referenced #ShellApp, or %NULL
*/
static ShellApp *
get_app_from_window_wmclass (MetaWindow *window)
{
ShellApp *app;
ShellAppSystem *appsys;
char *wmclass;
char *with_desktop;
appsys = shell_app_system_get_default ();
wmclass = get_appid_from_window (window);
if (!wmclass)
return NULL;
with_desktop = g_strjoin (NULL, wmclass, ".desktop", NULL);
g_free (wmclass);
app = shell_app_system_lookup_heuristic_basename (appsys, with_desktop);
if (app != NULL)
g_object_ref (app);
g_free (with_desktop);
return app;
}
/**
* get_app_from_window_group:
* @monitor: a #ShellWindowTracker
@ -328,9 +270,12 @@ static ShellApp *
get_app_for_window (ShellWindowTracker *tracker,
MetaWindow *window)
{
ShellAppSystem *app_system;
ShellApp *result = NULL;
const char *startup_id;
app_system = shell_app_system_get_default ();
/* First, we check whether we already know about this window,
* if so, just return that.
*/
@ -351,7 +296,8 @@ get_app_for_window (ShellWindowTracker *tracker,
/* Check if the app's WM_CLASS specifies an app; this is
* canonical if it does.
*/
result = get_app_from_window_wmclass (window);
result = shell_app_system_lookup_wmclass (app_system,
meta_window_get_wm_class (window));
if (result != NULL)
return result;

View File

@ -85,23 +85,11 @@ st_bin_remove (ClutterContainer *container,
st_bin_set_child (ST_BIN (container), NULL);
}
static void
st_bin_foreach (ClutterContainer *container,
ClutterCallback callback,
gpointer user_data)
{
StBinPrivate *priv = ST_BIN (container)->priv;
if (priv->child)
callback (priv->child, user_data);
}
static void
clutter_container_iface_init (ClutterContainerIface *iface)
{
iface->add = st_bin_add;
iface->remove = st_bin_remove;
iface->foreach = st_bin_foreach;
}
static void

View File

@ -490,7 +490,7 @@ st_label_accessible_get_name (AtkObject *obj)
actor = CLUTTER_ACTOR (atk_gobject_accessible_get_object (ATK_GOBJECT_ACCESSIBLE (obj)));
if (actor == NULL) /* State is defunct */
if (actor == NULL || st_widget_has_style_class_name (ST_WIDGET (actor), "hidden"))
name = NULL;
else
name = st_label_get_text (ST_LABEL (actor));

View File

@ -444,14 +444,12 @@ st_scroll_bar_scroll_event (ClutterActor *actor,
ClutterScrollEvent *event)
{
StScrollBarPrivate *priv = ST_SCROLL_BAR (actor)->priv;
gdouble lower, step, upper, value, delta_x, delta_y;
gdouble step, value, delta_x, delta_y;
if (priv->adjustment)
{
g_object_get (priv->adjustment,
"lower", &lower,
"step-increment", &step,
"upper", &upper,
"value", &value,
NULL);
}
@ -472,17 +470,11 @@ st_scroll_bar_scroll_event (ClutterActor *actor,
break;
case CLUTTER_SCROLL_UP:
case CLUTTER_SCROLL_LEFT:
if (value == lower)
return FALSE;
else
st_adjustment_set_value (priv->adjustment, value - step);
st_adjustment_set_value (priv->adjustment, value - step);
break;
case CLUTTER_SCROLL_DOWN:
case CLUTTER_SCROLL_RIGHT:
if (value == upper)
return FALSE;
else
st_adjustment_set_value (priv->adjustment, value + step);
st_adjustment_set_value (priv->adjustment, value + step);
break;
}

View File

@ -687,7 +687,7 @@ st_scroll_view_scroll_event (ClutterActor *self,
ClutterScrollEvent *event)
{
StScrollViewPrivate *priv = ST_SCROLL_VIEW (self)->priv;
gdouble lower, value, upper, step, hvalue, vvalue, delta_x, delta_y;
gdouble value, step, hvalue, vvalue, delta_x, delta_y;
/* don't handle scroll events if requested not to */
if (!priv->mouse_scroll)
@ -708,19 +708,15 @@ st_scroll_view_scroll_event (ClutterActor *self,
case CLUTTER_SCROLL_UP:
case CLUTTER_SCROLL_DOWN:
g_object_get (priv->vadjustment,
"lower", &lower,
"step-increment", &step,
"value", &value,
"upper", &upper,
NULL);
break;
case CLUTTER_SCROLL_LEFT:
case CLUTTER_SCROLL_RIGHT:
g_object_get (priv->hadjustment,
"lower", &lower,
"step-increment", &step,
"value", &value,
"upper", &upper,
NULL);
break;
}
@ -732,28 +728,16 @@ st_scroll_view_scroll_event (ClutterActor *self,
st_adjustment_set_value (priv->vadjustment, vvalue + delta_y);
break;
case CLUTTER_SCROLL_UP:
if (value == lower)
return FALSE;
else
st_adjustment_set_value (priv->vadjustment, value - step);
st_adjustment_set_value (priv->vadjustment, value - step);
break;
case CLUTTER_SCROLL_DOWN:
if (value == upper)
return FALSE;
else
st_adjustment_set_value (priv->vadjustment, value + step);
st_adjustment_set_value (priv->vadjustment, value + step);
break;
case CLUTTER_SCROLL_LEFT:
if (value == lower)
return FALSE;
else
st_adjustment_set_value (priv->hadjustment, value - step);
st_adjustment_set_value (priv->hadjustment, value - step);
break;
case CLUTTER_SCROLL_RIGHT:
if (value == upper)
return FALSE;
else
st_adjustment_set_value (priv->hadjustment, value + step);
st_adjustment_set_value (priv->hadjustment, value + step);
break;
}

View File

@ -28,7 +28,6 @@
struct _StThemeContext {
GObject parent;
double resolution;
PangoFontDescription *font;
StThemeNode *root_node;
StTheme *theme;
@ -38,7 +37,6 @@ struct _StThemeContextClass {
GObjectClass parent_class;
};
#define DEFAULT_RESOLUTION 96.
#define DEFAULT_FONT "sans-serif 10"
enum
@ -93,7 +91,6 @@ st_theme_context_class_init (StThemeContextClass *klass)
static void
st_theme_context_init (StThemeContext *context)
{
context->resolution = DEFAULT_RESOLUTION;
context->font = pango_font_description_from_string (DEFAULT_FONT);
g_signal_connect (st_texture_cache_get_default (),
@ -232,66 +229,6 @@ st_theme_context_get_theme (StThemeContext *context)
return context->theme;
}
/**
* st_theme_context_set_resolution:
* @context: a #StThemeContext
* @resolution: resolution of the context (number of pixels in an "inch")
*
* Sets the resolution of the theme context. This is the scale factor
* used to convert between points and the length units pt, in, and cm.
* This does not necessarily need to correspond to the actual number
* resolution of the device. A value of 72. means that points and
* pixels are identical. The default value is 96.
*/
void
st_theme_context_set_resolution (StThemeContext *context,
double resolution)
{
g_return_if_fail (ST_IS_THEME_CONTEXT (context));
if (resolution == context->resolution)
return;
context->resolution = resolution;
st_theme_context_changed (context);
}
/**
* st_theme_context_set_default_resolution:
* @context: a #StThemeContext
*
* Sets the resolution of the theme context to the default value of 96.
* See st_theme_context_set_resolution().
*/
void
st_theme_context_set_default_resolution (StThemeContext *context)
{
g_return_if_fail (ST_IS_THEME_CONTEXT (context));
if (context->resolution == DEFAULT_RESOLUTION)
return;
context->resolution = DEFAULT_RESOLUTION;
st_theme_context_changed (context);
}
/**
* st_theme_context_get_resolution:
* @context: a #StThemeContext
*
* Gets the current resolution of the theme context.
* See st_theme_context_set_resolution().
*
* Return value: the resolution (in dots-per-"inch")
*/
double
st_theme_context_get_resolution (StThemeContext *context)
{
g_return_val_if_fail (ST_IS_THEME_CONTEXT (context), DEFAULT_RESOLUTION);
return context->resolution;
}
/**
* st_theme_context_set_font:
* @context: a #StThemeContext

View File

@ -56,10 +56,6 @@ void st_theme_context_set_theme (StThemeContext
StTheme *theme);
StTheme * st_theme_context_get_theme (StThemeContext *context);
void st_theme_context_set_resolution (StThemeContext *context,
gdouble resolution);
void st_theme_context_set_default_resolution (StThemeContext *context);
double st_theme_context_get_resolution (StThemeContext *context);
void st_theme_context_set_font (StThemeContext *context,
const PangoFontDescription *font);
const PangoFontDescription *st_theme_context_get_font (StThemeContext *context);

View File

@ -1782,7 +1782,7 @@ st_theme_node_paint_sliced_border_image (StThemeNode *node,
cogl_set_source (material);
{
GLfloat rectangles[] =
float rectangles[] =
{
/* top left corner */
0, 0, border_left, border_top,

View File

@ -820,7 +820,7 @@ get_length_from_term (StThemeNode *node,
break;
case POINTS:
{
double resolution = st_theme_context_get_resolution (node->context);
double resolution = clutter_backend_get_resolution (clutter_get_default_backend ());
*length = num->val * multiplier * (resolution / 72.);
}
break;
@ -842,7 +842,7 @@ get_length_from_term (StThemeNode *node,
}
else
{
double resolution = st_theme_context_get_resolution (node->context);
double resolution = clutter_backend_get_resolution (clutter_get_default_backend ());
*length = num->val * multiplier * (resolution / 72.) * font_size;
}
}
@ -2139,7 +2139,7 @@ font_size_from_term (StThemeNode *node,
{
if (term->type == TERM_IDENT)
{
double resolution = st_theme_context_get_resolution (node->context);
double resolution = clutter_backend_get_resolution (clutter_get_default_backend ());
/* We work in integers to avoid double comparisons when converting back
* from a size in pixels to a logical size.
*/
@ -2346,7 +2346,7 @@ st_theme_node_get_font (StThemeNode *node)
parent_size = pango_font_description_get_size (node->font_desc);
if (!pango_font_description_get_size_is_absolute (node->font_desc))
{
double resolution = st_theme_context_get_resolution (node->context);
double resolution = clutter_backend_get_resolution (clutter_get_default_backend ());
parent_size *= (resolution / 72.);
}

View File

@ -435,7 +435,6 @@ main (int argc, char **argv)
stage = clutter_stage_new ();
context = st_theme_context_get_for_stage (CLUTTER_STAGE (stage));
st_theme_context_set_theme (context, theme);
st_theme_context_set_resolution (context, 96.);
st_theme_context_set_font (context,
pango_font_description_from_string ("sans-serif 12"));

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