Compare commits

...

96 Commits

Author SHA1 Message Date
86bd5b281d Bump version to 3.29.2
Update NEWS.
2018-05-24 18:54:29 +02:00
ad3e9ab205 docs: Clarify where style changes should be done
After the move to Gitlab, the gnome-shell-sass repository is more
exposed than it used to; clarify that it is not the place where
style changes should happen, but rather the corresponding subtree
in the gnome-shell repository.
2018-05-23 19:03:01 +02:00
02bbf409ea docs: Use Markdown
Markdown produces nicer output where supported, so use that instead
of plain ASCII formatting.
2018-05-23 19:03:01 +02:00
f56e4e177e docs: Remove old style HACKING
The information is outdated, the relevant documentation is all in
[the README](data/theme/README) nowadays.
2018-05-23 19:01:10 +02:00
fc26559f2c docs: Remove obsolete files
The canonical maintainership information is tracked in the project's
.doap file as for any other GNOME project, and the empty AUTHORS
file only existed to make autotools happy.
2018-05-23 19:01:10 +02:00
fdaddbd1e0 Improve notification documentation
Ref: https://gitlab.gnome.org/GNOME/gnome-shell/issues/294
2018-05-22 18:39:19 +02:00
04f61567ba Update Chinese (China) translation 2018-05-21 14:27:23 +00:00
a0785cdbc1 Update Swedish translation 2018-05-20 17:28:17 +00:00
94101e8bb8 magnifier.js: Fix zoom juddering
Make Zoom respond to the mouse silky-smoothly.

It was previously hard-coded to: 1000/50 = 20 FPS.

https://bugzilla.gnome.org/show_bug.cgi?id=682013
https://launchpad.net/bugs/1691675
2018-05-17 11:42:20 +08:00
f13dbf2f26 Update Galician translation 2018-05-15 22:36:45 +00:00
bae6f06e4e Update Galician translation 2018-05-15 21:58:21 +00:00
d8b9e23502 network: Update the icon in the panel whenever NM's state changes
Similar to what it's done when the main connection changes, we need
to make sure that the icon in the panel gets updated before calling
_syncConnectivity(), so that the icon gets always updated if needed,
regardless of whether there's an active connection or not.

This is needed because there's at least one case when an icon should
be shown when the computer is not connected to any network: when a
hotspot has been enabled, which can be useful even if there's not
an internet connection to share (e.g. to easily allow connecting
other devices to the computer.

Closes: https://gitlab.gnome.org/GNOME/gnome-shell/issues/214
2018-05-15 09:15:43 +01:00
7d59eaa67e Update Indonesian translation 2018-05-12 03:59:42 +00:00
c0a453f64f networkAgent: Fix fallout from libnm port
While the libnm-glib version of the function returns a GByteArray*
that gjs can directly cast to the required gutf8*, the libnm function
returns GBytes* from which we need to explicitly fetch the data.

https://gitlab.gnome.org/GNOME/gnome-shell/issues/136
2018-05-09 16:19:58 +02:00
5336175736 osdWindow: Fix blurriness at certain resolutions
The y position wasn't rounded, leading to some blurriness at vertical
resolutions that aren't a multiple of 4 (e.g. 1050).

https://bugzilla.gnome.org/show_bug.cgi?id=782011
2018-05-08 21:04:02 +02:00
2997e4950b keyboardManager: take group index into account when preserving keymap
commit 642107a2 attempts to avoid resetting the current keymap on
spurious input source changes.

It does this by checking if the current layout id is found in
the new list of layouts and resetting the current layout to the
associated match in the list. By not nullifying the current
layout, it won't get subsequently reset.

Unfortunately, if the order of the list changes, resetting the
current keymap is still necessary, since the order corresponds
with the index of the activated group.

This commit changes the code to nullify the current layout if
its group index changes.

https://bugzilla.redhat.com/show_bug.cgi?id=1573923
2018-05-08 17:54:37 +00:00
a49fb90d86 build: Include Cally in St introspection
CallyActor is exposed indirectly via StAccessible's parent type,
so add the dependency to shut up a gjs warning.

https://bugzilla.gnome.org/show_bug.cgi?id=781471
2018-05-07 21:10:40 +00:00
ffc0eb1de2 remoteSearch: Actually return icons
Since commit 3b1330880f, a remote search result's createIcon() method
no longer returns the created icon, whoops ...

https://gitlab.gnome.org/GNOME/gnome-shell/issues/249
2018-05-03 08:22:58 +00:00
853c81eb62 Update Brazilian Portuguese translation
(cherry picked from commit e909db5848)
2018-05-02 18:47:03 +00:00
594cc7cbef workspaceThumbnails: Avoid access to undefined variables
If thumbnails haven't been created, they don't need to be destroyed.

https://bugzilla.gnome.org/show_bug.cgi?id=787871
2018-05-02 20:04:42 +02:00
0932324d39 calendar-server: Update views only after the time range is set
The gnome-shell-calendar-server calls to refresh queries even when it
has no time range set, which results in:
  a) waste of resources (for example after login),
  b) many runtime warnings in the journalctl log, related to
     incorrect time range being used.

https://gitlab.gnome.org/GNOME/gnome-shell/issues/244
2018-05-02 16:10:33 +02:00
2d6cf236c4 perf-tool: Fix default value for --extra-filter
While it is theoretically fine to run --perf=hwtest without passing --hwtest,
the test will hang in this case because it fails to start gedit. Always append
Gedit to the default value for --extra-filter when running the "hwtest" test
to make it work fine without --hwtest.
2018-04-29 16:15:16 +00:00
642107a28f keyboardManager: Preserve current keymap across reloads
The IM can pretty much update the input sources anytime (even if
to set the same ones). That ends up triggering rebuilding all user
defined keymaps, and losing modifier state if we are unfortunate
enough that this caught us while pressing one.

One common situation seems to be password entries, resulting in
the wrong character being printed if the first character happens
to require the shift key.

If the current keymap is not found in the newly loaded list,
this._current will end up null, with the same behavior as we get
currently (immediate keymap reload).

https://bugzilla.redhat.com/show_bug.cgi?id=1569211

https://gitlab.gnome.org/GNOME/gnome-shell/issues/240

Closes: #240
2018-04-29 17:46:31 +02:00
581b38ecf4 scripting: Fix argument list of createTestWindow()
Commit f285f2c6 changed Scripting.createTestWindow() to accept a parameter
object instead of a parameter list but forgot to remove the width and height
arguments. This breaks the "core" test as all windows are created with default
settings.
2018-04-25 23:47:06 +02:00
fbc03cc262 Bump version to 3.29.1
Update NEWS.
2018-04-25 20:34:05 +02:00
a6ff195893 Updated Spanish translation 2018-04-25 13:16:18 +02:00
f411724064 Updated Czech translation 2018-04-24 17:33:14 +02:00
39f43a4cd4 Update Friulian translation 2018-04-23 19:42:08 +00:00
c82cb918ae network: initialize the agent asynchronously
This also bumps the NM requirement. We actually already use API from
1.0, but regularly hit various NetworkManager bugs with versions prior
to 1.10.2. 1.10.4 fixes the asynchronous agent initialization.

https://bugzilla.gnome.org/show_bug.cgi?id=789811
https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/63
2018-04-23 10:45:20 +02:00
38cdaa6c20 Update Romanian translation 2018-04-22 16:48:18 +00:00
0327069e83 polkitAgent: Guard against repeated close() calls
We use the close() method to disconnect signal handlers set up in
init(), however the handler ID is only valid in the first call in
case the method is called more than once.

https://gitlab.gnome.org/GNOME/gnome-shell/issues/221
2018-04-21 18:42:15 +02:00
7601b029c8 Updated Slovenian translation 2018-04-20 21:59:35 +02:00
fb509dfc25 thunderbolt: sync D-Bus API with bolt changes
bolt 0.3 deprecated all AUTHORIZED_XXX status flags, but added
a CONNECTING one. Also AuthFlags got renamed to AuthCtrl.
2018-04-20 11:36:37 +02:00
874a91968f thunderbolt: remove gdbus error prefix, if present
If we get an error during device enrollment, the message might be
prefixed to indicate that the error came from the remote peer. We
are presenting that message to the user so strip that prefix away
if it was there.
2018-04-20 11:36:37 +02:00
0963ccddba thunderbolt: fix enroll-failed signal args order
The devices emitted (device, error) while the connected handler
was expecting (error, device). The former is more consistent
with the rest of the code (so change it to device, error).
2018-04-20 11:27:11 +02:00
c4e0f6df08 Update Russian translation
(cherry picked from commit 0d031dc20f)
2018-04-19 20:33:21 +00:00
58aafe9520 theme: Improve look of login user-list
* Remove tiny padding of user-list
* Less space between avatar and username
* Apply the 1em padding only to the user-widget, not the timed-login-indicator
2018-04-19 17:26:14 +02:00
a46df7f8ec theme: Use a padding of 6px on the user-list items according to HIG 2018-04-19 17:26:14 +02:00
1dd16618d1 loginDialog: Don't display timed login indicator if unused
This fixes the slightly bigger padding underneath the login item compared to the padding above
2018-04-19 17:26:14 +02:00
a4190f83ac loginDialog: Correct source name for timed login idle timeout
The _blockTimedLoginUntilIdle method sets a timeout to be called after
the user is idle for 5 seconds.  That timeout is erroneously given the
source name "[gnome-shell] this._timedLoginAnimationTime" which looks
like a copy-and-paste mistake.  The original intention was probably to
use a source name of "[gnome-shell] this._timedLoginIdleTimeOutId" which
more closely matches existing convention for source names.

This commit fixes that.
2018-04-19 17:26:14 +02:00
a8e17f73ec loginDialog: Use more function scope variables inside _startTimedLogin
Using function scope variables increases readability and prevents
unwanted changes from outside while the batch is running.
2018-04-19 17:26:13 +02:00
86a741c1ee loginDialog: Make sure timed login indicator is shown after idle timeout
If the idle timeout is done, always show the user list to make sure the
timed login indicator is visible.
2018-04-19 17:25:02 +02:00
5cc6fef689 loginDialog: Restrict grabbing of focus while timed login is running
Make sure the focus isn't grabbed right after user interaction starts a
new timed login. Only grab it after the idle timeout is done and on the
first run instead.
2018-04-19 09:08:45 +02:00
522a5fe480 loginDialog: Ensure old timed login timeout is removed before starting a new one
Normally, we give the user a 5 second grace period of inactivity before
starting a timed login operation. Unfortunately, that grace period
timeout isn't properly removed if the timed login operation is restarted
during the grace period. That means the timeout handler can
inadvertently get called multiple times leading to the grace period
duration getting subtracted from the total animation time more than
once.

This commit ensures we only ever have one grace period timeout scheduled
at a time.
2018-04-19 09:08:45 +02:00
b1239b1257 loginDialog: Use GLib instead of Mainloop for timeout
imports.mainloop is deprecated
2018-04-19 09:08:45 +02:00
58063d9ee1 loginDialog: Move reset of timed login into _startTimedLogin
This way we can make sure that already running timed logins are
always reset when starting a new one.
2018-04-19 09:08:45 +02:00
d7aba2dece loginDialog: Ensure timed login indicator is hidden on key presses
The timed login feature currently cancels the timed login operation when
a user presses a key but, oddly, only hides the indicator when the user
releases the key. This means that if a user holds down a key that
doesn't key repeat, the timed login indicator will continue to run after
the timed login operation is cancelled.

This commit address the problem by ensuring the timed login indicator is
hidden on any key press event, at the same time the timed login
operation is canceled.
2018-04-19 09:08:45 +02:00
35fced27df ibusCandidatePopup: Fix candidate-clicked signal 2018-04-18 13:37:53 +09:00
be76b19300 st-entry: Set text-related CSS properties on the internal ClutterText
Call _st_set_text_from_style() when updating the entry's style, so
that CSS style properties such as text-decoration or letter-spacing
are applied over the internal ClutterText instance.
2018-04-18 00:14:05 +00:00
376d696b8b st-private: Add support for letter-spacing in ClutterText based StWidgets
Add support in _st_set_text_from_style(), so that this CSS property can
be used from any StWidget holding an internal ClutterText.
2018-04-18 00:14:05 +00:00
695d61968d st-theme-node: Add new getter st_theme_node_get_letter_spacing
This will be used by ClutterText-backed StWidgets to update their
list of PangoAttributes according to the letter-spacing property.
2018-04-18 00:14:04 +00:00
d6d09fd3c8 ui: Theme lookup should respect XDG_DATA_DIRS
Modes, extensions and other GNOME Shell assets are searched in appropriate
subdirectories of each directory in XDG_DATA_DIRS, falling back
to global.datadir.
However, this isn't the case for themes, which are currently always expected
in global.datadir, even when referenced by a mode in a different XDG_DATA_DIR.

The fix is to have the theme finding pattern follow the same logic as other
elements.
Fixes #167.
2018-04-16 19:09:14 +02:00
f1b1501f9b Update Croatian translation 2018-04-16 12:31:09 +00:00
cdbc99e992 popupMenu: Fix wrong call to clutter_actor_add_child()
Specify the horizontal alignment via the x_align property when creating
the StIcon, since this function expects one argument, not two.
2018-04-16 11:40:04 +00:00
69afe7785d remoteMenu: Support icons in app-menu
The HIG discourages the use of icons in menus except for "noun" items
(files, bookmarks, ...). While those should be rarely used in the
application menu, it still makes sense to support them in the few
cases where they are used.

https://bugzilla.gnome.org/show_bug.cgi?id=760985
2018-04-14 09:02:20 +00:00
b99e304f1e workspaceThumbnail: initialize porthole based on workArea
https://bugzilla.gnome.org/show_bug.cgi?id=792687
2018-04-13 16:59:51 -05:00
c29bd46e7a workspaceThumbnail: rebuild thumbnails if workareas size changed
https://bugzilla.gnome.org/show_bug.cgi?id=792687
2018-04-13 16:58:28 -05:00
5fcf40b973 workspaceThumbnail: only update _porthole if the overview is visible
Otherwise it happens that porthole is computed again after that the
overlay is hidden (triggered by a layout reallocation) and thus not
regenerated again afterwards.

https://bugzilla.gnome.org/show_bug.cgi?id=792687
2018-04-13 16:53:18 -05:00
a198dfe3d8 thunderbolt: capitalize Thunderbolt in a translatable string 2018-04-13 21:52:32 +02:00
5b10d157fe Bump version to 3.28.1
Update NEWS.
2018-04-13 20:18:05 +02:00
5cc42b18b0 utils: Simplify URL regex to only support one layer of parentheses
The author of the original URL-matching regex warns[0] that the pattern may
cause certain regex engines to lock up with certain input, namely patterns
that contain parentheses. It turns out SpiderMonkey is affected, but rather
than switching to the author's improved version (that is still crazy), sim-
plify the pattern a bit by removing support for nested parentheses in URLs.
Even a single pair of parentheses is extremely rare, so this is unlikely to
make a noticeable difference (other than not locking up SpiderMonkey of
course) ...

[0] http://daringfireball.net/2010/07/improved_regex_for_matching_urls
2018-04-13 18:15:44 +00:00
cb4252e888 polkitAgent: Hide authentication dialogs while locked
Since commit 78a92fb6be we no longer pop up authentication dialogs
on the lock screen, however any dialog that is already open at that
time remains open. This is unexpected, so hide the dialog until
the screen is unlocked again.

https://gitlab.gnome.org/GNOME/gnome-shell/issues/166
2018-04-13 19:35:31 +02:00
09d3cdb023 workspace: Don't move focus unconditionally
Since commit 1939e22c22, we move the keyboard focus with the hover
highlight. However while this makes sense when interacting with
the window picker, it interferes with keyboard navigation of other
components like dash or top bar. Address this by only moving the
focus when the previous focus was already inside the window picker
or unset.

https://gitlab.gnome.org/GNOME/gnome-shell/issues/50
2018-04-13 14:13:35 +00:00
71515a8a11 networkAgent: Use libnm for plugin loading
After the networking code has been ported to libnm, we can use its
API for loading VPN plugins instead of rolling our own ...

https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/39
2018-04-13 14:04:55 +00:00
11ca8dd54f worldClock: Handle named timezones
The original UTC support in GWeather piggy-backed on the existing API, but
as "country" or "city" don't make sense in the context of UTC or AoE, the
concept of "named timezones" was introduced. Handle those explicitly to get
back labels for those locations.

https://gitlab.gnome.org/GNOME/gnome-shell/issues/150
2018-04-13 09:15:48 +00:00
e00f22ebe6 overview: Use monotonic time to check for consecutive activations
We don't toggle the overview if the request happens too close to the
last activation, to filter out double-clicks or activation by both
the hot corner and a click. However as the check is based on the
real time, the check breaks if the system clock moves backwards and
the last activations appears to be in the future. Fix this by using
monotonic time which is guaranteed to only move forward.

https://bugzilla.gnome.org/show_bug.cgi?id=763886
2018-04-13 09:13:45 +00:00
13390543b0 Update Russian translation 2018-04-12 13:58:31 +00:00
de95ced92c Update Russian translation 2018-04-12 11:47:00 +00:00
f6a08472a0 st: Do not force allocation updates during shadow creation
If an actor is pending a relayout when get_allocation_box() is called,
the method forces an allocation update. In case of StWidget, this might
then result in a style update and a consecutive invalidation of the
shadow spec.

A helper method that invalidates one of its parameters as a side effect
(and by extension its return value as well) is most unexpected, so cur-
rently _st_create_shadow_pipeline_from_actor() poses an easy trap to
callers to run into.

Remove that trap by calling get_size()/get_position() instead, which
don't have the unintended side effect - it is still a good idea to fix
callers who were running into this to not waste resources on creating
shadows that are invalidated before the next paint, but throwing un-
defined behavior at them is harsh ...

https://bugzilla.gnome.org/show_bug.cgi?id=788908
2018-04-11 19:29:25 +00:00
9f7b101437 appFavorites: Add evolution to rename list
Evolution 3.28 changed the desktop filename. Without this patch,
evolution will disappear from the dock.
2018-04-10 14:38:26 +00:00
9c0707d4dc build: Run postinstall script where necessary
Package managers usually take care of compiling GSettings schemas and
updating the .desktop database on installation, but when building
manually from source, we should perform the aforementioned actions
ourselves.

https://gitlab.gnome.org/GNOME/gnome-shell/issues/127
2018-04-09 19:19:33 +00:00
78a92fb6be polkitAgent: Queue authentication requests while locked
While polkit requests *should* be the result of a user action, that's
not always the case in practice and authentication dialogs can pop up
out of nowhere at any time. That's always annoying, but particularly
bad on the lock screen. If we disabled the polkit component altogether,
the fallback GTK-based agent would kick in, so instead handle the case
explicitly and postpone showing the dialog until the session is unlocked.

https://gitlab.gnome.org/GNOME/gnome-shell/issues/179
2018-04-06 20:08:29 +02:00
01509cf1a5 appFavorites: Rename gnome-tweaks.desktop 2018-04-05 22:06:15 -04:00
61e9f51274 system: Align submenu labels with parent - adjust for deeper hierarchies
Adjust the previous commit which applied the alignment to :first-child
descendants, instead of only immediate children. This fixes alignment
issues for a number of Shell extensions by making it easier to override
with a .popup-menu-item style-subclass.
2018-04-02 14:54:43 -07:00
201bd9d42e Update French translation 2018-03-27 12:26:10 +00:00
8a78f08f6c Update Arabic translation 2018-03-25 22:22:06 +02:00
a5e54f9712 Update Dutch translation 2018-03-23 09:12:25 +00:00
526834e39b modalDialog: Remove some unused code
No need to figure out an x_alignment variable that hasn't been used
since commit 0722c06275 ...
2018-03-21 16:48:56 +00:00
bdde2476d2 Added Slovenian translation 2018-03-20 22:37:08 +01:00
3171f9debe Update zh_CN translation 2018-03-20 17:03:11 +08:00
0e2aeac5f9 build: Bump required glib version
Required by 723c49a8

Thanks Marcus Lundblad for identifying this issue.
2018-03-19 16:49:47 -04:00
788fb5547c Update Dutch translation 2018-03-18 10:35:18 +00:00
c4d2c0ee64 Update Brazilian Portuguese translation 2018-03-16 22:42:50 +00:00
977686a77a Update Slovak translation 2018-03-16 21:34:03 +00:00
44b29f210c Update Romanian translation 2018-03-15 18:37:20 +00:00
36c7d65ccf inputMethod: Pass all key events through the current IM method
Even though we are using an "xkb" source, it still makes sense to
pass the event through the IBus simple engine, in order to let it
handle compose keys and ctrl+shift+[u|e].

https://gitlab.gnome.org/GNOME/gnome-shell/issues/115

Closes: #115
2018-03-15 16:09:38 +01:00
b81d24fdb4 Update Russian translation 2018-03-14 19:59:53 +00:00
bfdbee8115 shellEntry: Use correct enum for input purpose hints
This was mistakenly left using the GTK+ counterparts. Luckily the enums
are binary compatible, but oops.
2018-03-14 13:30:47 +00:00
4a17c8f4a9 shell-global: Do not deal with allocated strings as const char
The imagedir and userdatadir variables are not fetched from
constants/environment but created with g_strdup*/g_build*. Acknowledge that
and also free the strings in finalize.
2018-03-14 13:30:47 +00:00
d4f67a7d42 Bump version to 3.28.0
Update NEWS.
2018-03-12 12:17:03 +01:00
d5769ae409 Update Hungarian translation 2018-03-12 06:02:34 +00:00
f356b61e5a Update Swedish translation 2018-03-11 20:36:26 +00:00
398768dcbd Update Catalan translation 2018-03-10 21:30:17 +01:00
272d5b6e4a Update Chinese (Taiwan) translation 2018-03-10 12:31:16 +00:00
a479aa2594 Update Croatian translation 2018-03-07 21:47:09 +00:00
f48d620ac5 Update Punjabi translation 2018-03-07 11:57:04 +00:00
70 changed files with 5151 additions and 4074 deletions

View File

View File

@ -1,19 +1,16 @@
Coding guide
============
# Coding guide
Our goal is to have all JavaScript code in GNOME follow a consistent style. In
a dynamic language like JavaScript, it is essential to be rigorous about style
(and unit tests), or you rapidly end up with a spaghetti-code mess.
A quick note
------------
## A quick note
Life isn't fun if you can't break the rules. If a rule seems unnecessarily
restrictive while you're coding, ignore it, and let the patch reviewer decide
what to do.
Indentation and whitespace
--------------------------
## Indentation and whitespace
Use four-space indents. Braces are on the same line as their associated
statements. You should only omit braces if *both* sides of the statement are
@ -22,7 +19,7 @@ on one line.
* One space after the `function` keyword. No space between the function name
* in a declaration or a call. One space before the parens in the `if`
* statements, or `while`, or `for` loops.
```javascript
function foo(a, b) {
let bar;
@ -39,22 +36,20 @@ on one line.
print(20);
}
}
```
Semicolons
----------
## Semicolons
JavaScript allows omitting semicolons at the end of lines, but don't. Always
end statements with a semicolon.
js2-mode
--------
## js2-mode
If using Emacs, do not use js2-mode. It is outdated and hasn't worked for a
while. emacs now has a built-in JavaScript mode, js-mode, based on
espresso-mode. It is the de facto emacs mode for JavaScript.
File naming and creation
------------------------
## File naming and creation
For JavaScript files, use lowerCamelCase-style names, with a `.js` extension.
@ -67,14 +62,13 @@ library name followed by a dash, e.g. `shell-app-system.c`. Create a
`-private.h` header when you want to share code internally in the
library. These headers are not installed, distributed or introspected.
Imports
-------
## Imports
Use UpperCamelCase when importing modules to distinguish them from ordinary
variables, e.g.
```javascript
const GLib = imports.gi.GLib;
```
Imports should be categorized into one of two places. The top-most import block
should contain only "environment imports". These are either modules from
gobject-introspection or modules added by gjs itself.
@ -85,7 +79,7 @@ e.g. `imports.ui.popupMenu`.
Each import block should be sorted alphabetically. Don't import modules you
don't use.
```javascript
const GLib = imports.gi.GLib;
const Gio = imports.gi.Gio;
const Lang = imports.lang;
@ -95,23 +89,22 @@ don't use.
const Params = imports.misc.params;
const Tweener = imports.ui.tweener;
const Util = imports.misc.util;
```
The alphabetical ordering should be done independently of the location of the
location. Never reference `imports` in actual code.
Constants
---------
## Constants
We use CONSTANTS_CASE to define constants. All constants should be directly
under the imports:
```javascript
const MY_DBUS_INTERFACE = 'org.my.Interface';
```
Variable declaration
--------------------
## Variable declaration
Always use either `const` or `let` when defining a variable.
```javascript
// Iterating over an array
for (let i = 0; i < arr.length; ++i) {
let item = arr[i];
@ -121,17 +114,17 @@ Always use either `const` or `let` when defining a variable.
for (let prop in someobj) {
...
}
```
If you use "var" then the variable is added to function scope, not block scope.
See [What's new in JavaScript 1.7](https://developer.mozilla.org/en/JavaScript/New_in_JavaScript/1.7#Block_scope_with_let_%28Merge_into_let_Statement%29)
Classes
-------
## Classes
There are many approaches to classes in JavaScript. We use our own class framework
(sigh), which is built in gjs. The advantage is that it supports inheriting from
GObjects, although this feature isn't used very often in the Shell itself.
```javascript
var IconLabelMenuItem = new Lang.Class({
Name: 'IconLabelMenuItem',
Extends: PopupMenu.PopupMenuBaseItem,
@ -146,6 +139,7 @@ GObjects, although this feature isn't used very often in the Shell itself.
log("menu opened!");
}
});
```
* 'Name' is required. 'Extends' is optional. If you leave it out, you will
automatically inherit from Object.
@ -162,13 +156,12 @@ GObjects, although this feature isn't used very often in the Shell itself.
still a giant function call, even though it may resemble a more
conventional syntax.
GObject Introspection
---------------------
## GObject Introspection
GObject Introspection is a powerful feature that allows us to have native
bindings for almost any library built around GObject. If a library requires
you to inherit from a type to use it, you can do so:
```javascript
var MyClutterActor = new Lang.Class({
Name: 'MyClutterActor',
Extends: Clutter.Actor,
@ -188,9 +181,9 @@ you to inherit from a type to use it, you can do so:
alloc.x2, alloc.y2);
}
});
```
Translatable strings, `environment.js`
--------------------------------------
## Translatable strings, `environment.js`
We use gettext to translate the GNOME Shell into all the languages that GNOME
supports. The `gettext` function is aliased globally as `_`, you do not need to
@ -204,8 +197,7 @@ and "double quotes" for strings that the user may see. This allows us to
quickly find untranslated or mistranslated strings by grepping through the
sources for double quotes without a gettext call around them.
`actor` and `_delegate`
-----------------------
## `actor` and `_delegate`
gjs allows us to set so-called "expando properties" on introspected objects,
allowing us to treat them like any other. Because the Shell was built before
@ -214,7 +206,7 @@ that has a property called `actor`. We call this wrapper class the "delegate".
We sometimes use expando properties to set a property called `_delegate` on
the actor itself:
```javascript
var MyClass = new Lang.Class({
Name: 'MyClass',
@ -229,6 +221,7 @@ the actor itself:
actor.set_label("You clicked the button!");
}
});
```
The 'delegate' property is important for anything which trying to get the
delegate object from an associated actor. For instance, the drag and drop
@ -236,16 +229,14 @@ system calls the `handleDragOver` function on the delegate of a "drop target"
when the user drags an item over it. If you do not set the `_delegate`
property, your actor will not be able to be dropped onto.
Functional style
----------------
## Functional style
JavaScript Array objects offer a lot of common functional programming
capabilities such as forEach, map, filter and so on. You can use these when
they make sense, but please don't have a spaghetti mess of function programming
messed in a procedural style. Use your best judgment.
Closures
--------
## Closures
`this` will not be captured in a closure, it is relative to how the closure is
invoked, not to the value of this where the closure is created, because "this"
@ -254,15 +245,16 @@ variable that can be captured in closures.
All closures should be wrapped with Function.prototype.bind or use arrow
notation.
```javascript
const Lang = imports.lang;
let closure1 = () => { this._fnorbate(); };
let closure2 = this._fnorbate.bind(this);
```
A more realistic example would be connecting to a signal on a method of a
prototype:
```javascript
const Lang = imports.lang;
const FnorbLib = imports.fborbLib;
@ -276,19 +268,21 @@ prototype:
this._updateFnorb();
}
});
```
Object literal syntax
---------------------
## Object literal syntax
In JavaScript, these are equivalent:
```javascript
foo = { 'bar': 42 };
foo = { bar: 42 };
```
and so are these:
```javascript
var b = foo['bar'];
var b = foo.bar;
```
If your usage of an object is like an object, then you're defining "member
variables." For member variables, use the no-quotes no-brackets syntax: `{ bar:
@ -298,14 +292,13 @@ If your usage of an object is like a hash table (and thus conceptually the keys
can have special chars in them), don't use quotes, but use brackets: `{ bar: 42
}`, `foo['bar']`.
Getters, setters, and Tweener
-----------------------------
## Getters, setters, and Tweener
Getters and setters should be used when you are dealing with an API that is
designed around setting properties, like Tweener. If you want to animate an
arbitrary property, create a getter and setter, and use Tweener to animate the
property.
```javascript
var ANIMATION_TIME = 2000;
var MyClass = new Lang.Class({
@ -331,3 +324,4 @@ property.
{ position: 100,
time: ANIMATION_TIME,
transition: 'easeOutQuad' });
```

View File

@ -1,7 +0,0 @@
Owen Taylor
E-mail: otaylor@redhat.com
Userid: otaylor
Colin Walters
E-mail: walters@verbum.org
Userid: walters

56
NEWS
View File

@ -1,3 +1,59 @@
3.29.2
======
* Guard against untimely keyboard map changes [Carlos; #240]
* Fix icons in search provider results [Florian; #249]
* Fix blurriness of OSD under some resolutions [Silvère; #782011]
* Fix lagging pointer when zoomed [Daniel; #682013]
* Misc. bug fixes [Milan, Xiaoguang, Florian, Mario, Ole; #244, #787871,
#781471, #136, #214, #294]
Contributors:
Ole Jørgen Brønner, Milan Crha, Carlos Garnacho, Yussuf Khalil,
Silvère Latchurié, Florian Müllner, Mario Sanchez Prada, Ray Strode,
Daniel van Vugt, Xiaoguang Wang
Translators:
Rafael Fontenelle [pt_BR], Kukuh Syafaat [id], Marcos Lans [gl],
Anders Jonsson [sv], Mingcong Bai [zh_CN]
3.29.1
======
* Support icons in app-menu [Florian; #760985]
* Misc. bug fixes [Marco, Florian, Lubomir; #792687, #221, !63]
Contributors:
Piotr Drąg, Takao Fujiwara, Christian Kellner, Florian Müllner,
Mario Sanchez Prada, Lubomir Rintel, Didier Roche, Marco Trevisan (Treviño),
verdre
Translators:
gogo [hr], Stas Solovey [ru], Matej Urbančič [sl], Daniel Șerbănescu [ro],
Fabio Tomat [fur], Marek Cernocky [cs], Daniel Mustieles [es]
3.28.1
======
* Fix compose characters in shell entries [Carlos; #115]
* Don't show authentication dialogs on lock screen [Florian; #179, #166]
* Fix handling of UTC timezone in world clock [Florian; #150]
* Fix keyboard navigation in overview when hovering windows [Florian; #50]
* Misc. bug fixes [Florian; #127, #788908, #763886, !39]
Contributors:
Jeremy Bicha, Carlos Garnacho, Andy Holmes, Florian Müllner, Bastien Nocera
Translators:
Stas Solovey [ru], Daniel Șerbănescu [ro], Dušan Kazik [sk],
Rafael Fontenelle [pt_BR], Nathan Follens [nl], Dz Chen [zh_CN],
Matej Urbančič [sl], Hannie Dumoleyn [nl], Khaled Hosny [ar],
Guillaume Bernard [fr]
3.28.0
======
Translators:
A S Alam [pa], gogo [hr], Chao-Hsiung Liao [zh_TW], Jordi Mas [ca],
Anders Jonsson [sv], Balázs Úr [hu]
3.27.92
=======
* Misc. bug fixes [Florian; #64, #66, #72]

View File

@ -1,3 +1,4 @@
# GNOME Shell
GNOME Shell provides core user interface functions for the GNOME 3 desktop,
like switching to windows and launching applications. GNOME Shell takes
advantage of the capabilities of modern graphics hardware and introduces
@ -6,15 +7,14 @@ easy to use experience.
For more information about GNOME Shell, including instructions on how
to build GNOME Shell from source and how to get involved with the project,
see:
see the [project wiki][wiki]
https://wiki.gnome.org/Projects/GnomeShell
Bugs should be reported to the GNOME [bug tracking system][bug-tracker].
Bugs should be reported at http://bugzilla.gnome.org against the 'gnome-shell'
product.
License
=======
## License
GNOME Shell is distributed under the terms of the GNU General Public License,
version 2 or later. See the COPYING file for details.
version 2 or later. See the [COPYING][license] file for details.
[project-wiki]: https://wiki.gnome.org/Projects/GnomeShell
[bug-tracker]: https://gitlab.gnome.org/GNOME/gnome-shell/issues
[license]: COPYING

View File

@ -4,14 +4,14 @@ the extensions repository to provide good integration, letting the website
know which extensions are enabled and disabled, and allowing the website to
enable, disable and install them.
Bugs should be reported at http://bugzilla.gnome.org against the 'gnome-shell'
product.
Bugs should be reported to the GNOME [bug tracking system][bug-tracker].
License
=======
## License
The GNOME Shell Browser Plugin, like GNOME Shell itself is distributed under
the GNU General Public License, version 2 or later. The plugin also contains
header files from the "NPAPI SDK" project, tri-licensed under MPL 1.1, GPL 2.0
and LGPL 2.1. These headers are third-party sources and can be retrieved from:
http://code.google.com/p/npapi-sdk/
[bug-tracker]: https://gitlab.gnome.org/GNOME/gnome-shell/issues

View File

@ -1,3 +0,0 @@
To generate the css files, from the project directory:
sass --sourcemap=none --update .

View File

@ -1,31 +0,0 @@
Summary
-------
* Do not edit the CSS directly, edit the source SCSS files and the CSS files will be generated
automatically when building with meson + ninja and left inside the build directory to be
incorporated into the gresource XML (you'll need to have sassc installed).
How to tweak the theme
----------------------
Adwaita is a complex theme, so to keep it maintainable it's written and processed in SASS, the
generated CSS is then transformed into a gresource file during gtk build and used at runtime in a
non-legible or editable form.
It is very likely your change will happen in the _common.scss file. That's where all the widget
selectors are defined. Here's a rundown of the "supporting" stylesheets, that are unlikely to be the
right place for a drive by stylesheet fix:
_colors.scss - global color definitions. We keep the number of defined colors to a necessary minimum,
most colors are derived from a handful of basics. It is an exact copy of the gtk+
counterpart. Light theme is used for the classic theme and dark is for GNOME3 shell
default.
_drawing.scss - drawing helper mixings/functions to allow easier definition of widget drawing under
specific context. This is why Adwaita isn't 15000 LOC.
_common.scss - actual definitions of style for each widget. This is where you are likely to add/remove
your changes.
You can read about SASS at http://sass-lang.com/documentation/. Once you make your changes to the
_common.scss file, you can run ninja to generate the final CSS files.

32
data/theme/README.md Normal file
View File

@ -0,0 +1,32 @@
## Summary
Do not edit the CSS directly, edit the source SCSS files and the CSS files
will be generated automatically when building with meson + ninja and left
inside the build directory to be incorporated into the gresource XML (you'll
need to have sassc installed).
## How to tweak the theme
Adwaita is a complex theme, so to keep it maintainable it's written and
processed in SASS, the generated CSS is then transformed into a gresource
file during gtk build and used at runtime in a non-legible or editable form.
It is very likely your change will happen in the [_common.scss][common] file.
That's where all the widget selectors are defined. Here's a rundown of
the "supporting" stylesheets, that are unlikely to be the right place
for a drive by stylesheet fix:
| File | Description |
| ------------------------ | ----------------- |
| [_colors.scss][colors] | global color definitions. We keep the number of defined colors to a necessary minimum, most colors are derived from a handful of basics. It is an exact copy of the gtk+ counterpart. Light theme is used for the classic theme and dark is for GNOME3 shell default. |
| [_drawing.scss][drawing] | drawing helper mixings/functions to allow easier definition of widget drawing under specific context. This is why Adwaita isn't 15000 LOC. |
| [_common.scss][common] | actual definitions of style for each widget. This is where you are likely to add/remove your changes. |
You can read about SASS on its [web page][sass-web]. Once you make your
changes to the [_common.scss][common] file, you can run ninja to generate the
final CSS files.
[common]: data/theme/gnome-shell-sass/_common.scss
[colors]: data/theme/gnome-shell-sass/_colors.scss
[drawing]: data/theme/gnome-shell-sass/_drawing.scss
[sass-web]: http://sass-lang.com/documentation/

View File

@ -1,6 +0,0 @@
--- Generating the css file ---
You need sass to generate the css file.
To generate them run from a command line in the project directory:
sass --sourcemap=none --update ./

View File

@ -1,7 +0,0 @@
GNOME Shell Sass is a project intended to allow the sharing of the theme sources in sass between gnome-shell and other projects like gnome-shell-extensions.
License
=======
GNOME Shell Sass is distributed under the terms of the GNU General Public License,
version 2 or later. See the COPYING file for details.

View File

@ -0,0 +1,16 @@
# GNOME Shell Sass
GNOME Shell Sass is a project intended to allow the sharing of the
theme sources in sass between gnome-shell and other projects like
gnome-shell-extensions.
Any changes should be done in the [GNOME Shell subtree][shell-subtree]
and not the stand-alone [gnome-shell-sass repository][sass-repo]. They
will then be synchronized periodically before releases.
## License
GNOME Shell Sass is distributed under the terms of the GNU General Public
License, version 2 or later. See the [COPYING][license] file for details.
[shell-subtree]: https://gitlab.gnome.org/GNOME/gnome-shell/tree/master/data/theme/gnome-shell-sass
[sass-repo]: https://gitlab.gnome.org/GNOME/gnome-shell-sass
[license]: COPYING

View File

@ -1111,7 +1111,7 @@ StScrollBar {
.aggregate-menu {
min-width: 21em;
.popup-menu-icon { padding: 0 4px; }
.popup-sub-menu .popup-menu-item :first-child {
.popup-sub-menu .popup-menu-item > :first-child {
&:ltr { /* 12px spacing + 2*4px padding */
padding-left: 20px; margin-left: 1.09em; }
&:rtl { /* 12px spacing + 2*4px padding */
@ -1788,20 +1788,19 @@ StScrollBar {
.login-dialog-user-list-view { -st-vfade-offset: 1em; }
.login-dialog-user-list {
spacing: 12px;
padding: .2em;
width: 23em;
&:expanded .login-dialog-user-list-item:selected { background-color: $selected_bg_color; color: $selected_fg_color; }
&:expanded .login-dialog-user-list-item:logged-in { border-right: 2px solid $selected_bg_color; }
}
.login-dialog-user-list-item {
border-radius: 5px;
padding: .2em;
padding: 6px;
color: darken($osd_fg_color,30%);
&:ltr { padding-right: 1em; }
&:rtl { padding-left: 1em; }
&:ltr .user-widget { padding-right: 1em; }
&:rtl .user-widget { padding-left: 1em; }
.login-dialog-timed-login-indicator {
height: 2px;
margin: 2px 0 0 0;
margin-top: 6px;
background-color: $osd_fg_color;
}
&:focus .login-dialog-timed-login-indicator { background-color: $selected_fg_color; }
@ -1816,8 +1815,8 @@ StScrollBar {
padding-left: 15px;
}
.user-widget-label {
&:ltr { padding-left: 18px; }
&:rtl { padding-right: 18px; }
&:ltr { padding-left: 14px; }
&:rtl { padding-right: 14px; }
}
.login-dialog-prompt-layout {

View File

@ -25,7 +25,6 @@ const GLib = imports.gi.GLib;
const GObject = imports.gi.GObject;
const Gtk = imports.gi.Gtk;
const Lang = imports.lang;
const Mainloop = imports.mainloop;
const Meta = imports.gi.Meta;
const Pango = imports.gi.Pango;
const Shell = imports.gi.Shell;
@ -86,7 +85,8 @@ var UserListItem = new Lang.Class({
GObject.BindingFlags.SYNC_CREATE);
this._timedLoginIndicator = new St.Bin({ style_class: 'login-dialog-timed-login-indicator',
scale_x: 0 });
scale_x: 0,
visible: false });
layout.add(this._timedLoginIndicator);
this.actor.connect('clicked', this._onClicked.bind(this));
@ -126,6 +126,8 @@ var UserListItem = new Lang.Class({
this.hideTimedLoginIndicator();
this._timedLoginIndicator.visible = true;
let startTime = GLib.get_monotonic_time();
this._timedLoginTimeoutId = GLib.timeout_add (GLib.PRIORITY_DEFAULT, 33,
@ -152,6 +154,8 @@ var UserListItem = new Lang.Class({
GLib.source_remove(this._timedLoginTimeoutId);
this._timedLoginTimeoutId = 0;
}
this._timedLoginIndicator.visible = false;
this._timedLoginIndicator.scale_x = 0.;
}
});
@ -991,59 +995,81 @@ var LoginDialog = new Lang.Class({
return hold;
},
_showTimedLoginAnimation() {
this._timedLoginItem.actor.grab_key_focus();
return this._timedLoginItem.showTimedLoginIndicator(this._timedLoginAnimationTime);
},
_blockTimedLoginUntilIdle() {
// This blocks timed login from starting until a few
// seconds after the user stops interacting with the
// login screen.
//
// We skip this step if the timed login delay is very
// short.
if ((this._timedLoginDelay - _TIMED_LOGIN_IDLE_THRESHOLD) <= 0)
return null;
let hold = new Batch.Hold();
this._timedLoginIdleTimeOutId = Mainloop.timeout_add_seconds(_TIMED_LOGIN_IDLE_THRESHOLD,
this._timedLoginIdleTimeOutId = GLib.timeout_add_seconds(GLib.PRIORITY_DEFAULT, _TIMED_LOGIN_IDLE_THRESHOLD,
() => {
this._timedLoginAnimationTime -= _TIMED_LOGIN_IDLE_THRESHOLD;
this._timedLoginIdleTimeOutId = 0;
hold.release();
return GLib.SOURCE_REMOVE;
});
GLib.Source.set_name_by_id(this._timedLoginIdleTimeOutId, '[gnome-shell] this._timedLoginAnimationTime');
GLib.Source.set_name_by_id(this._timedLoginIdleTimeOutId, '[gnome-shell] this._timedLoginIdleTimeOutId');
return hold;
},
_startTimedLogin(userName, delay) {
this._timedLoginItem = null;
this._timedLoginDelay = delay;
this._timedLoginAnimationTime = delay;
let firstRun = true;
// Cancel execution of old batch
if (this._timedLoginBatch) {
this._timedLoginBatch.cancel();
this._timedLoginBatch = null;
firstRun = false;
}
// Reset previous idle-timeout
if (this._timedLoginIdleTimeOutId) {
GLib.source_remove(this._timedLoginIdleTimeOutId);
this._timedLoginIdleTimeOutId = 0;
}
let loginItem = null;
let animationTime;
let tasks = [() => this._waitForItemForUser(userName),
() => {
this._timedLoginItem = this._userList.getItemFromUserName(userName);
loginItem = this._userList.getItemFromUserName(userName);
// If there is an animation running on the item, reset it.
loginItem.hideTimedLoginIndicator();
},
() => {
// If we're just starting out, start on the right
// item.
// If we're just starting out, start on the right item.
if (!this._userManager.is_loaded) {
this._userList.jumpToItem(this._timedLoginItem);
this._userList.jumpToItem(loginItem);
}
},
this._blockTimedLoginUntilIdle,
() => {
this._userList.scrollToItem(this._timedLoginItem);
// This blocks the timed login animation until a few
// seconds after the user stops interacting with the
// login screen.
// We skip this step if the timed login delay is very short.
if (delay > _TIMED_LOGIN_IDLE_THRESHOLD) {
animationTime = delay - _TIMED_LOGIN_IDLE_THRESHOLD;
return this._blockTimedLoginUntilIdle();
} else {
animationTime = delay;
}
},
this._showTimedLoginAnimation,
() => {
// If idle timeout is done, make sure the timed login indicator is shown
if (delay > _TIMED_LOGIN_IDLE_THRESHOLD &&
this._authPrompt.actor.visible)
this._authPrompt.cancel();
if (delay > _TIMED_LOGIN_IDLE_THRESHOLD || firstRun) {
this._userList.scrollToItem(loginItem);
loginItem.actor.grab_key_focus();
}
},
() => loginItem.showTimedLoginIndicator(animationTime),
() => {
this._timedLoginBatch = null;
@ -1055,37 +1081,17 @@ var LoginDialog = new Lang.Class({
return this._timedLoginBatch.run();
},
_resetTimedLogin() {
if (this._timedLoginBatch) {
this._timedLoginBatch.cancel();
this._timedLoginBatch = null;
}
if (this._timedLoginItem)
this._timedLoginItem.hideTimedLoginIndicator();
let userName = this._timedLoginItem.user.get_user_name();
if (userName)
this._startTimedLogin(userName, this._timedLoginDelay);
},
_onTimedLoginRequested(client, userName, seconds) {
if (this._timedLoginBatch)
return;
this._startTimedLogin(userName, seconds);
// Restart timed login on user interaction
global.stage.connect('captured-event', (actor, event) => {
if (this._timedLoginDelay == undefined)
return Clutter.EVENT_PROPAGATE;
if (event.type() == Clutter.EventType.KEY_PRESS ||
event.type() == Clutter.EventType.BUTTON_PRESS) {
if (this._timedLoginBatch) {
this._timedLoginBatch.cancel();
this._timedLoginBatch = null;
}
} else if (event.type() == Clutter.EventType.KEY_RELEASE ||
event.type() == Clutter.EventType.BUTTON_RELEASE) {
this._resetTimedLogin();
this._startTimedLogin(userName, seconds);
}
return Clutter.EVENT_PROPAGATE;

View File

@ -188,8 +188,7 @@ var InputMethod = new Lang.Class({
vfunc_filter_key_event(event) {
if (!this._context || !this._enabled)
return false;
if (!this._currentSource ||
this._currentSource.type == Keyboard.INPUT_SOURCE_TYPE_XKB)
if (!this._currentSource)
return false;
let state = event.get_state();

View File

@ -89,6 +89,8 @@ var KeyboardManager = new Lang.Class({
},
setUserLayouts(ids) {
let currentId = this._current ? this._current.id : null;
let currentGroupIndex = this._current ? this._current.groupIndex : null;
this._current = null;
this._layoutInfos = {};
@ -115,6 +117,9 @@ var KeyboardManager = new Lang.Class({
info.group = group;
info.groupIndex = groupIndex;
if (currentId == id && currentGroupIndex == groupIndex)
this._current = info;
i += 1;
}
},

View File

@ -17,7 +17,7 @@ const Params = imports.misc.params;
var SCROLL_TIME = 0.1;
// http://daringfireball.net/2010/07/improved_regex_for_matching_urls
const _balancedParens = '\\((?:[^\\s()<>]+|(?:\\(?:[^\\s()<>]+\\)))*\\)';
const _balancedParens = '\\([^\\s()<>]+\\)';
const _leadingJunk = '[\\s`(\\[{\'\\"<\u00AB\u201C\u2018]';
const _notTrailingJunk = '[^\\s`!()\\[\\]{};:\'\\".,<>?\u00AB\u00BB\u201C\u201D\u2018\u2019]';

View File

@ -136,8 +136,7 @@ function run() {
global.frame_finish_timestamp = true;
for (let k = 0; k < 5; k++)
yield Scripting.createTestWindow(640, 480,
{ maximized: true });
yield Scripting.createTestWindow({ maximized: true });
yield Scripting.waitTestWindows();
yield Scripting.sleep(1000);
@ -158,8 +157,7 @@ function run() {
yield Scripting.destroyTestWindows();
Main.overview.hide();
yield Scripting.createTestWindow(640, 480,
{ maximized: true,
yield Scripting.createTestWindow({ maximized: true,
redraws: true});
yield Scripting.waitTestWindows();

View File

@ -13,6 +13,7 @@ const RENAMED_DESKTOP_IDS = {
'dconf-editor.desktop': 'ca.desrt.dconf-editor.desktop',
'empathy.desktop': 'org.gnome.Empathy.desktop',
'epiphany.desktop': 'org.gnome.Epiphany.desktop',
'evolution.desktop': 'org.gnome.Evolution.desktop',
'file-roller.desktop': 'org.gnome.FileRoller.desktop',
'gcalctool.desktop': 'org.gnome.Calculator.desktop',
'geary.desktop': 'org.gnome.Geary.desktop',
@ -34,6 +35,7 @@ const RENAMED_DESKTOP_IDS = {
'gnome-screenshot.desktop': 'org.gnome.Screenshot.desktop',
'gnome-software.desktop': 'org.gnome.Software.desktop',
'gnome-terminal.desktop': 'org.gnome.Terminal.desktop',
'gnome-tweaks.desktop': 'org.gnome.tweaks.desktop',
'gnome-weather.desktop': 'org.gnome.Weather.Application.desktop',
'gnomine.desktop': 'gnome-mines.desktop',
'gnotravex.desktop': 'gnome-tetravex.desktop',

View File

@ -604,12 +604,17 @@ var NetworkAgent = new Lang.Class({
this._native.connect('new-request', this._newRequest.bind(this));
this._native.connect('cancel-request', this._cancelRequest.bind(this));
try {
this._native.init(null);
} catch(e) {
this._native = null;
logError(e, 'error initializing the NetworkManager Agent');
}
this._initialized = false;
this._native.init_async(GLib.PRIORITY_DEFAULT, null, (o, res) => {
try {
this._native.init_finish(res);
this._initialized = true;
} catch(e) {
this._native = null;
logError(e, 'error initializing the NetworkManager Agent');
}
});
},
enable() {
@ -617,7 +622,7 @@ var NetworkAgent = new Lang.Class({
return;
this._native.auto_register = true;
if (!this._native.registered)
if (this._initialized && !this._native.registered)
this._native.register_async(null, null);
},
@ -640,7 +645,7 @@ var NetworkAgent = new Lang.Class({
return;
this._native.auto_register = false;
if (this._native.registered)
if (this._initialized && this._native.registered)
this._native.unregister_async(null, null);
},
@ -655,7 +660,7 @@ var NetworkAgent = new Lang.Class({
switch (connectionType) {
case '802-11-wireless':
let wirelessSetting = connection.get_setting_wireless();
let ssid = NM.utils_ssid_to_utf8(wirelessSetting.get_ssid());
let ssid = NM.utils_ssid_to_utf8(wirelessSetting.get_ssid().get_data());
title = _("Authentication required by wireless network");
body = _("Passwords or encryption keys are required to access the wireless network “%s”.").format(ssid);
break;
@ -765,57 +770,29 @@ var NetworkAgent = new Lang.Class({
this._vpnCacheBuilt = true;
this._vpnBinaries = { };
try {
let fileEnum = this._pluginDir.enumerate_children('standard::name', Gio.FileQueryInfoFlags.NONE, null);
let info;
NM.VpnPluginInfo.list_load().forEach(plugin => {
let service = plugin.get_service();
let fileName = plugin.get_auth_dialog();
let supportsHints = plugin.supports_hints();
let externalUIMode = false;
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(this._pluginDir.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;
let hints = false;
try {
externalUIMode = keyfile.get_boolean('GNOME', 'supports-external-ui-mode');
} catch(e) { } // ignore errors if key does not exist
try {
hints = keyfile.get_boolean('GNOME', 'supports-hints');
} catch(e) { } // ignore errors if key does not exist
let path = binary;
if (!GLib.path_is_absolute(path)) {
path = GLib.build_filenamev([Config.LIBEXECDIR, path]);
}
if (GLib.file_test(path, GLib.FileTest.IS_EXECUTABLE)) {
this._vpnBinaries[service] = { fileName: path, externalUIMode: externalUIMode, supportsHints: hints };
try {
let aliases = keyfile.get_string_list('VPN Connection', 'aliases');
for (let alias of aliases) {
this._vpnBinaries[alias] = { fileName: path, externalUIMode: externalUIMode, supportsHints: hints };
}
} catch(e) { } // ignore errors if key does not exist
} 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, this._pluginDir.get_child(name).get_path()));
continue;
}
let prop = plugin.lookup_property('GNOME', 'supports-external-ui-mode');
if (prop) {
prop = prop.trim().toLowerCase();
externalUIMode = ['true', 'yes', 'on', '1'].includes(prop);
}
} catch(e) {
logError(e, 'error while enumerating VPN auth helpers');
}
if (GLib.file_test(fileName, GLib.FileTest.IS_EXECUTABLE)) {
let binary = { fileName, externalUIMode, supportsHints };
this._vpnBinaries[service] = binary;
plugin.get_aliases().forEach(alias => {
this._vpnBinaries[alias] = binary;
});
} else {
log('VPN plugin at %s is not executable'.format(fileName));
}
});
}
});
var Component = NetworkAgent;

View File

@ -16,6 +16,7 @@ const PolkitAgent = imports.gi.PolkitAgent;
const Animation = imports.ui.animation;
const Components = imports.ui.components;
const Dialog = imports.ui.dialog;
const Main = imports.ui.main;
const ModalDialog = imports.ui.modalDialog;
const ShellEntry = imports.ui.shellEntry;
const UserWidget = imports.ui.userWidget;
@ -39,6 +40,10 @@ var AuthenticationDialog = new Lang.Class({
this.userNames = userNames;
this._wasDismissed = false;
this._sessionUpdatedId = Main.sessionMode.connect('updated', () => {
this._group.visible = !Main.sessionMode.isLocked;
});
let icon = new Gio.ThemedIcon({ name: 'dialog-password-symbolic' });
let title = _("Authentication Required");
@ -193,6 +198,14 @@ var AuthenticationDialog = new Lang.Class({
this._session.initiate();
},
close(timestamp) {
this.parent(timestamp);
if (this._sessionUpdatedId)
Main.sessionMode.disconnect(this._sessionUpdatedId);
this._sessionUpdatedId = 0;
},
_ensureOpen() {
// NOTE: ModalDialog.open() is safe to call if the dialog is
// already open - it just returns true without side-effects
@ -348,6 +361,7 @@ var AuthenticationAgent = new Lang.Class({
this._native = new Shell.PolkitAuthenticationAgent();
this._native.connect('initiate', this._onInitiate.bind(this));
this._native.connect('cancel', this._onCancel.bind(this));
this._sessionUpdatedId = 0;
},
enable() {
@ -367,6 +381,17 @@ var AuthenticationAgent = new Lang.Class({
},
_onInitiate(nativeAgent, actionId, message, iconName, cookie, userNames) {
// Don't pop up a dialog while locked
if (Main.sessionMode.isLocked) {
this._sessionUpdatedId = Main.sessionMode.connect('updated', () => {
Main.sessionMode.disconnect(this._sessionUpdatedId);
this._sessionUpdatedId = 0;
this._onInitiate(nativeAgent, actionId, message, iconName, cookie, userNames);
});
return;
}
this._currentDialog = new AuthenticationDialog(actionId, message, cookie, userNames);
// We actually don't want to open the dialog until we know for
@ -396,6 +421,10 @@ var AuthenticationAgent = new Lang.Class({
this._currentDialog.destroySession();
this._currentDialog = null;
if (this._sessionUpdatedId)
Main.sessionMode.disconnect(this._sessionUpdatedId);
this._sessionUpdatedId = 0;
this._native.complete(dismissed);
},
});

View File

@ -153,8 +153,10 @@ var WorldClocksSection = new Lang.Class({
for (let i = 0; i < this._locations.length; i++) {
let l = this._locations[i].location;
let name = l.get_level() == GWeather.LocationLevel.NAMED_TIMEZONE ? l.get_name()
: l.get_city_name();
let label = new St.Label({ style_class: 'world-clocks-city',
text: l.get_city_name(),
text: name,
x_align: Clutter.ActorAlign.START,
x_expand: true });

View File

@ -166,7 +166,7 @@ var CandidatePopup = new Lang.Class({
this._panelService.cursor_down();
});
this._candidateArea.connect('candidate-clicked', () => {
this._candidateArea.connect('candidate-clicked', (area, index, button, state) => {
this._panelService.candidate_clicked(index, button, state);
});

View File

@ -19,7 +19,6 @@ const MagnifierDBus = imports.ui.magnifierDBus;
const Params = imports.misc.params;
const PointerWatcher = imports.ui.pointerWatcher;
var MOUSE_POLL_FREQUENCY = 50;
var CROSSHAIRS_CLIP_SIZE = [100, 100];
var NO_CHANGE = 0.0;
@ -152,8 +151,10 @@ var Magnifier = new Lang.Class({
* Turn on mouse tracking, if not already doing so.
*/
startTrackingMouse() {
if (!this._pointerWatch)
this._pointerWatch = PointerWatcher.getPointerWatcher().addWatch(MOUSE_POLL_FREQUENCY, this.scrollToMousePos.bind(this));
if (!this._pointerWatch) {
let interval = 1000 / Clutter.get_default_frame_rate();
this._pointerWatch = PointerWatcher.getPointerWatcher().addWatch(interval, this.scrollToMousePos.bind(this));
}
},
/**

View File

@ -256,6 +256,14 @@ function _getStylesheet(name) {
if (stylesheet.query_exists(null))
return stylesheet;
let dataDirs = GLib.get_system_data_dirs();
for (let i = 0; i < dataDirs.length; i++) {
let path = GLib.build_filenamev([dataDirs[i], 'gnome-shell', 'theme', name]);
let stylesheet = Gio.file_new_for_path(path);
if (stylesheet.query_exists(null))
return stylesheet;
}
stylesheet = Gio.File.new_for_path(global.datadir + '/theme/' + name);
if (stylesheet.query_exists(null))
return stylesheet;

View File

@ -27,6 +27,7 @@ function _fixMarkup(text, allowMarkup) {
// Support <b>, <i>, and <u>, escape anything else
// so it displays as raw markup.
// Ref: https://developer.gnome.org/notification-spec/#markup
_text = _text.replace(/<(?!\/?[biu]>)/g, '&lt;');
try {

View File

@ -315,10 +315,10 @@ var NotificationApplicationPolicy = new Lang.Class({
// You can add a secondary icon to the banner with 'secondaryGIcon'. There
// is no fallback for this icon.
//
// If @params contains 'bannerMarkup', with the value %true, then
// the corresponding element is assumed to use pango markup. If the
// parameter is not present for an element, then anything that looks
// like markup in that element will appear literally in the output.
// If @params contains 'bannerMarkup', with the value %true, a subset (<b>,
// <i> and <u>) of the markup in [1] will be interpreted within @banner. If
// the parameter is not present, then anything that looks like markup
// in @banner will appear literally in the output.
//
// If @params contains a 'clear' parameter with the value %true, then
// the content and the action area of the notification will be cleared.
@ -328,6 +328,8 @@ var NotificationApplicationPolicy = new Lang.Class({
// If @params contains 'soundName' or 'soundFile', the corresponding
// event sound is played when the notification is shown (if the policy for
// @source allows playing sounds).
//
// [1] https://developer.gnome.org/notification-spec/#markup
var Notification = new Lang.Class({
Name: 'Notification',

View File

@ -100,21 +100,8 @@ var ModalDialog = new Lang.Class({
setButtons(buttons) {
this.clearButtons();
for (let i = 0; i < buttons.length; i++) {
let buttonInfo = buttons[i];
let x_alignment;
if (buttons.length == 1)
x_alignment = St.Align.END;
else if (i == 0)
x_alignment = St.Align.START;
else if (i == buttons.length - 1)
x_alignment = St.Align.END;
else
x_alignment = St.Align.MIDDLE;
for (let buttonInfo of buttons)
this.addButton(buttonInfo);
}
},
addButton(buttonInfo) {

View File

@ -204,7 +204,7 @@ var OsdWindow = new Lang.Class({
let scaleFactor = St.ThemeContext.get_for_stage(global.stage).scale_factor;
this._icon.icon_size = popupSize / (2 * scaleFactor);
this._box.translation_y = monitor.height / 4;
this._box.translation_y = Math.round(monitor.height / 4);
this._boxConstraint.minSize = popupSize;
}
});

View File

@ -488,7 +488,8 @@ var Overview = new Lang.Class({
return false;
if (this._inItemDrag || this._inWindowDrag)
return false;
if (this._activationTime == 0 || Date.now() / 1000 - this._activationTime > OVERVIEW_ACTIVATION_TIMEOUT)
if (this._activationTime == 0 ||
GLib.get_monotonic_time() / GLib.USEC_PER_SEC - this._activationTime > OVERVIEW_ACTIVATION_TIMEOUT)
return true;
return false;
},
@ -547,7 +548,7 @@ var Overview = new Lang.Class({
this.visible = true;
this.animationInProgress = true;
this.visibleTarget = true;
this._activationTime = Date.now() / 1000;
this._activationTime = GLib.get_monotonic_time() / GLib.USEC_PER_SEC;
Meta.disable_unredirect_for_screen(global.screen);
this.viewSelector.show();

View File

@ -394,8 +394,9 @@ var PopupImageMenuItem = new Lang.Class({
_init(text, icon, params) {
this.parent(params);
this._icon = new St.Icon({ style_class: 'popup-menu-icon' });
this.actor.add_child(this._icon, { align: St.Align.END });
this._icon = new St.Icon({ style_class: 'popup-menu-icon',
x_align: Clutter.ActorAlign.END });
this.actor.add_child(this._icon);
this.label = new St.Label({ text: text });
this.actor.add_child(this.label);
this.actor.label_actor = this.label;

View File

@ -119,6 +119,9 @@ var RemoteMenuItemMapper = new Lang.Class({
this._trackerItem = trackerItem;
this.menuItem = new PopupMenu.PopupBaseMenuItem();
this._icon = new St.Icon({ style_class: 'popup-menu-icon' });
this.menuItem.actor.add_child(this._icon);
this._label = new St.Label();
this.menuItem.actor.add_child(this._label);
this.menuItem.actor.label_actor = this._label;
@ -129,11 +132,13 @@ var RemoteMenuItemMapper = new Lang.Class({
this._trackerItem.bind_property('visible', this.menuItem.actor, 'visible', GObject.BindingFlags.SYNC_CREATE);
this._trackerItem.connect('notify::icon', this._updateIcon.bind(this));
this._trackerItem.connect('notify::label', this._updateLabel.bind(this));
this._trackerItem.connect('notify::sensitive', this._updateSensitivity.bind(this));
this._trackerItem.connect('notify::role', this._updateRole.bind(this));
this._trackerItem.connect('notify::toggled', this._updateDecoration.bind(this));
this._updateIcon();
this._updateLabel();
this._updateSensitivity();
this._updateRole();
@ -143,6 +148,11 @@ var RemoteMenuItemMapper = new Lang.Class({
});
},
_updateIcon() {
this._icon.gicon = this._trackerItem.icon;
this._icon.visible = (this._icon.gicon != null);
},
_updateLabel() {
this._label.text = stripMnemonics(this._trackerItem.label);
},

View File

@ -295,7 +295,7 @@ var RemoteSearchProvider = new Lang.Class({
name: metas[i]['name'],
description: metas[i]['description'],
createIcon: size => {
this.createIcon(size, metas[i]);
return this.createIcon(size, metas[i]);
},
clipboardText: metas[i]['clipboardText'] });
}

View File

@ -133,7 +133,7 @@ function _callRemote(obj, method, ...args) {
* because of the normal X asynchronous mapping process, to actually wait
* until the window has been mapped and exposed, use waitTestWindows().
*/
function createTestWindow(width, height, params) {
function createTestWindow(params) {
params = Params.parse(params, { width: 640,
height: 480,
alpha: false,

View File

@ -55,11 +55,11 @@ var EntryMenu = new Lang.Class({
if (v) {
this._makePasswordItem();
this._entry.input_purpose = Gtk.InputPurpose.PASSWORD;
this._entry.input_purpose = Clutter.InputContentPurpose.PASSWORD;
} else {
this._passwordItem.destroy();
this._passwordItem = null;
this._entry.input_purpose = Gtk.InputPurpose.FREE_FORM;
this._entry.input_purpose = Clutter.InputContentPurpose.NORMAL;
}
},

View File

@ -1944,6 +1944,7 @@ var NMApplet = new Lang.Class({
this.indicators.visible = this._client.nm_running;
this.menu.actor.visible = this._client.networking_enabled;
this._updateIcon();
this._syncConnectivity();
},

View File

@ -56,12 +56,11 @@ const BoltDeviceProxy = Gio.DBusProxy.makeProxyWrapper(BoltDeviceInterface);
var Status = {
DISCONNECTED: 'disconnected',
CONNECTING: 'connecting',
CONNECTED: 'connected',
AUTHORIZING: 'authorizing',
AUTH_ERROR: 'auth-error',
AUTHORIZED: 'authorized',
AUTHORIZED_SECURE: 'authorized-secure',
AUTHORIZED_NEWKEY: 'authorized-newkey'
AUTHORIZED: 'authorized'
};
var Policy = {
@ -70,7 +69,7 @@ var Policy = {
AUTO: 'auto'
};
var AuthFlags = {
var AuthCtrl = {
NONE: 'none',
};
@ -141,9 +140,10 @@ var Client = new Lang.Class({
},
enrollDevice(id, policy, callback) {
this._proxy.EnrollDeviceRemote(id, policy, AuthFlags.NONE,
this._proxy.EnrollDeviceRemote(id, policy, AuthCtrl.NONE,
(res, error) => {
if (error) {
Gio.DBusError.strip_remote_error(error);
callback(null, error);
return;
}
@ -228,7 +228,7 @@ var AuthRobot = new Lang.Class({
_onEnrollDone(device, error) {
if (error)
this.emit('enroll-failed', error, device);
this.emit('enroll-failed', device, error);
/* TODO: scan the list of devices to be authorized for children
* of this device and remove them (and their children and
@ -354,7 +354,7 @@ var Indicator = new Lang.Class({
_onEnrollFailed(obj, device, error) {
const title = _('Thunderbolt authorization error');
const body = _('Could not authorize the thunderbolt device: %s'.format(error.message));
const body = _('Could not authorize the Thunderbolt device: %s'.format(error.message));
this._notify(title, body);
}

View File

@ -660,7 +660,6 @@ var WindowOverlay = new Lang.Class({
if (this._hidden)
return;
this._windowClone.actor.grab_key_focus();
this._animateVisible();
this.emit('show-close-button');
},
@ -1852,7 +1851,12 @@ var Workspace = new Lang.Class({
this.actor.add_actor(clone.actor);
overlay.connect('show-close-button', this._onShowOverlayClose.bind(this));
overlay.connect('show-close-button', () => {
let focus = global.stage.key_focus;
if (focus == null || this.actor.contains(focus))
clone.actor.grab_key_focus();
this._onShowOverlayClose(overlay);
});
if (this._windows.length == 0)
clone.setStackAbove(null);

View File

@ -275,8 +275,8 @@ var WorkspaceThumbnail = new Lang.Class({
this._createBackground();
let monitor = Main.layoutManager.primaryMonitor;
this.setPorthole(monitor.x, monitor.y, monitor.width, monitor.height);
let workArea = Main.layoutManager.getWorkAreaForMonitor(this.monitorIndex);
this.setPorthole(workArea.x, workArea.y, workArea.width, workArea.height);
let windows = global.get_window_actors().filter(actor => {
let win = actor.meta_window;
@ -321,8 +321,6 @@ var WorkspaceThumbnail = new Lang.Class({
},
setPorthole(x, y, width, height) {
this._portholeX = x;
this._portholeY = y;
this.actor.set_size(width, height);
this._contents.set_position(-x, -y);
},
@ -675,11 +673,7 @@ var ThumbnailsBox = new Lang.Class({
this._settings.connect('changed::dynamic-workspaces',
this._updateSwitcherVisibility.bind(this));
Main.layoutManager.connect('monitors-changed', () => {
this._destroyThumbnails();
if (Main.overview.visible)
this._createThumbnails();
});
Main.layoutManager.connect('monitors-changed', this._rebuildThumbnails.bind(this));
},
_updateSwitcherVisibility() {
@ -872,6 +866,9 @@ var ThumbnailsBox = new Lang.Class({
Main.overview.connect('windows-restacked',
this._syncStacking.bind(this));
this._workareasChangedId =
global.screen.connect('workareas-changed', this._rebuildThumbnails.bind(this));
this._targetScale = 0;
this._scale = 0;
this._pendingScaleUpdate = false;
@ -887,6 +884,9 @@ var ThumbnailsBox = new Lang.Class({
},
_destroyThumbnails() {
if (this._thumbnails.length == 0)
return;
if (this._switchWorkspaceNotifyId > 0) {
global.window_manager.disconnect(this._switchWorkspaceNotifyId);
this._switchWorkspaceNotifyId = 0;
@ -901,12 +901,24 @@ var ThumbnailsBox = new Lang.Class({
this._syncStackingId = 0;
}
if (this._workareasChangedId > 0) {
global.screen.disconnect(this._workareasChangedId);
this._workareasChangedId = 0;
}
for (let w = 0; w < this._thumbnails.length; w++)
this._thumbnails[w].destroy();
this._thumbnails = [];
this._porthole = null;
},
_rebuildThumbnails() {
this._destroyThumbnails();
if (Main.overview.visible)
this._createThumbnails();
},
_workspacesChanged() {
let validThumbnails =
this._thumbnails.filter(t => t.state <= ThumbnailState.NORMAL);
@ -1159,7 +1171,7 @@ var ThumbnailsBox = new Lang.Class({
// The "porthole" is the portion of the screen that we show in the
// workspaces
_ensurePorthole() {
if (!Main.layoutManager.primaryMonitor)
if (!Main.layoutManager.primaryMonitor || !Main.overview.visible)
return false;
if (!this._porthole)

View File

@ -1,5 +1,5 @@
project('gnome-shell', 'c',
version: '3.27.92',
version: '3.29.2',
meson_version: '>= 0.42.0',
license: 'GPLv2+'
)
@ -18,12 +18,12 @@ ecal_req = '>= 3.5.3'
eds_req = '>= 3.17.2'
gcr_req = '>= 3.7.5'
gdesktop_req = '>= 3.7.90'
gio_req = '>= 2.53.0'
gio_req = '>= 2.56.0'
gi_req = '>= 1.49.1'
gjs_req = '>= 1.47.0'
gtk_req = '>= 3.15.0'
json_glib_req = '>= 0.13.2'
mutter_req = '>= 3.27.91'
mutter_req = '>= 3.29.2'
polkit_req = '>= 0.100'
schemas_req = '>= 3.21.3'
startup_req = '>= 0.11'
@ -31,7 +31,7 @@ ibus_req = '>= 1.5.2'
bt_req = '>= 3.9.0'
gst_req = '>= 0.11.92'
nm_req = '>= 0.9.8'
nm_req = '>= 1.10.4'
secret_req = '>= 0.18'
gnome = import('gnome')
@ -189,3 +189,5 @@ subdir('tests')
if get_option('gtk_doc')
subdir('docs/reference')
endif
meson.add_install_script('meson/meson-postinstall.sh')

10
meson/meson-postinstall.sh Executable file
View File

@ -0,0 +1,10 @@
#!/bin/sh
# Package managers set this so we don't need to run
if [ -z "$DESTDIR" ]; then
echo Compiling GSettings schemas...
glib-compile-schemas ${MESON_INSTALL_PREFIX}/share/glib-2.0/schemas
echo Updating desktop database...
update-desktop-database -q ${MESON_INSTALL_PREFIX}/share/applications
fi

512
po/ar.po

File diff suppressed because it is too large Load Diff

371
po/ca.po

File diff suppressed because it is too large Load Diff

View File

@ -11,8 +11,8 @@ msgid ""
msgstr ""
"Project-Id-Version: gnome-shell\n"
"Report-Msgid-Bugs-To: https://gitlab.gnome.org/GNOME/gnome-shell/issues\n"
"POT-Creation-Date: 2018-02-26 12:57+0000\n"
"PO-Revision-Date: 2018-02-26 17:57+0100\n"
"POT-Creation-Date: 2018-04-13 19:54+0000\n"
"PO-Revision-Date: 2018-04-24 17:32+0200\n"
"Last-Translator: Marek Černocký <marek@manet.cz>\n"
"Language-Team: čeština <gnome-cs-list@gnome.org>\n"
"Language: cs\n"
@ -332,7 +332,7 @@ msgstr ""
"Nastala chyba při načítání dialogového okna předvoleb pro rozšíření %s:"
#: js/gdm/authPrompt.js:147 js/ui/audioDeviceSelection.js:71
#: js/ui/components/networkAgent.js:117 js/ui/components/polkitAgent.js:148
#: js/ui/components/networkAgent.js:117 js/ui/components/polkitAgent.js:153
#: js/ui/endSessionDialog.js:482 js/ui/extensionDownloader.js:197
#: js/ui/shellMountOperation.js:343 js/ui/status/network.js:919
msgid "Cancel"
@ -667,12 +667,12 @@ msgstr "Přidat mezi oblíbené"
msgid "Show Details"
msgstr "Zobrazit podrobnosti"
#: js/ui/appFavorites.js:138
#: js/ui/appFavorites.js:140
#, javascript-format
msgid "%s has been added to your favorites."
msgstr "%s byl přidán mezi oblíbené."
#: js/ui/appFavorites.js:172
#: js/ui/appFavorites.js:174
#, javascript-format
msgid "%s has been removed from your favorites."
msgstr "%s byl odstraněn z oblíbených."
@ -867,7 +867,7 @@ msgstr "Externí svazek odpojen"
msgid "Open with %s"
msgstr "Otevřít pomocí %s"
#: js/ui/components/keyring.js:107 js/ui/components/polkitAgent.js:284
#: js/ui/components/keyring.js:107 js/ui/components/polkitAgent.js:295
msgid "Password:"
msgstr "Heslo:"
@ -955,15 +955,15 @@ msgstr "Pro připojení k „%s“ je vyžadováno heslo."
msgid "Network Manager"
msgstr "Network Manager"
#: js/ui/components/polkitAgent.js:43
#: js/ui/components/polkitAgent.js:48
msgid "Authentication Required"
msgstr "Je vyžadováno ověření"
#: js/ui/components/polkitAgent.js:71
#: js/ui/components/polkitAgent.js:76
msgid "Administrator"
msgstr "Správce"
#: js/ui/components/polkitAgent.js:151
#: js/ui/components/polkitAgent.js:156
msgid "Authenticate"
msgstr "Ověřit"
@ -971,7 +971,7 @@ msgstr "Ověřit"
#. * requested authentication was not gained; this can happen
#. * because of an authentication error (like invalid password),
#. * for instance.
#: js/ui/components/polkitAgent.js:270 js/ui/shellMountOperation.js:327
#: js/ui/components/polkitAgent.js:281 js/ui/shellMountOperation.js:327
msgid "Sorry, that didnt work. Please try again."
msgstr "Ověření bohužel nebylo úspěšné. Zkuste to prosím znovu."
@ -1021,7 +1021,7 @@ msgstr "Přidat světový čas…"
msgid "World Clocks"
msgstr "Světové hodiny"
#: js/ui/dateMenu.js:225
#: js/ui/dateMenu.js:227
msgid "Weather"
msgstr "Počasí"
@ -1029,7 +1029,7 @@ msgstr "Počasí"
#. libgweather for the possible condition strings. If at all
#. possible, the sentence should match the grammatical case etc. of
#. the inserted conditions.
#: js/ui/dateMenu.js:289
#: js/ui/dateMenu.js:291
#, javascript-format
msgid "%s all day."
msgstr "%s celý den."
@ -1038,7 +1038,7 @@ msgstr "%s celý den."
#. libgweather for the possible condition strings. If at all
#. possible, the sentence should match the grammatical case etc. of
#. the inserted conditions.
#: js/ui/dateMenu.js:295
#: js/ui/dateMenu.js:297
#, javascript-format
msgid "%s, then %s later."
msgstr "%s, později %s."
@ -1047,30 +1047,30 @@ msgstr "%s, později %s."
#. libgweather for the possible condition strings. If at all
#. possible, the sentence should match the grammatical case etc. of
#. the inserted conditions.
#: js/ui/dateMenu.js:301
#: js/ui/dateMenu.js:303
#, javascript-format
msgid "%s, then %s, followed by %s later."
msgstr "%s, pak %s a později %s."
#: js/ui/dateMenu.js:312
#: js/ui/dateMenu.js:314
msgid "Select a location…"
msgstr "Vybrat místo…"
#: js/ui/dateMenu.js:315
#: js/ui/dateMenu.js:317
msgid "Loading…"
msgstr "Načítá se…"
#. Translators: %s is a temperature with unit, e.g. "23℃"
#: js/ui/dateMenu.js:321
#: js/ui/dateMenu.js:323
#, javascript-format
msgid "Feels like %s."
msgstr "Pocitově jako %s."
#: js/ui/dateMenu.js:324
#: js/ui/dateMenu.js:326
msgid "Go online for weather information"
msgstr "Připojit se kvůli informacím o počasí"
#: js/ui/dateMenu.js:326
#: js/ui/dateMenu.js:328
msgid "Weather information is currently unavailable"
msgstr "Informace o počasí nejsou nyní dostupné"
@ -1986,16 +1986,16 @@ msgstr "Uspat do paměti"
msgid "Power Off"
msgstr "Vypnout"
#: js/ui/status/thunderbolt.js:272
#: js/ui/status/thunderbolt.js:294
msgid "Thunderbolt"
msgstr "Thunderbolt"
#. we are done
#: js/ui/status/thunderbolt.js:328
#: js/ui/status/thunderbolt.js:350
msgid "Unknown Thunderbolt device"
msgstr "Neznámé zařízení Thunderbolt"
#: js/ui/status/thunderbolt.js:329
#: js/ui/status/thunderbolt.js:351
msgid ""
"New device has been detected while you were away. Please disconnect and "
"reconnect the device to start using it."
@ -2003,13 +2003,13 @@ msgstr ""
"Zatímco jste byli pryč, bylo nalezeno nové zařízení. Odpojte jej prosím a "
"znovu připojte, abyste jej mohli používat."
#: js/ui/status/thunderbolt.js:334
#: js/ui/status/thunderbolt.js:356
msgid "Thunderbolt authorization error"
msgstr "Chyba ověření Thunderbolt"
#: js/ui/status/thunderbolt.js:335
#: js/ui/status/thunderbolt.js:357
#, javascript-format
msgid "Could not authorize the thunderbolt device: %s"
msgid "Could not authorize the Thunderbolt device: %s"
msgstr "Nezdařilo se provést ověření zařízení Thunderbolt: %s"
#: js/ui/status/volume.js:128
@ -2233,15 +2233,3 @@ msgstr[2] "%u vstupů"
#: subprojects/gvc/gvc-mixer-control.c:2738
msgid "System Sounds"
msgstr "Systémové zvuky"
#~ msgctxt "search-result"
#~ msgid "Power off"
#~ msgstr "Vypnout"
#~ msgctxt "search-result"
#~ msgid "Log out"
#~ msgstr "Odhlásit se"
#~ msgctxt "search-result"
#~ msgid "Switch user"
#~ msgstr "Přepnout uživatele"

View File

@ -9,8 +9,8 @@ msgid ""
msgstr ""
"Project-Id-Version: gnome-shell.master\n"
"Report-Msgid-Bugs-To: https://gitlab.gnome.org/GNOME/gnome-shell/issues\n"
"POT-Creation-Date: 2018-02-22 09:24+0000\n"
"PO-Revision-Date: 2018-02-23 08:26+0100\n"
"POT-Creation-Date: 2018-04-13 19:54+0000\n"
"PO-Revision-Date: 2018-04-25 12:54+0200\n"
"Last-Translator: Daniel Mustieles <daniel.mustieles@gmail.com>\n"
"Language-Team: es <gnome-es-list@gnome.org>\n"
"Language: es\n"
@ -346,7 +346,7 @@ msgid "There was an error loading the preferences dialog for %s:"
msgstr "Hubo un error al lanzar el diálogo de preferencias para %s:"
#: js/gdm/authPrompt.js:147 js/ui/audioDeviceSelection.js:71
#: js/ui/components/networkAgent.js:117 js/ui/components/polkitAgent.js:148
#: js/ui/components/networkAgent.js:117 js/ui/components/polkitAgent.js:153
#: js/ui/endSessionDialog.js:482 js/ui/extensionDownloader.js:197
#: js/ui/shellMountOperation.js:343 js/ui/status/network.js:919
msgid "Cancel"
@ -665,12 +665,12 @@ msgstr "Añadir a los favoritos"
msgid "Show Details"
msgstr "Mostrar detalles"
#: js/ui/appFavorites.js:138
#: js/ui/appFavorites.js:140
#, javascript-format
msgid "%s has been added to your favorites."
msgstr "Se ha añadido %s a sus favoritos."
#: js/ui/appFavorites.js:172
#: js/ui/appFavorites.js:174
#, javascript-format
msgid "%s has been removed from your favorites."
msgstr "Se ha quitado %s de sus favoritos."
@ -865,7 +865,7 @@ msgstr "Dispositivo externo desconectado"
msgid "Open with %s"
msgstr "Abrir con %s"
#: js/ui/components/keyring.js:107 js/ui/components/polkitAgent.js:284
#: js/ui/components/keyring.js:107 js/ui/components/polkitAgent.js:295
msgid "Password:"
msgstr "Contraseña:"
@ -953,15 +953,15 @@ msgstr "Se requiere una contraseña para conectarse a «%s»."
msgid "Network Manager"
msgstr "Gestor de la red"
#: js/ui/components/polkitAgent.js:43
#: js/ui/components/polkitAgent.js:48
msgid "Authentication Required"
msgstr "Se necesita autenticación"
#: js/ui/components/polkitAgent.js:71
#: js/ui/components/polkitAgent.js:76
msgid "Administrator"
msgstr "Administrador"
#: js/ui/components/polkitAgent.js:151
#: js/ui/components/polkitAgent.js:156
msgid "Authenticate"
msgstr "Autenticar"
@ -969,7 +969,7 @@ msgstr "Autenticar"
#. * requested authentication was not gained; this can happen
#. * because of an authentication error (like invalid password),
#. * for instance.
#: js/ui/components/polkitAgent.js:270 js/ui/shellMountOperation.js:327
#: js/ui/components/polkitAgent.js:281 js/ui/shellMountOperation.js:327
msgid "Sorry, that didnt work. Please try again."
msgstr "Eso no ha funcionado. Inténtelo de nuevo."
@ -1017,7 +1017,7 @@ msgstr "Añadir relojes del mundo…"
msgid "World Clocks"
msgstr "Relojes del mundo"
#: js/ui/dateMenu.js:225
#: js/ui/dateMenu.js:227
msgid "Weather"
msgstr "Meteorología"
@ -1025,7 +1025,7 @@ msgstr "Meteorología"
#. libgweather for the possible condition strings. If at all
#. possible, the sentence should match the grammatical case etc. of
#. the inserted conditions.
#: js/ui/dateMenu.js:289
#: js/ui/dateMenu.js:291
#, javascript-format
msgid "%s all day."
msgstr "%s todo el día."
@ -1034,7 +1034,7 @@ msgstr "%s todo el día."
#. libgweather for the possible condition strings. If at all
#. possible, the sentence should match the grammatical case etc. of
#. the inserted conditions.
#: js/ui/dateMenu.js:295
#: js/ui/dateMenu.js:297
#, javascript-format
msgid "%s, then %s later."
msgstr "%s, luego %s."
@ -1043,30 +1043,30 @@ msgstr "%s, luego %s."
#. libgweather for the possible condition strings. If at all
#. possible, the sentence should match the grammatical case etc. of
#. the inserted conditions.
#: js/ui/dateMenu.js:301
#: js/ui/dateMenu.js:303
#, javascript-format
msgid "%s, then %s, followed by %s later."
msgstr "%s, luego %s seguido de %s."
#: js/ui/dateMenu.js:312
#: js/ui/dateMenu.js:314
msgid "Select a location…"
msgstr "Seleccionar ubicación…"
#: js/ui/dateMenu.js:315
#: js/ui/dateMenu.js:317
msgid "Loading…"
msgstr "Cargando…"
#. Translators: %s is a temperature with unit, e.g. "23℃"
#: js/ui/dateMenu.js:321
#: js/ui/dateMenu.js:323
#, javascript-format
msgid "Feels like %s."
msgstr "Sensación térmica de %s."
#: js/ui/dateMenu.js:324
#: js/ui/dateMenu.js:326
msgid "Go online for weather information"
msgstr "Conectarse para obtener la información meteorológica"
#: js/ui/dateMenu.js:326
#: js/ui/dateMenu.js:328
msgid "Weather information is currently unavailable"
msgstr "La información meteorológica no está disponible actualmente."
@ -1968,16 +1968,16 @@ msgstr "Suspender"
msgid "Power Off"
msgstr "Apagar"
#: js/ui/status/thunderbolt.js:272
#: js/ui/status/thunderbolt.js:294
msgid "Thunderbolt"
msgstr "Thunderbolt"
#. we are done
#: js/ui/status/thunderbolt.js:328
#: js/ui/status/thunderbolt.js:350
msgid "Unknown Thunderbolt device"
msgstr "Dispositivo Thunderbolt desconocido"
#: js/ui/status/thunderbolt.js:329
#: js/ui/status/thunderbolt.js:351
msgid ""
"New device has been detected while you were away. Please disconnect and "
"reconnect the device to start using it."
@ -1985,13 +1985,14 @@ msgstr ""
"Se ha detectado un dispositivo nuevo mientras estaba fuera. Desconéctelo y "
"vuélvalo a conectar para empezar a usarlo."
#: js/ui/status/thunderbolt.js:334
#: js/ui/status/thunderbolt.js:356
msgid "Thunderbolt authorization error"
msgstr "Error de autorización de Thunderbolt"
#: js/ui/status/thunderbolt.js:335
#: js/ui/status/thunderbolt.js:357
#, javascript-format
msgid "Could not authorize the thunderbolt device: %s"
#| msgid "Could not authorize the thunderbolt device: %s"
msgid "Could not authorize the Thunderbolt device: %s"
msgstr "No se pudo autorizar el dispositivo Thunderbolt: %s"
#: js/ui/status/volume.js:128

370
po/fr.po

File diff suppressed because it is too large Load Diff

368
po/fur.po

File diff suppressed because it is too large Load Diff

418
po/gl.po

File diff suppressed because it is too large Load Diff

384
po/hr.po

File diff suppressed because it is too large Load Diff

374
po/hu.po

File diff suppressed because it is too large Load Diff

368
po/id.po

File diff suppressed because it is too large Load Diff

View File

@ -8,22 +8,22 @@
# Wouter Bolsterlee <wbolster@gnome.org>, 20112014.
# Erwin Poeze <donnut@outlook.com>, 2013.
# Nathan Follens <nthn@unseen.is>, 2015-2018.
# Hannie Dumoleyn <hannie@ubuntu-nl.org>, 2015, 2017.
# Hannie Dumoleyn <hannie@ubuntu-nl.org>, 2015, 2017, 2018.
# Justin van Steijn <jvs@fsfe.org>, 2016, 2018.
msgid ""
msgstr ""
"Project-Id-Version: gnome-shell\n"
"Report-Msgid-Bugs-To: https://gitlab.gnome.org/GNOME/gnome-shell/issues\n"
"POT-Creation-Date: 2018-02-21 14:13+0000\n"
"PO-Revision-Date: 2018-02-21 22:05+0100\n"
"Last-Translator: Justin van Steijn <jvs@fsfe.org>\n"
"POT-Creation-Date: 2018-03-19 21:43+0000\n"
"PO-Revision-Date: 2018-03-23 10:09+0100\n"
"Last-Translator: Hannie Dumoleyn <hannie@ubuntu-nl.org>\n"
"Language-Team: Dutch <gnome-nl-list@gnome.org>\n"
"Language: nl\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"
"X-Generator: Poedit 1.8.11\n"
"X-Generator: Lokalize 2.0\n"
"X-Project-Style: gnome\n"
#: data/50-gnome-shell-system.xml:6
@ -283,7 +283,7 @@ msgid ""
msgstr ""
"Geeft aan hoe vensters in het overzicht getoond worden. Geldige waarden zijn "
"thumbnail-only (alleen een miniatuur tonen), app-icon-only (alleen het "
"pictogram van de toepassing tonen) of both (beide tonen)."
"pictogram van de toepassing tonen) of both (beide tonen)."
#: data/org.gnome.shell.gschema.xml.in:186
msgid ""
@ -470,7 +470,7 @@ msgstr "Oriëntatievergrendeling"
msgid "lock orientation;screen;rotation"
msgstr ""
"lock orientation;screen;rotation;oriëntatievergrendeling;scherm;draaiing;"
"rotatie;"
"rotatie"
#: js/misc/util.js:122
msgid "Command not found"
@ -1232,11 +1232,11 @@ msgstr "%s downloaden van extensions.gnome.org en daarna installeren?"
#: js/ui/inhibitShortcutsDialog.js:59
#, javascript-format
msgid "%s wants to inhibit shortcuts"
msgstr "%s wil sneltoetsen inhiberen"
msgstr "%s wil sneltoetsen blokkeren"
#: js/ui/inhibitShortcutsDialog.js:60
msgid "Application wants to inhibit shortcuts"
msgstr "Toepassing wil sneltoetsen inhiberen"
msgstr "Toepassing wil sneltoetsen blokkeren"
#. Translators: %s is a keyboard shortcut like "Super+x"
#: js/ui/inhibitShortcutsDialog.js:69
@ -1655,7 +1655,7 @@ msgstr "Locatie ingeschakeld"
#: js/ui/status/location.js:90 js/ui/status/location.js:198
msgid "Disable"
msgstr "Uischakelen"
msgstr "Uitschakelen"
#: js/ui/status/location.js:91
msgid "Privacy Settings"
@ -1823,7 +1823,7 @@ msgstr "Wifi-instellingen"
#: js/ui/status/network.js:1298
#, javascript-format
msgid "%s Hotspot Active"
msgstr "%s hotspot actief"
msgstr "%s-hotspot actief"
#. Translators: %s is a network identifier
#: js/ui/status/network.js:1313
@ -1967,16 +1967,16 @@ msgstr "Pauzestand"
msgid "Power Off"
msgstr "Uitschakelen"
#: js/ui/status/thunderbolt.js:272
#: js/ui/status/thunderbolt.js:294
msgid "Thunderbolt"
msgstr "Thunderbolt"
#. we are done
#: js/ui/status/thunderbolt.js:328
#: js/ui/status/thunderbolt.js:350
msgid "Unknown Thunderbolt device"
msgstr "Onbekend Thunderbolt-apparaat"
#: js/ui/status/thunderbolt.js:329
#: js/ui/status/thunderbolt.js:351
msgid ""
"New device has been detected while you were away. Please disconnect and "
"reconnect the device to start using it."
@ -1984,11 +1984,11 @@ msgstr ""
"Terwijl u weg was is er een nieuw apparaat gedetecteerd. Koppel het apparaat "
"los en verbind het opnieuw om het te gebruiken."
#: js/ui/status/thunderbolt.js:334
#: js/ui/status/thunderbolt.js:356
msgid "Thunderbolt authorization error"
msgstr "Thunderbolt-autorisatiefout"
#: js/ui/status/thunderbolt.js:335
#: js/ui/status/thunderbolt.js:357
#, javascript-format
msgid "Could not authorize the thunderbolt device: %s"
msgstr "Kon het Thunderbolt-apparaat niet autoriseren: %s"
@ -2162,7 +2162,7 @@ msgstr "De modus die door GDM voor het aanmeldscherm gebruikt wordt"
#: src/main.c:444
msgid "Use a specific mode, e.g. “gdm” for login screen"
msgstr "Specifieke modus gebruiken, bijv. gdm voor het aanmeldscherm"
msgstr "Specifieke modus gebruiken, bijv. gdm voor het aanmeldscherm"
#: src/main.c:450
msgid "List possible modes"
@ -2176,7 +2176,7 @@ msgstr "Onbekend"
#: src/shell-app.c:511
#, c-format
msgid "Failed to launch “%s”"
msgstr "Kon %s niet starten"
msgstr "Kon %s niet starten"
#: src/shell-keyring-prompt.c:730
msgid "Passwords do not match."

501
po/pa.po

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

1544
po/ro.po

File diff suppressed because it is too large Load Diff

405
po/ru.po

File diff suppressed because it is too large Load Diff

360
po/sk.po

File diff suppressed because it is too large Load Diff

574
po/sl.po

File diff suppressed because it is too large Load Diff

415
po/sv.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

View File

@ -590,6 +590,11 @@ app_load_events (App *app)
g_list_free (app->live_views);
app->live_views = NULL;
if (!app->since || !app->until)
{
print_debug ("Skipping load of events, no time interval set yet");
return;
}
/* timezone could have changed */
app_update_timezone (app);

View File

@ -347,10 +347,10 @@ if options.perf == None:
options.perf = 'core'
if options.extra_filter is None:
if options.hwtest:
options.extra_filter = ['Gedit']
else:
options.extra_filter = []
options.extra_filter = []
if options.perf == 'hwtest':
options.extra_filter.append('Gedit')
if args:
parser.print_usage()

View File

@ -73,8 +73,8 @@ struct _ShellGlobal {
ShellWM *wm;
GSettings *settings;
const char *datadir;
const char *imagedir;
const char *userdatadir;
char *imagedir;
char *userdatadir;
GFile *userdatadir_path;
GFile *runtime_state_path;
@ -337,6 +337,10 @@ shell_global_finalize (GObject *object)
g_clear_object (&global->userdatadir_path);
g_clear_object (&global->runtime_state_path);
g_free (global->session_mode);
g_free (global->imagedir);
g_free (global->userdatadir);
G_OBJECT_CLASS(shell_global_parent_class)->finalize (object);
}

View File

@ -142,7 +142,7 @@ libst_gir = gnome.generate_gir(libst,
sources: st_gir_sources,
nsversion: '1.0',
namespace: 'St',
includes: ['Clutter-' + mutter_api_version, 'Gtk-3.0'],
includes: ['Clutter-' + mutter_api_version, 'Cally-' + mutter_api_version, 'Gtk-3.0'],
dependencies: [mutter_dep],
include_directories: include_directories('..'),
extra_args: ['-DST_COMPILATION', '--quiet'],

View File

@ -308,9 +308,8 @@ st_entry_style_changed (StWidget *self)
}
theme_node = st_widget_get_theme_node (self);
st_theme_node_get_foreground_color (theme_node, &color);
clutter_text_set_color (CLUTTER_TEXT (priv->entry), &color);
_st_set_text_from_style (CLUTTER_TEXT (priv->entry), theme_node);
if (st_theme_node_lookup_length (theme_node, "caret-size", TRUE, &size))
clutter_text_set_cursor_size (CLUTTER_TEXT (priv->entry), (int)(.5 + size));

View File

@ -116,6 +116,7 @@ _st_set_text_from_style (ClutterText *text,
PangoAttrList *attribs = NULL;
const PangoFontDescription *font;
StTextAlign align;
gdouble spacing;
st_theme_node_get_foreground_color (theme_node, &color);
clutter_text_set_color (text, &color);
@ -123,11 +124,11 @@ _st_set_text_from_style (ClutterText *text,
font = st_theme_node_get_font (theme_node);
clutter_text_set_font_description (text, (PangoFontDescription *) font);
attribs = pango_attr_list_new ();
decoration = st_theme_node_get_text_decoration (theme_node);
if (decoration)
{
attribs = pango_attr_list_new ();
if (decoration & ST_TEXT_DECORATION_UNDERLINE)
{
PangoAttribute *underline = pango_attr_underline_new (PANGO_UNDERLINE_SINGLE);
@ -143,6 +144,13 @@ _st_set_text_from_style (ClutterText *text,
*/
}
spacing = st_theme_node_get_letter_spacing (theme_node);
if (spacing)
{
PangoAttribute *letter_spacing = pango_attr_letter_spacing_new ((int)(.5 + spacing) * PANGO_SCALE);
pango_attr_list_insert (attribs, letter_spacing);
}
clutter_text_set_attributes (text, attribs);
if (attribs)
@ -414,11 +422,9 @@ _st_create_shadow_pipeline_from_actor (StShadow *shadow_spec,
ClutterActor *actor)
{
CoglPipeline *shadow_pipeline = NULL;
ClutterActorBox box;
float width, height;
clutter_actor_get_allocation_box (actor, &box);
clutter_actor_box_get_size (&box, &width, &height);
clutter_actor_get_size (actor, &width, &height);
if (width == 0 || height == 0)
return NULL;
@ -441,6 +447,7 @@ _st_create_shadow_pipeline_from_actor (StShadow *shadow_spec,
CoglFramebuffer *fb;
CoglColor clear_color;
CoglError *catch_error = NULL;
float x, y;
buffer = cogl_texture_new_with_size (width,
height,
@ -462,6 +469,7 @@ _st_create_shadow_pipeline_from_actor (StShadow *shadow_spec,
}
cogl_color_init_from_4ub (&clear_color, 0, 0, 0, 0);
clutter_actor_get_position (actor, &x, &y);
/* XXX: There's no way to render a ClutterActor to an offscreen
* as it uses the implicit API. */
@ -470,7 +478,7 @@ _st_create_shadow_pipeline_from_actor (StShadow *shadow_spec,
G_GNUC_END_IGNORE_DEPRECATIONS;
cogl_framebuffer_clear (fb, COGL_BUFFER_BIT_COLOR, &clear_color);
cogl_framebuffer_translate (fb, -box.x1, -box.y1, 0);
cogl_framebuffer_translate (fb, -x, -y, 0);
cogl_framebuffer_orthographic (fb, 0, 0, width, height, 0, 1.0);
clutter_actor_set_opacity_override (actor, 255);

View File

@ -2545,6 +2545,28 @@ st_theme_node_get_text_align(StThemeNode *node)
return ST_TEXT_ALIGN_LEFT;
}
/**
* st_theme_node_get_letter_spacing:
* @node: a #StThemeNode
*
* Gets the value for the letter-spacing style property, in pixels.
*
* Return value: the value of the letter-spacing property, if
* found, or zero if such property has not been found.
*/
gdouble
st_theme_node_get_letter_spacing (StThemeNode *node)
{
gdouble spacing = 0.;
g_return_val_if_fail (ST_IS_THEME_NODE (node), spacing);
ensure_properties (node);
st_theme_node_lookup_length (node, "letter-spacing", FALSE, &spacing);
return spacing;
}
static gboolean
font_family_from_terms (CRTerm *term,
char **family)

View File

@ -223,6 +223,8 @@ StTextDecoration st_theme_node_get_text_decoration (StThemeNode *node);
StTextAlign st_theme_node_get_text_align (StThemeNode *node);
double st_theme_node_get_letter_spacing (StThemeNode *node);
/* Font rule processing is pretty complicated, so we just hardcode it
* under the standard font/font-family/font-size/etc names. This means
* you can't have multiple separate styled fonts for a single item,

View File

@ -38,6 +38,10 @@ const tests = [
output: [ { url: 'http://www.gnome.org:99/port', pos: 10 } ] },
{ input: 'This is an ftp://www.gnome.org/ test.',
output: [ { url: 'ftp://www.gnome.org/', pos: 11 } ] },
{ input: 'https://www.gnome.org/(some_url,_with_very_unusual_characters)',
output: [ { url: 'https://www.gnome.org/(some_url,_with_very_unusual_characters)', pos: 0 } ] },
{ input: 'https://www.gnome.org/(some_url_with_unbalanced_parenthesis',
output: [ { url: 'https://www.gnome.org/', pos: 0 } ] },
{ input: 'Visit http://www.gnome.org/ and http://developer.gnome.org',
output: [ { url: 'http://www.gnome.org/', pos: 6 },
@ -68,4 +72,4 @@ for (let i = 0; i < tests.length; i++) {
JsUnit.assertEquals('Test ' + i + ', match ' + j + ' position',
match[j].pos, tests[i].output[j].pos);
}
}
}