Compare commits

...

189 Commits

Author SHA1 Message Date
b18cc8de86 Bump version to 3.3.90
Update NEWS
2012-02-22 22:30:47 -05:00
30e4f80894 Fix generation of config.js
* Create the misc/ subdir of the build dir if it doesn't exist
* Add config.js to CLEANFILES
2012-02-22 22:30:47 -05:00
dd8a53d5e0 Revert "Fixed typo in string"
This reverts commit 44e02003ad.

The change:

 "GNOME Shell Extension Preferences" to "GNOME Shell Extensions Preferences"

was incorrect.
2012-02-22 18:52:08 -05:00
0f01928402 Revert "Fixed typo in string"
This reverts commit e8bfd990e4.

The change:

 "GNOME Shell Extension Preferences" to "GNOME Shell Extensions Preferences"

was incorrect.
2012-02-22 18:50:36 -05:00
a8b081661c st-box-layout: Remove insert_actor/insert_before
Now that 'insert_child_at_index' and 'insert_child_below' exist
on ClutterActor, these aren't necessary.

https://bugzilla.gnome.org/show_bug.cgi?id=670034
2012-02-22 17:00:44 -05:00
c892610f27 st-container: Remove st_container_destroy_children
It was a simple wrapper around clutter_actor_destroy_all_children.

https://bugzilla.gnome.org/show_bug.cgi?id=670034
2012-02-22 17:00:44 -05:00
72dad591fa st-container: Remove ClutterContainer implementation
Now that ClutterActor has a ClutterContainer implementation, we
can start removing StContainer. To help make this a bit more
understandable, instead of converting everything at once, make
StContainer a compatible API wrapper around the ClutterActor
implementation, and then we'll remove those wrappers in later
commits.

https://bugzilla.gnome.org/show_bug.cgi?id=670034
2012-02-22 17:00:44 -05:00
ea19790828 st-widget: Implement a proper allocate
Since an StWidget now has children, it needs to allocate those children
properly. Defer to the currently installed layout manager, like Clutter
does.

Now that we have something that allocates children in St, to prevent
double allocations, we use clutter_actor_set_allocation rather than
chaining up to StWidget::allocate.

https://bugzilla.gnome.org/show_bug.cgi?id=670034
2012-02-22 17:00:44 -05:00
cc2f5d19c8 st-widget: Implement a proper get_preferred_width/height
Now that StWidget is concrete and instantiable, we need to do something
other than return an adjusted 0 for width and height. Just chain up
to ClutterActor's default implementation, which uses the layout manager.

https://bugzilla.gnome.org/show_bug.cgi?id=670034
2012-02-22 17:00:44 -05:00
64b2c5d1b4 st-widget: Add a proper paint, add st_widget_paint_background
Since we want to paint children by default in StWidget, we need to
provide a way for custom subclasses to paint their CSS backgrounds
without painting children... introducing st_widget_paint_background.

Additionally, remove any custom paint/pick handlers added by subclasses
of StWidget that just painted their children. This will cause double
painting if left alone.

This also removes the hacky things that some subclasses of StBin did
to prevent their one child to be painted by StBin.

https://bugzilla.gnome.org/show_bug.cgi?id=670034
2012-02-22 17:00:44 -05:00
a9f728d2a7 st-widget: Keep track of first/last children
Clutter now provides two new properties on ClutterActor - first-child
and last-child, so we have notifiers on when they change. Unfortunately,
it still doesn't help us too much - we need to keep track of the previous
values of the properties so we can remove their pseudoclasses.

https://bugzilla.gnome.org/show_bug.cgi?id=670034
2012-02-22 17:00:44 -05:00
3736d81d8f st-widget: Copy get_focus_chain and navigate_focus from StContainer
We can't get rid of the implementations in StContainer just yet,
as StContainer still keeps its own child list. But this should
lower the amount of code that has to be moved around when we
remove StContainer.

https://bugzilla.gnome.org/show_bug.cgi?id=670034
2012-02-22 17:00:44 -05:00
fbcea03ab3 st-widget: Don't explicitly check for ClutterContainer inheritance
Since all ClutterActors implement the ClutterContainer interface, there
isn't a case where this check could fail.

https://bugzilla.gnome.org/show_bug.cgi?id=670034
2012-02-22 17:00:44 -05:00
f19ee78fb2 st-widget: Don't use deprecated API
clutter_container_foreach is deprecated, so let's replace that
with some ClutterActorIter usage. Additionally, remove the checks
for ClutterContainer, as all ClutterActors are now ClutterContainers.

https://bugzilla.gnome.org/show_bug.cgi?id=670034
2012-02-22 17:00:44 -05:00
b47fd6df31 st-widget: Make into a concrete class
ClutterActor is concrete, so StWidget should be too.

https://bugzilla.gnome.org/show_bug.cgi?id=670034
2012-02-22 17:00:44 -05:00
786beccca5 workspaceThumbnail: don't queue unnecessary relayouts
Relayouts are expensive and can make the UI laggy.
2012-02-22 13:43:04 +01:00
916c62a702 update Punjabi Translation 2012-02-22 06:59:55 +05:30
11234c7cfc Updated POTFILES.in 2012-02-21 23:33:36 +01:00
80eac7370e st: Remove thumbnail functions from TextureCache
They were only used by the recent item search, which has been removed.

https://bugzilla.gnome.org/show_bug.cgi?id=670150
2012-02-21 23:00:53 +01:00
ac78a1e1c0 docDisplay: Remove "Recent Items" search provider
Although not all "Finding and reminding" applications are ready
yet, the integration with gnome-documents' search results overlaps
enough with the "Recent Items" provider to justify its removal.

https://bugzilla.gnome.org/show_bug.cgi?id=670150
2012-02-21 23:00:53 +01:00
34c6ff9645 overview: Load RemoteSearchProviders
Allow applications to register search providers by dropping a keyfile
into a well-known directory. For now, initialize all found providers;
long term, we probably want to give users the ability to restrict the
set of active search providers.

https://bugzilla.gnome.org/show_bug.cgi?id=663125
2012-02-21 23:00:53 +01:00
f6749fb204 search: Add RemoteSearchProvider
Add an asynchronous search provider for results from a DBus service
implementing the org.gnome.Shell.SearchProvider interface; this
will allow applications to hook into the Shell's search without
implementing it in Shell itself or requiring an extension.

https://bugzilla.gnome.org/show_bug.cgi?id=663125
2012-02-21 23:00:53 +01:00
89fe43f70c search: Rename search_providers to open-search-providers
We will allow applications to hook into shell's search by registering
a service which implements a well-known DBus interface.
"search-providers" is a reasonable directory name for applications to
drop their registration files, but it conflicts with "search_providers"
used by open search providers - rename the latter to avoid confusion.

https://bugzilla.gnome.org/show_bug.cgi?id=663125
2012-02-21 23:00:53 +01:00
e2c66ce48a search: Make asynchronous providers more explicit
Currently, asynchronous search providers are expected to call
startAsync() in getInitialResultSet()/getSubsearchResultSet(),
which will trigger async mode until the search is canceled or
updated. Switching between synchronous and asynchronous mode like
this makes asynchronous search an implementation detail, but being
transparent to the searchDisplay means that certain optimizations
don't work as expected. Namely, updating asynchronous search results
causes flickering, and the automatic selection never focuses
asynchronous results.
So change the API to require providers being either synchronous (with
the current getInitialResultSet()/getSubsearchResultSet() methods)
or asynchronous (with asynchronous variants), and handle asynchronous
providers explicitly in searchDisplay.

https://bugzilla.gnome.org/show_bug.cgi?id=663125
2012-02-21 23:00:53 +01:00
eb0d803617 searchDisplay: Split renderResults()
renderResults() updates the results set, determines the number of
results to display, retrieves the corresponding result metas and
adds a new results actor for each meta.
Splitting the function in those parts allows to move the retrieval
of the result metas into SearchResults, which is where we ensure
flicker-free rendering and control the selection - we want to keep
both features for asynchronous result metas which we are about to
introduce.

https://bugzilla.gnome.org/show_bug.cgi?id=663125
2012-02-21 23:00:53 +01:00
53d9ea7a2c search: Replace getResultMeta() with getResultMetas()
Save some function calls by fetching all search results we want to
display for a provider at once, rather than one result at a time.

https://bugzilla.gnome.org/show_bug.cgi?id=663125
2012-02-21 23:00:53 +01:00
0fbdd0b67f Updated Slovenian translation 2012-02-21 22:29:23 +01:00
f248aa69dc Support only Call1 channels
Empathy uses to support 2 D-Bus API for calls:
- StreamedMedia: legacy API
- Call.DRAFT: experimental version of the new API

Since 3.3.90, Empathy only supports Call1, the first stable version of the new
API, so the Shell should do the same.

https://bugzilla.gnome.org/show_bug.cgi?id=667694
2012-02-21 17:43:05 +01:00
9f1ed13a38 Updated Galician translations 2012-02-21 11:18:21 +01:00
9400d8f6db browser-plugin: Correct check for checking the hostname/protocol
While it's extremely unlikely that document.location would not be an
object in the browser setting, this check is incorrect and we could
possibly crash an NPAPI host if this is the case.

https://bugzilla.gnome.org/show_bug.cgi?id=670489
2012-02-21 04:06:10 -05:00
c7a4b307af Updated Serbian translation 2012-02-21 10:04:49 +01:00
0bac3a5dd7 Updated Danish translation 2012-02-20 23:16:43 +01:00
14b92a4897 dbus: Add FlashArea method
Add a new dbus method that takes an area (x, y, width, height) and fires a
flashspot on it.

This would be useful for applications like totem and cheese.

https://bugzilla.gnome.org/show_bug.cgi?id=669660
2012-02-20 21:54:06 +01:00
66bd8b553f Updated Lithuanian translation 2012-02-20 22:40:08 +02:00
e80462a2c3 Updated Belarusian translation. 2012-02-20 16:47:37 +03:00
b990ed2c23 app-system: Don't assume that gmenu_tree_load_sync() sets error
The function may return FALSE without setting the GError, so don't
assume it is set to prevent a crash in that case. While at it, free
the GError we were leaking before.

https://bugzilla.gnome.org/show_bug.cgi?id=670418
2012-02-20 11:41:57 +01:00
097e56f4ab Updated Spanish translation 2012-02-20 11:00:37 +01:00
7a4b6138c1 set a summary on the saved-im-presence and saved-session-presence keys
https://bugzilla.gnome.org/show_bug.cgi?id=669098
2012-02-20 08:42:17 +01:00
bc918d0d18 Updated Norwegian bokmål translation 2012-02-19 20:03:49 +01:00
8b08d8bf2d l10n: Updated Italian translation 2012-02-19 15:39:31 +01:00
d92c97f755 Updated Czech translation 2012-02-19 12:35:20 +01:00
6a367917f7 [l10n] Updated Estonian translation 2012-02-19 12:18:09 +02:00
b67138b5ae pokit-agent: fix segfault when we we fail to get the current session
When using systemd, polkit doesn't set the error even when returning false in g_initable_init

Signed-off-by: Marc-Antoine Perennou <Marc-Antoine@Perennou.com>

https://bugzilla.gnome.org/show_bug.cgi?id=670319
2012-02-18 20:27:39 +01:00
0e5177c329 Updated Telugu Translation 2012-02-18 22:49:41 +05:30
c6ed3cdb61 Updated Traditional Chinese translation(Hong Kong and Taiwan) 2012-02-18 08:46:57 +08:00
fd99d13f04 messageTray: Correctly show the icon on a notification stack
An actor is removed from its parent after it emits the destroy signal,
so we can't just check if the notification stack has more than one
notification -- we need to check if there's a notification there
that is not the current one.

This was causing spew in the form of:

    "this.notificationStack.get_children()[0]._delegate.setIconVisible
     is not a function"
2012-02-17 13:52:48 -05:00
36c3ce9333 theme: Adjust checkbox style
Replace the original hacked-up style with some original Steiner
artwork.

https://bugzilla.gnome.org/show_bug.cgi?id=669811
2012-02-17 18:37:27 +01:00
aee28616a9 wanda: Fix after clutter deprecation changes
Animated icons now use ClutterActor instead of ClutterGroup, so
adjust to that change.
2012-02-17 17:05:31 +01:00
70830560ae Updated Hebrew translation. 2012-02-17 15:10:07 +02:00
df6cd46bd6 l10n: Updated Italian translation 2012-02-16 22:30:42 +01:00
dce797f4d9 Updated Serbian translation 2012-02-16 11:47:08 +01:00
f3232901d8 Update Simplified Chinese translation. 2012-02-16 10:44:12 +00:00
d3e4f44d37 Update Simplified Chinese translation. 2012-02-16 10:36:16 +00:00
d81958a074 st: Remove st-tooltip
StTooltip has been plagued by lots of issues, and we recently ditched
it in the dash. Remove it for good.

https://bugzilla.gnome.org/show_bug.cgi?id=670034
2012-02-15 20:12:49 -05:00
92ee17493c st: Don't use deprecated API
clutter_actor_set_parent and clutter_actor_unparent are both
deprecated, and come from a time before a well-thought API
was introduced.

https://bugzilla.gnome.org/show_bug.cgi?id=670034
2012-02-15 20:12:16 -05:00
f9e456bb47 st-scroll-view: Remove unnecessary VISIBLE checks
clutter_actor_paint already checks for VISIBLE before painting

https://bugzilla.gnome.org/show_bug.cgi?id=670034
2012-02-15 20:12:16 -05:00
740388c778 st-texture-cache: Use ClutterActor, not ClutterGroup
ClutterGroup is deprecated, and since ClutterActor is concrete, we
can use that now instead.

https://bugzilla.gnome.org/show_bug.cgi?id=670034
2012-02-15 20:12:16 -05:00
1c0c42e8e7 iconGrid: Split vertical/horizontal item size
IconGrid items used to be square, so a single size value made
perfect sense. However, as contact search uses rectangular items,
using a single size is wrong - the allocated height ends up twice
the size of the visible height, which is particularly visible if
another provider displays results below contact results.

https://bugzilla.gnome.org/show_bug.cgi?id=670148
2012-02-15 22:14:11 +01:00
e2726f3e38 Add a checkbox widget
gnome-keyring dialogs need checkboxes, and while it is possible to
get pretty close using CSS tricks, a dedicated widgets yields better
results.

https://bugzilla.gnome.org/show_bug.cgi?id=669811
2012-02-15 22:14:11 +01:00
ed465a6ffe Bump clutter version requirement
We depend on API added in 1.9.11 so bump the min version.
2012-02-15 22:07:43 +01:00
fd8f3df2cd Updated Slovenian translation 2012-02-15 20:37:38 +01:00
0c2037875a main, lightbox: Fix lightbox for zoomed windows
The correct way to make an actor having the same size as another is
a ClutterBindConstraint. Connecting to 'allocation-changed' fails because
the allocation might not change even when 'width' and 'height' properties do.
This is the case of Main.uiGroup, used as parent container for zoomed
window clones.

In lightbox.js we bind also the position because in principle it could change,
even if currently only fullscreen lightboxes are used.
2012-02-15 18:18:46 +01:00
fbf6e032d0 modalDialog: Fix bindConstraint
Clutter.BindCoordinate is an enum not a bitmask, so use Clutter.BindCoordinate.ALL
instead of a bitmask of POSITION and SIZE.
2012-02-15 18:13:10 +01:00
c8020e6559 NetworkAgent: rename VPN keyfile key to "supports-external-ui-mode"
Dan Williams requested this change before merging the plugin patches,
so this is the key actually exposed.
2012-02-15 15:41:26 +01:00
68b7e8437b telepathyClient: Remove extremely outdated comment
The Shell has not been just an "Observer" for a long while now.
2012-02-14 17:29:52 -05:00
6528f8366f st-scroll-bar: Clean up get_preferred_width/height
With the steppers gone, we can remove this macro madness

https://bugzilla.gnome.org/show_bug.cgi?id=670034
2012-02-14 16:48:47 -05:00
88eb246b60 st-scroll-bar: Remove stepper buttons
This was a feature that was never used by the Shell.

https://bugzilla.gnome.org/show_bug.cgi?id=670034
2012-02-14 16:48:47 -05:00
bed50688d2 st-scroll-bar: Set the handle as a child of the bar, not the trough
The handle was a child of the trough, but it was allocated and painted
like it was a child of the bar. This will wreak havoc when we port over
to the new Clutter API, so let's just make it a child of the bar.

https://bugzilla.gnome.org/show_bug.cgi?id=670034
2012-02-14 16:48:47 -05:00
44686bac3e st-scroll-bar: Use clutter_actor_destroy in dispose
https://bugzilla.gnome.org/show_bug.cgi?id=670034
2012-02-14 16:48:47 -05:00
ca575ef0ae st: Remove st-overflow-box
It's unused, and has been for some time now.

https://bugzilla.gnome.org/show_bug.cgi?id=670034
2012-02-14 16:48:47 -05:00
c20503028a screenshot: add missing shell_screenshot_new()
And fix its declaration.
2012-02-14 15:57:34 -05:00
4516e4cc3b screenshot: Split into separate file / class
Split the screenshot functionality from ShellGlobal into its own class.

https://bugzilla.gnome.org/show_bug.cgi?id=670086
2012-02-14 21:10:08 +01:00
b2ec340f9e screenshot: Add include_cursor parameter
Add a boolean parameter to Screenshot and ScreenshotWindow which draws the cursor on the screenshot when set
to true.

https://bugzilla.gnome.org/show_bug.cgi?id=670086
2012-02-14 21:10:08 +01:00
570a029f27 test-recorder: Don't use deprecated API
https://bugzilla.gnome.org/show_bug.cgi?id=670034
2012-02-14 14:04:11 -05:00
ebe72e197d test-theme: Don't use deprecated API
https://bugzilla.gnome.org/show_bug.cgi?id=670034
2012-02-14 14:04:11 -05:00
ce629b09b2 st: Fix formatting
https://bugzilla.gnome.org/show_bug.cgi?id=670034
2012-02-14 14:04:10 -05:00
97c2db1cfd NetworkAgent: fix g_key_file_load_from_data()
Missed this in the rebase to the new annotations.
2012-02-14 19:29:25 +01:00
c5804c1929 ShellNetworkAgent: don't access request fields if the operation is cancelled
When the operation is cancelled by NetworkManager, the request is
cancelled immediately. Later when gnome-keyring invokes the callback
notifying the error we must therefore not access its memory.
Previously the callback would mistakenly treat "cancelled" (which
indicates a programmatic cancel) as "denied" (which means the user
clicked "Cancel" on the keyring prompt)

https://bugzilla.gnome.org/show_bug.cgi?id=658484
2012-02-14 19:16:50 +01:00
92276c5e70 NetworkAgent: add support for VPN connections
VPN secrets are stored by the plugins, that provide separate
helpers for authentication. This commit adds the support for invoking
the binaries and pass them connection details.
For plugins that support it (as exposed by their keyfile), we invoke
them in "external-ui-mode" and expect a set of metadata about the
secrets which is used to build a shell styled dialog.

https://bugzilla.gnome.org/show_bug.cgi?id=658484
2012-02-14 19:16:28 +01:00
62c0088dd8 Config: use sed for substituting variables
Substitutions generated by configure don't resolve prefixes, so
cannot be used for paths. Config already had localedir, and next
commit will need libexecdir and sysconfdir, so just bite the bullet
and move to sed.

https://bugzilla.gnome.org/show_bug.cgi?id=658484
2012-02-14 19:13:02 +01:00
e8498adaf1 automount: port from CK to systemd-logind
ConsoleKit is being obsoleted by systemd. Accordingly port the CK logic
in the gnome-shell automount manager to systemd-logind APIs.

This makes use of systemd-logind's native C APIs which are much easier
to use than the D-Bus APIs in this case, and much faster too (since they
are synchronous and directly query the kernel for the information we
need). The dependency is compile time optional, and in order to be nice
to the Debian folks g-s compiled with this enabled fill automatically
fall back to CK support on systems lacking systemd.
2012-02-13 23:17:09 +01:00
c7fa719cc3 gdm: port gnome-shell --gdm-mode to systemd
ConsoleKit is obsoleted by systemd-logind. Accordingly, port
the current CK code to systemd. In order to be nice to
the Debian people fall back to CK if systemd is not found,
so that the code makes the best of whatever it runs on.
2012-02-13 23:17:09 +01:00
41f0e133a9 extension-prefs-tool: fix sensitivity of combobox items
Extensions are load asynchronously, and they're availability can
change at times, so sensitivity must sometimes be restored to true.

https://bugzilla.gnome.org/show_bug.cgi?id=670006
2012-02-13 19:29:42 +01:00
7705a65beb ModemManager: fix dbus parameters
Gsm.GetRegistrationInfo and Cdma.GetServingSystem return a single argument
consisting of a tuple, not three separate arguments. This is
a regression from the GDBus port.

https://bugzilla.gnome.org/show_bug.cgi?id=670005
2012-02-13 19:28:25 +01:00
604e8f4f8a theme - give labels and captions the same padding
Give the window captions the same padding as the dash labels. This
makes things look nice and consistent.
2012-02-13 17:48:24 +00:00
de0116d8c8 theme - nicer contact search results
Make the results dark so they blend in nicely, and make the layout
match how contacts look in the contacts app.

https://bugzilla.gnome.org/show_bug.cgi?id=669993
2012-02-13 17:38:20 +00:00
8d968e5c9b Updated Czech translation 2012-02-13 18:18:27 +01:00
758e573483 Fixed LINGUAS 2012-02-12 22:19:37 +01:00
eab4f4c963 Return expected type from handleDragOver for Activities button actors
Currently they return 'undefined' instead of something meaningful,
e.g. DND.DragMotionResult.CONTINUE. This was unnoticed because none
of the ancestors of the Activities button actors do any drag handling.
The only visible issue are JS errors generated when dragging, for example,
a window thumbnail over the button, because the cursor cannot be set.

https://bugzilla.gnome.org/show_bug.cgi?id=669921
2012-02-12 20:22:04 +01:00
245c58842b xdndHandler: pass actor-relative coordinates to handleDragOver
This is more reasonable and consistent with what is done in dnd.js.

https://bugzilla.gnome.org/show_bug.cgi?id=669887
2012-02-12 20:21:56 +01:00
e508635c6e [l10n] Updated Kazakh translation 2012-02-12 19:40:09 +01:00
138b8cf874 xdndHandler: prevent dummy actor from interfering with Hot Corner
Since the dummy actor occupies exactly the same area of the Hot Corner,
it can be erroneously picked during xdnd operations. Fix this by
hiding it from pick.

https://bugzilla.gnome.org/show_bug.cgi?id=669831
2012-02-10 21:16:16 +01:00
d446b657f3 Updated Spanish translation 2012-02-10 14:57:23 +01:00
019dd2e1b0 telepathyClient: show connection manager crashes as "Internal error"
We use the same error messages as Empathy; this one was added to Empathy
in commit 756dbf5a7a658ba472fc63ef6034d2c4d90e3260.

https://bugzilla.gnome.org/show_bug.cgi?id=658908
2012-02-10 10:50:45 +00:00
602da771f6 Rename CSS selectors for password prompts
* Use .prompt-xxx selectors instead of .polkit-xxx,
   as the selectors are now used by various non-polkit
   dialogs as well

https://bugzilla.gnome.org/show_bug.cgi?id=669776
2012-02-10 09:16:09 +01:00
5de8a0a84b Updated Spanish translation 2012-02-09 17:29:59 +01:00
d2198925e1 Updated Spanish translation 2012-02-09 12:34:29 +01:00
44e02003ad Fixed typo in string 2012-02-09 10:10:18 +01:00
e8bfd990e4 Fixed typo in string 2012-02-09 10:09:33 +01:00
d1fc87577a panel: Simplify corner drawing
With the panel border removed, it is no longer necessary to account
for it in the corner drawing code, so simplify the drawing code
a bit.

https://bugzilla.gnome.org/show_bug.cgi?id=669489
2012-02-08 23:39:24 +01:00
8b4c1a80d0 theme: Remove border from top bar
Remove the border to make the top bar a better negative space.

https://bugzilla.gnome.org/show_bug.cgi?id=669489
2012-02-08 23:39:24 +01:00
6ca0d4a5ef Looking Glass: fix error line when there are no errors
The No error code path still used the old metadata object.

https://bugzilla.gnome.org/show_bug.cgi?id=669694
2012-02-08 23:29:44 +01:00
d0cd6ba47d extensionSystem: fix runtime enable()/disable() after last changes
disableExtension still used the old way to retrieve the state object,
and enableExtension called loadExtension at a time that would
always fail.

https://bugzilla.gnome.org/show_bug.cgi?id=669694
2012-02-08 23:29:39 +01:00
aa2a63bd84 volume: Clarify translatable string
https://bugzilla.gnome.org/show_bug.cgi?id=642135
2012-02-08 17:50:57 +01:00
daa380fb0e configure: GNOME_SHELL_JS needs gio-2.0
I didn't realize it when I wrote the patches, but GNOME_SHELL_JS needs
gio, not glib, as it uses the G_IO_ERROR quarks.

https://bugzilla.gnome.org/show_bug.cgi?id=669637
2012-02-08 10:34:53 -05:00
61e2e04f13 improve TP_ERROR_STR_ALREADY_CONNECTED displayed error string
'ressource' is XMPP specific and not clear to most users.

https://bugzilla.gnome.org/show_bug.cgi?id=669662
2012-02-08 13:37:30 +01:00
db7e4ddc04 [l10n] Updated Estonian translation 2012-02-08 10:51:09 +02:00
c4aa277b19 NEWS: minor fix to contributors list for 3.3.5 2012-02-07 18:36:43 -05:00
ab29ce872a Bump version to 3.3.5
Updated NEWS
Require Mutter 3.3.5
2012-02-07 18:31:29 -05:00
57beb0ade1 data/Makefile.am: fix typo in EXTRA_DIST 2012-02-07 18:31:29 -05:00
e3d0b6f90f Add -Wno-error=deprecated declarations
Even with --enable-compile-warnings=error, avoid erroring out on deprecations
for the moment, since we are hitting many Clutter deprecations and some are
hard to fix.
2012-02-07 18:21:56 -05:00
e2aa954cb5 st: Fix typo in doc comment 2012-02-08 00:01:12 +01:00
05c285a945 st: Shut up a compiler warning
Remove an unused variable to make GCC happy.
2012-02-08 00:01:12 +01:00
27b34992c6 iconGrid: Don't enter an infinite loop
If both spacing and -shell-grid-item-size are 0, as they would be with nothing
setting them, we enter an infinite loop where we try to compute the layout.
Avoid the situation entirely by defaulting -shell-grid-item-size to a sane
value instead of 0.

https://bugzilla.gnome.org/show_bug.cgi?id=662747
2012-02-07 17:40:22 -05:00
4886238761 Updated POTFILES.in 2012-02-07 23:14:34 +01:00
42d46aed90 po: Add extensionPrefs/main.js to the localized file set 2012-02-07 16:49:19 -05:00
a622aba7eb extensionUtils: Create and allow access to a new "extension" object
The "extension" object is what I previously called the "helper" object.
It contains the extension importer object as well as the metadata object.
Things that were previously added on to the metadata (state, path, dir, etc.)
are now part of this new "extension" object.

With the new importer changes brought on by the extension prefs tool,
extensions are left without a way to import submodules at the global scope,
which would make them rely on techniques like:

  var MySubModule;

  function init(meta) {
      MySubModule = meta.importer.mySubModule;
  }

That is, there's now a lot more meaningless boilerplate that nobody wants
to write and nobody wants to reivew.

Let's solve this with a few clever hacks.
Allow extensions to get their current extension object with:

  let extension = imports.misc.extensionUtils.getCurrentExtension();

As such, extensions can now get their own extension object before the
'init' method is called, so they can import submodules or do other things
at the module scope:

  const MySubModule = extension.imports.mySubModule;
  const dataPath = GLib.build_filenamev([extension.path, 'awesome-data.json']);

https://bugzilla.gnome.org/show_bug.cgi?id=668429
2012-02-07 16:00:37 -05:00
831099cca5 browser-plugin: Provide new APIs for launching extension preferences
Add two new APIs, "launchExtensionPrefs" to let SweetTooth let the user
launch the extension preferences tool directly from the browser. To allow
SweetTooth to check if an extension can be configured, add a new key to
the 'metadata', 'hasPrefs', which is returned by the GetExtensionInfo/
ListExtensions DBus methods.

https://bugzilla.gnome.org/show_bug.cgi?id=668429
2012-02-07 16:00:37 -05:00
b8a54faf94 Add a new tool, 'gnome-shell-extension-prefs', which can configure extensions
A new tool, 'gnome-shell-extension-prefs' can load a new entry point from
extensions, 'prefs.js', which has an entry point to return a GTK+ widget.
This allows extensions to have their own preferences dialog, without each
extension needing to ship its own Python script and .desktop file.

https://bugzilla.gnome.org/show_bug.cgi?id=668429
2012-02-07 16:00:37 -05:00
80ff6ff797 Move a lot of miscellaneous code related to extensions into a new module
ExtensionUtils is a new module that has a lot of miscellaneous things related
to loading extensions and the extension system put into a place that does not
depend on Shell or St.

Note that this will break extensions that have with multiple files by replacing
the old uuid-based importer with an object directly on the meta object.

https://bugzilla.gnome.org/show_bug.cgi?id=668429
2012-02-07 16:00:37 -05:00
2f27b94757 extensionSystem: Fix an error related to extension importing
If an extension fails to import, we will pass the error object
to logExtensionError, which fails to pass it onto DBus as an
error object is not a string. To fix, convert the error object
to a string before passing it to logExtensionError.

https://bugzilla.gnome.org/show_bug.cgi?id=668429
2012-02-07 16:00:37 -05:00
b2f33e2895 Split off the extension importing stuff into a new library, 'ShellJS'
This allows us to create a separate utility to import things from
shell extensions that does not have the entire Shell stack built up

https://bugzilla.gnome.org/show_bug.cgi?id=668429
2012-02-07 16:00:37 -05:00
d1d4142052 Makefile.am: Use global substitutions
This allows us to make more than one of the same replacement in a .in file

https://bugzilla.gnome.org/show_bug.cgi?id=668429
2012-02-07 16:00:36 -05:00
46caf6d673 ShellApp: Fix warning with call to g_strv_length()
There is no implicit cast from const char * const * to char **.
2012-02-07 13:06:24 -05:00
2864c360bc theme: Fix highlight of panel buttons
More fallout from the background-size change ...
2012-02-07 18:58:59 +01:00
e5dfc6323a Updated Galician translations 2012-02-07 11:54:19 +01:00
5bc042ba6f Remove override of map/unmap
Clutter, since version 1.8, does The Right Thing™ inside the default
implementation of ClutterActor::map and ClutterActor::unmap, even for
non-container actors: it will iterate over the list of children and
map, or unmap, each one of them, respectively.

This means that the requirement to override map and unmap for composite
actors to map and unmap the internal children has been dropped.

https://bugzilla.gnome.org/show_bug.cgi?id=669239
2012-02-06 23:36:43 +00:00
c63fe5ee24 workspaceThumbnail: avoid bouncing of the drop placeholder above the first workspace
https://bugzilla.gnome.org/show_bug.cgi?id=664622
2012-02-06 11:16:28 -05:00
ee6bc33cea PopupSwitchMenuItem: allow toggling without closing the menu
Similar to what Gtk does, now toggling with Space does not close
the menu.

https://bugzilla.gnome.org/show_bug.cgi?id=664416
2012-02-06 16:49:15 +01:00
5c730dc53d st-theme-node-drawing: Remove possible subtexturing
Since our implementation of background-size is now CSS-compliant, we
do not need this subtexture hack that clips a "leak". The comment here
is also incorrect.

https://bugzilla.gnome.org/show_bug.cgi?id=633462
2012-02-06 08:01:33 -05:00
5a3de8d663 st-theme-node-drawing: Fix implementation of background-size
It seems that accidentally, two variables were swapped in one code path
of the background-size implementation, causing interesting but wrong
images for some elements.

https://bugzilla.gnome.org/show_bug.cgi?id=633462
2012-02-06 08:01:33 -05:00
fad88dd517 theme: More fallout from background-size
The app filter arrows and scroll handles should be at 100%, not
mapped to their container

https://bugzilla.gnome.org/show_bug.cgi?id=633462
2012-02-06 08:01:33 -05:00
39dd24310d Updated Galician translations 2012-02-06 02:52:16 +01:00
b13809d0c7 Updated Dutch translation 2012-02-04 17:13:10 +01:00
87559414a3 screenGrabber: Pass correct coordinates to glReadPixels
Pass x and y to glReadPixels rather then always 0, 0.

https://bugzilla.gnome.org/show_bug.cgi?id=669366
2012-02-04 17:08:28 +01:00
b5b5759829 Updated Dutch translation 2012-02-04 15:59:58 +01:00
d254e2e1f2 shell-global: Correct screenshot_window() after mutter changes
Recent mutter changes made MetaShapedTexture not a ClutterTexture,
but instead a special ClutterActor subclass that implemented the texture-y
bits itself. Use recently introduced API in MetaShapedTexture so that we can
get the raw texture data and spit it out as a PNG.

Use the new meta_shaped_texture_get_image() to get a window's texture data.
meta_shaped_texture_get_image() flattens the image against any mask it may
have, so a screenshot of it should look exactly as it does on the display.

https://bugzilla.gnome.org/show_bug.cgi?id=662486
2012-02-03 19:58:39 -05:00
458b0b22fc shell-util: Remove shell_breakpoint
A near identical function appears in gjs, in the "system" module:

    const System = imports.system;
    System.breakpoint();
2012-02-03 14:21:57 -05:00
cd30128af8 placeDisplay: Fix accidental swap of parameters
https://bugzilla.gnome.org/show_bug.cgi?id=669236
2012-02-02 15:31:46 -05:00
d61cdd8cea Updated Slovenian translation 2012-02-02 20:58:35 +01:00
0d0e545979 configure: fix help string for jhbuild-wrapper-script option 2012-02-02 08:26:44 -05:00
6c5e96c33a added Sinhala language to LINGUAS file 2012-02-01 15:53:10 +05:30
bae2359b54 added Sinhala translation 2012-02-01 15:46:43 +05:30
8cbbb456f0 mount-operation: set a max-width for the question subject label
Since the string can be arbitrairly long.

https://bugzilla.gnome.org/show_bug.cgi?id=665322
2012-02-01 00:57:19 -05:00
dfd39461cf Updated Spanish translation 2012-01-31 17:49:13 +01:00
60d8683ae7 ShellRecorder: drop frames to approximate the target framerate
Instead of adding every rendered frame into the recording, drop frames
and only buffer and record enough frames to match the target framerate.

Increase the default frame rate from 15 to 30, since now that we're
actually enforcing framerate, it's noticeable that 15fps is not smooth.

https://bugzilla.gnome.org/show_bug.cgi?id=669066
2012-01-31 10:47:19 -05:00
f2cc5cf152 ShellRecorder: drop frames to keep from running the user out of memory.
Once we're buffering more than 3/4's of the "half of memory" target
for total buffer usage, start dropping frames.

https://bugzilla.gnome.org/show_bug.cgi?id=669066
2012-01-31 10:47:19 -05:00
d4a26fbf4b ShellRecorder: improve the default pipeline
The default pipeline was fairly aggressive about quality, and could
be too expensive for some computers. Decrease the quality setting for
the vp8 codec from 10 to 8, and increase the speed setting from 2 to 6.

(Basically, quality affects the visual fidelity of the end result, while
speed affects how much CPU the encoder uses to get a high compression
ratio at that quality level.)

Remove videorate from the pipeline, since the GStreamer VP8 encoder can
handle variable-framerate streams. This means that we won't spend CPU
encoding duplicate frames added by videorate.

https://bugzilla.gnome.org/show_bug.cgi?id=669066
2012-01-31 10:47:19 -05:00
025784fd83 ShellRecorderSrc: Set as GST_FORMAT_TIME
We need to indicate that our GStreamer source produces timestamped
frames, instead of the default, which is to produce a stream of bytes.
This is needed for correctness, and to avoid warnings for some
pipelines.

https://bugzilla.gnome.org/show_bug.cgi?id=669066
2012-01-31 10:47:19 -05:00
4e89a5edde ShellScreenGrabber: grab the screen using pixel buffers
For the Intel drivers, using glReadPixels() to read into client-memory
directly from the frame buffer is much slower than creating a pixel
buffer, copying into that, and then mapping that for reading. On other
drivers, the two approaches are likely to be similar in speed. Create
a ShellScreenGrabber abstraction that uses pixel buffers if available.
Use that for screenshots and screen recording.

https://bugzilla.gnome.org/show_bug.cgi?id=669065
2012-01-31 10:47:19 -05:00
b3936ecadf user-menu: Don't change HIDDEN to EXTENDED_AWAY
When the session status changes to IDLE, we automatically adjust
the IM presence; however, we should treat HIDDEN the same as OFFLINE
and not change the presence.

https://bugzilla.gnome.org/show_bug.cgi?id=642408
2012-01-31 10:22:53 +01:00
2c9e6bb589 browser-plugin: Fix the browser plugin
commit 26991988cb broke the browser plugin
by trying to reference a uninitialized pointer and making the NPAPI retain
a NULL object.

https://bugzilla.gnome.org/show_bug.cgi?id=668517
2012-01-30 19:26:50 -05:00
73261a4a66 Updated Traditional Chinese translation(Hong Kong and Taiwan) 2012-01-30 19:30:53 +08:00
3d0dd38045 automountManager: Make sure sessionActive is initialized
Since the port to GDBus, sessionActive is only set on DBus name
owner changes; this means that it may end up not being initialized
at all, and therefore always evaluate to false.
Make sure that the property is always initialized on startup.

https://bugzilla.gnome.org/show_bug.cgi?id=668020
2012-01-30 00:09:56 +01:00
8bcbf3030f power: Fix icon updates
gnome-settings-daemon commit 07b1ed63016 removed the custom 'Changed'
DBus signal in favor of the standard 'PropertiesChanged' signal, so
use that instead to update the icon.

https://bugzilla.gnome.org/show_bug.cgi?id=667371
2012-01-29 23:21:01 +01:00
1bc7edc5d8 Updated Slovenian translation 2012-01-28 19:52:48 +01:00
0673720db9 Updated Norwegian bokmål translation 2012-01-28 15:53:43 +01:00
730a0d4c5a Updated Hebrew translation. 2012-01-28 11:25:20 +02:00
9147dee0de screenshot: use the correct offsets when calculating the window area
Use the correct clip offsets when taking the screenshot of a window, to
exclude possible invisible borders and to include the case where the
window doesn't have any frame itself.
2012-01-27 17:15:03 -05:00
12746a1949 modemManager: Fix fallout from GDBus port
We need to listen to DBus signals with the 'connectSignal' method, not
the Signals 'connect' method.
2012-01-27 14:59:32 -05:00
bdd65fe755 AppMenuButton: bind "can-focus" to "reactive"
When changing to an empty workspace we make the AppMenuButton invisible but
the user could still get to the menu using keyboard navigation.

https://bugzilla.gnome.org/show_bug.cgi?id=643867
2012-01-27 18:01:22 +00:00
21e2280825 AppMenuButton: only show the button if the target app is on the current ws
When the last window on a workspace is closed the focus goes to some other
window in another workspace which would cause us to show the AppMenuButton for
an application that isn't visible on the current empty workspace.

https://bugzilla.gnome.org/show_bug.cgi?id=643867
2012-01-27 16:34:52 +00:00
e9d2a429eb message-tray: Allow to switch between left/right click directly
Currently it is not possible to trigger the context menu while the
summary notification is opened (and vice versa). To actually trigger
the desired item, the user has to click again, which is annoying
without a good justification, so allow switching directly between
left/right click items.

https://bugzilla.gnome.org/show_bug.cgi?id=666197
2012-01-27 14:27:41 +01:00
b67dfb9edf Updated Spanish translation 2012-01-27 13:40:06 +01:00
55308917f9 popup-menu: Do not open empty menus
There is little point in showing an empty menu, so return early from
open() if the menu does not contain any items.

https://bugzilla.gnome.org/show_bug.cgi?id=643867
2012-01-27 13:32:43 +01:00
1b64b09532 a11y: StLabelAccessible needs to notify accessible-name change
https://bugzilla.gnome.org/show_bug.cgi?id=667376
2012-01-27 12:29:57 +01:00
74dd298891 a11y: Setting a name/label_actor for several items on the panel
https://bugzilla.gnome.org/show_bug.cgi?id=667376
2012-01-27 12:29:52 +01:00
5a85fc0e55 magnifier: Handle screen size changes
Update everything that depends on the screen size whenever it changes.

https://bugzilla.gnome.org/show_bug.cgi?id=667860
2012-01-26 15:14:48 +00:00
26991988cb browser-plugin: Refactor plugin_object_set_property, and fix a bug
If the user did "obj.onchanged = 1;" or passed another sort of invalid type,
then we would clear the old listener as well as throw an exception.

https://bugzilla.gnome.org/show_bug.cgi?id=668517
2012-01-26 05:13:21 -05:00
15563444cf browser-plugin: Fix callback for "onchange"
In the case that calling the listener fails, "result" may be uninitialized.
Sending NPAPI uninitialized memory is never a good idea.

https://bugzilla.gnome.org/show_bug.cgi?id=668517
2012-01-26 05:13:21 -05:00
3bcdba6e1d browser-plugin: Add a new "onshellrestart" API
This function is something the client sets and is called whenever the Shell's
DBus name is acquired.

https://bugzilla.gnome.org/show_bug.cgi?id=668517
2012-01-26 05:13:21 -05:00
ef56a78544 shell-dbus: factor screenshot callback into a separate function
Share the screenshot methods callback into a factored out function.

https://bugzilla.gnome.org/show_bug.cgi?id=668618
2012-01-25 19:20:09 -05:00
049a561466 screenshot: add a 'flash' boolean flag to screenshot methods
Add a flag to these methods that allows flashing the area of the
screenshot directly from the compositor.

https://bugzilla.gnome.org/show_bug.cgi?id=668618
2012-01-25 19:20:09 -05:00
b40b19997a shell: Use generic marshaller
https://bugzilla.gnome.org/show_bug.cgi?id=662152
2012-01-25 19:03:48 -05:00
46505a8314 etc: Use generic marshaller
https://bugzilla.gnome.org/show_bug.cgi?id=662152
2012-01-25 19:03:13 -05:00
78fb102002 st: Use generic marshaller
https://bugzilla.gnome.org/show_bug.cgi?id=662152
2012-01-25 19:03:01 -05:00
c6e924f788 browser-plugin: Fix leak in plugin_enable_extension
https://bugzilla.gnome.org/show_bug.cgi?id=668541
2012-01-25 19:02:08 -05:00
f6508b51a2 st-im-text: Guard against multiple dispose
This could cause warnings like "invalid (NULL) pointer instance"

https://bugzilla.gnome.org/show_bug.cgi?id=665000
2012-01-25 19:01:33 -05:00
b0ae596de8 contact-display: Don't show non-IM contacts as "offline"
Currently we display IM status information for every contact, falling
back to "offline" if the contact does not have an associated IM
account. Instead, don't show IM presence in this case.

https://bugzilla.gnome.org/show_bug.cgi?id=662685
2012-01-25 21:14:40 +01:00
1d311e7916 shell-app: Make use of Keywords in search
.desktop files have been designed for browsing, so the existing
fields often produce insufficient results when used for search.
gnome-control-center used X-GNOME-Keywords for that purpose, which
has now been standardized as Keywords. It makes sense for us to
support it in gnome-shell as well (and encourage its use outside
of settings panels).

https://bugzilla.gnome.org/show_bug.cgi?id=609702
2012-01-25 20:29:37 +01:00
0c19f71c96 telepathyClient: Fix fallout from Lang.Class port
this.parent was ported from calling the parent class's method like
MessageTray.Notification.prototype._init.call(this, ...);. When
porting to Lang.Class, the 'this' parameter is now passed automatically, but
removing it was forgot in a few places. Fix these places.

https://bugzilla.gnome.org/show_bug.cgi?id=665017
2012-01-25 02:13:37 -05:00
8d6ab32b9a shell-app-system: Add Debian to the vendor prefixes
It seems that Debian has their own prefixes in something like
debian-xterm.desktop. To properly do application matching in these cases,
we need to strip the debian- prefix.

https://bugzilla.gnome.org/show_bug.cgi?id=665647
2012-01-25 02:11:11 -05:00
6c1a2d531f Updated Irish translation 2012-01-24 16:40:55 -07:00
c6e9f9742b dash: Use the correct theme node for spacing/padding
We consider spacing and padding in _adjustIconSize, but as we use
the theme node from an actor which is not exposed to the CSS, we
miss the "real" values - correct this.

https://bugzilla.gnome.org/show_bug.cgi?id=662213
2012-01-24 22:53:22 +01:00
d23aaf3cea Updated Finnish translation. 2012-01-24 15:37:21 +02:00
017fde91ad Updated Galician translations 2012-01-23 04:05:43 +01:00
31ffc5a85d theme: Fix some more fallout from background-size addition
The workspace-switcher-popup background should be at 100%, not upscaled
to contain the entire popup.

https://bugzilla.gnome.org/show_bug.cgi?id=668430
2012-01-22 06:09:01 -05:00
62b65a25d8 workspace: fix dragging of window thumbnails
Clear the ClutterClickAction state before starting the drag,
otherwise it will eat the first button event after the drag,
preventing a new drag from being started.

https://bugzilla.gnome.org/show_bug.cgi?id=662386
2012-01-22 06:06:35 -05:00
882fe48d80 Screenshot: Move filesystem I/O to a thread
Writting the screenshot to a file can take a relativly long time
in which we block the compositor, so do that part in a separate
thread to avoid the hang.

https://bugzilla.gnome.org/show_bug.cgi?id=652952
2012-01-22 11:47:56 +01:00
167 changed files with 16482 additions and 12108 deletions

3
.gitignore vendored
View File

@ -18,6 +18,8 @@ config
configure
data/gnome-shell.desktop
data/gnome-shell.desktop.in
data/gnome-shell-extension-prefs.desktop
data/gnome-shell-extension-prefs.desktop.in
data/gschemas.compiled
data/org.gnome.shell.gschema.xml
data/org.gnome.shell.gschema.valid
@ -62,6 +64,7 @@ src/calendar-server/org.gnome.Shell.CalendarServer.service
src/gnome-shell
src/gnome-shell-calendar-server
src/gnome-shell-extension-tool
src/gnome-shell-extension-prefs
src/gnome-shell-hotplug-sniffer
src/gnome-shell-jhbuild
src/gnome-shell-perf-helper

90
NEWS
View File

@ -1,3 +1,93 @@
3.3.90
======
* All other applications to implement search providers via D-Bus
[Florian; #663125, #670148]
* Remove "Recent Items" search, as replaced by Documents search
[Florian; #663125]
* Allow NetworkManager VPN plugins to use a shell-themed dialog
[Giovanni; #658484]
* Port away from deprecated Clutter API [Jasper, Florian, Adel; #670034]
- StTooltip is removed
- StWidget is now a concrete class and can be instantiated
- st_container_destroy_children(), st_box_layout_insert_actor(),
and other functions removed in favor of new replacements in Clutter.
* Use systemd for console/session handling when available [Lennart]
* Visual improvements to contact search, padding, top panel, checkboxes
[Allan, Florian, Jakub; #669489, #669811, #669993]
* Add a include_cursor parameter to Screenshot and ScreenshotWindow
D-Bus methods [Adel; #670086]
* Add a "FlashArea" D-Bus method to do the screenshot flash without a
screenshot [Adel; #669660]
* Build fixes [Adel, Giovanni, Jasper; #658484, #669637]
* Misc bug fixes [Adel, Florian, Giovanni, Guillaume, Jasper, Jeff,
Marc-Antoine, Stef, Stefano, Will; #642135, #658484, #658908, #667694,
#669098, #669921, #669662, #669694, #669776, #669887, #669921, #670005,
#670006, #670319, #670418, #670489]
Contributors:
Giovanni Campagna, Cosimo Cecchi, Allan Day, Guillaume Desmottes, Jeff Epler,
Stefano Facchini, Adel Gadllah, Florian Müllner, Marc-Antoine Perennou,
Jasper St. Pierre, Lennart Poettering, Jakub Steiner, Jasper St. Pierre,
Will Thompson, Stef Walter
Translations:
Ihar Hrachyshka [be], Marek Černocký, Adam Matoušek [cz],
Kenneth Nielsen [dk], Daniel Mustieles [es], Mattias Põldaru [et],
Fran Diéguez [gl], Yaron Shahrabani [he], Luca Ferretti [it],
Baurzhan Muftakhidinov [kk], Aurimas Černius [lt], Kjartan Maraas [nb],
A S Alam [pa], Matej Urbančič [sl], Miroslav Nikolić [sr],
Praveen Illa [te], Chao-Hsiung Liao [zh_HK, zh_TW]
3.3.5
=====
* Extension system: [Jasper; #668429]
http://blog.mecheye.net/2012/02/more-extension-api-breaks/
- Add a 'gnome-shell-extension-prefs' application for displaying extension
preferences as provided by the extension in a prefs.js file.
- Allow launching gnome-shell-extension-prefs from extensions.gnome.org
throuhg the browser plugin.
- Add ExtensionUtils.getCurrentExtension() for an extension to get a
handle to an extension object, to get local imports or paths.
- Add an onshellrestart callback to the browser plugin [Jasper; #668517]
* Screenshots:
- Move the screenshot "flash" to the shell [Cosimo; #668618]
- Move saving screenshots to a thread [Adel; #652952]
- Correctly screenshot rounded decorations [Jasper; #662486]
* Screen recorder:
- Change the default pipeline to favor speed over quality [Owen; #669066]
- Drop frames to keep from running the user out of memory [Owen; #669066]
* Work around a slow implementation of glReadPixels() in the Intel drivers,
improving performance for screenshots and the screen recorder.
[Owen; #669065]
* Use Keywords: field in desktop files when search for applications
[Florian; #609702]
* Strip debian- when matching desktop file names [Jasper; #665647]
* Fix up various problems from CSS background size-addition
[Florian, Jasper; #668430, #633462]
* UI tweaks and behavior fixes
[Florian, Giovanni, Stefano; #643867, #666197, #664622]
* Some improvements to exported accessibility information [Alejando; #667376]
* Don't show contacts without IM information as offline [Florian; #662685]
* Don't change status from hidden to extended_away when going idle
[Florian; #642408]
* Cleanups [Emmanuele, Jasper; #662152, #669239]
* Misc bug fixes [Cosimo, Dan, Florian, Jasper, Rui, Stefano;
#633462, #643867, #662213, #662386, #662747, #665000, #665017, #665322,
#667371, #667860, #668020, #668517, #668541, #669236]
Contributors:
Emmanuele Bassi, Giovanni Campagna, Cosimo Cecchi, Stefano Facchini,
Adel Gadllah, Rui Matos, Florian Müllner, Alejandro Piñeiro,
Jasper St. Pierre, Owen Taylor, Dan Winship
Translations:
Daniel Mustieles [es], Timo Jyrinki [fi], Seán de Búrca [ga],
Fran Diéguez [gl], Kjartan Maraas [nb], Wouter Bolsterlee [nl],
Danishka Navin [si], Yaron Shahrabani [he], Matej Urbančič [sl],
Chao-Hsiung Liao [zh_HK, zh_TW]
3.3.4
=====
* https://live.gnome.org/EveryDetailMatters

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 1
#define PLUGIN_API_VERSION 3
typedef struct {
GDBusProxy *proxy;
@ -104,7 +104,7 @@ check_origin_and_protocol (NPP instance)
&location))
goto out;
if (!NPVARIANT_IS_OBJECT (document))
if (!NPVARIANT_IS_OBJECT (location))
goto out;
hostname = get_string_property (instance,
@ -262,11 +262,13 @@ NPP_Destroy(NPP instance,
/* =================== scripting interface =================== */
typedef struct {
NPObject parent;
NPP instance;
GDBusProxy *proxy;
NPObject *listener;
gint signal_id;
NPObject parent;
NPP instance;
GDBusProxy *proxy;
NPObject *listener;
NPObject *restart_listener;
gint signal_id;
guint watch_name_id;
} PluginObject;
static void
@ -284,7 +286,7 @@ on_shell_signal (GDBusProxy *proxy,
gint32 status;
gchar *error;
NPVariant args[3];
NPVariant result;
NPVariant result = { NPVariantType_Void };
g_variant_get (parameters, "(sis)", &uuid, &status, &error);
STRINGZ_TO_NPVARIANT (uuid, args[0]);
@ -300,6 +302,25 @@ on_shell_signal (GDBusProxy *proxy,
}
}
static void
on_shell_appeared (GDBusConnection *connection,
const gchar *name,
const gchar *name_owner,
gpointer user_data)
{
PluginObject *obj = (PluginObject*) user_data;
if (obj->restart_listener)
{
NPVariant result = { NPVariantType_Void };
funcs.invokeDefault (obj->instance, obj->restart_listener,
NULL, 0, &result);
funcs.releasevariantvalue (&result);
}
}
static NPObject *
plugin_object_allocate (NPP instance,
NPClass *klass)
@ -312,6 +333,14 @@ plugin_object_allocate (NPP instance,
obj->signal_id = g_signal_connect (obj->proxy, "g-signal",
G_CALLBACK (on_shell_signal), obj);
obj->watch_name_id = g_bus_watch_name (G_BUS_TYPE_SESSION,
"org.gnome.Shell",
G_BUS_NAME_WATCHER_FLAGS_NONE,
on_shell_appeared,
NULL,
obj,
NULL);
g_debug ("plugin object created");
return (NPObject*)obj;
@ -328,6 +357,9 @@ plugin_object_deallocate (NPObject *npobj)
if (obj->listener)
funcs.releaseobject (obj->listener);
if (obj->watch_name_id)
g_bus_unwatch_name (obj->watch_name_id);
g_debug ("plugin object destroyed");
g_slice_free (PluginObject, obj);
@ -341,7 +373,9 @@ static NPIdentifier enable_extension_id;
static NPIdentifier install_extension_id;
static NPIdentifier uninstall_extension_id;
static NPIdentifier onextension_changed_id;
static NPIdentifier onrestart_id;
static NPIdentifier get_errors_id;
static NPIdentifier launch_extension_prefs_id;
static bool
plugin_object_has_method (NPObject *npobj,
@ -352,7 +386,8 @@ plugin_object_has_method (NPObject *npobj,
name == enable_extension_id ||
name == install_extension_id ||
name == uninstall_extension_id ||
name == get_errors_id);
name == get_errors_id ||
name == launch_extension_prefs_id);
}
static inline gboolean
@ -457,7 +492,10 @@ plugin_enable_extension (PluginObject *obj,
{
gchar *uuid_str = g_strndup (uuid.UTF8Characters, uuid.UTF8Length);
if (!uuid_is_valid (uuid_str))
return FALSE;
{
g_free (uuid_str);
return FALSE;
}
g_dbus_proxy_call (obj->proxy,
(enabled ? "EnableExtension" : "DisableExtension"),
@ -616,6 +654,33 @@ plugin_get_errors (PluginObject *obj,
return jsonify_variant (res, result);
}
static gboolean
plugin_launch_extension_prefs (PluginObject *obj,
NPString uuid,
NPVariant *result)
{
gchar *uuid_str;
uuid_str = g_strndup (uuid.UTF8Characters, uuid.UTF8Length);
if (!uuid_is_valid (uuid_str))
{
g_free (uuid_str);
return FALSE;
}
g_dbus_proxy_call (obj->proxy,
"LaunchExtensionPrefs",
g_variant_new ("(s)", uuid_str),
G_DBUS_CALL_FLAGS_NONE,
-1, /* timeout */
NULL, /* cancellable */
NULL, /* callback */
NULL /* user_data */);
g_free (uuid_str);
return TRUE;
}
static int
plugin_get_api_version (PluginObject *obj,
NPVariant *result)
@ -726,6 +791,14 @@ plugin_object_invoke (NPObject *npobj,
NPVARIANT_TO_STRING(args[0]),
result);
}
else if (name == launch_extension_prefs_id)
{
if (!NPVARIANT_IS_STRING(args[0])) return FALSE;
return plugin_launch_extension_prefs (obj,
NPVARIANT_TO_STRING(args[0]),
result);
}
return TRUE;
}
@ -735,6 +808,7 @@ plugin_object_has_property (NPObject *npobj,
NPIdentifier name)
{
return (name == onextension_changed_id ||
name == onrestart_id ||
name == api_version_id ||
name == shell_version_id);
}
@ -761,6 +835,33 @@ plugin_object_get_property (NPObject *npobj,
else
NULL_TO_NPVARIANT (*result);
}
else if (name == onrestart_id)
{
if (obj->restart_listener)
OBJECT_TO_NPVARIANT (obj->restart_listener, *result);
else
NULL_TO_NPVARIANT (*result);
}
return TRUE;
}
static bool
plugin_object_set_callback (NPObject **listener,
const NPVariant *value)
{
if (!NPVARIANT_IS_OBJECT (*value) && !NPVARIANT_IS_NULL (*value))
return FALSE;
if (*listener)
funcs.releaseobject (*listener);
*listener = NULL;
if (NPVARIANT_IS_OBJECT (*value))
{
*listener = NPVARIANT_TO_OBJECT (*value);
funcs.retainobject (*listener);
}
return TRUE;
}
@ -772,25 +873,13 @@ plugin_object_set_property (NPObject *npobj,
{
PluginObject *obj;
if (!plugin_object_has_property (npobj, name))
return FALSE;
obj = (PluginObject *)npobj;
if (name == onextension_changed_id)
{
obj = (PluginObject*) npobj;
if (obj->listener)
funcs.releaseobject (obj->listener);
return plugin_object_set_callback (&obj->listener, value);
obj->listener = NULL;
if (NPVARIANT_IS_OBJECT (*value))
{
obj->listener = NPVARIANT_TO_OBJECT (*value);
funcs.retainobject (obj->listener);
return TRUE;
}
else if (NPVARIANT_IS_NULL (*value))
return TRUE;
}
if (name == onrestart_id)
return plugin_object_set_callback (&obj->restart_listener, value);
return FALSE;
}
@ -824,7 +913,9 @@ init_methods_and_properties (void)
install_extension_id = funcs.getstringidentifier ("installExtension");
uninstall_extension_id = funcs.getstringidentifier ("uninstallExtension");
get_errors_id = funcs.getstringidentifier ("getExtensionErrors");
launch_extension_prefs_id = funcs.getstringidentifier ("launchExtensionPrefs");
onrestart_id = funcs.getstringidentifier ("onshellrestart");
onextension_changed_id = funcs.getstringidentifier ("onchange");
}

View File

@ -1,5 +1,5 @@
AC_PREREQ(2.63)
AC_INIT([gnome-shell],[3.3.4],[https://bugzilla.gnome.org/enter_bug.cgi?product=gnome-shell],[gnome-shell])
AC_INIT([gnome-shell],[3.3.90],[https://bugzilla.gnome.org/enter_bug.cgi?product=gnome-shell],[gnome-shell])
AC_CONFIG_HEADERS([config.h])
AC_CONFIG_SRCDIR([src/shell-global.c])
@ -53,24 +53,24 @@ if $PKG_CONFIG --exists gstreamer-0.10 '>=' $GSTREAMER_MIN_VERSION ; then
AC_MSG_RESULT(yes)
build_recorder=true
recorder_modules="gstreamer-0.10 gstreamer-base-0.10 x11"
PKG_CHECK_MODULES(TEST_SHELL_RECORDER, $recorder_modules clutter-1.0 xfixes)
PKG_CHECK_MODULES(TEST_SHELL_RECORDER, $recorder_modules clutter-1.0 xfixes gl)
else
AC_MSG_RESULT(no)
fi
AM_CONDITIONAL(BUILD_RECORDER, $build_recorder)
CLUTTER_MIN_VERSION=1.7.5
CLUTTER_MIN_VERSION=1.9.11
GOBJECT_INTROSPECTION_MIN_VERSION=0.10.1
GJS_MIN_VERSION=1.29.18
MUTTER_MIN_VERSION=3.3.3
MUTTER_MIN_VERSION=3.3.5
FOLKS_MIN_VERSION=0.5.2
GTK_MIN_VERSION=3.3.9
GIO_MIN_VERSION=2.31.6
LIBECAL_MIN_VERSION=2.32.0
LIBEDATASERVER_MIN_VERSION=1.2.0
LIBEDATASERVERUI_MIN_VERSION=2.91.6
TELEPATHY_GLIB_MIN_VERSION=0.15.6
TELEPATHY_GLIB_MIN_VERSION=0.17.5
TELEPATHY_LOGGER_MIN_VERSION=0.2.4
POLKIT_MIN_VERSION=0.100
STARTUP_NOTIFICATION_MIN_VERSION=0.11
@ -117,7 +117,8 @@ AC_CHECK_FUNCS(JS_NewGlobalObject XFixesCreatePointerBarrier)
CFLAGS=$saved_CFLAGS
LIBS=$saved_LIBS
PKG_CHECK_MODULES(ST, clutter-1.0 gtk+-3.0 libcroco-0.6 >= 0.6.2 gnome-desktop-3.0 >= 2.90.0 x11)
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)
@ -140,6 +141,33 @@ PKG_CHECK_MODULES(CALENDAR_SERVER, libecal-1.2 >= $LIBECAL_MIN_VERSION libedatas
AC_SUBST(CALENDAR_SERVER_CFLAGS)
AC_SUBST(CALENDAR_SERVER_LIBS)
AC_ARG_WITH(systemd,
AS_HELP_STRING([--with-systemd],
[Add systemd support]),
[with_systemd=$withval], [with_systemd=auto])
PKG_CHECK_MODULES(SYSTEMD,
[libsystemd-login libsystemd-daemon],
[have_systemd=yes], [have_systemd=no])
if test "x$with_systemd" = "xauto" ; then
if test x$have_systemd = xno ; then
use_systemd=no
else
use_systemd=yes
fi
else
use_systemd=$with_systemd
fi
if test "x$use_systemd" = "xyes"; then
if test "x$have_systemd" = "xno"; then
AC_MSG_ERROR([Systemd support explicitly required, but systemd not found])
fi
AC_DEFINE(WITH_SYSTEMD, 1, [systemd support])
fi
MUTTER_GIR_DIR=`$PKG_CONFIG --variable=girdir libmutter`
MUTTER_TYPELIB_DIR=`$PKG_CONFIG --variable=typelibdir libmutter`
AC_SUBST(MUTTER_GIR_DIR)
@ -198,7 +226,7 @@ if test "$enable_compile_warnings" != no ; then
if test "$enable_compile_warnings" = error ; then
case " $CFLAGS " in
*[\ \ ]-Werror[\ \ ]*) ;;
*) CFLAGS="$CFLAGS -Werror" ;;
*) CFLAGS="$CFLAGS -Werror -Wno-error=deprecated-declarations" ;;
esac
fi
fi
@ -206,7 +234,7 @@ fi
changequote([,])dnl
AC_ARG_ENABLE(jhbuild-wrapper-script,
AS_HELP_STRING([--jhbuild-wrapper-script=yes],[Make "gnome-shell" script work for jhbuild]),,enable_jhbuild_wrapper_script=no)
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])
@ -247,7 +275,6 @@ AC_CONFIG_FILES([
docs/reference/st/Makefile
docs/reference/st/st-docs.sgml
js/Makefile
js/misc/config.js
src/Makefile
browser-plugin/Makefile
tests/Makefile

View File

@ -1,5 +1,5 @@
desktopdir=$(datadir)/applications
desktop_DATA = gnome-shell.desktop
desktop_DATA = gnome-shell.desktop gnome-shell-extension-prefs.desktop
# We substitute in bindir so it works as an autostart
# file when built in a non-system prefix
@ -12,16 +12,23 @@ desktop_DATA = gnome-shell.desktop
%.desktop:%.desktop.in
$(AM_V_GEN) sed s/^_// < $< > $@ || rm $@
searchprovidersdir = $(pkgdatadir)/search_providers
searchprovidersdir = $(pkgdatadir)/open-search-providers
dist_searchproviders_DATA = \
search_providers/google.xml \
search_providers/wikipedia.xml
open-search-providers/google.xml \
open-search-providers/wikipedia.xml
introspectiondir = $(datadir)/dbus-1/interfaces
introspection_DATA = org.gnome.ShellSearchProvider.xml
themedir = $(pkgdatadir)/theme
dist_theme_DATA = \
theme/calendar-arrow-left.svg \
theme/calendar-arrow-right.svg \
theme/calendar-today.svg \
theme/checkbox-focused.svg \
theme/checkbox-off-focused.svg \
theme/checkbox-off.svg \
theme/checkbox.svg \
theme/close-window.svg \
theme/close.svg \
theme/corner-ripple-ltr.png \
@ -31,7 +38,6 @@ dist_theme_DATA = \
theme/filter-selected-rtl.svg \
theme/gdm.css \
theme/gnome-shell.css \
theme/panel-border.svg \
theme/panel-button-border.svg \
theme/panel-button-highlight-narrow.svg \
theme/panel-button-highlight-wide.svg \
@ -69,6 +75,8 @@ shaders_DATA = \
EXTRA_DIST = \
gnome-shell.desktop.in.in \
gnome-shell-extension-prefs.desktop.in.in \
$(introspection_DATA) \
$(menu_DATA) \
$(shaders_DATA) \
$(convert_DATA) \
@ -76,6 +84,7 @@ EXTRA_DIST = \
CLEANFILES = \
gnome-shell.desktop.in \
gnome-shell-extension-prefs.in \
$(desktop_DATA) \
$(gsettings_SCHEMAS) \
gschemas.compiled

View File

@ -0,0 +1,12 @@
[Desktop Entry]
Type=Application
_Name=GNOME Shell Extension Preferences
_Comment=Configure GNOME Shell Extensions
Exec=@bindir@/gnome-shell-extension-prefs %u
X-GNOME-Bugzilla-Bugzilla=GNOME
X-GNOME-Bugzilla-Product=gnome-shell
X-GNOME-Bugzilla-Component=extensions
X-GNOME-Bugzilla-Version=@VERSION@
Categories=GNOME;GTK;
OnlyShowIn=GNOME;
NoDisplay=true

View File

@ -0,0 +1,147 @@
<!DOCTYPE node PUBLIC
'-//freedesktop//DTD D-BUS Object Introspection 1.0//EN'
'http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd'>
<node>
<interface name="org.gnome.Shell.SearchProvider">
<doc:doc>
<doc:description>
<doc:para>
The interface used for integrating into GNOME Shell's search
interface.
</doc:para>
</doc:description>
</doc:doc>
<method name="GetInitialResultSet">
<doc:doc>
<doc:description>
<doc:para>
Called when the user first begins a search.
</doc:para>
</doc:description>
</doc:doc>
<arg type="as" direction="in">
<doc:doc>
<doc:summary>
<doc:para>
Array of search terms, which the provider should treat as
logical AND.
</doc:para>
</doc:summary>
</doc:doc>
</arg>
<arg type="as" direction="out">
<doc:doc>
<doc:summary>
<doc:para>
An array of result identifier strings representing items which
match the given search terms. Identifiers must be unique within
the provider's domain, but other than that may be chosen freely
by the provider.
</doc:para>
</doc:summary>
</doc:doc>
</arg>
</method>
<method name="GetSubsearchResultSet">
<doc:doc>
<doc:description>
<doc:para>
Called when a search is performed which is a "subsearch" of
the previous search, e.g. the method may return less results, but
not more or different results.
This allows search providers to only search through the previous
result set, rather than possibly performing a full re-query.
</doc:para>
</doc:description>
</doc:doc>
<arg type="as" direction="in">
<doc:doc>
<doc:summary>
<doc:para>
Array of item identifiers
</doc:para>
</doc:summary>
</doc:doc>
</arg>
<arg type="as" direction="in">
<doc:doc>
<doc:summary>
<doc:para>
Array of updated search terms, which the provider should treat as
logical AND.
</doc:para>
</doc:summary>
</doc:doc>
</arg>
<arg type="as" direction="out">
<doc:doc>
<doc:summary>
<doc:para>
An array of result identifier strings representing items which
match the given search terms. Identifiers must be unique within
the provider's domain, but other than that may be chosen freely
by the provider.
</doc:para>
</doc:summary>
</doc:doc>
</arg>
</method>
<method name="GetResultMetas">
<doc:doc>
<doc:description>
<doc:para>
Return an array of meta data used to display each given result
</doc:para>
</doc:description>
</doc:doc>
<arg type="as" direction="in">
<doc:doc>
<doc:summary>
<doc:para>
An array of result identifiers as returned by
GetInitialResultSet() or GetSubsearchResultSet()
</doc:para>
</doc:summary>
</doc:doc>
</arg>
<arg type="a{sv}" direction="out">
<doc:doc>
<doc:summary>
<doc:para>
A dictionary describing the given search result, containing
'id', 'name' (both strings) and either 'icon' (a serialized
GIcon) or 'icon-data' (raw image data as (iiibiiay) - width,
height, rowstride, has-alpha, bits per sample, channels, data)
</doc:para>
</doc:summary>
</doc:doc>
</arg>
</method>
<method name="ActivateResult">
<doc:doc>
<doc:description>
<doc:para>
Called when the users chooses a given result. The result should
be displayed in the application associated with the corresponding
provider.
</doc:para>
</doc:description>
</doc:doc>
<arg type="s" direction="in">
<doc:doc>
<doc:summary>
<doc:para>
A result identifier as returned by GetInitialResultSet() or
GetSubsearchResultSet()
</doc:para>
</doc:summary>
</doc:doc>
</arg>
</method>
</interface>
</node>

View File

@ -53,11 +53,13 @@
</key>
<key name="saved-im-presence" type="i">
<default>1</default>
<_summary></_summary>
<_summary>Internally used to store the last IM presence explicitly set by the user. The
value here is from the TpConnectionPresenceType enumeration.</_summary>
</key>
<key name="saved-session-presence" type="i">
<default>0</default>
<_summary></_summary>
<_summary>Internally used to store the last session presence status for the user. The
value here is from the GsmPresenceStatus enumeration.</_summary>
</key>
<child name="clock" schema="org.gnome.shell.clock"/>
<child name="calendar" schema="org.gnome.shell.calendar"/>
@ -108,7 +110,7 @@
<schema id="org.gnome.shell.recorder" path="/org/gnome/shell/recorder/"
gettext-domain="@GETTEXT_PACKAGE@">
<key name="framerate" type="i">
<default>15</default>
<default>30</default>
<_summary>Framerate used for recording screencasts.</_summary>
<_description>
The framerate of the resulting screencast recordered
@ -127,7 +129,7 @@
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'
'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.
</_description>

View File

@ -0,0 +1,289 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="24"
height="22"
id="svg3199"
version="1.1"
inkscape:version="0.48.1 r9760"
sodipodi:docname="checkbox.svg">
<defs
id="defs3201">
<linearGradient
id="linearGradient15404"
inkscape:collect="always">
<stop
id="stop15406"
offset="0"
style="stop-color:#515151;stop-opacity:1" />
<stop
id="stop15408"
offset="1"
style="stop-color:#292929;stop-opacity:1" />
</linearGradient>
<inkscape:perspective
sodipodi:type="inkscape:persp3d"
inkscape:vp_x="0 : 526.18109 : 1"
inkscape:vp_y="0 : 1000 : 0"
inkscape:vp_z="744.09448 : 526.18109 : 1"
inkscape:persp3d-origin="372.04724 : 350.78739 : 1"
id="perspective3207" />
<inkscape:perspective
id="perspective3187"
inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
inkscape:vp_z="1 : 0.5 : 1"
inkscape:vp_y="0 : 1000 : 0"
inkscape:vp_x="0 : 0.5 : 1"
sodipodi:type="inkscape:persp3d" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient5872-5-1"
id="linearGradient5891-0-4"
gradientUnits="userSpaceOnUse"
x1="205.84143"
y1="246.7094"
x2="206.74803"
y2="231.24142" />
<linearGradient
inkscape:collect="always"
id="linearGradient5872-5-1">
<stop
style="stop-color:#0b2e52;stop-opacity:1"
offset="0"
id="stop5874-4-4" />
<stop
style="stop-color:#1862af;stop-opacity:1"
offset="1"
id="stop5876-0-5" />
</linearGradient>
<inkscape:path-effect
effect="spiro"
id="path-effect5837-4-6"
is_visible="true" />
<inkscape:path-effect
effect="spiro"
id="path-effect14768"
is_visible="true" />
<inkscape:path-effect
effect="spiro"
id="path-effect5884-4-7"
is_visible="true" />
<linearGradient
y2="-388.72955"
x2="-93.031357"
y1="-396.34738"
x1="-93.031357"
gradientTransform="matrix(1.5918367,0,0,0.85714285,-256.56122,59.685418)"
gradientUnits="userSpaceOnUse"
id="linearGradient14219"
xlink:href="#linearGradient15404"
inkscape:collect="always" />
<linearGradient
inkscape:collect="always"
id="linearGradient10013-4-63-6">
<stop
style="stop-color:#333333;stop-opacity:1;"
offset="0"
id="stop10015-2-76-1" />
<stop
style="stop-color:#292929;stop-opacity:1"
offset="1"
id="stop10017-46-15-8" />
</linearGradient>
<linearGradient
inkscape:collect="always"
id="linearGradient10597-5">
<stop
style="stop-color:#16191a;stop-opacity:1;"
offset="0"
id="stop10599-2" />
<stop
style="stop-color:#2b3133;stop-opacity:1"
offset="1"
id="stop10601-5" />
</linearGradient>
<linearGradient
y2="-322.16354"
x2="921.22498"
y1="-330.05121"
x1="921.32812"
gradientTransform="matrix(1.5918367,0,0,0.85714285,-1456.5464,275.45191)"
gradientUnits="userSpaceOnUse"
id="linearGradient15374"
xlink:href="#linearGradient10013-4-63-6"
inkscape:collect="always" />
<linearGradient
gradientTransform="translate(-1199.9852,216.38048)"
y2="-227.07961"
x2="1203.9177"
y1="-217.56708"
x1="1203.9177"
gradientUnits="userSpaceOnUse"
id="linearGradient15376"
xlink:href="#linearGradient10597-5"
inkscape:collect="always" />
<linearGradient
y2="-388.72955"
x2="-93.031357"
y1="-396.34738"
x1="-93.031357"
gradientTransform="matrix(1.5918367,0,0,0.85714285,-256.56122,59.685418)"
gradientUnits="userSpaceOnUse"
id="linearGradient14219-6"
xlink:href="#linearGradient15404-9"
inkscape:collect="always" />
<linearGradient
id="linearGradient15404-9"
inkscape:collect="always">
<stop
id="stop15406-6"
offset="0"
style="stop-color:#515151;stop-opacity:1" />
<stop
id="stop15408-7"
offset="1"
style="stop-color:#292929;stop-opacity:1" />
</linearGradient>
</defs>
<sodipodi:namedview
id="base"
pagecolor="#000000"
bordercolor="#2d2d2d"
borderopacity="1"
inkscape:pageopacity="1"
inkscape:pageshadow="2"
inkscape:zoom="1"
inkscape:cx="71.516955"
inkscape:cy="5.8710559"
inkscape:document-units="px"
inkscape:current-layer="layer1"
showgrid="false"
inkscape:window-width="1412"
inkscape:window-height="1067"
inkscape:window-x="2635"
inkscape:window-y="226"
inkscape:window-maximized="0"
borderlayer="true"
inkscape:showpageshadow="false"
inkscape:snap-nodes="false"
inkscape:snap-bbox="true"
showborder="false">
<inkscape:grid
type="xygrid"
id="grid14843"
empspacing="5"
visible="true"
enabled="true"
snapvisiblegridlinesonly="true" />
</sodipodi:namedview>
<metadata
id="metadata3204">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title></dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<g
inkscape:label="Layer 1"
inkscape:groupmode="layer"
id="layer1"
transform="translate(-342.5,-521.36218)">
<g
transform="matrix(0.80230061,0,0,0.80230061,-87.624044,-453.10297)"
id="g14586-0"
style="stroke-width:2.3714385;stroke-miterlimit:4;stroke-dasharray:none">
<g
inkscape:export-ydpi="90"
inkscape:export-xdpi="90"
inkscape:export-filename="/home/jimmac/SparkleShare/gnome-mockups/boxes/interactive/img/checkbox-on.png"
transform="matrix(1.9969286,0,0,1.9969286,-397.05491,877.00482)"
id="g15291-9-6"
style="stroke-width:1.18754292;stroke-miterlimit:4;stroke-dasharray:none;display:inline;enable-background:new">
<g
transform="translate(877.50354,-102.83507)"
id="g16853-4-9"
style="stroke-width:1.18754292;stroke-miterlimit:4;stroke-dasharray:none;enable-background:new">
<rect
transform="scale(1,-1)"
style="color:#000000;fill:url(#linearGradient14219-6);fill-opacity:1;fill-rule:nonzero;stroke:#3465a4;stroke-width:1.24833274;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:new"
id="rect6506-6"
width="11.281681"
height="11.26221"
x="-409.59354"
y="-284.40115"
rx="1.0052766"
ry="1.0052764" />
</g>
</g>
<g
inkscape:export-ydpi="90"
inkscape:export-xdpi="90"
inkscape:export-filename="/home/jimmac/SparkleShare/gnome-mockups/boxes/interactive/img/checkbox-on.png"
transform="translate(343.99999,987.99997)"
id="g5886-5"
style="stroke-width:2.3714385;stroke-miterlimit:4;stroke-dasharray:none;display:inline;enable-background:new" />
</g>
<g
transform="matrix(0.84337,0,0,0.84337,-110.16632,-503.56182)"
id="g14586">
<g
inkscape:export-ydpi="90"
inkscape:export-xdpi="90"
inkscape:export-filename="/home/jimmac/SparkleShare/gnome-mockups/boxes/interactive/img/checkbox-on.png"
transform="matrix(1.9969286,0,0,1.9969286,-397.05491,877.00482)"
id="g15291-9"
style="display:inline;enable-background:new">
<g
transform="translate(877.50354,-102.83507)"
id="g16853-4"
style="enable-background:new" />
</g>
<g
inkscape:export-ydpi="90"
inkscape:export-xdpi="90"
inkscape:export-filename="/home/jimmac/SparkleShare/gnome-mockups/boxes/interactive/img/checkbox-on.png"
transform="translate(343.99999,987.99997)"
id="g5886"
style="display:inline;enable-background:new">
<path
style="fill:none;stroke:url(#linearGradient5891-0-4);stroke-width:7.11431503;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
d="m 198.5,240 5.25,5.25 13.98616,-14.43081"
id="path5835"
inkscape:path-effect="#path-effect5837-4-6"
inkscape:original-d="m 198.5,240 5.25,5.25 13.98616,-14.43081"
inkscape:connector-curvature="0"
sodipodi:nodetypes="ccc" />
<path
inkscape:connector-curvature="0"
inkscape:original-d="m 198.5,240 5.25,5.25 13.91205,-14.31964"
inkscape:path-effect="#path-effect5837-4-6"
id="path5880"
d="m 198.5,240 5.25,5.25 13.91205,-14.31964"
style="fill:none;stroke:#4787c8;stroke-width:3.55715752;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
sodipodi:nodetypes="ccc" />
<path
style="fill:none;stroke:#7ea7d3;stroke-width:1.18571913px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m 197.45937,240.47455 c -0.17828,-0.29362 -0.20087,-0.67548 -0.0603,-0.98892 0.14055,-0.31344 0.43739,-0.54812 0.77144,-0.62817 0.33405,-0.08 0.69314,-0.01 0.99635,0.15175 0.30321,0.16144 0.55146,0.40727 0.79165,0.65284 l 3.66429,3.74643 12.87946,-12.98973 c 0.20796,-0.20974 0.42306,-0.41969 0.68548,-0.55522 0.26242,-0.13553 0.57293,-0.19052 0.85827,-0.11426 0.14267,0.0381 0.27708,0.10787 0.38874,0.20452 0.11167,0.0966 0.20021,0.22004 0.25479,0.35726 0.0546,0.13722 0.075,0.28793 0.0585,0.43468 -0.0165,0.14674 -0.07,0.28919 -0.15422,0.41052"
id="path5882"
inkscape:path-effect="#path-effect5884-4-7"
inkscape:original-d="m 197.45937,240.47455 c 0.65604,-0.56057 2.02485,-1.34847 2.49911,-0.8125 l 3.66429,3.74643 12.87946,-12.98973 c 0.6875,-0.6875 2.09152,0.7375 2.09152,0.7375"
inkscape:connector-curvature="0"
sodipodi:nodetypes="csccc" />
</g>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 11 KiB

View File

@ -0,0 +1,198 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="24"
height="22"
id="svg3199"
version="1.1"
inkscape:version="0.48.1 r9760"
sodipodi:docname="checkbox-off.svg">
<defs
id="defs3201">
<linearGradient
id="linearGradient15404"
inkscape:collect="always">
<stop
id="stop15406"
offset="0"
style="stop-color:#515151;stop-opacity:1" />
<stop
id="stop15408"
offset="1"
style="stop-color:#292929;stop-opacity:1" />
</linearGradient>
<inkscape:perspective
sodipodi:type="inkscape:persp3d"
inkscape:vp_x="0 : 526.18109 : 1"
inkscape:vp_y="0 : 1000 : 0"
inkscape:vp_z="744.09448 : 526.18109 : 1"
inkscape:persp3d-origin="372.04724 : 350.78739 : 1"
id="perspective3207" />
<inkscape:perspective
id="perspective3187"
inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
inkscape:vp_z="1 : 0.5 : 1"
inkscape:vp_y="0 : 1000 : 0"
inkscape:vp_x="0 : 0.5 : 1"
sodipodi:type="inkscape:persp3d" />
<inkscape:path-effect
effect="spiro"
id="path-effect5837-4-6"
is_visible="true" />
<inkscape:path-effect
effect="spiro"
id="path-effect14768"
is_visible="true" />
<inkscape:path-effect
effect="spiro"
id="path-effect5884-4-7"
is_visible="true" />
<linearGradient
y2="-388.72955"
x2="-93.031357"
y1="-396.34738"
x1="-93.031357"
gradientTransform="matrix(1.5918367,0,0,0.85714285,-256.56122,59.685418)"
gradientUnits="userSpaceOnUse"
id="linearGradient14219"
xlink:href="#linearGradient15404"
inkscape:collect="always" />
<linearGradient
inkscape:collect="always"
id="linearGradient10013-4-63-6">
<stop
style="stop-color:#333333;stop-opacity:1;"
offset="0"
id="stop10015-2-76-1" />
<stop
style="stop-color:#292929;stop-opacity:1"
offset="1"
id="stop10017-46-15-8" />
</linearGradient>
<linearGradient
inkscape:collect="always"
id="linearGradient10597-5">
<stop
style="stop-color:#16191a;stop-opacity:1;"
offset="0"
id="stop10599-2" />
<stop
style="stop-color:#2b3133;stop-opacity:1"
offset="1"
id="stop10601-5" />
</linearGradient>
<linearGradient
y2="-322.16354"
x2="921.22498"
y1="-330.05121"
x1="921.32812"
gradientTransform="matrix(1.5918367,0,0,0.85714285,-1456.5464,275.45191)"
gradientUnits="userSpaceOnUse"
id="linearGradient15374"
xlink:href="#linearGradient10013-4-63-6"
inkscape:collect="always" />
<linearGradient
gradientTransform="translate(-1199.9852,216.38048)"
y2="-227.07961"
x2="1203.9177"
y1="-217.56708"
x1="1203.9177"
gradientUnits="userSpaceOnUse"
id="linearGradient15376"
xlink:href="#linearGradient10597-5"
inkscape:collect="always" />
</defs>
<sodipodi:namedview
id="base"
pagecolor="#000000"
bordercolor="#2d2d2d"
borderopacity="1"
inkscape:pageopacity="1"
inkscape:pageshadow="2"
inkscape:zoom="1"
inkscape:cx="6.1225392"
inkscape:cy="3.6003241"
inkscape:document-units="px"
inkscape:current-layer="layer1"
showgrid="false"
inkscape:window-width="1412"
inkscape:window-height="1067"
inkscape:window-x="2116"
inkscape:window-y="261"
inkscape:window-maximized="0"
borderlayer="true"
inkscape:showpageshadow="false"
inkscape:snap-nodes="false"
inkscape:snap-bbox="true"
showborder="false">
<inkscape:grid
type="xygrid"
id="grid14843"
empspacing="5"
visible="true"
enabled="true"
snapvisiblegridlinesonly="true" />
</sodipodi:namedview>
<metadata
id="metadata3204">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title></dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<g
inkscape:label="Layer 1"
inkscape:groupmode="layer"
id="layer1"
transform="translate(-342.5,-521.36218)">
<g
transform="matrix(0.80230061,0,0,0.80230061,-87.624044,-453.10297)"
id="g14586"
style="stroke-width:2.3714385;stroke-miterlimit:4;stroke-dasharray:none">
<g
inkscape:export-ydpi="90"
inkscape:export-xdpi="90"
inkscape:export-filename="/home/jimmac/SparkleShare/gnome-mockups/boxes/interactive/img/checkbox-on.png"
transform="matrix(1.9969286,0,0,1.9969286,-397.05491,877.00482)"
id="g15291-9"
style="stroke-width:1.18754292;stroke-miterlimit:4;stroke-dasharray:none;display:inline;enable-background:new">
<g
transform="translate(877.50354,-102.83507)"
id="g16853-4"
style="stroke-width:1.18754292;stroke-miterlimit:4;stroke-dasharray:none;enable-background:new">
<rect
transform="scale(1,-1)"
style="color:#000000;fill:url(#linearGradient14219);fill-opacity:1;fill-rule:nonzero;stroke:#3465a4;stroke-width:1.24833274;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:new"
id="rect6506-6"
width="11.281681"
height="11.26221"
x="-409.59354"
y="-284.40115"
rx="1.0052766"
ry="1.0052764" />
</g>
</g>
<g
inkscape:export-ydpi="90"
inkscape:export-xdpi="90"
inkscape:export-filename="/home/jimmac/SparkleShare/gnome-mockups/boxes/interactive/img/checkbox-on.png"
transform="translate(343.99999,987.99997)"
id="g5886"
style="stroke-width:2.3714385;stroke-miterlimit:4;stroke-dasharray:none;display:inline;enable-background:new" />
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 6.5 KiB

218
data/theme/checkbox-off.svg Normal file
View File

@ -0,0 +1,218 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="24"
height="22"
id="svg3199"
version="1.1"
inkscape:version="0.48.1 r9760"
sodipodi:docname="checkbox.svg">
<defs
id="defs3201">
<linearGradient
id="linearGradient15404"
inkscape:collect="always">
<stop
id="stop15406"
offset="0"
style="stop-color:#515151;stop-opacity:1" />
<stop
id="stop15408"
offset="1"
style="stop-color:#292929;stop-opacity:1" />
</linearGradient>
<inkscape:perspective
sodipodi:type="inkscape:persp3d"
inkscape:vp_x="0 : 526.18109 : 1"
inkscape:vp_y="0 : 1000 : 0"
inkscape:vp_z="744.09448 : 526.18109 : 1"
inkscape:persp3d-origin="372.04724 : 350.78739 : 1"
id="perspective3207" />
<inkscape:perspective
id="perspective3187"
inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
inkscape:vp_z="1 : 0.5 : 1"
inkscape:vp_y="0 : 1000 : 0"
inkscape:vp_x="0 : 0.5 : 1"
sodipodi:type="inkscape:persp3d" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient5872-5-1"
id="linearGradient5891-0-4"
gradientUnits="userSpaceOnUse"
x1="205.84143"
y1="246.7094"
x2="206.74803"
y2="231.24142" />
<linearGradient
inkscape:collect="always"
id="linearGradient5872-5-1">
<stop
style="stop-color:#0b2e52;stop-opacity:1"
offset="0"
id="stop5874-4-4" />
<stop
style="stop-color:#1862af;stop-opacity:1"
offset="1"
id="stop5876-0-5" />
</linearGradient>
<inkscape:path-effect
effect="spiro"
id="path-effect5837-4-6"
is_visible="true" />
<inkscape:path-effect
effect="spiro"
id="path-effect14768"
is_visible="true" />
<inkscape:path-effect
effect="spiro"
id="path-effect5884-4-7"
is_visible="true" />
<linearGradient
y2="-388.72955"
x2="-93.031357"
y1="-396.34738"
x1="-93.031357"
gradientTransform="matrix(1.5918367,0,0,0.85714285,-256.56122,59.685418)"
gradientUnits="userSpaceOnUse"
id="linearGradient14219"
xlink:href="#linearGradient15404"
inkscape:collect="always" />
<linearGradient
inkscape:collect="always"
id="linearGradient10013-4-63-6">
<stop
style="stop-color:#333333;stop-opacity:1;"
offset="0"
id="stop10015-2-76-1" />
<stop
style="stop-color:#292929;stop-opacity:1"
offset="1"
id="stop10017-46-15-8" />
</linearGradient>
<linearGradient
inkscape:collect="always"
id="linearGradient10597-5">
<stop
style="stop-color:#16191a;stop-opacity:1;"
offset="0"
id="stop10599-2" />
<stop
style="stop-color:#2b3133;stop-opacity:1"
offset="1"
id="stop10601-5" />
</linearGradient>
<linearGradient
y2="-322.16354"
x2="921.22498"
y1="-330.05121"
x1="921.32812"
gradientTransform="matrix(1.5918367,0,0,0.85714285,-1456.5464,275.45191)"
gradientUnits="userSpaceOnUse"
id="linearGradient15374"
xlink:href="#linearGradient10013-4-63-6"
inkscape:collect="always" />
<linearGradient
gradientTransform="translate(-1199.9852,216.38048)"
y2="-227.07961"
x2="1203.9177"
y1="-217.56708"
x1="1203.9177"
gradientUnits="userSpaceOnUse"
id="linearGradient15376"
xlink:href="#linearGradient10597-5"
inkscape:collect="always" />
</defs>
<sodipodi:namedview
id="base"
pagecolor="#000000"
bordercolor="#2d2d2d"
borderopacity="1"
inkscape:pageopacity="1"
inkscape:pageshadow="2"
inkscape:zoom="4"
inkscape:cx="71.247925"
inkscape:cy="33.339093"
inkscape:document-units="px"
inkscape:current-layer="layer1"
showgrid="false"
inkscape:window-width="1412"
inkscape:window-height="1067"
inkscape:window-x="2116"
inkscape:window-y="261"
inkscape:window-maximized="0"
borderlayer="true"
inkscape:showpageshadow="false"
inkscape:snap-nodes="false"
inkscape:snap-bbox="true"
showborder="false">
<inkscape:grid
type="xygrid"
id="grid14843"
empspacing="5"
visible="true"
enabled="true"
snapvisiblegridlinesonly="true" />
</sodipodi:namedview>
<metadata
id="metadata3204">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title></dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<g
inkscape:label="Layer 1"
inkscape:groupmode="layer"
id="layer1"
transform="translate(-342.5,-521.36218)">
<g
transform="matrix(0.84337,0,0,0.84337,-110.16632,-503.56182)"
id="g14586">
<g
inkscape:export-ydpi="90"
inkscape:export-xdpi="90"
inkscape:export-filename="/home/jimmac/SparkleShare/gnome-mockups/boxes/interactive/img/checkbox-on.png"
transform="matrix(1.9969286,0,0,1.9969286,-397.05491,877.00482)"
id="g15291-9"
style="display:inline;enable-background:new">
<g
transform="translate(877.50354,-102.83507)"
id="g16853-4"
style="enable-background:new">
<rect
transform="scale(1,-1)"
style="color:#000000;fill:url(#linearGradient14219);fill-opacity:1;fill-rule:nonzero;stroke:#868686;stroke-width:0.59377144999999998;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:new"
id="rect6506-6"
width="11.281681"
height="11.26221"
x="-409.59354"
y="-284.40115"
rx="0.95632279"
ry="0.95632273" />
</g>
</g>
<g
inkscape:export-ydpi="90"
inkscape:export-xdpi="90"
inkscape:export-filename="/home/jimmac/SparkleShare/gnome-mockups/boxes/interactive/img/checkbox-on.png"
transform="translate(343.99999,987.99997)"
id="g5886"
style="display:inline;enable-background:new" />
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 6.8 KiB

243
data/theme/checkbox.svg Normal file
View File

@ -0,0 +1,243 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="24"
height="22"
id="svg3199"
version="1.1"
inkscape:version="0.48.1 r9760"
sodipodi:docname="checkbox-focused.svg">
<defs
id="defs3201">
<linearGradient
id="linearGradient15404"
inkscape:collect="always">
<stop
id="stop15406"
offset="0"
style="stop-color:#515151;stop-opacity:1" />
<stop
id="stop15408"
offset="1"
style="stop-color:#292929;stop-opacity:1" />
</linearGradient>
<inkscape:perspective
sodipodi:type="inkscape:persp3d"
inkscape:vp_x="0 : 526.18109 : 1"
inkscape:vp_y="0 : 1000 : 0"
inkscape:vp_z="744.09448 : 526.18109 : 1"
inkscape:persp3d-origin="372.04724 : 350.78739 : 1"
id="perspective3207" />
<inkscape:perspective
id="perspective3187"
inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
inkscape:vp_z="1 : 0.5 : 1"
inkscape:vp_y="0 : 1000 : 0"
inkscape:vp_x="0 : 0.5 : 1"
sodipodi:type="inkscape:persp3d" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient5872-5-1"
id="linearGradient5891-0-4"
gradientUnits="userSpaceOnUse"
x1="205.84143"
y1="246.7094"
x2="206.74803"
y2="231.24142" />
<linearGradient
inkscape:collect="always"
id="linearGradient5872-5-1">
<stop
style="stop-color:#0b2e52;stop-opacity:1"
offset="0"
id="stop5874-4-4" />
<stop
style="stop-color:#1862af;stop-opacity:1"
offset="1"
id="stop5876-0-5" />
</linearGradient>
<inkscape:path-effect
effect="spiro"
id="path-effect5837-4-6"
is_visible="true" />
<inkscape:path-effect
effect="spiro"
id="path-effect14768"
is_visible="true" />
<inkscape:path-effect
effect="spiro"
id="path-effect5884-4-7"
is_visible="true" />
<linearGradient
y2="-388.72955"
x2="-93.031357"
y1="-396.34738"
x1="-93.031357"
gradientTransform="matrix(1.5918367,0,0,0.85714285,-256.56122,59.685418)"
gradientUnits="userSpaceOnUse"
id="linearGradient14219"
xlink:href="#linearGradient15404"
inkscape:collect="always" />
<linearGradient
inkscape:collect="always"
id="linearGradient10013-4-63-6">
<stop
style="stop-color:#333333;stop-opacity:1;"
offset="0"
id="stop10015-2-76-1" />
<stop
style="stop-color:#292929;stop-opacity:1"
offset="1"
id="stop10017-46-15-8" />
</linearGradient>
<linearGradient
inkscape:collect="always"
id="linearGradient10597-5">
<stop
style="stop-color:#16191a;stop-opacity:1;"
offset="0"
id="stop10599-2" />
<stop
style="stop-color:#2b3133;stop-opacity:1"
offset="1"
id="stop10601-5" />
</linearGradient>
<linearGradient
y2="-322.16354"
x2="921.22498"
y1="-330.05121"
x1="921.32812"
gradientTransform="matrix(1.5918367,0,0,0.85714285,-1456.5464,275.45191)"
gradientUnits="userSpaceOnUse"
id="linearGradient15374"
xlink:href="#linearGradient10013-4-63-6"
inkscape:collect="always" />
<linearGradient
gradientTransform="translate(-1199.9852,216.38048)"
y2="-227.07961"
x2="1203.9177"
y1="-217.56708"
x1="1203.9177"
gradientUnits="userSpaceOnUse"
id="linearGradient15376"
xlink:href="#linearGradient10597-5"
inkscape:collect="always" />
</defs>
<sodipodi:namedview
id="base"
pagecolor="#000000"
bordercolor="#2d2d2d"
borderopacity="1"
inkscape:pageopacity="1"
inkscape:pageshadow="2"
inkscape:zoom="1"
inkscape:cx="64.516955"
inkscape:cy="13.871056"
inkscape:document-units="px"
inkscape:current-layer="layer1"
showgrid="false"
inkscape:window-width="1412"
inkscape:window-height="1067"
inkscape:window-x="2635"
inkscape:window-y="226"
inkscape:window-maximized="0"
borderlayer="true"
inkscape:showpageshadow="false"
inkscape:snap-nodes="false"
inkscape:snap-bbox="true"
showborder="false">
<inkscape:grid
type="xygrid"
id="grid14843"
empspacing="5"
visible="true"
enabled="true"
snapvisiblegridlinesonly="true" />
</sodipodi:namedview>
<metadata
id="metadata3204">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title></dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<g
inkscape:label="Layer 1"
inkscape:groupmode="layer"
id="layer1"
transform="translate(-342.5,-521.36218)">
<g
transform="matrix(0.84337,0,0,0.84337,-110.16632,-503.56182)"
id="g14586">
<g
inkscape:export-ydpi="90"
inkscape:export-xdpi="90"
inkscape:export-filename="/home/jimmac/SparkleShare/gnome-mockups/boxes/interactive/img/checkbox-on.png"
transform="matrix(1.9969286,0,0,1.9969286,-397.05491,877.00482)"
id="g15291-9"
style="display:inline;enable-background:new">
<g
transform="translate(877.50354,-102.83507)"
id="g16853-4"
style="enable-background:new">
<rect
transform="scale(1,-1)"
style="color:#000000;fill:url(#linearGradient14219);fill-opacity:1;fill-rule:nonzero;stroke:#868686;stroke-width:0.59377144999999998;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:new"
id="rect6506-6"
width="11.281681"
height="11.26221"
x="-409.59354"
y="-284.40115"
rx="0.95632279"
ry="0.95632273" />
</g>
</g>
<g
inkscape:export-ydpi="90"
inkscape:export-xdpi="90"
inkscape:export-filename="/home/jimmac/SparkleShare/gnome-mockups/boxes/interactive/img/checkbox-on.png"
transform="translate(343.99999,987.99997)"
id="g5886"
style="display:inline;enable-background:new">
<path
style="fill:none;stroke:url(#linearGradient5891-0-4);stroke-width:7.11431503;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
d="m 198.5,240 5.25,5.25 13.98616,-14.43081"
id="path5835"
inkscape:path-effect="#path-effect5837-4-6"
inkscape:original-d="m 198.5,240 5.25,5.25 13.98616,-14.43081"
inkscape:connector-curvature="0"
sodipodi:nodetypes="ccc" />
<path
inkscape:connector-curvature="0"
inkscape:original-d="m 198.5,240 5.25,5.25 13.91205,-14.31964"
inkscape:path-effect="#path-effect5837-4-6"
id="path5880"
d="m 198.5,240 5.25,5.25 13.91205,-14.31964"
style="fill:none;stroke:#4787c8;stroke-width:3.55715752;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
sodipodi:nodetypes="ccc" />
<path
style="fill:none;stroke:#7ea7d3;stroke-width:1.18571913px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m 197.45937,240.47455 c -0.17828,-0.29362 -0.20087,-0.67548 -0.0603,-0.98892 0.14055,-0.31344 0.43739,-0.54812 0.77144,-0.62817 0.33405,-0.08 0.69314,-0.01 0.99635,0.15175 0.30321,0.16144 0.55146,0.40727 0.79165,0.65284 l 3.66429,3.74643 12.87946,-12.98973 c 0.20796,-0.20974 0.42306,-0.41969 0.68548,-0.55522 0.26242,-0.13553 0.57293,-0.19052 0.85827,-0.11426 0.14267,0.0381 0.27708,0.10787 0.38874,0.20452 0.11167,0.0966 0.20021,0.22004 0.25479,0.35726 0.0546,0.13722 0.075,0.28793 0.0585,0.43468 -0.0165,0.14674 -0.07,0.28919 -0.15422,0.41052"
id="path5882"
inkscape:path-effect="#path-effect5884-4-7"
inkscape:original-d="m 197.45937,240.47455 c 0.65604,-0.56057 2.02485,-1.34847 2.49911,-0.8125 l 3.66429,3.74643 12.87946,-12.98973 c 0.6875,-0.6875 2.09152,0.7375 2.09152,0.7375"
inkscape:connector-curvature="0"
sodipodi:nodetypes="csccc" />
</g>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 8.8 KiB

View File

@ -60,7 +60,6 @@ StScrollBar StBin#trough {
StScrollBar StButton#vhandle
{
background-image: url("scroll-vhandle.svg");
background-size: contain;
background-color: #252525;
border: 1px solid #080808;
border-radius: 8px;
@ -69,7 +68,6 @@ StScrollBar StButton#vhandle
StScrollBar StButton#hhandle
{
background-image: url("scroll-hhandle.svg");
background-size: contain;
background-color: #252525;
border: 1px solid #080808;
border-radius: 8px;
@ -81,15 +79,26 @@ StScrollBar StButton#vhandle:hover
background-color: #292929;
}
StTooltip StLabel {
border: 1px solid rgba(255,255,255,0.6);
border-radius: 5px;
padding: 2px 12px;
background-color: rgba(0,0,0,0.9);
color: #ffffff;
font-size: 0.8em;
font-weight: normal;
text-align: center;
.check-box ShellGenericContainer {
spacing: .8em;
}
.check-box StBin {
width: 24px;
height: 22px;
background-image: url("checkbox-off.svg");
}
.check-box:focus StBin {
background-image: url("checkbox-off-focused.svg");
}
.check-box:checked StBin {
background-image: url("checkbox.svg");
}
.check-box:focus:checked StBin {
background-image: url("checkbox-focused.svg");
}
/* PopupMenu */
@ -284,7 +293,6 @@ StTooltip StLabel {
#panel {
color: #ffffff;
background-color: black;
border-image: url("panel-border.svg") 1;
font-size: 10.5pt;
font-weight: bold;
height: 1.86em;
@ -313,16 +321,14 @@ StTooltip StLabel {
.panel-corner {
-panel-corner-radius: 10px;
-panel-corner-background-color: black;
-panel-corner-inner-border-width: 2px;
-panel-corner-inner-border-color: transparent;
-panel-corner-outer-border-width: 1px;
-panel-corner-outer-border-color: #536272;
-panel-corner-border-width: 2px;
-panel-corner-border-color: transparent;
}
.panel-corner:active,
.panel-corner:overview,
.panel-corner:focus {
-panel-corner-inner-border-color: rgba(255,255,255,0.8);
-panel-corner-border-color: rgba(255,255,255,0.8);
}
#appMenu {
@ -362,7 +368,6 @@ StTooltip StLabel {
.panel-button:focus {
border-image: url("panel-button-border.svg") 10 10 0 2;
background-image: url("panel-button-highlight-wide.svg");
background-size: contain;
color: white;
text-shadow: black 0px 2px 2px;
}
@ -371,7 +376,6 @@ StTooltip StLabel {
.panel-status-button:checked,
.panel-status-button:focus {
background-image: url("panel-button-highlight-narrow.svg");
background-size: contain;
}
.panel-button:active > .system-status-icon,
@ -479,7 +483,7 @@ StTooltip StLabel {
border-radius: 8px;
font-size: 9pt;
font-weight: bold;
padding: 6px 12px;
padding: 4px 12px;
-shell-caption-spacing: 12px;
}
@ -670,12 +674,14 @@ StTooltip StLabel {
.icon-grid {
spacing: 36px;
-shell-grid-item-size: 118px;
-shell-grid-horizontal-item-size: 118px;
-shell-grid-vertical-item-size: 118px;
}
.contact-grid {
spacing: 36px;
-shell-grid-item-size: 272px; /* 2 * -shell-grid-item-size + spacing */
-shell-grid-horizontal-item-size: 272px; /* 2 * -shell-grid-horizontal-item-size + spacing */
-shell-grid-vertical-item-size: 118px;
}
.icon-grid .overview-icon {
@ -707,13 +713,11 @@ StTooltip StLabel {
.app-filter:selected {
color: #ffffff;
background-image: url("filter-selected-ltr.svg");
background-size: contain;
background-position: 190px 10px;
}
.app-filter:selected:rtl {
background-image: url("filter-selected-rtl.svg");
background-size: contain;
background-position: 10px 10px;
}
@ -757,13 +761,12 @@ StTooltip StLabel {
}
.contact-content {
border-radius: 2px;
border-radius: 7px;
padding: 8px;
width: 232px;
height: 84px;
background-color: white;
color: black;
text-align: center;
background-color: rgba(0.0, 0.0, 0.0, 0.5);
color: white;
}
.contact-icon {
@ -771,20 +774,20 @@ StTooltip StLabel {
}
.contact-details {
padding: 6px 8px 11px 8px;
padding: 0px 6px 22px 10px;
}
.contact-details-alias {
font-size: 16px;
padding-bottom: 11px;
font-size: 18px;
padding-bottom: 8px;
}
.contact-details-status {
font-size: 11pt;
font-size: 10pt;
}
.contact-details-status-icon {
padding-right: 2px;
padding-right: 4px;
}
.contact:hover {
@ -1624,7 +1627,6 @@ StTooltip StLabel {
border: 0px;
background: rgba(255,255,255,0.5);
background-image: url("ws-switch-arrow-up.svg");
background-size: contain;
border-radius: 8px;
}
@ -1633,7 +1635,6 @@ StTooltip StLabel {
border: 0px;
background: rgba(255,255,255,0.5);
background-image: url("ws-switch-arrow-down.svg");
background-size: contain;
border-radius: 8px;
}
@ -1718,6 +1719,10 @@ StTooltip StLabel {
background-color: rgba(0, 0, 0, 0.4);
}
.flashspot {
background-color: white;
}
/* End Session Dialog */
.end-session-dialog {
spacing: 42px;
@ -1830,6 +1835,10 @@ StTooltip StLabel {
padding-bottom: 6px;
}
.mount-question-dialog-subject {
max-width: 500px;
}
.show-processes-dialog-subject:rtl,
.mount-question-dialog-subject:rtl {
padding-left: 0px;
@ -1890,32 +1899,80 @@ StTooltip StLabel {
font-size: 10pt;
}
/* PolicyKit Authentication Dialog */
.polkit-dialog {
/* Password or Authentication Dialog */
.prompt-dialog {
/* this is the width of the entire modal popup */
width: 500px;
}
.polkit-dialog-main-layout {
.prompt-dialog-main-layout {
spacing: 24px;
padding: 10px;
}
.polkit-dialog-message-layout {
.prompt-dialog-message-layout {
spacing: 16px;
}
.polkit-dialog-headline {
.prompt-dialog-headline {
font-size: 12pt;
font-weight: bold;
color: #666666;
}
.polkit-dialog-description {
.prompt-dialog-description {
font-size: 10pt;
color: white;
}
.prompt-dialog-password-label:ltr {
padding-right: 0.5em;
}
.prompt-dialog-password-label:rtl {
padding-left: 0.5em;
}
.prompt-dialog-password-entry {
background-gradient-start: rgb(236,236,236);
background-gradient-end: white;
background-gradient-direction: vertical;
color: black;
selected-color: white;
border-radius: 5px;
border: 2px solid #555753;
}
.prompt-dialog-password-entry:focus {
border: 2px solid #3465a4;
}
.prompt-dialog-password-entry .capslock-warning {
icon-size: 16px;
warning-color: #999;
padding: 0 4px;
}
.prompt-dialog-error-label {
font-size: 10pt;
color: #ffff00;
padding-bottom: 8px;
}
.prompt-dialog-info-label {
font-size: 10pt;
padding-bottom: 8px;
}
/* intentionally left transparent to avoid dialog changing size */
.prompt-dialog-null-label {
font-size: 10pt;
color: rgba(0,0,0,0);
padding-bottom: 8px;
}
/* Polkit Dialog */
.polkit-dialog-user-layout {
padding-left: 10px;
spacing: 10px;
@ -1930,51 +1987,7 @@ StTooltip StLabel {
color: #ff0000;
}
.polkit-dialog-password-label:ltr {
padding-right: 0.5em;
}
.polkit-dialog-password-label:rtl {
padding-left: 0.5em;
}
.polkit-dialog-password-entry {
background-gradient-start: rgb(236,236,236);
background-gradient-end: white;
background-gradient-direction: vertical;
color: black;
selected-color: white;
border-radius: 5px;
border: 2px solid #555753;
}
.polkit-dialog-password-entry:focus {
border: 2px solid #3465a4;
}
.polkit-dialog-password-entry .capslock-warning {
icon-size: 16px;
warning-color: #999;
padding: 0 4px;
}
.polkit-dialog-error-label {
font-size: 10pt;
color: #ffff00;
padding-bottom: 8px;
}
.polkit-dialog-info-label {
font-size: 10pt;
padding-bottom: 8px;
}
/* intentionally left transparent to avoid dialog changing size */
.polkit-dialog-null-label {
font-size: 10pt;
color: rgba(0,0,0,0);
padding-bottom: 8px;
}
/* Network Agent Dialog */
.network-dialog-secret-table {
spacing-rows: 15px;

View File

@ -1,33 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
width="3"
height="10"
id="svg2"
version="1.1">
<defs
id="defs4" />
<metadata
id="metadata7">
</metadata>
<g
id="layer1">
<rect
style="fill:#000000;fill-opacity:1;stroke-width:0.43599999000000000;stroke-miterlimit:4;stroke-dasharray:none"
id="rect3779"
width="3"
height="10"
x="0"
y="0" />
<rect
style="fill:#536272;fill-opacity:1;stroke-width:0.43599999;stroke-miterlimit:4;stroke-dasharray:none"
id="rect3796"
width="3"
height="1"
x="0"
y="9" />
</g>
</svg>

Before

Width:  |  Height:  |  Size: 787 B

View File

@ -30,14 +30,12 @@
<xi:include href="xml/st-entry.xml"/>
<xi:include href="xml/st-icon.xml"/>
<xi:include href="xml/st-label.xml"/>
<xi:include href="xml/st-tooltip.xml"/>
</chapter>
<chapter id="containers">
<title>Containers</title>
<xi:include href="xml/st-bin.xml"/>
<xi:include href="xml/st-box-layout.xml"/>
<xi:include href="xml/st-group.xml"/>
<xi:include href="xml/st-overflow-box.xml"/>
<xi:include href="xml/st-scroll-view.xml"/>
<xi:include href="xml/st-table.xml"/>
</chapter>

View File

@ -1,4 +1,20 @@
EXTRA_DIST = misc/config.js.in
CLEANFILES = misc/config.js
misc/config.js: misc/config.js.in Makefile
[ -d $(@D) ] || $(mkdir_p) $(@D) ; \
sed -e "s|[@]PACKAGE_NAME@|$(PACKAGE_NAME)|g" \
-e "s|[@]PACKAGE_VERSION@|$(PACKAGE_VERSION)|g" \
-e "s|[@]GJS_VERSION@|$(GJS_VERSION)|g" \
-e "s|[@]HAVE_BLUETOOTH@|$(HAVE_BLUETOOTH)|g" \
-e "s|[@]SHELL_SYSTEM_CA_FILE@|$(SHELL_SYSTEM_CA_FILE)|g" \
-e "s|[@]GETTEXT_PACKAGE@|$(GETTEXT_PACKAGE)|g" \
-e "s|[@]datadir@|$(datadir)|g" \
-e "s|[@]libexecdir@|$(libexecdir)|g" \
-e "s|[@]sysconfdir@|$(sysconfdir)|g" \
$< > $@
jsdir = $(pkgdatadir)/js
nobase_dist_js_DATA = \
@ -7,8 +23,10 @@ nobase_dist_js_DATA = \
gdm/fingerprint.js \
gdm/loginDialog.js \
gdm/powerMenu.js \
gdm/systemd.js \
extensionPrefs/main.js \
misc/config.js \
misc/docInfo.js \
misc/extensionUtils.js \
misc/fileUtils.js \
misc/format.js \
misc/gnomeSession.js \
@ -26,15 +44,16 @@ nobase_dist_js_DATA = \
ui/autorunManager.js \
ui/boxpointer.js \
ui/calendar.js \
ui/checkBox.js \
ui/contactDisplay.js \
ui/ctrlAltTab.js \
ui/dash.js \
ui/dateMenu.js \
ui/dnd.js \
ui/docDisplay.js \
ui/endSessionDialog.js \
ui/environment.js \
ui/extensionSystem.js \
ui/flashspot.js \
ui/iconGrid.js \
ui/keyboard.js \
ui/layout.js \
@ -56,6 +75,7 @@ nobase_dist_js_DATA = \
ui/placeDisplay.js \
ui/polkitAuthenticationAgent.js \
ui/popupMenu.js \
ui/remoteSearch.js \
ui/runDialog.js \
ui/scripting.js \
ui/search.js \

278
js/extensionPrefs/main.js Normal file
View File

@ -0,0 +1,278 @@
const Lang = imports.lang;
const Gettext = imports.gettext;
const GLib = imports.gi.GLib;
const GObject = imports.gi.GObject;
const Gio = imports.gi.Gio;
const Gtk = imports.gi.Gtk;
const Pango = imports.gi.Pango;
const _ = Gettext.gettext;
const Config = imports.misc.config;
const Format = imports.misc.format;
const ExtensionUtils = imports.misc.extensionUtils;
const GnomeShellIface = <interface name="org.gnome.Shell">
<signal name="ExtensionStatusChanged">
<arg type="s" name="uuid"/>
<arg type="i" name="state"/>
<arg type="s" name="error"/>
</signal>
</interface>;
const GnomeShellProxy = Gio.DBusProxy.makeProxyWrapper(GnomeShellIface);
function stripPrefix(string, prefix) {
if (string.slice(0, prefix.length) == prefix)
return string.slice(prefix.length);
return string;
}
const Application = new Lang.Class({
Name: 'Application',
_init: function() {
GLib.set_prgname('gnome-shell-extension-prefs');
this.application = new Gtk.Application({
application_id: 'org.gnome.shell.ExtensionPrefs',
flags: Gio.ApplicationFlags.HANDLES_COMMAND_LINE
});
this.application.connect('activate', Lang.bind(this, this._onActivate));
this.application.connect('command-line', Lang.bind(this, this._onCommandLine));
this.application.connect('startup', Lang.bind(this, this._onStartup));
this._extensionPrefsModules = {};
this._extensionIters = {};
},
_buildModel: function() {
this._model = new Gtk.ListStore();
this._model.set_column_types([GObject.TYPE_STRING, GObject.TYPE_STRING]);
},
_extensionAvailable: function(uuid) {
let extension = ExtensionUtils.extensions[uuid];
if (!extension)
return false;
if (ExtensionUtils.isOutOfDate(extension))
return false;
if (!extension.dir.get_child('prefs.js').query_exists(null))
return false;
return true;
},
_setExtensionInsensitive: function(layout, cell, model, iter, data) {
let uuid = model.get_value(iter, 0);
cell.set_sensitive(this._extensionAvailable(uuid));
},
_getExtensionPrefsModule: function(extension) {
let uuid = extension.metadata.uuid;
if (this._extensionPrefsModules.hasOwnProperty(uuid))
return this._extensionPrefsModules[uuid];
ExtensionUtils.installImporter(extension);
let prefsModule = extension.imports.prefs;
prefsModule.init(extension.metadata);
this._extensionPrefsModules[uuid] = prefsModule;
return prefsModule;
},
_selectExtension: function(uuid) {
if (!this._extensionAvailable(uuid))
return;
let extension = ExtensionUtils.extensions[uuid];
let widget;
try {
let prefsModule = this._getExtensionPrefsModule(extension);
widget = prefsModule.buildPrefsWidget();
} catch (e) {
widget = this._buildErrorUI(extension, e);
}
// Destroy the current prefs widget, if it exists
if (this._extensionPrefsBin.get_child())
this._extensionPrefsBin.get_child().destroy();
this._extensionPrefsBin.add(widget);
this._extensionSelector.set_active_iter(this._extensionIters[uuid]);
},
_extensionSelected: function() {
let [success, iter] = this._extensionSelector.get_active_iter();
if (!success)
return;
let uuid = this._model.get_value(iter, 0);
this._selectExtension(uuid);
},
_buildErrorUI: function(extension, exc) {
let box = new Gtk.Box({ orientation: Gtk.Orientation.VERTICAL });
let label = new Gtk.Label({
label: _("There was an error loading the preferences dialog for %s:").format(extension.metadata.name)
});
box.add(label);
let errortext = '';
errortext += exc;
errortext += '\n\n';
errortext += 'Stack trace:\n';
// Indent stack trace.
errortext += exc.stack.split('\n').map(function(line) {
return ' ' + line;
}).join('\n');
let scroll = new Gtk.ScrolledWindow({ vexpand: true });
let buffer = new Gtk.TextBuffer({ text: errortext });
let textview = new Gtk.TextView({ buffer: buffer });
textview.override_font(Pango.font_description_from_string('monospace'));
scroll.add(textview);
box.add(scroll);
box.show_all();
return box;
},
_buildUI: function(app) {
this._window = new Gtk.ApplicationWindow({ application: app,
window_position: Gtk.WindowPosition.CENTER,
title: _("GNOME Shell Extension Preferences") });
this._window.set_size_request(600, 400);
let vbox = new Gtk.Box({ orientation: Gtk.Orientation.VERTICAL });
this._window.add(vbox);
let toolbar = new Gtk.Toolbar();
toolbar.get_style_context().add_class(Gtk.STYLE_CLASS_PRIMARY_TOOLBAR);
vbox.add(toolbar);
let toolitem;
let label = new Gtk.Label({ label: _("<b>Extension</b>"),
use_markup: true });
toolitem = new Gtk.ToolItem({ child: label });
toolbar.add(toolitem);
this._extensionSelector = new Gtk.ComboBox({ model: this._model,
margin_left: 8,
hexpand: true });
this._extensionSelector.get_style_context().add_class(Gtk.STYLE_CLASS_RAISED);
let renderer = new Gtk.CellRendererText();
this._extensionSelector.pack_start(renderer, true);
this._extensionSelector.add_attribute(renderer, 'text', 1);
this._extensionSelector.set_cell_data_func(renderer, Lang.bind(this, this._setExtensionInsensitive), null);
this._extensionSelector.connect('changed', Lang.bind(this, this._extensionSelected));
toolitem = new Gtk.ToolItem({ child: this._extensionSelector });
toolitem.set_expand(true);
toolbar.add(toolitem);
this._extensionPrefsBin = new Gtk.Frame();
vbox.add(this._extensionPrefsBin);
let label = new Gtk.Label({
label: _("Select an extension to configure using the combobox above."),
vexpand: true
});
this._extensionPrefsBin.add(label);
this._shellProxy = new GnomeShellProxy(Gio.DBus.session, 'org.gnome.Shell', '/org/gnome/Shell');
this._shellProxy.connectSignal('ExtensionStatusChanged', Lang.bind(this, function(proxy, senderName, [uuid, state, error]) {
if (ExtensionUtils.extensions[uuid] !== undefined)
this._scanExtensions();
}));
this._window.show_all();
},
_scanExtensions: function() {
ExtensionUtils.scanExtensions(Lang.bind(this, function(uuid, dir, type) {
if (ExtensionUtils.extensions[uuid] !== undefined)
return;
let extension;
try {
extension = ExtensionUtils.createExtensionObject(uuid, dir, type);
} catch(e) {
global.logError('' + e);
return;
}
let iter = this._model.append();
this._model.set(iter, [0, 1], [uuid, extension.metadata.name]);
this._extensionIters[uuid] = iter;
}));
},
_onActivate: function() {
this._window.present();
},
_onStartup: function(app) {
this._buildModel();
this._buildUI(app);
this._scanExtensions();
},
_onCommandLine: function(app, commandLine) {
app.activate();
let args = commandLine.get_arguments();
if (args.length) {
let uuid = args[0];
// Strip off "extension:///" prefix which fakes a URI, if it exists
uuid = stripPrefix(uuid, "extension:///");
if (!this._extensionAvailable(uuid))
return 1;
this._selectExtension(uuid);
}
return 0;
}
});
function initEnvironment() {
// Monkey-patch in a "global" object that fakes some Shell utilities
// that ExtensionUtils depends on.
window.global = {
log: function() {
print([].join.call(arguments, ', '));
},
logError: function(s) {
global.log('ERROR: ' + s);
},
userdatadir: GLib.build_filenamev([GLib.get_user_data_dir(), 'gnome-shell'])
};
String.prototype.format = Format.format;
}
function main(argv) {
initEnvironment();
ExtensionUtils.init();
Gettext.bindtextdomain(Config.GETTEXT_PACKAGE, Config.LOCALEDIR);
Gettext.textdomain(Config.GETTEXT_PACKAGE);
let app = new Application();
app.application.run(argv);
}

View File

@ -694,7 +694,7 @@ const SessionList = new Lang.Class({
},
_populate: function() {
this._itemList.destroy_children();
this._itemList.destroy_all_children();
this._activeSessionId = null;
this._items = {};

View File

@ -22,6 +22,8 @@ const Lang = imports.lang;
const UPowerGlib = imports.gi.UPowerGlib;
const ConsoleKit = imports.gdm.consoleKit;
const Systemd = imports.gdm.systemd;
const PanelMenu = imports.ui.panelMenu;
const PopupMenu = imports.ui.popupMenu;
@ -32,6 +34,7 @@ const PowerMenuButton = new Lang.Class({
_init: function() {
this.parent('system-shutdown', null);
this._consoleKitManager = new ConsoleKit.ConsoleKitManager();
this._systemdLoginManager = new Systemd.SystemdLoginManager();
this._upClient = new UPowerGlib.Client();
this._createSubMenu();
@ -61,39 +64,75 @@ const PowerMenuButton = new Lang.Class({
},
_updateHaveShutdown: function() {
this._consoleKitManager.CanStopRemote(Lang.bind(this,
function(result, error) {
if (!error)
this._haveShutdown = result;
else
this._haveShutdown = false;
if (this._haveShutdown) {
this._powerOffItem.actor.show();
} else {
this._powerOffItem.actor.hide();
}
if (Systemd.haveSystemd()) {
this._systemdLoginManager.CanPowerOffRemote(Lang.bind(this,
function(result, error) {
if (!error)
this._haveShutdown = result != 'no';
else
this._haveShutdown = false;
this._updateVisibility();
}));
if (this._haveShutdown)
this._powerOffItem.actor.show();
else
this._powerOffItem.actor.hide();
this._updateVisibility();
}));
} else {
this._consoleKitManager.CanStopRemote(Lang.bind(this,
function(result, error) {
if (!error)
this._haveShutdown = result;
else
this._haveShutdown = false;
if (this._haveShutdown) {
this._powerOffItem.actor.show();
} else {
this._powerOffItem.actor.hide();
}
this._updateVisibility();
}));
}
},
_updateHaveRestart: function() {
this._consoleKitManager.CanRestartRemote(Lang.bind(this,
function(result, error) {
if (!error)
this._haveRestart = result;
else
this._haveRestart = false;
if (this._haveRestart) {
this._restartItem.actor.show();
} else {
this._restartItem.actor.hide();
}
if (Systemd.haveSystemd()) {
this._systemdLoginManager.CanRebootRemote(Lang.bind(this,
function(result, error) {
if (!error)
this._haveRestart = result != 'no';
else
this._haveRestart = false;
this._updateVisibility();
}));
if (this._haveRestart)
this._restartItem.actor.show();
else
this._restartItem.actor.hide();
this._updateVisibility();
}));
} else {
this._consoleKitManager.CanRestartRemote(Lang.bind(this,
function(result, error) {
if (!error)
this._haveRestart = result;
else
this._haveRestart = false;
if (this._haveRestart) {
this._restartItem.actor.show();
} else {
this._restartItem.actor.hide();
}
this._updateVisibility();
}));
}
},
_updateHaveSuspend: function() {
@ -132,12 +171,22 @@ const PowerMenuButton = new Lang.Class({
},
_onActivateRestart: function() {
if (this._haveRestart)
if (!this._haveRestart)
return;
if (Systemd.haveSystemd())
this._systemdLoginManager.RebootRemote(true);
else
this._consoleKitManager.RestartRemote();
},
_onActivatePowerOff: function() {
if (this._haveShutdown)
if (!this._haveShutdown)
return;
if (Systemd.haveSystemd())
this._systemdLoginManager.PowerOffRemote(true);
else
this._consoleKitManager.StopRemote();
}
});

31
js/gdm/systemd.js Normal file
View File

@ -0,0 +1,31 @@
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
const GLib = imports.gi.GLib;
const Gio = imports.gi.Gio;
const SystemdLoginManagerIface = <interface name='org.freedesktop.login1.Manager'>
<method name='PowerOff'>
<arg type='b' direction='in'/>
</method>
<method name='Reboot'>
<arg type='b' direction='in'/>
</method>
<method name='CanPowerOff'>
<arg type='s' direction='out'/>
</method>
<method name='CanReboot'>
<arg type='s' direction='out'/>
</method>
</interface>;
const SystemdLoginManagerProxy = Gio.DBusProxy.makeProxyWrapper(SystemdLoginManagerIface);
function SystemdLoginManager() {
return new SystemdLoginManagerProxy(Gio.DBus.system,
'org.freedesktop.login1',
'/org/freedesktop/login1');
};
function haveSystemd() {
return GLib.access("/sys/fs/cgroup/systemd", 0) >= 0;
}

View File

@ -10,3 +10,10 @@ const GJS_VERSION = '@GJS_VERSION@';
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 */
const LOCALEDIR = '@datadir@/locale';
/* other standard directories */
const LIBEXECDIR = '@libexecdir@';
const SYSCONFDIR = '@sysconfdir@';

View File

@ -1,136 +0,0 @@
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
const St = imports.gi.St;
const Shell = imports.gi.Shell;
const Lang = imports.lang;
const Signals = imports.signals;
const Search = imports.ui.search;
const THUMBNAIL_ICON_MARGIN = 2;
const DocInfo = new Lang.Class({
Name: 'DocInfo',
_init : function(recentInfo) {
this.recentInfo = recentInfo;
// We actually used get_modified() instead of get_visited()
// here, as GtkRecentInfo doesn't updated get_visited()
// correctly. See http://bugzilla.gnome.org/show_bug.cgi?id=567094
this.timestamp = recentInfo.get_modified();
this.name = recentInfo.get_display_name();
this._lowerName = this.name.toLowerCase();
this.uri = recentInfo.get_uri();
this.mimeType = recentInfo.get_mime_type();
},
createIcon : function(size) {
return St.TextureCache.get_default().load_recent_thumbnail(size, this.recentInfo);
},
launch : function(workspaceIndex) {
Shell.DocSystem.get_default().open(this.recentInfo, workspaceIndex);
},
matchTerms: function(terms) {
let mtype = Search.MatchType.NONE;
for (let i = 0; i < terms.length; i++) {
let term = terms[i];
let idx = this._lowerName.indexOf(term);
if (idx == 0) {
mtype = Search.MatchType.PREFIX;
} else if (idx > 0) {
if (mtype == Search.MatchType.NONE)
mtype = Search.MatchType.SUBSTRING;
} else {
return Search.MatchType.NONE;
}
}
return mtype;
}
});
var docManagerInstance = null;
function getDocManager() {
if (docManagerInstance == null)
docManagerInstance = new DocManager();
return docManagerInstance;
}
/**
* DocManager wraps the DocSystem, primarily to expose DocInfo objects.
*/
const DocManager = new Lang.Class({
Name: 'DocManager',
_init: function() {
this._docSystem = Shell.DocSystem.get_default();
this._infosByTimestamp = [];
this._infosByUri = {};
this._docSystem.connect('changed', Lang.bind(this, this._reload));
this._reload();
},
_reload: function() {
let docs = this._docSystem.get_all();
this._infosByTimestamp = [];
this._infosByUri = {};
for (let i = 0; i < docs.length; i++) {
let recentInfo = docs[i];
let docInfo = new DocInfo(recentInfo);
this._infosByTimestamp.push(docInfo);
this._infosByUri[docInfo.uri] = docInfo;
}
this.emit('changed');
},
getTimestampOrderedInfos: function() {
return this._infosByTimestamp;
},
getInfosByUri: function() {
return this._infosByUri;
},
lookupByUri: function(uri) {
return this._infosByUri[uri];
},
queueExistenceCheck: function(count) {
return this._docSystem.queue_existence_check(count);
},
_searchDocs: function(items, terms) {
let multiplePrefixMatches = [];
let prefixMatches = [];
let multipleSubtringMatches = [];
let substringMatches = [];
for (let i = 0; i < items.length; i++) {
let item = items[i];
let mtype = item.matchTerms(terms);
if (mtype == Search.MatchType.MULTIPLE_PREFIX)
multiplePrefixMatches.push(item.uri);
else if (mtype == Search.MatchType.PREFIX)
prefixMatches.push(item.uri);
else if (mtype == Search.MatchType.MULTIPLE_SUBSTRING)
multipleSubtringMatches.push(item.uri);
else if (mtype == Search.MatchType.SUBSTRING)
substringMatches.push(item.uri);
}
return multiplePrefixMatches.concat(prefixMatches.concat(multipleSubtringMatches.concat(substringMatches)));
},
initialSearch: function(terms) {
return this._searchDocs(this._infosByTimestamp, terms);
},
subsearch: function(previousResults, terms) {
return this._searchDocs(previousResults.map(Lang.bind(this,
function(url) {
return this._infosByUri[url];
})), terms);
}
});
Signals.addSignalMethods(DocManager.prototype);

194
js/misc/extensionUtils.js Normal file
View File

@ -0,0 +1,194 @@
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
// Common utils for the extension system and the extension
// preferences tool
const GLib = imports.gi.GLib;
const Gio = imports.gi.Gio;
const ShellJS = imports.gi.ShellJS;
const Config = imports.misc.config;
const ExtensionType = {
SYSTEM: 1,
PER_USER: 2
};
// GFile for user extensions
var userExtensionsDir = null;
// Maps uuid -> metadata object
const extensions = {};
function getCurrentExtension() {
let stack = (new Error()).stack;
// Assuming we're importing this directly from an extension (and we shouldn't
// ever not be), its UUID should be directly in the path here.
let extensionStackLine = stack.split('\n')[1];
if (!extensionStackLine)
throw new Error('Could not find current extension');
// The stack line is like:
// init([object Object])@/home/user/data/gnome-shell/extensions/u@u.id/prefs.js:8
//
// In the case that we're importing from
// module scope, the first field is blank:
// @/home/user/data/gnome-shell/extensions/u@u.id/prefs.js:8
let match = new RegExp('@(.+):\\d+').exec(extensionStackLine);
if (!match)
throw new Error('Could not find current extension');
let path = match[1];
let uuid = GLib.path_get_basename(GLib.path_get_dirname(path));
let extension = extensions[uuid];
if (extension === undefined)
throw new Error('Could not find current extension');
return extension;
}
/**
* versionCheck:
* @required: an array of versions we're compatible with
* @current: the version we have
*
* Check if a component is compatible for an extension.
* @required is an array, and at least one version must match.
* @current must be in the format <major>.<minor>.<point>.<micro>
* <micro> is always ignored
* <point> is ignored if <minor> is even (so you can target the
* whole stable release)
* <minor> and <major> must match
* Each target version must be at least <major> and <minor>
*/
function versionCheck(required, current) {
let currentArray = current.split('.');
let major = currentArray[0];
let minor = currentArray[1];
let point = currentArray[2];
for (let i = 0; i < required.length; i++) {
let requiredArray = required[i].split('.');
if (requiredArray[0] == major &&
requiredArray[1] == minor &&
(requiredArray[2] == point ||
(requiredArray[2] == undefined && parseInt(minor) % 2 == 0)))
return true;
}
return false;
}
function isOutOfDate(extension) {
if (!versionCheck(extension.metadata['shell-version'], Config.PACKAGE_VERSION))
return true;
if (extension.metadata['js-version'] && !versionCheck(extension.metadata['js-version'], Config.GJS_VERSION))
return true;
return false;
}
function createExtensionObject(uuid, dir, type) {
let info;
let metadataFile = dir.get_child('metadata.json');
if (!metadataFile.query_exists(null)) {
throw new Error('Missing metadata.json');
}
let metadataContents, success, tag;
try {
[success, metadataContents, tag] = metadataFile.load_contents(null);
} catch (e) {
throw new Error('Failed to load metadata.json: ' + e);
}
let meta;
try {
meta = JSON.parse(metadataContents);
} catch (e) {
throw new Error('Failed to parse metadata.json: ' + e);
}
let requiredProperties = ['uuid', 'name', 'description', 'shell-version'];
for (let i = 0; i < requiredProperties.length; i++) {
let prop = requiredProperties[i];
if (!meta[prop]) {
throw new Error('missing "' + prop + '" property in metadata.json');
}
}
// Encourage people to add this
if (!meta.url) {
global.log('Warning: Missing "url" property in metadata.json');
}
if (uuid != meta.uuid) {
throw new Error('uuid "' + meta.uuid + '" from metadata.json does not match directory name "' + uuid + '"');
}
let extension = {};
extension.metadata = meta;
extension.uuid = meta.uuid;
extension.type = type;
extension.dir = dir;
extension.path = dir.get_path();
extension.error = '';
extension.hasPrefs = dir.get_child('prefs.js').query_exists(null);
extensions[uuid] = extension;
return extension;
}
var _extension = null;
function installImporter(extension) {
_extension = extension;
ShellJS.add_extension_importer('imports.misc.extensionUtils._extension', 'imports', extension.path);
_extension = null;
}
function init() {
let userExtensionsPath = GLib.build_filenamev([global.userdatadir, 'extensions']);
userExtensionsDir = Gio.file_new_for_path(userExtensionsPath);
try {
if (!userExtensionsDir.query_exists(null))
userExtensionsDir.make_directory_with_parents(null);
} catch (e) {
global.logError('' + e);
}
}
function scanExtensionsInDirectory(callback, dir, type) {
let fileEnum;
let file, info;
try {
fileEnum = dir.enumerate_children('standard::*', Gio.FileQueryInfoFlags.NONE, null);
} catch(e) {
global.logError('' + e);
return;
}
while ((info = fileEnum.next_file(null)) != null) {
let fileType = info.get_file_type();
if (fileType != Gio.FileType.DIRECTORY)
continue;
let uuid = info.get_name();
let extensionDir = dir.get_child(uuid);
callback(uuid, extensionDir, type);
}
fileEnum.close(null);
}
function scanExtensions(callback) {
let systemDataDirs = GLib.get_system_data_dirs();
for (let i = 0; i < systemDataDirs.length; i++) {
let dirPath = GLib.build_filenamev([systemDataDirs[i], 'gnome-shell', 'extensions']);
let dir = Gio.file_new_for_path(dirPath);
if (dir.query_exists(null))
scanExtensionsInDirectory(callback, dir, ExtensionType.SYSTEM);
}
scanExtensionsInDirectory(callback, userExtensionsDir, ExtensionType.PER_USER);
}

View File

@ -10,9 +10,7 @@ const Signals = imports.signals;
const ModemGsmNetworkInterface = <interface name="org.freedesktop.ModemManager.Modem.Gsm.Network">
<method name="GetRegistrationInfo">
<arg type="u" direction="out" />
<arg type="s" direction="out" />
<arg type="s" direction="out" />
<arg type="(uss)" direction="out" />
</method>
<method name="GetSignalQuality">
<arg type="u" direction="out" />
@ -35,9 +33,7 @@ const ModemCdmaInterface = <interface name="org.freedesktop.ModemManager.Modem.C
<arg type="u" direction="out" />
</method>
<method name="GetServingSystem">
<arg type="u" direction="out" />
<arg type="s" direction="out" />
<arg type="u" direction="out" />
<arg type="(usu)" direction="out" />
</method>
<signal name="SignalQuality">
<arg type="u" direction="out" />
@ -72,7 +68,7 @@ const ModemGsm = new Lang.Class({
this.operator_name = this._findOperatorName(name, code);
this.emit('notify::operator-name');
}));
this._proxy.GetRegistrationInfoRemote(Lang.bind(this, function(result, err) {
this._proxy.GetRegistrationInfoRemote(Lang.bind(this, function([result], err) {
if (err) {
log(err);
return;
@ -165,7 +161,7 @@ const ModemCdma = new Lang.Class({
this.signal_quality = 0;
this.operator_name = null;
this._proxy.connect('SignalQuality', Lang.bind(this, function(proxy, sender, params) {
this._proxy.connectSignal('SignalQuality', Lang.bind(this, function(proxy, sender, params) {
this.signal_quality = params[0];
this.emit('notify::signal-quality');
@ -187,7 +183,7 @@ const ModemCdma = new Lang.Class({
},
_refreshServingSystem: function() {
this._proxy.GetServingSystemRemote(Lang.bind(this, function(result, err) {
this._proxy.GetServingSystemRemote(Lang.bind(this, function([result], err) {
if (err) {
// it will return an error if the device is not connected
this.operator_name = null;

View File

@ -236,7 +236,7 @@ const ViewByCategories = new Lang.Class({
_removeAll: function() {
this._categories = [];
this._categoryBox.destroy_children();
this._categoryBox.destroy_all_children();
},
refresh: function() {
@ -312,13 +312,18 @@ const AppSearchProvider = new Lang.Class({
this._appSys = Shell.AppSystem.get_default();
},
getResultMeta: function(app) {
return { 'id': app,
'name': app.get_name(),
'createIcon': function(size) {
return app.create_icon_texture(size);
}
};
getResultMetas: function(apps) {
let metas = [];
for (let i = 0; i < apps.length; i++) {
let app = apps[i];
metas.push({ 'id': app,
'name': app.get_name(),
'createIcon': function(size) {
return app.create_icon_texture(size);
}
});
}
return metas;
},
getInitialResultSet: function(terms) {
@ -369,13 +374,18 @@ const SettingsSearchProvider = new Lang.Class({
this._gnomecc = this._appSys.lookup_app('gnome-control-center.desktop');
},
getResultMeta: function(pref) {
return { 'id': pref,
'name': pref.get_name(),
'createIcon': function(size) {
return pref.create_icon_texture(size);
}
};
getResultMetas: function(prefs) {
let metas = [];
for (let i = 0; i < prefs.length; i++) {
let pref = prefs[i];
metas.push({ 'id': pref,
'name': pref.get_name(),
'createIcon': function(size) {
return pref.create_icon_texture(size);
}
});
}
return metas;
},
getInitialResultSet: function(terms) {

View File

@ -2,9 +2,11 @@
const Lang = imports.lang;
const Mainloop = imports.mainloop;
const GLib = imports.gi.GLib;
const Gio = imports.gi.Gio;
const Params = imports.misc.params;
const Shell = imports.gi.Shell;
const Main = imports.ui.main;
const ShellMountOperation = imports.ui.shellMountOperation;
const ScreenSaver = imports.misc.screenSaver;
@ -43,7 +45,7 @@ function ConsoleKitManager() {
g_flags: (Gio.DBusProxyFlags.DO_NOT_AUTO_START |
Gio.DBusProxyFlags.DO_NOT_LOAD_PROPERTIES) });
self.connect('notify::g-name-owner', function() {
self._updateSessionActive = function() {
if (self.g_name_owner) {
self.GetCurrentSessionRemote(function([session]) {
self._ckSession = new ConsoleKitSessionProxy(Gio.DBus.system, 'org.freedesktop.ConsoleKit', session);
@ -58,12 +60,19 @@ function ConsoleKitManager() {
} else {
self.sessionActive = true;
}
});
};
self.connect('notify::g-name-owner',
Lang.bind(self, self._updateSessionActive));
self._updateSessionActive();
self.init(null);
return self;
}
function haveSystemd() {
return GLib.access("/sys/fs/cgroup/systemd", 0) >= 0;
}
const AutomountManager = new Lang.Class({
Name: 'AutomountManager',
@ -71,7 +80,8 @@ const AutomountManager = new Lang.Class({
this._settings = new Gio.Settings({ schema: SETTINGS_SCHEMA });
this._volumeQueue = [];
this.ckListener = new ConsoleKitManager();
if (!haveSystemd())
this.ckListener = new ConsoleKitManager();
this._ssProxy = new ScreenSaver.ScreenSaverProxy();
this._ssProxy.connectSignal('ActiveChanged',
@ -119,11 +129,22 @@ const AutomountManager = new Lang.Class({
return false;
},
_sessionActive: function() {
// Return whether the current session is active, using the
// right mechanism: either systemd if available or ConsoleKit
// as fallback.
if (haveSystemd())
return Shell.session_is_active_for_systemd();
return this.ckListener.sessionActive;
},
_onDriveConnected: function() {
// if we're not in the current ConsoleKit session,
// or screensaver is active, don't play sounds
if (!this.ckListener.sessionActive)
return;
if (!this._sessionActive())
return;
if (this._ssProxy.screenSaverActive)
return;
@ -134,8 +155,8 @@ const AutomountManager = new Lang.Class({
_onDriveDisconnected: function() {
// if we're not in the current ConsoleKit session,
// or screensaver is active, don't play sounds
if (!this.ckListener.sessionActive)
return;
if (!this._sessionActive())
return;
if (this._ssProxy.screenSaverActive)
return;
@ -146,7 +167,7 @@ const AutomountManager = new Lang.Class({
_onDriveEjectButton: function(monitor, drive) {
// TODO: this code path is not tested, as the GVfs volume monitor
// doesn't emit this signal just yet.
if (!this.ckListener.sessionActive)
if (!this._sessionActive())
return;
// we force stop/eject in this case, so we don't have to pass a
@ -185,7 +206,7 @@ const AutomountManager = new Lang.Class({
if (params.checkSession) {
// if we're not in the current ConsoleKit session,
// don't attempt automount
if (!this.ckListener.sessionActive)
if (!this._sessionActive())
return;
if (this._ssProxy.screenSaverActive) {

View File

@ -339,7 +339,7 @@ const AutorunResidentNotification = new Lang.Class({
updateForMounts: function(mounts) {
// remove all the layout content
this._layout.destroy_children();
this._layout.destroy_all_children();
for (let idx = 0; idx < mounts.length; idx++) {
let element = mounts[idx];

View File

@ -406,7 +406,7 @@ const Calendar = new Lang.Class({
_buildHeader: function() {
let offsetCols = this._useWeekdate ? 1 : 0;
this.actor.destroy_children();
this.actor.destroy_all_children();
// Top line of the calendar '<| September 2009 |>'
this._topBox = new St.BoxLayout();
@ -685,7 +685,7 @@ const EventsList = new Lang.Class({
},
_showOtherDay: function(day) {
this.actor.destroy_children();
this.actor.destroy_all_children();
let dayBegin = _getBeginningOfDay(day);
let dayEnd = _getEndOfDay(day);
@ -702,7 +702,7 @@ const EventsList = new Lang.Class({
},
_showToday: function() {
this.actor.destroy_children();
this.actor.destroy_all_children();
let now = new Date();
let dayBegin = _getBeginningOfDay(now);

97
js/ui/checkBox.js Normal file
View File

@ -0,0 +1,97 @@
const Clutter = imports.gi.Clutter;
const Pango = imports.gi.Pango;
const Shell = imports.gi.Shell;
const St = imports.gi.St;
const Lang = imports.lang;
const CheckBoxContainer = new Lang.Class({
Name: 'CheckBoxContainer',
_init: function() {
this.actor = new Shell.GenericContainer();
this.actor.connect('get-preferred-width',
Lang.bind(this, this._getPreferredWidth));
this.actor.connect('get-preferred-height',
Lang.bind(this, this._getPreferredHeight));
this.actor.connect('allocate',
Lang.bind(this, this._allocate));
this.actor.connect('style-changed', Lang.bind(this,
function() {
let node = this.actor.get_theme_node();
this._spacing = node.get_length('spacing');
}));
this.actor.request_mode = Clutter.RequestMode.HEIGHT_FOR_WIDTH;
this._box = new St.Bin();
this.actor.add_actor(this._box);
this.label = new St.Label();
this.label.clutter_text.set_line_wrap(true);
this.label.clutter_text.set_ellipsize(Pango.EllipsizeMode.NONE);
this.actor.add_actor(this.label);
this._spacing = 0;
},
_getPreferredWidth: function(actor, forHeight, alloc) {
let [minWidth, natWidth] = this._box.get_preferred_width(forHeight);
alloc.min_size = minWidth + this._spacing;
alloc.natural_size = natWidth + this._spacing;
},
_getPreferredHeight: function(actor, forWidth, alloc) {
let [minBoxHeight, natBoxHeight] =
this._box.get_preferred_height(forWidth);
let [minLabelHeight, natLabelHeight] =
this.label.get_preferred_height(forWidth);
alloc.min_size = Math.max(minBoxHeight, minLabelHeight);
alloc.natural_size = Math.max(natBoxHeight, natLabelHeight);
},
_allocate: function(actor, box, flags) {
let availWidth = box.x2 - box.x1;
let availHeight = box.y2 - box.y1;
let childBox = new Clutter.ActorBox();
let [minBoxWidth, natBoxWidth] =
this._box.get_preferred_width(-1);
let [minBoxHeight, natBoxHeight] =
this._box.get_preferred_height(-1);
childBox.x1 = box.x1;
childBox.x2 = box.x1 + natBoxWidth;
childBox.y1 = box.y1;
childBox.y2 = box.y1 + natBoxHeight;
this._box.allocate(childBox, flags);
childBox.x1 = box.x1 + natBoxWidth + this._spacing;
childBox.x2 = availWidth - childBox.x1;
childBox.y1 = box.y1;
childBox.y2 = box.y2;
this.label.allocate(childBox, flags);
}
});
const CheckBox = new Lang.Class({
Name: 'CheckBox',
_init: function(label) {
this.actor = new St.Button({ style_class: 'check-box',
button_mask: St.ButtonMask.ONE,
toggle_mode: true,
can_focus: true,
x_fill: true,
y_fill: true });
this._container = new CheckBoxContainer();
this.actor.set_child(this._container.actor);
if (label)
this.setLabel(label);
},
setLabel: function(label) {
this._container.label.set_text(label);
}
});

View File

@ -93,23 +93,30 @@ const Contact = new Lang.Class({
text = _("Busy");
iconName = 'user-busy';
break;
default:
case Folks.PresenceType.OFFLINE:
text = _("Offline");
iconName = 'user-offline';
break;
default:
text = '';
iconName = null;
}
let icon = new St.Icon({ icon_name: iconName,
icon_type: St.IconType.FULLCOLOR,
icon_size: 16,
style_class: 'contact-details-status-icon' });
let label = new St.Label({ text: text });
let box = new St.BoxLayout({ vertical: false,
style_class: 'contact-details-status' });
box.add(icon, { x_fill: true,
y_fill: false,
x_align: St.Align.START,
y_align: St.Align.START });
if (iconName) {
let icon = new St.Icon({ icon_name: iconName,
icon_type: St.IconType.FULLCOLOR,
icon_size: 16,
style_class: 'contact-details-status-icon' });
box.add(icon, { x_fill: true,
y_fill: false,
x_align: St.Align.START,
y_align: St.Align.START });
}
let label = new St.Label({ text: text });
box.add(label, { x_fill: true,
y_fill: false,
@ -142,14 +149,18 @@ const ContactSearchProvider = new Lang.Class({
this._contactSys = Shell.ContactSystem.get_default();
},
getResultMeta: function(id) {
let contact = new Contact(id);
return { 'id': id,
'name': contact.alias,
'createIcon': function(size) {
return contact.createIcon(size);
}
};
getResultMetas: function(ids) {
let metas = [];
for (let i = 0; i < ids.length; i++) {
let contact = new Contact(ids[i]);
metas.push({ 'id': ids[i],
'name': contact.alias,
'createIcon': function(size) {
return contact.createIcon(size);
}
});
}
return metas;
},
getInitialResultSet: function(terms) {

View File

@ -148,7 +148,7 @@ const DashItemContainer = new Lang.Class({
if (this.child == actor)
return;
this.actor.destroy_children();
this.actor.destroy_all_children();
this.child = actor;
this.actor.add_actor(this.child);
@ -501,7 +501,7 @@ const Dash = new Lang.Class({
return;
let themeNode = this.actor.get_theme_node();
let themeNode = this._box.get_theme_node();
let maxAllocation = new Clutter.ActorBox({ x1: 0, y1: 0,
x2: 42 /* whatever */,
y2: this._maxHeight });
@ -677,8 +677,8 @@ const Dash = new Lang.Class({
}
for (let i = 0; i < addedItems.length; i++)
this._box.insert_actor(addedItems[i].item.actor,
addedItems[i].pos);
this._box.insert_child_at_index(addedItems[i].item.actor,
addedItems[i].pos);
for (let i = 0; i < removedActors.length; i++) {
let item = removedActors[i]._delegate;
@ -787,8 +787,8 @@ const Dash = new Lang.Class({
this._dragPlaceholder = new DragPlaceholderItem();
this._dragPlaceholder.child.set_width (this.iconSize);
this._dragPlaceholder.child.set_height (this.iconSize / 2);
this._box.insert_actor(this._dragPlaceholder.actor,
this._dragPlaceholderPos);
this._box.insert_child_at_index(this._dragPlaceholder.actor,
this._dragPlaceholderPos);
if (fadeIn)
this._dragPlaceholder.animateIn();
}

View File

@ -69,6 +69,7 @@ const DateMenuButton = new Lang.Class({
// Date
this._date = new St.Label();
this.actor.label_actor = this._date;
this._date.style_class = 'datemenu-date-label';
vbox.add(this._date);

View File

@ -103,8 +103,8 @@ const _Draggable = new Lang.Class({
this._dragInProgress = false; // The drag has been started, and has not been dropped or cancelled yet.
this._animationInProgress = false; // The drag is over and the item is in the process of animating to its original position (snapping back or reverting).
// During the drag, we eat enter/leave events so that actors don't prelight or show
// tooltips. But we remember the actors that we first left/last entered so we can
// During the drag, we eat enter/leave events so that actors don't prelight.
// But we remember the actors that we first left/last entered so we can
// fix up the hover state after the drag ends.
this._firstLeaveActor = null;
this._lastEnterActor = null;

View File

@ -1,44 +0,0 @@
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
const DocInfo = imports.misc.docInfo;
const Lang = imports.lang;
const Params = imports.misc.params;
const Search = imports.ui.search;
const DocSearchProvider = new Lang.Class({
Name: 'DocSearchProvider',
Extends: Search.SearchProvider,
_init: function(name) {
this.parent(_("RECENT ITEMS"));
this._docManager = DocInfo.getDocManager();
},
getResultMeta: function(resultId) {
let docInfo = this._docManager.lookupByUri(resultId);
if (!docInfo)
return null;
return { 'id': resultId,
'name': docInfo.name,
'createIcon': function(size) {
return docInfo.createIcon(size);
}
};
},
activateResult: function(id, params) {
params = Params.parse(params, { workspace: -1,
timestamp: 0 });
let docInfo = this._docManager.lookupByUri(id);
docInfo.launch(params.workspace);
},
getInitialResultSet: function(terms) {
return this._docManager.initialSearch(terms);
},
getSubsearchResultSet: function(previousResults, terms) {
return this._docManager.subsearch(previousResults, terms);
}
});

View File

@ -501,7 +501,7 @@ const EndSessionDialog = new Lang.Class({
let [type, timestamp, totalSecondsToStayOpen, inhibitorObjectPaths] = parameters;
this._totalSecondsToStayOpen = totalSecondsToStayOpen;
this._inhibitors = [];
this._applicationList.destroy_children();
this._applicationList.destroy_all_children();
this._type = type;
if (!(this._type in DialogContent)) {

View File

@ -11,6 +11,7 @@ const Shell = imports.gi.Shell;
const Soup = imports.gi.Soup;
const Config = imports.misc.config;
const ExtensionUtils = imports.misc.extensionUtils;
const FileUtils = imports.misc.fileUtils;
const ModalDialog = imports.ui.modalDialog;
@ -29,11 +30,6 @@ const ExtensionState = {
UNINSTALLED: 99
};
const ExtensionType = {
SYSTEM: 1,
PER_USER: 2
};
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/';
@ -57,19 +53,10 @@ function _getCertFile() {
_httpSession.ssl_ca_file = _getCertFile();
// Maps uuid -> metadata object
const extensionMeta = {};
// Maps uuid -> importer object (extension directory tree)
const extensions = {};
// Maps uuid -> extension state object (returned from init())
const extensionStateObjs = {};
// Contains the order that extensions were enabled in.
const extensionOrder = [];
// Arrays of uuids
var enabledExtensions;
// GFile for user extensions
var userExtensionsDir = null;
// Contains the order that extensions were enabled in.
const extensionOrder = [];
// We don't really have a class to add signals on. So, create
// a simple dummy object, add the signal methods, and export those
@ -80,41 +67,8 @@ Signals.addSignalMethods(_signals);
const connect = Lang.bind(_signals, _signals.connect);
const disconnect = Lang.bind(_signals, _signals.disconnect);
// UUID => Array of error messages
var errors = {};
const ENABLED_EXTENSIONS_KEY = 'enabled-extensions';
/**
* versionCheck:
* @required: an array of versions we're compatible with
* @current: the version we have
*
* Check if a component is compatible for an extension.
* @required is an array, and at least one version must match.
* @current must be in the format <major>.<minor>.<point>.<micro>
* <micro> is always ignored
* <point> is ignored if <minor> is even (so you can target the
* whole stable release)
* <minor> and <major> must match
* Each target version must be at least <major> and <minor>
*/
function versionCheck(required, current) {
let currentArray = current.split('.');
let major = currentArray[0];
let minor = currentArray[1];
let point = currentArray[2];
for (let i = 0; i < required.length; i++) {
let requiredArray = required[i].split('.');
if (requiredArray[0] == major &&
requiredArray[1] == minor &&
(requiredArray[2] == point ||
(requiredArray[2] == undefined && parseInt(minor) % 2 == 0)))
return true;
}
return false;
}
function installExtensionFromUUID(uuid, version_tag) {
let params = { uuid: uuid,
version_tag: version_tag,
@ -132,8 +86,8 @@ function installExtensionFromUUID(uuid, version_tag) {
}
function uninstallExtensionFromUUID(uuid) {
let meta = extensionMeta[uuid];
if (!meta)
let extension = ExtensionUtils.extensions[uuid];
if (!extension)
return false;
// Try to disable it -- if it's ERROR'd, we can't guarantee that,
@ -142,22 +96,17 @@ function uninstallExtensionFromUUID(uuid) {
disableExtension(uuid);
// Don't try to uninstall system extensions
if (meta.type != ExtensionType.PER_USER)
if (extension.type != ExtensionUtils.ExtensionType.PER_USER)
return false;
meta.state = ExtensionState.UNINSTALLED;
_signals.emit('extension-state-changed', meta);
delete extensionMeta[uuid];
// Importers are marked as PERMANENT, so we can't do this.
// delete extensions[uuid];
extensions[uuid] = undefined;
extension.state = ExtensionState.UNINSTALLED;
_signals.emit('extension-state-changed', extension);
delete ExtensionUtils.extensions[uuid];
delete extensionStateObjs[uuid];
delete errors[uuid];
FileUtils.recursivelyDeleteDir(Gio.file_new_for_path(meta.path));
FileUtils.recursivelyDeleteDir(Gio.file_new_for_path(extension.path));
return true;
}
@ -178,7 +127,7 @@ function gotExtensionZipFile(session, message, uuid) {
}
let stream = new Gio.UnixOutputStream({ fd: fd });
let dir = userExtensionsDir.get_child(uuid);
let dir = ExtensionUtils.userExtensionsDir.get_child(uuid);
Shell.write_soup_message_to_stream(stream, message);
stream.close(null);
let [success, pid] = GLib.spawn_async(null,
@ -202,20 +151,18 @@ function gotExtensionZipFile(session, message, uuid) {
global.settings.set_strv(ENABLED_EXTENSIONS_KEY, enabledExtensions);
}
loadExtension(dir, ExtensionType.PER_USER, true);
loadExtension(dir, ExtensionUtils.ExtensionType.PER_USER, true);
});
}
function disableExtension(uuid) {
let meta = extensionMeta[uuid];
if (!meta)
let extension = ExtensionUtils.extensions[uuid];
if (!extension)
return;
if (meta.state != ExtensionState.ENABLED)
if (extension.state != ExtensionState.ENABLED)
return;
let extensionState = extensionStateObjs[uuid];
// "Rebase" the extension order by disabling and then enabling extensions
// in order to help prevent conflicts.
@ -231,14 +178,14 @@ function disableExtension(uuid) {
for (let i = 0; i < orderReversed.length; i++) {
let uuid = orderReversed[i];
try {
extensionStateObjs[uuid].disable();
ExtensionUtils.extensions[uuid].stateObj.disable();
} catch(e) {
logExtensionError(uuid, e.toString());
}
}
try {
extensionState.disable();
extension.stateObj.disable();
} catch(e) {
logExtensionError(uuid, e.toString());
return;
@ -247,7 +194,7 @@ function disableExtension(uuid) {
for (let i = 0; i < order.length; i++) {
let uuid = order[i];
try {
extensionStateObjs[uuid].enable();
ExtensionUtils.extensions[uuid].stateObj.enable();
} catch(e) {
logExtensionError(uuid, e.toString());
}
@ -255,41 +202,43 @@ function disableExtension(uuid) {
extensionOrder.splice(orderIdx, 1);
meta.state = ExtensionState.DISABLED;
_signals.emit('extension-state-changed', meta);
extension.state = ExtensionState.DISABLED;
_signals.emit('extension-state-changed', extension);
}
function enableExtension(uuid) {
let meta = extensionMeta[uuid];
if (!meta)
let extension = ExtensionUtils.extensions[uuid];
if (!extension)
return;
if (meta.state == ExtensionState.INITIALIZED) {
loadExtension(meta.dir, meta.type, true);
return;
}
if (extension.state == ExtensionState.INITIALIZED)
initExtension(uuid);
if (meta.state != ExtensionState.DISABLED)
if (extension.state != ExtensionState.DISABLED)
return;
let extensionState = extensionStateObjs[uuid];
extensionOrder.push(uuid);
try {
extensionState.enable();
extension.stateObj.enable();
} catch(e) {
logExtensionError(uuid, e.toString());
return;
}
meta.state = ExtensionState.ENABLED;
_signals.emit('extension-state-changed', meta);
extension.state = ExtensionState.ENABLED;
_signals.emit('extension-state-changed', extension);
}
function logExtensionError(uuid, message, state) {
if (!errors[uuid]) errors[uuid] = [];
errors[uuid].push(message);
let extension = ExtensionUtils.extensions[uuid];
if (!extension)
return;
if (!extension.errors)
extension.errors = [];
extension.errors.push(message);
global.logError('Extension "%s" had error: %s'.format(uuid, message));
state = state || ExtensionState.ERROR;
_signals.emit('extension-state-changed', { uuid: uuid,
@ -298,75 +247,48 @@ function logExtensionError(uuid, message, state) {
}
function loadExtension(dir, type, enabled) {
let info;
let uuid = dir.get_basename();
let extension;
let metadataFile = dir.get_child('metadata.json');
if (!metadataFile.query_exists(null)) {
logExtensionError(uuid, 'Missing metadata.json');
return;
if (ExtensionUtils.extensions[uuid] != undefined) {
throw new Error('extension already loaded');
}
let metadataContents;
try {
metadataContents = Shell.get_file_contents_utf8_sync(metadataFile.get_path());
} catch (e) {
logExtensionError(uuid, 'Failed to load metadata.json: ' + e);
extension = ExtensionUtils.createExtensionObject(uuid, dir, type);
} catch(e) {
logExtensionError(uuid, e.message);
return;
}
let meta;
try {
meta = JSON.parse(metadataContents);
} catch (e) {
logExtensionError(uuid, 'Failed to parse metadata.json: ' + e);
return;
}
let requiredProperties = ['uuid', 'name', 'description', 'shell-version'];
for (let i = 0; i < requiredProperties.length; i++) {
let prop = requiredProperties[i];
if (!meta[prop]) {
logExtensionError(uuid, 'missing "' + prop + '" property in metadata.json');
return;
}
}
if (extensions[uuid] != undefined) {
logExtensionError(uuid, 'extension already loaded');
return;
}
// Encourage people to add this
if (!meta['url']) {
global.log('Warning: Missing "url" property in metadata.json');
}
if (uuid != meta.uuid) {
logExtensionError(uuid, 'uuid "' + meta.uuid + '" from metadata.json does not match directory name "' + uuid + '"');
return;
}
extensionMeta[uuid] = meta;
meta.type = type;
meta.dir = dir;
meta.path = dir.get_path();
meta.error = '';
// Default to error, we set success as the last step
meta.state = ExtensionState.ERROR;
extension.state = ExtensionState.ERROR;
if (!versionCheck(meta['shell-version'], Config.PACKAGE_VERSION) ||
(meta['js-version'] && !versionCheck(meta['js-version'], Config.GJS_VERSION))) {
if (ExtensionUtils.isOutOfDate(extension)) {
logExtensionError(uuid, 'extension is not compatible with current GNOME Shell and/or GJS version', ExtensionState.OUT_OF_DATE);
meta.state = ExtensionState.OUT_OF_DATE;
extension.state = ExtensionState.OUT_OF_DATE;
return;
}
if (!enabled) {
meta.state = ExtensionState.INITIALIZED;
return;
if (enabled) {
initExtension(uuid);
if (extension.state == ExtensionState.DISABLED)
enableExtension(uuid);
} else {
extension.state = ExtensionState.INITIALIZED;
}
_signals.emit('extension-state-changed', extension);
global.log('Loaded extension ' + uuid);
}
function initExtension(uuid) {
let extension = ExtensionUtils.extensions[uuid];
let dir = extension.dir;
if (!extension)
throw new Error("Extension was not properly created. Call loadExtension first");
let extensionJs = dir.get_child('extension.js');
if (!extensionJs.query_exists(null)) {
logExtensionError(uuid, 'Missing extension.js');
@ -388,12 +310,12 @@ function loadExtension(dir, type, enabled) {
let extensionModule;
let extensionState = null;
try {
global.add_extension_importer('imports.ui.extensionSystem.extensions', meta.uuid, dir.get_path());
extensionModule = extensions[meta.uuid].extension;
ExtensionUtils.installImporter(extension);
extensionModule = extension.imports.extension;
} catch (e) {
if (stylesheetPath != null)
theme.unload_stylesheet(stylesheetPath);
logExtensionError(uuid, e);
logExtensionError(uuid, '' + e);
return;
}
@ -403,7 +325,7 @@ function loadExtension(dir, type, enabled) {
}
try {
extensionState = extensionModule.init(meta);
extensionState = extensionModule.init(extension);
} catch (e) {
if (stylesheetPath != null)
theme.unload_stylesheet(stylesheetPath);
@ -413,7 +335,7 @@ function loadExtension(dir, type, enabled) {
if (!extensionState)
extensionState = extensionModule;
extensionStateObjs[uuid] = extensionState;
extension.stateObj = extensionState;
if (!extensionState.enable) {
logExtensionError(uuid, 'missing \'enable\' function');
@ -424,13 +346,9 @@ function loadExtension(dir, type, enabled) {
return;
}
meta.state = ExtensionState.DISABLED;
extension.state = ExtensionState.DISABLED;
enableExtension(uuid);
_signals.emit('extension-loaded', meta.uuid);
_signals.emit('extension-state-changed', meta);
global.log('Loaded extension ' + meta.uuid);
_signals.emit('extension-loaded', uuid);
}
function onEnabledExtensionsChanged() {
@ -456,50 +374,17 @@ function onEnabledExtensionsChanged() {
}
function init() {
let userExtensionsPath = GLib.build_filenamev([global.userdatadir, 'extensions']);
userExtensionsDir = Gio.file_new_for_path(userExtensionsPath);
try {
if (!userExtensionsDir.query_exists(null))
userExtensionsDir.make_directory_with_parents(null);
} catch (e) {
global.logError('' + e);
}
ExtensionUtils.init();
global.settings.connect('changed::' + ENABLED_EXTENSIONS_KEY, onEnabledExtensionsChanged);
enabledExtensions = global.settings.get_strv(ENABLED_EXTENSIONS_KEY);
}
function _loadExtensionsIn(dir, type) {
let fileEnum;
let file, info;
try {
fileEnum = dir.enumerate_children('standard::*', Gio.FileQueryInfoFlags.NONE, null);
} catch (e) {
global.logError('' + e);
return;
}
while ((info = fileEnum.next_file(null)) != null) {
let fileType = info.get_file_type();
if (fileType != Gio.FileType.DIRECTORY)
continue;
let name = info.get_name();
let child = dir.get_child(name);
let enabled = enabledExtensions.indexOf(name) != -1;
loadExtension(child, type, enabled);
}
fileEnum.close(null);
}
function loadExtensions() {
let systemDataDirs = GLib.get_system_data_dirs();
for (let i = 0; i < systemDataDirs.length; i++) {
let dirPath = systemDataDirs[i] + '/gnome-shell/extensions';
let dir = Gio.file_new_for_path(dirPath);
if (dir.query_exists(null))
_loadExtensionsIn(dir, ExtensionType.SYSTEM);
}
_loadExtensionsIn(userExtensionsDir, ExtensionType.PER_USER);
ExtensionUtils.scanExtensions(function(uuid, dir, type) {
let enabled = enabledExtensions.indexOf(uuid) != -1;
loadExtension(dir, type, enabled);
});
}
const InstallExtensionDialog = new Lang.Class({
@ -545,13 +430,13 @@ const InstallExtensionDialog = new Lang.Class({
},
_onInstallButtonPressed: function(button, event) {
let meta = { uuid: this._uuid,
state: ExtensionState.DOWNLOADING,
error: '' };
let extension = { uuid: this._uuid,
state: ExtensionState.DOWNLOADING,
error: '' };
extensionMeta[this._uuid] = meta;
ExtensionUtils.extensions[this._uuid] = extension;
_signals.emit('extension-state-changed', meta);
_signals.emit('extension-state-changed', extension);
let params = { version_tag: this._version_tag,
shell_version: Config.PACKAGE_VERSION,

45
js/ui/flashspot.js Normal file
View File

@ -0,0 +1,45 @@
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
const Lang = imports.lang;
const Lightbox = imports.ui.lightbox;
const Main = imports.ui.main;
const Tweener = imports.ui.tweener;
const FLASHSPOT_ANIMATION_TIME = 0.25; // seconds
const Flashspot = new Lang.Class({
Name: 'Flashspot',
Extends: Lightbox.Lightbox,
_init: function(area) {
this.parent(Main.uiGroup, { inhibitEvents: true,
width: area.width,
height: area.height });
this.actor.style_class = 'flashspot';
this.actor.set_position(area.x, area.y);
},
fire: function() {
this.actor.opacity = 0;
Tweener.addTween(this.actor,
{ opacity: 255,
time: FLASHSPOT_ANIMATION_TIME,
transition: 'linear',
onComplete: Lang.bind(this, this._onFireShowComplete)
});
this.actor.show();
},
_onFireShowComplete: function() {
Tweener.addTween(this.actor,
{ opacity: 0,
time: FLASHSPOT_ANIMATION_TIME,
transition: 'linear',
onComplete: Lang.bind(this, function() {
this.destroy();
})
});
}
});

View File

@ -170,7 +170,7 @@ const IconGrid = new Lang.Class({
vertical: true });
// Pulled from CSS, but hardcode some defaults here
this._spacing = 0;
this._item_size = ICON_SIZE;
this._hItemSize = this._vItemSize = ICON_SIZE;
this._grid = new Shell.GenericContainer();
this.actor.add(this._grid, { expand: true, y_align: St.Align.START });
this.actor.connect('style-changed', Lang.bind(this, this._onStyleChanged));
@ -189,8 +189,8 @@ const IconGrid = new Lang.Class({
// Kind of a lie, but not really an issue right now. If
// we wanted to support some sort of hidden/overflow that would
// need higher level design
alloc.min_size = this._item_size;
alloc.natural_size = nColumns * this._item_size + totalSpacing;
alloc.min_size = this._hItemSize;
alloc.natural_size = nColumns * this._hItemSize + totalSpacing;
},
_getVisibleChildren: function() {
@ -212,7 +212,7 @@ const IconGrid = new Lang.Class({
if (this._rowLimit)
nRows = Math.min(nRows, this._rowLimit);
let totalSpacing = Math.max(0, nRows - 1) * this._spacing;
let height = nRows * this._item_size + totalSpacing;
let height = nRows * this._vItemSize + totalSpacing;
alloc.min_size = height;
alloc.natural_size = height;
},
@ -245,9 +245,9 @@ const IconGrid = new Lang.Class({
= children[i].get_preferred_size();
/* Center the item in its allocation horizontally */
let width = Math.min(this._item_size, childNaturalWidth);
let width = Math.min(this._hItemSize, childNaturalWidth);
let childXSpacing = Math.max(0, width - childNaturalWidth) / 2;
let height = Math.min(this._item_size, childNaturalHeight);
let height = Math.min(this._vItemSize, childNaturalHeight);
let childYSpacing = Math.max(0, height - childNaturalHeight) / 2;
let childBox = new Clutter.ActorBox();
@ -275,10 +275,10 @@ const IconGrid = new Lang.Class({
}
if (columnIndex == 0) {
y += this._item_size + this._spacing;
y += this._vItemSize + this._spacing;
x = box.x1 + leftPadding;
} else {
x += this._item_size + this._spacing;
x += this._hItemSize + this._spacing;
}
}
},
@ -291,8 +291,8 @@ const IconGrid = new Lang.Class({
let nColumns = 0;
let usedWidth = 0;
while ((this._colLimit == null || nColumns < this._colLimit) &&
(usedWidth + this._item_size <= forWidth)) {
usedWidth += this._item_size + this._spacing;
(usedWidth + this._hItemSize <= forWidth)) {
usedWidth += this._hItemSize + this._spacing;
nColumns += 1;
}
@ -305,7 +305,8 @@ const IconGrid = new Lang.Class({
_onStyleChanged: function() {
let themeNode = this.actor.get_theme_node();
this._spacing = themeNode.get_length('spacing');
this._item_size = themeNode.get_length('-shell-grid-item-size');
this._hItemSize = themeNode.get_length('-shell-grid-horizontal-item-size') || ICON_SIZE;
this._vItemSize = themeNode.get_length('-shell-grid-vertical-item-size') || ICON_SIZE;
this._grid.queue_relayout();
},

View File

@ -8,6 +8,7 @@ const Shell = imports.gi.Shell;
const Signals = imports.signals;
const St = imports.gi.St;
const DND = imports.ui.dnd;
const Main = imports.ui.main;
const Params = imports.misc.params;
const ScreenSaver = imports.misc.screenSaver;
@ -490,13 +491,15 @@ const HotCorner = new Lang.Class({
handleDragOver: function(source, actor, x, y, time) {
if (source != Main.xdndHandler)
return;
return DND.DragMotionResult.CONTINUE;
if (!Main.overview.visible && !Main.overview.animationInProgress) {
this.rippleAnimation();
Main.overview.showTemporarily();
Main.overview.beginItemDrag(actor);
}
return DND.DragMotionResult.CONTINUE;
},
_onCornerEntered : function() {

View File

@ -1,5 +1,6 @@
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
const Clutter = imports.gi.Clutter;
const Lang = imports.lang;
const Meta = imports.gi.Meta;
const St = imports.gi.St;
@ -57,11 +58,10 @@ const Lightbox = new Lang.Class({
if (params.width && params.height) {
this.actor.width = params.width;
this.actor.height = params.height;
this._allocationChangedSignalId = 0;
} else {
this.actor.width = container.width;
this.actor.height = container.height;
this._allocationChangedSignalId = container.connect('allocation-changed', Lang.bind(this, this._allocationChanged));
let constraint = new Clutter.BindConstraint({ source: container,
coordinate: Clutter.BindCoordinate.ALL });
this.actor.add_constraint(constraint);
}
this._actorAddedSignalId = container.connect('actor-added', Lang.bind(this, this._actorAdded));
@ -70,16 +70,6 @@ const Lightbox = new Lang.Class({
this._highlighted = null;
},
_allocationChanged : function(container, box, flags) {
Meta.later_add(Meta.LaterType.BEFORE_REDRAW, Lang.bind(this, function() {
this.actor.width = this.width;
this.actor.height = this.height;
return false;
}));
this.width = this._container.width;
this.height = this._container.height;
},
_actorAdded : function(container, newChild) {
let children = this._container.get_children();
let myIndex = children.indexOf(this.actor);
@ -187,8 +177,6 @@ const Lightbox = new Lang.Class({
* by destroying its container or by explicitly calling this.destroy().
*/
_onDestroy: function() {
if (this._allocationChangedSignalId != 0)
this._container.disconnect(this._allocationChangedSignalId);
this._container.disconnect(this._actorAddedSignalId);
this._container.disconnect(this._actorRemovedSignalId);

View File

@ -15,6 +15,7 @@ const Mainloop = imports.mainloop;
const History = imports.misc.history;
const ExtensionSystem = imports.ui.extensionSystem;
const ExtensionUtils = imports.misc.extensionUtils;
const Link = imports.ui.link;
const ShellEntry = imports.ui.shellEntry;
const Tweener = imports.ui.tweener;
@ -728,7 +729,7 @@ const Extensions = new Lang.Class({
this._extensionsList.add(this._noExtensions);
this.actor.add(this._extensionsList);
for (let uuid in ExtensionSystem.extensionMeta)
for (let uuid in ExtensionUtils.extensions)
this._loadExtension(null, uuid);
ExtensionSystem.connect('extension-loaded',
@ -736,10 +737,10 @@ const Extensions = new Lang.Class({
},
_loadExtension: function(o, uuid) {
let extension = ExtensionSystem.extensionMeta[uuid];
let extension = ExtensionUtils.extensions[uuid];
// There can be cases where we create dummy extension metadata
// that's not really a proper extension. Don't bother with these.
if (!extension.name)
if (!extension.metadata.name)
return;
let extensionDisplay = this._createExtensionDisplay(extension);
@ -751,32 +752,31 @@ const Extensions = new Lang.Class({
},
_onViewSource: function (actor) {
let meta = actor._extensionMeta;
let file = Gio.file_new_for_path(meta.path);
let uri = file.get_uri();
let extension = actor._extension;
let uri = extension.dir.get_uri();
Gio.app_info_launch_default_for_uri(uri, global.create_app_launch_context());
Main.lookingGlass.close();
},
_onWebPage: function (actor) {
let meta = actor._extensionMeta;
Gio.app_info_launch_default_for_uri(meta.url, global.create_app_launch_context());
let extension = actor._extension;
Gio.app_info_launch_default_for_uri(extension.metadata.url, global.create_app_launch_context());
Main.lookingGlass.close();
},
_onViewErrors: function (actor) {
let meta = actor._extensionMeta;
let extension = actor._extension;
let shouldShow = !actor._isShowing;
if (shouldShow) {
let errors = ExtensionSystem.errors[meta.uuid];
let errors = extension.errors;
let errorDisplay = new St.BoxLayout({ vertical: true });
if (errors && errors.length) {
for (let i = 0; i < errors.length; i ++)
errorDisplay.add(new St.Label({ text: errors[i] }));
} else {
/* Translators: argument is an extension UUID. */
let message = _("%s has not emitted any errors.").format(meta.uuid);
let message = _("%s has not emitted any errors.").format(extension.uuid);
errorDisplay.add(new St.Label({ text: message }));
}
@ -809,36 +809,36 @@ const Extensions = new Lang.Class({
return 'Unknown'; // Not translated, shouldn't appear
},
_createExtensionDisplay: function(meta) {
_createExtensionDisplay: function(extension) {
let box = new St.BoxLayout({ style_class: 'lg-extension', vertical: true });
let name = new St.Label({ style_class: 'lg-extension-name',
text: meta.name });
text: extension.metadata.name });
box.add(name, { expand: true });
let description = new St.Label({ style_class: 'lg-extension-description',
text: meta.description || 'No description' });
text: extension.metadata.description || 'No description' });
box.add(description, { expand: true });
let metaBox = new St.BoxLayout({ style_class: 'lg-extension-meta' });
box.add(metaBox);
let stateString = this._stateToString(meta.state);
let stateString = this._stateToString(extension.state);
let state = new St.Label({ style_class: 'lg-extension-state',
text: this._stateToString(meta.state) });
text: this._stateToString(extension.state) });
metaBox.add(state);
let viewsource = new Link.Link({ label: _("View Source") });
viewsource.actor._extensionMeta = meta;
viewsource.actor._extension = extension;
viewsource.actor.connect('clicked', Lang.bind(this, this._onViewSource));
metaBox.add(viewsource.actor);
if (meta.url) {
if (extension.metadata.url) {
let webpage = new Link.Link({ label: _("Web Page") });
webpage.actor._extensionMeta = meta;
webpage.actor._extension = extension;
webpage.actor.connect('clicked', Lang.bind(this, this._onWebPage));
metaBox.add(webpage.actor);
}
let viewerrors = new Link.Link({ label: _("Show Errors") });
viewerrors.actor._extensionMeta = meta;
viewerrors.actor._extension = extension;
viewerrors.actor._parentBox = box;
viewerrors.actor._isShowing = false;
viewerrors.actor.connect('clicked', Lang.bind(this, this._onViewErrors));
@ -1038,7 +1038,7 @@ const LookingGlass = new Lang.Class({
actor.add(padBin);
this._completionActor = actor;
this._evalBox.insert_before(this._completionActor, this._entryArea);
this._evalBox.insert_child_below(this._completionActor, this._entryArea);
}
this._completionText.set_text(completions.join(', '));

View File

@ -556,6 +556,7 @@ const ZoomRegion = new Lang.Class({
this._screenPosition = GDesktopEnums.MagnifierScreenPosition.FULL_SCREEN;
this._magView = null;
this._background = null;
this._uiGroupClone = null;
this._mouseSourceActor = mouseSourceActor;
this._mouseActor = null;
@ -565,12 +566,15 @@ const ZoomRegion = new Lang.Class({
this._viewPortX = 0;
this._viewPortY = 0;
this._viewPortWidth = global.screen_width;
this._viewPortWidth = global.screen_height;
this._viewPortHeight = global.screen_height;
this._xCenter = this._viewPortWidth / 2;
this._yCenter = this._viewPortHeight / 2;
this._xMagFactor = 1;
this._yMagFactor = 1;
this._followingCursor = false;
Main.layoutManager.connect('monitors-changed',
Lang.bind(this, this._monitorsChanged));
},
/**
@ -891,15 +895,15 @@ const ZoomRegion = new Lang.Class({
// Add a background for when the magnified uiGroup is scrolled
// out of view (don't want to see desktop showing through).
let background = new Clutter.Rectangle({ color: Main.DEFAULT_BACKGROUND_COLOR });
mainGroup.add_actor(background);
this._background = new Clutter.Rectangle({ color: Main.DEFAULT_BACKGROUND_COLOR });
mainGroup.add_actor(this._background);
// Clone the group that contains all of UI on the screen. This is the
// chrome, the windows, etc.
this._uiGroupClone = new Clutter.Clone({ source: Main.uiGroup });
mainGroup.add_actor(this._uiGroupClone);
Main.uiGroup.set_size(global.screen_width, global.screen_height);
background.set_size(global.screen_width, global.screen_height);
this._background.set_size(global.screen_width, global.screen_height);
// Add either the given mouseSourceActor to the ZoomRegion, or a clone of
// it.
@ -923,6 +927,7 @@ const ZoomRegion = new Lang.Class({
this._magView.destroy();
this._magView = null;
this._background = null;
this._uiGroupClone = null;
this._mouseActor = null;
this._crossHairsActor = null;
@ -1145,6 +1150,22 @@ const ZoomRegion = new Lang.Class({
this._crossHairsActor.set_position(xMagMouse - groupWidth / 2,
yMagMouse - groupHeight / 2);
}
},
_monitorsChanged: function() {
if (!this.isActive())
return;
Main.uiGroup.set_size(global.screen_width, global.screen_height);
this._background.set_size(global.screen_width, global.screen_height);
if (this._screenPosition == GDesktopEnums.MagnifierScreenPosition.NONE)
this._setViewPort({ x: this._viewPortX,
y: this._viewPortY,
width: this._viewPortWidth,
height: this._viewPortHeight });
else
this.setScreenPosition(this._screenPosition);
}
});
@ -1175,6 +1196,14 @@ const Crosshairs = new Lang.Class({
this._clipSize = [0, 0];
this._clones = [];
this.reCenter();
Main.layoutManager.connect('monitors-changed',
Lang.bind(this, this._monitorsChanged));
},
_monitorsChanged: function() {
this._actor.set_size(global.screen_width * 3, global.screen_height * 3);
this.reCenter();
},
/**

View File

@ -187,7 +187,9 @@ function start() {
for (let i = 0; i < children.length; i++)
children[i].allocate_preferred_size(flags);
});
St.set_ui_root(global.stage, uiGroup);
let constraint = new Clutter.BindConstraint({ source: global.stage,
coordinate: Clutter.BindCoordinate.SIZE });
uiGroup.add_constraint(constraint);
global.window_group.reparent(uiGroup);
global.overlay_group.reparent(uiGroup);
global.stage.add_actor(uiGroup);

View File

@ -1327,8 +1327,9 @@ const SummaryItem = new Lang.Class({
}
}
if (this.notificationStack.get_children().length > 0)
this.notificationStack.get_children()[0]._delegate.setIconVisible(true);
let firstNotification = this._stackedNotifications[0];
if (firstNotification)
firstNotification.notification.setIconVisible(true);
}
});
Signals.addSignalMethods(SummaryItem.prototype);
@ -1519,10 +1520,10 @@ const MessageTray = new Lang.Class({
let summaryItem = new SummaryItem(source);
if (source.isChat) {
this._summary.insert_actor(summaryItem.actor, 0);
this._summary.insert_child_at_index(summaryItem.actor, 0);
this._chatSummaryItemsCount++;
} else {
this._summary.insert_actor(summaryItem.actor, this._chatSummaryItemsCount);
this._summary.insert_child_at_index(summaryItem.actor, this._chatSummaryItemsCount);
}
let titleWidth = summaryItem.getTitleNaturalWidth();
@ -2048,8 +2049,11 @@ const MessageTray = new Lang.Class({
if (haveClickedSummaryItem && !summarySourceIsMainNotificationSource && canShowSummaryBoxPointer && !requestedNotificationStackIsEmpty)
this._showSummaryBoxPointer();
} else if (this._summaryBoxPointerState == State.SHOWN) {
if (!haveClickedSummaryItem || !canShowSummaryBoxPointer || wrongSummaryBoxPointer || mustHideSummary)
if (!haveClickedSummaryItem || !canShowSummaryBoxPointer || wrongSummaryBoxPointer || mustHideSummary) {
this._hideSummaryBoxPointer();
if (wrongSummaryBoxPointer)
this._showSummaryBoxPointer();
}
}
// Tray itself
@ -2390,9 +2394,8 @@ const MessageTray = new Lang.Class({
}
this._summaryBoxPointerState = State.HIDING;
// Unset this._clickedSummaryItem if we are no longer showing the summary or if
// this._clickedSummaryItem is still the item associated with the currently showing box pointer
if (this._summaryState != State.SHOWN || this._summaryBoxPointerItem == this._clickedSummaryItem)
// Unset this._clickedSummaryItem if we are no longer showing the summary
if (this._summaryState != State.SHOWN)
this._unsetClickedSummaryItem();
this._focusGrabber.ungrabFocus();

View File

@ -46,7 +46,7 @@ const ModalDialog = new Lang.Class({
Main.uiGroup.add_actor(this._group);
let constraint = new Clutter.BindConstraint({ source: global.stage,
coordinate: Clutter.BindCoordinate.POSITION | Clutter.BindCoordinate.SIZE });
coordinate: Clutter.BindCoordinate.ALL });
this._group.add_constraint(constraint);
this._group.connect('destroy', Lang.bind(this, this._onGroupDestroy));
@ -105,7 +105,7 @@ const ModalDialog = new Lang.Class({
setButtons: function(buttons) {
let hadChildren = this._buttonLayout.get_children() > 0;
this._buttonLayout.destroy_children();
this._buttonLayout.destroy_all_children();
this._actionKeys = {};
for (let i = 0; i < buttons.length; i++) {

View File

@ -21,6 +21,8 @@
const Clutter = imports.gi.Clutter;
const Gio = imports.gi.Gio;
const GLib = imports.gi.GLib;
const GObject = imports.gi.GObject;
const Lang = imports.lang;
const NetworkManager = imports.gi.NetworkManager;
const NMClient = imports.gi.NMClient;
@ -28,16 +30,19 @@ const Pango = imports.gi.Pango;
const Shell = imports.gi.Shell;
const St = imports.gi.St;
const Config = imports.misc.config;
const ModalDialog = imports.ui.modalDialog;
const PopupMenu = imports.ui.popupMenu;
const ShellEntry = imports.ui.shellEntry;
const VPN_UI_GROUP = 'VPN Plugin UI';
const NetworkSecretDialog = new Lang.Class({
Name: 'NetworkSecretDialog',
Extends: ModalDialog.ModalDialog,
_init: function(agent, requestId, connection, settingName, hints) {
this.parent({ styleClass: 'polkit-dialog' });
_init: function(agent, requestId, connection, settingName, hints, contentOverride) {
this.parent({ styleClass: 'prompt-dialog' });
this._agent = agent;
this._requestId = requestId;
@ -45,9 +50,12 @@ const NetworkSecretDialog = new Lang.Class({
this._settingName = settingName;
this._hints = hints;
this._content = this._getContent();
if (contentOverride)
this._content = contentOverride;
else
this._content = this._getContent();
let mainContentBox = new St.BoxLayout({ style_class: 'polkit-dialog-main-layout',
let mainContentBox = new St.BoxLayout({ style_class: 'prompt-dialog-main-layout',
vertical: false });
this.contentLayout.add(mainContentBox,
{ x_fill: true,
@ -60,19 +68,19 @@ const NetworkSecretDialog = new Lang.Class({
x_align: St.Align.END,
y_align: St.Align.START });
let messageBox = new St.BoxLayout({ style_class: 'polkit-dialog-message-layout',
let messageBox = new St.BoxLayout({ style_class: 'prompt-dialog-message-layout',
vertical: true });
mainContentBox.add(messageBox,
{ y_align: St.Align.START });
let subjectLabel = new St.Label({ style_class: 'polkit-dialog-headline',
let subjectLabel = new St.Label({ style_class: 'prompt-dialog-headline',
text: this._content.title });
messageBox.add(subjectLabel,
{ y_fill: false,
y_align: St.Align.START });
if (this._content.message != null) {
let descriptionLabel = new St.Label({ style_class: 'polkit-dialog-description',
let descriptionLabel = new St.Label({ style_class: 'prompt-dialog-description',
text: this._content.message,
// HACK: for reasons unknown to me, the label
// is not asked the correct height for width,
@ -93,12 +101,12 @@ const NetworkSecretDialog = new Lang.Class({
let pos = 0;
for (let i = 0; i < this._content.secrets.length; i++) {
let secret = this._content.secrets[i];
let label = new St.Label({ style_class: 'polkit-dialog-password-label',
let label = new St.Label({ style_class: 'prompt-dialog-password-label',
text: secret.label });
let reactive = secret.key != null;
secret.entry = new St.Entry({ style_class: 'polkit-dialog-password-entry',
secret.entry = new St.Entry({ style_class: 'prompt-dialog-password-entry',
text: secret.value, can_focus: reactive,
reactive: reactive });
ShellEntry.addContextMenu(secret.entry,
@ -174,14 +182,14 @@ const NetworkSecretDialog = new Lang.Class({
}
if (valid) {
this._agent.respond(this._requestId, false);
this._agent.respond(this._requestId, Shell.NetworkAgentResponse.CONFIRMED);
this.close(global.get_current_time());
}
// do nothing if not valid
},
cancel: function() {
this._agent.respond(this._requestId, true);
this._agent.respond(this._requestId, Shell.NetworkAgentResponse.USER_CANCELED);
this.close(global.get_current_time());
},
@ -357,6 +365,240 @@ const NetworkSecretDialog = new Lang.Class({
}
});
const VPNRequestHandler = new Lang.Class({
Name: 'VPNRequestHandler',
_init: function(agent, requestId, authHelper, serviceType, connection, hints, flags) {
this._agent = agent;
this._requestId = requestId;
this._connection = connection;
this._pluginOutBuffer = [];
this._title = null;
this._description = null;
this._content = [ ];
this._shellDialog = null;
let connectionSetting = connection.get_setting_connection();
let argv = [ authHelper.fileName,
'-u', connectionSetting.uuid,
'-n', connectionSetting.id,
'-s', serviceType
];
if (authHelper.externalUIMode)
argv.push('--external-ui-mode');
if (flags & NMClient.SecretAgentGetSecretsFlags.ALLOW_INTERACTION)
argv.push('-i');
if (flags & NMClient.SecretAgentGetSecretsFlags.REQUEST_NEW)
argv.push('-r');
this._newStylePlugin = authHelper.externalUIMode;
try {
let [success, pid, stdin, stdout, stderr] =
GLib.spawn_async_with_pipes(null, /* pwd */
argv,
null, /* envp */
GLib.SpawnFlags.DO_NOT_REAP_CHILD,
null /* child_setup */);
this._childPid = pid;
this._stdin = new Gio.UnixOutputStream({ fd: stdin, close_fd: true });
this._stdout = new Gio.UnixInputStream({ fd: stdout, close_fd: true });
// We need this one too, even if don't actually care of what the process
// has to say on stderr, because otherwise the fd opened by g_spawn_async_with_pipes
// is kept open indefinitely
let stderrStream = new Gio.UnixInputStream({ fd: stderr, close_fd: true });
stderrStream.close(null);
this._dataStdout = new Gio.DataInputStream({ base_stream: this._stdout });
if (this._newStylePlugin)
this._readStdoutNewStyle();
else
this._readStdoutOldStyle();
this._childWatch = GLib.child_watch_add(GLib.PRIORITY_DEFAULT, pid,
Lang.bind(this, this._vpnChildFinished));
this._writeConnection();
} catch(e) {
logError(e, 'error while spawning VPN auth helper');
this._agent.respond(requestId, Shell.NetworkAgentResponse.INTERNAL_ERROR);
}
},
cancel: function() {
if (this._newStylePlugin && this._shellDialog) {
this._shellDialog.close(global.get_current_time());
this._shellDialog.destroy();
} else {
try {
this._stdin.write('QUIT\n\n', null);
} catch(e) { /* ignore broken pipe errors */ }
}
this.destroy();
},
destroy: function() {
if (this._destroyed)
return;
GLib.source_remove(this._childWatch);
this._stdin.close(null);
// Stdout is closed when we finish reading from it
this._destroyed = true;
},
_vpnChildFinished: function(pid, status, requestObj) {
if (this._newStylePlugin) {
// For new style plugin, all work is done in the async reading functions
// Just reap the process here
return;
}
let [exited, exitStatus] = Shell.util_wifexited(status);
if (exited) {
if (exitStatus != 0)
this._agent.respond(this._requestId, Shell.NetworkAgentResponse.USER_CANCELED);
else
this._agent.respond(this._requestId, Shell.NetworkAgentResponse.CONFIRMED);
} else
this._agent.respond(this._requestId, Shell.NetworkAgentResponse.INTERNAL_ERROR);
this.destroy();
},
_vpnChildProcessLineOldStyle: function(line) {
if (this._previousLine != undefined) {
// Two consecutive newlines mean that the child should be closed
// (the actual newlines are eaten by Gio.DataInputStream)
// Send a termination message
if (line == '' && this._previousLine == '') {
try {
this._stdin.write('QUIT\n\n', null);
} catch(e) { /* ignore broken pipe errors */ }
} else {
this._agent.set_password(this._requestId, this._previousLine, line);
this._previousLine = undefined;
}
} else {
this._previousLine = line;
}
},
_readStdoutOldStyle: function() {
this._dataStdout.read_line_async(GLib.PRIORITY_DEFAULT, null, Lang.bind(this, function(stream, result) {
let [line, len] = this._dataStdout.read_line_finish_utf8(result);
if (line == null) {
// end of file
this._stdout.close(null);
return;
}
this._vpnChildProcessLineOldStyle(line);
// try to read more!
this._readStdoutOldStyle();
}));
},
_readStdoutNewStyle: function() {
this._dataStdout.fill_async(-1, GLib.PRIORITY_DEFAULT, null, Lang.bind(this, function(stream, result) {
let cnt = this._dataStdout.fill_finish(result);
if (cnt == 0) {
// end of file
this._showNewStyleDialog();
this._stdout.close(null);
return;
}
// Try to read more
this._dataStdout.set_buffer_size(2 * this._dataStdout.get_buffer_size());
this._readStdoutNewStyle();
}));
},
_showNewStyleDialog: function() {
let keyfile = new GLib.KeyFile();
let contentOverride;
try {
keyfile.load_from_data(this._dataStdout.peek_buffer(), -1,
GLib.KeyFileFlags.NONE);
if (keyfile.get_integer(VPN_UI_GROUP, 'Version') != 2)
throw new Error('Invalid plugin keyfile version, is %d');
contentOverride = { title: keyfile.get_string(VPN_UI_GROUP, 'Title'),
message: keyfile.get_string(VPN_UI_GROUP, 'Description'),
secrets: [] };
let [groups, len] = keyfile.get_groups();
for (let i = 0; i < groups.length; i++) {
if (groups[i] == VPN_UI_GROUP)
continue;
let value = keyfile.get_string(groups[i], 'Value');
let shouldAsk = keyfile.get_boolean(groups[i], 'ShouldAsk');
if (shouldAsk) {
contentOverride.secrets.push({ label: keyfile.get_string(groups[i], 'Label'),
key: groups[i],
value: value,
password: keyfile.get_boolean(groups[i], 'IsSecret')
});
} else {
if (!value.length) // Ignore empty secrets
continue;
this._agent.set_password(this._requestId, groups[i], value);
}
}
} catch(e) {
logError(e, 'error while reading VPN plugin output keyfile');
this._agent.respond(this._requestId, Shell.NetworkAgentResponse.INTERNAL_ERROR);
return;
}
if (contentOverride.secrets.length) {
// Only show the dialog if we actually have something to ask
this._shellDialog = new NetworkSecretDialog(this._agent, this._requestId, this._connection, 'vpn', [], contentOverride);
this._shellDialog.open(global.get_current_time());
} else {
this._agent.respond(this._requestId, Shell.NetworkAgentResponse.CONFIRMED);
}
},
_writeConnection: function() {
let vpnSetting = this._connection.get_setting_vpn();
try {
vpnSetting.foreach_data_item(Lang.bind(this, function(key, value) {
this._stdin.write('DATA_KEY=' + key + '\n', null);
this._stdin.write('DATA_VAL=' + (value || '') + '\n\n', null);
}));
vpnSetting.foreach_secret(Lang.bind(this, function(key, value) {
this._stdin.write('SECRET_KEY=' + key + '\n', null);
this._stdin.write('SECRET_VAL=' + (value || '') + '\n\n', null);
}));
this._stdin.write('DONE\n\n', null);
} catch(e) {
logError(e, 'internal error while writing connection to helper');
this._agent.respond(this._requestId, Shell.NetworkAgentResponse.INTERNAL_ERROR);
}
},
});
const NetworkAgent = new Lang.Class({
Name: 'NetworkAgent',
@ -365,11 +607,18 @@ const NetworkAgent = new Lang.Class({
identifier: 'org.gnome.Shell.NetworkAgent' });
this._dialogs = { };
this._vpnRequests = { };
this._native.connect('new-request', Lang.bind(this, this._newRequest));
this._native.connect('cancel-request', Lang.bind(this, this._cancelRequest));
},
_newRequest: function(agent, requestId, connection, settingName, hints) {
_newRequest: function(agent, requestId, connection, settingName, hints, flags) {
if (settingName == 'vpn') {
this._vpnRequest(requestId, connection, hints, flags);
return;
}
let dialog = new NetworkSecretDialog(agent, requestId, connection, settingName, hints);
dialog.connect('destroy', Lang.bind(this, function() {
delete this._dialogs[requestId];
@ -379,7 +628,74 @@ const NetworkAgent = new Lang.Class({
},
_cancelRequest: function(agent, requestId) {
this._dialogs[requestId].close(global.get_current_time());
this._dialogs[requestId].destroy();
if (this._dialogs[requestId]) {
this._dialogs[requestId].close(global.get_current_time());
this._dialogs[requestId].destroy();
delete this._dialogs[requestId];
} else if (this._vpnRequests[requestId]) {
this._vpnRequests[requestId].cancel();
delete this._vpnRequests[requestId];
}
},
_vpnRequest: function(requestId, connection, hints, flags) {
let vpnSetting = connection.get_setting_vpn();
let serviceType = vpnSetting.service_type;
this._buildVPNServiceCache();
let binary = this._vpnBinaries[serviceType];
if (!binary) {
log('Invalid VPN service type (cannot find authentication binary)');
/* cancel the auth process */
this._native.respond(requestId, Shell.NetworkAgentResponse.INTERNAL_ERROR);
return;
}
this._vpnRequests[requestId] = new VPNRequestHandler(this._native, requestId, binary, serviceType, connection, hints, flags);
},
_buildVPNServiceCache: function() {
if (this._vpnCacheBuilt)
return;
this._vpnCacheBuilt = true;
this._vpnBinaries = { };
let dir = Gio.file_new_for_path(GLib.build_filenamev([Config.SYSCONFDIR, 'NetworkManager/VPN']));
try {
let fileEnum = dir.enumerate_children('standard::name', Gio.FileQueryInfoFlags.NONE, null);
let info;
while ((info = fileEnum.next_file(null))) {
let name = info.get_name();
if (name.substr(-5) != '.name')
continue;
try {
let keyfile = new GLib.KeyFile();
keyfile.load_from_file(dir.get_child(name).get_path(), GLib.KeyFileFlags.NONE);
let service = keyfile.get_string('VPN Connection', 'service');
let binary = keyfile.get_string('GNOME', 'auth-dialog');
let externalUIMode = false;
try {
externalUIMode = keyfile.get_boolean('GNOME', 'supports-external-ui-mode');
} catch(e) { } // ignore errors if key does not exist
let path = GLib.build_filenamev([Config.LIBEXECDIR, binary]);
if (GLib.file_test(path, GLib.FileTest.IS_EXECUTABLE))
this._vpnBinaries[service] = { fileName: path, externalUIMode: externalUIMode };
else
throw new Error('VPN plugin at %s is not executable'.format(path));
} catch(e) {
log('Error \'%s\' while processing VPN keyfile \'%s\''.
format(e.message, dir.get_child(name).get_path()));
continue;
}
}
} catch(e) {
logError(e, 'error while enumerating VPN auth helpers');
}
}
});

View File

@ -14,13 +14,13 @@ const AppDisplay = imports.ui.appDisplay;
const ContactDisplay = imports.ui.contactDisplay;
const Dash = imports.ui.dash;
const DND = imports.ui.dnd;
const DocDisplay = imports.ui.docDisplay;
const Lightbox = imports.ui.lightbox;
const Main = imports.ui.main;
const MessageTray = imports.ui.messageTray;
const Panel = imports.ui.panel;
const Params = imports.misc.params;
const PlaceDisplay = imports.ui.placeDisplay;
const RemoteSearch = imports.ui.remoteSearch;
const Tweener = imports.ui.tweener;
const ViewSelector = imports.ui.viewSelector;
const Wanda = imports.ui.wanda;
@ -207,9 +207,11 @@ const Overview = new Lang.Class({
this.addSearchProvider(new AppDisplay.AppSearchProvider());
this.addSearchProvider(new AppDisplay.SettingsSearchProvider());
this.addSearchProvider(new PlaceDisplay.PlaceSearchProvider());
this.addSearchProvider(new DocDisplay.DocSearchProvider());
this.addSearchProvider(new ContactDisplay.ContactSearchProvider());
// Load remote search providers provided by applications
RemoteSearch.loadRemoteSearchProviders(Lang.bind(this, this.addSearchProvider));
// TODO - recalculate everything when desktop size changes
this._dash = new Dash.Dash();
this._group.add_actor(this._dash.actor);

View File

@ -13,6 +13,7 @@ const Signals = imports.signals;
const Config = imports.misc.config;
const CtrlAltTab = imports.ui.ctrlAltTab;
const DND = imports.ui.dnd;
const Layout = imports.ui.layout;
const Overview = imports.ui.overview;
const PopupMenu = imports.ui.popupMenu;
@ -105,38 +106,47 @@ const AnimatedIcon = new Lang.Class({
_init: function(name, size) {
this.actor = new St.Bin({ visible: false });
this.actor.connect('destroy', Lang.bind(this, this._onDestroy));
this.actor.connect('notify::visible', Lang.bind(this, function() {
if (this.actor.visible) {
this._timeoutId = Mainloop.timeout_add(ANIMATED_ICON_UPDATE_TIMEOUT, Lang.bind(this, this._update));
} else {
if (this._timeoutId)
Mainloop.source_remove(this._timeoutId);
this._timeoutId = 0;
}
}));
this.actor.connect('notify::visible', Lang.bind(this, this._onVisibleNotify));
this._timeoutId = 0;
this._i = 0;
this._frame = 0;
this._animations = St.TextureCache.get_default().load_sliced_image (global.datadir + '/theme/' + name, size, size);
this.actor.set_child(this._animations);
},
_update: function() {
this._animations.hide_all();
this._animations.show();
if (this._i && this._i < this._animations.get_n_children())
this._animations.get_nth_child(this._i++).show();
else {
this._i = 1;
if (this._animations.get_n_children())
this._animations.get_nth_child(0).show();
_disconnectTimeout: function() {
if (this._timeoutId > 0) {
Mainloop.source_remove(this._timeoutId);
this._timeoutId = 0;
}
},
_onVisibleNotify: function() {
if (this.actor.visible)
this._timeoutId = Mainloop.timeout_add(ANIMATED_ICON_UPDATE_TIMEOUT, Lang.bind(this, this._update));
else
this._disconnectTimeout();
},
_showFrame: function(frame) {
let oldFrameActor = this._animations.get_child_at_index(this._frame);
if (oldFrameActor)
oldFrameActor.hide();
this._frame = (frame % this._animations.get_n_children());
let newFrameActor = this._animations.get_child_at_index(this._frame);
if (newFrameActor)
newFrameActor.show();
},
_update: function() {
this._showFrame(this._frame + 1);
return true;
},
_onDestroy: function() {
if (this._timeoutId)
Mainloop.source_remove(this._timeoutId);
this._disconnectTimeout();
}
});
@ -237,7 +247,7 @@ const AppMenuButton = new Lang.Class({
Extends: PanelMenu.Button,
_init: function(menuManager) {
this.parent(0.0, true);
this.parent(0.0, null, true);
this._startingApps = [];
@ -249,6 +259,7 @@ const AppMenuButton = new Lang.Class({
let bin = new St.Bin({ name: 'appMenu' });
this.actor.add_actor(bin);
this.actor.bind_property("reactive", this.actor, "can-focus", 0);
this.actor.reactive = false;
this._targetIsCurrent = false;
@ -497,6 +508,9 @@ const AppMenuButton = new Lang.Class({
return;
}
if (!targetApp.is_on_workspace(workspace))
return;
if (!this._targetIsCurrent) {
this.actor.reactive = true;
this._targetIsCurrent = true;
@ -537,6 +551,7 @@ const AppMenuButton = new Lang.Class({
let icon = targetApp.get_faded_icon(2 * PANEL_ICON_SIZE);
this._label.setText(targetApp.get_name());
this.setName(targetApp.get_name());
this._iconBox.set_child(icon);
this._iconBox.show();
@ -655,12 +670,14 @@ const ActivitiesButton = new Lang.Class({
handleDragOver: function(source, actor, x, y, time) {
if (source != Main.xdndHandler)
return;
return DND.DragMotionResult.CONTINUE;
if (this._xdndTimeOut != 0)
Mainloop.source_remove(this._xdndTimeOut);
this._xdndTimeOut = Mainloop.timeout_add(BUTTON_DND_ACTIVATION_TIMEOUT,
Lang.bind(this, this._xdndShowOverview, actor));
return DND.DragMotionResult.CONTINUE;
},
_escapeMenuGrab: function() {
@ -836,12 +853,10 @@ const PanelCorner = new Lang.Class({
let node = this.actor.get_theme_node();
let cornerRadius = node.get_length("-panel-corner-radius");
let innerBorderWidth = node.get_length('-panel-corner-inner-border-width');
let outerBorderWidth = node.get_length('-panel-corner-outer-border-width');
let borderWidth = node.get_length('-panel-corner-border-width');
let backgroundColor = node.get_color('-panel-corner-background-color');
let innerBorderColor = node.get_color('-panel-corner-inner-border-color');
let outerBorderColor = node.get_color('-panel-corner-outer-border-color');
let borderColor = node.get_color('-panel-corner-border-color');
let cr = this.actor.get_context();
cr.setOperator(Cairo.Operator.SOURCE);
@ -849,40 +864,23 @@ const PanelCorner = new Lang.Class({
cr.moveTo(0, 0);
if (this._side == St.Side.LEFT)
cr.arc(cornerRadius,
innerBorderWidth + cornerRadius,
borderWidth + cornerRadius,
cornerRadius, Math.PI, 3 * Math.PI / 2);
else
cr.arc(0,
innerBorderWidth + cornerRadius,
borderWidth + cornerRadius,
cornerRadius, 3 * Math.PI / 2, 2 * Math.PI);
cr.lineTo(cornerRadius, 0);
cr.closePath();
let savedPath = cr.copyPath();
let over = _over(innerBorderColor,
_over(outerBorderColor, backgroundColor));
Clutter.cairo_set_source_color(cr, over);
cr.fill();
let xOffsetDirection = this._side == St.Side.LEFT ? -1 : 1;
let offset = outerBorderWidth;
over = _over(innerBorderColor, backgroundColor);
let over = _over(borderColor, backgroundColor);
Clutter.cairo_set_source_color(cr, over);
cr.save();
cr.translate(xOffsetDirection * offset, - offset);
cr.appendPath(savedPath);
cr.fill();
cr.restore();
if (this._side == St.Side.LEFT)
cr.rectangle(cornerRadius - offset, 0, offset, outerBorderWidth);
else
cr.rectangle(0, 0, offset, outerBorderWidth);
cr.fill();
offset = innerBorderWidth;
let offset = borderWidth;
Clutter.cairo_set_source_color(cr, backgroundColor);
cr.save();
@ -896,10 +894,10 @@ const PanelCorner = new Lang.Class({
let node = this.actor.get_theme_node();
let cornerRadius = node.get_length("-panel-corner-radius");
let innerBorderWidth = node.get_length('-panel-corner-inner-border-width');
let borderWidth = node.get_length('-panel-corner-border-width');
this.actor.set_size(cornerRadius, innerBorderWidth + cornerRadius);
this.actor.set_anchor_point(0, innerBorderWidth);
this.actor.set_size(cornerRadius, borderWidth + cornerRadius);
this.actor.set_anchor_point(0, borderWidth);
}
});
@ -1080,13 +1078,13 @@ const Panel = new Lang.Class({
for (i = children.length - 1; i >= 0; i--) {
let rolePosition = children[i]._rolePosition;
if (position > rolePosition) {
this._rightBox.insert_actor(actor, i + 1);
this._rightBox.insert_child_at_index(actor, i + 1);
break;
}
}
if (i == -1) {
// If we didn't find a position, we must be first
this._rightBox.insert_actor(actor, 0);
this._rightBox.insert_child_at_index(actor, 0);
}
actor._rolePosition = position;
},

View File

@ -96,7 +96,7 @@ const Button = new Lang.Class({
Name: 'PanelMenuButton',
Extends: ButtonBox,
_init: function(menuAlignment, dontCreateMenu) {
_init: function(menuAlignment, nameText, dontCreateMenu) {
this.parent({ reactive: true,
can_focus: true,
track_hover: true });
@ -108,6 +108,24 @@ const Button = new Lang.Class({
this.menu = null;
else
this.setMenu(new PopupMenu.PopupMenu(this.actor, menuAlignment, St.Side.TOP, 0));
this.setName(nameText);
},
setName: function(text) {
if (text != null) {
// This is the easiest way to provide a accessible name to
// this widget. The label could be also used for other
// purposes in the future.
if (!this.label) {
this.label = new St.Label({ text: text });
this.actor.label_actor = this.label;
} else
this.label.text = text;
} else {
this.label = null;
this.actor.label_actor = null;
}
},
setMenu: function(menu) {
@ -197,21 +215,20 @@ Signals.addSignalMethods(Button.prototype);
*
* This class manages one System Status indicator (network, keyboard,
* volume, bluetooth...), which is just a PanelMenuButton with an
* icon and a tooltip
* icon.
*/
const SystemStatusButton = new Lang.Class({
Name: 'SystemStatusButton',
Extends: Button,
_init: function(iconName,tooltipText) {
this.parent(0.0);
_init: function(iconName, nameText) {
this.parent(0.0, nameText);
this._iconActor = new St.Icon({ icon_name: iconName,
icon_type: St.IconType.SYMBOLIC,
style_class: 'system-status-icon' });
this.actor.add_actor(this._iconActor);
this.actor.add_style_class_name('panel-status-button');
this.setTooltip(tooltipText);
},
setIcon: function(iconName) {
@ -220,16 +237,5 @@ const SystemStatusButton = new Lang.Class({
setGIcon: function(gicon) {
this._iconActor.gicon = gicon;
},
setTooltip: function(text) {
if (text != null) {
this.tooltip = text;
this.actor.has_tooltip = true;
this.actor.tooltip_text = text;
} else {
this.actor.has_tooltip = false;
this.tooltip = null;
}
}
});

View File

@ -157,8 +157,8 @@ const PlacesManager = new Lang.Class({
function (size) {
// do NOT use St.Icon here, it crashes the shell
// see wanda.js for details
return St.TextureCache.get_default().load_icon_name('applications-internet',
null,
return St.TextureCache.get_default().load_icon_name(null,
'applications-internet',
St.IconType.FULLCOLOR,
size);
},
@ -367,16 +367,21 @@ const PlaceSearchProvider = new Lang.Class({
this.parent(_("PLACES & DEVICES"));
},
getResultMeta: function(resultId) {
let placeInfo = Main.placesManager.lookupPlaceById(resultId);
if (!placeInfo)
return null;
return { 'id': resultId,
'name': placeInfo.name,
'createIcon': function(size) {
return placeInfo.iconFactory(size);
}
};
getResultMetas: function(resultIds) {
let metas = [];
for (let i = 0; i < resultIds.length; i++) {
let placeInfo = Main.placesManager.lookupPlaceById(resultIds[i]);
if (!placeInfo)
metas.push(null);
else
metas.push({ 'id': resultIds[i],
'name': placeInfo.name,
'createIcon': function(size) {
return placeInfo.iconFactory(size);
}
});
}
return metas;
},
activateResult: function(id, params) {

View File

@ -41,7 +41,7 @@ const AuthenticationDialog = new Lang.Class({
Extends: ModalDialog.ModalDialog,
_init: function(actionId, message, cookie, userNames) {
this.parent({ styleClass: 'polkit-dialog' });
this.parent({ styleClass: 'prompt-dialog' });
this.actionId = actionId;
this.message = message;
@ -49,7 +49,7 @@ const AuthenticationDialog = new Lang.Class({
this._wasDismissed = false;
this._completed = false;
let mainContentBox = new St.BoxLayout({ style_class: 'polkit-dialog-main-layout',
let mainContentBox = new St.BoxLayout({ style_class: 'prompt-dialog-main-layout',
vertical: false });
this.contentLayout.add(mainContentBox,
{ x_fill: true,
@ -62,19 +62,19 @@ const AuthenticationDialog = new Lang.Class({
x_align: St.Align.END,
y_align: St.Align.START });
let messageBox = new St.BoxLayout({ style_class: 'polkit-dialog-message-layout',
let messageBox = new St.BoxLayout({ style_class: 'prompt-dialog-message-layout',
vertical: true });
mainContentBox.add(messageBox,
{ y_align: St.Align.START });
this._subjectLabel = new St.Label({ style_class: 'polkit-dialog-headline',
this._subjectLabel = new St.Label({ style_class: 'prompt-dialog-headline',
text: _("Authentication Required") });
messageBox.add(this._subjectLabel,
{ y_fill: false,
y_align: St.Align.START });
this._descriptionLabel = new St.Label({ style_class: 'polkit-dialog-description',
this._descriptionLabel = new St.Label({ style_class: 'prompt-dialog-description',
text: message });
this._descriptionLabel.clutter_text.ellipsize = Pango.EllipsizeMode.NONE;
this._descriptionLabel.clutter_text.line_wrap = true;
@ -137,9 +137,9 @@ const AuthenticationDialog = new Lang.Class({
this._passwordBox = new St.BoxLayout({ vertical: false });
messageBox.add(this._passwordBox);
this._passwordLabel = new St.Label(({ style_class: 'polkit-dialog-password-label' }));
this._passwordLabel = new St.Label(({ style_class: 'prompt-dialog-password-label' }));
this._passwordBox.add(this._passwordLabel);
this._passwordEntry = new St.Entry({ style_class: 'polkit-dialog-password-entry',
this._passwordEntry = new St.Entry({ style_class: 'prompt-dialog-password-entry',
text: "",
can_focus: true});
ShellEntry.addContextMenu(this._passwordEntry, { isPassword: true });
@ -149,13 +149,13 @@ const AuthenticationDialog = new Lang.Class({
this.setInitialKeyFocus(this._passwordEntry);
this._passwordBox.hide();
this._errorMessageLabel = new St.Label({ style_class: 'polkit-dialog-error-label' });
this._errorMessageLabel = new St.Label({ style_class: 'prompt-dialog-error-label' });
this._errorMessageLabel.clutter_text.ellipsize = Pango.EllipsizeMode.NONE;
this._errorMessageLabel.clutter_text.line_wrap = true;
messageBox.add(this._errorMessageLabel);
this._errorMessageLabel.hide();
this._infoMessageLabel = new St.Label({ style_class: 'polkit-dialog-info-label' });
this._infoMessageLabel = new St.Label({ style_class: 'prompt-dialog-info-label' });
this._infoMessageLabel.clutter_text.ellipsize = Pango.EllipsizeMode.NONE;
this._infoMessageLabel.clutter_text.line_wrap = true;
messageBox.add(this._infoMessageLabel);
@ -165,7 +165,7 @@ const AuthenticationDialog = new Lang.Class({
* infoMessage and errorMessageLabel - but it is still invisible because
* gnome-shell.css sets the color to be transparent
*/
this._nullMessageLabel = new St.Label({ style_class: 'polkit-dialog-null-label',
this._nullMessageLabel = new St.Label({ style_class: 'prompt-dialog-null-label',
text: 'abc'});
this._nullMessageLabel.clutter_text.ellipsize = Pango.EllipsizeMode.NONE;
this._nullMessageLabel.clutter_text.line_wrap = true;

View File

@ -389,6 +389,7 @@ const PopupMenuItem = new Lang.Class({
this.label = new St.Label({ text: text });
this.addActor(this.label);
this.actor.label_actor = this.label
}
});
@ -773,6 +774,12 @@ const PopupSwitchMenuItem = new Lang.Class({
this.toggle();
}
// we allow pressing space to toggle the switch
// without closing the menu
if (event.type() == Clutter.EventType.KEY_PRESS &&
event.get_key_symbol() == Clutter.KEY_space)
return;
this.parent(event);
},
@ -869,6 +876,10 @@ const PopupMenuBase = new Lang.Class({
return menuItem;
},
isEmpty: function() {
return this.box.get_children().length == 0;
},
isChildMenu: function(menu) {
return this._childMenus.indexOf(menu) != -1;
},
@ -999,10 +1010,12 @@ const PopupMenuBase = new Lang.Class({
let items = this._getMenuItems();
if (position < items.length) {
before_item = items[position].actor;
this.box.insert_before(menuItem.actor, before_item);
} else
this.box.insert_child_below(menuItem.actor, before_item);
} else {
this.box.add(menuItem.actor);
}
}
if (menuItem instanceof PopupMenuSection) {
this._connectSubMenuSignals(menuItem, menuItem);
menuItem._closingId = this.connect('open-state-changed',
@ -1020,7 +1033,7 @@ const PopupMenuBase = new Lang.Class({
if (before_item == null)
this.box.add(menuItem.menu.actor);
else
this.box.insert_before(menuItem.menu.actor, before_item);
this.box.insert_child_below(menuItem.menu.actor, before_item);
this._connectSubMenuSignals(menuItem, menuItem.menu);
this._connectItemSignals(menuItem);
menuItem._closingId = this.connect('open-state-changed', function(self, open) {
@ -1194,6 +1207,9 @@ const PopupMenu = new Lang.Class({
if (this.isOpen)
return;
if (this.isEmpty())
return;
this.isOpen = true;
this._boxPointer.setPosition(this.sourceActor, this._arrowAlignment);
@ -1285,6 +1301,9 @@ const PopupSubMenu = new Lang.Class({
if (this.isOpen)
return;
if (this.isEmpty())
return;
this.isOpen = true;
this.actor.show();
@ -1428,6 +1447,7 @@ const PopupSubMenuMenuItem = new Lang.Class({
this.label = new St.Label({ text: text });
this.addActor(this.label);
this.actor.label_actor = this.label;
this._triangle = new St.Label({ text: '\u25B8' });
this.addActor(this._triangle, { align: St.Align.END });
@ -1528,6 +1548,9 @@ const PopupComboMenu = new Lang.Class({
if (this.isOpen)
return;
if (this.isEmpty())
return;
this.isOpen = true;
let [sourceX, sourceY] = this.sourceActor.get_transformed_position();

185
js/ui/remoteSearch.js Normal file
View File

@ -0,0 +1,185 @@
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
const Gio = imports.gi.Gio;
const GLib = imports.gi.GLib;
const Lang = imports.lang;
const St = imports.gi.St;
const FileUtils = imports.misc.fileUtils;
const Search = imports.ui.search;
const KEY_FILE_GROUP = 'Shell Search Provider';
const SearchProviderIface = <interface name="org.gnome.Shell.SearchProvider">
<method name="GetInitialResultSet">
<arg type="as" direction="in" />
<arg type="as" direction="out" />
</method>
<method name="GetSubsearchResultSet">
<arg type="as" direction="in" />
<arg type="as" direction="in" />
<arg type="as" direction="out" />
</method>
<method name="GetResultMetas">
<arg type="as" direction="in" />
<arg type="aa{sv}" direction="out" />
</method>
<method name="ActivateResult">
<arg type="s" direction="in" />
</method>
</interface>;
var SearchProviderProxy = Gio.DBusProxy.makeProxyWrapper(SearchProviderIface);
function loadRemoteSearchProviders(addProviderCallback) {
let dataDirs = GLib.get_system_data_dirs();
for (let i = 0; i < dataDirs.length; i++) {
let path = GLib.build_filenamev([dataDirs[i], 'gnome-shell', 'search-providers']);
let dir = Gio.file_new_for_path(path);
if (!dir.query_exists(null))
continue;
loadRemoteSearchProvidersFromDir(dir, addProviderCallback);
}
};
function loadRemoteSearchProvidersFromDir(dir, addProviderCallback) {
let dirPath = dir.get_path();
FileUtils.listDirAsync(dir, Lang.bind(this, function(files) {
for (let i = 0; i < files.length; i++) {
let keyfile = new GLib.KeyFile();
let path = GLib.build_filenamev([dirPath, files[i].get_name()]);
try {
keyfile.load_from_file(path, 0);
} catch(e) {
continue;
}
if (!keyfile.has_group(KEY_FILE_GROUP))
continue;
let remoteProvider;
try {
let group = KEY_FILE_GROUP;
let title = keyfile.get_locale_string(group, 'Title', null);
let icon = keyfile.get_string(group, 'Icon');
let busName = keyfile.get_string(group, 'BusName');
let objectPath = keyfile.get_string(group, 'ObjectPath');
remoteProvider = new RemoteSearchProvider(title,
icon,
busName,
objectPath);
} catch(e) {
log('Failed to add search provider "%s": %s'.format(title, e.toString()));
continue;
}
addProviderCallback(remoteProvider);
}
}));
};
const RemoteSearchProvider = new Lang.Class({
Name: 'RemoteSearchProvider',
Extends: Search.SearchProvider,
_init: function(title, icon, dbusName, dbusPath) {
this._proxy = new SearchProviderProxy(Gio.DBus.session,
dbusName, dbusPath);
this.parent(title.toUpperCase());
this.async = true;
this._cancellable = new Gio.Cancellable();
},
createIcon: function(size, meta) {
if (meta['gicon']) {
return new St.Icon({ gicon: Gio.icon_new_for_string(meta['gicon']),
icon_size: size,
icon_type: St.IconType.FULLCOLOR });
} else if (meta['icon-data']) {
let [width, height, rowStride, hasAlpha,
bitsPerSample, nChannels, data] = meta['icon-data'];
let textureCache = St.TextureCache.get_default();
return textureCache.load_from_raw(data, hasAlpha,
width, height, rowStride, size);
}
// Ugh, but we want to fall back to something ...
return new St.Icon({ icon_name: 'text-x-generic',
icon_size: size,
icon_type: St.IconType.FULLCOLOR });
},
_getResultsFinished: function(results, error) {
if (error)
return;
this.searchSystem.pushResults(this, results[0]);
},
getInitialResultSetAsync: function(terms) {
this._cancellable.cancel();
this._cancellable.reset();
try {
this._proxy.GetInitialResultSetRemote(terms,
Lang.bind(this, this._getResultsFinished),
this._cancellable);
} catch(e) {
log('Error calling GetInitialResultSet for provider %s: %s'.format( this.title, e.toString()));
this.searchSystem.pushResults(this, []);
}
},
getSubsearchResultSetAsync: function(previousResults, newTerms) {
this._cancellable.cancel();
this._cancellable.reset();
try {
this._proxy.GetSubsearchResultSetRemote(previousResults, newTerms,
Lang.bind(this, this._getResultsFinished),
this._cancellable);
} catch(e) {
log('Error calling GetSubsearchResultSet for provider %s: %s'.format(this.title, e.toString()));
this.searchSystem.pushResults(this, []);
}
},
_getResultMetasFinished: function(results, error, callback) {
if (error) {
callback([]);
return;
}
let metas = results[0];
let resultMetas = [];
for (let i = 0; i < metas.length; i++) {
for (let prop in metas[i])
metas[i][prop] = metas[i][prop].deep_unpack();
resultMetas.push({ id: metas[i]['id'],
name: metas[i]['name'],
createIcon: Lang.bind(this,
this.createIcon, metas[i]) });
}
callback(resultMetas);
},
getResultMetasAsync: function(ids, callback) {
this._cancellable.cancel();
this._cancellable.reset();
try {
this._proxy.GetResultMetasRemote(ids,
Lang.bind(this, this._getResultMetasFinished, callback),
this._cancellable);
} catch(e) {
log('Error calling GetResultMetas for provider %s: %s'.format(this.title, e.toString()));
callback([]);
}
},
activateResult: function(id) {
this._proxy.ActivateResultRemote(id);
}
});

View File

@ -102,6 +102,11 @@ 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
* getInitialResultSet()/getSubsearchResultSet() methods.
* For asynchronous search, set the async property to true
* and implement getInitialResultSetAsync()/getSubsearchResultSetAsync()
* instead.
*/
const SearchProvider = new Lang.Class({
Name: 'SearchProvider',
@ -109,42 +114,7 @@ const SearchProvider = new Lang.Class({
_init: function(title) {
this.title = title;
this.searchSystem = null;
this.searchAsync = false;
},
_asyncCancelled: function() {
},
startAsync: function() {
this.searchAsync = true;
},
tryCancelAsync: function() {
if (!this.searchAsync)
return;
this._asyncCancelled();
this.searchAsync = false;
},
/**
* addItems:
* @items: an array of result identifier strings representing
* items which match the last given search terms.
*
* This should be used for something that requires a bit more
* logic; it's designed to be an asyncronous way to add a result
* to the current search.
*/
addItems: function(items) {
if (!this.searchSystem)
throw new Error('Search provider not registered');
if (!items.length)
return;
this.tryCancelAsync();
this.searchSystem.addProviderItems(this, items);
this.async = false;
},
/**
@ -172,6 +142,18 @@ 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
@ -190,14 +172,40 @@ const SearchProvider = new Lang.Class({
},
/**
* getResultMeta:
* @id: Result identifier string
* getSubsearchResultSetAsync:
* @previousResults: Array of item identifiers
* @newTerms: Updated search terms
*
* Return an object with 'id', 'name', (both strings) and 'createIcon'
* (function(size) returning a Clutter.Texture) properties which describe
* the given search result.
* Like getSubsearchResultSet(), but the method should return immediately
* without a return value - use SearchSystem.pushResults() when the
* corresponding results are ready.
*/
getResultMeta: function(id) {
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
* '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) {
throw new Error('Not implemented');
},
@ -302,7 +310,7 @@ const OpenSearchSystem = new Lang.Class({
},
_addProvider: function(fileName) {
let path = global.datadir + '/search_providers/' + fileName;
let path = global.datadir + '/open-search-providers/' + fileName;
let source = Shell.get_file_contents_utf8_sync(path);
let [success, name, url, langs, icon_uri] = Shell.parse_search_provider(source);
let provider ={ name: name,
@ -319,7 +327,7 @@ const OpenSearchSystem = new Lang.Class({
_refresh: function() {
this._providers = [];
let names = global.settings.get_strv(DISABLED_OPEN_SEARCH_PROVIDERS_KEY);
let file = Gio.file_new_for_path(global.datadir + '/search_providers');
let file = Gio.file_new_for_path(global.datadir + '/open-search-providers');
FileUtils.listDirAsync(file, Lang.bind(this, function(files) {
for (let i = 0; i < files.length; i++) {
let enabled = true;
@ -369,8 +377,13 @@ const SearchSystem = new Lang.Class({
this._previousResults = [];
},
addProviderItems: function(provider, items) {
this.emit('search-updated', provider, items);
pushResults: function(provider, results) {
let i = this._providers.indexOf(provider);
if (i == -1)
return;
this._previousResults[i] = [provider, results];
this.emit('search-updated', this._previousResults[i]);
},
updateSearch: function(searchString) {
@ -400,10 +413,14 @@ const SearchSystem = new Lang.Class({
if (isSubSearch) {
for (let i = 0; i < this._providers.length; i++) {
let [provider, previousResults] = this._previousResults[i];
provider.tryCancelAsync();
try {
let providerResults = provider.getSubsearchResultSet(previousResults, terms);
results.push([provider, providerResults]);
if (provider.async) {
provider.getSubsearchResultSetAsync(previousResults, terms);
results.push([provider, []]);
} else {
let providerResults = provider.getSubsearchResultSet(previousResults, terms);
results.push([provider, providerResults]);
}
} catch (error) {
global.log ('A ' + error.name + ' has occured in ' + provider.title + ': ' + error.message);
}
@ -411,10 +428,14 @@ const SearchSystem = new Lang.Class({
} else {
for (let i = 0; i < this._providers.length; i++) {
let provider = this._providers[i];
provider.tryCancelAsync();
try {
let providerResults = provider.getInitialResultSet(terms);
results.push([provider, providerResults]);
if (provider.async) {
provider.getInitialResultSetAsync(terms);
results.push([provider, []]);
} else {
let providerResults = provider.getInitialResultSet(terms);
results.push([provider, providerResults]);
}
} catch (error) {
global.log ('A ' + error.name + ' has occured in ' + provider.title + ': ' + error.message);
}

View File

@ -115,41 +115,56 @@ const GridSearchResults = new Lang.Class({
this.actor.connect('notify::width', Lang.bind(this, function() {
this._width = this.actor.width;
Meta.later_add(Meta.LaterType.BEFORE_REDRAW, Lang.bind(this, function() {
this._tryAddResults();
let results = this.getResultsForDisplay();
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);
}
}));
}));
this._notDisplayedResult = [];
this._terms = [];
this._pendingClear = false;
},
_tryAddResults: function() {
getResultsForDisplay: function() {
let alreadyVisible = this._pendingClear ? 0 : this._grid.visibleItemsCount();
let canDisplay = this._grid.childrenInRow(this._width) * MAX_SEARCH_RESULTS_ROWS
- this._grid.visibleItemsCount();
- alreadyVisible;
for (let i = Math.min(this._notDisplayedResult.length, canDisplay); i > 0; i--) {
let result = this._notDisplayedResult.shift();
let meta = this.provider.getResultMeta(result);
let display = new SearchResult(this.provider, meta, this._terms);
this._grid.addItem(display.actor);
}
let numResults = Math.min(this._notDisplayedResult.length, canDisplay);
return this._notDisplayedResult.splice(0, numResults);
},
getVisibleResultCount: function() {
return this._grid.visibleItemsCount();
},
renderResults: function(results, terms) {
setResults: function(results, terms) {
// copy the lists
this._notDisplayedResult = results.slice(0);
this._terms = terms.slice(0);
this._tryAddResults();
this._pendingClear = true;
},
renderResults: function(metas) {
for (let i = 0; i < metas.length; i++) {
let display = new SearchResult(this.provider, metas[i], this._terms);
this._grid.addItem(display.actor);
}
},
clear: function () {
this._terms = [];
this._notDisplayedResult = [];
this._grid.removeAll();
this.selectionIndex = -1;
this._pendingClear = false;
},
selectIndex: function (index) {
@ -289,7 +304,8 @@ const SearchResults = new Lang.Class({
this._providerMeta.push({ provider: provider,
actor: providerBox,
resultDisplay: resultDisplay });
resultDisplay: resultDisplay,
hasPendingResults: false });
this._content.add(providerBox);
},
@ -314,8 +330,8 @@ const SearchResults = new Lang.Class({
}
},
_clearDisplayForProvider: function(index) {
let meta = this._providerMeta[index];
_clearDisplayForProvider: function(provider) {
let meta = this._metaForProvider(provider);
meta.resultDisplay.clear();
meta.actor.hide();
},
@ -342,13 +358,58 @@ const SearchResults = new Lang.Class({
return this._providerMeta[this._providers.indexOf(provider)];
},
_updateCurrentResults: function(searchSystem, provider, results) {
_maybeSetInitialSelection: function() {
if (this._selectedOpenSearchButton > -1 || this._selectedProvider > -1)
return;
for (let i = 0; i < this._providerMeta.length; i++) {
let meta = this._providerMeta[i];
if (meta.hasPendingResults)
return;
if (meta.actor.visible)
break; // select this one!
}
this.selectDown(false);
this._initialSelectionSet = true;
},
_updateCurrentResults: function(searchSystem, results) {
let terms = searchSystem.getTerms();
let [provider, providerResults] = results;
let meta = this._metaForProvider(provider);
meta.resultDisplay.clear();
meta.actor.show();
meta.resultDisplay.renderResults(results, terms);
return true;
meta.hasPendingResults = false;
this._updateProviderResults(provider, providerResults, terms);
},
_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);
}
}
},
_updateResults: function(searchSystem, results) {
@ -358,6 +419,7 @@ const SearchResults = new Lang.Class({
} else {
this._selectedOpenSearchButton = -1;
this._updateOpenSearchButtonState();
this._selectedProvider = -1;
this._statusText.hide();
}
@ -373,20 +435,13 @@ const SearchResults = new Lang.Class({
for (let i = 0; i < results.length; i++) {
let [provider, providerResults] = results[i];
if (providerResults.length == 0) {
this._clearDisplayForProvider(i);
} else {
this._providerMetaResults[provider.title] = providerResults;
this._clearDisplayForProvider(i);
let meta = this._metaForProvider(provider);
meta.actor.show();
meta.resultDisplay.renderResults(providerResults, terms);
}
let meta = this._metaForProvider(provider);
meta.hasPendingResults = provider.async;
if (!meta.hasPendingResults)
this._updateProviderResults(provider, providerResults, terms);
}
if (this._selectedOpenSearchButton == -1)
this.selectDown(false);
this._maybeSetInitialSelection();
this._content.show();
return true;

View File

@ -3,9 +3,12 @@
const Lang = imports.lang;
const Gio = imports.gi.Gio;
const GLib = imports.gi.GLib;
const Shell = imports.gi.Shell;
const Config = imports.misc.config;
const ExtensionSystem = imports.ui.extensionSystem;
const ExtensionUtils = imports.misc.extensionUtils;
const Flashspot = imports.ui.flashspot;
const Main = imports.ui.main;
const GnomeShellIface = <interface name="org.gnome.Shell">
@ -30,18 +33,29 @@ const GnomeShellIface = <interface name="org.gnome.Shell">
<arg type="i" direction="in" name="y"/>
<arg type="i" direction="in" name="width"/>
<arg type="i" direction="in" name="height"/>
<arg type="b" direction="in" name="flash"/>
<arg type="s" direction="in" name="filename"/>
<arg type="b" direction="out" name="success"/>
</method>
<method name="ScreenshotWindow">
<arg type="b" direction="in" name="include_frame"/>
<arg type="b" direction="in" name="include_cursor"/>
<arg type="b" direction="in" name="flash"/>
<arg type="s" direction="in" name="filename"/>
<arg type="b" direction="out" name="success"/>
</method>
<method name="Screenshot">
<arg type="b" direction="in" name="include_cursor"/>
<arg type="b" direction="in" name="flash"/>
<arg type="s" direction="in" name="filename"/>
<arg type="b" direction="out" name="success"/>
</method>
<method name="FlashArea">
<arg type="i" direction="in" name="x"/>
<arg type="i" direction="in" name="y"/>
<arg type="i" direction="in" name="width"/>
<arg type="i" direction="in" name="height"/>
</method>
<method name="EnableExtension">
<arg type="s" direction="in" name="uuid"/>
</method>
@ -56,6 +70,9 @@ const GnomeShellIface = <interface name="org.gnome.Shell">
<arg type="s" direction="in" name="uuid"/>
<arg type="b" direction="out" name="success"/>
</method>
<method name="LaunchExtensionPrefs">
<arg type="s" direction="in" name="uuid"/>
</method>
<property name="OverviewActive" type="b" access="readwrite" />
<property name="ApiVersion" type="i" access="read" />
<property name="ShellVersion" type="s" access="read" />
@ -109,12 +126,23 @@ const GnomeShell = new Lang.Class({
return [success, returnValue];
},
_onScreenshotComplete: function(obj, result, area, flash, invocation) {
if (flash) {
let flashspot = new Flashspot.Flashspot(area);
flashspot.fire();
}
let retval = GLib.Variant.new('(b)', [result]);
invocation.return_value(retval);
},
/**
* ScreenshotArea:
* @x: The X coordinate of the area
* @y: The Y coordinate of the area
* @width: The width of the area
* @height: The height of the area
* @flash: Whether to flash the area or not
* @filename: The filename for the screenshot
*
* Takes a screenshot of the passed in area and saves it
@ -123,17 +151,18 @@ const GnomeShell = new Lang.Class({
*
*/
ScreenshotAreaAsync : function (params, invocation) {
let [x, y, width, height, filename, callback] = params;
global.screenshot_area (x, y, width, height, filename,
function (obj, result) {
let retval = GLib.Variant.new('(b)', [result]);
invocation.return_value(retval);
});
let [x, y, width, height, flash, filename, callback] = params;
let screenshot = new Shell.Screenshot();
screenshot.screenshot_area (x, y, width, height, filename,
Lang.bind(this, this._onScreenshotComplete,
flash, invocation));
},
/**
* ScreenshotWindow:
* @include_frame: Whether to include the frame or not
* @include_cursor: Whether to include the cursor image or not
* @flash: Whether to flash the window area or not
* @filename: The filename for the screenshot
*
* Takes a screenshot of the focused window (optionally omitting the frame)
@ -141,13 +170,19 @@ const GnomeShell = new Lang.Class({
* indicating whether the operation was successful or not.
*
*/
ScreenshotWindow : function (include_frame, filename) {
return global.screenshot_window (include_frame, filename);
ScreenshotWindowAsync : function (params, invocation) {
let [include_frame, include_cursor, flash, filename] = params;
let screenshot = new Shell.Screenshot();
screenshot.screenshot_window (include_frame, include_cursor, filename,
Lang.bind(this, this._onScreenshotComplete,
flash, invocation));
},
/**
* Screenshot:
* @filename: The filename for the screenshot
* @include_cursor: Whether to include the cursor image or not
* @flash: Whether to flash the screen or not
*
* Takes a screenshot of the whole screen and saves it
* in @filename as png image, it returns a boolean
@ -155,17 +190,21 @@ const GnomeShell = new Lang.Class({
*
*/
ScreenshotAsync : function (params, invocation) {
let [filename] = params;
global.screenshot(filename,
function (obj, result) {
let retval = GLib.Variant.new('(b)', [result]);
invocation.return_value(retval);
});
let [include_cursor, flash, filename] = params;
let screenshot = new Shell.Screenshot();
screenshot.screenshot(include_cursor, filename,
Lang.bind(this, this._onScreenshotComplete,
flash, invocation));
},
FlashArea: function(x, y, width, height) {
let flashspot = new Flashspot.Flashspot({ x : x, y : y, width: width, height: height});
flashspot.fire();
},
ListExtensions: function() {
let out = {};
for (let uuid in ExtensionSystem.extensionMeta) {
for (let uuid in ExtensionUtils.extensions) {
let dbusObj = this.GetExtensionInfo(uuid);
out[uuid] = dbusObj;
}
@ -173,10 +212,23 @@ const GnomeShell = new Lang.Class({
},
GetExtensionInfo: function(uuid) {
let meta = ExtensionSystem.extensionMeta[uuid] || {};
let extension = ExtensionUtils.extensions[uuid];
if (!extension)
return {};
let obj = {};
Lang.copyProperties(extension.metadata, obj);
// Only serialize the properties that we actually need.
const serializedProperties = ["type", "state", "path", "error", "hasPrefs"];
serializedProperties.forEach(function(prop) {
obj[prop] = extension[prop];
});
let out = {};
for (let key in meta) {
let val = meta[key];
for (let key in obj) {
let val = obj[key];
let type;
switch (typeof val) {
case 'string':
@ -185,16 +237,27 @@ const GnomeShell = new Lang.Class({
case 'number':
type = 'd';
break;
case 'boolean':
type = 'b';
break;
default:
continue;
}
out[key] = GLib.Variant.new(type, val);
}
return out;
},
GetExtensionErrors: function(uuid) {
return ExtensionSystem.errors[uuid] || [];
let extension = ExtensionUtils.extensions[uuid];
if (!extension)
return [];
if (!extension.errors)
return [];
return extension.errors;
},
EnableExtension: function(uuid) {
@ -219,6 +282,13 @@ const GnomeShell = new Lang.Class({
return ExtensionSystem.uninstallExtensionFromUUID(uuid);
},
LaunchExtensionPrefs: function(uuid) {
let appSys = Shell.AppSystem.get_default();
let app = appSys.lookup_app('gnome-shell-extension-prefs.desktop');
app.launch(global.display.get_current_time_roundtrip(),
['extension:///' + uuid], -1, null);
},
get OverviewActive() {
return Main.overview.visible;
},

View File

@ -211,6 +211,8 @@ const ShellMountQuestionDialog = new Lang.Class({
{ y_align: St.Align.START });
this.subjectLabel = new St.Label({ style_class: 'mount-question-dialog-subject' });
this.subjectLabel.clutter_text.ellipsize = Pango.EllipsizeMode.NONE;
this.subjectLabel.clutter_text.line_wrap = true;
messageLayout.add(this.subjectLabel,
{ y_fill: false,
@ -357,7 +359,7 @@ const ShellProcessesDialog = new Lang.Class({
_setAppsForPids: function(pids) {
// remove all the items
this._applicationList.destroy_children();
this._applicationList.destroy_all_children();
pids.forEach(Lang.bind(this, function(pid) {
let tracker = Shell.WindowTracker.get_default();

View File

@ -44,7 +44,7 @@ const ATIndicator = new Lang.Class({
Extends: PanelMenu.SystemStatusButton,
_init: function() {
this.parent('preferences-desktop-accessibility', null);
this.parent('preferences-desktop-accessibility', _("Accessibility"));
let highContrast = this._buildHCItem();
this.menu.addMenuItem(highContrast);

View File

@ -28,7 +28,7 @@ const Indicator = new Lang.Class({
Extends: PanelMenu.SystemStatusButton,
_init: function() {
this.parent('bluetooth-disabled', null);
this.parent('bluetooth-disabled', _("Bluetooth"));
this._applet = new GnomeBluetoothApplet.Applet();

View File

@ -113,6 +113,7 @@ const NMNetworkMenuItem = new Lang.Class({
}
this._label = new St.Label({ text: title });
this.actor.label_actor = this._label;
this.addActor(this._label);
this._icons = new St.BoxLayout({ style_class: 'nm-menu-item-icons' });
this.addActor(this._icons, { align: St.Align.END });
@ -1537,7 +1538,7 @@ const NMApplet = new Lang.Class({
Extends: PanelMenu.SystemStatusButton,
_init: function() {
this.parent('network-error', null);
this.parent('network-error', _("Network"));
this._client = NMClient.Client.new();

View File

@ -46,7 +46,6 @@ const PowerManagerInterface = <interface name="org.gnome.SettingsDaemon.Power">
<method name="GetPrimaryDevice">
<arg type="(susdut)" direction="out" />
</method>
<signal name="Changed" />
<property name="Icon" type="s" access="read" />
</interface>;
@ -57,7 +56,7 @@ const Indicator = new Lang.Class({
Extends: PanelMenu.SystemStatusButton,
_init: function() {
this.parent('battery-missing', null);
this.parent('battery-missing', _("Battery"));
this._proxy = new PowerManagerProxy(Gio.DBus.session, BUS_NAME, OBJECT_PATH);
@ -76,7 +75,8 @@ const Indicator = new Lang.Class({
this.menu.addMenuItem(new PopupMenu.PopupSeparatorMenuItem());
this.menu.addSettingsAction(_("Power Settings"), 'gnome-power-panel.desktop');
this._proxy.connectSignal('Changed', Lang.bind(this, this._devicesChanged));
this._proxy.connect('g-properties-changed',
Lang.bind(this, this._devicesChanged));
this._devicesChanged();
},

View File

@ -22,7 +22,7 @@ const Indicator = new Lang.Class({
Extends: PanelMenu.SystemStatusButton,
_init: function() {
this.parent('audio-volume-muted', null);
this.parent('audio-volume-muted', _("Volume"));
this._control = new Gvc.MixerControl({ name: 'GNOME Shell Volume Control' });
this._control.connect('state-changed', Lang.bind(this, this._onControlStateChanged));
@ -35,6 +35,7 @@ const Indicator = new Lang.Class({
this._output = null;
this._outputVolumeId = 0;
this._outputMutedId = 0;
/* Translators: This is the label for audio volume */
this._outputTitle = new PopupMenu.PopupMenuItem(_("Volume"), { reactive: false });
this._outputSlider = new PopupMenu.PopupSliderMenuItem(0);
this._outputSlider.connect('value-changed', Lang.bind(this, this._sliderChanged, '_output'));

View File

@ -33,11 +33,6 @@ const NotificationDirection = {
RECEIVED: 'chat-received'
};
// This is GNOME Shell's implementation of the Telepathy 'Client'
// interface. Specifically, the shell is a Telepathy 'Observer', which
// lets us see messages even if they belong to another app (eg,
// Empathy).
function makeMessageFromTpMessage(tpMessage, direction) {
let [text, flags] = tpMessage.to_text();
@ -238,8 +233,7 @@ const Client = new Lang.Class({
if (chanType == Tp.IFACE_CHANNEL_TYPE_TEXT)
this._approveTextChannel(account, conn, channel, dispatchOp, context);
else if (chanType == Tp.IFACE_CHANNEL_TYPE_STREAMED_MEDIA ||
chanType == 'org.freedesktop.Telepathy.Channel.Type.Call.DRAFT')
else if (chanType == Tp.IFACE_CHANNEL_TYPE_CALL)
this._approveCall(account, conn, channel, dispatchOp, context);
else if (chanType == Tp.IFACE_CHANNEL_TYPE_FILE_TRANSFER)
this._approveFileTransfer(account, conn, channel, dispatchOp, context);
@ -270,8 +264,7 @@ const Client = new Lang.Class({
let props = channel.borrow_immutable_properties();
if (props['org.freedesktop.Telepathy.Channel.Type.Call.DRAFT.InitialVideo'] ||
props[Tp.PROP_CHANNEL_TYPE_STREAMED_MEDIA_INITIAL_VIDEO])
if (props[Tp.PROP_CHANNEL_TYPE_CALL_INITIAL_VIDEO])
isVideo = true;
// We got the TpContact
@ -1092,7 +1085,7 @@ const AudioVideoNotification = new Lang.Class({
/* translators: argument is a contact name like Alice for example. */
title = _("Call from %s").format(contact.get_alias());
this.parent(this, source, title, null, { customContent: true });
this.parent(source, title, null, { customContent: true });
this.setResident(true);
this.addButton('reject', _("Reject"));
@ -1123,8 +1116,7 @@ const FileTransferNotification = new Lang.Class({
Extends: MessageTray.Notification,
_init: function(source, dispatchOp, channel, contact) {
this.parent(this,
source,
this.parent(source,
/* To translators: The first parameter is
* the contact's alias and the second one is the
* file name. The string will be something
@ -1197,7 +1189,7 @@ const SubscriptionRequestNotification = new Lang.Class({
Extends: MessageTray.Notification,
_init: function(source, contact) {
this.parent(this, source,
this.parent(source,
/* To translators: The parameter is the contact's alias */
_("%s would like permission to see when you are online").format(contact.get_alias()),
null, { customContent: true });
@ -1324,7 +1316,7 @@ _connectionErrorMessages[Tp.error_get_dbus_name(Tp.Error.CONNECTION_FAILED)]
_connectionErrorMessages[Tp.error_get_dbus_name(Tp.Error.CONNECTION_LOST)]
= _("Connection has been lost");
_connectionErrorMessages[Tp.error_get_dbus_name(Tp.Error.ALREADY_CONNECTED)]
= _("This resource is already connected to the server");
= _("This account is already connected to the server");
_connectionErrorMessages[Tp.error_get_dbus_name(Tp.Error.CONNECTION_REPLACED)]
= _("Connection has been replaced by a new connection using the same resource");
_connectionErrorMessages[Tp.error_get_dbus_name(Tp.Error.REGISTRATION_EXISTS)]
@ -1337,6 +1329,8 @@ _connectionErrorMessages[Tp.error_get_dbus_name(Tp.Error.CERT_INSECURE)]
= _("Certificate uses an insecure cipher algorithm or is cryptographically weak");
_connectionErrorMessages[Tp.error_get_dbus_name(Tp.Error.CERT_LIMIT_EXCEEDED)]
= _("The length of the server certificate, or the depth of the server certificate chain, exceed the limits imposed by the cryptography library");
_connectionErrorMessages['org.freedesktop.DBus.Error.NoReply']
= _("Internal error");
const AccountNotification = new Lang.Class({
Name: 'AccountNotification',

View File

@ -376,7 +376,8 @@ const IMStatusChooserItem = new Lang.Class({
if (sessionStatus == GnomeSession.PresenceStatus.IDLE) {
// Only change presence if the current one is "more present" than
// idle
if (this._currentPresence != Tp.ConnectionPresenceType.OFFLINE)
if (this._currentPresence != Tp.ConnectionPresenceType.OFFLINE &&
this._currentPresence != Tp.ConnectionPresenceType.HIDDEN)
return Tp.ConnectionPresenceType.EXTENDED_AWAY;
}
@ -466,6 +467,7 @@ const UserMenuButton = new Lang.Class({
}));
this._name = new St.Label();
this.actor.label_actor = this._name;
box.add(this._name, { y_align: St.Align.MIDDLE, y_fill: false });
this._userLoadedId = this._user.connect('notify::is-loaded', Lang.bind(this, this._updateUserName));
this._userChangedId = this._user.connect('changed', Lang.bind(this, this._updateUserName));
@ -611,7 +613,7 @@ const UserMenuButton = new Lang.Class({
this._statusChooser = item;
item = new PopupMenu.PopupSwitchMenuItem(_("Notifications"));
item.connect('activate', Lang.bind(this, this._updatePresenceStatus));
item.connect('toggled', Lang.bind(this, this._updatePresenceStatus));
this.menu.addMenuItem(item);
this._notificationsSwitch = item;

View File

@ -89,9 +89,9 @@ const WandaIcon = new Lang.Class({
return true;
}
this._animations.get_nth_child(this._i).hide();
this._animations.get_child_at_index(this._i).hide();
this._i = (this._i + 1) % n;
this._animations.get_nth_child(this._i).show();
this._animations.get_child_at_index(this._i).show();
return true;
},
@ -124,14 +124,14 @@ const FortuneDialog = new Lang.Class({
text = _("Sorry, no wisdom for you today:\n%s").format(e.message);
}
this._title = new St.Label({ style_class: 'polkit-dialog-headline',
this._title = new St.Label({ style_class: 'prompt-dialog-headline',
text: _("%s the Oracle says").format(name) });
this._label = new St.Label({ style_class: 'polkit-dialog-description',
this._label = new St.Label({ style_class: 'prompt-dialog-description',
text: text });
this._label.clutter_text.line_wrap = true;
this._box = new St.BoxLayout({ vertical: true,
style_class: 'polkit-dialog' // this is just to force a reasonable width
style_class: 'prompt-dialog' // this is just to force a reasonable width
});
this._box.add(this._title, { align: St.Align.MIDDLE });
this._box.add(this._label, { expand: true });
@ -168,22 +168,23 @@ const WandaSearchProvider = new Lang.Class({
this.parent(_("Your favorite Easter Egg"));
},
getResultMeta: function(fish) {
return { 'id': fish,
'name': capitalize(fish),
'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) {
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);
}
}];
},
getInitialResultSet: function(terms) {

View File

@ -370,6 +370,7 @@ const WindowClone = new Lang.Class({
if (this._selected)
return;
let [x, y] = action.get_coords();
action.release();
this._draggable.startDrag(x, y, global.get_current_time());
}));
}

View File

@ -105,7 +105,7 @@ const WorkspaceSwitcherPopup = new Lang.Class({
},
_redraw : function(direction, activeWorkspaceIndex) {
this._list.destroy_children();
this._list.destroy_all_children();
for (let i = 0; i < global.screen.n_workspaces; i++) {
let indicator = null;

View File

@ -598,6 +598,9 @@ const ThumbnailsBox = new Lang.Class({
},
_clearDragPlaceholder: function() {
if (this._dropPlaceholderPos == -1)
return;
this._dropPlaceholderPos = -1;
this.actor.queue_relayout();
},
@ -611,7 +614,11 @@ const ThumbnailsBox = new Lang.Class({
let thumbHeight = this._porthole.height * this._scale;
let workspace = -1;
let firstThumbY = this._thumbnails[0].actor.y;
let firstThumbY;
if (this._dropPlaceholderPos == 0)
firstThumbY = this._dropPlaceholder.y;
else
firstThumbY = this._thumbnails[0].actor.y;
for (let i = 0; i < this._thumbnails.length; i ++) {
let targetBase = firstThumbY + (thumbHeight + spacing) * i;
@ -631,8 +638,10 @@ const ThumbnailsBox = new Lang.Class({
}
}
this._dropPlaceholderPos = workspace;
this.actor.queue_relayout();
if (this._dropPlaceholderPos != workspace) {
this._dropPlaceholderPos = workspace;
this.actor.queue_relayout();
}
if (workspace == -1)
return DND.DragMotionResult.CONTINUE;

View File

@ -17,6 +17,7 @@ const XdndHandler = new Lang.Class({
// Used as a drag actor in case we don't have a cursor window clone
this._dummy = new Clutter.Rectangle({ width: 1, height: 1, opacity: 0 });
global.stage.add_actor(this._dummy);
Shell.util_set_hidden_from_pick(this._dummy, true);
this._dummy.hide();
// Mutter delays the creation of the output window as long
@ -112,10 +113,11 @@ const XdndHandler = new Lang.Class({
while (pickedActor) {
if (pickedActor._delegate && pickedActor._delegate.handleDragOver) {
let [r, targX, targY] = pickedActor.transform_stage_point(x, y);
let result = pickedActor._delegate.handleDragOver(this,
dragEvent.dragActor,
x,
y,
targX,
targY,
global.get_current_time());
if (result != DND.DragMotionResult.CONTINUE)
return;

View File

@ -30,8 +30,9 @@ hu
id
it
ja
ko
kk
kn
ko
ku
lt
lv
@ -48,6 +49,7 @@ pt
pt_BR
ro
ru
si
sk
sl
sr

View File

@ -1,5 +1,7 @@
data/gnome-shell.desktop.in.in
data/gnome-shell-extension-prefs.desktop.in.in
data/org.gnome.shell.gschema.xml.in
js/extensionPrefs/main.js
js/gdm/loginDialog.js
js/gdm/powerMenu.js
js/misc/util.js
@ -10,7 +12,6 @@ js/ui/calendar.js
js/ui/contactDisplay.js
js/ui/dash.js
js/ui/dateMenu.js
js/ui/docDisplay.js
js/ui/endSessionDialog.js
js/ui/extensionSystem.js
js/ui/keyboard.js

View File

@ -1,2 +1,2 @@
data/gnome-shell.desktop.in
data/gnome-shell-clock-preferences.desktop.in
data/gnome-shell-extension-prefs.desktop.in

530
po/be.po

File diff suppressed because it is too large Load Diff

666
po/cs.po

File diff suppressed because it is too large Load Diff

426
po/da.po

File diff suppressed because it is too large Load Diff

651
po/es.po

File diff suppressed because it is too large Load Diff

253
po/et.po
View File

@ -5,23 +5,23 @@
#
# This file is distributed under the same license as the gnome-shell package.
#
# Mattias Põldaru <mahfiaz gmail com>, 2010, 2011.
# Ivar Smolin <okul linux ee>, 2011.
# Mattias Põldaru <mahfiaz@gmail.com>, 2010, 2011, 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: 2011-11-05 13:23+0000\n"
"PO-Revision-Date: 2011-11-05 18:16+0300\n"
"POT-Creation-Date: 2012-02-18 00:47+0000\n"
"PO-Revision-Date: 2012-02-18 02:56+0200\n"
"Last-Translator: Mattias Põldaru <mahfiaz@gmail.com>\n"
"Language-Team: Estonian <gnome-et@linux.ee>\n"
"Language-Team: Estonian <>\n"
"Language: et\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"
"Content-Transfer-Encoding: 8bits\n"
"Plural-Forms: nplurals=2; plural=(n!=1);\n"
"X-Poedit-Language: Estonian\n"
"X-Poedit-Country: Estonia\n"
@ -31,6 +31,16 @@ msgstr "GNOME Shell"
msgid "Window management and application launching"
msgstr "Aknahaldur ja rakenduste käivitaja"
msgid "GNOME Shell Extensions Preferences"
msgstr "GNOME Shelli laienduste eelistused"
msgid "Configure GNOME Shell Extensions"
msgstr "GNOME Shelli laienduste seadistamine"
msgid "Enable internal tools useful for developers and testers from Alt-F2"
msgstr ""
"Arendajate ja testijate jaoks sisemiste tööriistade lubamine Alt-F2 alt"
msgid ""
"Allows access to internal debugging and monitoring tools using the Alt-F2 "
"dialog."
@ -38,15 +48,8 @@ msgstr ""
"Lubab ligipääsu sisemistele silumise ja monitoorimise tööriistadele Alt-F2 "
"dialoogi kaudu."
msgid "Enable internal tools useful for developers and testers from Alt-F2"
msgstr ""
"Arendajate ja testijate jaoks sisemiste tööriistade lubamine Alt-F2 alt"
msgid "File extension used for storing the screencast"
msgstr "Ekraanivideo salvestamisel kasutatav faililaiend"
msgid "Framerate used for recording screencasts."
msgstr "Ekraanivideo lindistamisel kasutatav kaadrikiirus."
msgid "Uuids of extensions to enable"
msgstr "Lubatavate laienduste UUID-d"
msgid ""
"GNOME Shell extensions have a uuid property; this key lists extensions which "
@ -58,81 +61,8 @@ msgstr ""
"tuleks laadida. Seda loendit saab muuta kasutades EnableExtension ja "
"DisableExtension DBus-i meetodit kohas org.gnome.Shell."
msgid "History for command (Alt-F2) dialog"
msgstr "Käsudialoogi (Alt-F2) ajalugu"
# suurendusklaasidialoog? miks ka mitte :)
msgid "History for the looking glass dialog"
msgstr "Otsingudialoogi ajalugu"
msgid "If true, display date in the clock, in addition to time."
msgstr "Kui määratud, siis kuvatakse kellaaja kõrval ka kuupäeva."
msgid "If true, display seconds in time."
msgstr "Kui määratud, siis kuvatakse aja juures ka sekundeid."
msgid "If true, display the ISO week date in the calendar."
msgstr "Kui määratud, kuvatakse kalendris kuupäeva ISO nädalavormingus."
msgid "List of desktop file IDs for favorite applications"
msgstr "Lemmikrakenduste töölauafailide ID-de loend"
#, 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."
msgstr ""
"Määrab GStreameri toru, mida kasutatakse lindistuste kodeerimiseks. See peab "
"vastama gst-launch'i süntaksile. Torul peaks olema vaba plokk (pad), kuhu "
"lindistatav video salvestatakse. Tavaliselt on vaba plokk olemas; selle "
"ploki väljund kirjutatakse väljundfaili. Toru võib hoolitseda ka enda "
"väljundi eest - seda võib kasutada väljundi saatmiseks icecast serverisse "
"shout2send või sarnase tehnoloogia abil. Kui see on määramata või väärtus on "
"tühi, kasutatakse vaikimisi toru. See on praegu 'videorate ! vp8enc "
"quality=10 speed=2 threads=%T ! queue ! webmmux' ning lindistab WEBM "
"vormingusse VP8 koodekiga. %T asendatakse süsteemi oletatava optimaalseima "
"lõimede (thread) arvuga."
msgid "Show date in clock"
msgstr "Kell näitab kuupäeva"
msgid "Show the week date in the calendar"
msgstr "Kalendris näidatakse kuupäeva nädalavormingus"
msgid "Show time with seconds"
msgstr "Kellaaega näidatakse sekunditega"
msgid ""
"The applications corresponding to these identifiers will be displayed in the "
"favorites area."
msgstr "Nendele tunnustele vastavaid rakendusi kuvatakse lemmikutes."
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 ""
"Ekraanivideo jaoks kasutatav failinimi on unikaalne, see sisaldab "
"salvestamise kuupäeva ja ka käesoleva võtmega määratud laiendit. Mõnda teise "
"konteinervormingusse salvestades tuleks ka sellele vormingule vastav laiend "
"määrata."
msgid ""
"The framerate of the resulting screencast recordered by GNOME Shell's "
"screencast recorder in frames-per-second."
msgstr ""
"GNOME Shelli lindistatava ekraanivideo kaadrisagedus (kaadrit sekundis)."
msgid "The gstreamer pipeline used to encode the screencast"
msgstr "GStreameri toru, mida ekraanivideo kodeerimiseks kasutatakse"
msgid "Whether to collect stats about applications usage"
msgstr "Kas rakenduste kasutuse kohta kogutakse andmeid"
msgid ""
"The shell normally monitors active applications in order to present the most "
@ -145,20 +75,105 @@ msgstr ""
"privaatsuse suurendamiseks selle keelata. Selle keelamine siiski ei eemalda "
"juba salvestatud andmeid."
msgid "The type of keyboard to use."
msgstr "Kasutatava klaviatuuri liik."
msgid "List of desktop file IDs for favorite applications"
msgstr "Lemmikrakenduste töölauafailide ID-de loend"
msgid "Uuids of extensions to enable"
msgstr "Lubatavate laienduste UUID-d"
msgid ""
"The applications corresponding to these identifiers will be displayed in the "
"favorites area."
msgstr "Nendele tunnustele vastavaid rakendusi kuvatakse lemmikutes."
msgid "Whether to collect stats about applications usage"
msgstr "Kas rakenduste kasutuse kohta kogutakse andmeid"
msgid "disabled OpenSearch providers"
msgstr "keelatud OpenSearch pakkujad"
msgid "History for command (Alt-F2) dialog"
msgstr "Käsudialoogi (Alt-F2) ajalugu"
# suurendusklaasidialoog? miks ka mitte :)
msgid "History for the looking glass dialog"
msgstr "Otsingudialoogi ajalugu"
msgid "Show the week date in the calendar"
msgstr "Kalendris näidatakse kuupäeva nädalavormingus"
msgid "If true, display the ISO week date in the calendar."
msgstr "Kui määratud, kuvatakse kalendris kuupäeva ISO nädalavormingus."
msgid "Which keyboard to use"
msgstr "Millist klaviatuuri kasutada"
msgid "disabled OpenSearch providers"
msgstr "keelatud OpenSearch pakkujad"
msgid "The type of keyboard to use."
msgstr "Kasutatava klaviatuuri liik."
msgid "Show time with seconds"
msgstr "Kellaaega näidatakse sekunditega"
msgid "If true, display seconds in time."
msgstr "Kui määratud, siis kuvatakse aja juures ka sekundeid."
msgid "Show date in clock"
msgstr "Kell näitab kuupäeva"
msgid "If true, display date in the clock, in addition to time."
msgstr "Kui määratud, siis kuvatakse kellaaja kõrval ka kuupäeva."
msgid "Framerate used for recording screencasts."
msgstr "Ekraanivideo lindistamisel kasutatav kaadrikiirus."
msgid ""
"The framerate of the resulting screencast recordered by GNOME Shell's "
"screencast recorder in frames-per-second."
msgstr ""
"GNOME Shelli lindistatava ekraanivideo kaadrisagedus (kaadrit sekundis)."
msgid "The gstreamer pipeline used to encode the screencast"
msgstr "GStreameri toru, mida ekraanivideo kodeerimiseks kasutatakse"
#, 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 "
"'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 ""
"Määrab GStreameri toru, mida kasutatakse lindistuste kodeerimiseks. See peab "
"vastama gst-launch'i süntaksile. Torul peaks olema vaba plokk (sink pad), "
"kuhu lindistatav video salvestatakse. Tavaliselt on vaba plokk olemas; selle "
"ploki väljund kirjutatakse väljundfaili. Toru võib hoolitseda ka enda "
"väljundi eest - seda võib kasutada väljundi saatmiseks icecast serverisse "
"shout2send või sarnase tehnoloogia abil. Kui see on määramata või väärtus on "
"tühi, kasutatakse vaikimisi toru. See on praegu 'vp8enc quality=8 speed=6 "
"threads=%T ! queue ! webmmux' ning lindistab WEBM vormingusse VP8 koodekiga. "
"%T asendatakse süsteemi oletatava optimaalseima lõimede (thread) arvuga."
msgid "File extension used for storing the screencast"
msgstr "Ekraanivideo salvestamisel kasutatav faililaiend"
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 ""
"Ekraanivideo jaoks kasutatav failinimi on unikaalne, see sisaldab "
"salvestamise kuupäeva ja ka käesoleva võtmega määratud laiendit. Mõnda teise "
"konteinervormingusse salvestades tuleks ka sellele vormingule vastav laiend "
"määrata."
#, c-format
msgid "There was an error loading the preferences dialog for %s:"
msgstr "%s jaoks eelistuste dialoogi laadimisel esines viga:"
msgid "<b>Extension</b>"
msgstr "<b>Laiendus</b>"
msgid "Select an extension to configure using the combobox above."
msgstr "Vali seadistatav laiendus kasutades ülemist valikukasti."
msgid "Session..."
msgstr "Seanss..."
@ -167,11 +182,14 @@ msgctxt "title"
msgid "Sign In"
msgstr "Sisselogimine"
#. translators: this message is shown below the password entry field
#. Translators: this message is shown below the password entry field
#. to indicate the user can swipe their finger instead
msgid "(or swipe finger)"
msgstr "(või libista näpp üle lugeja)"
#. 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.
msgid "Not listed?"
msgstr "Pole loendis?"
@ -647,10 +665,8 @@ msgstr "Rakendused"
msgid "Dash"
msgstr "Dokk"
#. TODO - _quit() doesn't really work on apps in state STARTING yet
#, c-format
msgid "Quit %s"
msgstr "Sulge %s"
msgid "Quit"
msgstr "Sulge"
#. Translators: If there is no suitable word for "Activities"
#. in your language, you can use the word for "Overview".
@ -724,6 +740,9 @@ msgstr "Tekst on peidetud"
msgid "Wrong password, please try again"
msgstr "Vale parool, palun proovi uuesti"
msgid "Accessibility"
msgstr "Kasutaja abivahendid"
msgid "Zoom"
msgstr "Suurendus"
@ -919,6 +938,9 @@ msgstr "Automaatne bluetooth"
msgid "Auto wireless"
msgstr "Automaatne juhtmeta ühendus"
msgid "Network"
msgstr "Võrk"
msgid "Enable networking"
msgstr "Luba võrguühendused"
@ -949,6 +971,9 @@ msgstr "Võrguühendused on keelatud"
msgid "Network Manager"
msgstr "Võrguhaldur"
msgid "Battery"
msgstr "Aku"
msgid "Power Settings"
msgstr "Toitesätted..."
@ -1019,13 +1044,13 @@ msgstr "Graafikalaud"
msgid "Computer"
msgstr "Arvuti"
#. Translators: This is the label for audio volume
msgid "Volume"
msgstr "Helivaljus"
msgid "Microphone"
msgstr "Mikrofon"
#. We got the TpContact
#. FIXME: We don't have a 'chat room' icon (bgo #653737) use
#. system-users for now as Empathy does.
msgid "Invitation"
@ -1181,7 +1206,7 @@ msgstr "Ühendust pole võimalik luua"
msgid "Connection has been lost"
msgstr "Ühendus katkes"
msgid "This resource is already connected to the server"
msgid "This account is already connected to the server"
msgstr "Selle kontoga on juba serverisse ühendutud"
msgid ""
@ -1209,6 +1234,9 @@ msgstr ""
"Serveri sertifikaadi pikkus ehk sertifikaatide keti sügavus ületab "
"krüptograafiateegi määratud piiri"
msgid "Internal error"
msgstr "Sisemine viga"
#. translators: argument is the account name, like
#. * name@jabber.org for example.
#, c-format
@ -1274,6 +1302,21 @@ msgstr "Otsing..."
msgid "Search"
msgstr "Otsing"
#, c-format
msgid ""
"Sorry, no wisdom for you today:\n"
"%s"
msgstr ""
"Vabandust, tänaseks tarkuseteri pole:\n"
"%s"
#, c-format
msgid "%s the Oracle says"
msgstr "Oraakel %s ütleb"
msgid "Your favorite Easter Egg"
msgstr "Sinu lemmiküllatusmuna"
#, c-format
msgid "'%s' is ready"
msgstr "'%s' on valmis"

335
po/fi.po
View File

@ -21,8 +21,8 @@ msgid ""
msgstr ""
"Project-Id-Version: gnome-shell\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2012-01-10 09:26+0100\n"
"PO-Revision-Date: 2012-01-09 16:54+0200\n"
"POT-Creation-Date: 2012-01-24 15:37+0200\n"
"PO-Revision-Date: 2012-01-22 14:10+0200\n"
"Last-Translator: Jiri Grönroos <jiri.gronroos@iki.fi>\n"
"Language-Team: Finnish <>\n"
"Language: fi\n"
@ -43,11 +43,6 @@ msgid "Window management and application launching"
msgstr "Ikkunanhallinta ja sovelluksien käynnistäminen"
#: ../data/org.gnome.shell.gschema.xml.in.h:1
msgid "Enable internal tools useful for developers and testers from Alt-F2"
msgstr ""
"Ota käyttöön sisäiset kehittäjiä ja testaajia hyödyttävät työkalut Alt-F2:sta"
#: ../data/org.gnome.shell.gschema.xml.in.h:2
msgid ""
"Allows access to internal debugging and monitoring tools using the Alt-F2 "
"dialog."
@ -55,11 +50,20 @@ msgstr ""
"Salli pääsy sisäiseen vianselvitys- ja monitorointityökaluun Alt-F2-ikkunan "
"kautta."
#: ../data/org.gnome.shell.gschema.xml.in.h:2
msgid "Enable internal tools useful for developers and testers from Alt-F2"
msgstr ""
"Ota käyttöön sisäiset kehittäjiä ja testaajia hyödyttävät työkalut Alt-F2:sta"
#: ../data/org.gnome.shell.gschema.xml.in.h:3
msgid "Uuids of extensions to enable"
msgstr "Käyttöön otettavien laajennosten UUID:t"
msgid "File extension used for storing the screencast"
msgstr "Tiedostopääte ruutunauhoitusten tallentamiseen"
#: ../data/org.gnome.shell.gschema.xml.in.h:4
msgid "Framerate used for recording screencasts."
msgstr "Ruutunauhoitusten kuvataajuus."
#: ../data/org.gnome.shell.gschema.xml.in.h:5
msgid ""
"GNOME Shell extensions have a uuid property; this key lists extensions which "
"should be loaded. Any extension that wants to be loaded needs to be in this "
@ -71,94 +75,31 @@ msgstr ""
"halutaan ladata, on oltava tässä luettelossa. Tätä luetteloa voi muokata "
"myös org.gnome.Shell-DBus-metodeilla EnableExtension ja DisableExtension."
#: ../data/org.gnome.shell.gschema.xml.in.h:5
msgid "Whether to collect stats about applications usage"
msgstr "Kerätäänkö sovellusten käytöstä tilastoja"
#: ../data/org.gnome.shell.gschema.xml.in.h:6
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 "
"want to disable this for privacy reasons. Please note that doing so won't "
"remove already saved data."
msgstr ""
"Ikkunanhallinta seuraa normaalisti aktiivisia sovelluksia, jotta eniten "
"käytetyt voidaan esittää (esim. käynnistimissä). Vaikka nämä tiedot pysyvät "
"yksityisinä, voit silti haluta ottaa ominaisuuden pois käytöstä "
"yksityisyyden vuoksi. Huomaa että pois kytkeminen ei poista aiemmin "
"tallennettuja tietoja."
#: ../data/org.gnome.shell.gschema.xml.in.h:7
msgid "List of desktop file IDs for favorite applications"
msgstr "Luettelo työpöytätiedostojen tunnisteista lempisovelluksille"
#: ../data/org.gnome.shell.gschema.xml.in.h:8
msgid ""
"The applications corresponding to these identifiers will be displayed in the "
"favorites area."
msgstr "Näitä tunnisteita vastaavat sovellukset näytetään suosikkien alueella."
#: ../data/org.gnome.shell.gschema.xml.in.h:9
msgid "disabled OpenSearch providers"
msgstr "käytöstä poistetut OpenSearch-tarjoajat"
#: ../data/org.gnome.shell.gschema.xml.in.h:10
msgid "History for command (Alt-F2) dialog"
msgstr "Historia komentoikkunalle (Alt-F2)"
#: ../data/org.gnome.shell.gschema.xml.in.h:11
#: ../data/org.gnome.shell.gschema.xml.in.h:7
msgid "History for the looking glass dialog"
msgstr "Historia näyttölasi-ikkunalle"
#: ../data/org.gnome.shell.gschema.xml.in.h:12
msgid "Show the week date in the calendar"
msgstr "Näytä viikonpäivä kalenterissa"
#: ../data/org.gnome.shell.gschema.xml.in.h:13
msgid "If true, display the ISO week date in the calendar."
msgstr "Jos tosi, näytä ISO-viikonpäivät kalenterissa."
#: ../data/org.gnome.shell.gschema.xml.in.h:14
msgid "Which keyboard to use"
msgstr "Mitä näppäimistöä käytetään"
#: ../data/org.gnome.shell.gschema.xml.in.h:15
msgid "The type of keyboard to use."
msgstr "Käytettävän näppäimistön tyyppi."
#: ../data/org.gnome.shell.gschema.xml.in.h:16
msgid "Show time with seconds"
msgstr "Näytä aika sekuntien kera"
#: ../data/org.gnome.shell.gschema.xml.in.h:17
msgid "If true, display seconds in time."
msgstr "Jos tosi, näytä sekunnit ajassa."
#: ../data/org.gnome.shell.gschema.xml.in.h:18
msgid "Show date in clock"
msgstr "Näytä päivämäärä kellossa"
#: ../data/org.gnome.shell.gschema.xml.in.h:19
#: ../data/org.gnome.shell.gschema.xml.in.h:8
msgid "If true, display date in the clock, in addition to time."
msgstr "Jos tosi, näytä päivämäärä kellossa ajan lisäksi."
#: ../data/org.gnome.shell.gschema.xml.in.h:20
msgid "Framerate used for recording screencasts."
msgstr "Ruutunauhoitusten kuvataajuus."
#: ../data/org.gnome.shell.gschema.xml.in.h:9
msgid "If true, display seconds in time."
msgstr "Jos tosi, näytä sekunnit ajassa."
#: ../data/org.gnome.shell.gschema.xml.in.h:21
msgid ""
"The framerate of the resulting screencast recordered by GNOME Shell's "
"screencast recorder in frames-per-second."
msgstr ""
"Nauhoituksesta tuloksena saatavan ruutunauhoituksen kuvataajuus kun käytössä "
"on GNOMEn ikkunanhallinnan nauhoitin, kuvaa per sekunti."
#: ../data/org.gnome.shell.gschema.xml.in.h:10
msgid "If true, display the ISO week date in the calendar."
msgstr "Jos tosi, näytä ISO-viikonpäivät kalenterissa."
#: ../data/org.gnome.shell.gschema.xml.in.h:22
msgid "The gstreamer pipeline used to encode the screencast"
msgstr "Gstreamer-liukuhihna jolla ruutunauhoitukset pakataan"
#: ../data/org.gnome.shell.gschema.xml.in.h:11
msgid "List of desktop file IDs for favorite applications"
msgstr "Luettelo työpöytätiedostojen tunnisteista lempisovelluksille"
#: ../data/org.gnome.shell.gschema.xml.in.h:24
#: ../data/org.gnome.shell.gschema.xml.in.h:13
#, no-c-format
msgid ""
"Sets the GStreamer pipeline used to encode recordings. It follows the syntax "
@ -184,11 +125,25 @@ msgstr ""
"muotoon VP8-koodekilla. %T korvautuu arvauksella parhaan suorituskyvy "
"antavasta säiemäärästä järjestelmässä."
#: ../data/org.gnome.shell.gschema.xml.in.h:25
msgid "File extension used for storing the screencast"
msgstr "Tiedostopääte ruutunauhoitusten tallentamiseen"
#: ../data/org.gnome.shell.gschema.xml.in.h:14
msgid "Show date in clock"
msgstr "Näytä päivämäärä kellossa"
#: ../data/org.gnome.shell.gschema.xml.in.h:26
#: ../data/org.gnome.shell.gschema.xml.in.h:15
msgid "Show the week date in the calendar"
msgstr "Näytä viikonpäivä kalenterissa"
#: ../data/org.gnome.shell.gschema.xml.in.h:16
msgid "Show time with seconds"
msgstr "Näytä aika sekuntien kera"
#: ../data/org.gnome.shell.gschema.xml.in.h:17
msgid ""
"The applications corresponding to these identifiers will be displayed in the "
"favorites area."
msgstr "Näitä tunnisteita vastaavat sovellukset näytetään suosikkien alueella."
#: ../data/org.gnome.shell.gschema.xml.in.h:18
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 "
@ -198,45 +153,90 @@ msgstr ""
"nykyisen päivämäärän ja tämän tiedostopäätteen mukaisesti. Tiedostopääte "
"tulisi vaihtaa mikäli nauhoitetaan eri tallennusmuotoon."
#: ../js/gdm/loginDialog.js:623
#: ../data/org.gnome.shell.gschema.xml.in.h:19
msgid ""
"The framerate of the resulting screencast recordered by GNOME Shell's "
"screencast recorder in frames-per-second."
msgstr ""
"Nauhoituksesta tuloksena saatavan ruutunauhoituksen kuvataajuus kun käytössä "
"on GNOMEn ikkunanhallinnan nauhoitin, kuvaa per sekunti."
#: ../data/org.gnome.shell.gschema.xml.in.h:20
msgid "The gstreamer pipeline used to encode the screencast"
msgstr "Gstreamer-liukuhihna jolla ruutunauhoitukset pakataan"
#: ../data/org.gnome.shell.gschema.xml.in.h:21
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 "
"want to disable this for privacy reasons. Please note that doing so won't "
"remove already saved data."
msgstr ""
"Ikkunanhallinta seuraa normaalisti aktiivisia sovelluksia, jotta eniten "
"käytetyt voidaan esittää (esim. käynnistimissä). Vaikka nämä tiedot pysyvät "
"yksityisinä, voit silti haluta ottaa ominaisuuden pois käytöstä "
"yksityisyyden vuoksi. Huomaa että pois kytkeminen ei poista aiemmin "
"tallennettuja tietoja."
#: ../data/org.gnome.shell.gschema.xml.in.h:22
msgid "The type of keyboard to use."
msgstr "Käytettävän näppäimistön tyyppi."
#: ../data/org.gnome.shell.gschema.xml.in.h:23
msgid "Uuids of extensions to enable"
msgstr "Käyttöön otettavien laajennosten UUID:t"
#: ../data/org.gnome.shell.gschema.xml.in.h:24
msgid "Whether to collect stats about applications usage"
msgstr "Kerätäänkö sovellusten käytöstä tilastoja"
#: ../data/org.gnome.shell.gschema.xml.in.h:25
msgid "Which keyboard to use"
msgstr "Mitä näppäimistöä käytetään"
#: ../data/org.gnome.shell.gschema.xml.in.h:26
msgid "disabled OpenSearch providers"
msgstr "käytöstä poistetut OpenSearch-tarjoajat"
#: ../js/gdm/loginDialog.js:624
msgid "Session..."
msgstr "Istunto…"
#: ../js/gdm/loginDialog.js:785
#: ../js/gdm/loginDialog.js:786
msgctxt "title"
msgid "Sign In"
msgstr "Kirjaudu sisään"
#. Translators: this message is shown below the password entry field
#. to indicate the user can swipe their finger instead
#: ../js/gdm/loginDialog.js:830
#: ../js/gdm/loginDialog.js:831
msgid "(or swipe finger)"
msgstr "(tai pyyhkäise sormella)"
#. 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:851
#: ../js/gdm/loginDialog.js:852
msgid "Not listed?"
msgstr "Ei luettelossa?"
#: ../js/gdm/loginDialog.js:1019 ../js/ui/endSessionDialog.js:418
#: ../js/gdm/loginDialog.js:1020 ../js/ui/endSessionDialog.js:419
#: ../js/ui/extensionSystem.js:516 ../js/ui/networkAgent.js:145
#: ../js/ui/polkitAuthenticationAgent.js:175 ../js/ui/status/bluetooth.js:462
msgid "Cancel"
msgstr "Peru"
#: ../js/gdm/loginDialog.js:1024
#: ../js/gdm/loginDialog.js:1025
msgctxt "button"
msgid "Sign In"
msgstr "Kirjaudu sisään"
#: ../js/gdm/loginDialog.js:1376
#: ../js/gdm/loginDialog.js:1377
msgid "Login Window"
msgstr "Kirjautumisikkuna"
#: ../js/gdm/powerMenu.js:113 ../js/ui/userMenu.js:578
#: ../js/ui/userMenu.js:580 ../js/ui/userMenu.js:649
#: ../js/gdm/powerMenu.js:113 ../js/ui/userMenu.js:579
#: ../js/ui/userMenu.js:581 ../js/ui/userMenu.js:650
msgid "Suspend"
msgstr "Valmiustila"
@ -460,7 +460,7 @@ msgid "Next week"
msgstr "Ensi viikolla"
#: ../js/ui/contactDisplay.js:63 ../js/ui/notificationDaemon.js:486
#: ../js/ui/status/power.js:215 ../src/shell-app.c:394
#: ../js/ui/status/power.js:215 ../src/shell-app.c:371
msgid "Unknown"
msgstr "Tuntematon"
@ -830,17 +830,17 @@ msgstr "Sovellukset"
msgid "Dash"
msgstr "Pikavalikko"
#: ../js/ui/panel.js:564
#: ../js/ui/panel.js:567
msgid "Quit"
msgstr "Lopeta"
#. Translators: If there is no suitable word for "Activities"
#. in your language, you can use the word for "Overview".
#: ../js/ui/panel.js:595
#: ../js/ui/panel.js:598
msgid "Activities"
msgstr "Toiminnot"
#: ../js/ui/panel.js:982
#: ../js/ui/panel.js:985
msgid "Top Bar"
msgstr "Yläpalkki"
@ -857,7 +857,7 @@ msgstr "Yritä uudelleen"
msgid "Connect to..."
msgstr "Yhdistä…"
#: ../js/ui/placeDisplay.js:364
#: ../js/ui/placeDisplay.js:367
msgid "PLACES & DEVICES"
msgstr "SIJAINNIT JA LAITTEET"
@ -1056,7 +1056,7 @@ msgstr "Salli pääsy aina"
msgid "Grant this time only"
msgstr "Salli vain tällä kerralla"
#: ../js/ui/status/bluetooth.js:382 ../js/ui/telepathyClient.js:1168
#: ../js/ui/status/bluetooth.js:382 ../js/ui/telepathyClient.js:1098
msgid "Reject"
msgstr "Hylkää"
@ -1213,11 +1213,11 @@ msgstr "Yhteys epäonnistui"
msgid "Activation of network connection failed"
msgstr "Verkkoyhteyden aktivointi epäonnistui"
#: ../js/ui/status/network.js:1989
#: ../js/ui/status/network.js:1992
msgid "Networking is disabled"
msgstr "Verkko ei ole käytössä"
#: ../js/ui/status/network.js:2113
#: ../js/ui/status/network.js:2116
msgid "Network Manager"
msgstr "Verkon hallinta"
@ -1317,47 +1317,46 @@ msgstr "Äänenvoimakkuus"
msgid "Microphone"
msgstr "Mikrofoni"
#. We got the TpContact
#. FIXME: We don't have a 'chat room' icon (bgo #653737) use
#. system-users for now as Empathy does.
#: ../js/ui/telepathyClient.js:267
#: ../js/ui/telepathyClient.js:225
msgid "Invitation"
msgstr "Kutsu"
#. We got the TpContact
#: ../js/ui/telepathyClient.js:335
#: ../js/ui/telepathyClient.js:278
msgid "Call"
msgstr "Soita"
#. We got the TpContact
#: ../js/ui/telepathyClient.js:365
#: ../js/ui/telepathyClient.js:294
msgid "File Transfer"
msgstr "Tiedostonsiirto"
#: ../js/ui/telepathyClient.js:446
#: ../js/ui/telepathyClient.js:376
msgid "Subscription request"
msgstr "Tilauspyyntö"
#: ../js/ui/telepathyClient.js:482
#: ../js/ui/telepathyClient.js:412
msgid "Connection error"
msgstr "Yhteysvirhe"
#: ../js/ui/telepathyClient.js:740
#: ../js/ui/telepathyClient.js:670
#, c-format
msgid "%s is online."
msgstr "%s on linjoilla."
#: ../js/ui/telepathyClient.js:745
#: ../js/ui/telepathyClient.js:674
#, c-format
msgid "%s is offline."
msgstr "%s on poissa linjoilta."
#: ../js/ui/telepathyClient.js:748
#: ../js/ui/telepathyClient.js:678
#, c-format
msgid "%s is away."
msgstr "%s on poissa."
#: ../js/ui/telepathyClient.js:751
#: ../js/ui/telepathyClient.js:681
#, c-format
msgid "%s is busy."
msgstr "%s on kiireinen."
@ -1365,35 +1364,35 @@ msgstr "%s on kiireinen."
#. 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:964
#: ../js/ui/telepathyClient.js:894
#, no-c-format
msgid "Sent at <b>%X</b> on <b>%A</b>"
msgstr "Lähetetty <b>%Ana</b> kello <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:970
#: ../js/ui/telepathyClient.js:900
#, no-c-format
msgid "Sent on <b>%A</b>, <b>%B %d</b>"
msgstr "Lähetetty <b>%Ana</b> <b>%d. %Bta</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:975
#: ../js/ui/telepathyClient.js:905
#, no-c-format
msgid "Sent on <b>%A</b>, <b>%B %d</b>, %Y"
msgstr "Lähetetty <b>%Ana</b> <b>%d. %Bta</b> %Y"
#. Translators: this is the other person changing their old IM name to their new
#. IM name.
#: ../js/ui/telepathyClient.js:1017
#: ../js/ui/telepathyClient.js:947
#, c-format
msgid "%s is now known as %s"
msgstr "%s on nyt nimeltään %s"
#. translators: argument is a room name like
#. * room@jabber.org for example.
#: ../js/ui/telepathyClient.js:1119
#: ../js/ui/telepathyClient.js:1049
#, c-format
msgid "Invitation to %s"
msgstr "Kutsu huoneeseen %s"
@ -1401,35 +1400,35 @@ msgstr "Kutsu huoneeseen %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:1127
#: ../js/ui/telepathyClient.js:1057
#, c-format
msgid "%s is inviting you to join %s"
msgstr "%s kutsuu sinut huoneeseen %s"
#: ../js/ui/telepathyClient.js:1129 ../js/ui/telepathyClient.js:1209
#: ../js/ui/telepathyClient.js:1307
#: ../js/ui/telepathyClient.js:1059 ../js/ui/telepathyClient.js:1139
#: ../js/ui/telepathyClient.js:1237
msgid "Decline"
msgstr "Kieltäydy"
#: ../js/ui/telepathyClient.js:1130 ../js/ui/telepathyClient.js:1210
#: ../js/ui/telepathyClient.js:1308
#: ../js/ui/telepathyClient.js:1060 ../js/ui/telepathyClient.js:1140
#: ../js/ui/telepathyClient.js:1238
msgid "Accept"
msgstr "Hyväksy"
#. translators: argument is a contact name like Alice for example.
#: ../js/ui/telepathyClient.js:1160
#: ../js/ui/telepathyClient.js:1090
#, c-format
msgid "Video call from %s"
msgstr "Videopuhelu käyttäjältä %s"
#. translators: argument is a contact name like Alice for example.
#: ../js/ui/telepathyClient.js:1163
#: ../js/ui/telepathyClient.js:1093
#, c-format
msgid "Call from %s"
msgstr "Puhelu käyttäjältä %s"
#. translators: this is a button label (verb), not a noun
#: ../js/ui/telepathyClient.js:1170
#: ../js/ui/telepathyClient.js:1100
msgid "Answer"
msgstr "Vastaa"
@ -1438,108 +1437,108 @@ msgstr "Vastaa"
#. * file name. The string will be something
#. * like: "Alice is sending you test.ogg"
#.
#: ../js/ui/telepathyClient.js:1203
#: ../js/ui/telepathyClient.js:1133
#, c-format
msgid "%s is sending you %s"
msgstr "%s on lähettämässä sinulle tiedostoa %s"
#. To translators: The parameter is the contact's alias
#: ../js/ui/telepathyClient.js:1272
#: ../js/ui/telepathyClient.js:1202
#, c-format
msgid "%s would like permission to see when you are online"
msgstr "%s haluaisi saada luvan nähdä, milloin olet linjoilla"
#: ../js/ui/telepathyClient.js:1365
#: ../js/ui/telepathyClient.js:1295
msgid "Network error"
msgstr "Verkkovirhe"
#: ../js/ui/telepathyClient.js:1367
#: ../js/ui/telepathyClient.js:1297
msgid "Authentication failed"
msgstr "Tunnistautuminen epäonnistui"
#: ../js/ui/telepathyClient.js:1369
#: ../js/ui/telepathyClient.js:1299
msgid "Encryption error"
msgstr "Salausvirhe"
#: ../js/ui/telepathyClient.js:1371
#: ../js/ui/telepathyClient.js:1301
msgid "Certificate not provided"
msgstr "Varmennetta ei annettu"
#: ../js/ui/telepathyClient.js:1373
#: ../js/ui/telepathyClient.js:1303
msgid "Certificate untrusted"
msgstr "Varmenteeseen ei luoteta"
#: ../js/ui/telepathyClient.js:1375
#: ../js/ui/telepathyClient.js:1305
msgid "Certificate expired"
msgstr "Varmenne on vanhentunut"
#: ../js/ui/telepathyClient.js:1377
#: ../js/ui/telepathyClient.js:1307
msgid "Certificate not activated"
msgstr "Varmennetta ei ole aktivoitu"
#: ../js/ui/telepathyClient.js:1379
#: ../js/ui/telepathyClient.js:1309
msgid "Certificate hostname mismatch"
msgstr "Varmenteen konenimiristiriita"
#: ../js/ui/telepathyClient.js:1381
#: ../js/ui/telepathyClient.js:1311
msgid "Certificate fingerprint mismatch"
msgstr "Varmenteen sormenjälkiristiriita"
#: ../js/ui/telepathyClient.js:1383
#: ../js/ui/telepathyClient.js:1313
msgid "Certificate self-signed"
msgstr "Varmenne on itseallekirjoitettu"
#: ../js/ui/telepathyClient.js:1385
#: ../js/ui/telepathyClient.js:1315
msgid "Status is set to offline"
msgstr "Tilaksi on asetettu ”poissa linjoilta”"
#: ../js/ui/telepathyClient.js:1387
#: ../js/ui/telepathyClient.js:1317
msgid "Encryption is not available"
msgstr "Salaus ei ole käytettävissä"
#: ../js/ui/telepathyClient.js:1389
#: ../js/ui/telepathyClient.js:1319
msgid "Certificate is invalid"
msgstr "Varmenne ei kelpaa"
#: ../js/ui/telepathyClient.js:1391
#: ../js/ui/telepathyClient.js:1321
msgid "Connection has been refused"
msgstr "Yhteys on evätty"
#: ../js/ui/telepathyClient.js:1393
#: ../js/ui/telepathyClient.js:1323
msgid "Connection can't be established"
msgstr "Yhteyttä ei voida muodostaa"
#: ../js/ui/telepathyClient.js:1395
#: ../js/ui/telepathyClient.js:1325
msgid "Connection has been lost"
msgstr "Yhteys on katkennut"
#: ../js/ui/telepathyClient.js:1397
#: ../js/ui/telepathyClient.js:1327
msgid "This resource is already connected to the server"
msgstr "Tämä resurssi on jo yhteydessä palvelimeen"
#: ../js/ui/telepathyClient.js:1399
#: ../js/ui/telepathyClient.js:1329
msgid ""
"Connection has been replaced by a new connection using the same resource"
msgstr "Yhteys on korvattu uudella samaa resurssia käyttävällä yhteydellä"
#: ../js/ui/telepathyClient.js:1401
#: ../js/ui/telepathyClient.js:1331
msgid "The account already exists on the server"
msgstr "Tili on jo olemassa palvelimella"
#: ../js/ui/telepathyClient.js:1403
#: ../js/ui/telepathyClient.js:1333
msgid "Server is currently too busy to handle the connection"
msgstr "Palvelin on tällä hetkellä liian kiireinen käsittelemään yhteyttä"
#: ../js/ui/telepathyClient.js:1405
#: ../js/ui/telepathyClient.js:1335
msgid "Certificate has been revoked"
msgstr "Varmenne on kumottu"
#: ../js/ui/telepathyClient.js:1407
#: ../js/ui/telepathyClient.js:1337
msgid ""
"Certificate uses an insecure cipher algorithm or is cryptographically weak"
msgstr "Varmenne käyttää turvatonta salausmenetelmää"
#: ../js/ui/telepathyClient.js:1409
#: ../js/ui/telepathyClient.js:1339
msgid ""
"The length of the server certificate, or the depth of the server certificate "
"chain, exceed the limits imposed by the cryptography library"
@ -1548,20 +1547,20 @@ msgstr ""
#. translators: argument is the account name, like
#. * name@jabber.org for example.
#: ../js/ui/telepathyClient.js:1419
#: ../js/ui/telepathyClient.js:1349
#, c-format
msgid "Connection to %s failed"
msgstr "Yhteys kohteeseen %s katkesi"
#: ../js/ui/telepathyClient.js:1428
#: ../js/ui/telepathyClient.js:1358
msgid "Reconnect"
msgstr "Yhdistä uudelleen"
#: ../js/ui/telepathyClient.js:1429
#: ../js/ui/telepathyClient.js:1359
msgid "Edit account"
msgstr "Muokkaa tiliä"
#: ../js/ui/telepathyClient.js:1475
#: ../js/ui/telepathyClient.js:1405
msgid "Unknown reason"
msgstr "Tuntematon syy"
@ -1577,39 +1576,39 @@ msgstr "Jouten"
msgid "Unavailable"
msgstr "Ei tavoitettavissa"
#: ../js/ui/userMenu.js:576 ../js/ui/userMenu.js:580 ../js/ui/userMenu.js:650
#: ../js/ui/userMenu.js:577 ../js/ui/userMenu.js:581 ../js/ui/userMenu.js:651
msgid "Power Off..."
msgstr "Sammuta…"
#: ../js/ui/userMenu.js:612
#: ../js/ui/userMenu.js:613
msgid "Notifications"
msgstr "Ilmoitukset"
#: ../js/ui/userMenu.js:620
#: ../js/ui/userMenu.js:621
msgid "Online Accounts"
msgstr "Verkkotilit"
#: ../js/ui/userMenu.js:624
#: ../js/ui/userMenu.js:625
msgid "System Settings"
msgstr "Järjestelmän asetukset"
#: ../js/ui/userMenu.js:631
#: ../js/ui/userMenu.js:632
msgid "Lock Screen"
msgstr "Lukitse näyttö"
#: ../js/ui/userMenu.js:636
#: ../js/ui/userMenu.js:637
msgid "Switch User"
msgstr "Vaihda käyttäjää"
#: ../js/ui/userMenu.js:641
#: ../js/ui/userMenu.js:642
msgid "Log Out..."
msgstr "Kirjaudu ulos…"
#: ../js/ui/userMenu.js:669
#: ../js/ui/userMenu.js:670
msgid "Your chat status will be set to busy"
msgstr "Pikaviestitilaksi asetetaan ”kiireinen”"
#: ../js/ui/userMenu.js:670
#: ../js/ui/userMenu.js:671
msgid ""
"Notifications are now disabled, including chat messages. Your online status "
"has been adjusted to let others know that you might not see their messages."
@ -1642,7 +1641,7 @@ msgstr ""
#: ../js/ui/wanda.js:128
#, c-format
msgid "%s the Oracle says"
msgstr ""
msgstr "%s, sanoo oraakkeli"
#: ../js/ui/wanda.js:168
msgid "Your favorite Easter Egg"
@ -1683,7 +1682,7 @@ msgstr "Tulosta versio"
msgid "Mode used by GDM for login screen"
msgstr "GDM:n kirjautumisruudussa käyttämä tila"
#: ../src/shell-app.c:639
#: ../src/shell-app.c:616
#, c-format
msgid "Failed to launch '%s'"
msgstr "Sovelluksen ”%s” käynnistäminen epäonnistui"

902
po/ga.po

File diff suppressed because it is too large Load Diff

668
po/gl.po

File diff suppressed because it is too large Load Diff

392
po/he.po

File diff suppressed because it is too large Load Diff

1068
po/it.po

File diff suppressed because it is too large Load Diff

1697
po/kk.po Normal file

File diff suppressed because it is too large Load Diff

774
po/lt.po

File diff suppressed because it is too large Load Diff

368
po/nb.po
View File

@ -8,8 +8,8 @@ msgid ""
msgstr ""
"Project-Id-Version: gnome-shell 3.3.x\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2012-01-06 21:16+0100\n"
"PO-Revision-Date: 2012-01-06 21:18+0100\n"
"POT-Creation-Date: 2012-02-19 20:02+0100\n"
"PO-Revision-Date: 2012-02-19 20:03+0100\n"
"Last-Translator: Kjartan Maraas <kmaraas@gnome.org>\n"
"Language-Team: Norwegian bokmål <i18n-nb@lister.ping.uio.no>\n"
"Language: \n"
@ -26,6 +26,15 @@ msgstr "GNOME Shell"
msgid "Window management and application launching"
msgstr "Vindushåndtering og oppstart av programmer"
#: ../data/gnome-shell-extension-prefs.desktop.in.in.h:1
#: ../js/extensionPrefs/main.js:153
msgid "GNOME Shell Extensions Preferences"
msgstr "Brukervalg for GNOME Shell utvidelser"
#: ../data/gnome-shell-extension-prefs.desktop.in.in.h:2
msgid "Configure GNOME Shell Extensions"
msgstr "Konfigurer utvidelser for GNOME Shell"
#: ../data/org.gnome.shell.gschema.xml.in.h:1
msgid "Enable internal tools useful for developers and testers from Alt-F2"
msgstr "Aktiver interne verktøy for utviklere og testere fra Alt-F2"
@ -152,9 +161,9 @@ msgid ""
"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."
"'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 ""
"Setter GStreamer-rør som brukes til å kode opptak. Den følger syntaksen som "
"brukes for gst-launch. Røret må ha en..."
@ -173,53 +182,66 @@ msgstr ""
"og bruke denne filendelsen. Den bør endres når du gjør opptak til et nytt "
"oppbevaringsformat."
#: ../js/gdm/loginDialog.js:623
#: ../js/extensionPrefs/main.js:125
#, c-format
msgid "There was an error loading the preferences dialog for %s:"
msgstr "Det oppsto en feil ved lasting av brukervalgdialog for %s:"
#: ../js/extensionPrefs/main.js:165
msgid "<b>Extension</b>"
msgstr "<b>Utvidelse</b>"
#: ../js/extensionPrefs/main.js:189
msgid "Select an extension to configure using the combobox above."
msgstr "Velg en utvidelse som skal konfigureres med komboboksen over."
#: ../js/gdm/loginDialog.js:624
msgid "Session..."
msgstr "Økt …"
#: ../js/gdm/loginDialog.js:785
#: ../js/gdm/loginDialog.js:786
msgctxt "title"
msgid "Sign In"
msgstr "Logg inn"
#. Translators: this message is shown below the password entry field
#. to indicate the user can swipe their finger instead
#: ../js/gdm/loginDialog.js:830
#: ../js/gdm/loginDialog.js:831
msgid "(or swipe finger)"
msgstr "(eller dra finger)"
#. 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:851
#: ../js/gdm/loginDialog.js:852
msgid "Not listed?"
msgstr "Ikke listet?"
#: ../js/gdm/loginDialog.js:1019 ../js/ui/endSessionDialog.js:418
#: ../js/ui/extensionSystem.js:516 ../js/ui/networkAgent.js:145
#: ../js/gdm/loginDialog.js:1020 ../js/ui/endSessionDialog.js:419
#: ../js/ui/extensionSystem.js:401 ../js/ui/networkAgent.js:153
#: ../js/ui/polkitAuthenticationAgent.js:175 ../js/ui/status/bluetooth.js:462
msgid "Cancel"
msgstr "Avbryt"
#: ../js/gdm/loginDialog.js:1024
#: ../js/gdm/loginDialog.js:1025
msgctxt "button"
msgid "Sign In"
msgstr "Logg inn"
#: ../js/gdm/loginDialog.js:1376
#: ../js/gdm/loginDialog.js:1377
msgid "Login Window"
msgstr "Innloggingsvindu"
#: ../js/gdm/powerMenu.js:113 ../js/ui/userMenu.js:578
#: ../js/ui/userMenu.js:580 ../js/ui/userMenu.js:649
#: ../js/gdm/powerMenu.js:152 ../js/ui/userMenu.js:581
#: ../js/ui/userMenu.js:583 ../js/ui/userMenu.js:652
msgid "Suspend"
msgstr "Hvilemodus"
#: ../js/gdm/powerMenu.js:118
#: ../js/gdm/powerMenu.js:157
msgid "Restart"
msgstr "Start på nytt"
#: ../js/gdm/powerMenu.js:123
#: ../js/gdm/powerMenu.js:162
msgid "Power Off"
msgstr "Slå av"
@ -433,7 +455,7 @@ msgid "Next week"
msgstr "Neste uke"
#: ../js/ui/contactDisplay.js:63 ../js/ui/notificationDaemon.js:486
#: ../js/ui/status/power.js:215 ../src/shell-app.c:394
#: ../js/ui/status/power.js:215 ../src/shell-app.c:372
msgid "Unknown"
msgstr "Ukjent"
@ -453,7 +475,7 @@ msgstr "Opptatt"
msgid "Offline"
msgstr "Frakoblet"
#: ../js/ui/contactDisplay.js:141
#: ../js/ui/contactDisplay.js:148
msgid "CONTACTS"
msgstr "KONTAKTER"
@ -461,58 +483,58 @@ msgstr "KONTAKTER"
msgid "Remove"
msgstr "Fjern"
#: ../js/ui/dateMenu.js:96
#: ../js/ui/dateMenu.js:97
msgid "Date and Time Settings"
msgstr "Innstillinger for dato og klokkeslett"
#: ../js/ui/dateMenu.js:122
#: ../js/ui/dateMenu.js:123
msgid "Open Calendar"
msgstr "Åpne kalender"
#. Translators: This is the time format with date used
#. in 24-hour mode.
#: ../js/ui/dateMenu.js:180
#: ../js/ui/dateMenu.js:181
msgid "%a %b %e, %R:%S"
msgstr "%a %e %b, %R.%S"
#: ../js/ui/dateMenu.js:181
#: ../js/ui/dateMenu.js:182
msgid "%a %b %e, %R"
msgstr "%a %e %b, %R"
#. Translators: This is the time format without date used
#. in 24-hour mode.
#: ../js/ui/dateMenu.js:185
#: ../js/ui/dateMenu.js:186
msgid "%a %R:%S"
msgstr "%a %R.%S"
#: ../js/ui/dateMenu.js:186
#: ../js/ui/dateMenu.js:187
msgid "%a %R"
msgstr "%a %R"
#. Translators: This is a time format with date used
#. for AM/PM.
#: ../js/ui/dateMenu.js:193
#: ../js/ui/dateMenu.js:194
msgid "%a %b %e, %l:%M:%S %p"
msgstr "%a %e %b, %l.%M.%S %p"
#: ../js/ui/dateMenu.js:194
#: ../js/ui/dateMenu.js:195
msgid "%a %b %e, %l:%M %p"
msgstr "%a %e %b, %l.%M %p"
#. Translators: This is a time format without date used
#. for AM/PM.
#: ../js/ui/dateMenu.js:198
#: ../js/ui/dateMenu.js:199
msgid "%a %l:%M:%S %p"
msgstr "%a %l.%M.%S %p"
#: ../js/ui/dateMenu.js:199
#: ../js/ui/dateMenu.js:200
msgid "%a %l:%M %p"
msgstr "%a %l.%M %p"
#. Translators: This is the date format to use when the calendar popup is
#. * shown - it is shown just below the time in the shell (e.g. "Tue 9:29 AM").
#.
#: ../js/ui/dateMenu.js:210
#: ../js/ui/dateMenu.js:211
msgid "%A %B %e, %Y"
msgstr "%a %e %B, %Y"
@ -612,11 +634,11 @@ msgstr[1] "Systemet vil starte på nytt automatisk om %d sekunder."
msgid "Restarting the system."
msgstr "Starter systemet på nytt."
#: ../js/ui/extensionSystem.js:520
#: ../js/ui/extensionSystem.js:405
msgid "Install"
msgstr "Installer"
#: ../js/ui/extensionSystem.js:524
#: ../js/ui/extensionSystem.js:409
#, c-format
msgid "Download and install '%s' from extensions.gnome.org?"
msgstr "Last ned og installer «%s» fra extensions.gnome.org?"
@ -629,7 +651,7 @@ msgstr "varslingsområde"
msgid "Keyboard"
msgstr "Tastatur"
#: ../js/ui/lookingGlass.js:724
#: ../js/ui/lookingGlass.js:725
msgid "No extensions installed"
msgstr "Ingen utvidelser installert"
@ -689,50 +711,50 @@ msgstr "Fjern demping"
msgid "Mute"
msgstr "Demp"
#: ../js/ui/messageTray.js:2444
#: ../js/ui/messageTray.js:2447
msgid "System Information"
msgstr "Systeminformasjon"
#: ../js/ui/networkAgent.js:140
#: ../js/ui/networkAgent.js:148
msgid "Connect"
msgstr "Koble til"
#. Cisco LEAP
#: ../js/ui/networkAgent.js:235 ../js/ui/networkAgent.js:247
#: ../js/ui/networkAgent.js:274 ../js/ui/networkAgent.js:294
#: ../js/ui/networkAgent.js:304
#: ../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: "
msgstr "Passord: "
#. static WEP
#: ../js/ui/networkAgent.js:240
#: ../js/ui/networkAgent.js:248
msgid "Key: "
msgstr "Nøkkel: "
#. TTLS and PEAP are actually much more complicated, but this complication
#. is not visible here since we only care about phase2 authentication
#. (and don't even care of which one)
#: ../js/ui/networkAgent.js:272 ../js/ui/networkAgent.js:290
#: ../js/ui/networkAgent.js:280 ../js/ui/networkAgent.js:298
msgid "Username: "
msgstr "Brukernavn: "
#: ../js/ui/networkAgent.js:278
#: ../js/ui/networkAgent.js:286
msgid "Identity: "
msgstr "Identitet: "
#: ../js/ui/networkAgent.js:280
#: ../js/ui/networkAgent.js:288
msgid "Private key password: "
msgstr "Passord for privat nøkkel: "
#: ../js/ui/networkAgent.js:292
#: ../js/ui/networkAgent.js:300
msgid "Service: "
msgstr "Tjeneste: "
#: ../js/ui/networkAgent.js:321
#: ../js/ui/networkAgent.js:329
msgid "Authentication required by wireless network"
msgstr "Autentisering kreves av trådløst nettverk"
#: ../js/ui/networkAgent.js:322
#: ../js/ui/networkAgent.js:330
#, c-format
msgid ""
"Passwords or encryption keys are required to access the wireless network "
@ -741,35 +763,35 @@ msgstr ""
"Passord eller krypteringsnøkler kreves for å koble til trådløst nettverk "
"«%s»."
#: ../js/ui/networkAgent.js:326
#: ../js/ui/networkAgent.js:334
msgid "Wired 802.1X authentication"
msgstr "802.1X autentisering for trådbundet nettverk"
#: ../js/ui/networkAgent.js:328
#: ../js/ui/networkAgent.js:336
msgid "Network name: "
msgstr "Navn på nettverk: "
#: ../js/ui/networkAgent.js:333
#: ../js/ui/networkAgent.js:341
msgid "DSL authentication"
msgstr "DSL-autentisering"
#: ../js/ui/networkAgent.js:340
#: ../js/ui/networkAgent.js:348
msgid "PIN code required"
msgstr "PIN-kode kreves"
#: ../js/ui/networkAgent.js:341
#: ../js/ui/networkAgent.js:349
msgid "PIN code is needed for the mobile broadband device"
msgstr "PIN-kode kreves for mobil bredbåndsenhet"
#: ../js/ui/networkAgent.js:342
#: ../js/ui/networkAgent.js:350
msgid "PIN: "
msgstr "PIN: "
#: ../js/ui/networkAgent.js:348
#: ../js/ui/networkAgent.js:356
msgid "Mobile broadband network password"
msgstr "Nettverkspassord for mobilt bredbånd"
#: ../js/ui/networkAgent.js:349
#: ../js/ui/networkAgent.js:357
#, c-format
msgid "A password is required to connect to '%s'."
msgstr "Et passord kreves for å koble til «%s»."
@ -792,17 +814,17 @@ msgstr "Programmer"
msgid "Dash"
msgstr "Favoritter"
#: ../js/ui/panel.js:564
#: ../js/ui/panel.js:582
msgid "Quit"
msgstr "Avslutt"
#. Translators: If there is no suitable word for "Activities"
#. in your language, you can use the word for "Overview".
#: ../js/ui/panel.js:595
#: ../js/ui/panel.js:613
msgid "Activities"
msgstr "Aktiviteter"
#: ../js/ui/panel.js:982
#: ../js/ui/panel.js:983
msgid "Top Bar"
msgstr "Topp-panel"
@ -819,7 +841,7 @@ msgstr "Prøv igjen"
msgid "Connect to..."
msgstr "Koble til …"
#: ../js/ui/placeDisplay.js:364
#: ../js/ui/placeDisplay.js:367
msgid "PLACES & DEVICES"
msgstr "STEDER & ENHETER"
@ -852,7 +874,7 @@ msgstr "Passord:"
#. "ON" and "OFF") or "toggle-switch-intl" (for toggle
#. switches containing "◯" and "|"). Other values will
#. simply result in invisible toggle switches.
#: ../js/ui/popupMenu.js:719
#: ../js/ui/popupMenu.js:720
msgid "toggle-switch-us"
msgstr "toggle-switch-intl"
@ -884,10 +906,14 @@ msgstr "Vis tekst"
msgid "Hide Text"
msgstr "Skjul tekst"
#: ../js/ui/shellMountOperation.js:269
#: ../js/ui/shellMountOperation.js:271
msgid "Wrong password, please try again"
msgstr "Feil passord. Prøv igjen"
#: ../js/ui/status/accessibility.js:47
msgid "Accessibility"
msgstr "Tilgjengelighet"
#: ../js/ui/status/accessibility.js:52
msgid "Zoom"
msgstr "Zoom"
@ -931,10 +957,10 @@ msgstr "Høy kontrast"
msgid "Large Text"
msgstr "Stor tekst"
#: ../js/ui/status/bluetooth.js:35 ../js/ui/status/bluetooth.js:258
#: ../js/ui/status/bluetooth.js:341 ../js/ui/status/bluetooth.js:371
#: ../js/ui/status/bluetooth.js:407 ../js/ui/status/bluetooth.js:436
#: ../js/ui/status/network.js:892
#: ../js/ui/status/bluetooth.js:31 ../js/ui/status/bluetooth.js:35
#: ../js/ui/status/bluetooth.js:258 ../js/ui/status/bluetooth.js:341
#: ../js/ui/status/bluetooth.js:371 ../js/ui/status/bluetooth.js:407
#: ../js/ui/status/bluetooth.js:436 ../js/ui/status/network.js:893
msgid "Bluetooth"
msgstr "Bluetooth"
@ -955,7 +981,7 @@ msgid "Bluetooth Settings"
msgstr "Innstillinger for Bluetooth"
#. TRANSLATORS: this means that bluetooth was disabled by hardware rfkill
#: ../js/ui/status/bluetooth.js:107 ../js/ui/status/network.js:255
#: ../js/ui/status/bluetooth.js:107 ../js/ui/status/network.js:256
msgid "hardware disabled"
msgstr "maskinvare slått av"
@ -963,11 +989,11 @@ msgstr "maskinvare slått av"
msgid "Connection"
msgstr "Tilkobling"
#: ../js/ui/status/bluetooth.js:214 ../js/ui/status/network.js:490
#: ../js/ui/status/bluetooth.js:214 ../js/ui/status/network.js:491
msgid "disconnecting..."
msgstr "kobler fra …"
#: ../js/ui/status/bluetooth.js:227 ../js/ui/status/network.js:496
#: ../js/ui/status/bluetooth.js:227 ../js/ui/status/network.js:497
msgid "connecting..."
msgstr "kobler til …"
@ -996,7 +1022,7 @@ msgstr "Innstillinger for tastatur"
msgid "Mouse Settings"
msgstr "Innstillinger for mus"
#: ../js/ui/status/bluetooth.js:276 ../js/ui/status/volume.js:58
#: ../js/ui/status/bluetooth.js:276 ../js/ui/status/volume.js:59
msgid "Sound Settings"
msgstr "Innstillinger for lyd"
@ -1018,7 +1044,7 @@ msgstr "Alltid gi tilgang"
msgid "Grant this time only"
msgstr "Gi tilgang kun denne ene gangen"
#: ../js/ui/status/bluetooth.js:382 ../js/ui/telepathyClient.js:1168
#: ../js/ui/status/bluetooth.js:382 ../js/ui/telepathyClient.js:1093
msgid "Reject"
msgstr "Avvis"
@ -1071,119 +1097,127 @@ msgid "<unknown>"
msgstr "<ukjent>"
#. Translators: this indicates that wireless or wwan is disabled by hardware killswitch
#: ../js/ui/status/network.js:277
#: ../js/ui/status/network.js:278
msgid "disabled"
msgstr "slått av"
#. Translators: this is for network devices that are physically present but are not
#. under NetworkManager's control (and thus cannot be used in the menu)
#: ../js/ui/status/network.js:488
#: ../js/ui/status/network.js:489
msgid "unmanaged"
msgstr "ikke håndtert"
#. Translators: this is for network connections that require some kind of key or password
#: ../js/ui/status/network.js:499
#: ../js/ui/status/network.js:500
msgid "authentication required"
msgstr "autentisering kreves"
#. Translators: this is for devices that require some kind of firmware or kernel
#. module, which is missing
#: ../js/ui/status/network.js:509
#: ../js/ui/status/network.js:510
msgid "firmware missing"
msgstr "fastvare mangler"
#. Translators: this is for wired network devices that are physically disconnected
#: ../js/ui/status/network.js:516
#: ../js/ui/status/network.js:517
msgid "cable unplugged"
msgstr "kabel koblet fra"
#. Translators: this is for a network device that cannot be activated (for example it
#. is disabled by rfkill, or it has no coverage
#: ../js/ui/status/network.js:521
#: ../js/ui/status/network.js:522
msgid "unavailable"
msgstr "ikke tilgjengelig"
#: ../js/ui/status/network.js:523
#: ../js/ui/status/network.js:524
msgid "connection failed"
msgstr "tilkobling feilet"
#: ../js/ui/status/network.js:584 ../js/ui/status/network.js:1504
#: ../js/ui/status/network.js:585 ../js/ui/status/network.js:1505
msgid "More..."
msgstr "Mer …"
#. TRANSLATORS: this is the indication that a connection for another logged in user is active,
#. and we cannot access its settings (including the name)
#: ../js/ui/status/network.js:620 ../js/ui/status/network.js:1439
#: ../js/ui/status/network.js:621 ../js/ui/status/network.js:1440
msgid "Connected (private)"
msgstr "Tilkoblet (privat)"
#: ../js/ui/status/network.js:695
#: ../js/ui/status/network.js:696
msgid "Auto Ethernet"
msgstr "Automatisk Ethernet"
#: ../js/ui/status/network.js:756
#: ../js/ui/status/network.js:757
msgid "Auto broadband"
msgstr "Automatisk bredbånd"
#: ../js/ui/status/network.js:759
#: ../js/ui/status/network.js:760
msgid "Auto dial-up"
msgstr "Automatisk oppringt"
#. TRANSLATORS: this the automatic wireless connection name (including the network name)
#: ../js/ui/status/network.js:878 ../js/ui/status/network.js:1451
#: ../js/ui/status/network.js:879 ../js/ui/status/network.js:1452
#, c-format
msgid "Auto %s"
msgstr "Automatisk %s"
#: ../js/ui/status/network.js:880
#: ../js/ui/status/network.js:881
msgid "Auto bluetooth"
msgstr "Automatisk Bluetooth"
#: ../js/ui/status/network.js:1453
#: ../js/ui/status/network.js:1454
msgid "Auto wireless"
msgstr "Automatisk trådløst"
#: ../js/ui/status/network.js:1547
#: ../js/ui/status/network.js:1541
msgid "Network"
msgstr "Nettverk"
#: ../js/ui/status/network.js:1548
msgid "Enable networking"
msgstr "Slå på nettverk"
#: ../js/ui/status/network.js:1559
#: ../js/ui/status/network.js:1560
msgid "Wired"
msgstr "Kablet"
#: ../js/ui/status/network.js:1570
#: ../js/ui/status/network.js:1571
msgid "Wireless"
msgstr "Trådløst"
#: ../js/ui/status/network.js:1580
#: ../js/ui/status/network.js:1581
msgid "Mobile broadband"
msgstr "Mobilt bredbånd"
#: ../js/ui/status/network.js:1590
#: ../js/ui/status/network.js:1591
msgid "VPN Connections"
msgstr "VPN-tilkoblinger"
#: ../js/ui/status/network.js:1601
#: ../js/ui/status/network.js:1602
msgid "Network Settings"
msgstr "Innstillinger for nettverk"
#: ../js/ui/status/network.js:1738
#: ../js/ui/status/network.js:1739
msgid "Connection failed"
msgstr "Tilkobling feilet"
#: ../js/ui/status/network.js:1739
#: ../js/ui/status/network.js:1740
msgid "Activation of network connection failed"
msgstr "Aktivering av nettverkstilkobling feilet"
#: ../js/ui/status/network.js:1989
#: ../js/ui/status/network.js:1993
msgid "Networking is disabled"
msgstr "Nettverk er slått av"
#: ../js/ui/status/network.js:2113
#: ../js/ui/status/network.js:2117
msgid "Network Manager"
msgstr "Nettverkshåndtering"
#: ../js/ui/status/power.js:77
#: ../js/ui/status/power.js:59
msgid "Battery"
msgstr "Batteri"
#: ../js/ui/status/power.js:76
msgid "Power Settings"
msgstr "Innstillinger for strøm"
@ -1271,55 +1305,55 @@ msgstr "Nettbrett"
msgid "Computer"
msgstr "Datamaskin"
#: ../js/ui/status/volume.js:38
#. Translators: This is the label for audio volume
#: ../js/ui/status/volume.js:25 ../js/ui/status/volume.js:39
msgid "Volume"
msgstr "Volum"
#: ../js/ui/status/volume.js:50
#: ../js/ui/status/volume.js:51
msgid "Microphone"
msgstr "Mikrofon"
#. We got the TpContact
#. FIXME: We don't have a 'chat room' icon (bgo #653737) use
#. system-users for now as Empathy does.
#: ../js/ui/telepathyClient.js:267
#: ../js/ui/telepathyClient.js:220
msgid "Invitation"
msgstr "Invitasjon"
#. We got the TpContact
#: ../js/ui/telepathyClient.js:335
#: ../js/ui/telepathyClient.js:273
msgid "Call"
msgstr "Ring"
#. We got the TpContact
#: ../js/ui/telepathyClient.js:365
#: ../js/ui/telepathyClient.js:289
msgid "File Transfer"
msgstr "Filoverføring"
#: ../js/ui/telepathyClient.js:446
#: ../js/ui/telepathyClient.js:371
msgid "Subscription request"
msgstr "Forespørsel om abbonering"
#: ../js/ui/telepathyClient.js:482
#: ../js/ui/telepathyClient.js:407
msgid "Connection error"
msgstr "Feil ved tilkobling"
#: ../js/ui/telepathyClient.js:740
#: ../js/ui/telepathyClient.js:665
#, c-format
msgid "%s is online."
msgstr "%s er tilkoblet."
#: ../js/ui/telepathyClient.js:745
#: ../js/ui/telepathyClient.js:669
#, c-format
msgid "%s is offline."
msgstr "%s er frakoblet."
#: ../js/ui/telepathyClient.js:748
#: ../js/ui/telepathyClient.js:673
#, c-format
msgid "%s is away."
msgstr "«%s» er borte."
#: ../js/ui/telepathyClient.js:751
#: ../js/ui/telepathyClient.js:676
#, c-format
msgid "%s is busy."
msgstr "%s er opptatt."
@ -1327,35 +1361,35 @@ msgstr "%s er opptatt."
#. Translators: this is a time format string followed by a date.
#. If applicable, replace %X with a strftime format valid for your
#. locale, without seconds.
#: ../js/ui/telepathyClient.js:964
#: ../js/ui/telepathyClient.js:889
#, no-c-format
msgid "Sent at <b>%X</b> on <b>%A</b>"
msgstr "Sendt <b>%X</b> på <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:970
#: ../js/ui/telepathyClient.js:895
#, no-c-format
msgid "Sent on <b>%A</b>, <b>%B %d</b>"
msgstr "Sendt <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:975
#: ../js/ui/telepathyClient.js:900
#, no-c-format
msgid "Sent on <b>%A</b>, <b>%B %d</b>, %Y"
msgstr "Sendt <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:1017
#: ../js/ui/telepathyClient.js:942
#, c-format
msgid "%s is now known as %s"
msgstr "%s er nå kjent som %s"
#. translators: argument is a room name like
#. * room@jabber.org for example.
#: ../js/ui/telepathyClient.js:1119
#: ../js/ui/telepathyClient.js:1044
#, c-format
msgid "Invitation to %s"
msgstr "Invitasjon til %s"
@ -1363,35 +1397,35 @@ msgstr "Invitasjon til %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:1127
#: ../js/ui/telepathyClient.js:1052
#, c-format
msgid "%s is inviting you to join %s"
msgstr "%s inviterer deg til å bli med i %s"
#: ../js/ui/telepathyClient.js:1129 ../js/ui/telepathyClient.js:1209
#: ../js/ui/telepathyClient.js:1307
#: ../js/ui/telepathyClient.js:1054 ../js/ui/telepathyClient.js:1133
#: ../js/ui/telepathyClient.js:1231
msgid "Decline"
msgstr "Avslå"
#: ../js/ui/telepathyClient.js:1130 ../js/ui/telepathyClient.js:1210
#: ../js/ui/telepathyClient.js:1308
#: ../js/ui/telepathyClient.js:1055 ../js/ui/telepathyClient.js:1134
#: ../js/ui/telepathyClient.js:1232
msgid "Accept"
msgstr "Godta"
#. translators: argument is a contact name like Alice for example.
#: ../js/ui/telepathyClient.js:1160
#: ../js/ui/telepathyClient.js:1085
#, c-format
msgid "Video call from %s"
msgstr "Videosamtale fra %s"
#. translators: argument is a contact name like Alice for example.
#: ../js/ui/telepathyClient.js:1163
#: ../js/ui/telepathyClient.js:1088
#, c-format
msgid "Call from %s"
msgstr "Samtale fra %s"
#. translators: this is a button label (verb), not a noun
#: ../js/ui/telepathyClient.js:1170
#: ../js/ui/telepathyClient.js:1095
msgid "Answer"
msgstr "Svar"
@ -1400,110 +1434,110 @@ msgstr "Svar"
#. * file name. The string will be something
#. * like: "Alice is sending you test.ogg"
#.
#: ../js/ui/telepathyClient.js:1203
#: ../js/ui/telepathyClient.js:1127
#, c-format
msgid "%s is sending you %s"
msgstr "%s sender deg %s"
#. To translators: The parameter is the contact's alias
#: ../js/ui/telepathyClient.js:1272
#: ../js/ui/telepathyClient.js:1196
#, c-format
msgid "%s would like permission to see when you are online"
msgstr "%s vil ha rettigheter til å se når du er tilkoblet"
#: ../js/ui/telepathyClient.js:1365
#: ../js/ui/telepathyClient.js:1289
msgid "Network error"
msgstr "Nettverksfeil"
#: ../js/ui/telepathyClient.js:1367
#: ../js/ui/telepathyClient.js:1291
msgid "Authentication failed"
msgstr "Autentisering feilet"
#: ../js/ui/telepathyClient.js:1369
#: ../js/ui/telepathyClient.js:1293
msgid "Encryption error"
msgstr "Feil ved kryptering"
#: ../js/ui/telepathyClient.js:1371
#: ../js/ui/telepathyClient.js:1295
msgid "Certificate not provided"
msgstr "Sertifikat ikke oppgitt"
#: ../js/ui/telepathyClient.js:1373
#: ../js/ui/telepathyClient.js:1297
msgid "Certificate untrusted"
msgstr "Stoler ikke på sertifikatet"
#: ../js/ui/telepathyClient.js:1375
#: ../js/ui/telepathyClient.js:1299
msgid "Certificate expired"
msgstr "Sertifikatet er utløpt"
#: ../js/ui/telepathyClient.js:1377
#: ../js/ui/telepathyClient.js:1301
msgid "Certificate not activated"
msgstr "Sertifikatet er ikke aktivert"
#: ../js/ui/telepathyClient.js:1379
#: ../js/ui/telepathyClient.js:1303
msgid "Certificate hostname mismatch"
msgstr "Feil vertsnavn for sertifikat"
#: ../js/ui/telepathyClient.js:1381
#: ../js/ui/telepathyClient.js:1305
msgid "Certificate fingerprint mismatch"
msgstr "Feil fingeravtrykk for sertifikat"
#: ../js/ui/telepathyClient.js:1383
#: ../js/ui/telepathyClient.js:1307
msgid "Certificate self-signed"
msgstr "Sertifikatet er selvsignert"
#: ../js/ui/telepathyClient.js:1385
#: ../js/ui/telepathyClient.js:1309
msgid "Status is set to offline"
msgstr "Status er satt til frakoblet"
#: ../js/ui/telepathyClient.js:1387
#: ../js/ui/telepathyClient.js:1311
msgid "Encryption is not available"
msgstr "Kryptering er ikke tilgjengelig"
#: ../js/ui/telepathyClient.js:1389
#: ../js/ui/telepathyClient.js:1313
msgid "Certificate is invalid"
msgstr "Sertifikatet er ugyldig"
#: ../js/ui/telepathyClient.js:1391
#: ../js/ui/telepathyClient.js:1315
msgid "Connection has been refused"
msgstr "Tilkobling ble nektet"
#: ../js/ui/telepathyClient.js:1393
#: ../js/ui/telepathyClient.js:1317
msgid "Connection can't be established"
msgstr "Tilkobling kan ikke etableres"
#: ../js/ui/telepathyClient.js:1395
#: ../js/ui/telepathyClient.js:1319
msgid "Connection has been lost"
msgstr "Tilkobling tapt"
#: ../js/ui/telepathyClient.js:1397
msgid "This resource is already connected to the server"
msgstr "Denne ressursen er allerede koblet til tjeneren"
#: ../js/ui/telepathyClient.js:1321
msgid "This account is already connected to the server"
msgstr "Denne kontoen er allerede koblet til tjeneren"
#: ../js/ui/telepathyClient.js:1399
#: ../js/ui/telepathyClient.js:1323
msgid ""
"Connection has been replaced by a new connection using the same resource"
msgstr ""
"Tilkoblingen har blitt erstattet av en ny tilkobling som bruker samme ressurs"
#: ../js/ui/telepathyClient.js:1401
#: ../js/ui/telepathyClient.js:1325
msgid "The account already exists on the server"
msgstr "Kontoen eksisterer allerede på tjeneren"
#: ../js/ui/telepathyClient.js:1403
#: ../js/ui/telepathyClient.js:1327
msgid "Server is currently too busy to handle the connection"
msgstr "Tjener er for opptatt til å håndtere tilkoblingen"
#: ../js/ui/telepathyClient.js:1405
#: ../js/ui/telepathyClient.js:1329
msgid "Certificate has been revoked"
msgstr "Sertifikatet er tilbaketrukket"
#: ../js/ui/telepathyClient.js:1407
#: ../js/ui/telepathyClient.js:1331
msgid ""
"Certificate uses an insecure cipher algorithm or is cryptographically weak"
msgstr ""
"Sertifikatet bruker en usikker sifferalgoritme eller er krytografisk svakt"
#: ../js/ui/telepathyClient.js:1409
#: ../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"
@ -1511,22 +1545,26 @@ msgstr ""
"Lengden eller dybden på tjenersertifikatet oversteg grensen som er satt i "
"kryptografibiblioteket"
#: ../js/ui/telepathyClient.js:1335
msgid "Internal error"
msgstr "Intern feil"
#. translators: argument is the account name, like
#. * name@jabber.org for example.
#: ../js/ui/telepathyClient.js:1419
#: ../js/ui/telepathyClient.js:1345
#, c-format
msgid "Connection to %s failed"
msgstr "Tilkobling til %s feilet"
#: ../js/ui/telepathyClient.js:1428
#: ../js/ui/telepathyClient.js:1354
msgid "Reconnect"
msgstr "Koble til på nytt"
#: ../js/ui/telepathyClient.js:1429
#: ../js/ui/telepathyClient.js:1355
msgid "Edit account"
msgstr "Rediger konto"
#: ../js/ui/telepathyClient.js:1475
#: ../js/ui/telepathyClient.js:1401
msgid "Unknown reason"
msgstr "Ukjent årsak"
@ -1542,39 +1580,39 @@ msgstr "Ledig"
msgid "Unavailable"
msgstr "Ikke tilgjengelig"
#: ../js/ui/userMenu.js:576 ../js/ui/userMenu.js:580 ../js/ui/userMenu.js:650
#: ../js/ui/userMenu.js:579 ../js/ui/userMenu.js:583 ../js/ui/userMenu.js:653
msgid "Power Off..."
msgstr "Slå av …"
#: ../js/ui/userMenu.js:612
#: ../js/ui/userMenu.js:615
msgid "Notifications"
msgstr "Varslinger"
#: ../js/ui/userMenu.js:620
#: ../js/ui/userMenu.js:623
msgid "Online Accounts"
msgstr "Kontoer på nettet"
#: ../js/ui/userMenu.js:624
#: ../js/ui/userMenu.js:627
msgid "System Settings"
msgstr "Systeminnstillinger"
#: ../js/ui/userMenu.js:631
#: ../js/ui/userMenu.js:634
msgid "Lock Screen"
msgstr "Lås skjerm"
#: ../js/ui/userMenu.js:636
#: ../js/ui/userMenu.js:639
msgid "Switch User"
msgstr "Bytt bruker"
#: ../js/ui/userMenu.js:641
#: ../js/ui/userMenu.js:644
msgid "Log Out..."
msgstr "Logg ut …"
#: ../js/ui/userMenu.js:669
#: ../js/ui/userMenu.js:672
msgid "Your chat status will be set to busy"
msgstr "Din pratestatus vil bli satt til opptatt"
#: ../js/ui/userMenu.js:670
#: ../js/ui/userMenu.js:673
msgid ""
"Notifications are now disabled, including chat messages. Your online status "
"has been adjusted to let others know that you might not see their messages."
@ -1591,7 +1629,7 @@ msgstr ""
msgid "Type to search..."
msgstr "Skriv for å søke …"
#: ../js/ui/viewSelector.js:131 ../src/shell-util.c:244
#: ../js/ui/viewSelector.js:131 ../src/shell-util.c:252
msgid "Search"
msgstr "Søk"
@ -1648,7 +1686,7 @@ msgstr "Skriv ut versjon"
msgid "Mode used by GDM for login screen"
msgstr "Modus som brukes av GDM for innloggingsskjermen"
#: ../src/shell-app.c:639
#: ../src/shell-app.c:617
#, c-format
msgid "Failed to launch '%s'"
msgstr "Klarte ikke å starte «%s»"
@ -1661,19 +1699,19 @@ msgstr "Storbritannia"
msgid "Default"
msgstr "Forvalg"
#: ../src/shell-polkit-authentication-agent.c:334
#: ../src/shell-polkit-authentication-agent.c:339
msgid "Authentication dialog was dismissed by the user"
msgstr "Autentiseringsdialogen ble lukket av brukeren"
#. Translators: this is the same string as the one found in
#. * nautilus
#: ../src/shell-util.c:89
#: ../src/shell-util.c:97
msgid "Home"
msgstr "Hjem"
#. Translators: this is the same string as the one found in
#. * nautilus
#: ../src/shell-util.c:98
#: ../src/shell-util.c:106
msgid "File System"
msgstr "Filsystem"
@ -1682,7 +1720,7 @@ msgstr "Filsystem"
#. * example, "Trash: some-directory". It means that the
#. * directory called "some-directory" is in the trash.
#.
#: ../src/shell-util.c:294
#: ../src/shell-util.c:302
#, c-format
msgid "%1$s: %2$s"
msgstr "%1$s: %2$s"

745
po/nl.po

File diff suppressed because it is too large Load Diff

1100
po/pa.po

File diff suppressed because it is too large Load Diff

1667
po/si.po Normal file

File diff suppressed because it is too large Load Diff

543
po/sl.po

File diff suppressed because it is too large Load Diff

1032
po/sr.po

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

744
po/te.po

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -11,39 +11,16 @@ st_cflags = \
st_built_sources = \
st-enum-types.h \
st-enum-types.c \
st-marshal.h \
st-marshal.c
st-enum-types.c
BUILT_SOURCES += $(st_built_sources)
EXTRA_DIST += \
st/test-theme.css \
st/st-marshal.list \
st/st-enum-types.h.in \
st/st-enum-types.c.in
CLEANFILES += stamp-st-marshal.h stamp-st-enum-types.h
st-marshal.h: stamp-st-marshal.h
@true
stamp-st-marshal.h: Makefile st/st-marshal.list
$(AM_V_GEN) $(GLIB_GENMARSHAL) \
--prefix=_st_marshal \
--header \
$(srcdir)/st/st-marshal.list > $@.tmp && \
(cmp -s $@.tmp st-marshal.h || cp -f $@.tmp st-marshal.h) && \
rm -f $@.tmp && \
echo timestamp > $(@F)
st-marshal.c: Makefile st/st-marshal.list
$(AM_V_GEN) (echo "#include \"st-marshal.h\"" ; \
$(GLIB_GENMARSHAL) \
--prefix=_st_marshal \
--body \
$(srcdir)/st/st-marshal.list ) > $@.tmp && \
cp -f $@.tmp st-marshal.c && \
rm -f $@.tmp
CLEANFILES += stamp-st-enum-types.h
st-enum-types.h: stamp-st-enum-types.h Makefile
@true
@ -82,7 +59,6 @@ st_source_h = \
st/st-icon-colors.h \
st/st-im-text.h \
st/st-label.h \
st/st-overflow-box.h \
st/st-private.h \
st/st-scrollable.h \
st/st-scroll-bar.h \
@ -94,7 +70,6 @@ st_source_h = \
st/st-theme.h \
st/st-theme-context.h \
st/st-theme-node.h \
st/st-tooltip.h \
st/st-types.h \
st/st-widget.h \
st/st-widget-accessible.h \
@ -139,7 +114,6 @@ st_source_c = \
st/st-icon-colors.c \
st/st-im-text.c \
st/st-label.c \
st/st-overflow-box.c \
st/st-private.c \
st/st-scrollable.c \
st/st-scroll-bar.c \
@ -153,7 +127,6 @@ st_source_c = \
st/st-theme-node.c \
st/st-theme-node-drawing.c \
st/st-theme-node-transition.c \
st/st-tooltip.c \
st/st-widget.c \
$(NULL)

View File

@ -5,14 +5,8 @@ tray_cflags = \
$(TRAY_CFLAGS) \
$(NULL)
tray_built_sources = \
na-marshal.h \
na-marshal.c
BUILT_SOURCES += $(tray_built_sources)
TRAY_STAMP_FILES = stamp-na-marshal.h
# please, keep this sorted alphabetically
tray_source = \
tray/na-tray-child.c \
@ -21,26 +15,6 @@ tray_source = \
tray/na-tray-manager.h \
$(NULL)
na-marshal.h: stamp-na-marshal.h
@true
stamp-na-marshal.h: Makefile tray/na-marshal.list
$(AM_V_GEN) $(GLIB_GENMARSHAL) \
--prefix=_na_marshal \
--header \
$(srcdir)/tray/na-marshal.list > xgen-tmh && \
(cmp -s xgen-tmh na-marshal.h || cp -f xgen-tmh na-marshal.h) && \
rm -f xgen-tmh && \
echo timestamp > $(@F)
na-marshal.c: Makefile tray/na-marshal.list
$(AM_V_GEN) (echo "#include \"na-marshal.h\"" ; \
$(GLIB_GENMARSHAL) \
--prefix=_na_marshal \
--body \
$(srcdir)/tray/na-marshal.list ) > xgen-tmc && \
cp -f xgen-tmc na-marshal.c && \
rm -f xgen-tmc
noinst_LTLIBRARIES += libtray.la
libtray_la_LIBADD = $(TRAY_LIBS)
@ -52,6 +26,3 @@ libtray_la_CPPFLAGS = $(tray_cflags)
libtray_la_LDFLAGS = $(LDADD)
CLEANFILES += $(TRAY_STAMP_FILES) $(BUILT_SOURCES)
EXTRA_DIST += \
tray/na-marshal.list

View File

@ -27,8 +27,8 @@ CLEANFILES += $(service_DATA)
CLEANFILES += $(gir_DATA) $(typelib_DATA)
bin_SCRIPTS += gnome-shell-extension-tool
EXTRA_DIST += gnome-shell-extension-tool.in
bin_SCRIPTS += gnome-shell-extension-tool gnome-shell-extension-prefs
EXTRA_DIST += gnome-shell-extension-tool.in gnome-shell-extension-prefs.in
bin_PROGRAMS = gnome-shell-real
if USE_JHBUILD_WRAPPER_SCRIPT
@ -48,15 +48,17 @@ uninstall-hook:
rm -f $(DESTDIR)$(bindir)/gnome-shell
generated_script_substitutions = \
-e "s|@bindir[@]|$(bindir)|" \
-e "s|@datadir[@]|$(datadir)|" \
-e "s|@libexecdir[@]|$(libexecdir)|" \
-e "s|@libdir[@]|$(libdir)|" \
-e "s|@JHBUILD_TYPELIBDIR[@]|$(JHBUILD_TYPELIBDIR)|" \
-e "s|@pkgdatadir[@]|$(pkgdatadir)|" \
-e "s|@PYTHON[@]|$(PYTHON)|" \
-e "s|@VERSION[@]|$(VERSION)|" \
-e "s|@sysconfdir[@]|$(sysconfdir)|"
-e "s|@bindir[@]|$(bindir)|g" \
-e "s|@datadir[@]|$(datadir)|g" \
-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" \
-e "s|@sysconfdir[@]|$(sysconfdir)|g" \
-e "s|@GJS_CONSOLE[@]|$(GJS_CONSOLE)|g"
gnome-shell-jhbuild: gnome-shell-jhbuild.in gnome-shell-real Makefile
$(AM_V_GEN) sed $(generated_script_substitutions) $< > $@.tmp && mv $@.tmp $@ && chmod a+x $@
@ -66,6 +68,9 @@ gnome-shell-jhbuild: gnome-shell-jhbuild.in gnome-shell-real Makefile
gnome-shell-extension-tool: gnome-shell-extension-tool.in Makefile
$(AM_V_GEN) sed $(generated_script_substitutions) $< > $@.tmp && mv $@.tmp $@ && chmod a+x $@
gnome-shell-extension-prefs: gnome-shell-extension-prefs.in Makefile
$(AM_V_GEN) sed $(generated_script_substitutions) $< > $@.tmp && mv $@.tmp $@ && chmod a+x $@
CLEANFILES += gnome-shell $(bin_SCRIPTS)
include Makefile-st.am
@ -76,6 +81,7 @@ include Makefile-hotplug-sniffer.am
gnome_shell_cflags = \
$(GNOME_SHELL_CFLAGS) \
$(SYSTEMD_CFLAGS) \
-I$(srcdir)/tray \
-DVERSION=\"$(VERSION)\" \
-DLOCALEDIR=\"$(datadir)/locale\" \
@ -86,23 +92,19 @@ gnome_shell_cflags = \
-DJSDIR=\"$(pkgdatadir)/js\"
privlibdir = $(pkglibdir)
privlib_LTLIBRARIES = libgnome-shell.la
privlib_LTLIBRARIES = libgnome-shell.la libgnome-shell-js.la
shell_built_sources = \
shell-marshal.h \
shell-marshal.c \
shell-enum-types.h \
shell-enum-types.c
BUILT_SOURCES += $(shell_built_sources)
EXTRA_DIST += shell-marshal.list
shell_public_headers_h = \
shell-app.h \
shell-app-system.h \
shell-app-usage.h \
shell-contact-system.h \
shell-doc-system.h \
shell-embedded-window.h \
shell-generic-container.h \
shell-gtk-embed.h \
@ -111,6 +113,8 @@ shell_public_headers_h = \
shell-mount-operation.h \
shell-network-agent.h \
shell-perf-log.h \
shell-screenshot.h \
shell-screen-grabber.h \
shell-slicer.h \
shell-stack.h \
shell-tp-client.h \
@ -147,7 +151,6 @@ libgnome_shell_la_SOURCES = \
shell-app-system.c \
shell-app-usage.c \
shell-contact-system.c \
shell-doc-system.c \
shell-embedded-window.c \
shell-generic-container.c \
shell-gtk-embed.c \
@ -158,6 +161,8 @@ libgnome_shell_la_SOURCES = \
shell-perf-log.c \
shell-polkit-authentication-agent.h \
shell-polkit-authentication-agent.c \
shell-screenshot.c \
shell-screen-grabber.c \
shell-slicer.c \
shell-stack.c \
shell-tp-client.c \
@ -183,6 +188,23 @@ EXTRA_DIST += test-gapplication.js
########################################
libgnome_shell_js_la_SOURCES = \
shell-js.h \
shell-js.c \
$(NULL)
libgnome_shell_js_la_LIBADD = \
$(GNOME_SHELL_JS_LIBS) \
$(NULL)
libgnome_shell_js_la_LDFLAGS = \
-avoid-version
libgnome_shell_js_la_CPPFLAGS = \
$(GNOME_SHELL_JS_CFLAGS)
########################################
shell_recorder_sources = \
shell-recorder.c \
shell-recorder.h
@ -206,6 +228,8 @@ test_recorder_LDADD = $(TEST_SHELL_RECORDER_LIBS)
test_recorder_SOURCES = \
$(shell_recorder_sources) $(shell_recorder_private_sources) \
shell-screen-grabber.c \
shell-screen-grabber.h \
test-recorder.c
endif BUILD_RECORDER
@ -230,28 +254,6 @@ run_js_test_SOURCES = \
########################################
shell-marshal.h: stamp-shell-marshal.h
@true
stamp-shell-marshal.h: Makefile shell-marshal.list
$(AM_V_GEN) $(GLIB_GENMARSHAL) \
--prefix=_shell_marshal \
--header \
$(srcdir)/shell-marshal.list > xgen-smh && \
(cmp -s xgen-smh shell-marshal.h || cp -f xgen-smh shell-marshal.h) && \
rm -f xgen-smh && \
echo timestamp > $(@F)
CLEANFILES += stamp-shell-marshal.h
shell-marshal.c: Makefile shell-marshal.list
$(AM_V_GEN) (echo "#include \"shell-marshal.h\"" ; \
$(GLIB_GENMARSHAL) \
--prefix=_shell_marshal \
--body \
$(srcdir)/shell-marshal.list ) > xgen-smc && \
cp -f xgen-smc shell-marshal.c && \
rm -f xgen-smc
shell-enum-types.h: stamp-shell-enum-types.h Makefile
@true
stamp-shell-enum-types.h: $(srcdir)/shell-enum-types.h.in $(shell_public_headers_h)
@ -278,6 +280,7 @@ libgnome_shell_la_LDFLAGS = -avoid-version
libgnome_shell_la_LIBADD = \
-lm \
$(GNOME_SHELL_LIBS) \
$(SYSTEMD_LIBS) \
$(BLUETOOTH_LIBS) \
libst-1.0.la \
libtray.la \
@ -296,6 +299,13 @@ Shell_0_1_gir_SCANNERFLAGS = --include-uninstalled=$(builddir)/St-1.0.gir \
INTROSPECTION_GIRS += Shell-0.1.gir
CLEANFILES += Shell-0.1.gir
ShellJS-0.1.gir: libgnome-shell-js.la
ShellJS_0_1_gir_CFLAGS = $(libgnome_shell_la_CPPFLAGS) -I $(srcdir)
ShellJS_0_1_gir_LIBS = libgnome-shell-js.la
ShellJS_0_1_gir_FILES = $(libgnome_shell_js_la_SOURCES)
INTROSPECTION_GIRS += ShellJS-0.1.gir
CLEANFILES += ShellJS-0.1.gir
St-1.0.gir: libst-1.0.la
St_1_0_gir_INCLUDES = Clutter-1.0 Gtk-3.0
St_1_0_gir_CFLAGS = $(st_cflags) -DST_COMPILATION

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