Compare commits

...

297 Commits

Author SHA1 Message Date
5ea032bbf7 Bump version to 3.2.1
Update NEWS
2011-10-18 00:23:51 -04:00
897fadfb40 Require Mutter 3.2.1
This is needed for meta_display_unmanage_screen()
2011-10-18 00:19:32 -04:00
b05f71eb9b messageTray: Add banner body when setting the image for a notification
We always place the banner in the body if the notification has additional
content.

https://bugzilla.gnome.org/show_bug.cgi?id=659158
2011-10-18 00:16:25 -04:00
4ce0e80956 user-menu: Be more cautious about saving status
When requesting a presence change, the actual presence set by
mission control does not necessarily match the requested presence
(if an active account does not support the requested presence),
which may result in the wrong presence being restored.
As a fix, be more cautious about saving status by assuming that
users do not request presence changes between an automatic presence
change request and the actual change.

https://bugzilla.gnome.org/show_bug.cgi?id=661485
2011-10-18 04:25:57 +02:00
577ccc4d56 Unmanage the screen before reexecing
This ensures a 'clean shutdown' of mutter.

https://bugzilla.gnome.org/show_bug.cgi?id=660848
2011-10-17 21:55:13 -04:00
39d12351ba gdm: move focus to first item in list
This allows the user to just hit when the user
list first comes up (in many cases).

https://bugzilla.gnome.org/show_bug.cgi?id=657996
2011-10-17 20:49:04 -04:00
e37bc6d7f0 Updated Galician translations 2011-10-18 00:05:07 +02:00
9593ff3582 notificationDaemon: only display a large image if an icon is also specified
Historically, when applications set "image-data" they expect it to show up
as an icon. So we display it as such if an icon is not specified with an
"app_icon" argument to Notify(). We also use "image-path" for an icon if
an icon is not specified.

We only display a large image specified with "image-data" or "image-path"
if an icon is also specified.

https://bugzilla.gnome.org/show_bug.cgi?id=659158
2011-10-17 17:53:16 -04:00
ad8dfd7b04 Updated Hungarian translation 2011-10-17 23:44:33 +02:00
ca5ab20f67 gdm: don't clear bullets while authenticating
Users don't expect the bullets they just typed into an entry
field to disappear as soon as they hit enter.

Instead, they want the dialog to become insensitive during the
authentication process, so that it's clear that what they typed
in is being processed.

https://bugzilla.gnome.org/show_bug.cgi?id=657894
2011-10-17 17:37:06 -04:00
0eab448221 css: Style the capslock warning in password entries
https://bugzilla.gnome.org/show_bug.cgi?id=660806
2011-10-17 22:43:47 +02:00
a26a77f9db st-entry: Display a capslock warning in password entries
Implement the GtkEntry behavior of showing a warning icon when
capslock is turned on while entering hidden text.

https://bugzilla.gnome.org/show_bug.cgi?id=660806
2011-10-17 22:43:47 +02:00
c3df6bb8bd [l10n] Updated German translation 2011-10-17 22:07:46 +02:00
ce3a26cf37 Updated Polish translation 2011-10-17 22:04:00 +02:00
04482c23c4 Updated POTFILES.in 2011-10-17 22:02:37 +02:00
ff20fe856e keyboard: show the keyboard immediately when the user toggles it on
Enabling the keyboard currently doesn't give much notification. Make
it so that the keyboard shows right away when it first gets turned on.

https://bugzilla.gnome.org/show_bug.cgi?id=659743
2011-10-17 14:55:17 -04:00
12e3921f81 messageTray: only set stage input mode when necessary
The message tray focus grabbing code sets the stage input
mode to Shell.StageInputMode.FOCUSED when the overview is
not visible. This ensures the stage window's input
region gets reshaped to include the notification chrome,
and so that input events get delivered appropriately to
the notification that grabbed focus.

The message tray code never tries to restore the stage input
mode later. Instead, the code relies on the stage input
mode (and input region) getting reset to
shell.StageInputMode.NORMAL automatically when focus moves
back from the shell chrome to a window in the user's session.

It's not really correct to set the stage input mode based
on the overview's visibility, though. At the login screen,
even though no overview is visible, the stage input mode is
Shell.StageInputMode.FULLSCREEN which is sufficient
for the notification's needs,  Furthermore,
Shell.StageInputMode.FOCUSED is insufficient for the login
dialog's needs since the login dialog isn't considered
part of the shell's chrome and won't get included in the
stage input region.

This commit changes the message tray code to only set the
stage input mode if the current stage input mode isn't good enough,
rather than assuming the input mode isn't good enough just because
the overview is hidden.

https://bugzilla.gnome.org/show_bug.cgi?id=660919
2011-10-17 13:24:12 -04:00
928fbee15b altTab: fix app ordering in certain edge cases
Because we were sorting the Alt+Tab list by user_time rather than
stacking order / MRU, it was possible for the currently-focused window
to sometimes not be the first app in the list. Fix this by using
meta_display_get_tab_list() to get the proper MRU ordering of windows
on the current workspace, and then convert that to an ordered list of
apps.

https://bugzilla.gnome.org/show_bug.cgi?id=645026
2011-10-17 12:54:03 -04:00
a103c028f9 gdm: add prelight to Not Listed? button
The prelight makes it clearer that the button is
clickable, and makes it more consistent with other
clickable parts of the dialog.

https://bugzilla.gnome.org/show_bug.cgi?id=659763
2011-10-17 11:55:46 -04:00
775347d865 Updated Japanese translation 2011-10-18 00:54:05 +09:00
6d0be86a4e dash: Add minor optimization to _adjustIconSize()
In case _adjustIconSize() is called while the the dash icons are
animating, some extra work is required to yield the expected result.
Skip those extra steps when the icons are not actually animating.

https://bugzilla.gnome.org/show_bug.cgi?id=649248
2011-10-17 16:07:52 +02:00
a4b69db8af dash: Rework _adjustIconSize()
The current code uses the dash's height and current icon size to
calculate the new icon size. However, the height does not correctly
relate to the icon size while the icons are animating, in which
case the resulting icon size may be wrong.
Rework the function to be independent from the actual icon sizes,
so that a correct size is calculated even when called during an
animation.

https://bugzilla.gnome.org/show_bug.cgi?id=649248
2011-10-17 16:07:52 +02:00
790b9d3371 dash: Ignore hiding items in _adjustIconSize()
Rather than relying on the caller to hide the remove target and
removed items before calling _adjustIconSize(), move that logic
into _adjustIconSize() itself.

https://bugzilla.gnome.org/show_bug.cgi?id=649248
2011-10-17 16:07:52 +02:00
adef2009a5 Revert "dash: Ignore hiding items in _adjustIconSize()"
Ooops, a patch got lost in rebase.

This reverts commit b07f9932db.
2011-10-17 16:01:19 +02:00
1721db6d8d Revert "dash: Add minor optimization to _adjustIconSize()"
Ooops, a patch got lost in rebase ...

This reverts commit 6d95e8b988.
2011-10-17 16:00:52 +02:00
6d95e8b988 dash: Add minor optimization to _adjustIconSize()
In case _adjustIconSize() is called while the the dash icons are
animating, some extra work is required to yield the expected result.
Skip those extra steps when the icons are not actually animating.

https://bugzilla.gnome.org/show_bug.cgi?id=649248
2011-10-17 15:58:25 +02:00
b07f9932db dash: Ignore hiding items in _adjustIconSize()
Rather than relying on the caller to hide the remove target and
removed items before calling _adjustIconSize(), move that logic
into _adjustIconSize() itself.

https://bugzilla.gnome.org/show_bug.cgi?id=649248
2011-10-17 15:58:16 +02:00
9439da81c4 Add context menus to some entries
Use ShellEntry.addContextMenu() to add context menus to most
existing entries, with the exception of:

 - the login dialog - it may act be used to enter either the
                      username (e.g. no password entry) or the
                      password, and copy/paste does not make sense
                      (nowhere to copy from, nowhere to paste to)
 - notifications    - while adding a context menu is useful here as
                      well, it will require changes to the tray's
                      focus grab handling, so leave those entries
                      out for now

https://bugzilla.gnome.org/show_bug.cgi?id=659275
2011-10-17 15:29:32 +02:00
6257e64d03 shell-entry: Add API to support entry context menus
Add addContextMenu() to support context menus on right-click/long-press.
Depending on the parameters passed, the context menu only contains
"Copy"/"Paste" actions or an additional "Show/Hide Text" toggle action
for password entries.

https://bugzilla.gnome.org/show_bug.cgi?id=659275
2011-10-17 15:29:32 +02:00
ba110f2d2e network-agent: Remove "Show password" switch
While the ability to show the password can be useful at times,
the existing implementation is problematic:

  1) The use of a switch is wrong (as even noted in a code
     comment).

  2) It is inconsistent with any other password dialog (login screen,
     polkit).

In lack of a properly designed solution (for all password dialogs),
the designers agreed to remove the switch for now.

https://bugzilla.gnome.org/show_bug.cgi?id=658948
2011-10-17 15:29:32 +02:00
6bdf621d05 Fixed some strings in Brazilian Portuguese translation 2011-10-17 10:38:23 -02:00
1c4db98c95 added Kurdish translation 2011-10-17 14:28:49 +02:00
dadac957e4 updated Kurdish translation 2011-10-17 13:38:39 +02:00
cf3976d496 l10n: updated Italian translation 2011-10-17 10:31:24 +02:00
82ed80c9c3 extensionSystem: Load user extensions after system ones
https://bugzilla.gnome.org/show_bug.cgi?id=661815
2011-10-16 14:54:17 -04:00
67222525ad Updated Korean translation 2011-10-17 03:00:56 +09:00
fff0861773 Updated French translation 2011-10-16 12:50:22 +02:00
13ffe41498 Updated Persian translations 2011-10-15 16:05:29 +03:30
96e0528a7b Updated Bulgarian translation 2011-10-15 10:43:14 +03:00
3df30fbd57 Updated Bulgarian translation 2011-10-15 10:00:14 +03:00
b57d8b336b Updated British English translation 2011-10-14 19:12:28 +01:00
3169b2c440 keyboard: fix the keyboard hiding when an extended key is selected
Add a corner case for when the extended key is clicked in order to stop the keyboard
from prematurely closing.

https://bugzilla.gnome.org/show_bug.cgi?id=661707
2011-10-13 16:12:16 -04:00
6bc34e0f32 shell-app: Plug a small memory leak 2011-10-13 22:09:39 +02:00
cecb1a41fb st-texture-cache: Fix a minor crash when computing our border-radius
If we add a 0-sized actor with a border-radius, we will crash as we try to
allocate a 0-sized texture in Cogl. Bail out early instead of doing that.

https://bugzilla.gnome.org/show_bug.cgi?id=661617
2011-10-13 14:15:18 -04:00
b9069df85c search: fix keyboard hiding when user starts a new search
The keyboard hides prematurely when the user is typing into
an empty search box because the click is a captured event that
triggers a loss of entry focus. By adding a keyboard check to
this event, the problem is solved.

https://bugzilla.gnome.org/show_bug.cgi?id=661340
2011-10-13 14:12:21 -04:00
aee3c6f041 shell-app: Remove MATCH_MULTIPLE_{PREFIX,SUFFIX}
We originally OR'ed search terms and favored results which matched
multiple times to get more relevant results. When changing search
to AND search terms, the semantics of "multiple matches" were
changed to refer to a single term matching multiple criteria (name,
executable), which seemed like a good idea at the time.

However in practice this just results in applications whose
user-visible name matches the executable name on disk being
favored over applications using a more generic name, which
isn't too useful (in particular when taking usage frequency
into account).

https://bugzilla.gnome.org/show_bug.cgi?id=623372
2011-10-13 17:46:45 +02:00
c427bba9f1 shell-app: Improve prefix matches
Currently we use a very strict definition of "prefix", where the
search term has to match at the very beginning of the searched
criteria (application name, executable name). Use a more liberal
definition by including matches where the preceding character is
a space (application name) or hyphen (executable name) as well;
as many applications use a prefix, this should improve the quality
of results.

https://bugzilla.gnome.org/show_bug.cgi?id=623372
2011-10-13 17:46:45 +02:00
da83ad561b app-system: Consider usage frequency in search results
Application search results are internally categorized in four sets,
multiple and single prefix matches and multiple and single substring
matches. Each set is currently sorted alphabetically by application
name when concatenating the sets to the final result.
Change the last step to sort each set by usage frequency instead,
which is more likely to favor the most relevant match than
"arbitrary" alphabetic order.

https://bugzilla.gnome.org/show_bug.cgi?id=623372
2011-10-13 17:46:45 +02:00
85520e34ab popup-menu: Allow adjusting where in the source the arrow points to
Currently BoxPointer/Menus always point to the center of the
associated source actor. This is generally what we want, but
add some API to adjust that behavior for the cases where it
isn't.

https://bugzilla.gnome.org/show_bug.cgi?id=659274
2011-10-13 15:03:32 +02:00
d0edd970e1 gdm: clean up spacing
There's a lot of dead vertical space right now from
the session list, even if there are no sessions.

This commit mops that up.

https://bugzilla.gnome.org/show_bug.cgi?id=661479
2011-10-11 17:27:42 -04:00
8529ca70af gdm: don't show fingerprint message right away
Right now we show "(or swipe finger)" at the user login prompt
any time we detect a fingerprint reader.

Checking for the presense of a fingerprint reader isn't really
sufficient for knowing if it is appropriate or not to show the
message, though. Often, a user's fingerprint won't be enrolled
in the system even if the machine has a fingerprint reader.

In this scenario, we end up in a situation where the code will
fade out the message right after fading it in, or worse, fade
out the message while fading it in.

The former case looks flickery and bad, and the latter case
causes the login dialog to lock up since it never completes its
"show prompt" animation and we don't procede with the login
process until after that animation.

If a user is enrolled in the system, the fingerprint pam module
tries to tell the user to swipe their finger.  We never show the
user that message because it's redundant with our own "(or swipe
finger)" message and because it uses techy words like "UPEK" and
"TouchStrip".

This commit changes the code to defer showing "(or swipe
finger)" until the fingerprint pam module forwards us its own
message. This makes it less likely we'll show the message when
fingerprint login won't work, and also removes the fingerprint
animation from the critical path "show prompt" animation.

https://bugzilla.gnome.org/show_bug.cgi?id=660492
2011-10-11 17:25:44 -04:00
1a8d78212f layoutManager: Ignore 1px overlap in _isAboveOrBelowPrimary()
Nvidia's twin view option does not align monitors properly, but with
a one pixel overlap. It looks safe to ignore an overlap this small
to make this case work.

https://bugzilla.gnome.org/show_bug.cgi?id=661387
2011-10-11 16:20:12 +02:00
4270a2806d Updated Hungarian translation 2011-10-11 16:12:28 +02:00
4333bdc709 *.[ch]: add emacs modeline to C files that were missing it
(excluding files that are synced from another module)

https://bugzilla.gnome.org/show_bug.cgi?id=660358
2011-10-11 08:05:17 -04:00
75b824d032 *.js: Make emacs modelines consistent
js2-mode is no longer developed and we recommend js-mode these days,
so switch the modelines to specify that, and make them consistent
across all files.

https://bugzilla.gnome.org/show_bug.cgi?id=660358
2011-10-11 08:05:12 -04:00
7bc2573d85 window-clone: Use ClutterClickAction
Right-click menus in the dash can be dismissed by clicking anywhere
outside the menu. However, if a window clone is located beneath the
pointer when doing so, the window is activated and the overview
closed.
The cause of this unexpected behavior is that window previews are
activated on button-release, which is delivered to the preview after
the menu releases its grab on button-press. Use a ClutterClickAction
instead and let Clutter do the right thing, i.e. only trigger a
'clicked' signal when a button-release event is matched by a
corresponding button-press event.

https://bugzilla.gnome.org/show_bug.cgi?id=661151
2011-10-11 12:56:34 +02:00
67b7b7a950 shell-util: Fix a bogus annotation
Creating a new instance is not (transfer none), unless I'm missing
somehting here...

https://bugzilla.gnome.org/show_bug.cgi?id=661231
2011-10-11 00:07:31 -04:00
786cfbd397 shell-util: Remove shell_util_icon_from_string
GJS doesn't need to be able to represent interfaces for you to be able to
access an interface method, so Gio.icon_new_for_string works fine.

https://bugzilla.gnome.org/show_bug.cgi?id=661231
2011-10-11 00:07:31 -04:00
9df8b583cf Updated Telugu Translations 2011-10-10 16:53:43 +05:30
8e32290dc9 Change default of saved-im-presence to Offline
Unset is not a valid presence type so the Shell shouldn't try setting it when
starting for the first time.

https://bugzilla.gnome.org/show_bug.cgi?id=661272
2011-10-09 15:23:59 -04:00
23478f3336 Updated Lithuanian translation 2011-10-09 00:40:32 +03:00
2e244ecb63 Updated Latvian translation. 2011-10-08 22:48:44 +03:00
e307680206 [l10n] Updated German translation 2011-10-08 20:38:19 +02:00
6bb1a3e2c4 Updated Russian translation 2011-10-08 11:34:28 +04:00
8a1ac6b13f Updated Dutch translation by Wouter Bolsterlee 2011-10-08 02:04:37 +02:00
61b8af2252 Add translator comment for button label 2011-10-08 01:50:20 +02:00
c99afed012 messageTray: Fix accidental typo 2011-10-07 16:34:04 -04:00
2947b92148 user-menu: Restore previous session presence at startup
Save the session presence in GSettings and restore it on startup.

https://bugzilla.gnome.org/show_bug.cgi?id=659021
2011-10-07 07:24:21 +02:00
39c5d23a87 user-menu: Restore previous IM presence on startup
Move the saved user-set presence to GSettings, so it is preserved
between logins.

https://bugzilla.gnome.org/show_bug.cgi?id=659021
2011-10-07 07:24:21 +02:00
d839670f54 Updated Spanish translation 2011-10-06 23:39:36 +02:00
0d1b7e15d1 Updated Swedish translation 2011-10-06 08:09:28 +02:00
ac678f63ee Updated Galician translations 2011-10-06 02:52:18 +02:00
d862c0879b telepathyClient: Check for a no-op before pushing an alias change message
tp-glib can sometimes emit a notify::alias signal when the alias doesn't
actually change. Bail out early instead of pushing an alias change message.

https://bugzilla.gnome.org/show_bug.cgi?id=660774
2011-10-05 15:34:40 -04:00
23a4d4c69e texture-cache: Don't share requests for uncachable textures
Make create_texture_and_ensure_request() aware of the caching
policy to avoid returning the same texture for different
images.

https://bugzilla.gnome.org/show_bug.cgi?id=660585
2011-10-05 21:30:27 +02:00
472b20d933 ShellContactSystem: Make address search actually work
The code was not dealing properly with what folks returns
for im and email addresses.

https://bugzilla.gnome.org/show_bug.cgi?id=660925
2011-10-05 20:26:39 +02:00
492dd718fb ShellContactSystem: make search terms conjunctive
Require that all terms match. This is the expected behaviour
and matches what gnome-contacts does. Keep the prefix/infix
weights in place for now.

https://bugzilla.gnome.org/show_bug.cgi?id=660912
2011-10-05 20:26:38 +02:00
0d5618fdd1 contact-display: Try harder to display a meaningful name
We now match individuals on other properties than alias, so take
this into account when representing a contact in search results
to avoid having them show up as "Unknown".

https://bugzilla.gnome.org/show_bug.cgi?id=660580
2011-10-05 20:26:38 +02:00
503508af41 contact-system: Add helper method to get a (display) email
Folks uses collection/set objects from libgee to store email addresses
associated with an individual. Unfortunately to extract addresses, parts
of libgee which are unusable from (introspected) bindings have to be
used[0], so add a helper method.

[0] in particular gee_iterator_get(), which is annotated as
    "return: (transfer full): gpointer"

https://bugzilla.gnome.org/show_bug.cgi?id=660580
2011-10-05 20:26:38 +02:00
4ec5e55122 Move shell contacts search closer to gnome-contacts
Match folks' name and nick fields, in addition to alias,
and look at email addresses in addition to im addresses.
This is more in line with what gnome-contacts does.

To match this new usage, rename the ALIAS_..._WEIGHT and
IM_..._WEIGHT constants to NAME_ and ADDR_, respectively.

https://bugzilla.gnome.org/show_bug.cgi?id=660580
2011-10-05 20:26:38 +02:00
8daca865ca Updated Slovenian translation 2011-10-05 19:59:01 +02:00
f9b37a21e8 StThemeNodeDrawing: Remove useless LoadCornerData
Done as part of my quest to merge Mx and St:

https://github.com/magcius/mx/tree/st-rebase

https://bugzilla.gnome.org/show_bug.cgi?id=660968
2011-10-05 12:24:28 -04:00
c398f319fc [l10n]Updated Catalan translation 2011-10-04 23:30:47 +02:00
1e049f88b8 Updated Polish translation 2011-10-04 23:25:07 +02:00
4831d9c3a3 lookingGlass: Fix referencing undefined variables 2011-10-04 16:50:58 -04:00
f13f5bc1bb Use '' for non-translated strings
Pay attention to the style guidelines.

https://bugzilla.gnome.org/show_bug.cgi?id=660600
2011-10-04 16:47:53 -04:00
4e114107ed keyboard: Add a missed translation
The word "tray" should be translated to other languages.

https://bugzilla.gnome.org/show_bug.cgi?id=660600
2011-10-04 16:47:53 -04:00
0ccb280008 st-theme-node-drawing: Fix centering when the image needs to be scaled
The translate coordinates are calculated as the offset after the scale, so it
needs to be applied after the scale as well. This fixes random centering issues
in the UI.

https://bugzilla.gnome.org/show_bug.cgi?id=660674
2011-10-04 15:46:01 -04:00
28c3e0693e workspaces-view: Remove window dnd between workspaces
When workspace "previews" in the overview were just tiny gray
rectangles, it made sense to provide a way to move windows
directly between workspaces (by switching workspaces when dragging
a window to the corresponding screen edge). As the overview has
evolved however, the workspace switcher provides a good and
intuitive drop target already, so the alternative provided by the
screen edges is no longer necessary. As it also conflicts with
moving windows between monitors when using a vertical layout,
just remove it.

https://bugzilla.gnome.org/show_bug.cgi?id=660838
2011-10-04 20:30:20 +02:00
c321c8a02f Updated Polish translation 2011-10-04 20:09:02 +02:00
2407ec7b47 Revert "lookingGlass: Add an easier way to see extension errors"
This reverts commit 1e6b824ede.
2011-10-04 13:15:10 -04:00
70eeb75716 lookingGlass: Show extension state in gnome-shell
We translate and create an actor to show the extension state, but we never
actually add it anywhere. Fix that.

https://bugzilla.gnome.org/show_bug.cgi?id=660494
2011-10-04 13:14:54 -04:00
751d250471 autorun: fix a typo in a variable name
The variable |type| doesn't exist here; what we want to do is using the
first member of the contentTypes array instead.
Probably a leftover of some refactoring of the code I did while working
on this.

This patch fixes starting of the default application for a given content
type if the control-center panel is set to run it when a device is
plugged.

https://bugzilla.gnome.org/show_bug.cgi?id=660821
2011-10-03 16:34:59 -04:00
c28217db80 Updated Esperanto translation 2011-10-03 20:40:41 +02:00
0968e556fa WindowDimmer: Make effect private
There is no need for making this public as it is only accessed from within
WindowDimmer.
2011-10-03 18:22:58 +02:00
130f2cf808 WindowDimmer: Don't try to use a ShaderEffect when GLSL is not available
This obviously won't work anyway but will just spam stderr with warnings,
so don't do it.
2011-10-03 18:22:47 +02:00
4eec7413c7 Revert "lookingGlass: Show extension state in gnome-shell"
This reverts commit 32dc24c59b, as it caused
a string break.

https://bugzilla.gnome.org/show_bug.cgi?id=660494
2011-10-02 12:05:21 -04:00
efc3246d26 Updated Bulgarian translation 2011-10-02 13:52:37 +03:00
9930dbc0ff Updated Galician translations 2011-10-02 00:24:03 +02:00
754f87dac3 Updated Swedish translation 2011-10-01 21:57:10 +02:00
51139bd096 Updated Irish translation 2011-10-01 13:26:46 -06:00
6e0119d620 Updated Irish translation 2011-10-01 13:16:56 -06:00
a3528bf973 layout: Fix the actor tracking parameter parsing
It's not appropriate to inherit from the parent property if we pass "false"
as a value, especially when all current parameters are booleans.

https://bugzilla.gnome.org/show_bug.cgi?id=660608
2011-10-01 14:41:53 -04:00
77c36af588 [l10n]Updated Catalan (Valencian) translation 2011-10-01 16:04:25 +02:00
69c0a52a33 [l10n]Updated Catalan translation 2011-10-01 16:04:18 +02:00
a7442cd0a5 Updated Vietnamese translation 2011-10-01 10:31:24 +10:00
d47a013931 vi.po: import from Damned Lies 2011-10-01 10:29:31 +10:00
745f9c0e6e Added asturian language 2011-09-30 21:04:02 +02:00
414f49fd80 Updated asturian translation 2011-09-30 21:02:57 +02:00
e49a595f54 st-texture-cache: Don't cache GIcons which cannot be serialized
For GIcons we use g_icon_to_string() in the key, but the function
will return NULL if the icon cannot be serialized. As a result,
all non-serializable GIcons of the same size end up with the same
cache key - an example for this are contacts with avatars, which
currently all end up with the same image.
To fix, opt out of caching for GIcons which cannot be serialized.

https://bugzilla.gnome.org/show_bug.cgi?id=660585
2011-09-30 20:14:25 +02:00
77485c2a04 [l10n] Updated German translation 2011-09-30 20:07:51 +02:00
e9b28634e5 Updated Slovenian translation 2011-09-30 19:13:24 +02:00
b43dcb8876 layout: Fix setting fullscreen for screen sized windows
We have to set the flag for all monitors in that case.
2011-09-30 18:46:14 +02:00
f0c1eeece8 Updated Spanish translation 2011-09-30 18:27:07 +02:00
1e6b824ede lookingGlass: Add an easier way to see extension errors
Use the extensions tab to show errors belonging to each extension.

https://bugzilla.gnome.org/show_bug.cgi?id=660546
2011-09-30 12:19:30 -04:00
1e2d16273c layoutManager: Treat screen_sized OR windows as fullscreen
https://bugzilla.gnome.org/show_bug.cgi?id=660166
2011-09-29 21:38:05 +02:00
32dc24c59b lookingGlass: Show extension state in gnome-shell
We translate and create an actor to show the extension state, but we never
actually add it anywhere. Fix that.

https://bugzilla.gnome.org/show_bug.cgi?id=660494
2011-09-29 13:15:27 -04:00
7a8a189c48 boxpointer: Don't constrain box pointer to primary monitor
A boxPointer should be able to be attached to any actor, not just ones on the
primary monitor. Assume that the sourceActor doesn't straddle monitors, and
constrain the boxPointer to the monitor the sourceActor is on.

https://bugzilla.gnome.org/show_bug.cgi?id=659861
2011-09-29 13:15:01 -04:00
6aa411fecc keyboard: ignore D-Bus requests when the OSK isn't enabled
Fixes spurious warnings about "this.actor is null" when processing
org.gnome.Caribou.Keyboard messages when the keyboard isn't enabled.

https://bugzilla.gnome.org/show_bug.cgi?id=659940
2011-09-29 10:28:49 -04:00
9c76318df8 main: remove a stray second keyboard.init() call
Originally the keyboard was initialized in the user-session-specific
code, but it was later moved to the generic code. Except that it was
accidentally copied rather than moved.

https://bugzilla.gnome.org/show_bug.cgi?id=659940
2011-09-29 10:28:46 -04:00
6510904711 windowAttentionHandler: Remove "%s has finished starting"
The message is verbose and confusing. Use the traditional "'%s' is ready"
for all cases.

https://bugzilla.gnome.org/show_bug.cgi?id=660310
2011-09-29 09:59:09 -04:00
a9817f4832 automountManager: Don't mount already-mounted volumes
Don't pester the user with autorun popups if a volume is already mounted.

https://bugzilla.gnome.org/show_bug.cgi?id=660397
2011-09-28 16:51:02 -04:00
9067689839 power-status: Use correct DBus signatures
Devices are represented as susdut, not susbut (i.e. the percentage
is a double rather than a boolean) - apparently the wrong signature
works, but correct it anyway.

https://bugzilla.gnome.org/show_bug.cgi?id=660122
2011-09-28 19:56:23 +02:00
4e9e91fdce recorder: Use CoglHandle instead of CoglHandle*
The latter has always been wrong and should have been fixed a
while ago, but somehow we overlooked shell-recorder.

https://bugzilla.gnome.org/show_bug.cgi?id=659822
2011-09-28 19:56:23 +02:00
73cc91ba60 update zh_CN translation 2011-09-28 01:01:12 +08:00
0ab0d0860f Uploaded Ukranian 2011-09-27 14:56:16 +03:00
337b399a75 Updated Serbian translation 2011-09-27 02:47:53 +02:00
46f21e81e3 updated Tamil translation 2011-09-27 05:14:59 +05:30
c1300ddbbc Bump version to 3.2.0
Update NEWS
2011-09-26 16:39:21 -04:00
8bd5b1e696 st: Fix crash in theme-node-transition
Setting up the framebuffers for transitions may fail, in which case
the material used for drawing is left uninitialized, so trying to
access it results in a crash.
Instead bail out in this case, which means that we won't paint
anything during the transition - still, drawing errors are better
than crashes ...

https://bugzilla.gnome.org/show_bug.cgi?id=659676
2011-09-26 19:52:36 +02:00
40c5db397d messageTray: unset this._clickedSummaryItem if we are hiding the summary box pointer and don't have a new clicked summary item
This ensures that this._clickedSummaryItem is always unset correctly.

Because we disconnect the signals that have _adjustSummaryBoxPointerPosition()
as a callback when unsetting this._clickedSummaryItem, we no longer call
setPosition() on this._summaryBoxPointer after it is hidden. Calling
setPosition() shows the box pointer again, which previously resulted in
an empty box pointer staying behind when a notification associated with
a tray icon was clicked.

https://bugzilla.gnome.org/show_bug.cgi?id=659862
2011-09-26 13:30:46 -04:00
8b52919b4d Updated Telugu Translation 2011-09-26 22:46:26 +05:30
2859f23038 Fixed some strings in Brazilian Portuguese translation 2011-09-26 10:36:54 -03:00
00384ccb47 telepathyClient: call delay on context when approving a FT or call
Not doing so is considered as a bug as we don't accept the context right away.
It leads to tp-glib returning directly from the AddDispatchOperation() D-Bus
call and so automatically approve the channel if the Shell is the only
approver running.

https://bugzilla.gnome.org/show_bug.cgi?id=660084
2011-09-26 14:49:21 +02:00
0191cc589a Updated Finnish translation 2011-09-26 15:43:09 +03:00
dae6db9b51 [l10n]Updated Catalan (Valencian) translation 2011-09-26 14:26:05 +02:00
4d912c9feb Updated Japanese translation 2011-09-26 11:59:08 +09:00
07c4b46466 Update Czech translation 2011-09-26 02:00:30 +02:00
e9cdce49a3 Updated Russian translation 2011-09-26 01:18:09 +04:00
84c3ce8778 Updated Latvian translation. 2011-09-25 21:55:16 +03:00
d5a32a7fe4 Updated Japanese translation 2011-09-26 01:04:14 +09:00
cc4dfda21b Updated Indonesian translation 2011-09-25 15:41:58 +07:00
703b37aa7b Updated Traditional Chinese translation(Hong Kong and Taiwan) 2011-09-25 14:52:31 +08:00
b433de9022 Updated Bulgarian translation 2011-09-25 08:34:54 +03:00
0c1a22ff95 Updated Slovak translation 2011-09-24 22:57:48 +02:00
4d526e40c3 [l10n] Updated German translation 2011-09-24 20:46:15 +02:00
4586c7b36b Fix display of dates in the Hungarian translation 2011-09-24 19:18:51 +02:00
3d60b73b60 Updated Lithuanian translation 2011-09-24 15:41:38 +03:00
4ef5cd8ef6 Updated Hungarian translation 2011-09-24 01:46:46 +02:00
6959bd19f1 Updated Basque language 2011-09-23 18:19:56 +02:00
17e4ce5ea8 Updated French translation 2011-09-23 18:08:57 +02:00
33094b4988 messageTray: fix notification/keyboard interaction
If the pointer moves from the notification into the keyboard, don't
treat that as moving out of the tray.

https://bugzilla.gnome.org/show_bug.cgi?id=658603
2011-09-23 07:56:45 -04:00
a8fdcffd44 messageTray: move the summary box pointer up when the keyboard shows
If the keyboard is shown when a summary boxpointer is visible (eg,
when opening a chat source), animate the boxpointer up with the tray.

https://bugzilla.gnome.org/show_bug.cgi?id=658603
2011-09-23 07:55:47 -04:00
5adb5411fa keyboard: fix D-Bus name acquisition flags to totally block Antler
We never want the antler keyboard to run if gnome-shell is running, so
grab org.gnome.Caribou.Keyboard without the "allow replacement" flag.

https://bugzilla.gnome.org/show_bug.cgi?id=659865
2011-09-23 07:53:51 -04:00
ff0d11c89c Updated Hebrew translation. 2011-09-23 08:51:57 +03:00
5f6dce2b5c popup-menu: Fix allocation in RTL locales
Commit ed7d4928e5 fixed some width-for-height cases in popup menu items,
but did not consider RTL locales. Fix this.

https://bugzilla.gnome.org/show_bug.cgi?id=659827
2011-09-22 21:52:26 +02:00
a7405e8b39 Updated translation for Afrikaans (af) not including latest strings since freeze 2011-09-22 21:20:29 +02:00
d87c520bad Updated Esperanto translation 2011-09-22 20:29:31 +02:00
24959f8d34 Updated Esperanto translation 2011-09-22 20:26:25 +02:00
6d1432e166 [l10n]Updated Catalan translation 2011-09-22 19:54:11 +02:00
2c7ba2c125 Updated Korean translation 2011-09-23 02:33:19 +09:00
a0ba664c64 messageTray: only update an icon when necessary on notification update
This avoids unnecessarily removing and resetting the icon in the notifications.

This fixes the new chat notification sliding down and up slightly when new
messages are received.

https://bugzilla.gnome.org/show_bug.cgi?id=659768
2011-09-22 13:25:35 -04:00
131da5f523 telepathyClient: update the avatar correctly when it changes
Previously, when the avatar changed, we would not update the summary icon
for the source at all and would only update the notification icon when the
next message was received. Instead, we should update both immediately upon
recieving the signal that the avatar has changed.

https://bugzilla.gnome.org/show_bug.cgi?id=659768
2011-09-22 13:25:35 -04:00
7c6144450a Updated Slovenian translation 2011-09-22 18:06:45 +02:00
4c7369db16 build: Switch to stable cogl/clutter branches for now 2011-09-22 16:35:45 +02:00
f4355de896 Updated Telugu Translation 2011-09-22 19:56:35 +05:30
4a3db9f44d Updated Danish translation 2011-09-22 16:07:11 +02:00
6c0a9ff9cc Updated Brazilian Portuguese translation. Reviewed by Djavan Fagundes <djavanf@gnome.org>. 2011-09-22 09:59:50 -03:00
57b1695fcf keyboard: don't try to move windows out of the way of the keyboard
This code was never tested very well, and has several problems
currently (windows creeping down and to the right, windows snapping to
a different location after you move them). To be fixed in 3.4.

https://bugzilla.gnome.org/show_bug.cgi?id=659643
2011-09-22 07:55:20 -04:00
045c6546cc Add Assamese translation 2011-09-22 12:19:02 +02:00
ce5bd954bf Add Assamese translation 2011-09-22 12:18:08 +02:00
6ef00a4a3b Updated Spanish translation 2011-09-22 11:47:37 +02:00
569d9718a0 Updated Norwegian bokmål translation 2011-09-22 10:10:41 +02:00
00a3a8697f [l10n] Updated German translation 2011-09-22 08:50:50 +02:00
c93444e390 Updated Swedish translation 2011-09-22 06:38:15 +02:00
5e5788ab14 update Punjabi Translation 2011-09-22 06:16:06 +05:30
abf57e6362 Updated Portuguese translation 2011-09-22 00:35:36 +01:00
74c2074d5a Updated Galician translations 2011-09-21 22:51:32 +02:00
b74606312e Updated Polish translation 2011-09-21 22:05:00 +02:00
0c849df4d5 Updated Belarusian translation. 2011-09-21 22:18:23 +03:00
38690d4a09 autorun: mark string as translatable 2011-09-21 21:10:50 +02:00
b64c237cb3 Updated Polish translation 2011-09-21 20:39:04 +02:00
3fbee8e027 configure.ac: switch to tar-ustar
tar-ustar is the GNOME standard and has some small advantages
over the default tar-v7, like support for long file names.
2011-09-21 12:33:11 -04:00
a68e6e3c63 Updated Danish translation 2011-09-21 17:57:09 +02:00
db5a72774d configure: Require gjs 1.29.18 for GC stuff 2011-09-21 10:04:36 -04:00
966f90f24a Updated Hungarian translation 2011-09-21 03:08:49 +02:00
eaa664c023 Updated Portuguese translation 2011-09-21 00:45:47 +01:00
e9282c3987 Bump version to 3.1.92
Update NEWS
2011-09-20 17:16:24 -04:00
ed1f8ed339 Add missing test to Makefile.am 2011-09-20 17:15:41 -04:00
5d0d637eb8 Updated Serbian translation 2011-09-20 22:14:58 +02:00
7e70dfdf4c messageTray: Fix line wrapping
Clutter 1.4 had a bug where it would wrap when it wasn't supposed to, and we
were unknowingly relying on it. Explicitly pass the available width/height
to get a perfect allocation.

https://bugzilla.gnome.org/show_bug.cgi?id=659633
2011-09-20 16:06:06 -04:00
3f61f39ae3 dash: Adjust placeholder size to icon size
The placeholder looks odd near small icons and causes the dash to get wider
when visible and narrower when hidden.

https://bugzilla.gnome.org/show_bug.cgi?id=659210
2011-09-20 21:01:25 +01:00
371f623a3e Updated Latvian translation. 2011-09-20 22:15:44 +03:00
566d566f26 alt-tab: Do not hardcode ALT modifier
While we allow for arbitrary modifiers in keybindings, both the
alt-tab and ctrl-alt-tab popups close when ALT is not present in
the modifier mask, resulting in ALT being de-facto hardcoded.
Instead, pass the actual modifier mask when invoking the popups.

https://bugzilla.gnome.org/show_bug.cgi?id=645200
2011-09-20 21:07:19 +02:00
fb30822860 windowManager: shade the actor, not the texture
Applying the "dim window" effect to the MetaWindowActor has two avantages:
first it avoids triggering bugs where ClutterOffscreenEffect doesn't handle
clone paint correctly. Second, it avoids showing the window as dimmed in
alt-Tab and the overview, which is weird.

The small downside of this is that the shadow becomes slightly gray when
the window dimmed, which is wrong - if we switched from blending with gray
to a combination of desaturation and darkening, this problem wouldn't
happen.

Revert out the addition of startY to the shader, since we don't need it
and fix the application of alpha, since we need to handle alpha correctly
for the shadow.

https://bugzilla.gnome.org/show_bug.cgi?id=659634
2011-09-20 14:56:25 -04:00
526a53bdd4 shell-network-agent: Do not handle VPN secrets
VPN secrets are currently unhandled by the UI code. To avoid
lengthy timeouts, bail out early with an error, so NetworkManager
falls back to the nm-applet agent directly.

https://bugzilla.gnome.org/show_bug.cgi?id=658484
2011-09-20 20:05:21 +02:00
3833124d66 apps: Uniquify application instances explicitly by id
Commit 0af108211c introduced a
regression where applications that appear in multiple categories were
duplicated in the "All Apps" list, because we switched from
uniquifying on desktop file ID to the GMenuTreeEntry.

Switch back to keeping the set of apps based on ID.  To flesh this
out, we keep the ShellApp instance for a given ID around forever, and
when we're loading new contents, we replace the GMenuTreeEntry inside
the app. That means callers still get new data.

We still keep around the running app list, though we could just
recompute it from the app list now.

https://bugzilla.gnome.org/show_bug.cgi?id=659351
2011-09-20 13:56:53 -04:00
e5e1b52abf apps: Unify code for apps/settings loading more
The apps and settings loading code duplicated the part to traverse a
GMenuTree.  Unify this by adding a new function to return a flattened
set.

This will also be useful for a future change to how we store apps -
this way we can look at both the current set of apps and the new set.

https://bugzilla.gnome.org/show_bug.cgi?id=659351
2011-09-20 13:56:53 -04:00
82fc66305d Clear the active network when removing the active access point
When the active AP disappears, it is possible to receive the
"access-point-removed" signal before the "notify::active-ap" (as
dbus-glib + libnm-glib property notifications are not reliable).
In that case, we would remove the AP from the network object, thus
an attempt to update the UI would create an item for an empty
network.

https://bugzilla.gnome.org/show_bug.cgi?id=658150
2011-09-20 19:01:23 +02:00
05e0d5066f Don't create AP items for empty networks
Current code is sometime attempting to create menu items for wifi
networks that have no visible AP. I have no idea why this is
happening, but it should fix the symptoms and avoid exceptions.

https://bugzilla.gnome.org/show_bug.cgi?id=658150
2011-09-20 19:01:01 +02:00
ce2dc84e49 Updated Slovenian translation 2011-09-20 13:08:28 +02:00
eb14ed32ea Updated Russian translation 2011-09-20 12:02:47 +04:00
f97987d0d8 Updated Norwegian bokmål translation 2011-09-20 09:16:33 +02:00
d23d9c3b05 update Punjabi Translation 2011-09-20 07:22:39 +05:30
3ebf6e3bea autorun: don't use a custom size for the hotplug icon
Instead, just use the default MessageTray.Source icon size (24px).

https://bugzilla.gnome.org/show_bug.cgi?id=658004
2011-09-19 20:53:50 -04:00
9f41f5c740 l10n: Updated Italian translation 2011-09-20 00:17:09 +02:00
ae00f86887 panel: allow padding around panel buttons to shrink
for narrow screens (eg, portrait orientation)

https://bugzilla.gnome.org/show_bug.cgi?id=651299
2011-09-19 17:43:54 -04:00
ab67c0f8b0 userMenu: fix line wrapping
The previous wrapping code hardcoded a width in pixels, making it
non-text-zoom-friendly. Specify a CSS width in pts, and fix the
userMenu code to completely opt out of the popupMenu column behavior.
Hack PopupComboBoxMenuItem slightly to deal with the fact that the
pop-up no longer gets setColumnWidth'ed.

https://bugzilla.gnome.org/show_bug.cgi?id=652837
2011-09-19 17:36:13 -04:00
ed7d4928e5 popupMenu: fix a few width-for-height cases
specifically, non-columned menus, and span==-1

https://bugzilla.gnome.org/show_bug.cgi?id=652837
2011-09-19 17:36:13 -04:00
f23239a923 status/keyboard: use correct style class name to fix menu highlight
The keyboard status item doesn't derive from SystemStatusButton, since
it doesn't use an icon. But this meant it wasn't getting the right
class name, and so was using the full-width menu title highlight
rather than the small one. Fix that.
2011-09-19 17:36:13 -04:00
d949920e68 status/keyboard: fix function naming style 2011-09-19 17:36:13 -04:00
a1def85c18 Updated Latvian translation. 2011-09-19 23:30:31 +03:00
dc624f65e4 user-menu: Fix spacing in combobox item
At some time an additional container was added which broke the
existing CSS rule.
2011-09-19 22:06:31 +02:00
361652d028 popup-menu: Use correct St.Align values
It is not St.Align.CENTER, but St.Align.MIDDLE - in contrast to
St.TextAlign, where it *is* CENTER. Yay consistency!
2011-09-19 22:06:31 +02:00
92024b7e54 network-agent: Allow entries to activate default action
Currently entries' 'activate' signal is ignored, so hitting enter
does not have any effect, even if all required information has been
entered.
Instead, connect to the 'activate' signal so that hitting enter
behaves as if the "OK" button had been pressed.

https://bugzilla.gnome.org/show_bug.cgi?id=659133
2011-09-19 21:26:32 +02:00
4e4ce0dd21 network-agent: Focus the first reactive entry
Currently network dialogs don't focus password entries, which means
that rather than entering their password directly, users first have
to click the entry (or tab around the dialog).
Instead, put keyboard focus on the first entry that requires user
input.

https://bugzilla.gnome.org/show_bug.cgi?id=659133
2011-09-19 21:26:32 +02:00
bc0c490ec3 polkit-agent: Remove hack to focus password entry
As dialog buttons used to "steal" the initial key focus, the polkit
dialog delayed focusing the password entry. With buttons no longer
overwriting the manually set focus, this is no longer necessary.

https://bugzilla.gnome.org/show_bug.cgi?id=659133
2011-09-19 21:26:32 +02:00
6d92af17fd modal-dialog: Don't let buttons steal manually-set focus
ModalDialog provides a method to set the initial focus. However,
when adding buttons, the initial focus is always set to the last
button, thus overwriting a previously set manual focus.
Instead, only set the initial key focus if setInitialKeyFocus()
has not been called manually before.

https://bugzilla.gnome.org/show_bug.cgi?id=659133
2011-09-19 21:26:32 +02:00
2140a498a2 StTable: Silence row_span warning for now
This seems to be very noisy and generally harmless so
silence it up for now.

https://bugzilla.gnome.org/show_bug.cgi?id=658939
2011-09-19 21:25:07 +02:00
28349d362c Updated Belarusian translation. 2011-09-19 21:59:18 +03:00
e7af9f98e3 [l10n] Updated German translation 2011-09-19 20:17:24 +02:00
dd6053c5e1 [l10n] Updated German translation 2011-09-19 20:14:48 +02:00
37726a4cb6 app: Don't abort if a .desktop file has no Exec= key
Seen in the wild in nautilus-pastebin-configurator.desktop.
2011-09-19 14:13:20 -04:00
4352cc231e modalDialog: Don't use a for...in loop for iterating over arrays.
for...in loops do not guarantee that the indexes iterate in order. As a
consequence, buttons may appear in an undesired order.
2011-09-19 13:42:47 -04:00
824220356f popup-menu: Add 'sensitive' flag to item parameters
A menu action may not make sense at any time, so add API to mark
an item insensitive to indicate that its action is currently
unavailable, but may become activatable at a later point.

https://bugzilla.gnome.org/show_bug.cgi?id=659270
2011-09-19 18:54:15 +02:00
247ad9d7ab scroll-view-sizing: Add tests for padding / borders
Add tests to verify that the fade works fine with borders and
padding.

https://bugzilla.gnome.org/show_bug.cgi?id=659159
2011-09-19 18:51:07 +02:00
09fe12d0c1 st-scroll-view-fade: Pass a precomputed fade area to the shader
Instead of doing complex computations in the shader just pass in the correct
fade area (taking padding, scrollbars and rtl into account) and just work
with that in the shader.

That fixes a bug where we would fade the scrollbar when padding is present.

https://bugzilla.gnome.org/show_bug.cgi?id=659159
2011-09-19 18:51:01 +02:00
127ef8383b windowManager: Incorporate invisible borders into window dimming effect
Without this, the dim "fade" will start at the top of the untrimmed actor. With
a large enough draggable_border_width setting, this will show no fade at all.

https://bugzilla.gnome.org/show_bug.cgi?id=659302
2011-09-19 12:39:48 -04:00
82eccb566c windowManager: Use an off-screen buffer for window dimming
The way the window dimmer shader is applied will cause rendering errors with
the rounded corners, invisible borders or shaped textures since it doesn't deal
well with the multitexturing used by the MetaShapedTexture. Use an off-screen
buffer to flatten the texture before being applied.

https://bugzilla.gnome.org/show_bug.cgi?id=659302
2011-09-19 12:39:41 -04:00
543b29efe7 userMenu: Update the user information if the object is already loaded
Any time we get a cached user object from the AccountsService, it will
already be loaded.

https://bugzilla.gnome.org/show_bug.cgi?id=658605
2011-09-19 10:50:54 -04:00
0f4ce5dd4e altTab: Fix icon scrolling
Don't depend on the primary monitor position for determining whether we should
scroll, just use our own container's size.

https://bugzilla.gnome.org/show_bug.cgi?id=658239
2011-09-19 10:50:54 -04:00
c23919df15 Silently add chat source in the MessageTray
We don't want the tray bar to open/close quickly when adding a chat because
it happens when user opens the chat from Empathy. The notification will
popup on incoming message anyway.

https://bugzilla.gnome.org/show_bug.cgi?id=657249
2011-09-19 16:19:26 +02:00
2b2a8b4747 ctrlAltTab: don't allow more than one popup
In a normal user session you can't have more than one
popup, because the popup is modal and we don't allow
the popup to show up when there are other modals.

In a GDM session, however, the login dialog is modal, and
we want a popup, so we don't have that same check.

This commit changes the ctrlAltTab manager code to not
allow multiple popups.

https://bugzilla.gnome.org/show_bug.cgi?id=659177
2011-09-19 10:17:19 -04:00
2e48dbf6ee main: Let SWITCH_PANELS keybinding through at login screen
Users depend on being able to switch focus between the panel
and the login screen using ctrl-alt-tab.

Because the login screen has no overview, we were short circuiting
some code that needs to get run to support ctrl-alt-tab.

This commit changes the short-circuit code to only run for user
sessions.

https://bugzilla.gnome.org/show_bug.cgi?id=659177
2011-09-19 10:17:18 -04:00
207917ba45 Updated Slovenian translation 2011-09-19 16:15:44 +02:00
f824b97f3a Updated Polish translation 2011-09-19 15:07:04 +02:00
a5ff2fc68f Updated Spanish translation 2011-09-19 14:57:34 +02:00
4906806c0b Updated Gujarati Translations 2011-09-19 18:10:00 +05:30
d98336a906 updated Tamil translation 2011-09-19 17:51:28 +05:30
9ddd11cdb8 Updated Galician translations 2011-09-19 13:44:45 +02:00
554ad4ef05 keyboard: switch to using the correct gsettings key for enable/disable
https://bugzilla.gnome.org/show_bug.cgi?id=612662
2011-09-19 07:34:02 -04:00
45d8550044 Updated Galician translations 2011-09-19 13:18:59 +02:00
f2b44c1494 Updated Persian translation 2011-09-19 14:37:17 +04:30
bdb28e87a9 Updated Persian translation 2011-09-19 14:35:13 +04:30
8b9592e53e Updated Slovak translation 2011-09-19 11:30:12 +02:00
84f89648a6 Update Simplified Chinese translation. 2011-09-19 09:25:48 +00:00
1174992099 Updated Spanish translation 2011-09-19 10:35:57 +02:00
391a220dc1 gdm: add optional logo to user list
This commit adds the ability to set a small logo
at the login screen for administrators and
distributions.

https://bugzilla.gnome.org/show_bug.cgi?id=658062
2011-09-19 00:08:55 -04:00
43f1d0578b gdm: add fingerprint support
This commit adds the ability to log in with a fingerprint instead
of a password (assuming the user is enrolled and fingerprint
isn't disabled via gsettings)

https://bugzilla.gnome.org/show_bug.cgi?id=657823
2011-09-18 23:32:03 -04:00
d3e35028ca Updated Hungarian translation 2011-09-19 02:00:57 +02:00
61c7d87003 Updated Hungarian translation 2011-09-19 02:00:57 +02:00
20f2fa84a4 Updated Swedish translation 2011-09-18 19:35:23 +02:00
17e269b96c Updated Latvian translation. 2011-09-18 20:16:21 +03:00
6a57ac92ba Updated Spanish translation 2011-09-18 17:23:31 +02:00
07ad03556f Updated POTFILES.in 2011-09-18 14:09:01 +02:00
04c33230c8 Updated Bulgarian translation 2011-09-18 11:40:55 +03:00
083dac630f updated Tamil translation 2011-09-18 14:05:50 +05:30
6375724196 Updated Vietnamese translation 2011-09-18 15:59:43 +10:00
922957c1ae po/vi: import from Damned Lies 2011-09-18 15:34:15 +10:00
cbf7d0e738 vi/po: removed redudant %d 2011-09-18 15:30:50 +10:00
fb81efeecf theme/gdm: shrink entry
commit 8424236daa
set the entry to a specific size to prevent it from
growing for long passwords.

The size is a little too long though, since it makes
the dialog pop out horizontally when showing the entry.

This commit drops it down a few em.

https://bugzilla.gnome.org/show_bug.cgi?id=659370
2011-09-17 23:40:20 -04:00
8466198626 loginDialog: subtract padding when drawing focus line
If there's no scrollbar in the user list it grows as the
user arrows around.  This is because it wasn't taking
padding into account when computing its destination size.

https://bugzilla.gnome.org/show_bug.cgi?id=658469
2011-09-17 23:25:31 -04:00
33718ef7a5 panel: drop dead code
The _userMenu variable never gets initialized anymore,
so remove some code that only gets run when it's defined.

https://bugzilla.gnome.org/show_bug.cgi?id=651299
2011-09-17 23:23:15 -04:00
a94a62764d gdm: add a power button
Making users have to log in to power off the machine isn't a good idea.

This commit adds a power menu similar to the one in the fallback greeter
which offers 3 items:

- Suspend
- Restart
- Power off

https://bugzilla.gnome.org/show_bug.cgi?id=657822
2011-09-17 23:16:20 -04:00
12c98df3db Updated Traditional Chinese translation(Hong Kong and Taiwan) 2011-09-18 08:35:10 +08:00
81909a406f Updated reduced Finnish translation 2011-09-17 22:29:36 +03:00
d291aaa4f2 Updated Galician translations 2011-09-17 21:21:38 +02:00
da36d87e46 Updated Punjabi Translation 2011-09-18 00:42:12 +05:30
42bc09a7ef Updated Polish translation 2011-09-17 20:55:43 +02:00
d0defc592e Updated Belarusian translation. 2011-09-17 20:15:11 +03:00
700f7fbaf3 gdm: replace 'gdm-password' with a constant
It's a little messy to have 'gdm-password' strung all
through the code, so this commit defines a constant up
top and uses that instead.

https://bugzilla.gnome.org/show_bug.cgi?id=657823
2011-09-17 12:53:54 -04:00
74f2d02ac3 Updated Slovenian translation 2011-09-17 18:15:01 +02:00
c865d96f4b Update Simplified Chinese translation. 2011-09-17 16:04:56 +00:00
cd7b9e108c user-menu: Explain why disabling notifications changes IM status
While the current behavior of setting the IM status to "busy" while
notifications are disabled makes sense, as incoming messages are
very likely to be missed, it is not immediately obvious.
Display a transient notification to explain the behavior to the user.

https://bugzilla.gnome.org/show_bug.cgi?id=652718
2011-09-17 17:18:29 +02:00
f54b82f64c global: Initiate *full* GC at idle
While I've been trying to make the GC kick in more often, I've decided
it's a better tradeoff to aggressively GC at "leisure", for multiple
reasons.

We can and should revisit this at a later time, but basically:

* The shell doesn't generate *that* much JS data - garbage collection
  is very fast here.
* Long periods without GC mean we're not calling free() when we
  could, which in turn makes heap fragmentation much worse.
* Ensuring the GC runs at idle makes it much less likely we'll take
  a random large GC hit in the middle of an animation.

https://bugzilla.gnome.org/show_bug.cgi?id=659254
2011-09-17 10:16:35 -04:00
36bfe8c533 memory: Add display of elapsed seconds since a garbage collection
This is useful information for debugging.

https://bugzilla.gnome.org/show_bug.cgi?id=659254
2011-09-17 10:16:35 -04:00
a40d063cb8 Updated Russian translation 2011-09-17 14:14:52 +04:00
ac88a88bfb Updated Norwegian bokmål translation 2011-09-17 11:47:14 +02:00
d89c9b4556 Updated Japanese translation 2011-09-17 13:07:50 +09:00
a07056f5e2 l10n: Updated Italian translation 2011-09-17 02:01:56 +02:00
f91bea3ea5 Updated Portuguese translation 2011-09-17 01:00:25 +01:00
9fbd79316a panel: merge statusBox into rightBox
Simplify the layout in rightBox by getting rid of statusBox, and just
putting everything into rightBox directly.

Simplify the handling of the user menu by adding it like it was a
status icon rather than special-casing it. Rename the "tray_icon"
variables to "status_area" to reflect this better.

https://bugzilla.gnome.org/show_bug.cgi?id=651299
2011-09-16 14:15:49 -04:00
6d89d0b02a panel: remove legacyBox, mix legacy icons in with regular
Legacy trayicons are mostly gone, so remove some of the special-casing
for them to simplify things.

Also, fix panel.addToStatusArea() to interpret its "position" relative
to tray_icon_order, not relative to the existing contents of
statusBox, so that the order that extension icons appear in does not
depend on the order they are loaded in.

https://bugzilla.gnome.org/show_bug.cgi?id=651299
2011-09-16 14:15:49 -04:00
0febcbfa2a userMenu: belatedly rename CSS to match the new filename
https://bugzilla.gnome.org/show_bug.cgi?id=651299
2011-09-16 14:15:48 -04:00
f2f2898fe3 panel: fix part of the panel-corner-highlighting hack
The underline highlights on the panel menu items normally have a 100ms
transition between highlighted and unhighlighted, but the panel corner
graphics can't do that, so we hacked the Activities button and user
menu to have no transition. But in gdm mode, the user menu isn't the
rightmost item any more. Fix this by modifying the CSS from the code
instead.

https://bugzilla.gnome.org/show_bug.cgi?id=651299
2011-09-16 14:15:48 -04:00
f65826b3ba network: Don't notify on connection lost
The design is for applications to do this, basically.  Web browsers,
Evolution, Empathy already display something on network status change.

Note though we need an application API in GIO to monitor network state;
see https://bugzilla.gnome.org/show_bug.cgi?id=620932

https://bugzilla.gnome.org/show_bug.cgi?id=658954
2011-09-16 13:57:14 -04:00
a869007180 calendar: Improve Layout
- align event header with buttons
 - button hovers stretch across fully like menus
 - better padding for month
 - day hover is lighter

https://bugzilla.gnome.org/show_bug.cgi?id=641135
2011-09-16 19:22:12 +02:00
b5fa48f485 status: don't show 'Show Keyboard Layout' on the login screen
It does not make a great amount of sense to have this function
on the login screen. And worse, it does not work, since the greeter
is currently a modal dialog, so interaction with the opening
window is impossible.

https://bugzilla.gnome.org/show_bug.cgi?id=659164
2011-09-16 09:45:11 -04:00
36d564526c build: Fix rule to create .service files
It was always taking the first .service.in file to create all .service
files: org.gnome.Shell.CalendarServer.service.in was the only one being
used.

https://bugzilla.gnome.org/show_bug.cgi?id=659194
2011-09-16 09:21:14 +02:00
063f34b5d3 browser-plugin: Add support for BROWSER_PLUGIN_DIR environment variable
This makes it easy to override where the plugin should be installed.

This is based on what totem does.

https://bugzilla.gnome.org/show_bug.cgi?id=659123
2011-09-16 00:17:59 +02:00
9486ca5975 Updated Slovenian translation 2011-09-15 22:44:09 +02:00
63ead272a9 Updated Slovenian translation 2011-09-15 22:37:02 +02:00
9dfa2ad84e app-display: Remove AppIconMenu::popup
The signal is just duplicating the parent class' ::open-state-changed
signal, so remove it.
2011-09-15 22:01:58 +02:00
523e431ece tests: Add transition test
https://bugzilla.gnome.org/show_bug.cgi?id=658092
2011-09-15 13:27:12 -04:00
768c4a0dd5 Updated Punjabi Translation 2011-09-15 20:49:58 +05:30
fd25cf30ff messageTray: fix a warning
Check for click in keyboardBox rather than Main.keyboard.actor, since
the latter won't exist when the keyboard is hidden.

https://bugzilla.gnome.org/show_bug.cgi?id=658598
2011-09-15 08:34:29 -04:00
1d14488a4f telepathyClient: notify only once per account for connection error
https://bugzilla.gnome.org/show_bug.cgi?id=659050
2011-09-15 10:10:22 +02:00
6e32c97c43 Updated Bulgarian translation 2011-09-15 07:16:02 +03:00
188 changed files with 28260 additions and 14202 deletions

159
NEWS
View File

@ -1,3 +1,162 @@
3.2.1
=====
* Restore the IM state on startup - if you were available in when you logged
out, then you'll be set available again when you log in.
[Florian; #65902, #661485]
* Improve searching for contacts in the overview: search more fields,
show a more meaningful name, require that all search terms match.
[Florian, Matthias; #660580]
* Improve search for applications in the overview: take frequency into
account and tweak match algorithm [Florian; #623372]
* Remove the "Show Password" switch from network password prompts, and
move the functionality to a right-click menu [Florian; #658948]
* Add context menus with Cut/Paste options to most entries [Florian; #659275]
* On screen keyboard:
- Show the keyboard immediately when it's turned enabled [Dan; #659743]
- Fix problem where keyboard would hide when starting to type
in the search entry [Nohemi; #661340]
- Fix problem with keyboard hiding when selected accented characters
[Nohemi; 661707]
* Login mode:
- Allow hitting Enter to select the first user [Ray; #657996]
- Fix flicker of a fingerprint prompt that could show up [Ray; #660492]
- Fix password bullets vanishing during login [Ray; #657894]
- Misc bug fixes and visual tweaks [Ray; #659763, #660919, #661479]
* Display a caps-lock warning in password entries [Florian; #660806]
* Show the state of installed extensions in Looking Glass [Jasper; #660494]
* Load user extensions after system ones [Jasper; #661815]
* Fix problem with many applications showing extra-large icons in
notifications [Marina; #659158]
* Fix a problem where alt-Tab had trouble tracking the current
application with certain applications such as Emacs. [Dan; #645026]
* Fix confusion between different users avatar images [Florian; #660585]
* Remove behavior where you could switch workspaces by bumping
a dragged window in the overview against a screen edge; it was
leftover and just confusing. [Florian; #660838]
* Fix long-standing bug where the Dash in the overview could end up mis-sized
and run off the screen [Florian; #649248]
* Fix automatic launching of applications when media is inserted
[Cosimo; #660821]
* Fix handling of vertically stacked monitors with NVIDIA drivers
[Florian; #661387]
* Translation marking fixes [Jasper, Wouter; #660600]
* Code cleanups and warning fixes [Adel, Dan, Florian, Jasper;
#659822, #659940, #660122, #660358, #660968, #661231]
* Small memory leak fixes [Florian, Jasper; #661231]
* Misc bug fixes [Adel, Florian, Jasper; #659274, #659861, #660166, #660310,
#660397, #660608, #660606, #660674, #660774. #660848, #661151, #661617]
Contributors:
Wouter Bolsterlee, Cosimo Cecchi, Matthias Clasen, Nohemi Fernandez,
Adel Gadllah, Florian Müllner, Jasper St. Pierre, Ray Strode, Dan Winship,
Marina Zhurakhinskaya
Translations:
Tiffany Antopolski [eo], Xandru Armesto [ast], Alexander Shopov,
Ivaylo Valkov [bg], Gil Forcada [ca], Carles Ferrando [ca@valencia],
Mario Blättermann, Paul Seyfert [de], Bruce Cowan [en_GB],
Jorge González, Daniel Mustieles [es], Arash Mousavi [fa], Bruno Brouard [fr],
Seán de Búrca [ga], Fran Diéguez [gl], Gabor Kelemen [hu], Luca Ferretti [it],
Takayuki Kusano [ja], Changwoo Ryu [ko], Erdal Ronahi [ku],
Algimantas Margevičius [lt], Rudolfs Mazurs [lv], Wouter Bolsterlee [nl],
Piotr Drąg [pl], Adorilson Bezerra [pt_BR], Yuri Myasoedov [ru],
Matej Urbančič [sl], Daniel Nylander [sv], Miroslav Nikolić [sr, sr@latin],
Tirumurti Vasudevan [ta], Krishnababu Krothapalli [te], Daniel Korostil [uk],
Nguyễn Thái Ngọc Duy [vi], YunQiang Su [zh_CN]
3.2.0
=====
* Prevent the fallback on-screen keyboard from showing up while
GNOME Shell is running [Dan, #659865]
* Disable code to reposition windows around the on-screen keyboard;
it wasn't finished or working properly. [Dan; #659643]
* Fix interaction between on-screen keyboard and notifications
[Dan; #658603]
* Fix menu-sizing problems in right-to-left locales. [Florian; #659827]
* Update chat icons in the message tray when an avatar image changes
[Marina; #659768]
* Fix problem with empty notification bubbles being left [Marina; #659862]
* Fix problem with chat notifications bouncing when new messages come in.
[Marina; #659768]
* Fix bug that was causing SIP calls to automatically be accepted in some
circumstances [Guillaume; #660084]
* Fix string that should have been marked translatable [Frédéric]
* Fix a crash that could happen during CSS transitions [Florian; #659676]
* Build fixes [Colin, Florian]
Contributors:
Guillaume Desmottes, Florian Müllner, Frédéric Péters, Colin Walters,
Dan Winship, Marina Zhurakhinskaya
Translations:
Friedel Wolff [af], Nilamdyuti Goswami [as], Ihar Hrachyshka [be],
Ivaylo Valkov [bg], Gil Forcada [ca], Carles Ferrando [ca@valencia],
Petr Kovar [cz], Mario Blättermann [de], Kris Thomsen [dk],
Tiffany Antopolski, Kristjan Schmidt [eo], Daniel Mustieles [es],
Inaki Larranaga Murgoitio [eu], Tommi Vainikainen [fi], Bruno Brouard [fr],
Fran Dieguez [gl], Yaron Shahrabani [he], Gabor Kelemen [hu],
Andika Triwidada [id], Jiro Matsuzawa [ja], Changwoo Ryu [ko],
Rudolfs Mazurs [lv], Aurimas Černius [lt], Kjartan Maraas [nb],
A S Alam [pa], Piotr Drąg [pl], Duarte Loreto [pt], Djavan Fagundes,
Rodolfo Ribeiro Gomes, Gabriel F. Vilar [pt_BR], Yuri Myasoedov [ru],
Daniel Nylander [se], Martin Srebotnjak [sl], Michal Štrba [sv],
Krishnababu Krothapalli, Praveen Illa [te], Cheng-Chia Tseng [zh_KH, zh_TW]
3.1.92
======
* Login screen
- Add the ability to set a logo at the top of the user list [Ray; #658062]
- Add fingerprint reader support [Ray; #657823]
- Add a power button offering the choice of Suspend/Restart/Power off
[Ray; #657822]
- Remove the option to view the current keyboad layout [Matthias; #659164]
- Make Control-Alt-Tab work for full keyboard access [Ray; #659177]
* Frequently initiate a full garbage collection; Spidermonkey isn't very good
at tracking the amount of resources we have allocated so this hopefully will
improve memory usage without affecting performance too much [Colin; #659254]
* Stop adding a notification when the network connection is lost
[Colin; #658954]
* When disabling notifications; display a notification
"Your chat status will be set to busy" [Florian; #652718]
* Fix keynav in network dialogs [Florian; #659133]
* Improve calendar styling [Sean; #641135, #651299]
* Shrink padding around panel buttons for narrow screens [Dan; #651299]
* Allow enabling the onscreen keyboard through the accessibility menu
[Dan; #612662]
* Fix problem that was causing VPN secret dialogs to be delayed before showing
[Florian; #658484]
* Make custom-keybindings for the window switcher that don't use alt
work correctly [Florian; #645200]
* Fix duplicate application icons in the Activities Overview [Colin; #659351]
* Bug fixes for dimming windows with attached modal dialogs
[Jasper, Owen; #659302, 659634]
* Add build-time support for BROWSER_PLUGIN_DIR environment variable
[Vincent; #659123]
* Build fixes [Vincent; #659194]
* Code cleanups and test cases
[Adel, Dan, Florian, Jasper; #651299, #658092, #658939]
* Misc bug fixes
[Adel, Colin, Cosimo, Dan, Florian, Giovanni, Jasper, Ray, Xavier;
#651299, #652837, #657249, #658004, #658150, #658239, #658469, #658598,
#658605, #659050, #659159, #659210, #659270, #659370, #659633]
Contributors:
Giovanni Campagna, Cosimo Cecchi, Xavier Claessens, Matthias Clasen,
Rui Matos, Florian Müllner, Jasper St. Pierre, Owen Taylor,
Vincent Untz, Colin Walters, Sean Wilson, Dan Winship
Translations:
Ihar Hrachyshka [be], Alexander Shopov, Ivaylo Valkov [bg],
Mario Blättermann [de], Jorge González, Daniel Mustieles [es],
Arash Mousavi [fa], Ville-Pekka Vainio [fi], Fran Dieguez [gl],
Sweta Kothari [gu], Gabor Kelemen [hu], Jiro Matsuzawa [ja],
Luca Ferretti [it], Rudolfs Mazurs [lv], Kjartan Maraas [nb], A S Alam [pa],
Piotr Drąg [pl], Duarte Loreto [pt], Yuri Myasoedov [ru],
Daniel Nylander [se], Matej Urbančič [sl], Miroslav Nikolić [sr, sr@latin],
Michal Štrba [sv], Tirumurti Vasudevan [ta], Phương Lê Hoàng [vi],
Aron Xu [zh_CN], Chao-Hsiung Liao [zh_HK, zh_TW]
3.1.91.1
========

View File

@ -1,5 +1,5 @@
mozillalibdir = $(libdir)/mozilla/plugins
mozillalibdir = $(BROWSER_PLUGIN_DIR)
mozillalib_LTLIBRARIES = libgnome-shell-browser-plugin.la

View File

@ -1,5 +1,5 @@
AC_PREREQ(2.63)
AC_INIT([gnome-shell],[3.1.91.1],[https://bugzilla.gnome.org/enter_bug.cgi?product=gnome-shell],[gnome-shell])
AC_INIT([gnome-shell],[3.2.1],[https://bugzilla.gnome.org/enter_bug.cgi?product=gnome-shell],[gnome-shell])
AC_CONFIG_HEADERS([config.h])
AC_CONFIG_SRCDIR([src/shell-global.c])
@ -9,7 +9,7 @@ AC_CONFIG_AUX_DIR([config])
AC_SUBST([PACKAGE_NAME], ["$PACKAGE_NAME"])
AC_SUBST([PACKAGE_VERSION], ["$PACKAGE_VERSION"])
AM_INIT_AUTOMAKE([1.10 dist-xz no-dist-gzip foreign])
AM_INIT_AUTOMAKE([1.11 no-dist-gzip dist-xz tar-ustar foreign])
AM_MAINTAINER_MODE([enable])
m4_ifdef([AM_SILENT_RULES],[AM_SILENT_RULES([yes])])
@ -66,8 +66,8 @@ AM_CONDITIONAL(BUILD_RECORDER, $build_recorder)
CLUTTER_MIN_VERSION=1.7.5
GOBJECT_INTROSPECTION_MIN_VERSION=0.10.1
GJS_MIN_VERSION=1.29.15
MUTTER_MIN_VERSION=3.0.0
GJS_MIN_VERSION=1.29.18
MUTTER_MIN_VERSION=3.2.1
FOLKS_MIN_VERSION=0.5.2
GTK_MIN_VERSION=3.0.0
GIO_MIN_VERSION=2.29.10
@ -235,6 +235,9 @@ else
fi
AC_SUBST(SHELL_SYSTEM_CA_FILE,["$with_ca_certificates"])
BROWSER_PLUGIN_DIR="${BROWSER_PLUGIN_DIR:-"\${libdir}/mozilla/plugins"}"
AC_ARG_VAR([BROWSER_PLUGIN_DIR],[Where to install the plugin to])
AC_CONFIG_FILES([
Makefile
data/Makefile

View File

@ -50,6 +50,14 @@
<default>[]</default>
<_summary>History for the looking glass dialog</_summary>
</key>
<key name="saved-im-presence" type="i">
<default>1</default>
<_summary></_summary>
</key>
<key name="saved-session-presence" type="i">
<default>0</default>
<_summary></_summary>
</key>
<child name="clock" schema="org.gnome.shell.clock"/>
<child name="calendar" schema="org.gnome.shell.calendar"/>
<child name="recorder" schema="org.gnome.shell.recorder"/>
@ -69,13 +77,6 @@
<schema id="org.gnome.shell.keyboard" path="/org/gnome/shell/keyboard/"
gettext-domain="@GETTEXT_PACKAGE@">
<key name="show-keyboard" type="b">
<default>false</default>
<_summary>Show the onscreen keyboard</_summary>
<_description>
If true, display onscreen keyboard.
</_description>
</key>
<key name="keyboard-type" type="s">
<default>'touch'</default>
<_summary>Which keyboard to use</_summary>

View File

@ -1,5 +1,5 @@
#version 110
uniform sampler2D sampler0;
uniform sampler2D tex;
uniform float fraction;
uniform float height;
const float c = -0.2;
@ -12,15 +12,16 @@ mat4 contrast = mat4 (1.0 + c, 0.0, 0.0, 0.0,
vec4 off = vec4(0.633, 0.633, 0.633, 0);
void main()
{
vec4 color = texture2D(sampler0, gl_TexCoord[0].st);
float y = height * gl_TexCoord[0][1];
vec4 color = texture2D(tex, cogl_tex_coord_in[0].xy);
float y = height * cogl_tex_coord_in[0].y;
// To reduce contrast, blend with a mid gray
gl_FragColor = color * contrast - off * c;
cogl_color_out = color * contrast - off * c * color.a;
// We only fully dim at a distance of BORDER_MAX_HEIGHT from the edge and
// We only fully dim at a distance of BORDER_MAX_HEIGHT from the top and
// when the fraction is 1.0. For other locations and fractions we linearly
// interpolate back to the original undimmed color.
gl_FragColor = color + (gl_FragColor - color) * min(y / border_max_height, 1.0);
gl_FragColor = color + (gl_FragColor - color) * fraction;
// interpolate back to the original undimmed color, so the top of the window
// is at full color.
cogl_color_out = color + (cogl_color_out - color) * max(min(y / border_max_height, 1.0), 0.0);
cogl_color_out = color + (cogl_color_out - color) * fraction;
}

View File

@ -30,6 +30,10 @@
min-width: 350px;
}
.login-dialog-prompt-fingerprint-message {
font-size: 10.5pt;
}
.login-dialog-user-list-view {
-st-vfade-offset: 1em;
}
@ -94,8 +98,12 @@
color: #666666;
}
.login-dialog-not-listed-button:hover .login-dialog-not-listed-label {
color: white;
}
.login-dialog-prompt-layout {
padding-bottom: 64px;
padding-bottom: 32px;
}
.login-dialog-prompt-label {
color: white;
@ -110,7 +118,17 @@
background-color: white;
caret-color: black;
caret-size: 1px;
width: 23em;
width: 15em;
}
.login-dialog-prompt-entry .capslock-warning {
icon-size: 16px;
warning-color: #999;
}
.login-dialog-prompt-entry:insensitive {
color: rgba(0,0,0,0.7);
border: 2px solid #565656;
}
.login-dialog-session-list {

View File

@ -164,6 +164,10 @@ StTooltip StLabel {
background-color: #4c4c4c;
}
.popup-menu-item:insensitive {
color: #9f9f9f;
}
.popup-image-menu-item {
}
@ -276,12 +280,12 @@ StTooltip StLabel {
background-color: black;
border-image: url("panel-border.svg") 1;
font-size: 10.5pt;
font-weight: bold;
height: 1.86em;
}
#panelLeft, #panelCenter, #panelRight {
#panelLeft, #panelCenter {
spacing: 4px;
font-weight: bold;
}
#panelLeft:ltr {
@ -335,7 +339,8 @@ StTooltip StLabel {
}
.panel-button {
padding: 0px 12px;
-natural-hpadding: 12px;
-minimum-hpadding: 6px;
font-weight: bold;
color: #ccc;
transition-duration: 100;
@ -355,9 +360,9 @@ StTooltip StLabel {
text-shadow: black 0px 2px 2px;
}
#statusTray > .panel-button:active,
#statusTray > .panel-button:checked,
#statusTray > .panel-button:focus {
.panel-status-button:active,
.panel-status-button:checked,
.panel-status-button:focus {
background-image: url("panel-button-highlight-narrow.svg");
}
@ -371,19 +376,7 @@ StTooltip StLabel {
-boxpointer-gap: 4px
}
/* The rounded panel corners we draw don't
* support transitions, so disable transitions
* for the buttons at the left/right edges
*/
#panelActivities {
transition-duration: 0;
}
#panelStatus {
transition-duration: 0;
}
#panelStatusMenu {
#panelUserMenu {
spacing: 4px;
}
@ -410,6 +403,7 @@ StTooltip StLabel {
.status-chooser-user-name {
font-weight: bold;
font-size: 1.3em;
min-width: 120pt;
}
.status-chooser-combo {
@ -426,24 +420,10 @@ StTooltip StLabel {
}
.status-chooser-status-item,
.status-chooser-combo > .popup-combobox-item {
.status-chooser-combo .popup-combobox-item {
spacing: .4em;
}
#legacyTray {
spacing: 14px;
padding-left: 14px;
}
#legacyTray:rtl {
padding-left: 0px;
padding-right: 14px;
}
#legacyTray:compact {
spacing: 8px;
}
.system-status-icon {
icon-size: 1.14em;
}
@ -531,8 +511,6 @@ StTooltip StLabel {
.dash-placeholder {
background-image: url("dash-placeholder.svg");
height: 27px;
width: 48px;
}
#viewSelector {
@ -929,7 +907,7 @@ StTooltip StLabel {
font-weight: bold;
}
.lg-extension-actions {
.lg-extension-meta {
spacing: 6px;
}
@ -951,7 +929,7 @@ StTooltip StLabel {
.calendar-vertical-separator {
-stipple-width: 1px;
-stipple-color: #505050;
width: 1.5em;
width: 0.3em;
}
#calendarPopup {
@ -974,13 +952,14 @@ StTooltip StLabel {
.calendar-month-label {
color: #666666;
font-size: 7.5pt;
padding: 2px;
padding-bottom: 8px;
padding-top: 8px;
font-weight: bold;
}
.calendar-change-month-back {
width: 20px;
height: 20px;
width: 18px;
height: 12px;
background-image: url("calendar-arrow-left.svg");
border-radius: 4px;
}
@ -997,8 +976,8 @@ StTooltip StLabel {
}
.calendar-change-month-forward {
width: 20px;
height: 20px;
width: 18px;
height: 12px;
background-image: url("calendar-arrow-right.svg");
border-radius: 4px;
}
@ -1030,6 +1009,7 @@ StTooltip StLabel {
.calendar-day-base:hover {
background-color: #777777;
color: #fff;
}
.calendar-day-base:active {
@ -1038,6 +1018,7 @@ StTooltip StLabel {
.calendar-day-heading {
color: #666666;
padding-top: 1em;
}
.calendar-week-number {
@ -1100,7 +1081,8 @@ StTooltip StLabel {
font-size: 9pt;
font-weight: bold;
color: rgba(153, 153, 153, 1.0);
padding-left: 0.3em;
padding-left: 1.8em;
padding-top: 0.8em;
}
.events-day-header:rtl {
@ -1925,6 +1907,12 @@ StTooltip StLabel {
border: 2px solid #3465a4;
}
.polkit-dialog-password-entry .capslock-warning {
icon-size: 16px;
warning-color: #999;
padding: 0 4px;
}
.polkit-dialog-error-label {
font-size: 10pt;
color: #ffff00;
@ -1943,14 +1931,6 @@ StTooltip StLabel {
padding-bottom: 8px;
}
.network-dialog-show-password-checkbox {
padding-top: 5px;
padding-bottom: 5px;
font-size: 10pt;
color: white;
spacing: 10px;
}
.network-dialog-secret-table {
spacing-rows: 15px;
}

View File

@ -3,7 +3,10 @@ jsdir = $(pkgdatadir)/js
nobase_dist_js_DATA = \
gdm/batch.js \
gdm/consoleKit.js \
gdm/fingerprint.js \
gdm/loginDialog.js \
gdm/powerMenu.js \
misc/config.js \
misc/docInfo.js \
misc/fileUtils.js \
@ -43,6 +46,7 @@ nobase_dist_js_DATA = \
ui/messageTray.js \
ui/modalDialog.js \
ui/networkAgent.js \
ui/shellEntry.js \
ui/shellMountOperation.js \
ui/notificationDaemon.js \
ui/overview.js \

View File

@ -1,5 +1,5 @@
/* -*- mode: js2; js2-basic-offset: 4; indent-tabs-mode: nil -*-
*
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
/*
* Copyright 2011 Red Hat, Inc
*
* This program is free software; you can redistribute it and/or modify

32
js/gdm/consoleKit.js Normal file
View File

@ -0,0 +1,32 @@
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
const DBus = imports.dbus;
const ConsoleKitManagerIface = {
name: 'org.freedesktop.ConsoleKit.Manager',
methods: [{ name: 'CanRestart',
inSignature: '',
outSignature: 'b' },
{ name: 'CanStop',
inSignature: '',
outSignature: 'b' },
{ name: 'Restart',
inSignature: '',
outSignature: '' },
{ name: 'Stop',
inSignature: '',
outSignature: '' }]
};
function ConsoleKitManager() {
this._init();
};
ConsoleKitManager.prototype = {
_init: function() {
DBus.system.proxifyObject(this,
'org.freedesktop.ConsoleKit',
'/org/freedesktop/ConsoleKit/Manager');
}
};
DBus.proxifyPrototype(ConsoleKitManager.prototype, ConsoleKitManagerIface);

26
js/gdm/fingerprint.js Normal file
View File

@ -0,0 +1,26 @@
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
const DBus = imports.dbus;
const Lang = imports.lang;
const Shell = imports.gi.Shell;
const Signals = imports.signals;
const FprintManagerIface = {
name: 'net.reactivated.Fprint.Manager',
methods: [{ name: 'GetDefaultDevice',
inSignature: '',
outSignature: 'o' }]
};
function FprintManager() {
this._init();
};
FprintManager.prototype = {
_init: function() {
DBus.system.proxifyObject(this,
'net.reactivated.Fprint',
'/net/reactivated/Fprint/Manager');
}
};
DBus.proxifyPrototype(FprintManager.prototype, FprintManagerIface);

View File

@ -1,5 +1,5 @@
/* -*- mode: js2; js2-basic-offset: 4; indent-tabs-mode: nil -*-
*
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
/*
* Copyright 2011 Red Hat, Inc
*
* This program is free software; you can redistribute it and/or modify
@ -33,15 +33,25 @@ const St = imports.gi.St;
const GdmGreeter = imports.gi.GdmGreeter;
const Batch = imports.gdm.batch;
const DBus = imports.dbus;
const Fprint = imports.gdm.fingerprint;
const Lightbox = imports.ui.lightbox;
const Main = imports.ui.main;
const ModalDialog = imports.ui.modalDialog;
const Tweener = imports.ui.tweener;
const _PASSWORD_SERVICE_NAME = 'gdm-password';
const _FINGERPRINT_SERVICE_NAME = 'gdm-fingerprint';
const _FADE_ANIMATION_TIME = 0.16;
const _RESIZE_ANIMATION_TIME = 0.25;
const _SCROLL_ANIMATION_TIME = 2.0;
const _TIMED_LOGIN_IDLE_THRESHOLD = 5.0;
const _LOGO_ICON_NAME_SIZE = 48;
const _LOGIN_SCREEN_SCHEMA = 'org.gnome.login-screen';
const _FINGERPRINT_AUTHENTICATION_KEY = 'enable-fingerprint-authentication';
const _LOGO_KEY = 'logo';
let _loginDialog = null;
@ -246,12 +256,15 @@ UserListItem.prototype = {
showFocusAnimation: function(time) {
let hold = new Batch.Hold();
let node = this.actor.get_theme_node();
let padding = node.get_horizontal_padding();
let box = this._verticalBox.get_allocation_box();
Tweener.removeTweens(this._focusBin);
this._focusBin.width = 0;
Tweener.addTween(this._focusBin,
{ width: box.x2 - box.x1,
{ width: (box.x2 - box.x1 - padding),
time: time,
transition: 'linear',
onComplete: function() {
@ -284,6 +297,20 @@ UserList.prototype = {
x_align: St.Align.START,
y_align: St.Align.MIDDLE });
this._items = {};
this.actor.connect('key-focus-in', Lang.bind(this, this._moveFocusToItems));
},
_moveFocusToItems: function() {
let hasItems = Object.keys(this._items).length > 0;
if (!hasItems)
return;
if (global.stage.get_key_focus() != this.actor)
return;
this.actor.navigate_focus(null, Gtk.DirectionType.TAB_FORWARD, false);
},
_showItem: function(item) {
@ -489,6 +516,8 @@ UserList.prototype = {
item.showFocusAnimation(0);
}));
this._moveFocusToItems();
this.emit('item-added', item);
},
@ -681,10 +710,13 @@ SessionList.prototype = {
let ids = GdmGreeter.get_session_ids();
ids.sort();
if (ids.length <= 1)
if (ids.length <= 1) {
this._box.hide();
else
this._button.hide();
} else {
this._button.show();
this._box.show();
}
for (let i = 0; i < ids.length; i++) {
let [sessionName, sessionDescription] = GdmGreeter.get_session_name_and_description(ids[i]);
@ -734,7 +766,7 @@ LoginDialog.prototype = {
this._greeterClient.open_connection();
this._greeterClient.call_start_conversation('gdm-password');
this._greeterClient.call_start_conversation(_PASSWORD_SERVICE_NAME);
this._greeterClient.connect('reset',
Lang.bind(this, this._onReset));
@ -757,6 +789,17 @@ LoginDialog.prototype = {
this._greeterClient.connect('conversation-stopped',
Lang.bind(this, this._onConversationStopped));
this._settings = new Gio.Settings({ schema: _LOGIN_SCREEN_SCHEMA });
this._fprintManager = new Fprint.FprintManager();
this._startFingerprintConversationIfNeeded();
this._settings.connect('changed::' + _LOGO_KEY,
Lang.bind(this, this._updateLogo));
this._logoBox = new St.Bin({ style_class: 'login-dialog-logo-box' });
this.contentLayout.add(this._logoBox);
this._updateLogo();
this._titleLabel = new St.Label({ style_class: 'login-dialog-title',
text: C_("title", "Sign In") });
@ -801,6 +844,12 @@ LoginDialog.prototype = {
x_fill: true,
y_fill: false,
x_align: St.Align.START });
// translators: this message is shown below the password entry field
// to indicate the user can swipe their finger instead
this._promptFingerprintMessage = new St.Label({ text: _("(or swipe finger)"),
style_class: 'login-dialog-prompt-fingerprint-message' });
this._promptFingerprintMessage.hide();
this._promptBox.add(this._promptFingerprintMessage);
this._sessionList = new SessionList();
this._sessionList.connect('session-activated',
@ -848,18 +897,51 @@ LoginDialog.prototype = {
this._onUserListActivated(item);
}));
},
_startFingerprintConversationIfNeeded: function() {
this._haveFingerprintReader = false;
if (!this._settings.get_boolean(_FINGERPRINT_AUTHENTICATION_KEY))
return;
this._fprintManager.GetDefaultDeviceRemote(DBus.CALL_FLAG_START, Lang.bind(this,
function(device, error) {
if (!error && device)
this._haveFingerprintReader = true;
if (this._haveFingerprintReader)
this._greeterClient.call_start_conversation(_FINGERPRINT_SERVICE_NAME);
}));
},
_updateLogo: function() {
this._logoBox.child = null;
let path = this._settings.get_string(_LOGO_KEY);
if (path) {
let file = Gio.file_new_for_path(path);
let uri = file.get_uri();
let textureCache = St.TextureCache.get_default();
this._logoBox.child = textureCache.load_uri_async(uri, -1, _LOGO_ICON_NAME_SIZE);
}
},
_onReset: function(client, serviceName) {
this._greeterClient.call_start_conversation('gdm-password');
this._greeterClient.call_start_conversation(_PASSWORD_SERVICE_NAME);
this._startFingerprintConversationIfNeeded();
let tasks = [this._hidePrompt,
new Batch.ConcurrentBatch(this, [this._fadeInTitleLabel,
this._fadeInNotListedButton]),
this._fadeInNotListedButton,
this._fadeInLogo]),
function() {
this._sessionList.close();
this._promptFingerprintMessage.hide();
this._userList.actor.show();
this._userList.actor.opacity = 255;
return this._userList.showItems();
@ -881,10 +963,28 @@ LoginDialog.prototype = {
},
_onInfo: function(client, serviceName, info) {
// We don't display fingerprint messages, because they
// have words like UPEK in them. Instead we use the messages
// as a cue to display our own message.
if (serviceName == _FINGERPRINT_SERVICE_NAME &&
this._haveFingerprintReader &&
(!this._promptFingerprintMessage.visible ||
this._promptFingerprintMessage.opacity != 255)) {
_fadeInActor(this._promptFingerprintMessage);
return;
}
if (serviceName != _PASSWORD_SERVICE_NAME)
return;
Main.notifyError(info);
},
_onProblem: function(client, serviceName, problem) {
// we don't want to show auth failed messages to
// users who haven't enrolled their fingerprint.
if (serviceName != _PASSWORD_SERVICE_NAME)
return;
Main.notifyError(problem);
},
@ -901,6 +1001,13 @@ LoginDialog.prototype = {
return _fadeInActor(this._promptEntry);
},
function() {
// Show it with 0 opacity so we preallocate space for it
// in the event we need to fade in the message
this._promptFingerprintMessage.opacity = 0;
this._promptFingerprintMessage.show();
},
function() {
return _fadeInActor(this._promptBox);
},
@ -969,6 +1076,9 @@ LoginDialog.prototype = {
},
function() {
this._promptFingerprintMessage.hide();
this._promptEntry.reactive = true;
this._promptEntry.remove_style_pseudo_class('insensitive');
this._promptEntry.set_text('');
}];
@ -984,7 +1094,8 @@ LoginDialog.prototype = {
function() {
let _text = this._promptEntry.get_text();
this._promptEntry.set_text('');
this._promptEntry.reactive = false;
this._promptEntry.add_style_pseudo_class('insensitive');
this._greeterClient.call_answer_query(serviceName, _text);
}];
@ -992,12 +1103,20 @@ LoginDialog.prototype = {
return batch.run();
},
_onInfoQuery: function(client, serviceName, question) {
// We only expect questions to come from the main auth service
if (serviceName != _PASSWORD_SERVICE_NAME)
return;
this._promptEntry.set_text('');
this._promptEntry.clutter_text.set_password_char('');
this._askQuestion(serviceName, question);
},
_onSecretInfoQuery: function(client, serviceName, secretQuestion) {
// We only expect secret requests to come from the main auth service
if (serviceName != _PASSWORD_SERVICE_NAME)
return;
this._promptEntry.set_text('');
this._promptEntry.clutter_text.set_password_char('\u25cf');
this._askQuestion(serviceName, secretQuestion);
@ -1134,7 +1253,14 @@ LoginDialog.prototype = {
},
_onConversationStopped: function(client, serviceName) {
this._greeterClient.call_cancel();
// if the password service fails, then cancel everything.
// But if, e.g., fingerprint fails, still give
// password authentication a chance to succeed
if (serviceName == _PASSWORD_SERVICE_NAME) {
this._greeterClient.call_cancel();
} else if (serviceName == _FINGERPRINT_SERVICE_NAME) {
_fadeOutActor(this._promptFingerprintMessage);
}
},
_onNotListedClicked: function(user) {
@ -1151,16 +1277,25 @@ LoginDialog.prototype = {
},
new Batch.ConcurrentBatch(this, [this._fadeOutTitleLabel,
this._fadeOutNotListedButton]),
this._fadeOutNotListedButton,
this._fadeOutLogo]),
function() {
this._greeterClient.call_begin_verification('gdm-password');
this._greeterClient.call_begin_verification(_PASSWORD_SERVICE_NAME);
}];
let batch = new Batch.ConsecutiveBatch(this, tasks);
batch.run();
},
_fadeInLogo: function() {
return _fadeInActor(this._logoBox);
},
_fadeOutLogo: function() {
return _fadeOutActor(this._logoBox);
},
_fadeInTitleLabel: function() {
return _fadeInActor(this._titleLabel);
},
@ -1196,7 +1331,8 @@ LoginDialog.prototype = {
},
new Batch.ConcurrentBatch(this, [this._fadeOutTitleLabel,
this._fadeOutNotListedButton]),
this._fadeOutNotListedButton,
this._fadeOutLogo]),
function() {
return this._userList.shrinkToNaturalHeight();
@ -1204,8 +1340,11 @@ LoginDialog.prototype = {
function() {
let userName = activatedItem.user.get_user_name();
this._greeterClient.call_begin_verification_for_user('gdm-password',
this._greeterClient.call_begin_verification_for_user(_PASSWORD_SERVICE_NAME,
userName);
if (this._haveFingerprintReader)
this._greeterClient.call_begin_verification_for_user(_FINGERPRINT_SERVICE_NAME, userName);
}];
this._user = activatedItem.user;

146
js/gdm/powerMenu.js Normal file
View File

@ -0,0 +1,146 @@
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
/*
* Copyright 2011 Red Hat, Inc
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
* 02111-1307, USA.
*/
const Lang = imports.lang;
const UPowerGlib = imports.gi.UPowerGlib;
const ConsoleKit = imports.gdm.consoleKit;
const PanelMenu = imports.ui.panelMenu;
const PopupMenu = imports.ui.popupMenu;
function PowerMenuButton() {
this._init();
}
PowerMenuButton.prototype = {
__proto__: PanelMenu.SystemStatusButton.prototype,
_init: function() {
PanelMenu.SystemStatusButton.prototype._init.call(this, 'system-shutdown', null);
this._consoleKitManager = new ConsoleKit.ConsoleKitManager();
this._upClient = new UPowerGlib.Client();
this._createSubMenu();
this._upClient.connect('notify::can-suspend',
Lang.bind(this, this._updateHaveSuspend));
this._updateHaveSuspend();
// ConsoleKit doesn't send notifications when shutdown/reboot
// are disabled, so we update the menu item each time the menu opens
this.menu.connect('open-state-changed', Lang.bind(this,
function(menu, open) {
if (open) {
this._updateHaveShutdown();
this._updateHaveRestart();
}
}));
this._updateHaveShutdown();
this._updateHaveRestart();
},
_updateVisibility: function() {
if (!this._haveSuspend && !this._haveShutdown && !this._haveRestart)
this.actor.hide();
else
this.actor.show();
},
_updateHaveShutdown: function() {
this._consoleKitManager.CanStopRemote(Lang.bind(this,
function(result, error) {
if (!error)
this._haveShutdown = result;
else
this._haveShutdown = false;
if (this._haveShutdown) {
this._powerOffItem.actor.show();
} else {
this._powerOffItem.actor.hide();
}
this._updateVisibility();
}));
},
_updateHaveRestart: function() {
this._consoleKitManager.CanRestartRemote(Lang.bind(this,
function(result, error) {
if (!error)
this._haveRestart = result;
else
this._haveRestart = false;
if (this._haveRestart) {
this._restartItem.actor.show();
} else {
this._restartItem.actor.hide();
}
this._updateVisibility();
}));
},
_updateHaveSuspend: function() {
this._haveSuspend = this._upClient.get_can_suspend();
if (this._haveSuspend)
this._suspendItem.actor.show();
else
this._suspendItem.actor.hide();
this._updateVisibility();
},
_createSubMenu: function() {
let item;
item = new PopupMenu.PopupMenuItem(_("Suspend"));
item.connect('activate', Lang.bind(this, this._onActivateSuspend));
this.menu.addMenuItem(item);
this._suspendItem = item;
item = new PopupMenu.PopupMenuItem(_("Restart"));
item.connect('activate', Lang.bind(this, this._onActivateRestart));
this.menu.addMenuItem(item);
this._restartItem = item;
item = new PopupMenu.PopupMenuItem(_("Power Off"));
item.connect('activate', Lang.bind(this, this._onActivatePowerOff));
this.menu.addMenuItem(item);
this._powerOffItem = item;
},
_onActivateSuspend: function() {
if (this._haveSuspend)
this._upClient.suspend_sync(null);
},
_onActivateRestart: function() {
if (this._haveRestart)
this._consoleKitManager.RestartRemote();
},
_onActivatePowerOff: function() {
if (this._haveShutdown)
this._consoleKitManager.StopRemote();
}
};

View File

@ -1,4 +1,5 @@
/* mode: js2; indent-tabs-mode: nil; tab-size: 4 */
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
/* The name of this package (not localized) */
const PACKAGE_NAME = '@PACKAGE_NAME@';
/* The version of this package */

View File

@ -1,4 +1,4 @@
/* -*- mode: js2; js2-basic-offset: 4; indent-tabs-mode: nil -*- */
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
const St = imports.gi.St;
const Shell = imports.gi.Shell;

View File

@ -1,3 +1,5 @@
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
const Gio = imports.gi.Gio;
const GLib = imports.gi.GLib;

View File

@ -1,4 +1,4 @@
/* -*- mode: js2; js2-basic-offset: 4; indent-tabs-mode: nil -*- */
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
/*
* This function is intended to extend the String object and provide

View File

@ -1,4 +1,4 @@
/* -*- mode: js2; js2-basic-offset: 4; indent-tabs-mode: nil -*- */
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
const DBus = imports.dbus;
const Lang = imports.lang;
@ -78,7 +78,7 @@ function Inhibitor(objectPath) {
Inhibitor.prototype = {
_init: function(objectPath) {
DBus.session.proxifyObject(this,
"org.gnome.SessionManager",
'org.gnome.SessionManager',
objectPath);
this.isLoaded = false;
this._loadingPropertiesCount = InhibitorIface.properties.length;
@ -94,7 +94,7 @@ Inhibitor.prototype = {
if (this._loadingPropertiesCount == 0) {
this.isLoaded = true;
this.emit("is-loaded");
this.emit('is-loaded');
}
}));
}

View File

@ -1,4 +1,4 @@
/* -*- mode: js2; js2-basic-offset: 4; indent-tabs-mode: nil -*- */
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
const Lang = imports.lang;
const Signals = imports.signals;

View File

@ -1,4 +1,4 @@
// -*- mode: js2; indent-tabs-mode: nil; js2-basic-offset: 4 -*-
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
const DBus = imports.dbus;
const Lang = imports.lang;

View File

@ -1,4 +1,4 @@
/* -*- mode: js2; js2-basic-offset: 4; indent-tabs-mode: nil -*- */
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
// parse:
// @params: caller-provided parameter object, or %null

View File

@ -1,4 +1,4 @@
/* -*- mode: js2; js2-basic-offset: 4; indent-tabs-mode: nil -*- */
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
const DBus = imports.dbus;
const Lang = imports.lang;

View File

@ -1,4 +1,4 @@
/* -*- mode: js2; js2-basic-offset: 4; indent-tabs-mode: nil -*- */
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
const Gdk = imports.gi.Gdk;
const Gio = imports.gi.Gio;

View File

@ -1,4 +1,4 @@
/* -*- mode: js2; js2-basic-offset: 4; indent-tabs-mode: nil -*- */
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
const Main = imports.ui.main;
const Scripting = imports.ui.scripting;

View File

@ -1,4 +1,4 @@
/* -*- mode: js2; js2-basic-offset: 4; indent-tabs-mode: nil -*- */
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
const Clutter = imports.gi.Clutter;
const Gdk = imports.gi.Gdk;
@ -31,6 +31,18 @@ function mod(a, b) {
return (a + b) % b;
}
function primaryModifier(mask) {
if (mask == 0)
return 0;
let primary = 1;
while (mask > 1) {
mask >>= 1;
primary <<= 1;
}
return primary;
}
function AltTabPopup() {
this._init();
}
@ -48,6 +60,7 @@ AltTabPopup.prototype = {
this.actor.connect('destroy', Lang.bind(this, this._onDestroy));
this._haveModal = false;
this._modifierMask = 0;
this._currentApp = 0;
this._currentWindow = -1;
@ -121,16 +134,46 @@ AltTabPopup.prototype = {
}
},
show : function(backward, binding) {
_getAppLists: function() {
let tracker = Shell.WindowTracker.get_default();
let appSys = Shell.AppSystem.get_default();
let apps = appSys.get_running ();
let allApps = appSys.get_running ();
if (!apps.length)
let screen = global.screen;
let display = screen.get_display();
let windows = display.get_tab_list(Meta.TabList.NORMAL, screen,
screen.get_active_workspace());
// windows is only the windows on the current workspace. For
// each one, if it corresponds to an app we know, move that
// app from allApps to apps.
let apps = [];
for (let i = 0; i < windows.length && allApps.length != 0; i++) {
let app = tracker.get_window_app(windows[i]);
let index = allApps.indexOf(app);
if (index != -1) {
apps.push(app);
allApps.splice(index, 1);
}
}
// Now @apps is a list of apps on the current workspace, in
// standard Alt+Tab order (MRU except for minimized windows),
// and allApps is a list of apps that only appear on other
// workspaces, sorted by user_time, which is good enough.
return [apps, allApps];
},
show : function(backward, binding, mask) {
let [localApps, otherApps] = this._getAppLists();
if (localApps.length == 0 && otherApps.length == 0)
return false;
if (!Main.pushModal(this.actor))
return false;
this._haveModal = true;
this._modifierMask = primaryModifier(mask);
this.actor.connect('key-press-event', Lang.bind(this, this._keyPressEvent));
this.actor.connect('key-release-event', Lang.bind(this, this._keyReleaseEvent));
@ -138,7 +181,7 @@ AltTabPopup.prototype = {
this.actor.connect('button-press-event', Lang.bind(this, this._clickedOutside));
this.actor.connect('scroll-event', Lang.bind(this, this._onScroll));
this._appSwitcher = new AppSwitcher(apps, this);
this._appSwitcher = new AppSwitcher(localApps, otherApps, this);
this.actor.add_actor(this._appSwitcher.actor);
this._appSwitcher.connect('item-activated', Lang.bind(this, this._appActivated));
this._appSwitcher.connect('item-entered', Lang.bind(this, this._appEntered));
@ -179,7 +222,7 @@ AltTabPopup.prototype = {
// details.) So we check now. (Have to do this after updating
// selection.)
let [x, y, mods] = global.get_pointer();
if (!(mods & Gdk.ModifierType.MOD1_MASK)) {
if (!(mods & this._modifierMask)) {
this._finish();
return false;
}
@ -256,7 +299,7 @@ AltTabPopup.prototype = {
_keyReleaseEvent : function(actor, event) {
let [x, y, mods] = global.get_pointer();
let state = mods & Clutter.ModifierType.MOD1_MASK;
let state = mods & this._modifierMask;
if (state == 0)
this._finish();
@ -636,11 +679,10 @@ SwitcherList.prototype = {
this._items[this._highlighted].add_style_pseudo_class('selected');
}
let monitor = Main.layoutManager.primaryMonitor;
let itemSize = this._items[index].allocation.x2 - this._items[index].allocation.x1;
let [posX, posY] = this._items[index].get_transformed_position();
posX += this.actor.x;
if (posX + itemSize > monitor.width + monitor.x)
let [absItemX, absItemY] = this._items[index].get_transformed_position();
let [result, posX, posY] = this.actor.transform_stage_point(absItemX, 0);
let [containerWidth, containerHeight] = this.actor.get_transformed_size();
if (posX + this._items[index].get_width() > containerWidth)
this._scrollToRight();
else if (posX < 0)
this._scrollToLeft();
@ -833,33 +875,32 @@ AppIcon.prototype = {
}
};
function AppSwitcher(apps, altTabPopup) {
this._init(apps, altTabPopup);
function AppSwitcher() {
this._init.apply(this, arguments);
}
AppSwitcher.prototype = {
__proto__ : SwitcherList.prototype,
_init : function(apps, altTabPopup) {
_init : function(localApps, otherApps, altTabPopup) {
SwitcherList.prototype._init.call(this, true);
// Construct the AppIcons, sort by time, add to the popup
// Construct the AppIcons, add to the popup
let activeWorkspace = global.screen.get_active_workspace();
let workspaceIcons = [];
let otherIcons = [];
for (let i = 0; i < apps.length; i++) {
let appIcon = new AppIcon(apps[i]);
for (let i = 0; i < localApps.length; i++) {
let appIcon = new AppIcon(localApps[i]);
// Cache the window list now; we don't handle dynamic changes here,
// and we don't want to be continually retrieving it
appIcon.cachedWindows = appIcon.app.get_windows();
if (this._hasWindowsOnWorkspace(appIcon, activeWorkspace))
workspaceIcons.push(appIcon);
else
otherIcons.push(appIcon);
workspaceIcons.push(appIcon);
}
for (let i = 0; i < otherApps.length; i++) {
let appIcon = new AppIcon(otherApps[i]);
appIcon.cachedWindows = appIcon.app.get_windows();
otherIcons.push(appIcon);
}
workspaceIcons.sort(Lang.bind(this, this._sortAppIcon));
otherIcons.sort(Lang.bind(this, this._sortAppIcon));
this.icons = [];
this._arrows = [];
@ -999,19 +1040,6 @@ AppSwitcher.prototype = {
if (appIcon.cachedWindows.length == 1)
arrow.hide();
},
_hasWindowsOnWorkspace: function(appIcon, workspace) {
let windows = appIcon.cachedWindows;
for (let i = 0; i < windows.length; i++) {
if (windows[i].get_workspace() == workspace)
return true;
}
return false;
},
_sortAppIcon : function(appIcon1, appIcon2) {
return appIcon1.app.compare(appIcon2.app);
}
};

View File

@ -1,4 +1,4 @@
/* -*- mode: js2; js2-basic-offset: 4; indent-tabs-mode: nil -*- */
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
const Clutter = imports.gi.Clutter;
const GLib = imports.gi.GLib;
@ -559,7 +559,7 @@ AppWellIcon.prototype = {
this._menu.connect('activate-window', Lang.bind(this, function (menu, window) {
this.activateWindow(window);
}));
this._menu.connect('popup', Lang.bind(this, function (menu, isPoppedUp) {
this._menu.connect('open-state-changed', Lang.bind(this, function (menu, isPoppedUp) {
if (!isPoppedUp)
this._onMenuPoppedDown();
}));
@ -643,7 +643,6 @@ AppIconMenu.prototype = {
this._source = source;
this.connect('activate', Lang.bind(this, this._onActivate));
this.connect('open-state-changed', Lang.bind(this, this._onOpenStateChanged));
this.actor.add_style_class_name('app-well-menu');
@ -707,14 +706,6 @@ AppIconMenu.prototype = {
this.open();
},
_onOpenStateChanged: function (menu, open) {
if (open) {
this.emit('popup', true);
} else {
this.emit('popup', false);
}
},
_onActivate: function (actor, child) {
if (child._window) {
let metaWindow = child._window;

View File

@ -1,4 +1,4 @@
/* -*- mode: js2; js2-basic-offset: 4; indent-tabs-mode: nil -*- */
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
const Shell = imports.gi.Shell;
const Lang = imports.lang;

View File

@ -1,4 +1,4 @@
/* -*- mode: js2; js2-basic-offset: 4; indent-tabs-mode: nil -*- */
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
const Lang = imports.lang;
const DBus = imports.dbus;
@ -209,10 +209,14 @@ AutomountManager.prototype = {
}
}
// Volume is already mounted, don't bother.
if (volume.get_mount())
return;
if (!this._settings.get_boolean(SETTING_ENABLE_AUTOMOUNT) ||
!volume.should_automount() ||
!volume.can_mount()) {
// allow the autorun to run anyway; this can happen if the
// allow the autorun to run anyway; this can happen if the
// mount gets added programmatically later, even if
// should_automount() or can_mount() are false, like for
// blank optical media.

View File

@ -1,4 +1,4 @@
/* -*- mode: js2; js2-basic-offset: 4; indent-tabs-mode: nil -*- */
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
const Lang = imports.lang;
const DBus = imports.dbus;
@ -23,8 +23,6 @@ const AutorunSetting = {
ASK: 3
};
const HOTPLUG_ICON_SIZE = 16;
// misc utils
function ignoreAutorunForMount(mount) {
let root = mount.get_root();
@ -279,12 +277,12 @@ AutorunResidentSource.prototype = {
__proto__: MessageTray.Source.prototype,
_init: function() {
MessageTray.Source.prototype._init.call(this, _('Removable Devices'));
MessageTray.Source.prototype._init.call(this, _("Removable Devices"));
this._mounts = [];
this._notification = new AutorunResidentNotification(this);
this._setSummaryIcon(this.createNotificationIcon(HOTPLUG_ICON_SIZE));
this._setSummaryIcon(this.createNotificationIcon());
},
addMount: function(mount, apps) {
@ -329,10 +327,10 @@ AutorunResidentSource.prototype = {
}
},
createNotificationIcon: function(iconSize) {
createNotificationIcon: function() {
return new St.Icon ({ icon_name: 'media-removable',
icon_type: St.IconType.FULLCOLOR,
icon_size: iconSize ? iconSize : this.ICON_SIZE });
icon_size: this.ICON_SIZE });
}
}
@ -493,7 +491,7 @@ AutorunTransientDispatcher.prototype = {
let app = null;
if (setting == AutorunSetting.RUN) {
app = Gio.app_info_get_default_for_type(type, false);
app = Gio.app_info_get_default_for_type(contentTypes[0], false);
} else if (setting == AutorunSetting.FILES) {
app = Gio.app_info_get_default_for_type('inode/directory', false);
}
@ -533,16 +531,16 @@ AutorunTransientSource.prototype = {
this.apps = apps;
this._notification = new AutorunTransientNotification(this);
this._setSummaryIcon(this.createNotificationIcon(this.ICON_SIZE));
this._setSummaryIcon(this.createNotificationIcon());
// add ourselves as a source, and popup the notification
Main.messageTray.add(this);
this.notify(this._notification);
},
createNotificationIcon: function(iconSize) {
createNotificationIcon: function() {
return new St.Icon({ gicon: this.mount.get_icon(),
icon_size: iconSize ? iconSize : this.ICON_SIZE });
icon_size: this.ICON_SIZE });
}
}

View File

@ -1,4 +1,4 @@
/* -*- mode: js2; js2-basic-offset: 4; indent-tabs-mode: nil -*- */
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
const Clutter = imports.gi.Clutter;
const Lang = imports.lang;
@ -46,6 +46,7 @@ BoxPointer.prototype = {
this._yOffset = 0;
this._xPosition = 0;
this._yPosition = 0;
this._sourceAlignment = 0.5;
},
show: function(animate, onComplete) {
@ -75,7 +76,7 @@ BoxPointer.prototype = {
Tweener.addTween(this, { opacity: 255,
xOffset: 0,
yOffset: 0,
transition: "linear",
transition: 'linear',
onComplete: onComplete,
time: POPUP_ANIMATION_TIME });
},
@ -106,7 +107,7 @@ BoxPointer.prototype = {
Tweener.addTween(this, { opacity: 0,
xOffset: xOffset,
yOffset: yOffset,
transition: "linear",
transition: 'linear',
time: POPUP_ANIMATION_TIME,
onComplete: Lang.bind(this, function () {
this.actor.hide();
@ -180,7 +181,7 @@ BoxPointer.prototype = {
this.bin.allocate(childBox, flags);
if (this._sourceActor && this._sourceActor.mapped)
this._reposition(this._sourceActor, this._alignment);
this._reposition(this._sourceActor, this._arrowAlignment);
},
_drawBorder: function(area) {
@ -312,24 +313,37 @@ BoxPointer.prototype = {
this.actor.show();
this._sourceActor = sourceActor;
this._alignment = alignment;
this._arrowAlignment = alignment;
this._reposition(sourceActor, alignment);
},
setSourceAlignment: function(alignment) {
this._sourceAlignment = alignment;
if (!this._sourceActor)
return;
// We need to show it now to force an allocation,
// so that we can query the correct size.
this.actor.show();
this._reposition(this._sourceActor, this._arrowAlignment);
},
_reposition: function(sourceActor, alignment) {
// Position correctly relative to the sourceActor
let sourceNode = sourceActor.get_theme_node();
let sourceContentBox = sourceNode.get_content_box(sourceActor.get_allocation_box());
let sourceAllocation = Shell.util_get_transformed_allocation(sourceActor);
let sourceCenterX = sourceAllocation.x1 + sourceContentBox.x1 + (sourceContentBox.x2 - sourceContentBox.x1) / 2;
let sourceCenterY = sourceAllocation.y1 + sourceContentBox.y1 + (sourceContentBox.y2 - sourceContentBox.y1) / 2;
let sourceCenterX = sourceAllocation.x1 + sourceContentBox.x1 + (sourceContentBox.x2 - sourceContentBox.x1) * this._sourceAlignment;
let sourceCenterY = sourceAllocation.y1 + sourceContentBox.y1 + (sourceContentBox.y2 - sourceContentBox.y1) * this._sourceAlignment;
let [minWidth, minHeight, natWidth, natHeight] = this.actor.get_preferred_size();
// We also want to keep it onscreen, and separated from the
// edge by the same distance as the main part of the box is
// separated from its sourceActor
let primary = Main.layoutManager.primaryMonitor;
let monitor = Main.layoutManager.findMonitorForActor(sourceActor);
let themeNode = this.actor.get_theme_node();
let borderWidth = themeNode.get_length('-arrow-border-width');
let arrowBase = themeNode.get_length('-arrow-base');
@ -364,8 +378,8 @@ BoxPointer.prototype = {
case St.Side.BOTTOM:
resX = sourceCenterX - (halfMargin + (natWidth - margin) * alignment);
resX = Math.max(resX, primary.x + 10);
resX = Math.min(resX, primary.x + primary.width - (10 + natWidth));
resX = Math.max(resX, monitor.x + 10);
resX = Math.min(resX, monitor.x + monitor.width - (10 + natWidth));
this.setArrowOrigin(sourceCenterX - resX);
break;
@ -373,8 +387,8 @@ BoxPointer.prototype = {
case St.Side.RIGHT:
resY = sourceCenterY - (halfMargin + (natHeight - margin) * alignment);
resY = Math.max(resY, primary.y + 10);
resY = Math.min(resY, primary.y + primary.height - (10 + natHeight));
resY = Math.max(resY, monitor.y + 10);
resY = Math.min(resY, monitor.y + monitor.height - (10 + natHeight));
this.setArrowOrigin(sourceCenterY - resY);
break;

View File

@ -1,4 +1,4 @@
/* -*- mode: js2; js2-basic-offset: 4; indent-tabs-mode: nil -*- */
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
const DBus = imports.dbus;
const Clutter = imports.gi.Clutter;

View File

@ -1,4 +1,4 @@
/* -*- mode: js2; js2-basic-offset: 4; indent-tabs-mode: nil -*- */
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
const Folks = imports.gi.Folks
const Lang = imports.lang;
@ -26,7 +26,8 @@ function Contact(id) {
Contact.prototype = {
_init: function(id) {
this.individual = Shell.ContactSystem.get_default().get_individual(id);
this._contactSys = Shell.ContactSystem.get_default();
this.individual = this._contactSys.get_individual(id);
this.actor = new St.Bin({ style_class: 'contact',
reactive: true,
@ -56,7 +57,12 @@ Contact.prototype = {
x_align: St.Align.START,
y_align: St.Align.MIDDLE });
let aliasText = this.individual.alias || _("Unknown");
let email = this._contactSys.get_email_for_display(this.individual);
let aliasText = this.individual.alias ||
this.individual.full_name ||
this.individual.nickname ||
email ||
_("Unknown");
let aliasLabel = new St.Label({ text: aliasText,
style_class: 'contact-details-alias' });
details.add(aliasLabel, { x_fill: true,

View File

@ -1,4 +1,4 @@
/* -*- mode: js2; js2-basic-offset: 4; indent-tabs-mode: nil -*- */
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
const Clutter = imports.gi.Clutter;
const Gdk = imports.gi.Gdk;
@ -94,7 +94,7 @@ CtrlAltTabManager.prototype = {
return a.x - b.x;
},
popup: function(backwards) {
popup: function(backwards, mask) {
// Start with the set of focus groups that are currently mapped
let items = this._items.filter(function (item) { return item.proxy.mapped; });
@ -123,7 +123,16 @@ CtrlAltTabManager.prototype = {
return;
items.sort(Lang.bind(this, this._sortItems));
new CtrlAltTabPopup().show(items, backwards);
if (!this._popup) {
this._popup = new CtrlAltTabPopup();
this._popup.show(items, backwards, mask);
this._popup.actor.connect('destroy',
Lang.bind(this, function() {
this._popup = null;
}));
}
}
};
@ -147,6 +156,7 @@ CtrlAltTabPopup.prototype = {
this.actor.connect('destroy', Lang.bind(this, this._onDestroy));
this._haveModal = false;
this._modifierMask = 0;
this._selection = 0;
Main.uiGroup.add_actor(this.actor);
@ -183,10 +193,11 @@ CtrlAltTabPopup.prototype = {
this._switcher.actor.allocate(childBox, flags);
},
show : function(items, startBackwards) {
show : function(items, startBackwards, mask) {
if (!Main.pushModal(this.actor))
return false;
this._haveModal = true;
this._modifierMask = AltTab.primaryModifier(mask);
this._keyPressEventId = this.actor.connect('key-press-event', Lang.bind(this, this._keyPressEvent));
this._keyReleaseEventId = this.actor.connect('key-release-event', Lang.bind(this, this._keyReleaseEvent));
@ -200,7 +211,7 @@ CtrlAltTabPopup.prototype = {
this._select(this._selection);
let [x, y, mods] = global.get_pointer();
if (!(mods & Gdk.ModifierType.MOD1_MASK)) {
if (!(mods & this._modifierMask)) {
this._finish();
return false;
}
@ -246,7 +257,7 @@ CtrlAltTabPopup.prototype = {
_keyReleaseEvent : function(actor, event) {
let [x, y, mods] = global.get_pointer();
let state = mods & Clutter.ModifierType.MOD1_MASK;
let state = mods & this._modifierMask;
if (state == 0)
this._finish();

View File

@ -1,4 +1,4 @@
/* -*- mode: js2; js2-basic-offset: 4; indent-tabs-mode: nil -*- */
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
const Clutter = imports.gi.Clutter;
const Signals = imports.signals;
@ -37,6 +37,7 @@ DashItemContainer.prototype = {
this.child = null;
this._childScale = 1;
this._childOpacity = 255;
this.animatingOut = false;
},
_allocate: function(actor, box, flags) {
@ -115,6 +116,7 @@ DashItemContainer.prototype = {
return;
}
this.animatingOut = true;
this.childScale = 1.0;
Tweener.addTween(this,
{ childScale: 0.0,
@ -177,12 +179,6 @@ RemoveFavoriteIcon.prototype = {
this._iconBin._delegate = this;
this.setChild(this._iconBin);
this.hiding = false;
},
animateOutAndDestroy: function() {
DashItemContainer.prototype.animateOutAndDestroy.call(this);
this.hiding = true;
},
_createIcon: function(size) {
@ -314,15 +310,12 @@ Dash.prototype = {
_endDrag: function() {
this._clearDragPlaceholder();
if (this._favRemoveTarget) {
this._favRemoveTarget.actor.hide();
this._adjustIconSize();
this._favRemoveTarget.actor.show();
this._favRemoveTarget.animateOutAndDestroy();
this._favRemoveTarget.actor.connect('destroy', Lang.bind(this,
function() {
this._favRemoveTarget = null;
}));
this._adjustIconSize();
}
DND.removeDragMonitor(this._dragMonitor);
},
@ -401,8 +394,18 @@ Dash.prototype = {
},
_adjustIconSize: function() {
let children = this._box.get_children();
if (children.length == 0) {
// For the icon size, we only consider children which are "proper"
// icons (i.e. ignoring drag placeholders) and which are not
// animating out (which means they will be destroyed at the end of
// the animation)
let iconChildren = this._box.get_children().filter(function(actor) {
return actor._delegate.child &&
actor._delegate.child._delegate &&
actor._delegate.child._delegate.icon &&
!actor._delegate.animatingOut;
});
if (iconChildren.length == 0) {
this._box.add_style_pseudo_class('empty');
return;
}
@ -412,23 +415,45 @@ Dash.prototype = {
if (this._maxHeight == -1)
return;
let iconChildren = children.filter(function(actor) {
return actor.visible &&
actor._delegate.child &&
actor._delegate.child._delegate &&
actor._delegate.child._delegate.icon;
});
// Compute the amount of extra space (or missing space) we have
// per icon with the current icon size
let [minHeight, natHeight] = this.actor.get_preferred_height(-1);
let diff = (this._maxHeight - natHeight) / iconChildren.length;
let themeNode = this.actor.get_theme_node();
let maxAllocation = new Clutter.ActorBox({ x1: 0, y1: 0,
x2: 42 /* whatever */,
y2: this._maxHeight });
let maxContent = themeNode.get_content_box(maxAllocation);
let availHeight = maxContent.y2 - maxContent.y1;
let spacing = themeNode.get_length('spacing');
let firstIcon = iconChildren[0]._delegate.child._delegate.icon;
let minHeight, natHeight;
// Enforce the current icon size during the size request if
// the icon is animating
if (firstIcon._animating) {
let [currentWidth, currentHeight] = firstIcon.icon.get_size();
firstIcon.icon.set_size(this.iconSize, this.iconSize);
[minHeight, natHeight] = iconChildren[0].get_preferred_height(-1);
firstIcon.icon.set_size(currentWidth, currentHeight);
} else {
[minHeight, natHeight] = iconChildren[0].get_preferred_height(-1);
}
// Subtract icon padding and box spacing from the available height
availHeight -= iconChildren.length * (natHeight - this.iconSize) +
(iconChildren.length - 1) * spacing;
let availSize = availHeight / iconChildren.length;
let iconSizes = [ 16, 22, 24, 32, 48, 64 ];
let newIconSize = 16;
for (let i = 0; i < iconSizes.length; i++) {
if (iconSizes[i] < this.iconSize + diff)
if (iconSizes[i] < availSize)
newIconSize = iconSizes[i];
}
@ -459,11 +484,15 @@ Dash.prototype = {
icon.icon.set_size(icon.icon.width * scale,
icon.icon.height * scale);
icon._animating = true;
Tweener.addTween(icon.icon,
{ width: targetWidth,
height: targetHeight,
time: DASH_ANIMATION_TIME,
transition: 'easeOutQuad'
transition: 'easeOutQuad',
onComplete: function() {
icon._animating = false;
}
});
}
},
@ -566,29 +595,7 @@ Dash.prototype = {
this._box.insert_actor(addedItems[i].item.actor,
addedItems[i].pos);
// Hide removed actors to not take them into account
// when adjusting the icon size ...
for (let i = 0; i < removedActors.length; i++)
removedActors[i].hide();
// ... and do the same for the remove target if necessary
if (this._favRemoveTarget && this._favRemoveTarget.hiding)
this._favRemoveTarget.actor.hide();
this._adjustIconSize();
if (this._favRemoveTarget && this._favRemoveTarget.hiding)
this._favRemoveTarget.actor.show();
// Skip animations on first run when adding the initial set
// of items, to avoid all items zooming in at once
if (!this._shownInitially) {
this._shownInitially = true;
return;
}
for (let i = 0; i < removedActors.length; i++) {
removedActors[i].show();
let item = removedActors[i]._delegate;
// Don't animate item removal when the overview is hidden
@ -598,6 +605,15 @@ Dash.prototype = {
item.actor.destroy();
}
this._adjustIconSize();
// Skip animations on first run when adding the initial set
// of items, to avoid all items zooming in at once
if (!this._shownInitially) {
this._shownInitially = true;
return;
}
// Don't animate item addition when the overview is hidden
if (!Main.overview.visible)
return;
@ -684,6 +700,8 @@ Dash.prototype = {
}
this._dragPlaceholder = new DragPlaceholderItem();
this._dragPlaceholder.child.set_width (this.iconSize);
this._dragPlaceholder.child.set_height (this.iconSize / 2);
this._box.insert_actor(this._dragPlaceholder.actor,
this._dragPlaceholderPos);
if (fadeIn)

View File

@ -1,4 +1,4 @@
/* -*- mode: js2; js2-basic-offset: 4; indent-tabs-mode: nil -*- */
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
const GLib = imports.gi.GLib;
const Gio = imports.gi.Gio;
@ -60,7 +60,7 @@ DateMenuButton.prototype = {
PanelMenu.Button.prototype._init.call(this, menuAlignment);
this._clock = new St.Label();
this.actor.set_child(this._clock);
this.actor.add_actor(this._clock);
hbox = new St.BoxLayout({name: 'calendarArea' });
this.menu.addActor(hbox);

View File

@ -1,4 +1,4 @@
/* -*- mode: js2; js2-basic-offset: 4; indent-tabs-mode: nil -*- */
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
const Clutter = imports.gi.Clutter;
const Gtk = imports.gi.Gtk;

View File

@ -1,4 +1,4 @@
/* -*- mode: js2; js2-basic-offset: 4; indent-tabs-mode: nil -*- */
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
const DocInfo = imports.misc.docInfo;
const Params = imports.misc.params;

View File

@ -1,5 +1,5 @@
/* -*- mode: js2; js2-basic-offset: 4; indent-tabs-mode: nil -*-
*
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
/*
* Copyright 2010 Red Hat, Inc
*
* This program is free software; you can redistribute it and/or modify

View File

@ -1,4 +1,4 @@
/* -*- mode: js2; js2-basic-offset: 4; indent-tabs-mode: nil -*- */
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
imports.gi.versions.Clutter = '1.0';
imports.gi.versions.Gio = '2.0';

View File

@ -1,4 +1,4 @@
/* -*- mode: js2; js2-basic-offset: 4; indent-tabs-mode: nil -*- */
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
const Lang = imports.lang;
const Signals = imports.signals;
@ -289,7 +289,7 @@ function loadExtension(dir, enabled, type) {
}
if (extensions[uuid] != undefined) {
logExtensionError(uuid, "extension already loaded");
logExtensionError(uuid, 'extension already loaded');
return;
}
@ -450,7 +450,6 @@ function _loadExtensionsIn(dir, type) {
}
function loadExtensions() {
_loadExtensionsIn(userExtensionsDir, ExtensionType.PER_USER);
let systemDataDirs = GLib.get_system_data_dirs();
for (let i = 0; i < systemDataDirs.length; i++) {
let dirPath = systemDataDirs[i] + '/gnome-shell/extensions';
@ -458,6 +457,7 @@ function loadExtensions() {
if (dir.query_exists(null))
_loadExtensionsIn(dir, ExtensionType.SYSTEM);
}
_loadExtensionsIn(userExtensionsDir, ExtensionType.PER_USER);
}
function InstallExtensionDialog(uuid, version_tag, name) {

View File

@ -1,4 +1,4 @@
/* -*- mode: js2; js2-basic-offset: 4; indent-tabs-mode: nil -*- */
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
const Clutter = imports.gi.Clutter;
const Shell = imports.gi.Shell;

View File

@ -1,4 +1,4 @@
/* -*- mode: js2; js2-basic-offset: 4; indent-tabs-mode: nil -*- */
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
const Caribou = imports.gi.Caribou;
const Clutter = imports.gi.Clutter;
@ -15,9 +15,11 @@ const Main = imports.ui.main;
const MessageTray = imports.ui.messageTray;
const KEYBOARD_SCHEMA = 'org.gnome.shell.keyboard';
const SHOW_KEYBOARD = 'show-keyboard';
const KEYBOARD_TYPE = 'keyboard-type';
const A11Y_APPLICATIONS_SCHEMA = 'org.gnome.desktop.a11y.applications';
const SHOW_KEYBOARD = 'screen-keyboard-enabled';
// Key constants taken from Antler
// FIXME: ought to be moved into libcaribou
const PRETTY_KEYS = {
@ -73,7 +75,7 @@ Key.prototype = {
this._extended_keys = this._key.get_extended_keys();
this._extended_keyboard = null;
if (this._key.name == "Control_L" || this._key.name == "Alt_L")
if (this._key.name == 'Control_L' || this._key.name == 'Alt_L')
this._key.latch = true;
this._key.connect('key-pressed', Lang.bind(this, function ()
@ -207,6 +209,8 @@ Keyboard.prototype = {
this._keyboardSettings = new Gio.Settings({ schema: KEYBOARD_SCHEMA });
this._keyboardSettings.connect('changed', Lang.bind(this, this._settingsChanged));
this._a11yApplicationsSettings = new Gio.Settings({ schema: A11Y_APPLICATIONS_SCHEMA });
this._a11yApplicationsSettings.connect('changed', Lang.bind(this, this._settingsChanged));
this._settingsChanged();
},
@ -214,8 +218,8 @@ Keyboard.prototype = {
this._redraw();
},
_settingsChanged: function () {
this._enableKeyboard = this._keyboardSettings.get_boolean(SHOW_KEYBOARD);
_settingsChanged: function (settings, key) {
this._enableKeyboard = this._a11yApplicationsSettings.get_boolean(SHOW_KEYBOARD);
if (!this._enableKeyboard && !this._keyboard)
return;
if (this._enableKeyboard && this._keyboard &&
@ -224,9 +228,20 @@ Keyboard.prototype = {
if (this._keyboard)
this._destroyKeyboard();
if (this._enableKeyboard)
this._setupKeyboard();
else
if (this._enableKeyboard) {
// If we've been called because the setting actually just
// changed to true (as opposed to being called from
// this._init()), then we want to pop up the keyboard.
let showKeyboard = (settings != null);
// However, caribou-gtk-module or this._onKeyFocusChanged
// will probably immediately tell us to hide it, so we
// have to fake things out so we'll ignore that request.
if (showKeyboard)
this._timestamp = global.display.get_current_time_roundtrip() + 1;
this._setupKeyboard(showKeyboard);
} else
Main.layoutManager.hideKeyboard(true);
},
@ -242,7 +257,7 @@ Keyboard.prototype = {
this._destroySource();
},
_setupKeyboard: function() {
_setupKeyboard: function(show) {
this.actor = new St.BoxLayout({ name: 'keyboard', vertical: true, reactive: true });
Main.layoutManager.keyboardBox.add_actor(this.actor);
Main.layoutManager.trackChrome(this.actor);
@ -259,20 +274,26 @@ Keyboard.prototype = {
this._keyboardNotifyId = this._keyboard.connect('notify::active-group', Lang.bind(this, this._onGroupChanged));
this._focusNotifyId = global.stage.connect('notify::key-focus', Lang.bind(this, this._onKeyFocusChanged));
this._createSource();
if (show)
this.show();
else
this._createSource();
},
_onKeyFocusChanged: function () {
let focus = global.stage.key_focus;
// Showing an extended key popup will grab focus, but ignore that
if (focus && focus._extended_keys)
// Showing an extended key popup and clicking a key from the extended keys
// will grab focus, but ignore that
if (focus && (focus._extended_keys || (focus._key && focus._key.extended_key)))
return;
let time = global.current_event_time();
if (focus instanceof Clutter.Text)
this.show();
this.Show(time);
else
this.hide();
this.Hide(time);
},
_addKeys: function () {
@ -301,7 +322,8 @@ Keyboard.prototype = {
},
_getTrayIcon: function () {
let trayButton = new St.Button ({ label: "tray", style_class: 'keyboard-key' });
let trayButton = new St.Button ({ label: _("tray"),
style_class: 'keyboard-key' });
trayButton.key_width = 1;
trayButton.connect('button-press-event', Lang.bind(this, function () {
Main.messageTray.toggle();
@ -335,7 +357,7 @@ Keyboard.prototype = {
right_box.add(button.actor);
else
left_box.add(button.actor);
if (key.name == "Caribou_Prefs") {
if (key.name == 'Caribou_Prefs') {
key.connect('key-released', Lang.bind(this, this.hide));
// Add new key for hiding message tray
@ -472,6 +494,9 @@ Keyboard.prototype = {
// D-Bus methods
Show: function(timestamp) {
if (!this._enableKeyboard)
return;
if (timestamp - this._timestamp < 0)
return;
@ -480,6 +505,9 @@ Keyboard.prototype = {
},
Hide: function(timestamp) {
if (!this._enableKeyboard)
return;
if (timestamp - this._timestamp < 0)
return;
@ -488,11 +516,17 @@ Keyboard.prototype = {
},
SetCursorLocation: function(x, y, w, h) {
this._setLocation(x, y);
if (!this._enableKeyboard)
return;
// this._setLocation(x, y);
},
SetEntryLocation: function(x, y, w, h) {
this._setLocation(x, y);
if (!this._enableKeyboard)
return;
// this._setLocation(x, y);
},
get Name() {

View File

@ -1,4 +1,4 @@
/* -*- mode: js2; js2-basic-offset: 4; indent-tabs-mode: nil -*- */
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
const Clutter = imports.gi.Clutter;
const Lang = imports.lang;
@ -45,7 +45,9 @@ LayoutManager.prototype = {
this.trayBox.connect('allocation-changed',
Lang.bind(this, this._updateTrayBarrier));
this.keyboardBox = new St.BoxLayout({ name: 'keyboardBox' });
this.keyboardBox = new St.BoxLayout({ name: 'keyboardBox',
reactive: true,
track_hover: true });
this.addChrome(this.keyboardBox, { visibleInFullscreen: true });
this._keyboardHeightNotifyId = 0;
@ -214,10 +216,10 @@ LayoutManager.prototype = {
let monitorLeft = monitor.x, monitorRight = monitor.x + monitor.width;
let primaryLeft = primary.x, primaryRight = primary.x + primary.width;
if ((monitorLeft >= primaryLeft && monitorLeft <= primaryRight) ||
(monitorRight >= primaryLeft && monitorRight <= primaryRight) ||
(primaryLeft >= monitorLeft && primaryLeft <= monitorRight) ||
(primaryRight >= monitorLeft && primaryRight <= monitorRight))
if ((monitorLeft >= primaryLeft && monitorLeft < primaryRight) ||
(monitorRight > primaryLeft && monitorRight <= primaryRight) ||
(primaryLeft >= monitorLeft && primaryLeft < monitorRight) ||
(primaryRight > monitorLeft && primaryRight <= monitorRight))
return true;
return false;
@ -367,6 +369,10 @@ LayoutManager.prototype = {
// Removes @actor from the chrome
removeChrome: function(actor) {
this._chrome.removeActor(actor);
},
findMonitorForActor: function(actor) {
return this._chrome.findMonitorForActor(actor);
}
};
Signals.addSignalMethods(LayoutManager.prototype);
@ -619,7 +625,7 @@ Chrome.prototype = {
// We can't use Params.parse here because we want to drop
// the extra values like ancestorData.actor
for (let prop in defaultParams) {
if (!params[prop])
if (!params.hasOwnProperty(prop))
params[prop] = ancestorData[prop];
}
@ -698,7 +704,7 @@ Chrome.prototype = {
else if (this._inOverview)
visible = true;
else if (!actorData.visibleInFullscreen &&
this._findMonitorForActor(actorData.actor).inFullscreen)
this.findMonitorForActor(actorData.actor).inFullscreen)
visible = false;
else
visible = true;
@ -760,7 +766,7 @@ Chrome.prototype = {
// This call guarantees that we return some monitor to simplify usage of it
// In practice all tracked actors should be visible on some monitor anyway
_findMonitorForActor: function(actor) {
findMonitorForActor: function(actor) {
let [x, y] = actor.get_transformed_position();
let [w, h] = actor.get_transformed_size();
let monitor = this._findMonitorForRect(x, y, w, h);
@ -819,6 +825,18 @@ Chrome.prototype = {
monitor.inFullscreen = true;
}
if (layer == Meta.StackLayer.OVERRIDE_REDIRECT) {
// Check whether the window is screen sized
let isScreenSized =
(window.x == 0 && window.y == 0 &&
window.width == global.screen_width &&
window.height == global.screen_height);
if (isScreenSized) {
for (let i = 0; i < this._monitors.length; i++)
this._monitors[i].inFullscreen = true;
}
// Or whether it is monitor sized
let monitor = this._findMonitorForWindow(window);
if (monitor &&
window.x <= monitor.x &&

View File

@ -1,4 +1,4 @@
/* -*- mode: js2; js2-basic-offset: 4; indent-tabs-mode: nil -*- */
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
const Lang = imports.lang;
const Meta = imports.gi.Meta;

View File

@ -1,4 +1,4 @@
/* -*- mode: js2; js2-basic-offset: 4; indent-tabs-mode: nil -*- */
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
const Lang = imports.lang;
const Signals = imports.signals;

View File

@ -1,4 +1,4 @@
/* -*- mode: js2; js2-basic-offset: 4; indent-tabs-mode: nil -*- */
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
const Clutter = imports.gi.Clutter;
const Cogl = imports.gi.Cogl;
@ -17,6 +17,7 @@ const Mainloop = imports.mainloop;
const History = imports.misc.history;
const ExtensionSystem = imports.ui.extensionSystem;
const Link = imports.ui.link;
const ShellEntry = imports.ui.shellEntry;
const Tweener = imports.ui.tweener;
const Main = imports.ui.main;
@ -157,9 +158,9 @@ Signals.addSignalMethods(Notebook.prototype);
function objectToString(o) {
if (typeof(o) == typeof(objectToString)) {
// special case this since the default is way, way too verbose
return "<js function>";
return '<js function>';
} else {
return "" + o;
return '' + o;
}
}
@ -322,7 +323,7 @@ ObjInspector.prototype = {
link = new St.Label({ text: '<error>' });
}
let hbox = new St.BoxLayout();
let propText = propName + ": " + valueStr;
let propText = propName + ': ' + valueStr;
hbox.add(new St.Label({ text: propName + ': ' }));
hbox.add(link);
this._container.add_actor(hbox);
@ -343,7 +344,7 @@ ObjInspector.prototype = {
this.actor.move_anchor_point(Math.floor(sourceX + sourceWidth / 2),
Math.floor(sourceY + sourceHeight / 2));
Tweener.addTween(this.actor, { scale_x: 1, scale_y: 1,
transition: "easeOutQuad",
transition: 'easeOutQuad',
time: 0.2 });
} else {
this.actor.set_scale(1, 1);
@ -607,6 +608,9 @@ Memory.prototype = {
this._gjs_closure = new St.Label();
this.actor.add(this._gjs_closure);
this._last_gc_seconds_ago = new St.Label();
this.actor.add(this._last_gc_seconds_ago);
this._gcbutton = new St.Button({ label: 'Full GC',
style_class: 'lg-obj-inspector-button' });
this._gcbutton.connect('clicked', Lang.bind(this, function () { global.gc(); this._renderText(); }));
@ -626,6 +630,7 @@ Memory.prototype = {
this._gjs_gobject.text = 'gjs_gobject: ' + memInfo.gjs_gobject;
this._gjs_function.text = 'gjs_function: ' + memInfo.gjs_function;
this._gjs_closure.text = 'gjs_closure: ' + memInfo.gjs_closure;
this._last_gc_seconds_ago.text = 'last_gc_seconds_ago: ' + memInfo.last_gc_seconds_ago;
}
};
@ -706,27 +711,23 @@ Extensions.prototype = {
text: meta.description || 'No description' });
box.add(description, { expand: true });
let metaBox = new St.BoxLayout();
let metaBox = new St.BoxLayout({ style_class: 'lg-extension-meta' });
box.add(metaBox);
let stateString = this._stateToString(meta.state);
let state = new St.Label({ style_class: 'lg-extension-state',
text: this._stateToString(meta.state) });
let actionsContainer = new St.Bin({ x_align: St.Align.END });
metaBox.add(actionsContainer);
let actionsBox = new St.BoxLayout({ style_class: 'lg-extension-actions' });
actionsContainer.set_child(actionsBox);
metaBox.add(state);
let viewsource = new Link.Link({ label: _("View Source") });
viewsource.actor._extensionMeta = meta;
viewsource.actor.connect('clicked', Lang.bind(this, this._onViewSource));
actionsBox.add(viewsource.actor);
metaBox.add(viewsource.actor);
if (meta.url) {
let webpage = new Link.Link({ label: _("Web Page") });
webpage.actor._extensionMeta = meta;
webpage.actor.connect('clicked', Lang.bind(this, this._onWebPage));
actionsBox.add(webpage.actor);
metaBox.add(webpage.actor);
}
return box;
@ -816,6 +817,7 @@ LookingGlass.prototype = {
entryArea.add(label);
this._entry = new St.Entry({ can_focus: true });
ShellEntry.addContextMenu(this._entry);
entryArea.add(this._entry, { expand: true });
this._windowList = new WindowList();

View File

@ -1,4 +1,4 @@
/* -*- mode: js2; js2-basic-offset: 4; indent-tabs-mode: nil -*- */
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
const Clutter = imports.gi.Clutter;
const Gio = imports.gi.Gio;

View File

@ -1,4 +1,4 @@
/* -*- mode: js2; js2-basic-offset: 4; indent-tabs-mode: nil -*- */
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
const DBus = imports.dbus;
const Main = imports.ui.main;

View File

@ -1,4 +1,4 @@
/* -*- mode: js2; js2-basic-offset: 4; indent-tabs-mode: nil -*- */
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
const Clutter = imports.gi.Clutter;
const DBus = imports.dbus;
@ -129,8 +129,6 @@ function _initRecorder() {
function _initUserSession() {
_initRecorder();
keyboard.init();
global.screen.override_workspace_layout(Meta.ScreenCorner.TOPLEFT, false, -1, 1);
ExtensionSystem.init();
@ -496,9 +494,9 @@ function notify(msg, details) {
function notifyError(msg, details) {
// Also print to stderr so it's logged somewhere
if (details)
log("error: " + msg + ": " + details);
log('error: ' + msg + ': ' + details);
else
log("error: " + msg)
log('error: ' + msg);
notify(msg, details);
}
@ -595,9 +593,9 @@ function _globalKeyPressHandler(actor, event) {
return true;
}
// Other bindings are only available when the overview is up and
// Other bindings are only available to the user session when the overview is up and
// no modal dialog is present.
if (!overview.visible || modalCount > 1)
if (global.session_type == Shell.SessionType.USER && (!overview.visible || modalCount > 1))
return false;
// This isn't a Meta.KeyBindingAction yet
@ -607,7 +605,8 @@ function _globalKeyPressHandler(actor, event) {
}
if (action == Meta.KeyBindingAction.SWITCH_PANELS) {
ctrlAltTabManager.popup(modifierState & Clutter.ModifierType.SHIFT_MASK);
ctrlAltTabManager.popup(modifierState & Clutter.ModifierType.SHIFT_MASK,
modifierState);
return true;
}

View File

@ -1,4 +1,4 @@
/* -*- mode: js2; js2-basic-offset: 4; indent-tabs-mode: nil -*- */
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
const Clutter = imports.gi.Clutter;
const GLib = imports.gi.GLib;
@ -252,7 +252,8 @@ FocusGrabber.prototype = {
this._prevFocusedWindow = global.display.focus_window;
this._prevKeyFocusActor = global.stage.get_key_focus();
if (!Main.overview.visible)
if (global.stage_input_mode == Shell.StageInputMode.NONREACTIVE ||
global.stage_input_mode == Shell.StageInputMode.NORMAL)
global.set_stage_input_mode(Shell.StageInputMode.FOCUSED);
// Use captured-event to notice clicks outside the focused actor
@ -284,7 +285,8 @@ FocusGrabber.prototype = {
let source = event.get_source();
switch (event.type()) {
case Clutter.EventType.BUTTON_PRESS:
if (!this.actor.contains(source) && !Main.keyboard.actor.contains(source))
if (!this.actor.contains(source) &&
!Main.layoutManager.keyboardBox.contains(source))
this.emit('button-pressed', source);
break;
case Clutter.EventType.KEY_PRESS:
@ -415,6 +417,7 @@ Notification.prototype = {
_init: function(source, title, banner, params) {
this.source = source;
this.title = title;
this.urgency = Urgency.NORMAL;
this.resident = false;
// 'transient' is a reserved keyword in JS, so we have to use an alternate variable name
@ -502,8 +505,11 @@ Notification.prototype = {
let oldFocus = global.stage.key_focus;
if (this._icon)
if (this._icon && (params.icon || params.clear)) {
this._icon.destroy();
this._icon = null;
}
// We always clear the content area if we don't have custom
// content because it might contain the @banner that didn't
// fit in the banner mode.
@ -529,14 +535,17 @@ Notification.prototype = {
if (!this._scrollArea && !this._actionArea && !this._imageBin)
this._table.remove_style_class_name('multi-line-notification');
this._icon = params.icon || this.source.createNotificationIcon();
this._table.add(this._icon, { row: 0,
col: 0,
x_expand: false,
y_expand: false,
y_fill: false,
y_align: St.Align.START });
if (!this._icon) {
this._icon = params.icon || this.source.createNotificationIcon();
this._table.add(this._icon, { row: 0,
col: 0,
x_expand: false,
y_expand: false,
y_fill: false,
y_align: St.Align.START });
}
this.title = title;
title = title ? _fixMarkup(title.replace(/\n/g, ' '), params.titleMarkup) : '';
this._titleLabel.clutter_text.set_markup('<b>' + title + '</b>');
@ -694,6 +703,7 @@ Notification.prototype = {
this._imageBin.opacity = 230;
this._table.add_style_class_name('multi-line-notification');
this._table.add_style_class_name('notification-with-image');
this._addBannerBody();
this._updateLastColumnSettings();
this._table.add(this._imageBin, { row: 1,
col: 1,
@ -791,11 +801,12 @@ Notification.prototype = {
},
_bannerBoxAllocate: function(actor, box, flags) {
let [titleMinW, titleNatW] = this._titleLabel.get_preferred_width(-1);
let [titleMinH, titleNatH] = this._titleLabel.get_preferred_height(-1);
let [bannerMinW, bannerNatW] = this._bannerLabel.get_preferred_width(-1);
let availWidth = box.x2 - box.x1;
let [titleMinW, titleNatW] = this._titleLabel.get_preferred_width(-1);
let [titleMinH, titleNatH] = this._titleLabel.get_preferred_height(availWidth);
let [bannerMinW, bannerNatW] = this._bannerLabel.get_preferred_width(availWidth);
let titleBox = new Clutter.ActorBox();
let titleBoxW = Math.min(titleNatW, availWidth);
if (this._titleDirection == St.TextDirection.RTL) {
@ -1347,6 +1358,7 @@ MessageTray.prototype = {
this._summaryBin.opacity = 0;
this._summaryMotionId = 0;
this._trayMotionId = 0;
this._summaryBoxPointer = new BoxPointer.BoxPointer(St.Side.BOTTOM,
{ reactive: true,
@ -1386,12 +1398,15 @@ MessageTray.prototype = {
}));
this._focusGrabber.connect('escape-pressed', Lang.bind(this, this._escapeTray));
Main.layoutManager.keyboardBox.connect('notify::hover', Lang.bind(this, this._onKeyboardHoverChanged));
this._trayState = State.HIDDEN;
this._locked = false;
this._traySummoned = false;
this._useLongerTrayLeftTimeout = false;
this._trayLeftTimeoutId = 0;
this._pointerInTray = false;
this._pointerInKeyboard = false;
this._summaryState = State.HIDDEN;
this._summaryTimeoutId = 0;
this._pointerInSummary = false;
@ -1494,8 +1509,11 @@ MessageTray.prototype = {
// after notifications are done showing. However, we don't want that to happen for
// transient sources, which are removed after the notification is shown, but are
// not removed fast enough because of the callbacks to avoid the summary popping up.
// So we just don't add transient sources to this._newSummaryItems .
if (!source.isTransient)
// So we just don't add transient sources to this._newSummaryItems.
// We don't want that to happen for chat sources neither, because they
// can be added when the user starts a chat from Empathy and they are not transient.
// The notification will popup on incoming message anyway. See bug #657249.
if (!source.isTransient && !source.isChat)
this._newSummaryItems.push(summaryItem);
source.connect('notify', Lang.bind(this, this._onNotify));
@ -1569,7 +1587,7 @@ MessageTray.prototype = {
summaryItemToRemove.actor.destroy();
if (needUpdate);
if (needUpdate)
this._updateState();
},
@ -1838,6 +1856,24 @@ MessageTray.prototype = {
}
},
_onKeyboardHoverChanged: function(keyboard) {
this._pointerInKeyboard = keyboard.hover;
if (!keyboard.hover) {
let event = Clutter.get_current_event();
if (event && event.type() == Clutter.EventType.LEAVE) {
let into = event.get_related();
if (into && this.actor.contains(into)) {
// Don't call _updateState, because pointerInTray is
// still false
return;
}
}
}
this._updateState();
},
_onStatusChanged: function(presence, status) {
this._backFromAway = (this._userStatus == GnomeSession.PresenceStatus.IDLE && this._userStatus != status);
this._userStatus = status;
@ -1902,7 +1938,7 @@ MessageTray.prototype = {
let notificationsPending = this._notificationQueue.length > 0 && (!this._busy || notificationUrgent);
let notificationPinned = this._pointerInTray && !this._pointerInSummary && !this._notificationRemoved;
let notificationExpanded = this._notificationBin.y < 0;
let notificationExpired = (this._notificationTimeoutId == 0 && !(this._notification && this._notification.urgency == Urgency.CRITICAL) && !this._pointerInTray && !this._locked) || this._notificationRemoved;
let notificationExpired = (this._notificationTimeoutId == 0 && !(this._notification && this._notification.urgency == Urgency.CRITICAL) && !this._pointerInTray && !this._locked && !(this._pointerInKeyboard && notificationExpanded)) || this._notificationRemoved;
let canShowNotification = notificationsPending && this._summaryState == State.HIDDEN;
if (this._notificationState == State.HIDDEN) {
@ -2260,6 +2296,8 @@ MessageTray.prototype = {
// _clickedSummaryItem.actor can change absolute position without changing allocation
this._summaryMotionId = this._summary.connect('allocation-changed',
Lang.bind(this, this._adjustSummaryBoxPointerPosition));
this._trayMotionId = Main.layoutManager.trayBox.connect('notify::anchor-y',
Lang.bind(this, this._adjustSummaryBoxPointerPosition));
this._summaryBoxPointer.actor.opacity = 0;
this._summaryBoxPointer.actor.show();
@ -2291,8 +2329,10 @@ MessageTray.prototype = {
if (this._clickedSummaryItemAllocationChangedId) {
this._clickedSummaryItem.actor.disconnect(this._clickedSummaryItemAllocationChangedId);
this._summary.disconnect(this._summaryMotionId);
Main.layoutManager.trayBox.disconnect(this._trayMotionId);
this._clickedSummaryItemAllocationChangedId = 0;
this._summaryMotionId = 0;
this._trayMotionId = 0;
}
if (this._clickedSummaryItem)
@ -2311,8 +2351,9 @@ MessageTray.prototype = {
}
this._summaryBoxPointerState = State.HIDING;
// Unset this._clickedSummaryItem if we are no longer showing the summary
if (this._summaryState != State.SHOWN)
// Unset this._clickedSummaryItem if we are no longer showing the summary or if
// this._clickedSummaryItem is still the item associated with the currently showing box pointer
if (this._summaryState != State.SHOWN || this._summaryBoxPointerItem == this._clickedSummaryItem)
this._unsetClickedSummaryItem();
this._focusGrabber.ungrabFocus();

View File

@ -1,4 +1,4 @@
/* -*- mode: js2; js2-basic-offset: 4; indent-tabs-mode: nil -*- */
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
const Clutter = imports.gi.Clutter;
const Gdk = imports.gi.Gdk;
@ -110,9 +110,8 @@ ModalDialog.prototype = {
this._buttonLayout.destroy_children();
this._actionKeys = {};
let i = 0;
for (let index in buttons) {
let buttonInfo = buttons[index];
for (let i = 0; i < buttons.length; i ++) {
let buttonInfo = buttons[i];
let label = buttonInfo['label'];
let action = buttonInfo['action'];
let key = buttonInfo['key'];
@ -132,7 +131,9 @@ ModalDialog.prototype = {
else
x_alignment = St.Align.MIDDLE;
this._initialKeyFocus = buttonInfo.button;
if (this._initialKeyFocus == this._dialogLayout ||
this._buttonLayout.contains(this._initialKeyFocus))
this._initialKeyFocus = buttonInfo.button;
this._buttonLayout.add(buttonInfo.button,
{ expand: true,
x_fill: false,
@ -144,11 +145,10 @@ ModalDialog.prototype = {
if (key)
this._actionKeys[key] = action;
i++;
}
// Fade in buttons if there weren't any before
if (!hadChildren && i > 0) {
if (!hadChildren && buttons.length > 0) {
this._buttonLayout.opacity = 0;
Tweener.addTween(this._buttonLayout,
{ opacity: 255,

View File

@ -1,5 +1,5 @@
/* -*- mode: js2; js2-basic-offset: 4; indent-tabs-mode: nil -*-
*
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
/*
* Copyright 2011 Giovanni Campagna <scampa.giovanni@gmail.com>
*
* This program is free software; you can redistribute it and/or modify
@ -30,6 +30,7 @@ const St = imports.gi.St;
const ModalDialog = imports.ui.modalDialog;
const PopupMenu = imports.ui.popupMenu;
const ShellEntry = imports.ui.shellEntry;
function NetworkSecretDialog() {
this._init.apply(this, arguments);
@ -91,6 +92,7 @@ NetworkSecretDialog.prototype = {
}
let secretTable = new St.Table({ style_class: 'network-dialog-secret-table' });
let initialFocusSet = false;
let pos = 0;
for (let i = 0; i < this._content.secrets.length; i++) {
let secret = this._content.secrets[i];
@ -102,6 +104,8 @@ NetworkSecretDialog.prototype = {
secret.entry = new St.Entry({ style_class: 'polkit-dialog-password-entry',
text: secret.value, can_focus: reactive,
reactive: reactive });
ShellEntry.addContextMenu(secret.entry,
{ isPassword: secret.password });
if (secret.validate)
secret.valid = secret.validate(secret);
@ -109,6 +113,12 @@ NetworkSecretDialog.prototype = {
secret.valid = secret.value.length > 0;
if (reactive) {
if (!initialFocusSet) {
this.setInitialKeyFocus(secret.entry);
initialFocusSet = true;
}
secret.entry.clutter_text.connect('activate', Lang.bind(this, this._onOk));
secret.entry.clutter_text.connect('text-changed', Lang.bind(this, function() {
secret.value = secret.entry.get_text();
if (secret.validate)
@ -120,34 +130,14 @@ NetworkSecretDialog.prototype = {
} else
secret.valid = true;
secretTable.add(label, { row: pos, col: 0, x_align: St.Align.START, y_align: St.Align.START });
secretTable.add(label, { row: pos, col: 0, x_expand: false, x_fill: true, x_align: St.Align.START, y_align: St.Align.START });
secretTable.add(secret.entry, { row: pos, col: 1, x_expand: true, x_fill: true, y_align: St.Align.END });
pos++;
if (secret.password) {
if (secret.password)
secret.entry.clutter_text.set_password_char('\u25cf');
// FIXME: need a real checkbox here
let button = new St.Button({ button_mask: St.ButtonMask.ONE,
can_focus: true });
let checkbox = new St.BoxLayout({ vertical: false,
style_class: 'network-dialog-show-password-checkbox'
});
let _switch = new PopupMenu.Switch(false);
checkbox.add(_switch.actor);
checkbox.add(new St.Label({ text: _("Show password") }), { expand: true });
button.connect('clicked', function() {
_switch.toggle();
if (_switch.state)
secret.entry.clutter_text.set_password_char('');
else
secret.entry.clutter_text.set_password_char('\u25cf');
});
button.child = checkbox;
secretTable.add(button, { row: pos, col: 1, x_expand: true, x_fill: true, y_fill: true })
pos++;
}
}
messageBox.add(secretTable);
this._okButton = { label: _("Connect"),
@ -397,4 +387,4 @@ NetworkAgent.prototype = {
this._dialogs[requestId].close(global.get_current_time());
this._dialogs[requestId].destroy();
}
};
};

View File

@ -1,4 +1,4 @@
/* -*- mode: js2; js2-basic-offset: 4; indent-tabs-mode: nil -*- */
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
const Clutter = imports.gi.Clutter;
const DBus = imports.dbus;
@ -109,6 +109,14 @@ NotificationDaemon.prototype = {
_iconForNotificationData: function(icon, hints, size) {
let textureCache = St.TextureCache.get_default();
// If an icon is not specified, we use 'image-data' or 'image-path' hint for an icon
// and don't show a large image. There are currently many applications that use
// notify_notification_set_icon_from_pixbuf() from libnotify, which in turn sets
// the 'image-data' hint. These applications don't typically pass in 'app_icon'
// argument to Notify() and actually expect the pixbuf to be shown as an icon.
// So the logic here does the right thing for this case. If both an icon and either
// one of 'image-data' or 'image-path' are specified, we show both an icon and
// a large image.
if (icon) {
if (icon.substr(0, 7) == 'file://')
return textureCache.load_uri_async(icon, size, size);
@ -119,6 +127,12 @@ NotificationDaemon.prototype = {
return new St.Icon({ icon_name: icon,
icon_type: St.IconType.FULLCOLOR,
icon_size: size });
} else if (hints['image-data']) {
let [width, height, rowStride, hasAlpha,
bitsPerSample, nChannels, data] = hints['image-data'];
return textureCache.load_from_raw(data, hasAlpha, width, height, rowStride, size);
} else if (hints['image-path']) {
return textureCache.load_uri_async(GLib.filename_to_uri(hints['image-path'], null), size, size);
} else {
let stockIcon;
switch (hints.urgency) {
@ -330,7 +344,8 @@ NotificationDaemon.prototype = {
clear: true });
}
if (hints['image-data'] || hints['image-path']) {
// We only display a large image if an icon is also specified.
if (icon && (hints['image-data'] || hints['image-path'])) {
let image = null;
if (hints['image-data']) {
let [width, height, rowStride, hasAlpha,

View File

@ -1,4 +1,4 @@
/* -*- mode: js2; js2-basic-offset: 4; indent-tabs-mode: nil -*- */
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
const Clutter = imports.gi.Clutter;
const Gtk = imports.gi.Gtk;

View File

@ -1,4 +1,4 @@
/* -*- mode: js2; js2-basic-offset: 4; indent-tabs-mode: nil -*- */
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
const Cairo = imports.cairo;
const Clutter = imports.gi.Clutter;
@ -16,7 +16,6 @@ const Layout = imports.ui.layout;
const Overview = imports.ui.overview;
const PopupMenu = imports.ui.popupMenu;
const PanelMenu = imports.ui.panelMenu;
const UserMenu = imports.ui.userMenu;
const DateMenu = imports.ui.dateMenu;
const Main = imports.ui.main;
const Tweener = imports.ui.tweener;
@ -28,29 +27,31 @@ const BUTTON_DND_ACTIVATION_TIMEOUT = 250;
const ANIMATED_ICON_UPDATE_TIMEOUT = 100;
const SPINNER_ANIMATION_TIME = 0.2;
const STANDARD_TRAY_ICON_ORDER = ['a11y', 'keyboard', 'volume', 'bluetooth', 'network', 'battery'];
const STANDARD_TRAY_ICON_SHELL_IMPLEMENTATION = {
const STANDARD_STATUS_AREA_ORDER = ['a11y', 'keyboard', 'volume', 'bluetooth', 'network', 'battery', 'userMenu'];
const STANDARD_STATUS_AREA_SHELL_IMPLEMENTATION = {
'a11y': imports.ui.status.accessibility.ATIndicator,
'volume': imports.ui.status.volume.Indicator,
'battery': imports.ui.status.power.Indicator,
'keyboard': imports.ui.status.keyboard.XKBIndicator
'keyboard': imports.ui.status.keyboard.XKBIndicator,
'userMenu': imports.ui.userMenu.UserMenuButton
};
if (Config.HAVE_BLUETOOTH)
STANDARD_TRAY_ICON_SHELL_IMPLEMENTATION['bluetooth'] = imports.ui.status.bluetooth.Indicator;
STANDARD_STATUS_AREA_SHELL_IMPLEMENTATION['bluetooth'] = imports.ui.status.bluetooth.Indicator;
try {
STANDARD_TRAY_ICON_SHELL_IMPLEMENTATION['network'] = imports.ui.status.network.NMApplet;
STANDARD_STATUS_AREA_SHELL_IMPLEMENTATION['network'] = imports.ui.status.network.NMApplet;
} catch(e) {
log('NMApplet is not supported. It is possible that your NetworkManager version is too old');
}
const GDM_TRAY_ICON_ORDER = ['a11y', 'display', 'keyboard', 'volume', 'battery'];
const GDM_TRAY_ICON_SHELL_IMPLEMENTATION = {
const GDM_STATUS_AREA_ORDER = ['a11y', 'display', 'keyboard', 'volume', 'battery', 'powerMenu'];
const GDM_STATUS_AREA_SHELL_IMPLEMENTATION = {
'a11y': imports.ui.status.accessibility.ATIndicator,
'volume': imports.ui.status.volume.Indicator,
'battery': imports.ui.status.power.Indicator,
'keyboard': imports.ui.status.keyboard.XKBIndicator
'keyboard': imports.ui.status.keyboard.XKBIndicator,
'powerMenu': imports.gdm.powerMenu.PowerMenuButton
};
// To make sure the panel corners blend nicely with the panel,
@ -248,7 +249,7 @@ AppMenuButton.prototype = {
this._targetApp = null;
let bin = new St.Bin({ name: 'appMenu' });
this.actor.set_child(bin);
this.actor.add_actor(bin);
this.actor.reactive = false;
this._targetIsCurrent = false;
@ -563,10 +564,10 @@ ActivitiesButton.prototype = {
PanelMenu.Button.prototype._init.call(this, 0.0);
let container = new Shell.GenericContainer();
container.connect('get-preferred-width', Lang.bind(this, this._getPreferredWidth));
container.connect('get-preferred-height', Lang.bind(this, this._getPreferredHeight));
container.connect('allocate', Lang.bind(this, this._allocate));
this.actor.child = container;
container.connect('get-preferred-width', Lang.bind(this, this._containerGetPreferredWidth));
container.connect('get-preferred-height', Lang.bind(this, this._containerGetPreferredHeight));
container.connect('allocate', Lang.bind(this, this._containerAllocate));
this.actor.add_actor(container);
this.actor.name = 'panelActivities';
/* Translators: If there is no suitable word for "Activities"
@ -598,15 +599,15 @@ ActivitiesButton.prototype = {
this._xdndTimeOut = 0;
},
_getPreferredWidth: function(actor, forHeight, alloc) {
_containerGetPreferredWidth: function(actor, forHeight, alloc) {
[alloc.min_size, alloc.natural_size] = this._label.get_preferred_width(forHeight);
},
_getPreferredHeight: function(actor, forWidth, alloc) {
_containerGetPreferredHeight: function(actor, forWidth, alloc) {
[alloc.min_size, alloc.natural_size] = this._label.get_preferred_height(forWidth);
},
_allocate: function(actor, box, flags) {
_containerAllocate: function(actor, box, flags) {
this._label.allocate(box, flags);
// The hot corner needs to be outside any padding/alignment
@ -782,8 +783,10 @@ PanelCorner.prototype = {
button = this._findRightmostButton(this._box);
if (button) {
if (this._button && this._buttonStyleChangedSignalId)
if (this._button && this._buttonStyleChangedSignalId) {
this._button.disconnect(this._buttonStyleChangedSignalId);
this._button.style = null;
}
this._button = button;
@ -801,6 +804,10 @@ PanelCorner.prototype = {
let pseudoClass = button.get_style_pseudo_class();
this.actor.set_style_pseudo_class(pseudoClass);
}));
// The corner doesn't support theme transitions, so override
// the .panel-button default
button.style = 'transition-duration: 0';
}
},
@ -895,14 +902,6 @@ Panel.prototype = {
this.actor.remove_style_class_name('in-overview');
}));
if (global.session_type == Shell.SessionType.GDM) {
this._tray_icon_order = GDM_TRAY_ICON_ORDER;
this._tray_icon_shell_implementation = GDM_TRAY_ICON_SHELL_IMPLEMENTATION;
} else {
this._tray_icon_order = STANDARD_TRAY_ICON_ORDER;
this._tray_icon_shell_implementation = STANDARD_TRAY_ICON_SHELL_IMPLEMENTATION;
}
this._menus = new PopupMenu.PopupMenuManager(this);
this._leftBox = new St.BoxLayout({ name: 'panelLeft' });
@ -953,21 +952,12 @@ Panel.prototype = {
this._menus.addMenu(this._dateMenu.menu);
/* right */
// System status applets live in statusBox, while legacy tray icons
// live in trayBox
// The trayBox is hidden when there are no tray icons.
this._trayBox = new St.BoxLayout({ name: 'legacyTray' });
this._statusBox = new St.BoxLayout({ name: 'statusTray' });
this._trayBox.hide();
this._rightBox.add(this._trayBox);
this._rightBox.add(this._statusBox);
if (global.session_type == Shell.SessionType.USER) {
this._userMenu = new UserMenu.UserMenuButton();
this._userMenu.actor.name = 'panelStatus';
this._rightBox.add(this._userMenu.actor);
if (global.session_type == Shell.SessionType.GDM) {
this._status_area_order = GDM_STATUS_AREA_ORDER;
this._status_area_shell_implementation = GDM_STATUS_AREA_SHELL_IMPLEMENTATION;
} else {
this._status_area_order = STANDARD_STATUS_AREA_ORDER;
this._status_area_shell_implementation = STANDARD_STATUS_AREA_SHELL_IMPLEMENTATION;
}
Main.statusIconDispatcher.connect('status-icon-added', Lang.bind(this, this._onTrayIconAdded));
@ -1053,9 +1043,9 @@ Panel.prototype = {
},
startStatusArea: function() {
for (let i = 0; i < this._tray_icon_order.length; i++) {
let role = this._tray_icon_order[i];
let constructor = this._tray_icon_shell_implementation[role];
for (let i = 0; i < this._status_area_order.length; i++) {
let role = this._status_area_order[i];
let constructor = this._status_area_shell_implementation[role];
if (!constructor) {
// This icon is not implemented (this is a bug)
continue;
@ -1064,11 +1054,23 @@ Panel.prototype = {
let indicator = new constructor();
this.addToStatusArea(role, indicator, i);
}
},
// PopupMenuManager depends on menus being added in order for
// keyboard navigation
if (this._userMenu)
this._menus.addMenu(this._userMenu.menu);
_insertStatusItem: function(actor, position) {
let children = this._rightBox.get_children();
let i;
for (i = children.length - 1; i >= 0; i--) {
let rolePosition = children[i]._rolePosition;
if (position > rolePosition) {
this._rightBox.insert_actor(actor, i + 1);
break;
}
}
if (i == -1) {
// If we didn't find a position, we must be first
this._rightBox.insert_actor(actor, 0);
}
actor._rolePosition = position;
},
addToStatusArea: function(role, indicator, position) {
@ -1080,8 +1082,7 @@ Panel.prototype = {
if (!position)
position = 0;
this._statusBox.insert_actor(indicator.actor, position);
this._insertStatusItem(indicator.actor, position);
this._menus.addMenu(indicator.menu);
this._statusArea[role] = indicator;
@ -1094,39 +1095,24 @@ Panel.prototype = {
},
_onTrayIconAdded: function(o, icon, role) {
icon.height = PANEL_ICON_SIZE;
if (this._tray_icon_shell_implementation[role]) {
if (this._status_area_shell_implementation[role]) {
// This icon is legacy, and replaced by a Shell version
// Hide it
return;
}
// Figure out the index in our well-known order for this icon
let position = this._tray_icon_order.indexOf(role);
icon._rolePosition = position;
let children = this._trayBox.get_children();
let i;
// Walk children backwards, until we find one that isn't
// well-known, or one where we should follow
for (i = children.length - 1; i >= 0; i--) {
let rolePosition = children[i]._rolePosition;
if (!rolePosition || position > rolePosition) {
this._trayBox.insert_actor(icon, i + 1);
break;
}
}
if (i == -1) {
// If we didn't find a position, we must be first
this._trayBox.insert_actor(icon, 0);
}
// Make sure the trayBox is shown.
this._trayBox.show();
icon.height = PANEL_ICON_SIZE;
let buttonBox = new PanelMenu.ButtonBox();
let box = buttonBox.actor;
box.add_actor(icon);
this._insertStatusItem(box, this._status_area_order.indexOf(role));
},
_onTrayIconRemoved: function(o, icon) {
if (icon.get_parent() != null)
this._trayBox.remove_actor(icon);
let box = icon.get_parent();
if (box && box._delegate instanceof PanelMenu.ButtonBox)
box.destroy();
},
};

View File

@ -1,27 +1,111 @@
/* -*- mode: js2; js2-basic-offset: 4; indent-tabs-mode: nil -*- */
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
const Clutter = imports.gi.Clutter;
const Gtk = imports.gi.Gtk;
const Lang = imports.lang;
const Shell = imports.gi.Shell;
const Signals = imports.signals;
const St = imports.gi.St;
const Lang = imports.lang;
const PopupMenu = imports.ui.popupMenu;
const Main = imports.ui.main;
const Params = imports.misc.params;
const PopupMenu = imports.ui.popupMenu;
function ButtonBox(params) {
this._init.apply(this, arguments);
};
ButtonBox.prototype = {
_init: function(params) {
params = Params.parse(params, { style_class: 'panel-button' }, true);
this.actor = new Shell.GenericContainer(params);
this.actor._delegate = this;
this.actor.connect('get-preferred-width', Lang.bind(this, this._getPreferredWidth));
this.actor.connect('get-preferred-height', Lang.bind(this, this._getPreferredHeight));
this.actor.connect('allocate', Lang.bind(this, this._allocate));
this.actor.connect('style-changed', Lang.bind(this, this._onStyleChanged));
this._minHPadding = this._natHPadding = 0.0;
},
_onStyleChanged: function(actor) {
let themeNode = actor.get_theme_node();
this._minHPadding = themeNode.get_length('-minimum-hpadding');
this._natHPadding = themeNode.get_length('-natural-hpadding');
},
_getPreferredWidth: function(actor, forHeight, alloc) {
let children = actor.get_children();
let child = children.length > 0 ? children[0] : null;
if (child) {
[alloc.min_size, alloc.natural_size] = child.get_preferred_width(-1);
} else {
alloc.min_size = alloc.natural_size = 0;
}
alloc.min_size += 2 * this._minHPadding;
alloc.natural_size += 2 * this._natHPadding;
},
_getPreferredHeight: function(actor, forWidth, alloc) {
let children = actor.get_children();
let child = children.length > 0 ? children[0] : null;
if (child) {
[alloc.min_size, alloc.natural_size] = child.get_preferred_height(-1);
} else {
alloc.min_size = alloc.natural_size = 0;
}
},
_allocate: function(actor, box, flags) {
let children = actor.get_children();
if (children.length == 0)
return;
let child = children[0];
let [minWidth, natWidth] = child.get_preferred_width(-1);
let [minHeight, natHeight] = child.get_preferred_height(-1);
let availWidth = box.x2 - box.x1;
let availHeight = box.y2 - box.y1;
let childBox = new Clutter.ActorBox();
if (natWidth + 2 * this._natHPadding <= availWidth) {
childBox.x1 = this._natHPadding;
childBox.x2 = availWidth - this._natHPadding;
} else {
childBox.x1 = this._minHPadding;
childBox.x2 = availWidth - this._minHPadding;
}
if (natHeight <= availHeight) {
childBox.y1 = Math.floor((availHeight - natHeight) / 2);
childBox.y2 = childBox.y1 + natHeight;
} else {
childBox.y1 = 0;
childBox.y2 = availHeight;
}
child.allocate(childBox, flags);
},
}
function Button(menuAlignment) {
this._init(menuAlignment);
}
Button.prototype = {
__proto__: ButtonBox.prototype,
_init: function(menuAlignment) {
this.actor = new St.Bin({ style_class: 'panel-button',
reactive: true,
can_focus: true,
x_fill: true,
y_fill: false,
track_hover: true });
this.actor._delegate = this;
ButtonBox.prototype._init.call(this, { reactive: true,
can_focus: true,
track_hover: true });
this.actor.connect('button-press-event', Lang.bind(this, this._onButtonPress));
this.actor.connect('key-press-event', Lang.bind(this, this._onSourceKeyPress));
this.menu = new PopupMenu.PopupMenu(this.actor, menuAlignment, St.Side.TOP);
@ -112,7 +196,8 @@ SystemStatusButton.prototype = {
this._iconActor = new St.Icon({ icon_name: iconName,
icon_type: St.IconType.SYMBOLIC,
style_class: 'system-status-icon' });
this.actor.set_child(this._iconActor);
this.actor.add_actor(this._iconActor);
this.actor.add_style_class_name('panel-status-button');
this.setTooltip(tooltipText);
},

View File

@ -1,4 +1,4 @@
/* -*- mode: js2; js2-basic-offset: 4; indent-tabs-mode: nil -*- */
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
const GLib = imports.gi.GLib;
const Gio = imports.gi.Gio;

View File

@ -1,5 +1,5 @@
/* -*- mode: js2; js2-basic-offset: 4; indent-tabs-mode: nil -*-
*
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
/*
* Copyright 2010 Red Hat, Inc
*
* This program is free software; you can redistribute it and/or modify
@ -33,6 +33,7 @@ const Polkit = imports.gi.Polkit;
const PolkitAgent = imports.gi.PolkitAgent;
const ModalDialog = imports.ui.modalDialog;
const ShellEntry = imports.ui.shellEntry;
function AuthenticationDialog(actionId, message, cookie, userNames) {
this._init(actionId, message, cookie, userNames);
@ -139,9 +140,11 @@ AuthenticationDialog.prototype = {
this._passwordEntry = new St.Entry({ style_class: 'polkit-dialog-password-entry',
text: "",
can_focus: true});
ShellEntry.addContextMenu(this._passwordEntry, { isPassword: true });
this._passwordEntry.clutter_text.connect('activate', Lang.bind(this, this._onEntryActivate));
this._passwordBox.add(this._passwordEntry,
{expand: true });
this.setInitialKeyFocus(this._passwordEntry);
this._passwordBox.hide();
this._errorMessageLabel = new St.Label({ style_class: 'polkit-dialog-error-label' });
@ -186,13 +189,6 @@ AuthenticationDialog.prototype = {
this._session.connect('request', Lang.bind(this, this._onSessionRequest));
this._session.connect('show-error', Lang.bind(this, this._onSessionShowError));
this._session.connect('show-info', Lang.bind(this, this._onSessionShowInfo));
// Delay focus grab to avoid ModalDialog stealing focus with
// its buttons
this.connect('opened',
Lang.bind(this, function() {
this._passwordEntry.grab_key_focus();
}));
},
startAuthentication: function() {

View File

@ -1,4 +1,4 @@
/* -*- mode: js2; js2-basic-offset: 4; indent-tabs-mode: nil -*- */
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
const Cairo = imports.cairo;
const Clutter = imports.gi.Clutter;
@ -35,6 +35,7 @@ PopupBaseMenuItem.prototype = {
params = Params.parse (params, { reactive: true,
activate: true,
hover: true,
sensitive: true,
style_class: null
});
this.actor = new Shell.GenericContainer({ style_class: 'popup-menu-item',
@ -52,11 +53,15 @@ PopupBaseMenuItem.prototype = {
this._columnWidths = null;
this._spacing = 0;
this.active = false;
this._activatable = params.reactive && params.activate;
this.sensitive = this._activatable && params.sensitive;
this.setSensitive(this.sensitive);
if (params.style_class)
this.actor.add_style_class_name(params.style_class);
if (params.reactive && params.activate) {
if (this._activatable) {
this.actor.connect('button-release-event', Lang.bind(this, this._onButtonReleaseEvent));
this.actor.connect('key-press-event', Lang.bind(this, this._onKeyPressEvent));
}
@ -117,6 +122,23 @@ PopupBaseMenuItem.prototype = {
}
},
setSensitive: function(sensitive) {
if (!this._activatable)
return;
if (this.sensitive == sensitive)
return;
this.sensitive = sensitive;
this.actor.reactive = sensitive;
this.actor.can_focus = sensitive;
if (sensitive)
this.actor.remove_style_pseudo_class('insensitive');
else
this.actor.add_style_pseudo_class('insensitive');
this.emit('sensitive-changed', sensitive);
},
destroy: function() {
this.actor.destroy();
this.emit('destroy');
@ -222,10 +244,25 @@ PopupBaseMenuItem.prototype = {
},
_getPreferredHeight: function(actor, forWidth, alloc) {
let height = 0;
let height = 0, x = 0, minWidth, childWidth;
for (let i = 0; i < this._children.length; i++) {
let child = this._children[i];
let [min, natural] = child.actor.get_preferred_height(forWidth);
if (this._columnWidths) {
if (child.span == -1) {
childWidth = 0;
for (let j = i; j < this._columnWidths.length; j++)
childWidth += this._columnWidths[j]
} else
childWidth = this._columnWidths[i];
} else {
if (child.span == -1)
childWidth = forWidth - x;
else
[minWidth, childWidth] = child.actor.get_preferred_width(-1);
}
x += childWidth;
let [min, natural] = child.actor.get_preferred_height(childWidth);
if (natural > height)
height = natural;
}
@ -283,7 +320,14 @@ PopupBaseMenuItem.prototype = {
}
extraWidth = availWidth - naturalWidth;
} else {
availWidth = naturalWidth;
if (child.span == -1) {
if (direction == St.TextDirection.LTR)
availWidth = box.x2 - x;
else
availWidth = x - box.x1;
} else {
availWidth = naturalWidth;
}
extraWidth = 0;
}
@ -291,7 +335,7 @@ PopupBaseMenuItem.prototype = {
if (child.expand) {
childBox.x1 = x;
childBox.x2 = x + availWidth;
} else if (child.align === St.Align.CENTER) {
} else if (child.align === St.Align.MIDDLE) {
childBox.x1 = x + Math.round(extraWidth / 2);
childBox.x2 = childBox.x1 + naturalWidth;
} else if (child.align === St.Align.END) {
@ -305,7 +349,7 @@ PopupBaseMenuItem.prototype = {
if (child.expand) {
childBox.x1 = x - availWidth;
childBox.x2 = x;
} else if (child.align === St.Align.CENTER) {
} else if (child.align === St.Align.MIDDLE) {
childBox.x1 = x - Math.round(extraWidth / 2);
childBox.x2 = childBox.x1 + naturalWidth;
} else if (child.align === St.Align.END) {
@ -899,6 +943,17 @@ PopupMenuBase.prototype = {
this.emit('active-changed', null);
}
}));
menuItem._sensitiveChangeId = menuItem.connect('sensitive-changed', Lang.bind(this, function(menuItem, sensitive) {
if (!sensitive && this._activeMenuItem == menuItem) {
if (!this.actor.navigate_focus(menuItem.actor,
Gtk.DirectionType.TAB_FORWARD,
true))
this.actor.grab_key_focus();
} else if (sensitive && this._activeMenuItem == null) {
if (global.stage.get_key_focus() == this.actor)
menuItem.actor.grab_key_focus();
}
}));
menuItem._activateId = menuItem.connect('activate', Lang.bind(this, function (menuItem, event) {
this.emit('activate', menuItem);
this.close(true);
@ -906,6 +961,7 @@ PopupMenuBase.prototype = {
menuItem.connect('destroy', Lang.bind(this, function(emitter) {
menuItem.disconnect(menuItem._activateId);
menuItem.disconnect(menuItem._activeChangeId);
menuItem.disconnect(menuItem._sensitiveChangeId);
if (menuItem.menu) {
menuItem.menu.disconnect(menuItem._subMenuActivateId);
menuItem.menu.disconnect(menuItem._subMenuActiveChangeId);
@ -1086,10 +1142,10 @@ function PopupMenu() {
PopupMenu.prototype = {
__proto__: PopupMenuBase.prototype,
_init: function(sourceActor, alignment, arrowSide) {
_init: function(sourceActor, arrowAlignment, arrowSide) {
PopupMenuBase.prototype._init.call (this, sourceActor, 'popup-menu-content');
this._alignment = alignment;
this._arrowAlignment = arrowAlignment;
this._arrowSide = arrowSide;
this._boxPointer = new BoxPointer.BoxPointer(arrowSide,
@ -1142,13 +1198,17 @@ PopupMenu.prototype = {
this._boxPointer.setArrowOrigin(origin);
},
setSourceAlignment: function(alignment) {
this._boxPointer.setSourceAlignment(alignment);
},
open: function(animate) {
if (this.isOpen)
return;
this.isOpen = true;
this._boxPointer.setPosition(this.sourceActor, this._alignment);
this._boxPointer.setPosition(this.sourceActor, this._arrowAlignment);
this._boxPointer.show(animate);
this.actor.raise_top();
@ -1528,7 +1588,8 @@ PopupComboBoxMenuItem.prototype = {
this.addActor(this._itemBox);
let expander = new St.Label({ text: '\u2304' });
this.addActor(expander, { align: St.Align.END });
this.addActor(expander, { align: St.Align.END,
span: -1 });
this._menu = new PopupComboMenu(this.actor);
Main.uiGroup.add_actor(this._menu.actor);

View File

@ -1,4 +1,4 @@
/* -*- mode: js2; js2-basic-offset: 4; indent-tabs-mode: nil -*- */
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
const Clutter = imports.gi.Clutter;
const Gio = imports.gi.Gio;
@ -12,6 +12,7 @@ const Signals = imports.signals;
const FileUtils = imports.misc.fileUtils;
const Main = imports.ui.main;
const ModalDialog = imports.ui.modalDialog;
const ShellEntry = imports.ui.shellEntry;
const Tweener = imports.ui.tweener;
const Util = imports.misc.util;
const History = imports.misc.history;
@ -210,6 +211,7 @@ __proto__: ModalDialog.ModalDialog.prototype,
this.contentLayout.add(label, { y_align: St.Align.START });
let entry = new St.Entry({ style_class: 'run-dialog-entry' });
ShellEntry.addContextMenu(entry);
this._entryText = entry.clutter_text;
this.contentLayout.add(entry, { y_align: St.Align.START });

View File

@ -1,4 +1,4 @@
/* -*- mode: js2; js2-basic-offset: 4; indent-tabs-mode: nil -*- */
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
const DBus = imports.dbus;
const Gio = imports.gi.Gio;

View File

@ -1,4 +1,4 @@
/* -*- mode: js2; js2-basic-offset: 4; indent-tabs-mode: nil -*- */
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
const Gio = imports.gi.Gio;
const GLib = imports.gi.GLib;

View File

@ -1,4 +1,4 @@
/* -*- mode: js2; js2-basic-offset: 4; indent-tabs-mode: nil -*- */
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
const Clutter = imports.gi.Clutter;
const Lang = imports.lang;

View File

@ -1,4 +1,4 @@
/* -*- mode: js2; js2-basic-offset: 4; indent-tabs-mode: nil -*- */
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
const DBus = imports.dbus;
const Lang = imports.lang;

173
js/ui/shellEntry.js Normal file
View File

@ -0,0 +1,173 @@
const Clutter = imports.gi.Clutter;
const Gtk = imports.gi.Gtk;
const Lang = imports.lang;
const St = imports.gi.St;
const Main = imports.ui.main;
const Params = imports.misc.params;
const PopupMenu = imports.ui.popupMenu;
function _EntryMenu(entry, params) {
this._init(entry, params);
};
_EntryMenu.prototype = {
__proto__: PopupMenu.PopupMenu.prototype,
_init: function(entry, params) {
params = Params.parse (params, { isPassword: false });
PopupMenu.PopupMenu.prototype._init.call(this, entry, 0, St.Side.TOP);
this.actor.add_style_class_name('entry-context-menu');
this._entry = entry;
this._clipboard = St.Clipboard.get_default();
// Populate menu
let item;
item = new PopupMenu.PopupMenuItem(_("Copy"));
item.connect('activate', Lang.bind(this, this._onCopyActivated));
this.addMenuItem(item);
this._copyItem = item;
item = new PopupMenu.PopupMenuItem(_("Paste"));
item.connect('activate', Lang.bind(this, this._onPasteActivated));
this.addMenuItem(item);
this._pasteItem = item;
this._passwordItem = null;
if (params.isPassword) {
item = new PopupMenu.PopupMenuItem('');
item.connect('activate', Lang.bind(this,
this._onPasswordActivated));
this.addMenuItem(item);
this._passwordItem = item;
}
Main.uiGroup.add_actor(this.actor);
this.actor.hide();
},
open: function() {
this._updatePasteItem();
this._updateCopyItem();
if (this._passwordItem)
this._updatePasswordItem();
let direction = Gtk.DirectionType.TAB_FORWARD;
if (!this.actor.navigate_focus(null, direction, false))
this.actor.grab_key_focus();
PopupMenu.PopupMenu.prototype.open.call(this);
},
_updateCopyItem: function() {
let selection = this._entry.clutter_text.get_selection();
this._copyItem.setSensitive(selection && selection != '');
},
_updatePasteItem: function() {
this._clipboard.get_text(Lang.bind(this,
function(clipboard, text) {
this._pasteItem.setSensitive(text && text != '');
}));
},
_updatePasswordItem: function() {
let textHidden = (this._entry.clutter_text.password_char);
if (textHidden)
this._passwordItem.label.set_text(_("Show Text"));
else
this._passwordItem.label.set_text(_("Hide Text"));
},
_onCopyActivated: function() {
let selection = this._entry.clutter_text.get_selection();
this._clipboard.set_text(selection);
},
_onPasteActivated: function() {
this._clipboard.get_text(Lang.bind(this,
function(clipboard, text) {
if (!text)
return;
this._entry.clutter_text.delete_selection();
let pos = this._entry.clutter_text.get_cursor_position();
this._entry.clutter_text.insert_text(text, pos);
}));
},
_onPasswordActivated: function() {
let visible = !!(this._entry.clutter_text.password_char);
this._entry.clutter_text.set_password_char(visible ? '' : '\u25cf');
}
};
function _setMenuAlignment(entry, stageX) {
let [success, entryX, entryY] = entry.transform_stage_point(stageX, 0);
if (success)
entry._menu.setSourceAlignment(entryX / entry.width);
};
function _onClicked(action, actor) {
let entry = actor._menu ? actor : actor.get_parent();
if (entry._menu.isOpen) {
entry._menu.close();
} else if (action.get_button() == 3) {
let [stageX, stageY] = action.get_coords();
_setMenuAlignment(entry, stageX);
entry._menu.open();
}
};
function _onLongPress(action, actor, state) {
let entry = actor._menu ? actor : actor.get_parent();
if (state == Clutter.LongPressState.QUERY)
return action.get_button() == 1 && !entry._menu.isOpen;
if (state == Clutter.LongPressState.ACTIVATE) {
let [stageX, stageY] = action.get_coords();
_setMenuAlignment(entry, stageX);
entry._menu.open();
}
return false;
};
function _onPopup(actor) {
let entry = actor._menu ? actor : actor.get_parent();
let [success, textX, textY, lineHeight] = entry.clutter_text.position_to_coords(-1);
if (success)
entry._menu.setSourceAlignment(textX / entry.width);
entry._menu.open();
};
function addContextMenu(entry, params) {
if (entry._menu)
return;
entry._menu = new _EntryMenu(entry, params);
entry._menuManager = new PopupMenu.PopupMenuManager({ actor: entry });
entry._menuManager.addMenu(entry._menu);
let clickAction;
// Add a click action to both the entry and its clutter_text; the former
// so padding is included in the clickable area, the latter because the
// event processing of ClutterText prevents event-bubbling.
clickAction = new Clutter.ClickAction();
clickAction.connect('clicked', _onClicked);
clickAction.connect('long-press', _onLongPress);
entry.clutter_text.add_action(clickAction);
clickAction = new Clutter.ClickAction();
clickAction.connect('clicked', _onClicked);
clickAction.connect('long-press', _onLongPress);
entry.add_action(clickAction);
entry.connect('popup-menu', _onPopup);
}

View File

@ -1,4 +1,4 @@
/* -*- mode: js2; js2-basic-offset: 4; indent-tabs-mode: nil -*- */
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
const Lang = imports.lang;
const Signals = imports.signals;

View File

@ -1,4 +1,4 @@
/* -*- mode: js2; js2-basic-offset: 4; indent-tabs-mode: nil -*- */
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
const DBus = imports.dbus;
const GConf = imports.gi.GConf;
@ -68,9 +68,9 @@ ATIndicator.prototype = {
// 'screen-reader-enabled');
// this.menu.addMenuItem(screenReader);
// let screenKeyboard = this._buildItem(_("Screen Keyboard"), APPLICATIONS_SCHEMA,
// 'screen-keyboard-enabled');
// this.menu.addMenuItem(screenKeyboard);
let screenKeyboard = this._buildItem(_("Screen Keyboard"), APPLICATIONS_SCHEMA,
'screen-keyboard-enabled');
this.menu.addMenuItem(screenKeyboard);
let visualBell = this._buildItemGConf(_("Visual Alerts"), client, KEY_VISUAL_BELL);
this.menu.addMenuItem(visualBell);

View File

@ -1,4 +1,4 @@
/* -*- mode: js2; js2-basic-offset: 4; indent-tabs-mode: nil -*- */
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
const Clutter = imports.gi.Clutter;
const Gdk = imports.gi.Gdk;

View File

@ -1,4 +1,4 @@
/* -*- mode: js2; js2-basic-offset: 4; indent-tabs-mode: nil -*- */
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
const Clutter = imports.gi.Clutter;
const GdkPixbuf = imports.gi.GdkPixbuf;
@ -49,10 +49,11 @@ XKBIndicator.prototype = {
PanelMenu.Button.prototype._init.call(this, St.Align.START);
this._container = new Shell.GenericContainer();
this._container.connect('get-preferred-width', Lang.bind(this, this._get_preferred_width));
this._container.connect('get-preferred-height', Lang.bind(this, this._get_preferred_height));
this._container.connect('allocate', Lang.bind(this, this._allocate));
this.actor.set_child(this._container);
this._container.connect('get-preferred-width', Lang.bind(this, this._containerGetPreferredWidth));
this._container.connect('get-preferred-height', Lang.bind(this, this._containerGetPreferredHeight));
this._container.connect('allocate', Lang.bind(this, this._containerAllocate));
this.actor.add_actor(this._container);
this.actor.add_style_class_name('panel-status-button');
this._iconActor = new St.Icon({ icon_name: 'keyboard', icon_type: St.IconType.SYMBOLIC, style_class: 'system-status-icon' });
this._container.add_actor(this._iconActor);
@ -61,21 +62,23 @@ XKBIndicator.prototype = {
this._showFlags = false;
this._config = Gkbd.Configuration.get();
this._config.connect('changed', Lang.bind(this, this._sync_config));
this._config.connect('group-changed', Lang.bind(this, this._sync_group));
this._config.connect('changed', Lang.bind(this, this._syncConfig));
this._config.connect('group-changed', Lang.bind(this, this._syncGroup));
this._config.start_listen();
this._sync_config();
this._syncConfig();
this.menu.addMenuItem(new PopupMenu.PopupSeparatorMenuItem());
this.menu.addAction(_("Show Keyboard Layout"), Lang.bind(this, function() {
Main.overview.hide();
Util.spawn(['gkbd-keyboard-display', '-g', String(this._config.get_current_group() + 1)]);
}));
if (global.session_type == Shell.SessionType.USER) {
this.menu.addMenuItem(new PopupMenu.PopupSeparatorMenuItem());
this.menu.addAction(_("Show Keyboard Layout"), Lang.bind(this, function() {
Main.overview.hide();
Util.spawn(['gkbd-keyboard-display', '-g', String(this._config.get_current_group() + 1)]);
}));
}
this.menu.addSettingsAction(_("Region and Language Settings"), 'gnome-region-panel.desktop');
},
_adjust_group_names: function(names) {
_adjustGroupNames: function(names) {
// Disambiguate duplicate names with a subscript
// This is O(N^2) to avoid sorting names
// but N <= 4 so who cares?
@ -97,7 +100,7 @@ XKBIndicator.prototype = {
return names;
},
_sync_config: function() {
_syncConfig: function() {
this._showFlags = this._config.if_flags_shown();
if (this._showFlags) {
this._container.set_skip_paint(this._iconActor, false);
@ -119,7 +122,7 @@ XKBIndicator.prototype = {
for (let i = 0; i < this._labelActors.length; i++)
this._labelActors[i].destroy();
let short_names = this._adjust_group_names(this._config.get_short_group_names());
let short_names = this._adjustGroupNames(this._config.get_short_group_names());
this._selectedLayout = null;
this._layoutItems = [ ];
@ -144,10 +147,10 @@ XKBIndicator.prototype = {
this._container.set_skip_paint(shortLabel, true);
}
this._sync_group();
this._syncGroup();
},
_sync_group: function() {
_syncGroup: function() {
let selected = this._config.get_current_group();
if (this._selectedLayout) {
@ -170,10 +173,10 @@ XKBIndicator.prototype = {
this._selectedLayout = item;
},
_get_preferred_width: function(container, for_height, alloc) {
/* Here, and in _get_preferred_height, we need to query for the
height of all children, but we ignore the results for those
we don't actually display. */
_containerGetPreferredWidth: function(container, for_height, alloc) {
// Here, and in _containerGetPreferredHeight, we need to query
// for the height of all children, but we ignore the results
// for those we don't actually display.
let max_min_width = 0, max_natural_width = 0;
if (this._showFlags)
[max_min_width, max_natural_width] = this._iconActor.get_preferred_width(for_height);
@ -190,7 +193,7 @@ XKBIndicator.prototype = {
alloc.natural_size = max_natural_width;
},
_get_preferred_height: function(container, for_width, alloc) {
_containerGetPreferredHeight: function(container, for_width, alloc) {
let max_min_height = 0, max_natural_height = 0;
if (this._showFlags)
[max_min_height, max_natural_height] = this._iconActor.get_preferred_height(for_width);
@ -207,7 +210,7 @@ XKBIndicator.prototype = {
alloc.natural_size = max_natural_height;
},
_allocate: function(container, box, flags) {
_containerAllocate: function(container, box, flags) {
// translate box to (0, 0)
box.x2 -= box.x1;
box.x1 = 0;

View File

@ -1,4 +1,4 @@
// -*- mode: js2; indent-tabs-mode: nil; js2-basic-offset: 4 -*-
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
const ByteArray = imports.byteArray;
const DBus = imports.dbus;
const GLib = imports.gi.GLib;
@ -1291,6 +1291,9 @@ NMDeviceWireless.prototype = {
apObj.accessPoints.splice(i, 1);
if (apObj.accessPoints.length == 0) {
if (this._activeNetwork == apObj)
this._activeNetwork = null;
if (apObj.item)
apObj.item.destroy();
@ -1480,6 +1483,11 @@ NMDeviceWireless.prototype = {
},
_createNetworkItem: function(apObj, position) {
if(!apObj.accessPoints || apObj.accessPoints.length == 0) {
// this should not happen, but I have no idea why it happens
return;
}
if(apObj.connections.length > 0) {
if (apObj.connections.length == 1)
apObj.item = this._createAPItem(apObj.connections[0], apObj, false);
@ -1742,13 +1750,6 @@ NMApplet.prototype = {
if (wrapperClass) {
let wrapper = new wrapperClass(this._client, device, this._connections);
wrapper._networkLostId = wrapper.connect('network-lost', Lang.bind(this, function(device) {
this._notifyForDevice(device, 'network-offline',
_("Connectivity lost"),
_("You are no longer connected to the network"),
// set critical urgency to popup the notification automatically
MessageTray.Urgency.CRITICAL);
}));
wrapper._activationFailedId = wrapper.connect('activation-failed', Lang.bind(this, function(device, reason) {
// XXX: nm-applet has no special text depending on reason
// but I'm not sure of this generic message
@ -1761,7 +1762,6 @@ NMApplet.prototype = {
this._syncSectionTitle(dev.category);
}));
wrapper._destroyId = wrapper.connect('destroy', function(wrapper) {
wrapper.disconnect(wrapper._networkLostId);
wrapper.disconnect(wrapper._activationFailedId);
wrapper.disconnect(wrapper._deviceStateChangedId);
wrapper.disconnect(wrapper._destroyId);

View File

@ -1,4 +1,4 @@
/* -*- mode: js2; js2-basic-offset: 4; indent-tabs-mode: nil -*- */
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
const Gio = imports.gi.Gio;
const DBus = imports.dbus;
@ -43,8 +43,8 @@ const UPDeviceState = {
const PowerManagerInterface = {
name: 'org.gnome.SettingsDaemon.Power',
methods: [
{ name: 'GetDevices', inSignature: '', outSignature: 'a(susbut)' },
{ name: 'GetPrimaryDevice', inSignature: '', outSignature: '(susbut)' },
{ name: 'GetDevices', inSignature: '', outSignature: 'a(susdut)' },
{ name: 'GetPrimaryDevice', inSignature: '', outSignature: '(susdut)' },
],
signals: [
{ name: 'Changed', inSignature: '' },
@ -155,7 +155,7 @@ Indicator.prototype = {
_devicesChanged: function() {
this._proxy.GetRemote('Icon', Lang.bind(this, function(icon, error) {
if (icon) {
let gicon = Shell.util_icon_from_string (icon);
let gicon = Gio.icon_new_for_string(icon);
this.setGIcon(gicon);
this.actor.show();
} else {
@ -183,7 +183,7 @@ DeviceItem.prototype = {
this._box = new St.BoxLayout({ style_class: 'popup-device-menu-item' });
this._label = new St.Label({ text: this._deviceTypeToString(device_type) });
this._icon = new St.Icon({ gicon: Shell.util_icon_from_string(icon),
this._icon = new St.Icon({ gicon: Gio.icon_new_for_string(icon),
icon_type: St.IconType.SYMBOLIC,
style_class: 'popup-menu-icon' });

View File

@ -1,4 +1,4 @@
/* -*- mode: js2; js2-basic-offset: 4; indent-tabs-mode: nil -*- */
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
const Clutter = imports.gi.Clutter;
const DBus = imports.dbus;

View File

@ -1,4 +1,4 @@
/* -*- mode: js2; js2-basic-offset: 4; indent-tabs-mode: nil -*- */
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
const Lang = imports.lang;
const Shell = imports.gi.Shell;

View File

@ -1,4 +1,4 @@
/* -*- mode: js2; js2-basic-offset: 4; indent-tabs-mode: nil -*- */
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
const DBus = imports.dbus;
const Gio = imports.gi.Gio;
@ -83,6 +83,9 @@ Client.prototype = {
this._chatSources = {};
this._chatState = Tp.ChannelChatState.ACTIVE;
// account path -> AccountNotification
this._accountNotifications = {};
// Set up a SimpleObserver, which will call _observeChannels whenever a
// channel matching its filters is detected.
// The second argument, recover, means _observeChannels will be run
@ -254,7 +257,7 @@ Client.prototype = {
// FIXME: We don't have a 'chat room' icon (bgo #653737) use
// system-users for now as Empathy does.
let source = new ApproverSource(dispatchOp, _("Invitation"),
Shell.util_icon_from_string('system-users'));
Gio.icon_new_for_string('system-users'));
Main.messageTray.add(source);
let notif = new RoomInviteNotification(source, dispatchOp, channel, contacts[0]);
@ -302,6 +305,8 @@ Client.prototype = {
Shell.get_tp_contacts(conn, [targetHandle],
contactFeatures,
Lang.bind(this, this._createAudioVideoSource, channel, context, dispatchOp));
context.delay();
},
_createAudioVideoSource: function(connection, contacts, failed, channel, context, dispatchOp) {
@ -320,8 +325,8 @@ Client.prototype = {
// We got the TpContact
let source = new ApproverSource(dispatchOp, _("Call"), isVideo ?
Shell.util_icon_from_string('camera-web') :
Shell.util_icon_from_string('audio-input-microphone'));
Gio.icon_new_for_string('camera-web') :
Gio.icon_new_for_string('audio-input-microphone'));
Main.messageTray.add(source);
let notif = new AudioVideoNotification(source, dispatchOp, channel, contacts[0], isVideo);
@ -335,6 +340,8 @@ Client.prototype = {
Shell.get_tp_contacts(conn, [targetHandle],
contactFeatures,
Lang.bind(this, this._createFileTransferSource, channel, context, dispatchOp));
context.delay();
},
_createFileTransferSource: function(connection, contacts, failed, channel, context, dispatchOp) {
@ -420,7 +427,6 @@ Client.prototype = {
/* Display notification to ask user to accept/reject request */
let source = this._ensureSubscriptionSource();
Main.messageTray.add(source);
let notif = new SubscriptionRequestNotification(source, contact);
source.notify(notif);
@ -430,6 +436,7 @@ Client.prototype = {
if (this._subscriptionSource == null) {
this._subscriptionSource = new MultiNotificationSource(
_("Subscription request"), 'gtk-dialog-question');
Main.messageTray.add(this._subscriptionSource);
this._subscriptionSource.connect('destroy', Lang.bind(this, function () {
this._subscriptionSource = null;
}));
@ -446,11 +453,18 @@ Client.prototype = {
return;
}
let notif = this._accountNotifications[account.get_object_path()];
if (notif)
return;
/* Display notification that account failed to connect */
let source = this._ensureAccountSource();
Main.messageTray.add(source);
let notif = new AccountNotification(source, account, connectionError);
notif = new AccountNotification(source, account, connectionError);
this._accountNotifications[account.get_object_path()] = notif;
notif.connect('destroy', Lang.bind(this, function() {
delete this._accountNotifications[account.get_object_path()];
}));
source.notify(notif);
},
@ -458,6 +472,7 @@ Client.prototype = {
if (this._accountSource == null) {
this._accountSource = new MultiNotificationSource(
_("Connection error"), 'gtk-dialog-error');
Main.messageTray.add(this._accountSource);
this._accountSource.connect('destroy', Lang.bind(this, function () {
this._accountSource = null;
}));
@ -524,21 +539,18 @@ ChatSource.prototype = {
_updateAlias: function() {
let oldAlias = this.title;
this.setTitle(this._contact.get_alias());
this._notification.appendAliasChange(oldAlias, this.title);
this.pushNotification(this._notification);
let newAlias = this._contact.get_alias();
if (oldAlias == newAlias)
return;
this.setTitle(newAlias);
this._notification.appendAliasChange(oldAlias, newAlias);
},
createNotificationIcon: function() {
this._iconBox = new St.Bin({ style_class: 'avatar-box' });
this._iconBox._size = this.ICON_SIZE;
this._updateAvatarIcon();
return this._iconBox;
},
_updateAvatarIcon: function() {
let textureCache = St.TextureCache.get_default();
let file = this._contact.get_avatar_file();
@ -550,12 +562,19 @@ ChatSource.prototype = {
icon_type: St.IconType.FULLCOLOR,
icon_size: this._iconBox._size });
}
return this._iconBox;
},
_updateAvatarIcon: function() {
this._setSummaryIcon(this.createNotificationIcon());
this._notification.update(this._notification.title, null, { customContent: true, icon: this.createNotificationIcon() });
},
open: function(notification) {
if (this._client.is_handling_channel(this._channel)) {
// We are handling the channel, try to pass it to Empathy
this._client.delegate_channels_async([this._channel], global.get_current_time(), "", null);
this._client.delegate_channels_async([this._channel], global.get_current_time(), '', null);
}
else {
// We are not the handler, just ask to present the channel
@ -1183,6 +1202,7 @@ AudioVideoNotification.prototype = {
this.setResident(true);
this.addButton('reject', _("Reject"));
/* translators: this is a button label (verb), not a noun */
this.addButton('answer', _("Answer"));
this.connect('action-invoked', Lang.bind(this, function(self, action) {
@ -1448,17 +1468,12 @@ AccountNotification.prototype = {
_("Connection to %s failed").format(account.get_display_name()),
null, { customContent: true });
let message;
if (connectionError in _connectionErrorMessages) {
message = _connectionErrorMessages[connectionError];
} else {
message = _("Unknown reason");
}
this._label = new St.Label();
this.addActor(this._label);
this._updateMessage(connectionError);
this._account = account;
this.addBody(message);
this.addButton('reconnect', _("Reconnect"));
this.addButton('edit', _("Edit account"));
@ -1492,11 +1507,25 @@ AccountNotification.prototype = {
this._connectionStatusId = account.connect('notify::connection-status',
Lang.bind(this, function() {
if (account.connection_status != Tp.ConnectionStatus.DISCONNECTED)
let status = account.connection_status;
if (status == Tp.ConnectionStatus.CONNECTED) {
this.destroy();
} else if (status == Tp.ConnectionStatus.DISCONNECTED) {
this._updateMessage(account.connection_error);
}
}));
},
_updateMessage: function(connectionError) {
let message;
if (connectionError in _connectionErrorMessages) {
message = _connectionErrorMessages[connectionError];
} else {
message = _("Unknown reason");
}
this._label.set_text(message);
},
destroy: function() {
if (this._enabledId != 0) {
this._account.disconnect(this._enabledId);

View File

@ -1,4 +1,4 @@
/* -*- mode: js2; js2-basic-offset: 4; indent-tabs-mode: nil -*- */
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
const Clutter = imports.gi.Clutter;
const Lang = imports.lang;

View File

@ -1,10 +1,11 @@
/* -*- mode: js2; js2-basic-offset: 4; indent-tabs-mode: nil -*- */
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
const AccountsService = imports.gi.AccountsService;
const DBus = imports.dbus;
const Gio = imports.gi.Gio;
const GLib = imports.gi.GLib;
const Lang = imports.lang;
const Pango = imports.gi.Pango;
const Shell = imports.gi.Shell;
const St = imports.gi.St;
const Tp = imports.gi.TelepathyGLib;
@ -22,7 +23,6 @@ const DISABLE_USER_SWITCH_KEY = 'disable-user-switching';
const DISABLE_LOCK_SCREEN_KEY = 'disable-lock-screen';
const DISABLE_LOG_OUT_KEY = 'disable-log-out';
const WRAP_WIDTH = 150;
const DIALOG_ICON_SIZE = 64;
const IMStatus = {
@ -87,28 +87,20 @@ IMUserNameItem.prototype = {
this.label = new St.Label();
this.label.clutter_text.set_line_wrap(true);
this.label.clutter_text.set_ellipsize(Pango.EllipsizeMode.NONE);
this._wrapper.add_actor(this.label);
},
_wrapperGetPreferredWidth: function(actor, forHeight, alloc) {
[alloc.min_size, alloc.natural_size] = this.label.get_preferred_width(-1);
if (alloc.natural_size > WRAP_WIDTH)
alloc.natural_size = WRAP_WIDTH;
alloc.min_size = 1;
alloc.natural_size = 1;
},
_wrapperGetPreferredHeight: function(actor, forWidth, alloc) {
let minWidth, natWidth;
[alloc.min_size, alloc.natural_size] = this.label.get_preferred_height(forWidth);
[minWidth, natWidth] = this.label.get_preferred_width(-1);
if (natWidth > WRAP_WIDTH) {
alloc.min_size *= 2;
alloc.natural_size *= 2;
}
},
_wrapperAllocate: function(actor, box, flags) {
let availWidth = box.x2 - box.x1;
let availHeight = box.y2 - box.y1;
this.label.allocate(box, flags);
}
};
@ -166,22 +158,29 @@ IMStatusChooserItem.prototype = {
Lang.bind(this, this._changeIMStatus));
this._presence = new GnomeSession.Presence();
this._presence.getStatus(Lang.bind(this, this._sessionStatusChanged));
this._presence.connect('StatusChanged',
Lang.bind(this, this._sessionStatusChanged));
this._sessionPresenceRestored = false;
this._imPresenceRestored = false;
this._currentPresence = undefined;
this._previousPresence = undefined;
this._accountMgr = Tp.AccountManager.dup()
this._accountMgr.connect('most-available-presence-changed',
Lang.bind(this, this._IMStatusChanged));
this._accountMgr.prepare_async(null, Lang.bind(this,
function(mgr) {
let [presence, s, msg] = mgr.get_most_available_presence();
let [presence, status, msg] = mgr.get_most_available_presence();
this._previousPresence = presence;
this._IMStatusChanged(mgr, presence, s, msg);
let savedPresence = global.settings.get_int('saved-im-presence');
if (savedPresence == presence) {
this._IMStatusChanged(mgr, presence, status, msg);
} else {
this._setComboboxPresence(savedPresence);
status = this._statusForPresence(savedPresence);
msg = msg ? msg : '';
mgr.set_all_requested_presences(savedPresence, status, msg);
}
}));
this._userManager = AccountsService.UserManager.get_default();
@ -194,6 +193,10 @@ IMStatusChooserItem.prototype = {
this._userChangedId = this._user.connect('changed',
Lang.bind(this,
this._updateUser));
this.actor.connect('notify::mapped', Lang.bind(this, function() {
if (this.actor.mapped)
this._updateUser();
}));
},
// Override getColumnWidths()/setColumnWidths() to make the item
@ -203,9 +206,6 @@ IMStatusChooserItem.prototype = {
},
setColumnWidths: function(widths) {
this._columnWidths = PopupMenu.PopupBaseMenuItem.prototype.getColumnWidths.call(this);
let sectionWidths = this._section.getColumnWidths();
this._section.setColumnWidths(sectionWidths);
},
_updateUser: function() {
@ -268,19 +268,35 @@ IMStatusChooserItem.prototype = {
},
_IMStatusChanged: function(accountMgr, presence, status, message) {
if (!this._imPresenceRestored)
this._imPresenceRestored = true;
if (presence == this._currentPresence)
return;
this._currentPresence = presence;
this._setComboboxPresence(presence);
if (!this._sessionPresenceRestored) {
this._presence.getStatus(Lang.bind(this, this._sessionStatusChanged));
return;
}
if (presence == Tp.ConnectionPresenceType.AVAILABLE)
this._presence.setStatus(GnomeSession.PresenceStatus.AVAILABLE);
if (!this._expectedPresence || presence != this._expectedPresence)
this._previousPresence = presence;
// We ignore the actual value of _expectedPresence and never safe
// the first presence change after an "automatic" change, assuming
// that it is the response to our request; this is to account for
// mission control falling back to "similar" presences if an account
// type does not implement the requested presence.
if (!this._expectedPresence)
global.settings.set_int('saved-im-presence', presence);
else
this._expectedPresence = undefined;
},
_setComboboxPresence: function(presence) {
let activatedItem;
if (presence == Tp.ConnectionPresenceType.AVAILABLE)
@ -317,41 +333,60 @@ IMStatusChooserItem.prototype = {
return;
status = this._statusForPresence(newPresence);
msg = msg ? msg : "";
msg = msg ? msg : '';
this._accountMgr.set_all_requested_presences(newPresence, status, msg);
},
getIMPresenceForSessionStatus: function(sessionStatus) {
// Restore the last user-set presence when coming back from
// BUSY/IDLE (otherwise the last user-set presence matches
// the current one)
if (sessionStatus == GnomeSession.PresenceStatus.AVAILABLE)
return global.settings.get_int('saved-im-presence');
if (sessionStatus == GnomeSession.PresenceStatus.BUSY) {
// Only change presence if the current one is "more present" than
// busy, or if coming back from idle
if (this._currentPresence == Tp.ConnectionPresenceType.AVAILABLE ||
this._currentPresence == Tp.ConnectionPresenceType.EXTENDED_AWAY)
return Tp.ConnectionPresenceType.BUSY;
}
if (sessionStatus == GnomeSession.PresenceStatus.IDLE) {
// Only change presence if the current one is "more present" than
// idle
if (this._currentPresence != Tp.ConnectionPresenceType.OFFLINE)
return Tp.ConnectionPresenceType.EXTENDED_AWAY;
}
return this._currentPresence;
},
_sessionStatusChanged: function(sessionPresence, sessionStatus) {
if (!this._imPresenceRestored)
return;
if (!this._sessionPresenceRestored) {
let savedStatus = global.settings.get_int('saved-session-presence');
if (sessionStatus != savedStatus) {
this._presence.setStatus(savedStatus);
return;
}
this._sessionPresenceRestored = true;
}
global.settings.set_int('saved-session-presence', sessionStatus);
let [presence, s, msg] = this._accountMgr.get_most_available_presence();
let newPresence, status;
if (sessionStatus == GnomeSession.PresenceStatus.AVAILABLE) {
newPresence = this._previousPresence;
} else if (sessionStatus == GnomeSession.PresenceStatus.BUSY) {
// Only change presence if the current one is "more present" than
// busy, or if coming back from idle
if (presence == Tp.ConnectionPresenceType.AVAILABLE ||
presence == Tp.ConnectionPresenceType.EXTENDED_AWAY) {
newPresence = Tp.ConnectionPresenceType.BUSY;
} else {
return;
}
} else if (sessionStatus == GnomeSession.PresenceStatus.IDLE) {
// Only change presence if the current one is "more present" than
// idle
if (presence != Tp.ConnectionPresenceType.OFFLINE)
newPresence = Tp.ConnectionPresenceType.EXTENDED_AWAY;
else
return;
} else {
return;
}
let newPresence = this.getIMPresenceForSessionStatus(sessionStatus);
if (newPresence == undefined)
if (!newPresence || newPresence == presence)
return;
status = this._statusForPresence(newPresence);
msg = msg ? msg : "";
msg = msg ? msg : '';
this._expectedPresence = newPresence;
this._accountMgr.set_all_requested_presences(newPresence, status, msg);
@ -368,8 +403,8 @@ UserMenuButton.prototype = {
_init: function() {
PanelMenu.Button.prototype._init.call(this, 0.0);
let box = new St.BoxLayout({ name: 'panelStatusMenu' });
this.actor.set_child(box);
let box = new St.BoxLayout({ name: 'panelUserMenu' });
this.actor.add_actor(box);
this._lockdownSettings = new Gio.Settings({ schema: LOCKDOWN_SCHEMA });
@ -419,6 +454,7 @@ UserMenuButton.prototype = {
box.add(this._name, { y_align: St.Align.MIDDLE, y_fill: false });
this._userLoadedId = this._user.connect('notify::is-loaded', Lang.bind(this, this._updateUserName));
this._userChangedId = this._user.connect('changed', Lang.bind(this, this._updateUserName));
this._updateUserName();
this._createSubMenu();
this._userManager.connect('notify::is-loaded',
@ -547,6 +583,7 @@ UserMenuButton.prototype = {
item = new IMStatusChooserItem();
item.connect('activate', Lang.bind(this, this._onMyAccountActivate));
this.menu.addMenuItem(item);
this._statusChooser = item;
item = new PopupMenu.PopupSwitchMenuItem(_("Notifications"));
item.connect('activate', Lang.bind(this, this._updatePresenceStatus));
@ -594,8 +631,21 @@ UserMenuButton.prototype = {
},
_updatePresenceStatus: function(item, event) {
let status = item.state ? GnomeSession.PresenceStatus.AVAILABLE
: GnomeSession.PresenceStatus.BUSY;
let status;
if (item.state) {
status = GnomeSession.PresenceStatus.AVAILABLE;
} else {
status = GnomeSession.PresenceStatus.BUSY;
let [presence, s, msg] = this._account_mgr.get_most_available_presence();
let newPresence = this._statusChooser.getIMPresenceForSessionStatus(status);
if (newPresence != presence &&
newPresence == Tp.ConnectionPresenceType.BUSY)
Main.notify(_("Your chat status will be set to busy"),
_("Notifications are now disabled, including chat messages. Your online status has been adjusted to let others know that you might not see their messages."));
}
this._presence.setStatus(status);
},

View File

@ -1,4 +1,4 @@
/* -*- mode: js2; js2-basic-offset: 4; indent-tabs-mode: nil -*- */
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
const Clutter = imports.gi.Clutter;
const Gtk = imports.gi.Gtk;
@ -12,6 +12,7 @@ const St = imports.gi.St;
const Main = imports.ui.main;
const Search = imports.ui.search;
const SearchDisplay = imports.ui.searchDisplay;
const ShellEntry = imports.ui.shellEntry;
const Tweener = imports.ui.tweener;
function BaseTab(titleActor, pageActor, name, a11yIcon) {
@ -120,6 +121,7 @@ SearchTab.prototype = {
hint_text: _("Type to search..."),
track_hover: true,
can_focus: true });
ShellEntry.addContextMenu(this._entry);
this._text = this._entry.clutter_text;
this._text.connect('key-press-event', Lang.bind(this, this._onKeyPress));
@ -289,9 +291,11 @@ SearchTab.prototype = {
_onCapturedEvent: function(actor, event) {
if (event.type() == Clutter.EventType.BUTTON_PRESS) {
let source = event.get_source();
if (source != this._text && this._text.text == '') {
if (source != this._text && this._text.text == '' &&
!Main.layoutManager.keyboardBox.contains(source)) {
// the user clicked outside after activating the entry, but
// with no search term entered - cancel the search
// with no search term entered and no keyboard button pressed
// - cancel the search
this._reset();
}
}

View File

@ -1,4 +1,4 @@
/* -*- mode: js2; js2-basic-offset: 4; indent-tabs-mode: nil -*- */
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
const Lang = imports.lang;
const Shell = imports.gi.Shell;
@ -12,35 +12,10 @@ function WindowAttentionHandler() {
WindowAttentionHandler.prototype = {
_init : function() {
this._startupIds = {};
this._tracker = Shell.WindowTracker.get_default();
this._tracker.connect('startup-sequence-changed', Lang.bind(this, this._onStartupSequenceChanged));
global.display.connect('window-demands-attention', Lang.bind(this, this._onWindowDemandsAttention));
},
_onStartupSequenceChanged : function(tracker) {
let sequences = tracker.get_startup_sequences();
this._startupIds = {};
for(let i = 0; i < sequences.length; i++) {
this._startupIds[sequences[i].get_id()] = true;
}
},
_getTitle : function(app, window) {
if (this._startupIds[window.get_startup_id()])
return app.get_name();
else
return window.title;
},
_getBanner : function(app, window) {
if (this._startupIds[window.get_startup_id()])
return _("%s has finished starting").format(app.get_name());
else
return _("'%s' is ready").format(window.title);
},
_onWindowDemandsAttention : function(display, window) {
// We don't want to show the notification when the window is already focused,
// because this is rather pointless.
@ -57,12 +32,16 @@ WindowAttentionHandler.prototype = {
let source = new Source(app, window);
Main.messageTray.add(source);
let notification = new MessageTray.Notification(source, this._getTitle(app, window), this._getBanner(app, window));
let banner = _("'%s' is ready").format(window.title);
let title = app.get_name();
let notification = new MessageTray.Notification(source, title, banner);
source.notify(notification);
source.signalIDs.push(window.connect('notify::title', Lang.bind(this, function(win) {
notification.update(this._getTitle(app, win), this._getBanner(app, win));
})));
source.signalIDs.push(window.connect('notify::title',
Lang.bind(this, function() {
notification.update(title, banner);
})));
}
};

View File

@ -1,4 +1,4 @@
/* -*- mode: js2; js2-basic-offset: 4; indent-tabs-mode: nil -*- */
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
const Clutter = imports.gi.Clutter;
const GLib = imports.gi.GLib;
@ -19,47 +19,55 @@ const UNDIM_TIME = 0.250;
var dimShader = undefined;
function getDimShader() {
if (dimShader === null)
return null;
if (!dimShader) {
let source = Shell.get_file_contents_utf8_sync(global.datadir + '/shaders/dim-window.glsl');
try {
let shader = new Clutter.Shader();
shader.set_fragment_source(source, -1);
shader.compile();
dimShader = shader;
} catch (e) {
log(e.message);
dimShader = null;
}
}
function getDimShaderSource() {
if (!dimShader)
dimShader = Shell.get_file_contents_utf8_sync(global.datadir + '/shaders/dim-window.glsl');
return dimShader;
}
function getTopInvisibleBorder(metaWindow) {
let outerRect = metaWindow.get_outer_rect();
let inputRect = metaWindow.get_input_rect();
return outerRect.y - inputRect.y;
}
function WindowDimmer(actor) {
this._init(actor);
}
WindowDimmer.prototype = {
_init: function(actor) {
if (Clutter.feature_available(Clutter.FeatureFlags.SHADERS_GLSL)) {
this._effect = new Clutter.ShaderEffect({ shader_type: Clutter.ShaderType.FRAGMENT_SHADER });
this._effect.set_shader_source(getDimShaderSource());
} else {
this._effect = null;
}
this.actor = actor;
},
set dimFraction(fraction) {
this._dimFraction = fraction;
let shader = getDimShader();
if (!Meta.prefs_get_attach_modal_dialogs() || !shader) {
this.actor.set_shader(null);
if (this._effect == null)
return;
if (!Meta.prefs_get_attach_modal_dialogs()) {
this._effect.enabled = false;
return;
}
if (fraction > 0.01) {
this.actor.set_shader(shader);
this.actor.set_shader_param_float('height', this.actor.get_height());
this.actor.set_shader_param_float('fraction', fraction);
} else
this.actor.set_shader(null);
Shell.shader_effect_set_double_uniform(this._effect, 'height', this.actor.get_height());
Shell.shader_effect_set_double_uniform(this._effect, 'fraction', fraction);
if (!this._effect.actor)
this.actor.add_effect(this._effect);
} else {
if (this._effect.actor)
this.actor.remove_effect(this._effect);
}
},
get dimFraction() {
@ -69,11 +77,11 @@ WindowDimmer.prototype = {
_dimFraction: 0.0
};
function getWindowDimmer(texture) {
if (!texture._windowDimmer)
texture._windowDimmer = new WindowDimmer(texture);
function getWindowDimmer(actor) {
if (!actor._windowDimmer)
actor._windowDimmer = new WindowDimmer(actor);
return texture._windowDimmer;
return actor._windowDimmer;
}
function WindowManager() {
@ -268,30 +276,28 @@ WindowManager.prototype = {
let actor = window.get_compositor_private();
if (!actor)
return;
let texture = actor.get_texture();
if (animate)
Tweener.addTween(getWindowDimmer(texture),
Tweener.addTween(getWindowDimmer(actor),
{ dimFraction: 1.0,
time: DIM_TIME,
transition: 'linear'
});
else
getWindowDimmer(texture).dimFraction = 1.0;
getWindowDimmer(actor).dimFraction = 1.0;
},
_undimWindow: function(window, animate) {
let actor = window.get_compositor_private();
if (!actor)
return;
let texture = actor.get_texture();
if (animate)
Tweener.addTween(getWindowDimmer(texture),
Tweener.addTween(getWindowDimmer(actor),
{ dimFraction: 0.0,
time: UNDIM_TIME,
transition: 'linear'
});
else
getWindowDimmer(texture).dimFraction = 0.0;
getWindowDimmer(actor).dimFraction = 0.0;
},
_mapWindow : function(shellwm, actor) {
@ -528,22 +534,22 @@ WindowManager.prototype = {
shellwm.completed_switch_workspace();
},
_startAppSwitcher : function(shellwm, binding, window, backwards) {
_startAppSwitcher : function(shellwm, binding, mask, window, backwards) {
/* prevent a corner case where both popups show up at once */
if (this._workspaceSwitcherPopup != null)
this._workspaceSwitcherPopup.actor.hide();
let tabPopup = new AltTab.AltTabPopup();
if (!tabPopup.show(backwards, binding))
if (!tabPopup.show(backwards, binding, mask))
tabPopup.destroy();
},
_startA11ySwitcher : function(shellwm, binding, window, backwards) {
Main.ctrlAltTabManager.popup(backwards);
_startA11ySwitcher : function(shellwm, binding, mask, window, backwards) {
Main.ctrlAltTabManager.popup(backwards, mask);
},
_showWorkspaceSwitcher : function(shellwm, binding, window, backwards) {
_showWorkspaceSwitcher : function(shellwm, binding, mask, window, backwards) {
if (global.screen.n_workspaces == 1)
return;

View File

@ -1,4 +1,4 @@
/* -*- mode: js2; js2-basic-offset: 4; indent-tabs-mode: nil -*- */
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
const Clutter = imports.gi.Clutter;
const GConf = imports.gi.GConf;
@ -135,8 +135,11 @@ WindowClone.prototype = {
this._realWindowDestroyId = this.realWindow.connect('destroy',
Lang.bind(this, this._disconnectRealWindowSignals));
this.actor.connect('button-release-event',
Lang.bind(this, this._onButtonRelease));
let clickAction = new Clutter.ClickAction();
clickAction.connect('clicked', Lang.bind(this, this._onClicked));
clickAction.connect('long-press', Lang.bind(this, this._onLongPress));
this.actor.add_action(clickAction);
this.actor.connect('scroll-event',
Lang.bind(this, this._onScroll));
@ -147,6 +150,7 @@ WindowClone.prototype = {
this._draggable = DND.makeDraggable(this.actor,
{ restoreOnSuccess: true,
manualMode: true,
dragActorMaxSize: WINDOW_DND_SIZE,
dragActorOpacity: DRAGGING_WINDOW_OPACITY });
this._draggable.connect('drag-begin', Lang.bind(this, this._onDragBegin));
@ -345,9 +349,27 @@ WindowClone.prototype = {
this._zoomStep = undefined;
},
_onButtonRelease : function (actor, event) {
_onClicked: function(action, actor) {
this._selected = true;
this.emit('selected', event.get_time());
this.emit('selected', global.get_current_time());
},
_onLongPress: function(action, actor, state) {
// Take advantage of the Clutter policy to consider
// a long-press canceled when the pointer movement
// exceeds dnd-drag-threshold to manually start the drag
if (state == Clutter.LongPressState.CANCEL) {
// A click cancels a long-press before any click handler is
// run - make sure to not start a drag in that case
Meta.later_add(Meta.LaterType.BEFORE_REDRAW, Lang.bind(this,
function() {
if (this._selected)
return;
let [x, y] = action.get_coords();
this._draggable.startDrag(x, y, global.get_current_time());
}));
}
return true;
},
_onDragBegin : function (draggable, time) {

View File

@ -1,4 +1,4 @@
/* -*- mode: js2; js2-basic-offset: 4; indent-tabs-mode: nil -*- */
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
const Clutter = imports.gi.Clutter;
const Lang = imports.lang;

View File

@ -1,4 +1,4 @@
/* -*- mode: js2; js2-basic-offset: 4; indent-tabs-mode: nil -*- */
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
const Clutter = imports.gi.Clutter;
const Lang = imports.lang;

View File

@ -1,4 +1,4 @@
/* -*- mode: js2; js2-basic-offset: 4; indent-tabs-mode: nil -*- */
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
const Clutter = imports.gi.Clutter;
const Lang = imports.lang;
@ -109,8 +109,6 @@ WorkspacesView.prototype = {
this._scrollAdjustment.connect('notify::value',
Lang.bind(this, this._onScroll));
this._timeoutId = 0;
this._switchWorkspaceNotifyId =
global.window_manager.connect('switch-workspace',
Lang.bind(this, this._activeWorkspaceChanged));
@ -321,10 +319,6 @@ WorkspacesView.prototype = {
if (this._inDrag)
this._dragEnd();
if (this._timeoutId) {
Mainloop.source_remove(this._timeoutId);
this._timeoutId = 0;
}
if (this._itemDragBeginId > 0) {
Main.overview.disconnect(this._itemDragBeginId);
this._itemDragBeginId = 0;
@ -383,72 +377,10 @@ WorkspacesView.prototype = {
this._extraWorkspaces[i].setReservedSlot(dragEvent.dragActor._delegate);
}
let primary = Main.layoutManager.primaryMonitor;
let activeWorkspaceIndex = global.screen.get_active_workspace_index();
let topWorkspace, bottomWorkspace;
topWorkspace = this._workspaces[activeWorkspaceIndex - 1];
bottomWorkspace = this._workspaces[activeWorkspaceIndex + 1];
let hoverWorkspace = null;
// reactive monitor edges
let topEdge = primary.y;
let switchTop = (dragEvent.y <= topEdge && topWorkspace);
if (switchTop && this._dragOverLastY != topEdge) {
topWorkspace.metaWorkspace.activate(global.get_current_time());
this._dragOverLastY = topEdge;
return DND.DragMotionResult.CONTINUE;
}
let bottomEdge = primary.y + primary.height - 1;
let switchBottom = (dragEvent.y >= bottomEdge && bottomWorkspace);
if (switchBottom && this._dragOverLastY != bottomEdge) {
bottomWorkspace.metaWorkspace.activate(global.get_current_time());
this._dragOverLastY = bottomEdge;
return DND.DragMotionResult.CONTINUE;
}
this._dragOverLastY = dragEvent.y;
let result = DND.DragMotionResult.CONTINUE;
// check hover state of new workspace area / inactive workspaces
if (topWorkspace) {
if (topWorkspace.actor.contains(dragEvent.targetActor)) {
hoverWorkspace = topWorkspace;
result = topWorkspace.handleDragOver(dragEvent.source, dragEvent.dragActor);
}
}
if (bottomWorkspace) {
if (bottomWorkspace.actor.contains(dragEvent.targetActor)) {
hoverWorkspace = bottomWorkspace;
result = bottomWorkspace.handleDragOver(dragEvent.source, dragEvent.dragActor);
}
}
// handle delayed workspace switches
if (hoverWorkspace) {
if (!this._timeoutId)
this._timeoutId = Mainloop.timeout_add_seconds(1,
Lang.bind(this, function() {
hoverWorkspace.metaWorkspace.activate(global.get_current_time());
return false;
}));
} else {
if (this._timeoutId) {
Mainloop.source_remove(this._timeoutId);
this._timeoutId = 0;
}
}
return result;
return DND.DragMotionResult.CONTINUE;
},
_dragEnd: function() {
if (this._timeoutId) {
Mainloop.source_remove(this._timeoutId);
this._timeoutId = 0;
}
DND.removeDragMonitor(this._dragMonitor);
this._inDrag = false;

View File

@ -1,4 +1,4 @@
/* -*- mode: js2; js2-basic-offset: 4; indent-tabs-mode: nil -*- */
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
const Clutter = imports.gi.Clutter;
const Lang = imports.lang;

View File

@ -1,6 +1,8 @@
af
an
ar
as
ast
be
bg
bn
@ -30,6 +32,7 @@ it
ja
ko
kn
ku
lt
lv
mr

View File

@ -1,6 +1,7 @@
data/gnome-shell.desktop.in.in
data/org.gnome.shell.gschema.xml.in
js/gdm/loginDialog.js
js/gdm/powerMenu.js
js/misc/util.js
js/ui/appDisplay.js
js/ui/appFavorites.js
@ -24,6 +25,7 @@ js/ui/polkitAuthenticationAgent.js
js/ui/popupMenu.js
js/ui/runDialog.js
js/ui/searchDisplay.js
js/ui/shellEntry.js
js/ui/shellMountOperation.js
js/ui/status/accessibility.js
js/ui/status/bluetooth.js
@ -43,4 +45,3 @@ src/shell-global.c
src/shell-mobile-providers.c
src/shell-polkit-authentication-agent.c
src/shell-util.c

1024
po/af.po

File diff suppressed because it is too large Load Diff

1616
po/as.po Normal file

File diff suppressed because it is too large Load Diff

1630
po/ast.po Normal file

File diff suppressed because it is too large Load Diff

382
po/be.po
View File

@ -2,8 +2,8 @@ msgid ""
msgstr ""
"Project-Id-Version: gnome-shell.master\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2011-09-14 22:03+0300\n"
"PO-Revision-Date: 2011-09-14 22:03+0300\n"
"POT-Creation-Date: 2011-09-21 22:18+0300\n"
"PO-Revision-Date: 2011-09-21 22:18+0300\n"
"Last-Translator: Ігар Грачышка <ihar.hrachyshka@gmail.com>\n"
"Language-Team: Belarusian <i18n-bel-gnome@googlegroups.com>\n"
"Language: be\n"
@ -60,22 +60,18 @@ msgid "If true, display date in the clock, in addition to time."
msgstr ""
#: ../data/org.gnome.shell.gschema.xml.in.h:9
msgid "If true, display onscreen keyboard."
msgstr ""
#: ../data/org.gnome.shell.gschema.xml.in.h:10
msgid "If true, display seconds in time."
msgstr ""
#: ../data/org.gnome.shell.gschema.xml.in.h:11
#: ../data/org.gnome.shell.gschema.xml.in.h:10
msgid "If true, display the ISO week date in the calendar."
msgstr ""
#: ../data/org.gnome.shell.gschema.xml.in.h:12
#: ../data/org.gnome.shell.gschema.xml.in.h:11
msgid "List of desktop file IDs for favorite applications"
msgstr ""
#: ../data/org.gnome.shell.gschema.xml.in.h:14
#: ../data/org.gnome.shell.gschema.xml.in.h:13
#, no-c-format
msgid ""
"Sets the GStreamer pipeline used to encode recordings. It follows the syntax "
@ -90,46 +86,42 @@ msgid ""
"at the optimal thread count on the system."
msgstr ""
#: ../data/org.gnome.shell.gschema.xml.in.h:15
#: ../data/org.gnome.shell.gschema.xml.in.h:14
msgid "Show date in clock"
msgstr ""
#: ../data/org.gnome.shell.gschema.xml.in.h:16
msgid "Show the onscreen keyboard"
msgstr ""
#: ../data/org.gnome.shell.gschema.xml.in.h:17
#: ../data/org.gnome.shell.gschema.xml.in.h:15
msgid "Show the week date in the calendar"
msgstr ""
#: ../data/org.gnome.shell.gschema.xml.in.h:18
#: ../data/org.gnome.shell.gschema.xml.in.h:16
msgid "Show time with seconds"
msgstr ""
#: ../data/org.gnome.shell.gschema.xml.in.h:19
#: ../data/org.gnome.shell.gschema.xml.in.h:17
msgid ""
"The applications corresponding to these identifiers will be displayed in the "
"favorites area."
msgstr ""
#: ../data/org.gnome.shell.gschema.xml.in.h:20
#: ../data/org.gnome.shell.gschema.xml.in.h:18
msgid ""
"The filename for recorded screencasts will be a unique filename based on the "
"current date, and use this extension. It should be changed when recording to "
"a different container format."
msgstr ""
#: ../data/org.gnome.shell.gschema.xml.in.h:21
#: ../data/org.gnome.shell.gschema.xml.in.h:19
msgid ""
"The framerate of the resulting screencast recordered by GNOME Shell's "
"screencast recorder in frames-per-second."
msgstr ""
#: ../data/org.gnome.shell.gschema.xml.in.h:22
#: ../data/org.gnome.shell.gschema.xml.in.h:20
msgid "The gstreamer pipeline used to encode the screencast"
msgstr ""
#: ../data/org.gnome.shell.gschema.xml.in.h:23
#: ../data/org.gnome.shell.gschema.xml.in.h:21
msgid ""
"The shell normally monitors active applications in order to present the most "
"used ones (e.g. in launchers). While this data will be kept private, you may "
@ -137,54 +129,75 @@ msgid ""
"remove already saved data."
msgstr ""
#: ../data/org.gnome.shell.gschema.xml.in.h:24
#: ../data/org.gnome.shell.gschema.xml.in.h:22
msgid "The type of keyboard to use."
msgstr ""
#: ../data/org.gnome.shell.gschema.xml.in.h:25
#: ../data/org.gnome.shell.gschema.xml.in.h:23
msgid "Uuids of extensions to enable"
msgstr "UUID-значэнні пашырэнняў, якія трэба ўключыць"
#: ../data/org.gnome.shell.gschema.xml.in.h:26
#: ../data/org.gnome.shell.gschema.xml.in.h:24
msgid "Whether to collect stats about applications usage"
msgstr ""
#: ../data/org.gnome.shell.gschema.xml.in.h:27
#: ../data/org.gnome.shell.gschema.xml.in.h:25
msgid "Which keyboard to use"
msgstr ""
#: ../data/org.gnome.shell.gschema.xml.in.h:28
#: ../data/org.gnome.shell.gschema.xml.in.h:26
msgid "disabled OpenSearch providers"
msgstr ""
#: ../js/gdm/loginDialog.js:604
#: ../js/gdm/loginDialog.js:617
msgid "Session..."
msgstr "Сеанс..."
#: ../js/gdm/loginDialog.js:761
#: ../js/gdm/loginDialog.js:785
msgctxt "title"
msgid "Sign In"
msgstr "Уваход"
#: ../js/gdm/loginDialog.js:818
#. translators: this message is shown below the password entry field
#. to indicate the user can swipe their finger instead
#: ../js/gdm/loginDialog.js:830
msgid "(or swipe finger)"
msgstr "(або правядзіце пальцам)"
#: ../js/gdm/loginDialog.js:848
msgid "Not listed?"
msgstr "Няма ў спісе?"
#: ../js/gdm/loginDialog.js:928 ../js/ui/endSessionDialog.js:426
#: ../js/ui/extensionSystem.js:477 ../js/ui/networkAgent.js:158
#: ../js/ui/polkitAuthenticationAgent.js:170 ../js/ui/status/bluetooth.js:480
#: ../js/gdm/loginDialog.js:1004 ../js/ui/endSessionDialog.js:426
#: ../js/ui/extensionSystem.js:477 ../js/ui/networkAgent.js:165
#: ../js/ui/polkitAuthenticationAgent.js:171 ../js/ui/status/bluetooth.js:480
msgid "Cancel"
msgstr "Скасаваць"
#: ../js/gdm/loginDialog.js:933
#: ../js/gdm/loginDialog.js:1009
msgctxt "button"
msgid "Sign In"
msgstr "Увайсці"
#: ../js/gdm/loginDialog.js:1253
#: ../js/gdm/loginDialog.js:1358
msgid "Login Window"
msgstr "Акно ўваходу"
#: ../js/gdm/powerMenu.js:116 ../js/ui/userMenu.js:514
#: ../js/ui/userMenu.js:516 ../js/ui/userMenu.js:585
msgid "Suspend"
msgstr "Прыпыніць камп'ютар"
#: ../js/gdm/powerMenu.js:121 ../js/ui/endSessionDialog.js:89
#: ../js/ui/endSessionDialog.js:97 ../js/ui/endSessionDialog.js:106
msgid "Restart"
msgstr "Перазапусціць сістэму"
#: ../js/gdm/powerMenu.js:126 ../js/ui/endSessionDialog.js:80
#: ../js/ui/endSessionDialog.js:91
msgid "Power Off"
msgstr "Выключыць камп'ютар"
#: ../js/misc/util.js:92
msgid "Command not found"
msgstr "Загад не знойдзены"
@ -213,15 +226,15 @@ msgstr "ПРАГРАМЫ"
msgid "SETTINGS"
msgstr "НАСТРОЙКІ"
#: ../js/ui/appDisplay.js:685
#: ../js/ui/appDisplay.js:684
msgid "New Window"
msgstr "Новае акно"
#: ../js/ui/appDisplay.js:688
#: ../js/ui/appDisplay.js:687
msgid "Remove from Favorites"
msgstr "Выдаліць са спіса ўпадабанага"
#: ../js/ui/appDisplay.js:689
#: ../js/ui/appDisplay.js:688
msgid "Add to Favorites"
msgstr "Дадаць у спіс упадабанага"
@ -235,12 +248,16 @@ msgstr "%s дададзены ў ваш спіс упадабанага."
msgid "%s has been removed from your favorites."
msgstr "%s выдалены з вашага спіса ўпадабанага."
#: ../js/ui/autorunManager.js:592
#: ../js/ui/autorunManager.js:280
msgid "Removable Devices"
msgstr "Зменныя прыстасаванні"
#: ../js/ui/autorunManager.js:590
#, c-format
msgid "Open with %s"
msgstr "Адкрыць у %s"
#: ../js/ui/autorunManager.js:618
#: ../js/ui/autorunManager.js:616
msgid "Eject"
msgstr "Выняць"
@ -395,15 +412,15 @@ msgstr "На наступным тыдні"
msgid "Unknown"
msgstr "Невядома"
#: ../js/ui/contactDisplay.js:80 ../js/ui/userMenu.js:147
#: ../js/ui/contactDisplay.js:80 ../js/ui/userMenu.js:139
msgid "Available"
msgstr "Даступны"
#: ../js/ui/contactDisplay.js:85 ../js/ui/userMenu.js:156
#: ../js/ui/contactDisplay.js:85 ../js/ui/userMenu.js:148
msgid "Away"
msgstr "Адсутны"
#: ../js/ui/contactDisplay.js:89 ../js/ui/userMenu.js:150
#: ../js/ui/contactDisplay.js:89 ../js/ui/userMenu.js:142
msgid "Busy"
msgstr "Заняты"
@ -415,7 +432,7 @@ msgstr "Па-за сеткай"
msgid "CONTACTS"
msgstr "КАНТАКТЫ"
#: ../js/ui/dash.js:172 ../js/ui/messageTray.js:1195
#: ../js/ui/dash.js:172 ../js/ui/messageTray.js:1197
msgid "Remove"
msgstr "Выдаліць"
@ -513,10 +530,6 @@ msgstr[2] "Вы аўтаматычна скончыце сеанс працы з
msgid "Logging out of the system."
msgstr "Заканчэнне сеанса працы з сістэмай."
#: ../js/ui/endSessionDialog.js:80 ../js/ui/endSessionDialog.js:91
msgid "Power Off"
msgstr "Выключыць камп'ютар"
#: ../js/ui/endSessionDialog.js:81
msgid "Click Power Off to quit these applications and power off the system."
msgstr ""
@ -535,11 +548,6 @@ msgstr[2] "Сістэма аўтаматычна выключыцца праз %
msgid "Powering off the system."
msgstr "Выключэнне сістэмы."
#: ../js/ui/endSessionDialog.js:89 ../js/ui/endSessionDialog.js:97
#: ../js/ui/endSessionDialog.js:106
msgid "Restart"
msgstr "Перазапусціць сістэму"
#: ../js/ui/endSessionDialog.js:98
msgid "Click Restart to quit these applications and restart the system."
msgstr ""
@ -567,96 +575,96 @@ msgstr "Усталяваць"
msgid "Download and install '%s' from extensions.gnome.org?"
msgstr "Сцягнуць і ўсталяваць \"%s\" з extensions.gnome.org?"
#: ../js/ui/keyboard.js:513 ../js/ui/status/power.js:211
#: ../js/ui/keyboard.js:517 ../js/ui/status/power.js:211
msgid "Keyboard"
msgstr "Клавіятура"
#: ../js/ui/lookingGlass.js:641
#: ../js/ui/lookingGlass.js:645
msgid "No extensions installed"
msgstr "Няма ўсталяваных пашырэнняў"
#: ../js/ui/lookingGlass.js:687
#: ../js/ui/lookingGlass.js:691
msgid "Enabled"
msgstr "Уключана"
#. translators:
#. * The device has been disabled
#: ../js/ui/lookingGlass.js:689 ../src/gvc/gvc-mixer-control.c:1093
#: ../js/ui/lookingGlass.js:693 ../src/gvc/gvc-mixer-control.c:1093
msgid "Disabled"
msgstr "Выключана"
#: ../js/ui/lookingGlass.js:691
#: ../js/ui/lookingGlass.js:695
msgid "Error"
msgstr "Памылка"
#: ../js/ui/lookingGlass.js:693
#: ../js/ui/lookingGlass.js:697
msgid "Out of date"
msgstr "Састарэла"
#: ../js/ui/lookingGlass.js:695
#: ../js/ui/lookingGlass.js:699
msgid "Downloading"
msgstr "Сцягванне"
#: ../js/ui/lookingGlass.js:720
#: ../js/ui/lookingGlass.js:724
msgid "View Source"
msgstr "Паглядзець выточны код"
#: ../js/ui/lookingGlass.js:726
#: ../js/ui/lookingGlass.js:730
msgid "Web Page"
msgstr "Сеціўная старонка"
#: ../js/ui/messageTray.js:1188
#: ../js/ui/messageTray.js:1190
msgid "Open"
msgstr "Адкрыць"
#: ../js/ui/messageTray.js:2367
#: ../js/ui/messageTray.js:2372
msgid "System Information"
msgstr "Сістэмная інфармацыя"
#: ../js/ui/networkAgent.js:138
#: ../js/ui/networkAgent.js:145
msgid "Show password"
msgstr "Паказваць пароль"
#: ../js/ui/networkAgent.js:153
#: ../js/ui/networkAgent.js:160
msgid "Connect"
msgstr "Злучыць"
#. Cisco LEAP
#: ../js/ui/networkAgent.js:248 ../js/ui/networkAgent.js:260
#: ../js/ui/networkAgent.js:287 ../js/ui/networkAgent.js:307
#: ../js/ui/networkAgent.js:317
#: ../js/ui/networkAgent.js:255 ../js/ui/networkAgent.js:267
#: ../js/ui/networkAgent.js:294 ../js/ui/networkAgent.js:314
#: ../js/ui/networkAgent.js:324
msgid "Password: "
msgstr "Пароль: "
#. static WEP
#: ../js/ui/networkAgent.js:253
#: ../js/ui/networkAgent.js:260
msgid "Key: "
msgstr "Ключ: "
#. TTLS and PEAP are actually much more complicated, but this complication
#. is not visible here since we only care about phase2 authentication
#. (and don't even care of which one)
#: ../js/ui/networkAgent.js:285 ../js/ui/networkAgent.js:303
#: ../js/ui/networkAgent.js:292 ../js/ui/networkAgent.js:310
msgid "Username: "
msgstr "Імя карыстальніка: "
#: ../js/ui/networkAgent.js:291
#: ../js/ui/networkAgent.js:298
msgid "Identity: "
msgstr "Ідэнтычнасць: "
#: ../js/ui/networkAgent.js:293
#: ../js/ui/networkAgent.js:300
msgid "Private key password: "
msgstr "Пароль да прыватнага ключа: "
#: ../js/ui/networkAgent.js:305
#: ../js/ui/networkAgent.js:312
msgid "Service: "
msgstr "Паслуга: "
#: ../js/ui/networkAgent.js:334
#: ../js/ui/networkAgent.js:341
msgid "Authentication required by wireless network"
msgstr "Для бесправадной сеткі патрэбная ідэнтыфікацыя"
#: ../js/ui/networkAgent.js:335
#: ../js/ui/networkAgent.js:342
#, c-format
msgid ""
"Passwords or encryption keys are required to access the wireless network "
@ -665,37 +673,37 @@ msgstr ""
"Для доступу да бесправадной сеткі \"%s\" патрэбны пароль або ключы "
"шыфравання."
#: ../js/ui/networkAgent.js:339
#: ../js/ui/networkAgent.js:346
msgid "Wired 802.1X authentication"
msgstr "Правадная ідэнтыфікацыя 802.1X"
#: ../js/ui/networkAgent.js:341
#: ../js/ui/networkAgent.js:348
msgid "Network name: "
msgstr "Назва сеткі: "
#: ../js/ui/networkAgent.js:346
#: ../js/ui/networkAgent.js:353
msgid "DSL authentication"
msgstr "DSL-ідэнтыфікацыя"
#: ../js/ui/networkAgent.js:353
#: ../js/ui/networkAgent.js:360
msgid "PIN code required"
msgstr "Патрэбны PIN-код"
#: ../js/ui/networkAgent.js:354
#: ../js/ui/networkAgent.js:361
msgid "PIN code is needed for the mobile broadband device"
msgstr ""
"Для прыстасавання для доступу да шырокапалоснай мабільнай сеткі патрэбны PIN-"
"код"
#: ../js/ui/networkAgent.js:355
#: ../js/ui/networkAgent.js:362
msgid "PIN: "
msgstr "PIN-код: "
#: ../js/ui/networkAgent.js:361
#: ../js/ui/networkAgent.js:368
msgid "Mobile broadband network password"
msgstr "Пароль да шырокапалоснай мабільнай сеткі"
#: ../js/ui/networkAgent.js:362
#: ../js/ui/networkAgent.js:369
#, c-format
msgid "A password is required to connect to '%s'."
msgstr "Каб злучыцца з \"%s\", патрэбны пароль."
@ -719,14 +727,14 @@ msgid "Dash"
msgstr "Прыборная дошка"
#. TODO - _quit() doesn't really work on apps in state STARTING yet
#: ../js/ui/panel.js:538
#: ../js/ui/panel.js:539
#, c-format
msgid "Quit %s"
msgstr "%s: выйсці"
#. Translators: If there is no suitable word for "Activities"
#. in your language, you can use the word for "Overview".
#: ../js/ui/panel.js:574
#: ../js/ui/panel.js:575
msgid "Activities"
msgstr "Заняткі"
@ -759,7 +767,7 @@ msgstr "Патрэбная ідэнтыфікацыя"
msgid "Administrator"
msgstr "Адміністратар"
#: ../js/ui/polkitAuthenticationAgent.js:174
#: ../js/ui/polkitAuthenticationAgent.js:175
msgid "Authenticate"
msgstr "Ідэнтыфікаваць"
@ -767,11 +775,11 @@ msgstr "Ідэнтыфікаваць"
#. * requested authentication was not gained; this can happen
#. * because of an authentication error (like invalid password),
#. * for instance.
#: ../js/ui/polkitAuthenticationAgent.js:262
#: ../js/ui/polkitAuthenticationAgent.js:256
msgid "Sorry, that didn't work. Please try again."
msgstr "На жаль, ідэнтыфікацыя не адбылася. Паўтарыце спробу."
#: ../js/ui/polkitAuthenticationAgent.js:274
#: ../js/ui/polkitAuthenticationAgent.js:268
msgid "Password:"
msgstr "Пароль:"
@ -780,7 +788,7 @@ msgstr "Пароль:"
#. "ON" and "OFF") or "toggle-switch-intl" (for toggle
#. switches containing "◯" and "|"). Other values will
#. simply result in invisible toggle switches.
#: ../js/ui/popupMenu.js:687
#: ../js/ui/popupMenu.js:727
msgid "toggle-switch-us"
msgstr "toggle-switch-intl"
@ -807,9 +815,10 @@ msgstr "Маштабаванне"
#. let screenReader = this._buildItem(_("Screen Reader"), APPLICATIONS_SCHEMA,
#. 'screen-reader-enabled');
#. this.menu.addMenuItem(screenReader);
#. let screenKeyboard = this._buildItem(_("Screen Keyboard"), APPLICATIONS_SCHEMA,
#. 'screen-keyboard-enabled');
#. this.menu.addMenuItem(screenKeyboard);
#: ../js/ui/status/accessibility.js:71
msgid "Screen Keyboard"
msgstr "Экранная клавіятура"
#: ../js/ui/status/accessibility.js:75
msgid "Visual Alerts"
msgstr "Візуальныя сігналы"
@ -929,7 +938,7 @@ msgstr "Заўсёды даваць дазвол"
msgid "Grant this time only"
msgstr "Даць дазвол аднойчы"
#: ../js/ui/status/bluetooth.js:392 ../js/ui/telepathyClient.js:1185
#: ../js/ui/status/bluetooth.js:392 ../js/ui/telepathyClient.js:1196
msgid "Reject"
msgstr "Адмовіць"
@ -969,11 +978,11 @@ msgstr "Увядзіце PIN, які паказвае прыстасаванне
msgid "OK"
msgstr "Добра"
#: ../js/ui/status/keyboard.js:71
#: ../js/ui/status/keyboard.js:73
msgid "Show Keyboard Layout"
msgstr "Паказаць раскладку"
#: ../js/ui/status/keyboard.js:75
#: ../js/ui/status/keyboard.js:78
msgid "Region and Language Settings"
msgstr "Настройкі мясцовасці і мовы"
@ -1018,13 +1027,13 @@ msgstr "недаступна"
msgid "connection failed"
msgstr "не ўдалося злучыцца"
#: ../js/ui/status/network.js:575 ../js/ui/status/network.js:1515
#: ../js/ui/status/network.js:575 ../js/ui/status/network.js:1523
msgid "More..."
msgstr "Яшчэ..."
#. TRANSLATORS: this is the indication that a connection for another logged in user is active,
#. and we cannot access its settings (including the name)
#: ../js/ui/status/network.js:611 ../js/ui/status/network.js:1455
#: ../js/ui/status/network.js:611 ../js/ui/status/network.js:1458
msgid "Connected (private)"
msgstr "Злучана (прыватна)"
@ -1041,7 +1050,7 @@ msgid "Auto dial-up"
msgstr "Аўтаматычна: мадэм"
#. TRANSLATORS: this the automatic wireless connection name (including the network name)
#: ../js/ui/status/network.js:878 ../js/ui/status/network.js:1467
#: ../js/ui/status/network.js:878 ../js/ui/status/network.js:1470
#, c-format
msgid "Auto %s"
msgstr "Аўтаматычна: %s"
@ -1050,47 +1059,39 @@ msgstr "Аўтаматычна: %s"
msgid "Auto bluetooth"
msgstr "Аўтаматычна: Bluetooth"
#: ../js/ui/status/network.js:1469
#: ../js/ui/status/network.js:1472
msgid "Auto wireless"
msgstr "Аўтаматычна: wireless"
#: ../js/ui/status/network.js:1558
#: ../js/ui/status/network.js:1566
msgid "Enable networking"
msgstr "Уключыць сеткавыя функцыі"
#: ../js/ui/status/network.js:1570
#: ../js/ui/status/network.js:1578
msgid "Wired"
msgstr "Правадное злучэнне"
#: ../js/ui/status/network.js:1581
#: ../js/ui/status/network.js:1589
msgid "Wireless"
msgstr "Бесправадное злучэнне"
#: ../js/ui/status/network.js:1591
#: ../js/ui/status/network.js:1599
msgid "Mobile broadband"
msgstr "Мабільны broadband"
#: ../js/ui/status/network.js:1601
#: ../js/ui/status/network.js:1609
msgid "VPN Connections"
msgstr "VPN-злучэнні"
#: ../js/ui/status/network.js:1612
#: ../js/ui/status/network.js:1620
msgid "Network Settings"
msgstr "Сеткавыя настройкі"
#: ../js/ui/status/network.js:1747
msgid "Connectivity lost"
msgstr "Злучэнне страчана"
#: ../js/ui/status/network.js:1748
msgid "You are no longer connected to the network"
msgstr "Вы больш не злучаны з сеткай"
#: ../js/ui/status/network.js:1756
#: ../js/ui/status/network.js:1757
msgid "Connection failed"
msgstr "Не ўдалося злучыцца"
#: ../js/ui/status/network.js:1757
#: ../js/ui/status/network.js:1758
msgid "Activation of network connection failed"
msgstr "Не ўдалося ўключыць сеткавае злучэнне"
@ -1205,44 +1206,44 @@ msgstr "Мікрафон"
#. We got the TpContact
#. FIXME: We don't have a 'chat room' icon (bgo #653737) use
#. system-users for now as Empathy does.
#: ../js/ui/telepathyClient.js:256
#: ../js/ui/telepathyClient.js:259
msgid "Invitation"
msgstr "Запрашэнне"
#. We got the TpContact
#: ../js/ui/telepathyClient.js:322
#: ../js/ui/telepathyClient.js:325
msgid "Call"
msgstr "Званок"
#. We got the TpContact
#: ../js/ui/telepathyClient.js:350
#: ../js/ui/telepathyClient.js:353
msgid "File Transfer"
msgstr "Перадача файла"
#: ../js/ui/telepathyClient.js:432
#: ../js/ui/telepathyClient.js:434
msgid "Subscription request"
msgstr "Запыт на падпіску"
#: ../js/ui/telepathyClient.js:460
#: ../js/ui/telepathyClient.js:470
msgid "Connection error"
msgstr "Памылка злучэння"
#: ../js/ui/telepathyClient.js:722
#: ../js/ui/telepathyClient.js:733
#, c-format
msgid "%s is online."
msgstr "%s у сетцы."
#: ../js/ui/telepathyClient.js:727
#: ../js/ui/telepathyClient.js:738
#, c-format
msgid "%s is offline."
msgstr "%s па-за сеткай."
#: ../js/ui/telepathyClient.js:730
#: ../js/ui/telepathyClient.js:741
#, c-format
msgid "%s is away."
msgstr "%s далёка ад камп'ютара."
#: ../js/ui/telepathyClient.js:733
#: ../js/ui/telepathyClient.js:744
#, c-format
msgid "%s is busy."
msgstr "%s мае пільныя справы."
@ -1250,35 +1251,35 @@ msgstr "%s мае пільныя справы."
#. Translators: this is a time format string followed by a date.
#. If applicable, replace %X with a strftime format valid for your
#. locale, without seconds.
#: ../js/ui/telepathyClient.js:967
#: ../js/ui/telepathyClient.js:978
#, no-c-format
msgid "Sent at <b>%X</b> on <b>%A</b>"
msgstr "Адпраўлена ў <b>%X</b>, <b>%A</b>"
#. Translators: this is a time format in the style of "Wednesday, May 25",
#. shown when you get a chat message in the same year.
#: ../js/ui/telepathyClient.js:973
#: ../js/ui/telepathyClient.js:984
#, no-c-format
msgid "Sent on <b>%A</b>, <b>%B %d</b>"
msgstr "Адпраўлена ў <b>%A</b>, <b>%d %B</b>"
#. Translators: this is a time format in the style of "Wednesday, May 25, 2012",
#. shown when you get a chat message in a different year.
#: ../js/ui/telepathyClient.js:978
#: ../js/ui/telepathyClient.js:989
#, no-c-format
msgid "Sent on <b>%A</b>, <b>%B %d</b>, %Y"
msgstr "Адпраўлена ў <b>%A</b>, <b>%d %B</b>, %Y"
#. Translators: this is the other person changing their old IM name to their new
#. IM name.
#: ../js/ui/telepathyClient.js:1020
#: ../js/ui/telepathyClient.js:1031
#, c-format
msgid "%s is now known as %s"
msgstr "%s змяніў імя на %s"
#. translators: argument is a room name like
#. * room@jabber.org for example.
#: ../js/ui/telepathyClient.js:1129
#: ../js/ui/telepathyClient.js:1140
#, c-format
msgid "Invitation to %s"
msgstr "Запрашэнне ў %s"
@ -1286,34 +1287,34 @@ msgstr "Запрашэнне ў %s"
#. translators: first argument is the name of a contact and the second
#. * one the name of a room. "Alice is inviting you to join room@jabber.org
#. * for example.
#: ../js/ui/telepathyClient.js:1137
#: ../js/ui/telepathyClient.js:1148
#, c-format
msgid "%s is inviting you to join %s"
msgstr "Удзельнік %s запрашае вас далучыцца да %s"
#: ../js/ui/telepathyClient.js:1139 ../js/ui/telepathyClient.js:1228
#: ../js/ui/telepathyClient.js:1332
#: ../js/ui/telepathyClient.js:1150 ../js/ui/telepathyClient.js:1239
#: ../js/ui/telepathyClient.js:1343
msgid "Decline"
msgstr "Адмовіцца"
#: ../js/ui/telepathyClient.js:1140 ../js/ui/telepathyClient.js:1229
#: ../js/ui/telepathyClient.js:1333
#: ../js/ui/telepathyClient.js:1151 ../js/ui/telepathyClient.js:1240
#: ../js/ui/telepathyClient.js:1344
msgid "Accept"
msgstr "Прыняць"
#. translators: argument is a contact name like Alice for example.
#: ../js/ui/telepathyClient.js:1173
#: ../js/ui/telepathyClient.js:1184
#, c-format
msgid "Video call from %s"
msgstr "Відэазванок ад %s"
#. translators: argument is a contact name like Alice for example.
#: ../js/ui/telepathyClient.js:1176
#: ../js/ui/telepathyClient.js:1187
#, c-format
msgid "Call from %s"
msgstr "Званок ад %s"
#: ../js/ui/telepathyClient.js:1186
#: ../js/ui/telepathyClient.js:1197
msgid "Answer"
msgstr "Адказаць"
@ -1322,108 +1323,108 @@ msgstr "Адказаць"
#. * file name. The string will be something
#. * like: "Alice is sending you test.ogg"
#.
#: ../js/ui/telepathyClient.js:1222
#: ../js/ui/telepathyClient.js:1233
#, c-format
msgid "%s is sending you %s"
msgstr "%s пасылае вам %s"
#. To translators: The parameter is the contact's alias
#: ../js/ui/telepathyClient.js:1297
#: ../js/ui/telepathyClient.js:1308
#, c-format
msgid "%s would like permission to see when you are online"
msgstr "%s просіць дазволу на прагляд вашага сеткавага стану"
#: ../js/ui/telepathyClient.js:1395
#: ../js/ui/telepathyClient.js:1406
msgid "Network error"
msgstr "Сеткавая памылка"
#: ../js/ui/telepathyClient.js:1397
#: ../js/ui/telepathyClient.js:1408
msgid "Authentication failed"
msgstr "Няўдалая ідэнтыфікацыя"
#: ../js/ui/telepathyClient.js:1399
#: ../js/ui/telepathyClient.js:1410
msgid "Encryption error"
msgstr "Памылка шыфравання"
#: ../js/ui/telepathyClient.js:1401
#: ../js/ui/telepathyClient.js:1412
msgid "Certificate not provided"
msgstr "Сертыфікат не пададзены"
#: ../js/ui/telepathyClient.js:1403
#: ../js/ui/telepathyClient.js:1414
msgid "Certificate untrusted"
msgstr "Сертыфікат не заслугоўвае даверу"
#: ../js/ui/telepathyClient.js:1405
#: ../js/ui/telepathyClient.js:1416
msgid "Certificate expired"
msgstr "Сертыфікат састарэў"
#: ../js/ui/telepathyClient.js:1407
#: ../js/ui/telepathyClient.js:1418
msgid "Certificate not activated"
msgstr "Сертыфікат не актывізаваны"
#: ../js/ui/telepathyClient.js:1409
#: ../js/ui/telepathyClient.js:1420
msgid "Certificate hostname mismatch"
msgstr "Назва камп'ютара ў сертыфікаце не адпавядае патрэбнай"
#: ../js/ui/telepathyClient.js:1411
#: ../js/ui/telepathyClient.js:1422
msgid "Certificate fingerprint mismatch"
msgstr "Адбітак сертыфіката не адпавядае патрэбнаму"
#: ../js/ui/telepathyClient.js:1413
#: ../js/ui/telepathyClient.js:1424
msgid "Certificate self-signed"
msgstr "Сертыфікат уласнаручна падпісаны"
#: ../js/ui/telepathyClient.js:1415
#: ../js/ui/telepathyClient.js:1426
msgid "Status is set to offline"
msgstr "Уключаны рэжым па-за сеткай"
#: ../js/ui/telepathyClient.js:1417
#: ../js/ui/telepathyClient.js:1428
msgid "Encryption is not available"
msgstr "Шыфраванне недаступнае"
#: ../js/ui/telepathyClient.js:1419
#: ../js/ui/telepathyClient.js:1430
msgid "Certificate is invalid"
msgstr "Хібны сертыфікат"
#: ../js/ui/telepathyClient.js:1421
#: ../js/ui/telepathyClient.js:1432
msgid "Connection has been refused"
msgstr "Адмоўлена ў злучэнні"
#: ../js/ui/telepathyClient.js:1423
#: ../js/ui/telepathyClient.js:1434
msgid "Connection can't be established"
msgstr "Не ўдалося ўсталяваць злучэнне"
#: ../js/ui/telepathyClient.js:1425
#: ../js/ui/telepathyClient.js:1436
msgid "Connection has been lost"
msgstr "Злучэнне страчана"
#: ../js/ui/telepathyClient.js:1427
#: ../js/ui/telepathyClient.js:1438
msgid "This resource is already connected to the server"
msgstr "Гэты рэсурс ужо злучаны з серверам"
#: ../js/ui/telepathyClient.js:1429
#: ../js/ui/telepathyClient.js:1440
msgid ""
"Connection has been replaced by a new connection using the same resource"
msgstr "Злучэнне заменена новым для таго ж самага рэсурсу"
#: ../js/ui/telepathyClient.js:1431
#: ../js/ui/telepathyClient.js:1442
msgid "The account already exists on the server"
msgstr "Такі конт ужо існуе на серверы"
#: ../js/ui/telepathyClient.js:1433
#: ../js/ui/telepathyClient.js:1444
msgid "Server is currently too busy to handle the connection"
msgstr "Сервер надта заняты і не можа абслужыць гэта злучэнне"
#: ../js/ui/telepathyClient.js:1435
#: ../js/ui/telepathyClient.js:1446
msgid "Certificate has been revoked"
msgstr "Сертыфікат быў адкліканы"
#: ../js/ui/telepathyClient.js:1437
#: ../js/ui/telepathyClient.js:1448
msgid ""
"Certificate uses an insecure cipher algorithm or is cryptographically weak"
msgstr "Для сертыфіката выкарыстаны слабы або небяспечны алгарытм шыфравання"
#: ../js/ui/telepathyClient.js:1439
#: ../js/ui/telepathyClient.js:1450
msgid ""
"The length of the server certificate, or the depth of the server certificate "
"chain, exceed the limits imposed by the cryptography library"
@ -1433,67 +1434,76 @@ msgstr ""
#. translators: argument is the account name, like
#. * name@jabber.org for example.
#: ../js/ui/telepathyClient.js:1448
#: ../js/ui/telepathyClient.js:1459
#, c-format
msgid "Connection to %s failed"
msgstr "не ўдалося злучыцца з %s"
#: ../js/ui/telepathyClient.js:1455
msgid "Unknown reason"
msgstr "Невядомая прычына"
#: ../js/ui/telepathyClient.js:1462
#: ../js/ui/telepathyClient.js:1468
msgid "Reconnect"
msgstr "Перазлучыцца"
#: ../js/ui/telepathyClient.js:1463
#: ../js/ui/telepathyClient.js:1469
msgid "Edit account"
msgstr "Рэдагаваць конт"
#: ../js/ui/userMenu.js:153
#: ../js/ui/telepathyClient.js:1515
msgid "Unknown reason"
msgstr "Невядомая прычына"
#: ../js/ui/userMenu.js:145
msgid "Hidden"
msgstr "Схаваны"
#: ../js/ui/userMenu.js:159
#: ../js/ui/userMenu.js:151
msgid "Idle"
msgstr "Бяздзейны"
#: ../js/ui/userMenu.js:162
#: ../js/ui/userMenu.js:154
msgid "Unavailable"
msgstr "Недаступны"
#: ../js/ui/userMenu.js:516 ../js/ui/userMenu.js:520 ../js/ui/userMenu.js:589
#: ../js/ui/userMenu.js:512 ../js/ui/userMenu.js:516 ../js/ui/userMenu.js:586
msgid "Power Off..."
msgstr "Выключыць камп'ютар..."
#: ../js/ui/userMenu.js:518 ../js/ui/userMenu.js:520 ../js/ui/userMenu.js:588
msgid "Suspend"
msgstr "Прыпыніць камп'ютар"
#: ../js/ui/userMenu.js:551
#: ../js/ui/userMenu.js:548
msgid "Notifications"
msgstr "Апавяшчэнні"
#: ../js/ui/userMenu.js:559
#: ../js/ui/userMenu.js:556
msgid "Online Accounts"
msgstr "Сеціўныя конты"
#: ../js/ui/userMenu.js:563
#: ../js/ui/userMenu.js:560
msgid "System Settings"
msgstr "Сістэмныя настройкі"
#: ../js/ui/userMenu.js:570
#: ../js/ui/userMenu.js:567
msgid "Lock Screen"
msgstr "Замкнуць экран"
#: ../js/ui/userMenu.js:575
#: ../js/ui/userMenu.js:572
msgid "Switch User"
msgstr "Перамяніць карыстальніка"
#: ../js/ui/userMenu.js:580
#: ../js/ui/userMenu.js:577
msgid "Log Out..."
msgstr "Скончыць сеанс..."
#: ../js/ui/userMenu.js:605
msgid "Your chat status will be set to busy"
msgstr "Вам прызначаны стан занятасці для чату"
#: ../js/ui/userMenu.js:606
msgid ""
"Notifications are now disabled, including chat messages. Your online status "
"has been adjusted to let others know that you might not see their messages."
msgstr ""
"Апавяшчэнні выключаныя, у тым ліку аб новых паведамленнях у чаце. Ваш "
"сеціўны стан абноўлены інфармацыяй аб тым, што вы можаце не ўбачыць чужых "
"паведамленняў у час."
#. Translators: this is the text displayed
#. in the search entry when no search is
#. active; it should not exceed ~30
@ -1584,9 +1594,3 @@ msgstr "Файлавая сістэма"
#, c-format
msgid "%1$s: %2$s"
msgstr "%1$s: %2$s"
#~ msgid "calendar:week_start:0"
#~ msgstr "calendar:week_start:1"
#~ msgid "Do Not Disturb"
#~ msgstr "Не турбаваць"

927
po/bg.po

File diff suppressed because it is too large Load Diff

1078
po/ca.po

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

1119
po/cs.po

File diff suppressed because it is too large Load Diff

662
po/da.po

File diff suppressed because it is too large Load Diff

586
po/de.po

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

1317
po/eo.po

File diff suppressed because it is too large Load Diff

419
po/es.po

File diff suppressed because it is too large Load Diff

1156
po/eu.po

File diff suppressed because it is too large Load Diff

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