Compare commits

...

82 Commits

Author SHA1 Message Date
dafb7b5259 Bump version to 3.11.3
Update NEWS.
2013-12-19 21:54:37 +01:00
92906e217c Updated Spanish translation 2013-12-19 14:36:46 +01:00
5c7b721879 Tajik translation updated 2013-12-19 14:13:33 +05:00
c27dcb0414 Updated Galician translations 2013-12-19 01:53:09 +01:00
7fcae1e974 Remove use of superfluous MetaWindowActor APIs 2013-12-16 12:48:53 -05:00
cc4659f5c6 calendar: Don't rebuild the entire calendar widget when choosing a date
It's inefficient and wasteful. Combined with the JS GC not being great,
it leaks around 100 actors waiting to be GC'd. Yikes.

https://bugzilla.gnome.org/show_bug.cgi?id=720298
2013-12-16 12:44:23 -05:00
9fce12d6b4 calendar: Don't ever force reload
https://bugzilla.gnome.org/show_bug.cgi?id=720298
2013-12-16 12:44:22 -05:00
deb2f30b37 js: Use EVENT_PROPAGATE/EVENT_STOP constants in event handlers
Just as SOURCE_CONTINUE/SOURCE_REMOVE in source functions, these
constants increase code clarity over plain true/false.

https://bugzilla.gnome.org/show_bug.cgi?id=719567
2013-12-16 18:27:19 +01:00
751a3f0e94 js: Use SOURCE_CONTINUE/SOURCE_REMOVE constants in source functions
With support for boolean constants in g-i, we can finally use the
more readable constants instead of true/false.

https://bugzilla.gnome.org/show_bug.cgi?id=719567
2013-12-16 18:27:19 +01:00
fee2a07e08 runDialog: Explicitly set horizontal alignment
When set to fill, the label will always end up left-aligned, which
is only correct in LTR locales. Set the alignment explicitly to
work in both RTL and LTR locales.

https://bugzilla.gnome.org/show_bug.cgi?id=712579
2013-12-16 18:27:19 +01:00
17726abb0a NetworkAgent: handle empty hints and VPN secrets correctly
get_secrets_keyring_cb() contained an optimization (copied over from
nm-applet) that avoided a D-Bus round-trip when NetworkManager sent
secrets hints that were not satisified by the user.  This code did
not properly handle empty hints though, and proceeded to always
request new secrets whenever empty hints were sent.  Remove this
code entirely since the complexity is not worth it (per Jasper).

Second, get_secrets_keyring_cb() was mishandling VPN secrets which
were marked as "always ask".  Because the VPN secrets are not GObject
properties because they cannot be pre-defined, they are passed in
a hash table that is a GObject property marked 'secret'.  Unfortunately,
that means that the shell agent cannot determine their secret flags.
But since the VPN plugin auth dialogs have much better information
about what's required than the shell agent does, always ask the VPN
auth dialogs to handle the secrets requests after grabbing any that
already exist from the keyring.  This is also what nm-applet does.

https://bugzilla.gnome.org/show_bug.cgi?id=719815
2013-12-13 16:23:24 -06:00
01f740ce69 background: Don't prematurely remove file monitors
We need to only remove file monitors when there's no other users
of the content...
2013-12-13 11:50:17 -05:00
b168ccb605 st-scroll-view: Fix style 2013-12-11 20:36:44 -05:00
04a31a52ae calendar: Fix style 2013-12-11 20:36:44 -05:00
6a236fb91e keyring: Align more a srtings to the right side in RTL
It is missed in the previous patch.

Signed-off-by: Yosef Or Boczko <yoseforb@gmail.com>
2013-12-11 23:23:23 +02:00
619fa1bff8 polkitAgent: Align more a string to the right side in RTL
Signed-off-by: Yosef Or Boczko <yoseforb@gmail.com>
2013-12-11 23:14:08 +02:00
53b37e8d0c endSessionDialog: Align some strings to the right in RTL
https://bugzilla.gnome.org/show_bug.cgi?id=712600
2013-12-11 22:42:01 +02:00
f8eb8adfbe keyring: Align some srtings to right in RTL
https://bugzilla.gnome.org/show_bug.cgi?id=712594
2013-12-11 22:40:18 +02:00
3c2aecb81f polkitAgent: Explicitly set horizontal alignment
When set to fill, the label will always end up left-aligned, which
is only correct in LTR locales. Set the alignment explicitly to
work in both RTL and LTR locales.

https://bugzilla.gnome.org/show_bug.cgi?id=712596
2013-12-11 22:38:58 +02:00
efca9e11d6 unlockDialog: Explicitly set horizontal alignment
When set to fill, the label will always end up left-aligned, which
is only correct in LTR locales. Set the alignment explicitly to
work in both RTL and LTR locales.

https://bugzilla.gnome.org/show_bug.cgi?id=712638
2013-12-11 22:36:49 +02:00
49189e0e43 authPrompt: Explicitly set horizontal alignment
When set to fill, the label will always end up left-aligned, which
is only correct in LTR locales. Set the alignment explicitly to
work in both RTL and LTR locales.

https://bugzilla.gnome.org/show_bug.cgi?id=712638
2013-12-11 22:36:15 +02:00
ea86c9bafb userWidget: Fix the padding in RTL
https://bugzilla.gnome.org/show_bug.cgi?id=712638
2013-12-11 22:35:44 +02:00
c361b6a85c Update Arabic translation 2013-12-11 06:53:36 +02:00
c7ff45045c remoteSearch: Let remote search providers not provide an icon
The documentation indicates that they are optional, so let us make the
code behave accordingly.

https://bugzilla.gnome.org/show_bug.cgi?id=719965
2013-12-10 17:01:42 +01:00
090af35ea1 Finnish translation update 2013-12-09 08:08:10 +02:00
8e668ca633 sessionMode: Add back external session modes
Since commit da4238ec68, external session modes are no longer
loaded during start-up; bring them back.

https://bugzilla.gnome.org/show_bug.cgi?id=720017
2013-12-07 10:10:06 +01:00
4d9a16f33b sessionMode: Fix listModes()
Commit da4238ec68 just broke that function completely by
calling array methods on objects and other funny stuff. Fix it.

https://bugzilla.gnome.org/show_bug.cgi?id=720017
2013-12-07 10:10:06 +01:00
c9f2a0f694 sessionMode: Rename _getModes()
Since commit da4238ec68, the function doesn't return anything,
so rename it to _loadModes() to reflect this.

https://bugzilla.gnome.org/show_bug.cgi?id=720017
2013-12-07 10:10:06 +01:00
46bac3069e sessionMode: Fix left-over variable in _loadMode()
Commit da4238ec68 dropped a variable, but didn't replace all
consumers.

https://bugzilla.gnome.org/show_bug.cgi?id=720017
2013-12-07 10:10:06 +01:00
d21aa0d85f shell-app: Track all application windows
Filtering out "non-interesting" windows beforehand as we currently do
means that we may get properties that should be based on all windows,
like the last time the application was used, wrong.
Just track all windows and filter out non-interesting windows manually
in the one place we actually care about the difference.

https://bugzilla.gnome.org/show_bug.cgi?id=719824
2013-12-07 10:10:06 +01:00
3e87d699eb [l10n]Updated Turkish translation 2013-12-07 08:20:27 +02:00
23aa216908 [l10n] Updated Estonian translation 2013-12-05 12:45:57 +02:00
e34e681157 messageTray: Fix style 2013-12-05 01:32:28 -05:00
acd543fe4b messageTray: Fix style
We're missing a semi here
2013-12-04 20:51:10 -05:00
c2df5939d6 Sort js-resources.gresource.xml 2013-12-04 20:44:22 -05:00
b52e74b615 messageTray: Remove transient sources
As far as I can tell, the only behavior change of a transient source
is that they auto-destroy after viewing their summary box pointer.
Since all transient sources are only associated with transient
notifications, it seems that we can never get to their summary box
pointer in the first place! Remove support for this.

https://bugzilla.gnome.org/show_bug.cgi?id=710115
2013-12-04 20:25:28 -05:00
ec2bb039ae viewSelector: Give the active page key focus when it is shown
Rather than implement special focus policies like only allowing keynav
when pressing down, simply give the active page key focus when entering
the overview.

This may break stuff, as it's somewhat of a tricky patch to get right.
Testing this one would be super appreciated.

https://bugzilla.gnome.org/show_bug.cgi?id=644306
2013-12-04 11:22:55 -05:00
aeb9f5775f workspace: Grab the key focus when hovering over a window
This is simply an experiment. I'm not sure I like the result, but it was
worth trying out regardless.

https://bugzilla.gnome.org/show_bug.cgi?id=644306
2013-12-04 11:22:55 -05:00
47a20756b9 workspace: Implement key navigation on the workspaces page
Simply use St's existing key navigation system by making all the window
clones StWidgets, and making the WorkspacesView a focus group.

Since the workspace view is effectively "fake", we need to add a focus
delegator so that when key focus is assigned to the fake workspaces page,
we can keynav inside it properly.

https://bugzilla.gnome.org/show_bug.cgi?id=644306
2013-12-04 11:22:55 -05:00
a7aba1d585 st-widget: Sort actors by distance from the focused actor
Sorting actors by the distance in the axis of movement first and against
the axis otherwise means that if we have a situation like:

  A      F
   B

where "F" is the focused actor, and it slightly overlaps with B vertically,
then we'll choose "B" to go left, rather than "A", which is most likely
what the user intended.

This is especially apparent in the overview where slight window size
differences mean we might not get an exact grid shape.

https://bugzilla.gnome.org/show_bug.cgi?id=644306
2013-12-04 11:22:55 -05:00
c89af0cea4 messageTray: Only attempt to grab the summary box pointer after showing it
For mysterious reasons I'm not sure of myself, navigate_focus will only focus
mapped actors. So, make sure the widget is showing before navigating to it.

https://bugzilla.gnome.org/show_bug.cgi?id=709853
2013-12-04 11:22:55 -05:00
9d3a109946 messageTray: Reword a boolean condition
Just so it's a bit easier to understand...
2013-12-04 11:22:55 -05:00
079f1e6fff messageTray: Fix style 2013-12-04 11:22:55 -05:00
7249b11899 background: Don't silently fizzle out when removing bad content from the cache
If the background is already removed, or we're trying to remove bad content,
this is probably a bug in content accounting, so let us crash so we can fix
the bugs.

https://bugzilla.gnome.org/show_bug.cgi?id=719803
2013-12-03 19:13:12 -05:00
4cfb000812 background: Add copied content from pending image loads to the cache
https://bugzilla.gnome.org/show_bug.cgi?id=719803
2013-12-03 19:13:12 -05:00
5262a41619 background: Clarify the intent of the code
Stomping on local variables and trying to keep loop state isn't
too fun. Just use a new variable here so we aren't too confused
with what we're doing.

https://bugzilla.gnome.org/show_bug.cgi?id=719803
2013-12-03 19:13:12 -05:00
887590730d background: Simplify animation code
https://bugzilla.gnome.org/show_bug.cgi?id=719803
2013-12-03 19:13:12 -05:00
adb49bdf0b background: Remove unused variable
https://bugzilla.gnome.org/show_bug.cgi?id=719803
2013-12-03 19:13:12 -05:00
7f3aadc157 background: Remove the system noise content when not in use
https://bugzilla.gnome.org/show_bug.cgi?id=719803
2013-12-03 19:13:12 -05:00
eb1c85f3f5 background: Don't wait for gdk-pixbuf to fail before loading animations
We don't have any better way of determining whether something is a slideshow
animation, so discriminate on the .xml filename instead of waiting for
gdk-pixbuf to determine whether it can load a file or not.

https://bugzilla.gnome.org/show_bug.cgi?id=719803
2013-12-03 19:13:12 -05:00
dbdc884c96 background: Remove more bogus checks
The content in these arrays can never be null...

https://bugzilla.gnome.org/show_bug.cgi?id=719803
2013-12-03 19:13:12 -05:00
5166354e34 networkAgent: add support for EAP-FAST password requests
EAP-FAST is a top-level EAP method like TTLS, PEAP, etc.

https://bugzilla.gnome.org/show_bug.cgi?id=719813
2013-12-03 18:03:52 -06:00
04ea95049a background: Fix the check for spanning backgrounds
this._monitorIndex does not exist, and neither does
MetaBackground.monitor_index...

https://bugzilla.gnome.org/show_bug.cgi?id=719803
2013-12-03 18:36:46 -05:00
ec62e49001 bluetooth: Remove unused import 2013-12-03 18:36:46 -05:00
6fb21850d8 Updated Brazilian Portuguese translation 2013-12-02 23:17:13 -02:00
98b50fd942 UserWidget: replace vfunc_destroy override with a signal connection
The destroy vfunc might be called during object finalization, and
we can't call any JS from a GC finalizer, so we use a signal
connection instead, as that is removed by GObject the first time
the object is disposed.

https://bugzilla.gnome.org/show_bug.cgi?id=719730
2013-12-02 23:59:50 +01:00
729c962b7c loginDialog: Implement cancel()
The screen shield expects a cancel() method on the unlockDialog
implementation, but LoginDialog does not provide it currently.

https://bugzilla.gnome.org/show_bug.cgi?id=719378
2013-11-27 14:30:24 +01:00
ebc15e60a8 bluetooth: Remove GnomeBluetoothApplet hacks
https://bugzilla.gnome.org/show_bug.cgi?id=719341
2013-11-26 18:53:18 +01:00
85f2d94253 bluetooth: Use BluetoothClient to detect connected devices
Instead of the GnomeBluetoothApplet helper.

https://bugzilla.gnome.org/show_bug.cgi?id=719341
2013-11-26 18:53:18 +01:00
981a536cb5 bluetooth: Use g-s-d to turn off Bluetooth
https://bugzilla.gnome.org/show_bug.cgi?id=719341
2013-11-26 18:53:18 +01:00
abf7c333b1 bluetooth: Remove pairing agent
We'll only have it in the Bluetooth settings panel.

https://bugzilla.gnome.org/show_bug.cgi?id=719341
2013-11-26 18:53:18 +01:00
b2f547e934 authPrompt: propagate gdm "reset" signal after user switching
After a user types in their password at the login screen, one
of two things can happen

1) a new session is started
2) an existing session is switched to

In the latter case, GDM sends a reset signal to the login screen,
so it knows to go back to the user list and wait to be summoned
again.

Unfortunately, all reset signals are ignored after verification
success.  The reason is because the reset handler was copied from
the unlock dialog as part of a deduplication effort in commit
7e7295f259 and the unlock dialog
handler at the time also emitted a "failed" signal on reset
(which wouldn't make sense to emit after success).

These days "failed" is handled in a different way.

This commit changes the code to let reset signals through after
successful verification.

https://bugzilla.gnome.org/show_bug.cgi?id=710456
2013-11-25 22:38:44 -05:00
0870a25e2f Typo fixed in Dutch translation 2013-11-22 22:44:13 +01:00
1091e577a5 Updated Dutch translation by Erwin Poeze 2013-11-22 22:41:18 +01:00
151ad16fe6 Updated Norwegian bokmål translation 2013-11-21 21:24:50 +01:00
e325258091 build: require gjs 1.39.0
This is required for the gresources loader
2013-11-22 06:58:33 +11:00
1139a02b40 viewSelector: Don't show pages until they need to be visible
AppDisplay queues a deferred work to load frequently used apps when the
apps page is loaded. Unfortunately, when the overview is first opened,
all the pages start out visible and then immediately get hidden, so the
deferred work runs immediately after the first overview opening, whether
the user was going to view their frequent apps or not.

Start all pages off as hidden, and rearrange the code so that pages are
only shown when they really need to be.

https://bugzilla.gnome.org/show_bug.cgi?id=712753
2013-11-21 12:50:03 -05:00
4b90953226 osdWindow: add setMonitor() to allow changing the monitor
This is also exposed in the ShowOSD DBus method, the "monitor"
parameter may contain an integer to indicate the monitor number.
If the value is not provided or <0 is used, the monitor is shown
on the primary monitor as usually.

This way, the OSD can be used to notify upon events that solely
apply to one monitor, like tablet mapping as discussed in
https://bugzilla.gnome.org/show_bug.cgi?id=710373.

https://bugzilla.gnome.org/show_bug.cgi?id=712664
2013-11-20 18:03:32 +01:00
d77fc01580 boxpointer: Don't hide when we're already hidden
You would think we would already do something like this, but apparently
lots of code was calling hide() without checking if the box pointer was
already visible, causing it to queue a full tween. The biggest win was
with ibusCandidatePopup.js, which called hide() on every DBus message.

This increases the performance for me to enter the overview by a tiny
bit. The remaining time is spent updating the frequent apps / all apps
display.

https://bugzilla.gnome.org/show_bug.cgi?id=712727
2013-11-19 23:23:25 -05:00
216d84faeb layout: Adjust the opening animation to be less intense
https://bugzilla.gnome.org/show_bug.cgi?id=712362
2013-11-19 22:09:34 -05:00
0c9d95f183 userWidget: Chain up in destroy() 2013-11-19 18:11:43 -05:00
913739d732 shell-app: Remove unused method 2013-11-19 18:11:43 -05:00
7ecb5af587 appDisplay: Remove unused signal
The signal was last used in the pre-3.0 days, so we can stop dragging
it along and just remove it.
2013-11-18 16:24:13 +01:00
87f0e79749 messageTray: Prevent reentrancy issues in _updateState
The methods we call in _updateState may not be reentrant, so make
sure that we never get into a situation where _updateState, through
some crazy chain of events, calls itself.

https://bugzilla.gnome.org/show_bug.cgi?id=711694
2013-11-17 12:06:38 -05:00
c85145d73c entry: Make sure we chain up in enter/leave handlers
To ensure that the focus tracking executes correctly.

https://bugzilla.gnome.org/show_bug.cgi?id=706749
2013-11-15 12:51:19 -05:00
eea689841b highlight session menu button on key focus
https://bugzilla.gnome.org/show_bug.cgi?id=710539
2013-11-15 11:29:21 -05:00
e50a59361d entry: Remove old documentation about the hover style class 2013-11-15 11:14:36 -05:00
9862185bda theme: Clean up
Remove some unused CSS
2013-11-15 11:14:35 -05:00
fe05d35bbb messageTray: Fix style 2013-11-15 10:39:30 -05:00
ba602c17d4 appDisplay: Use the desktop file index for app searching
Rather than scanning all apps for searching, use Ryan's new desktop
file index and the glib support APIs for app searching instead of our
own system.

https://bugzilla.gnome.org/show_bug.cgi?id=711631
2013-11-14 14:28:52 -05:00
831bd07b0d layout: Fix several issues with the background management code
If monitor-changed fires at startup, it will destroy all of the
backgrounds, but since this._isStartup is true, won't recreate any
of them. Additionally, since _bgManagers is indexed by monitor index,
if the primary index is not 0, it could become a sparse array (e.g.
[undefined, undefined, primaryBackground]), and our for loop will
crash trying to access properties of undefined.

Fix both of these issues by always creating background managers for
every monitor, hiding them on startup but only showing them after
the startup animation is complete.

One thing we need to watch out for is that while LayoutManager is
constructing, Main.uiGroup / Main.layoutManager will be undefined,
so addBackgroundMenu will fail. Fix this by passing down the uiGroup
to the background menu code.

https://bugzilla.gnome.org/show_bug.cgi?id=709313
2013-11-14 14:28:51 -05:00
175c5d9fc3 overview: Fix stacking of background and desktop icons
If desktop icons are enabled and not covered by maximized windows,
we will fade them in/out during overview transitions. However when
moving background handling into mutter/gnome-shell, we ended up with
the overview background on top of the DESKTOP window clone, hiding
the fade transition.
Fix the stack order to bring the effect back.

https://bugzilla.gnome.org/show_bug.cgi?id=707671
2013-11-14 15:49:28 +00:00
92 changed files with 4156 additions and 5444 deletions

34
NEWS
View File

@ -1,3 +1,37 @@
3.11.3
======
* Fix fade effect of desktop icons [Florian; #707671]
* Fix issues with background management code [Jasper; #709313]
* Use new Glib facilities for application search [Jasper; #711631]
* Add focus indication to session menu button [Sebastien; #710539]
* Fix hover tracking for StEntries [Jasper; #706749]
* Fix reentrancy issue in message tray [Jasper; #711694]
* Tone down zoom animation on login/unlock [Jasper; #712362]
* Allow specifying monitor for OSD [Carlos; #712664]
* Fix resetting prompt on user switch [Ray; #710456]
* Stop using gnome-bluetooth-applet [Bastien; #719341]
* Add support for EAP-FAST password requests [Dan; #719813]
* Fix entry focus of chat notifications [Jasper; #709853]
* Make window previews keyboard navigatable [Jasper; #644306]
* Fix app switcher order with dialog windows [Florian; #719824]
* Allow remote search providers without icons [Debarshi; #719965]
* Fix various alignment issues in RTL locales [Yosef; #712638, #712596,
#712594, #712600, #712579]
* Misc. bug fixes and cleanups [Jasper, Florian, Giovanni, Dan; #712727,
#712753, #719378, #719730, #719803, #710115, #720017, #719815, #719567,
#720298]
Contributors:
Giovanni Campagna, Carlos Garnacho, Sebastien Lafargue, Tim Lunn,
Florian Müllner, Bastien Nocera, Yosef Or Boczko, Debarshi Ray,
Jasper St. Pierre, Ray Strode, Dan Williams
Translations:
Kjartan Maraas [nb], Reinout van Schouwen [nl], Rafael Ferreira [pt_BR],
Mattias Põldaru [et], Emin Tufan Çetin [tr], Jiri Grönroos [fi],
Khaled Hosny [ar], Fran Diéguez [gl], Victor Ibragimov [tg],
Daniel Mustieles [es]
3.11.2
======
* Cache search result display actors [Jasper; #704912]

View File

@ -1,5 +1,5 @@
AC_PREREQ(2.63)
AC_INIT([gnome-shell],[3.11.2],[https://bugzilla.gnome.org/enter_bug.cgi?product=gnome-shell],[gnome-shell])
AC_INIT([gnome-shell],[3.11.3],[https://bugzilla.gnome.org/enter_bug.cgi?product=gnome-shell],[gnome-shell])
AC_CONFIG_HEADERS([config.h])
AC_CONFIG_SRCDIR([src/shell-global.c])
@ -75,7 +75,7 @@ AC_MSG_RESULT($enable_systemd)
CLUTTER_MIN_VERSION=1.13.4
GOBJECT_INTROSPECTION_MIN_VERSION=0.10.1
GJS_MIN_VERSION=1.38.1
GJS_MIN_VERSION=1.39.0
MUTTER_MIN_VERSION=3.11.1
GTK_MIN_VERSION=3.7.9
GIO_MIN_VERSION=2.37.0
@ -140,19 +140,11 @@ AS_IF([test x$enable_browser_plugin = xyes], [
])
AM_CONDITIONAL(BUILD_BROWSER_PLUGIN, test x$enable_browser_plugin = xyes)
AC_MSG_CHECKING([for bluetooth support])
PKG_CHECK_EXISTS([gnome-bluetooth-1.0 >= 3.9.0],
[BLUETOOTH_DIR=`$PKG_CONFIG --variable=applet_libdir gnome-bluetooth-1.0`
BLUETOOTH_LIBS=`$PKG_CONFIG --variable=applet_libs gnome-bluetooth-1.0`
AC_SUBST([BLUETOOTH_LIBS],["$BLUETOOTH_LIBS"])
AC_SUBST([BLUETOOTH_DIR],["$BLUETOOTH_DIR"])
AC_DEFINE_UNQUOTED([BLUETOOTH_DIR],["$BLUETOOTH_DIR"],[Path to installed GnomeBluetooth typelib and library])
AC_DEFINE([HAVE_BLUETOOTH],[1],[Define if you have libgnome-bluetooth-applet])
AC_SUBST([HAVE_BLUETOOTH],[1])
AC_MSG_RESULT([yes])],
PKG_CHECK_MODULES(BLUETOOTH, gnome-bluetooth-1.0 >= 3.9.0,
[AC_DEFINE([HAVE_BLUETOOTH],[1],[Define if you have libgnome-bluetooth-applet])
AC_SUBST([HAVE_BLUETOOTH],[1])],
[AC_DEFINE([HAVE_BLUETOOTH],[0])
AC_SUBST([HAVE_BLUETOOTH],[0])
AC_MSG_RESULT([no])])
AC_SUBST([HAVE_BLUETOOTH],[0])])
PKG_CHECK_MODULES(CALENDAR_SERVER, libecal-1.2 >= $LIBECAL_MIN_VERSION libedataserver-1.2 >= $LIBEDATASERVER_MIN_VERSION gio-2.0)
AC_SUBST(CALENDAR_SERVER_CFLAGS)

View File

@ -1944,6 +1944,7 @@ StScrollBar StButton#vhandle:active {
.end-session-dialog-description:rtl {
padding-right: 17px;
text-align: right;
}
.end-session-dialog-logout-icon {
@ -1976,6 +1977,10 @@ StScrollBar StButton#vhandle:active {
font-weight: bold;
}
.end-session-dialog-list-header:rtl {
text-align: right;
}
.end-session-dialog-app-list-item,
.end-session-dialog-session-list-item {
spacing: 1em;
@ -2095,6 +2100,10 @@ StScrollBar StButton#vhandle:active {
color: #666666;
}
.prompt-dialog-description:rtl {
text-align: right;
}
.prompt-dialog-password-box {
spacing: 1em;
padding-bottom: 1em;
@ -2321,6 +2330,8 @@ StScrollBar StButton#vhandle:active {
.login-dialog-user-list-item {
border-radius: 5px;
padding: .2em;
color: #bfbfbf;
text-shadow: black 0px 2px 2px;
}
.login-dialog-user-list-item:ltr {
@ -2331,24 +2342,6 @@ StScrollBar StButton#vhandle:active {
padding-left: 1em;
}
.login-dialog-user-list-item .login-dialog-user-list-item-name {
font-size: 20px;
padding-left: 18px;
font-weight: bold;
}
.login-dialog-user-list:expanded .login-dialog-user-list-item {
color: #bfbfbf;
}
.login-dialog-user-list-item,
.login-dialog-user-list-item:hover .login-dialog-user-list-item-name,
.login-dialog-user-list:expanded .login-dialog-user-list-item:focus .login-dialog-user-list-item-name,
.login-dialog-user-list:expanded .login-dialog-user-list-item:logged-in {
color: #bfbfbf;
text-shadow: black 0px 2px 2px;
}
.login-dialog-user-list-item:hover {
background-color: rgba(255,255,255,0.1);
}
@ -2375,13 +2368,6 @@ StScrollBar StButton#vhandle:active {
background-color: #8b8b8b;
}
.login-dialog-user-list-item-icon {
border: 2px solid #8b8b8b;
border-radius: 3px;
width: 64px;
height: 64px;
}
.login-dialog-not-listed-label {
font-size: 10.5pt;
font-weight: bold;
@ -2432,6 +2418,7 @@ StScrollBar StButton#vhandle:active {
}
.login-dialog-session-list-button:hover,
.login-dialog-session-list-button:focus,
.login-dialog-session-list-button:active {
color: white;
}
@ -2501,11 +2488,18 @@ StScrollBar StButton#vhandle:active {
font-size: 20px;
font-weight: bold;
text-align: left;
padding-left: 18px;
color:white;
text-shadow: black 0px 4px 3px 0px;
}
.user-widget-label:ltr {
padding-left: 18px;
}
.user-widget-label:rtl {
padding-right: 18px;
}
/* Screen shield */
#panel.lock-screen,

View File

@ -112,7 +112,7 @@ expand_content_files=
# e.g. GTKDOC_CFLAGS=-I$(top_srcdir) -I$(top_builddir) $(GTK_DEBUG_FLAGS)
# e.g. GTKDOC_LIBS=$(top_builddir)/gtk/$(gtktargetlib)
GTKDOC_CFLAGS=$(GNOME_SHELL_CFLAGS)
GTKDOC_LIBS=$(GNOME_SHELL_LIBS) $(BLUETOOTH_LIBS) $(top_builddir)/src/libgnome-shell-menu.la $(top_builddir)/src/libgnome-shell-base.la $(top_builddir)/src/libgnome-shell.la
GTKDOC_LIBS=$(GNOME_SHELL_LIBS) $(top_builddir)/src/libgnome-shell-menu.la $(top_builddir)/src/libgnome-shell-base.la $(top_builddir)/src/libgnome-shell.la
# This includes the standard gtk-doc make rules, copied by gtkdocize.
include $(top_srcdir)/gtk-doc.make

View File

@ -80,6 +80,7 @@ const AuthPrompt = new Lang.Class({
if (event.get_key_symbol() == Clutter.KEY_Escape) {
this.cancel();
}
return Clutter.EVENT_PROPAGATE;
}));
this._userWell = new St.Bin({ x_fill: true,
@ -93,7 +94,7 @@ const AuthPrompt = new Lang.Class({
this.actor.add(this._label,
{ expand: true,
x_fill: true,
x_fill: false,
y_fill: true,
x_align: St.Align.START });
this._entry = new St.Entry({ style_class: 'login-dialog-prompt-entry',
@ -111,7 +112,7 @@ const AuthPrompt = new Lang.Class({
this._message = new St.Label({ opacity: 0,
styleClass: 'login-dialog-message' });
this._message.clutter_text.line_wrap = true;
this.actor.add(this._message, { x_fill: true, y_align: St.Align.START });
this.actor.add(this._message, { x_fill: false, x_align: St.Align.START, y_align: St.Align.START });
this._buttonBox = new St.BoxLayout({ style_class: 'login-dialog-button-box',
vertical: false });
@ -263,10 +264,8 @@ const AuthPrompt = new Lang.Class({
},
_onReset: function() {
if (this.verificationStatus != AuthPromptStatus.VERIFICATION_SUCCEEDED) {
this.verificationStatus = AuthPromptStatus.NOT_VERIFYING;
this.reset();
}
},
addActorToDefaultButtonWell: function(actor) {

View File

@ -644,7 +644,7 @@ const LoginDialog = new Lang.Class({
onComplete: function() {
Mainloop.idle_add(Lang.bind(this, function() {
this._greeter.call_start_session_when_ready_sync(serviceName, true, null);
return false;
return GLib.SOURCE_REMOVE;
}));
},
onCompleteScope: this });
@ -699,6 +699,7 @@ const LoginDialog = new Lang.Class({
function() {
this._timedLoginAnimationTime -= _TIMED_LOGIN_IDLE_THRESHOLD;
hold.release();
return GLib.SOURCE_REMOVE;
});
return hold;
},
@ -763,7 +764,7 @@ const LoginDialog = new Lang.Class({
global.stage.connect('captured-event',
Lang.bind(this, function(actor, event) {
if (this._timedLoginDelay == undefined)
return false;
return Clutter.EVENT_PROPAGATE;
if (event.type() == Clutter.EventType.KEY_PRESS ||
event.type() == Clutter.EventType.BUTTON_PRESS) {
@ -776,7 +777,7 @@ const LoginDialog = new Lang.Class({
this._resetTimedLogin();
}
return false;
return Clutter.EVENT_PROPAGATE;
}));
},
@ -885,6 +886,10 @@ const LoginDialog = new Lang.Class({
Main.ctrlAltTabManager.removeGroup(this.dialogLayout);
},
cancel: function() {
this._authPrompt.cancel();
},
addCharacter: function(unichar) {
this._authPrompt.addCharacter(unichar);
},

View File

@ -250,6 +250,7 @@ const ShellUserVerifier = new Lang.Class({
Lang.bind(this, function() {
this._messageQueueTimeoutId = 0;
this._queueMessageTimeout();
return GLib.SOURCE_REMOVE;
}));
},

View File

@ -8,7 +8,9 @@
<file>gdm/oVirt.js</file>
<file>gdm/realmd.js</file>
<file>gdm/util.js</file>
<file>extensionPrefs/main.js</file>
<file>misc/config.js</file>
<file>misc/extensionUtils.js</file>
<file>misc/fileUtils.js</file>
@ -22,7 +24,9 @@
<file>misc/params.js</file>
<file>misc/smartcardManager.js</file>
<file>misc/util.js</file>
<file>perf/core.js</file>
<file>ui/altTab.js</file>
<file>ui/animation.js</file>
<file>ui/appDisplay.js</file>
@ -37,12 +41,12 @@
<file>ui/dateMenu.js</file>
<file>ui/dnd.js</file>
<file>ui/endSessionDialog.js</file>
<file>ui/extensionSystem.js</file>
<file>ui/extensionDownloader.js</file>
<file>ui/environment.js</file>
<file>ui/extensionDownloader.js</file>
<file>ui/extensionSystem.js</file>
<file>ui/focusCaretTracker.js</file>
<file>ui/ibusCandidatePopup.js</file>
<file>ui/grabHelper.js</file>
<file>ui/ibusCandidatePopup.js</file>
<file>ui/iconGrid.js</file>
<file>ui/keyboard.js</file>
<file>ui/layout.js</file>
@ -53,11 +57,6 @@
<file>ui/main.js</file>
<file>ui/messageTray.js</file>
<file>ui/modalDialog.js</file>
<file>ui/separator.js</file>
<file>ui/sessionMode.js</file>
<file>ui/shellEntry.js</file>
<file>ui/shellMountOperation.js</file>
<file>ui/slider.js</file>
<file>ui/notificationDaemon.js</file>
<file>ui/osdWindow.js</file>
<file>ui/overview.js</file>
@ -66,15 +65,41 @@
<file>ui/panelMenu.js</file>
<file>ui/pointerWatcher.js</file>
<file>ui/popupMenu.js</file>
<file>ui/remoteSearch.js</file>
<file>ui/remoteMenu.js</file>
<file>ui/remoteSearch.js</file>
<file>ui/runDialog.js</file>
<file>ui/screenShield.js</file>
<file>ui/screencast.js</file>
<file>ui/screenshot.js</file>
<file>ui/screenShield.js</file>
<file>ui/scripting.js</file>
<file>ui/search.js</file>
<file>ui/separator.js</file>
<file>ui/sessionMode.js</file>
<file>ui/shellDBus.js</file>
<file>ui/shellEntry.js</file>
<file>ui/shellMountOperation.js</file>
<file>ui/slider.js</file>
<file>ui/switcherPopup.js</file>
<file>ui/tweener.js</file>
<file>ui/unlockDialog.js</file>
<file>ui/userWidget.js</file>
<file>ui/viewSelector.js</file>
<file>ui/windowAttentionHandler.js</file>
<file>ui/windowManager.js</file>
<file>ui/workspace.js</file>
<file>ui/workspaceSwitcherPopup.js</file>
<file>ui/workspaceThumbnail.js</file>
<file>ui/workspacesView.js</file>
<file>ui/xdndHandler.js</file>
<file>ui/components/__init__.js</file>
<file>ui/components/autorunManager.js</file>
<file>ui/components/automountManager.js</file>
<file>ui/components/networkAgent.js</file>
<file>ui/components/polkitAgent.js</file>
<file>ui/components/telepathyClient.js</file>
<file>ui/components/keyring.js</file>
<file>ui/status/accessibility.js</file>
<file>ui/status/brightness.js</file>
<file>ui/status/keyboard.js</file>
@ -85,24 +110,5 @@
<file>ui/status/bluetooth.js</file>
<file>ui/status/screencast.js</file>
<file>ui/status/system.js</file>
<file>ui/switcherPopup.js</file>
<file>ui/tweener.js</file>
<file>ui/unlockDialog.js</file>
<file>ui/userWidget.js</file>
<file>ui/viewSelector.js</file>
<file>ui/windowAttentionHandler.js</file>
<file>ui/windowManager.js</file>
<file>ui/workspace.js</file>
<file>ui/workspaceThumbnail.js</file>
<file>ui/workspacesView.js</file>
<file>ui/workspaceSwitcherPopup.js</file>
<file>ui/xdndHandler.js</file>
<file>ui/components/__init__.js</file>
<file>ui/components/autorunManager.js</file>
<file>ui/components/automountManager.js</file>
<file>ui/components/networkAgent.js</file>
<file>ui/components/polkitAgent.js</file>
<file>ui/components/telepathyClient.js</file>
<file>ui/components/keyring.js</file>
</gresource>
</gresources>

View File

@ -89,7 +89,7 @@ const HistoryManager = new Lang.Class({
} else if (symbol == Clutter.KEY_Down) {
return this._setNextItem(entry.get_text());
}
return false;
return Clutter.EVENT_PROPAGATE;
},
_indexChanged: function() {

View File

@ -2,6 +2,7 @@
const Clutter = imports.gi.Clutter;
const Gio = imports.gi.Gio;
const GLib = imports.gi.GLib;
const Lang = imports.lang;
const Mainloop = imports.mainloop;
const Meta = imports.gi.Meta;
@ -312,7 +313,7 @@ const AppSwitcherPopup = new Lang.Class({
this._createThumbnails();
this._thumbnailTimeoutId = 0;
this._thumbnailsFocused = false;
return false;
return GLib.SOURCE_REMOVE;
},
_destroyThumbnails : function() {
@ -547,7 +548,7 @@ const AppSwitcher = new Lang.Class({
Lang.bind(this, function () {
this._enterItem(index);
this._mouseTimeOutId = 0;
return false;
return GLib.SOURCE_REMOVE;
}));
} else
this._itemEntered(index);

View File

@ -1,5 +1,6 @@
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
const GLib = imports.gi.GLib;
const Lang = imports.lang;
const Mainloop = imports.mainloop;
const St = imports.gi.St;
@ -59,7 +60,7 @@ const Animation = new Lang.Class({
_update: function() {
this._showFrame(this._frame + 1);
return true;
return GLib.SOURCE_CONTINUE;
},
_animationsLoaded: function() {

View File

@ -415,7 +415,7 @@ const AllView = new Lang.Class({
_onScroll: function(actor, event) {
if (this._displayingPopup)
return true;
return Clutter.EVENT_STOP;
let direction = event.get_scroll_direction();
if (direction == Clutter.ScrollDirection.UP)
@ -423,7 +423,7 @@ const AllView = new Lang.Class({
else if (direction == Clutter.ScrollDirection.DOWN)
this.goToPage(this._currentPage + 1);
return true;
return Clutter.EVENT_STOP;
},
_onPan: function(action) {
@ -454,17 +454,17 @@ const AllView = new Lang.Class({
_onKeyPressEvent: function(actor, event) {
if (this._displayingPopup)
return true;
return Clutter.EVENT_STOP;
if (event.get_key_symbol() == Clutter.Page_Up) {
this.goToPage(this._currentPage - 1);
return true;
return Clutter.EVENT_STOP;
} else if (event.get_key_symbol() == Clutter.Page_Down) {
this.goToPage(this._currentPage + 1);
return true;
return Clutter.EVENT_STOP;
}
return false;
return Clutter.EVENT_PROPAGATE;
},
_getItemId: function(item) {
@ -889,11 +889,24 @@ const AppSearchProvider = new Lang.Class({
},
getInitialResultSet: function(terms, callback, cancellable) {
callback(this._appSys.initial_search(terms));
let query = terms.join(' ');
let groups = Gio.DesktopAppInfo.search(query);
let usage = Shell.AppUsage.get_default();
let results = [];
groups.forEach(function(group) {
group = group.filter(function(appID) {
let app = Gio.DesktopAppInfo.new(appID);
return app && app.should_show();
});
results = results.concat(group.sort(function(a, b) {
return usage.compare('', a, b);
}));
});
callback(results);
},
getSubsearchResultSet: function(previousResults, terms, callback, cancellable) {
callback(this._appSys.subsearch(previousResults, terms));
this.getInitialResultSet(terms, callback, cancellable);
},
activateResult: function(result) {
@ -1210,13 +1223,13 @@ const AppFolderPopup = new Lang.Class({
_onKeyPress: function(actor, event) {
if (!this._isOpen)
return false;
return Clutter.EVENT_PROPAGATE;
if (event.get_key_symbol() != Clutter.KEY_Escape)
return false;
return Clutter.EVENT_PROPAGATE;
this.popdown();
return true;
return Clutter.EVENT_STOP;
},
toggle: function() {
@ -1357,13 +1370,13 @@ const AppIcon = new Lang.Class({
Lang.bind(this, function() {
this._menuTimeoutId = 0;
this.popupMenu();
return false;
return GLib.SOURCE_REMOVE;
}));
} else if (button == 3) {
this.popupMenu();
return true;
return Clutter.EVENT_STOP;
}
return false;
return Clutter.EVENT_PROPAGATE;
},
_onClicked: function(actor, button) {
@ -1375,7 +1388,6 @@ const AppIcon = new Lang.Class({
// Last workspace is always empty
let launchWorkspace = global.screen.get_workspace_by_index(global.screen.n_workspaces - 1);
launchWorkspace.activate(global.get_current_time());
this.emit('launching');
this.app.open_new_window(-1);
Main.overview.hide();
}
@ -1434,7 +1446,6 @@ const AppIcon = new Lang.Class({
},
_onActivate: function (event) {
this.emit('launching');
let modifiers = event.get_state();
if (modifiers & Clutter.ModifierType.CONTROL_MASK
@ -1503,7 +1514,9 @@ const AppIconMenu = new Lang.Class({
_redisplay: function() {
this.removeAll();
let windows = this._source.app.get_windows();
let windows = this._source.app.get_windows().filter(function(w) {
return Shell.WindowTracker.is_window_interesting(w);
});
// Display the app windows menu items and the separator between windows
// of the current desktop and other windows.

View File

@ -50,11 +50,9 @@ const BackgroundCache = new Lang.Class({
effects: Meta.BackgroundEffects.NONE });
let content = null;
let candidateContent = null;
for (let i = 0; i < this._patterns.length; i++) {
if (!this._patterns[i])
continue;
if (this._patterns[i].get_shading() != params.shadingType)
continue;
@ -88,7 +86,6 @@ const BackgroundCache = new Lang.Class({
}
this._patterns.push(content);
return content;
},
@ -116,8 +113,8 @@ const BackgroundCache = new Lang.Class({
_removeContent: function(contentList, content) {
let index = contentList.indexOf(content);
if (index >= 0)
if (index < 0)
throw new Error("Trying to remove invalid content: " + content);
contentList.splice(index, 1);
},
@ -128,7 +125,8 @@ const BackgroundCache = new Lang.Class({
removeImageContent: function(content) {
let filename = content.get_filename();
if (filename && this._fileMonitors[filename])
let hasOtherUsers = this._images.some(function(content) { return filename == content.get_filename(); });
if (!hasOtherUsers)
delete this._fileMonitors[filename];
this._removeContent(this._images, content);
@ -186,13 +184,17 @@ const BackgroundCache = new Lang.Class({
for (let j = 0; j < pendingLoad.callers.length; j++) {
if (pendingLoad.callers[j].onFinished) {
if (content && pendingLoad.callers[j].shouldCopy) {
content = object.copy(pendingLoad.callers[j].monitorIndex,
pendingLoad.callers[j].effects);
let newContent;
if (content && pendingLoad.callers[j].shouldCopy) {
newContent = content.copy(pendingLoad.callers[j].monitorIndex,
pendingLoad.callers[j].effects);
this._images.push(newContent);
} else {
newContent = content;
}
pendingLoad.callers[j].onFinished(content);
pendingLoad.callers[j].onFinished(newContent);
}
}
@ -210,11 +212,9 @@ const BackgroundCache = new Lang.Class({
onFinished: null });
let content = null;
let candidateContent = null;
for (let i = 0; i < this._images.length; i++) {
if (!this._images[i])
continue;
if (this._images[i].get_style() != params.style)
continue;
@ -222,7 +222,7 @@ const BackgroundCache = new Lang.Class({
continue;
if (params.style == GDesktopEnums.BackgroundStyle.SPANNED &&
this._images[i].monitor_index != this._monitorIndex)
this._images[i].monitor != params.monitorIndex)
continue;
candidateContent = this._images[i];
@ -262,6 +262,7 @@ const BackgroundCache = new Lang.Class({
if (params.onLoaded) {
GLib.idle_add(GLib.PRIORITY_DEFAULT, Lang.bind(this, function() {
params.onLoaded(this._animation);
return GLib.SOURCE_REMOVE;
}));
}
}
@ -276,6 +277,7 @@ const BackgroundCache = new Lang.Class({
if (params.onLoaded) {
GLib.idle_add(GLib.PRIORITY_DEFAULT, Lang.bind(this, function() {
params.onLoaded(this._animation);
return GLib.SOURCE_REMOVE;
}));
}
}));
@ -375,7 +377,7 @@ const Background = new Lang.Class({
GLib.idle_add(GLib.PRIORITY_DEFAULT, Lang.bind(this, function() {
this.emit('loaded');
return false;
return GLib.SOURCE_REMOVE;
}));
},
@ -414,27 +416,26 @@ const Background = new Lang.Class({
this._fileWatches[filename] = signalId;
},
_addImage: function(content, index, filename) {
content.brightness = this._brightness;
content.vignette_sharpness = this._vignetteSharpness;
_ensureImage: function(index) {
if (this._images[index])
return;
let actor = new Meta.BackgroundActor();
actor.content = content;
// The background pattern is the first actor in
// the group, and all images should be above that.
this.actor.insert_child_at_index(actor, index + 1);
this._images[index] = actor;
this._watchCacheFile(filename);
},
_updateImage: function(content, index, filename) {
_updateImage: function(index, content, filename) {
content.brightness = this._brightness;
content.vignette_sharpness = this._vignetteSharpness;
this._cache.removeImageContent(this._images[index].content);
this._images[index].content = content;
let image = this._images[index];
if (image.content)
this._cache.removeImageContent(content);
image.content = content;
this._watchCacheFile(filename);
},
@ -482,11 +483,8 @@ const Background = new Lang.Class({
return;
}
if (!this._images[i]) {
this._addImage(content, i, files[i]);
} else {
this._updateImage(content, i, files[i]);
}
this._ensureImage(i);
this._updateImage(i, content, files[i]);
if (numPendingImages == 0) {
this._setLoaded();
@ -521,7 +519,7 @@ const Background = new Lang.Class({
Lang.bind(this, function() {
this._updateAnimationTimeoutId = 0;
this._updateAnimation();
return false;
return GLib.SOURCE_REMOVE;
}));
},
@ -541,24 +539,27 @@ const Background = new Lang.Class({
});
},
_loadFile: function(filename) {
_loadImage: function(filename) {
this._cache.getImageContent({ monitorIndex: this._monitorIndex,
effects: this._effects,
style: this._style,
filename: filename,
cancellable: this._cancellable,
onFinished: Lang.bind(this, function(content) {
if (!content) {
if (!this._cancellable.is_cancelled())
this._loadAnimation(filename);
return;
if (content) {
this._ensureImage(0);
this._updateImage(0, content, filename);
}
this._addImage(content, 0, filename);
this._setLoaded();
})
});
},
_loadFile: function(filename) {
if (filename.endsWith('.xml'))
this._loadAnimation(filename);
else
this._loadImage(filename);
},
_load: function () {
@ -638,7 +639,13 @@ const SystemBackground = new Lang.Class({
this.emit('loaded');
})
});
}
this.actor.connect('destroy', Lang.bind(this, this._onDestroy));
},
_onDestroy: function() {
this._cache.removeImageContent(this.actor.content);
},
});
Signals.addSignalMethods(SystemBackground.prototype);
@ -726,8 +733,8 @@ const BackgroundManager = new Lang.Class({
}
},
_updateBackground: function(background, monitorIndex) {
let newBackground = this._createBackground(monitorIndex);
_updateBackground: function(background) {
let newBackground = this._createBackground();
newBackground.vignetteSharpness = background.vignetteSharpness;
newBackground.brightness = background.brightness;
newBackground.visible = background.visible;
@ -776,7 +783,7 @@ const BackgroundManager = new Lang.Class({
background.changeSignalId = background.connect('changed', Lang.bind(this, function() {
background.disconnect(background.changeSignalId);
background.changeSignalId = 0;
this._updateBackground(background, this._monitorIndex);
this._updateBackground(background);
}));
background.actor.connect('destroy', Lang.bind(this, function() {

View File

@ -13,7 +13,7 @@ const BackgroundMenu = new Lang.Class({
Name: 'BackgroundMenu',
Extends: PopupMenu.PopupMenu,
_init: function(source) {
_init: function(source, layoutManager) {
this.parent(source, 0, St.Side.TOP);
this.addSettingsAction(_("Settings"), 'gnome-control-center.desktop');
@ -22,17 +22,17 @@ const BackgroundMenu = new Lang.Class({
this.actor.add_style_class_name('background-menu');
Main.uiGroup.add_actor(this.actor);
layoutManager.uiGroup.add_actor(this.actor);
this.actor.hide();
}
});
function addBackgroundMenu(actor) {
function addBackgroundMenu(actor, layoutManager) {
let cursor = new St.Bin({ opacity: 0 });
Main.uiGroup.add_actor(cursor);
layoutManager.uiGroup.add_actor(cursor);
actor.reactive = true;
actor._backgroundMenu = new BackgroundMenu(cursor);
actor._backgroundMenu = new BackgroundMenu(cursor, layoutManager);
actor._backgroundManager = new PopupMenu.PopupMenuManager({ actor: actor });
actor._backgroundManager.addMenu(actor._backgroundMenu);

View File

@ -69,7 +69,7 @@ const BoxPointer = new Lang.Class({
_muteInput: function() {
if (this._capturedEventId == 0)
this._capturedEventId = this.actor.connect('captured-event',
function() { return true; });
function() { return Clutter.EVENT_STOP; });
},
_unmuteInput: function() {
@ -121,6 +121,9 @@ const BoxPointer = new Lang.Class({
},
hide: function(animate, onComplete) {
if (!this.actor.visible)
return;
let xOffset = 0;
let yOffset = 0;
let themeNode = this.actor.get_theme_node();

View File

@ -17,16 +17,18 @@ const SHOW_WEEKDATE_KEY = 'show-weekdate';
// in org.gnome.desktop.interface
const CLOCK_FORMAT_KEY = 'clock-format';
function _sameDay(dateA, dateB) {
return (dateA.getDate() == dateB.getDate() &&
dateA.getMonth() == dateB.getMonth() &&
dateA.getYear() == dateB.getYear());
}
function _sameYear(dateA, dateB) {
return (dateA.getYear() == dateB.getYear());
}
function _sameMonth(dateA, dateB) {
return _sameYear(dateA, dateB) && (dateA.getMonth() == dateB.getMonth());
}
function _sameDay(dateA, dateB) {
return _sameMonth(dateA, dateB) && (dateA.getDate() == dateB.getDate());
}
/* TODO: maybe needs config - right now we assume that Saturday and
* Sunday are non-work days (not true in e.g. Israel, it's Sunday and
* Monday there)
@ -329,25 +331,22 @@ const DBusEventSource = new Lang.Class({
return;
if (this._curRequestBegin && this._curRequestEnd){
let callFlags = Gio.DBusCallFlags.NO_AUTO_START;
if (forceReload)
callFlags = Gio.DBusCallFlags.NONE;
this._dbusProxy.GetEventsRemote(this._curRequestBegin.getTime() / 1000,
this._curRequestEnd.getTime() / 1000,
forceReload,
Lang.bind(this, this._onEventsReceived),
callFlags);
Gio.DBusCallFlags.NONE);
}
},
requestRange: function(begin, end, forceReload) {
if (forceReload || !(_datesEqual(begin, this._lastRequestBegin) && _datesEqual(end, this._lastRequestEnd))) {
requestRange: function(begin, end) {
if (!(_datesEqual(begin, this._lastRequestBegin) && _datesEqual(end, this._lastRequestEnd))) {
this.isLoading = true;
this._lastRequestBegin = begin;
this._lastRequestEnd = end;
this._curRequestBegin = begin;
this._curRequestEnd = end;
this._loadEvents(forceReload);
this._loadEvents(false);
}
},
@ -419,21 +418,19 @@ const Calendar = new Lang.Class({
setEventSource: function(eventSource) {
this._eventSource = eventSource;
this._eventSource.connect('changed', Lang.bind(this, function() {
this._update(false);
this._update();
}));
this._update(true);
this._update();
},
// Sets the calendar to show a specific date
setDate: function(date, forceReload) {
if (!_sameDay(date, this._selectedDate)) {
setDate: function(date) {
if (_sameDay(date, this._selectedDate))
return;
this._selectedDate = date;
this._update(forceReload);
this._update();
this.emit('selected-date-changed', new Date(this._selectedDate));
} else {
if (forceReload)
this._update(forceReload);
}
},
_buildHeader: function() {
@ -497,6 +494,7 @@ const Calendar = new Lang.Class({
this._onNextMonthButtonClicked();
break;
}
return Clutter.EVENT_PROPAGATE;
},
_onPrevMonthButtonClicked: function() {
@ -520,7 +518,7 @@ const Calendar = new Lang.Class({
this._backButton.grab_key_focus();
this.setDate(newDate, false);
this.setDate(newDate);
},
_onNextMonthButtonClicked: function() {
@ -544,28 +542,25 @@ const Calendar = new Lang.Class({
this._forwardButton.grab_key_focus();
this.setDate(newDate, false);
this.setDate(newDate);
},
_onSettingsChange: function() {
this._useWeekdate = this._settings.get_boolean(SHOW_WEEKDATE_KEY);
this._buildHeader();
this._update(false);
this._update();
},
_update: function(forceReload) {
_rebuildCalendar: function() {
let now = new Date();
if (_sameYear(this._selectedDate, now))
this._monthLabel.text = this._selectedDate.toLocaleFormat(this._headerFormatWithoutYear);
else
this._monthLabel.text = this._selectedDate.toLocaleFormat(this._headerFormat);
// Remove everything but the topBox and the weekday labels
let children = this.actor.get_children();
for (let i = this._firstDayIndex; i < children.length; i++)
children[i].destroy();
this._buttons = [];
// Start at the beginning of the week before the start of the month
//
// We want to show always 6 weeks (to keep the calendar menu at the same
@ -583,11 +578,13 @@ const Calendar = new Lang.Class({
// Actually computing the number of weeks is complex, but we know that the
// problematic categories (2 and 4) always start on week start, and that
// all months at the end have 6 weeks.
let beginDate = new Date(this._selectedDate);
beginDate.setDate(1);
beginDate.setSeconds(0);
beginDate.setHours(12);
this._calendarBegin = new Date(beginDate);
let year = beginDate.getYear();
let daysToWeekStart = (7 + beginDate.getDay() - this._weekStart) % 7;
@ -608,23 +605,18 @@ const Calendar = new Lang.Class({
if (this._eventSource.isDummy)
button.reactive = false;
let iterStr = iter.toUTCString();
button._date = new Date(iter);
button.connect('clicked', Lang.bind(this, function() {
this._shouldDateGrabFocus = true;
let newlySelectedDate = new Date(iterStr);
this.setDate(newlySelectedDate, false);
this._shouldDateGrabFocus = false;
this.setDate(button._date);
}));
let hasEvents = this._eventSource.hasEvents(iter);
let styleClass = 'calendar-day-base calendar-day';
if (_isWorkDay(iter))
styleClass += ' calendar-work-day'
styleClass += ' calendar-work-day';
else
styleClass += ' calendar-nonwork-day'
styleClass += ' calendar-nonwork-day';
// Hack used in lieu of border-collapse - see gnome-shell.css
if (row == 2)
@ -641,7 +633,7 @@ const Calendar = new Lang.Class({
styleClass += ' calendar-other-month-day';
if (hasEvents)
styleClass += ' calendar-day-with-events'
styleClass += ' calendar-day-with-events';
button.style_class = styleClass;
@ -649,12 +641,7 @@ const Calendar = new Lang.Class({
this.actor.add(button,
{ row: row, col: offsetCols + (7 + iter.getDay() - this._weekStart) % 7 });
if (_sameDay(this._selectedDate, iter)) {
button.add_style_pseudo_class('active');
if (this._shouldDateGrabFocus)
button.grab_key_focus();
}
this._buttons.push(button);
if (this._useWeekdate && iter.getDay() == 4) {
let label = new St.Label({ text: _getCalendarWeekForDate(iter).toString(),
@ -668,9 +655,29 @@ const Calendar = new Lang.Class({
if (iter.getDay() == this._weekStart)
row++;
}
// Signal to the event source that we are interested in events
// only from this date range
this._eventSource.requestRange(beginDate, iter, forceReload);
this._eventSource.requestRange(beginDate, iter);
},
_update: function() {
let now = new Date();
if (_sameYear(this._selectedDate, now))
this._monthLabel.text = this._selectedDate.toLocaleFormat(this._headerFormatWithoutYear);
else
this._monthLabel.text = this._selectedDate.toLocaleFormat(this._headerFormat);
if (!this._calendarBegin || !_sameMonth(this._selectedDate, this._calendarBegin))
this._rebuildCalendar();
this._buttons.forEach(Lang.bind(this, function(button) {
if (_sameDay(button._date, this._selectedDate))
button.add_style_pseudo_class('active');
else
button.remove_style_pseudo_class('active');
}));
}
});

View File

@ -77,7 +77,7 @@ const AutomountManager = new Lang.Class({
}));
this._mountAllId = 0;
return false;
return GLib.SOURCE_REMOVE;
},
_onDriveConnected: function() {
@ -236,7 +236,7 @@ const AutomountManager = new Lang.Class({
_allowAutorunExpire: function(volume) {
Mainloop.timeout_add_seconds(AUTORUN_EXPIRE_TIMEOUT_SECS, function() {
volume.allowAutorun = false;
return false;
return GLib.SOURCE_REMOVE;
});
}
});

View File

@ -45,7 +45,9 @@ const KeyringDialog = new Lang.Class({
this.prompt.bind_property('message', subject, 'text', GObject.BindingFlags.SYNC_CREATE);
this._messageBox.add(subject,
{ y_fill: false,
{ x_fill: false,
y_fill: false,
x_align: St.Align.START,
y_align: St.Align.START });
let description = new St.Label({ style_class: 'prompt-dialog-description' });
@ -136,6 +138,7 @@ const KeyringDialog = new Lang.Class({
warning.clutter_text.ellipsize = Pango.EllipsizeMode.NONE;
warning.clutter_text.line_wrap = true;
layout.pack(warning, 1, row);
layout.child_set(warning, { x_fill: false, x_align: Clutter.TableAlignment.START });
this.prompt.bind_property('warning-visible', warning, 'visible', GObject.BindingFlags.SYNC_CREATE);
this.prompt.bind_property('warning', warning, 'text', GObject.BindingFlags.SYNC_CREATE);

View File

@ -255,6 +255,7 @@ const NetworkSecretDialog = new Lang.Class({
case 'leap':
case 'ttls':
case 'peap':
case 'fast':
// 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)

View File

@ -54,7 +54,9 @@ const AuthenticationDialog = new Lang.Class({
text: _("Authentication Required") });
messageBox.add(this._subjectLabel,
{ y_fill: false,
{ x_fill: false,
y_fill: false,
x_align: St.Align.START,
y_align: St.Align.START });
this._descriptionLabel = new St.Label({ style_class: 'prompt-dialog-description',
@ -63,7 +65,9 @@ const AuthenticationDialog = new Lang.Class({
this._descriptionLabel.clutter_text.line_wrap = true;
messageBox.add(this._descriptionLabel,
{ y_fill: true,
{ x_fill: false,
y_fill: true,
x_align: St.Align.START,
y_align: St.Align.START });
if (userNames.length > 1) {
@ -95,7 +99,8 @@ const AuthenticationDialog = new Lang.Class({
if (userIsRoot) {
let userLabel = new St.Label(({ style_class: 'polkit-dialog-user-root-label',
text: userRealName }));
messageBox.add(userLabel);
messageBox.add(userLabel, { x_fill: false,
x_align: St.Align.START });
} else {
let userBox = new St.BoxLayout({ style_class: 'polkit-dialog-user-layout',
vertical: false });
@ -137,7 +142,7 @@ const AuthenticationDialog = new Lang.Class({
this._errorMessageLabel = new St.Label({ style_class: 'prompt-dialog-error-label' });
this._errorMessageLabel.clutter_text.ellipsize = Pango.EllipsizeMode.NONE;
this._errorMessageLabel.clutter_text.line_wrap = true;
messageBox.add(this._errorMessageLabel);
messageBox.add(this._errorMessageLabel, { x_fill: false, x_align: St.Align.START });
this._errorMessageLabel.hide();
this._infoMessageLabel = new St.Label({ style_class: 'prompt-dialog-info-label' });

View File

@ -675,7 +675,7 @@ const ChatSource = new Lang.Class({
this._notifyTimeoutId = 0;
return false;
return GLib.SOURCE_REMOVE;
},
// This is called for both messages we send from
@ -975,7 +975,7 @@ const ChatNotification = new Lang.Class({
this._filterMessages();
return false;
return GLib.SOURCE_REMOVE;
},
appendAliasChange: function(oldAlias, newAlias) {
@ -1013,7 +1013,7 @@ const ChatNotification = new Lang.Class({
this.source.setChatState(Tp.ChannelChatState.PAUSED);
return false;
return GLib.SOURCE_REMOVE;
},
_onEntryChanged: function() {

View File

@ -1,6 +1,7 @@
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
const Clutter = imports.gi.Clutter;
const GLib = imports.gi.GLib;
const Signals = imports.signals;
const Lang = imports.lang;
const Meta = imports.gi.Meta;
@ -577,7 +578,7 @@ const Dash = new Lang.Class({
this._labelShowing = true;
item.showLabel();
this._showLabelTimeoutId = 0;
return false;
return GLib.SOURCE_REMOVE;
}));
if (this._resetHoverTimeoutId > 0) {
Mainloop.source_remove(this._resetHoverTimeoutId);
@ -594,7 +595,7 @@ const Dash = new Lang.Class({
Lang.bind(this, function() {
this._labelShowing = false;
this._resetHoverTimeoutId = 0;
return false;
return GLib.SOURCE_REMOVE;
}));
}
}

View File

@ -113,22 +113,7 @@ const DateMenuButton = new Lang.Class({
this.menu.connect('open-state-changed', Lang.bind(this, function(menu, isOpen) {
if (isOpen) {
let now = new Date();
/* Passing true to setDate() forces events to be reloaded. We
* want this behavior, because
*
* o It will cause activation of the calendar server which is
* useful if it has crashed
*
* o It will cause the calendar server to reload events which
* is useful if dynamic updates are not supported or not
* properly working
*
* Since this only happens when the menu is opened, the cost
* isn't very big.
*/
this._calendar.setDate(now, true);
// No need to update this._eventList as ::selected-date-changed
// signal will fire
this._calendar.setDate(now);
}
}));

View File

@ -106,10 +106,10 @@ const _Draggable = new Lang.Class({
_onButtonPress : function (actor, event) {
if (event.get_button() != 1)
return false;
return Clutter.EVENT_PROPAGATE;
if (Tweener.getTweenCount(actor))
return false;
return Clutter.EVENT_PROPAGATE;
this._buttonDown = true;
this._grabActor();
@ -118,7 +118,7 @@ const _Draggable = new Lang.Class({
this._dragStartX = stageX;
this._dragStartY = stageY;
return false;
return Clutter.EVENT_PROPAGATE;
},
_grabActor: function() {
@ -164,11 +164,11 @@ const _Draggable = new Lang.Class({
} else if (this._dragActor != null && !this._animationInProgress) {
// Drag must have been cancelled with Esc.
this._dragComplete();
return true;
return Clutter.EVENT_STOP;
} else {
// Drag has never started.
this._ungrabActor();
return false;
return Clutter.EVENT_PROPAGATE;
}
// We intercept MOTION event to figure out if the drag has started and to draw
// this._dragActor under the pointer when dragging is in progress
@ -184,11 +184,11 @@ const _Draggable = new Lang.Class({
let symbol = event.get_key_symbol();
if (symbol == Clutter.Escape) {
this._cancelDrag(event.get_time());
return true;
return Clutter.EVENT_STOP;
}
}
return false;
return Clutter.EVENT_PROPAGATE;
},
/**
@ -362,7 +362,7 @@ const _Draggable = new Lang.Class({
let result = motionFunc(dragEvent);
if (result != DragMotionResult.CONTINUE) {
global.screen.set_cursor(DRAG_CURSOR_MAP[result]);
return false;
return GLib.SOURCE_REMOVE;
}
}
}
@ -380,13 +380,13 @@ const _Draggable = new Lang.Class({
0);
if (result != DragMotionResult.CONTINUE) {
global.screen.set_cursor(DRAG_CURSOR_MAP[result]);
return false;
return GLib.SOURCE_REMOVE;
}
}
target = target.get_parent();
}
global.screen.set_cursor(Meta.Cursor.DND_IN_DRAG);
return false;
return GLib.SOURCE_REMOVE;
},
_queueUpdateDragHover: function() {

View File

@ -249,7 +249,9 @@ const EndSessionDialog = new Lang.Class({
this._subjectLabel = new St.Label({ style_class: 'end-session-dialog-subject' });
messageLayout.add(this._subjectLabel,
{ y_fill: false,
{ x_fill: false,
y_fill: false,
x_align: St.Align.START,
y_align: St.Align.START });
this._descriptionLabel = new St.Label({ style_class: 'end-session-dialog-description' });
@ -409,7 +411,7 @@ const EndSessionDialog = new Lang.Class({
this._secondsLeft = this._totalSecondsToStayOpen - secondsElapsed;
if (this._secondsLeft > 0) {
this._sync();
return true;
return GLib.SOURCE_CONTINUE;
}
let dialogContent = DialogContent[this._type];
@ -417,7 +419,7 @@ const EndSessionDialog = new Lang.Class({
this._confirm(button.signal);
this._timerId = 0;
return false;
return GLib.SOURCE_REMOVE;
}));
},

View File

@ -280,7 +280,7 @@ const GrabHelper = new Lang.Class({
if (type == Clutter.EventType.KEY_PRESS &&
event.get_key_symbol() == Clutter.KEY_Escape) {
this.ungrab({ isUser: true });
return true;
return Clutter.EVENT_STOP;
}
let press = type == Clutter.EventType.BUTTON_PRESS;
@ -289,14 +289,14 @@ const GrabHelper = new Lang.Class({
if (release && this._ignoreRelease) {
this._ignoreRelease = false;
return true;
return Clutter.EVENT_STOP;
}
if (this._isWithinGrabbedActor(event.get_source()))
return false;
return Clutter.EVENT_PROPAGATE;
if (Main.keyboard.shouldTakeEvent(event))
return false;
return Clutter.EVENT_PROPAGATE;
if (button) {
// If we have a press event, ignore the next event,
@ -305,9 +305,9 @@ const GrabHelper = new Lang.Class({
this._ignoreRelease = true;
let i = this._actorInGrabStack(event.get_source()) + 1;
this.ungrab({ actor: this._grabStack[i].actor, isUser: true });
return true;
return Clutter.EVENT_STOP;
}
return true;
return Clutter.EVENT_STOP;
},
});

View File

@ -32,6 +32,7 @@ const CandidateArea = new Lang.Class({
let j = i;
box.connect('button-release-event', Lang.bind(this, function(actor, event) {
this.emit('candidate-clicked', j, event.get_button(), event.get_state());
return Clutter.EVENT_PROPAGATE;
}));
}

View File

@ -82,8 +82,16 @@ const Key = new Lang.Class({
style_class: 'keyboard-key' });
button.key_width = this._key.width;
button.connect('button-press-event', Lang.bind(this, function () { this._key.press(); }));
button.connect('button-release-event', Lang.bind(this, function () { this._key.release(); }));
button.connect('button-press-event', Lang.bind(this,
function () {
this._key.press();
return Clutter.EVENT_PROPAGATE;
}));
button.connect('button-release-event', Lang.bind(this,
function () {
this._key.release();
return Clutter.EVENT_PROPAGATE;
}));
return button;
},
@ -106,8 +114,16 @@ const Key = new Lang.Class({
let label = this._getUnichar(extended_key);
let key = new St.Button({ label: label, style_class: 'keyboard-key' });
key.extended_key = extended_key;
key.connect('button-press-event', Lang.bind(this, function () { extended_key.press(); }));
key.connect('button-release-event', Lang.bind(this, function () { extended_key.release(); }));
key.connect('button-press-event', Lang.bind(this,
function () {
extended_key.press();
return Clutter.EVENT_PROPAGATE;
}));
key.connect('button-release-event', Lang.bind(this,
function () {
extended_key.release();
return Clutter.EVENT_PROPAGATE;
}));
this._extended_keyboard.add(key);
}
this._boxPointer.bin.add_actor(this._extended_keyboard);
@ -252,7 +268,10 @@ const Keyboard = new Lang.Class({
if (!this._showIdleId)
this._showIdleId = GLib.idle_add(GLib.PRIORITY_DEFAULT_IDLE,
Lang.bind(this, function() { this.Show(time); }));
Lang.bind(this, function() {
this.Show(time);
return GLib.SOURCE_REMOVE;
}));
},
_createLayersForGroup: function (gname) {
@ -294,7 +313,7 @@ const Keyboard = new Lang.Class({
else if (release && this._capturedPress)
this._hideSubkeys();
return true;
return Clutter.EVENT_STOP;
},
_addRows : function (keys, layout) {
@ -438,7 +457,6 @@ const Keyboard = new Lang.Class({
_createSource: function () {
if (this._source == null) {
this._source = new KeyboardSource(this);
this._source.setTransient(true);
Main.messageTray.add(this._source);
}
},
@ -480,6 +498,7 @@ const Keyboard = new Lang.Class({
Lang.bind(this, function() {
this._clearKeyboardRestTimer();
this._show(monitor);
return GLib.SOURCE_REMOVE;
}));
},
@ -505,6 +524,7 @@ const Keyboard = new Lang.Class({
Lang.bind(this, function() {
this._clearKeyboardRestTimer();
this._hide();
return GLib.SOURCE_REMOVE;
}));
},

View File

@ -352,26 +352,26 @@ const LayoutManager = new Lang.Class({
this.emit('hot-corners-changed');
},
_createBackground: function(monitorIndex) {
_addBackgroundMenu: function(bgManager) {
BackgroundMenu.addBackgroundMenu(bgManager.background.actor, this);
},
_createBackgroundManager: function(monitorIndex) {
let bgManager = new Background.BackgroundManager({ container: this._backgroundGroup,
layoutManager: this,
monitorIndex: monitorIndex });
BackgroundMenu.addBackgroundMenu(bgManager.background.actor);
bgManager.connect('changed', Lang.bind(this, function() {
BackgroundMenu.addBackgroundMenu(bgManager.background.actor);
}));
bgManager.connect('changed', Lang.bind(this, this._addBackgroundMenu));
this._addBackgroundMenu(bgManager);
this._bgManagers[monitorIndex] = bgManager;
return bgManager.background;
return bgManager;
},
_createSecondaryBackgrounds: function() {
_showSecondaryBackgrounds: function() {
for (let i = 0; i < this.monitors.length; i++) {
if (i != this.primaryIndex) {
let background = this._createBackground(i);
let background = this._bgManagers[i].background;
background.actor.show();
background.actor.opacity = 0;
Tweener.addTween(background.actor,
{ opacity: 255,
@ -381,10 +381,6 @@ const LayoutManager = new Lang.Class({
}
},
_createPrimaryBackground: function() {
this._createBackground(this.primaryIndex);
},
_updateBackgrounds: function() {
let i;
for (i = 0; i < this._bgManagers.length; i++)
@ -395,11 +391,12 @@ const LayoutManager = new Lang.Class({
if (Main.sessionMode.isGreeter)
return;
if (this._startingUp)
return;
for (let i = 0; i < this.monitors.length; i++) {
this._createBackground(i);
let bgManager = this._createBackgroundManager(i);
this._bgManagers.push(bgManager);
if (i != this.primaryIndex && this._startingUp)
bgManager.background.actor.hide();
}
},
@ -595,7 +592,7 @@ const LayoutManager = new Lang.Class({
if (Main.sessionMode.isGreeter) {
this.panelBox.translation_y = -this.panelBox.height;
} else {
this._createPrimaryBackground();
this._updateBackgrounds();
// We need to force an update of the regions now before we scale
// the UI group to get the coorect allocation for the struts.
@ -610,7 +607,7 @@ const LayoutManager = new Lang.Class({
this.uiGroup.set_pivot_point(x / global.screen_width,
y / global.screen_height);
this.uiGroup.scale_x = this.uiGroup.scale_y = 0.5;
this.uiGroup.scale_x = this.uiGroup.scale_y = 0.75;
this.uiGroup.opacity = 0;
global.window_group.set_clip(monitor.x, monitor.y, monitor.width, monitor.height);
}
@ -625,7 +622,7 @@ const LayoutManager = new Lang.Class({
// when the system is bogged down
GLib.idle_add(GLib.PRIORITY_LOW, Lang.bind(this, function() {
this._startupAnimation();
return false;
return GLib.SOURCE_REMOVE;
}));
},
@ -673,7 +670,7 @@ const LayoutManager = new Lang.Class({
this.keyboardBox.show();
if (!Main.sessionMode.isGreeter) {
this._createSecondaryBackgrounds();
this._showSecondaryBackgrounds();
global.window_group.remove_clip();
}
@ -1042,7 +1039,7 @@ const LayoutManager = new Lang.Class({
workspace.set_builtin_struts(struts);
}
return false;
return GLib.SOURCE_REMOVE;
}
});
Signals.addSignalMethods(LayoutManager.prototype);
@ -1229,20 +1226,20 @@ const HotCorner = new Lang.Class({
this._entered = true;
this._toggleOverview();
}
return false;
return Clutter.EVENT_PROPAGATE;
},
_onCornerLeft : function(actor, event) {
if (event.get_related() != this.actor)
this._entered = false;
// Consume event, otherwise this will confuse onEnvironsLeft
return true;
return Clutter.EVENT_STOP;
},
_onEnvironsLeft : function(actor, event) {
if (event.get_related() != this._corner)
this._entered = false;
return false;
return Clutter.EVENT_PROPAGATE;
}
});

View File

@ -109,6 +109,7 @@ const AutoComplete = new Lang.Class({
}
this._lastTabTime = currTime;
}
return Clutter.EVENT_PROPAGATE;
},
// Insert characters of text not already included in head at cursor position. i.e., if text="abc" and head="a",
@ -558,7 +559,7 @@ const Inspector = new Lang.Class({
_onKeyPressEvent: function (actor, event) {
if (event.get_key_symbol() == Clutter.Escape)
this._close();
return true;
return Clutter.EVENT_STOP;
},
_onButtonPressEvent: function (actor, event) {
@ -567,7 +568,7 @@ const Inspector = new Lang.Class({
this.emit('target', this._target, stageX, stageY);
}
this._close();
return true;
return Clutter.EVENT_STOP;
},
_onScrollEvent: function (actor, event) {
@ -601,12 +602,12 @@ const Inspector = new Lang.Class({
default:
break;
}
return true;
return Clutter.EVENT_STOP;
},
_onMotionEvent: function (actor, event) {
this._update(event);
return true;
return Clutter.EVENT_STOP;
},
_update: function(event) {
@ -828,7 +829,7 @@ const LookingGlass = new Lang.Class({
global.stage.set_key_focus(this._entry);
}));
this.actor.hide();
return true;
return Clutter.EVENT_STOP;
}));
let gcIcon = new St.Icon({ icon_name: 'gnome-fs-trash-full',
@ -841,7 +842,9 @@ const LookingGlass = new Lang.Class({
this._timeoutId = Mainloop.timeout_add(500, Lang.bind(this, function () {
gcIcon.icon_name = 'gnome-fs-trash-full';
Mainloop.source_remove(this._timeoutId);
return GLib.SOURCE_REMOVE;
}));
return Clutter.EVENT_PROPAGATE;
}));
let notebook = new Notebook();
@ -1063,7 +1066,7 @@ const LookingGlass = new Lang.Class({
} else {
this.close();
}
return true;
return Clutter.EVENT_STOP;
}
// Ctrl+PgUp and Ctrl+PgDown switches tabs in the notebook view
if (modifierState & Clutter.ModifierType.CONTROL_MASK) {
@ -1073,7 +1076,7 @@ const LookingGlass = new Lang.Class({
this._notebook.nextTab();
}
}
return false;
return Clutter.EVENT_PROPAGATE;
},
open : function() {

View File

@ -609,7 +609,7 @@ function queueDeferredWork(workId) {
_deferredTimeoutId = Mainloop.timeout_add_seconds(DEFERRED_TIMEOUT_SECONDS, function () {
_runAllDeferredWork();
_deferredTimeoutId = 0;
return false;
return GLib.SOURCE_REMOVE;
});
}
}

View File

@ -76,7 +76,7 @@ const Urgency = {
NORMAL: 1,
HIGH: 2,
CRITICAL: 3
}
};
function _fixMarkup(text, allowMarkup) {
if (allowMarkup) {
@ -187,7 +187,7 @@ const URLHighlighter = new Lang.Class({
// The MessageTray doesn't actually hide us, so
// we need to check for paint opacities as well.
if (!actor.visible || actor.get_paint_opacity() == 0)
return false;
return Clutter.EVENT_PROPAGATE;
// Keep Notification.actor from seeing this and taking
// a pointer grab, which would block our button-release-event
@ -196,7 +196,7 @@ const URLHighlighter = new Lang.Class({
}));
this.actor.connect('button-release-event', Lang.bind(this, function (actor, event) {
if (!actor.visible || actor.get_paint_opacity() == 0)
return false;
return Clutter.EVENT_PROPAGATE;
let urlId = this._findUrlAtPos(event);
if (urlId != -1) {
@ -205,13 +205,13 @@ const URLHighlighter = new Lang.Class({
url = 'http://' + url;
Gio.app_info_launch_default_for_uri(url, global.create_app_launch_context());
return true;
return Clutter.EVENT_STOP;
}
return false;
return Clutter.EVENT_PROPAGATE;
}));
this.actor.connect('motion-event', Lang.bind(this, function(actor, event) {
if (!actor.visible || actor.get_paint_opacity() == 0)
return false;
return Clutter.EVENT_PROPAGATE;
let urlId = this._findUrlAtPos(event);
if (urlId != -1 && !this._cursorChanged) {
@ -221,16 +221,17 @@ const URLHighlighter = new Lang.Class({
global.screen.set_cursor(Meta.Cursor.DEFAULT);
this._cursorChanged = false;
}
return false;
return Clutter.EVENT_PROPAGATE;
}));
this.actor.connect('leave-event', Lang.bind(this, function() {
if (!this.actor.visible || this.actor.get_paint_opacity() == 0)
return;
return Clutter.EVENT_PROPAGATE;
if (this._cursorChanged) {
this._cursorChanged = false;
global.screen.set_cursor(Meta.Cursor.DEFAULT);
}
return Clutter.EVENT_PROPAGATE;
}));
},
@ -1263,7 +1264,6 @@ const Source = new Lang.Class({
this.title = title;
this.iconName = iconName;
this.isTransient = false;
this.isChat = false;
this.isMuted = false;
this.keepTrayOnSummaryClick = false;
@ -1323,10 +1323,6 @@ const Source = new Lang.Class({
return rightClickMenu;
},
setTransient: function(isTransient) {
this.isTransient = isTransient;
},
setTitle: function(newTitle) {
this.title = newTitle;
this.emit('title-changed');
@ -1528,9 +1524,9 @@ const SummaryItem = new Lang.Class({
_onKeyPress: function(actor, event) {
if (event.get_key_symbol() == Clutter.KEY_Up) {
actor.emit('clicked', 1);
return true;
return Clutter.EVENT_STOP;
}
return false;
return Clutter.EVENT_PROPAGATE;
},
prepareNotificationStackForShowing: function() {
@ -1625,7 +1621,7 @@ const MessageTrayMenu = new Lang.Class({
this._clearItem = this.addAction(_("Clear Messages"), function() {
let toDestroy = tray.getSources().filter(function(source) {
return source.isClearable;
})
});
toDestroy.forEach(function(source) {
source.destroy();
@ -1788,6 +1784,7 @@ const MessageTray = new Lang.Class({
this._setClickedSummaryItem(null);
this._updateState();
actor.grab_key_focus();
return Clutter.EVENT_PROPAGATE;
}));
global.focus_manager.add_group(this.actor);
this._summary = new St.BoxLayout({ style_class: 'message-tray-summary',
@ -1993,32 +1990,32 @@ const MessageTray = new Lang.Class({
this._trayDwellTimeoutId = 0;
if (Main.layoutManager.bottomMonitor.inFullscreen)
return false;
return GLib.SOURCE_REMOVE;
// We don't want to open the tray when a modal dialog
// is up, so we check the modal count for that. When we are in the
// overview we have to take the overview's modal push into account
if (Main.modalCount > (Main.overview.visible ? 1 : 0))
return false;
return GLib.SOURCE_REMOVE;
// If the user interacted with the focus window since we started the tray
// dwell (by clicking or typing), don't activate the message tray
let focusWindow = global.display.focus_window;
let currentUserTime = focusWindow ? focusWindow.user_time : 0;
if (currentUserTime != this._trayDwellUserTime)
return false;
return GLib.SOURCE_REMOVE;
this.openTray();
return false;
return GLib.SOURCE_REMOVE;
},
_onNotificationKeyRelease: function(actor, event) {
if (event.get_key_symbol() == Clutter.KEY_Escape && event.get_state() == 0) {
this._closeNotification();
return true;
return Clutter.EVENT_STOP;
}
return false;
return Clutter.EVENT_PROPAGATE;
},
_closeNotification: function() {
@ -2339,7 +2336,7 @@ const MessageTray = new Lang.Class({
this._updateNotificationTimeout(0);
this._updateState();
}
return false;
return GLib.SOURCE_REMOVE;
},
_escapeTray: function() {
@ -2356,6 +2353,13 @@ const MessageTray = new Lang.Class({
// _updateState() figures out what (if anything) needs to be done
// at the present time.
_updateState: function() {
// If our state changes caused _updateState to be called,
// just exit now to prevent reentrancy issues.
if (this._updatingState)
return;
this._updatingState = true;
// Filter out acknowledged notifications.
this._notificationQueue = this._notificationQueue.filter(function(n) {
return !n.acknowledged;
@ -2375,7 +2379,7 @@ const MessageTray = new Lang.Class({
} else if (this._notificationState == State.SHOWN) {
let expired = (this._userActiveWhileNotificationShown &&
this._notificationTimeoutId == 0 &&
!(this._notification.urgency == Urgency.CRITICAL) &&
this._notification.urgency != Urgency.CRITICAL &&
!this._notification.focused &&
!this._pointerInNotification);
let mustClose = (this._notificationRemoved || !hasNotifications || expired || this._traySummoned);
@ -2432,11 +2436,12 @@ const MessageTray = new Lang.Class({
this._desktopCloneState == State.SHOWN);
let desktopCloneShouldBeVisible = (trayShouldBeVisible);
if (!desktopCloneIsVisible && desktopCloneShouldBeVisible) {
if (!desktopCloneIsVisible && desktopCloneShouldBeVisible)
this._showDesktopClone();
} else if (desktopCloneIsVisible && !desktopCloneShouldBeVisible) {
else if (desktopCloneIsVisible && !desktopCloneShouldBeVisible)
this._hideDesktopClone();
}
this._updatingState = false;
},
_tween: function(actor, statevar, value, params) {
@ -2664,7 +2669,7 @@ const MessageTray = new Lang.Class({
this._lastSeenMouseX = x;
this._lastSeenMouseY = y;
return false;
return GLib.SOURCE_REMOVE;
},
_hideNotification: function(animate) {
@ -2801,13 +2806,13 @@ const MessageTray = new Lang.Class({
Lang.bind(this, this._onSourceDoneDisplayingContent));
this._summaryBoxPointer.bin.child = child;
this._grabHelper.grab({ actor: this._summaryBoxPointer.bin.child,
onUngrab: Lang.bind(this, this._onSummaryBoxPointerUngrabbed) });
this._summaryBoxPointer.actor.opacity = 0;
this._summaryBoxPointer.actor.show();
this._adjustSummaryBoxPointerPosition();
this._grabHelper.grab({ actor: this._summaryBoxPointer.bin.child,
onUngrab: Lang.bind(this, this._onSummaryBoxPointerUngrabbed) });
this._summaryBoxPointerState = State.SHOWING;
this._summaryBoxPointer.show(BoxPointer.PopupAnimation.FULL, Lang.bind(this, function() {
this._summaryBoxPointerState = State.SHOWN;
@ -2862,13 +2867,13 @@ const MessageTray = new Lang.Class({
case Clutter.KEY_Escape:
this._setClickedSummaryItem(null);
this._updateState();
return true;
return Clutter.EVENT_STOP;
case Clutter.KEY_Delete:
this._clickedSummaryItem.source.destroy();
this._escapeTray();
return true;
return Clutter.EVENT_STOP;
}
return false;
return Clutter.EVENT_PROPAGATE;
},
_onSummaryBoxPointerUngrabbed: function() {
@ -2906,8 +2911,6 @@ const MessageTray = new Lang.Class({
this._summaryBoxPointerItem.doneShowingNotificationStack();
this._summaryBoxPointerItem = null;
if (source.isTransient && !this._reNotifyAfterHideNotification)
source.destroy(NotificationDestroyedReason.EXPIRED);
if (this._reNotifyAfterHideNotification) {
this._onNotify(this._reNotifyAfterHideNotification.source, this._reNotifyAfterHideNotification);
this._reNotifyAfterHideNotification = null;
@ -2926,7 +2929,6 @@ const SystemNotificationSource = new Lang.Class({
_init: function() {
this.parent(_("System Information"), 'dialog-information-symbolic');
this.setTransient(true);
},
open: function() {

View File

@ -229,6 +229,7 @@ const ModalDialog = new Lang.Class({
_onKeyPressEvent: function(object, event) {
this._pressedKey = event.get_key_symbol();
return Clutter.EVENT_PROPAGATE;
},
_onKeyReleaseEvent: function(object, event) {
@ -237,21 +238,21 @@ const ModalDialog = new Lang.Class({
let symbol = event.get_key_symbol();
if (symbol != pressedKey)
return false;
return Clutter.EVENT_PROPAGATE;
let buttonInfo = this._buttonKeys[symbol];
if (!buttonInfo)
return false;
return Clutter.EVENT_PROPAGATE;
let button = buttonInfo['button'];
let action = buttonInfo['action'];
if (action && button.reactive) {
action();
return true;
return Clutter.EVENT_STOP;
}
return false;
return Clutter.EVENT_PROPAGATE;
},
_onGroupDestroy: function() {

View File

@ -181,12 +181,10 @@ const FdoNotificationDaemon = new Lang.Class({
},
// Returns the source associated with ndata.notification if it is set.
// Otherwise, returns the source associated with the title and pid if
// such source is stored in this._sources and the notification is not
// transient. If the existing or requested source is associated with
// a tray icon and passed in pid matches a pid of an existing source,
// the title match is ignored to enable representing a tray icon and
// notifications from the same application with a single source.
// If the existing or requested source is associated with a tray icon
// and passed in pid matches a pid of an existing source, the title
// match is ignored to enable representing a tray icon and notifications
// from the same application with a single source.
//
// If no existing source is found, a new source is created as long as
// pid is provided.
@ -204,32 +202,20 @@ const FdoNotificationDaemon = new Lang.Class({
if (ndata && ndata.notification)
return ndata.notification.source;
let isForTransientNotification = (ndata && ndata.hints['transient'] == true);
// We don't want to override a persistent notification
// with a transient one from the same sender, so we
// always create a new source object for new transient notifications
// and never add it to this._sources .
if (!isForTransientNotification) {
let source = this._lookupSource(title, pid, trayIcon);
if (source) {
source.setTitle(title);
return source;
}
}
let source = new FdoNotificationDaemonSource(title, pid, sender, trayIcon, ndata ? ndata.hints['desktop-entry'] : null);
source.setTransient(isForTransientNotification);
if (!isForTransientNotification) {
this._sources.push(source);
source.connect('destroy', Lang.bind(this,
function() {
source.connect('destroy', Lang.bind(this, function() {
let index = this._sources.indexOf(source);
if (index >= 0)
this._sources.splice(index, 1);
}));
}
Main.messageTray.add(source);
return source;
@ -261,7 +247,7 @@ const FdoNotificationDaemon = new Lang.Class({
Mainloop.idle_add(Lang.bind(this,
function () {
this._emitNotificationClosed(id, NotificationClosedReason.DISMISSED);
return false;
return GLib.SOURCE_REMOVE;
}));
return invocation.return_value(GLib.Variant.new('(u)', [id]));
}
@ -336,20 +322,10 @@ const FdoNotificationDaemon = new Lang.Class({
let [pid] = result;
source = this._getSource(appName, pid, ndata, sender, null);
// We only store sender-pid entries for persistent sources.
// Removing the entries once the source is destroyed
// would result in the entries associated with transient
// sources removed once the notification is shown anyway.
// However, keeping these pairs would mean that we would
// possibly remove an entry associated with a persistent
// source when a transient source for the same sender is
// distroyed.
if (!source.isTransient) {
this._senderToPid[sender] = pid;
source.connect('destroy', Lang.bind(this, function() {
delete this._senderToPid[sender];
}));
}
this._notifyForSource(source, ndata);
}));

View File

@ -1,6 +1,7 @@
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
const Clutter = imports.gi.Clutter;
const GLib = imports.gi.GLib;
const St = imports.gi.St;
const Lang = imports.lang;
@ -77,7 +78,8 @@ const OsdWindow = new Lang.Class({
y_expand: true,
x_align: Clutter.ActorAlign.CENTER,
y_align: Clutter.ActorAlign.CENTER });
this.actor.add_constraint(new Layout.MonitorConstraint({ primary: true }));
this._currentMonitor = undefined;
this.setMonitor (-1);
this._box = new St.BoxLayout({ style_class: 'osd-window',
vertical: true });
this.actor.add_actor(this._box);
@ -172,6 +174,7 @@ const OsdWindow = new Lang.Class({
Meta.enable_unredirect_for_screen(global.screen);
})
});
return GLib.SOURCE_REMOVE;
},
_reset: function() {
@ -182,7 +185,13 @@ const OsdWindow = new Lang.Class({
_monitorsChanged: function() {
/* assume 110x110 on a 640x480 display and scale from there */
let monitor = Main.layoutManager.primaryMonitor;
let monitor;
if (this._currentMonitor >= 0)
monitor = Main.layoutManager.monitors[this._currentMonitor];
else
monitor = Main.layoutManager.primaryMonitor;
let scalew = monitor.width / 640.0;
let scaleh = monitor.height / 480.0;
let scale = Math.min(scalew, scaleh);
@ -206,5 +215,23 @@ const OsdWindow = new Lang.Class({
let minHeight = this._popupSize - horizontalPadding - topBorder - bottomBorder;
this._box.style = 'min-height: %dpx;'.format(Math.max(minWidth, minHeight));
},
setMonitor: function(index) {
let constraint;
if (index < 0)
index = -1;
if (this._currentMonitor == index)
return;
if (index < 0)
constraint = new Layout.MonitorConstraint({ primary: true });
else
constraint = new Layout.MonitorConstraint({ index: index });
this.actor.clear_constraints();
this.actor.add_constraint(constraint);
this._currentMonitor = index;
}
});

View File

@ -1,6 +1,7 @@
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
const Clutter = imports.gi.Clutter;
const GLib = imports.gi.GLib;
const Gtk = imports.gi.Gtk;
const Meta = imports.gi.Meta;
const Mainloop = imports.mainloop;
@ -112,9 +113,6 @@ const Overview = new Lang.Class({
// rendering options without duplicating the texture data.
let monitor = Main.layoutManager.primaryMonitor;
this._desktopFade = new St.Bin();
Main.layoutManager.overviewGroup.add_child(this._desktopFade);
let layout = new Clutter.BinLayout();
this._stack = new Clutter.Actor({ layout_manager: layout });
this._stack.add_constraint(new LayoutManager.MonitorConstraint({ primary: true }));
@ -133,6 +131,9 @@ const Overview = new Lang.Class({
Main.layoutManager.overviewGroup.add_child(this._backgroundGroup);
this._bgManagers = [];
this._desktopFade = new St.Bin();
Main.layoutManager.overviewGroup.add_child(this._desktopFade);
this._activationTime = 0;
this.visible = false; // animating to overview, in overview, animating out
@ -147,7 +148,7 @@ const Overview = new Lang.Class({
this._coverPane = new Clutter.Actor({ opacity: 0,
reactive: true });
Main.layoutManager.overviewGroup.add_child(this._coverPane);
this._coverPane.connect('event', Lang.bind(this, function (actor, event) { return true; }));
this._coverPane.connect('event', Lang.bind(this, function (actor, event) { return Clutter.EVENT_STOP; }));
this._stack.add_actor(this._overview);
Main.layoutManager.overviewGroup.add_child(this._stack);
@ -369,7 +370,7 @@ const Overview = new Lang.Class({
this._windowSwitchTimestamp);
this.hide();
this._lastHoveredWindow = null;
return false;
return GLib.SOURCE_REMOVE;
}));
}
@ -378,6 +379,7 @@ const Overview = new Lang.Class({
_onScrollEvent: function(actor, event) {
this.emit('scroll-event', event);
return Clutter.EVENT_PROPAGATE;
},
addAction: function(action) {

View File

@ -460,9 +460,6 @@ const MessagesIndicator = new Lang.Class({
if (source.trayIcon)
return;
if (source.isTransient)
return;
source.connect('count-updated', Lang.bind(this, this._updateCount));
this._sources.push(source);
this._updateCount();

View File

@ -602,14 +602,15 @@ const ActivitiesButton = new Lang.Class({
_onCapturedEvent: function(actor, event) {
if (event.type() == Clutter.EventType.BUTTON_PRESS) {
if (!Main.overview.shouldToggleByCornerOrButton())
return true;
return Clutter.EVENT_STOP;
}
return false;
return Clutter.EVENT_PROPAGATE;
},
_onButtonRelease: function() {
Main.overview.toggle();
this.menu.close();
return Clutter.EVENT_PROPAGATE;
},
_onKeyRelease: function(actor, event) {
@ -617,6 +618,7 @@ const ActivitiesButton = new Lang.Class({
if (symbol == Clutter.KEY_Return || symbol == Clutter.KEY_space) {
Main.overview.toggle();
}
return Clutter.EVENT_PROPAGATE;
},
_xdndToggleOverview: function(actor) {
@ -628,6 +630,7 @@ const ActivitiesButton = new Lang.Class({
Mainloop.source_remove(this._xdndTimeOut);
this._xdndTimeOut = 0;
return GLib.SOURCE_REMOVE;
}
});
@ -983,23 +986,23 @@ const Panel = new Lang.Class({
_onButtonPress: function(actor, event) {
if (Main.modalCount > 0)
return false;
return Clutter.EVENT_PROPAGATE;
if (event.get_source() != actor)
return false;
return Clutter.EVENT_PROPAGATE;
let button = event.get_button();
if (button != 1)
return false;
return Clutter.EVENT_PROPAGATE;
let focusWindow = global.display.focus_window;
if (!focusWindow)
return false;
return Clutter.EVENT_PROPAGATE;
let dragWindow = focusWindow.is_attached_dialog() ? focusWindow.get_transient_for()
: focusWindow;
if (!dragWindow)
return false;
return Clutter.EVENT_PROPAGATE;
let rect = dragWindow.get_outer_rect();
let [stageX, stageY] = event.get_coords();
@ -1008,7 +1011,7 @@ const Panel = new Lang.Class({
stageX > rect.x && stageX < rect.x + rect.width;
if (!allowDrag)
return false;
return Clutter.EVENT_PROPAGATE;
global.display.begin_grab_op(global.screen,
dragWindow,
@ -1020,7 +1023,7 @@ const Panel = new Lang.Class({
event.get_time(),
stageX, stageY);
return true;
return Clutter.EVENT_STOP;
},
toggleAppMenu: function() {

View File

@ -137,29 +137,30 @@ const Button = new Lang.Class({
_onButtonPress: function(actor, event) {
if (!this.menu)
return;
return Clutter.EVENT_PROPAGATE;
this.menu.toggle();
return Clutter.EVENT_PROPAGATE;
},
_onSourceKeyPress: function(actor, event) {
if (!this.menu)
return false;
return Clutter.EVENT_PROPAGATE;
let symbol = event.get_key_symbol();
if (symbol == Clutter.KEY_space || symbol == Clutter.KEY_Return) {
this.menu.toggle();
return true;
return Clutter.EVENT_STOP;
} else if (symbol == Clutter.KEY_Escape && this.menu.isOpen) {
this.menu.close();
return true;
return Clutter.EVENT_STOP;
} else if (symbol == Clutter.KEY_Down) {
if (!this.menu.isOpen)
this.menu.toggle();
this.menu.actor.navigate_focus(this.actor, Gtk.DirectionType.DOWN, false);
return true;
return Clutter.EVENT_STOP;
} else
return false;
return Clutter.EVENT_PROPAGATE;
},
_onVisibilityChanged: function() {
@ -172,7 +173,7 @@ const Button = new Lang.Class({
_onMenuKeyPress: function(actor, event) {
if (global.focus_manager.navigate_from_event(event))
return true;
return Clutter.EVENT_STOP;
let symbol = event.get_key_symbol();
if (symbol == Clutter.KEY_Left || symbol == Clutter.KEY_Right) {
@ -180,10 +181,10 @@ const Button = new Lang.Class({
if (group) {
let direction = (symbol == Clutter.KEY_Left) ? Gtk.DirectionType.LEFT : Gtk.DirectionType.RIGHT;
group.navigate_focus(this.actor, direction, false);
return true;
return Clutter.EVENT_STOP;
}
}
return false;
return Clutter.EVENT_PROPAGATE;
},
_onOpenStateChanged: function(menu, open) {

View File

@ -1,5 +1,6 @@
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
const GLib = imports.gi.GLib;
const Lang = imports.lang;
const Mainloop = imports.mainloop;
const Meta = imports.gi.Meta;
@ -110,7 +111,7 @@ const PointerWatcher = new Lang.Class({
_onTimeout: function() {
this._updatePointer();
return true;
return GLib.SOURCE_CONTINUE;
},
_updatePointer: function() {

View File

@ -126,7 +126,7 @@ const PopupBaseMenuItem = new Lang.Class({
_onButtonReleaseEvent: function (actor, event) {
this.activate(event);
return true;
return Clutter.EVENT_STOP;
},
_onKeyPressEvent: function (actor, event) {
@ -134,9 +134,9 @@ const PopupBaseMenuItem = new Lang.Class({
if (symbol == Clutter.KEY_space || symbol == Clutter.KEY_Return) {
this.activate(event);
return true;
return Clutter.EVENT_STOP;
}
return false;
return Clutter.EVENT_PROPAGATE;
},
_onKeyFocusIn: function (actor) {
@ -928,10 +928,10 @@ const PopupSubMenu = new Lang.Class({
if (this.isOpen && event.get_key_symbol() == Clutter.KEY_Left) {
this.close(BoxPointer.PopupAnimation.FULL);
this.sourceActor._delegate.setActive(true);
return true;
return Clutter.EVENT_STOP;
}
return false;
return Clutter.EVENT_PROPAGATE;
}
});
@ -1056,10 +1056,10 @@ const PopupSubMenuMenuItem = new Lang.Class({
if (symbol == Clutter.KEY_Right) {
this._setOpenState(true);
this.menu.actor.navigate_focus(null, Gtk.DirectionType.DOWN, false);
return true;
return Clutter.EVENT_STOP;
} else if (symbol == Clutter.KEY_Left && this._getOpenState()) {
this._setOpenState(false);
return true;
return Clutter.EVENT_STOP;
}
return this.parent(actor, event);
@ -1071,6 +1071,7 @@ const PopupSubMenuMenuItem = new Lang.Class({
_onButtonReleaseEvent: function(actor) {
this._setOpenState(!this._getOpenState());
return Clutter.EVENT_PROPAGATE;
}
});
@ -1102,7 +1103,7 @@ const PopupMenuManager = new Lang.Class({
if (source) {
if (!menu.blockSourceEvents)
this._grabHelper.addActor(source);
menudata.enterId = source.connect('enter-event', Lang.bind(this, function() { this._onMenuSourceEnter(menu); }));
menudata.enterId = source.connect('enter-event', Lang.bind(this, function() { return this._onMenuSourceEnter(menu); }));
menudata.focusInId = source.connect('key-focus-in', Lang.bind(this, function() { this._onMenuSourceEnter(menu); }));
}
@ -1164,13 +1165,13 @@ const PopupMenuManager = new Lang.Class({
_onMenuSourceEnter: function(menu) {
if (!this._grabHelper.grabbed)
return false;
return Clutter.EVENT_PROPAGATE;
if (this._grabHelper.isActorGrabbed(menu.actor))
return false;
return Clutter.EVENT_PROPAGATE;
this._changeMenu(menu);
return false;
return Clutter.EVENT_PROPAGATE;
},
_onMenuDestroy: function(menu) {

View File

@ -191,7 +191,9 @@ const RemoteSearchProvider = new Lang.Class({
},
createIcon: function(size, meta) {
let gicon;
let gicon = null;
let icon = null;
if (meta['icon']) {
gicon = Gio.icon_deserialize(meta['icon']);
} else if (meta['gicon']) {
@ -203,8 +205,10 @@ const RemoteSearchProvider = new Lang.Class({
bitsPerSample, width, height, rowStride);
}
return new St.Icon({ gicon: gicon,
if (gicon)
icon = new St.Icon({ gicon: gicon,
icon_size: size });
return icon;
},
filterResults: function(results, maxNumber) {

View File

@ -73,7 +73,9 @@ const RunDialog = new Lang.Class({
let label = new St.Label({ style_class: 'run-dialog-label',
text: _("Enter a Command") });
this.contentLayout.add(label, { y_align: St.Align.START });
this.contentLayout.add(label, { x_fill: false,
x_align: St.Align.START,
y_align: St.Align.START });
let entry = new St.Entry({ style_class: 'run-dialog-entry',
can_focus: true });
@ -101,6 +103,8 @@ const RunDialog = new Lang.Class({
this._errorMessage.clutter_text.line_wrap = true;
this._errorBox.add(this._errorMessage, { expand: true,
x_align: St.Align.START,
x_fill: false,
y_align: St.Align.MIDDLE,
y_fill: false });
@ -124,7 +128,7 @@ const RunDialog = new Lang.Class({
!this.pushModal())
this.close();
return true;
return Clutter.EVENT_STOP;
}
if (symbol == Clutter.Tab) {
let text = o.get_text();
@ -138,9 +142,9 @@ const RunDialog = new Lang.Class({
o.insert_text(postfix, -1);
o.set_cursor_position(text.length + postfix.length);
}
return true;
return Clutter.EVENT_STOP;
}
return false;
return Clutter.EVENT_PROPAGATE;
}));
},

View File

@ -240,10 +240,6 @@ const NotificationsBox = new Lang.Class({
},
_sourceAdded: function(tray, source, initial) {
// Ignore transient sources
if (source.isTransient)
return;
let obj = {
visible: source.policy.showInLockScreen,
detailed: source.policy.detailsInLockScreen,
@ -673,11 +669,11 @@ const ScreenShield = new Lang.Class({
// down after cancel.
if (this._lockScreenState != MessageTray.State.SHOWN)
return false;
return Clutter.EVENT_PROPAGATE;
let isEnter = (symbol == Clutter.KEY_Return || symbol == Clutter.KEY_KP_Enter);
if (!isEnter && !(GLib.unichar_isprint(unichar) || symbol == Clutter.KEY_Escape))
return false;
return Clutter.EVENT_PROPAGATE;
if (this._isLocked &&
this._ensureUnlockDialog(true, true) &&
@ -685,12 +681,12 @@ const ScreenShield = new Lang.Class({
this._dialog.addCharacter(unichar);
this._liftShield(true, 0);
return true;
return Clutter.EVENT_STOP;
},
_onLockScreenScroll: function(actor, event) {
if (this._lockScreenState != MessageTray.State.SHOWN)
return false;
return Clutter.EVENT_PROPAGATE;
let delta = 0;
if (event.get_scroll_direction() == Clutter.ScrollDirection.UP)
@ -705,7 +701,7 @@ const ScreenShield = new Lang.Class({
this._liftShield(true, 0);
}
return true;
return Clutter.EVENT_STOP;
},
_inhibitSuspend: function() {
@ -756,7 +752,7 @@ const ScreenShield = new Lang.Class({
});
}
return true;
return GLib.SOURCE_CONTINUE;
},
_onDragBegin: function() {
@ -852,7 +848,7 @@ const ScreenShield = new Lang.Class({
Lang.bind(this, function() {
this._lockTimeoutId = 0;
this.lock(false);
return false;
return GLib.SOURCE_REMOVE;
}));
}
@ -1101,7 +1097,7 @@ const ScreenShield = new Lang.Class({
global.stage.disconnect(motionId);
}
return false;
return Clutter.EVENT_PROPAGATE;
}));
this._cursorTracker.set_pointer_visible(false);
@ -1114,6 +1110,7 @@ const ScreenShield = new Lang.Class({
Mainloop.timeout_add(1000 * MANUAL_FADE_TIME, Lang.bind(this, function() {
this._activateFade(this._shortLightbox, MANUAL_FADE_TIME);
return GLib.SOURCE_REMOVE;
}));
} else {
if (params.fadeToBlack)

View File

@ -206,12 +206,12 @@ const SelectArea = new Lang.Class({
if (event.get_key_symbol() == Clutter.Escape)
this._destroy(null, false);
return;
return Clutter.EVENT_PROPAGATE;
},
_onMotionEvent: function(actor, event) {
if (this._startX == -1 || this._startY == -1)
return false;
return Clutter.EVENT_PROPAGATE;
[this._lastX, this._lastY] = event.get_coords();
let geometry = this._getGeometry();
@ -219,19 +219,19 @@ const SelectArea = new Lang.Class({
this._rubberband.set_position(geometry.x, geometry.y);
this._rubberband.set_size(geometry.width, geometry.height);
return false;
return Clutter.EVENT_PROPAGATE;
},
_onButtonPress: function(actor, event) {
[this._startX, this._startY] = event.get_coords();
this._rubberband.set_position(this._startX, this._startY);
return false;
return Clutter.EVENT_PROPAGATE;
},
_onButtonRelease: function(actor, event) {
this._destroy(this._getGeometry(), true);
return false;
return Clutter.EVENT_PROPAGATE;
},
_destroy: function(geometry, fade) {

View File

@ -1,6 +1,7 @@
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
const Gio = imports.gi.Gio;
const GLib = imports.gi.GLib;
const Mainloop = imports.mainloop;
const Meta = imports.gi.Meta;
const Shell = imports.gi.Shell;
@ -41,7 +42,7 @@ function sleep(milliseconds) {
Mainloop.timeout_add(milliseconds, function() {
if (cb)
cb();
return false;
return GLib.SOURCE_REMOVE;
});
return function(callback) {

View File

@ -120,22 +120,22 @@ function _loadMode(file, info) {
_modes[modeName] = {};
let propBlacklist = ['unlockDialog'];
for (let prop in loadedData[DEFAULT_MODE]) {
for (let prop in _modes[DEFAULT_MODE]) {
if (newMode[prop] !== undefined &&
propBlacklist.indexOf(prop) == -1)
loadedData[modeName][prop] = newMode[prop];
_modes[modeName][prop] = newMode[prop];
}
_modes[modeName]['isPrimary'] = true;
}
function _getModes() {
function _loadModes() {
FileUtils.collectFromDatadirs('modes', false, _loadMode);
}
function listModes() {
let modes = _getModes();
modes.forEach(function() {
let names = Object.getOwnPropertyNames(modes);
_loadModes();
Mainloop.idle_add(function() {
let names = Object.getOwnPropertyNames(_modes);
for (let i = 0; i < names.length; i++)
if (_modes[names[i]].isPrimary)
print(names[i]);
@ -148,6 +148,7 @@ const SessionMode = new Lang.Class({
Name: 'SessionMode',
_init: function() {
_loadModes();
let isPrimary = (_modes[global.session_mode] &&
_modes[global.session_mode].isPrimary);
let mode = isPrimary ? global.session_mode : 'user';

View File

@ -133,11 +133,16 @@ const GnomeShell = new Lang.Class({
for (let param in params)
params[param] = params[param].deep_unpack();
let monitorIndex = -1;
if (params['monitor'])
monitorIndex = params['monitor'];
let icon = null;
if (params['icon'])
icon = Gio.Icon.new_for_string(params['icon']);
Main.osdWindow.setIcon(icon);
Main.osdWindow.setMonitor (monitorIndex);
Main.osdWindow.setLabel(params['label']);
Main.osdWindow.setLevel(params['level']);

View File

@ -132,14 +132,14 @@ function _setMenuAlignment(entry, stageX) {
function _onButtonPressEvent(actor, event, entry) {
if (entry.menu.isOpen) {
entry.menu.close(BoxPointer.PopupAnimation.FULL);
return true;
return Clutter.EVENT_STOP;
} else if (event.get_button() == 3) {
let [stageX, stageY] = event.get_coords();
_setMenuAlignment(entry, stageX);
entry.menu.open(BoxPointer.PopupAnimation.FULL);
return true;
return Clutter.EVENT_STOP;
}
return false;
return Clutter.EVENT_PROPAGATE;
};
function _onPopup(actor, entry) {

View File

@ -111,12 +111,12 @@ const Slider = new Lang.Class({
},
_startDragging: function(actor, event) {
this.startDragging(event);
return this.startDragging(event);
},
startDragging: function(event) {
if (this._dragging)
return false;
return Clutter.EVENT_PROPAGATE;
this._dragging = true;
@ -129,7 +129,7 @@ const Slider = new Lang.Class({
let absX, absY;
[absX, absY] = event.get_coords();
this._moveHandle(absX, absY);
return true;
return Clutter.EVENT_STOP;
},
_endDragging: function() {
@ -143,7 +143,7 @@ const Slider = new Lang.Class({
this.emit('drag-end');
}
return true;
return Clutter.EVENT_STOP;
},
scroll: function(event) {
@ -151,7 +151,7 @@ const Slider = new Lang.Class({
let delta;
if (event.is_pointer_emulated())
return;
return Clutter.EVENT_PROPAGATE;
if (direction == Clutter.ScrollDirection.DOWN) {
delta = -SLIDER_SCROLL_STEP;
@ -168,17 +168,18 @@ const Slider = new Lang.Class({
this.actor.queue_repaint();
this.emit('value-changed', this._value);
return Clutter.EVENT_STOP;
},
_onScrollEvent: function(actor, event) {
this.scroll(event);
return this.scroll(event);
},
_motionEvent: function(actor, event) {
let absX, absY;
[absX, absY] = event.get_coords();
this._moveHandle(absX, absY);
return true;
return Clutter.EVENT_STOP;
},
onKeyPressEvent: function (actor, event) {
@ -189,9 +190,9 @@ const Slider = new Lang.Class({
this.actor.queue_repaint();
this.emit('value-changed', this._value);
this.emit('drag-end');
return true;
return Clutter.EVENT_STOP;
}
return false;
return Clutter.EVENT_PROPAGATE;
},
_moveHandle: function(absX, absY) {

View File

@ -2,6 +2,7 @@
const Clutter = imports.gi.Clutter;
const Gio = imports.gi.Gio;
const GLib = imports.gi.GLib;
const Lang = imports.lang;
const Mainloop = imports.mainloop;
const St = imports.gi.St;
@ -94,7 +95,7 @@ const ATIndicator = new Lang.Class({
this.actor.visible = alwaysShow || items.some(function(f) { return !!f.state; });
return false;
return GLib.SOURCE_REMOVE;
},
_queueSyncMenuVisibility: function() {

View File

@ -2,16 +2,26 @@
const Clutter = imports.gi.Clutter;
const GLib = imports.gi.GLib;
const GnomeBluetoothApplet = imports.gi.GnomeBluetoothApplet;
const Gio = imports.gi.Gio;
const GnomeBluetooth = imports.gi.GnomeBluetooth;
const Lang = imports.lang;
const St = imports.gi.St;
const Main = imports.ui.main;
const MessageTray = imports.ui.messageTray;
const PanelMenu = imports.ui.panelMenu;
const PopupMenu = imports.ui.popupMenu;
const BUS_NAME = 'org.gnome.SettingsDaemon.Rfkill';
const OBJECT_PATH = '/org/gnome/SettingsDaemon/Rfkill';
const RfkillManagerInterface = '<node> \
<interface name="org.gnome.SettingsDaemon.Rfkill"> \
<property name="BluetoothAirplaneMode" type="b" access="readwrite" /> \
</interface> \
</node>';
const RfkillManagerProxy = Gio.DBusProxy.makeProxyWrapper(RfkillManagerInterface);
const Indicator = new Lang.Class({
Name: 'BTIndicator',
Extends: PanelMenu.SystemIndicator,
@ -22,32 +32,63 @@ const Indicator = new Lang.Class({
this._indicator = this._addIndicator();
this._indicator.icon_name = 'bluetooth-active-symbolic';
this._proxy = new RfkillManagerProxy(Gio.DBus.session, BUS_NAME, OBJECT_PATH,
Lang.bind(this, function(proxy, error) {
if (error) {
log(error.message);
return;
}
}));
// The Bluetooth menu only appears when Bluetooth is in use,
// so just statically build it with a "Turn Off" menu item.
this._item = new PopupMenu.PopupSubMenuMenuItem(_("Bluetooth"), true);
this._item.icon.icon_name = 'bluetooth-active-symbolic';
this._item.menu.addAction(_("Turn Off"), Lang.bind(this, function() {
this._applet.killswitch_state = GnomeBluetooth.KillswitchState.SOFT_BLOCKED;
this._proxy.BluetoothAirplaneMode = true;
}));
this._item.menu.addSettingsAction(_("Bluetooth Settings"), 'gnome-bluetooth-panel.desktop');
this.menu.addMenuItem(this._item);
this._applet = new GnomeBluetoothApplet.Applet();
this._applet.connect('devices-changed', Lang.bind(this, this._sync));
this._client = new GnomeBluetooth.Client();
this._model = this._client.get_model();
this._model.connect('row-changed', Lang.bind(this, this._sync));
this._model.connect('row-deleted', Lang.bind(this, this._sync));
this._model.connect('row-inserted', Lang.bind(this, this._sync));
this._sync();
},
this._applet.connect('pincode-request', Lang.bind(this, this._pinRequest));
this._applet.connect('confirm-request', Lang.bind(this, this._confirmRequest));
this._applet.connect('auth-request', Lang.bind(this, this._authRequest));
this._applet.connect('auth-service-request', Lang.bind(this, this._authServiceRequest));
this._applet.connect('cancel-request', Lang.bind(this, this._cancelRequest));
_getDefaultAdapter: function() {
let [ret, iter] = this._model.get_iter_first();
while (ret) {
let isDefault = this._model.get_value(iter,
GnomeBluetooth.Column.DEFAULT);
if (isDefault)
return iter;
ret = this._model.iter_next(iter);
}
return null;
},
_getNConnectedDevices: function() {
let adapter = this._getDefaultAdapter();
if (!adapter)
return 0;
let nDevices = 0;
let [ret, iter] = this._model.iter_children(adapter);
while (ret) {
let isConnected = this._model.get_value(iter,
GnomeBluetooth.Column.CONNECTED);
if (isConnected)
nDevices++;
ret = this._model.iter_next(iter);
}
return nDevices;
},
_sync: function() {
let connectedDevices = this._applet.get_devices().filter(function(device) {
return device.connected;
});
let nDevices = connectedDevices.length;
let nDevices = this._getNConnectedDevices();
let on = nDevices > 0;
this._indicator.visible = on;
@ -56,204 +97,4 @@ const Indicator = new Lang.Class({
if (on)
this._item.status.text = ngettext("%d Connected Device", "%d Connected Devices", nDevices).format(nDevices);
},
_ensureSource: function() {
if (!this._source) {
this._source = new MessageTray.Source(_("Bluetooth"), 'bluetooth-active');
this._source.policy = new MessageTray.NotificationApplicationPolicy('gnome-bluetooth-panel');
Main.messageTray.add(this._source);
}
},
_authRequest: function(applet, device_path, name, long_name) {
this._ensureSource();
this._source.notify(new AuthNotification(this._source, this._applet, device_path, name, long_name));
},
_authServiceRequest: function(applet, device_path, name, long_name, uuid) {
this._ensureSource();
this._source.notify(new AuthServiceNotification(this._source, this._applet, device_path, name, long_name, uuid));
},
_confirmRequest: function(applet, device_path, name, long_name, pin) {
this._ensureSource();
this._source.notify(new ConfirmNotification(this._source, this._applet, device_path, name, long_name, pin));
},
_pinRequest: function(applet, device_path, name, long_name, numeric) {
this._ensureSource();
this._source.notify(new PinNotification(this._source, this._applet, device_path, name, long_name, numeric));
},
_cancelRequest: function() {
this._source.destroy();
}
});
const AuthNotification = new Lang.Class({
Name: 'AuthNotification',
Extends: MessageTray.Notification,
_init: function(source, applet, device_path, name, long_name) {
this.parent(source,
_("Bluetooth"),
_("Authorization request from %s").format(name),
{ customContent: true });
this.setResident(true);
this._applet = applet;
this._devicePath = device_path;
this.addBody(_("Device %s wants to pair with this computer").format(long_name));
this.addAction('allow', _("Allow"));
this.addAction('deny', _("Deny"));
this.connect('action-invoked', Lang.bind(this, function(self, action) {
if (action == 'allow')
this._applet.agent_reply_confirm(this._devicePath, true);
else
this._applet.agent_reply_confirm(this._devicePath, false);
this.destroy();
}));
}
});
const AuthServiceNotification = new Lang.Class({
Name: 'AuthServiceNotification',
Extends: MessageTray.Notification,
_init: function(source, applet, device_path, name, long_name, uuid) {
this.parent(source,
_("Bluetooth"),
_("Authorization request from %s").format(name),
{ customContent: true });
this.setResident(true);
this._applet = applet;
this._devicePath = device_path;
this.addBody(_("Device %s wants access to the service '%s'").format(long_name, uuid));
this.addAction('always-grant', _("Always grant access"));
this.addAction('grant', _("Grant this time only"));
this.addAction('reject', _("Reject"));
this.connect('action-invoked', Lang.bind(this, function(self, action) {
switch (action) {
case 'always-grant':
this._applet.agent_reply_auth_service(this._devicePath, true, true);
break;
case 'grant':
this._applet.agent_reply_auth_service(this._devicePath, true, false);
break;
case 'reject':
default:
this._applet.agent_reply_auth_service(this._devicePath, false, false);
}
this.destroy();
}));
}
});
const ConfirmNotification = new Lang.Class({
Name: 'ConfirmNotification',
Extends: MessageTray.Notification,
_init: function(source, applet, device_path, name, long_name, pin) {
this.parent(source,
_("Bluetooth"),
/* Translators: argument is the device short name */
_("Pairing confirmation for %s").format(name),
{ customContent: true });
this.setResident(true);
this._applet = applet;
this._devicePath = device_path;
this.addBody(_("Device %s wants to pair with this computer").format(long_name));
this.addBody(_("Please confirm whether the Passkey '%06d' matches the one on the device.").format(pin));
/* Translators: this is the verb, not the noun */
this.addAction('matches', _("Matches"));
this.addAction('does-not-match', _("Does not match"));
this.connect('action-invoked', Lang.bind(this, function(self, action) {
if (action == 'matches')
this._applet.agent_reply_confirm(this._devicePath, true);
else
this._applet.agent_reply_confirm(this._devicePath, false);
this.destroy();
}));
}
});
const PinNotification = new Lang.Class({
Name: 'PinNotification',
Extends: MessageTray.Notification,
_init: function(source, applet, device_path, name, long_name, numeric) {
this.parent(source,
_("Bluetooth"),
_("Pairing request for %s").format(name),
{ customContent: true });
this.setResident(true);
this._applet = applet;
this._devicePath = device_path;
this._numeric = numeric;
this.addBody(_("Device %s wants to pair with this computer").format(long_name));
this.addBody(_("Please enter the PIN mentioned on the device."));
this._entry = new St.Entry();
this._entry.connect('key-release-event', Lang.bind(this, function(entry, event) {
let key = event.get_key_symbol();
if (key == Clutter.KEY_Return) {
if (this._canActivateOkButton())
this._ok();
return true;
} else if (key == Clutter.KEY_Escape) {
this._cancel();
return true;
}
return false;
}));
this.addActor(this._entry);
let okButton = this.addAction(_("OK"), Lang.bind(this, this._ok));
this.addAction(_("Cancel"), Lang.bind(this, this._cancel));
okButton.reactive = this._canActivateOkButton();
this._entry.clutter_text.connect('text-changed', Lang.bind(this, function() {
okButton.reactive = this._canActivateOkButton();
}));
},
_ok: function() {
if (this._numeric) {
let num = parseInt(this._entry.text, 10);
if (isNaN(num)) {
// user reply was empty, or was invalid
// cancel the operation
num = -1;
}
this._applet.agent_reply_passkey(this._devicePath, num);
} else {
this._applet.agent_reply_pincode(this._devicePath, this._entry.text);
}
this.destroy();
},
_cancel: function() {
if (this._numeric)
this._applet.agent_reply_passkey(this._devicePath, -1);
else
this._applet.agent_reply_pincode(this._devicePath, null);
this.destroy();
},
_canActivateOkButton: function() {
// PINs have a fixed length of 6
if (this._numeric)
return this._entry.clutter_text.text.length == 6;
else
return true;
}
});

View File

@ -48,7 +48,7 @@ const Indicator = new Lang.Class({
this._item.actor.add(icon);
this._item.actor.add(this._slider.actor, { expand: true });
this._item.actor.connect('button-press-event', Lang.bind(this, function(actor, event) {
this._slider.startDragging(event);
return this._slider.startDragging(event);
}));
this._item.actor.connect('key-press-event', Lang.bind(this, function(actor, event) {
return this._slider.onKeyPressEvent(actor, event);

View File

@ -81,7 +81,7 @@ const AltSwitcher = new Lang.Class({
this._sync();
}
return false;
return Clutter.EVENT_PROPAGATE;
},
});

View File

@ -42,7 +42,7 @@ const StreamSlider = new Lang.Class({
this.item.actor.add(this._icon);
this.item.actor.add(this._slider.actor, { expand: true });
this.item.actor.connect('button-press-event', Lang.bind(this, function(actor, event) {
this._slider.startDragging(event);
return this._slider.startDragging(event);
}));
this.item.actor.connect('key-press-event', Lang.bind(this, function(actor, event) {
return this._slider.onKeyPressEvent(actor, event);
@ -94,7 +94,7 @@ const StreamSlider = new Lang.Class({
},
scroll: function(event) {
this._slider.scroll(event);
return this._slider.scroll(event);
},
setValue: function(value) {
@ -276,7 +276,7 @@ const VolumeMenu = new Lang.Class({
},
scroll: function(event) {
this._output.scroll(event);
return this._output.scroll(event);
},
_onControlStateChanged: function() {
@ -329,6 +329,6 @@ const Indicator = new Lang.Class({
},
_onScrollEvent: function(actor, event) {
this._volumeMenu.scroll(event);
return this._volumeMenu.scroll(event);
}
});

View File

@ -1,6 +1,7 @@
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
const Clutter = imports.gi.Clutter;
const GLib = imports.gi.GLib;
const Gtk = imports.gi.Gtk;
const Lang = imports.lang;
const Mainloop = imports.mainloop;
@ -163,6 +164,7 @@ const SwitcherPopup = new Lang.Class({
Main.osdWindow.cancel();
this.actor.opacity = 255;
this._initialDelayTimeoutId = 0;
return GLib.SOURCE_REMOVE;
}));
return true;
},
@ -192,7 +194,7 @@ const SwitcherPopup = new Lang.Class({
else
this._keyPressHandler(keysym, backwards, action);
return true;
return Clutter.EVENT_STOP;
},
_keyReleaseEvent: function(actor, event) {
@ -202,11 +204,12 @@ const SwitcherPopup = new Lang.Class({
if (state == 0)
this._finish(event.get_time());
return true;
return Clutter.EVENT_STOP;
},
_clickedOutside: function(actor, event) {
this.destroy();
return Clutter.EVENT_PROPAGATE;
},
_scrollHandler: function(direction) {
@ -218,6 +221,7 @@ const SwitcherPopup = new Lang.Class({
_scrollEvent: function(actor, event) {
this._scrollHandler(event.get_scroll_direction());
return Clutter.EVENT_PROPAGATE;
},
_itemActivatedHandler: function(n) {
@ -251,6 +255,7 @@ const SwitcherPopup = new Lang.Class({
_mouseTimedOut: function() {
this._motionTimeoutId = 0;
this.mouseActive = true;
return GLib.SOURCE_REMOVE;
},
_popModal: function() {
@ -400,6 +405,7 @@ const SwitcherList = new Lang.Class({
_onItemEnter: function (index) {
this._itemEntered(index);
return Clutter.EVENT_PROPAGATE;
},
highlight: function(index, justOutline) {

View File

@ -71,7 +71,7 @@ const UnlockDialog = new Lang.Class({
child: otherUserLabel,
reactive: true,
x_align: St.Align.START,
x_fill: true });
x_fill: false });
this._otherUserButton.connect('clicked', Lang.bind(this, this._otherUserClicked));
this._promptBox.add_child(this._otherUserButton);
} else {

View File

@ -79,9 +79,16 @@ const UserWidgetLabel = new Lang.Class({
this._userLoadedId = this._user.connect('notify::is-loaded', Lang.bind(this, this._updateUser));
this._userChangedId = this._user.connect('changed', Lang.bind(this, this._updateUser));
this._updateUser();
// We can't override the destroy vfunc because that might be called during
// object finalization, and we can't call any JS inside a GC finalize callback,
// so we use a signal, that will be disconnected by GObject the first time
// the actor is destroyed (which is guaranteed to be as part of a normal
// destroy() call from JS, possibly from some ancestor)
this.connect('destroy', Lang.bind(this, this._onDestroy));
},
vfunc_destroy: function() {
_onDestroy: function() {
if (this._userLoadedId != 0) {
this._user.disconnect(this._userLoadedId);
this._userLoadedId = 0;

View File

@ -2,6 +2,7 @@
const Clutter = imports.gi.Clutter;
const Gio = imports.gi.Gio;
const GLib = imports.gi.GLib;
const Gtk = imports.gi.Gtk;
const Mainloop = imports.mainloop;
const Meta = imports.gi.Meta;
@ -157,17 +158,14 @@ const ViewSelector = new Lang.Class({
},
show: function() {
this._activePage = this._workspacesPage;
this.reset();
this._appsPage.hide();
this._searchPage.hide();
this._workspacesDisplay.show();
this._activePage = null;
this._showPage(this._workspacesPage);
if (!this._workspacesDisplay.activeWorkspaceHasMaximizedWindows())
Main.overview.fadeOutDesktop();
this._showPage(this._workspacesPage, true);
},
zoomFromOverview: function() {
@ -189,6 +187,7 @@ const ViewSelector = new Lang.Class({
params = Params.parse(params, { a11yFocus: null });
let page = new St.Bin({ child: actor,
visible: false,
x_align: St.Align.START,
y_align: St.Align.START,
x_fill: true,
@ -203,6 +202,7 @@ const ViewSelector = new Lang.Class({
this._a11yFocusPage(page);
})
});;
page.hide();
this.actor.add_actor(page);
return page;
},
@ -212,7 +212,7 @@ const ViewSelector = new Lang.Class({
oldPage.hide();
this.emit('page-empty');
this._activePage.navigate_focus(null, Gtk.DirectionType.TAB_FORWARD, false);
this._activePage.show();
Tweener.addTween(this._activePage,
{ opacity: 255,
@ -268,7 +268,7 @@ const ViewSelector = new Lang.Class({
// Ignore events while anything but the overview has
// pushed a modal (system modals, looking glass, ...)
if (Main.modalCount > 1)
return false;
return Clutter.EVENT_PROPAGATE;
let modifiers = event.get_state();
let symbol = event.get_key_symbol();
@ -280,19 +280,11 @@ const ViewSelector = new Lang.Class({
this._showAppsButton.checked = false;
else
Main.overview.hide();
return true;
return Clutter.EVENT_STOP;
} else if (this._shouldTriggerSearch(symbol)) {
this.startSearch(event);
} else if (!this._searchActive) {
if (symbol == Clutter.Tab || symbol == Clutter.Down) {
this._activePage.navigate_focus(null, Gtk.DirectionType.TAB_FORWARD, false);
return true;
} else if (symbol == Clutter.ISO_Left_Tab) {
this._activePage.navigate_focus(null, Gtk.DirectionType.TAB_BACKWARD, false);
return true;
}
}
return false;
return Clutter.EVENT_PROPAGATE;
},
_searchCancelled: function() {
@ -408,7 +400,7 @@ const ViewSelector = new Lang.Class({
if (symbol == Clutter.Escape) {
if (this._isActivated()) {
this.reset();
return true;
return Clutter.EVENT_STOP;
}
} else if (this._searchActive) {
let arrowNext, nextDirection;
@ -422,18 +414,18 @@ const ViewSelector = new Lang.Class({
if (symbol == Clutter.Tab) {
this._searchResults.navigateFocus(Gtk.DirectionType.TAB_FORWARD);
return true;
return Clutter.EVENT_STOP;
} else if (symbol == Clutter.ISO_Left_Tab) {
this._focusTrap.can_focus = false;
this._searchResults.navigateFocus(Gtk.DirectionType.TAB_BACKWARD);
this._focusTrap.can_focus = true;
return true;
return Clutter.EVENT_STOP;
} else if (symbol == Clutter.Down) {
this._searchResults.navigateFocus(Gtk.DirectionType.DOWN);
return true;
return Clutter.EVENT_STOP;
} else if (symbol == arrowNext && this._text.position == -1) {
this._searchResults.navigateFocus(nextDirection);
return true;
return Clutter.EVENT_STOP;
} else if (symbol == Clutter.Return || symbol == Clutter.KP_Enter) {
// We can't connect to 'activate' here because search providers
// might want to do something with the modifiers in activateDefault.
@ -442,10 +434,10 @@ const ViewSelector = new Lang.Class({
this._doSearch();
}
this._searchResults.activateDefault();
return true;
return Clutter.EVENT_STOP;
}
}
return false;
return Clutter.EVENT_PROPAGATE;
},
_onCapturedEvent: function(actor, event) {
@ -460,7 +452,7 @@ const ViewSelector = new Lang.Class({
}
}
return false;
return Clutter.EVENT_PROPAGATE;
},
_doSearch: function () {
@ -470,6 +462,8 @@ const ViewSelector = new Lang.Class({
this._searchResults.setTerms(terms);
this._showPage(this._searchPage);
return GLib.SOURCE_REMOVE;
},
getActivePage: function() {

View File

@ -106,11 +106,11 @@ const DisplayChangeDialog = new Lang.Class({
/* mutter already takes care of failing at timeout */
this._timeoutId = 0;
this.close();
return false;
return GLib.SOURCE_REMOVE;
}
this._descriptionLabel.text = this._formatCountDown();
return true;
return GLib.SOURCE_CONTINUE;
},
_onFailure: function() {
@ -232,12 +232,13 @@ const WorkspaceTracker = new Lang.Class({
let windows = global.get_window_actors();
for (i = 0; i < windows.length; i++) {
let win = windows[i];
let actor = windows[i];
let win = actor.get_meta_window();
if (win.get_meta_window().is_on_all_workspaces())
if (win.is_on_all_workspaces())
continue;
let workspaceIndex = win.get_workspace();
let workspaceIndex = win.get_workspace().index();
emptyWorkspaces[workspaceIndex] = false;
}
@ -278,7 +279,7 @@ const WorkspaceTracker = new Lang.Class({
workspace._keepAliveId = Mainloop.timeout_add(duration, Lang.bind(this, function() {
workspace._keepAliveId = 0;
this._queueCheckWorkspaces();
return false;
return GLib.SOURCE_REMOVE;
}));
},
@ -290,7 +291,7 @@ const WorkspaceTracker = new Lang.Class({
workspace._lastRemovedWindow = null;
this._queueCheckWorkspaces();
}
return false;
return GLib.SOURCE_REMOVE;
}));
},
@ -975,25 +976,29 @@ const WindowManager = new Lang.Class({
wgroup.add_actor(switchData.movingWindowBin);
for (let i = 0; i < windows.length; i++) {
let window = windows[i];
let actor = windows[i];
let window = actor.get_meta_window();
if (!window.meta_window.showing_on_its_workspace())
if (!window.showing_on_its_workspace())
continue;
if (this._movingWindow && window.meta_window == this._movingWindow) {
switchData.movingWindow = { window: window,
parent: window.get_parent() };
if (window.is_on_all_workspaces())
continue;
let record = { window: actor,
parent: actor.get_parent() };
if (this._movingWindow && window == this._movingWindow) {
switchData.movingWindow = record;
switchData.windows.push(switchData.movingWindow);
window.reparent(switchData.movingWindowBin);
} else if (window.get_workspace() == from) {
switchData.windows.push({ window: window,
parent: window.get_parent() });
window.reparent(switchData.outGroup);
} else if (window.get_workspace() == to) {
switchData.windows.push({ window: window,
parent: window.get_parent() });
window.reparent(switchData.inGroup);
window.show();
actor.reparent(switchData.movingWindowBin);
} else if (window.get_workspace().index() == from) {
switchData.windows.push(record);
actor.reparent(switchData.outGroup);
} else if (window.get_workspace().index() == to) {
switchData.windows.push(record);
actor.reparent(switchData.inGroup);
actor.show();
}
}

View File

@ -1,6 +1,7 @@
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
const Clutter = imports.gi.Clutter;
const GLib = imports.gi.GLib;
const Lang = imports.lang;
const Mainloop = imports.mainloop;
const Meta = imports.gi.Meta;
@ -63,7 +64,8 @@ const WindowClone = new Lang.Class({
// the invisible border; this is inconvenient; rather than trying
// to compensate all over the place we insert a ClutterActor into
// the hierarchy that is sized to only the visible portion.
this.actor = new Clutter.Actor({ reactive: true,
this.actor = new St.Widget({ reactive: true,
can_focus: true,
x: this.origX,
y: this.origY,
width: outerRect.width,
@ -85,10 +87,10 @@ const WindowClone = new Lang.Class({
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('destroy', Lang.bind(this, this._onDestroy));
this.actor.connect('key-press-event', Lang.bind(this, this._onKeyPress));
this.actor.connect('enter-event', Lang.bind(this, this._onEnter));
this._draggable = DND.makeDraggable(this.actor,
{ restoreOnSuccess: true,
@ -197,11 +199,30 @@ const WindowClone = new Lang.Class({
this.disconnectAll();
},
_onClicked: function(action, actor) {
_activate: function() {
this._selected = true;
this.emit('selected', global.get_current_time());
},
_onKeyPress: function(actor, event) {
let symbol = event.get_key_symbol();
let isEnter = (symbol == Clutter.KEY_Return || symbol == Clutter.KEY_KP_Enter);
if (isEnter) {
this._activate();
return true;
}
return false;
},
_onEnter: function() {
this.actor.grab_key_focus();
},
_onClicked: function(action, actor) {
this._activate();
},
_onLongPress: function(action, actor, state) {
// Take advantage of the Clutter policy to consider
// a long-press canceled when the pointer movement
@ -301,6 +322,10 @@ const WindowOverlay = new Lang.Class({
Lang.bind(this, this._onEnter));
windowClone.actor.connect('leave-event',
Lang.bind(this, this._onLeave));
windowClone.actor.connect('key-focus-in',
Lang.bind(this, this._onEnter));
windowClone.actor.connect('key-focus-out',
Lang.bind(this, this._onLeave));
this._windowAddedId = 0;
@ -448,7 +473,7 @@ const WindowOverlay = new Lang.Class({
Mainloop.idle_add(Lang.bind(this,
function() {
this._windowClone.emit('selected');
return false;
return GLib.SOURCE_REMOVE;
}));
}
},
@ -512,15 +537,17 @@ const WindowOverlay = new Lang.Class({
// as the close button will be shown as needed when the overlays
// are shown again
if (this._hidden)
return;
return Clutter.EVENT_PROPAGATE;
this._animateVisible();
this.emit('show-close-button');
return Clutter.EVENT_PROPAGATE;
},
_onLeave: function() {
if (this._idleToggleCloseId == 0)
this._idleToggleCloseId = Mainloop.timeout_add(750, Lang.bind(this, this._idleToggleCloseButton));
return Clutter.EVENT_PROPAGATE;
},
_idleToggleCloseButton: function() {
@ -530,7 +557,7 @@ const WindowOverlay = new Lang.Class({
!this.closeButton.has_pointer)
this._animateInvisible();
return false;
return GLib.SOURCE_REMOVE;
},
hideCloseButton: function() {
@ -1198,18 +1225,18 @@ const Workspace = new Lang.Class({
// store current cursor position
this._cursorX = x;
this._cursorY = y;
return true;
return GLib.SOURCE_CONTINUE;
}
let actorUnderPointer = global.stage.get_actor_at_pos(Clutter.PickMode.REACTIVE, x, y);
for (let i = 0; i < this._windows.length; i++) {
if (this._windows[i].actor == actorUnderPointer)
return true;
return GLib.SOURCE_CONTINUE;
}
this._recalculateWindowPositions(WindowPositionFlags.ANIMATE);
this._repositionWindowsId = 0;
return false;
return GLib.SOURCE_REMOVE;
},
_doRemoveWindow : function(metaWin) {
@ -1284,7 +1311,7 @@ const Workspace = new Lang.Class({
metaWin.get_compositor_private() &&
metaWin.get_workspace() == this.metaWorkspace)
this._doAddWindow(metaWin);
return false;
return GLib.SOURCE_REMOVE;
}));
return;
}

View File

@ -1,6 +1,7 @@
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
const Clutter = imports.gi.Clutter;
const GLib = imports.gi.GLib;
const Lang = imports.lang;
const Mainloop = imports.mainloop;
const Meta = imports.gi.Meta;
@ -156,6 +157,7 @@ const WorkspaceSwitcherPopup = new Lang.Class({
onComplete: function() { this.destroy(); },
onCompleteScope: this
});
return GLib.SOURCE_REMOVE;
},
destroy: function() {

View File

@ -2,6 +2,7 @@
const Clutter = imports.gi.Clutter;
const Gio = imports.gi.Gio;
const GLib = imports.gi.GLib;
const Lang = imports.lang;
const Mainloop = imports.mainloop;
const Meta = imports.gi.Meta;
@ -130,7 +131,7 @@ const WindowClone = new Lang.Class({
_onButtonRelease : function (actor, event) {
this.emit('selected', event.get_time());
return true;
return Clutter.EVENT_STOP;
},
_onDragBegin : function (draggable, time) {
@ -325,7 +326,7 @@ const WorkspaceThumbnail = new Lang.Class({
metaWin.get_compositor_private() &&
metaWin.get_workspace() == this.metaWorkspace)
this._doAddWindow(metaWin);
return false;
return GLib.SOURCE_REMOVE;
}));
return;
}
@ -561,7 +562,7 @@ const ThumbnailsBox = new Lang.Class({
this._thumbnails = [];
this.actor.connect('button-press-event', function() { return true; });
this.actor.connect('button-press-event', function() { return Clutter.EVENT_STOP; });
this.actor.connect('button-release-event', Lang.bind(this, this._onButtonRelease));
Main.overview.connect('showing',
@ -606,7 +607,7 @@ const ThumbnailsBox = new Lang.Class({
}
}
return true;
return Clutter.EVENT_STOP;
},
_onDragBegin: function() {

View File

@ -30,6 +30,7 @@ const WorkspacesViewBase = new Lang.Class({
this.actor = new St.Widget({ style_class: 'workspaces-view',
reactive: true });
this.actor.connect('destroy', Lang.bind(this, this._onDestroy));
global.focus_manager.add_group(this.actor);
// The actor itself isn't a drop target, so we don't want to pick on its area
this.actor.set_size(0, 0);
@ -371,11 +372,21 @@ const ExtraWorkspaceView = new Lang.Class({
},
});
const DelegateFocusNavigator = new Lang.Class({
Name: 'DelegateFocusNavigator',
Extends: St.Widget,
vfunc_navigate_focus: function(from, direction) {
return this._delegate.navigateFocus(from, direction);
},
});
const WorkspacesDisplay = new Lang.Class({
Name: 'WorkspacesDisplay',
_init: function() {
this.actor = new St.Widget({ clip_to_allocation: true });
this.actor = new DelegateFocusNavigator({ clip_to_allocation: true });
this.actor._delegate = this;
this.actor.connect('notify::allocation', Lang.bind(this, this._updateWorkspacesActualGeometry));
this.actor.connect('parent-set', Lang.bind(this, this._parentSet));
@ -437,6 +448,10 @@ const WorkspacesDisplay = new Lang.Class({
return false;
},
navigateFocus: function(from, direction) {
return this._getPrimaryView().actor.navigate_focus(from, direction, false);
},
show: function() {
this._updateWorkspacesViews();
for (let i = 0; i < this._workspacesViews.length; i++)
@ -599,7 +614,7 @@ const WorkspacesDisplay = new Lang.Class({
_onScrollEvent: function(actor, event) {
if (!this.actor.mapped)
return false;
return Clutter.EVENT_PROPAGATE;
let activeWs = global.screen.get_active_workspace();
let ws;
switch (event.get_scroll_direction()) {
@ -610,10 +625,10 @@ const WorkspacesDisplay = new Lang.Class({
ws = activeWs.get_neighbor(Meta.MotionDirection.DOWN);
break;
default:
return false;
return Clutter.EVENT_PROPAGATE;
}
Main.wm.actionMoveWorkspace(ws);
return true;
return Clutter.EVENT_STOP;
}
});
Signals.addSignalMethods(WorkspacesDisplay.prototype);

View File

@ -62,7 +62,7 @@ const XdndHandler = new Lang.Class({
let cursorWindow = windows[windows.length - 1];
// FIXME: more reliable way?
if (!cursorWindow.is_override_redirect())
if (!cursorWindow.get_meta_window().is_override_redirect())
return;
let constraint_position = new Clutter.BindConstraint({ coordinate : Clutter.BindCoordinate.POSITION,

891
po/ar.po

File diff suppressed because it is too large Load Diff

927
po/es.po

File diff suppressed because it is too large Load Diff

121
po/et.po
View File

@ -13,8 +13,8 @@ msgstr ""
"Project-Id-Version: gnome-shell MASTER\n"
"Report-Msgid-Bugs-To: http://bugzilla.gnome.org/enter_bug.cgi?product=gnome-"
"shell&keywords=I18N+L10N&component=general\n"
"POT-Creation-Date: 2013-09-30 11:41+0000\n"
"PO-Revision-Date: 2013-10-01 16:40+0300\n"
"POT-Creation-Date: 2013-11-22 21:44+0000\n"
"PO-Revision-Date: 2013-11-18 13:56+0300\n"
"Last-Translator: Mattias Põldaru <mahfiaz@gmail.com>\n"
"Language-Team: Estonian <>\n"
"Language: et\n"
@ -218,6 +218,13 @@ msgstr "Tööalad peamisel monitoril"
msgid "Delay focus changes in mouse mode until the pointer stops moving"
msgstr "Hiire all asuv aken saab fookuse alles hiire peatumisel"
#, javascript-format
msgid "There was an error loading the preferences dialog for %s:"
msgstr "%s jaoks eelistuste dialoogi laadimisel esines viga:"
msgid "Extension"
msgstr "Laiendus"
msgid "Select an extension to configure using the combobox above."
msgstr "Vali seadistatav laiendus kasutades ülemist valikukasti."
@ -240,6 +247,7 @@ msgstr "Seansi valimine"
msgid "Not listed?"
msgstr "Pole loendis?"
#, javascript-format
msgid "(e.g., user or %s)"
msgstr "(nt 'user' või %s)"
@ -261,6 +269,7 @@ msgstr "Käsku ei leitud"
msgid "Could not parse command:"
msgstr "Käsku pole võimalik analüüsida:"
#, javascript-format
msgid "Execution of '%s' failed:"
msgstr "'%s' käivitamine nurjus:"
@ -282,9 +291,11 @@ msgstr "Eemalda lemmikutest"
msgid "Add to Favorites"
msgstr "Lisa lemmikutesse"
#, javascript-format
msgid "%s has been added to your favorites."
msgstr "%s lisati lemmikutesse."
#, javascript-format
msgid "%s has been removed from your favorites."
msgstr "%s eemaldati lemmikutest."
@ -437,6 +448,7 @@ msgstr "Väline ketas eemaldati"
msgid "Removable Devices"
msgstr "Eemaldatavad seadmed"
#, javascript-format
msgid "Open with %s"
msgstr "Ava programmiga %s"
@ -470,6 +482,7 @@ msgstr "Teenus: "
msgid "Authentication required by wireless network"
msgstr "Juhtmeta võrgu jaoks on vajalik autentimine"
#, javascript-format
msgid ""
"Passwords or encryption keys are required to access the wireless network "
"'%s'."
@ -497,6 +510,7 @@ msgstr "PIN: "
msgid "Mobile broadband network password"
msgstr "Mobiiliühenduse võrgu parool"
#, javascript-format
msgid "A password is required to connect to '%s'."
msgstr "'%s' ühenduse loomiseks on vaja parooli."
@ -552,17 +566,20 @@ msgstr "<b>%d. %B %Y</b>, <b>%H:%M</b>"
#. Translators: this is the other person changing their old IM name to their new
#. IM name. */
#, javascript-format
msgid "%s is now known as %s"
msgstr "%s nimi on nüüd %s"
#. translators: argument is a room name like
#. * room@jabber.org for example. */
#, javascript-format
msgid "Invitation to %s"
msgstr "Kutse: %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. */
#, javascript-format
msgid "%s is inviting you to join %s"
msgstr "%s kutsub sind liituma: %s"
@ -573,10 +590,12 @@ msgid "Accept"
msgstr "Nõustu"
#. translators: argument is a contact name like Alice for example. */
#, javascript-format
msgid "Video call from %s"
msgstr "%s tahab alustada videokõnet"
#. translators: argument is a contact name like Alice for example. */
#, javascript-format
msgid "Call from %s"
msgstr "%s helistab"
@ -589,10 +608,12 @@ msgstr "Vasta"
#. * file name. The string will be something
#. * like: "Alice is sending you test.ogg"
#. */
#, javascript-format
msgid "%s is sending you %s"
msgstr "%s saadab sulle %s"
#. To translators: The parameter is the contact's alias */
#, javascript-format
msgid "%s would like permission to see when you are online"
msgstr "%s palub sinu luba, et näha, kui sa oled võrgus"
@ -677,6 +698,7 @@ msgstr "Sisemine viga"
#. translators: argument is the account name, like
#. * name@jabber.org for example. */
#, javascript-format
msgid "Unable to connect to %s"
msgstr "Pole võimalik ühenduda võrguga %s"
@ -710,6 +732,7 @@ msgstr "Kuupäeva ja kella sätted"
msgid "%A %B %e, %Y"
msgstr "%A, %d. %B %Y"
#, javascript-format
msgctxt "title"
msgid "Log Out %s"
msgstr "%s väljalogimine"
@ -718,11 +741,13 @@ msgctxt "title"
msgid "Log Out"
msgstr "Väljalogimine"
#, javascript-format
msgid "%s will be logged out automatically in %d second."
msgid_plural "%s will be logged out automatically in %d seconds."
msgstr[0] "%s logitakse %d sekundi pärast automaatselt välja."
msgstr[1] "%s logitakse %d sekundi pärast automaatselt välja."
#, javascript-format
msgid "You will be logged out automatically in %d second."
msgid_plural "You will be logged out automatically in %d seconds."
msgstr[0] "Sind logitakse %d sekundi pärast automaatselt välja."
@ -736,6 +761,7 @@ msgctxt "title"
msgid "Power Off"
msgstr "Väljalülitamine"
#, javascript-format
msgid "The system will power off automatically in %d second."
msgid_plural "The system will power off automatically in %d seconds."
msgstr[0] "%d sekundi pärast lülitub süsteem automaatselt välja."
@ -753,6 +779,7 @@ msgctxt "title"
msgid "Restart"
msgstr "Taaskäivitamine"
#, javascript-format
msgid "The system will restart automatically in %d second."
msgid_plural "The system will restart automatically in %d seconds."
msgstr[0] "Süsteem taaskäivitub automaatselt %d sekundi pärast."
@ -762,6 +789,7 @@ msgctxt "title"
msgid "Restart & Install Updates"
msgstr "Taaskäivitamine ja uuenduste paigaldamine"
#, javascript-format
msgid "The system will automatically restart and install updates in %d second."
msgid_plural ""
"The system will automatically restart and install updates in %d seconds."
@ -779,16 +807,19 @@ msgid "Other users are logged in."
msgstr "Teised kasutajad on sisse logitud."
#. Translators: Remote here refers to a remote session, like a ssh login */
#, javascript-format
msgid "%s (remote)"
msgstr "%s (kaugühendus)"
#. Translators: Console here refers to a tty like a VT console */
#, javascript-format
msgid "%s (console)"
msgstr "%s (konsool)"
msgid "Install"
msgstr "Paigalda"
#, javascript-format
msgid "Download and install '%s' from extensions.gnome.org?"
msgstr "Kas laadida alla ja paigaldada '%s' aadressilt extensions.gnome.org?"
@ -799,6 +830,7 @@ msgid "No extensions installed"
msgstr "Ühtegi laiendust pole paigaldatud"
#. Translators: argument is an extension UUID. */
#, javascript-format
msgid "%s has not emitted any errors."
msgstr "%s ei ole väljastanud ühtegi veateadet."
@ -811,6 +843,8 @@ msgstr "Näita vigu"
msgid "Enabled"
msgstr "Lubatud"
#. Translators: this is for a network device that cannot be activated
#. because it's disabled by rfkill (airplane mode) */
#. translators:
#. * The device has been disabled
msgid "Disabled"
@ -837,6 +871,9 @@ msgstr "Ava"
msgid "Remove"
msgstr "Eemalda"
msgid "Notifications"
msgstr "Märguanded"
msgid "Clear Messages"
msgstr "Kustuta teated"
@ -859,6 +896,7 @@ msgctxt "program"
msgid "Unknown"
msgstr "Tundmatu"
#, javascript-format
msgid "%d new message"
msgid_plural "%d new messages"
msgstr[0] "%d uus sõnum"
@ -902,6 +940,7 @@ msgstr "Sulge"
msgid "%A, %B %d"
msgstr "%A, %d. %B"
#, javascript-format
msgid "%d new notification"
msgid_plural "%d new notifications"
msgstr[0] "%d uus märguanne"
@ -985,14 +1024,17 @@ msgstr "Lülita välja"
msgid "Bluetooth Settings"
msgstr "Bluetoothi sätted"
#, javascript-format
msgid "%d Connected Device"
msgid_plural "%d Connected Devices"
msgstr[0] "%d ühendatud seade"
msgstr[1] "%d ühendatud seadet"
#, javascript-format
msgid "Authorization request from %s"
msgstr "Autoriseerimise päring seadmelt %s"
#, javascript-format
msgid "Device %s wants to pair with this computer"
msgstr "Seade '%s' tahab selle arvutiga paarduda"
@ -1002,6 +1044,7 @@ msgstr "Luba"
msgid "Deny"
msgstr "Keela"
#, javascript-format
msgid "Device %s wants access to the service '%s'"
msgstr "Seade %s soovib ligipääsu teenusele '%s'"
@ -1015,9 +1058,11 @@ msgid "Reject"
msgstr "Lükka tagasi"
#. Translators: argument is the device short name */
#, javascript-format
msgid "Pairing confirmation for %s"
msgstr "Paardumise kinnitus seadmele %s"
#, javascript-format
msgid ""
"Please confirm whether the Passkey '%06d' matches the one on the device."
msgstr "Palun kontrolli, kas parool '%06d' kattub seadme parooliga."
@ -1029,6 +1074,7 @@ msgstr "Kattub"
msgid "Does not match"
msgstr "Ei kattu"
#, javascript-format
msgid "Pairing request for %s"
msgstr "Seadmega %s paardumise päring"
@ -1041,15 +1087,15 @@ msgstr "Olgu"
msgid "Brightness"
msgstr "Heledus"
msgid "Show Keyboard Layout"
msgstr "Klaviatuuripaigutuse kuvamine"
msgid "<unknown>"
msgstr "<tundmatu>"
msgid "Off"
msgstr "Väljas"
msgid "Network Settings"
msgstr "Võrgusätted"
#. Translators: this is for network devices that are physically present but are not
#. under NetworkManager's control (and thus cannot be used in the menu) */
msgid "unmanaged"
@ -1078,6 +1124,12 @@ msgstr "pole saadaval"
msgid "connection failed"
msgstr "ühendumine nurjus"
msgid "Mobile Broadband Settings"
msgstr "Mobiiliühenduse sätted"
msgid "Hardware Disabled"
msgstr "Riistvara on keelatud"
msgid "Wi-Fi Networks"
msgstr "Wi-Fi võrgud"
@ -1090,9 +1142,15 @@ msgstr "Võrke pole"
msgid "Select Network"
msgstr "Võrgu valimine"
msgid "Wi-Fi Settings"
msgstr "Wi-Fi sätted"
msgid "Turn On"
msgstr "Lülita sisse"
msgid "Not Connected"
msgstr "Pole ühenduses"
msgid "VPN"
msgstr "VPN"
@ -1105,9 +1163,6 @@ msgstr "Ühendus nurjus"
msgid "Activation of network connection failed"
msgstr "Võrguühenduse aktiveerimine nurjus"
msgid "Battery"
msgstr "Aku"
msgid "Power Settings"
msgstr "Toitesätted..."
@ -1117,18 +1172,29 @@ msgstr "Täiesti täis"
msgid "Estimating…"
msgstr "Andmete kogumine…"
#, javascript-format
msgid "%d%02d Remaining (%d%%)"
msgstr "%d%02d jäänud (%d%%)"
#, javascript-format
msgid "%d%02d Until Full (%d%%)"
msgstr "%d%02d täitumiseni (%d%%)"
msgid "UPS"
msgstr "UPS"
msgid "Battery"
msgstr "Aku"
msgid "Airplane Mode"
msgstr "Lennukirežiim"
msgid "On"
msgstr "Sees"
msgid "Network Settings"
msgstr "Võrgusätted"
msgid "Switch User"
msgstr "Vaheta kasutajat"
@ -1165,16 +1231,7 @@ msgstr "Rakendused"
msgid "Search"
msgstr "Otsing"
msgid ""
"Sorry, no wisdom for you today:\n"
"%s"
msgstr ""
"Vabandust, tänaseks tarkuseteri pole:\n"
"%s"
msgid "%s the Oracle says"
msgstr "Oraakel %s ütleb"
#, javascript-format
msgid "'%s' is ready"
msgstr "'%s' on valmis"
@ -1190,6 +1247,7 @@ msgstr "Taasta sätted"
msgid "Keep Changes"
msgstr "Säilita muudatused"
#, javascript-format
msgid "Settings changes will revert in %d second"
msgid_plural "Settings changes will revert in %d seconds"
msgstr[0] "Sätete muudatused ennistatakse %d sekundi pärast"
@ -1242,11 +1300,15 @@ msgstr "Parool ei saa olla tühi"
msgid "Authentication dialog was dismissed by the user"
msgstr "Kasutaja katkestas autentimisdialoogi"
#~ msgid "There was an error loading the preferences dialog for %s:"
#~ msgstr "%s jaoks eelistuste dialoogi laadimisel esines viga:"
#~ msgid ""
#~ "Sorry, no wisdom for you today:\n"
#~ "%s"
#~ msgstr ""
#~ "Vabandust, tänaseks tarkuseteri pole:\n"
#~ "%s"
#~ msgid "Extension"
#~ msgstr "Laiendus"
#~ msgid "%s the Oracle says"
#~ msgstr "Oraakel %s ütleb"
#~ msgctxt "event list time"
#~ msgid "%H\\u2236%M"
@ -1256,9 +1318,6 @@ msgstr "Kasutaja katkestas autentimisdialoogi"
#~ msgid "%l\\u2236%M\\u2009%p"
#~ msgstr "%l\\u2236%M\\u2009%p"
#~ msgid "Show Keyboard Layout"
#~ msgstr "Klaviatuuripaigutuse kuvamine"
#~ msgid "Settings Menu"
#~ msgstr "Sätete menüü"
@ -1400,9 +1459,6 @@ msgstr "Kasutaja katkestas autentimisdialoogi"
#~ msgid "Set Up a New Device…"
#~ msgstr "Uue seadme häälestamine…"
#~ msgid "hardware disabled"
#~ msgstr "riistvara on keelatud"
#~ msgid "Connection"
#~ msgstr "Ühendus"
@ -1439,9 +1495,6 @@ msgstr "Kasutaja katkestas autentimisdialoogi"
#~ msgid "Auto Ethernet"
#~ msgstr "Automaatne ethernet"
#~ msgid "Mobile broadband"
#~ msgstr "Mobiiliühendus"
#~ msgid "Auto broadband"
#~ msgstr "Automaatne lairibaühendus"
@ -1496,9 +1549,6 @@ msgstr "Kasutaja katkestas autentimisdialoogi"
#~ msgid "Laptop Battery"
#~ msgstr "Sülearvuti aku"
#~ msgid "UPS"
#~ msgstr "UPS"
#~ msgid "Monitor"
#~ msgstr "Monitor"
@ -1539,9 +1589,6 @@ msgstr "Kasutaja katkestas autentimisdialoogi"
#~ msgid "Idle"
#~ msgstr "Jõude"
#~ msgid "Notifications"
#~ msgstr "Märguanded"
#~ msgid "Your chat status will be set to busy"
#~ msgstr "Sinu vestluse olekuks määratakse hõivatud"

584
po/fi.po

File diff suppressed because it is too large Load Diff

923
po/gl.po

File diff suppressed because it is too large Load Diff

150
po/nb.po
View File

@ -8,7 +8,7 @@ msgid ""
msgstr ""
"Project-Id-Version: gnome-shell 3.11.x\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2013-11-03 16:01+0100\n"
"POT-Creation-Date: 2013-11-21 21:24+0100\n"
"PO-Revision-Date: 2013-11-03 16:03+0100\n"
"Last-Translator: Kjartan Maraas <kmaraas@gnome.org>\n"
"Language-Team: Norwegian bokmål <i18n-nb@lister.ping.uio.no>\n"
@ -299,8 +299,8 @@ msgstr "Ikke listet?"
msgid "(e.g., user or %s)"
msgstr "(f.eks. bruker eller %s)"
#: ../js/gdm/loginDialog.js:605 ../js/ui/components/networkAgent.js:259
#: ../js/ui/components/networkAgent.js:277
#: ../js/gdm/loginDialog.js:605 ../js/ui/components/networkAgent.js:261
#: ../js/ui/components/networkAgent.js:279
msgid "Username: "
msgstr "Brukernavn: "
@ -341,15 +341,15 @@ msgstr "Ofte"
msgid "All"
msgstr "Alle"
#: ../js/ui/appDisplay.js:1526
#: ../js/ui/appDisplay.js:1539
msgid "New Window"
msgstr "Nytt vindu"
#: ../js/ui/appDisplay.js:1529 ../js/ui/dash.js:284
#: ../js/ui/appDisplay.js:1542 ../js/ui/dash.js:284
msgid "Remove from Favorites"
msgstr "Fjern fra favoritter"
#: ../js/ui/appDisplay.js:1530
#: ../js/ui/appDisplay.js:1543
msgid "Add to Favorites"
msgstr "Legg til i favoritter"
@ -567,35 +567,35 @@ msgstr "Skriv på nytt:"
msgid "Connect"
msgstr "Koble til"
#: ../js/ui/components/networkAgent.js:222
#: ../js/ui/components/networkAgent.js:234
#: ../js/ui/components/networkAgent.js:261
#: ../js/ui/components/networkAgent.js:281
#: ../js/ui/components/networkAgent.js:291
#: ../js/ui/components/networkAgent.js:224
#: ../js/ui/components/networkAgent.js:236
#: ../js/ui/components/networkAgent.js:263
#: ../js/ui/components/networkAgent.js:283
#: ../js/ui/components/networkAgent.js:293
msgid "Password: "
msgstr "Passord: "
#: ../js/ui/components/networkAgent.js:227
#: ../js/ui/components/networkAgent.js:229
msgid "Key: "
msgstr "Nøkkel: "
#: ../js/ui/components/networkAgent.js:265
#: ../js/ui/components/networkAgent.js:267
msgid "Identity: "
msgstr "Identitet: "
#: ../js/ui/components/networkAgent.js:267
#: ../js/ui/components/networkAgent.js:269
msgid "Private key password: "
msgstr "Passord for privat nøkkel: "
#: ../js/ui/components/networkAgent.js:279
#: ../js/ui/components/networkAgent.js:281
msgid "Service: "
msgstr "Tjeneste: "
#: ../js/ui/components/networkAgent.js:308
#: ../js/ui/components/networkAgent.js:310
msgid "Authentication required by wireless network"
msgstr "Autentisering kreves av trådløst nettverk"
#: ../js/ui/components/networkAgent.js:309
#: ../js/ui/components/networkAgent.js:311
#, javascript-format
msgid ""
"Passwords or encryption keys are required to access the wireless network "
@ -604,35 +604,35 @@ msgstr ""
"Passord eller krypteringsnøkler kreves for å koble til trådløst nettverk "
"«%s»."
#: ../js/ui/components/networkAgent.js:313
#: ../js/ui/components/networkAgent.js:315
msgid "Wired 802.1X authentication"
msgstr "802.1X autentisering for trådbundet nettverk"
#: ../js/ui/components/networkAgent.js:315
#: ../js/ui/components/networkAgent.js:317
msgid "Network name: "
msgstr "Navn på nettverk: "
#: ../js/ui/components/networkAgent.js:320
#: ../js/ui/components/networkAgent.js:322
msgid "DSL authentication"
msgstr "DSL-autentisering"
#: ../js/ui/components/networkAgent.js:327
#: ../js/ui/components/networkAgent.js:329
msgid "PIN code required"
msgstr "PIN-kode kreves"
#: ../js/ui/components/networkAgent.js:328
#: ../js/ui/components/networkAgent.js:330
msgid "PIN code is needed for the mobile broadband device"
msgstr "PIN-kode kreves for mobil bredbåndsenhet"
#: ../js/ui/components/networkAgent.js:329
#: ../js/ui/components/networkAgent.js:331
msgid "PIN: "
msgstr "PIN: "
#: ../js/ui/components/networkAgent.js:335
#: ../js/ui/components/networkAgent.js:337
msgid "Mobile broadband network password"
msgstr "Nettverkspassord for mobilt bredbånd"
#: ../js/ui/components/networkAgent.js:336
#: ../js/ui/components/networkAgent.js:338
#, javascript-format
msgid "A password is required to connect to '%s'."
msgstr "Et passord kreves for å koble til «%s»."
@ -703,14 +703,14 @@ msgstr "<b>%d</b> <b>%B</b> <b>%Y</b>, <b>%H.%M</b> "
#. Translators: this is the other person changing their old IM name to their new
#. IM name. */
#: ../js/ui/components/telepathyClient.js:985
#: ../js/ui/components/telepathyClient.js:987
#, javascript-format
msgid "%s is now known as %s"
msgstr "%s er nå kjent som %s"
#. translators: argument is a room name like
#. * room@jabber.org for example. */
#: ../js/ui/components/telepathyClient.js:1088
#: ../js/ui/components/telepathyClient.js:1090
#, javascript-format
msgid "Invitation to %s"
msgstr "Invitasjon til %s"
@ -718,38 +718,38 @@ msgstr "Invitasjon til %s"
#. translators: first argument is the name of a contact and the second
#. * one the name of a room. "Alice is inviting you to join room@jabber.org
#. * for example. */
#: ../js/ui/components/telepathyClient.js:1096
#: ../js/ui/components/telepathyClient.js:1098
#, javascript-format
msgid "%s is inviting you to join %s"
msgstr "%s inviterer deg til å bli med i %s"
#: ../js/ui/components/telepathyClient.js:1098
#: ../js/ui/components/telepathyClient.js:1133
#: ../js/ui/components/telepathyClient.js:1167
#: ../js/ui/components/telepathyClient.js:1224
#: ../js/ui/components/telepathyClient.js:1100
#: ../js/ui/components/telepathyClient.js:1135
#: ../js/ui/components/telepathyClient.js:1169
#: ../js/ui/components/telepathyClient.js:1226
msgid "Decline"
msgstr "Avslå"
#: ../js/ui/components/telepathyClient.js:1104
#: ../js/ui/components/telepathyClient.js:1173
#: ../js/ui/components/telepathyClient.js:1229
#: ../js/ui/components/telepathyClient.js:1106
#: ../js/ui/components/telepathyClient.js:1175
#: ../js/ui/components/telepathyClient.js:1231
msgid "Accept"
msgstr "Godta"
#. translators: argument is a contact name like Alice for example. */
#: ../js/ui/components/telepathyClient.js:1123
#: ../js/ui/components/telepathyClient.js:1125
#, javascript-format
msgid "Video call from %s"
msgstr "Videosamtale fra %s"
#. translators: argument is a contact name like Alice for example. */
#: ../js/ui/components/telepathyClient.js:1126
#: ../js/ui/components/telepathyClient.js:1128
#, javascript-format
msgid "Call from %s"
msgstr "Samtale fra %s"
#. translators: this is a button label (verb), not a noun */
#: ../js/ui/components/telepathyClient.js:1140
#: ../js/ui/components/telepathyClient.js:1142
msgid "Answer"
msgstr "Svar"
@ -758,110 +758,110 @@ msgstr "Svar"
#. * file name. The string will be something
#. * like: "Alice is sending you test.ogg"
#. */
#: ../js/ui/components/telepathyClient.js:1161
#: ../js/ui/components/telepathyClient.js:1163
#, javascript-format
msgid "%s is sending you %s"
msgstr "%s sender deg %s"
#. To translators: The parameter is the contact's alias */
#: ../js/ui/components/telepathyClient.js:1190
#: ../js/ui/components/telepathyClient.js:1192
#, javascript-format
msgid "%s would like permission to see when you are online"
msgstr "%s vil ha rettigheter til å se når du er tilkoblet"
#: ../js/ui/components/telepathyClient.js:1275
#: ../js/ui/components/telepathyClient.js:1277
msgid "Network error"
msgstr "Nettverksfeil"
#: ../js/ui/components/telepathyClient.js:1277
#: ../js/ui/components/telepathyClient.js:1279
msgid "Authentication failed"
msgstr "Autentisering feilet"
#: ../js/ui/components/telepathyClient.js:1279
#: ../js/ui/components/telepathyClient.js:1281
msgid "Encryption error"
msgstr "Feil ved kryptering"
#: ../js/ui/components/telepathyClient.js:1281
#: ../js/ui/components/telepathyClient.js:1283
msgid "Certificate not provided"
msgstr "Sertifikat ikke oppgitt"
#: ../js/ui/components/telepathyClient.js:1283
#: ../js/ui/components/telepathyClient.js:1285
msgid "Certificate untrusted"
msgstr "Stoler ikke på sertifikatet"
#: ../js/ui/components/telepathyClient.js:1285
#: ../js/ui/components/telepathyClient.js:1287
msgid "Certificate expired"
msgstr "Sertifikatet er utløpt"
#: ../js/ui/components/telepathyClient.js:1287
#: ../js/ui/components/telepathyClient.js:1289
msgid "Certificate not activated"
msgstr "Sertifikatet er ikke aktivert"
#: ../js/ui/components/telepathyClient.js:1289
#: ../js/ui/components/telepathyClient.js:1291
msgid "Certificate hostname mismatch"
msgstr "Feil vertsnavn for sertifikat"
#: ../js/ui/components/telepathyClient.js:1291
#: ../js/ui/components/telepathyClient.js:1293
msgid "Certificate fingerprint mismatch"
msgstr "Feil fingeravtrykk for sertifikat"
#: ../js/ui/components/telepathyClient.js:1293
#: ../js/ui/components/telepathyClient.js:1295
msgid "Certificate self-signed"
msgstr "Sertifikatet er selvsignert"
#: ../js/ui/components/telepathyClient.js:1295
#: ../js/ui/components/telepathyClient.js:1297
msgid "Status is set to offline"
msgstr "Status er satt til frakoblet"
#: ../js/ui/components/telepathyClient.js:1297
#: ../js/ui/components/telepathyClient.js:1299
msgid "Encryption is not available"
msgstr "Kryptering er ikke tilgjengelig"
#: ../js/ui/components/telepathyClient.js:1299
#: ../js/ui/components/telepathyClient.js:1301
msgid "Certificate is invalid"
msgstr "Sertifikatet er ugyldig"
#: ../js/ui/components/telepathyClient.js:1301
#: ../js/ui/components/telepathyClient.js:1303
msgid "Connection has been refused"
msgstr "Tilkobling ble nektet"
#: ../js/ui/components/telepathyClient.js:1303
#: ../js/ui/components/telepathyClient.js:1305
msgid "Connection can't be established"
msgstr "Tilkobling kan ikke etableres"
#: ../js/ui/components/telepathyClient.js:1305
#: ../js/ui/components/telepathyClient.js:1307
msgid "Connection has been lost"
msgstr "Tilkobling tapt"
#: ../js/ui/components/telepathyClient.js:1307
#: ../js/ui/components/telepathyClient.js:1309
msgid "This account is already connected to the server"
msgstr "Denne kontoen er allerede koblet til tjeneren"
#: ../js/ui/components/telepathyClient.js:1309
#: ../js/ui/components/telepathyClient.js:1311
msgid ""
"Connection has been replaced by a new connection using the same resource"
msgstr ""
"Tilkoblingen har blitt erstattet av en ny tilkobling som bruker samme ressurs"
#: ../js/ui/components/telepathyClient.js:1311
#: ../js/ui/components/telepathyClient.js:1313
msgid "The account already exists on the server"
msgstr "Kontoen eksisterer allerede på tjeneren"
#: ../js/ui/components/telepathyClient.js:1313
#: ../js/ui/components/telepathyClient.js:1315
msgid "Server is currently too busy to handle the connection"
msgstr "Tjener er for opptatt til å håndtere tilkoblingen"
#: ../js/ui/components/telepathyClient.js:1315
#: ../js/ui/components/telepathyClient.js:1317
msgid "Certificate has been revoked"
msgstr "Sertifikatet er tilbaketrukket"
#: ../js/ui/components/telepathyClient.js:1317
#: ../js/ui/components/telepathyClient.js:1319
msgid ""
"Certificate uses an insecure cipher algorithm or is cryptographically weak"
msgstr ""
"Sertifikatet bruker en usikker sifferalgoritme eller er krytografisk svakt"
#: ../js/ui/components/telepathyClient.js:1319
#: ../js/ui/components/telepathyClient.js:1321
msgid ""
"The length of the server certificate, or the depth of the server certificate "
"chain, exceed the limits imposed by the cryptography library"
@ -869,22 +869,22 @@ msgstr ""
"Lengden eller dybden på tjenersertifikatet oversteg grensen som er satt i "
"kryptografibiblioteket"
#: ../js/ui/components/telepathyClient.js:1321
#: ../js/ui/components/telepathyClient.js:1323
msgid "Internal error"
msgstr "Intern feil"
#. translators: argument is the account name, like
#. * name@jabber.org for example. */
#: ../js/ui/components/telepathyClient.js:1331
#: ../js/ui/components/telepathyClient.js:1333
#, javascript-format
msgid "Unable to connect to %s"
msgstr "Kan ikke koble til %s"
#: ../js/ui/components/telepathyClient.js:1336
#: ../js/ui/components/telepathyClient.js:1338
msgid "View account"
msgstr "Vis konto"
#: ../js/ui/components/telepathyClient.js:1368
#: ../js/ui/components/telepathyClient.js:1370
msgid "Unknown reason"
msgstr "Ukjent årsak"
@ -1014,13 +1014,13 @@ msgid "Other users are logged in."
msgstr "Andre brukere er logget inn."
#. Translators: Remote here refers to a remote session, like a ssh login */
#: ../js/ui/endSessionDialog.js:485
#: ../js/ui/endSessionDialog.js:486
#, javascript-format
msgid "%s (remote)"
msgstr "%s (ekstern)"
#. Translators: Console here refers to a tty like a VT console */
#: ../js/ui/endSessionDialog.js:488
#: ../js/ui/endSessionDialog.js:489
#, javascript-format
msgid "%s (console)"
msgstr "%s (konsoll)"
@ -1121,11 +1121,11 @@ msgstr "Ingen meldinger"
msgid "Message Tray"
msgstr "Meldingstrau"
#: ../js/ui/messageTray.js:2929
#: ../js/ui/messageTray.js:2936
msgid "System Information"
msgstr "Systeminformasjon"
#: ../js/ui/notificationDaemon.js:539 ../src/shell-app.c:396
#: ../js/ui/notificationDaemon.js:539 ../src/shell-app.c:397
msgctxt "program"
msgid "Unknown"
msgstr "Ukjent"
@ -1141,7 +1141,7 @@ msgstr[1] "%d nye meldinger"
msgid "Undo"
msgstr "Angre"
#: ../js/ui/overview.js:125
#: ../js/ui/overview.js:122
msgid "Overview"
msgstr "Oversikt"
@ -1208,11 +1208,11 @@ msgstr "Kan ikke låse"
msgid "Lock was blocked by an application"
msgstr "Låsing ble stoppet av et program"
#: ../js/ui/search.js:592
#: ../js/ui/search.js:589
msgid "Searching…"
msgstr "Søker …"
#: ../js/ui/search.js:635
#: ../js/ui/search.js:632
msgid "No results."
msgstr "Ingen resultater."
@ -1639,7 +1639,7 @@ msgstr "Bruk spesifikt modus, f.eks «gdm» for innloggingsskjerm"
msgid "List possible modes"
msgstr "Vis mulige modi"
#: ../src/shell-app.c:639
#: ../src/shell-app.c:640
#, c-format
msgid "Failed to launch '%s'"
msgstr "Klarte ikke å starte «%s»"

1230
po/nl.po

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

896
po/tg.po

File diff suppressed because it is too large Load Diff

1094
po/tr.po

File diff suppressed because it is too large Load Diff

View File

@ -191,7 +191,7 @@ gnome_shell_CPPFLAGS = \
# Here, and after, we repeat mutter and bluetooth libraries just for the rpath
# The dependency is already pulled in by libtool
gnome_shell_LDADD = libgnome-shell.la libgnome-shell-js.la $(GNOME_SHELL_LIBS) $(MUTTER_LIBS) $(BLUETOOTH_LIBS)
gnome_shell_LDADD = libgnome-shell.la libgnome-shell-js.la $(GNOME_SHELL_LIBS) $(MUTTER_LIBS)
gnome_shell_DEPENDENCIES = libgnome-shell.la
if HAVE_MUTTER_WAYLAND
@ -205,7 +205,7 @@ gnome_shell_wayland_CPPFLAGS = \
$(MUTTER_WAYLAND_CFLAGS) \
$(gnome_shell_cflags)
gnome_shell_wayland_LDADD = libgnome-shell-wayland.la libgnome-shell-js.la $(GNOME_SHELL_LIBS) $(MUTTER_WAYLAND_LIBS) $(BLUETOOTH_LIBS)
gnome_shell_wayland_LDADD = libgnome-shell-wayland.la libgnome-shell-js.la $(GNOME_SHELL_LIBS) $(MUTTER_WAYLAND_LIBS)
gnome_shell_wayland_DEPENDENCIES = libgnome-shell-wayland.la
endif HAVE_MUTTER_WAYLAND
@ -259,7 +259,7 @@ gnome_shell_perf_helper_LDADD = $(SHELL_PERF_HELPER_LIBS)
noinst_PROGRAMS += run-js-test
run_js_test_CPPFLAGS = $(MUTTER_CFLAGS) $(gnome_shell_cflags)
run_js_test_LDADD = libgnome-shell.la $(GNOME_SHELL_JS_LIBS) $(MUTTER_LIBS) $(BLUETOOTH_LIBS)
run_js_test_LDADD = libgnome-shell.la $(GNOME_SHELL_JS_LIBS) $(MUTTER_LIBS)
run_js_test_LDFLAGS = -export-dynamic
run_js_test_SOURCES = \
@ -331,8 +331,7 @@ ShellMenu_0_1_gir_FILES = \
gtkmenutrackeritem.h \
$(NULL)
ShellMenu_0_1_gir_SCANNERFLAGS = \
--namespace=ShellMenu --identifier-prefix=Gtk \
$(if $(BLUETOOTH_DIR),-L $(BLUETOOTH_DIR),)
--namespace=ShellMenu --identifier-prefix=Gtk
INTROSPECTION_GIRS += ShellMenu-0.1.gir
CLEANFILES += ShellMenu-0.1.gir
@ -348,7 +347,7 @@ Shell_0_1_gir_FILES = $(libgnome_shell_la_gir_sources)
Shell_0_1_gir_SCANNERFLAGS = \
--include-uninstalled=$(builddir)/St-1.0.gir \
--include-uninstalled=$(builddir)/ShellMenu-0.1.gir \
--add-include-path=$(MUTTER_GIR_DIR) $(if $(BLUETOOTH_DIR),-L $(BLUETOOTH_DIR),)
--add-include-path=$(MUTTER_GIR_DIR)
INTROSPECTION_GIRS += Shell-0.1.gir
CLEANFILES += Shell-0.1.gir

View File

@ -384,17 +384,3 @@ MetaPluginInfo *gnome_shell_plugin_plugin_info (MetaPlugin *plugin)
return &info;
}
#if HAVE_BLUETOOTH
/* HACK:
Add a non-static function that calls into libgnome-bluetooth-applet.so,
to avoid the linker being too smart and removing the dependency.
This function is never actually called.
*/
extern GType bluetooth_applet_get_type(void);
void _shell_link_to_bluetooth(void);
void _shell_link_to_bluetooth(void) {
bluetooth_applet_get_type();
}
#endif

View File

@ -173,10 +173,6 @@ shell_introspection_init (void)
g_irepository_prepend_search_path (MUTTER_TYPELIB_DIR);
g_irepository_prepend_search_path (GNOME_SHELL_PKGLIBDIR);
#if HAVE_BLUETOOTH
g_irepository_prepend_search_path (BLUETOOTH_DIR);
#endif
}
static void

View File

@ -126,14 +126,6 @@ main(int argc, char **argv)
g_set_prgname (title);
g_free (title);
#if HAVE_BLUETOOTH
/* The module imports are all so intertwined that if the test
* imports anything in js/ui, it will probably eventually end up
* pulling in ui/status/bluetooth.js. So we need this.
*/
g_irepository_prepend_search_path (BLUETOOTH_DIR);
#endif
/* evaluate the script */
error = NULL;
if (!gjs_context_eval (js_context, script, len,

View File

@ -22,11 +22,6 @@ void _shell_app_add_window (ShellApp *app, MetaWindow *window);
void _shell_app_remove_window (ShellApp *app, MetaWindow *window);
void _shell_app_do_match (ShellApp *app,
GSList *terms,
GSList **prefix_results,
GSList **substring_results);
G_END_DECLS
#endif /* __SHELL_APP_PRIVATE_H__ */

View File

@ -348,143 +348,3 @@ shell_app_system_get_running (ShellAppSystem *self)
return ret;
}
static gint
compare_apps_by_usage (gconstpointer a,
gconstpointer b,
gpointer data)
{
ShellAppUsage *usage = shell_app_usage_get_default ();
ShellApp *app_a = (ShellApp*)a;
ShellApp *app_b = (ShellApp*)b;
return shell_app_usage_compare (usage, "", app_a, app_b);
}
static GSList *
sort_and_concat_results (ShellAppSystem *system,
GSList *prefix_matches,
GSList *substring_matches)
{
GSList *matches = NULL;
GSList *l;
prefix_matches = g_slist_sort_with_data (prefix_matches,
compare_apps_by_usage,
system);
substring_matches = g_slist_sort_with_data (substring_matches,
compare_apps_by_usage,
system);
for (l = substring_matches; l != NULL; l = l->next)
matches = g_slist_prepend (matches, (char *) shell_app_get_id (SHELL_APP (l->data)));
for (l = prefix_matches; l != NULL; l = l->next)
matches = g_slist_prepend (matches, (char *) shell_app_get_id (SHELL_APP (l->data)));
return g_slist_reverse (matches);
}
/**
* normalize_terms:
* @terms: (element-type utf8): Input search terms
*
* Returns: (element-type utf8) (transfer full): Unicode-normalized and lowercased terms
*/
static GSList *
normalize_terms (GSList *terms)
{
GSList *normalized_terms = NULL;
GSList *iter;
for (iter = terms; iter; iter = iter->next)
{
const char *term = iter->data;
normalized_terms = g_slist_prepend (normalized_terms,
shell_util_normalize_casefold_and_unaccent (term));
}
return normalized_terms;
}
static GSList *
search_tree (ShellAppSystem *self,
GSList *terms,
GHashTable *apps)
{
GSList *prefix_results = NULL;
GSList *substring_results = NULL;
GSList *normalized_terms;
GHashTableIter iter;
gpointer key, value;
normalized_terms = normalize_terms (terms);
g_hash_table_iter_init (&iter, apps);
while (g_hash_table_iter_next (&iter, &key, &value))
{
ShellApp *app = value;
_shell_app_do_match (app, normalized_terms,
&prefix_results,
&substring_results);
}
g_slist_free_full (normalized_terms, g_free);
return sort_and_concat_results (self, prefix_results, substring_results);
}
/**
* shell_app_system_initial_search:
* @system: A #ShellAppSystem
* @terms: (element-type utf8): List of terms, logical AND
*
* Search through applications for the given search terms.
*
* Returns: (transfer container) (element-type utf8): List of applications
*/
GSList *
shell_app_system_initial_search (ShellAppSystem *self,
GSList *terms)
{
return search_tree (self, terms, self->priv->id_to_app);
}
/**
* shell_app_system_subsearch:
* @system: A #ShellAppSystem
* @previous_results: (element-type utf8): List of previous results
* @terms: (element-type utf8): List of terms, logical AND
*
* Search through a previous result set; for more information, see
* js/ui/search.js. Note that returned strings are only valid until
* a return to the main loop.
*
* Returns: (transfer container) (element-type utf8): List of application identifiers
*/
GSList *
shell_app_system_subsearch (ShellAppSystem *system,
GSList *previous_results,
GSList *terms)
{
GSList *iter;
GSList *prefix_results = NULL;
GSList *substring_results = NULL;
GSList *normalized_terms = normalize_terms (terms);
previous_results = g_slist_reverse (previous_results);
for (iter = previous_results; iter; iter = iter->next)
{
ShellApp *app = shell_app_system_lookup_app (system, iter->data);
_shell_app_do_match (app, normalized_terms,
&prefix_results,
&substring_results);
}
g_slist_free_full (normalized_terms, g_free);
/* Note that a shorter term might have matched as a prefix, but
when extended only as a substring, so we have to redo the
sort rather than reusing the existing ordering */
return sort_and_concat_results (system, prefix_results, substring_results);
}

View File

@ -49,10 +49,4 @@ ShellApp *shell_app_system_lookup_desktop_wmclass (ShellAppSystem *s
GSList *shell_app_system_get_running (ShellAppSystem *self);
GSList *shell_app_system_initial_search (ShellAppSystem *system,
GSList *terms);
GSList *shell_app_system_subsearch (ShellAppSystem *system,
GSList *previous_results,
GSList *terms);
#endif /* __SHELL_APP_SYSTEM_H__ */

View File

@ -527,19 +527,19 @@ shell_app_usage_get_most_used (ShellAppUsage *self,
* shell_app_usage_compare:
* @self: the usage instance to request
* @context: Activity identifier
* @app_a: First app
* @app_b: Second app
* @id_a: ID of first app
* @id_b: ID of second app
*
* Compare @app_a and @app_b based on frequency of use.
* Compare @id_a and @id_b based on frequency of use.
*
* Returns: -1 if @app_a ranks higher than @app_b, 1 if @app_b ranks higher
* than @app_a, and 0 if both rank equally.
* Returns: -1 if @id_a ranks higher than @id_b, 1 if @id_b ranks higher
* than @id_a, and 0 if both rank equally.
*/
int
shell_app_usage_compare (ShellAppUsage *self,
const char *context,
ShellApp *app_a,
ShellApp *app_b)
const char *id_a,
const char *id_b)
{
GHashTable *usages;
UsageData *usage_a, *usage_b;
@ -548,8 +548,8 @@ shell_app_usage_compare (ShellAppUsage *self,
if (usages == NULL)
return 0;
usage_a = g_hash_table_lookup (usages, shell_app_get_id (app_a));
usage_b = g_hash_table_lookup (usages, shell_app_get_id (app_b));
usage_a = g_hash_table_lookup (usages, id_a);
usage_b = g_hash_table_lookup (usages, id_b);
if (usage_a == NULL && usage_b == NULL)
return 0;

View File

@ -31,8 +31,8 @@ GSList *shell_app_usage_get_most_used (ShellAppUsage *usage,
const char *context);
int shell_app_usage_compare (ShellAppUsage *self,
const char *context,
ShellApp *app_a,
ShellApp *app_b);
const char *id_a,
const char *id_b);
G_END_DECLS

View File

@ -81,12 +81,7 @@ struct _ShellApp
ShellAppRunningState *running_state;
char *window_id_string;
char *casefolded_name;
char *casefolded_generic_name;
char *name_collation_key;
char *casefolded_exec;
char **casefolded_keywords;
};
enum {
@ -735,10 +730,10 @@ shell_app_compare_windows (gconstpointer a,
* shell_app_get_windows:
* @app:
*
* Get the toplevel, interesting windows which are associated with this
* application. The returned list will be sorted first by whether
* they're on the active workspace, then by whether they're visible,
* and finally by the time the user last interacted with them.
* Get the windows which are associated with this application. The
* returned list will be sorted first by whether they're on the
* active workspace, then by whether they're visible, and finally
* by the time the user last interacted with them.
*
* Returns: (transfer none) (element-type MetaWindow): List of windows
*/
@ -1341,68 +1336,6 @@ unref_running_state (ShellAppRunningState *state)
g_slice_free (ShellAppRunningState, state);
}
static char *
trim_exec_line (const char *str)
{
const char *start, *end, *pos;
if (str == NULL)
return NULL;
end = strchr (str, ' ');
if (end == NULL)
end = str + strlen (str);
start = str;
while ((pos = strchr (start, '/')) && pos < end)
start = ++pos;
return g_strndup (start, end - start);
}
static void
shell_app_init_search_data (ShellApp *app)
{
const char *name;
const char *generic_name;
const char *exec;
const char * const *keywords;
char *normalized_exec;
name = g_app_info_get_name (G_APP_INFO (app->info));
app->casefolded_name = shell_util_normalize_casefold_and_unaccent (name);
generic_name = g_desktop_app_info_get_generic_name (app->info);
if (generic_name)
app->casefolded_generic_name = shell_util_normalize_casefold_and_unaccent (generic_name);
else
app->casefolded_generic_name = NULL;
exec = g_app_info_get_executable (G_APP_INFO (app->info));
normalized_exec = shell_util_normalize_casefold_and_unaccent (exec);
app->casefolded_exec = trim_exec_line (normalized_exec);
g_free (normalized_exec);
keywords = g_desktop_app_info_get_keywords (app->info);
if (keywords)
{
int i;
app->casefolded_keywords = g_new0 (char*, g_strv_length ((char **)keywords) + 1);
i = 0;
while (keywords[i])
{
app->casefolded_keywords[i] = shell_util_normalize_casefold_and_unaccent (keywords[i]);
++i;
}
app->casefolded_keywords[i] = NULL;
}
else
app->casefolded_keywords = NULL;
}
/**
* shell_app_compare_by_name:
* @app: One app
@ -1419,116 +1352,6 @@ shell_app_compare_by_name (ShellApp *app, ShellApp *other)
return strcmp (app->name_collation_key, other->name_collation_key);
}
static ShellAppSearchMatch
_shell_app_match_search_terms (ShellApp *app,
GSList *terms)
{
GSList *iter;
ShellAppSearchMatch match;
if (G_UNLIKELY (!app->casefolded_name))
shell_app_init_search_data (app);
match = MATCH_NONE;
for (iter = terms; iter; iter = iter->next)
{
ShellAppSearchMatch current_match;
const char *term = iter->data;
const char *p;
current_match = MATCH_NONE;
p = strstr (app->casefolded_name, term);
if (p != NULL)
{
if (p == app->casefolded_name || *(p - 1) == ' ')
current_match = MATCH_PREFIX;
else
current_match = MATCH_SUBSTRING;
}
if (app->casefolded_generic_name)
{
p = strstr (app->casefolded_generic_name, term);
if (p != NULL)
{
if (p == app->casefolded_generic_name || *(p - 1) == ' ')
current_match = MATCH_PREFIX;
else if (current_match < MATCH_PREFIX)
current_match = MATCH_SUBSTRING;
}
}
if (app->casefolded_exec)
{
p = strstr (app->casefolded_exec, term);
if (p != NULL)
{
if (p == app->casefolded_exec || *(p - 1) == '-')
current_match = MATCH_PREFIX;
else if (current_match < MATCH_PREFIX)
current_match = MATCH_SUBSTRING;
}
}
if (app->casefolded_keywords)
{
int i = 0;
while (app->casefolded_keywords[i] && current_match < MATCH_PREFIX)
{
p = strstr (app->casefolded_keywords[i], term);
if (p != NULL)
{
if (p == app->casefolded_keywords[i])
current_match = MATCH_PREFIX;
else
current_match = MATCH_SUBSTRING;
}
++i;
}
}
if (current_match == MATCH_NONE)
return current_match;
if (current_match > match)
match = current_match;
}
return match;
}
void
_shell_app_do_match (ShellApp *app,
GSList *terms,
GSList **prefix_results,
GSList **substring_results)
{
ShellAppSearchMatch match;
g_assert (app != NULL);
/* Skip window-backed apps */
if (app->info == NULL)
return;
/* Skip not-visible apps */
if (!g_app_info_should_show (G_APP_INFO (app->info)))
return;
match = _shell_app_match_search_terms (app, terms);
switch (match)
{
case MATCH_NONE:
break;
case MATCH_PREFIX:
*prefix_results = g_slist_prepend (*prefix_results, app);
break;
case MATCH_SUBSTRING:
*substring_results = g_slist_prepend (*substring_results, app);
break;
}
}
static void
shell_app_init (ShellApp *self)
{
@ -1561,11 +1384,7 @@ shell_app_finalize (GObject *object)
g_free (app->window_id_string);
g_free (app->casefolded_name);
g_free (app->casefolded_generic_name);
g_free (app->name_collation_key);
g_free (app->casefolded_exec);
g_strfreev (app->casefolded_keywords);
G_OBJECT_CLASS(shell_app_parent_class)->finalize (object);
}

View File

@ -243,20 +243,6 @@ gvalue_destroy_notify (gpointer data)
g_slice_free (GValue, value);
}
static gboolean
strv_has (gchar **haystack,
gchar *needle)
{
gchar *iter;
for (iter = *haystack; iter; iter++)
{
if (g_strcmp0 (iter, needle) == 0)
return TRUE;
}
return FALSE;
}
static void
get_secrets_keyring_cb (GObject *source,
GAsyncResult *result,
@ -267,7 +253,6 @@ get_secrets_keyring_cb (GObject *source,
ShellNetworkAgentPrivate *priv;
GError *secret_error = NULL;
GError *error = NULL;
gint n_found = 0;
GList *items;
GList *l;
GHashTable *outer;
@ -327,11 +312,6 @@ get_secrets_keyring_cb (GObject *source,
else
g_hash_table_insert (closure->vpn_entries, secret_name, g_strdup (secret_value_get (secret, NULL)));
if (closure->hints)
n_found += strv_has (closure->hints, secret_name);
else
n_found += 1;
g_hash_table_unref (attributes);
secret_value_unref (secret);
break;
@ -344,8 +324,10 @@ get_secrets_keyring_cb (GObject *source,
g_list_free_full (items, g_object_unref);
if (n_found == 0 &&
(closure->flags & NM_SECRET_AGENT_GET_SECRETS_FLAG_ALLOW_INTERACTION))
/* All VPN requests get sent to the VPN's auth dialog, since it knows better
* than the agent do about what secrets are required.
*/
if (closure->is_vpn)
{
nm_connection_update_secrets (closure->connection, closure->setting_name, closure->entries, NULL);

View File

@ -111,98 +111,6 @@ shell_util_get_transformed_allocation (ClutterActor *actor,
box->y2 = y_max;
}
char *
shell_util_normalize_and_casefold (const char *str)
{
char *normalized, *result;
if (str == NULL)
return NULL;
/* NOTE: 'ALL' is equivalent to 'NFKD'. If this is ever updated, please
* update the unaccenting mechanism as well. */
normalized = g_utf8_normalize (str, -1, G_NORMALIZE_ALL);
result = g_utf8_casefold (normalized, -1);
g_free (normalized);
return result;
}
/* Combining diacritical mark?
* Basic range: [0x0300,0x036F]
* Supplement: [0x1DC0,0x1DFF]
* For Symbols: [0x20D0,0x20FF]
* Half marks: [0xFE20,0xFE2F]
*/
#define IS_CDM_UCS4(c) (((c) >= 0x0300 && (c) <= 0x036F) || \
((c) >= 0x1DC0 && (c) <= 0x1DFF) || \
((c) >= 0x20D0 && (c) <= 0x20FF) || \
((c) >= 0xFE20 && (c) <= 0xFE2F))
/* Copied from tracker/src/libtracker-fts/tracker-parser-glib.c under the GPL
* Originally written by Aleksander Morgado <aleksander@gnu.org>
*/
char *
shell_util_normalize_casefold_and_unaccent (const char *str)
{
char *tmp;
gsize i = 0, j = 0, ilen;
if (str == NULL)
return NULL;
/* Get the NFKD-normalized and casefolded string */
tmp = shell_util_normalize_and_casefold (str);
ilen = strlen (tmp);
while (i < ilen)
{
gunichar unichar;
gchar *next_utf8;
gint utf8_len;
/* Get next character of the word as UCS4 */
unichar = g_utf8_get_char_validated (&tmp[i], -1);
/* Invalid UTF-8 character or end of original string. */
if (unichar == (gunichar) -1 ||
unichar == (gunichar) -2)
{
break;
}
/* Find next UTF-8 character */
next_utf8 = g_utf8_next_char (&tmp[i]);
utf8_len = next_utf8 - &tmp[i];
if (IS_CDM_UCS4 ((guint32) unichar))
{
/* If the given unichar is a combining diacritical mark,
* just update the original index, not the output one */
i += utf8_len;
continue;
}
/* If already found a previous combining
* diacritical mark, indexes are different so
* need to copy characters. As output and input
* buffers may overlap, need to use memmove
* instead of memcpy */
if (i != j)
{
memmove (&tmp[j], &tmp[i], utf8_len);
}
/* Update both indexes */
i += utf8_len;
j += utf8_len;
}
/* Force proper string end */
tmp[j] = '\0';
return tmp;
}
/**
* shell_util_format_date:
* @format: a strftime-style string format, as parsed by

View File

@ -19,10 +19,6 @@ void shell_util_get_transformed_allocation (ClutterActor *actor,
int shell_util_get_week_start (void);
char *shell_util_normalize_and_casefold (const char *str);
char *shell_util_normalize_casefold_and_unaccent (const char *str);
char *shell_util_format_date (const char *format,
gint64 time_ms);

View File

@ -489,9 +489,6 @@ track_window (ShellWindowTracker *self,
{
ShellApp *app;
if (!shell_window_tracker_is_window_interesting (window))
return;
app = get_app_for_window (self, window);
if (!app)
return;
@ -530,11 +527,8 @@ disassociate_window (ShellWindowTracker *self,
g_hash_table_remove (self->window_to_app, window);
if (shell_window_tracker_is_window_interesting (window))
{
_shell_app_remove_window (app, window);
g_signal_handlers_disconnect_by_func (window, G_CALLBACK(on_wm_class_changed), self);
}
g_signal_emit (self, signals[TRACKED_WINDOWS_CHANGED], 0);

View File

@ -36,10 +36,6 @@
* <listitem>
* <para>indeterminate: the widget is showing the hint text</para>
* </listitem>
* <listitem>
* <para>hover: the widget is showing the hint text and is underneath the
* pointer</para>
* </listitem>
* </itemizedlist>
*/
@ -704,13 +700,23 @@ st_entry_set_cursor (StEntry *entry,
}
static gboolean
st_entry_crossing_event (ClutterActor *actor,
st_entry_enter_event (ClutterActor *actor,
ClutterCrossingEvent *event)
{
if (event->source == ST_ENTRY (actor)->priv->entry && event->related != NULL)
st_entry_set_cursor (ST_ENTRY (actor), (event->type == CLUTTER_ENTER));
st_entry_set_cursor (ST_ENTRY (actor), TRUE);
return FALSE;
return CLUTTER_ACTOR_CLASS (st_entry_parent_class)->enter_event (actor, event);
}
static gboolean
st_entry_leave_event (ClutterActor *actor,
ClutterCrossingEvent *event)
{
if (event->source == ST_ENTRY (actor)->priv->entry && event->related != NULL)
st_entry_set_cursor (ST_ENTRY (actor), FALSE);
return CLUTTER_ACTOR_CLASS (st_entry_parent_class)->leave_event (actor, event);
}
static void
@ -745,8 +751,8 @@ st_entry_class_init (StEntryClass *klass)
actor_class->key_press_event = st_entry_key_press_event;
actor_class->key_focus_in = st_entry_key_focus_in;
actor_class->enter_event = st_entry_crossing_event;
actor_class->leave_event = st_entry_crossing_event;
actor_class->enter_event = st_entry_enter_event;
actor_class->leave_event = st_entry_leave_event;
widget_class->style_changed = st_entry_style_changed;
widget_class->navigate_focus = st_entry_navigate_focus;

View File

@ -1861,83 +1861,45 @@ filter_by_position (GList *children,
}
typedef struct {
GtkDirectionType direction;
ClutterActorBox box;
} StWidgetChildSortData;
static void
get_midpoint (ClutterActorBox *box,
int *x,
int *y)
{
*x = (box->x1 + box->x2) / 2;
*y = (box->y1 + box->y2) / 2;
}
static double
get_distance (ClutterActor *actor,
ClutterActorBox *bbox)
{
int ax, ay, bx, by, dx, dy;
ClutterActorBox abox;
ClutterVertex abs_vertices[4];
clutter_actor_get_abs_allocation_vertices (actor, abs_vertices);
clutter_actor_box_from_vertices (&abox, abs_vertices);
get_midpoint (&abox, &ax, &ay);
get_midpoint (bbox, &bx, &by);
dx = ax - bx;
dy = ay - by;
/* Not the exact distance, but good enough to sort by. */
return dx*dx + dy*dy;
}
static int
sort_by_position (gconstpointer a,
sort_by_distance (gconstpointer a,
gconstpointer b,
gpointer user_data)
{
ClutterActor *actor_a = (ClutterActor *)a;
ClutterActor *actor_b = (ClutterActor *)b;
StWidgetChildSortData *sort_data = user_data;
GtkDirectionType direction = sort_data->direction;
ClutterActorBox abox, bbox;
ClutterVertex abs_vertices[4];
int ax, ay, bx, by;
int cmp, fmid;
ClutterActorBox *box = user_data;
/* Determine the relationship, relative to motion in @direction, of
* the center points of the two actors. Eg, for %GTK_DIR_UP, we
* return a negative number if @actor_a's center is below @actor_b's
* center, and postive if vice versa, which will result in an
* overall list sorted bottom-to-top.
*/
clutter_actor_get_abs_allocation_vertices (actor_a, abs_vertices);
clutter_actor_box_from_vertices (&abox, abs_vertices);
ax = (int)(abox.x1 + abox.x2) / 2;
ay = (int)(abox.y1 + abox.y2) / 2;
clutter_actor_get_abs_allocation_vertices (actor_b, abs_vertices);
clutter_actor_box_from_vertices (&bbox, abs_vertices);
bx = (int)(bbox.x1 + bbox.x2) / 2;
by = (int)(bbox.y1 + bbox.y2) / 2;
switch (direction)
{
case GTK_DIR_UP:
cmp = by - ay;
break;
case GTK_DIR_DOWN:
cmp = ay - by;
break;
case GTK_DIR_LEFT:
cmp = bx - ax;
break;
case GTK_DIR_RIGHT:
cmp = ax - bx;
break;
default:
g_return_val_if_reached (0);
}
if (cmp)
return cmp;
/* If two actors have the same center on the axis being sorted,
* prefer the one that is closer to the center of the current focus
* actor on the other axis. Eg, for %GTK_DIR_UP, prefer whichever
* of @actor_a and @actor_b has a horizontal center closest to the
* current focus actor's horizontal center.
*
* (This matches GTK's behavior.)
*/
switch (direction)
{
case GTK_DIR_UP:
case GTK_DIR_DOWN:
fmid = (int)(sort_data->box.x1 + sort_data->box.x2) / 2;
return abs (ax - fmid) - abs (bx - fmid);
case GTK_DIR_LEFT:
case GTK_DIR_RIGHT:
fmid = (int)(sort_data->box.y1 + sort_data->box.y2) / 2;
return abs (ay - fmid) - abs (by - fmid);
default:
g_return_val_if_reached (0);
}
return get_distance (actor_a, box) - get_distance (actor_b, box);
}
static gboolean
@ -2016,7 +1978,7 @@ st_widget_real_navigate_focus (StWidget *widget,
}
else /* direction is an arrow key, not tab */
{
StWidgetChildSortData sort_data;
ClutterActorBox sort_box;
ClutterVertex abs_vertices[4];
/* Compute the allocation box of the previous focused actor. If there
@ -2032,36 +1994,35 @@ st_widget_real_navigate_focus (StWidget *widget,
if (from)
{
clutter_actor_get_abs_allocation_vertices (from, abs_vertices);
clutter_actor_box_from_vertices (&sort_data.box, abs_vertices);
clutter_actor_box_from_vertices (&sort_box, abs_vertices);
}
else
{
clutter_actor_get_abs_allocation_vertices (widget_actor, abs_vertices);
clutter_actor_box_from_vertices (&sort_data.box, abs_vertices);
clutter_actor_box_from_vertices (&sort_box, abs_vertices);
switch (direction)
{
case GTK_DIR_UP:
sort_data.box.y1 = sort_data.box.y2;
sort_box.y1 = sort_box.y2;
break;
case GTK_DIR_DOWN:
sort_data.box.y2 = sort_data.box.y1;
sort_box.y2 = sort_box.y1;
break;
case GTK_DIR_LEFT:
sort_data.box.x1 = sort_data.box.x2;
sort_box.x1 = sort_box.x2;
break;
case GTK_DIR_RIGHT:
sort_data.box.x2 = sort_data.box.x1;
sort_box.x2 = sort_box.x1;
break;
default:
g_warn_if_reached ();
}
}
sort_data.direction = direction;
if (from)
children = filter_by_position (children, &sort_data.box, direction);
children = filter_by_position (children, &sort_box, direction);
if (children)
children = g_list_sort_with_data (children, sort_by_position, &sort_data);
children = g_list_sort_with_data (children, sort_by_distance, &sort_box);
}
/* Now try each child in turn */