Compare commits

...

159 Commits

Author SHA1 Message Date
ee3cd450a5 build: Don't introspect ShellMenu
It is now only used internally by ShellApp to track remote actions,
so there's no need to expose it to javascript code.

https://gitlab.gnome.org/GNOME/gnome-shell/issues/624
2019-01-26 14:35:30 +01:00
996369a22d build: Remove remote menu support
It is now unused.

https://gitlab.gnome.org/GNOME/gnome-shell/issues/624
2019-01-26 14:35:30 +01:00
ce6ab7e121 app: Remove :menu property
It is now unused.

https://gitlab.gnome.org/GNOME/gnome-shell/issues/624
2019-01-26 14:34:59 +01:00
3da747ec2d app: Don't rely on app menu to check for GtkApplications
As the app menu is being phased out, it is no longer a good indicator
for GtkApplications. Instead, base the check directly on the appropriate
D-Bus properties.

https://gitlab.gnome.org/GNOME/gnome-shell/issues/624
2019-01-26 14:34:59 +01:00
593f15ad63 windowMenu: Remove fallback app menu support
With the app menu being phased out entirely, there's no good reason to
keep support for the fallback app menu in decorations either - the number
of applications that set an app menu and haven't embraced client-side
decorations is extremely small, and they should already have alternative
fallbacks for non-GNOME environment in place.

https://gitlab.gnome.org/GNOME/gnome-shell/issues/624
2019-01-26 14:34:59 +01:00
acdbd28262 panel: Remove the app menu
As the app menu is in the process of being retired[0], stop displaying
it in the shell - GTK+ still has a fallback path for applications that
haven't removed it yet.

[0] https://gitlab.gnome.org/GNOME/Initiatives/wikis/App-Menu-Retirement

https://gitlab.gnome.org/GNOME/gnome-shell/issues/624
2019-01-26 14:34:00 +01:00
ca70a4fc17 panel: Remove unused import
https://gitlab.gnome.org/GNOME/gnome-shell/issues/624
2019-01-26 14:32:20 +01:00
dfa0750ffd networkAgent: Advise the user to push a WPS button on their router
When connecting to a Wi-Fi router that supports the WPS button method
(PBC, push button connection) the user can simply press the button on
the router. Show an explanation in the PSK prompt when this is
possible.

https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/329
2019-01-25 15:25:26 +01:00
d80e7e0118 lookingGlass: Don't import Lang by default
With arrow functions, Function.prototype.bind() and ES6 classes, the
Lang module is rarely needed nowadays.

https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/361
2019-01-25 14:02:44 +00:00
b7e2718bdc docs: Update HACKING
We no longer use Lang.Class(), so update the guidelines accordingly.

https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/361
2019-01-25 14:02:44 +00:00
e68dfed1f7 cleanup: Port GObject classes to JS6 classes
GJS added API for defining GObject classes with ES6 class syntax
last cycle, use it to port the remaining Lang.Class classes to
the new syntax.

https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/361
2019-01-25 14:02:44 +00:00
bacfdbbb03 cleanup: Port non-GObject classes to JS6 classes
ES6 finally adds standard class syntax to the language, so we can
replace our custom Lang.Class framework with the new syntax. Any
classes that inherit from GObject will need special treatment,
so limit the port to regular javascript classes for now.

https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/361
2019-01-25 14:02:44 +00:00
99ce3deeb0 st-button: Handle touch-cancel events
Handling those events is neccessary if a touch event that pressed down a
button turns out to be a gesture. In this case the button should be
released without emitting the clicked signal.
2019-01-25 10:31:41 +00:00
d75a3484d6 windowManager: detect change to a non-existent WS
When using dynamic workspaces, it is possible to try to change to a
non-existent one if the user defines hotkeys for changing to desktop
1, 2, 3... This case is not detected, and gnome shell shows an error:

JS ERROR: TypeError: workspace is null
actionMoveWorkspace@resource:///org/gnome/shell/ui/windowManager.js:2130:13
wrapper@resource:///org/gnome/gjs/modules/_legacy.js:82:22
_showWorkspaceSwitcher@resource:///org/gnome/shell/ui/windowManager.js:2104:13
wrapper@resource:///org/gnome/gjs/modules/_legacy.js:82:22

This patch adds a check before trying to change the workspace, to avoid
switching to a non-existent one.

https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/365
2019-01-24 23:59:23 +01:00
3dcb593a71 texture-cache: Simplify function with g_autoptr
st_texture_cache_reset_texture() is slightly easier to
read and follow by using g_autoptr, so use that.
2019-01-24 16:23:58 -02:00
1847a4f4cc texture-cache: Avoid creating unnecessary ClutterImages
After loading the GdkPixbuf, StTextureCache unconditionally
creates a ClutterImage and, if it's not in the cache, add
it to the cache. That's a waste of resources when the image
is already committed to the texture cache.

Fix that by reusing the ClutterImage of the cache if it is
already there; otherwise, create a new ClutterImage as we
were previously doing.
2019-01-24 16:23:58 -02:00
deec0bf255 texture-cache: Replace ClutterTexture by ClutterImage
ClutterTexture is a deprecated class that is simultaneously
an actor, and the content of the actor. Clutter's new model
is to separate painting (via ClutterContent) from actors.

Currently, StTextureCache relies on ClutterTexture to store
the loaded textures. This not only does not match the latest
practices of Clutter, but also generates various compile-time
warnings.

Port StTextureCache to store ClutterImages instead of storing
ClutterTextures. ClutterImage exposes the internal CoglTexture,
so no helpers are needed to match the current StTextureCache
API. Aspect ratio was dropped, but from my testing, it doesn't
change anything.
2019-01-24 16:23:58 -02:00
8bb9eb0fc9 keyboard: Disconnect from input source manager when destroying indicator
When an InputSourceIndicator is destroyed, the InputSourceManager it was
connected to could (and probably will) outlive it (since the manager is
a singleton). If the InputSourceManager emits any subsequent signals,
the callbacks from the finalised InputSourceIndicator could be invoked,
and will reference finalised objects.

This can be triggered by running `pkexec true` from a gnome-terminal
window, then calling `pkill pkexec` from another terminal (on a
different VT or via SSH). This causes the dialogue to be cancelled by
polkitd.

Signed-off-by: Philip Withnall <withnall@endlessm.com>

https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/357
2019-01-24 14:48:48 +00:00
21de3c327b polkitAgent: Disconnect from user signals when closing dialogue
Otherwise the user object could outlive the dialogue, emit a subsequent
signal, and the callback from that signal could reference finalised
objects/widgets from the dialogue. The likely mechanism for the user
outliving the dialogue is caching of user objects within
libaccountsservice.

This can be triggered by running `pkexec true` from a gnome-terminal
window, then calling `pkill pkexec` from another terminal (on a
different VT or via SSH). This causes the dialogue to be cancelled by
polkitd.

Signed-off-by: Philip Withnall <withnall@endlessm.com>

https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/357
2019-01-24 14:48:48 +00:00
081d94e0f6 polkitAgent: Destroy session from dialogue closed handler
Rather than explicitly destroying the session after calling close(),
destroy it from the `closed` signal handler.

This also means we can make the method internal.

Signed-off-by: Philip Withnall <withnall@endlessm.com>

https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/357
2019-01-24 14:48:48 +00:00
ddd1825162 polkitAgent: Drop close() override in favour of closed signal
In case there are any internal ways the dialogue can close itself
without calling its own close() method, it’s probably better to do all
our cleanup on a handler for the `closed` signal instead.

This should introduce no functional changes except ensuring the
polkitAgent cleanup is always done.

Signed-off-by: Philip Withnall <withnall@endlessm.com>

https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/357
2019-01-24 14:48:48 +00:00
5f223e0bd8 polkitAgent: Disconnect session signal handlers when destroying session
Otherwise the session could outlive the dialogue, emit a subsequent
signal, and its callback would reference finalised objects/widgets from
the dialogue. The PolkitSession object is implemented by
libpolkit-gobject, so we have no guarantees about its reference counting
— the session object could keep itself alive in another thread, or be a
singleton. In all likelihood, the session hangs around for longer than
the dialogue due to differences in when the two objects are garbage
collected.

This can be triggered by running `pkexec true` from a gnome-terminal
window, then calling `pkill pkexec` from another terminal (on a
different VT or via SSH). This causes the dialogue to be cancelled by
polkitd.

Signed-off-by: Philip Withnall <withnall@endlessm.com>

https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/357
2019-01-24 14:48:48 +00:00
809d92129b search: Initialise searchInProgress when search providers are registered
This avoids the following warning sometimes happening later:

JS WARNING: [resource:///org/gnome/shell/ui/search.js 701]: reference to undefined property "searchInProgress"

Signed-off-by: Philip Withnall <withnall@endlessm.com>

https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/357
2019-01-24 14:48:48 +00:00
8840608a25 Update Catalan translation 2019-01-24 11:31:05 +01:00
edbb204332 animation: Disable spinner animations when actor is destroyed
There's nothing to animate anymore, just a source for warnings when
trying to access a destroyed object.

https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/362
2019-01-24 00:20:58 +01:00
9dc3b73ef9 calendar: Rename "Clear All" button
While it hasn't really cleared everything previously (media notifications),
it does less so now. Update the button label to reflect that.

https://gitlab.gnome.org/GNOME/gnome-shell/issues/262
2019-01-22 21:35:52 +00:00
a7d618915c calendar: Remove ability to hide events
The functionality is no longer exposed, so remove it altogether.

https://gitlab.gnome.org/GNOME/gnome-shell/issues/262
2019-01-22 21:35:52 +00:00
3e3da8e2f8 calendar: Don't allow event messages to be closed
The built-in calendar isn't meant to replace a full-fledged calendar
app, which is why clearing event messages only hides the event in
gnome-shell rather than deleting the actual event. This has turned out
to not be overly useful and often confusing - it creates a discrepancy
with visible events in apps, isn't revertible in a non-obscure fashion
and non-obviously limited to the current date.

As we are considering moving events out of the message list and back to
the calendar, it looks like a good time to remove that ability and keep
notifications as the only removable messages.

https://gitlab.gnome.org/GNOME/gnome-shell/issues/262
2019-01-22 21:35:52 +00:00
a6763e7731 messageTray: Chain up in NotificationPolicy constructor
We currently deliberately avoid chaining up in derived policy
constructors to not override properties with their defaults.
That's a neat trick that will stop working when porting to ES6
classes, as chaining up is necessary to actually initialize the
object there (including "this").

Address this by turning all properties into (overridable) getters
that are backed by private properties by default.

https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/350
2019-01-22 21:33:46 +00:00
8f15193b40 messageTray: Split out policy creation
The _createPolicy() method of a subclass usually depends on some
constructor parameters that need to be set before chaining up to
the parent. This works fine with Lang.Class, but will break with
ES6 classes, as "this" is only initialized after chaining up.

Prepare for this by not creating the policy in the constructor,
but when it is first accessed.

https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/350
2019-01-22 21:33:46 +00:00
467b7c1bca lookingGlass: Stop using eval()
Its use is not only strongly discouraged[0], we also rely on it injecting
variables into the global scope to get command-line-like behavior. That
behavior is incompatible with strict mode[1], and in extension with ES6
classes (which imply strict mode).

So to prepare for porting to ES6 classes, replace it with a somewhat less
evil construct that is compatible with strict mode.

[0] https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/eval#Do_not_ever_use_eval!
[1]
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Strict_mode#Simplifying_variable_uses

https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/350
2019-01-22 21:33:46 +00:00
97963a1ca8 docs: Remove obsolete Lang references
https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/350
2019-01-22 21:33:46 +00:00
2fc1f1adbe cleanup: Remove obsolete Lang imports
https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/350
2019-01-22 21:33:46 +00:00
200f4908d5 Update Afrikaans translation 2019-01-20 23:04:31 +00:00
1f864c905d thunderbolt: only try to enroll if we are allowed
Check via Polkit if the current user is actually allowed to enroll
devices before trying to do so. If not, show a notification that
explains that a system administrator needs to authorize the device.
Clicking on the notification will guide the user to the thunderbolt
control center panel. Before this patch, when the current user was
not allowed to enroll a device a polkit dialog would pop up which
is confusing because it did not contain any information why it was
shown. This patch implements the behavior as designed (see [1],
section "Multi-user environments").

[1] https://wiki.gnome.org/Design/Whiteboards/ThunderboltAccess
2019-01-18 22:10:23 +01:00
df77fb6793 media section: Change size of the fallback cover
Fallback cover used to be larger than the non-fallback one,
making the media controls look inconsistent.
2019-01-18 21:36:10 +03:00
3fa3889fa5 Update French translation
(cherry picked from commit ee97f73521)
2019-01-17 16:58:43 +00:00
4b28b90e0f notificationDaemon.js: Fix a typo (missing ')')
Introduced in e0a992af73 it was preventing gnome-shell from starting.

https://gitlab.gnome.org/GNOME/gnome-shell/issues/915
2019-01-17 11:55:04 +08:00
e0a992af73 notificationDaemon: Fix warning
Since commit 33b8537bf5, we unconditionally access the 'image-path'
hint, resulting in a gjs warning if the hint is not defined.

https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/309
2019-01-16 18:57:04 +01:00
7c4e43c84f Remove deprecated CoglHandle
Prefer something a bit more type-safe instead and in the meantime use
the newly available `cogl_clear_object` to simplify some code a bit.
2019-01-16 17:54:29 +00:00
b57832716a calendar: Disconnect signals when resetting notification
Since commit 5fb8d4f730, a NotificationMessage's notification property
is reset to null when the notification is destroyed. However at that
point we still have connected signal handlers around that we'll try
to disconnect later.

Avoid the warnings by disconnecting and resetting the handler IDs at
the same time as the notification.

https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/308
2019-01-16 17:46:09 +00:00
945a019974 animation: Optionally animate spinner start/stop
In contrast to generic animated icons, it is reasonable to expect
spinners to be invisible while inactive. Implement that behavior
in the new Spinner class and optionally animate the transitions.

https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/316
2019-01-16 17:44:42 +00:00
22e21ad7d1 animation: Add dedicated Spinner class
We use AnimatedIcon with the same resource all over the place, cut
down on the duplication by providing a dedicated class.

https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/316
2019-01-16 17:44:42 +00:00
ae48f8bda9 inputMethod: Delete the enabled member since it's not used
When `ibus restart` runs, InputMethod.enabled is changed to false
and no longer enable ibus but 'enabled' and 'disabled' signals
are not used in the current IBus clients and it's good to delete
the member simply.

https://gitlab.gnome.org/GNOME/gnome-shell/issues/295
2019-01-16 17:33:58 +00:00
62abf3edc7 audioDeviceSelection: Only include settings button when allowed
https://gitlab.gnome.org/GNOME/gnome-shell/issues/909
2019-01-16 00:30:46 +00:00
f8ce47c24d keyboard: Use addSettingsItem() in language menu
If the session mode doesn't allow access to Settings, the language
menu should respect that and not expose the "Region & Languages"
panel. Using the dedicated method instead of manually constructing
the menu item takes care of that and makes for less code.

https://gitlab.gnome.org/GNOME/gnome-shell/issues/780
2019-01-16 00:29:23 +00:00
ddb3a5c625 Add Iagno to appFavorites 2019-01-15 15:31:13 +00:00
c6d2bc4c57 Update Esperanto translation 2019-01-14 21:48:02 +00:00
e3a0b6d4ee Updated Spanish translation 2019-01-14 15:43:41 +01:00
e5a0dcb47e Bump version to 3.31.4
Update NEWS.
2019-01-10 20:38:43 +01:00
3989cad3db build: Remove Canberra dependency
It is no longer direct, but rather through mutter API.

https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/327
2019-01-09 23:09:18 +00:00
2a1f915f9d global: Drop API to play sounds
All callers have been updated to use MetaSoundPlayer. This drops direct
usage of libcanberra-gtk, and the X11 connection indirectly. One thing
worth noting is that we pass less metadata (eg. event x/y that might be
used for surrounding effects). This was all largely unused, so the
MetaSoundPlayer was made simpler.

https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/327
2019-01-09 23:09:18 +00:00
a6002652d0 volume: Port to MetaSoundPlayer for emitting sounds
Move away from ShellGlobal API, which is too tightly coupled to
libcanberra-gtk.

https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/327
2019-01-09 23:09:18 +00:00
25bfe99ed5 messageTray: Port to MetaSoundPlayer for emitting sounds
Move away from ShellGlobal API, which is too tightly coupled to
libcanberra-gtk. The app ID/name seem unused in canberra, so we
may simplify this to a single case.

https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/327
2019-01-09 23:09:18 +00:00
9a35c9902a automountManager: Port to MetaSoundPlayer for emitting sounds
Move away from ShellGlobal API, which is too tightly coupled to
libcanberra-gtk.

https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/327
2019-01-09 23:09:18 +00:00
4259676f6e dnd: Repick target actor if destroyed mid iteration
The picked target actor may be destroyed (e.g. hover style change
resulting in the ClutterTexture to be destroyed). If we don't handle
this, GJS will abort when it sees the exception caused by Javascript
code trying to access the destroyed target actor.

To handle it, listen on the 'destroy' signal on the target actor, and
repick, so a valid actor is passed to the next motion callback.

Fixes: https://gitlab.gnome.org/GNOME/gnome-shell/issues/632
2019-01-09 16:15:59 +00:00
2159d6886f layout: Always allow hiding the overview
When a fullscreen application is focused,
toggling the overview via hot-corner is disabled,
even when the overview is currently visible.
This only makes sense, when the overview is
hidden to not to disturb the behaviour of the
fullscreen application, but leaves an
inconsistency when the overview is visible since
it should work there like when a non-fullscreen-
application is focused.

So, always allow hiding the overview using the
hot corner when the overview is visible.

https://gitlab.gnome.org/GNOME/gnome-shell/issues/429
2019-01-09 15:47:38 +00:00
ca4e563f55 introspect: Add GetWindows method
The `GetWindows` method gives access to the list of windows for each
application with some of their properties, so utilities such as dogtail
can pick the window of their choice to interfere with using the provided
window id.

https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/326
2019-01-09 10:13:45 +01:00
8be0c5a58a Add app introspection API
Add a D-Bus API that allows the API user to introspect the application
state of the shell. Currently the only exposed information is list of
running applications and which one is active (i.e. has focus).

https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/326
2019-01-09 10:13:45 +01:00
5edceba588 Update Japanese translation 2019-01-03 07:25:23 +00:00
49133c7245 Remove the browser plugin
The browser plugin is crashy and broken; there are dozens of bugs filed
against it on Bugzilla and nobody is looking at them. Chrome and Firefox
have both dropped support for NPAPI plugins. Epiphany still has support,
but it's hidden behind a gsetting and all the UI to enable it has been
removed, so very few users would be able to figure out how to enable.
I've even previously considered blacklisting this plugin in the past due
to all the crashes.

Since this plugin has not actually worked in any browsers for a long
time now, time to delete it.

https://bugzilla.gnome.org/show_bug.cgi?id=766776
2018-12-31 13:25:05 -06:00
c1c00a8c1d Update Swedish translation 2018-12-28 13:43:24 +00:00
d3bf1a9ee7 Update Turkish translation 2018-12-25 16:47:26 +00:00
f43f9557e4 Update Friulian translation 2018-12-24 18:05:47 +00:00
a92ad59595 Replace Bugzilla by Gitlab URL in DOAP file 2018-12-15 23:26:54 +01:00
616852cf2b thunderbolt: fix missing variable underscore for enrolling
The variable `this.enrolling` is a typo because it has not been defined
before and is also never used.
`this._enrolling` is what it was meant to be.
2018-12-07 11:19:57 +00:00
e5ce3d541e messageTray: Re-enable unredirection when banner is destroyed
The intention of commit 4dc20398 was to disable unredirection while
banners are shown, but the ::done-displaying signal currently used for
re-enabling unredirection is only emitted under some circumstances, so
it's possible that unredirection is left disabled indefinitely, whoops.

Fix this by tying disabling unredirection explicitly to the lifetime
of the banner actor.

https://gitlab.gnome.org/GNOME/gnome-shell/issues/799
2018-12-05 18:11:39 +00:00
925a25da17 st: Avoid integer overflow on unpremultiply
When computing the effective border color, we operate on colors with
premultiplied alpha to simplify the calculations, then unpremultiply
the result. However we miss a bounds check in the last check, so any
color component can overflow the allowed maximum of 0xff and shift the
result in unexpected ways.

https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/305
2018-12-04 15:55:39 +00:00
6743c18fdf StWidget: don't forget to invalidate the paint state if not on stage
If the actor is not on the stage yet (i.e. does not have a theme
node), but has a paint state cached, we currently fail to invalidate
it, which will lead to the actor painting with old contents once it
gets onto the stage.

This commit fixes the issue by changing our invalidation strategy;
previously we were looking at the widget's own theme node to determine
if it should be invalidated or not.
Now we look at the theme nodes of our cached paint states. When the
widget is mapped on stage, those are the same as the widget's own
theme node, but when the widget is not on the stage, we'll still be
able to invalidate them.

As part of this, we move the invalidation API to StThemeNodePaintState,
which is a more natural place for our use case.

https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/314
2018-12-04 15:52:36 +00:00
4d649d6ee8 Updated Spanish translation 2018-12-04 16:39:42 +01:00
121c427438 Updated Slovenian translation 2018-12-02 18:06:02 +01:00
25fbffc454 Update Esperanto translation 2018-11-28 09:05:52 +00:00
0e0574a0b4 iconGrid: Eliminate JavaScript for painting/picking
The only reason for `vfunc_paint` and `vfunc_pick` existing was to
implement a culling optimization. Although that optimization actually
made performance worse than none at all because it forced the painting
and picking cycles to spend more time calling into JavaScript.

Turns out we don't have to choose between native code and culling though.
Just reimplement the culling using native ClutterActor functions and we
get the benefits of both.

Performance on an i7-7700:

Moving the cursor over the icon grid:
Before: 70% CPU, 5.5ms per frame
After : 60% CPU, 4.5ms per frame

Scrolling the icon grid:
Before: 60% CPU, 4.4ms per frame
After : 50% CPU, 3.3ms per frame

Helps with https://gitlab.gnome.org/GNOME/gnome-shell/issues/174
2018-11-27 13:25:37 +00:00
4c11d15a07 st-button: Ignore pointer emulated touch events
In X11, pointer emulated touch events are replicated with normal PRESS, RELEASE
pair events which are generated by the server. Thus for a single tap we get:
 - TOUCH_BEGIN -> TOUCH_END, PRESS -> RELEASE

This will cause st-button to send two "clicked" signals, instead of just one,
breaking extensions (like dash-to-dock) that show buttons in the main stage
which will be checked two times or that will receive the same signal two times.
2018-11-26 21:18:25 +00:00
3217c10ff2 theme: Replace calendar arrow images with symbolic icons and CSS
https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/301
2018-11-26 15:34:08 +00:00
264050742b meson.build: Bump compatible mutter API version to 4 2018-11-23 14:46:51 +01:00
cdb8ac3a2f shell: Hide/drop unused public API
These static methods won't work as-is as MetaStartupSequence API in
JS bindings. Luckily those are used nowhere there.
2018-11-23 13:58:35 +01:00
10b3671a99 shell: Use MetaStartupNotification
This is "API compatible" with ShellStartupNotification, so only
C changes are necessary.
2018-11-23 13:58:35 +01:00
4d2dce2c52 theme: Drop custom assets for window close buttons in overview
They can be replaced by a themed icon and some CSS styling.

https://gitlab.gnome.org/GNOME/gnome-shell/issues/782
2018-11-22 23:50:24 +01:00
27c660d2a9 theme: Replace page indicator assets with css
https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/297
2018-11-22 19:28:14 +01:00
8e7c90b930 theme: Replace corner ripple png assets with css
https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/298
2018-11-22 19:23:24 +01:00
ff2fbf5ae4 dash: destroy items's child before tooltip
Destroy the DashItemContainer's child from the same handler as the tooltip. This
will prevent invalid reads when the item is destroyed while its quicklist is
still open.

Fixes: https://gitlab.gnome.org/GNOME/gnome-shell/issues/781
2018-11-19 15:51:32 +00:00
e77463b875 altSwitcher: Fix error when all alternatives are disabled
While we do consider the case that we don't have a child to show for the
visibility, we are still trying to move the click action unconditionally.

https://gitlab.gnome.org/GNOME/gnome-shell/issues/783
2018-11-17 12:18:23 +00:00
74bb9e6249 ibusManager: Don't pass undefined callback to ibus
Since commit 551e827841, we don't always pass a callback parameter.
However passing it on as undefined to ibus doesn't work, as gjs doesn't
accept that as a valid callback value and throw an error. As a result,
we can end up with no layout selected in the keyboard menu and an "empty"
indicator. Fix this by explicitly passing null if no callback has been
provided.

https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/293
2018-11-17 12:15:46 +00:00
43041f0464 app-usage: Remove more unused things
https://bugzilla.gnome.org/show_bug.cgi?id=673767
2018-11-17 12:08:33 +00:00
c3ec813f6f app-usage: Remove unused open-window-count attribute
Since this has already been unused and was inaccessible, this shouldn't
matter too much.

https://bugzilla.gnome.org/show_bug.cgi?id=673767
2018-11-17 12:08:33 +00:00
04d7069d83 app-usage: Remove crufty old "context"s idea
Back in the day, there was a proposed system of tracking apps in a
specific context.

The inspiration was that you may have used apps in multiple modes:
Firefox may have been used in both "Programmer Reference" and
"Kitten Videos" contexts. Early user response to the feedback wasn't
too positive - context switching is something that humans have trouble
doing implicitly, let alone explicitly. The old codebase still has a
few remnants of this around; let's finally put them to rest.

Note that we still write out a dummy context tag to the XML file - old
versions of the shell will flat out crash if you don't have one of those
in there, so just leave it in for compatibility sake.

https://bugzilla.gnome.org/show_bug.cgi?id=673767
2018-11-17 12:08:33 +00:00
52c59ac0dd power: Label the PENDING_CHARGE state as "Not Charging"
The pending-charge state means AC power is on but the battery is not
being charged. This can happen because its charge is above a certain
threshold, to avoid short charging cycles and prolong the battery's
life, or because the PSU is not powerful enough to charge the batteries.

Instead of lying to the user about something being estimated, we should
simply tell the truth and set the label to "Not Charging".

Closes: #701.
2018-11-14 13:51:26 -08:00
240f3faf6e windowAttentionHandler: Fix syntax errors
Gah, why didn't we catch those?!
2018-11-14 19:38:33 +01:00
284978757e windowAttentionHandler: Handle XUrgencyHint as well
While it's not commonly used, it is easy enough to handle it the
same as the demands-attention hint, so do just that.

https://bugzilla.gnome.org/show_bug.cgi?id=643595
2018-11-14 13:42:33 +00:00
50c28714df Bump version to 3.31.2
Update NEWS.
2018-11-14 01:03:45 +01:00
6099e92df5 workspace: Confine caption width to workspace area
When we started to only show a single caption at a time, we allowed
title captions to be wider than their corresponding window preview.
But while overlapping neighboring previews is fine, we shouldn't
allow the captions to leak outside the workspace area itself and
overlap unrelated elements like workspace switcher or dash.

This partly reverts commit b3b30f239d.

https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/214
2018-11-13 18:12:59 +00:00
a4d09b4264 workspace: Remove dead code
https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/214
2018-11-13 18:12:59 +00:00
6f5a099184 inputMethod: Keep track of preedit string visibility
So we can silence update-preedit-text signals that keep the
preedit string invisible.

https://gitlab.gnome.org/GNOME/gtk/issues/1447
2018-11-13 18:52:15 +01:00
8c3811a866 inputMethod: Avoid calling set_preedit_text() if unnecessary
This is easier down on clients.
2018-11-13 18:52:15 +01:00
118cab1766 windowManager: make TouchpadWorkspaceSwitchAction respect natural-scroll
Instead of defaulting to a natural scroll behavior,
have the workspace switch action use the natural-scroll setting
in org.gnome.peripherals.touchpad to determine the correct
direction of travel when swiping. 4 finger swipes will then
match the behavior of the rest of the UI.

Reference: https://gitlab.gnome.org/GNOME/gnome-shell/issues/516
2018-11-13 14:56:11 +00:00
367b1c0627 notificationDaemon: Don't pass unused extra hints value
Probably this is a leftover of old implementations of _iconForNotificationData,
but right now this only takes a value, so just pass one.

https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/285
2018-11-13 15:39:56 +01:00
33b8537bf5 notificationDaemon: support file:// or icon theme names for image-path
While this sounds counter-intuitive, the image-path hint value might also
be used with URIs or icon names.

As per freedesktop standard:
  The "app_icon" parameter and "image-path" hint should be either an URI
  (file:// is the only URI schema supported right now) or a name in a
  freedesktop.org-compliant icon theme (not a GTK+ stock ID).

Thus the image-path hint should also be parsed as it happens for the
app_icon.

Reuse same logic, by falling back on _iconForNotificationData with the
hint value.

https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/285
2018-11-13 15:39:46 +01:00
361cc6cf92 st: Remove deprecated cogl_texture_new()
cogl_texture_new() is used in a few places in GNOME Shell, but
it's a deprecated Cogl function. The replacement is the less
verbose cogl_texture_2d_new_with_size(), that is very much a
straightforward replacement.

Remove the few places where this function is used, replacing
it by the CoglTexture2d counterpart.

https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/287
2018-11-12 21:59:36 -02:00
5fb8d4f730 calendar: do not call destroy() recursively
We have a callback that will call close() when the notification is
destroyed, and a callback that will call destroy() on the notification
when the message is closed.

Currently, if the notification is destroyed we'll execute our callback
that will call again destroy() on the notification. That's bad
practice in general, and it also has the side effect of resetting the
destroy reason.

This commit avoids re-destroying the notification by dropping the
notification reference on destroy.

https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/258
2018-11-10 10:56:49 +00:00
a98ed08a54 notificationDaemon: use different reason when replacing notification
Differently from the fd.o notifications, Gtk notifications do not
have a mechanism to update themselves. Instead, when a new
notification is received for an ID already known to the notification
daemon, the old notification is dismissed and a replaced with a new
one.

Currently though, there is no way to distinguish a notification that
was dismissed because of an user interaction, or because it was
replaced. That is an useful piece of information, so add a new value
to the NotificationDestroyedReason enum to account for it.

https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/258
2018-11-10 10:56:49 +00:00
80a7547129 notificationDaemon: separate out GtkNotification creation
This way, source subclasses can easily use a notification subclass
if different functionality is required.

https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/258
2018-11-10 10:56:49 +00:00
ca3f4cfb41 StTextureCache: use right event to detect file changes
StTextureCache installs file monitors that invalidate caches when
contents of the underlying file change.
At the moment, the cache uses the Gio.FileMonitorEvent.CHANGED event
type to make that determination.

However, that is suboptimal for at least two reasons:
- while a file is being written to disk, many CHANGED events will be
  emitted in sequence. That will cause needless cache invalidations,
  and we will risk loading the file before it's fully loaded.
- if an existing file is replaced, e.g. with g_file_replace(), we may
  not get a CHANGED event but a CREATED one instead, so the cache ends
  up never getting invalidated.

The good news is that in both of those cases GFileMonitor will send a
CHANGES_DONE_HINT event after changes have settled, or after the file
is replaced.

This commit fixes both cases by switching from the CHANGED event to
CHANGES_DONE_HINT to determine that a file has in fact changed.

https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/286
2018-11-10 00:42:49 +01:00
551e827841 keyboard: Do not call KeyboardManager.holdKeyboard() with set-content-type
When gnome-shell receives the signal of 'set-content-type' from ibus,
gnome-shell calls KeyboardManager.holdKeyboard() and
KeyboardManager.releaseKeyboard() and the functions change the current
input focus in GNOME Xorg and it could result in closing a popup window
which has a password entry by focusing on the entry.
The solution is to stop to call the APIs on 'set-content-type' signal.

https://gitlab.gnome.org/GNOME/gnome-shell/issues/391
2018-11-09 10:55:30 +00:00
4dc2039859 messageTray: Disable unredirection while showing banners
We don't usually show notification banners while the monitor is in
fullscreen, but when we do - the notification is urgent - we should
actually show the banner, even if the top-most window is unredirected.
To achieve that, disable unredirection while the banner is showing.

https://gitlab.gnome.org/GNOME/gnome-shell/issues/430
2018-11-08 12:51:27 +00:00
f1195ecb01 workspaces: Use correct schema for workspace settings
The custom overrides system is gone, we need to use the original
mutter schema.

https://gitlab.gnome.org/GNOME/gnome-shell/issues/768
2018-11-08 10:50:32 +01:00
127ba318fd polkit: Only unregister registered handles
If the initialization fails for some reason, for example by
running 'gnome-shell --replace', we should not crash because
of an attempt of unregistering an unregistered agent handle.

Fix that by checking if the handle is not NULL before calling
the unregistering routines.

https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/66
2018-11-06 13:05:29 -02:00
72fa44d0fd polkit: Port to G_DECLARE_FINAL_CLASS
So we can remove this old boilerplate code. In order to be able
to use that, the autoptr function for PolkitAgentListener was
added as well.

https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/66
2018-11-06 13:05:15 -02:00
b96cc9a161 Update Spanish translation 2018-11-06 11:04:19 +00:00
5f2c167947 Update Brazilian Portuguese translation
(cherry picked from commit e55bdb0fbb)
2018-11-05 19:58:53 +00:00
86a78c340f Theme: fix modal dialog button
- allow for focused hover state

Fixes issue #727
2018-11-02 14:45:05 +01:00
1acdff822a iconGrid: Keep icons reactive during pulse animation
The `reactive` property of icon actors was being restored multiple times
over the course of the pulse animation, all at slightly different times
as each icon finished animating at different times.

The problem is that toggling `reactive` on an `StWidget` incurs a style
change of the `insensitive` pseudo class, and style changes would quickly
queue relayouts incurring full stage reallocation. This occurred many times
during a pulse animation, limiting its smoothness and performance.

The solution is to not toggle the `reactive` property in the pulse
animation at all, which avoids incurring multiple full stage relayouts.

As a bonus, this means the icon under the cursor pulses with the correct
selection highlight, appearing more seamless and responsive.

https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/261
2018-10-30 19:58:52 +01:00
a5e6dd52d2 iconGrid: Defer and group animation cleanup
The `reactive` property of icon actors was being restored 24 times over
the course of the spring animation, all at slightly different times as
each icon finished animating at different times.

The problem is that toggling `reactive` on an `StWidget` incurs a style
change of the `insensitive` pseudo class, and style changes would quickly
queue relayouts incurring full stage reallocation. This occurred many times
during a spring animation hogging the CPU and limiting the frame rate.

The solution is defer and batch the cleanup for all icons until after the
last icon has finished animating. This way the CPU impact of the style
change and stage relayout isn't felt during the animation so the frame
rate remains higher and smoother. The overall CPU usage of the animation
is also reduced as the remaining relayouts are much more likely to be
grouped into a single frame.

Icon spring animation performance on an i7-7700:
Before: 83% CPU and 47 FPS
After : 78% CPU and 54 FPS
which is about a 22% increase in performance per clock (FPS/CPU).

https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/253
2018-10-30 18:01:05 +00:00
14953041cc Update Malayalam translation 2018-10-28 14:08:07 +00:00
4e422a527f Updated Slovenian translation 2018-10-25 21:40:05 +02:00
c0b561dd4a switcherPopup: Bind to the stage, not the monitor
The switcher popup is a large, mostly transparent actor that
should cover all the clickable area of GNOME Shell. In Clutter
terms, it should cover the whole stage.

By binding it to the primary monitor, the Alt+Tab behavior
becomes a bit inconsistent. For example, by not hiding when
clicking at empty spaces at other monitors.

Fix that by binding the SwitcherPopup to the whole stage,
and not only the primary monitor.

Fixes https://gitlab.gnome.org/GNOME/gnome-shell/issues/647
2018-10-25 12:33:10 -03:00
0f542c2e16 Remove padding from date strings
The padding is removed by using %-d instead of %e or %d.

Examples:

"%B %d %Y"  -> "October 04 2018"

"%B %e %Y"  -> "October  4 2018"

"%B %-d %Y" -> "October 4 2018"

https://gitlab.gnome.org/GNOME/gnome-shell/issues/666
2018-10-25 13:05:47 +02:00
cff9eaf5aa Change a translator comment to be less ambiguous
https://gitlab.gnome.org/GNOME/gnome-shell/issues/666
2018-10-25 13:05:08 +02:00
468117583a Update Slovak translation 2018-10-24 06:31:09 +00:00
7026a6fd32 automountManager: Add handling of udisks errors for no/wrong passwords
If no password or a wrong password is entered after automounting an
encrypted device, then the password should be reasked. However, this
does not happen because the relevant udisks error messages for this
cases are missing in the exception handler that calls _reaskPassword.

Fix this issue by adding the relevant udisks error strings to the
exception handling in the _onVolumeMounted method.

https://gitlab.gnome.org/GNOME/gnome-shell/issues/640
2018-10-24 00:13:10 +02:00
ceed3e07e4 build: Include params.js in portal-helper gresources
Fix a regression causing the portal helper to crash.
In 94423151b2 we moved the dbus interface
descriptions into seperate files which is why we had to include the
fileUtils js module. This module imports the params js module, so add
params.js to the gresources file for the portal helper.
2018-10-23 15:38:31 +00:00
a0dc8dc7ef panel: Also ignore hidden windows for proximity
We currently only ignore minimized windows, not windows that are
hidden for other reasons - namely on wayland windows are initially
hidden until they are placed.

This fixes a flicker in the transparent top bar on wayland when the
"position" of an unplaced window wrongly suggests the window is
overlapping the top bar.

https://gitlab.gnome.org/GNOME/gnome-shell/issues/693
2018-10-23 16:24:22 +02:00
b405ed6442 keyboardManager: Avoid idempotent calls to meta_backend_set_keymap()
But still try to apply the keymap whenever the input sources changed. This
is a different approach to gnome-shell#240 that still avoid redundant
changes to the current keymap, but actually trigger one when input sources
are added.

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

Closes: https://gitlab.gnome.org/GNOME/gnome-shell/issues/691
2018-10-23 09:45:02 +00:00
8566ec2ee5 osdWindow: Disconnect signals on destroy
Since we started to show OSD windows on all monitors, OSD windows are
destroyed when the corresponding monitor is disconnected. We shouldn't
leave any signal handlers around in that case - they prevent the object
from being garbage collected, and trigger warnings for accessing proper-
ties of invalidated GObjects.

https://gitlab.gnome.org/GNOME/gnome-shell/issues/602
2018-10-22 14:58:50 +00:00
ae7dd5e2db osdWindow: Ensure we setMaxLevel before setting Level itself
When maxLevel is > 100%, first OSD appearance was capping the current
level to 100%. Consecutives key press were then OK.
Ensure we setMaxLevel before setting Level itself, so that correct cap
value is applied.
2018-10-19 16:18:41 +02:00
9f3c85fdc8 Update Esperanto translation 2018-10-16 21:02:53 +00:00
aa685310bb Fix enumeration in HACKING.md
The HACKING.md file contains an enumeration in the Indentation and
whitespace section, but the sentences look incorrectly divided.

This patch proposes a fix for that section, reordering all its
contents in a single enumeration, instead of a paragraph and
an enumeration, and also reconstruct the sentences.
2018-10-14 14:05:04 +02:00
76117fd306 appFolder: Don't block all shortcuts
App folder popups take a grab when opened, and as we don't pass any
particular pushModal() parameters, all keybindings are blocked. While
this makes sense for most keybindings that would interfere with the
popup interaction, others like volume/brightness keys or screenshots
can be allowed safely.

https://gitlab.gnome.org/GNOME/gnome-shell/issues/648
2018-10-11 20:12:54 +02:00
8855622666 popupMenu: Handle keypress if numlock is enabled
Add exception to handle a keypress if numlock is enabled as we already do for
capslock. This uses Clutter.ModifierType.MOD2_MASK because at the moment there
is not a more explicit way to refer to the numlock mask.

Fixes: https://gitlab.gnome.org/GNOME/gnome-shell/issues/550
2018-10-11 07:45:44 +00:00
655234e6c3 shell: Remove ShellGenericContainer
Now that it is no longer used in GNOME Shell, let's
remove this old workaround. This commit also removes
the docs reference from the sgml file.

https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/153
2018-10-08 22:44:14 -03:00
38c1ebba62 dash: expand and center align DashItemContainer
This is necessary to keep the small actor that shows up
during drag motion center aligned.
2018-10-08 22:43:13 -03:00
557b232c89 panel: Delegate container destruction to PanelMenu.ButtonBox
Instead of taking care of the PanelMenu.ButtonBox.container
destruction by itself, delegate that to the very object that
created it in the first place: PanelMenu.ButtonBox itself.
2018-10-08 22:43:13 -03:00
b719744e75 st-bin: Destroy child in ClutterActor:destroy vfunc
According to Clutter documentation, "[…] actors implementing the
ClutterContainer interface should override the default implementation
of the class handler of this signal and call clutter_actor_destroy()
on their  children."

StBin was doing that in GObject:dispose() instead. Move the child
destruction to a new ClutterActor:destroy() vfunc override.
2018-10-08 22:43:13 -03:00
038f8b6ea5 keyboard: Stop using Shell.GenericContainer
This is the last remaining usage of Shell.GenericContainer
in the codebase, and posed small challenges compared to the
other removals.

A new St.Widget subclass called InputSourceIndicatorContainer
was added as a replacement to the Shell.GenericContainer. It
was needed because GNOME Shell needs to override the regular
size allocation functions, but InputSourceIndicator already
is a St.Widget with its own size allocation overrides.

https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/153
2018-10-08 22:43:01 -03:00
2ee321e0d8 tests: Stop using Shell.GenericContainer
The test doesn't look and behave like before, but they are
already broken in master anyway. This commit makes it work
without Shell.GenericContainer, but the test itself remains
to be fixed.

https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/153
2018-10-08 22:43:01 -03:00
b4c674900f inspector: Stop using Shell.GenericContainer
No alarms and no surprises here.

https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/153
2018-10-08 22:43:01 -03:00
3fa19e58ac boxPointer: Stop using Shell.GenericContainer
An easy removal too.

https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/153
2018-10-08 22:43:01 -03:00
f460f2748d boxPointer: Add compatibility API
Because we're late in the cycle, and don't know how many
extensions actually rely on this API, this commit adds
back the BoxPointer.show() and .hide() functions, with
warning messages to notify consumers that this is going
to be removed.

https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/153
2018-10-08 22:43:01 -03:00
8b215b2446 boxPointer: Rename show/hide to open/close
Pretty much like dd4709bb2, BoxPointer's show() and hide()
functions will clash with Clutter.Actor's ones.

In addition to that, on a conceptual level, the current API
is not great, because calling boxPointer.hide() won't result
in boxPointer.actor.visible == false.

For these reasons, rename show() and hide() to open() and
close(). A compatibility layer will be added in a following
commit, warning about the usage of show() and hide().

https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/153
2018-10-08 22:42:53 -03:00
0c0d76f7d6 loginDialog: Stop using Shell.GenericContainer
Removing the Shell.GenericContainer from the login dialog
was remarkably easier, since it only overrides 'allocate'.

https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/153
2018-10-08 22:42:26 -03:00
dd225713a1 layoutManager: Subclass GObject.Object
LayoutManager is currently a pure JavaScript class that
relies on the rudimentary Signals.addSignalMethods() to
handle signals. This is an inefficient implementation of
one of the most central classes in GNOME Shell.

In addition to removing Shell.GenericContainer, then,
turn LayoutManager into a proper GObject.Object subclass.

https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/153
2018-10-08 22:42:26 -03:00
f4682748fa layoutManager: Stop using Shell.GenericContainer
This one was remarkably easy to port. In order to make it,
replace the Shell.GenericContainer handlers by a constraint
and simply replace it by a St.Widget.

https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/153
2018-10-08 22:42:26 -03:00
b058e89166 workspaceSwitcherPopup: Stop using Shell.GenericContainer
Removing Shell.GenericContainer here was slightly trickier
because it required factoring out a new JavaScript class.

It's nevertheless a straightforward removal.

https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/153
2018-10-08 22:42:26 -03:00
ac314cfb05 messageTray: Drop Shell.GenericContainer usage
Nothing particularly outstanding with this class - it was
a straightforward removal and subclassing.

https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/153
2018-10-08 22:42:26 -03:00
fc342fe8c5 buttonBox: Drop Shell.GenericContainer usage
Another easy port.

https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/153
2018-10-08 22:42:25 -03:00
dd4709bb27 appMenuButton: Rename show/hide to fadeIn/fadeOut
In the next commit, we will turn PanelMenu.ButtonBox into a
St.Widget subclass. As a domino effect, PanelMenu.Button will
become one too, and so will Panel.AppMenuButton.

When that happens, the current show() and hide() functions in
Panel.AppMenuButton will clash with Clutter.Actor's ones.

To avoid that, rename these functions to fadeIn() and fadeOut()
and avoid a name clash.

https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/153
2018-10-08 22:42:25 -03:00
e9f4f2e8ae thumbnailBox: Stop using Shell.GenericContainer
This is another straight port from Shell.GenericContainer.
The important thing to notice is that the calculation is
broken if the StThemeNode helpers (adjust_preferred_* and
adjust_for_*) aren't used.

The downside of this patch is that it removed the skip_paint
from the thumbnails. Keeping it would add an unecessarily
large amount of code.

https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/153
2018-10-08 22:42:25 -03:00
197c0eee29 iconGrid: Stop using Shell.GenericContainer
Removing Shell.GenericContainer from the IconGrid class was
challenging because it needs the "skip paint" API from it.
This API was added, too, as a workaround to the inability
to override vfuncs from GJS.

The overrides are largely copy-pasted and translated versions
of the Shell.GenericContainer code.

The IconGrid:key-focus-in signal was renamed to :child-focused
to avoid clashing with ClutterActor:key-focus-in.

In GridSearchResults, the internal IconGrid had it's y_expand
set to false, so it doesn't push other search elements (the
list results mainly) to the bottom of the screen.

Because skip paint wasn't and still isn't a GObject property,
rename it to _skipPaint to reflect that.

https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/153
2018-10-08 22:42:25 -03:00
034a723677 iconGrid: Rename ::key-focus-in signal
As part of our quest to obsolete Shell.GenericContainer, IconGrid will
become a Clutter.Actor subclass. As the ::key-focus-in signal would
clash with Clutter.Actor::key-focus-in, rename it to ::child-focused.

https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/153
2018-10-08 22:42:25 -03:00
efb3025d8c dash: Set scale and opacity on parent actor
DashItemContainer currently animates the scale and opacity
of its child when zooming in. This is visible when adding
a new favorite item to the dash; the items will zoom in from
the center.

After the previous commit, however, the zoom animation got
slightly broken, and looked like the icon was coming from
the bottom instead of the center.

Fix that by setting the scale and opacity of DashItemContainer
itself, instead of its child. Remove the unused code after that
too.

https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/153
2018-10-08 22:42:24 -03:00
81ec8215a0 baseIcon: Stop using Shell.GenericContainer
Pretty much like the previous patches, this extends St.Bin. The
most interesting aspect of this patch is that most of the sizing
routines of the icons is now delegated to the actors and layout
managers, removing quite a bunch of code.

The 'spacing' theme property is now redirected to StBoxLayout's
spacing property. Also adjust the Dash code to stop forcing a
potentially invalid width in the first icon too.

https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/153
2018-10-08 22:42:24 -03:00
4be66ecf01 windowIcon: Subclass St.BoxLayout
Following the previous work, turn WindowIcon into a
St.BoxLayout subclass, and remove the this.actor
field from it.
2018-10-08 22:42:24 -03:00
2717ca9d08 st-box-layout: Pass correct allocation box to layout manager
StBoxLayout implements StScrollable, which, semantically, means that
the StBoxLayout size may not match the minimum size reported by the
layout manager. In this specific case, the layout manager by is a
ClutterBoxLayout by default. For example:

        +--------------+
        |   Viewport   |
 +------+--------------+-----------------+
 |      |              |                 |
 |      |              |     Content     |
 |      |              |                 |
 +------+--------------+-----------------+
        |              |
        +--------------+

So, assuming that:

 - ContentSize = the minimum size of the content;
 - ViewportSize = the allocated size of the viewport;

When allocating StBoxLayout, it must assume ViewportSize, but must
pass ContentSize to the layout manager. That way, the children of
StBoxLayout are correctly placed within it, even if it's bigger than
ViewportSize.

And here's the problem: right now, StBoxLayout assumes ViewportSize
AND also passes it to layout manager. Commit 77c4c6b6d specifically
exposed this bug by relying entirely on StBoxLayout to arrange the
app and window icons.

Fix that by using ViewportSize to allocate StBoxLayout itself, but
passing ContentSize to the layout manager.

https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/153
2018-10-08 22:42:24 -03:00
c6cea277eb switcherList: Stop using Shell.GenericContainer
This commit removes all the uses of Shell.GenericContainer from
SwitcherPopup.SwitcherList. Compared to the other patches, this
one was specially trickier to get right, and a few invasive
changes needed to be done.

The most noticeable one is that the allocation of the items is
done entirely by St.BoxLayout -- we don't manually allocate them
anymore. To make it work, get_preferred_width() had to calculate
the correct value. It now assumes that:

 * Minimum width: the minimum width of the widest child.
 * Natural width: the minimum width of the StBoxLayout (use it
   instead of the natural width to force the labels to ellipsize
   when too long.)

The AppIcon class became a St.Widget subclass as well, to override
get_preferred_width() and be able to keep the squared shape.

Besides that, add a new SwitcherButton class to reimplement squared
icons without having to resort to hacks in the size allocation
machinery. This class has a single vfunc override to ensure that it
is squared when the SwitcherList is.

The arrows indicating multiple windows are now in this._list
actor to the SwitcherPopup itself, since this._list automatically
manages its own children now.

At last, adapt (but preserve) the hack in CyclerPopup.

https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/153
2018-10-08 22:42:24 -03:00
9a47b4b343 switcherList: Remove unused variable
The title is self-explanatory, 'primary' was not being used
anywhere.

https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/153
2018-10-08 22:42:24 -03:00
0ec36fc5cf switcherPopup: Use MonitorConstraint instead of vfunc overrides
Instead of overriding vfunc_get_preferred_width|height(), use the
already available Layout.MonitorConstraint to bind SwitcherPopup
to the primary monitor.
2018-10-08 22:42:23 -03:00
a315e75e95 switcherPopup: Subclass St.Widget
This commit turns SwitcherPopup.SwitcherPopup into a St.Widget
subclass, and gets rid of Shell.GenericContainer usage. Subclasses
were adapted to that too.

This class introduced a new challenge: it overrides show(). As per
discussions, we now call this.visible = true inside show().

https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/153
2018-10-08 22:42:23 -03:00
e82c68accd switcherPopup: Rename destroy() to fadeAndDestroy()
In the process of purging all usages of Shell.GenericContainer
of GNOME Shell, one specific problematic situation that might
occur is when classes have functions that would clash with any
ClutterActor or StWidget function name.

One of such example is SwitcherPopup.destroy(). Right now, this
class is a pure JavaScript class that wraps a real actor, but
soon this will change, and it'll become a St.Widget subclass.

Another problem with functions that mimic the toolkit ones is
the predictability of them; after calling destroy(), that widget
is expected to not be available anymore. In SwitcherPopup case,
it is still available for a short while. In this case, that's not
a big problem, but the show() and hide() functions in other clases
are more problematic because the actor's visibility does not
follow that.

This commit is a first step in cleaning that up, and changes the
SwitcherPopup.destroy() to fadeAndDestroy().

https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/153
2018-10-08 22:42:23 -03:00
286ffbe2b6 panel: Stop using Shell.GenericContainer
Shell.GenericContainer exposes the size negotiation machinery
through the use of signals. Signals are not specially performant.
One of the reasons is that they acquire a global lock for signal
handlers lookup. GNOME Shell has more than 2,000 actors at any
given point in time, up to 20 levels deep in hierarchy, making
size negotiation and painting non-trivial tasks. Such a critical
section of Clutter's machinery shouldn't rely on signals
whatsoever.

Regardless of that, Shell.GenericContainer is a workaround to
a non-existing issue anymore. It shouldn't be used anyway, and
any performance improvements that removing it can potentially
yield are bonuses to it.

This commit starts this work by removing Shell.GenericContainer
usage from Panel.Panel class. The class now extends St.Widget,
and as such, it has no "this.actor" field set anymore. A couple
of places where this actor field was used are adjuste as well.

It is important to notice that we now allocate the Panel itself
inside vfunc_allocate(). This was previously done before emitting
the signal by Shell.GenericContainer.

https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/153
2018-10-08 22:42:23 -03:00
206 changed files with 12756 additions and 18779 deletions

View File

@ -10,15 +10,15 @@ Life isn't fun if you can't break the rules. If a rule seems unnecessarily
restrictive while you're coding, ignore it, and let the patch reviewer decide
what to do.
## Indentation and whitespace
## Indentation, braces and whitespace
Use four-space indents. Braces are on the same line as their associated
statements. You should only omit braces if *both* sides of the statement are
on one line.
* Use four-space indents.
* Braces are on the same line as their associated statements.
* You should only omit braces if *both* sides of the statement are on one line.
* One space after the `function` keyword.
* No space between the function name in a declaration or a call.
* One space before the parens in the `if` statements, or `while`, or `for` loops.
* One space after the `function` keyword. No space between the function name
* in a declaration or a call. One space before the parens in the `if`
* statements, or `while`, or `for` loops.
```javascript
function foo(a, b) {
let bar;
@ -82,7 +82,6 @@ don't use.
```javascript
const GLib = imports.gi.GLib;
const Gio = imports.gi.Gio;
const Lang = imports.lang;
const St = imports.gi.St;
const Main = imports.ui.main;
@ -121,40 +120,34 @@ See [What's new in JavaScript 1.7](https://developer.mozilla.org/en/JavaScript/N
## Classes
There are many approaches to classes in JavaScript. We use our own class framework
(sigh), which is built in gjs. The advantage is that it supports inheriting from
GObjects, although this feature isn't used very often in the Shell itself.
There are many approaches to classes in JavaScript. We use standard ES6 classes
whenever possible, that is when not inheriting from GObjects.
```javascript
var IconLabelMenuItem = new Lang.Class({
Name: 'IconLabelMenuItem',
Extends: PopupMenu.PopupMenuBaseItem,
_init(icon, label) {
this.parent({ reactive: false });
var IconLabelMenuItem = class extends PopupMenu.PopupMenuBaseItem {
constructor(icon, label) {
super({ reactive: false });
this.actor.add_child(icon);
this.actor.add_child(label);
},
}
open() {
log("menu opened!");
}
});
};
```
* 'Name' is required. 'Extends' is optional. If you leave it out, you will
automatically inherit from Object.
For GObject inheritence, we use the GObject.registerClass() function provided
by gjs.
```javascript
var MyActor = GObject.registerClass(
class MyActor extends Clutter.Actor {
_init(params) {
super._init(params);
* Leave a blank line between the "class header" (Name, Extends, and other
things) and the "class body" (methods). Leave a blank line between each
method.
* No space before the colon, one space after.
* No trailing comma after the last item.
* Make sure to use a semicolon after the closing paren to the class. It's
still a giant function call, even though it may resemble a more
conventional syntax.
this.name = 'MyCustomActor';
}
});
```
## GObject Introspection
@ -162,17 +155,16 @@ GObject Introspection is a powerful feature that allows us to have native
bindings for almost any library built around GObject. If a library requires
you to inherit from a type to use it, you can do so:
```javascript
var MyClutterActor = new Lang.Class({
Name: 'MyClutterActor',
Extends: Clutter.Actor,
var MyClutterActor = GObject.registerClass(
class MyClutterActor extends Clutter.Actor {
vfunc_get_preferred_width(actor, forHeight) {
return [100, 100];
},
}
vfunc_get_preferred_height(actor, forWidth) {
return [100, 100];
},
}
vfunc_paint(actor) {
let alloc = this.get_allocation_box();
@ -207,20 +199,18 @@ that has a property called `actor`. We call this wrapper class the "delegate".
We sometimes use expando properties to set a property called `_delegate` on
the actor itself:
```javascript
var MyClass = new Lang.Class({
Name: 'MyClass',
_init() {
var MyClass = class {
constructor() {
this.actor = new St.Button({ text: "This is a button" });
this.actor._delegate = this;
this.actor.connect('clicked', this._onClicked.bind(this));
},
}
_onClicked(actor) {
actor.set_label("You clicked the button!");
}
});
};
```
The 'delegate' property is important for anything which trying to get the
@ -246,8 +236,6 @@ variable that can be captured in closures.
All closures should be wrapped with Function.prototype.bind or use arrow
notation.
```javascript
const Lang = imports.lang;
let closure1 = () => { this._fnorbate(); };
let closure2 = this._fnorbate.bind(this);
```
@ -255,19 +243,18 @@ notation.
A more realistic example would be connecting to a signal on a method of a
prototype:
```javascript
const Lang = imports.lang;
const FnorbLib = imports.fborbLib;
var MyClass = new Lang.Class({
var MyClass = class {
_init() {
let fnorb = new FnorbLib.Fnorb();
fnorb.connect('frobate', this._onFnorbFrobate.bind(this));
},
}
_onFnorbFrobate(fnorb) {
this._updateFnorb();
}
});
};
```
## Object literal syntax
@ -301,23 +288,21 @@ property.
```javascript
var ANIMATION_TIME = 2000;
var MyClass = new Lang.Class({
Name: 'MyClass',
_init() {
var MyClass = class {
constructor() {
this.actor = new St.BoxLayout();
this._position = 0;
},
}
get position() {
return this._position;
},
}
set position(value) {
this._position = value;
this.actor.set_position(value, value);
}
});
};
let myThing = new MyClass();
Tweener.addTween(myThing,

46
NEWS
View File

@ -1,3 +1,49 @@
3.31.4
======
* Improve icon grid performance [Daniel; #174]
* Remove browser plugin [Michael; #766776]
* Add DBus API for introspecting the application state [Jonas, Olivier; !326]
* Always allow leaving the overview via the hot-corner [Pascal; #429]
* Misc. bug fixes [Florian, Jasper, Andrea, Sam, Dani, Cosimo, Jonas, Carlos;
#643595, #673767, !293, #783, #781, !298, !297, #782, !301, !314, !305, #799,
#632, !327]
Contributors:
Jonas Ådahl, Andrea Azzarone, Michael Catanzaro, Cosimo Cecchi, daniruiz,
Olivier Fourdan, Carlos Garnacho, Sam Hewitt, Andre Klapper, Florian Müllner,
Pascal Nowack, Jasper St. Pierre, RyuzakiKK, Marco Trevisan (Treviño),
João Paulo Rechi Vita, Daniel van Vugt
Translators:
Kristjan SCHMIDT [eo], Matej Urbančič [sl], Daniel Mustieles [es],
Fabio Tomat [fur], Emin Tufan Çetin [tr], Anders Jonsson [sv],
Ryuta Fujii [ja]
3.31.2
======
* Port away from and remove ShellGenericContainer [Georges; !153]
* popupMenu: Fix keyboard activation when numlock is active [Andrea; #550]
* Do not block all shortcuts while app folders are expanded [Florian; #648]
* Fix regression in handling new input sources [Carlos; #691]
* Reask password after udisk errors for no/wrong passwords [Sebastian; #640]
* Improve performance of app icon animations [Daniel; !253, !261]
* Avoid focus changes when updating keyboard options [Takao; #391]
* notifications: Support icon theme names in 'image-path' hint [Marco; !285]
* Respect natural-scroll setting for workspace swipe gesture [Erik; #516]
* Confine window preview titles to workspace area [Florian; !214]
* Misc. bug fixes [Florian, Carmen, Georges, Cosimo, Carlos; #602, #693,
#666, #647, !66, #768, #430, !286, !258, !287, gtk#1447]
Contributors:
Andrea Azzarone, Carmen Bianca Bakker, Cosimo Cecchi, Sergio Costas,
Erik Duxstad, Takao Fujiwara, Carlos Garnacho, Florian Müllner,
Georges Basile Stavracas Neto, Sebastian Pinnau, Didier Roche, Jakub Steiner,
Marco Trevisan (Treviño), verdre, Daniel van Vugt
Translators:
Kristjan SCHMIDT [eo], Dušan Kazik [sk], Matej Urbančič [sl],
Anish Sheela [ml], Rafael Fontenelle [pt_BR], Daniel Mustieles [es]
3.30.1
======
* Cancel search on overview hiding [Marco; !205]

View File

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

File diff suppressed because it is too large Load Diff

View File

@ -1,19 +0,0 @@
plugin_sources = [
'browser-plugin.c',
'npapi/npapi.h',
'npapi/npfunctions.h',
'npapi/npruntime.h',
'npapi/nptypes.h'
]
shared_module('gnome-shell-browser-plugin', plugin_sources,
dependencies: [gio_dep, json_glib_dep],
c_args: ['-DG_LOG_DOMAIN="GnomeShellBrowserPlugin"'],
# Browsers can unload and reload the module while browsing, which is not
# supported by GObject.
# We pass -Wl,-z,nodelete to the linker to ensure the module is never
# unloaded. See https://bugzilla.gnome.org/show_bug.cgi?id=737932.
link_args: ['-Wl,-z,nodelete'],
install: true,
install_dir: plugindir
)

View File

@ -1,893 +0,0 @@
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is
* Netscape Communications Corporation.
* Portions created by the Initial Developer are Copyright (C) 1998
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#ifndef npapi_h_
#define npapi_h_
#if defined(__OS2__)
#pragma pack(1)
#endif
#include "nptypes.h"
#if defined(__OS2__) || defined(OS2)
#ifndef XP_OS2
#define XP_OS2 1
#endif
#endif
#if defined(_WIN32) && !defined(__SYMBIAN32__)
#include <windef.h>
#ifndef XP_WIN
#define XP_WIN 1
#endif
#endif
#if defined(__SYMBIAN32__)
#ifndef XP_SYMBIAN
#define XP_SYMBIAN 1
#undef XP_WIN
#endif
#endif
#if defined(__APPLE_CC__) && !defined(XP_UNIX)
#ifndef XP_MACOSX
#define XP_MACOSX 1
#endif
#endif
#if defined(XP_MACOSX) && defined(__LP64__)
#define NP_NO_QUICKDRAW
#define NP_NO_CARBON
#endif
#if defined(XP_MACOSX)
#include <ApplicationServices/ApplicationServices.h>
#include <OpenGL/OpenGL.h>
#ifndef NP_NO_CARBON
#include <Carbon/Carbon.h>
#endif
#endif
#if defined(XP_UNIX)
#include <stdio.h>
#if defined(MOZ_X11)
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#endif
#endif
#if defined(XP_SYMBIAN)
#include <QEvent>
#include <QRegion>
#endif
/*----------------------------------------------------------------------*/
/* Plugin Version Constants */
/*----------------------------------------------------------------------*/
#define NP_VERSION_MAJOR 0
#define NP_VERSION_MINOR 27
/* The OS/2 version of Netscape uses RC_DATA to define the
mime types, file extensions, etc that are required.
Use a vertical bar to separate types, end types with \0.
FileVersion and ProductVersion are 32bit ints, all other
entries are strings that MUST be terminated with a \0.
AN EXAMPLE:
RCDATA NP_INFO_ProductVersion { 1,0,0,1,}
RCDATA NP_INFO_MIMEType { "video/x-video|",
"video/x-flick\0" }
RCDATA NP_INFO_FileExtents { "avi|",
"flc\0" }
RCDATA NP_INFO_FileOpenName{ "MMOS2 video player(*.avi)|",
"MMOS2 Flc/Fli player(*.flc)\0" }
RCDATA NP_INFO_FileVersion { 1,0,0,1 }
RCDATA NP_INFO_CompanyName { "Netscape Communications\0" }
RCDATA NP_INFO_FileDescription { "NPAVI32 Extension DLL\0"
RCDATA NP_INFO_InternalName { "NPAVI32\0" )
RCDATA NP_INFO_LegalCopyright { "Copyright Netscape Communications \251 1996\0"
RCDATA NP_INFO_OriginalFilename { "NVAPI32.DLL" }
RCDATA NP_INFO_ProductName { "NPAVI32 Dynamic Link Library\0" }
*/
/* RC_DATA types for version info - required */
#define NP_INFO_ProductVersion 1
#define NP_INFO_MIMEType 2
#define NP_INFO_FileOpenName 3
#define NP_INFO_FileExtents 4
/* RC_DATA types for version info - used if found */
#define NP_INFO_FileDescription 5
#define NP_INFO_ProductName 6
/* RC_DATA types for version info - optional */
#define NP_INFO_CompanyName 7
#define NP_INFO_FileVersion 8
#define NP_INFO_InternalName 9
#define NP_INFO_LegalCopyright 10
#define NP_INFO_OriginalFilename 11
#ifndef RC_INVOKED
/*----------------------------------------------------------------------*/
/* Definition of Basic Types */
/*----------------------------------------------------------------------*/
typedef unsigned char NPBool;
typedef int16_t NPError;
typedef int16_t NPReason;
typedef char* NPMIMEType;
/*----------------------------------------------------------------------*/
/* Structures and definitions */
/*----------------------------------------------------------------------*/
#if !defined(__LP64__)
#if defined(XP_MACOSX)
#pragma options align=mac68k
#endif
#endif /* __LP64__ */
/*
* NPP is a plug-in's opaque instance handle
*/
typedef struct _NPP
{
void* pdata; /* plug-in private data */
void* ndata; /* netscape private data */
} NPP_t;
typedef NPP_t* NPP;
typedef struct _NPStream
{
void* pdata; /* plug-in private data */
void* ndata; /* netscape private data */
const char* url;
uint32_t end;
uint32_t lastmodified;
void* notifyData;
const char* headers; /* Response headers from host.
* Exists only for >= NPVERS_HAS_RESPONSE_HEADERS.
* Used for HTTP only; NULL for non-HTTP.
* Available from NPP_NewStream onwards.
* Plugin should copy this data before storing it.
* Includes HTTP status line and all headers,
* preferably verbatim as received from server,
* headers formatted as in HTTP ("Header: Value"),
* and newlines (\n, NOT \r\n) separating lines.
* Terminated by \n\0 (NOT \n\n\0). */
} NPStream;
typedef struct _NPByteRange
{
int32_t offset; /* negative offset means from the end */
uint32_t length;
struct _NPByteRange* next;
} NPByteRange;
typedef struct _NPSavedData
{
int32_t len;
void* buf;
} NPSavedData;
typedef struct _NPRect
{
uint16_t top;
uint16_t left;
uint16_t bottom;
uint16_t right;
} NPRect;
typedef struct _NPSize
{
int32_t width;
int32_t height;
} NPSize;
typedef enum {
NPFocusNext = 0,
NPFocusPrevious = 1
} NPFocusDirection;
/* Return values for NPP_HandleEvent */
#define kNPEventNotHandled 0
#define kNPEventHandled 1
/* Exact meaning must be spec'd in event model. */
#define kNPEventStartIME 2
#if defined(XP_UNIX)
/*
* Unix specific structures and definitions
*/
/*
* Callback Structures.
*
* These are used to pass additional platform specific information.
*/
enum {
NP_SETWINDOW = 1,
NP_PRINT
};
typedef struct
{
int32_t type;
} NPAnyCallbackStruct;
typedef struct
{
int32_t type;
#if defined(MOZ_X11)
Display* display;
Visual* visual;
Colormap colormap;
unsigned int depth;
#endif
} NPSetWindowCallbackStruct;
typedef struct
{
int32_t type;
FILE* fp;
} NPPrintCallbackStruct;
#endif /* XP_UNIX */
#if defined(XP_MACOSX)
typedef enum {
#ifndef NP_NO_QUICKDRAW
NPDrawingModelQuickDraw = 0,
#endif
NPDrawingModelCoreGraphics = 1,
NPDrawingModelOpenGL = 2,
NPDrawingModelCoreAnimation = 3,
NPDrawingModelInvalidatingCoreAnimation = 4
} NPDrawingModel;
typedef enum {
#ifndef NP_NO_CARBON
NPEventModelCarbon = 0,
#endif
NPEventModelCocoa = 1
} NPEventModel;
#endif
/*
* The following masks are applied on certain platforms to NPNV and
* NPPV selectors that pass around pointers to COM interfaces. Newer
* compilers on some platforms may generate vtables that are not
* compatible with older compilers. To prevent older plugins from
* not understanding a new browser's ABI, these masks change the
* values of those selectors on those platforms. To remain backwards
* compatible with different versions of the browser, plugins can
* use these masks to dynamically determine and use the correct C++
* ABI that the browser is expecting. This does not apply to Windows
* as Microsoft's COM ABI will likely not change.
*/
#define NP_ABI_GCC3_MASK 0x10000000
/*
* gcc 3.x generated vtables on UNIX and OSX are incompatible with
* previous compilers.
*/
#if (defined(XP_UNIX) && defined(__GNUC__) && (__GNUC__ >= 3))
#define _NP_ABI_MIXIN_FOR_GCC3 NP_ABI_GCC3_MASK
#else
#define _NP_ABI_MIXIN_FOR_GCC3 0
#endif
#if defined(XP_MACOSX)
#define NP_ABI_MACHO_MASK 0x01000000
#define _NP_ABI_MIXIN_FOR_MACHO NP_ABI_MACHO_MASK
#else
#define _NP_ABI_MIXIN_FOR_MACHO 0
#endif
#define NP_ABI_MASK (_NP_ABI_MIXIN_FOR_GCC3 | _NP_ABI_MIXIN_FOR_MACHO)
/*
* List of variable names for which NPP_GetValue shall be implemented
*/
typedef enum {
NPPVpluginNameString = 1,
NPPVpluginDescriptionString,
NPPVpluginWindowBool,
NPPVpluginTransparentBool,
NPPVjavaClass,
NPPVpluginWindowSize,
NPPVpluginTimerInterval,
NPPVpluginScriptableInstance = (10 | NP_ABI_MASK),
NPPVpluginScriptableIID = 11,
NPPVjavascriptPushCallerBool = 12,
NPPVpluginKeepLibraryInMemory = 13,
NPPVpluginNeedsXEmbed = 14,
/* Get the NPObject for scripting the plugin. Introduced in NPAPI minor version 14.
*/
NPPVpluginScriptableNPObject = 15,
/* Get the plugin value (as \0-terminated UTF-8 string data) for
* form submission if the plugin is part of a form. Use
* NPN_MemAlloc() to allocate memory for the string data. Introduced
* in NPAPI minor version 15.
*/
NPPVformValue = 16,
NPPVpluginUrlRequestsDisplayedBool = 17,
/* Checks if the plugin is interested in receiving the http body of
* all http requests (including failed ones, http status != 200).
*/
NPPVpluginWantsAllNetworkStreams = 18,
/* Browsers can retrieve a native ATK accessibility plug ID via this variable. */
NPPVpluginNativeAccessibleAtkPlugId = 19,
/* Checks to see if the plug-in would like the browser to load the "src" attribute. */
NPPVpluginCancelSrcStream = 20,
NPPVsupportsAdvancedKeyHandling = 21,
NPPVpluginUsesDOMForCursorBool = 22
#if defined(XP_MACOSX)
/* Used for negotiating drawing models */
, NPPVpluginDrawingModel = 1000
/* Used for negotiating event models */
, NPPVpluginEventModel = 1001
/* In the NPDrawingModelCoreAnimation drawing model, the browser asks the plug-in for a Core Animation layer. */
, NPPVpluginCoreAnimationLayer = 1003
#endif
#if (MOZ_PLATFORM_MAEMO == 5) || (MOZ_PLATFORM_MAEMO == 6)
, NPPVpluginWindowlessLocalBool = 2002
#endif
} NPPVariable;
/*
* List of variable names for which NPN_GetValue should be implemented.
*/
typedef enum {
NPNVxDisplay = 1,
NPNVxtAppContext,
NPNVnetscapeWindow,
NPNVjavascriptEnabledBool,
NPNVasdEnabledBool,
NPNVisOfflineBool,
NPNVserviceManager = (10 | NP_ABI_MASK),
NPNVDOMElement = (11 | NP_ABI_MASK),
NPNVDOMWindow = (12 | NP_ABI_MASK),
NPNVToolkit = (13 | NP_ABI_MASK),
NPNVSupportsXEmbedBool = 14,
/* Get the NPObject wrapper for the browser window. */
NPNVWindowNPObject = 15,
/* Get the NPObject wrapper for the plugins DOM element. */
NPNVPluginElementNPObject = 16,
NPNVSupportsWindowless = 17,
NPNVprivateModeBool = 18,
NPNVsupportsAdvancedKeyHandling = 21
#if defined(XP_MACOSX)
/* Used for negotiating drawing models */
, NPNVpluginDrawingModel = 1000
#ifndef NP_NO_QUICKDRAW
, NPNVsupportsQuickDrawBool = 2000
#endif
, NPNVsupportsCoreGraphicsBool = 2001
, NPNVsupportsOpenGLBool = 2002
, NPNVsupportsCoreAnimationBool = 2003
, NPNVsupportsInvalidatingCoreAnimationBool = 2004
#ifndef NP_NO_CARBON
, NPNVsupportsCarbonBool = 3000 /* TRUE if the browser supports the Carbon event model */
#endif
, NPNVsupportsCocoaBool = 3001 /* TRUE if the browser supports the Cocoa event model */
, NPNVsupportsUpdatedCocoaTextInputBool = 3002 /* TRUE if the browser supports the updated
Cocoa text input specification. */
, NPNVsupportsCompositingCoreAnimationPluginsBool = 74656 /* TRUE if the browser supports
CA model compositing */
#endif
#if (MOZ_PLATFORM_MAEMO == 5) || (MOZ_PLATFORM_MAEMO == 6)
, NPNVSupportsWindowlessLocal = 2002
#endif
} NPNVariable;
typedef enum {
NPNURLVCookie = 501,
NPNURLVProxy
} NPNURLVariable;
/*
* The type of Toolkit the widgets use
*/
typedef enum {
NPNVGtk12 = 1,
NPNVGtk2
} NPNToolkitType;
/*
* The type of a NPWindow - it specifies the type of the data structure
* returned in the window field.
*/
typedef enum {
NPWindowTypeWindow = 1,
NPWindowTypeDrawable
} NPWindowType;
typedef struct _NPWindow
{
void* window; /* Platform specific window handle */
/* OS/2: x - Position of bottom left corner */
/* OS/2: y - relative to visible netscape window */
int32_t x; /* Position of top left corner relative */
int32_t y; /* to a netscape page. */
uint32_t width; /* Maximum window size */
uint32_t height;
NPRect clipRect; /* Clipping rectangle in port coordinates */
#if (defined(XP_UNIX) || defined(XP_SYMBIAN)) && !defined(XP_MACOSX)
void * ws_info; /* Platform-dependent additional data */
#endif /* XP_UNIX */
NPWindowType type; /* Is this a window or a drawable? */
} NPWindow;
typedef struct _NPImageExpose
{
char* data; /* image pointer */
int32_t stride; /* Stride of data image pointer */
int32_t depth; /* Depth of image pointer */
int32_t x; /* Expose x */
int32_t y; /* Expose y */
uint32_t width; /* Expose width */
uint32_t height; /* Expose height */
NPSize dataSize; /* Data buffer size */
float translateX; /* translate X matrix value */
float translateY; /* translate Y matrix value */
float scaleX; /* scale X matrix value */
float scaleY; /* scale Y matrix value */
} NPImageExpose;
typedef struct _NPFullPrint
{
NPBool pluginPrinted;/* Set TRUE if plugin handled fullscreen printing */
NPBool printOne; /* TRUE if plugin should print one copy to default
printer */
void* platformPrint; /* Platform-specific printing info */
} NPFullPrint;
typedef struct _NPEmbedPrint
{
NPWindow window;
void* platformPrint; /* Platform-specific printing info */
} NPEmbedPrint;
typedef struct _NPPrint
{
uint16_t mode; /* NP_FULL or NP_EMBED */
union
{
NPFullPrint fullPrint; /* if mode is NP_FULL */
NPEmbedPrint embedPrint; /* if mode is NP_EMBED */
} print;
} NPPrint;
#if defined(XP_MACOSX)
#ifndef NP_NO_CARBON
typedef EventRecord NPEvent;
#endif
#elif defined(XP_SYMBIAN)
typedef QEvent NPEvent;
#elif defined(XP_WIN)
typedef struct _NPEvent
{
uint16_t event;
uintptr_t wParam;
uintptr_t lParam;
} NPEvent;
#elif defined(XP_OS2)
typedef struct _NPEvent
{
uint32_t event;
uint32_t wParam;
uint32_t lParam;
} NPEvent;
#elif defined(XP_UNIX) && defined(MOZ_X11)
typedef XEvent NPEvent;
#else
typedef void* NPEvent;
#endif
#if defined(XP_MACOSX)
typedef void* NPRegion;
#ifndef NP_NO_QUICKDRAW
typedef RgnHandle NPQDRegion;
#endif
typedef CGPathRef NPCGRegion;
#elif defined(XP_WIN)
typedef HRGN NPRegion;
#elif defined(XP_UNIX) && defined(MOZ_X11)
typedef Region NPRegion;
#elif defined(XP_SYMBIAN)
typedef QRegion* NPRegion;
#else
typedef void *NPRegion;
#endif
typedef struct _NPNSString NPNSString;
typedef struct _NPNSWindow NPNSWindow;
typedef struct _NPNSMenu NPNSMenu;
#if defined(XP_MACOSX)
typedef NPNSMenu NPMenu;
#else
typedef void *NPMenu;
#endif
typedef enum {
NPCoordinateSpacePlugin = 1,
NPCoordinateSpaceWindow,
NPCoordinateSpaceFlippedWindow,
NPCoordinateSpaceScreen,
NPCoordinateSpaceFlippedScreen
} NPCoordinateSpace;
#if defined(XP_MACOSX)
#ifndef NP_NO_QUICKDRAW
typedef struct NP_Port
{
CGrafPtr port;
int32_t portx; /* position inside the topmost window */
int32_t porty;
} NP_Port;
#endif /* NP_NO_QUICKDRAW */
/*
* NP_CGContext is the type of the NPWindow's 'window' when the plugin specifies NPDrawingModelCoreGraphics
* as its drawing model.
*/
typedef struct NP_CGContext
{
CGContextRef context;
void *window; /* A WindowRef under the Carbon event model. */
} NP_CGContext;
/*
* NP_GLContext is the type of the NPWindow's 'window' when the plugin specifies NPDrawingModelOpenGL as its
* drawing model.
*/
typedef struct NP_GLContext
{
CGLContextObj context;
#ifdef NP_NO_CARBON
NPNSWindow *window;
#else
void *window; /* Can be either an NSWindow or a WindowRef depending on the event model */
#endif
} NP_GLContext;
typedef enum {
NPCocoaEventDrawRect = 1,
NPCocoaEventMouseDown,
NPCocoaEventMouseUp,
NPCocoaEventMouseMoved,
NPCocoaEventMouseEntered,
NPCocoaEventMouseExited,
NPCocoaEventMouseDragged,
NPCocoaEventKeyDown,
NPCocoaEventKeyUp,
NPCocoaEventFlagsChanged,
NPCocoaEventFocusChanged,
NPCocoaEventWindowFocusChanged,
NPCocoaEventScrollWheel,
NPCocoaEventTextInput
} NPCocoaEventType;
typedef struct _NPCocoaEvent {
NPCocoaEventType type;
uint32_t version;
union {
struct {
uint32_t modifierFlags;
double pluginX;
double pluginY;
int32_t buttonNumber;
int32_t clickCount;
double deltaX;
double deltaY;
double deltaZ;
} mouse;
struct {
uint32_t modifierFlags;
NPNSString *characters;
NPNSString *charactersIgnoringModifiers;
NPBool isARepeat;
uint16_t keyCode;
} key;
struct {
CGContextRef context;
double x;
double y;
double width;
double height;
} draw;
struct {
NPBool hasFocus;
} focus;
struct {
NPNSString *text;
} text;
} data;
} NPCocoaEvent;
#ifndef NP_NO_CARBON
/* Non-standard event types that can be passed to HandleEvent */
enum NPEventType {
NPEventType_GetFocusEvent = (osEvt + 16),
NPEventType_LoseFocusEvent,
NPEventType_AdjustCursorEvent,
NPEventType_MenuCommandEvent,
NPEventType_ClippingChangedEvent,
NPEventType_ScrollingBeginsEvent = 1000,
NPEventType_ScrollingEndsEvent
};
#endif /* NP_NO_CARBON */
#endif /* XP_MACOSX */
/*
* Values for mode passed to NPP_New:
*/
#define NP_EMBED 1
#define NP_FULL 2
/*
* Values for stream type passed to NPP_NewStream:
*/
#define NP_NORMAL 1
#define NP_SEEK 2
#define NP_ASFILE 3
#define NP_ASFILEONLY 4
#define NP_MAXREADY (((unsigned)(~0)<<1)>>1)
/*
* Flags for NPP_ClearSiteData.
*/
#define NP_CLEAR_ALL 0
#define NP_CLEAR_CACHE (1 << 0)
#if !defined(__LP64__)
#if defined(XP_MACOSX)
#pragma options align=reset
#endif
#endif /* __LP64__ */
/*----------------------------------------------------------------------*/
/* Error and Reason Code definitions */
/*----------------------------------------------------------------------*/
/*
* Values of type NPError:
*/
#define NPERR_BASE 0
#define NPERR_NO_ERROR (NPERR_BASE + 0)
#define NPERR_GENERIC_ERROR (NPERR_BASE + 1)
#define NPERR_INVALID_INSTANCE_ERROR (NPERR_BASE + 2)
#define NPERR_INVALID_FUNCTABLE_ERROR (NPERR_BASE + 3)
#define NPERR_MODULE_LOAD_FAILED_ERROR (NPERR_BASE + 4)
#define NPERR_OUT_OF_MEMORY_ERROR (NPERR_BASE + 5)
#define NPERR_INVALID_PLUGIN_ERROR (NPERR_BASE + 6)
#define NPERR_INVALID_PLUGIN_DIR_ERROR (NPERR_BASE + 7)
#define NPERR_INCOMPATIBLE_VERSION_ERROR (NPERR_BASE + 8)
#define NPERR_INVALID_PARAM (NPERR_BASE + 9)
#define NPERR_INVALID_URL (NPERR_BASE + 10)
#define NPERR_FILE_NOT_FOUND (NPERR_BASE + 11)
#define NPERR_NO_DATA (NPERR_BASE + 12)
#define NPERR_STREAM_NOT_SEEKABLE (NPERR_BASE + 13)
#define NPERR_TIME_RANGE_NOT_SUPPORTED (NPERR_BASE + 14)
#define NPERR_MALFORMED_SITE (NPERR_BASE + 15)
/*
* Values of type NPReason:
*/
#define NPRES_BASE 0
#define NPRES_DONE (NPRES_BASE + 0)
#define NPRES_NETWORK_ERR (NPRES_BASE + 1)
#define NPRES_USER_BREAK (NPRES_BASE + 2)
/*
* Don't use these obsolete error codes any more.
*/
#define NP_NOERR NP_NOERR_is_obsolete_use_NPERR_NO_ERROR
#define NP_EINVAL NP_EINVAL_is_obsolete_use_NPERR_GENERIC_ERROR
#define NP_EABORT NP_EABORT_is_obsolete_use_NPRES_USER_BREAK
/*
* Version feature information
*/
#define NPVERS_HAS_STREAMOUTPUT 8
#define NPVERS_HAS_NOTIFICATION 9
#define NPVERS_HAS_LIVECONNECT 9
#define NPVERS_68K_HAS_LIVECONNECT 11
#define NPVERS_HAS_WINDOWLESS 11
#define NPVERS_HAS_XPCONNECT_SCRIPTING 13
#define NPVERS_HAS_NPRUNTIME_SCRIPTING 14
#define NPVERS_HAS_FORM_VALUES 15
#define NPVERS_HAS_POPUPS_ENABLED_STATE 16
#define NPVERS_HAS_RESPONSE_HEADERS 17
#define NPVERS_HAS_NPOBJECT_ENUM 18
#define NPVERS_HAS_PLUGIN_THREAD_ASYNC_CALL 19
#define NPVERS_HAS_ALL_NETWORK_STREAMS 20
#define NPVERS_HAS_URL_AND_AUTH_INFO 21
#define NPVERS_HAS_PRIVATE_MODE 22
#define NPVERS_MACOSX_HAS_COCOA_EVENTS 23
#define NPVERS_HAS_ADVANCED_KEY_HANDLING 25
#define NPVERS_HAS_URL_REDIRECT_HANDLING 26
#define NPVERS_HAS_CLEAR_SITE_DATA 27
/*----------------------------------------------------------------------*/
/* Function Prototypes */
/*----------------------------------------------------------------------*/
#if defined(__OS2__)
#define NP_LOADDS _System
#else
#define NP_LOADDS
#endif
#ifdef __cplusplus
extern "C" {
#endif
/* NPP_* functions are provided by the plugin and called by the navigator. */
#if defined(XP_UNIX)
const char* NPP_GetMIMEDescription(void);
#endif
NPError NP_LOADDS NPP_New(NPMIMEType pluginType, NPP instance,
uint16_t mode, int16_t argc, char* argn[],
char* argv[], NPSavedData* saved);
NPError NP_LOADDS NPP_Destroy(NPP instance, NPSavedData** save);
NPError NP_LOADDS NPP_SetWindow(NPP instance, NPWindow* window);
NPError NP_LOADDS NPP_NewStream(NPP instance, NPMIMEType type,
NPStream* stream, NPBool seekable,
uint16_t* stype);
NPError NP_LOADDS NPP_DestroyStream(NPP instance, NPStream* stream,
NPReason reason);
int32_t NP_LOADDS NPP_WriteReady(NPP instance, NPStream* stream);
int32_t NP_LOADDS NPP_Write(NPP instance, NPStream* stream, int32_t offset,
int32_t len, void* buffer);
void NP_LOADDS NPP_StreamAsFile(NPP instance, NPStream* stream,
const char* fname);
void NP_LOADDS NPP_Print(NPP instance, NPPrint* platformPrint);
int16_t NP_LOADDS NPP_HandleEvent(NPP instance, void* event);
void NP_LOADDS NPP_URLNotify(NPP instance, const char* url,
NPReason reason, void* notifyData);
NPError NP_LOADDS NPP_GetValue(NPP instance, NPPVariable variable, void *value);
NPError NP_LOADDS NPP_SetValue(NPP instance, NPNVariable variable, void *value);
NPBool NP_LOADDS NPP_GotFocus(NPP instance, NPFocusDirection direction);
void NP_LOADDS NPP_LostFocus(NPP instance);
void NP_LOADDS NPP_URLRedirectNotify(NPP instance, const char* url, int32_t status, void* notifyData);
NPError NP_LOADDS NPP_ClearSiteData(const char* site, uint64_t flags, uint64_t maxAge);
char** NP_LOADDS NPP_GetSitesWithData(void);
/* NPN_* functions are provided by the navigator and called by the plugin. */
void NP_LOADDS NPN_Version(int* plugin_major, int* plugin_minor,
int* netscape_major, int* netscape_minor);
NPError NP_LOADDS NPN_GetURLNotify(NPP instance, const char* url,
const char* target, void* notifyData);
NPError NP_LOADDS NPN_GetURL(NPP instance, const char* url,
const char* target);
NPError NP_LOADDS NPN_PostURLNotify(NPP instance, const char* url,
const char* target, uint32_t len,
const char* buf, NPBool file,
void* notifyData);
NPError NP_LOADDS NPN_PostURL(NPP instance, const char* url,
const char* target, uint32_t len,
const char* buf, NPBool file);
NPError NP_LOADDS NPN_RequestRead(NPStream* stream, NPByteRange* rangeList);
NPError NP_LOADDS NPN_NewStream(NPP instance, NPMIMEType type,
const char* target, NPStream** stream);
int32_t NP_LOADDS NPN_Write(NPP instance, NPStream* stream, int32_t len,
void* buffer);
NPError NP_LOADDS NPN_DestroyStream(NPP instance, NPStream* stream,
NPReason reason);
void NP_LOADDS NPN_Status(NPP instance, const char* message);
const char* NP_LOADDS NPN_UserAgent(NPP instance);
void* NP_LOADDS NPN_MemAlloc(uint32_t size);
void NP_LOADDS NPN_MemFree(void* ptr);
uint32_t NP_LOADDS NPN_MemFlush(uint32_t size);
void NP_LOADDS NPN_ReloadPlugins(NPBool reloadPages);
NPError NP_LOADDS NPN_GetValue(NPP instance, NPNVariable variable,
void *value);
NPError NP_LOADDS NPN_SetValue(NPP instance, NPPVariable variable,
void *value);
void NP_LOADDS NPN_InvalidateRect(NPP instance, NPRect *invalidRect);
void NP_LOADDS NPN_InvalidateRegion(NPP instance,
NPRegion invalidRegion);
void NP_LOADDS NPN_ForceRedraw(NPP instance);
void NP_LOADDS NPN_PushPopupsEnabledState(NPP instance, NPBool enabled);
void NP_LOADDS NPN_PopPopupsEnabledState(NPP instance);
void NP_LOADDS NPN_PluginThreadAsyncCall(NPP instance,
void (*func) (void *),
void *userData);
NPError NP_LOADDS NPN_GetValueForURL(NPP instance, NPNURLVariable variable,
const char *url, char **value,
uint32_t *len);
NPError NP_LOADDS NPN_SetValueForURL(NPP instance, NPNURLVariable variable,
const char *url, const char *value,
uint32_t len);
NPError NP_LOADDS NPN_GetAuthenticationInfo(NPP instance,
const char *protocol,
const char *host, int32_t port,
const char *scheme,
const char *realm,
char **username, uint32_t *ulen,
char **password,
uint32_t *plen);
uint32_t NP_LOADDS NPN_ScheduleTimer(NPP instance, uint32_t interval, NPBool repeat, void (*timerFunc)(NPP npp, uint32_t timerID));
void NP_LOADDS NPN_UnscheduleTimer(NPP instance, uint32_t timerID);
NPError NP_LOADDS NPN_PopUpContextMenu(NPP instance, NPMenu* menu);
NPBool NP_LOADDS NPN_ConvertPoint(NPP instance, double sourceX, double sourceY, NPCoordinateSpace sourceSpace, double *destX, double *destY, NPCoordinateSpace destSpace);
NPBool NP_LOADDS NPN_HandleEvent(NPP instance, void *event, NPBool handled);
NPBool NP_LOADDS NPN_UnfocusInstance(NPP instance, NPFocusDirection direction);
void NP_LOADDS NPN_URLRedirectResponse(NPP instance, void* notifyData, NPBool allow);
#ifdef __cplusplus
} /* end extern "C" */
#endif
#endif /* RC_INVOKED */
#if defined(__OS2__)
#pragma pack()
#endif
#endif /* npapi_h_ */

View File

@ -1,322 +0,0 @@
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is
* Netscape Communications Corporation.
* Portions created by the Initial Developer are Copyright (C) 1998
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#ifndef npfunctions_h_
#define npfunctions_h_
#ifdef __OS2__
#pragma pack(1)
#define NP_LOADDS _System
#else
#define NP_LOADDS
#endif
#include "npapi.h"
#include "npruntime.h"
typedef NPError (* NP_LOADDS NPP_NewProcPtr)(NPMIMEType pluginType, NPP instance, uint16_t mode, int16_t argc, char* argn[], char* argv[], NPSavedData* saved);
typedef NPError (* NP_LOADDS NPP_DestroyProcPtr)(NPP instance, NPSavedData** save);
typedef NPError (* NP_LOADDS NPP_SetWindowProcPtr)(NPP instance, NPWindow* window);
typedef NPError (* NP_LOADDS NPP_NewStreamProcPtr)(NPP instance, NPMIMEType type, NPStream* stream, NPBool seekable, uint16_t* stype);
typedef NPError (* NP_LOADDS NPP_DestroyStreamProcPtr)(NPP instance, NPStream* stream, NPReason reason);
typedef int32_t (* NP_LOADDS NPP_WriteReadyProcPtr)(NPP instance, NPStream* stream);
typedef int32_t (* NP_LOADDS NPP_WriteProcPtr)(NPP instance, NPStream* stream, int32_t offset, int32_t len, void* buffer);
typedef void (* NP_LOADDS NPP_StreamAsFileProcPtr)(NPP instance, NPStream* stream, const char* fname);
typedef void (* NP_LOADDS NPP_PrintProcPtr)(NPP instance, NPPrint* platformPrint);
typedef int16_t (* NP_LOADDS NPP_HandleEventProcPtr)(NPP instance, void* event);
typedef void (* NP_LOADDS NPP_URLNotifyProcPtr)(NPP instance, const char* url, NPReason reason, void* notifyData);
/* Any NPObjects returned to the browser via NPP_GetValue should be retained
by the plugin on the way out. The browser is responsible for releasing. */
typedef NPError (* NP_LOADDS NPP_GetValueProcPtr)(NPP instance, NPPVariable variable, void *ret_value);
typedef NPError (* NP_LOADDS NPP_SetValueProcPtr)(NPP instance, NPNVariable variable, void *value);
typedef NPBool (* NP_LOADDS NPP_GotFocusPtr)(NPP instance, NPFocusDirection direction);
typedef void (* NP_LOADDS NPP_LostFocusPtr)(NPP instance);
typedef void (* NP_LOADDS NPP_URLRedirectNotifyPtr)(NPP instance, const char* url, int32_t status, void* notifyData);
typedef NPError (* NP_LOADDS NPP_ClearSiteDataPtr)(const char* site, uint64_t flags, uint64_t maxAge);
typedef char** (* NP_LOADDS NPP_GetSitesWithDataPtr)(void);
typedef NPError (*NPN_GetValueProcPtr)(NPP instance, NPNVariable variable, void *ret_value);
typedef NPError (*NPN_SetValueProcPtr)(NPP instance, NPPVariable variable, void *value);
typedef NPError (*NPN_GetURLNotifyProcPtr)(NPP instance, const char* url, const char* window, void* notifyData);
typedef NPError (*NPN_PostURLNotifyProcPtr)(NPP instance, const char* url, const char* window, uint32_t len, const char* buf, NPBool file, void* notifyData);
typedef NPError (*NPN_GetURLProcPtr)(NPP instance, const char* url, const char* window);
typedef NPError (*NPN_PostURLProcPtr)(NPP instance, const char* url, const char* window, uint32_t len, const char* buf, NPBool file);
typedef NPError (*NPN_RequestReadProcPtr)(NPStream* stream, NPByteRange* rangeList);
typedef NPError (*NPN_NewStreamProcPtr)(NPP instance, NPMIMEType type, const char* window, NPStream** stream);
typedef int32_t (*NPN_WriteProcPtr)(NPP instance, NPStream* stream, int32_t len, void* buffer);
typedef NPError (*NPN_DestroyStreamProcPtr)(NPP instance, NPStream* stream, NPReason reason);
typedef void (*NPN_StatusProcPtr)(NPP instance, const char* message);
/* Browser manages the lifetime of the buffer returned by NPN_UserAgent, don't
depend on it sticking around and don't free it. */
typedef const char* (*NPN_UserAgentProcPtr)(NPP instance);
typedef void* (*NPN_MemAllocProcPtr)(uint32_t size);
typedef void (*NPN_MemFreeProcPtr)(void* ptr);
typedef uint32_t (*NPN_MemFlushProcPtr)(uint32_t size);
typedef void (*NPN_ReloadPluginsProcPtr)(NPBool reloadPages);
typedef void* (*NPN_GetJavaEnvProcPtr)(void);
typedef void* (*NPN_GetJavaPeerProcPtr)(NPP instance);
typedef void (*NPN_InvalidateRectProcPtr)(NPP instance, NPRect *rect);
typedef void (*NPN_InvalidateRegionProcPtr)(NPP instance, NPRegion region);
typedef void (*NPN_ForceRedrawProcPtr)(NPP instance);
typedef NPIdentifier (*NPN_GetStringIdentifierProcPtr)(const NPUTF8* name);
typedef void (*NPN_GetStringIdentifiersProcPtr)(const NPUTF8** names, int32_t nameCount, NPIdentifier* identifiers);
typedef NPIdentifier (*NPN_GetIntIdentifierProcPtr)(int32_t intid);
typedef bool (*NPN_IdentifierIsStringProcPtr)(NPIdentifier identifier);
typedef NPUTF8* (*NPN_UTF8FromIdentifierProcPtr)(NPIdentifier identifier);
typedef int32_t (*NPN_IntFromIdentifierProcPtr)(NPIdentifier identifier);
typedef NPObject* (*NPN_CreateObjectProcPtr)(NPP npp, NPClass *aClass);
typedef NPObject* (*NPN_RetainObjectProcPtr)(NPObject *obj);
typedef void (*NPN_ReleaseObjectProcPtr)(NPObject *obj);
typedef bool (*NPN_InvokeProcPtr)(NPP npp, NPObject* obj, NPIdentifier methodName, const NPVariant *args, uint32_t argCount, NPVariant *result);
typedef bool (*NPN_InvokeDefaultProcPtr)(NPP npp, NPObject* obj, const NPVariant *args, uint32_t argCount, NPVariant *result);
typedef bool (*NPN_EvaluateProcPtr)(NPP npp, NPObject *obj, NPString *script, NPVariant *result);
typedef bool (*NPN_GetPropertyProcPtr)(NPP npp, NPObject *obj, NPIdentifier propertyName, NPVariant *result);
typedef bool (*NPN_SetPropertyProcPtr)(NPP npp, NPObject *obj, NPIdentifier propertyName, const NPVariant *value);
typedef bool (*NPN_RemovePropertyProcPtr)(NPP npp, NPObject *obj, NPIdentifier propertyName);
typedef bool (*NPN_HasPropertyProcPtr)(NPP npp, NPObject *obj, NPIdentifier propertyName);
typedef bool (*NPN_HasMethodProcPtr)(NPP npp, NPObject *obj, NPIdentifier propertyName);
typedef void (*NPN_ReleaseVariantValueProcPtr)(NPVariant *variant);
typedef void (*NPN_SetExceptionProcPtr)(NPObject *obj, const NPUTF8 *message);
typedef void (*NPN_PushPopupsEnabledStateProcPtr)(NPP npp, NPBool enabled);
typedef void (*NPN_PopPopupsEnabledStateProcPtr)(NPP npp);
typedef bool (*NPN_EnumerateProcPtr)(NPP npp, NPObject *obj, NPIdentifier **identifier, uint32_t *count);
typedef void (*NPN_PluginThreadAsyncCallProcPtr)(NPP instance, void (*func)(void *), void *userData);
typedef bool (*NPN_ConstructProcPtr)(NPP npp, NPObject* obj, const NPVariant *args, uint32_t argCount, NPVariant *result);
typedef NPError (*NPN_GetValueForURLPtr)(NPP npp, NPNURLVariable variable, const char *url, char **value, uint32_t *len);
typedef NPError (*NPN_SetValueForURLPtr)(NPP npp, NPNURLVariable variable, const char *url, const char *value, uint32_t len);
typedef NPError (*NPN_GetAuthenticationInfoPtr)(NPP npp, const char *protocol, const char *host, int32_t port, const char *scheme, const char *realm, char **username, uint32_t *ulen, char **password, uint32_t *plen);
typedef uint32_t (*NPN_ScheduleTimerPtr)(NPP instance, uint32_t interval, NPBool repeat, void (*timerFunc)(NPP npp, uint32_t timerID));
typedef void (*NPN_UnscheduleTimerPtr)(NPP instance, uint32_t timerID);
typedef NPError (*NPN_PopUpContextMenuPtr)(NPP instance, NPMenu* menu);
typedef NPBool (*NPN_ConvertPointPtr)(NPP instance, double sourceX, double sourceY, NPCoordinateSpace sourceSpace, double *destX, double *destY, NPCoordinateSpace destSpace);
typedef NPBool (*NPN_HandleEventPtr)(NPP instance, void *event, NPBool handled);
typedef NPBool (*NPN_UnfocusInstancePtr)(NPP instance, NPFocusDirection direction);
typedef void (*NPN_URLRedirectResponsePtr)(NPP instance, void* notifyData, NPBool allow);
typedef struct _NPPluginFuncs {
uint16_t size;
uint16_t version;
NPP_NewProcPtr newp;
NPP_DestroyProcPtr destroy;
NPP_SetWindowProcPtr setwindow;
NPP_NewStreamProcPtr newstream;
NPP_DestroyStreamProcPtr destroystream;
NPP_StreamAsFileProcPtr asfile;
NPP_WriteReadyProcPtr writeready;
NPP_WriteProcPtr write;
NPP_PrintProcPtr print;
NPP_HandleEventProcPtr event;
NPP_URLNotifyProcPtr urlnotify;
void* javaClass;
NPP_GetValueProcPtr getvalue;
NPP_SetValueProcPtr setvalue;
NPP_GotFocusPtr gotfocus;
NPP_LostFocusPtr lostfocus;
NPP_URLRedirectNotifyPtr urlredirectnotify;
NPP_ClearSiteDataPtr clearsitedata;
NPP_GetSitesWithDataPtr getsiteswithdata;
} NPPluginFuncs;
typedef struct _NPNetscapeFuncs {
uint16_t size;
uint16_t version;
NPN_GetURLProcPtr geturl;
NPN_PostURLProcPtr posturl;
NPN_RequestReadProcPtr requestread;
NPN_NewStreamProcPtr newstream;
NPN_WriteProcPtr write;
NPN_DestroyStreamProcPtr destroystream;
NPN_StatusProcPtr status;
NPN_UserAgentProcPtr uagent;
NPN_MemAllocProcPtr memalloc;
NPN_MemFreeProcPtr memfree;
NPN_MemFlushProcPtr memflush;
NPN_ReloadPluginsProcPtr reloadplugins;
NPN_GetJavaEnvProcPtr getJavaEnv;
NPN_GetJavaPeerProcPtr getJavaPeer;
NPN_GetURLNotifyProcPtr geturlnotify;
NPN_PostURLNotifyProcPtr posturlnotify;
NPN_GetValueProcPtr getvalue;
NPN_SetValueProcPtr setvalue;
NPN_InvalidateRectProcPtr invalidaterect;
NPN_InvalidateRegionProcPtr invalidateregion;
NPN_ForceRedrawProcPtr forceredraw;
NPN_GetStringIdentifierProcPtr getstringidentifier;
NPN_GetStringIdentifiersProcPtr getstringidentifiers;
NPN_GetIntIdentifierProcPtr getintidentifier;
NPN_IdentifierIsStringProcPtr identifierisstring;
NPN_UTF8FromIdentifierProcPtr utf8fromidentifier;
NPN_IntFromIdentifierProcPtr intfromidentifier;
NPN_CreateObjectProcPtr createobject;
NPN_RetainObjectProcPtr retainobject;
NPN_ReleaseObjectProcPtr releaseobject;
NPN_InvokeProcPtr invoke;
NPN_InvokeDefaultProcPtr invokeDefault;
NPN_EvaluateProcPtr evaluate;
NPN_GetPropertyProcPtr getproperty;
NPN_SetPropertyProcPtr setproperty;
NPN_RemovePropertyProcPtr removeproperty;
NPN_HasPropertyProcPtr hasproperty;
NPN_HasMethodProcPtr hasmethod;
NPN_ReleaseVariantValueProcPtr releasevariantvalue;
NPN_SetExceptionProcPtr setexception;
NPN_PushPopupsEnabledStateProcPtr pushpopupsenabledstate;
NPN_PopPopupsEnabledStateProcPtr poppopupsenabledstate;
NPN_EnumerateProcPtr enumerate;
NPN_PluginThreadAsyncCallProcPtr pluginthreadasynccall;
NPN_ConstructProcPtr construct;
NPN_GetValueForURLPtr getvalueforurl;
NPN_SetValueForURLPtr setvalueforurl;
NPN_GetAuthenticationInfoPtr getauthenticationinfo;
NPN_ScheduleTimerPtr scheduletimer;
NPN_UnscheduleTimerPtr unscheduletimer;
NPN_PopUpContextMenuPtr popupcontextmenu;
NPN_ConvertPointPtr convertpoint;
NPN_HandleEventPtr handleevent;
NPN_UnfocusInstancePtr unfocusinstance;
NPN_URLRedirectResponsePtr urlredirectresponse;
} NPNetscapeFuncs;
#ifdef XP_MACOSX
/*
* Mac OS X version(s) of NP_GetMIMEDescription(const char *)
* These can be called to retreive MIME information from the plugin dynamically
*
* Note: For compatibility with Quicktime, BPSupportedMIMEtypes is another way
* to get mime info from the plugin only on OSX and may not be supported
* in furture version -- use NP_GetMIMEDescription instead
*/
enum
{
kBPSupportedMIMETypesStructVers_1 = 1
};
typedef struct _BPSupportedMIMETypes
{
SInt32 structVersion; /* struct version */
Handle typeStrings; /* STR# formated handle, allocated by plug-in */
Handle infoStrings; /* STR# formated handle, allocated by plug-in */
} BPSupportedMIMETypes;
OSErr BP_GetSupportedMIMETypes(BPSupportedMIMETypes *mimeInfo, UInt32 flags);
#define NP_GETMIMEDESCRIPTION_NAME "NP_GetMIMEDescription"
typedef const char* (*NP_GetMIMEDescriptionProcPtr)(void);
typedef OSErr (*BP_GetSupportedMIMETypesProcPtr)(BPSupportedMIMETypes*, UInt32);
#endif
#if defined(_WIN32)
#define OSCALL WINAPI
#else
#if defined(__OS2__)
#define OSCALL _System
#else
#define OSCALL
#endif
#endif
#if defined(XP_UNIX)
/* GCC 3.3 and later support the visibility attribute. */
#if defined(__GNUC__) && ((__GNUC__ >= 4) || (__GNUC__ == 3 && __GNUC_MINOR__ >= 3))
#define NP_VISIBILITY_DEFAULT __attribute__((visibility("default")))
#elif defined(__SUNPRO_C) || defined(__SUNPRO_CC)
#define NP_VISIBILITY_DEFAULT __global
#else
#define NP_VISIBILITY_DEFAULT
#endif
#define NP_EXPORT(__type) NP_VISIBILITY_DEFAULT __type
#endif
#if defined(_WIN32) || defined (__OS2__)
#ifdef __cplusplus
extern "C" {
#endif
/* plugin meta member functions */
#if defined(__OS2__)
typedef struct _NPPluginData { /* Alternate OS2 Plugin interface */
char *pMimeTypes;
char *pFileExtents;
char *pFileOpenTemplate;
char *pProductName;
char *pProductDescription;
unsigned long dwProductVersionMS;
unsigned long dwProductVersionLS;
} NPPluginData;
typedef NPError (*NP_GetPluginDataFunc)(NPPluginData*);
NPError OSCALL NP_GetPluginData(NPPluginData * pPluginData);
#endif
typedef NPError (*NP_GetEntryPointsFunc)(NPPluginFuncs*);
NPError OSCALL NP_GetEntryPoints(NPPluginFuncs* pFuncs);
typedef NPError (*NP_InitializeFunc)(NPNetscapeFuncs*);
NPError OSCALL NP_Initialize(NPNetscapeFuncs* bFuncs);
typedef NPError (*NP_ShutdownFunc)(void);
NPError OSCALL NP_Shutdown(void);
typedef const char* (*NP_GetMIMEDescriptionFunc)(void);
const char* NP_GetMIMEDescription(void);
#ifdef __cplusplus
}
#endif
#endif
#if defined(__OS2__)
#pragma pack()
#endif
#ifdef XP_UNIX
#ifdef __cplusplus
extern "C" {
#endif
typedef char* (*NP_GetPluginVersionFunc)(void);
NP_EXPORT(char*) NP_GetPluginVersion(void);
typedef const char* (*NP_GetMIMEDescriptionFunc)(void);
NP_EXPORT(const char*) NP_GetMIMEDescription(void);
#ifdef XP_MACOSX
typedef NPError (*NP_InitializeFunc)(NPNetscapeFuncs*);
NP_EXPORT(NPError) NP_Initialize(NPNetscapeFuncs* bFuncs);
typedef NPError (*NP_GetEntryPointsFunc)(NPPluginFuncs*);
NP_EXPORT(NPError) NP_GetEntryPoints(NPPluginFuncs* pFuncs);
#else
typedef NPError (*NP_InitializeFunc)(NPNetscapeFuncs*, NPPluginFuncs*);
NP_EXPORT(NPError) NP_Initialize(NPNetscapeFuncs* bFuncs, NPPluginFuncs* pFuncs);
#endif
typedef NPError (*NP_ShutdownFunc)(void);
NP_EXPORT(NPError) NP_Shutdown(void);
typedef NPError (*NP_GetValueFunc)(void *, NPPVariable, void *);
NP_EXPORT(NPError) NP_GetValue(void *future, NPPVariable aVariable, void *aValue);
#ifdef __cplusplus
}
#endif
#endif
#endif /* npfunctions_h_ */

View File

@ -1,393 +0,0 @@
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
* Copyright (c) 2004, Apple Computer, Inc. and The Mozilla Foundation.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the names of Apple Computer, Inc. ("Apple") or The Mozilla
* Foundation ("Mozilla") nor the names of their contributors may be used
* to endorse or promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY APPLE, MOZILLA AND THEIR CONTRIBUTORS "AS
* IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE, MOZILLA OR
* THEIR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
* TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#ifndef _NP_RUNTIME_H_
#define _NP_RUNTIME_H_
#ifdef __cplusplus
extern "C" {
#endif
#include "nptypes.h"
/*
This API is used to facilitate binding code written in C to script
objects. The API in this header does not assume the presence of a
user agent. That is, it can be used to bind C code to scripting
environments outside of the context of a user agent.
However, the normal use of the this API is in the context of a
scripting environment running in a browser or other user agent.
In particular it is used to support the extended Netscape
script-ability API for plugins (NP-SAP). NP-SAP is an extension
of the Netscape plugin API. As such we have adopted the use of
the "NP" prefix for this API.
The following NP{N|P}Variables were added to the Netscape plugin
API (in npapi.h):
NPNVWindowNPObject
NPNVPluginElementNPObject
NPPVpluginScriptableNPObject
These variables are exposed through NPN_GetValue() and
NPP_GetValue() (respectively) and are used to establish the
initial binding between the user agent and native code. The DOM
objects in the user agent can be examined and manipulated using
the NPN_ functions that operate on NPObjects described in this
header.
To the extent possible the assumptions about the scripting
language used by the scripting environment have been minimized.
*/
#define NP_BEGIN_MACRO do {
#define NP_END_MACRO } while (0)
/*
Objects (non-primitive data) passed between 'C' and script is
always wrapped in an NPObject. The 'interface' of an NPObject is
described by an NPClass.
*/
typedef struct NPObject NPObject;
typedef struct NPClass NPClass;
typedef char NPUTF8;
typedef struct _NPString {
const NPUTF8 *UTF8Characters;
uint32_t UTF8Length;
} NPString;
typedef enum {
NPVariantType_Void,
NPVariantType_Null,
NPVariantType_Bool,
NPVariantType_Int32,
NPVariantType_Double,
NPVariantType_String,
NPVariantType_Object
} NPVariantType;
typedef struct _NPVariant {
NPVariantType type;
union {
bool boolValue;
int32_t intValue;
double doubleValue;
NPString stringValue;
NPObject *objectValue;
} value;
} NPVariant;
/*
NPN_ReleaseVariantValue is called on all 'out' parameters
references. Specifically it is to be called on variants that own
their value, as is the case with all non-const NPVariant*
arguments after a successful call to any methods (except this one)
in this API.
After calling NPN_ReleaseVariantValue, the type of the variant
will be NPVariantType_Void.
*/
void NPN_ReleaseVariantValue(NPVariant *variant);
#define NPVARIANT_IS_VOID(_v) ((_v).type == NPVariantType_Void)
#define NPVARIANT_IS_NULL(_v) ((_v).type == NPVariantType_Null)
#define NPVARIANT_IS_BOOLEAN(_v) ((_v).type == NPVariantType_Bool)
#define NPVARIANT_IS_INT32(_v) ((_v).type == NPVariantType_Int32)
#define NPVARIANT_IS_DOUBLE(_v) ((_v).type == NPVariantType_Double)
#define NPVARIANT_IS_STRING(_v) ((_v).type == NPVariantType_String)
#define NPVARIANT_IS_OBJECT(_v) ((_v).type == NPVariantType_Object)
#define NPVARIANT_TO_BOOLEAN(_v) ((_v).value.boolValue)
#define NPVARIANT_TO_INT32(_v) ((_v).value.intValue)
#define NPVARIANT_TO_DOUBLE(_v) ((_v).value.doubleValue)
#define NPVARIANT_TO_STRING(_v) ((_v).value.stringValue)
#define NPVARIANT_TO_OBJECT(_v) ((_v).value.objectValue)
#define VOID_TO_NPVARIANT(_v) \
NP_BEGIN_MACRO \
(_v).type = NPVariantType_Void; \
(_v).value.objectValue = NULL; \
NP_END_MACRO
#define NULL_TO_NPVARIANT(_v) \
NP_BEGIN_MACRO \
(_v).type = NPVariantType_Null; \
(_v).value.objectValue = NULL; \
NP_END_MACRO
#define BOOLEAN_TO_NPVARIANT(_val, _v) \
NP_BEGIN_MACRO \
(_v).type = NPVariantType_Bool; \
(_v).value.boolValue = !!(_val); \
NP_END_MACRO
#define INT32_TO_NPVARIANT(_val, _v) \
NP_BEGIN_MACRO \
(_v).type = NPVariantType_Int32; \
(_v).value.intValue = _val; \
NP_END_MACRO
#define DOUBLE_TO_NPVARIANT(_val, _v) \
NP_BEGIN_MACRO \
(_v).type = NPVariantType_Double; \
(_v).value.doubleValue = _val; \
NP_END_MACRO
#define STRINGZ_TO_NPVARIANT(_val, _v) \
NP_BEGIN_MACRO \
(_v).type = NPVariantType_String; \
NPString str = { _val, (uint32_t)(strlen(_val)) }; \
(_v).value.stringValue = str; \
NP_END_MACRO
#define STRINGN_TO_NPVARIANT(_val, _len, _v) \
NP_BEGIN_MACRO \
(_v).type = NPVariantType_String; \
NPString str = { _val, (uint32_t)(_len) }; \
(_v).value.stringValue = str; \
NP_END_MACRO
#define OBJECT_TO_NPVARIANT(_val, _v) \
NP_BEGIN_MACRO \
(_v).type = NPVariantType_Object; \
(_v).value.objectValue = _val; \
NP_END_MACRO
/*
Type mappings (JavaScript types have been used for illustration
purposes):
JavaScript to C (NPVariant with type:)
undefined NPVariantType_Void
null NPVariantType_Null
Boolean NPVariantType_Bool
Number NPVariantType_Double or NPVariantType_Int32
String NPVariantType_String
Object NPVariantType_Object
C (NPVariant with type:) to JavaScript
NPVariantType_Void undefined
NPVariantType_Null null
NPVariantType_Bool Boolean
NPVariantType_Int32 Number
NPVariantType_Double Number
NPVariantType_String String
NPVariantType_Object Object
*/
typedef void *NPIdentifier;
/*
NPObjects have methods and properties. Methods and properties are
identified with NPIdentifiers. These identifiers may be reflected
in script. NPIdentifiers can be either strings or integers, IOW,
methods and properties can be identified by either strings or
integers (i.e. foo["bar"] vs foo[1]). NPIdentifiers can be
compared using ==. In case of any errors, the requested
NPIdentifier(s) will be NULL. NPIdentifier lifetime is controlled
by the browser. Plugins do not need to worry about memory management
with regards to NPIdentifiers.
*/
NPIdentifier NPN_GetStringIdentifier(const NPUTF8 *name);
void NPN_GetStringIdentifiers(const NPUTF8 **names, int32_t nameCount,
NPIdentifier *identifiers);
NPIdentifier NPN_GetIntIdentifier(int32_t intid);
bool NPN_IdentifierIsString(NPIdentifier identifier);
/*
The NPUTF8 returned from NPN_UTF8FromIdentifier SHOULD be freed.
*/
NPUTF8 *NPN_UTF8FromIdentifier(NPIdentifier identifier);
/*
Get the integer represented by identifier. If identifier is not an
integer identifier, the behaviour is undefined.
*/
int32_t NPN_IntFromIdentifier(NPIdentifier identifier);
/*
NPObject behavior is implemented using the following set of
callback functions.
The NPVariant *result argument of these functions (where
applicable) should be released using NPN_ReleaseVariantValue().
*/
typedef NPObject *(*NPAllocateFunctionPtr)(NPP npp, NPClass *aClass);
typedef void (*NPDeallocateFunctionPtr)(NPObject *npobj);
typedef void (*NPInvalidateFunctionPtr)(NPObject *npobj);
typedef bool (*NPHasMethodFunctionPtr)(NPObject *npobj, NPIdentifier name);
typedef bool (*NPInvokeFunctionPtr)(NPObject *npobj, NPIdentifier name,
const NPVariant *args, uint32_t argCount,
NPVariant *result);
typedef bool (*NPInvokeDefaultFunctionPtr)(NPObject *npobj,
const NPVariant *args,
uint32_t argCount,
NPVariant *result);
typedef bool (*NPHasPropertyFunctionPtr)(NPObject *npobj, NPIdentifier name);
typedef bool (*NPGetPropertyFunctionPtr)(NPObject *npobj, NPIdentifier name,
NPVariant *result);
typedef bool (*NPSetPropertyFunctionPtr)(NPObject *npobj, NPIdentifier name,
const NPVariant *value);
typedef bool (*NPRemovePropertyFunctionPtr)(NPObject *npobj,
NPIdentifier name);
typedef bool (*NPEnumerationFunctionPtr)(NPObject *npobj, NPIdentifier **value,
uint32_t *count);
typedef bool (*NPConstructFunctionPtr)(NPObject *npobj,
const NPVariant *args,
uint32_t argCount,
NPVariant *result);
/*
NPObjects returned by create, retain, invoke, and getProperty pass
a reference count to the caller. That is, the callee adds a
reference count which passes to the caller. It is the caller's
responsibility to release the returned object.
NPInvokeFunctionPtr function may return 0 to indicate a void
result.
NPInvalidateFunctionPtr is called by the scripting environment
when the native code is shutdown. Any attempt to message a
NPObject instance after the invalidate callback has been
called will result in undefined behavior, even if the native code
is still retaining those NPObject instances. (The runtime
will typically return immediately, with 0 or NULL, from an attempt
to dispatch to a NPObject, but this behavior should not be
depended upon.)
The NPEnumerationFunctionPtr function may pass an array of
NPIdentifiers back to the caller. The callee allocs the memory of
the array using NPN_MemAlloc(), and it's the caller's responsibility
to release it using NPN_MemFree().
*/
struct NPClass
{
uint32_t structVersion;
NPAllocateFunctionPtr allocate;
NPDeallocateFunctionPtr deallocate;
NPInvalidateFunctionPtr invalidate;
NPHasMethodFunctionPtr hasMethod;
NPInvokeFunctionPtr invoke;
NPInvokeDefaultFunctionPtr invokeDefault;
NPHasPropertyFunctionPtr hasProperty;
NPGetPropertyFunctionPtr getProperty;
NPSetPropertyFunctionPtr setProperty;
NPRemovePropertyFunctionPtr removeProperty;
NPEnumerationFunctionPtr enumerate;
NPConstructFunctionPtr construct;
};
#define NP_CLASS_STRUCT_VERSION 3
#define NP_CLASS_STRUCT_VERSION_ENUM 2
#define NP_CLASS_STRUCT_VERSION_CTOR 3
#define NP_CLASS_STRUCT_VERSION_HAS_ENUM(npclass) \
((npclass)->structVersion >= NP_CLASS_STRUCT_VERSION_ENUM)
#define NP_CLASS_STRUCT_VERSION_HAS_CTOR(npclass) \
((npclass)->structVersion >= NP_CLASS_STRUCT_VERSION_CTOR)
struct NPObject {
NPClass *_class;
uint32_t referenceCount;
/*
* Additional space may be allocated here by types of NPObjects
*/
};
/*
If the class has an allocate function, NPN_CreateObject invokes
that function, otherwise a NPObject is allocated and
returned. This method will initialize the referenceCount member of
the NPObject to 1.
*/
NPObject *NPN_CreateObject(NPP npp, NPClass *aClass);
/*
Increment the NPObject's reference count.
*/
NPObject *NPN_RetainObject(NPObject *npobj);
/*
Decremented the NPObject's reference count. If the reference
count goes to zero, the class's destroy function is invoke if
specified, otherwise the object is freed directly.
*/
void NPN_ReleaseObject(NPObject *npobj);
/*
Functions to access script objects represented by NPObject.
Calls to script objects are synchronous. If a function returns a
value, it will be supplied via the result NPVariant
argument. Successful calls will return true, false will be
returned in case of an error.
Calls made from plugin code to script must be made from the thread
on which the plugin was initialized.
*/
bool NPN_Invoke(NPP npp, NPObject *npobj, NPIdentifier methodName,
const NPVariant *args, uint32_t argCount, NPVariant *result);
bool NPN_InvokeDefault(NPP npp, NPObject *npobj, const NPVariant *args,
uint32_t argCount, NPVariant *result);
bool NPN_Evaluate(NPP npp, NPObject *npobj, NPString *script,
NPVariant *result);
bool NPN_GetProperty(NPP npp, NPObject *npobj, NPIdentifier propertyName,
NPVariant *result);
bool NPN_SetProperty(NPP npp, NPObject *npobj, NPIdentifier propertyName,
const NPVariant *value);
bool NPN_RemoveProperty(NPP npp, NPObject *npobj, NPIdentifier propertyName);
bool NPN_HasProperty(NPP npp, NPObject *npobj, NPIdentifier propertyName);
bool NPN_HasMethod(NPP npp, NPObject *npobj, NPIdentifier methodName);
bool NPN_Enumerate(NPP npp, NPObject *npobj, NPIdentifier **identifier,
uint32_t *count);
bool NPN_Construct(NPP npp, NPObject *npobj, const NPVariant *args,
uint32_t argCount, NPVariant *result);
/*
NPN_SetException may be called to trigger a script exception upon
return from entry points into NPObjects. Typical usage:
NPN_SetException (npobj, message);
*/
void NPN_SetException(NPObject *npobj, const NPUTF8 *message);
#ifdef __cplusplus
}
#endif
#endif

View File

@ -1,121 +0,0 @@
/* -*- Mode: C; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is
* mozilla.org.
* Portions created by the Initial Developer are Copyright (C) 2004
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Johnny Stenback <jst@mozilla.org> (Original author)
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#ifndef nptypes_h_
#define nptypes_h_
/*
* Header file for ensuring that C99 types ([u]int32_t, [u]int64_t and bool) and
* true/false macros are available.
*/
#if defined(WIN32) || defined(OS2)
/*
* Win32 and OS/2 don't know C99, so define [u]int_16/32/64 here. The bool
* is predefined tho, both in C and C++.
*/
typedef short int16_t;
typedef unsigned short uint16_t;
typedef int int32_t;
typedef unsigned int uint32_t;
typedef long long int64_t;
typedef unsigned long long uint64_t;
#elif defined(_AIX) || defined(__sun) || defined(__osf__) || defined(IRIX) || defined(HPUX)
/*
* AIX and SunOS ship a inttypes.h header that defines [u]int32_t,
* but not bool for C.
*/
#include <inttypes.h>
#ifndef __cplusplus
typedef int bool;
#define true 1
#define false 0
#endif
#elif defined(bsdi) || defined(FREEBSD) || defined(OPENBSD)
/*
* BSD/OS, FreeBSD, and OpenBSD ship sys/types.h that define int32_t and
* u_int32_t.
*/
#include <sys/types.h>
/*
* BSD/OS ships no header that defines uint32_t, nor bool (for C)
*/
#if defined(bsdi)
typedef u_int32_t uint32_t;
typedef u_int64_t uint64_t;
#if !defined(__cplusplus)
typedef int bool;
#define true 1
#define false 0
#endif
#else
/*
* FreeBSD and OpenBSD define uint32_t and bool.
*/
#include <inttypes.h>
#include <stdbool.h>
#endif
#elif defined(BEOS)
#include <inttypes.h>
#else
/*
* For those that ship a standard C99 stdint.h header file, include
* it. Can't do the same for stdbool.h tho, since some systems ship
* with a stdbool.h file that doesn't compile!
*/
#include <stdint.h>
#ifndef __cplusplus
#if !defined(__GNUC__) || (__GNUC__ > 2 || __GNUC_MINOR__ > 95)
#include <stdbool.h>
#else
/*
* GCC 2.91 can't deal with a typedef for bool, but a #define
* works.
*/
#define bool int
#define true 1
#define false 0
#endif
#endif
#endif
#endif /* nptypes_h_ */

View File

@ -1,5 +1,6 @@
dbus_interfaces = [
'org.gnome.Shell.Extensions.xml',
'org.gnome.Shell.Introspect.xml',
'org.gnome.Shell.PadOsd.xml',
'org.gnome.Shell.Screencast.xml',
'org.gnome.Shell.Screenshot.xml',

View File

@ -0,0 +1,61 @@
<!DOCTYPE node PUBLIC
'-//freedesktop//DTD D-BUS Object Introspection 1.0//EN'
'http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd'>
<node>
<!--
org.gnome.Shell.Introspect:
@short_description: Introspection interface
The interface used to introspect the state of Shell, such as running
applications, currently active application, etc.
-->
<interface name="org.gnome.Shell.Introspect">
<!--
RunningApplicationsChanged:
@short_description: Notifies when the running applications changes
-->
<signal name="RunningApplicationsChanged" />
<!--
GetRunningApplications:
@short_description: Retrieves the description of all running applications
Each application is associated by an application ID. The details of
each application consists of a varlist of keys and values. Available
keys are listed below.
'active-on-seats' - (as) list of seats the application is active on
(a seat only has at most one active
application)
-->
<method name="GetRunningApplications">
<arg name="apps" direction="out" type="a{sa{sv}}" />
</method>
<!--
GetWindows:
@short_description: Retrieves the current list of windows and their properties
A window is exposed as:
* t ID: unique ID of the window
* a{sv} properties: high-level properties
Known properties:
- "title" (s): (readonly) title of the window
- "app-id" (s): (readonly) application ID of the window
- "wm-class" (s): (readonly) class of the window
- "client-type" (u): (readonly) 0 for Wayland, 1 for X11
- "is-hidden" (b): (readonly) if the window is currently hidden
- "has-focus" (b): (readonly) if the window currently have
keyboard focus
- "width" (u): (readonly) width of the window
- "height" (u): (readonly) height of the window
-->
<method name="GetWindows">
<arg name="windows" direction="out" type="a{ta{sv}}" />
</method>
</interface>
</node>

View File

@ -40,6 +40,7 @@
<file preprocess="xml-stripblanks">org.gnome.SettingsDaemon.Wacom.xml</file>
<file preprocess="xml-stripblanks">org.gnome.Shell.AudioDeviceSelection.xml</file>
<file preprocess="xml-stripblanks">org.gnome.Shell.Extensions.xml</file>
<file preprocess="xml-stripblanks">org.gnome.Shell.Introspect.xml</file>
<file preprocess="xml-stripblanks">org.gnome.Shell.HotplugSniffer.xml</file>
<file preprocess="xml-stripblanks">org.gnome.Shell.PerfHelper.xml</file>
<file preprocess="xml-stripblanks">org.gnome.Shell.PortalHelper.xml</file>

View File

@ -1,18 +1,11 @@
<?xml version="1.0" encoding="UTF-8"?>
<gresources>
<gresource prefix="/org/gnome/shell/theme">
<file>calendar-arrow-left.svg</file>
<file>calendar-arrow-right.svg</file>
<file>calendar-today.svg</file>
<file>checkbox-focused.svg</file>
<file>checkbox-off-focused.svg</file>
<file>checkbox-off.svg</file>
<file>checkbox.svg</file>
<file>close-window.svg</file>
<file>close-window-active.svg</file>
<file>close-window-hover.svg</file>
<file>corner-ripple-ltr.png</file>
<file>corner-ripple-rtl.png</file>
<file>dash-placeholder.svg</file>
<file>gnome-shell.css</file>
<file>gnome-shell-high-contrast.css</file>
@ -27,10 +20,6 @@
<file>no-notifications.svg</file>
<file>noise-texture.png</file>
<file>pad-osd.css</file>
<file>page-indicator-active.svg</file>
<file>page-indicator-inactive.svg</file>
<file>page-indicator-checked.svg</file>
<file>page-indicator-hover.svg</file>
<file>process-working.svg</file>
<file>toggle-off-us.svg</file>
<file>toggle-off-intl.svg</file>

View File

@ -90,19 +90,20 @@
adapter is ever seen not to have devices associated to it.
</description>
</key>
<key name="introspect" type="b">
<default>false</default>
<summary>Enable introspection API</summary>
<description>
Enables a D-Bus API that allows to introspect the application state of
the shell.
</description>
</key>
<child name="keybindings" schema="org.gnome.shell.keybindings"/>
<child name="keyboard" schema="org.gnome.shell.keyboard"/>
</schema>
<schema id="org.gnome.shell.keybindings" path="/org/gnome/shell/keybindings/"
gettext-domain="@GETTEXT_PACKAGE@">
<key name="open-application-menu" type="as">
<default>["&lt;Super&gt;F10"]</default>
<summary>Keybinding to open the application menu</summary>
<description>
Keybinding to open the application menu.
</description>
</key>
<key name="toggle-application-view" type="as">
<default>["&lt;Super&gt;a"]</default>
<summary>Keybinding to open the “Show Applications” view</summary>

View File

@ -1,82 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="16"
height="16"
id="svg2"
version="1.1"
inkscape:version="0.48+devel r9942 custom"
sodipodi:docname="New document 4">
<defs
id="defs4" />
<sodipodi:namedview
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="1"
inkscape:cx="8.984481"
inkscape:cy="5.6224906"
inkscape:document-units="px"
inkscape:current-layer="layer1"
showgrid="false"
borderlayer="true"
inkscape:showpageshadow="false"
inkscape:window-width="930"
inkscape:window-height="681"
inkscape:window-x="1892"
inkscape:window-y="272"
inkscape:window-maximized="0">
<inkscape:grid
type="xygrid"
id="grid17403"
empspacing="5"
visible="true"
enabled="true"
snapvisiblegridlinesonly="true" />
</sodipodi:namedview>
<metadata
id="metadata7">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title></dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<g
inkscape:label="Layer 1"
inkscape:groupmode="layer"
id="layer1"
transform="translate(0,-1036.3622)">
<path
sodipodi:type="star"
style="fill:#5f5f5f;fill-opacity:1;stroke:#5f5f5f;stroke-width:0.43015847;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;display:inline"
id="path18028"
sodipodi:sides="3"
sodipodi:cx="84.5"
sodipodi:cy="337.5"
sodipodi:r1="5"
sodipodi:r2="2.5"
sodipodi:arg1="0.52359878"
sodipodi:arg2="1.5707963"
inkscape:flatsided="true"
inkscape:rounded="0"
inkscape:randomized="0"
d="M 88.830127,340 80.169873,340 84.5,332.5 z"
transform="matrix(0,1.3621708,0.99186247,0,-325.48222,929.32667)" />
</g>
</svg>

Before

Width:  |  Height:  |  Size: 2.5 KiB

View File

@ -1,82 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="16"
height="16"
id="svg2"
version="1.1"
inkscape:version="0.48+devel r9942 custom"
sodipodi:docname="arrow-left.svg">
<defs
id="defs4" />
<sodipodi:namedview
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="1"
inkscape:cx="7.7366092"
inkscape:cy="6.4536271"
inkscape:document-units="px"
inkscape:current-layer="layer1"
showgrid="false"
borderlayer="true"
inkscape:showpageshadow="false"
inkscape:window-width="930"
inkscape:window-height="681"
inkscape:window-x="1892"
inkscape:window-y="272"
inkscape:window-maximized="0">
<inkscape:grid
type="xygrid"
id="grid17403"
empspacing="5"
visible="true"
enabled="true"
snapvisiblegridlinesonly="true" />
</sodipodi:namedview>
<metadata
id="metadata7">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title></dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<g
inkscape:label="Layer 1"
inkscape:groupmode="layer"
id="layer1"
transform="translate(0,-1036.3622)">
<path
sodipodi:type="star"
style="fill:#5f5f5f;fill-opacity:1;stroke:#5f5f5f;stroke-width:0.43015847;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;display:inline"
id="path18028"
sodipodi:sides="3"
sodipodi:cx="84.5"
sodipodi:cy="337.5"
sodipodi:r1="5"
sodipodi:r2="2.5"
sodipodi:arg1="0.52359878"
sodipodi:arg2="1.5707963"
inkscape:flatsided="true"
inkscape:rounded="0"
inkscape:randomized="0"
d="M 88.830127,340 80.169873,340 84.5,332.5 z"
transform="matrix(0,1.3621708,-0.99186247,0,342.48324,929.32667)" />
</g>
</svg>

Before

Width:  |  Height:  |  Size: 2.5 KiB

View File

@ -1,81 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Generator: Adobe Illustrator 13.0.2, SVG Export Plug-In . SVG Version: 6.00 Build 14948) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
version="1.0"
id="Foreground"
x="0px"
y="0px"
width="32"
height="32"
viewBox="0 0 32 32"
enable-background="new 0 0 16 16"
xml:space="preserve"
sodipodi:version="0.32"
inkscape:version="0.92.2 5c3e80d, 2017-08-06"
sodipodi:docname="close-window-active.svg"
inkscape:output_extension="org.inkscape.output.svg.inkscape"><metadata
id="metadata2399"><rdf:RDF><cc:Work
rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" /><dc:title></dc:title></cc:Work></rdf:RDF></metadata><defs
id="defs2397"><linearGradient
id="linearGradient3173"><stop
style="stop-color:#c4c4c4;stop-opacity:1;"
offset="0"
id="stop3175" /><stop
style="stop-color:#ffffff;stop-opacity:1;"
offset="1"
id="stop3177" /></linearGradient><inkscape:perspective
sodipodi:type="inkscape:persp3d"
inkscape:vp_x="0 : 11 : 1"
inkscape:vp_y="0 : 1375 : 0"
inkscape:vp_z="22 : 11 : 1"
inkscape:persp3d-origin="11 : 7.3333334 : 1"
id="perspective2401" /></defs><sodipodi:namedview
inkscape:window-height="1106"
inkscape:window-width="1700"
inkscape:pageshadow="2"
inkscape:pageopacity="0"
guidetolerance="10.0"
gridtolerance="10.0"
objecttolerance="10.0"
borderopacity="1.0"
bordercolor="#666666"
pagecolor="#797979"
id="base"
showgrid="false"
inkscape:zoom="4"
inkscape:cx="28.483745"
inkscape:cy="67.714004"
inkscape:window-x="1427"
inkscape:window-y="127"
inkscape:current-layer="Foreground"
showguides="true"
inkscape:guide-bbox="true"
borderlayer="true"
inkscape:showpageshadow="false"
inkscape:window-maximized="0"
inkscape:document-rotation="0"><inkscape:grid
type="xygrid"
id="grid11246"
empspacing="32"
visible="true"
enabled="true"
snapvisiblegridlinesonly="true" /></sodipodi:namedview><path
d="m 4.4362021,16 c 0,-6.410121 5.1728276,-11.60728 11.5529359,-11.60728 6.380109,0 11.552937,5.197159 11.552937,11.60728 0,6.410122 -5.172828,11.607281 -11.552937,11.607281 C 9.6090297,27.607281 4.4362021,22.410122 4.4362021,16 Z"
id="path883"
style="color:#000000;clip-rule:evenodd;display:inline;overflow:visible;visibility:visible;fill:#a5c8ec;fill-opacity:1;fill-rule:nonzero;stroke:#2975c4;stroke-width:4;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;enable-background:accumulate"
sodipodi:nodetypes="csssc"
inkscape:connector-curvature="0" /><path
d="m 11.718386,11.764547 h 1.055207 c 0.01091,-1.26e-4 0.02193,-4.86e-4 0.03298,0 0.269026,0.01183 0.538019,0.135679 0.725455,0.329752 l 2.407192,2.407192 2.440166,-2.407192 c 0.28029,-0.243226 0.471333,-0.322366 0.725455,-0.329752 h 1.055207 v 1.055208 c 0,0.302285 -0.03623,0.581049 -0.263801,0.791405 l -2.407191,2.407191 2.374217,2.374216 c 0.198577,0.198559 0.296768,0.478484 0.296775,0.758432 v 1.055206 h -1.055211 c -0.279947,-10e-6 -0.559877,-0.09824 -0.75843,-0.296777 l -2.407192,-2.407192 -2.407192,2.407192 c -0.198551,0.198579 -0.478493,0.296777 -0.758429,0.296777 H 11.71839 v -1.055206 c -3e-6,-0.279936 0.0982,-0.559873 0.296777,-0.758432 L 14.422359,16.018351 12.015167,13.61116 C 11.79279,13.405784 11.69527,13.116003 11.71839,12.819755 Z"
inkscape:connector-curvature="0"
id="path887"
style="color:#bebebe;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:'Andale Mono';-inkscape-font-specification:'Andale Mono';text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;letter-spacing:normal;word-spacing:normal;text-transform:none;writing-mode:lr-tb;direction:ltr;text-anchor:start;display:inline;overflow:visible;visibility:visible;fill:#4a90d9;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.87958801;marker:none;enable-background:new"
sodipodi:nodetypes="ccsccccccccccccccccccccccc" /></svg>

Before

Width:  |  Height:  |  Size: 4.6 KiB

View File

@ -1,81 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Generator: Adobe Illustrator 13.0.2, SVG Export Plug-In . SVG Version: 6.00 Build 14948) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
version="1.0"
id="Foreground"
x="0px"
y="0px"
width="32"
height="32"
viewBox="0 0 32 32"
enable-background="new 0 0 16 16"
xml:space="preserve"
sodipodi:version="0.32"
inkscape:version="0.92.2 5c3e80d, 2017-08-06"
sodipodi:docname="close-window-hover.svg"
inkscape:output_extension="org.inkscape.output.svg.inkscape"><metadata
id="metadata2399"><rdf:RDF><cc:Work
rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" /><dc:title /></cc:Work></rdf:RDF></metadata><defs
id="defs2397"><linearGradient
id="linearGradient3173"><stop
style="stop-color:#c4c4c4;stop-opacity:1;"
offset="0"
id="stop3175" /><stop
style="stop-color:#ffffff;stop-opacity:1;"
offset="1"
id="stop3177" /></linearGradient><inkscape:perspective
sodipodi:type="inkscape:persp3d"
inkscape:vp_x="0 : 11 : 1"
inkscape:vp_y="0 : 1375 : 0"
inkscape:vp_z="22 : 11 : 1"
inkscape:persp3d-origin="11 : 7.3333334 : 1"
id="perspective2401" /></defs><sodipodi:namedview
inkscape:window-height="1106"
inkscape:window-width="1700"
inkscape:pageshadow="2"
inkscape:pageopacity="0"
guidetolerance="10.0"
gridtolerance="10.0"
objecttolerance="10.0"
borderopacity="1.0"
bordercolor="#666666"
pagecolor="#797979"
id="base"
showgrid="false"
inkscape:zoom="4"
inkscape:cx="28.483745"
inkscape:cy="67.714004"
inkscape:window-x="1427"
inkscape:window-y="127"
inkscape:current-layer="Foreground"
showguides="true"
inkscape:guide-bbox="true"
borderlayer="true"
inkscape:showpageshadow="false"
inkscape:window-maximized="0"
inkscape:document-rotation="0"><inkscape:grid
type="xygrid"
id="grid11246"
empspacing="32"
visible="true"
enabled="true"
snapvisiblegridlinesonly="true" /></sodipodi:namedview><path
inkscape:connector-curvature="0"
sodipodi:nodetypes="csssc"
style="color:#000000;clip-rule:evenodd;display:inline;overflow:visible;visibility:visible;fill:#2975c4;fill-opacity:1;fill-rule:nonzero;stroke:#ffffff;stroke-width:4;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;enable-background:accumulate"
id="path822"
d="m 4.4362021,16 c 0,-6.410121 5.1728276,-11.60728 11.5529359,-11.60728 6.380109,0 11.552937,5.197159 11.552937,11.60728 0,6.410122 -5.172828,11.607281 -11.552937,11.607281 C 9.6090297,27.607281 4.4362021,22.410122 4.4362021,16 Z" /><path
sodipodi:nodetypes="ccsccccccccccccccccccccccc"
style="color:#bebebe;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:'Andale Mono';-inkscape-font-specification:'Andale Mono';text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;letter-spacing:normal;word-spacing:normal;text-transform:none;writing-mode:lr-tb;direction:ltr;text-anchor:start;display:inline;overflow:visible;visibility:visible;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.87958801;marker:none;enable-background:new"
id="path826"
inkscape:connector-curvature="0"
d="m 11.718386,11.764547 h 1.055207 c 0.01091,-1.26e-4 0.02193,-4.86e-4 0.03298,0 0.269026,0.01183 0.538019,0.135679 0.725455,0.329752 l 2.407192,2.407192 2.440166,-2.407192 c 0.28029,-0.243226 0.471333,-0.322366 0.725455,-0.329752 h 1.055207 v 1.055208 c 0,0.302285 -0.03623,0.581049 -0.263801,0.791405 l -2.407191,2.407191 2.374217,2.374216 c 0.198577,0.198559 0.296768,0.478484 0.296775,0.758432 v 1.055206 h -1.055211 c -0.279947,-10e-6 -0.559877,-0.09824 -0.75843,-0.296777 l -2.407192,-2.407192 -2.407192,2.407192 c -0.198551,0.198579 -0.478493,0.296777 -0.758429,0.296777 H 11.71839 v -1.055206 c -3e-6,-0.279936 0.0982,-0.559873 0.296777,-0.758432 L 14.422359,16.018351 12.015167,13.61116 C 11.79279,13.405784 11.69527,13.116003 11.71839,12.819755 Z" /></svg>

Before

Width:  |  Height:  |  Size: 4.6 KiB

View File

@ -1,85 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Generator: Adobe Illustrator 13.0.2, SVG Export Plug-In . SVG Version: 6.00 Build 14948) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
version="1.0"
id="Foreground"
x="0px"
y="0px"
width="32"
height="32"
viewBox="0 0 32 32"
enable-background="new 0 0 16 16"
xml:space="preserve"
sodipodi:version="0.32"
inkscape:version="0.92.2 5c3e80d, 2017-08-06"
sodipodi:docname="close-window.svg"
inkscape:output_extension="org.inkscape.output.svg.inkscape"><metadata
id="metadata2399"><rdf:RDF><cc:Work
rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" /><dc:title></dc:title></cc:Work></rdf:RDF></metadata><defs
id="defs2397"><linearGradient
id="linearGradient3173"><stop
style="stop-color:#c4c4c4;stop-opacity:1;"
offset="0"
id="stop3175" /><stop
style="stop-color:#ffffff;stop-opacity:1;"
offset="1"
id="stop3177" /></linearGradient><inkscape:perspective
sodipodi:type="inkscape:persp3d"
inkscape:vp_x="0 : 11 : 1"
inkscape:vp_y="0 : 1375 : 0"
inkscape:vp_z="22 : 11 : 1"
inkscape:persp3d-origin="11 : 7.3333334 : 1"
id="perspective2401" /></defs><sodipodi:namedview
inkscape:window-height="1106"
inkscape:window-width="1700"
inkscape:pageshadow="2"
inkscape:pageopacity="0"
guidetolerance="10.0"
gridtolerance="10.0"
objecttolerance="10.0"
borderopacity="1.0"
bordercolor="#666666"
pagecolor="#797979"
id="base"
showgrid="false"
inkscape:zoom="4"
inkscape:cx="28.483745"
inkscape:cy="67.714004"
inkscape:window-x="1427"
inkscape:window-y="127"
inkscape:current-layer="Foreground"
showguides="true"
inkscape:guide-bbox="true"
borderlayer="true"
inkscape:showpageshadow="false"
inkscape:window-maximized="0"
inkscape:document-rotation="0"><inkscape:grid
type="xygrid"
id="grid11246"
empspacing="32"
visible="true"
enabled="true"
snapvisiblegridlinesonly="true" /></sodipodi:namedview><path
d="m 4.4362021,15.860384 c 0,-6.410121 5.1728276,-11.60728 11.5529359,-11.60728 6.380109,0 11.552937,5.197159 11.552937,11.60728 0,6.410122 -5.172828,11.607281 -11.552937,11.607281 -6.3801083,0 -11.5529359,-5.197159 -11.5529359,-11.607281 z"
id="path2394-32"
style="color:#000000;clip-rule:evenodd;display:inline;overflow:visible;visibility:visible;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:#2975c4;stroke-width:4;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;enable-background:accumulate"
sodipodi:nodetypes="csssc"
inkscape:connector-curvature="0" /><path
style="color:#000000;display:inline;overflow:visible;visibility:visible;opacity:0.49900004;fill:#4a90d9;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.74932218;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;enable-background:accumulate"
d="m 6.4654832,15.001321 c -0.025906,0.288419 -0.044417,0.579469 -0.044417,0.874662 0,5.313347 4.2883848,9.621271 9.5768588,9.621271 5.288466,0 9.575143,-4.307924 9.575143,-9.621271 0,-0.295193 -0.01852,-0.586243 -0.04441,-0.874662 -0.440376,4.903023 -4.536071,8.746611 -9.53073,8.746611 -4.994659,0 -9.0920617,-3.843588 -9.5324391,-8.746611 z"
id="path2561"
inkscape:connector-curvature="0" /><path
d="m 11.718386,11.639547 h 1.055207 c 0.01091,-1.26e-4 0.02193,-4.86e-4 0.03298,0 0.269026,0.01183 0.538019,0.135679 0.725455,0.329752 l 2.407192,2.407192 2.440166,-2.407192 c 0.28029,-0.243226 0.471333,-0.322366 0.725455,-0.329752 h 1.055207 v 1.055208 c 0,0.302285 -0.03623,0.581049 -0.263801,0.791405 l -2.407191,2.407191 2.374217,2.374216 c 0.198577,0.198559 0.296768,0.478484 0.296775,0.758432 v 1.055206 h -1.055211 c -0.279947,-10e-6 -0.559877,-0.09824 -0.75843,-0.296777 l -2.407192,-2.407192 -2.407192,2.407192 c -0.198551,0.198579 -0.478493,0.296777 -0.758429,0.296777 H 11.71839 v -1.055206 c -3e-6,-0.279936 0.0982,-0.559873 0.296777,-0.758432 L 14.422359,15.893351 12.015167,13.48616 C 11.79279,13.280784 11.69527,12.991003 11.71839,12.694755 Z"
inkscape:connector-curvature="0"
id="path27279-0-5"
style="color:#bebebe;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:'Andale Mono';-inkscape-font-specification:'Andale Mono';text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;letter-spacing:normal;word-spacing:normal;text-transform:none;writing-mode:lr-tb;direction:ltr;text-anchor:start;display:inline;overflow:visible;visibility:visible;fill:#4a90d9;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.87958801;marker:none;enable-background:new"
sodipodi:nodetypes="ccsccccccccccccccccccccccc" /></svg>

Before

Width:  |  Height:  |  Size: 5.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.3 KiB

View File

@ -57,8 +57,8 @@ stage {
border-right-width: 1px;
@include button(normal);
&:insensitive { @include button(insensitive); }
&:focus { @include button(focus); }
&:hover { @include button(hover); }
&:focus { @include button(focus); }
&:active { @include button(active); }
padding: 12px;
@ -938,7 +938,6 @@ StScrollBar {
}
.pager-button {
color: white;
background-color: transparent;
width: 32px;
border-radius: 4px;
@ -946,13 +945,8 @@ StScrollBar {
&:active { background-color: transparentize($bg_color,0.95); }
}
.calendar-change-month-back { //arrow back
background-image: url("resource:///org/gnome/shell/theme/calendar-arrow-left.svg");
&:rtl { background-image: url("resource:///org/gnome/shell/theme/calendar-arrow-right.svg"); }
}
.calendar-change-month-forward { //arrow foreward
background-image: url("resource:///org/gnome/shell/theme/calendar-arrow-right.svg");
&:rtl { background-image: url("resource:///org/gnome/shell/theme/calendar-arrow-left.svg"); }
.calendar-change-month-back StIcon, .calendar-change-month-forward StIcon { // arrows
icon-size: 1.09em;
}
.calendar-day-base {
@ -1090,8 +1084,8 @@ StScrollBar {
background-color: $bg_color;
border: 2px solid $bg_color;
border-radius: 2px;
icon-size: 16px;
padding: 8px; }
icon-size: 32px !important;
padding: 6px; }
}
@ -1142,17 +1136,16 @@ StScrollBar {
& > StIcon { icon-size: 16px; }
}
//Activities Ripples
// Activities Ripples
.ripple-box {
width: 52px;
height: 52px;
background-image: url("resource:///org/gnome/shell/theme/corner-ripple-ltr.png");
background-size: contain;
border-radius: 0 0 52px 0; // radius the size of the box give us the curve
background-color: lighten(transparentize($selected_bg_color, 0.7), 40%);
box-shadow: 0 0 2px 2px lighten($selected_bg_color, 20%);
}
.ripple-box:rtl {
background-image: url("resource:///org/gnome/shell/theme/corner-ripple-rtl.png");
}
.ripple-box:rtl { border-radius: 0 0 0 52px; } // just a simple change to the border radius position
// not really top bar only
.popup-menu-arrow { width: 16px; height: 16px; }
@ -1161,14 +1154,26 @@ StScrollBar {
//close buttons
.window-close {
background-image: url("resource:///org/gnome/shell/theme/close-window.svg");
background-size: 32px;
height: 32px;
width: 32px;
-shell-close-overlap: 16px;
background-color: white;
border-radius: 24px;
border: 4px solid $selected_bg_color;
box-shadow: inset 0 -4px 0 0 transparentize($selected_bg_color, 0.5);
color: $selected_bg_color;
height: 24px;
width: 24px;
-shell-close-overlap: 14px;
&:hover { background-image: url("resource:///org/gnome/shell/theme/close-window-hover.svg"); }
&:active { background-image: url("resource:///org/gnome/shell/theme/close-window-active.svg"); }
&:hover {
background-color: $selected_bg_color;
border-color: white;
color: white;
}
&:active {
background-color: mix(white, $selected_bg_color, 75%);
border-color: $selected_bg_color;
color: $selected_bg_color;
}
}
/* NETWORK DIALOGS */
@ -1447,15 +1452,17 @@ StScrollBar {
padding: 15px 20px;
.page-indicator-icon {
width: 18px;
height: 18px;
background-image: url(resource:///org/gnome/shell/theme/page-indicator-inactive.svg);
width: 12px;
height: 12px;
background-color: transparent;
border: 2px solid rgba(255, 255, 255, 0.4);
border-radius:12px;
}
&:hover .page-indicator-icon { background-image: url(resource:///org/gnome/shell/theme/page-indicator-hover.svg); }
&:active .page-indicator-icon { background-image: url(resource:///org/gnome/shell/theme/page-indicator-active.svg); }
&:hover .page-indicator-icon { border-color: white; }
&:active .page-indicator-icon { border: none; margin: 2px; background-color:#fff; }
&:checked .page-indicator-icon,
&:checked:active { background-image: url(resource:///org/gnome/shell/theme/page-indicator-checked.svg); }
&:checked:active { background-color: #fff;}
}
.no-frequent-applications-label { @extend %status_text; }

View File

@ -1,71 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="18"
height="18"
id="svg4703"
version="1.1"
inkscape:version="0.48.4 r9939"
sodipodi:docname="page-indicator-pushed.svg">
<defs
id="defs4705" />
<sodipodi:namedview
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="31.392433"
inkscape:cx="1.0245308"
inkscape:cy="13.3715"
inkscape:current-layer="layer1"
showgrid="true"
inkscape:grid-bbox="true"
inkscape:document-units="px"
inkscape:window-width="2560"
inkscape:window-height="1374"
inkscape:window-x="0"
inkscape:window-y="27"
inkscape:window-maximized="1">
<inkscape:grid
type="xygrid"
id="grid6140" />
</sodipodi:namedview>
<metadata
id="metadata4708">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title></dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<g
id="layer1"
inkscape:label="Layer 1"
inkscape:groupmode="layer"
transform="translate(0,2)">
<path
transform="matrix(0.54617904,0,0,0.62523128,-1131.9904,-392.39214)"
d="m 2099.9808,638.83099 a 10.985409,9.5964489 0 1 1 -21.9708,0 10.985409,9.5964489 0 1 1 21.9708,0 z"
sodipodi:ry="9.5964489"
sodipodi:rx="10.985409"
sodipodi:cy="638.83099"
sodipodi:cx="2088.9954"
id="path4711"
style="fill:#fdffff;fill-opacity:1;stroke:none"
sodipodi:type="arc" />
</g>
</svg>

Before

Width:  |  Height:  |  Size: 2.1 KiB

View File

@ -1,67 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="18"
height="18"
id="svg4703"
version="1.1"
inkscape:version="0.48.4 r9939"
sodipodi:docname="page-indicator-active.svg">
<defs
id="defs4705" />
<sodipodi:namedview
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="22.197802"
inkscape:cx="2.1522887"
inkscape:cy="16.782904"
inkscape:current-layer="layer1"
showgrid="true"
inkscape:grid-bbox="true"
inkscape:document-units="px"
inkscape:window-width="1920"
inkscape:window-height="1021"
inkscape:window-x="0"
inkscape:window-y="27"
inkscape:window-maximized="1" />
<metadata
id="metadata4708">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title />
</cc:Work>
</rdf:RDF>
</metadata>
<g
id="layer1"
inkscape:label="Layer 1"
inkscape:groupmode="layer"
transform="translate(0,2)">
<path
transform="matrix(0.72823872,0,0,0.8336417,-1512.2872,-525.55618)"
d="m 2099.9808,638.83099 c 0,5.29998 -4.9184,9.59645 -10.9854,9.59645 -6.0671,0 -10.9854,-4.29647 -10.9854,-9.59645 0,-5.29997 4.9183,-9.59645 10.9854,-9.59645 6.067,0 10.9854,4.29648 10.9854,9.59645 z"
sodipodi:ry="9.5964489"
sodipodi:rx="10.985409"
sodipodi:cy="638.83099"
sodipodi:cx="2088.9954"
id="path4711"
style="fill:#fdffff;fill-opacity:0.94117647;stroke:none"
sodipodi:type="arc" />
</g>
</svg>

Before

Width:  |  Height:  |  Size: 2.1 KiB

View File

@ -1,67 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="18"
height="18"
id="svg5266"
version="1.1"
inkscape:version="0.48.4 r9939"
sodipodi:docname="page-indicator-inactive.svg">
<defs
id="defs5268" />
<sodipodi:namedview
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="0"
inkscape:pageshadow="2"
inkscape:zoom="11.313709"
inkscape:cx="-2.307566"
inkscape:cy="17.859535"
inkscape:current-layer="layer1"
showgrid="true"
inkscape:grid-bbox="true"
inkscape:document-units="px"
inkscape:window-width="2560"
inkscape:window-height="1374"
inkscape:window-x="0"
inkscape:window-y="27"
inkscape:window-maximized="1" />
<metadata
id="metadata5271">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title></dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<g
id="layer1"
inkscape:label="Layer 1"
inkscape:groupmode="layer"
transform="translate(0,2)">
<path
sodipodi:type="arc"
style="fill:none;fill-opacity:0;stroke:#ffffff;stroke-width:2.93356276000000005;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
id="path5274"
sodipodi:cx="2088.9954"
sodipodi:cy="638.83099"
sodipodi:rx="10.985409"
sodipodi:ry="9.5964489"
d="m 2099.9808,638.83099 c 0,5.29998 -4.9184,9.59645 -10.9854,9.59645 -6.0671,0 -10.9854,-4.29647 -10.9854,-9.59645 0,-5.29997 4.9183,-9.59645 10.9854,-9.59645 6.067,0 10.9854,4.29648 10.9854,9.59645 z"
transform="matrix(0.63720887,0,0,0.72943648,-1322.1264,-458.98661)" />
</g>
</svg>

Before

Width:  |  Height:  |  Size: 2.2 KiB

View File

@ -1,67 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="18"
height="18"
id="svg5266"
version="1.1"
inkscape:version="0.48.4 r9939"
sodipodi:docname="page-indicator-inactive.svg">
<defs
id="defs5268" />
<sodipodi:namedview
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="0"
inkscape:pageshadow="2"
inkscape:zoom="11.313709"
inkscape:cx="-2.307566"
inkscape:cy="17.859535"
inkscape:current-layer="layer1"
showgrid="true"
inkscape:grid-bbox="true"
inkscape:document-units="px"
inkscape:window-width="2560"
inkscape:window-height="1374"
inkscape:window-x="0"
inkscape:window-y="27"
inkscape:window-maximized="1" />
<metadata
id="metadata5271">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title />
</cc:Work>
</rdf:RDF>
</metadata>
<g
id="layer1"
inkscape:label="Layer 1"
inkscape:groupmode="layer"
transform="translate(0,2)">
<path
sodipodi:type="arc"
style="fill:none;fill-opacity:0;stroke:#ffffff;stroke-width:2.93356276000000005;stroke-miterlimit:4;stroke-opacity:0.39215686000000000;stroke-dasharray:none"
id="path5274"
sodipodi:cx="2088.9954"
sodipodi:cy="638.83099"
sodipodi:rx="10.985409"
sodipodi:ry="9.5964489"
d="m 2099.9808,638.83099 c 0,5.29998 -4.9184,9.59645 -10.9854,9.59645 -6.0671,0 -10.9854,-4.29647 -10.9854,-9.59645 0,-5.29997 4.9183,-9.59645 10.9854,-9.59645 6.067,0 10.9854,4.29648 10.9854,9.59645 z"
transform="matrix(0.63720887,0,0,0.72943648,-1322.1264,-458.98661)" />
</g>
</svg>

Before

Width:  |  Height:  |  Size: 2.2 KiB

View File

@ -17,7 +17,6 @@
<chapter>
<title>Actors</title>
<xi:include href="xml/shell-generic-container.xml"/>
<xi:include href="xml/shell-stack.xml"/>
</chapter>
<chapter>

View File

@ -25,7 +25,7 @@ its dependencies to build from tarballs.</description>
<homepage rdf:resource="https://wiki.gnome.org/Projects/GnomeShell" />
<mailing-list rdf:resource="http://mail.gnome.org/mailman/listinfo/gnome-shell-list" />
<download-page rdf:resource="http://download.gnome.org/sources/gnome-shell/" />
<bug-database rdf:resource="https://bugzilla.gnome.org/browse.cgi?product=gnome-shell" />
<bug-database rdf:resource="https://gitlab.gnome.org/GNOME/gnome-shell/issues/" />
<category rdf:resource="http://api.gnome.org/doap-extensions#core" />
<programming-language>JavaScript</programming-language>

View File

@ -1,5 +1,3 @@
const Lang = imports.lang;
const Gettext = imports.gettext;
const GLib = imports.gi.GLib;
const GObject = imports.gi.GObject;
@ -24,9 +22,8 @@ function stripPrefix(string, prefix) {
return string;
}
var Application = new Lang.Class({
Name: 'Application',
_init() {
var Application = class {
constructor() {
GLib.set_prgname('gnome-shell-extension-prefs');
this.application = new Gtk.Application({
application_id: 'org.gnome.shell.ExtensionPrefs',
@ -42,7 +39,7 @@ var Application = new Lang.Class({
this._startupUuid = null;
this._loaded = false;
this._skipMainWindow = false;
},
}
_extensionAvailable(uuid) {
let extension = ExtensionUtils.extensions[uuid];
@ -54,7 +51,7 @@ var Application = new Lang.Class({
return false;
return true;
},
}
_getExtensionPrefsModule(extension) {
let uuid = extension.metadata.uuid;
@ -69,7 +66,7 @@ var Application = new Lang.Class({
this._extensionPrefsModules[uuid] = prefsModule;
return prefsModule;
},
}
_selectExtension(uuid) {
if (!this._extensionAvailable(uuid))
@ -104,7 +101,7 @@ var Application = new Lang.Class({
dialog.set_default_size(600, 400);
dialog.add(widget);
dialog.show();
},
}
_buildErrorUI(extension, exc) {
let box = new Gtk.Box({ orientation: Gtk.Orientation.VERTICAL });
@ -130,7 +127,7 @@ var Application = new Lang.Class({
box.show_all();
return box;
},
}
_buildUI(app) {
this._window = new Gtk.ApplicationWindow({ application: app,
@ -167,13 +164,13 @@ var Application = new Lang.Class({
});
this._window.show_all();
},
}
_sortList(row1, row2) {
let name1 = ExtensionUtils.extensions[row1.uuid].metadata.name;
let name2 = ExtensionUtils.extensions[row2.uuid].metadata.name;
return name1.localeCompare(name2);
},
}
_updateHeader(row, before) {
if (!before || row.get_header())
@ -181,14 +178,14 @@ var Application = new Lang.Class({
let sep = new Gtk.Separator({ orientation: Gtk.Orientation.HORIZONTAL });
row.set_header(sep);
},
}
_scanExtensions() {
let finder = new ExtensionUtils.ExtensionFinder();
finder.connect('extension-found', this._extensionFound.bind(this));
finder.scanExtensions();
this._extensionsLoaded();
},
}
_extensionFound(finder, extension) {
let row = new ExtensionRow(extension.uuid);
@ -200,7 +197,7 @@ var Application = new Lang.Class({
row.show_all();
this._extensionSelector.add(row);
},
}
_extensionsLoaded() {
if (this._startupUuid && this._extensionAvailable(this._startupUuid))
@ -208,16 +205,16 @@ var Application = new Lang.Class({
this._startupUuid = null;
this._skipMainWindow = false;
this._loaded = true;
},
}
_onActivate() {
this._window.present();
},
}
_onStartup(app) {
this._buildUI(app);
this._scanExtensions();
},
}
_onCommandLine(app, commandLine) {
app.activate();
@ -240,26 +237,22 @@ var Application = new Lang.Class({
}
return 0;
}
});
var DescriptionLabel = new Lang.Class({
Name: 'DescriptionLabel',
Extends: Gtk.Label,
};
var DescriptionLabel = GObject.registerClass(
class DescriptionLabel extends Gtk.Label {
vfunc_get_preferred_height_for_width(width) {
// Hack: Request the maximum height allowed by the line limit
if (this.lines > 0)
return this.parent(0);
return this.parent(width);
return super.vfunc_get_preferred_height_for_width(0);
return super.vfunc_get_preferred_height_for_width(width);
}
});
var ExtensionRow = new Lang.Class({
Name: 'ExtensionRow',
Extends: Gtk.ListBoxRow,
var ExtensionRow = GObject.registerClass(
class ExtensionRow extends Gtk.ListBoxRow {
_init(uuid) {
this.parent();
super._init();
this.uuid = uuid;
@ -277,7 +270,7 @@ var ExtensionRow = new Lang.Class({
});
this._buildUI();
},
}
_buildUI() {
let extension = ExtensionUtils.extensions[this.uuid];
@ -324,7 +317,7 @@ var ExtensionRow = new Lang.Class({
});
this._switch.connect('state-set', () => true);
hbox.add(this._switch);
},
}
_canEnable() {
let extension = ExtensionUtils.extensions[this.uuid];
@ -332,12 +325,12 @@ var ExtensionRow = new Lang.Class({
return !this._settings.get_boolean('disable-user-extensions') &&
!(checkVersion && ExtensionUtils.isOutOfDate(extension));
},
}
_isEnabled() {
let extensions = this._settings.get_strv('enabled-extensions');
return extensions.indexOf(this.uuid) != -1;
},
}
_enable() {
let extensions = this._settings.get_strv('enabled-extensions');
@ -346,7 +339,7 @@ var ExtensionRow = new Lang.Class({
extensions.push(this.uuid);
this._settings.set_strv('enabled-extensions', extensions);
},
}
_disable() {
let extensions = this._settings.get_strv('enabled-extensions');

View File

@ -2,7 +2,6 @@
const Clutter = imports.gi.Clutter;
const Gio = imports.gi.Gio;
const Lang = imports.lang;
const Pango = imports.gi.Pango;
const Signals = imports.signals;
const St = imports.gi.St;
@ -38,10 +37,8 @@ var BeginRequestType = {
DONT_PROVIDE_USERNAME: 1
};
var AuthPrompt = new Lang.Class({
Name: 'AuthPrompt',
_init(gdmClient, mode) {
var AuthPrompt = class {
constructor(gdmClient, mode) {
this.verificationStatus = AuthPromptStatus.NOT_VERIFYING;
this._gdmClient = gdmClient;
@ -127,17 +124,16 @@ var AuthPrompt = new Lang.Class({
this._initButtons();
let spinnerIcon = Gio.File.new_for_uri('resource:///org/gnome/shell/theme/process-working.svg');
this._spinner = new Animation.AnimatedIcon(spinnerIcon, DEFAULT_BUTTON_WELL_ICON_SIZE);
this._spinner = new Animation.Spinner(DEFAULT_BUTTON_WELL_ICON_SIZE);
this._spinner.actor.opacity = 0;
this._spinner.actor.show();
this._defaultButtonWell.add_child(this._spinner.actor);
},
}
_onDestroy() {
this._userVerifier.destroy();
this._userVerifier = null;
},
}
_initButtons() {
this.cancelButton = new St.Button({ style_class: 'modal-dialog-button button',
@ -185,7 +181,7 @@ var AuthPrompt = new Lang.Class({
if (this.nextButton.reactive)
this.emit('next');
});
},
}
_onAskQuestion(verifier, serviceName, question, passwordChar) {
if (this._queryingService)
@ -211,12 +207,12 @@ var AuthPrompt = new Lang.Class({
this.updateSensitivity(true);
this.emit('prompted');
},
}
_onOVirtUserAuthenticated() {
if (this.verificationStatus != AuthPromptStatus.VERIFICATION_SUCCEEDED)
this.reset();
},
}
_onSmartcardStatusChanged() {
this.smartcardDetected = this._userVerifier.smartcardDetected;
@ -235,12 +231,12 @@ var AuthPrompt = new Lang.Class({
if (this.verificationStatus != AuthPromptStatus.VERIFICATION_SUCCEEDED)
this.reset();
},
}
_onShowMessage(userVerifier, message, type) {
this.setMessage(message, type);
this.emit('prompted');
},
}
_onVerificationFailed(userVerifier, canRetry) {
this._queryingService = null;
@ -249,22 +245,22 @@ var AuthPrompt = new Lang.Class({
this.updateSensitivity(canRetry);
this.setActorInDefaultButtonWell(null);
this.verificationStatus = AuthPromptStatus.VERIFICATION_FAILED;
},
}
_onVerificationComplete() {
this.setActorInDefaultButtonWell(null);
this.verificationStatus = AuthPromptStatus.VERIFICATION_SUCCEEDED;
this.cancelButton.reactive = false;
},
}
_onReset() {
this.verificationStatus = AuthPromptStatus.NOT_VERIFYING;
this.reset();
},
}
addActorToDefaultButtonWell(actor) {
this._defaultButtonWell.add_child(actor);
},
}
setActorInDefaultButtonWell(actor, animate) {
if (!this._defaultButtonWellActor &&
@ -328,25 +324,25 @@ var AuthPrompt = new Lang.Class({
}
this._defaultButtonWellActor = actor;
},
}
startSpinning() {
this.setActorInDefaultButtonWell(this._spinner.actor, true);
},
}
stopSpinning() {
this.setActorInDefaultButtonWell(null, false);
},
}
clear() {
this._entry.text = '';
this.stopSpinning();
},
}
setPasswordChar(passwordChar) {
this._entry.clutter_text.set_password_char(passwordChar);
this._entry.menu.isPassword = passwordChar != '';
},
}
setQuestion(question) {
this._label.set_text(question);
@ -355,7 +351,7 @@ var AuthPrompt = new Lang.Class({
this._entry.show();
this._entry.grab_key_focus();
},
}
getAnswer() {
let text;
@ -368,7 +364,7 @@ var AuthPrompt = new Lang.Class({
}
return text;
},
}
_fadeOutMessage() {
if (this._message.opacity == 0)
@ -379,7 +375,7 @@ var AuthPrompt = new Lang.Class({
time: MESSAGE_FADE_OUT_ANIMATION_TIME,
transition: 'easeOutQuad'
});
},
}
setMessage(message, type) {
if (type == GdmUtil.MessageType.ERROR)
@ -399,18 +395,18 @@ var AuthPrompt = new Lang.Class({
} else {
this._message.opacity = 0;
}
},
}
_updateNextButtonSensitivity(sensitive) {
this.nextButton.reactive = sensitive;
this.nextButton.can_focus = sensitive;
},
}
updateSensitivity(sensitive) {
this._updateNextButtonSensitivity(sensitive && (this._entry.text.length > 0 || this.verificationStatus == AuthPromptStatus.VERIFYING));
this._entry.reactive = sensitive;
this._entry.clutter_text.editable = sensitive;
},
}
hide() {
this.setActorInDefaultButtonWell(null, true);
@ -421,7 +417,7 @@ var AuthPrompt = new Lang.Class({
this.updateSensitivity(true);
this._entry.set_text('');
},
}
setUser(user) {
let oldChild = this._userWell.get_child();
@ -432,7 +428,7 @@ var AuthPrompt = new Lang.Class({
let userWidget = new UserWidget.UserWidget(user);
this._userWell.set_child(userWidget.actor);
}
},
}
reset() {
let oldStatus = this.verificationStatus;
@ -470,7 +466,7 @@ var AuthPrompt = new Lang.Class({
}
this.emit('reset', beginRequestType);
},
}
addCharacter(unichar) {
if (!this._entry.visible)
@ -478,7 +474,7 @@ var AuthPrompt = new Lang.Class({
this._entry.grab_key_focus();
this._entry.clutter_text.insert_unichar(unichar);
},
}
begin(params) {
params = Params.parse(params, { userName: null,
@ -492,7 +488,7 @@ var AuthPrompt = new Lang.Class({
this._userVerifier.begin(params.userName, hold);
this.verificationStatus = AuthPromptStatus.VERIFYING;
},
}
finish(onComplete) {
if (!this._userVerifier.hasPendingMessages) {
@ -506,7 +502,7 @@ var AuthPrompt = new Lang.Class({
this._userVerifier.clear();
onComplete();
});
},
}
cancel() {
if (this.verificationStatus == AuthPromptStatus.VERIFICATION_SUCCEEDED) {
@ -515,5 +511,5 @@ var AuthPrompt = new Lang.Class({
this.reset();
this.emit('cancelled');
}
});
};
Signals.addSignalMethods(AuthPrompt.prototype);

View File

@ -44,45 +44,39 @@
* replaced by something else.
*/
const Lang = imports.lang;
const Signals = imports.signals;
var Task = new Lang.Class({
Name: 'Task',
_init(scope, handler) {
var Task = class {
constructor(scope, handler) {
if (scope)
this.scope = scope;
else
this.scope = this;
this.handler = handler;
},
}
run() {
if (this.handler)
return this.handler.call(this.scope);
return null;
},
});
}
};
Signals.addSignalMethods(Task.prototype);
var Hold = new Lang.Class({
Name: 'Hold',
Extends: Task,
_init() {
this.parent(this, () => this);
var Hold = class extends Task {
constructor() {
super(null, () => this);
this._acquisitions = 1;
},
}
acquire() {
if (this._acquisitions <= 0)
throw new Error("Cannot acquire hold after it's been released");
this._acquisitions++;
},
}
acquireUntilAfter(hold) {
if (!hold.isAcquired())
@ -93,27 +87,24 @@ var Hold = new Lang.Class({
hold.disconnect(signalId);
this.release();
});
},
}
release() {
this._acquisitions--;
if (this._acquisitions == 0)
this.emit('release');
},
}
isAcquired() {
return this._acquisitions > 0;
}
});
};
Signals.addSignalMethods(Hold.prototype);
var Batch = new Lang.Class({
Name: 'Batch',
Extends: Task,
_init(scope, tasks) {
this.parent();
var Batch = class extends Task {
constructor(scope, tasks) {
super();
this.tasks = [];
@ -130,11 +121,11 @@ var Batch = new Lang.Class({
this.tasks.push(task);
}
},
}
process() {
throw new Error('Not implemented');
},
}
runTask() {
if (!(this._currentTaskIndex in this.tasks)) {
@ -142,11 +133,11 @@ var Batch = new Lang.Class({
}
return this.tasks[this._currentTaskIndex].run();
},
}
_finish() {
this.hold.release();
},
}
nextTask() {
this._currentTaskIndex++;
@ -159,7 +150,7 @@ var Batch = new Lang.Class({
}
this.process();
},
}
_start() {
// acquire a hold to get released when the entire
@ -167,7 +158,7 @@ var Batch = new Lang.Class({
this.hold = new Hold();
this._currentTaskIndex = 0;
this.process();
},
}
run() {
this._start();
@ -175,18 +166,15 @@ var Batch = new Lang.Class({
// hold may be destroyed at this point
// if we're already done running
return this.hold;
},
}
cancel() {
this.tasks = this.tasks.splice(0, this._currentTaskIndex + 1);
}
});
};
Signals.addSignalMethods(Batch.prototype);
var ConcurrentBatch = new Lang.Class({
Name: 'ConcurrentBatch',
Extends: Batch,
var ConcurrentBatch = class extends Batch {
process() {
let hold = this.runTask();
@ -199,13 +187,10 @@ var ConcurrentBatch = new Lang.Class({
// concurrently.
this.nextTask();
}
});
};
Signals.addSignalMethods(ConcurrentBatch.prototype);
var ConsecutiveBatch = new Lang.Class({
Name: 'ConsecutiveBatch',
Extends: Batch,
var ConsecutiveBatch = class extends Batch {
process() {
let hold = this.runTask();
@ -222,5 +207,5 @@ var ConsecutiveBatch = new Lang.Class({
this.nextTask();
}
}
});
};
Signals.addSignalMethods(ConsecutiveBatch.prototype);

View File

@ -1,7 +1,6 @@
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
const Gio = imports.gi.Gio;
const Lang = imports.lang;
const Shell = imports.gi.Shell;
const Signals = imports.signals;

View File

@ -24,7 +24,6 @@ const Gio = imports.gi.Gio;
const GLib = imports.gi.GLib;
const GObject = imports.gi.GObject;
const Gtk = imports.gi.Gtk;
const Lang = imports.lang;
const Meta = imports.gi.Meta;
const Pango = imports.gi.Pango;
const Shell = imports.gi.Shell;
@ -50,10 +49,8 @@ const _TIMED_LOGIN_IDLE_THRESHOLD = 5.0;
const _LOGO_ICON_HEIGHT = 48;
const _MAX_BOTTOM_MENU_ITEMS = 5;
var UserListItem = new Lang.Class({
Name: 'UserListItem',
_init(user) {
var UserListItem = class {
constructor(user) {
this.user = user;
this._userChangedId = this.user.connect('changed',
this._onUserChanged.bind(this));
@ -91,26 +88,26 @@ var UserListItem = new Lang.Class({
this.actor.connect('clicked', this._onClicked.bind(this));
this._onUserChanged();
},
}
_onUserChanged() {
this._updateLoggedIn();
},
}
_updateLoggedIn() {
if (this.user.is_logged_in())
this.actor.add_style_pseudo_class('logged-in');
else
this.actor.remove_style_pseudo_class('logged-in');
},
}
_onDestroy() {
this.user.disconnect(this._userChangedId);
},
}
_onClicked() {
this.emit('activate');
},
}
_setSelected(selected) {
if (selected) {
@ -119,7 +116,7 @@ var UserListItem = new Lang.Class({
} else {
this.actor.remove_style_pseudo_class('selected');
}
},
}
showTimedLoginIndicator(time) {
let hold = new Batch.Hold();
@ -147,7 +144,7 @@ var UserListItem = new Lang.Class({
GLib.Source.set_name_by_id(this._timedLoginTimeoutId, '[gnome-shell] this._timedLoginTimeoutId');
return hold;
},
}
hideTimedLoginIndicator() {
if (this._timedLoginTimeoutId) {
@ -158,13 +155,11 @@ var UserListItem = new Lang.Class({
this._timedLoginIndicator.visible = false;
this._timedLoginIndicator.scale_x = 0.;
}
});
};
Signals.addSignalMethods(UserListItem.prototype);
var UserList = new Lang.Class({
Name: 'UserList',
_init() {
var UserList = class {
constructor() {
this.actor = new St.ScrollView({ style_class: 'login-dialog-user-list-view'});
this.actor.set_policy(Gtk.PolicyType.NEVER,
Gtk.PolicyType.AUTOMATIC);
@ -177,7 +172,7 @@ var UserList = new Lang.Class({
this._items = {};
this.actor.connect('key-focus-in', this._moveFocusToItems.bind(this));
},
}
_moveFocusToItems() {
let hasItems = Object.keys(this._items).length > 0;
@ -195,11 +190,11 @@ var UserList = new Lang.Class({
return false;
});
}
},
}
_onItemActivated(activatedItem) {
this.emit('activate', activatedItem);
},
}
updateStyle(isExpanded) {
let tasks = [];
@ -213,7 +208,7 @@ var UserList = new Lang.Class({
let item = this._items[userName];
item.actor.sync_hover();
}
},
}
scrollToItem(item) {
let box = item.actor.get_allocation_box();
@ -226,7 +221,7 @@ var UserList = new Lang.Class({
{ value: value,
time: _SCROLL_ANIMATION_TIME,
transition: 'easeOutQuad' });
},
}
jumpToItem(item) {
let box = item.actor.get_allocation_box();
@ -236,7 +231,7 @@ var UserList = new Lang.Class({
let value = (box.y1 + adjustment.step_increment / 2.0) - (adjustment.page_size / 2.0);
adjustment.set_value(value);
},
}
getItemFromUserName(userName) {
let item = this._items[userName];
@ -245,11 +240,11 @@ var UserList = new Lang.Class({
return null;
return item;
},
}
containsUser(user) {
return this._items[user.get_user_name()] != null;
},
}
addUser(user) {
if (!user.is_loaded)
@ -281,7 +276,7 @@ var UserList = new Lang.Class({
this._moveFocusToItems();
this.emit('item-added', item);
},
}
removeUser(user) {
if (!user.is_loaded)
@ -299,18 +294,16 @@ var UserList = new Lang.Class({
item.actor.destroy();
delete this._items[userName];
},
}
numItems() {
return Object.keys(this._items).length;
}
});
};
Signals.addSignalMethods(UserList.prototype);
var SessionMenuButton = new Lang.Class({
Name: 'SessionMenuButton',
_init() {
var SessionMenuButton = class {
constructor() {
let gearIcon = new St.Icon({ icon_name: 'emblem-system-symbolic' });
this._button = new St.Button({ style_class: 'login-dialog-session-list-button',
reactive: true,
@ -350,13 +343,13 @@ var SessionMenuButton = new Lang.Class({
this._items = {};
this._activeSessionId = null;
this._populate();
},
}
updateSensitivity(sensitive) {
this._button.reactive = sensitive;
this._button.can_focus = sensitive;
this._menu.close(BoxPointer.PopupAnimation.NONE);
},
}
_updateOrnament() {
let itemIds = Object.keys(this._items);
@ -366,7 +359,7 @@ var SessionMenuButton = new Lang.Class({
else
this._items[itemIds[i]].setOrnament(PopupMenu.Ornament.NONE);
}
},
}
setActiveSession(sessionId) {
if (sessionId == this._activeSessionId)
@ -374,11 +367,11 @@ var SessionMenuButton = new Lang.Class({
this._activeSessionId = sessionId;
this._updateOrnament();
},
}
close() {
this._menu.close();
},
}
_populate() {
let ids = Gdm.get_session_ids();
@ -403,21 +396,21 @@ var SessionMenuButton = new Lang.Class({
});
}
}
});
};
Signals.addSignalMethods(SessionMenuButton.prototype);
var LoginDialog = new Lang.Class({
Name: 'LoginDialog',
var LoginDialog = GObject.registerClass({
Signals: { 'failed': {} },
}, class LoginDialog extends St.Widget {
_init(parentActor) {
this.actor = new Shell.GenericContainer({ style_class: 'login-dialog',
visible: false });
this.actor.get_accessible().set_role(Atk.Role.WINDOW);
super._init({ style_class: 'login-dialog',
visible: false });
this.actor.add_constraint(new Layout.MonitorConstraint({ primary: true }));
this.actor.connect('allocate', this._onAllocate.bind(this));
this.actor.connect('destroy', this._onDestroy.bind(this));
parentActor.add_child(this.actor);
this.get_accessible().set_role(Atk.Role.WINDOW);
this.add_constraint(new Layout.MonitorConstraint({ primary: true }));
this.connect('destroy', this._onDestroy.bind(this));
parentActor.add_child(this);
this._userManager = AccountsService.UserManager.get_default()
this._gdmClient = new Gdm.Client();
@ -442,7 +435,7 @@ var LoginDialog = new Lang.Class({
y_align: Clutter.ActorAlign.CENTER,
vertical: true,
visible: false });
this.actor.add_child(this._userSelectionBox);
this.add_child(this._userSelectionBox);
this._userList = new UserList();
this._userSelectionBox.add(this._userList.actor,
@ -454,7 +447,7 @@ var LoginDialog = new Lang.Class({
this._authPrompt.connect('prompted', this._onPrompted.bind(this));
this._authPrompt.connect('reset', this._onReset.bind(this));
this._authPrompt.hide();
this.actor.add_child(this._authPrompt.actor);
this.add_child(this._authPrompt.actor);
// translators: this message is shown below the user list on the
// login screen. It can be activated to reveal an entry for
@ -482,7 +475,7 @@ var LoginDialog = new Lang.Class({
opacity: 0,
vscrollbar_policy: Gtk.PolicyType.AUTOMATIC,
hscrollbar_policy: Gtk.PolicyType.NEVER });
this.actor.add_child(this._bannerView);
this.add_child(this._bannerView);
let bannerBox = new St.BoxLayout({ vertical: true });
@ -497,7 +490,7 @@ var LoginDialog = new Lang.Class({
this._logoBin = new St.Widget({ style_class: 'login-dialog-logo-bin',
x_align: Clutter.ActorAlign.CENTER,
y_align: Clutter.ActorAlign.END });
this.actor.add_child(this._logoBin);
this.add_child(this._logoBin);
this._updateLogo();
this._userList.connect('activate', (userList, item) => {
@ -528,7 +521,7 @@ var LoginDialog = new Lang.Class({
// focus later
this._startupCompleteId = Main.layoutManager.connect('startup-complete',
this._updateDisableUserList.bind(this));
},
}
_getBannerAllocation(dialogBox) {
let actorBox = new Clutter.ActorBox();
@ -542,7 +535,7 @@ var LoginDialog = new Lang.Class({
actorBox.y2 = actorBox.y1 + natHeight;
return actorBox;
},
}
_getLogoBinAllocation(dialogBox) {
let actorBox = new Clutter.ActorBox();
@ -556,7 +549,7 @@ var LoginDialog = new Lang.Class({
actorBox.y2 = actorBox.y1 + natHeight;
return actorBox;
},
}
_getCenterActorAllocation(dialogBox, actor) {
let actorBox = new Clutter.ActorBox();
@ -574,9 +567,14 @@ var LoginDialog = new Lang.Class({
actorBox.y2 = actorBox.y1 + natHeight;
return actorBox;
},
}
vfunc_allocate(dialogBox, flags) {
this.set_allocation(dialogBox, flags);
let themeNode = this.get_theme_node();
dialogBox = themeNode.get_content_box(dialogBox);
_onAllocate(actor, dialogBox, flags) {
let dialogWidth = dialogBox.x2 - dialogBox.x1;
let dialogHeight = dialogBox.y2 - dialogBox.y1;
@ -712,7 +710,7 @@ var LoginDialog = new Lang.Class({
if (logoAllocation)
this._logoBin.allocate(logoAllocation, flags);
},
}
_ensureUserListLoaded() {
if (!this._userManager.is_loaded) {
@ -728,7 +726,7 @@ var LoginDialog = new Lang.Class({
let id = GLib.idle_add(GLib.PRIORITY_DEFAULT, this._loadUserList.bind(this));
GLib.Source.set_name_by_id(id, '[gnome-shell] _loadUserList');
}
},
}
_updateDisableUserList() {
let disableUserList = this._settings.get_boolean(GdmUtil.DISABLE_USER_LIST_KEY);
@ -743,7 +741,7 @@ var LoginDialog = new Lang.Class({
if (this._authPrompt.verificationStatus == AuthPrompt.AuthPromptStatus.NOT_VERIFYING)
this._authPrompt.reset();
}
},
}
_updateCancelButton() {
let cancelVisible;
@ -756,7 +754,7 @@ var LoginDialog = new Lang.Class({
cancelVisible = true;
this._authPrompt.cancelButton.visible = cancelVisible;
},
}
_updateBanner() {
let enabled = this._settings.get_boolean(GdmUtil.BANNER_MESSAGE_KEY);
@ -768,7 +766,7 @@ var LoginDialog = new Lang.Class({
} else {
this._bannerLabel.hide();
}
},
}
_fadeInBannerView() {
this._bannerView.show();
@ -776,13 +774,13 @@ var LoginDialog = new Lang.Class({
{ opacity: 255,
time: _FADE_ANIMATION_TIME,
transition: 'easeOutQuad' });
},
}
_hideBannerView() {
Tweener.removeTweens(this._bannerView);
this._bannerView.opacity = 0;
this._bannerView.hide();
},
}
_updateLogoTexture(cache, file) {
if (this._logoFile && !this._logoFile.equal(file))
@ -795,14 +793,14 @@ var LoginDialog = new Lang.Class({
-1, _LOGO_ICON_HEIGHT,
scaleFactor));
}
},
}
_updateLogo() {
let path = this._settings.get_string(GdmUtil.LOGO_KEY);
this._logoFile = path ? Gio.file_new_for_path(path) : null;
this._updateLogoTexture(this._textureCache, this._logoFile);
},
}
_onPrompted() {
if (this._shouldShowSessionMenuButton()) {
@ -812,7 +810,7 @@ var LoginDialog = new Lang.Class({
this._sessionMenuButton.updateSensitivity(false);
}
this._showPrompt();
},
}
_resetGreeterProxy() {
if (GLib.getenv('GDM_GREETER_TEST') != '1') {
@ -828,7 +826,7 @@ var LoginDialog = new Lang.Class({
this._timedLoginRequestedId = this._greeter.connect('timed-login-requested',
this._onTimedLoginRequested.bind(this));
}
},
}
_onReset(authPrompt, beginRequest) {
this._resetGreeterProxy();
@ -849,11 +847,11 @@ var LoginDialog = new Lang.Class({
} else {
this._hideUserListAndBeginVerification();
}
},
}
_onDefaultSessionChanged(client, sessionId) {
this._sessionMenuButton.setActiveSession(sessionId);
},
}
_shouldShowSessionMenuButton() {
if (this._authPrompt.verificationStatus != AuthPrompt.AuthPromptStatus.VERIFYING &&
@ -864,7 +862,7 @@ var LoginDialog = new Lang.Class({
return false;
return true;
},
}
_showPrompt() {
if (this._authPrompt.actor.visible)
@ -876,7 +874,7 @@ var LoginDialog = new Lang.Class({
time: _FADE_ANIMATION_TIME,
transition: 'easeOutQuad' });
this._fadeInBannerView();
},
}
_showRealmLoginHint(realmManager, hint) {
if (!hint)
@ -889,7 +887,7 @@ var LoginDialog = new Lang.Class({
// Translators: this message is shown below the username entry field
// to clue the user in on how to login to the local network realm
this._authPrompt.setMessage(_("(e.g., user or %s)").format(hint), GdmUtil.MessageType.HINT);
},
}
_askForUsernameAndBeginVerification() {
this._authPrompt.setPasswordChar('');
@ -916,13 +914,13 @@ var LoginDialog = new Lang.Class({
this._sessionMenuButton.updateSensitivity(false);
this._authPrompt.updateSensitivity(true);
this._showPrompt();
},
}
_loginScreenSessionActivated() {
if (this.actor.opacity == 255 && this._authPrompt.verificationStatus == AuthPrompt.AuthPromptStatus.NOT_VERIFYING)
if (this.opacity == 255 && this._authPrompt.verificationStatus == AuthPrompt.AuthPromptStatus.NOT_VERIFYING)
return;
Tweener.addTween(this.actor,
Tweener.addTween(this,
{ opacity: 255,
time: _FADE_ANIMATION_TIME,
transition: 'easeOutQuad',
@ -931,7 +929,7 @@ var LoginDialog = new Lang.Class({
for (let i = 0; i < children.length; i++) {
if (children[i] != Main.layoutManager.screenShieldGroup)
children[i].opacity = this.actor.opacity;
children[i].opacity = this.opacity;
}
},
onUpdateScope: this,
@ -940,7 +938,7 @@ var LoginDialog = new Lang.Class({
this._authPrompt.reset();
},
onCompleteScope: this });
},
}
_gotGreeterSessionProxy(proxy) {
this._greeterSessionProxy = proxy;
@ -949,10 +947,10 @@ var LoginDialog = new Lang.Class({
if (proxy.Active)
this._loginScreenSessionActivated();
});
},
}
_startSession(serviceName) {
Tweener.addTween(this.actor,
Tweener.addTween(this,
{ opacity: 0,
time: _FADE_ANIMATION_TIME,
transition: 'easeOutQuad',
@ -961,7 +959,7 @@ var LoginDialog = new Lang.Class({
for (let i = 0; i < children.length; i++) {
if (children[i] != Main.layoutManager.screenShieldGroup)
children[i].opacity = this.actor.opacity;
children[i].opacity = this.opacity;
}
},
onUpdateScope: this,
@ -969,11 +967,11 @@ var LoginDialog = new Lang.Class({
this._greeter.call_start_session_when_ready_sync(serviceName, true, null);
},
onCompleteScope: this });
},
}
_onSessionOpened(client, serviceName) {
this._authPrompt.finish(() => { this._startSession(serviceName); });
},
}
_waitForItemForUser(userName) {
let item = this._userList.getItemFromUserName(userName);
@ -993,7 +991,7 @@ var LoginDialog = new Lang.Class({
hold.connect('release', () => { this._userList.disconnect(signalId); });
return hold;
},
}
_blockTimedLoginUntilIdle() {
let hold = new Batch.Hold();
@ -1006,7 +1004,7 @@ var LoginDialog = new Lang.Class({
});
GLib.Source.set_name_by_id(this._timedLoginIdleTimeOutId, '[gnome-shell] this._timedLoginIdleTimeOutId');
return hold;
},
}
_startTimedLogin(userName, delay) {
let firstRun = true;
@ -1079,7 +1077,7 @@ var LoginDialog = new Lang.Class({
this._timedLoginBatch = new Batch.ConsecutiveBatch(this, tasks);
return this._timedLoginBatch.run();
},
}
_onTimedLoginRequested(client, userName, seconds) {
if (this._timedLoginBatch)
@ -1096,28 +1094,28 @@ var LoginDialog = new Lang.Class({
return Clutter.EVENT_PROPAGATE;
});
},
}
_setUserListExpanded(expanded) {
this._userList.updateStyle(expanded);
this._userSelectionBox.visible = expanded;
},
}
_hideUserList() {
this._setUserListExpanded(false);
if (this._userSelectionBox.visible)
GdmUtil.cloneAndFadeOutActor(this._userSelectionBox);
},
}
_hideUserListAskForUsernameAndBeginVerification() {
this._hideUserList();
this._askForUsernameAndBeginVerification();
},
}
_hideUserListAndBeginVerification() {
this._hideUserList();
this._authPrompt.begin();
},
}
_showUserList() {
this._ensureUserListLoaded();
@ -1127,7 +1125,7 @@ var LoginDialog = new Lang.Class({
this._setUserListExpanded(true);
this._notListedButton.show();
this._userList.actor.grab_key_focus();
},
}
_beginVerificationForItem(item) {
this._authPrompt.setUser(item.user);
@ -1138,7 +1136,7 @@ var LoginDialog = new Lang.Class({
this._authPrompt.begin({ userName: userName,
hold: hold });
return hold;
},
}
_onUserListActivated(activatedItem) {
this._user = activatedItem.user;
@ -1148,7 +1146,7 @@ var LoginDialog = new Lang.Class({
let batch = new Batch.ConcurrentBatch(this, [GdmUtil.cloneAndFadeOutActor(this._userSelectionBox),
this._beginVerificationForItem(activatedItem)]);
batch.run();
},
}
_onDestroy() {
if (this._userManagerLoadedId) {
@ -1189,7 +1187,7 @@ var LoginDialog = new Lang.Class({
this._realmManager.release();
this._realmManager = null;
}
},
}
_loadUserList() {
if (this._userListLoaded)
@ -1227,42 +1225,41 @@ var LoginDialog = new Lang.Class({
});
return GLib.SOURCE_REMOVE;
},
}
open() {
Main.ctrlAltTabManager.addGroup(this.actor,
Main.ctrlAltTabManager.addGroup(this,
_("Login Window"),
'dialog-password-symbolic',
{ sortGroup: CtrlAltTab.SortGroup.MIDDLE });
this._userList.actor.grab_key_focus();
this.actor.show();
this.actor.opacity = 0;
this.show();
this.opacity = 0;
Main.pushModal(this.actor, { actionMode: Shell.ActionMode.LOGIN_SCREEN });
Main.pushModal(this, { actionMode: Shell.ActionMode.LOGIN_SCREEN });
Tweener.addTween(this.actor,
Tweener.addTween(this,
{ opacity: 255,
time: 1,
transition: 'easeInQuad' });
return true;
},
}
close() {
Main.popModal(this.actor);
Main.ctrlAltTabManager.removeGroup(this.actor);
},
Main.popModal(this);
Main.ctrlAltTabManager.removeGroup(this);
}
cancel() {
this._authPrompt.cancel();
},
}
addCharacter(unichar) {
// Don't allow type ahead at the login screen
},
}
finish(onComplete) {
this._authPrompt.finish(onComplete);
},
}
});
Signals.addSignalMethods(LoginDialog.prototype);

View File

@ -1,7 +1,6 @@
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
const Gio = imports.gi.Gio;
const Lang = imports.lang;
const Signals = imports.signals;
const OVirtCredentialsIface = `
@ -28,33 +27,32 @@ function OVirtCredentials() {
return self;
}
var OVirtCredentialsManager = new Lang.Class({
Name: 'OVirtCredentialsManager',
_init() {
var OVirtCredentialsManager = class {
constructor() {
this._token = null;
this._credentials = new OVirtCredentials();
this._credentials.connectSignal('UserAuthenticated',
this._onUserAuthenticated.bind(this));
},
}
_onUserAuthenticated(proxy, sender, [token]) {
this._token = token;
this.emit('user-authenticated', token);
},
}
hasToken() {
return this._token != null;
},
}
getToken() {
return this._token;
},
}
resetToken() {
this._token = null;
}
});
};
Signals.addSignalMethods(OVirtCredentialsManager.prototype);
function getOVirtCredentialsManager() {

View File

@ -1,7 +1,6 @@
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
const Gio = imports.gi.Gio;
const Lang = imports.lang;
const Shell = imports.gi.Shell;
const Signals = imports.signals;
@ -16,10 +15,8 @@ const Service = Gio.DBusProxy.makeProxyWrapper(ServiceIface);
const RealmIface = loadInterfaceXML("org.freedesktop.realmd.Realm");
const Realm = Gio.DBusProxy.makeProxyWrapper(RealmIface);
var Manager = new Lang.Class({
Name: 'Manager',
_init(parentActor) {
var Manager = class {
constructor(parentActor) {
this._aggregateProvider = Provider(Gio.DBus.system,
'org.freedesktop.realmd',
'/org/freedesktop/realmd',
@ -31,7 +28,7 @@ var Manager = new Lang.Class({
if ('Realms' in properties.deep_unpack())
this._reloadRealms();
});
},
}
_reloadRealms() {
let realmPaths = this._aggregateProvider.Realms;
@ -45,7 +42,7 @@ var Manager = new Lang.Class({
realmPaths[i],
this._onRealmLoaded.bind(this));
}
},
}
_reloadRealm(realm) {
if (!realm.Configured) {
@ -58,7 +55,7 @@ var Manager = new Lang.Class({
this._realms[realm.get_object_path()] = realm;
this._updateLoginFormat();
},
}
_onRealmLoaded(realm, error) {
if (error)
@ -70,7 +67,7 @@ var Manager = new Lang.Class({
if ('Configured' in properties.deep_unpack())
this._reloadRealm(realm);
});
},
}
_updateLoginFormat() {
let newLoginFormat;
@ -87,7 +84,7 @@ var Manager = new Lang.Class({
this._loginFormat = newLoginFormat;
this.emit('login-format-changed', newLoginFormat);
}
},
}
get loginFormat() {
if (this._loginFormat !== undefined)
@ -96,7 +93,7 @@ var Manager = new Lang.Class({
this._updateLoginFormat();
return this._loginFormat;
},
}
release() {
Service(Gio.DBus.system,
@ -107,5 +104,5 @@ var Manager = new Lang.Class({
this._realms = { };
this._updateLoginFormat();
}
});
};
Signals.addSignalMethods(Manager.prototype)

View File

@ -3,7 +3,6 @@
const Clutter = imports.gi.Clutter;
const Gio = imports.gi.Gio;
const GLib = imports.gi.GLib;
const Lang = imports.lang;
const Mainloop = imports.mainloop;
const Signals = imports.signals;
const St = imports.gi.St;
@ -119,10 +118,8 @@ function cloneAndFadeOutActor(actor) {
return hold;
}
var ShellUserVerifier = new Lang.Class({
Name: 'ShellUserVerifier',
_init(client, params) {
var ShellUserVerifier = class {
constructor(client, params) {
params = Params.parse(params, { reauthenticationOnly: false });
this._reauthOnly = params.reauthenticationOnly;
@ -165,7 +162,7 @@ var ShellUserVerifier = new Lang.Class({
this._oVirtUserAuthenticatedId = this._oVirtCredentialsManager.connect('user-authenticated',
this._oVirtUserAuthenticated.bind(this));
},
}
begin(userName, hold) {
this._cancellable = new Gio.Cancellable();
@ -183,7 +180,7 @@ var ShellUserVerifier = new Lang.Class({
} else {
this._client.get_user_verifier(this._cancellable, this._userVerifierGot.bind(this));
}
},
}
cancel() {
if (this._cancellable)
@ -193,14 +190,14 @@ var ShellUserVerifier = new Lang.Class({
this._userVerifier.call_cancel_sync(null);
this.clear();
}
},
}
_clearUserVerifier() {
if (this._userVerifier) {
this._userVerifier.run_dispose();
this._userVerifier = null;
}
},
}
clear() {
if (this._cancellable) {
@ -210,7 +207,7 @@ var ShellUserVerifier = new Lang.Class({
this._clearUserVerifier();
this._clearMessageQueue();
},
}
destroy() {
this.clear();
@ -224,7 +221,7 @@ var ShellUserVerifier = new Lang.Class({
this._oVirtCredentialsManager.disconnect(this._oVirtUserAuthenticatedId);
this._oVirtCredentialsManager = null;
},
}
answerQuery(serviceName, answer) {
if (!this.hasPendingMessages) {
@ -235,12 +232,12 @@ var ShellUserVerifier = new Lang.Class({
this._userVerifier.call_answer_query(serviceName, answer, this._cancellable, null);
});
}
},
}
_getIntervalForMessage(message) {
// We probably could be smarter here
return message.length * USER_READ_TIME;
},
}
finishMessageQueue() {
if (!this.hasPendingMessages)
@ -250,7 +247,7 @@ var ShellUserVerifier = new Lang.Class({
this.hasPendingMessages = false;
this.emit('no-more-messages');
},
}
_queueMessageTimeout() {
if (this._messageQueue.length == 0) {
@ -273,7 +270,7 @@ var ShellUserVerifier = new Lang.Class({
return GLib.SOURCE_REMOVE;
});
GLib.Source.set_name_by_id(this._messageQueueTimeoutId, '[gnome-shell] this._queueMessageTimeout');
},
}
_queueMessage(message, messageType) {
let interval = this._getIntervalForMessage(message);
@ -281,7 +278,7 @@ var ShellUserVerifier = new Lang.Class({
this.hasPendingMessages = true;
this._messageQueue.push({ text: message, type: messageType, interval: interval });
this._queueMessageTimeout();
},
}
_clearMessageQueue() {
this.finishMessageQueue();
@ -291,7 +288,7 @@ var ShellUserVerifier = new Lang.Class({
this._messageQueueTimeoutId = 0;
}
this.emit('show-message', null, MessageType.NONE);
},
}
_checkForFingerprintReader() {
this._haveFingerprintReader = false;
@ -309,12 +306,12 @@ var ShellUserVerifier = new Lang.Class({
this._updateDefaultService();
}
});
},
}
_oVirtUserAuthenticated(token) {
this._preemptingService = OVIRT_SERVICE_NAME;
this.emit('ovirt-user-authenticated');
},
}
_checkForSmartcard() {
let smartcardDetected;
@ -336,7 +333,7 @@ var ShellUserVerifier = new Lang.Class({
this.emit('smartcard-status-changed');
}
},
}
_reportInitError(where, error) {
logError(error, where);
@ -344,7 +341,7 @@ var ShellUserVerifier = new Lang.Class({
this._queueMessage(_("Authentication error"), MessageType.ERROR);
this._verificationFailed(false);
},
}
_reauthenticationChannelOpened(client, result) {
try {
@ -371,7 +368,7 @@ var ShellUserVerifier = new Lang.Class({
this._connectSignals();
this._beginVerification();
this._hold.release();
},
}
_userVerifierGot(client, result) {
try {
@ -387,7 +384,7 @@ var ShellUserVerifier = new Lang.Class({
this._connectSignals();
this._beginVerification();
this._hold.release();
},
}
_connectSignals() {
this._userVerifier.connect('info', this._onInfo.bind(this));
@ -397,22 +394,22 @@ var ShellUserVerifier = new Lang.Class({
this._userVerifier.connect('conversation-stopped', this._onConversationStopped.bind(this));
this._userVerifier.connect('reset', this._onReset.bind(this));
this._userVerifier.connect('verification-complete', this._onVerificationComplete.bind(this));
},
}
_getForegroundService() {
if (this._preemptingService)
return this._preemptingService;
return this._defaultService;
},
}
serviceIsForeground(serviceName) {
return serviceName == this._getForegroundService();
},
}
serviceIsDefault(serviceName) {
return serviceName == this._defaultService;
},
}
_updateDefaultService() {
if (this._settings.get_boolean(PASSWORD_AUTHENTICATION_KEY))
@ -426,7 +423,7 @@ var ShellUserVerifier = new Lang.Class({
log("no authentication service is enabled, using password authentication");
this._defaultService = PASSWORD_SERVICE_NAME;
}
},
}
_startService(serviceName) {
this._hold.acquire();
@ -462,14 +459,14 @@ var ShellUserVerifier = new Lang.Class({
this._hold.release();
});
}
},
}
_beginVerification() {
this._startService(this._getForegroundService());
if (this._userName && this._haveFingerprintReader && !this.serviceIsForeground(FINGERPRINT_SERVICE_NAME))
this._startService(FINGERPRINT_SERVICE_NAME);
},
}
_onInfo(client, serviceName, info) {
if (this.serviceIsForeground(serviceName)) {
@ -484,21 +481,21 @@ var ShellUserVerifier = new Lang.Class({
// to indicate the user can swipe their finger instead
this._queueMessage(_("(or swipe finger)"), MessageType.HINT);
}
},
}
_onProblem(client, serviceName, problem) {
if (!this.serviceIsForeground(serviceName))
return;
this._queueMessage(problem, MessageType.ERROR);
},
}
_onInfoQuery(client, serviceName, question) {
if (!this.serviceIsForeground(serviceName))
return;
this.emit('ask-question', serviceName, question, '');
},
}
_onSecretInfoQuery(client, serviceName, secretQuestion) {
if (!this.serviceIsForeground(serviceName))
@ -511,7 +508,7 @@ var ShellUserVerifier = new Lang.Class({
}
this.emit('ask-question', serviceName, secretQuestion, '\u25cf');
},
}
_onReset() {
// Clear previous attempts to authenticate
@ -519,20 +516,20 @@ var ShellUserVerifier = new Lang.Class({
this._updateDefaultService();
this.emit('reset');
},
}
_onVerificationComplete() {
this.emit('verification-complete');
},
}
_cancelAndReset() {
this.cancel();
this._onReset();
},
}
_retry() {
this.begin(this._userName, new Batch.Hold());
},
}
_verificationFailed(retry) {
// For Not Listed / enterprise logins, immediately reset
@ -567,7 +564,7 @@ var ShellUserVerifier = new Lang.Class({
}
this.emit('verification-failed', canRetry);
},
}
_onConversationStopped(client, serviceName) {
// If the login failed with the preauthenticated oVirt credentials
@ -586,6 +583,6 @@ var ShellUserVerifier = new Lang.Class({
if (this.serviceIsForeground(serviceName)) {
this._verificationFailed(true);
}
},
});
}
};
Signals.addSignalMethods(ShellUserVerifier.prototype);

View File

@ -16,6 +16,7 @@
<file>misc/history.js</file>
<file>misc/ibusManager.js</file>
<file>misc/inputMethod.js</file>
<file>misc/introspect.js</file>
<file>misc/jsParse.js</file>
<file>misc/keyboardManager.js</file>
<file>misc/loginManager.js</file>
@ -81,7 +82,6 @@
<file>ui/panelMenu.js</file>
<file>ui/pointerWatcher.js</file>
<file>ui/popupMenu.js</file>
<file>ui/remoteMenu.js</file>
<file>ui/remoteSearch.js</file>
<file>ui/runDialog.js</file>
<file>ui/screenShield.js</file>

View File

@ -3,7 +3,6 @@
// Common utils for the extension system and the extension
// preferences tool
const Lang = imports.lang;
const Signals = imports.signals;
const Gio = imports.gi.Gio;
@ -160,9 +159,7 @@ function installImporter(extension) {
imports.searchPath = oldSearchPath;
}
var ExtensionFinder = new Lang.Class({
Name: 'ExtensionFinder',
var ExtensionFinder = class {
_loadExtension(extensionDir, info, perUserDir) {
let fileType = info.get_file_type();
if (fileType != Gio.FileType.DIRECTORY)
@ -184,7 +181,7 @@ var ExtensionFinder = new Lang.Class({
return;
}
this.emit('extension-found', extension);
},
}
scanExtensions() {
let perUserDir = Gio.File.new_for_path(global.userdatadir);
@ -192,5 +189,5 @@ var ExtensionFinder = new Lang.Class({
this._loadExtension(dir, info, perUserDir);
});
}
});
};
Signals.addSignalMethods(ExtensionFinder.prototype);

View File

@ -2,7 +2,6 @@
const Gio = imports.gi.Gio;
const GLib = imports.gi.GLib;
const Lang = imports.lang;
const Config = imports.misc.config;
const Params = imports.misc.params;

View File

@ -1,7 +1,6 @@
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
const Gio = imports.gi.Gio;
const Lang = imports.lang;
const Signals = imports.signals;
const { loadInterfaceXML } = imports.misc.fileUtils;

View File

@ -1,16 +1,13 @@
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
const Lang = imports.lang;
const Signals = imports.signals;
const Clutter = imports.gi.Clutter;
const Params = imports.misc.params;
var DEFAULT_LIMIT = 512;
var HistoryManager = new Lang.Class({
Name: 'HistoryManager',
_init(params) {
var HistoryManager = class {
constructor(params) {
params = Params.parse(params, { gsettingsKey: null,
limit: DEFAULT_LIMIT,
entry: null });
@ -34,12 +31,12 @@ var HistoryManager = new Lang.Class({
this._entry.connect('key-press-event',
this._onEntryKeyPress.bind(this));
}
},
}
_historyChanged() {
this._history = global.settings.get_strv(this._key);
this._historyIndex = this._history.length;
},
}
_setPrevItem(text) {
if (this._historyIndex <= 0)
@ -50,7 +47,7 @@ var HistoryManager = new Lang.Class({
this._historyIndex--;
this._indexChanged();
return true;
},
}
_setNextItem(text) {
if (this._historyIndex >= this._history.length)
@ -61,7 +58,7 @@ var HistoryManager = new Lang.Class({
this._historyIndex++;
this._indexChanged();
return true;
},
}
lastItem() {
if (this._historyIndex != this._history.length) {
@ -70,7 +67,7 @@ var HistoryManager = new Lang.Class({
}
return this._historyIndex ? this._history[this._historyIndex -1] : null;
},
}
addItem(input) {
if (this._history.length == 0 ||
@ -81,7 +78,7 @@ var HistoryManager = new Lang.Class({
this._save();
}
this._historyIndex = this._history.length;
},
}
_onEntryKeyPress(entry, event) {
let symbol = event.get_key_symbol();
@ -91,7 +88,7 @@ var HistoryManager = new Lang.Class({
return this._setNextItem(entry.get_text());
}
return Clutter.EVENT_PROPAGATE;
},
}
_indexChanged() {
let current = this._history[this._historyIndex] || '';
@ -99,7 +96,7 @@ var HistoryManager = new Lang.Class({
if (this._entry)
this._entry.set_text(current);
},
}
_save() {
if (this._history.length > this._limit)
@ -108,5 +105,5 @@ var HistoryManager = new Lang.Class({
if (this._key)
global.settings.set_strv(this._key, this._history);
}
});
};
Signals.addSignalMethods(HistoryManager.prototype);

View File

@ -2,7 +2,6 @@
const Gio = imports.gi.Gio;
const GLib = imports.gi.GLib;
const Lang = imports.lang;
const Mainloop = imports.mainloop;
const Signals = imports.signals;
@ -32,17 +31,16 @@ function getIBusManager() {
return _ibusManager;
}
var IBusManager = new Lang.Class({
Name: 'IBusManager',
// This is the longest we'll keep the keyboard frozen until an input
// source is active.
_MAX_INPUT_SOURCE_ACTIVATION_TIME: 4000, // ms
_PRELOAD_ENGINES_DELAY_TIME: 30, // sec
_init() {
var IBusManager = class {
constructor() {
IBus.init();
// This is the longest we'll keep the keyboard frozen until an input
// source is active.
this._MAX_INPUT_SOURCE_ACTIVATION_TIME = 4000; // ms
this._PRELOAD_ENGINES_DELAY_TIME = 30; // sec
this._candidatePopup = new IBusCandidatePopup.CandidatePopup();
this._panelService = null;
@ -60,7 +58,7 @@ var IBusManager = new Lang.Class({
this._ibus.connect('global-engine-changed', this._engineChanged.bind(this));
this._spawn();
},
}
_spawn() {
try {
@ -69,7 +67,7 @@ var IBusManager = new Lang.Class({
} catch(e) {
log('Failed to launch ibus-daemon: ' + e.message);
}
},
}
_clear() {
if (this._panelService)
@ -85,7 +83,7 @@ var IBusManager = new Lang.Class({
this.emit('ready', false);
this._spawn();
},
}
_onConnected() {
this._ibus.list_engines_async(-1, null, this._initEngines.bind(this));
@ -93,7 +91,7 @@ var IBusManager = new Lang.Class({
IBus.BusNameFlag.REPLACE_EXISTING,
-1, null,
this._initPanelService.bind(this));
},
}
_initEngines(ibus, result) {
let enginesList = this._ibus.list_engines_async_finish(result);
@ -106,7 +104,7 @@ var IBusManager = new Lang.Class({
} else {
this._clear();
}
},
}
_initPanelService(ibus, result) {
let success = this._ibus.request_name_async_finish(result);
@ -151,13 +149,13 @@ var IBusManager = new Lang.Class({
} else {
this._clear();
}
},
}
_updateReadiness() {
this._ready = (Object.keys(this._engines).length > 0 &&
this._panelService != null);
this.emit('ready', this._ready);
},
}
_engineChanged(bus, engineName) {
if (!this._ready)
@ -178,26 +176,26 @@ var IBusManager = new Lang.Class({
this.emit('properties-registered', this._currentEngineName, props);
});
},
}
_updateProperty(panel, prop) {
this.emit('property-updated', this._currentEngineName, prop);
},
}
_setContentType(panel, purpose, hints) {
this.emit('set-content-type', purpose, hints);
},
}
activateProperty(key, state) {
this._panelService.property_activate(key, state);
},
}
getEngineDesc(id) {
if (!this._ready || !this._engines.hasOwnProperty(id))
return null;
return this._engines[id];
},
}
setEngine(id, callback) {
// Send id even if id == this._currentEngineName
@ -210,8 +208,8 @@ var IBusManager = new Lang.Class({
}
this._ibus.set_global_engine_async(id, this._MAX_INPUT_SOURCE_ACTIVATION_TIME,
null, callback);
},
null, callback || null);
}
preloadEngines(ids) {
if (!this._ibus || ids.length == 0)
@ -233,6 +231,6 @@ var IBusManager = new Lang.Class({
this._preloadEnginesId = 0;
return GLib.SOURCE_REMOVE;
});
},
});
}
};
Signals.addSignalMethods(IBusManager.prototype);

View File

@ -1,22 +1,20 @@
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
const Clutter = imports.gi.Clutter;
const GObject = imports.gi.GObject;
const IBus = imports.gi.IBus;
const Keyboard = imports.ui.status.keyboard;
const Lang = imports.lang;
const Signals = imports.signals;
var InputMethod = new Lang.Class({
Name: 'InputMethod',
Extends: Clutter.InputMethod,
var InputMethod = GObject.registerClass(
class InputMethod extends Clutter.InputMethod {
_init() {
this.parent();
super._init();
this._hints = 0;
this._purpose = 0;
this._enabled = true;
this._currentFocus = null;
this._preeditStr = '';
this._preeditPos = 0;
this._preeditVisible = false;
this._ibus = IBus.Bus.new_async();
this._ibus.connect('connected', this._onConnected.bind(this));
this._ibus.connect('disconnected', this._clear.bind(this));
@ -29,11 +27,11 @@ var InputMethod = new Lang.Class({
if (this._ibus.is_connected())
this._onConnected();
},
}
get currentFocus() {
return this._currentFocus;
},
}
_updateCapabilities() {
let caps = 0;
@ -48,21 +46,19 @@ var InputMethod = new Lang.Class({
if (this._context)
this._context.set_capabilities(caps);
},
}
_onSourceChanged() {
this._currentSource = this._inputSourceManager.currentSource;
},
}
_onConnected() {
this._ibus.create_input_context_async ('gnome-shell', -1, null,
this._setContext.bind(this));
},
}
_setContext(bus, res) {
this._context = this._ibus.create_input_context_async_finish(res);
this._context.connect('enabled', () => { this._enabled = true });
this._context.connect('disabled', () => { this._enabled = false });
this._context.connect('commit-text', this._onCommitText.bind(this));
this._context.connect('delete-surrounding-text', this._onDeleteSurroundingText.bind(this));
this._context.connect('update-preedit-text', this._onUpdatePreeditText.bind(this));
@ -71,48 +67,55 @@ var InputMethod = new Lang.Class({
this._context.connect('forward-key-event', this._onForwardKeyEvent.bind(this));
this._updateCapabilities();
},
}
_clear() {
this._context = null;
this._hints = 0;
this._purpose = 0;
this._enabled = false;
this._preeditStr = ''
this._preeditPos = 0;
},
this._preeditVisible = false;
}
_emitRequestSurrounding() {
if (this._context.needs_surrounding_text())
this.emit('request-surrounding');
},
}
_onCommitText(context, text) {
this.commit(text.get_text());
},
}
_onDeleteSurroundingText(context) {
this.delete_surrounding();
},
}
_onUpdatePreeditText(context, text, pos, visible) {
if (text == null)
return;
this._preeditStr = text.get_text();
this._preeditPos = pos;
let preedit = text.get_text();
if (visible)
this.set_preedit_text(this._preeditStr, pos);
else
this.set_preedit_text(preedit, pos);
else if (this._preeditVisible)
this.set_preedit_text(null, pos);
},
this._preeditStr = preedit;
this._preeditPos = pos;
this._preeditVisible = visible;
}
_onShowPreeditText(context) {
this._preeditVisible = true;
this.set_preedit_text(this._preeditStr, this._preeditPos);
},
}
_onHidePreeditText(context) {
this.set_preedit_text(null, this._preeditPos);
},
this._preeditVisible = false;
}
_onForwardKeyEvent(context, keyval, keycode, state) {
let press = (state & IBus.ModifierType.RELEASE_MASK) == 0;
@ -126,7 +129,7 @@ var InputMethod = new Lang.Class({
time = global.display.get_current_time_roundtrip();
this.forward_key(keyval, keycode + 8, state & Clutter.ModifierType.MODIFIER_MASK, time, press);
},
}
vfunc_focus_in(focus) {
this._currentFocus = focus;
@ -135,7 +138,7 @@ var InputMethod = new Lang.Class({
this._updateCapabilities();
this._emitRequestSurrounding();
}
},
}
vfunc_focus_out() {
this._currentFocus = null;
@ -144,9 +147,12 @@ var InputMethod = new Lang.Class({
this._updateCapabilities();
}
// Unset any preedit text
this.set_preedit_text(null, 0);
},
if (this._preeditStr) {
// Unset any preedit text
this.set_preedit_text(null, 0);
this._preeditStr = null;
}
}
vfunc_reset() {
if (this._context) {
@ -154,9 +160,12 @@ var InputMethod = new Lang.Class({
this._emitRequestSurrounding();
}
// Unset any preedit text
this.set_preedit_text(null, 0);
},
if (this._preeditStr) {
// Unset any preedit text
this.set_preedit_text(null, 0);
this._preeditStr = null;
}
}
vfunc_set_cursor_location(rect) {
if (this._context) {
@ -164,7 +173,7 @@ var InputMethod = new Lang.Class({
rect.get_width(), rect.get_height());
this._emitRequestSurrounding();
}
},
}
vfunc_set_surrounding(text, cursor, anchor) {
if (!this._context || !text)
@ -172,7 +181,7 @@ var InputMethod = new Lang.Class({
let ibusText = IBus.Text.new_from_string(text);
this._context.set_surrounding_text(ibusText, cursor, anchor);
},
}
vfunc_update_content_hints(hints) {
let ibusHints = 0;
@ -192,7 +201,7 @@ var InputMethod = new Lang.Class({
this._hints = ibusHints;
if (this._context)
this._context.set_content_type(this._purpose, this._hints);
},
}
vfunc_update_content_purpose(purpose) {
let ibusPurpose = 0;
@ -218,10 +227,10 @@ var InputMethod = new Lang.Class({
this._purpose = ibusPurpose;
if (this._context)
this._context.set_content_type(this._purpose, this._hints);
},
}
vfunc_filter_key_event(event) {
if (!this._context || !this._enabled)
if (!this._context)
return false;
if (!this._currentSource)
return false;
@ -245,5 +254,5 @@ var InputMethod = new Lang.Class({
}
});
return true;
},
}
});

163
js/misc/introspect.js Normal file
View File

@ -0,0 +1,163 @@
const Gio = imports.gi.Gio;
const GLib = imports.gi.GLib;
const Meta = imports.gi.Meta;
const Shell = imports.gi.Shell;
const INTROSPECT_SCHEMA = 'org.gnome.shell';
const INTROSPECT_KEY = 'introspect';
const APP_WHITELIST = ['org.freedesktop.impl.portal.desktop.gtk'];
const { loadInterfaceXML } = imports.misc.fileUtils;
const IntrospectDBusIface = loadInterfaceXML('org.gnome.Shell.Introspect');
var IntrospectService = class {
constructor() {
this._dbusImpl = Gio.DBusExportedObject.wrapJSObject(IntrospectDBusIface,
this);
this._dbusImpl.export(Gio.DBus.session, '/org/gnome/Shell/Introspect');
Gio.DBus.session.own_name('org.gnome.Shell.Introspect',
Gio.BusNameOwnerFlags.REPLACE,
null, null);
this._runningApplications = {};
this._runningApplicationsDirty = true;
this._activeApplication = null;
this._activeApplicationDirty = true;
this._appSystem = Shell.AppSystem.get_default();
this._appSystem.connect('app-state-changed',
() => {
this._runningApplicationsDirty = true;
this._syncRunningApplications();
});
this._settings = new Gio.Settings({ schema_id: INTROSPECT_SCHEMA });
let tracker = Shell.WindowTracker.get_default();
tracker.connect('notify::focus-app',
() => {
this._activeApplicationDirty = true;
this._syncRunningApplications();
});
this._syncRunningApplications();
}
_isStandaloneApp(app) {
let windows = app.get_windows();
return app.get_windows().some(w => w.transient_for == null);
}
_isIntrospectEnabled() {
return this._settings.get_boolean(INTROSPECT_KEY);
}
_isSenderWhitelisted(sender) {
return APP_WHITELIST.includes(sender);
}
_syncRunningApplications() {
let tracker = Shell.WindowTracker.get_default();
let apps = this._appSystem.get_running();
let seatName = "seat0";
let newRunningApplications = {};
let newActiveApplication = null;
let focusedApp = tracker.focus_app;
for (let app of apps) {
let appInfo = {};
let isAppActive = (focusedApp == app);
if (!this._isStandaloneApp(app))
continue;
if (isAppActive) {
appInfo['active-on-seats'] = new GLib.Variant('as', [seatName]);
newActiveApplication = app.get_id();
}
newRunningApplications[app.get_id()] = appInfo;
}
if (this._runningApplicationsDirty ||
(this._activeApplicationDirty &&
this._activeApplication != newActiveApplication)) {
this._runningApplications = newRunningApplications;
this._activeApplication = newActiveApplication;
this._dbusImpl.emit_signal('RunningApplicationsChanged', null);
}
this._runningApplicationsDirty = false;
this._activeApplicationDirty = false;
}
_isEligibleWindow(window) {
if (window.is_override_redirect())
return false;
let type = window.get_window_type();
return (type == Meta.WindowType.NORMAL ||
type == Meta.WindowType.DIALOG ||
type == Meta.WindowType.MODAL_DIALOG ||
type == Meta.WindowType.UTILITY);
}
GetRunningApplicationsAsync(params, invocation) {
if (!this._isIntrospectEnabled() &&
!this._isSenderWhitelisted(invocation.get_sender())) {
invocation.return_error_literal(Gio.DBusError,
Gio.DBusError.ACCESS_DENIED,
'App introspection not allowed');
return;
}
invocation.return_value(new GLib.Variant('(a{sa{sv}})', [this._runningApplications]));
}
GetWindowsAsync(params, invocation) {
let focusWindow = global.display.get_focus_window();
let apps = this._appSystem.get_running();
let windowsList = {};
if (!this._isIntrospectEnabled()) {
invocation.return_error_literal(Gio.DBusError,
Gio.DBusError.ACCESS_DENIED,
'App introspection not allowed');
return;
}
for (let app of apps) {
let windows = app.get_windows();
for (let window of windows) {
if (!this._isEligibleWindow(window))
continue;
let windowId = window.get_id();
let frameRect = window.get_frame_rect();
let title = window.get_title();
let wmClass = window.get_wm_class();
windowsList[windowId] = {
'app-id': GLib.Variant.new('s', app.get_id()),
'client-type': GLib.Variant.new('u', window.get_client_type()),
'is-hidden': GLib.Variant.new('b', window.is_hidden()),
'has-focus': GLib.Variant.new('b', (window == focusWindow)),
'width': GLib.Variant.new('u', frameRect.width),
'height': GLib.Variant.new('u', frameRect.height)
};
// These properties may not be available for all windows:
if (title != null)
windowsList[windowId]['title'] = GLib.Variant.new('s', title);
if (wmClass != null)
windowsList[windowId]['wm-class'] = GLib.Variant.new('s', wmClass);
}
}
invocation.return_value(new GLib.Variant('(a{ta{sv}})', [windowsList]));
}
};

View File

@ -2,7 +2,6 @@
const GLib = imports.gi.GLib;
const GnomeDesktop = imports.gi.GnomeDesktop;
const Lang = imports.lang;
const Meta = imports.gi.Meta;
const Main = imports.ui.main;
@ -38,31 +37,38 @@ function holdKeyboard() {
global.display.freeze_keyboard(global.get_current_time());
}
var KeyboardManager = new Lang.Class({
Name: 'KeyboardManager',
var KeyboardManager = class {
constructor() {
// The XKB protocol doesn't allow for more that 4 layouts in a
// keymap. Wayland doesn't impose this limit and libxkbcommon can
// handle up to 32 layouts but since we need to support X clients
// even as a Wayland compositor, we can't bump this.
this.MAX_LAYOUTS_PER_GROUP = 4;
// The XKB protocol doesn't allow for more that 4 layouts in a
// keymap. Wayland doesn't impose this limit and libxkbcommon can
// handle up to 32 layouts but since we need to support X clients
// even as a Wayland compositor, we can't bump this.
MAX_LAYOUTS_PER_GROUP: 4,
_init() {
this._xkbInfo = getXkbInfo();
this._current = null;
this._localeLayoutInfo = this._getLocaleLayout();
this._layoutInfos = {};
},
this._currentKeymap = null;
}
_applyLayoutGroup(group) {
let options = this._buildOptionsString();
let [layouts, variants] = this._buildGroupStrings(group);
if (this._currentKeymap &&
this._currentKeymap.layouts == layouts &&
this._currentKeymap.variants == variants &&
this._currentKeymap.options == options)
return;
this._currentKeymap = {layouts, variants, options};
Meta.get_backend().set_keymap(layouts, variants, options);
},
}
_applyLayoutGroupIndex(idx) {
Meta.get_backend().lock_layout_group(idx);
},
}
apply(id) {
let info = this._layoutInfos[id];
@ -78,7 +84,7 @@ var KeyboardManager = new Lang.Class({
}
this._current = info;
},
}
reapply() {
if (!this._current)
@ -86,11 +92,9 @@ var KeyboardManager = new Lang.Class({
this._applyLayoutGroup(this._current.group);
this._applyLayoutGroupIndex(this._current.groupIndex);
},
}
setUserLayouts(ids) {
let currentId = this._current ? this._current.id : null;
let currentGroupIndex = this._current ? this._current.groupIndex : null;
this._current = null;
this._layoutInfos = {};
@ -117,12 +121,9 @@ var KeyboardManager = new Lang.Class({
info.group = group;
info.groupIndex = groupIndex;
if (currentId == id && currentGroupIndex == groupIndex)
this._current = info;
i += 1;
}
},
}
_getLocaleLayout() {
let locale = GLib.get_language_names()[0];
@ -139,21 +140,21 @@ var KeyboardManager = new Lang.Class({
return { layout: _layout, variant: _variant };
else
return { layout: DEFAULT_LAYOUT, variant: DEFAULT_VARIANT };
},
}
_buildGroupStrings(_group) {
let group = _group.concat(this._localeLayoutInfo);
let layouts = group.map(g => g.layout).join(',');
let variants = group.map(g => g.variant).join(',');
return [layouts, variants];
},
}
setKeyboardOptions(options) {
this._xkbOptions = options;
},
}
_buildOptionsString() {
let options = this._xkbOptions.join(',');
return options;
}
});
};

View File

@ -2,7 +2,6 @@
const GLib = imports.gi.GLib;
const Gio = imports.gi.Gio;
const Lang = imports.lang;
const Mainloop = imports.mainloop;
const Shell = imports.gi.Shell;
const Signals = imports.signals;
@ -70,10 +69,8 @@ function getLoginManager() {
return _loginManager;
}
var LoginManagerSystemd = new Lang.Class({
Name: 'LoginManagerSystemd',
_init() {
var LoginManagerSystemd = class {
constructor() {
this._proxy = new SystemdLoginManager(Gio.DBus.system,
'org.freedesktop.login1',
'/org/freedesktop/login1');
@ -82,7 +79,7 @@ var LoginManagerSystemd = new Lang.Class({
'/org/freedesktop/login1/user/self');
this._proxy.connectSignal('PrepareForSleep',
this._prepareForSleep.bind(this));
},
}
getCurrentSessionProxy(callback) {
if (this._currentSession) {
@ -129,7 +126,7 @@ var LoginManagerSystemd = new Lang.Class({
callback(this._currentSession);
}
});
},
}
canSuspend(asyncCallback) {
this._proxy.CanSuspendRemote((result, error) => {
@ -141,7 +138,7 @@ var LoginManagerSystemd = new Lang.Class({
asyncCallback(canSuspend, needsAuth);
}
});
},
}
listSessions(asyncCallback) {
this._proxy.ListSessionsRemote((result, error) => {
@ -150,11 +147,11 @@ var LoginManagerSystemd = new Lang.Class({
else
asyncCallback(result[0]);
});
},
}
suspend() {
this._proxy.SuspendRemote(true);
},
}
inhibit(reason, callback) {
let inVariant = GLib.Variant.new('(ssss)',
@ -174,38 +171,36 @@ var LoginManagerSystemd = new Lang.Class({
callback(null);
}
});
},
}
_prepareForSleep(proxy, sender, [aboutToSuspend]) {
this.emit('prepare-for-sleep', aboutToSuspend);
}
});
};
Signals.addSignalMethods(LoginManagerSystemd.prototype);
var LoginManagerDummy = new Lang.Class({
Name: 'LoginManagerDummy',
var LoginManagerDummy = class {
getCurrentSessionProxy(callback) {
// we could return a DummySession object that fakes whatever callers
// expect (at the time of writing: connect() and connectSignal()
// methods), but just never calling the callback should be safer
},
}
canSuspend(asyncCallback) {
asyncCallback(false, false);
},
}
listSessions(asyncCallback) {
asyncCallback([]);
},
}
suspend() {
this.emit('prepare-for-sleep', true);
this.emit('prepare-for-sleep', false);
},
}
inhibit(reason, callback) {
callback(null);
}
});
};
Signals.addSignalMethods(LoginManagerDummy.prototype);

View File

@ -1,7 +1,6 @@
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
const Gio = imports.gi.Gio;
const Lang = imports.lang;
const NMA = imports.gi.NMA;
const Signals = imports.signals;
@ -100,10 +99,8 @@ const ModemGsmNetworkProxy = Gio.DBusProxy.makeProxyWrapper(ModemGsmNetworkInter
const ModemCdmaInterface = loadInterfaceXML('org.freedesktop.ModemManager.Modem.Cdma');
const ModemCdmaProxy = Gio.DBusProxy.makeProxyWrapper(ModemCdmaInterface);
var ModemGsm = new Lang.Class({
Name: 'ModemGsm',
_init(path) {
var ModemGsm = class {
constructor(path) {
this._proxy = new ModemGsmNetworkProxy(Gio.DBus.system, 'org.freedesktop.ModemManager', path);
this.signal_quality = 0;
@ -139,13 +136,11 @@ var ModemGsm = new Lang.Class({
this.emit('notify::signal-quality');
});
}
});
};
Signals.addSignalMethods(ModemGsm.prototype);
var ModemCdma = new Lang.Class({
Name: 'ModemCdma',
_init(path) {
var ModemCdma = class {
constructor(path) {
this._proxy = new ModemCdmaProxy(Gio.DBus.system, 'org.freedesktop.ModemManager', path);
this.signal_quality = 0;
@ -169,7 +164,7 @@ var ModemCdma = new Lang.Class({
}
this.emit('notify::signal-quality');
});
},
}
_refreshServingSystem() {
this._proxy.GetServingSystemRemote(([result], err) => {
@ -184,7 +179,7 @@ var ModemCdma = new Lang.Class({
this.emit('notify::operator-name');
});
}
});
};
Signals.addSignalMethods(ModemCdma.prototype);
@ -201,10 +196,8 @@ const BroadbandModem3gppProxy = Gio.DBusProxy.makeProxyWrapper(BroadbandModem3gp
const BroadbandModemCdmaInterface = loadInterfaceXML('org.freedesktop.ModemManager1.Modem.ModemCdma');
const BroadbandModemCdmaProxy = Gio.DBusProxy.makeProxyWrapper(BroadbandModemCdmaInterface);
var BroadbandModem = new Lang.Class({
Name: 'BroadbandModem',
_init(path, capabilities) {
var BroadbandModem = class {
constructor(path, capabilities) {
this._proxy = new BroadbandModemProxy(Gio.DBus.system, 'org.freedesktop.ModemManager1', path);
this._proxy_3gpp = new BroadbandModem3gppProxy(Gio.DBus.system, 'org.freedesktop.ModemManager1', path);
this._proxy_cdma = new BroadbandModemCdmaProxy(Gio.DBus.system, 'org.freedesktop.ModemManager1', path);
@ -229,13 +222,13 @@ var BroadbandModem = new Lang.Class({
this._reloadCdmaOperatorName();
});
this._reloadCdmaOperatorName();
},
}
_reloadSignalQuality() {
let [quality, recent] = this._proxy.SignalQuality;
this.signal_quality = quality;
this.emit('notify::signal-quality');
},
}
_reloadOperatorName() {
let new_name = "";
@ -250,19 +243,19 @@ var BroadbandModem = new Lang.Class({
this.operator_name = new_name;
this.emit('notify::operator-name');
},
}
_reload3gppOperatorName() {
let name = this._proxy_3gpp.OperatorName;
let code = this._proxy_3gpp.OperatorCode;
this.operator_name_3gpp = _findProviderForMccMnc(name, code);
this._reloadOperatorName();
},
}
_reloadCdmaOperatorName() {
let sid = this._proxy_cdma.Sid;
this.operator_name_cdma = _findProviderForSid(sid);
this._reloadOperatorName();
}
});
};
Signals.addSignalMethods(BroadbandModem.prototype);

View File

@ -2,7 +2,6 @@
const Gio = imports.gi.Gio;
const GLib = imports.gi.GLib;
const Lang = imports.lang;
const Params = imports.misc.params;
const Signals = imports.signals;
@ -27,9 +26,8 @@ const ObjectManagerIface = `
const ObjectManagerInfo = Gio.DBusInterfaceInfo.new_for_xml(ObjectManagerIface);
var ObjectManager = new Lang.Class({
Name: 'ObjectManager',
_init(params) {
var ObjectManager = class {
constructor(params) {
params = Params.parse(params, { connection: null,
name: null,
objectPath: null,
@ -63,7 +61,7 @@ var ObjectManager = new Lang.Class({
this._managerProxy.init_async(GLib.PRIORITY_DEFAULT,
this._cancellable,
this._onManagerProxyLoaded.bind(this));
},
}
_tryToCompleteLoad() {
if (this._numLoadInhibitors == 0)
@ -74,7 +72,7 @@ var ObjectManager = new Lang.Class({
if (this._onLoaded)
this._onLoaded();
}
},
}
_addInterface(objectPath, interfaceName, onFinished) {
let info = this._interfaceInfos[interfaceName];
@ -129,7 +127,7 @@ var ObjectManager = new Lang.Class({
if (onFinished)
onFinished();
});
},
}
_removeInterface(objectPath, interfaceName) {
if (!this._objects[objectPath])
@ -155,7 +153,7 @@ var ObjectManager = new Lang.Class({
delete this._objects[objectPath];
this.emit('object-removed', objectPath);
}
},
}
_onManagerProxyLoaded(initable, result) {
let error = null;
@ -194,7 +192,7 @@ var ObjectManager = new Lang.Class({
if (this._managerProxy.g_name_owner)
this._onNameAppeared();
},
}
_onNameAppeared() {
this._managerProxy.GetManagedObjectsRemote((result, error) => {
@ -232,7 +230,7 @@ var ObjectManager = new Lang.Class({
}
this._tryToCompleteLoad();
});
},
}
_onNameVanished() {
let objectPaths = Object.keys(this._objects);
@ -248,14 +246,14 @@ var ObjectManager = new Lang.Class({
this._removeInterface(objectPath, interfaceName);
}
}
},
}
_registerInterfaces(interfaces) {
for (let i = 0; i < interfaces.length; i++) {
let info = Gio.DBusInterfaceInfo.new_for_xml(interfaces[i]);
this._interfaceInfos[info.name] = info;
}
},
}
getProxy(objectPath, interfaceName) {
let object = this._objects[objectPath];
@ -264,7 +262,7 @@ var ObjectManager = new Lang.Class({
return null;
return object[interfaceName];
},
}
getProxiesForInterface(interfaceName) {
let proxyList = this._interfaces[interfaceName];
@ -273,7 +271,7 @@ var ObjectManager = new Lang.Class({
return [];
return proxyList;
},
}
getAllProxies() {
let proxies = [];
@ -292,5 +290,5 @@ var ObjectManager = new Lang.Class({
return proxies;
}
});
};
Signals.addSignalMethods(ObjectManager.prototype);

View File

@ -1,7 +1,6 @@
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
const Gio = imports.gi.Gio;
const Lang = imports.lang;
const Shell = imports.gi.Shell;
const Signals = imports.signals;
@ -26,9 +25,8 @@ function getSmartcardManager() {
return _smartcardManager;
}
var SmartcardManager = new Lang.Class({
Name: 'SmartcardManager',
_init() {
var SmartcardManager = class {
constructor() {
this._objectManager = new ObjectManager.ObjectManager({ connection: Gio.DBus.session,
name: "org.gnome.SettingsDaemon.Smartcard",
objectPath: '/org/gnome/SettingsDaemon/Smartcard',
@ -36,7 +34,7 @@ var SmartcardManager = new Lang.Class({
onLoaded: this._onLoaded.bind(this) });
this._insertedTokens = {};
this._loginToken = null;
},
}
_onLoaded() {
let tokens = this._objectManager.getProxiesForInterface('org.gnome.SettingsDaemon.Smartcard.Token');
@ -53,7 +51,7 @@ var SmartcardManager = new Lang.Class({
if (interfaceName == 'org.gnome.SettingsDaemon.Smartcard.Token')
this._removeToken(proxy);
});
},
}
_updateToken(token) {
let objectPath = token.get_object_path();
@ -65,7 +63,7 @@ var SmartcardManager = new Lang.Class({
if (token.UsedToLogin)
this._loginToken = token;
},
}
_addToken(token) {
this._updateToken(token);
@ -85,7 +83,7 @@ var SmartcardManager = new Lang.Class({
// Emit a smartcard-inserted at startup if it's already plugged in
if (token.IsInserted)
this.emit('smartcard-inserted', token);
},
}
_removeToken(token) {
let objectPath = token.get_object_path();
@ -99,11 +97,11 @@ var SmartcardManager = new Lang.Class({
this._loginToken = null;
token.disconnectAll();
},
}
hasInsertedTokens() {
return Object.keys(this._insertedTokens).length > 0;
},
}
hasInsertedLoginToken() {
if (!this._loginToken)
@ -115,5 +113,5 @@ var SmartcardManager = new Lang.Class({
return true;
}
});
};
Signals.addSignalMethods(SmartcardManager.prototype);

View File

@ -3,7 +3,6 @@ const Clutter = imports.gi.Clutter;
const Gdm = imports.gi.Gdm;
const Gio = imports.gi.Gio;
const GLib = imports.gi.GLib;
const Lang = imports.lang;
const Meta = imports.gi.Meta;
const GObject = imports.gi.GObject;
@ -44,9 +43,7 @@ function getDefault() {
return _singleton;
}
const SystemActions = new Lang.Class({
Name: 'SystemActions',
Extends: GObject.Object,
const SystemActions = GObject.registerClass({
Properties: {
'can-power-off': GObject.ParamSpec.boolean('can-power-off',
'can-power-off',
@ -83,10 +80,10 @@ const SystemActions = new Lang.Class({
'orientation-lock-icon',
GObject.ParamFlags.READWRITE,
null)
},
}
}, class SystemActions extends GObject.Object {
_init() {
this.parent();
super._init();
this._canHavePowerOff = true;
this._canHaveSuspend = true;
@ -186,35 +183,35 @@ const SystemActions = new Lang.Class({
Main.sessionMode.connect('updated', () => { this._sessionUpdated(); });
this._sessionUpdated();
},
}
get can_power_off() {
return this._actions.get(POWER_OFF_ACTION_ID).available;
},
}
get can_suspend() {
return this._actions.get(SUSPEND_ACTION_ID).available;
},
}
get can_lock_screen() {
return this._actions.get(LOCK_SCREEN_ACTION_ID).available;
},
}
get can_switch_user() {
return this._actions.get(SWITCH_USER_ACTION_ID).available;
},
}
get can_logout() {
return this._actions.get(LOGOUT_ACTION_ID).available;
},
}
get can_lock_orientation() {
return this._actions.get(LOCK_ORIENTATION_ACTION_ID).available;
},
}
get orientation_lock_icon() {
return this._actions.get(LOCK_ORIENTATION_ACTION_ID).iconName;
},
}
_sensorProxyAppeared() {
this._sensorProxy = new SensorProxy(Gio.DBus.system, SENSOR_BUS_NAME, SENSOR_OBJECT_PATH,
@ -227,7 +224,7 @@ const SystemActions = new Lang.Class({
() => { this._updateOrientationLock(); });
this._updateOrientationLock();
});
},
}
_updateOrientationLock() {
let available = false;
@ -238,7 +235,7 @@ const SystemActions = new Lang.Class({
this._actions.get(LOCK_ORIENTATION_ACTION_ID).available = available;
this.notify('can-lock-orientation');
},
}
_updateOrientationLockIcon() {
let locked = this._orientationSettings.get_boolean('orientation-lock');
@ -247,14 +244,14 @@ const SystemActions = new Lang.Class({
this._actions.get(LOCK_ORIENTATION_ACTION_ID).iconName = iconName;
this.notify('orientation-lock-icon');
},
}
_sessionUpdated() {
this._updateLockScreen();
this._updatePowerOff();
this._updateSuspend();
this._updateMultiUser();
},
}
forceUpdate() {
// Whether those actions are available or not depends on both lockdown
@ -262,7 +259,7 @@ const SystemActions = new Lang.Class({
// latter, so their value may be outdated; force an update now
this._updateHaveShutdown();
this._updateHaveSuspend();
},
}
getMatchingActions(terms) {
// terms is a list of strings
@ -275,15 +272,15 @@ const SystemActions = new Lang.Class({
results.push(key);
return results;
},
}
getName(id) {
return this._actions.get(id).name;
},
}
getIconName(id) {
return this._actions.get(id).iconName;
},
}
activateAction(id) {
switch (id) {
@ -306,14 +303,14 @@ const SystemActions = new Lang.Class({
this.activateLockOrientation();
break;
}
},
}
_updateLockScreen() {
let showLock = !Main.sessionMode.isLocked && !Main.sessionMode.isGreeter;
let allowLockScreen = !this._lockdownSettings.get_boolean(DISABLE_LOCK_SCREEN_KEY);
this._actions.get(LOCK_SCREEN_ACTION_ID).available = showLock && allowLockScreen && LoginManager.canLock();
this.notify('can-lock-screen');
},
}
_updateHaveShutdown() {
this._session.CanShutdownRemote((result, error) => {
@ -323,7 +320,7 @@ const SystemActions = new Lang.Class({
this._canHavePowerOff = result[0];
this._updatePowerOff();
});
},
}
_updatePowerOff() {
let disabled = Main.sessionMode.isLocked ||
@ -331,7 +328,7 @@ const SystemActions = new Lang.Class({
this._loginScreenSettings.get_boolean(DISABLE_RESTART_KEY));
this._actions.get(POWER_OFF_ACTION_ID).available = this._canHavePowerOff && !disabled;
this.notify('can-power-off');
},
}
_updateHaveSuspend() {
this._loginManager.canSuspend(
@ -340,7 +337,7 @@ const SystemActions = new Lang.Class({
this._suspendNeedsAuth = needsAuth;
this._updateSuspend();
});
},
}
_updateSuspend() {
let disabled = (Main.sessionMode.isLocked &&
@ -349,12 +346,12 @@ const SystemActions = new Lang.Class({
this._loginScreenSettings.get_boolean(DISABLE_RESTART_KEY));
this._actions.get(SUSPEND_ACTION_ID).available = this._canHaveSuspend && !disabled;
this.notify('can-suspend');
},
}
_updateMultiUser() {
this._updateLogout();
this._updateSwitchUser();
},
}
_updateSwitchUser() {
let allowSwitch = !this._lockdownSettings.get_boolean(DISABLE_USER_SWITCH_KEY);
@ -366,7 +363,7 @@ const SystemActions = new Lang.Class({
this.notify('can-switch-user');
return visible;
},
}
_updateLogout() {
let user = this._userManager.get_user(GLib.get_user_name());
@ -384,7 +381,7 @@ const SystemActions = new Lang.Class({
this.notify('can-logout');
return visible;
},
}
activateLockOrientation() {
if (!this._actions.get(LOCK_ORIENTATION_ACTION_ID).available)
@ -392,14 +389,14 @@ const SystemActions = new Lang.Class({
let locked = this._orientationSettings.get_boolean('orientation-lock');
this._orientationSettings.set_boolean('orientation-lock', !locked);
},
}
activateLockScreen() {
if (!this._actions.get(LOCK_SCREEN_ACTION_ID).available)
throw new Error('The lock-screen action is not available!');
Main.screenShield.lock(true);
},
}
activateSwitchUser() {
if (!this._actions.get(SWITCH_USER_ACTION_ID).available)
@ -412,7 +409,7 @@ const SystemActions = new Lang.Class({
Gdm.goto_login_session_sync(null);
return false;
});
},
}
activateLogout() {
if (!this._actions.get(LOGOUT_ACTION_ID).available)
@ -420,14 +417,14 @@ const SystemActions = new Lang.Class({
Main.overview.hide();
this._session.LogoutRemote(0);
},
}
activatePowerOff() {
if (!this._actions.get(POWER_OFF_ACTION_ID).available)
throw new Error('The power-off action is not available!');
this._session.ShutdownRemote(0);
},
}
activateSuspend() {
if (!this._actions.get(SUSPEND_ACTION_ID).available)

View File

@ -4,7 +4,7 @@ const Clutter = imports.gi.Clutter;
const Gettext = imports.gettext;
const Gio = imports.gi.Gio;
const GLib = imports.gi.GLib;
const Lang = imports.lang;
const GObject = imports.gi.GObject;
const Mainloop = imports.mainloop;
const Signals = imports.signals;
const Shell = imports.gi.Shell;
@ -243,13 +243,13 @@ function formatTime(time, params) {
followed by a time string in 24h format.
i.e. "May 25, 14:30" */
// xgettext:no-c-format
format = N_("%B %d, %H\u2236%M");
format = N_("%B %-d, %H\u2236%M");
else
/* Translators: this is the month name, day number, year
number followed by a time string in 24h format.
i.e. "May 25 2012, 14:30" */
// xgettext:no-c-format
format = N_("%B %d %Y, %H\u2236%M");
format = N_("%B %-d %Y, %H\u2236%M");
} else {
// Show only the time if date is on today
if (daysAgo < 1 || params.timeOnly)
@ -272,13 +272,13 @@ function formatTime(time, params) {
followed by a time string in 12h format.
i.e. "May 25, 2:30 pm" */
// xgettext:no-c-format
format = N_("%B %d, %l\u2236%M %p");
format = N_("%B %-d, %l\u2236%M %p");
else
/* Translators: this is the month name, day number, year
number followed by a time string in 12h format.
i.e. "May 25 2012, 2:30 pm"*/
// xgettext:no-c-format
format = N_("%B %d %Y, %l\u2236%M %p");
format = N_("%B %-d %Y, %l\u2236%M %p");
}
let formattedTime = date.format(Shell.util_translate_time_string(format));
@ -348,12 +348,10 @@ function insertSorted(array, val, cmp) {
return pos;
}
var CloseButton = new Lang.Class({
Name: 'CloseButton',
Extends: St.Button,
var CloseButton = GObject.registerClass(
class CloseButton extends St.Button {
_init(boxpointer) {
this.parent({ style_class: 'notification-close'});
super._init({ style_class: 'notification-close'});
// This is a bit tricky. St.Bin has its own x-align/y-align properties
// that compete with Clutter's properties. This should be fixed for
@ -370,7 +368,7 @@ var CloseButton = new Lang.Class({
this._boxPointer = boxpointer;
if (boxpointer)
this._boxPointer.connect('arrow-side-changed', this._sync.bind(this));
},
}
_computeBoxPointerOffset() {
if (!this._boxPointer || !this._boxPointer.actor.get_stage())
@ -381,7 +379,7 @@ var CloseButton = new Lang.Class({
return this._boxPointer.getArrowHeight();
else
return 0;
},
}
_sync() {
let themeNode = this.get_theme_node();
@ -389,12 +387,12 @@ var CloseButton = new Lang.Class({
let offY = this._computeBoxPointerOffset();
this.translation_x = themeNode.get_length('-shell-close-overlap-x')
this.translation_y = themeNode.get_length('-shell-close-overlap-y') + offY;
},
}
vfunc_style_changed() {
this._sync();
this.parent();
},
super.vfunc_style_changed();
}
});
function makeCloseButton(boxpointer) {
@ -437,10 +435,8 @@ function ensureActorVisibleInScrollView(scrollView, actor) {
transition: 'easeOutQuad' });
}
var AppSettingsMonitor = new Lang.Class({
Name: 'AppSettingsMonitor',
_init(appId, schemaId) {
var AppSettingsMonitor = class {
constructor(appId, schemaId) {
this._appId = appId;
this._schemaId = schemaId;
@ -454,23 +450,23 @@ var AppSettingsMonitor = new Lang.Class({
this._appSystem.connect('installed-changed',
this._onInstalledChanged.bind(this));
this._onInstalledChanged();
},
}
get available() {
return this._app != null && this._settings != null;
},
}
activateApp() {
if (this._app)
this._app.activate();
},
}
watchSetting(key, callback) {
let handler = { id: 0, key: key, callback: callback };
this._handlers.push(handler);
this._connectHandler(handler);
},
}
_connectHandler(handler) {
if (!this._settings || handler.id > 0)
@ -479,13 +475,13 @@ var AppSettingsMonitor = new Lang.Class({
handler.id = this._settings.connect('changed::' + handler.key,
handler.callback);
handler.callback(this._settings, handler.key);
},
}
_disconnectHandler(handler) {
if (this._settings && handler.id > 0)
this._settings.disconnect(handler.id);
handler.id = 0;
},
}
_onInstalledChanged() {
let hadApp = (this._app != null);
@ -499,7 +495,7 @@ var AppSettingsMonitor = new Lang.Class({
this._checkSettings();
else
this._setSettings(null);
},
}
_setSettings(settings) {
this._handlers.forEach((handler) => { this._disconnectHandler(handler); });
@ -512,7 +508,7 @@ var AppSettingsMonitor = new Lang.Class({
if (hadSettings != haveSettings)
this.emit('available-changed');
},
}
_checkSettings() {
let schema = this._schemaSource.lookup(this._schemaId, true);
@ -525,5 +521,5 @@ var AppSettingsMonitor = new Lang.Class({
});
}
}
});
};
Signals.addSignalMethods(AppSettingsMonitor.prototype);

View File

@ -4,7 +4,6 @@ const Geoclue = imports.gi.Geoclue;
const Gio = imports.gi.Gio;
const GLib = imports.gi.GLib;
const GWeather = imports.gi.GWeather;
const Lang = imports.lang;
const Signals = imports.signals;
const PermissionStore = imports.misc.permissionStore;
@ -13,10 +12,8 @@ const Util = imports.misc.util;
// Minimum time between updates to show loading indication
var UPDATE_THRESHOLD = 10 * GLib.TIME_SPAN_MINUTE;
var WeatherClient = new Lang.Class({
Name: 'WeatherClient',
_init() {
var WeatherClient = class {
constructor() {
this._loading = false;
this._locationValid = false;
this._lastUpdate = GLib.DateTime.new_from_unix_local(0);
@ -71,27 +68,27 @@ var WeatherClient = new Lang.Class({
this._onAutomaticLocationChanged.bind(this));
this._weatherAppMon.watchSetting('locations',
this._onLocationsChanged.bind(this));
},
}
get available() {
return this._weatherAppMon.available;
},
}
get loading() {
return this._loading;
},
}
get hasLocation() {
return this._locationValid;
},
}
get info() {
return this._weatherInfo;
},
}
activateApp() {
this._weatherAppMon.activateApp();
},
}
update() {
if (!this._locationValid)
@ -104,13 +101,13 @@ var WeatherClient = new Lang.Class({
this._weatherInfo.update();
else
this._loadInfo();
},
}
get _useAutoLocation() {
return this._autoLocationRequested &&
this._locationSettings.get_boolean('enabled') &&
this._weatherAuthorized;
},
}
_loadInfo() {
let id = this._weatherInfo.connect('updated', () => {
@ -122,7 +119,7 @@ var WeatherClient = new Lang.Class({
this.emit('changed');
this._weatherInfo.update();
},
}
_locationsEqual(loc1, loc2) {
if (loc1 == loc2)
@ -132,7 +129,7 @@ var WeatherClient = new Lang.Class({
return false;
return loc1.equal(loc2);
},
}
_setLocation(location) {
if (this._locationsEqual(this._weatherInfo.location, location))
@ -148,7 +145,7 @@ var WeatherClient = new Lang.Class({
this._loadInfo();
else
this.emit('changed');
},
}
_updateLocationMonitoring() {
if (this._useAutoLocation) {
@ -164,7 +161,7 @@ var WeatherClient = new Lang.Class({
this._gclueService.disconnect(this._gclueLocationChangedId);
this._gclueLocationChangedId = 0;
}
},
}
_startGClueService() {
if (this._gclueStarting)
@ -185,7 +182,7 @@ var WeatherClient = new Lang.Class({
this._gclueService.get_client().distance_threshold = 100;
this._updateLocationMonitoring();
});
},
}
_onGClueLocationChanged() {
let geoLocation = this._gclueService.location;
@ -194,7 +191,7 @@ var WeatherClient = new Lang.Class({
geoLocation.latitude,
geoLocation.longitude);
this._setLocation(location);
},
}
_onAutomaticLocationChanged(settings, key) {
let useAutoLocation = settings.get_boolean(key);
@ -204,7 +201,7 @@ var WeatherClient = new Lang.Class({
this._autoLocationRequested = useAutoLocation;
this._updateAutoLocation();
},
}
_updateAutoLocation() {
this._updateLocationMonitoring();
@ -213,7 +210,7 @@ var WeatherClient = new Lang.Class({
this._startGClueService();
else
this._setLocation(this._mostRecentLocation);
},
}
_onLocationsChanged(settings, key) {
let serialized = settings.get_value(key).deep_unpack().shift();
@ -229,7 +226,7 @@ var WeatherClient = new Lang.Class({
if (!this._useAutoLocation || !this._gclueStarted)
this._setLocation(this._mostRecentLocation);
},
}
_onPermStoreChanged(proxy, sender, params) {
let [table, id, deleted, data, perms] = params;
@ -243,5 +240,5 @@ var WeatherClient = new Lang.Class({
this._updateAutoLocation();
}
});
};
Signals.addSignalMethods(WeatherClient.prototype);

View File

@ -1,8 +1,10 @@
<?xml version="1.0" encoding="UTF-8"?>
<gresources>
<gresource prefix="/org/gnome/shell">
<file>portalHelper/main.js</file>
<file>misc/config.js</file>
<file>misc/fileUtils.js</file>
<file>portalHelper/main.js</file>
<file>misc/params.js</file>
</gresource>
</gresources>

View File

@ -4,7 +4,6 @@ const GLib = imports.gi.GLib;
const GObject = imports.gi.GObject;
const Gio = imports.gi.Gio;
const Gtk = imports.gi.Gtk;
const Lang = imports.lang;
const Pango = imports.gi.Pango;
const Soup = imports.gi.Soup;
const WebKit = imports.gi.WebKit2;
@ -33,12 +32,10 @@ const CONNECTIVITY_RECHECK_RATELIMIT_TIMEOUT = 30 * GLib.USEC_PER_SEC;
const HelperDBusInterface = loadInterfaceXML('org.gnome.Shell.PortalHelper');
var PortalHeaderBar = new Lang.Class({
Name: 'PortalHeaderBar',
Extends: Gtk.HeaderBar,
var PortalHeaderBar = GObject.registerClass(
class PortalHeaderBar extends Gtk.HeaderBar {
_init() {
this.parent({ show_close_button: true });
super._init({ show_close_button: true });
// See ephy-title-box.c in epiphany for the layout
let vbox = new Gtk.Box({ orientation: Gtk.Orientation.VERTICAL,
@ -73,11 +70,11 @@ var PortalHeaderBar = new Lang.Class({
hbox.add(this.subtitleLabel);
vbox.show_all();
},
}
setSubtitle(label) {
this.subtitleLabel.set_text(label);
},
}
setSecurityIcon(securityLevel) {
switch (securityLevel) {
@ -95,15 +92,13 @@ var PortalHeaderBar = new Lang.Class({
this._lockImage.set_tooltip_text(_('Your connection to this hotspot login is not secure. Passwords or other information you enter on this page can be viewed by people nearby.'));
break;
}
},
}
});
var PortalWindow = new Lang.Class({
Name: 'PortalWindow',
Extends: Gtk.ApplicationWindow,
var PortalWindow = GObject.registerClass(
class PortalWindow extends Gtk.ApplicationWindow {
_init(application, url, timestamp, doneCallback) {
this.parent({ application: application });
super._init({ application: application });
this.connect('delete-event', this.destroyWindow.bind(this));
this._headerBar = new PortalHeaderBar();
@ -144,11 +139,11 @@ var PortalWindow = new Lang.Class({
this.present_with_time(timestamp);
this.application.set_accels_for_action('app.quit', ['<Primary>q', '<Primary>w']);
},
}
destroyWindow() {
this.destroy();
},
}
_syncUri() {
let uri = this._webView.uri;
@ -156,12 +151,12 @@ var PortalWindow = new Lang.Class({
this._headerBar.setSubtitle(GLib.uri_unescape_string(uri, null));
else
this._headerBar.setSubtitle('');
},
}
refresh() {
this._everSeenRedirect = false;
this._webView.load_uri(this._originalUrl);
},
}
vfunc_delete_event(event) {
if (this._recheckAtExit)
@ -169,7 +164,7 @@ var PortalWindow = new Lang.Class({
else
this._doneCallback(PortalHelperResult.CANCELLED);
return false;
},
}
_onLoadChanged(view, loadEvent) {
if (loadEvent == WebKit.LoadEvent.STARTED) {
@ -183,11 +178,11 @@ var PortalWindow = new Lang.Class({
else
this._headerBar.setSecurityIcon(PortalHelperSecurityLevel.INSECURE);
}
},
}
_onInsecureContentDetected() {
this._headerBar.setSecurityIcon(PortalHelperSecurityLevel.INSECURE);
},
}
_onLoadFailedWithTlsErrors(view, failingURI, certificate, errors) {
this._headerBar.setSecurityIcon(PortalHelperSecurityLevel.INSECURE);
@ -195,7 +190,7 @@ var PortalWindow = new Lang.Class({
this._webContext.allow_tls_certificate_for_host(certificate, uri.get_host());
this._webView.load_uri(failingURI);
return true;
},
}
_onDecidePolicy(view, decision, type) {
if (type == WebKit.PolicyDecisionType.NEW_WINDOW_ACTION) {
@ -262,15 +257,13 @@ var PortalWindow = new Lang.Class({
decision.use();
return true;
},
}
});
var WebPortalHelper = new Lang.Class({
Name: 'WebPortalHelper',
Extends: Gtk.Application,
var WebPortalHelper = GObject.registerClass(
class WebPortalHelper extends Gtk.Application {
_init() {
this.parent({ application_id: 'org.gnome.Shell.PortalHelper',
super._init({ application_id: 'org.gnome.Shell.PortalHelper',
flags: Gio.ApplicationFlags.IS_SERVICE,
inactivity_timeout: 30000 });
@ -280,30 +273,30 @@ var WebPortalHelper = new Lang.Class({
let action = new Gio.SimpleAction({ name: 'quit' });
action.connect('activate', () => { this.active_window.destroyWindow(); });
this.add_action(action);
},
}
vfunc_dbus_register(connection, path) {
this._dbusImpl.export(connection, path);
this.parent(connection, path);
super.vfunc_dbus_register(connection, path);
return true;
},
}
vfunc_dbus_unregister(connection, path) {
this._dbusImpl.unexport_from_connection(connection);
this.parent(connection, path);
},
super.vfunc_dbus_unregister(connection, path);
}
vfunc_activate() {
// If launched manually (for example for testing), force a dummy authentication
// session with the default url
this.Authenticate('/org/gnome/dummy', '', 0);
},
}
Authenticate(connection, url, timestamp) {
this._queue.push({ connection: connection, url: url, timestamp: timestamp });
this._processQueue();
},
}
Close(connection) {
for (let i = 0; i < this._queue.length; i++) {
@ -318,7 +311,7 @@ var WebPortalHelper = new Lang.Class({
}
this._processQueue();
},
}
Refresh(connection) {
for (let i = 0; i < this._queue.length; i++) {
@ -330,7 +323,7 @@ var WebPortalHelper = new Lang.Class({
break;
}
}
},
}
_processQueue() {
if (this._queue.length == 0)
@ -343,7 +336,7 @@ var WebPortalHelper = new Lang.Class({
top.window = new PortalWindow(this, top.url, top.timestamp, result => {
this._dbusImpl.emit_signal('Done', new GLib.Variant('(ou)', [top.connection, result]));
});
},
}
});
function initEnvironment() {

View File

@ -1,7 +1,6 @@
const Clutter = imports.gi.Clutter;
const Gio = imports.gi.Gio;
const GLib = imports.gi.GLib;
const Lang = imports.lang;
const Pango = imports.gi.Pango;
const Shell = imports.gi.Shell;
const St = imports.gi.St;
@ -21,12 +20,9 @@ var DialogResponse = {
CLOSED: 2
};
var AccessDialog = new Lang.Class({
Name: 'AccessDialog',
Extends: ModalDialog.ModalDialog,
_init(invocation, handle, title, subtitle, body, options) {
this.parent({ styleClass: 'access-dialog' });
var AccessDialog = class extends ModalDialog.ModalDialog {
constructor(invocation, handle, title, subtitle, body, options) {
super({ styleClass: 'access-dialog' });
this._invocation = invocation;
this._handle = handle;
@ -38,7 +34,7 @@ var AccessDialog = new Lang.Class({
options[option] = options[option].deep_unpack();
this._buildLayout(title, subtitle, body, options);
},
}
_buildLayout(title, subtitle, body, options) {
// No support for non-modal system dialogs, so ignore the option
@ -78,14 +74,14 @@ var AccessDialog = new Lang.Class({
action: () => {
this._sendResponse(DialogResponse.OK);
}});
},
}
open() {
this.parent();
super.open();
let connection = this._invocation.get_connection();
this._requestExported = this._request.export(connection, this._handle);
},
}
CloseAsync(invocation, params) {
if (this._invocation.get_sender() != invocation.get_sender()) {
@ -96,7 +92,7 @@ var AccessDialog = new Lang.Class({
}
this._sendResponse(DialogResponse.CLOSED);
},
}
_sendResponse(response) {
if (this._requestExported)
@ -118,12 +114,10 @@ var AccessDialog = new Lang.Class({
});
this.close();
}
});
};
var AccessDialogDBus = new Lang.Class({
Name: 'AccessDialogDBus',
_init() {
var AccessDialogDBus = class {
constructor() {
this._accessDialog = null;
this._windowTracker = Shell.WindowTracker.get_default();
@ -132,7 +126,7 @@ var AccessDialogDBus = new Lang.Class({
this._dbusImpl.export(Gio.DBus.session, '/org/freedesktop/portal/desktop');
Gio.DBus.session.own_name('org.freedesktop.impl.portal.desktop.gnome', Gio.BusNameOwnerFlags.REPLACE, null, null);
},
}
AccessDialogAsync(params, invocation) {
if (this._accessDialog) {
@ -160,4 +154,4 @@ var AccessDialogDBus = new Lang.Class({
this._accessDialog = dialog;
}
});
};

View File

@ -3,7 +3,7 @@
const Clutter = imports.gi.Clutter;
const Gio = imports.gi.Gio;
const GLib = imports.gi.GLib;
const Lang = imports.lang;
const GObject = imports.gi.GObject;
const Mainloop = imports.mainloop;
const Meta = imports.gi.Meta;
const Shell = imports.gi.Shell;
@ -58,12 +58,10 @@ function getWindows(workspace) {
}).filter((w, i, a) => !w.skip_taskbar && a.indexOf(w) == i);
}
var AppSwitcherPopup = new Lang.Class({
Name: 'AppSwitcherPopup',
Extends: SwitcherPopup.SwitcherPopup,
var AppSwitcherPopup = GObject.registerClass(
class AppSwitcherPopup extends SwitcherPopup.SwitcherPopup {
_init() {
this.parent();
super._init();
this._thumbnails = null;
this._thumbnailTimeoutId = 0;
@ -78,45 +76,45 @@ var AppSwitcherPopup = new Lang.Class({
this._switcherList = new AppSwitcher(apps, this);
this._items = this._switcherList.icons;
},
}
_allocate(actor, box, flags) {
this.parent(actor, box, flags);
vfunc_allocate(box, flags) {
super.vfunc_allocate(box, flags);
// Allocate the thumbnails
// We try to avoid overflowing the screen so we base the resulting size on
// those calculations
if (this._thumbnails) {
let childBox = this._switcherList.actor.get_allocation_box();
let childBox = this._switcherList.get_allocation_box();
let primary = Main.layoutManager.primaryMonitor;
let leftPadding = this.actor.get_theme_node().get_padding(St.Side.LEFT);
let rightPadding = this.actor.get_theme_node().get_padding(St.Side.RIGHT);
let bottomPadding = this.actor.get_theme_node().get_padding(St.Side.BOTTOM);
let leftPadding = this.get_theme_node().get_padding(St.Side.LEFT);
let rightPadding = this.get_theme_node().get_padding(St.Side.RIGHT);
let bottomPadding = this.get_theme_node().get_padding(St.Side.BOTTOM);
let hPadding = leftPadding + rightPadding;
let icon = this._items[this._selectedIndex].actor;
let icon = this._items[this._selectedIndex];
let [posX, posY] = icon.get_transformed_position();
let thumbnailCenter = posX + icon.width / 2;
let [childMinWidth, childNaturalWidth] = this._thumbnails.actor.get_preferred_width(-1);
let [childMinWidth, childNaturalWidth] = this._thumbnails.get_preferred_width(-1);
childBox.x1 = Math.max(primary.x + leftPadding, Math.floor(thumbnailCenter - childNaturalWidth / 2));
if (childBox.x1 + childNaturalWidth > primary.x + primary.width - hPadding) {
let offset = childBox.x1 + childNaturalWidth - primary.width + hPadding;
childBox.x1 = Math.max(primary.x + leftPadding, childBox.x1 - offset - hPadding);
}
let spacing = this.actor.get_theme_node().get_length('spacing');
let spacing = this.get_theme_node().get_length('spacing');
childBox.x2 = childBox.x1 + childNaturalWidth;
if (childBox.x2 > primary.x + primary.width - rightPadding)
childBox.x2 = primary.x + primary.width - rightPadding;
childBox.y1 = this._switcherList.actor.allocation.y2 + spacing;
childBox.y1 = this._switcherList.allocation.y2 + spacing;
this._thumbnails.addClones(primary.y + primary.height - bottomPadding - childBox.y1);
let [childMinHeight, childNaturalHeight] = this._thumbnails.actor.get_preferred_height(-1);
let [childMinHeight, childNaturalHeight] = this._thumbnails.get_preferred_height(-1);
childBox.y2 = childBox.y1 + childNaturalHeight;
this._thumbnails.actor.allocate(childBox, flags);
this._thumbnails.allocate(childBox, flags);
}
},
}
_initialSelection(backward, binding) {
if (binding == 'switch-group') {
@ -139,7 +137,7 @@ var AppSwitcherPopup = new Lang.Class({
} else {
this._select(1);
}
},
}
_nextWindow() {
// We actually want the second window if we're in the unset state
@ -147,14 +145,15 @@ var AppSwitcherPopup = new Lang.Class({
this._currentWindow = 0;
return SwitcherPopup.mod(this._currentWindow + 1,
this._items[this._selectedIndex].cachedWindows.length);
},
}
_previousWindow() {
// Also assume second window here
if (this._currentWindow == -1)
this._currentWindow = 1;
return SwitcherPopup.mod(this._currentWindow - 1,
this._items[this._selectedIndex].cachedWindows.length);
},
}
_closeAppWindow(appIndex, windowIndex) {
let appIcon = this._items[appIndex];
@ -166,7 +165,7 @@ var AppSwitcherPopup = new Lang.Class({
return;
window.delete(global.get_current_time());
},
}
_quitApplication(appIndex) {
let appIcon = this._items[appIndex];
@ -174,7 +173,7 @@ var AppSwitcherPopup = new Lang.Class({
return;
appIcon.app.request_quit();
},
}
_keyPressHandler(keysym, action) {
if (action == Meta.KeyBindingAction.SWITCH_GROUP) {
@ -213,7 +212,7 @@ var AppSwitcherPopup = new Lang.Class({
}
return Clutter.EVENT_STOP;
},
}
_scrollHandler(direction) {
if (direction == Clutter.ScrollDirection.UP) {
@ -243,7 +242,7 @@ var AppSwitcherPopup = new Lang.Class({
this._select(this._next());
}
}
},
}
_itemActivatedHandler(n) {
// If the user clicks on the selected app, activate the
@ -253,24 +252,24 @@ var AppSwitcherPopup = new Lang.Class({
this._select(n, this._currentWindow);
else
this._select(n);
},
}
_itemEnteredHandler(n) {
this._select(n);
},
}
_windowActivated(thumbnailList, n) {
let appIcon = this._items[this._selectedIndex];
Main.activateWindow(appIcon.cachedWindows[n]);
this.destroy();
},
this.fadeAndDestroy();
}
_windowEntered(thumbnailList, n) {
if (!this.mouseActive)
return;
this._select(this._selectedIndex, n);
},
}
_windowRemoved(thumbnailList, n) {
let appIcon = this._items[this._selectedIndex];
@ -281,7 +280,7 @@ var AppSwitcherPopup = new Lang.Class({
let newIndex = Math.min(n, appIcon.cachedWindows.length - 1);
this._select(this._selectedIndex, newIndex);
}
},
}
_finish(timestamp) {
let appIcon = this._items[this._selectedIndex];
@ -290,17 +289,17 @@ var AppSwitcherPopup = new Lang.Class({
else if (appIcon.cachedWindows[this._currentWindow])
Main.activateWindow(appIcon.cachedWindows[this._currentWindow], timestamp);
this.parent();
},
super._finish(timestamp);
}
_onDestroy() {
this.parent();
super._onDestroy();
if (this._thumbnails)
this._destroyThumbnails();
if (this._thumbnailTimeoutId != 0)
Mainloop.source_remove(this._thumbnailTimeoutId);
},
}
/**
* _select:
@ -356,7 +355,7 @@ var AppSwitcherPopup = new Lang.Class({
this._timeoutPopupThumbnails.bind(this));
GLib.Source.set_name_by_id(this._thumbnailTimeoutId, '[gnome-shell] this._timeoutPopupThumbnails');
}
},
}
_timeoutPopupThumbnails() {
if (!this._thumbnails)
@ -364,10 +363,10 @@ var AppSwitcherPopup = new Lang.Class({
this._thumbnailTimeoutId = 0;
this._thumbnailsFocused = false;
return GLib.SOURCE_REMOVE;
},
}
_destroyThumbnails() {
let thumbnailsActor = this._thumbnails.actor;
let thumbnailsActor = this._thumbnails;
Tweener.addTween(thumbnailsActor,
{ opacity: 0,
time: THUMBNAIL_FADE_TIME,
@ -378,28 +377,28 @@ var AppSwitcherPopup = new Lang.Class({
}
});
this._thumbnails = null;
if (this._switcherList._items[this._selectedIndex])
if (this._switcherList._items[this._selectedIndex])
this._switcherList._items[this._selectedIndex].remove_accessible_state (Atk.StateType.EXPANDED);
},
}
_createThumbnails() {
this._thumbnails = new ThumbnailList (this._items[this._selectedIndex].cachedWindows);
this._thumbnails.connect('item-activated', this._windowActivated.bind(this));
this._thumbnails.connect('item-entered', this._windowEntered.bind(this));
this._thumbnails.connect('item-removed', this._windowRemoved.bind(this));
this._thumbnails.actor.connect('destroy', () => {
this._thumbnails.connect('destroy', () => {
this._thumbnails = null;
this._thumbnailsFocused = false;
});
this.actor.add_actor(this._thumbnails.actor);
this.add_actor(this._thumbnails);
// Need to force an allocation so we can figure out whether we
// need to scroll when selecting
this._thumbnails.actor.get_allocation_box();
this._thumbnails.get_allocation_box();
this._thumbnails.actor.opacity = 0;
Tweener.addTween(this._thumbnails.actor,
this._thumbnails.opacity = 0;
Tweener.addTween(this._thumbnails,
{ opacity: 255,
time: THUMBNAIL_FADE_TIME,
transition: 'easeOutQuad',
@ -410,10 +409,8 @@ var AppSwitcherPopup = new Lang.Class({
}
});
var CyclerHighlight = new Lang.Class({
Name: 'CyclerHighlight',
_init() {
class CyclerHighlight {
constructor() {
this._window = null;
this.actor = new St.Widget({ layout_manager: new Clutter.BinLayout() });
@ -433,7 +430,7 @@ var CyclerHighlight = new Lang.Class({
this.actor.connect('notify::allocation',
this._onAllocationChanged.bind(this));
this.actor.connect('destroy', this._onDestroy.bind(this));
},
}
set window(w) {
if (this._window == w)
@ -451,7 +448,7 @@ var CyclerHighlight = new Lang.Class({
windowActor.hide();
this._clone.source = windowActor;
},
}
_onAllocationChanged() {
if (!this._window) {
@ -464,20 +461,33 @@ var CyclerHighlight = new Lang.Class({
this._highlight.set_position(rect.x - x, rect.y - y);
this._highlight.show();
}
},
}
_onDestroy() {
this.window = null;
}
};
// We don't show an actual popup, so just provide what SwitcherPopup
// expects instead of inheriting from SwitcherList
var CyclerList = GObject.registerClass({
Signals: { 'item-activated': { param_types: [GObject.TYPE_INT] },
'item-entered': { param_types: [GObject.TYPE_INT] },
'item-removed': { param_types: [GObject.TYPE_INT] },
'item-highlighted': { param_types: [GObject.TYPE_INT] } },
}, class CyclerList extends St.Widget {
highlight(index, justOutline) {
this.emit('item-highlighted', index);
}
});
var CyclerPopup = new Lang.Class({
Name: 'CyclerPopup',
Extends: SwitcherPopup.SwitcherPopup,
Abstract: true,
var CyclerPopup = GObject.registerClass(
class CyclerPopup extends SwitcherPopup.SwitcherPopup {
_init() {
this.parent();
if (new.target === CyclerPopup)
throw new TypeError('Cannot instantiate abstract class ' + new.target.name);
super._init();
this._items = this._getWindows();
@ -487,17 +497,16 @@ var CyclerPopup = new Lang.Class({
this._highlight = new CyclerHighlight();
global.window_group.add_actor(this._highlight.actor);
// We don't show an actual popup, so just provide what SwitcherPopup
// expects instead of inheriting from SwitcherList
this._switcherList = { actor: new St.Widget(),
highlight: this._highlightItem.bind(this),
connect() {} };
},
this._switcherList = new CyclerList();
this._switcherList.connect('item-highlighted', (list, index) => {
this._highlightItem(index);
});
}
_highlightItem(index, justOutline) {
this._highlight.window = this._items[index];
global.window_group.set_child_above_sibling(this._highlight.actor, null);
},
}
_finish() {
let window = this._items[this._selectedIndex];
@ -522,25 +531,23 @@ var CyclerPopup = new Lang.Class({
Main.wm.actionMoveWindow(window, ws);
}
this.parent();
},
super._finish();
}
_onDestroy() {
this._highlight.actor.destroy();
this.parent();
super._onDestroy();
}
});
var GroupCyclerPopup = new Lang.Class({
Name: 'GroupCyclerPopup',
Extends: CyclerPopup,
var GroupCyclerPopup = GObject.registerClass(
class GroupCyclerPopup extends CyclerPopup {
_getWindows() {
let app = Shell.WindowTracker.get_default().focus_app;
return app ? app.get_windows() : [];
},
}
_keyPressHandler(keysym, action) {
if (action == Meta.KeyBindingAction.CYCLE_GROUP)
@ -554,12 +561,10 @@ var GroupCyclerPopup = new Lang.Class({
}
});
var WindowSwitcherPopup = new Lang.Class({
Name: 'WindowSwitcherPopup',
Extends: SwitcherPopup.SwitcherPopup,
var WindowSwitcherPopup = GObject.registerClass(
class WindowSwitcherPopup extends SwitcherPopup.SwitcherPopup {
_init() {
this.parent();
super._init();
this._settings = new Gio.Settings({ schema_id: 'org.gnome.shell.window-switcher' });
let windows = this._getWindowList();
@ -570,7 +575,7 @@ var WindowSwitcherPopup = new Lang.Class({
let mode = this._settings.get_enum('app-icon-mode');
this._switcherList = new WindowList(windows, mode);
this._items = this._switcherList.icons;
},
}
_getWindowList() {
let workspace = null;
@ -582,7 +587,7 @@ var WindowSwitcherPopup = new Lang.Class({
}
return getWindows(workspace);
},
}
_closeWindow(windowIndex) {
let windowIcon = this._items[windowIndex];
@ -590,7 +595,7 @@ var WindowSwitcherPopup = new Lang.Class({
return;
windowIcon.window.delete(global.get_current_time());
},
}
_keyPressHandler(keysym, action) {
if (action == Meta.KeyBindingAction.SWITCH_WINDOWS) {
@ -609,23 +614,22 @@ var WindowSwitcherPopup = new Lang.Class({
}
return Clutter.EVENT_STOP;
},
}
_finish() {
Main.activateWindow(this._items[this._selectedIndex].window);
this.parent();
super._finish();
}
});
var WindowCyclerPopup = new Lang.Class({
Name: 'WindowCyclerPopup',
Extends: CyclerPopup,
var WindowCyclerPopup = GObject.registerClass(
class WindowCyclerPopup extends CyclerPopup {
_init() {
super._init();
this._settings = new Gio.Settings({ schema_id: 'org.gnome.shell.window-switcher' });
this.parent();
},
}
_getWindows() {
let workspace = null;
@ -637,7 +641,7 @@ var WindowCyclerPopup = new Lang.Class({
}
return getWindows(workspace);
},
}
_keyPressHandler(keysym, action) {
if (action == Meta.KeyBindingAction.CYCLE_WINDOWS)
@ -651,33 +655,39 @@ var WindowCyclerPopup = new Lang.Class({
}
});
var AppIcon = new Lang.Class({
Name: 'AppIcon',
var AppIcon = GObject.registerClass(
class AppIcon extends St.BoxLayout {
_init(app) {
super._init({ style_class: 'alt-tab-app',
vertical: true });
this.app = app;
this.actor = new St.BoxLayout({ style_class: 'alt-tab-app',
vertical: true });
this.icon = null;
this._iconBin = new St.Bin({ x_fill: true, y_fill: true });
this.actor.add(this._iconBin, { x_fill: false, y_fill: false } );
this.add(this._iconBin, { x_fill: false, y_fill: false } );
this.label = new St.Label({ text: this.app.get_name() });
this.actor.add(this.label, { x_fill: false });
},
this.add(this.label, { x_fill: false });
}
set_size(size) {
this.icon = this.app.create_icon_texture(size);
this._iconBin.child = this.icon;
this._iconBin.set_size(size, size);
}
vfunc_get_preferred_width(forHeight) {
let [minWidth, ] = super.vfunc_get_preferred_width(forHeight);
minWidth = Math.max(minWidth, forHeight);
return [minWidth, minWidth];
}
});
var AppSwitcher = new Lang.Class({
Name: 'AppSwitcher',
Extends: SwitcherPopup.SwitcherList,
var AppSwitcher = GObject.registerClass(
class AppSwitcher extends SwitcherPopup.SwitcherList {
_init(apps, altTabPopup) {
this.parent(true);
super._init(true);
this.icons = [];
this._arrows = [];
@ -707,12 +717,11 @@ var AppSwitcher = new Lang.Class({
}
this._curApp = -1;
this._iconSize = 0;
this._altTabPopup = altTabPopup;
this._mouseTimeOutId = 0;
this.actor.connect('destroy', this._onDestroy.bind(this));
},
this.connect('destroy', this._onDestroy.bind(this));
}
_onDestroy() {
if (this._mouseTimeOutId != 0)
@ -721,7 +730,7 @@ var AppSwitcher = new Lang.Class({
this.icons.forEach(icon => {
icon.app.disconnect(icon._stateChangedId);
});
},
}
_setIconSize() {
let j = 0;
@ -738,17 +747,16 @@ var AppSwitcher = new Lang.Class({
// We just assume the whole screen here due to weirdness happing with the passed width
let primary = Main.layoutManager.primaryMonitor;
let parentPadding = this.actor.get_parent().get_theme_node().get_horizontal_padding();
let availWidth = primary.width - parentPadding - this.actor.get_theme_node().get_horizontal_padding();
let parentPadding = this.get_parent().get_theme_node().get_horizontal_padding();
let availWidth = primary.width - parentPadding - this.get_theme_node().get_horizontal_padding();
let scaleFactor = St.ThemeContext.get_for_stage(global.stage).scale_factor;
let iconSizes = baseIconSizes.map(s => s * scaleFactor);
let iconSize = baseIconSizes[0];
if (this._items.length == 1) {
this._iconSize = baseIconSizes[0];
} else {
if (this._items.length > 1) {
for(let i = 0; i < baseIconSizes.length; i++) {
this._iconSize = baseIconSizes[i];
iconSize = baseIconSizes[i];
let height = iconSizes[i] + iconSpacing;
let w = height * this._items.length + totalSpacing;
if (w <= availWidth)
@ -756,36 +764,40 @@ var AppSwitcher = new Lang.Class({
}
}
this._iconSize = iconSize;
for(let i = 0; i < this.icons.length; i++) {
if (this.icons[i].icon != null)
break;
this.icons[i].set_size(this._iconSize);
this.icons[i].set_size(iconSize);
}
},
}
_getPreferredHeight(actor, forWidth, alloc) {
vfunc_get_preferred_height(forWidth) {
this._setIconSize();
this.parent(actor, forWidth, alloc);
},
return super.vfunc_get_preferred_height(forWidth);
}
_allocate(actor, box, flags) {
vfunc_allocate(box, flags) {
// Allocate the main list items
this.parent(actor, box, flags);
super.vfunc_allocate(box, flags);
let arrowHeight = Math.floor(this.actor.get_theme_node().get_padding(St.Side.BOTTOM) / 3);
let contentBox = this.get_theme_node().get_content_box(box);
let arrowHeight = Math.floor(this.get_theme_node().get_padding(St.Side.BOTTOM) / 3);
let arrowWidth = arrowHeight * 2;
// Now allocate each arrow underneath its item
let childBox = new Clutter.ActorBox();
for (let i = 0; i < this._items.length; i++) {
let itemBox = this._items[i].allocation;
childBox.x1 = Math.floor(itemBox.x1 + (itemBox.x2 - itemBox.x1 - arrowWidth) / 2);
childBox.x1 = contentBox.x1 + Math.floor(itemBox.x1 + (itemBox.x2 - itemBox.x1 - arrowWidth) / 2);
childBox.x2 = childBox.x1 + arrowWidth;
childBox.y1 = itemBox.y2 + arrowHeight;
childBox.y1 = contentBox.y1 + itemBox.y2 + arrowHeight;
childBox.y2 = childBox.y1 + arrowHeight;
this._arrows[i].allocate(childBox, flags);
}
},
}
// We override SwitcherList's _onItemEnter method to delay
// activation when the thumbnail list is open
@ -802,14 +814,14 @@ var AppSwitcher = new Lang.Class({
GLib.Source.set_name_by_id(this._mouseTimeOutId, '[gnome-shell] this._enterItem');
} else
this._itemEntered(index);
},
}
_enterItem(index) {
let [x, y, mask] = global.get_pointer();
let pickedActor = global.stage.get_actor_at_pos(Clutter.PickMode.ALL, x, y);
if (this._items[index].contains(pickedActor))
this._itemEntered(index);
},
}
// We override SwitcherList's highlight() method to also deal with
// the AppSwitcher->ThumbnailList arrows. Apps with only 1 window
@ -826,7 +838,7 @@ var AppSwitcher = new Lang.Class({
this._arrows[this._curApp].remove_style_pseudo_class('highlighted');
}
this.parent(n, justOutline);
super.highlight(n, justOutline);
this._curApp = n;
if (this._curApp != -1) {
@ -835,11 +847,11 @@ var AppSwitcher = new Lang.Class({
else
this._arrows[this._curApp].add_style_pseudo_class('highlighted');
}
},
}
_addIcon(appIcon) {
this.icons.push(appIcon);
let item = this.addItem(appIcon.actor, appIcon.label);
let item = this.addItem(appIcon, appIcon.label);
appIcon._stateChangedId = appIcon.app.connect('notify::state', app => {
if (app.state != Shell.AppState.RUNNING)
@ -849,14 +861,14 @@ var AppSwitcher = new Lang.Class({
let n = this._arrows.length;
let arrow = new St.DrawingArea({ style_class: 'switcher-arrow' });
arrow.connect('repaint', () => { SwitcherPopup.drawArrow(arrow, St.Side.BOTTOM); });
this._list.add_actor(arrow);
this.add_actor(arrow);
this._arrows.push(arrow);
if (appIcon.cachedWindows.length == 1)
arrow.hide();
else
item.add_accessible_state (Atk.StateType.EXPANDABLE);
},
}
_removeIcon(app) {
let index = this.icons.findIndex(icon => {
@ -867,15 +879,13 @@ var AppSwitcher = new Lang.Class({
this.icons.splice(index, 1);
this.removeItem(index);
},
}
});
var ThumbnailList = new Lang.Class({
Name: 'ThumbnailList',
Extends: SwitcherPopup.SwitcherList,
var ThumbnailList = GObject.registerClass(
class ThumbnailList extends SwitcherPopup.SwitcherList {
_init(windows) {
this.parent(false);
super._init(false);
this._labels = new Array();
this._thumbnailBins = new Array();
@ -907,21 +917,21 @@ var ThumbnailList = new Lang.Class({
}
this.actor.connect('destroy', this._onDestroy.bind(this));
},
this.connect('destroy', this._onDestroy.bind(this));
}
addClones(availHeight) {
if (!this._thumbnailBins.length)
return;
let totalPadding = this._items[0].get_theme_node().get_horizontal_padding() + this._items[0].get_theme_node().get_vertical_padding();
totalPadding += this.actor.get_theme_node().get_horizontal_padding() + this.actor.get_theme_node().get_vertical_padding();
totalPadding += this.get_theme_node().get_horizontal_padding() + this.get_theme_node().get_vertical_padding();
let [labelMinHeight, labelNaturalHeight] = this._labels[0].get_preferred_height(-1);
let spacing = this._items[0].child.get_theme_node().get_length('spacing');
let scaleFactor = St.ThemeContext.get_for_stage(global.stage).scale_factor;
let thumbnailSize = THUMBNAIL_DEFAULT_SIZE * scaleFactor;
availHeight = Math.min(availHeight - labelNaturalHeight - totalPadding - spacing, thumbnailSize);
let binHeight = availHeight + this._items[0].get_theme_node().get_vertical_padding() + this.actor.get_theme_node().get_vertical_padding() - spacing;
let binHeight = availHeight + this._items[0].get_theme_node().get_vertical_padding() + this.get_theme_node().get_vertical_padding() - spacing;
binHeight = Math.min(thumbnailSize, binHeight);
for (let i = 0; i < this._thumbnailBins.length; i++) {
@ -941,7 +951,7 @@ var ThumbnailList = new Lang.Class({
// Make sure we only do this once
this._thumbnailBins = new Array();
},
}
_removeThumbnail(source, clone) {
let index = this._clones.indexOf(clone);
@ -956,29 +966,28 @@ var ThumbnailList = new Lang.Class({
if (this._clones.length > 0)
this.highlight(SwitcherPopup.mod(index, this._clones.length));
else
this.actor.destroy();
},
this.destroy();
}
_onDestroy() {
this._clones.forEach(clone => {
if (clone.source)
clone.source.disconnect(clone._destroyId);
});
},
}
});
var WindowIcon = new Lang.Class({
Name: 'WindowIcon',
var WindowIcon = GObject.registerClass(
class WindowIcon extends St.BoxLayout {
_init(window, mode) {
super._init({ style_class: 'alt-tab-app',
vertical: true });
this.window = window;
this.actor = new St.BoxLayout({ style_class: 'alt-tab-app',
vertical: true });
this._icon = new St.Widget({ layout_manager: new Clutter.BinLayout() });
this.actor.add(this._icon, { x_fill: false, y_fill: false } );
this.add(this._icon, { x_fill: false, y_fill: false } );
this.label = new St.Label({ text: window.get_title() });
let tracker = Shell.WindowTracker.get_default();
@ -1012,7 +1021,7 @@ var WindowIcon = new Lang.Class({
}
this._icon.set_size(size * scaleFactor, size * scaleFactor);
},
}
_createAppIcon(app, size) {
let appIcon = app ? app.create_icon_texture(size)
@ -1025,16 +1034,14 @@ var WindowIcon = new Lang.Class({
}
});
var WindowList = new Lang.Class({
Name: 'WindowList',
Extends: SwitcherPopup.SwitcherList,
var WindowList = GObject.registerClass(
class WindowList extends SwitcherPopup.SwitcherList {
_init(windows, mode) {
this.parent(true);
super._init(true);
this._label = new St.Label({ x_align: Clutter.ActorAlign.CENTER,
y_align: Clutter.ActorAlign.CENTER });
this.actor.add_actor(this._label);
this.add_actor(this._label);
this.windows = windows;
this.icons = [];
@ -1043,7 +1050,7 @@ var WindowList = new Lang.Class({
let win = windows[i];
let icon = new WindowIcon(win, mode);
this.addItem(icon.actor, icon.label);
this.addItem(icon, icon.label);
this.icons.push(icon);
icon._unmanagedSignalId = icon.window.connect('unmanaged', (window) => {
@ -1051,42 +1058,56 @@ var WindowList = new Lang.Class({
});
}
this.actor.connect('destroy', () => { this._onDestroy(); });
},
this.connect('destroy', this._onDestroy.bind(this));
}
_onDestroy() {
this.icons.forEach(icon => {
icon.window.disconnect(icon._unmanagedSignalId);
});
},
}
_getPreferredHeight(actor, forWidth, alloc) {
this.parent(actor, forWidth, alloc);
vfunc_get_preferred_height(forWidth) {
let [minHeight, natHeight] = super.vfunc_get_preferred_height(forWidth);
let spacing = this.actor.get_theme_node().get_padding(St.Side.BOTTOM);
let spacing = this.get_theme_node().get_padding(St.Side.BOTTOM);
let [labelMin, labelNat] = this._label.get_preferred_height(-1);
alloc.min_size += labelMin + spacing;
alloc.natural_size += labelNat + spacing;
},
_allocateTop(actor, box, flags) {
minHeight += labelMin + spacing;
natHeight += labelNat + spacing;
return [minHeight, natHeight];
}
vfunc_allocate(box, flags) {
let themeNode = this.get_theme_node();
let contentBox = themeNode.get_content_box(box);
let childBox = new Clutter.ActorBox();
childBox.x1 = box.x1;
childBox.x2 = box.x2;
childBox.y2 = box.y2;
childBox.x1 = contentBox.x1;
childBox.x2 = contentBox.x2;
childBox.y2 = contentBox.y2;
childBox.y1 = childBox.y2 - this._label.height;
this._label.allocate(childBox, flags);
let spacing = this.actor.get_theme_node().get_padding(St.Side.BOTTOM);
box.y2 -= this._label.height + spacing;
this.parent(actor, box, flags);
},
let totalLabelHeight = this._label.height + themeNode.get_padding(St.Side.BOTTOM)
childBox.x1 = box.x1;
childBox.x2 = box.x2;
childBox.y1 = box.y1;
childBox.y2 = box.y2 - totalLabelHeight;
super.vfunc_allocate(childBox, flags);
// Hooking up the parent vfunc will call this.set_allocation() with
// the height without the label height, so call it again with the
// correct size here.
this.set_allocation(box, flags);
}
highlight(index, justOutline) {
this.parent(index, justOutline);
super.highlight(index, justOutline);
this._label.set_text(index == -1 ? '' : this.icons[index].label.text);
},
}
_removeWindow(window) {
let index = this.icons.findIndex(icon => {

View File

@ -1,18 +1,20 @@
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
const GLib = imports.gi.GLib;
const Lang = imports.lang;
const Gio = imports.gi.Gio;
const Mainloop = imports.mainloop;
const St = imports.gi.St;
const Signals = imports.signals;
const Atk = imports.gi.Atk;
const Tweener = imports.ui.tweener;
var ANIMATED_ICON_UPDATE_TIMEOUT = 16;
var SPINNER_ANIMATION_TIME = 0.3;
var SPINNER_ANIMATION_DELAY = 1.0;
var Animation = new Lang.Class({
Name: 'Animation',
_init(file, width, height, speed) {
var Animation = class {
constructor(file, width, height, speed) {
this.actor = new St.Bin();
this.actor.connect('destroy', this._onDestroy.bind(this));
this._speed = speed;
@ -26,7 +28,7 @@ var Animation = new Lang.Class({
this._animations = St.TextureCache.get_default().load_sliced_image (file, width, height, scaleFactor,
this._animationsLoaded.bind(this));
this.actor.set_child(this._animations);
},
}
play() {
if (this._isLoaded && this._timeoutId == 0) {
@ -38,7 +40,7 @@ var Animation = new Lang.Class({
}
this._isPlaying = true;
},
}
stop() {
if (this._timeoutId > 0) {
@ -47,7 +49,7 @@ var Animation = new Lang.Class({
}
this._isPlaying = false;
},
}
_showFrame(frame) {
let oldFrameActor = this._animations.get_child_at_index(this._frame);
@ -59,30 +61,77 @@ var Animation = new Lang.Class({
let newFrameActor = this._animations.get_child_at_index(this._frame);
if (newFrameActor)
newFrameActor.show();
},
}
_update() {
this._showFrame(this._frame + 1);
return GLib.SOURCE_CONTINUE;
},
}
_animationsLoaded() {
this._isLoaded = this._animations.get_n_children() > 0;
if (this._isPlaying)
this.play();
},
}
_onDestroy() {
this.stop();
}
});
};
var AnimatedIcon = new Lang.Class({
Name: 'AnimatedIcon',
Extends: Animation,
_init(file, size) {
this.parent(file, size, size, ANIMATED_ICON_UPDATE_TIMEOUT);
var AnimatedIcon = class extends Animation {
constructor(file, size) {
super(file, size, size, ANIMATED_ICON_UPDATE_TIMEOUT);
}
});
};
var Spinner = class extends AnimatedIcon {
constructor(size, animate=false) {
let file = Gio.File.new_for_uri('resource:///org/gnome/shell/theme/process-working.svg');
super(file, size);
this.actor.opacity = 0;
this._animate = animate;
}
_onDestroy() {
this._animate = false;
super._onDestroy();
}
play() {
Tweener.removeTweens(this.actor);
if (this._animate) {
super.play();
Tweener.addTween(this.actor, {
opacity: 255,
delay: SPINNER_ANIMATION_DELAY,
time: SPINNER_ANIMATION_TIME,
transition: 'linear'
});
} else {
this.actor.opacity = 255;
super.play();
}
}
stop() {
Tweener.removeTweens(this.actor);
if (this._animate) {
Tweener.addTween(this.actor, {
opacity: 0,
time: SPINNER_ANIMATION_TIME,
transition: 'linear',
onComplete: () => {
this.stop(false);
}
});
} else {
this.actor.opacity = 0;
super.stop();
}
}
};

File diff suppressed because it is too large Load Diff

View File

@ -1,7 +1,6 @@
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
const Shell = imports.gi.Shell;
const Lang = imports.lang;
const Signals = imports.signals;
const Main = imports.ui.main;
@ -30,6 +29,7 @@ const RENAMED_DESKTOP_IDS = {
'gnome-documents.desktop': 'org.gnome.Documents.desktop',
'gnome-font-viewer.desktop': 'org.gnome.font-viewer.desktop',
'gnome-nibbles.desktop': 'org.gnome.Nibbles.desktop',
'gnome-mahjongg.desktop': 'org.gnome.Mahjongg.desktop',
'gnome-music.desktop': 'org.gnome.Music.desktop',
'gnome-photos.desktop': 'org.gnome.Photos.desktop',
'gnome-screenshot.desktop': 'org.gnome.Screenshot.desktop',
@ -41,27 +41,25 @@ const RENAMED_DESKTOP_IDS = {
'gnotravex.desktop': 'gnome-tetravex.desktop',
'gnotski.desktop': 'gnome-klotski.desktop',
'gtali.desktop': 'tali.desktop',
'iagno.desktop': 'org.gnome.Iagno.desktop',
'nautilus.desktop': 'org.gnome.Nautilus.desktop',
'polari.desktop': 'org.gnome.Polari.desktop',
'totem.desktop': 'org.gnome.Totem.desktop',
'evince.desktop': 'org.gnome.Evince.desktop',
};
var AppFavorites = new Lang.Class({
Name: 'AppFavorites',
FAVORITE_APPS_KEY: 'favorite-apps',
_init() {
class AppFavorites {
constructor() {
this.FAVORITE_APPS_KEY = 'favorite-apps';
this._favorites = {};
global.settings.connect('changed::' + this.FAVORITE_APPS_KEY, this._onFavsChanged.bind(this));
this.reload();
},
}
_onFavsChanged() {
this.reload();
this.emit('changed');
},
}
reload() {
let ids = global.settings.get_strv(this.FAVORITE_APPS_KEY);
@ -89,29 +87,29 @@ var AppFavorites = new Lang.Class({
let app = apps[i];
this._favorites[app.get_id()] = app;
}
},
}
_getIds() {
let ret = [];
for (let id in this._favorites)
ret.push(id);
return ret;
},
}
getFavoriteMap() {
return this._favorites;
},
}
getFavorites() {
let ret = [];
for (let id in this._favorites)
ret.push(this._favorites[id]);
return ret;
},
}
isFavorite(appId) {
return appId in this._favorites;
},
}
_addFavorite(appId, pos) {
if (appId in this._favorites)
@ -129,7 +127,7 @@ var AppFavorites = new Lang.Class({
ids.splice(pos, 0, appId);
global.settings.set_strv(this.FAVORITE_APPS_KEY, ids);
return true;
},
}
addFavoriteAtPos(appId, pos) {
if (!this._addFavorite(appId, pos))
@ -143,16 +141,16 @@ var AppFavorites = new Lang.Class({
this._removeFavorite(appId);
}
});
},
}
addFavorite(appId) {
this.addFavoriteAtPos(appId, -1);
},
}
moveFavoriteToPos(appId, pos) {
this._removeFavorite(appId);
this._addFavorite(appId, pos);
},
}
_removeFavorite(appId) {
if (!appId in this._favorites)
@ -161,7 +159,7 @@ var AppFavorites = new Lang.Class({
let ids = this._getIds().filter(id => id != appId);
global.settings.set_strv(this.FAVORITE_APPS_KEY, ids);
return true;
},
}
removeFavorite(appId) {
let ids = this._getIds();
@ -178,7 +176,7 @@ var AppFavorites = new Lang.Class({
}
});
}
});
};
Signals.addSignalMethods(AppFavorites.prototype);
var appFavoritesInstance = null;

View File

@ -1,7 +1,6 @@
const Clutter = imports.gi.Clutter;
const Gio = imports.gi.Gio;
const GLib = imports.gi.GLib;
const Lang = imports.lang;
const Meta = imports.gi.Meta;
const Shell = imports.gi.Shell;
const St = imports.gi.St;
@ -19,12 +18,10 @@ var AudioDevice = {
const AudioDeviceSelectionIface = loadInterfaceXML('org.gnome.Shell.AudioDeviceSelection');
var AudioDeviceSelectionDialog = new Lang.Class({
Name: 'AudioDeviceSelectionDialog',
Extends: ModalDialog.ModalDialog,
_init(devices) {
this.parent({ styleClass: 'audio-device-selection-dialog' });
var AudioDeviceSelectionDialog =
class AudioDeviceSelectionDialog extends ModalDialog.ModalDialog {
constructor(devices) {
super({ styleClass: 'audio-device-selection-dialog' });
this._deviceItems = {};
@ -39,11 +36,11 @@ var AudioDeviceSelectionDialog = new Lang.Class({
if (this._selectionBox.get_n_children() < 2)
throw new Error('Too few devices for a selection');
},
}
destroy() {
this.parent();
},
super.destroy();
}
_buildLayout(devices) {
let title = new St.Label({ style_class: 'audio-selection-title',
@ -56,12 +53,13 @@ var AudioDeviceSelectionDialog = new Lang.Class({
this._selectionBox = new St.BoxLayout({ style_class: 'audio-selection-box' });
this.contentLayout.add(this._selectionBox, { expand: true });
this.addButton({ action: this._openSettings.bind(this),
label: _("Sound Settings") });
if (Main.sessionMode.allowSettings)
this.addButton({ action: this._openSettings.bind(this),
label: _("Sound Settings") });
this.addButton({ action: this.close.bind(this),
label: _("Cancel"),
key: Clutter.Escape });
},
}
_getDeviceLabel(device) {
switch(device) {
@ -74,7 +72,7 @@ var AudioDeviceSelectionDialog = new Lang.Class({
default:
return null;
}
},
}
_getDeviceIcon(device) {
switch(device) {
@ -87,7 +85,7 @@ var AudioDeviceSelectionDialog = new Lang.Class({
default:
return null;
}
},
}
_addDevice(device) {
let box = new St.BoxLayout({ style_class: 'audio-selection-device-box',
@ -117,7 +115,7 @@ var AudioDeviceSelectionDialog = new Lang.Class({
this.close();
Main.overview.hide();
});
},
}
_openSettings() {
let desktopFile = 'gnome-sound-panel.desktop'
@ -132,23 +130,21 @@ var AudioDeviceSelectionDialog = new Lang.Class({
Main.overview.hide();
app.activate();
}
});
};
var AudioDeviceSelectionDBus = new Lang.Class({
Name: 'AudioDeviceSelectionDBus',
_init() {
var AudioDeviceSelectionDBus = class AudioDeviceSelectionDBus {
constructor() {
this._audioSelectionDialog = null;
this._dbusImpl = Gio.DBusExportedObject.wrapJSObject(AudioDeviceSelectionIface, this);
this._dbusImpl.export(Gio.DBus.session, '/org/gnome/Shell/AudioDeviceSelection');
Gio.DBus.session.own_name('org.gnome.Shell.AudioDeviceSelection', Gio.BusNameOwnerFlags.REPLACE, null, null);
},
}
_onDialogClosed() {
this._audioSelectionDialog = null;
},
}
_onDeviceSelected(dialog, device) {
let connection = this._dbusImpl.get_connection();
@ -161,7 +157,7 @@ var AudioDeviceSelectionDBus = new Lang.Class({
info ? info.name : null,
'DeviceSelected',
GLib.Variant.new('(s)', [deviceName]));
},
}
OpenAsync(params, invocation) {
if (this._audioSelectionDialog) {
@ -189,7 +185,7 @@ var AudioDeviceSelectionDBus = new Lang.Class({
this._audioSelectionDialog = dialog;
invocation.return_value(null);
},
}
CloseAsync(params, invocation) {
if (this._audioSelectionDialog &&
@ -198,4 +194,4 @@ var AudioDeviceSelectionDBus = new Lang.Class({
invocation.return_value(null);
}
});
};

View File

@ -98,7 +98,6 @@ const GDesktopEnums = imports.gi.GDesktopEnums;
const Gio = imports.gi.Gio;
const GLib = imports.gi.GLib;
const GnomeDesktop = imports.gi.GnomeDesktop;
const Lang = imports.lang;
const Meta = imports.gi.Meta;
const Signals = imports.signals;
@ -138,14 +137,12 @@ function _fileEqual0(file1, file2) {
return file1.equal(file2);
}
var BackgroundCache = new Lang.Class({
Name: 'BackgroundCache',
_init() {
var BackgroundCache = class BackgroundCache {
constructor() {
this._fileMonitors = {};
this._backgroundSources = {};
this._animations = {};
},
}
monitorFile(file) {
let key = file.hash();
@ -163,7 +160,7 @@ var BackgroundCache = new Lang.Class({
});
this._fileMonitors[key] = monitor;
},
}
getAnimation(params) {
params = Params.parse(params, { file: null,
@ -195,7 +192,7 @@ var BackgroundCache = new Lang.Class({
GLib.Source.set_name_by_id(id, '[gnome-shell] params.onLoaded');
}
});
},
}
getBackgroundSource(layoutManager, settingsSchema) {
// The layoutManager is always the same one; we pass in it since
@ -209,7 +206,7 @@ var BackgroundCache = new Lang.Class({
}
return this._backgroundSources[settingsSchema];
},
}
releaseBackgroundSource(settingsSchema) {
if (settingsSchema in this._backgroundSources) {
@ -221,7 +218,7 @@ var BackgroundCache = new Lang.Class({
}
}
}
});
};
Signals.addSignalMethods(BackgroundCache.prototype);
function getBackgroundCache() {
@ -230,10 +227,8 @@ function getBackgroundCache() {
return _backgroundCache;
}
var Background = new Lang.Class({
Name: 'Background',
_init(params) {
var Background = class Background {
constructor(params) {
params = Params.parse(params, { monitorIndex: 0,
layoutManager: Main.layoutManager,
settings: null,
@ -272,7 +267,7 @@ var Background = new Lang.Class({
});
this._load();
},
}
destroy() {
this._cancellable.cancel();
@ -298,12 +293,12 @@ var Background = new Lang.Class({
if (this._settingsChangedSignalId != 0)
this._settings.disconnect(this._settingsChangedSignalId);
this._settingsChangedSignalId = 0;
},
}
updateResolution() {
if (this._animation)
this._refreshAnimation();
},
}
_refreshAnimation() {
if (!this._animation)
@ -311,7 +306,7 @@ var Background = new Lang.Class({
this._removeAnimationTimeout();
this._updateAnimation();
},
}
_setLoaded() {
if (this.isLoaded)
@ -324,7 +319,7 @@ var Background = new Lang.Class({
return GLib.SOURCE_REMOVE;
});
GLib.Source.set_name_by_id(id, '[gnome-shell] this.emit');
},
}
_loadPattern() {
let colorString, res, color, secondColor;
@ -340,7 +335,7 @@ var Background = new Lang.Class({
this.background.set_color(color);
else
this.background.set_gradient(shadingType, color, secondColor);
},
}
_watchFile(file) {
let key = file.hash();
@ -357,14 +352,14 @@ var Background = new Lang.Class({
}
});
this._fileWatches[key] = signalId;
},
}
_removeAnimationTimeout() {
if (this._updateAnimationTimeoutId) {
GLib.source_remove(this._updateAnimationTimeoutId);
this._updateAnimationTimeoutId = 0;
}
},
}
_updateAnimation() {
this._updateAnimationTimeoutId = 0;
@ -404,7 +399,7 @@ var Background = new Lang.Class({
});
}
}
},
}
_queueUpdateAnimation() {
if (this._updateAnimationTimeoutId != 0)
@ -433,7 +428,7 @@ var Background = new Lang.Class({
return GLib.SOURCE_REMOVE;
});
GLib.Source.set_name_by_id(this._updateAnimationTimeoutId, '[gnome-shell] this._updateAnimation');
},
}
_loadAnimation(file) {
this._cache.getAnimation({ file: file,
@ -450,7 +445,7 @@ var Background = new Lang.Class({
this._watchFile(file);
}
});
},
}
_loadImage(file) {
this.background.set_file(file, this._style);
@ -466,14 +461,14 @@ var Background = new Lang.Class({
image.disconnect(id);
});
}
},
}
_loadFile(file) {
if (file.get_basename().endsWith('.xml'))
this._loadAnimation(file);
else
this._loadImage(file);
},
}
_load() {
this._cache = getBackgroundCache();
@ -486,16 +481,14 @@ var Background = new Lang.Class({
}
this._loadFile(this._file);
},
});
}
};
Signals.addSignalMethods(Background.prototype);
let _systemBackground;
var SystemBackground = new Lang.Class({
Name: 'SystemBackground',
_init() {
var SystemBackground = class SystemBackground {
constructor() {
let file = Gio.File.new_for_uri('resource:///org/gnome/shell/theme/noise-texture.png');
if (_systemBackground == null) {
@ -524,14 +517,12 @@ var SystemBackground = new Lang.Class({
image = null;
});
}
},
});
}
};
Signals.addSignalMethods(SystemBackground.prototype);
var BackgroundSource = new Lang.Class({
Name: 'BackgroundSource',
_init(layoutManager, settingsSchema) {
var BackgroundSource = class BackgroundSource {
constructor(layoutManager, settingsSchema) {
// Allow override the background image setting for performance testing
this._layoutManager = layoutManager;
this._overrideImage = GLib.getenv('SHELL_BACKGROUND_IMAGE');
@ -542,7 +533,7 @@ var BackgroundSource = new Lang.Class({
this._monitorsChangedId =
monitorManager.connect('monitors-changed',
this._onMonitorsChanged.bind(this));
},
}
_onMonitorsChanged() {
for (let monitorIndex in this._backgrounds) {
@ -556,7 +547,7 @@ var BackgroundSource = new Lang.Class({
delete this._backgrounds[monitorIndex];
}
}
},
}
getBackground(monitorIndex) {
let file = null;
@ -603,7 +594,7 @@ var BackgroundSource = new Lang.Class({
}
return this._backgrounds[monitorIndex];
},
}
destroy() {
let monitorManager = Meta.MonitorManager.get();
@ -617,12 +608,10 @@ var BackgroundSource = new Lang.Class({
this._backgrounds = null;
}
});
};
var Animation = new Lang.Class({
Name: 'Animation',
_init(params) {
var Animation = class Animation {
constructor(params) {
params = Params.parse(params, { file: null });
this.file = params.file;
@ -630,7 +619,7 @@ var Animation = new Lang.Class({
this.transitionProgress = 0.0;
this.transitionDuration = 0.0;
this.loaded = false;
},
}
load(callback) {
this._show = new GnomeDesktop.BGSlideShow({ filename: this.file.get_path() });
@ -640,7 +629,7 @@ var Animation = new Lang.Class({
if (callback)
callback();
});
},
}
update(monitor) {
this.keyFrameFiles = [];
@ -661,14 +650,12 @@ var Animation = new Lang.Class({
if (filename2)
this.keyFrameFiles.push(Gio.File.new_for_path(filename2));
},
});
}
};
Signals.addSignalMethods(Animation.prototype);
var BackgroundManager = new Lang.Class({
Name: 'BackgroundManager',
_init(params) {
var BackgroundManager = class BackgroundManager {
constructor(params) {
params = Params.parse(params, { container: null,
layoutManager: Main.layoutManager,
monitorIndex: null,
@ -688,7 +675,7 @@ var BackgroundManager = new Lang.Class({
this.backgroundActor = this._createBackgroundActor();
this._newBackgroundActor = null;
},
}
destroy() {
let cache = getBackgroundCache();
@ -704,7 +691,7 @@ var BackgroundManager = new Lang.Class({
this.backgroundActor.destroy();
this.backgroundActor = null;
}
},
}
_swapBackgroundActor() {
let oldBackgroundActor = this.backgroundActor;
@ -721,7 +708,7 @@ var BackgroundManager = new Lang.Class({
oldBackgroundActor.destroy();
}
});
},
}
_updateBackgroundActor() {
if (this._newBackgroundActor) {
@ -750,7 +737,7 @@ var BackgroundManager = new Lang.Class({
this._swapBackgroundActor();
});
}
},
}
_createBackgroundActor() {
let background = this._backgroundSource.getBackground(this._monitorIndex);
@ -787,6 +774,6 @@ var BackgroundManager = new Lang.Class({
});
return backgroundActor;
},
});
}
};
Signals.addSignalMethods(BackgroundManager.prototype);

View File

@ -1,7 +1,6 @@
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
const Clutter = imports.gi.Clutter;
const Lang = imports.lang;
const St = imports.gi.St;
const Shell = imports.gi.Shell;
@ -9,12 +8,9 @@ const BoxPointer = imports.ui.boxpointer;
const Main = imports.ui.main;
const PopupMenu = imports.ui.popupMenu;
var BackgroundMenu = new Lang.Class({
Name: 'BackgroundMenu',
Extends: PopupMenu.PopupMenu,
_init(layoutManager) {
this.parent(layoutManager.dummyCursor, 0, St.Side.TOP);
var BackgroundMenu = class BackgroundMenu extends PopupMenu.PopupMenu {
constructor(layoutManager) {
super(layoutManager.dummyCursor, 0, St.Side.TOP);
this.addSettingsAction(_("Change Background…"), 'gnome-background-panel.desktop');
this.addMenuItem(new PopupMenu.PopupSeparatorMenuItem());
@ -26,7 +22,7 @@ var BackgroundMenu = new Lang.Class({
layoutManager.uiGroup.add_actor(this.actor);
this.actor.hide();
}
});
};
function addBackgroundMenu(actor, layoutManager) {
actor.reactive = true;

View File

@ -3,14 +3,11 @@
const Atk = imports.gi.Atk;
const Cairo = imports.cairo;
const Clutter = imports.gi.Clutter;
const Lang = imports.lang;
const St = imports.gi.St;
const Signals = imports.signals;
var BarLevel = new Lang.Class({
Name: "BarLevel",
_init(value, params) {
var BarLevel = class {
constructor(value, params) {
if (isNaN(value))
// Avoid spreading NaNs around
throw TypeError('The bar level value must be a number');
@ -40,7 +37,7 @@ var BarLevel = new Lang.Class({
this._customAccessible.connect('set-current-value', this._setCurrentValue.bind(this));
this.connect('value-changed', this._valueChanged.bind(this));
},
}
setValue(value) {
if (isNaN(value))
@ -48,7 +45,7 @@ var BarLevel = new Lang.Class({
this._value = Math.max(Math.min(value, this._maxValue), 0);
this.actor.queue_repaint();
},
}
setMaximumValue(value) {
if (isNaN(value))
@ -57,7 +54,7 @@ var BarLevel = new Lang.Class({
this._maxValue = Math.max(value, 1);
this._overdriveStart = Math.min(this._overdriveStart, this._maxValue);
this.actor.queue_repaint();
},
}
setOverdriveStart(value) {
if (isNaN(value))
@ -69,7 +66,7 @@ var BarLevel = new Lang.Class({
this._overdriveStart = value;
this._value = Math.max(Math.min(value, this._maxValue), 0);
this.actor.queue_repaint();
},
}
_barLevelRepaint(area) {
let cr = area.get_context();
@ -176,35 +173,34 @@ var BarLevel = new Lang.Class({
}
cr.$dispose();
},
}
_getCurrentValue(actor) {
return this._value;
},
}
_getOverdriveStart(actor) {
return this._overdriveStart;
},
}
_getMinimumValue(actor) {
return 0;
},
}
_getMaximumValue(actor) {
return this._maxValue;
},
}
_setCurrentValue(actor, value) {
this._value = value;
},
}
_valueChanged(barLevel, value, property) {
this._customAccessible.notify("accessible-value");
},
}
get value() {
return this._value;
}
});
};
Signals.addSignalMethods(BarLevel.prototype);

View File

@ -1,7 +1,7 @@
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
const Clutter = imports.gi.Clutter;
const Lang = imports.lang;
const GObject = imports.gi.GObject;
const Meta = imports.gi.Meta;
const Shell = imports.gi.Shell;
const Signals = imports.signals;
@ -32,27 +32,25 @@ var POPUP_ANIMATION_TIME = 0.15;
* totally inside the monitor if possible.
*
*/
var BoxPointer = new Lang.Class({
Name: 'BoxPointer',
var BoxPointer = GObject.registerClass({
Signals: { 'arrow-side-changed': {} },
}, class BoxPointer extends St.Widget {
_init(arrowSide, binProperties) {
super._init();
this.actor = this;
this.set_offscreen_redirect(Clutter.OffscreenRedirect.ALWAYS);
this._arrowSide = arrowSide;
this._userArrowSide = arrowSide;
this._arrowOrigin = 0;
this._arrowActor = null;
this.actor = new St.Bin({ x_fill: true,
y_fill: true });
this._container = new Shell.GenericContainer();
this.actor.set_child(this._container);
this.actor.set_offscreen_redirect(Clutter.OffscreenRedirect.ALWAYS);
this._container.connect('get-preferred-width', this._getPreferredWidth.bind(this));
this._container.connect('get-preferred-height', this._getPreferredHeight.bind(this));
this._container.connect('allocate', this._allocate.bind(this));
this.bin = new St.Bin(binProperties);
this._container.add_actor(this.bin);
this.add_actor(this.bin);
this._border = new St.DrawingArea();
this._border.connect('repaint', this._drawBorder.bind(this));
this._container.add_actor(this._border);
this.add_actor(this._border);
this.bin.raise(this._border);
this._xOffset = 0;
this._yOffset = 0;
@ -61,27 +59,57 @@ var BoxPointer = new Lang.Class({
this._sourceAlignment = 0.5;
this._capturedEventId = 0;
this._muteInput();
},
}
get arrowSide() {
return this._arrowSide;
},
}
_muteInput() {
if (this._capturedEventId == 0)
this._capturedEventId = this.actor.connect('captured-event',
() => Clutter.EVENT_STOP);
},
this._capturedEventId = this.connect('captured-event',
() => Clutter.EVENT_STOP);
}
_unmuteInput() {
if (this._capturedEventId != 0) {
this.actor.disconnect(this._capturedEventId);
this.disconnect(this._capturedEventId);
this._capturedEventId = 0;
}
},
}
// BoxPointer.show() and BoxPointer.hide() are here for only compatibility
// purposes, and will be removed in 3.32.
show(animate, onComplete) {
let themeNode = this.actor.get_theme_node();
if (animate !== undefined) {
try {
throw new Error('BoxPointer.show() has been moved to BoxPointer.open(), this code will break in the future.');
} catch(e) {
logError(e);
this.open(animate, onComplete);
return;
}
}
this.visible = true;
}
hide(animate, onComplete) {
if (animate !== undefined) {
try {
throw new Error('BoxPointer.hide() has been moved to BoxPointer.close(), this code will break in the future.');
} catch(e) {
logError(e);
this.close(animate, onComplete);
return;
}
}
this.visible = false;
}
open(animate, onComplete) {
let themeNode = this.get_theme_node();
let rise = themeNode.get_length('-arrow-rise');
let animationTime = (animate & PopupAnimation.FULL) ? POPUP_ANIMATION_TIME : 0;
@ -90,7 +118,7 @@ var BoxPointer = new Lang.Class({
else
this.opacity = 255;
this.actor.show();
this.show();
if (animate & PopupAnimation.SLIDE) {
switch (this._arrowSide) {
@ -119,15 +147,15 @@ var BoxPointer = new Lang.Class({
onComplete();
},
time: animationTime });
},
}
hide(animate, onComplete) {
if (!this.actor.visible)
close(animate, onComplete) {
if (!this.visible)
return;
let xOffset = 0;
let yOffset = 0;
let themeNode = this.actor.get_theme_node();
let themeNode = this.get_theme_node();
let rise = themeNode.get_length('-arrow-rise');
let fade = (animate & PopupAnimation.FADE);
let animationTime = (animate & PopupAnimation.FULL) ? POPUP_ANIMATION_TIME : 0;
@ -158,7 +186,7 @@ var BoxPointer = new Lang.Class({
transition: 'linear',
time: animationTime,
onComplete: () => {
this.actor.hide();
this.hide();
this.opacity = 0;
this.xOffset = 0;
this.yOffset = 0;
@ -166,39 +194,50 @@ var BoxPointer = new Lang.Class({
onComplete();
}
});
},
}
_adjustAllocationForArrow(isWidth, alloc) {
let themeNode = this.actor.get_theme_node();
_adjustAllocationForArrow(isWidth, minSize, natSize) {
let themeNode = this.get_theme_node();
let borderWidth = themeNode.get_length('-arrow-border-width');
alloc.min_size += borderWidth * 2;
alloc.natural_size += borderWidth * 2;
minSize += borderWidth * 2;
natSize += borderWidth * 2;
if ((!isWidth && (this._arrowSide == St.Side.TOP || this._arrowSide == St.Side.BOTTOM))
|| (isWidth && (this._arrowSide == St.Side.LEFT || this._arrowSide == St.Side.RIGHT))) {
let rise = themeNode.get_length('-arrow-rise');
alloc.min_size += rise;
alloc.natural_size += rise;
minSize += rise;
natSize += rise;
}
},
_getPreferredWidth(actor, forHeight, alloc) {
let [minInternalSize, natInternalSize] = this.bin.get_preferred_width(forHeight);
alloc.min_size = minInternalSize;
alloc.natural_size = natInternalSize;
this._adjustAllocationForArrow(true, alloc);
},
return [minSize, natSize];
}
_getPreferredHeight(actor, forWidth, alloc) {
let themeNode = this.actor.get_theme_node();
vfunc_get_preferred_width(forHeight) {
let themeNode = this.get_theme_node();
forHeight = themeNode.adjust_for_height(forHeight);
let width = this.bin.get_preferred_width(forHeight);
width = this._adjustAllocationForArrow(true, ...width);
return themeNode.adjust_preferred_width(...width);
}
vfunc_get_preferred_height(forWidth) {
let themeNode = this.get_theme_node();
let borderWidth = themeNode.get_length('-arrow-border-width');
let [minSize, naturalSize] = this.bin.get_preferred_height(forWidth - 2 * borderWidth);
alloc.min_size = minSize;
alloc.natural_size = naturalSize;
this._adjustAllocationForArrow(false, alloc);
},
forWidth = themeNode.adjust_for_width(forWidth);
let height = this.bin.get_preferred_height(forWidth - 2 * borderWidth);
height = this._adjustAllocationForArrow(false, ...height);
return themeNode.adjust_preferred_height(...height);
}
vfunc_allocate(box, flags) {
this.set_allocation(box, flags);
let themeNode = this.get_theme_node();
box = themeNode.get_content_box(box);
_allocate(actor, box, flags) {
let themeNode = this.actor.get_theme_node();
let borderWidth = themeNode.get_length('-arrow-border-width');
let rise = themeNode.get_length('-arrow-rise');
let childBox = new Clutter.ActorBox();
@ -235,15 +274,15 @@ var BoxPointer = new Lang.Class({
this._reposition();
this._updateFlip();
}
},
}
_drawBorder(area) {
let themeNode = this.actor.get_theme_node();
let themeNode = this.get_theme_node();
if (this._arrowActor) {
let [sourceX, sourceY] = this._arrowActor.get_transformed_position();
let [sourceWidth, sourceHeight] = this._arrowActor.get_transformed_size();
let [absX, absY] = this.actor.get_transformed_position();
let [absX, absY] = this.get_transformed_position();
if (this._arrowSide == St.Side.TOP ||
this._arrowSide == St.Side.BOTTOM) {
@ -417,19 +456,19 @@ var BoxPointer = new Lang.Class({
}
cr.$dispose();
},
}
setPosition(sourceActor, alignment) {
// We need to show it now to force an allocation,
// so that we can query the correct size.
this.actor.show();
this.show();
this._sourceActor = sourceActor;
this._arrowAlignment = alignment;
this._reposition();
this._updateFlip();
},
}
setSourceAlignment(alignment) {
this._sourceAlignment = alignment;
@ -438,7 +477,7 @@ var BoxPointer = new Lang.Class({
return;
this.setPosition(this._sourceActor, this._arrowAlignment);
},
}
_reposition() {
let sourceActor = this._sourceActor;
@ -450,13 +489,13 @@ var BoxPointer = new Lang.Class({
let sourceAllocation = Shell.util_get_transformed_allocation(sourceActor);
let sourceCenterX = sourceAllocation.x1 + sourceContentBox.x1 + (sourceContentBox.x2 - sourceContentBox.x1) * this._sourceAlignment;
let sourceCenterY = sourceAllocation.y1 + sourceContentBox.y1 + (sourceContentBox.y2 - sourceContentBox.y1) * this._sourceAlignment;
let [minWidth, minHeight, natWidth, natHeight] = this.actor.get_preferred_size();
let [minWidth, minHeight, natWidth, natHeight] = this.get_preferred_size();
// We also want to keep it onscreen, and separated from the
// edge by the same distance as the main part of the box is
// separated from its sourceActor
let monitor = Main.layoutManager.findMonitorForActor(sourceActor);
let themeNode = this.actor.get_theme_node();
let themeNode = this.get_theme_node();
let borderWidth = themeNode.get_length('-arrow-border-width');
let arrowBase = themeNode.get_length('-arrow-base');
let borderRadius = themeNode.get_length('-arrow-border-radius');
@ -542,7 +581,7 @@ var BoxPointer = new Lang.Class({
this.setArrowOrigin(arrowOrigin);
let parent = this.actor.get_parent();
let parent = this.get_parent();
let success, x, y;
while (!success) {
[success, x, y] = parent.transform_stage_point(resX, resY);
@ -552,7 +591,7 @@ var BoxPointer = new Lang.Class({
this._xPosition = Math.floor(x);
this._yPosition = Math.floor(y);
this._shiftActor();
},
}
// @origin: Coordinate specifying middle of the arrow, along
// the Y axis for St.Side.LEFT, St.Side.RIGHT from the top and X axis from
@ -562,7 +601,7 @@ var BoxPointer = new Lang.Class({
this._arrowOrigin = origin;
this._border.queue_repaint();
}
},
}
// @actor: an actor relative to which the arrow is positioned.
// Differently from setPosition, this will not move the boxpointer itself,
@ -572,7 +611,7 @@ var BoxPointer = new Lang.Class({
this._arrowActor = actor;
this._border.queue_repaint();
}
},
}
_shiftActor() {
// Since the position of the BoxPointer depends on the allocated size
@ -581,16 +620,16 @@ var BoxPointer = new Lang.Class({
// allocation loops and warnings. Instead we do the positioning via
// the anchor point, which is independent of allocation, and leave
// x == y == 0.
this.actor.set_anchor_point(-(this._xPosition + this._xOffset),
-(this._yPosition + this._yOffset));
},
this.set_anchor_point(-(this._xPosition + this._xOffset),
-(this._yPosition + this._yOffset));
}
_calculateArrowSide(arrowSide) {
let sourceAllocation = Shell.util_get_transformed_allocation(this._sourceActor);
let [minWidth, minHeight, boxWidth, boxHeight] = this._container.get_preferred_size();
let [minWidth, minHeight, boxWidth, boxHeight] = this.get_preferred_size();
let monitorActor = this.sourceActor;
if (!monitorActor)
monitorActor = this.actor;
monitorActor = this;
let monitor = Main.layoutManager.findMonitorForActor(monitorActor);
switch (arrowSide) {
@ -617,7 +656,7 @@ var BoxPointer = new Lang.Class({
}
return arrowSide;
},
}
_updateFlip() {
let arrowSide = this._calculateArrowSide(this._userArrowSide);
@ -625,53 +664,44 @@ var BoxPointer = new Lang.Class({
this._arrowSide = arrowSide;
this._reposition();
Meta.later_add(Meta.LaterType.BEFORE_REDRAW, () => {
this._container.queue_relayout();
this.queue_relayout();
return false;
});
this.emit('arrow-side-changed');
}
},
}
set xOffset(offset) {
this._xOffset = offset;
this._shiftActor();
},
}
get xOffset() {
return this._xOffset;
},
}
set yOffset(offset) {
this._yOffset = offset;
this._shiftActor();
},
}
get yOffset() {
return this._yOffset;
},
set opacity(opacity) {
this.actor.opacity = opacity;
},
get opacity() {
return this.actor.opacity;
},
}
updateArrowSide(side) {
this._arrowSide = side;
this._border.queue_repaint();
this.emit('arrow-side-changed');
},
}
getPadding(side) {
return this.bin.get_theme_node().get_padding(side);
},
}
getArrowHeight() {
return this.actor.get_theme_node().get_length('-arrow-rise');
return this.get_theme_node().get_length('-arrow-rise');
}
});
Signals.addSignalMethods(BoxPointer.prototype);

View File

@ -4,7 +4,6 @@ const Clutter = imports.gi.Clutter;
const Gio = imports.gi.Gio;
const GLib = imports.gi.GLib;
const Gtk = imports.gi.Gtk;
const Lang = imports.lang;
const St = imports.gi.St;
const Signals = imports.signals;
const Shell = imports.gi.Shell;
@ -89,49 +88,42 @@ function _getCalendarDayAbbreviation(dayNumber) {
// Abstraction for an appointment/event in a calendar
var CalendarEvent = new Lang.Class({
Name: 'CalendarEvent',
_init(id, date, end, summary, allDay) {
var CalendarEvent = class CalendarEvent {
constructor(id, date, end, summary, allDay) {
this.id = id;
this.date = date;
this.end = end;
this.summary = summary;
this.allDay = allDay;
}
});
};
// Interface for appointments/events - e.g. the contents of a calendar
//
// First, an implementation with no events
var EmptyEventSource = new Lang.Class({
Name: 'EmptyEventSource',
_init() {
var EmptyEventSource = class EmptyEventSource {
constructor() {
this.isLoading = false;
this.isDummy = true;
this.hasCalendars = false;
},
}
destroy() {
},
ignoreEvent(event) {
},
}
requestRange(begin, end) {
},
}
getEvents(begin, end) {
let result = [];
return result;
},
}
hasEvents(day) {
return false;
}
});
};
Signals.addSignalMethods(EmptyEventSource.prototype);
const CalendarServerIface = `
@ -177,22 +169,12 @@ function _dateIntervalsOverlap(a0, a1, b0, b1)
}
// an implementation that reads data from a session bus service
var DBusEventSource = new Lang.Class({
Name: 'DBusEventSource',
_init() {
var DBusEventSource = class DBusEventSource {
constructor() {
this._resetCache();
this.isLoading = false;
this.isDummy = false;
this._ignoredEvents = new Map();
let savedState = global.get_persistent_state('as', 'ignored_events');
if (savedState)
savedState.deep_unpack().forEach(eventId => {
this._ignoredEvents.set(eventId, true);
});
this._initialized = false;
this._dbusProxy = new CalendarServer();
this._dbusProxy.init_async(GLib.PRIORITY_DEFAULT, null, (object, result) => {
@ -235,39 +217,39 @@ var DBusEventSource = new Lang.Class({
this._onNameAppeared();
}
});
},
}
destroy() {
this._dbusProxy.run_dispose();
},
}
get hasCalendars() {
if (this._initialized)
return this._dbusProxy.HasCalendars;
else
return false;
},
}
_resetCache() {
this._events = [];
this._lastRequestBegin = null;
this._lastRequestEnd = null;
},
}
_onNameAppeared(owner) {
this._initialized = true;
this._resetCache();
this._loadEvents(true);
},
}
_onNameVanished(oldOwner) {
this._resetCache();
this.emit('changed');
},
}
_onChanged() {
this._loadEvents(false);
},
}
_onEventsReceived(results, error) {
let newEvents = [];
@ -289,7 +271,7 @@ var DBusEventSource = new Lang.Class({
this._events = newEvents;
this.isLoading = false;
this.emit('changed');
},
}
_loadEvents(forceReload) {
// Ignore while loading
@ -303,17 +285,7 @@ var DBusEventSource = new Lang.Class({
this._onEventsReceived.bind(this),
Gio.DBusCallFlags.NONE);
}
},
ignoreEvent(event) {
if (this._ignoredEvents.get(event.id))
return;
this._ignoredEvents.set(event.id, true);
let savedState = new GLib.Variant('as', [...this._ignoredEvents.keys()]);
global.set_persistent_state('ignored_events', savedState);
this.emit('changed');
},
}
requestRange(begin, end) {
if (!(_datesEqual(begin, this._lastRequestBegin) && _datesEqual(end, this._lastRequestEnd))) {
@ -324,16 +296,13 @@ var DBusEventSource = new Lang.Class({
this._curRequestEnd = end;
this._loadEvents(false);
}
},
}
getEvents(begin, end) {
let result = [];
for(let n = 0; n < this._events.length; n++) {
let event = this._events[n];
if (this._ignoredEvents.has(event.id))
continue;
if (_dateIntervalsOverlap (event.date, event.end, begin, end)) {
result.push(event);
}
@ -345,7 +314,7 @@ var DBusEventSource = new Lang.Class({
return d1.getTime() - d2.getTime();
});
return result;
},
}
hasEvents(day) {
let dayBegin = _getBeginningOfDay(day);
@ -358,13 +327,11 @@ var DBusEventSource = new Lang.Class({
return true;
}
});
};
Signals.addSignalMethods(DBusEventSource.prototype);
var Calendar = new Lang.Class({
Name: 'Calendar',
_init() {
var Calendar = class Calendar {
constructor() {
this._weekStart = Shell.util_get_week_start();
this._settings = new Gio.Settings({ schema_id: 'org.gnome.desktop.calendar' });
@ -402,7 +369,7 @@ var Calendar = new Lang.Class({
this._onScroll.bind(this));
this._buildHeader ();
},
}
// @eventSource: is an object implementing the EventSource API, e.g. the
// requestRange(), getEvents(), hasEvents() methods and the ::changed signal.
@ -414,7 +381,7 @@ var Calendar = new Lang.Class({
});
this._rebuildCalendar();
this._update();
},
}
// Sets the calendar to show a specific date
setDate(date) {
@ -424,14 +391,14 @@ var Calendar = new Lang.Class({
this._selectedDate = date;
this._update();
this.emit('selected-date-changed', new Date(this._selectedDate));
},
}
updateTimeZone() {
// The calendar need to be rebuilt after a time zone update because
// the date might have changed.
this._rebuildCalendar();
this._update();
},
}
_buildHeader() {
let layout = this.actor.layout_manager;
@ -446,6 +413,7 @@ var Calendar = new Lang.Class({
this._backButton = new St.Button({ style_class: 'calendar-change-month-back pager-button',
accessible_name: _("Previous month"),
can_focus: true });
this._backButton.add_actor(new St.Icon({ icon_name: 'pan-start-symbolic' }));
this._topBox.add(this._backButton);
this._backButton.connect('clicked', this._onPrevMonthButtonClicked.bind(this));
@ -456,6 +424,7 @@ var Calendar = new Lang.Class({
this._forwardButton = new St.Button({ style_class: 'calendar-change-month-forward pager-button',
accessible_name: _("Next month"),
can_focus: true });
this._forwardButton.add_actor(new St.Icon({ icon_name: 'pan-end-symbolic' }));
this._topBox.add(this._forwardButton);
this._forwardButton.connect('clicked', this._onNextMonthButtonClicked.bind(this));
@ -486,7 +455,7 @@ var Calendar = new Lang.Class({
// All the children after this are days, and get removed when we update the calendar
this._firstDayIndex = this.actor.get_n_children();
},
}
_onScroll(actor, event) {
switch (event.get_scroll_direction()) {
@ -500,7 +469,7 @@ var Calendar = new Lang.Class({
break;
}
return Clutter.EVENT_PROPAGATE;
},
}
_onPrevMonthButtonClicked() {
let newDate = new Date(this._selectedDate);
@ -524,7 +493,7 @@ var Calendar = new Lang.Class({
this._backButton.grab_key_focus();
this.setDate(newDate);
},
}
_onNextMonthButtonClicked() {
let newDate = new Date(this._selectedDate);
@ -548,14 +517,14 @@ var Calendar = new Lang.Class({
this._forwardButton.grab_key_focus();
this.setDate(newDate);
},
}
_onSettingsChange() {
this._useWeekdate = this._settings.get_boolean(SHOW_WEEKDATE_KEY);
this._buildHeader();
this._rebuildCalendar();
this._update();
},
}
_rebuildCalendar() {
let now = new Date();
@ -676,7 +645,7 @@ var Calendar = new Lang.Class({
// Signal to the event source that we are interested in events
// only from this date range
this._eventSource.requestRange(beginDate, iter);
},
}
_update() {
let now = new Date();
@ -699,18 +668,17 @@ var Calendar = new Lang.Class({
button.remove_style_pseudo_class('selected');
});
}
});
};
Signals.addSignalMethods(Calendar.prototype);
var EventMessage = new Lang.Class({
Name: 'EventMessage',
Extends: MessageList.Message,
var EventMessage = class EventMessage extends MessageList.Message {
constructor(event, date) {
super('', event.summary);
_init(event, date) {
this._event = event;
this._date = date;
this.parent(this._formatEventTime(), event.summary);
this.setTitle(this._formatEventTime());
this._icon = new St.Icon({ icon_name: 'x-office-calendar-symbolic' });
this.setIcon(this._icon);
@ -719,7 +687,7 @@ var EventMessage = new Lang.Class({
let iconVisible = this.actor.get_parent().has_style_pseudo_class('first-child');
this._icon.opacity = (iconVisible ? 255 : 0);
});
},
}
_formatEventTime() {
let periodBegin = _getBeginningOfDay(this._date);
@ -752,36 +720,33 @@ var EventMessage = new Lang.Class({
title = title + ELLIPSIS_CHAR;
}
return title;
},
canClose() {
return isToday(this._date);
}
});
};
var NotificationMessage = new Lang.Class({
Name: 'NotificationMessage',
Extends: MessageList.Message,
_init(notification) {
this.notification = notification;
this.parent(notification.title, notification.bannerBodyText);
var NotificationMessage =
class NotificationMessage extends MessageList.Message {
constructor(notification) {
super(notification.title, notification.bannerBodyText);
this.setUseBodyMarkup(notification.bannerBodyMarkup);
this.notification = notification;
this.setIcon(this._getIcon());
this.connect('close', () => {
this._closed = true;
this.notification.destroy(MessageTray.NotificationDestroyedReason.DISMISSED);
if (this.notification)
this.notification.destroy(MessageTray.NotificationDestroyedReason.DISMISSED);
});
this._destroyId = notification.connect('destroy', () => {
this._disconnectNotificationSignals();
this.notification = null;
if (!this._closed)
this.close();
});
this._updatedId = notification.connect('updated',
this._onUpdated.bind(this));
},
}
_getIcon() {
if (this.notification.gicon)
@ -789,22 +754,25 @@ var NotificationMessage = new Lang.Class({
icon_size: MESSAGE_ICON_SIZE });
else
return this.notification.source.createIcon(MESSAGE_ICON_SIZE);
},
}
_onUpdated(n, clear) {
this.setIcon(this._getIcon());
this.setTitle(n.title);
this.setBody(n.bannerBodyText);
this.setUseBodyMarkup(n.bannerBodyMarkup);
},
}
_onClicked() {
this.notification.activate();
},
}
_onDestroy() {
this.parent();
super._onDestroy();
this._disconnectNotificationSignals();
}
_disconnectNotificationSignals() {
if (this._updatedId)
this.notification.disconnect(this._updatedId);
this._updatedId = 0;
@ -813,21 +781,22 @@ var NotificationMessage = new Lang.Class({
this.notification.disconnect(this._destroyId);
this._destroyId = 0;
}
});
var EventsSection = new Lang.Class({
Name: 'EventsSection',
Extends: MessageList.MessageListSection,
canClose() {
return true;
}
};
var EventsSection = class EventsSection extends MessageList.MessageListSection {
constructor() {
super();
_init() {
this._desktopSettings = new Gio.Settings({ schema_id: 'org.gnome.desktop.interface' });
this._desktopSettings.connect('changed', this._reloadEvents.bind(this));
this._eventSource = new EmptyEventSource();
this._messageById = new Map();
this.parent();
this._title = new St.Button({ style_class: 'events-section-title',
label: '',
x_align: St.Align.START,
@ -840,20 +809,16 @@ var EventsSection = new Lang.Class({
Shell.AppSystem.get_default().connect('installed-changed',
this._appInstalledChanged.bind(this));
this._appInstalledChanged();
},
_ignoreEvent(event) {
this._eventSource.ignoreEvent(event);
},
}
setEventSource(eventSource) {
this._eventSource = eventSource;
this._eventSource.connect('changed', this._reloadEvents.bind(this));
},
}
get allowed() {
return Main.sessionMode.showCalendarEvents;
},
}
_updateTitle() {
this._title.visible = !isToday(this._date);
@ -866,13 +831,13 @@ var EventsSection = new Lang.Class({
if (sameYear(this._date, now))
/* Translators: Shown on calendar heading when selected day occurs on current year */
dayFormat = Shell.util_translate_time_string(NC_("calendar heading",
"%A, %B %d"));
"%A, %B %-d"));
else
/* Translators: Shown on calendar heading when selected day occurs on different year */
dayFormat = Shell.util_translate_time_string(NC_("calendar heading",
"%A, %B %d, %Y"));
"%A, %B %-d, %Y"));
this._title.label = this._date.toLocaleFormat(dayFormat);
},
}
_reloadEvents() {
if (this._eventSource.isLoading)
@ -898,9 +863,6 @@ var EventsSection = new Lang.Class({
let message = this._messageById.get(event.id);
if (!message) {
message = new EventMessage(event, this._date);
message.connect('close', () => {
this._ignoreEvent(event);
});
this._messageById.set(event.id, message);
this.addMessage(message, false);
} else {
@ -910,12 +872,12 @@ var EventsSection = new Lang.Class({
this._reloading = false;
this._sync();
},
}
_appInstalledChanged() {
this._calendarApp = undefined;
this._title.reactive = (this._getCalendarApp() != null);
},
}
_getCalendarApp() {
if (this._calendarApp !== undefined)
@ -930,7 +892,7 @@ var EventsSection = new Lang.Class({
this._calendarApp = null;
}
return this._calendarApp;
},
}
_onTitleClicked() {
Main.overview.hide();
@ -940,32 +902,30 @@ var EventsSection = new Lang.Class({
if (app.get_id() == 'evolution.desktop')
app = Gio.DesktopAppInfo.new('evolution-calendar.desktop');
app.launch([], global.create_app_launch_context(0, -1));
},
}
setDate(date) {
this.parent(date);
super.setDate(date);
this._updateTitle();
this._reloadEvents();
},
}
_shouldShow() {
return !this.empty || !isToday(this._date);
},
}
_sync() {
if (this._reloading)
return;
this.parent();
super._sync();
}
});
};
var NotificationSection = new Lang.Class({
Name: 'NotificationSection',
Extends: MessageList.MessageListSection,
_init() {
this.parent();
var NotificationSection =
class NotificationSection extends MessageList.MessageListSection {
constructor() {
super();
this._sources = new Map();
this._nUrgent = 0;
@ -976,12 +936,12 @@ var NotificationSection = new Lang.Class({
});
this.actor.connect('notify::mapped', this._onMapped.bind(this));
},
}
get allowed() {
return Main.sessionMode.hasNotifications &&
!Main.sessionMode.isGreeter;
},
}
_createTimeLabel(datetime) {
let label = new St.Label({ style_class: 'event-time',
@ -992,7 +952,7 @@ var NotificationSection = new Lang.Class({
label.text = Util.formatTimeSpan(datetime);
});
return label;
},
}
_sourceAdded(tray, source) {
let obj = {
@ -1007,7 +967,7 @@ var NotificationSection = new Lang.Class({
this._onNotificationAdded.bind(this));
this._sources.set(source, obj);
},
}
_onNotificationAdded(source, notification) {
let message = new NotificationMessage(notification);
@ -1038,14 +998,14 @@ var NotificationSection = new Lang.Class({
let index = isUrgent ? 0 : this._nUrgent;
this.addMessageAtIndex(message, index, this.actor.mapped);
},
}
_onSourceDestroy(source, obj) {
source.disconnect(obj.destroyId);
source.disconnect(obj.notificationAddedId);
this._sources.delete(source);
},
}
_onMapped() {
if (!this.actor.mapped)
@ -1054,17 +1014,15 @@ var NotificationSection = new Lang.Class({
for (let message of this._messages.keys())
if (message.notification.urgency != MessageTray.Urgency.CRITICAL)
message.notification.acknowledged = true;
},
}
_shouldShow() {
return !this.empty && isToday(this._date);
}
});
};
var Placeholder = new Lang.Class({
Name: 'Placeholder',
_init() {
var Placeholder = class Placeholder {
constructor() {
this.actor = new St.BoxLayout({ style_class: 'message-list-placeholder',
vertical: true });
@ -1082,14 +1040,14 @@ var Placeholder = new Lang.Class({
this.actor.add_actor(this._label);
this._sync();
},
}
setDate(date) {
if (sameDay(this._date, date))
return;
this._date = date;
this._sync();
},
}
_sync() {
let today = isToday(this._date);
@ -1106,12 +1064,10 @@ var Placeholder = new Lang.Class({
this._label.text = _("No Events");
}
}
});
};
var CalendarMessageList = new Lang.Class({
Name: 'CalendarMessageList',
_init() {
var CalendarMessageList = class CalendarMessageList {
constructor() {
this.actor = new St.Widget({ style_class: 'message-list',
layout_manager: new Clutter.BinLayout(),
x_expand: true, y_expand: true });
@ -1131,7 +1087,7 @@ var CalendarMessageList = new Lang.Class({
box.add_actor(this._scrollView);
this._clearButton = new St.Button({ style_class: 'message-list-clear-button button',
label: _("Clear All"),
label: _("Clear"),
can_focus: true });
this._clearButton.set_x_align(Clutter.ActorAlign.END);
this._clearButton.connect('clicked', () => {
@ -1157,7 +1113,7 @@ var CalendarMessageList = new Lang.Class({
this._addSection(this._eventsSection);
Main.sessionMode.connect('updated', this._sync.bind(this));
},
}
_addSection(section) {
let obj = {
@ -1182,7 +1138,7 @@ var CalendarMessageList = new Lang.Class({
this._sections.set(section, obj);
this._sectionList.add_actor(section.actor);
this._sync();
},
}
_removeSection(section) {
let obj = this._sections.get(section);
@ -1195,11 +1151,11 @@ var CalendarMessageList = new Lang.Class({
this._sections.delete(section);
this._sectionList.remove_actor(section.actor);
this._sync();
},
}
_onKeyFocusIn(section, actor) {
Util.ensureActorVisibleInScrollView(this._scrollView, actor);
},
}
_sync() {
let sections = [...this._sections.keys()];
@ -1214,15 +1170,15 @@ var CalendarMessageList = new Lang.Class({
let canClear = sections.some(s => s.canClear && s.actor.visible);
this._clearButton.reactive = canClear;
},
}
setEventSource(eventSource) {
this._eventsSection.setEventSource(eventSource);
},
}
setDate(date) {
for (let section of this._sections.keys())
section.setDate(date);
this._placeholder.setDate(date);
}
});
};

View File

@ -2,12 +2,8 @@ const Clutter = imports.gi.Clutter;
const Pango = imports.gi.Pango;
const St = imports.gi.St;
const Lang = imports.lang;
var CheckBox = new Lang.Class({
Name: 'CheckBox',
_init(label) {
var CheckBox = class CheckBox {
constructor(label) {
let container = new St.BoxLayout();
this.actor = new St.Button({ style_class: 'check-box',
child: container,
@ -28,13 +24,13 @@ var CheckBox = new Lang.Class({
if (label)
this.setLabel(label);
},
}
setLabel(label) {
this._label.set_text(label);
},
}
getLabelActor() {
return this._label;
}
});
};

View File

@ -4,7 +4,6 @@ const Clutter = imports.gi.Clutter;
const Gio = imports.gi.Gio;
const GLib = imports.gi.GLib;
const GObject = imports.gi.GObject;
const Lang = imports.lang;
const Meta = imports.gi.Meta;
const Shell = imports.gi.Shell;
@ -16,31 +15,29 @@ var FROZEN_WINDOW_BRIGHTNESS = -0.3
var DIALOG_TRANSITION_TIME = 0.15
var ALIVE_TIMEOUT = 5000;
var CloseDialog = new Lang.Class({
Name: 'CloseDialog',
Extends: GObject.Object,
var CloseDialog = GObject.registerClass({
Implements: [ Meta.CloseDialog ],
Properties: {
'window': GObject.ParamSpec.override('window', Meta.CloseDialog)
},
}, class CloseDialog extends GObject.Object {
_init(window) {
this.parent();
super._init();
this._window = window;
this._dialog = null;
this._tracked = undefined;
this._timeoutId = 0;
this._windowFocusChangedId = 0;
this._keyFocusChangedId = 0;
},
}
get window() {
return this._window;
},
}
set window(window) {
this._window = window;
},
}
_createDialogContent() {
let tracker = Shell.WindowTracker.get_default();
@ -52,7 +49,7 @@ var CloseDialog = new Lang.Class({
"continue or force the application to quit entirely.");
let icon = new Gio.ThemedIcon({ name: 'dialog-warning-symbolic' });
return new Dialog.MessageDialogContent({ icon, title, subtitle });
},
}
_initDialog() {
if (this._dialog)
@ -72,7 +69,7 @@ var CloseDialog = new Lang.Class({
key: Clutter.Escape });
global.focus_manager.add_group(this._dialog);
},
}
_addWindowEffect() {
// We set the effect on the surface actor, so the dialog itself
@ -83,21 +80,21 @@ var CloseDialog = new Lang.Class({
let effect = new Clutter.BrightnessContrastEffect();
effect.set_brightness(FROZEN_WINDOW_BRIGHTNESS);
surfaceActor.add_effect_with_name("gnome-shell-frozen-window", effect);
},
}
_removeWindowEffect() {
let windowActor = this._window.get_compositor_private();
let surfaceActor = windowActor.get_first_child();
surfaceActor.remove_effect_by_name("gnome-shell-frozen-window");
},
}
_onWait() {
this.response(Meta.CloseDialogResponse.WAIT);
},
}
_onClose() {
this.response(Meta.CloseDialogResponse.FORCE_CLOSE);
},
}
_onFocusChanged() {
if (Meta.is_wayland_compositor())
@ -128,7 +125,7 @@ var CloseDialog = new Lang.Class({
});
this._tracked = shouldTrack;
},
}
vfunc_show() {
if (this._dialog != null)
@ -162,7 +159,7 @@ var CloseDialog = new Lang.Class({
time: DIALOG_TRANSITION_TIME,
onComplete: this._onFocusChanged.bind(this)
});
},
}
vfunc_hide() {
if (this._dialog == null)
@ -191,7 +188,7 @@ var CloseDialog = new Lang.Class({
dialog.destroy();
}
});
},
}
vfunc_focus() {
if (this._dialog)

View File

@ -1,17 +1,13 @@
const Lang = imports.lang;
const Main = imports.ui.main;
var ComponentManager = new Lang.Class({
Name: 'ComponentManager',
_init() {
var ComponentManager = class {
constructor() {
this._allComponents = {};
this._enabledComponents = [];
Main.sessionMode.connect('updated', this._sessionUpdated.bind(this));
this._sessionUpdated();
},
}
_sessionUpdated() {
let newEnabledComponents = Main.sessionMode.components;
@ -29,12 +25,12 @@ var ComponentManager = new Lang.Class({
});
this._enabledComponents = newEnabledComponents;
},
}
_importComponent(name) {
let module = imports.ui.components[name];
return module.Component;
},
}
_ensureComponent(name) {
let component = this._allComponents[name];
@ -48,13 +44,13 @@ var ComponentManager = new Lang.Class({
component = new constructor();
this._allComponents[name] = component;
return component;
},
}
_enableComponent(name) {
let component = this._ensureComponent(name);
if (component)
component.enable();
},
}
_disableComponent(name) {
let component = this._allComponents[name];
@ -62,4 +58,4 @@ var ComponentManager = new Lang.Class({
return;
component.disable();
}
});
};

View File

@ -1,6 +1,5 @@
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
const Lang = imports.lang;
const Mainloop = imports.mainloop;
const GLib = imports.gi.GLib;
const Gio = imports.gi.Gio;
@ -19,10 +18,8 @@ const SETTING_ENABLE_AUTOMOUNT = 'automount';
var AUTORUN_EXPIRE_TIMEOUT_SECS = 10;
var AutomountManager = new Lang.Class({
Name: 'AutomountManager',
_init() {
var AutomountManager = class {
constructor() {
this._settings = new Gio.Settings({ schema_id: SETTINGS_SCHEMA });
this._volumeQueue = [];
this._activeOperations = new Map();
@ -34,7 +31,7 @@ var AutomountManager = new Lang.Class({
this._inhibited = false;
this._volumeMonitor = Gio.VolumeMonitor.get();
},
}
enable() {
this._volumeAddedId = this._volumeMonitor.connect('volume-added', this._onVolumeAdded.bind(this));
@ -45,7 +42,7 @@ var AutomountManager = new Lang.Class({
this._mountAllId = Mainloop.idle_add(this._startupMountAll.bind(this));
GLib.Source.set_name_by_id(this._mountAllId, '[gnome-shell] this._startupMountAll');
},
}
disable() {
this._volumeMonitor.disconnect(this._volumeAddedId);
@ -58,7 +55,7 @@ var AutomountManager = new Lang.Class({
Mainloop.source_remove(this._mountAllId);
this._mountAllId = 0;
}
},
}
_InhibitorsChanged(object, senderName, [inhibtor]) {
this._session.IsInhibitedRemote(GNOME_SESSION_AUTOMOUNT_INHIBIT,
@ -67,7 +64,7 @@ var AutomountManager = new Lang.Class({
this._inhibited = result[0];
}
});
},
}
_startupMountAll() {
let volumes = this._volumeMonitor.get_volumes();
@ -79,7 +76,7 @@ var AutomountManager = new Lang.Class({
this._mountAllId = 0;
return GLib.SOURCE_REMOVE;
},
}
_onDriveConnected() {
// if we're not in the current ConsoleKit session,
@ -87,10 +84,11 @@ var AutomountManager = new Lang.Class({
if (!this._session.SessionIsActive)
return;
global.play_theme_sound(0, 'device-added-media',
_("External drive connected"),
null);
},
let player = global.display.get_sound_player();
player.play_from_theme('device-added-media',
_("External drive connected"),
null);
}
_onDriveDisconnected() {
// if we're not in the current ConsoleKit session,
@ -98,10 +96,11 @@ var AutomountManager = new Lang.Class({
if (!this._session.SessionIsActive)
return;
global.play_theme_sound(0, 'device-removed-media',
_("External drive disconnected"),
null);
},
let sound = global.display.get_sound();
sound.play_from_theme('device-removed-media',
_("External drive disconnected"),
null);
}
_onDriveEjectButton(monitor, drive) {
// TODO: this code path is not tested, as the GVfs volume monitor
@ -132,11 +131,11 @@ var AutomountManager = new Lang.Class({
}
});
}
},
}
_onVolumeAdded(monitor, volume) {
this._checkAndMountVolume(volume);
},
}
_checkAndMountVolume(volume, params) {
params = Params.parse(params, { checkSession: true,
@ -176,7 +175,7 @@ var AutomountManager = new Lang.Class({
} else {
this._mountVolume(volume, null, params.allowAutorun);
}
},
}
_mountVolume(volume, operation, allowAutorun) {
if (allowAutorun)
@ -187,7 +186,7 @@ var AutomountManager = new Lang.Class({
volume.mount(0, mountOp, null,
this._onVolumeMounted.bind(this));
},
}
_onVolumeMounted(volume, res) {
this._allowAutorunExpire(volume);
@ -197,9 +196,13 @@ var AutomountManager = new Lang.Class({
this._closeOperation(volume);
} catch (e) {
// FIXME: we will always get G_IO_ERROR_FAILED from the gvfs udisks
// backend in this case, see
// https://bugs.freedesktop.org/show_bug.cgi?id=51271
if (e.message.indexOf('No key available with this passphrase') != -1) {
// backend, see https://bugs.freedesktop.org/show_bug.cgi?id=51271
// To reask the password if the user input was empty or wrong, we
// will check for corresponding error messages. However, these
// error strings are not unique for the cases in the comments below.
if (e.message.includes('No key available with this passphrase') || // cryptsetup
e.message.includes('No key available to unlock device') || // udisks (no password)
e.message.includes('Error unlocking')) { // udisks (wrong password)
this._reaskPassword(volume);
} else {
if (!e.matches(Gio.IOErrorEnum, Gio.IOErrorEnum.FAILED_HANDLED))
@ -208,7 +211,7 @@ var AutomountManager = new Lang.Class({
this._closeOperation(volume);
}
}
},
}
_onVolumeRemoved(monitor, volume) {
if (volume._allowAutorunExpireId && volume._allowAutorunExpireId > 0) {
@ -217,7 +220,7 @@ var AutomountManager = new Lang.Class({
}
this._volumeQueue =
this._volumeQueue.filter(element => (element != volume));
},
}
_reaskPassword(volume) {
let prevOperation = this._activeOperations.get(volume);
@ -226,7 +229,7 @@ var AutomountManager = new Lang.Class({
new ShellMountOperation.ShellMountOperation(volume,
{ existingDialog: existingDialog });
this._mountVolume(volume, operation);
},
}
_closeOperation(volume) {
let operation = this._activeOperations.get(volume);
@ -234,11 +237,11 @@ var AutomountManager = new Lang.Class({
return;
operation.close();
this._activeOperations.delete(volume);
},
}
_allowAutorun(volume) {
volume.allowAutorun = true;
},
}
_allowAutorunExpire(volume) {
let id = Mainloop.timeout_add_seconds(AUTORUN_EXPIRE_TIMEOUT_SECS, () => {
@ -249,5 +252,5 @@ var AutomountManager = new Lang.Class({
volume._allowAutorunExpireId = id;
GLib.Source.set_name_by_id(id, '[gnome-shell] volume.allowAutorun');
}
});
};
var Component = AutomountManager;

View File

@ -1,6 +1,5 @@
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
const Lang = imports.lang;
const Gio = imports.gi.Gio;
const St = imports.gi.St;
@ -84,13 +83,11 @@ function HotplugSniffer() {
'/org/gnome/Shell/HotplugSniffer');
}
var ContentTypeDiscoverer = new Lang.Class({
Name: 'ContentTypeDiscoverer',
_init(callback) {
var ContentTypeDiscoverer = class {
constructor(callback) {
this._callback = callback;
this._settings = new Gio.Settings({ schema_id: SETTINGS_SCHEMA });
},
}
guessContentTypes(mount) {
let autorunEnabled = !this._settings.get_boolean(SETTING_DISABLE_AUTORUN);
@ -103,7 +100,7 @@ var ContentTypeDiscoverer = new Lang.Class({
} else {
this._emitCallback(mount, []);
}
},
}
_onContentTypeGuessed(mount, res) {
let contentTypes = [];
@ -126,7 +123,7 @@ var ContentTypeDiscoverer = new Lang.Class({
this._emitCallback(mount, contentTypes);
});
}
},
}
_emitCallback(mount, contentTypes) {
if (!contentTypes)
@ -150,27 +147,25 @@ var ContentTypeDiscoverer = new Lang.Class({
this._callback(mount, apps, contentTypes);
}
});
};
var AutorunManager = new Lang.Class({
Name: 'AutorunManager',
_init() {
var AutorunManager = class {
constructor() {
this._session = new GnomeSession.SessionManager();
this._volumeMonitor = Gio.VolumeMonitor.get();
this._dispatcher = new AutorunDispatcher(this);
},
}
enable() {
this._mountAddedId = this._volumeMonitor.connect('mount-added', this._onMountAdded.bind(this));
this._mountRemovedId = this._volumeMonitor.connect('mount-removed', this._onMountRemoved.bind(this));
},
}
disable() {
this._volumeMonitor.disconnect(this._mountAddedId);
this._volumeMonitor.disconnect(this._mountRemovedId);
},
}
_onMountAdded(monitor, mount) {
// don't do anything if our session is not the currently
@ -182,21 +177,19 @@ var AutorunManager = new Lang.Class({
this._dispatcher.addMount(mount, apps, contentTypes);
});
discoverer.guessContentTypes(mount);
},
}
_onMountRemoved(monitor, mount) {
this._dispatcher.removeMount(mount);
}
});
};
var AutorunDispatcher = new Lang.Class({
Name: 'AutorunDispatcher',
_init(manager) {
var AutorunDispatcher = class {
constructor(manager) {
this._manager = manager;
this._sources = [];
this._settings = new Gio.Settings({ schema_id: SETTINGS_SCHEMA });
},
}
_getAutorunSettingForType(contentType) {
let runApp = this._settings.get_strv(SETTING_START_APP);
@ -212,7 +205,7 @@ var AutorunDispatcher = new Lang.Class({
return AutorunSetting.FILES;
return AutorunSetting.ASK;
},
}
_getSourceForMount(mount) {
let filtered = this._sources.filter(source => (source.mount == mount));
@ -224,7 +217,7 @@ var AutorunDispatcher = new Lang.Class({
return filtered[0];
return null;
},
}
_addSource(mount, apps) {
// if we already have a source showing for this
@ -234,7 +227,7 @@ var AutorunDispatcher = new Lang.Class({
// add a new source
this._sources.push(new AutorunSource(this._manager, mount, apps));
},
}
addMount(mount, apps, contentTypes) {
// if autorun is disabled globally, return
@ -272,7 +265,7 @@ var AutorunDispatcher = new Lang.Class({
// but we failed launching the default app or the default file manager
if (!success)
this._addSource(mount, apps);
},
}
removeMount(mount) {
let source = this._getSourceForMount(mount);
@ -284,45 +277,39 @@ var AutorunDispatcher = new Lang.Class({
// destroy the notification source
source.destroy();
}
});
};
var AutorunSource = new Lang.Class({
Name: 'AutorunSource',
Extends: MessageTray.Source,
var AutorunSource = class extends MessageTray.Source {
constructor(manager, mount, apps) {
super(mount.get_name());
_init(manager, mount, apps) {
this._manager = manager;
this.mount = mount;
this.apps = apps;
this.parent(mount.get_name());
this._notification = new AutorunNotification(this._manager, this);
// add ourselves as a source, and popup the notification
Main.messageTray.add(this);
this.notify(this._notification);
},
}
getIcon() {
return this.mount.get_icon();
},
}
_createPolicy() {
return new MessageTray.NotificationApplicationPolicy('org.gnome.Nautilus');
}
});
};
var AutorunNotification = new Lang.Class({
Name: 'AutorunNotification',
Extends: MessageTray.Notification,
_init(manager, source) {
this.parent(source, source.title);
var AutorunNotification = class extends MessageTray.Notification {
constructor(manager, source) {
super(source, source.title);
this._manager = manager;
this._mount = source.mount;
},
}
createBanner() {
let banner = new MessageTray.NotificationBanner(this);
@ -335,7 +322,7 @@ var AutorunNotification = new Lang.Class({
});
return banner;
},
}
_buttonForApp(app) {
let box = new St.BoxLayout();
@ -362,14 +349,14 @@ var AutorunNotification = new Lang.Class({
});
return button;
},
}
activate() {
this.parent();
super.activate();
let app = Gio.app_info_get_default_for_type('inode/directory', false);
startAppForMount(app, this._mount);
}
});
};
var Component = AutorunManager;

View File

@ -1,6 +1,5 @@
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
const Lang = imports.lang;
const Shell = imports.gi.Shell;
const Clutter = imports.gi.Clutter;
const St = imports.gi.St;
@ -17,15 +16,10 @@ const CheckBox = imports.ui.checkBox;
const Tweener = imports.ui.tweener;
var WORK_SPINNER_ICON_SIZE = 16;
var WORK_SPINNER_ANIMATION_DELAY = 1.0;
var WORK_SPINNER_ANIMATION_TIME = 0.3;
var KeyringDialog = new Lang.Class({
Name: 'KeyringDialog',
Extends: ModalDialog.ModalDialog,
_init() {
this.parent({ styleClass: 'prompt-dialog' });
var KeyringDialog = class extends ModalDialog.ModalDialog {
constructor() {
super({ styleClass: 'prompt-dialog' });
this.prompt = new Shell.KeyringPrompt();
this.prompt.connect('show-password', this._onShowPassword.bind(this));
@ -63,34 +57,17 @@ var KeyringDialog = new Lang.Class({
this.prompt.bind_property('cancel-label', this._cancelButton, 'label', GObject.BindingFlags.SYNC_CREATE);
this.prompt.bind_property('continue-label', this._continueButton, 'label', GObject.BindingFlags.SYNC_CREATE);
},
}
_setWorking(working) {
if (!this._workSpinner)
return;
Tweener.removeTweens(this._workSpinner.actor);
if (working) {
if (working)
this._workSpinner.play();
Tweener.addTween(this._workSpinner.actor,
{ opacity: 255,
delay: WORK_SPINNER_ANIMATION_DELAY,
time: WORK_SPINNER_ANIMATION_TIME,
transition: 'linear'
});
} else {
Tweener.addTween(this._workSpinner.actor,
{ opacity: 0,
time: WORK_SPINNER_ANIMATION_TIME,
transition: 'linear',
onCompleteScope: this,
onComplete() {
if (this._workSpinner)
this._workSpinner.stop();
}
});
}
},
else
this._workSpinner.stop();
}
_buildControlTable() {
let layout = new Clutter.GridLayout({ orientation: Clutter.Orientation.VERTICAL });
@ -114,9 +91,7 @@ var KeyringDialog = new Lang.Class({
ShellEntry.addContextMenu(this._passwordEntry, { isPassword: true });
this._passwordEntry.clutter_text.connect('activate', this._onPasswordActivate.bind(this));
let spinnerIcon = Gio.File.new_for_uri('resource:///org/gnome/shell/theme/process-working.svg');
this._workSpinner = new Animation.AnimatedIcon(spinnerIcon, WORK_SPINNER_ICON_SIZE);
this._workSpinner.actor.opacity = 0;
this._workSpinner = new Animation.Spinner(WORK_SPINNER_ICON_SIZE, true);
if (rtl) {
layout.attach(this._workSpinner.actor, 0, row, 1, 1);
@ -183,7 +158,7 @@ var KeyringDialog = new Lang.Class({
this._controlTable = table;
this._content.messageBox.add(table, { x_fill: true, y_fill: true });
},
}
_updateSensitivity(sensitive) {
if (this._passwordEntry) {
@ -199,7 +174,7 @@ var KeyringDialog = new Lang.Class({
this._continueButton.can_focus = sensitive;
this._continueButton.reactive = sensitive;
this._setWorking(!sensitive);
},
}
_ensureOpen() {
// NOTE: ModalDialog.open() is safe to call if the dialog is
@ -217,65 +192,61 @@ var KeyringDialog = new Lang.Class({
' Dismissing prompt request');
this.prompt.cancel()
return false;
},
}
_onShowPassword(prompt) {
this._buildControlTable();
this._ensureOpen();
this._updateSensitivity(true);
this._passwordEntry.grab_key_focus();
},
}
_onShowConfirm(prompt) {
this._buildControlTable();
this._ensureOpen();
this._updateSensitivity(true);
this._continueButton.grab_key_focus();
},
}
_onHidePrompt(prompt) {
this.close();
},
}
_onPasswordActivate() {
if (this.prompt.confirm_visible)
this._confirmEntry.grab_key_focus();
else
this._onContinueButton();
},
}
_onConfirmActivate() {
this._onContinueButton();
},
}
_onContinueButton() {
this._updateSensitivity(false);
this.prompt.complete();
},
}
_onCancelButton() {
this.prompt.cancel();
},
});
}
};
var KeyringDummyDialog = new Lang.Class({
Name: 'KeyringDummyDialog',
_init() {
var KeyringDummyDialog = class {
constructor() {
this.prompt = new Shell.KeyringPrompt();
this.prompt.connect('show-password', this._cancelPrompt.bind(this));
this.prompt.connect('show-confirm', this._cancelPrompt.bind(this));
},
}
_cancelPrompt() {
this.prompt.cancel();
}
});
};
var KeyringPrompter = new Lang.Class({
Name: 'KeyringPrompter',
_init() {
var KeyringPrompter = class {
constructor() {
this._prompter = new Gcr.SystemPrompter();
this._prompter.connect('new-prompt', () => {
let dialog = this._enabled ? new KeyringDialog()
@ -287,7 +258,7 @@ var KeyringPrompter = new Lang.Class({
this._registered = false;
this._enabled = false;
this._currentPrompt = null;
},
}
enable() {
if (!this._registered) {
@ -297,7 +268,7 @@ var KeyringPrompter = new Lang.Class({
this._registered = true;
}
this._enabled = true;
},
}
disable() {
this._enabled = false;
@ -306,6 +277,6 @@ var KeyringPrompter = new Lang.Class({
this._currentPrompt.cancel();
this._currentPrompt = null;
}
});
};
var Component = KeyringPrompter;

View File

@ -4,7 +4,6 @@ const Clutter = imports.gi.Clutter;
const Gio = imports.gi.Gio;
const GLib = imports.gi.GLib;
const GObject = imports.gi.GObject;
const Lang = imports.lang;
const NM = imports.gi.NM;
const Pango = imports.gi.Pango;
const Shell = imports.gi.Shell;
@ -21,12 +20,9 @@ const ShellEntry = imports.ui.shellEntry;
const VPN_UI_GROUP = 'VPN Plugin UI';
var NetworkSecretDialog = new Lang.Class({
Name: 'NetworkSecretDialog',
Extends: ModalDialog.ModalDialog,
_init(agent, requestId, connection, settingName, hints, contentOverride) {
this.parent({ styleClass: 'prompt-dialog' });
var NetworkSecretDialog = class extends ModalDialog.ModalDialog {
constructor(agent, requestId, connection, settingName, hints, flags, contentOverride) {
super({ styleClass: 'prompt-dialog' });
this._agent = agent;
this._requestId = requestId;
@ -109,6 +105,18 @@ var NetworkSecretDialog = new Lang.Class({
contentBox.messageBox.add(secretTable);
if (flags & NM.SecretAgentGetSecretsFlags.WPS_PBC_ACTIVE) {
let descriptionLabel = new St.Label({ style_class: 'prompt-dialog-description',
text: _("Alternatively you can connect by pushing the “WPS” button on your router.") });
descriptionLabel.clutter_text.line_wrap = true;
descriptionLabel.clutter_text.ellipsize = Pango.EllipsizeMode.NONE;
messageBox.add(descriptionLabel,
{ y_fill: true,
y_align: St.Align.START,
expand: true });
}
this._okButton = { label: _("Connect"),
action: this._onOk.bind(this),
default: true
@ -121,7 +129,7 @@ var NetworkSecretDialog = new Lang.Class({
this._okButton]);
this._updateOkButton();
},
}
_updateOkButton() {
let valid = true;
@ -132,7 +140,7 @@ var NetworkSecretDialog = new Lang.Class({
this._okButton.button.reactive = valid;
this._okButton.button.can_focus = valid;
},
}
_onOk() {
let valid = true;
@ -148,12 +156,12 @@ var NetworkSecretDialog = new Lang.Class({
this.close(global.get_current_time());
}
// do nothing if not valid
},
}
cancel() {
this._agent.respond(this._requestId, Shell.NetworkAgentResponse.USER_CANCELED);
this.close(global.get_current_time());
},
}
_validateWpaPsk(secret) {
let value = secret.value;
@ -169,7 +177,7 @@ var NetworkSecretDialog = new Lang.Class({
}
return (value.length >= 8 && value.length <= 63);
},
}
_validateStaticWep(secret) {
let value = secret.value;
@ -194,7 +202,7 @@ var NetworkSecretDialog = new Lang.Class({
return false;
}
return true;
},
}
_getWirelessSecrets(secrets, wirelessSetting) {
let wirelessSecuritySetting = this._connection.get_setting_wireless_security();
@ -231,7 +239,7 @@ var NetworkSecretDialog = new Lang.Class({
default:
log('Invalid wireless key management: ' + wirelessSecuritySetting.key_mgmt);
}
},
}
_get8021xSecrets(secrets) {
let ieee8021xSetting = this._connection.get_setting_802_1x();
@ -274,7 +282,7 @@ var NetworkSecretDialog = new Lang.Class({
default:
log('Invalid EAP/IEEE802.1x method: ' + ieee8021xSetting.get_eap_method(0));
}
},
}
_getPPPoESecrets(secrets) {
let pppoeSetting = this._connection.get_setting_pppoe();
@ -284,7 +292,7 @@ var NetworkSecretDialog = new Lang.Class({
value: pppoeSetting.service || '', password: false });
secrets.push({ label: _("Password: "), key: 'password',
value: pppoeSetting.password || '', password: true });
},
}
_getMobileSecrets(secrets, connectionType) {
let setting;
@ -294,7 +302,7 @@ var NetworkSecretDialog = new Lang.Class({
setting = this._connection.get_setting_by_name(connectionType);
secrets.push({ label: _("Password: "), key: 'password',
value: setting.value || '', password: true });
},
}
_getContent() {
let connectionSetting = this._connection.get_setting_connection();
@ -347,15 +355,14 @@ var NetworkSecretDialog = new Lang.Class({
return content;
}
});
};
var VPNRequestHandler = new Lang.Class({
Name: 'VPNRequestHandler',
_init(agent, requestId, authHelper, serviceType, connection, hints, flags) {
var VPNRequestHandler = class {
constructor(agent, requestId, authHelper, serviceType, connection, hints, flags) {
this._agent = agent;
this._requestId = requestId;
this._connection = connection;
this._flags = flags;
this._pluginOutBuffer = [];
this._title = null;
this._description = null;
@ -412,7 +419,7 @@ var VPNRequestHandler = new Lang.Class({
this._agent.respond(requestId, Shell.NetworkAgentResponse.INTERNAL_ERROR);
}
},
}
cancel(respond) {
if (respond)
@ -428,7 +435,7 @@ var VPNRequestHandler = new Lang.Class({
}
this.destroy();
},
}
destroy() {
if (this._destroyed)
@ -442,7 +449,7 @@ var VPNRequestHandler = new Lang.Class({
// Stdout is closed when we finish reading from it
this._destroyed = true;
},
}
_vpnChildFinished(pid, status, requestObj) {
this._childWatch = 0;
@ -463,7 +470,7 @@ var VPNRequestHandler = new Lang.Class({
this._agent.respond(this._requestId, Shell.NetworkAgentResponse.INTERNAL_ERROR);
this.destroy();
},
}
_vpnChildProcessLineOldStyle(line) {
if (this._previousLine != undefined) {
@ -481,7 +488,7 @@ var VPNRequestHandler = new Lang.Class({
} else {
this._previousLine = line;
}
},
}
_readStdoutOldStyle() {
this._dataStdout.read_line_async(GLib.PRIORITY_DEFAULT, null, (stream, result) => {
@ -498,7 +505,7 @@ var VPNRequestHandler = new Lang.Class({
// try to read more!
this._readStdoutOldStyle();
});
},
}
_readStdoutNewStyle() {
this._dataStdout.fill_async(-1, GLib.PRIORITY_DEFAULT, null, (stream, result) => {
@ -516,7 +523,7 @@ var VPNRequestHandler = new Lang.Class({
this._dataStdout.set_buffer_size(2 * this._dataStdout.get_buffer_size());
this._readStdoutNewStyle();
});
},
}
_showNewStyleDialog() {
let keyfile = new GLib.KeyFile();
@ -574,13 +581,13 @@ var VPNRequestHandler = new Lang.Class({
if (contentOverride && contentOverride.secrets.length) {
// Only show the dialog if we actually have something to ask
this._shellDialog = new NetworkSecretDialog(this._agent, this._requestId, this._connection, 'vpn', [], contentOverride);
this._shellDialog = new NetworkSecretDialog(this._agent, this._requestId, this._connection, 'vpn', [], this._flags, contentOverride);
this._shellDialog.open(global.get_current_time());
} else {
this._agent.respond(this._requestId, Shell.NetworkAgentResponse.CONFIRMED);
this.destroy();
}
},
}
_writeConnection() {
let vpnSetting = this._connection.get_setting_vpn();
@ -601,14 +608,12 @@ var VPNRequestHandler = new Lang.Class({
this._agent.respond(this._requestId, Shell.NetworkAgentResponse.INTERNAL_ERROR);
this.destroy();
}
},
});
}
};
Signals.addSignalMethods(VPNRequestHandler.prototype);
var NetworkAgent = new Lang.Class({
Name: 'NetworkAgent',
_init() {
var NetworkAgent = class {
constructor() {
this._native = new Shell.NetworkAgent({ identifier: 'org.gnome.Shell.NetworkAgent',
capabilities: NM.SecretAgentCapabilities.VPN_HINTS,
auto_register: false
@ -639,7 +644,7 @@ var NetworkAgent = new Lang.Class({
logError(e, 'error initializing the NetworkManager Agent');
}
});
},
}
enable() {
if (!this._native)
@ -648,7 +653,7 @@ var NetworkAgent = new Lang.Class({
this._native.auto_register = true;
if (this._initialized && !this._native.registered)
this._native.register_async(null, null);
},
}
disable() {
let requestId;
@ -671,7 +676,7 @@ var NetworkAgent = new Lang.Class({
this._native.auto_register = false;
if (this._initialized && this._native.registered)
this._native.unregister_async(null, null);
},
}
_showNotification(requestId, connection, settingName, hints, flags) {
let source = new MessageTray.Source(_("Network Manager"), 'network-transmit-receive');
@ -731,14 +736,14 @@ var NetworkAgent = new Lang.Class({
Main.messageTray.add(source);
source.notify(notification);
},
}
_newRequest(agent, requestId, connection, settingName, hints, flags) {
if (!(flags & NM.SecretAgentGetSecretsFlags.USER_REQUESTED))
this._showNotification(requestId, connection, settingName, hints, flags);
else
this._handleRequest(requestId, connection, settingName, hints, flags);
},
}
_handleRequest(requestId, connection, settingName, hints, flags) {
if (settingName == 'vpn') {
@ -746,13 +751,13 @@ var NetworkAgent = new Lang.Class({
return;
}
let dialog = new NetworkSecretDialog(this._native, requestId, connection, settingName, hints);
let dialog = new NetworkSecretDialog(this._native, requestId, connection, settingName, hints, flags);
dialog.connect('destroy', () => {
delete this._dialogs[requestId];
});
this._dialogs[requestId] = dialog;
dialog.open(global.get_current_time());
},
}
_cancelRequest(agent, requestId) {
if (this._dialogs[requestId]) {
@ -763,7 +768,7 @@ var NetworkAgent = new Lang.Class({
this._vpnRequests[requestId].cancel(false);
delete this._vpnRequests[requestId];
}
},
}
_vpnRequest(requestId, connection, hints, flags) {
let vpnSetting = connection.get_setting_vpn();
@ -785,7 +790,7 @@ var NetworkAgent = new Lang.Class({
delete this._vpnRequests[requestId];
});
this._vpnRequests[requestId] = vpnRequest;
},
}
_buildVPNServiceCache() {
if (this._vpnCacheBuilt)
@ -818,5 +823,5 @@ var NetworkAgent = new Lang.Class({
}
});
}
});
};
var Component = NetworkAgent;

View File

@ -1,6 +1,5 @@
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
const Lang = imports.lang;
const Signals = imports.signals;
const Shell = imports.gi.Shell;
const AccountsService = imports.gi.AccountsService;
@ -25,15 +24,10 @@ const Tweener = imports.ui.tweener;
var DIALOG_ICON_SIZE = 48;
var WORK_SPINNER_ICON_SIZE = 16;
var WORK_SPINNER_ANIMATION_DELAY = 1.0;
var WORK_SPINNER_ANIMATION_TIME = 0.3;
var AuthenticationDialog = new Lang.Class({
Name: 'AuthenticationDialog',
Extends: ModalDialog.ModalDialog,
_init(actionId, body, cookie, userNames) {
this.parent({ styleClass: 'prompt-dialog' });
var AuthenticationDialog = class extends ModalDialog.ModalDialog {
constructor(actionId, body, cookie, userNames) {
super({ styleClass: 'prompt-dialog' });
this.actionId = actionId;
this.message = body;
@ -44,6 +38,8 @@ var AuthenticationDialog = new Lang.Class({
this._group.visible = !Main.sessionMode.isLocked;
});
this.connect('closed', this._onDialogClosed.bind(this));
let icon = new Gio.ThemedIcon({ name: 'dialog-password-symbolic' });
let title = _("Authentication Required");
@ -117,10 +113,7 @@ var AuthenticationDialog = new Lang.Class({
this._passwordBox.add(this._passwordEntry,
{ expand: true });
let spinnerIcon = Gio.File.new_for_uri('resource:///org/gnome/shell/theme/process-working.svg');
this._workSpinner = new Animation.AnimatedIcon(spinnerIcon, WORK_SPINNER_ICON_SIZE);
this._workSpinner.actor.opacity = 0;
this._workSpinner = new Animation.Spinner(WORK_SPINNER_ICON_SIZE, true);
this._passwordBox.add(this._workSpinner.actor);
this.setInitialKeyFocus(this._passwordEntry);
@ -161,50 +154,25 @@ var AuthenticationDialog = new Lang.Class({
this._identityToAuth = Polkit.UnixUser.new_for_name(userName);
this._cookie = cookie;
},
}
_setWorking(working) {
Tweener.removeTweens(this._workSpinner.actor);
if (working) {
if (working)
this._workSpinner.play();
Tweener.addTween(this._workSpinner.actor,
{ opacity: 255,
delay: WORK_SPINNER_ANIMATION_DELAY,
time: WORK_SPINNER_ANIMATION_TIME,
transition: 'linear'
});
} else {
Tweener.addTween(this._workSpinner.actor,
{ opacity: 0,
time: WORK_SPINNER_ANIMATION_TIME,
transition: 'linear',
onCompleteScope: this,
onComplete() {
if (this._workSpinner)
this._workSpinner.stop();
}
});
}
},
else
this._workSpinner.stop();
}
performAuthentication() {
this.destroySession();
this._destroySession();
this._session = new PolkitAgent.Session({ identity: this._identityToAuth,
cookie: this._cookie });
this._session.connect('completed', this._onSessionCompleted.bind(this));
this._session.connect('request', this._onSessionRequest.bind(this));
this._session.connect('show-error', this._onSessionShowError.bind(this));
this._session.connect('show-info', this._onSessionShowInfo.bind(this));
this._sessionCompletedId = this._session.connect('completed', this._onSessionCompleted.bind(this));
this._sessionRequestId = this._session.connect('request', this._onSessionRequest.bind(this));
this._sessionShowErrorId = this._session.connect('show-error', this._onSessionShowError.bind(this));
this._sessionShowInfoId = this._session.connect('show-info', this._onSessionShowInfo.bind(this));
this._session.initiate();
},
close(timestamp) {
this.parent(timestamp);
if (this._sessionUpdatedId)
Main.sessionMode.disconnect(this._sessionUpdatedId);
this._sessionUpdatedId = 0;
},
}
_ensureOpen() {
// NOTE: ModalDialog.open() is safe to call if the dialog is
@ -226,14 +194,14 @@ var AuthenticationDialog = new Lang.Class({
' cookie ' + this._cookie);
this._emitDone(true);
}
},
}
_emitDone(dismissed) {
if (!this._doneEmitted) {
this._doneEmitted = true;
this.emit('done', dismissed);
}
},
}
_updateSensitivity(sensitive) {
this._passwordEntry.reactive = sensitive;
@ -242,7 +210,7 @@ var AuthenticationDialog = new Lang.Class({
this._okButton.can_focus = sensitive;
this._okButton.reactive = sensitive;
this._setWorking(!sensitive);
},
}
_onEntryActivate() {
let response = this._passwordEntry.get_text();
@ -253,11 +221,11 @@ var AuthenticationDialog = new Lang.Class({
this._errorMessageLabel.hide();
this._infoMessageLabel.hide();
this._nullMessageLabel.show();
},
}
_onAuthenticateButtonPressed() {
this._onEntryActivate();
},
}
_onSessionCompleted(session, gainedAuthorization) {
if (this._completed || this._doneEmitted)
@ -289,7 +257,7 @@ var AuthenticationDialog = new Lang.Class({
/* Try and authenticate again */
this.performAuthentication();
}
},
}
_onSessionRequest(session, request, echo_on) {
// Cheap localization trick
@ -308,7 +276,7 @@ var AuthenticationDialog = new Lang.Class({
this._passwordEntry.grab_key_focus();
this._updateSensitivity(true);
this._ensureOpen();
},
}
_onSessionShowError(session, text) {
this._passwordEntry.set_text('');
@ -317,7 +285,7 @@ var AuthenticationDialog = new Lang.Class({
this._infoMessageLabel.hide();
this._nullMessageLabel.hide();
this._ensureOpen();
},
}
_onSessionShowInfo(session, text) {
this._passwordEntry.set_text('');
@ -326,43 +294,60 @@ var AuthenticationDialog = new Lang.Class({
this._errorMessageLabel.hide();
this._nullMessageLabel.hide();
this._ensureOpen();
},
}
destroySession() {
_destroySession() {
if (this._session) {
if (!this._completed)
this._session.cancel();
this._completed = false;
this._session.disconnect(this._sessionCompletedId);
this._session.disconnect(this._sessionRequestId);
this._session.disconnect(this._sessionShowErrorId);
this._session.disconnect(this._sessionShowInfoId);
this._session = null;
}
},
}
_onUserChanged() {
if (this._user.is_loaded && this._userAvatar) {
this._userAvatar.update();
this._userAvatar.actor.show();
}
},
}
cancel() {
this._wasDismissed = true;
this.close(global.get_current_time());
this._emitDone(true);
},
});
}
_onDialogClosed() {
if (this._sessionUpdatedId)
Main.sessionMode.disconnect(this._sessionUpdatedId);
this._sessionUpdatedId = 0;
if (this._user) {
this._user.disconnect(this._userLoadedId);
this._user.disconnect(this._userChangedId);
this._user = null;
}
this._destroySession();
}
};
Signals.addSignalMethods(AuthenticationDialog.prototype);
var AuthenticationAgent = new Lang.Class({
Name: 'AuthenticationAgent',
_init() {
var AuthenticationAgent = class {
constructor() {
this._currentDialog = null;
this._handle = null;
this._native = new Shell.PolkitAuthenticationAgent();
this._native.connect('initiate', this._onInitiate.bind(this));
this._native.connect('cancel', this._onCancel.bind(this));
this._sessionUpdatedId = 0;
},
}
enable() {
try {
@ -370,7 +355,7 @@ var AuthenticationAgent = new Lang.Class({
} catch(e) {
log('Failed to register AuthenticationAgent');
}
},
}
disable() {
try {
@ -378,7 +363,7 @@ var AuthenticationAgent = new Lang.Class({
} catch(e) {
log('Failed to unregister AuthenticationAgent');
}
},
}
_onInitiate(nativeAgent, actionId, message, iconName, cookie, userNames) {
// Don't pop up a dialog while locked
@ -406,19 +391,18 @@ var AuthenticationAgent = new Lang.Class({
this._currentDialog.connect('done', this._onDialogDone.bind(this));
this._currentDialog.performAuthentication();
},
}
_onCancel(nativeAgent) {
this._completeRequest(false);
},
}
_onDialogDone(dialog, dismissed) {
this._completeRequest(dismissed);
},
}
_completeRequest(dismissed) {
this._currentDialog.close();
this._currentDialog.destroySession();
this._currentDialog = null;
if (this._sessionUpdatedId)
@ -426,7 +410,7 @@ var AuthenticationAgent = new Lang.Class({
this._sessionUpdatedId = 0;
this._native.complete(dismissed);
},
});
}
};
var Component = AuthenticationAgent;

View File

@ -3,6 +3,7 @@
const Clutter = imports.gi.Clutter;
const Gio = imports.gi.Gio;
const GLib = imports.gi.GLib;
const GObject = imports.gi.GObject;
const Gtk = imports.gi.Gtk;
const Lang = imports.lang;
const Mainloop = imports.mainloop;
@ -79,17 +80,15 @@ function makeMessageFromTplEvent(event) {
};
}
var TelepathyComponent = new Lang.Class({
Name: 'TelepathyComponent',
_init() {
var TelepathyComponent = class {
constructor() {
this._client = null;
if (!HAVE_TP)
return; // Telepathy isn't available
this._client = new TelepathyClient();
},
}
enable() {
if (!this._client)
@ -103,7 +102,7 @@ var TelepathyComponent = new Lang.Class({
if (!this._client.account_manager.is_prepared(Tp.AccountManager.get_feature_quark_core()))
this._client.account_manager.prepare_async(null, null);
},
}
disable() {
if (!this._client)
@ -111,12 +110,10 @@ var TelepathyComponent = new Lang.Class({
this._client.unregister();
}
});
var TelepathyClient = HAVE_TP ? new Lang.Class({
Name: 'TelepathyClient',
Extends: Tp.BaseClient,
};
var TelepathyClient = HAVE_TP ? GObject.registerClass(
class TelepathyClient extends Tp.BaseClient {
_init() {
// channel path -> ChatSource
this._chatSources = {};
@ -140,7 +137,7 @@ var TelepathyClient = HAVE_TP ? new Lang.Class({
// channel matching its filters is detected.
// The second argument, recover, means _observeChannels will be run
// for any existing channel as well.
this.parent({ name: 'GnomeShell',
super._init({ name: 'GnomeShell',
account_manager: this._accountManager,
uniquify_name: true });
@ -158,7 +155,7 @@ var TelepathyClient = HAVE_TP ? new Lang.Class({
// needed
this.set_delegated_channels_callback(
this._delegatedChannelsCb.bind(this));
},
}
vfunc_observe_channels(account, conn, channels,
dispatchOp, requests, context) {
@ -179,7 +176,7 @@ var TelepathyClient = HAVE_TP ? new Lang.Class({
}
context.accept();
},
}
_createChatSource(account, conn, channel, contact) {
if (this._chatSources[channel.get_object_path()])
@ -191,13 +188,13 @@ var TelepathyClient = HAVE_TP ? new Lang.Class({
source.connect('destroy', () => {
delete this._chatSources[channel.get_object_path()];
});
},
}
vfunc_handle_channels(account, conn, channels, requests,
user_action_time, context) {
this._handlingChannels(account, conn, channels, true);
context.accept();
},
}
_handlingChannels(account, conn, channels, notify) {
let len = channels.length;
@ -231,7 +228,7 @@ var TelepathyClient = HAVE_TP ? new Lang.Class({
source.notify();
}
}
},
}
vfunc_add_dispatch_operation(account, conn, channels,
dispatchOp, context) {
@ -249,7 +246,7 @@ var TelepathyClient = HAVE_TP ? new Lang.Class({
else
context.fail(new Tp.Error({ code: Tp.Error.INVALID_ARGUMENT,
message: 'Unsupported channel type' }));
},
}
_approveTextChannel(account, conn, channel, dispatchOp, context) {
let [targetHandle, targetHandleType] = channel.get_handle();
@ -271,25 +268,22 @@ var TelepathyClient = HAVE_TP ? new Lang.Class({
});
context.accept();
},
}
_delegatedChannelsCb(client, channels) {
// Nothing to do as we don't make a distinction between observed and
// handled channels.
},
}
}) : null;
var ChatSource = new Lang.Class({
Name: 'ChatSource',
Extends: MessageTray.Source,
var ChatSource = class extends MessageTray.Source {
constructor(account, conn, channel, contact, client) {
super(contact.get_alias());
_init(account, conn, channel, contact, client) {
this._account = account;
this._contact = contact;
this._client = client;
this.parent(contact.get_alias());
this.isChat = true;
this._pendingMessages = [];
@ -313,7 +307,7 @@ var ChatSource = new Lang.Class({
Main.messageTray.add(this);
this._getLogMessages();
},
}
_ensureNotification() {
if (this._notification)
@ -329,13 +323,13 @@ var ChatSource = new Lang.Class({
this._notification = null;
});
this.pushNotification(this._notification);
},
}
_createPolicy() {
if (this._account.protocol_name == 'irc')
return new MessageTray.NotificationApplicationPolicy('org.gnome.Polari');
return new MessageTray.NotificationApplicationPolicy('empathy');
},
}
createBanner() {
this._banner = new ChatNotificationBanner(this._notification);
@ -348,7 +342,7 @@ var ChatSource = new Lang.Class({
});
return this._banner;
},
}
_updateAlias() {
let oldAlias = this.title;
@ -360,7 +354,7 @@ var ChatSource = new Lang.Class({
this.setTitle(newAlias);
if (this._notification)
this._notification.appendAliasChange(oldAlias, newAlias);
},
}
getIcon() {
let file = this._contact.get_avatar_file();
@ -369,7 +363,7 @@ var ChatSource = new Lang.Class({
} else {
return new Gio.ThemedIcon({ name: 'avatar-default' });
}
},
}
getSecondaryIcon() {
let iconName;
@ -398,7 +392,7 @@ var ChatSource = new Lang.Class({
iconName = 'user-offline';
}
return new Gio.ThemedIcon({ name: iconName });
},
}
_updateAvatarIcon() {
this.iconUpdated();
@ -406,7 +400,7 @@ var ChatSource = new Lang.Class({
this._notification.update(this._notification.title,
this._notification.bannerBodyText,
{ gicon: this.getIcon() });
},
}
open() {
Main.overview.hide();
@ -431,7 +425,7 @@ var ChatSource = new Lang.Class({
cd.present_channel_async(this._channel, global.get_current_time(), null);
}
},
}
_getLogMessages() {
let logManager = Tpl.LogManager.dup_singleton();
@ -440,7 +434,7 @@ var ChatSource = new Lang.Class({
logManager.get_filtered_events_async(this._account, entity,
Tpl.EventTypeMask.TEXT, SCROLLBACK_HISTORY_LINES,
null, this._displayPendingMessages.bind(this));
},
}
_displayPendingMessages(logManager, result) {
let [success, events] = logManager.get_filtered_events_finish(result);
@ -493,7 +487,7 @@ var ChatSource = new Lang.Class({
if (pendingMessages.length > 0)
this.notify();
},
}
destroy(reason) {
if (this._client.is_handling_channel(this._channel)) {
@ -527,25 +521,25 @@ var ChatSource = new Lang.Class({
this._contact.disconnect(this._notifyAvatarId);
this._contact.disconnect(this._presenceChangedId);
this.parent(reason);
},
super.destroy(reason);
}
_channelClosed() {
this.destroy(MessageTray.NotificationDestroyedReason.SOURCE_CLOSED);
},
}
/* All messages are new messages for Telepathy sources */
get count() {
return this._pendingMessages.length;
},
}
get unseenCount() {
return this.count;
},
}
get countVisible() {
return this.count > 0;
},
}
_messageReceived(channel, message) {
if (message.get_message_type() == Tp.ChannelTextMessageType.DELIVERY_REPORT)
@ -565,7 +559,7 @@ var ChatSource = new Lang.Class({
this._notifyTimeoutId = Mainloop.timeout_add(500,
this._notifyTimeout.bind(this));
GLib.Source.set_name_by_id(this._notifyTimeoutId, '[gnome-shell] this._notifyTimeout');
},
}
_notifyTimeout() {
if (this._pendingMessages.length != 0)
@ -574,7 +568,7 @@ var ChatSource = new Lang.Class({
this._notifyTimeoutId = 0;
return GLib.SOURCE_REMOVE;
},
}
// This is called for both messages we send from
// our client and other clients as well.
@ -582,11 +576,11 @@ var ChatSource = new Lang.Class({
this._ensureNotification();
message = makeMessageFromTpMessage(message, NotificationDirection.SENT);
this._notification.appendMessage(message);
},
}
notify() {
this.parent(this._notification);
},
super.notify(this._notification);
}
respond(text) {
let type;
@ -601,7 +595,7 @@ var ChatSource = new Lang.Class({
this._channel.send_message_async(msg, 0, (src, result) => {
this._channel.send_message_finish(result);
});
},
}
setChatState(state) {
// We don't want to send COMPOSING every time a letter is typed into
@ -614,14 +608,14 @@ var ChatSource = new Lang.Class({
this._chatState = state;
this._channel.set_chat_state_async(state, null);
}
},
}
_presenceChanged(contact, presence, status, message) {
if (this._notification)
this._notification.update(this._notification.title,
this._notification.bannerBodyText,
{ secondaryGIcon: this.getSecondaryIcon() });
},
}
_pendingRemoved(channel, message) {
let idx = this._pendingMessages.indexOf(message);
@ -634,35 +628,32 @@ var ChatSource = new Lang.Class({
if (this._pendingMessages.length == 0 &&
this._banner && !this._banner.expanded)
this._banner.hide();
},
}
_ackMessages() {
// Don't clear our messages here, tp-glib will send a
// 'pending-message-removed' for each one.
this._channel.ack_all_pending_messages_async(null);
}
});
};
var ChatNotification = new Lang.Class({
Name: 'ChatNotification',
Extends: MessageTray.Notification,
_init(source) {
this.parent(source, source.title, null,
{ secondaryGIcon: source.getSecondaryIcon() });
var ChatNotification = class extends MessageTray.Notification {
constructor(source) {
super(source, source.title, null,
{ secondaryGIcon: source.getSecondaryIcon() });
this.setUrgency(MessageTray.Urgency.HIGH);
this.setResident(true);
this.messages = [];
this._timestampTimeoutId = 0;
},
}
destroy(reason) {
if (this._timestampTimeoutId)
Mainloop.source_remove(this._timestampTimeoutId);
this._timestampTimeoutId = 0;
this.parent(reason);
},
super.destroy(reason);
}
/**
* appendMessage:
@ -700,7 +691,7 @@ var ChatNotification = new Lang.Class({
styles: styles,
timestamp: message.timestamp,
noTimestamp: noTimestamp });
},
}
_filterMessages() {
if (this.messages.length < 1)
@ -725,7 +716,7 @@ var ChatNotification = new Lang.Class({
for (let i = 0; i < expired.length; i++)
this.emit('message-removed', expired[i]);
}
},
}
/**
* _append:
@ -773,7 +764,7 @@ var ChatNotification = new Lang.Class({
}
this._filterMessages();
},
}
appendTimestamp() {
this._timestampTimeoutId = 0;
@ -784,7 +775,7 @@ var ChatNotification = new Lang.Class({
this._filterMessages();
return GLib.SOURCE_REMOVE;
},
}
appendAliasChange(oldAlias, newAlias) {
oldAlias = GLib.markup_escape_text(oldAlias, -1);
@ -800,24 +791,19 @@ var ChatNotification = new Lang.Class({
this._filterMessages();
}
});
var ChatLineBox = new Lang.Class({
Name: 'ChatLineBox',
Extends: St.BoxLayout,
};
var ChatLineBox = GObject.registerClass(
class ChatLineBox extends St.BoxLayout {
vfunc_get_preferred_height(forWidth) {
let [, natHeight] = this.parent(forWidth);
let [, natHeight] = super.vfunc_get_preferred_height(forWidth);
return [natHeight, natHeight];
}
});
var ChatNotificationBanner = new Lang.Class({
Name: 'ChatNotificationBanner',
Extends: MessageTray.NotificationBanner,
_init(notification) {
this.parent(notification);
var ChatNotificationBanner = class extends MessageTray.NotificationBanner {
constructor(notification) {
super(notification);
this._responseEntry = new St.Entry({ style_class: 'chat-response',
x_expand: true,
@ -880,14 +866,14 @@ var ChatNotificationBanner = new Lang.Class({
for (let i = this.notification.messages.length - 1; i >= 0; i--)
this._addMessage(this.notification.messages[i]);
},
}
_onDestroy() {
this.parent();
super._onDestroy();
this.notification.disconnect(this._messageAddedId);
this.notification.disconnect(this._messageRemovedId);
this.notification.disconnect(this._timestampChangedId);
},
}
scrollTo(side) {
let adjustment = this._scrollArea.vscroll.adjustment;
@ -895,11 +881,11 @@ var ChatNotificationBanner = new Lang.Class({
adjustment.value = adjustment.lower;
else if (side == St.Side.BOTTOM)
adjustment.value = adjustment.upper;
},
}
hide() {
this.emit('done-displaying');
},
}
_addMessage(message) {
let highlighter = new MessageList.URLHighlighter(message.body, true, true);
@ -921,7 +907,7 @@ var ChatNotificationBanner = new Lang.Class({
this._messageActors.set(message, lineBox);
this._updateTimestamp(message);
},
}
_updateTimestamp(message) {
let actor = this._messageActors.get(message);
@ -942,7 +928,7 @@ var ChatNotificationBanner = new Lang.Class({
actor.add_actor(timeLabel);
}
},
}
_onEntryActivated() {
let text = this._responseEntry.get_text();
@ -955,7 +941,7 @@ var ChatNotificationBanner = new Lang.Class({
// see Source._messageSent
this._responseEntry.set_text('');
this.notification.source.respond(text);
},
}
_composingStopTimeout() {
this._composingTimeoutId = 0;
@ -963,7 +949,7 @@ var ChatNotificationBanner = new Lang.Class({
this.notification.source.setChatState(Tp.ChannelChatState.PAUSED);
return GLib.SOURCE_REMOVE;
},
}
_onEntryChanged() {
let text = this._responseEntry.get_text();
@ -990,6 +976,6 @@ var ChatNotificationBanner = new Lang.Class({
this.notification.source.setChatState(Tp.ChannelChatState.ACTIVE);
}
}
});
};
var Component = TelepathyComponent;

View File

@ -2,7 +2,6 @@
const Clutter = imports.gi.Clutter;
const Gtk = imports.gi.Gtk;
const Lang = imports.lang;
const Meta = imports.gi.Meta;
const Shell = imports.gi.Shell;
const St = imports.gi.St;
@ -21,15 +20,13 @@ var SortGroup = {
BOTTOM: 2
};
var CtrlAltTabManager = new Lang.Class({
Name: 'CtrlAltTabManager',
_init() {
var CtrlAltTabManager = class CtrlAltTabManager {
constructor() {
this._items = [];
this.addGroup(global.window_group, _("Windows"),
'focus-windows-symbolic', { sortGroup: SortGroup.TOP,
focusCallback: this._focusWindows.bind(this) });
},
}
addGroup(root, name, icon, params) {
let item = Params.parse(params, { sortGroup: SortGroup.MIDDLE,
@ -44,7 +41,7 @@ var CtrlAltTabManager = new Lang.Class({
root.connect('destroy', () => { this.removeGroup(root); });
if (root instanceof St.Widget)
global.focus_manager.add_group(root);
},
}
removeGroup(root) {
if (root instanceof St.Widget)
@ -55,14 +52,14 @@ var CtrlAltTabManager = new Lang.Class({
return;
}
}
},
}
focusGroup(item, timestamp) {
if (item.focusCallback)
item.focusCallback(timestamp);
else
item.root.navigate_focus(null, Gtk.DirectionType.TAB_FORWARD, false);
},
}
// Sort the items into a consistent order; panel first, tray last,
// and everything else in between, sorted by X coordinate, so that
@ -77,7 +74,7 @@ var CtrlAltTabManager = new Lang.Class({
[bx, y] = b.proxy.get_transformed_position();
return ax - bx;
},
}
popup(backward, binding, mask) {
// Start with the set of focus groups that are currently mapped
@ -125,27 +122,25 @@ var CtrlAltTabManager = new Lang.Class({
this._popup = new CtrlAltTabPopup(items);
this._popup.show(backward, binding, mask);
this._popup.actor.connect('destroy',
() => {
this._popup = null;
});
this._popup.connect('destroy',
() => {
this._popup = null;
});
}
},
}
_focusWindows(timestamp) {
global.display.focus_default_window(timestamp);
}
});
};
var CtrlAltTabPopup = new Lang.Class({
Name: 'CtrlAltTabPopup',
Extends: SwitcherPopup.SwitcherPopup,
_init(items) {
this.parent(items);
var CtrlAltTabPopup =
class CtrlAltTabPopup extends SwitcherPopup.SwitcherPopup {
constructor(items) {
super(items);
this._switcherList = new CtrlAltTabSwitcher(this._items);
},
}
_keyPressHandler(keysym, action) {
if (action == Meta.KeyBindingAction.SWITCH_PANELS)
@ -160,24 +155,22 @@ var CtrlAltTabPopup = new Lang.Class({
return Clutter.EVENT_PROPAGATE;
return Clutter.EVENT_STOP;
},
}
_finish(time) {
this.parent(time);
super._finish(time);
Main.ctrlAltTabManager.focusGroup(this._items[this._selectedIndex], time);
},
});
}
};
var CtrlAltTabSwitcher = new Lang.Class({
Name: 'CtrlAltTabSwitcher',
Extends: SwitcherPopup.SwitcherList,
_init(items) {
this.parent(true);
var CtrlAltTabSwitcher =
class CtrlAltTabSwitcher extends SwitcherPopup.SwitcherList {
constructor(items) {
super(true);
for (let i = 0; i < items.length; i++)
this._addIcon(items[i]);
},
}
_addIcon(item) {
let box = new St.BoxLayout({ style_class: 'alt-tab-app',
@ -195,4 +188,4 @@ var CtrlAltTabSwitcher = new Lang.Class({
this.addItem(box, text);
}
});
};

View File

@ -3,8 +3,8 @@
const Clutter = imports.gi.Clutter;
const Gio = imports.gi.Gio;
const GLib = imports.gi.GLib;
const GObject = imports.gi.GObject;
const Signals = imports.signals;
const Lang = imports.lang;
const Meta = imports.gi.Meta;
const Shell = imports.gi.Shell;
const St = imports.gi.St;
@ -33,12 +33,13 @@ function getAppFromSource(source) {
// A container like StBin, but taking the child's scale into account
// when requesting a size
var DashItemContainer = new Lang.Class({
Name: 'DashItemContainer',
Extends: St.Widget,
var DashItemContainer = GObject.registerClass(
class DashItemContainer extends St.Widget {
_init() {
this.parent({ style_class: 'dash-item-container' });
super._init({ style_class: 'dash-item-container',
pivot_point: new Clutter.Point({ x: .5, y: .5 }),
x_expand: true,
x_align: Clutter.ActorAlign.CENTER });
this._labelText = "";
this.label = new St.Label({ style_class: 'dash-label'});
@ -52,57 +53,27 @@ var DashItemContainer = new Lang.Class({
this.animatingOut = false;
this.connect('destroy', () => {
if (this.child != null)
this.child.destroy();
this.label.destroy();
});
},
vfunc_allocate(box, flags) {
this.set_allocation(box, flags);
if (this.child == null)
return;
let availWidth = box.x2 - box.x1;
let availHeight = box.y2 - box.y1;
let [minChildWidth, minChildHeight, natChildWidth, natChildHeight] =
this.child.get_preferred_size();
let [childScaleX, childScaleY] = this.child.get_scale();
let childWidth = Math.min(natChildWidth * childScaleX, availWidth);
let childHeight = Math.min(natChildHeight * childScaleY, availHeight);
let childBox = new Clutter.ActorBox();
childBox.x1 = (availWidth - childWidth) / 2;
childBox.y1 = (availHeight - childHeight) / 2;
childBox.x2 = childBox.x1 + childWidth;
childBox.y2 = childBox.y1 + childHeight;
this.child.allocate(childBox, flags);
},
}
vfunc_get_preferred_height(forWidth) {
let themeNode = this.get_theme_node();
if (this.child == null)
return [0, 0];
forWidth = themeNode.adjust_for_width(forWidth);
let [minHeight, natHeight] = this.child.get_preferred_height(forWidth);
return themeNode.adjust_preferred_height(minHeight * this.child.scale_y,
natHeight * this.child.scale_y);
},
let [minHeight, natHeight] = super.vfunc_get_preferred_height(forWidth);
return themeNode.adjust_preferred_height(minHeight * this.scale_y,
natHeight * this.scale_y);
}
vfunc_get_preferred_width(forHeight) {
let themeNode = this.get_theme_node();
if (this.child == null)
return [0, 0];
forHeight = themeNode.adjust_for_height(forHeight);
let [minWidth, natWidth] = this.child.get_preferred_width(forHeight);
return themeNode.adjust_preferred_width(minWidth * this.child.scale_y,
natWidth * this.child.scale_y);
},
let [minWidth, natWidth] = super.vfunc_get_preferred_width(forHeight);
return themeNode.adjust_preferred_width(minWidth * this.scale_x,
natWidth * this.scale_x);
}
showLabel() {
if (!this._labelText)
@ -136,12 +107,12 @@ var DashItemContainer = new Lang.Class({
time: DASH_ITEM_LABEL_SHOW_TIME,
transition: 'easeOutQuad',
});
},
}
setLabelText(text) {
this._labelText = text;
this.child.accessible_name = text;
},
}
hideLabel() {
Tweener.addTween(this.label,
@ -152,7 +123,7 @@ var DashItemContainer = new Lang.Class({
this.label.hide();
}
});
},
}
setChild(actor) {
if (this.child == actor)
@ -163,10 +134,9 @@ var DashItemContainer = new Lang.Class({
this.child = actor;
this.add_actor(this.child);
this.child.set_scale_with_gravity(this._childScale, this._childScale,
Clutter.Gravity.CENTER);
this.child.set_opacity(this._childOpacity);
},
this.set_scale(this._childScale, this._childScale);
this.set_opacity(this._childOpacity);
}
show(animate) {
if (this.child == null)
@ -179,7 +149,7 @@ var DashItemContainer = new Lang.Class({
time: time,
transition: 'easeOutQuad'
});
},
}
animateOutAndDestroy() {
this.label.hide();
@ -199,44 +169,35 @@ var DashItemContainer = new Lang.Class({
this.destroy();
}
});
},
}
set childScale(scale) {
this._childScale = scale;
if (this.child == null)
return;
this.child.set_scale_with_gravity(scale, scale,
Clutter.Gravity.CENTER);
this.set_scale(scale, scale);
this.queue_relayout();
},
}
get childScale() {
return this._childScale;
},
}
set childOpacity(opacity) {
this._childOpacity = opacity;
if (this.child == null)
return;
this.child.set_opacity(opacity);
this.set_opacity(opacity);
this.queue_redraw();
},
}
get childOpacity() {
return this._childOpacity;
}
});
var ShowAppsIcon = new Lang.Class({
Name: 'ShowAppsIcon',
Extends: DashItemContainer,
var ShowAppsIcon = GObject.registerClass(
class ShowAppsIcon extends DashItemContainer {
_init() {
this.parent();
super._init();
this.toggleButton = new St.Button({ style_class: 'show-apps',
track_hover: true,
@ -247,12 +208,12 @@ var ShowAppsIcon = new Lang.Class({
{ setSizeManually: true,
showLabel: false,
createIcon: this._createIcon.bind(this) });
this.toggleButton.add_actor(this.icon.actor);
this.toggleButton.add_actor(this.icon);
this.toggleButton._delegate = this;
this.setChild(this.toggleButton);
this.setDragApp(null);
},
}
_createIcon(size) {
this._iconActor = new St.Icon({ icon_name: 'view-app-grid-symbolic',
@ -260,7 +221,7 @@ var ShowAppsIcon = new Lang.Class({
style_class: 'show-apps-icon',
track_hover: true });
return this._iconActor;
},
}
_canRemoveApp(app) {
if (app == null)
@ -272,7 +233,7 @@ var ShowAppsIcon = new Lang.Class({
let id = app.get_id();
let isFavorite = AppFavorites.getAppFavorites().isFavorite(id);
return isFavorite;
},
}
setDragApp(app) {
let canRemove = this._canRemoveApp(app);
@ -285,14 +246,14 @@ var ShowAppsIcon = new Lang.Class({
this.setLabelText(_("Remove from Favorites"));
else
this.setLabelText(_("Show Applications"));
},
}
handleDragOver(source, actor, x, y, time) {
if (!this._canRemoveApp(getAppFromSource(source)))
return DND.DragMotionResult.NO_DROP;
return DND.DragMotionResult.MOVE_DROP;
},
}
acceptDrop(source, actor, x, y, time) {
let app = getAppFromSource(source);
@ -310,36 +271,30 @@ var ShowAppsIcon = new Lang.Class({
}
});
var DragPlaceholderItem = new Lang.Class({
Name: 'DragPlaceholderItem',
Extends: DashItemContainer,
var DragPlaceholderItem = GObject.registerClass(
class DragPlaceholderItem extends DashItemContainer {
_init() {
this.parent();
super._init();
this.setChild(new St.Bin({ style_class: 'placeholder' }));
}
});
var EmptyDropTargetItem = new Lang.Class({
Name: 'EmptyDropTargetItem',
Extends: DashItemContainer,
var EmptyDropTargetItem = GObject.registerClass(
class EmptyDropTargetItem extends DashItemContainer {
_init() {
this.parent();
super._init();
this.setChild(new St.Bin({ style_class: 'empty-dash-drop-target' }));
}
});
var DashActor = new Lang.Class({
Name: 'DashActor',
Extends: St.Widget,
var DashActor = GObject.registerClass(
class DashActor extends St.Widget {
_init() {
let layout = new Clutter.BoxLayout({ orientation: Clutter.Orientation.VERTICAL });
this.parent({ name: 'dash',
super._init({ name: 'dash',
layout_manager: layout,
clip_to_allocation: true });
},
}
vfunc_allocate(box, flags) {
let contentBox = this.get_theme_node().get_content_box(box);
@ -360,7 +315,7 @@ var DashActor = new Lang.Class({
childBox.y1 = contentBox.y2 - showAppsNatHeight;
childBox.y2 = contentBox.y2;
showAppsButton.allocate(childBox, flags);
},
}
vfunc_get_preferred_height(forWidth) {
// We want to request the natural height of all our children
@ -368,7 +323,7 @@ var DashActor = new Lang.Class({
// then calls BoxLayout), but we only request the showApps
// button as the minimum size
let [, natHeight] = this.parent(forWidth);
let [, natHeight] = super.vfunc_get_preferred_height(forWidth);
let themeNode = this.get_theme_node();
let adjustedForWidth = themeNode.adjust_for_width(forWidth);
@ -382,10 +337,8 @@ var DashActor = new Lang.Class({
const baseIconSizes = [ 16, 22, 24, 32, 48, 64 ];
var Dash = new Lang.Class({
Name: 'Dash',
_init() {
var Dash = class Dash {
constructor() {
this._maxHeight = -1;
this.iconSize = 64;
this._shownInitially = false;
@ -442,7 +395,7 @@ var Dash = new Lang.Class({
// Translators: this is the name of the dock/favorites area on
// the left of the overview
Main.ctrlAltTabManager.addGroup(this.actor, _("Dash"), 'user-bookmarks-symbolic');
},
}
_onDragBegin() {
this._dragCancelled = false;
@ -456,26 +409,26 @@ var Dash = new Lang.Class({
this._box.insert_child_at_index(this._emptyDropTarget, 0);
this._emptyDropTarget.show(true);
}
},
}
_onDragCancelled() {
this._dragCancelled = true;
this._endDrag();
},
}
_onDragEnd() {
if (this._dragCancelled)
return;
this._endDrag();
},
}
_endDrag() {
this._clearDragPlaceholder();
this._clearEmptyDropTarget();
this._showAppsIcon.setDragApp(null);
DND.removeDragMonitor(this._dragMonitor);
},
}
_onDragMotion(dragEvent) {
let app = getAppFromSource(dragEvent.source);
@ -494,18 +447,18 @@ var Dash = new Lang.Class({
this._showAppsIcon.setDragApp(null);
return DND.DragMotionResult.CONTINUE;
},
}
_appIdListToHash(apps) {
let ids = {};
for (let i = 0; i < apps.length; i++)
ids[apps[i].get_id()] = apps[i];
return ids;
},
}
_queueRedisplay() {
Main.queueDeferredWork(this._workId);
},
}
_hookUpLabel(item, appIcon) {
item.child.connect('notify::hover', () => {
@ -525,7 +478,7 @@ var Dash = new Lang.Class({
this._syncLabel(item, appIcon);
});
}
},
}
_createAppItem(app) {
let appIcon = new AppDisplay.AppIcon(app,
@ -559,7 +512,7 @@ var Dash = new Lang.Class({
this._hookUpLabel(item, appIcon);
return item;
},
}
_itemMenuStateChanged(item, opened) {
// When the menu closes, it calls sync_hover, which means
@ -572,7 +525,7 @@ var Dash = new Lang.Class({
item.hideLabel();
}
},
}
_syncLabel(item, appIcon) {
let shouldShow = appIcon ? appIcon.shouldShowTooltip() : item.child.get_hover();
@ -608,7 +561,7 @@ var Dash = new Lang.Class({
GLib.Source.set_name_by_id(this._resetHoverTimeoutId, '[gnome-shell] this._labelShowing');
}
}
},
}
_adjustIconSize() {
// For the icon size, we only consider children which are "proper"
@ -643,10 +596,10 @@ var Dash = new Lang.Class({
// Enforce the current icon size during the size request
firstIcon.icon.ensure_style();
let [currentWidth, currentHeight] = firstIcon.icon.get_size();
firstIcon.icon.set_size(this.iconSize * scaleFactor, this.iconSize * scaleFactor);
let [, currentHeight] = firstIcon.icon.get_size();
firstIcon.icon.set_height(this.iconSize * scaleFactor);
[minHeight, natHeight] = firstButton.get_preferred_height(-1);
firstIcon.icon.set_size(currentWidth, currentHeight);
firstIcon.icon.set_height(currentHeight);
// Subtract icon padding and box spacing from the available height
availHeight -= iconChildren.length * (natHeight - this.iconSize * scaleFactor) +
@ -698,7 +651,7 @@ var Dash = new Lang.Class({
transition: 'easeOutQuad',
});
}
},
}
_redisplay() {
let favorites = AppFavorites.getAppFavorites().getFavoriteMap();
@ -827,7 +780,7 @@ var Dash = new Lang.Class({
// Workaround for https://bugzilla.gnome.org/show_bug.cgi?id=692744
// Without it, StBoxLayout may use a stale size cache
this._box.queue_relayout();
},
}
_clearDragPlaceholder() {
if (this._dragPlaceholder) {
@ -839,14 +792,14 @@ var Dash = new Lang.Class({
this._dragPlaceholder = null;
}
this._dragPlaceholderPos = -1;
},
}
_clearEmptyDropTarget() {
if (this._emptyDropTarget) {
this._emptyDropTarget.animateOutAndDestroy();
this._emptyDropTarget = null;
}
},
}
handleDragOver(source, actor, x, y, time) {
let app = getAppFromSource(source);
@ -923,7 +876,7 @@ var Dash = new Lang.Class({
return DND.DragMotionResult.MOVE_DROP;
return DND.DragMotionResult.COPY_DROP;
},
}
// Draggable target interface
acceptDrop(source, actor, x, y, time) {
@ -973,6 +926,5 @@ var Dash = new Lang.Class({
return true;
}
});
};
Signals.addSignalMethods(Dash.prototype);

View File

@ -6,7 +6,6 @@ const GnomeDesktop = imports.gi.GnomeDesktop;
const GObject = imports.gi.GObject;
const Gtk = imports.gi.Gtk;
const GWeather = imports.gi.GWeather;
const Lang = imports.lang;
const Mainloop = imports.mainloop;
const Pango = imports.gi.Pango;
const Cairo = imports.cairo;
@ -31,10 +30,8 @@ function _isToday(date) {
now.getDate() == date.getDate();
}
var TodayButton = new Lang.Class({
Name: 'TodayButton',
_init(calendar) {
var TodayButton = class TodayButton {
constructor(calendar) {
// Having the ability to go to the current date if the user is already
// on the current date can be confusing. So don't make the button reactive
// until the selected date changes.
@ -63,15 +60,17 @@ var TodayButton = new Lang.Class({
// current date.
this.actor.reactive = !_isToday(date)
});
},
}
setDate(date) {
this._dayLabel.set_text(date.toLocaleFormat('%A'));
/* Translators: This is the date format to use when the calendar popup is
* shown - it is shown just below the time in the shell (e.g. "Tue 9:29 AM").
* shown - it is shown just below the time in the top bar (e.g.,
* "Tue 9:29 AM"). The string itself should become a full date, e.g.,
* "February 17 2015".
*/
let dateFormat = Shell.util_translate_time_string (N_("%B %e %Y"));
let dateFormat = Shell.util_translate_time_string (N_("%B %-d %Y"));
this._dateLabel.set_text(date.toLocaleFormat(dateFormat));
/* Translators: This is the accessible name of the date button shown
@ -81,12 +80,10 @@ var TodayButton = new Lang.Class({
dateFormat = Shell.util_translate_time_string (N_("%A %B %e %Y"));
this.actor.accessible_name = date.toLocaleFormat(dateFormat);
}
});
};
var WorldClocksSection = new Lang.Class({
Name: 'WorldClocksSection',
_init() {
var WorldClocksSection = class WorldClocksSection {
constructor() {
this._clock = new GnomeDesktop.WallClock();
this._clockNotifyId = 0;
@ -116,11 +113,11 @@ var WorldClocksSection = new Lang.Class({
this._clockAppMon.watchSetting('world-clocks',
this._clocksChanged.bind(this));
this._sync();
},
}
_sync() {
this.actor.visible = this._clockAppMon.available;
},
}
_clocksChanged(settings) {
this._grid.destroy_all_children();
@ -185,7 +182,7 @@ var WorldClocksSection = new Lang.Class({
this._clock.disconnect(this._clockNotifyId);
this._clockNotifyId = 0;
}
},
}
_updateLabels() {
for (let i = 0; i < this._locations.length; i++) {
@ -195,12 +192,10 @@ var WorldClocksSection = new Lang.Class({
l.actor.text = Util.formatTime(now, { timeOnly: true });
}
}
});
};
var WeatherSection = new Lang.Class({
Name: 'WeatherSection',
_init() {
var WeatherSection = class WeatherSection {
constructor() {
this._weatherClient = new Weather.WeatherClient();
this.actor = new St.Button({ style_class: 'weather-button',
@ -234,7 +229,7 @@ var WeatherSection = new Lang.Class({
this._weatherClient.connect('changed', this._sync.bind(this));
this._sync();
},
}
_getSummary(info, capitalize=false) {
let options = capitalize ? GWeather.FormatOptions.SENTENCE_CAPITALIZATION
@ -248,7 +243,7 @@ var WeatherSection = new Lang.Class({
let [, sky] = info.get_value_sky();
return GWeather.Sky.to_string_full(sky, options);
},
}
_sameSummary(info1, info2) {
let [ok1, phenom1, qualifier1] = info1.get_value_conditions();
@ -259,7 +254,7 @@ var WeatherSection = new Lang.Class({
let [, sky1] = info1.get_value_sky();
let [, sky2] = info2.get_value_sky();
return sky1 == sky2;
},
}
_getSummaryText() {
let info = this._weatherClient.info;
@ -307,7 +302,7 @@ var WeatherSection = new Lang.Class({
return this._getSummary(info, capitalize);
});
return String.prototype.format.apply(fmt, summaries);
},
}
_getLabelText() {
if (!this._weatherClient.hasLocation)
@ -326,7 +321,7 @@ var WeatherSection = new Lang.Class({
return _("Go online for weather information");
return _("Weather information is currently unavailable");
},
}
_sync() {
this.actor.visible = this._weatherClient.available;
@ -336,12 +331,10 @@ var WeatherSection = new Lang.Class({
this._conditionsLabel.text = this._getLabelText();
}
});
};
var MessagesIndicator = new Lang.Class({
Name: 'MessagesIndicator',
_init() {
var MessagesIndicator = class MessagesIndicator {
constructor() {
this.actor = new St.Icon({ icon_name: 'message-indicator-symbolic',
icon_size: 16,
visible: false, y_expand: true,
@ -355,18 +348,18 @@ var MessagesIndicator = new Lang.Class({
let sources = Main.messageTray.getSources();
sources.forEach(source => { this._onSourceAdded(null, source); });
},
}
_onSourceAdded(tray, source) {
source.connect('count-updated', this._updateCount.bind(this));
this._sources.push(source);
this._updateCount();
},
}
_onSourceRemoved(tray, source) {
this._sources.splice(this._sources.indexOf(source), 1);
this._updateCount();
},
}
_updateCount() {
let count = 0;
@ -375,23 +368,21 @@ var MessagesIndicator = new Lang.Class({
this.actor.visible = (count > 0);
}
});
var IndicatorPad = new Lang.Class({
Name: 'IndicatorPad',
Extends: St.Widget,
};
var IndicatorPad = GObject.registerClass(
class IndicatorPad extends St.Widget {
_init(actor) {
this._source = actor;
this._source.connect('notify::visible', () => { this.queue_relayout(); });
this.parent();
},
super._init();
}
vfunc_get_preferred_width(container, forHeight) {
if (this._source.visible)
return this._source.get_preferred_width(forHeight);
return [0, 0];
},
}
vfunc_get_preferred_height(container, forWidth) {
if (this._source.visible)
@ -400,17 +391,15 @@ var IndicatorPad = new Lang.Class({
}
});
var FreezableBinLayout = new Lang.Class({
Name: 'FreezableBinLayout',
Extends: Clutter.BinLayout,
var FreezableBinLayout = GObject.registerClass(
class FreezableBinLayout extends Clutter.BinLayout {
_init() {
this.parent();
super._init();
this._frozen = false;
this._savedWidth = [NaN, NaN];
this._savedHeight = [NaN, NaN];
},
}
set frozen(v) {
if (this._frozen == v)
@ -419,22 +408,22 @@ var FreezableBinLayout = new Lang.Class({
this._frozen = v;
if (!this._frozen)
this.layout_changed();
},
}
vfunc_get_preferred_width(container, forHeight) {
if (!this._frozen || this._savedWidth.some(isNaN))
return this.parent(container, forHeight);
return super.vfunc_get_preferred_width(container, forHeight);
return this._savedWidth;
},
}
vfunc_get_preferred_height(container, forWidth) {
if (!this._frozen || this._savedHeight.some(isNaN))
return this.parent(container, forWidth);
return super.vfunc_get_preferred_height(container, forWidth);
return this._savedHeight;
},
}
vfunc_allocate(container, allocation, flags) {
this.parent(container, allocation, flags);
super.vfunc_allocate(container, allocation, flags);
let [width, height] = allocation.get_size();
this._savedWidth = [width, width];
@ -442,26 +431,22 @@ var FreezableBinLayout = new Lang.Class({
}
});
var CalendarColumnLayout = new Lang.Class({
Name: 'CalendarColumnLayout',
Extends: Clutter.BoxLayout,
var CalendarColumnLayout = GObject.registerClass(
class CalendarColumnLayout extends Clutter.BoxLayout {
_init(actor) {
this.parent({ orientation: Clutter.Orientation.VERTICAL });
super._init({ orientation: Clutter.Orientation.VERTICAL });
this._calActor = actor;
},
}
vfunc_get_preferred_width(container, forHeight) {
if (!this._calActor || this._calActor.get_parent() != container)
return this.parent(container, forHeight);
return super.vfunc_get_preferred_width(container, forHeight);
return this._calActor.get_preferred_width(forHeight);
}
});
var DateMenuButton = new Lang.Class({
Name: 'DateMenuButton',
Extends: PanelMenu.Button,
var DateMenuButton = GObject.registerClass(
class DateMenuButton extends PanelMenu.Button {
_init() {
let item;
let hbox;
@ -470,7 +455,7 @@ var DateMenuButton = new Lang.Class({
let menuAlignment = 0.5;
if (Clutter.get_default_text_direction() == Clutter.TextDirection.RTL)
menuAlignment = 1.0 - menuAlignment;
this.parent(menuAlignment);
super._init(menuAlignment);
this._clockDisplay = new St.Label({ y_align: Clutter.ActorAlign.CENTER });
this._indicator = new MessagesIndicator();
@ -551,11 +536,11 @@ var DateMenuButton = new Lang.Class({
Main.sessionMode.connect('updated', this._sessionUpdated.bind(this));
this._sessionUpdated();
},
}
_getEventSource() {
return new Calendar.DBusEventSource();
},
}
_setEventSource(eventSource) {
if (this._eventSource)
@ -565,7 +550,7 @@ var DateMenuButton = new Lang.Class({
this._messageList.setEventSource(eventSource);
this._eventSource = eventSource;
},
}
_updateTimeZone() {
// SpiderMonkey caches the time zone so we must explicitly clear it
@ -574,7 +559,7 @@ var DateMenuButton = new Lang.Class({
System.clearDateCaches();
this._calendar.updateTimeZone();
},
}
_sessionUpdated() {
let eventSource;

View File

@ -5,14 +5,11 @@ const Gio = imports.gi.Gio;
const GObject = imports.gi.GObject;
const Pango = imports.gi.Pango;
const St = imports.gi.St;
const Lang = imports.lang;
var Dialog = new Lang.Class({
Name: 'Dialog',
Extends: St.Widget,
var Dialog = GObject.registerClass(
class Dialog extends St.Widget {
_init(parentActor, styleClass) {
this.parent({ layout_manager: new Clutter.BinLayout() });
super._init({ layout_manager: new Clutter.BinLayout() });
this.connect('destroy', this._onDestroy.bind(this));
this._initialKeyFocus = null;
@ -28,7 +25,7 @@ var Dialog = new Lang.Class({
this._parentActor = parentActor;
this._eventId = this._parentActor.connect('event', this._modalEventHandler.bind(this));
this._parentActor.add_child(this);
},
}
_createDialog() {
this._dialog = new St.BoxLayout({ style_class: 'modal-dialog',
@ -55,13 +52,13 @@ var Dialog = new Lang.Class({
this._dialog.add(this.buttonLayout,
{ x_align: St.Align.MIDDLE,
y_align: St.Align.START });
},
}
_onDestroy() {
if (this._eventId != 0)
this._parentActor.disconnect(this._eventId);
this._eventId = 0;
},
}
_modalEventHandler(actor, event) {
if (event.type() == Clutter.EventType.KEY_PRESS) {
@ -87,7 +84,7 @@ var Dialog = new Lang.Class({
}
return Clutter.EVENT_PROPAGATE;
},
}
_setInitialKeyFocus(actor) {
if (this._initialKeyFocus)
@ -99,15 +96,15 @@ var Dialog = new Lang.Class({
this._initialKeyFocus = null;
this._initialKeyFocusDestroyId = 0;
});
},
}
get initialKeyFocus() {
return this._initialKeyFocus || this;
},
}
addContent(actor) {
this.contentLayout.add (actor, { expand: true });
},
}
addButton(buttonInfo) {
let { label, action, key } = buttonInfo;
@ -144,17 +141,15 @@ var Dialog = new Lang.Class({
this.buttonLayout.add_actor(button);
return button;
},
}
clearButtons() {
this.buttonLayout.destroy_all_children();
this._buttonKeys = {};
},
}
});
var MessageDialogContent = new Lang.Class({
Name: 'MessageDialogContent',
Extends: St.BoxLayout,
var MessageDialogContent = GObject.registerClass({
Properties: {
'icon': GObject.ParamSpec.object('icon', 'icon', 'icon',
GObject.ParamFlags.READWRITE |
@ -172,8 +167,8 @@ var MessageDialogContent = new Lang.Class({
GObject.ParamFlags.READWRITE |
GObject.ParamFlags.CONSTRUCT,
null)
},
}
}, class MessageDialogContent extends St.BoxLayout {
_init(params) {
this._icon = new St.Icon({ y_align: Clutter.ActorAlign.START });
this._title = new St.Label({ style_class: 'headline' });
@ -192,7 +187,7 @@ var MessageDialogContent = new Lang.Class({
if (!params.hasOwnProperty('style_class'))
params.style_class = 'message-dialog-main-layout';
this.parent(params);
super._init(params);
this.messageBox = new St.BoxLayout({ style_class: 'message-dialog-content',
x_expand: true,
@ -204,45 +199,45 @@ var MessageDialogContent = new Lang.Class({
this.add_actor(this._icon);
this.add_actor(this.messageBox);
},
}
get icon() {
return this._icon.gicon;
},
}
get title() {
return this._title.text;
},
}
get subtitle() {
return this._subtitle.text;
},
}
get body() {
return this._body.text;
},
}
set icon(icon) {
Object.assign(this._icon, { gicon: icon, visible: icon != null });
this.notify('icon');
},
}
set title(title) {
this._setLabel(this._title, 'title', title);
},
}
set subtitle(subtitle) {
this._setLabel(this._subtitle, 'subtitle', subtitle);
},
}
set body(body) {
this._setLabel(this._body, 'body', body);
},
}
_setLabel(label, prop, value) {
Object.assign(label, { text: value || '', visible: value != null });
this.notify(prop);
},
}
insertBeforeBody(actor) {
this.messageBox.insert_child_below(actor, this._body);

View File

@ -4,7 +4,6 @@ const Clutter = imports.gi.Clutter;
const GLib = imports.gi.GLib;
const Gtk = imports.gi.Gtk;
const St = imports.gi.St;
const Lang = imports.lang;
const Meta = imports.gi.Meta;
const Shell = imports.gi.Shell;
const Signals = imports.signals;
@ -74,10 +73,8 @@ function removeDragMonitor(monitor) {
}
}
var _Draggable = new Lang.Class({
Name: 'Draggable',
_init(actor, params) {
var _Draggable = class _Draggable {
constructor(actor, params) {
params = Params.parse(params, { manualMode: false,
restoreOnSuccess: false,
dragActorMaxSize: undefined,
@ -112,7 +109,7 @@ var _Draggable = new Lang.Class({
this._dragCancellable = true;
this._eventsGrabbed = false;
},
}
_onButtonPress(actor, event) {
if (event.get_button() != 1)
@ -129,7 +126,7 @@ var _Draggable = new Lang.Class({
this._dragStartY = stageY;
return Clutter.EVENT_PROPAGATE;
},
}
_onTouchEvent(actor, event) {
if (event.type() != Clutter.EventType.TOUCH_BEGIN ||
@ -149,7 +146,7 @@ var _Draggable = new Lang.Class({
this._dragStartY = stageY;
return Clutter.EVENT_PROPAGATE;
},
}
_grabDevice(actor) {
let manager = Clutter.DeviceManager.get_default();
@ -161,7 +158,7 @@ var _Draggable = new Lang.Class({
pointer.grab (actor);
this._grabbedDevice = pointer;
},
}
_ungrabDevice() {
if (this._touchSequence)
@ -171,13 +168,13 @@ var _Draggable = new Lang.Class({
this._touchSequence = null;
this._grabbedDevice = null;
},
}
_grabActor() {
this._grabDevice(this.actor);
this._onEventId = this.actor.connect('event',
this._onEvent.bind(this));
},
}
_ungrabActor() {
if (!this._onEventId)
@ -186,7 +183,7 @@ var _Draggable = new Lang.Class({
this._ungrabDevice();
this.actor.disconnect(this._onEventId);
this._onEventId = null;
},
}
_grabEvents() {
if (!this._eventsGrabbed) {
@ -194,7 +191,7 @@ var _Draggable = new Lang.Class({
if (this._eventsGrabbed)
this._grabDevice(_getEventHandlerActor());
}
},
}
_ungrabEvents() {
if (this._eventsGrabbed) {
@ -202,7 +199,7 @@ var _Draggable = new Lang.Class({
Main.popModal(_getEventHandlerActor());
this._eventsGrabbed = false;
}
},
}
_onEvent(actor, event) {
// We intercept BUTTON_RELEASE event to know that the button was released in case we
@ -246,7 +243,7 @@ var _Draggable = new Lang.Class({
}
return Clutter.EVENT_PROPAGATE;
},
}
/**
* fakeRelease:
@ -259,7 +256,7 @@ var _Draggable = new Lang.Class({
fakeRelease() {
this._buttonDown = false;
this._ungrabActor();
},
}
/**
* startDrag:
@ -395,7 +392,7 @@ var _Draggable = new Lang.Class({
onUpdateScope: this });
}
}
},
}
_maybeStartDrag(event) {
let [stageX, stageY] = event.get_coords();
@ -409,12 +406,17 @@ var _Draggable = new Lang.Class({
}
return true;
},
}
_pickTargetActor() {
return this._dragActor.get_stage().get_actor_at_pos(Clutter.PickMode.ALL,
this._dragX, this._dragY);
}
_updateDragHover() {
this._updateHoverId = 0;
let target = this._dragActor.get_stage().get_actor_at_pos(Clutter.PickMode.ALL,
this._dragX, this._dragY);
let target = this._pickTargetActor();
let dragEvent = {
x: this._dragX,
y: this._dragY,
@ -422,6 +424,18 @@ var _Draggable = new Lang.Class({
source: this.actor._delegate,
targetActor: target
};
let targetActorDestroyHandlerId;
let handleTargetActorDestroyClosure;
handleTargetActorDestroyClosure = () => {
target = this._pickTargetActor();
dragEvent.targetActor = target;
targetActorDestroyHandlerId =
target.connect('destroy', handleTargetActorDestroyClosure);
};
targetActorDestroyHandlerId =
target.connect('destroy', handleTargetActorDestroyClosure);
for (let i = 0; i < dragMonitors.length; i++) {
let motionFunc = dragMonitors[i].dragMotion;
if (motionFunc) {
@ -432,6 +446,7 @@ var _Draggable = new Lang.Class({
}
}
}
dragEvent.targetActor.disconnect(targetActorDestroyHandlerId);
while (target) {
if (target._delegate && target._delegate.handleDragOver) {
@ -453,7 +468,7 @@ var _Draggable = new Lang.Class({
}
global.display.set_cursor(Meta.Cursor.DND_IN_DRAG);
return GLib.SOURCE_REMOVE;
},
}
_queueUpdateDragHover() {
if (this._updateHoverId)
@ -462,7 +477,7 @@ var _Draggable = new Lang.Class({
this._updateHoverId = GLib.idle_add(GLib.PRIORITY_DEFAULT,
this._updateDragHover.bind(this));
GLib.Source.set_name_by_id(this._updateHoverId, '[gnome-shell] this._updateDragHover');
},
}
_updateDragPosition(event) {
let [stageX, stageY] = event.get_coords();
@ -473,7 +488,7 @@ var _Draggable = new Lang.Class({
this._queueUpdateDragHover();
return true;
},
}
_dragActorDropped(event) {
let [dropX, dropY] = event.get_coords();
@ -536,7 +551,7 @@ var _Draggable = new Lang.Class({
this._cancelDrag(event.get_time());
return true;
},
}
_getRestoreLocation() {
let x, y, scale;
@ -568,7 +583,7 @@ var _Draggable = new Lang.Class({
}
return [x, y, scale];
},
}
_cancelDrag(eventTime) {
this.emit('drag-cancelled', eventTime);
@ -595,7 +610,7 @@ var _Draggable = new Lang.Class({
scale_y: snapBackScale,
time: SNAP_BACK_ANIMATION_TIME,
});
},
}
_restoreDragActor(eventTime) {
this._dragState = DragState.INIT;
@ -608,7 +623,7 @@ var _Draggable = new Lang.Class({
this._animateDragEnd(eventTime,
{ time: REVERT_ANIMATION_TIME });
},
}
_animateDragEnd(eventTime, params) {
this._animationInProgress = true;
@ -621,7 +636,7 @@ var _Draggable = new Lang.Class({
// start the animation
Tweener.addTween(this._dragActor, params)
},
}
_finishAnimation() {
if (!this._animationInProgress)
@ -632,7 +647,7 @@ var _Draggable = new Lang.Class({
this._dragComplete();
global.display.set_cursor(Meta.Cursor.DEFAULT);
},
}
_onAnimationComplete(dragActor, eventTime) {
if (this._dragOrigParent) {
@ -646,7 +661,7 @@ var _Draggable = new Lang.Class({
this.emit('drag-end', eventTime, false);
this._finishAnimation();
},
}
_dragComplete() {
if (!this._actorDestroyed && this._dragActor)
@ -668,8 +683,7 @@ var _Draggable = new Lang.Class({
this._dragState = DragState.INIT;
currentDraggable = null;
}
});
};
Signals.addSignalMethods(_Draggable.prototype);
/**

View File

@ -1,6 +1,6 @@
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
const Lang = imports.lang;
const GObject = imports.gi.GObject;
const Signals = imports.signals;
const Meta = imports.gi.Meta;
const Clutter = imports.gi.Clutter;
@ -11,26 +11,24 @@ const Main = imports.ui.main;
var EDGE_THRESHOLD = 20;
var DRAG_DISTANCE = 80;
var EdgeDragAction = new Lang.Class({
Name: 'EdgeDragAction',
Extends: Clutter.GestureAction,
var EdgeDragAction = GObject.registerClass({
Signals: { 'activated': {} },
}, class EdgeDragAction extends Clutter.GestureAction {
_init(side, allowedModes) {
this.parent();
super._init();
this._side = side;
this._allowedModes = allowedModes;
this.set_n_touch_points(1);
global.display.connect('grab-op-begin', () => { this.cancel(); });
},
}
_getMonitorRect(x, y) {
let rect = new Meta.Rectangle({ x: x - 1, y: y - 1, width: 1, height: 1 });
let monitorIndex = global.display.get_monitor_index_for_rect(rect);
return global.display.get_monitor_geometry(monitorIndex);
},
}
vfunc_gesture_prepare(action, actor) {
if (this.get_n_current_points() == 0)
@ -46,7 +44,7 @@ var EdgeDragAction = new Lang.Class({
(this._side == St.Side.RIGHT && x > monitorRect.x + monitorRect.width - EDGE_THRESHOLD) ||
(this._side == St.Side.TOP && y < monitorRect.y + EDGE_THRESHOLD) ||
(this._side == St.Side.BOTTOM && y > monitorRect.y + monitorRect.height - EDGE_THRESHOLD));
},
}
vfunc_gesture_progress(action, actor) {
let [startX, startY] = this.get_press_coords(0);
@ -66,7 +64,7 @@ var EdgeDragAction = new Lang.Class({
}
return true;
},
}
vfunc_gesture_end(action, actor) {
let [startX, startY] = this.get_press_coords(0);

View File

@ -16,7 +16,6 @@
* along with this program; if not, see <http://www.gnu.org/licenses/>.
*/
const Lang = imports.lang;
const Mainloop = imports.mainloop;
const AccountsService = imports.gi.AccountsService;
@ -235,13 +234,10 @@ function init() {
_endSessionDialog = new EndSessionDialog();
}
var EndSessionDialog = new Lang.Class({
Name: 'EndSessionDialog',
Extends: ModalDialog.ModalDialog,
_init() {
this.parent({ styleClass: 'end-session-dialog',
destroyOnClose: false });
var EndSessionDialog = class EndSessionDialog extends ModalDialog.ModalDialog {
constructor() {
super({ styleClass: 'end-session-dialog',
destroyOnClose: false });
this._loginManager = LoginManager.getLoginManager();
this._userManager = AccountsService.UserManager.get_default();
@ -356,12 +352,12 @@ var EndSessionDialog = new Lang.Class({
this._dbusImpl = Gio.DBusExportedObject.wrapJSObject(EndSessionDialogIface, this);
this._dbusImpl.export(Gio.DBus.session, '/org/gnome/SessionManager/EndSessionDialog');
},
}
_onDestroy() {
this._user.disconnect(this._userLoadedId);
this._user.disconnect(this._userChangedId);
},
}
_sync() {
let open = (this.state == ModalDialog.State.OPENING || this.state == ModalDialog.State.OPENED);
@ -434,7 +430,7 @@ var EndSessionDialog = new Lang.Class({
this._scrollView.visible = hasApplications || hasSessions;
this._applicationHeader.visible = hasApplications;
this._sessionHeader.visible = hasSessions;
},
}
_updateButtons() {
let dialogContent = DialogContent[this._type];
@ -456,20 +452,20 @@ var EndSessionDialog = new Lang.Class({
}
this.setButtons(buttons);
},
}
close(skipSignal) {
this.parent();
super.close();
if (!skipSignal)
this._dbusImpl.emit_signal('Closed', null);
},
}
cancel() {
this._stopTimer();
this._dbusImpl.emit_signal('Canceled', null);
this.close();
},
}
_confirm(signal) {
let callback = () => {
@ -504,11 +500,11 @@ var EndSessionDialog = new Lang.Class({
} else {
this._triggerOfflineUpdateCancel(callback);
}
},
}
_onOpened() {
this._sync();
},
}
_triggerOfflineUpdateReboot(callback) {
this._pkOfflineProxy.TriggerRemote('reboot', (result, error) => {
@ -517,7 +513,7 @@ var EndSessionDialog = new Lang.Class({
callback();
});
},
}
_triggerOfflineUpdateShutdown(callback) {
this._pkOfflineProxy.TriggerRemote('power-off', (result, error) => {
@ -526,7 +522,7 @@ var EndSessionDialog = new Lang.Class({
callback();
});
},
}
_triggerOfflineUpdateCancel(callback) {
this._pkOfflineProxy.CancelRemote((result, error) => {
@ -535,7 +531,7 @@ var EndSessionDialog = new Lang.Class({
callback();
});
},
}
_startTimer() {
let startTime = GLib.get_monotonic_time();
@ -559,7 +555,7 @@ var EndSessionDialog = new Lang.Class({
return GLib.SOURCE_REMOVE;
});
GLib.Source.set_name_by_id(this._timerId, '[gnome-shell] this._confirm');
},
}
_stopTimer() {
if (this._timerId > 0) {
@ -568,7 +564,7 @@ var EndSessionDialog = new Lang.Class({
}
this._secondsLeft = 0;
},
}
_constructListItemForApp(inhibitor, app) {
let actor = new St.BoxLayout({ style_class: 'end-session-dialog-app-list-item',
@ -593,7 +589,7 @@ var EndSessionDialog = new Lang.Class({
}
return actor;
},
}
_onInhibitorLoaded(inhibitor) {
if (this._applications.indexOf(inhibitor) < 0) {
@ -612,7 +608,7 @@ var EndSessionDialog = new Lang.Class({
}
this._sync();
},
}
_constructListItemForSession(session) {
let avatar = new UserWidget.Avatar(session.user, { iconSize: _ITEM_ICON_SIZE });
@ -642,7 +638,7 @@ var EndSessionDialog = new Lang.Class({
actor.label_actor = nameLabel;
return actor;
},
}
_loadSessions() {
this._loginManager.listSessions(result => {
@ -684,7 +680,7 @@ var EndSessionDialog = new Lang.Class({
this._sync();
});
},
}
OpenAsync(parameters, invocation) {
let [type, timestamp, totalSecondsToStayOpen, inhibitorObjectPaths] = parameters;
@ -754,9 +750,9 @@ var EndSessionDialog = new Lang.Class({
invocation.return_value(null);
this.disconnect(signalId);
});
},
}
Close(parameters, invocation) {
this.close();
}
});
};

View File

@ -14,7 +14,6 @@ const Clutter = imports.gi.Clutter;
const Gettext = imports.gettext;
const GLib = imports.gi.GLib;
const Gtk = imports.gi.Gtk;
const Lang = imports.lang;
const Shell = imports.gi.Shell;
const St = imports.gi.St;

View File

@ -1,7 +1,5 @@
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
const Lang = imports.lang;
const Clutter = imports.gi.Clutter;
const GLib = imports.gi.GLib;
const Gio = imports.gi.Gio;
@ -183,12 +181,10 @@ function checkForUpdates() {
});
}
var InstallExtensionDialog = new Lang.Class({
Name: 'InstallExtensionDialog',
Extends: ModalDialog.ModalDialog,
_init(uuid, info, invocation) {
this.parent({ styleClass: 'extension-dialog' });
var InstallExtensionDialog =
class InstallExtensionDialog extends ModalDialog.ModalDialog {
constructor(uuid, info, invocation) {
super({ styleClass: 'extension-dialog' });
this._uuid = uuid;
this._info = info;
@ -216,12 +212,12 @@ var InstallExtensionDialog = new Lang.Class({
let label = new St.Label({ style_class: 'message-dialog-title headline',
text: message });
box.add(label);
},
}
_onCancelButtonPressed(button, event) {
this.close();
this._invocation.return_value(GLib.Variant.new('(s)', ['cancelled']));
},
}
_onInstallButtonPressed(button, event) {
let params = { shell_version: Config.PACKAGE_VERSION };
@ -264,7 +260,7 @@ var InstallExtensionDialog = new Lang.Class({
this.close();
}
});
};
function init() {
_httpSession = new Soup.SessionAsync({ ssl_use_system_ca_file: true });

View File

@ -1,6 +1,5 @@
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
const Lang = imports.lang;
const Signals = imports.signals;
const GLib = imports.gi.GLib;

View File

@ -22,29 +22,26 @@
*/
const Atspi = imports.gi.Atspi;
const Lang = imports.lang;
const Signals = imports.signals;
const CARETMOVED = 'object:text-caret-moved';
const STATECHANGED = 'object:state-changed';
var FocusCaretTracker = new Lang.Class({
Name: 'FocusCaretTracker',
_init() {
var FocusCaretTracker = class FocusCaretTracker {
constructor() {
this._atspiListener = Atspi.EventListener.new(this._onChanged.bind(this));
this._atspiInited = false;
this._focusListenerRegistered = false;
this._caretListenerRegistered = false;
},
}
_onChanged(event) {
if (event.type.indexOf(STATECHANGED) == 0)
this.emit('focus-changed', event);
else if (event.type == CARETMOVED)
this.emit('caret-moved', event);
},
}
_initAtspi() {
if (!this._atspiInited && Atspi.init() == 0) {
@ -53,7 +50,7 @@ var FocusCaretTracker = new Lang.Class({
}
return this._atspiInited;
},
}
registerFocusListener() {
if (!this._initAtspi() || this._focusListenerRegistered)
@ -62,7 +59,7 @@ var FocusCaretTracker = new Lang.Class({
this._atspiListener.register(STATECHANGED + ':focused');
this._atspiListener.register(STATECHANGED + ':selected');
this._focusListenerRegistered = true;
},
}
registerCaretListener() {
if (!this._initAtspi() || this._caretListenerRegistered)
@ -70,7 +67,7 @@ var FocusCaretTracker = new Lang.Class({
this._atspiListener.register(CARETMOVED);
this._caretListenerRegistered = true;
},
}
deregisterFocusListener() {
if (!this._focusListenerRegistered)
@ -79,7 +76,7 @@ var FocusCaretTracker = new Lang.Class({
this._atspiListener.deregister(STATECHANGED + ':focused');
this._atspiListener.deregister(STATECHANGED + ':selected');
this._focusListenerRegistered = false;
},
}
deregisterCaretListener() {
if (!this._caretListenerRegistered)
@ -88,5 +85,5 @@ var FocusCaretTracker = new Lang.Class({
this._atspiListener.deregister(CARETMOVED);
this._caretListenerRegistered = false;
}
});
};
Signals.addSignalMethods(FocusCaretTracker.prototype);

View File

@ -2,7 +2,6 @@
const Clutter = imports.gi.Clutter;
const Gtk = imports.gi.Gtk;
const Lang = imports.lang;
const Meta = imports.gi.Meta;
const Shell = imports.gi.Shell;
const St = imports.gi.St;
@ -46,10 +45,8 @@ function _popGrabHelper(grabHelper) {
// your code just needs to deal with it; you shouldn't adjust behavior directly
// after you call ungrab(), but instead pass an 'onUngrab' callback when you
// call grab().
var GrabHelper = new Lang.Class({
Name: 'GrabHelper',
_init(owner, params) {
var GrabHelper = class GrabHelper {
constructor(owner, params) {
this._owner = owner;
this._modalParams = params;
@ -59,7 +56,7 @@ var GrabHelper = new Lang.Class({
this._ignoreUntilRelease = false;
this._modalCount = 0;
},
}
// addActor:
// @actor: an actor
@ -71,7 +68,7 @@ var GrabHelper = new Lang.Class({
this.removeActor(actor);
});
this._actors.push(actor);
},
}
// removeActor:
// @actor: an actor
@ -86,7 +83,7 @@ var GrabHelper = new Lang.Class({
actor.disconnect(actor.__grabHelperDestroyId);
delete actor.__grabHelperDestroyId;
}
},
}
_isWithinGrabbedActor(actor) {
let currentActor = this.currentGrab.actor;
@ -98,19 +95,19 @@ var GrabHelper = new Lang.Class({
actor = actor.get_parent();
}
return false;
},
}
get currentGrab() {
return this._grabStack[this._grabStack.length - 1] || {};
},
}
get grabbed() {
return this._grabStack.length > 0;
},
}
get grabStack() {
return this._grabStack;
},
}
_findStackIndex(actor) {
if (!actor)
@ -121,7 +118,7 @@ var GrabHelper = new Lang.Class({
return i;
}
return -1;
},
}
_actorInGrabStack(actor) {
while (actor) {
@ -131,11 +128,11 @@ var GrabHelper = new Lang.Class({
actor = actor.get_parent();
}
return -1;
},
}
isActorGrabbed(actor) {
return this._findStackIndex(actor) >= 0;
},
}
// grab:
// @params: A bunch of parameters, see below
@ -195,7 +192,7 @@ var GrabHelper = new Lang.Class({
}
return true;
},
}
_takeModalGrab() {
let firstGrab = (this._modalCount == 0);
@ -208,7 +205,7 @@ var GrabHelper = new Lang.Class({
this._modalCount++;
return true;
},
}
_releaseModalGrab() {
this._modalCount--;
@ -221,7 +218,7 @@ var GrabHelper = new Lang.Class({
Main.popModal(this._owner);
global.sync_pointer();
},
}
// ignoreRelease:
//
@ -231,7 +228,7 @@ var GrabHelper = new Lang.Class({
// the next release event.
ignoreRelease() {
this._ignoreUntilRelease = true;
},
}
// ungrab:
// @params: The parameters for the grab; see below.
@ -274,7 +271,7 @@ var GrabHelper = new Lang.Class({
if (poppedGrab.savedFocus)
poppedGrab.savedFocus.grab_key_focus();
}
},
}
onCapturedEvent(event) {
let type = event.type();
@ -322,5 +319,5 @@ var GrabHelper = new Lang.Class({
}
return Clutter.EVENT_STOP;
},
});
}
};

View File

@ -2,7 +2,6 @@
const Clutter = imports.gi.Clutter;
const IBus = imports.gi.IBus;
const Lang = imports.lang;
const Signals = imports.signals;
const St = imports.gi.St;
@ -14,10 +13,8 @@ var MAX_CANDIDATES_PER_PAGE = 16;
var DEFAULT_INDEX_LABELS = [ '1', '2', '3', '4', '5', '6', '7', '8',
'9', '0', 'a', 'b', 'c', 'd', 'e', 'f' ];
var CandidateArea = new Lang.Class({
Name: 'CandidateArea',
_init() {
var CandidateArea = class CandidateArea {
constructor() {
this.actor = new St.BoxLayout({ vertical: true,
reactive: true,
visible: false });
@ -74,7 +71,7 @@ var CandidateArea = new Lang.Class({
this._orientation = -1;
this._cursorPosition = 0;
},
}
setOrientation(orientation) {
if (this._orientation == orientation)
@ -95,7 +92,7 @@ var CandidateArea = new Lang.Class({
this._previousButton.child.icon_name = 'go-up-symbolic';
this._nextButton.child.icon_name = 'go-down-symbolic';
}
},
}
setCandidates(indexes, candidates, cursorPosition, cursorVisible) {
for (let i = 0; i < MAX_CANDIDATES_PER_PAGE; ++i) {
@ -114,7 +111,7 @@ var CandidateArea = new Lang.Class({
this._cursorPosition = cursorPosition;
if (cursorVisible)
this._candidateBoxes[cursorPosition].add_style_pseudo_class('selected');
},
}
updateButtons(wrapsAround, page, nPages) {
if (nPages < 2) {
@ -124,18 +121,16 @@ var CandidateArea = new Lang.Class({
this._buttonBox.show();
this._previousButton.reactive = wrapsAround || page > 0;
this._nextButton.reactive = wrapsAround || page < nPages - 1;
},
});
}
};
Signals.addSignalMethods(CandidateArea.prototype);
var CandidatePopup = new Lang.Class({
Name: 'CandidatePopup',
_init() {
var CandidatePopup = class CandidatePopup {
constructor() {
this._boxPointer = new BoxPointer.BoxPointer(St.Side.TOP);
this._boxPointer.actor.visible = false;
this._boxPointer.actor.style_class = 'candidate-popup-boxpointer';
Main.layoutManager.addChrome(this._boxPointer.actor);
this._boxPointer.visible = false;
this._boxPointer.style_class = 'candidate-popup-boxpointer';
Main.layoutManager.addChrome(this._boxPointer);
let box = new St.BoxLayout({ style_class: 'candidate-popup-content',
vertical: true });
@ -171,7 +166,7 @@ var CandidatePopup = new Lang.Class({
});
this._panelService = null;
},
}
setPanelService(panelService) {
this._panelService = panelService;
@ -272,16 +267,16 @@ var CandidatePopup = new Lang.Class({
this._updateVisibility();
});
panelService.connect('focus-out', ps => {
this._boxPointer.hide(BoxPointer.PopupAnimation.NONE);
this._boxPointer.close(BoxPointer.PopupAnimation.NONE);
Main.keyboard.resetSuggestions();
});
},
}
_setDummyCursorGeometry(x, y, w, h) {
Main.layoutManager.setDummyCursorGeometry(x, y, w, h);
if (this._boxPointer.actor.visible)
this._boxPointer.setPosition(Main.layoutManager.dummyCursor, 0);
},
}
_updateVisibility() {
let isVisible = (!Main.keyboard.visible &&
@ -291,12 +286,12 @@ var CandidatePopup = new Lang.Class({
if (isVisible) {
this._boxPointer.setPosition(Main.layoutManager.dummyCursor, 0);
this._boxPointer.show(BoxPointer.PopupAnimation.NONE);
this._boxPointer.open(BoxPointer.PopupAnimation.NONE);
this._boxPointer.actor.raise_top();
} else {
this._boxPointer.hide(BoxPointer.PopupAnimation.NONE);
this._boxPointer.close(BoxPointer.PopupAnimation.NONE);
}
},
}
_setTextAttributes(clutterText, ibusAttrList) {
let attr;
@ -304,4 +299,4 @@ var CandidatePopup = new Lang.Class({
if (attr.get_attr_type() == IBus.AttrType.BACKGROUND)
clutterText.set_selection(attr.get_start_index(), attr.get_end_index());
}
});
};

View File

@ -1,13 +1,13 @@
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
const Clutter = imports.gi.Clutter;
const GObject = imports.gi.GObject;
const Gtk = imports.gi.Gtk;
const Meta = imports.gi.Meta;
const Shell = imports.gi.Shell;
const Signals = imports.signals;
const St = imports.gi.St;
const Lang = imports.lang;
const Params = imports.misc.params;
const Tweener = imports.ui.tweener;
const Main = imports.ui.main;
@ -34,9 +34,8 @@ var AnimationDirection = {
var APPICON_ANIMATION_OUT_SCALE = 3;
var APPICON_ANIMATION_OUT_TIME = 0.25;
var BaseIcon = new Lang.Class({
Name: 'BaseIcon',
var BaseIcon = GObject.registerClass(
class BaseIcon extends St.Bin {
_init(label, params) {
params = Params.parse(params, { createIcon: null,
setSizeManually: false,
@ -46,32 +45,26 @@ var BaseIcon = new Lang.Class({
if (params.showLabel)
styleClass += ' overview-icon-with-label';
this.actor = new St.Bin({ style_class: styleClass,
x_fill: true,
y_fill: true });
this.actor._delegate = this;
this.actor.connect('style-changed', this._onStyleChanged.bind(this));
this.actor.connect('destroy', this._onDestroy.bind(this));
super._init({ style_class: styleClass,
x_fill: true,
y_fill: true });
this._spacing = 0;
this.actor = this;
let box = new Shell.GenericContainer();
box.connect('allocate', this._allocate.bind(this));
box.connect('get-preferred-width',
this._getPreferredWidth.bind(this));
box.connect('get-preferred-height',
this._getPreferredHeight.bind(this));
this.actor.set_child(box);
this.connect('destroy', this._onDestroy.bind(this));
this._box = new St.BoxLayout({ vertical: true });
this.set_child(this._box);
this.iconSize = ICON_SIZE;
this._iconBin = new St.Bin({ x_align: St.Align.MIDDLE,
y_align: St.Align.MIDDLE });
box.add_actor(this._iconBin);
this._box.add_actor(this._iconBin);
if (params.showLabel) {
this.label = new St.Label({ text: label });
box.add_actor(this.label);
this._box.add_actor(this.label);
} else {
this.label = null;
}
@ -84,63 +77,18 @@ var BaseIcon = new Lang.Class({
let cache = St.TextureCache.get_default();
this._iconThemeChangedId = cache.connect('icon-theme-changed', this._onIconThemeChanged.bind(this));
},
}
_allocate(actor, box, flags) {
let availWidth = box.x2 - box.x1;
let availHeight = box.y2 - box.y1;
let iconSize = availHeight;
let [iconMinHeight, iconNatHeight] = this._iconBin.get_preferred_height(-1);
let [iconMinWidth, iconNatWidth] = this._iconBin.get_preferred_width(-1);
let preferredHeight = iconNatHeight;
let childBox = new Clutter.ActorBox();
if (this.label) {
let [labelMinHeight, labelNatHeight] = this.label.get_preferred_height(-1);
preferredHeight += this._spacing + labelNatHeight;
let labelHeight = availHeight >= preferredHeight ? labelNatHeight
: labelMinHeight;
iconSize -= this._spacing + labelHeight;
childBox.x1 = 0;
childBox.x2 = availWidth;
childBox.y1 = iconSize + this._spacing;
childBox.y2 = childBox.y1 + labelHeight;
this.label.allocate(childBox, flags);
}
childBox.x1 = Math.floor((availWidth - iconNatWidth) / 2);
childBox.y1 = Math.floor((iconSize - iconNatHeight) / 2);
childBox.x2 = childBox.x1 + iconNatWidth;
childBox.y2 = childBox.y1 + iconNatHeight;
this._iconBin.allocate(childBox, flags);
},
_getPreferredWidth(actor, forHeight, alloc) {
this._getPreferredHeight(actor, -1, alloc);
},
_getPreferredHeight(actor, forWidth, alloc) {
let [iconMinHeight, iconNatHeight] = this._iconBin.get_preferred_height(forWidth);
alloc.min_size = iconMinHeight;
alloc.natural_size = iconNatHeight;
if (this.label) {
let [labelMinHeight, labelNatHeight] = this.label.get_preferred_height(forWidth);
alloc.min_size += this._spacing + labelMinHeight;
alloc.natural_size += this._spacing + labelNatHeight;
}
},
vfunc_get_preferred_width(forHeight) {
// Return the actual height to keep the squared aspect
return this.get_preferred_height(-1);
}
// This can be overridden by a subclass, or by the createIcon
// parameter to _init()
createIcon(size) {
throw new Error('no implementation of createIcon in ' + this);
},
}
setIconSize(size) {
if (!this._setSizeManually)
@ -150,7 +98,7 @@ var BaseIcon = new Lang.Class({
return;
this._createIconTexture(size);
},
}
_createIconTexture(size) {
if (this.icon)
@ -159,11 +107,10 @@ var BaseIcon = new Lang.Class({
this.icon = this.createIcon(this.iconSize);
this._iconBin.child = this.icon;
},
}
_onStyleChanged() {
let node = this.actor.get_theme_node();
this._spacing = node.get_length('spacing');
vfunc_style_changed() {
let node = this.get_theme_node();
let size;
if (this._setSizeManually) {
@ -177,7 +124,7 @@ var BaseIcon = new Lang.Class({
return;
this._createIconTexture(size);
},
}
_onDestroy() {
if (this._iconThemeChangedId > 0) {
@ -185,17 +132,17 @@ var BaseIcon = new Lang.Class({
cache.disconnect(this._iconThemeChangedId);
this._iconThemeChangedId = 0;
}
},
}
_onIconThemeChanged() {
this._createIconTexture(this.iconSize);
},
}
animateZoomOut() {
// Animate only the child instead of the entire actor, so the
// styles like hover and running are not applied while
// animating.
zoomOutActor(this.actor.child);
zoomOutActor(this.child);
}
});
@ -238,10 +185,16 @@ function zoomOutActor(actor) {
});
}
var IconGrid = new Lang.Class({
Name: 'IconGrid',
var IconGrid = GObject.registerClass({
Signals: {'animation-done': {},
'child-focused': { param_types: [Clutter.Actor.$gtype]} },
}, class IconGrid extends St.Widget {
_init(params) {
super._init({ style_class: 'icon-grid',
y_align: Clutter.ActorAlign.START });
this.actor = this;
params = Params.parse(params, { rowLimit: null,
columnLimit: null,
minRows: 1,
@ -262,51 +215,44 @@ var IconGrid = new Lang.Class({
this.rightPadding = 0;
this.leftPadding = 0;
this.actor = new St.BoxLayout({ style_class: 'icon-grid',
vertical: true });
this._items = [];
this._clonesAnimating = [];
// Pulled from CSS, but hardcode some defaults here
this._spacing = 0;
this._hItemSize = this._vItemSize = ICON_SIZE;
this._fixedHItemSize = this._fixedVItemSize = undefined;
this._grid = new Shell.GenericContainer();
this.actor.add(this._grid, { expand: true, y_align: St.Align.START });
this.actor.connect('style-changed', this._onStyleChanged.bind(this));
this.connect('style-changed', this._onStyleChanged.bind(this));
// Cancel animations when hiding the overview, to avoid icons
// swarming into the void ...
this.actor.connect('notify::mapped', () => {
if (!this.actor.mapped)
this.connect('notify::mapped', () => {
if (!this.mapped)
this._cancelAnimation();
});
this._grid.connect('get-preferred-width', this._getPreferredWidth.bind(this));
this._grid.connect('get-preferred-height', this._getPreferredHeight.bind(this));
this._grid.connect('allocate', this._allocate.bind(this));
this._grid.connect('actor-added', this._childAdded.bind(this));
this._grid.connect('actor-removed', this._childRemoved.bind(this));
},
this.connect('actor-added', this._childAdded.bind(this));
this.connect('actor-removed', this._childRemoved.bind(this));
}
_keyFocusIn(actor) {
this.emit('key-focus-in', actor);
},
this.emit('child-focused', actor);
}
_childAdded(grid, child) {
child._iconGridKeyFocusInId = child.connect('key-focus-in', this._keyFocusIn.bind(this));
},
}
_childRemoved(grid, child) {
child.disconnect(child._iconGridKeyFocusInId);
},
}
_getPreferredWidth(grid, forHeight, alloc) {
vfunc_get_preferred_width(forHeight) {
if (this._fillParent)
// Ignore all size requests of children and request a size of 0;
// later we'll allocate as many children as fit the parent
return;
return [0, 0];
let nChildren = this._grid.get_n_children();
let nChildren = this.get_n_children();
let nColumns = this._colLimit ? Math.min(this._colLimit,
nChildren)
: nChildren;
@ -314,22 +260,28 @@ var IconGrid = new Lang.Class({
// Kind of a lie, but not really an issue right now. If
// we wanted to support some sort of hidden/overflow that would
// need higher level design
alloc.min_size = this._getHItemSize() + this.leftPadding + this.rightPadding;
alloc.natural_size = nColumns * this._getHItemSize() + totalSpacing + this.leftPadding + this.rightPadding;
},
let minSize = this._getHItemSize() + this.leftPadding + this.rightPadding;
let natSize = nColumns * this._getHItemSize() + totalSpacing + this.leftPadding + this.rightPadding;
return this.get_theme_node().adjust_preferred_width(minSize, natSize);
}
_getVisibleChildren() {
return this._grid.get_children().filter(actor => actor.visible);
},
return this.get_children().filter(actor => actor.visible);
}
_getPreferredHeight(grid, forWidth, alloc) {
vfunc_get_preferred_height(forWidth) {
if (this._fillParent)
// Ignore all size requests of children and request a size of 0;
// later we'll allocate as many children as fit the parent
return;
return [0, 0];
let themeNode = this.get_theme_node();
let children = this._getVisibleChildren();
let nColumns;
forWidth = themeNode.adjust_for_width(forWidth);
if (forWidth < 0)
nColumns = children.length;
else
@ -344,16 +296,21 @@ var IconGrid = new Lang.Class({
nRows = Math.min(nRows, this._rowLimit);
let totalSpacing = Math.max(0, nRows - 1) * this._getSpacing();
let height = nRows * this._getVItemSize() + totalSpacing + this.topPadding + this.bottomPadding;
alloc.min_size = height;
alloc.natural_size = height;
},
_allocate(grid, box, flags) {
return themeNode.adjust_preferred_height(height, height);
}
vfunc_allocate(box, flags) {
this.set_allocation(box, flags);
let themeNode = this.get_theme_node();
box = themeNode.get_content_box(box);
if (this._fillParent) {
// Reset the passed in box to fill the parent
let parentBox = this.actor.get_parent().allocation;
let gridBox = this.actor.get_theme_node().get_content_box(parentBox);
box = this._grid.get_theme_node().get_content_box(gridBox);
let parentBox = this.get_parent().allocation;
let gridBox = themeNode.get_content_box(parentBox);
box = themeNode.get_content_box(gridBox);
}
let children = this._getVisibleChildren();
@ -383,10 +340,10 @@ var IconGrid = new Lang.Class({
if (this._rowLimit && rowIndex >= this._rowLimit ||
this._fillParent && childBox.y2 > availHeight - this.bottomPadding) {
this._grid.set_skip_paint(children[i], true);
children[i].hide();
} else {
children[i].allocate(childBox, flags);
this._grid.set_skip_paint(children[i], false);
children[i].show();
}
columnIndex++;
@ -402,7 +359,46 @@ var IconGrid = new Lang.Class({
x += this._getHItemSize() + spacing;
}
}
},
}
vfunc_get_paint_volume(paintVolume) {
// Setting the paint volume does not make sense when we don't have
// any allocation
if (!this.has_allocation())
return false;
let themeNode = this.get_theme_node();
let allocationBox = this.get_allocation_box();
let paintBox = themeNode.get_paint_box(allocationBox);
let origin = new Clutter.Vertex();
origin.x = paintBox.x1 - allocationBox.x1;
origin.y = paintBox.y1 - allocationBox.y1;
origin.z = 0.0;
paintVolume.set_origin(origin);
paintVolume.set_width(paintBox.x2 - paintBox.x1);
paintVolume.set_height(paintBox.y2 - paintBox.y1);
if (this.get_clip_to_allocation())
return true;
for (let child = this.get_first_child();
child != null;
child = child.get_next_sibling()) {
if (!child.visible)
continue;
let childVolume = child.get_transformed_paint_volume(this);
if (!childVolume)
return false
paintVolume.union(childVolume);
}
return true;
}
/**
* Intended to be override by subclasses if they need a different
@ -410,17 +406,22 @@ var IconGrid = new Lang.Class({
*/
_getChildrenToAnimate() {
return this._getVisibleChildren();
},
}
_cancelAnimation() {
this._clonesAnimating.forEach(clone => { clone.destroy(); });
this._clonesAnimating = [];
},
}
_animationDone() {
this._clonesAnimating.forEach(clone => {
clone.source.reactive = true;
clone.source.opacity = 255;
clone.destroy();
});
this._clonesAnimating = [];
this.emit('animation-done');
},
}
animatePulse(animationDirection) {
if (animationDirection != AnimationDirection.IN)
@ -443,7 +444,6 @@ var IconGrid = new Lang.Class({
for (let index = 0; index < actors.length; index++) {
let actor = actors[index];
actor.reactive = false;
actor.set_scale(0, 0);
actor.set_pivot_point(0.5, 0.5);
@ -465,13 +465,12 @@ var IconGrid = new Lang.Class({
onComplete: () => {
if (isLastItem)
this._animationDone();
actor.reactive = true;
}
});
}
});
}
},
}
animateSpring(animationDirection, sourceActor) {
this._cancelAnimation();
@ -538,10 +537,6 @@ var IconGrid = new Lang.Class({
onComplete: () => {
if (isLastItem)
this._animationDone();
actor.opacity = 255;
actor.reactive = true;
actorClone.destroy();
}};
fadeParams = { time: ANIMATION_FADE_IN_TIME_FOR_ITEM,
transition: 'easeInOutQuad',
@ -562,12 +557,8 @@ var IconGrid = new Lang.Class({
scale_x: scaleX,
scale_y: scaleY,
onComplete: () => {
if (isLastItem) {
if (isLastItem)
this._animationDone();
this._restoreItemsOpacity();
}
actor.reactive = true;
actorClone.destroy();
}};
fadeParams = { time: ANIMATION_FADE_IN_TIME_FOR_ITEM,
transition: 'easeInOutQuad',
@ -579,13 +570,7 @@ var IconGrid = new Lang.Class({
Tweener.addTween(actorClone, movementParams);
Tweener.addTween(actorClone, fadeParams);
}
},
_restoreItemsOpacity() {
for (let index = 0; index < this._items.length; index++) {
this._items[index].actor.opacity = 255;
}
},
}
_getAllocatedChildSizeAndSpacing(child) {
let [,, natWidth, natHeight] = child.get_preferred_size();
@ -594,7 +579,7 @@ var IconGrid = new Lang.Class({
let height = Math.min(this._getVItemSize(), natHeight);
let ySpacing = Math.max(0, height - natHeight) / 2;
return [width, height, xSpacing, ySpacing];
},
}
_calculateChildBox(child, x, y, box) {
/* Center the item in its allocation horizontally */
@ -612,15 +597,15 @@ var IconGrid = new Lang.Class({
childBox.x2 = childBox.x1 + width;
childBox.y2 = childBox.y1 + height;
return childBox;
},
}
columnsForWidth(rowWidth) {
return this._computeLayout(rowWidth)[0];
},
}
getRowLimit() {
return this._rowLimit;
},
}
_computeLayout(forWidth) {
let nColumns = 0;
@ -637,15 +622,15 @@ var IconGrid = new Lang.Class({
usedWidth -= spacing;
return [nColumns, usedWidth];
},
}
_onStyleChanged() {
let themeNode = this.actor.get_theme_node();
let themeNode = this.get_theme_node();
this._spacing = themeNode.get_length('spacing');
this._hItemSize = themeNode.get_length('-shell-grid-horizontal-item-size') || ICON_SIZE;
this._vItemSize = themeNode.get_length('-shell-grid-vertical-item-size') || ICON_SIZE;
this._grid.queue_relayout();
},
this.queue_relayout();
}
nRows(forWidth) {
let children = this._getVisibleChildren();
@ -654,35 +639,35 @@ var IconGrid = new Lang.Class({
if (this._rowLimit)
nRows = Math.min(nRows, this._rowLimit);
return nRows;
},
}
rowsForHeight(forHeight) {
return Math.floor((forHeight - (this.topPadding + this.bottomPadding) + this._getSpacing()) / (this._getVItemSize() + this._getSpacing()));
},
}
usedHeightForNRows(nRows) {
return (this._getVItemSize() + this._getSpacing()) * nRows - this._getSpacing() + this.topPadding + this.bottomPadding;
},
}
usedWidth(forWidth) {
return this.usedWidthForNColumns(this.columnsForWidth(forWidth));
},
}
usedWidthForNColumns(columns) {
let usedWidth = columns * (this._getHItemSize() + this._getSpacing());
usedWidth -= this._getSpacing();
return usedWidth + this.leftPadding + this.rightPadding;
},
}
removeAll() {
this._items = [];
this._grid.remove_all_children();
},
this.remove_all_children();
}
destroyAll() {
this._items = [];
this._grid.destroy_all_children();
},
this.destroy_all_children();
}
addItem(item, index) {
if (!item.icon instanceof BaseIcon)
@ -690,38 +675,38 @@ var IconGrid = new Lang.Class({
this._items.push(item);
if (index !== undefined)
this._grid.insert_child_at_index(item.actor, index);
this.insert_child_at_index(item.actor, index);
else
this._grid.add_actor(item.actor);
},
this.add_actor(item.actor);
}
removeItem(item) {
this._grid.remove_child(item.actor);
},
this.remove_child(item.actor);
}
getItemAtIndex(index) {
return this._grid.get_child_at_index(index);
},
return this.get_child_at_index(index);
}
visibleItemsCount() {
return this._grid.get_n_children() - this._grid.get_n_skip_paint();
},
return this.get_children().filter(c => c.is_visible()).length;
}
setSpacing(spacing) {
this._fixedSpacing = spacing;
},
}
_getSpacing() {
return this._fixedSpacing ? this._fixedSpacing : this._spacing;
},
}
_getHItemSize() {
return this._fixedHItemSize ? this._fixedHItemSize : this._hItemSize;
},
}
_getVItemSize() {
return this._fixedVItemSize ? this._fixedVItemSize : this._vItemSize;
},
}
_updateSpacingForSize(availWidth, availHeight) {
let maxEmptyVArea = availHeight - this._minRows * this._getVItemSize();
@ -754,7 +739,7 @@ var IconGrid = new Lang.Class({
this.setSpacing(spacing);
if (this._padWithSpacing)
this.topPadding = this.rightPadding = this.bottomPadding = this.leftPadding = spacing;
},
}
/**
* This function must to be called before iconGrid allocation,
@ -779,7 +764,7 @@ var IconGrid = new Lang.Class({
}
Meta.later_add(Meta.LaterType.BEFORE_REDRAW,
this._updateIconSizes.bind(this));
},
}
// Note that this is ICON_SIZE as used by BaseIcon, not elsewhere in IconGrid; it's a bit messed up
_updateIconSizes() {
@ -790,35 +775,36 @@ var IconGrid = new Lang.Class({
}
}
});
Signals.addSignalMethods(IconGrid.prototype);
var PaginatedIconGrid = new Lang.Class({
Name: 'PaginatedIconGrid',
Extends: IconGrid,
var PaginatedIconGrid = GObject.registerClass({
Signals: {'space-opened': {},
'space-closed': {} },
}, class PaginatedIconGrid extends IconGrid {
_init(params) {
this.parent(params);
super._init(params);
this._nPages = 0;
this.currentPage = 0;
this._rowsPerPage = 0;
this._spaceBetweenPages = 0;
this._childrenPerPage = 0;
},
}
_getPreferredHeight(grid, forWidth, alloc) {
alloc.min_size = (this._availableHeightPerPageForItems() + this.bottomPadding + this.topPadding) * this._nPages + this._spaceBetweenPages * this._nPages;
alloc.natural_size = (this._availableHeightPerPageForItems() + this.bottomPadding + this.topPadding) * this._nPages + this._spaceBetweenPages * this._nPages;
},
vfunc_get_preferred_height(forWidth) {
let height = (this._availableHeightPerPageForItems() + this.bottomPadding + this.topPadding) * this._nPages + this._spaceBetweenPages * this._nPages;
return [height, height];
}
_allocate(grid, box, flags) {
vfunc_allocate(box, flags) {
if (this._childrenPerPage == 0)
log('computePages() must be called before allocate(); pagination will not work.');
this.set_allocation(box, flags);
if (this._fillParent) {
// Reset the passed in box to fill the parent
let parentBox = this.actor.get_parent().allocation;
let gridBox = this.actor.get_theme_node().get_content_box(parentBox);
box = this._grid.get_theme_node().get_content_box(gridBox);
let parentBox = this.get_parent().allocation;
let gridBox = this.get_theme_node().get_content_box(parentBox);
box = this.get_theme_node().get_content_box(gridBox);
}
let children = this._getVisibleChildren();
let availWidth = box.x2 - box.x1;
@ -846,7 +832,7 @@ var PaginatedIconGrid = new Lang.Class({
for (let i = 0; i < children.length; i++) {
let childBox = this._calculateChildBox(children[i], x, y, box);
children[i].allocate(childBox, flags);
this._grid.set_skip_paint(children[i], false);
children[i].show();
columnIndex++;
if (columnIndex == nColumns) {
@ -861,7 +847,7 @@ var PaginatedIconGrid = new Lang.Class({
} else
x += this._getHItemSize() + spacing;
}
},
}
// Overriden from IconGrid
_getChildrenToAnimate() {
@ -870,7 +856,7 @@ var PaginatedIconGrid = new Lang.Class({
let lastIndex = firstIndex + this._childrenPerPage;
return children.slice(firstIndex, lastIndex);
},
}
_computePages(availWidthPerPage, availHeightPerPage) {
let [nColumns, usedWidth] = this._computeLayout(availWidthPerPage);
@ -889,24 +875,24 @@ var PaginatedIconGrid = new Lang.Class({
this._nPages = Math.ceil(nRows / this._rowsPerPage);
this._spaceBetweenPages = availHeightPerPage - (this.topPadding + this.bottomPadding) - this._availableHeightPerPageForItems();
this._childrenPerPage = nColumns * this._rowsPerPage;
},
}
adaptToSize(availWidth, availHeight) {
this.parent(availWidth, availHeight);
super.adaptToSize(availWidth, availHeight);
this._computePages(availWidth, availHeight);
},
}
_availableHeightPerPageForItems() {
return this.usedHeightForNRows(this._rowsPerPage) - (this.topPadding + this.bottomPadding);
},
}
nPages() {
return this._nPages;
},
}
getPageHeight() {
return this._availableHeightPerPageForItems();
},
}
getPageY(pageNumber) {
if (!this._nPages)
@ -915,7 +901,7 @@ var PaginatedIconGrid = new Lang.Class({
let firstPageItem = pageNumber * this._childrenPerPage
let childBox = this._getVisibleChildren()[firstPageItem].get_allocation_box();
return childBox.y1 - this.topPadding;
},
}
getItemPage(item) {
let children = this._getVisibleChildren();
@ -925,7 +911,7 @@ var PaginatedIconGrid = new Lang.Class({
return 0;
}
return Math.floor(index / this._childrenPerPage);
},
}
/**
* openExtraSpace:
@ -977,7 +963,7 @@ var PaginatedIconGrid = new Lang.Class({
this._translateChildren(childrenDown, Gtk.DirectionType.DOWN, nRowsDown);
this._translatedChildren = childrenUp.concat(childrenDown);
}
},
}
_translateChildren(children, direction, nRows) {
let translationY = nRows * (this._getVItemSize() + this._getSpacing());
@ -997,7 +983,7 @@ var PaginatedIconGrid = new Lang.Class({
params.onComplete = () => { this.emit('space-opened'); };
Tweener.addTween(children[i], params);
}
},
}
closeExtraSpace() {
if (!this._translatedChildren || !this._translatedChildren.length) {
@ -1017,4 +1003,3 @@ var PaginatedIconGrid = new Lang.Class({
}
}
});
Signals.addSignalMethods(PaginatedIconGrid.prototype);

View File

@ -2,7 +2,6 @@ const Clutter = imports.gi.Clutter;
const Gio = imports.gi.Gio;
const GObject = imports.gi.GObject;
const Gtk = imports.gi.Gtk;
const Lang = imports.lang;
const Meta = imports.gi.Meta;
const Shell = imports.gi.Shell;
const St = imports.gi.St;
@ -16,41 +15,39 @@ const APP_WHITELIST = ['gnome-control-center.desktop'];
var DialogResponse = Meta.InhibitShortcutsDialogResponse;
var InhibitShortcutsDialog = new Lang.Class({
Name: 'InhibitShortcutsDialog',
Extends: GObject.Object,
var InhibitShortcutsDialog = GObject.registerClass({
Implements: [Meta.InhibitShortcutsDialog],
Properties: {
'window': GObject.ParamSpec.override('window', Meta.InhibitShortcutsDialog)
},
}
}, class InhibitShortcutsDialog extends GObject.Object {
_init(window) {
this.parent();
super._init();
this._window = window;
this._dialog = new ModalDialog.ModalDialog();
this._buildLayout();
},
}
get window() {
return this._window;
},
}
set window(window) {
this._window = window;
},
}
get _app() {
let windowTracker = Shell.WindowTracker.get_default();
return windowTracker.get_window_app(this._window);
},
}
_getRestoreAccel() {
let settings = new Gio.Settings({ schema_id: WAYLAND_KEYBINDINGS_SCHEMA });
let accel = settings.get_strv('restore-shortcuts')[0] || '';
return Gtk.accelerator_get_label.apply(null,
Gtk.accelerator_parse(accel));
},
}
_buildLayout() {
let name = this._app ? this._app.get_name() : this._window.title;
@ -82,19 +79,19 @@ var InhibitShortcutsDialog = new Lang.Class({
this._emitResponse(DialogResponse.ALLOW);
},
default: true });
},
}
_emitResponse(response) {
this.emit('response', response);
this._dialog.close();
},
}
vfunc_show() {
if (this._app && APP_WHITELIST.indexOf(this._app.get_id()) != -1)
this._emitResponse(DialogResponse.ALLOW);
else
this._dialog.open();
},
}
vfunc_hide() {
this._dialog.close();

View File

@ -1,7 +1,6 @@
const Clutter = imports.gi.Clutter;
const Gio = imports.gi.Gio;
const GObject = imports.gi.GObject;
const Lang = imports.lang;
const Dialog = imports.ui.dialog;
const ModalDialog = imports.ui.modalDialog;
@ -9,17 +8,17 @@ const KEYBOARD_A11Y_SCHEMA = 'org.gnome.desktop.a11y.keyboard';
const KEY_STICKY_KEYS_ENABLED = 'stickykeys-enable';
const KEY_SLOW_KEYS_ENABLED = 'slowkeys-enable';
var KbdA11yDialog = new Lang.Class({
Name: 'KbdA11yDialog',
Extends: GObject.Object,
var KbdA11yDialog = new GObject.registerClass(
class KbdA11yDialog extends GObject.Object {
_init() {
super._init();
this._a11ySettings = new Gio.Settings({ schema_id: KEYBOARD_A11Y_SCHEMA });
let deviceManager = Clutter.DeviceManager.get_default();
deviceManager.connect('kbd-a11y-flags-changed',
this._showKbdA11yDialog.bind(this));
},
}
_showKbdA11yDialog(deviceManager, newFlags, whatChanged) {
let dialog = new ModalDialog.ModalDialog();

View File

@ -5,7 +5,7 @@ const Clutter = imports.gi.Clutter;
const Gdk = imports.gi.Gdk;
const Gio = imports.gi.Gio;
const GLib = imports.gi.GLib;
const Lang = imports.lang;
const GObject = imports.gi.GObject;
const Meta = imports.gi.Meta;
const Shell = imports.gi.Shell;
const Signals = imports.signals;
@ -55,15 +55,13 @@ const defaultKeysPost = [
[{ width: 1.5, action: 'languageMenu', extraClassName: 'layout-key' }, { width: 1.5, action: 'hide', extraClassName: 'hide-key' }] ],
];
var KeyContainer = new Lang.Class({
Name: 'KeyContainer',
Extends: St.Widget,
var KeyContainer = new GObject.registerClass(
class KeyContainer extends St.Widget {
_init() {
let gridLayout = new Clutter.GridLayout({ orientation: Clutter.Orientation.HORIZONTAL,
column_homogeneous: true,
row_homogeneous: true });
this.parent({ layout_manager: gridLayout });
super._init({ layout_manager: gridLayout });
this._gridLayout = gridLayout;
this._currentRow = 0;
this._currentCol = 0;
@ -71,7 +69,7 @@ var KeyContainer = new Lang.Class({
this._currentRow = null;
this._rows = [];
},
}
appendRow(length) {
this._currentRow++;
@ -81,7 +79,7 @@ var KeyContainer = new Lang.Class({
row.keys = [];
row.width = 0;
this._rows.push(row);
},
}
appendKey(key, width = 1, height = 1) {
let keyInfo = {
@ -98,7 +96,7 @@ var KeyContainer = new Lang.Class({
this._currentCol += width;
this._maxCols = Math.max(this._currentCol, this._maxCols);
},
}
vfunc_allocate(box, flags) {
if (box.get_width() > 0 && box.get_height() > 0 && this._maxCols > 0) {
@ -122,8 +120,8 @@ var KeyContainer = new Lang.Class({
}
}
this.parent (box, flags);
},
super.vfunc_allocate(box, flags);
}
layoutButtons() {
let nCol = 0, nRow = 0;
@ -155,33 +153,28 @@ var KeyContainer = new Lang.Class({
}
});
var Suggestions = new Lang.Class({
Name: 'Suggestions',
_init() {
var Suggestions = class {
constructor() {
this.actor = new St.BoxLayout({ style_class: 'word-suggestions',
vertical: false });
this.actor.show();
},
}
add(word, callback) {
let button = new St.Button({ label: word });
button.connect('clicked', callback);
this.actor.add(button);
},
}
clear() {
this.actor.remove_all_children();
},
});
}
};
Signals.addSignalMethods(Suggestions.prototype);
var LanguageSelectionPopup = new Lang.Class({
Name: 'LanguageSelectionPopup',
Extends: PopupMenu.PopupMenu,
_init(actor) {
this.parent(actor, 0.5, St.Side.BOTTOM);
var LanguageSelectionPopup = class extends PopupMenu.PopupMenu {
constructor(actor) {
super(actor, 0.5, St.Side.BOTTOM);
let inputSourceManager = InputSourceManager.getInputSourceManager();
let inputSources = inputSourceManager.inputSources;
@ -195,19 +188,14 @@ var LanguageSelectionPopup = new Lang.Class({
}
this.addMenuItem(new PopupMenu.PopupSeparatorMenuItem());
this.addAction(_("Region & Language Settings"), this._launchSettings.bind(this));
this.addSettingsAction(_("Region & Language Settings"), 'gnome-region-panel.desktop');
this._capturedEventId = 0;
this._unmapId = actor.connect('notify::mapped', () => {
if (!actor.is_mapped())
this.close(true);
});
},
_launchSettings() {
Util.spawn(['gnome-control-center', 'region']);
this.close(true);
},
}
_onCapturedEvent(actor, event) {
if (event.get_source() == this.actor ||
@ -218,35 +206,33 @@ var LanguageSelectionPopup = new Lang.Class({
this.close(true);
return Clutter.EVENT_STOP;
},
}
open(animate) {
this.parent(animate);
super.open(animate);
this._capturedEventId = global.stage.connect('captured-event',
this._onCapturedEvent.bind(this));
},
}
close(animate) {
this.parent(animate);
super.close(animate);
if (this._capturedEventId != 0) {
global.stage.disconnect(this._capturedEventId);
this._capturedEventId = 0;
}
},
}
destroy() {
if (this._capturedEventId != 0)
global.stage.disconnect(this._capturedEventId);
if (this._unmapId != 0)
this.sourceActor.disconnect(this._unmapId);
this.parent();
},
});
super.destroy();
}
};
var Key = new Lang.Class({
Name: 'Key',
_init(key, extendedKeys) {
var Key = class Key {
constructor(key) {
this.key = key || "";
this.keyButton = this._makeKey(this.key);
@ -265,14 +251,14 @@ var Key = new Lang.Class({
this._capturedEventId = 0;
this._unmapId = 0;
this._longPress = false;
},
}
_onDestroy() {
if (this._boxPointer) {
this._boxPointer.actor.destroy();
this._boxPointer.destroy();
this._boxPointer = null;
}
},
}
_ensureExtendedKeysPopup() {
if (this._extended_keys.length == 0)
@ -282,7 +268,7 @@ var Key = new Lang.Class({
{ x_fill: true,
y_fill: true,
x_align: St.Align.START });
this._boxPointer.actor.hide();
this._boxPointer.hide();
Main.layoutManager.addChrome(this._boxPointer.actor);
this._boxPointer.setPosition(this.keyButton, 0.5);
@ -290,12 +276,12 @@ var Key = new Lang.Class({
this._boxPointer.actor.add_style_class_name('keyboard-subkeys');
this._getExtendedKeys();
this.keyButton._extended_keys = this._extended_keyboard;
},
}
_getKeyval(key) {
let unicode = String.charCodeAt(key, 0);
return Gdk.unicode_to_keyval(unicode);
},
}
_press(key) {
if (key != this.key || this._extended_keys.length == 0) {
@ -322,7 +308,7 @@ var Key = new Lang.Class({
return GLib.SOURCE_REMOVE;
});
}
},
}
_release(key) {
if (this._pressTimeoutId != 0) {
@ -336,7 +322,7 @@ var Key = new Lang.Class({
this.emit('released', this._getKeyval(key), key);
this._hideSubkeys();
this._longPress = false;
},
}
_onCapturedEvent(actor, event) {
let type = event.type();
@ -353,21 +339,21 @@ var Key = new Lang.Class({
this._hideSubkeys();
return Clutter.EVENT_STOP;
},
}
_showSubkeys() {
this._boxPointer.show(BoxPointer.PopupAnimation.FULL);
this._boxPointer.open(BoxPointer.PopupAnimation.FULL);
this._capturedEventId = global.stage.connect('captured-event',
this._onCapturedEvent.bind(this));
this._unmapId = this.keyButton.connect('notify::mapped', () => {
if (!this.keyButton.is_mapped())
this._hideSubkeys();
});
},
}
_hideSubkeys() {
if (this._boxPointer)
this._boxPointer.hide(BoxPointer.PopupAnimation.FULL);
this._boxPointer.close(BoxPointer.PopupAnimation.FULL);
if (this._capturedEventId) {
global.stage.disconnect(this._capturedEventId);
this._capturedEventId = 0;
@ -377,7 +363,7 @@ var Key = new Lang.Class({
this._unmapId = 0;
}
this._capturedPress = false;
},
}
_makeKey(key) {
let label = GLib.markup_escape_text(key, -1);
@ -423,7 +409,7 @@ var Key = new Lang.Class({
});
return button;
},
}
_getExtendedKeys() {
this._extended_keyboard = new St.BoxLayout({ style_class: 'key-container',
@ -439,35 +425,33 @@ var Key = new Lang.Class({
key.height = this.keyButton.height;
}
this._boxPointer.bin.add_actor(this._extended_keyboard);
},
}
get subkeys() {
return this._boxPointer;
},
}
setWidth(width) {
this.keyButton.keyWidth = width;
},
}
setLatched(latched) {
if (latched)
this.keyButton.add_style_pseudo_class('latched');
else
this.keyButton.remove_style_pseudo_class('latched');
},
});
}
};
Signals.addSignalMethods(Key.prototype);
var KeyboardModel = new Lang.Class({
Name: 'KeyboardModel',
_init(groupName) {
var KeyboardModel = class {
constructor(groupName) {
try {
this._model = this._loadModel(groupName);
} catch (e) {
this._model = this._loadModel('us');
}
},
}
_loadModel(groupName) {
let file = Gio.File.new_for_uri('resource:///org/gnome/shell/osk-layouts/%s.json'.format(groupName));
@ -476,21 +460,19 @@ var KeyboardModel = new Lang.Class({
contents = imports.byteArray.toString(contents);
return JSON.parse(contents);
},
}
getLevels() {
return this._model.levels;
},
}
getKeysForLevel(levelName) {
return this._model.levels.find(level => level == levelName);
}
});
};
var FocusTracker = new Lang.Class({
Name: 'FocusTracker',
_init() {
var FocusTracker = class {
constructor() {
this._currentWindow = null;
this._rect = null;
@ -525,15 +507,15 @@ var FocusTracker = new Lang.Class({
this._ibusManager.connect('focus-out', () => {
this.emit('focus-changed', false);
});
},
}
get currentWindow() {
return this._currentWindow;
},
}
_setCurrentWindow(window) {
this._currentWindow = window;
},
}
_setCurrentRect(rect) {
if (this._currentWindow) {
@ -551,7 +533,7 @@ var FocusTracker = new Lang.Class({
this._rect = rect;
this.emit('position-changed');
},
}
getCurrentRect() {
let rect = { x: this._rect.x, y: this._rect.y,
@ -565,13 +547,11 @@ var FocusTracker = new Lang.Class({
return rect;
}
});
};
Signals.addSignalMethods(FocusTracker.prototype);
var Keyboard = new Lang.Class({
Name: 'Keyboard',
_init() {
var Keyboard = class Keyboard {
constructor() {
this.actor = null;
this._focusInExtendedKeys = false;
@ -629,16 +609,16 @@ var Keyboard = new Lang.Class({
this._keyboardRestingId = 0;
Main.layoutManager.connect('monitors-changed', this._relayout.bind(this));
},
}
get visible() {
return this._keyboardVisible;
},
}
_onFocusPositionChanged(focusTracker) {
let rect = focusTracker.getCurrentRect();
this.setCursorLocation(focusTracker.currentWindow, rect.x, rect.y, rect.width, rect.height);
},
}
_lastDeviceIsTouchscreen() {
if (!this._lastDeviceId)
@ -651,7 +631,7 @@ var Keyboard = new Lang.Class({
return false;
return device.get_device_type() == Clutter.InputDeviceType.TOUCHSCREEN_DEVICE;
},
}
_syncEnabled() {
let wasEnabled = this._enabled;
@ -667,7 +647,7 @@ var Keyboard = new Lang.Class({
if (!this._enabled && wasEnabled)
Main.layoutManager.hideKeyboard(true);
},
}
_destroyKeyboard() {
if (this._keyboardNotifyId)
@ -686,7 +666,7 @@ var Keyboard = new Lang.Class({
this._languagePopup.destroy();
this._languagePopup = null;
}
},
}
_setupKeyboard() {
this.actor = new St.BoxLayout({ name: 'keyboard', vertical: true, reactive: true });
@ -720,7 +700,7 @@ var Keyboard = new Lang.Class({
this._focusNotifyId = global.stage.connect('notify::key-focus', this._onKeyFocusChanged.bind(this));
this._relayout();
},
}
_onKeyFocusChanged() {
let focus = global.stage.key_focus;
@ -744,7 +724,7 @@ var Keyboard = new Lang.Class({
});
GLib.Source.set_name_by_id(this._showIdleId, '[gnome-shell] this.show');
}
},
}
_createLayersForGroup(groupName) {
let keyboardModel = new KeyboardModel(groupName);
@ -769,12 +749,12 @@ var Keyboard = new Lang.Class({
layout.hide();
}
return layers;
},
}
_ensureKeysForGroup(group) {
if (!this._groups[group])
this._groups[group] = this._createLayersForGroup(group);
},
}
_addRowKeys(keys, layout) {
for (let i = 0; i < keys.length; ++i) {
@ -807,7 +787,7 @@ var Keyboard = new Lang.Class({
layout.appendKey(button.actor, button.keyButton.keyWidth);
}
},
}
_popupLanguageMenu(keyActor) {
if (this._languagePopup)
@ -816,7 +796,7 @@ var Keyboard = new Lang.Class({
this._languagePopup = new LanguageSelectionPopup(keyActor);
Main.layoutManager.addChrome(this._languagePopup.actor);
this._languagePopup.open(true);
},
}
_loadDefaultKeys(keys, layout, numLevels, numKeys) {
let extraButton;
@ -881,14 +861,14 @@ var Keyboard = new Lang.Class({
layout.appendKey(extraButton.actor, extraButton.keyButton.keyWidth);
}
},
}
_setCurrentLevelLatched(layout, latched) {
for (let i = 0; layout.shiftKeys[i]; i++) {
let key = layout.shiftKeys[i];
key.setLatched(latched);
}
},
}
_getDefaultKeysForRow(row, numRows, level) {
let pre, post;
@ -906,7 +886,7 @@ var Keyboard = new Lang.Class({
} else {
return [null, null];
}
},
}
_mergeRowKeys(layout, pre, row, post, numLevels) {
if (pre != null)
@ -916,7 +896,7 @@ var Keyboard = new Lang.Class({
if (post != null)
this._loadDefaultKeys(post, layout, numLevels, row.length);
},
}
_loadRows(model, level, numLevels, layout) {
let rows = model.rows;
@ -925,7 +905,7 @@ var Keyboard = new Lang.Class({
let [pre, post] = this._getDefaultKeysForRow(i, rows.length, level);
this._mergeRowKeys (layout, pre, rows[i], post, numLevels);
}
},
}
_getGridSlots() {
let numOfHorizSlots = 0, numOfVertSlots;
@ -940,7 +920,7 @@ var Keyboard = new Lang.Class({
}
return [numOfHorizSlots, numOfVertSlots];
},
}
_relayout() {
let monitor = Main.layoutManager.keyboardMonitor;
@ -951,17 +931,17 @@ var Keyboard = new Lang.Class({
let maxHeight = monitor.height / 3;
this.actor.width = monitor.width;
this.actor.height = maxHeight;
},
}
_onGroupChanged() {
this._ensureKeysForGroup(this._keyboardController.getCurrentGroup());
this._setActiveLayer(0);
},
}
_onKeyboardGroupsChanged(keyboard) {
this._groups = [];
this._onGroupChanged();
},
}
_onKeyboardStateChanged(controller, state) {
let enabled;
@ -978,7 +958,7 @@ var Keyboard = new Lang.Class({
this.show(Main.layoutManager.focusIndex);
else
this.hide();
},
}
_setActiveLayer(activeLevel) {
let activeGroupName = this._keyboardController.getCurrentGroup();
@ -991,20 +971,20 @@ var Keyboard = new Lang.Class({
this._current_page = layers[activeLevel];
this._current_page.show();
},
}
shouldTakeEvent(event) {
let actor = event.get_source();
return Main.layoutManager.keyboardBox.contains(actor) ||
!!actor._extended_keys || !!actor.extended_key;
},
}
_clearKeyboardRestTimer() {
if (!this._keyboardRestingId)
return;
GLib.source_remove(this._keyboardRestingId);
this._keyboardRestingId = 0;
},
}
show(monitor) {
if (!this._enabled)
@ -1030,7 +1010,7 @@ var Keyboard = new Lang.Class({
return GLib.SOURCE_REMOVE;
});
GLib.Source.set_name_by_id(this._keyboardRestingId, '[gnome-shell] this._clearKeyboardRestTimer');
},
}
_show(monitor) {
if (!this._keyboardRequested)
@ -1044,7 +1024,7 @@ var Keyboard = new Lang.Class({
this._setAnimationWindow(this._delayedAnimFocusWindow);
this._delayedAnimFocusWindow = null;
}
},
}
hide() {
if (!this._enabled)
@ -1065,7 +1045,7 @@ var Keyboard = new Lang.Class({
return GLib.SOURCE_REMOVE;
});
GLib.Source.set_name_by_id(this._keyboardRestingId, '[gnome-shell] this._clearKeyboardRestTimer');
},
}
_hide() {
if (this._keyboardRequested)
@ -1073,7 +1053,7 @@ var Keyboard = new Lang.Class({
Main.layoutManager.hideKeyboard();
this.setCursorLocation(null);
},
}
_hideSubkeys() {
if (this._subkeysBoxPointer) {
@ -1085,26 +1065,26 @@ var Keyboard = new Lang.Class({
this._capturedEventId = 0;
}
this._capturedPress = false;
},
}
resetSuggestions() {
if (this._suggestions)
this._suggestions.clear();
},
}
addSuggestion(text, callback) {
if (!this._suggestions)
return;
this._suggestions.add(text, callback);
this._suggestions.actor.show();
},
}
_clearShowIdle() {
if (!this._showIdleId)
return;
GLib.source_remove(this._showIdleId);
this._showIdleId = 0;
},
}
_windowSlideAnimationComplete(window, delta) {
// Synchronize window and actor positions again.
@ -1112,7 +1092,7 @@ var Keyboard = new Lang.Class({
let frameRect = window.get_frame_rect();
frameRect.y += delta;
window.move_frame(true, frameRect.x, frameRect.y);
},
}
_animateWindow(window, show) {
let windowActor = window.get_compositor_private();
@ -1135,7 +1115,7 @@ var Keyboard = new Lang.Class({
onComplete: this._windowSlideAnimationComplete,
onCompleteParams: [window, deltaY] });
}
},
}
_setAnimationWindow(window) {
if (this._animFocusedWindow == window)
@ -1147,7 +1127,7 @@ var Keyboard = new Lang.Class({
this._animateWindow(window, true);
this._animFocusedWindow = window;
},
}
setCursorLocation(window, x, y , w, h) {
let monitor = Main.layoutManager.keyboardMonitor;
@ -1170,14 +1150,11 @@ var Keyboard = new Lang.Class({
}
this._oskFocusWindow = window;
},
});
}
};
var KeyboardController = new Lang.Class({
Name: 'KeyboardController',
_init() {
this.parent();
var KeyboardController = class {
constructor() {
let deviceManager = Clutter.DeviceManager.get_default();
this._virtualDevice = deviceManager.create_virtual_device(Clutter.InputDeviceType.KEYBOARD_DEVICE);
@ -1195,24 +1172,24 @@ var KeyboardController = new Lang.Class({
Main.inputMethod.connect('input-panel-state', (o, state) => {
this.emit('panel-state', state);
});
},
}
_onSourcesModified() {
this.emit('groups-changed');
},
}
_onSourceChanged(inputSourceManager, oldSource) {
let source = inputSourceManager.currentSource;
this._currentSource = source;
this.emit('active-group', source.id);
},
}
_onContentPurposeHintsChanged(method) {
let hints = method.content_hints;
let purpose = method.content_purpose;
// XXX: hook numeric/emoji/etc special keyboards
},
}
getGroups() {
let inputSources = this._inputSourceManager.inputSources;
@ -1224,11 +1201,11 @@ var KeyboardController = new Lang.Class({
}
return groups;
},
}
getCurrentGroup() {
return this._currentSource.xkbId;
},
}
commitString(string, fromKey) {
if (string == null)
@ -1239,16 +1216,16 @@ var KeyboardController = new Lang.Class({
Main.inputMethod.commit(string);
return true;
},
}
keyvalPress(keyval) {
this._virtualDevice.notify_keyval(Clutter.get_current_event_time(),
keyval, Clutter.KeyState.PRESSED);
},
}
keyvalRelease(keyval) {
this._virtualDevice.notify_keyval(Clutter.get_current_event_time(),
keyval, Clutter.KeyState.RELEASED);
},
});
}
};
Signals.addSignalMethods(KeyboardController.prototype);

View File

@ -3,7 +3,6 @@
const Clutter = imports.gi.Clutter;
const GLib = imports.gi.GLib;
const GObject = imports.gi.GObject;
const Lang = imports.lang;
const Meta = imports.gi.Meta;
const Shell = imports.gi.Shell;
const Signals = imports.signals;
@ -36,9 +35,7 @@ function isPopupMetaWindow(actor) {
}
}
var MonitorConstraint = new Lang.Class({
Name: 'MonitorConstraint',
Extends: Clutter.Constraint,
var MonitorConstraint = GObject.registerClass({
Properties: {'primary': GObject.ParamSpec.boolean('primary',
'Primary', 'Track primary monitor',
GObject.ParamFlags.READABLE | GObject.ParamFlags.WRITABLE,
@ -51,18 +48,18 @@ var MonitorConstraint = new Lang.Class({
'Work-area', 'Track monitor\'s work-area',
GObject.ParamFlags.READABLE | GObject.ParamFlags.WRITABLE,
false)},
}, class MonitorConstraint extends Clutter.Constraint {
_init(props) {
this._primary = false;
this._index = -1;
this._workArea = false;
this.parent(props);
},
super._init(props);
}
get primary() {
return this._primary;
},
}
set primary(v) {
if (v)
@ -71,11 +68,11 @@ var MonitorConstraint = new Lang.Class({
if (this.actor)
this.actor.queue_relayout();
this.notify('primary');
},
}
get index() {
return this._index;
},
}
set index(v) {
this._primary = false;
@ -83,11 +80,11 @@ var MonitorConstraint = new Lang.Class({
if (this.actor)
this.actor.queue_relayout();
this.notify('index');
},
}
get work_area() {
return this._workArea;
},
}
set work_area(v) {
if (v == this._workArea)
@ -96,7 +93,7 @@ var MonitorConstraint = new Lang.Class({
if (this.actor)
this.actor.queue_relayout();
this.notify('work-area');
},
}
vfunc_set_actor(actor) {
if (actor) {
@ -124,8 +121,8 @@ var MonitorConstraint = new Lang.Class({
this._workareasChangedId = 0;
}
this.parent(actor);
},
super.vfunc_set_actor(actor);
}
vfunc_update_allocation(actor, actorBox) {
if (!this._primary && this._index < 0)
@ -153,21 +150,19 @@ var MonitorConstraint = new Lang.Class({
}
});
var Monitor = new Lang.Class({
Name: 'Monitor',
_init(index, geometry) {
var Monitor = class Monitor {
constructor(index, geometry) {
this.index = index;
this.x = geometry.x;
this.y = geometry.y;
this.width = geometry.width;
this.height = geometry.height;
},
}
get inFullscreen() {
return global.display.get_monitor_in_fullscreen(this.index);
}
})
};
const defaultParams = {
trackFullscreen: false,
@ -175,10 +170,16 @@ const defaultParams = {
affectsInputRegion: true
};
var LayoutManager = new Lang.Class({
Name: 'LayoutManager',
var LayoutManager = GObject.registerClass({
Signals: { 'hot-corners-changed': {},
'startup-complete': {},
'startup-prepared': {},
'monitors-changed': {},
'keyboard-visible-changed': { param_types: [GObject.TYPE_BOOLEAN] } },
}, class LayoutManager extends GObject.Object {
_init() {
super._init();
this._rtl = (Clutter.get_default_text_direction() == Clutter.TextDirection.RTL);
this.monitors = [];
this.primaryMonitor = null;
@ -203,21 +204,12 @@ var LayoutManager = new Lang.Class({
global.stage.no_clear_hint = true;
// Set up stage hierarchy to group all UI actors under one container.
this.uiGroup = new Shell.GenericContainer({ name: 'uiGroup' });
this.uiGroup = new St.Widget({ name: 'uiGroup' });
this.uiGroup.set_flags(Clutter.ActorFlags.NO_LAYOUT);
this.uiGroup.connect('allocate', (actor, box, flags) => {
let children = actor.get_children();
for (let i = 0; i < children.length; i++)
children[i].allocate_preferred_size(flags);
});
this.uiGroup.connect('get-preferred-width', (actor, forHeight, alloc) => {
let width = global.stage.width;
[alloc.min_size, alloc.natural_size] = [width, width];
});
this.uiGroup.connect('get-preferred-height', (actor, forWidth, alloc) => {
let height = global.stage.height;
[alloc.min_size, alloc.natural_size] = [height, height];
});
this.uiGroup.add_constraint(new Clutter.BindConstraint({
source: global.stage,
coordinate: Clutter.BindCoordinate.ALL,
}));
global.stage.remove_actor(global.window_group);
this.uiGroup.add_actor(global.window_group);
@ -297,33 +289,33 @@ var LayoutManager = new Lang.Class({
Meta.Background.refresh_all();
});
}
},
}
// This is called by Main after everything else is constructed
init() {
Main.sessionMode.connect('updated', this._sessionUpdated.bind(this));
this._loadBackground();
},
}
showOverview() {
this.overviewGroup.show();
this._inOverview = true;
this._updateVisibility();
},
}
hideOverview() {
this.overviewGroup.hide();
this._inOverview = false;
this._updateVisibility();
},
}
_sessionUpdated() {
this._updateVisibility();
this._queueUpdateRegions();
},
}
_updateMonitors() {
let display = global.display;
@ -361,7 +353,7 @@ var LayoutManager = new Lang.Class({
this.primaryMonitor = null;
this.bottomMonitor = null;
}
},
}
_updateHotCorners() {
// destroy old hot corners
@ -420,11 +412,11 @@ var LayoutManager = new Lang.Class({
}
this.emit('hot-corners-changed');
},
}
_addBackgroundMenu(bgManager) {
BackgroundMenu.addBackgroundMenu(bgManager.backgroundActor, this);
},
}
_createBackgroundManager(monitorIndex) {
let bgManager = new Background.BackgroundManager({ container: this._backgroundGroup,
@ -435,7 +427,7 @@ var LayoutManager = new Lang.Class({
this._addBackgroundMenu(bgManager);
return bgManager;
},
}
_showSecondaryBackgrounds() {
for (let i = 0; i < this.monitors.length; i++) {
@ -449,7 +441,7 @@ var LayoutManager = new Lang.Class({
transition: 'easeOutQuad' });
}
}
},
}
_updateBackgrounds() {
let i;
@ -468,13 +460,13 @@ var LayoutManager = new Lang.Class({
if (i != this.primaryIndex && this._startingUp)
bgManager.backgroundActor.hide();
}
},
}
_updateKeyboardBox() {
this.keyboardBox.set_position(this.keyboardMonitor.x,
this.keyboardMonitor.y + this.keyboardMonitor.height);
this.keyboardBox.set_size(this.keyboardMonitor.width, -1);
},
}
_updateBoxes() {
this.screenShieldGroup.set_position(0, 0);
@ -487,7 +479,7 @@ var LayoutManager = new Lang.Class({
this.panelBox.set_size(this.primaryMonitor.width, -1);
this.keyboardIndex = this.primaryIndex;
},
}
_panelBoxChanged() {
this._updatePanelBarrier();
@ -497,7 +489,7 @@ var LayoutManager = new Lang.Class({
if (corner)
corner.setBarrierSize(size);
});
},
}
_updatePanelBarrier() {
if (this._rightPanelBarrier) {
@ -516,7 +508,7 @@ var LayoutManager = new Lang.Class({
x2: primary.x + primary.width, y2: primary.y + this.panelBox.height,
directions: Meta.BarrierDirection.NEGATIVE_X });
}
},
}
_monitorsChanged() {
this._updateMonitors();
@ -528,7 +520,7 @@ var LayoutManager = new Lang.Class({
this._queueUpdateRegions();
this.emit('monitors-changed');
},
}
_isAboveOrBelowPrimary(monitor) {
let primary = this.monitors[this.primaryIndex];
@ -542,16 +534,16 @@ var LayoutManager = new Lang.Class({
return true;
return false;
},
}
get currentMonitor() {
let index = global.display.get_current_monitor();
return this.monitors[index];
},
}
get keyboardMonitor() {
return this.monitors[this.keyboardIndex];
},
}
get focusIndex() {
let i = Main.layoutManager.primaryIndex;
@ -561,22 +553,22 @@ var LayoutManager = new Lang.Class({
else if (global.display.focus_window != null)
i = global.display.focus_window.get_monitor();
return i;
},
}
get focusMonitor() {
if (this.focusIndex < 0)
return null;
return this.monitors[this.focusIndex];
},
}
set keyboardIndex(v) {
this._keyboardIndex = v;
this._updateKeyboardBox();
},
}
get keyboardIndex() {
return this._keyboardIndex;
},
}
_loadBackground() {
if (!this.primaryMonitor) {
@ -599,7 +591,7 @@ var LayoutManager = new Lang.Class({
this._prepareStartupAnimation();
});
},
}
// Startup Animations
//
@ -665,7 +657,7 @@ var LayoutManager = new Lang.Class({
return GLib.SOURCE_REMOVE;
});
GLib.Source.set_name_by_id(id, '[gnome-shell] this._startupAnimation');
},
}
_startupAnimation() {
if (Meta.is_restart())
@ -674,7 +666,7 @@ var LayoutManager = new Lang.Class({
this._startupAnimationGreeter();
else
this._startupAnimationSession();
},
}
_startupAnimationGreeter() {
Tweener.addTween(this.panelBox,
@ -683,7 +675,7 @@ var LayoutManager = new Lang.Class({
transition: 'easeOutQuad',
onComplete: this._startupAnimationComplete,
onCompleteScope: this });
},
}
_startupAnimationSession() {
Tweener.addTween(this.uiGroup,
@ -694,7 +686,7 @@ var LayoutManager = new Lang.Class({
transition: 'easeOutQuad',
onComplete: this._startupAnimationComplete,
onCompleteScope: this });
},
}
_startupAnimationComplete() {
this._coverPane.destroy();
@ -715,7 +707,7 @@ var LayoutManager = new Lang.Class({
this._queueUpdateRegions();
this.emit('startup-complete');
},
}
showKeyboard() {
this.keyboardBox.show();
@ -728,7 +720,7 @@ var LayoutManager = new Lang.Class({
onCompleteScope: this
});
this.emit('keyboard-visible-changed', true);
},
}
_showKeyboardComplete() {
// Poke Chrome to update the input shape; it doesn't notice
@ -738,7 +730,7 @@ var LayoutManager = new Lang.Class({
this._keyboardHeightNotifyId = this.keyboardBox.connect('notify::height', () => {
this.keyboardBox.anchor_y = this.keyboardBox.height;
});
},
}
hideKeyboard(immediate) {
if (this._keyboardHeightNotifyId) {
@ -755,12 +747,12 @@ var LayoutManager = new Lang.Class({
});
this.emit('keyboard-visible-changed', false);
},
}
_hideKeyboardComplete() {
this.keyboardBox.hide();
this._updateRegions();
},
}
// setDummyCursorGeometry:
//
@ -775,7 +767,7 @@ var LayoutManager = new Lang.Class({
setDummyCursorGeometry(x, y, w, h) {
this.dummyCursor.set_position(Math.round(x), Math.round(y));
this.dummyCursor.set_size(Math.round(w), Math.round(h));
},
}
// addChrome:
// @actor: an actor to add to the chrome
@ -801,7 +793,7 @@ var LayoutManager = new Lang.Class({
if (this.uiGroup.contains(global.top_window_group))
this.uiGroup.set_child_below_sibling(actor, global.top_window_group);
this._trackActor(actor, params);
},
}
// trackChrome:
// @actor: a descendant of the chrome to begin tracking
@ -833,7 +825,7 @@ var LayoutManager = new Lang.Class({
}
this._trackActor(actor, params);
},
}
// untrackChrome:
// @actor: an actor previously tracked via trackChrome()
@ -841,7 +833,7 @@ var LayoutManager = new Lang.Class({
// Undoes the effect of trackChrome()
untrackChrome(actor) {
this._untrackActor(actor);
},
}
// removeChrome:
// @actor: a chrome actor
@ -850,7 +842,7 @@ var LayoutManager = new Lang.Class({
removeChrome(actor) {
this.uiGroup.remove_actor(actor);
this._untrackActor(actor);
},
}
_findActor(actor) {
for (let i = 0; i < this._trackedActors.length; i++) {
@ -859,7 +851,7 @@ var LayoutManager = new Lang.Class({
return i;
}
return -1;
},
}
_trackActor(actor, params) {
if (this._findActor(actor) != -1)
@ -879,7 +871,7 @@ var LayoutManager = new Lang.Class({
this._trackedActors.push(actorData);
this._updateActorVisibility(actorData);
this._queueUpdateRegions();
},
}
_untrackActor(actor) {
let i = this._findActor(actor);
@ -894,7 +886,7 @@ var LayoutManager = new Lang.Class({
actor.disconnect(actorData.destroyId);
this._queueUpdateRegions();
},
}
_updateActorVisibility(actorData) {
if (!actorData.trackFullscreen)
@ -904,7 +896,7 @@ var LayoutManager = new Lang.Class({
actorData.actor.visible = !(global.window_group.visible &&
monitor &&
monitor.inFullscreen);
},
}
_updateVisibility() {
let windowsVisible = Main.sessionMode.hasWindows && !this._inOverview;
@ -913,7 +905,7 @@ var LayoutManager = new Lang.Class({
global.top_window_group.visible = windowsVisible;
this._trackedActors.forEach(this._updateActorVisibility.bind(this));
},
}
getWorkAreaForMonitor(monitorIndex) {
// Assume that all workspaces will have the same
@ -921,7 +913,7 @@ var LayoutManager = new Lang.Class({
let workspaceManager = global.workspace_manager;
let ws = workspaceManager.get_workspace_by_index(0);
return ws.get_work_area_for_monitor(monitorIndex);
},
}
// This call guarantees that we return some monitor to simplify usage of it
// In practice all tracked actors should be visible on some monitor anyway
@ -930,14 +922,14 @@ var LayoutManager = new Lang.Class({
let [w, h] = actor.get_transformed_size();
let rect = new Meta.Rectangle({ x: x, y: y, width: w, height: h });
return global.display.get_monitor_index_for_rect(rect);
},
}
findMonitorForActor(actor) {
let index = this.findIndexForActor(actor);
if (index >= 0 && index < this.monitors.length)
return this.monitors[index];
return null;
},
}
_queueUpdateRegions() {
if (this._startingUp)
@ -946,19 +938,19 @@ var LayoutManager = new Lang.Class({
if (!this._updateRegionIdle)
this._updateRegionIdle = Meta.later_add(Meta.LaterType.BEFORE_REDRAW,
this._updateRegions.bind(this));
},
}
_getWindowActorsForWorkspace(workspace) {
return global.get_window_actors().filter(actor => {
let win = actor.meta_window;
return win.located_on_workspace(workspace);
});
},
}
_updateFullscreen() {
this._updateVisibility();
this._queueUpdateRegions();
},
}
_windowsRestacked() {
let changed = false;
@ -970,7 +962,7 @@ var LayoutManager = new Lang.Class({
this._updateVisibility();
this._queueUpdateRegions();
}
},
}
_updateRegions() {
if (this._updateRegionIdle) {
@ -1070,25 +1062,22 @@ var LayoutManager = new Lang.Class({
}
return GLib.SOURCE_REMOVE;
},
}
modalEnded() {
// We don't update the stage input region while in a modal,
// so queue an update now.
this._queueUpdateRegions();
},
}
});
Signals.addSignalMethods(LayoutManager.prototype);
// HotCorner:
//
// This class manages a "hot corner" that can toggle switching to
// overview.
var HotCorner = new Lang.Class({
Name: 'HotCorner',
_init(layoutManager, monitor, x, y) {
var HotCorner = class HotCorner {
constructor(layoutManager, monitor, x, y) {
// We use this flag to mark the case where the user has entered the
// hot corner and has not left both the hot corner and a surrounding
// guard area (the "environs"). This avoids triggering the hot corner
@ -1116,7 +1105,7 @@ var HotCorner = new Lang.Class({
layoutManager.uiGroup.add_actor(this._ripple1);
layoutManager.uiGroup.add_actor(this._ripple2);
layoutManager.uiGroup.add_actor(this._ripple3);
},
}
setBarrierSize(size) {
if (this._verticalBarrier) {
@ -1151,7 +1140,7 @@ var HotCorner = new Lang.Class({
this._pressureBarrier.addBarrier(this._verticalBarrier);
this._pressureBarrier.addBarrier(this._horizontalBarrier);
}
},
}
_setupFallbackCornerIfNeeded(layoutManager) {
if (!global.display.supports_extended_barriers()) {
@ -1186,7 +1175,7 @@ var HotCorner = new Lang.Class({
this._corner.connect('leave-event',
this._onCornerLeft.bind(this));
}
},
}
destroy() {
this.setBarrierSize(0);
@ -1195,7 +1184,7 @@ var HotCorner = new Lang.Class({
if (this.actor)
this.actor.destroy();
},
}
_animRipple(ripple, delay, time, startScale, startOpacity, finalScale) {
// We draw a ripple by using a source image and animating it scaling
@ -1225,7 +1214,7 @@ var HotCorner = new Lang.Class({
transition: 'linear',
onUpdate() { ripple.opacity = 255 * Math.sqrt(ripple._opacity); },
onComplete() { ripple.visible = false; } });
},
}
_rippleAnimation() {
// Show three concentric ripples expanding outwards; the exact
@ -1236,17 +1225,17 @@ var HotCorner = new Lang.Class({
this._animRipple(this._ripple1, 0.0, 0.83, 0.25, 1.0, 1.5);
this._animRipple(this._ripple2, 0.05, 1.0, 0.0, 0.7, 1.25);
this._animRipple(this._ripple3, 0.35, 1.0, 0.0, 0.3, 1);
},
}
_toggleOverview() {
if (this._monitor.inFullscreen)
if (this._monitor.inFullscreen && !Main.overview.visible)
return;
if (Main.overview.shouldToggleByCornerOrButton()) {
this._rippleAnimation();
Main.overview.toggle();
}
},
}
handleDragOver(source, actor, x, y, time) {
if (source != Main.xdndHandler)
@ -1255,7 +1244,7 @@ var HotCorner = new Lang.Class({
this._toggleOverview();
return DND.DragMotionResult.CONTINUE;
},
}
_onCornerEntered() {
if (!this._entered) {
@ -1263,26 +1252,24 @@ var HotCorner = new Lang.Class({
this._toggleOverview();
}
return Clutter.EVENT_PROPAGATE;
},
}
_onCornerLeft(actor, event) {
if (event.get_related() != this.actor)
this._entered = false;
// Consume event, otherwise this will confuse onEnvironsLeft
return Clutter.EVENT_STOP;
},
}
_onEnvironsLeft(actor, event) {
if (event.get_related() != this._corner)
this._entered = false;
return Clutter.EVENT_PROPAGATE;
}
});
};
var PressureBarrier = new Lang.Class({
Name: 'PressureBarrier',
_init(threshold, timeout, actionMode) {
var PressureBarrier = class PressureBarrier {
constructor(threshold, timeout, actionMode) {
this._threshold = threshold;
this._timeout = timeout;
this._actionMode = actionMode;
@ -1291,57 +1278,57 @@ var PressureBarrier = new Lang.Class({
this._isTriggered = false;
this._reset();
},
}
addBarrier(barrier) {
barrier._pressureHitId = barrier.connect('hit', this._onBarrierHit.bind(this));
barrier._pressureLeftId = barrier.connect('left', this._onBarrierLeft.bind(this));
this._barriers.push(barrier);
},
}
_disconnectBarrier(barrier) {
barrier.disconnect(barrier._pressureHitId);
barrier.disconnect(barrier._pressureLeftId);
},
}
removeBarrier(barrier) {
this._disconnectBarrier(barrier);
this._barriers.splice(this._barriers.indexOf(barrier), 1);
},
}
destroy() {
this._barriers.forEach(this._disconnectBarrier.bind(this));
this._barriers = [];
},
}
setEventFilter(filter) {
this._eventFilter = filter;
},
}
_reset() {
this._barrierEvents = [];
this._currentPressure = 0;
this._lastTime = 0;
},
}
_isHorizontal(barrier) {
return barrier.y1 == barrier.y2;
},
}
_getDistanceAcrossBarrier(barrier, event) {
if (this._isHorizontal(barrier))
return Math.abs(event.dy);
else
return Math.abs(event.dx);
},
}
_getDistanceAlongBarrier(barrier, event) {
if (this._isHorizontal(barrier))
return Math.abs(event.dx);
else
return Math.abs(event.dy);
},
}
_trimBarrierEvents() {
// Events are guaranteed to be sorted in time order from
@ -1365,7 +1352,7 @@ var PressureBarrier = new Lang.Class({
}
this._barrierEvents = this._barrierEvents.slice(firstNewEvent);
},
}
_onBarrierLeft(barrier, event) {
barrier._isHit = false;
@ -1373,13 +1360,13 @@ var PressureBarrier = new Lang.Class({
this._reset();
this._isTriggered = false;
}
},
}
_trigger() {
this._isTriggered = true;
this.emit('trigger');
this._reset();
},
}
_onBarrierHit(barrier, event) {
barrier._isHit = true;
@ -1421,5 +1408,5 @@ var PressureBarrier = new Lang.Class({
if (this._currentPressure >= this._threshold)
this._trigger();
}
});
};
Signals.addSignalMethods(PressureBarrier.prototype);

View File

@ -1,7 +1,7 @@
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
const Clutter = imports.gi.Clutter;
const Lang = imports.lang;
const GObject = imports.gi.GObject;
const Meta = imports.gi.Meta;
const Signals = imports.signals;
const St = imports.gi.St;
@ -27,38 +27,36 @@ t = clamp(t, 0.0, 1.0);\n\
float pixel_brightness = mix(1.0, 1.0 - vignette_sharpness, t);\n\
cogl_color_out.a = cogl_color_out.a * (1 - pixel_brightness * brightness);';
var RadialShaderQuad = new Lang.Class({
Name: 'RadialShaderQuad',
Extends: Shell.GLSLQuad,
var RadialShaderQuad = GObject.registerClass(
class RadialShaderQuad extends Shell.GLSLQuad {
_init(params) {
this.parent(params);
super._init(params);
this._brightnessLocation = this.get_uniform_location('brightness');
this._sharpnessLocation = this.get_uniform_location('vignette_sharpness');
this.brightness = 1.0;
this.vignetteSharpness = 0.0;
},
}
vfunc_build_pipeline() {
this.add_glsl_snippet(Shell.SnippetHook.FRAGMENT,
VIGNETTE_DECLARATIONS, VIGNETTE_CODE, true);
},
}
get brightness() {
return this._brightness;
},
}
set brightness(v) {
this._brightness = v;
this.set_uniform_float(this._brightnessLocation,
1, [this._brightness]);
},
}
get vignetteSharpness() {
return this._sharpness;
},
}
set vignetteSharpness(v) {
this._sharpness = v;
@ -91,10 +89,8 @@ var RadialShaderQuad = new Lang.Class({
* @container and will track any changes in its size. You can override
* this by passing an explicit width and height in @params.
*/
var Lightbox = new Lang.Class({
Name: 'Lightbox',
_init(container, params) {
var Lightbox = class Lightbox {
constructor(container, params) {
params = Params.parse(params, { inhibitEvents: false,
width: null,
height: null,
@ -137,7 +133,7 @@ var Lightbox = new Lang.Class({
this._actorRemovedSignalId = container.connect('actor-removed', this._actorRemoved.bind(this));
this._highlighted = null;
},
}
_actorAdded(container, newChild) {
let children = this._container.get_children();
@ -159,7 +155,7 @@ var Lightbox = new Lang.Class({
if (prevChild != -1) // paranoia
this._children.splice(prevChild + 1, 0, newChild);
}
},
}
show(fadeInTime) {
fadeInTime = fadeInTime || 0;
@ -189,7 +185,7 @@ var Lightbox = new Lang.Class({
}
this.actor.show();
},
}
hide(fadeOutTime) {
fadeOutTime = fadeOutTime || 0;
@ -217,7 +213,7 @@ var Lightbox = new Lang.Class({
}
});
}
},
}
_actorRemoved(container, child) {
let index = this._children.indexOf(child);
@ -226,7 +222,7 @@ var Lightbox = new Lang.Class({
if (child == this._highlighted)
this._highlighted = null;
},
}
/**
* highlight:
@ -257,7 +253,7 @@ var Lightbox = new Lang.Class({
}
this._highlighted = window;
},
}
/**
* destroy:
@ -266,7 +262,7 @@ var Lightbox = new Lang.Class({
*/
destroy() {
this.actor.destroy();
},
}
/**
* _onDestroy:
@ -280,5 +276,5 @@ var Lightbox = new Lang.Class({
this.highlight(null);
}
});
};
Signals.addSignalMethods(Lightbox.prototype);

View File

@ -4,13 +4,13 @@ const Clutter = imports.gi.Clutter;
const Cogl = imports.gi.Cogl;
const GLib = imports.gi.GLib;
const Gio = imports.gi.Gio;
const GObject = imports.gi.GObject;
const Gtk = imports.gi.Gtk;
const Meta = imports.gi.Meta;
const Pango = imports.gi.Pango;
const St = imports.gi.St;
const Shell = imports.gi.Shell;
const Signals = imports.signals;
const Lang = imports.lang;
const Mainloop = imports.mainloop;
const System = imports.system;
@ -34,7 +34,6 @@ var commandHeader = 'const Clutter = imports.gi.Clutter; ' +
'const Meta = imports.gi.Meta; ' +
'const Shell = imports.gi.Shell; ' +
'const Main = imports.ui.main; ' +
'const Lang = imports.lang; ' +
'const Tweener = imports.ui.tweener; ' +
/* Utility functions...we should probably be able to use these
* in the shell core code too. */
@ -61,14 +60,12 @@ function _getAutoCompleteGlobalKeywords() {
return keywords.concat(windowProperties).concat(headerProperties);
}
var AutoComplete = new Lang.Class({
Name: 'AutoComplete',
_init(entry) {
var AutoComplete = class AutoComplete {
constructor(entry) {
this._entry = entry;
this._entry.connect('key-press-event', this._entryKeyPressEvent.bind(this));
this._lastTabTime = global.get_current_time();
},
}
_processCompletionRequest(event) {
if (event.completions.length == 0) {
@ -90,7 +87,7 @@ var AutoComplete = new Lang.Class({
} else if (event.completions.length > 1 && event.tabType === 'double') {
this.emit('suggest', { completions: event.completions});
}
},
}
_entryKeyPressEvent(actor, event) {
let cursorPos = this._entry.clutter_text.get_cursor_position();
@ -113,7 +110,7 @@ var 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",
// the string "bc" will be appended to this._entry
@ -123,21 +120,19 @@ var AutoComplete = new Lang.Class({
this._entry.clutter_text.insert_text(additionalCompletionText, cursorPos);
}
});
};
Signals.addSignalMethods(AutoComplete.prototype);
var Notebook = new Lang.Class({
Name: 'Notebook',
_init() {
var Notebook = class Notebook {
constructor() {
this.actor = new St.BoxLayout({ vertical: true });
this.tabControls = new St.BoxLayout({ style_class: 'labels' });
this._selectedIndex = -1;
this._tabs = [];
},
}
appendPage(name, child) {
let labelBox = new St.BoxLayout({ style_class: 'notebook-tab',
@ -170,7 +165,7 @@ var Notebook = new Lang.Class({
if (this._selectedIndex == -1)
this.selectIndex(0);
},
}
_unselect() {
if (this._selectedIndex < 0)
@ -179,7 +174,7 @@ var Notebook = new Lang.Class({
tabData.labelBox.remove_style_pseudo_class('selected');
tabData.scrollView.hide();
this._selectedIndex = -1;
},
}
selectIndex(index) {
if (index == this._selectedIndex)
@ -201,7 +196,7 @@ var Notebook = new Lang.Class({
tabData.scrollView.show();
this._selectedIndex = index;
this.emit('selection', tabData.child);
},
}
selectChild(child) {
if (child == null)
@ -215,26 +210,26 @@ var Notebook = new Lang.Class({
}
}
}
},
}
scrollToBottom(index) {
let tabData = this._tabs[index];
tabData._scrollToBottom = true;
},
}
_onAdjustValueChanged(tabData) {
let vAdjust = tabData.scrollView.vscroll.adjustment;
if (vAdjust.value < (vAdjust.upper - vAdjust.lower - 0.5))
tabData._scrolltoBottom = false;
},
}
_onAdjustScopeChanged(tabData) {
if (!tabData._scrollToBottom)
return;
let vAdjust = tabData.scrollView.vscroll.adjustment;
vAdjust.value = vAdjust.upper - vAdjust.page_size;
},
}
nextTab() {
let nextIndex = this._selectedIndex;
@ -243,7 +238,7 @@ var Notebook = new Lang.Class({
}
this.selectIndex(nextIndex);
},
}
prevTab() {
let prevIndex = this._selectedIndex;
@ -253,7 +248,7 @@ var Notebook = new Lang.Class({
this.selectIndex(prevIndex);
}
});
};
Signals.addSignalMethods(Notebook.prototype);
function objectToString(o) {
@ -265,10 +260,8 @@ function objectToString(o) {
}
}
var ObjLink = new Lang.Class({
Name: 'ObjLink',
_init(lookingGlass, o, title) {
var ObjLink = class ObjLink {
constructor(lookingGlass, o, title) {
let text;
if (title)
text = title;
@ -285,17 +278,15 @@ var ObjLink = new Lang.Class({
this.actor.connect('clicked', this._onClicked.bind(this));
this._lookingGlass = lookingGlass;
},
}
_onClicked(link) {
this._lookingGlass.inspectObject(this._obj, this.actor);
}
});
};
var Result = new Lang.Class({
Name: 'Result',
_init(lookingGlass, command, o, index) {
var Result = class Result {
constructor(lookingGlass, command, o, index) {
this.index = index;
this.o = o;
@ -313,12 +304,10 @@ var Result = new Lang.Class({
let objLink = new ObjLink(this._lookingGlass, o);
box.add(objLink.actor);
}
});
};
var WindowList = new Lang.Class({
Name: 'WindowList',
_init(lookingGlass) {
var WindowList = class WindowList {
constructor(lookingGlass) {
this.actor = new St.BoxLayout({ name: 'Windows', vertical: true, style: 'spacing: 8px' });
let tracker = Shell.WindowTracker.get_default();
this._updateId = Main.initializeDeferredWork(this.actor, this._updateWindowList.bind(this));
@ -326,7 +315,7 @@ var WindowList = new Lang.Class({
tracker.connect('tracked-windows-changed', this._updateWindowList.bind(this));
this._lookingGlass = lookingGlass;
},
}
_updateWindowList() {
this.actor.destroy_all_children();
@ -360,13 +349,11 @@ var WindowList = new Lang.Class({
}
}
}
});
};
Signals.addSignalMethods(WindowList.prototype);
var ObjInspector = new Lang.Class({
Name: 'ObjInspector',
_init(lookingGlass) {
var ObjInspector = class ObjInspector {
constructor(lookingGlass) {
this._obj = null;
this._previousObj = null;
@ -381,7 +368,7 @@ var ObjInspector = new Lang.Class({
this.actor.add_actor(this._container);
this._lookingGlass = lookingGlass;
},
}
selectObject(obj, skipPrevious) {
if (!skipPrevious)
@ -435,7 +422,7 @@ var ObjInspector = new Lang.Class({
this._container.add_actor(hbox);
}
}
},
}
open(sourceActor) {
if (this._open)
@ -451,7 +438,7 @@ var ObjInspector = new Lang.Class({
} else {
this.actor.set_scale(1, 1);
}
},
}
close() {
if (!this._open)
@ -460,23 +447,21 @@ var ObjInspector = new Lang.Class({
this.actor.hide();
this._previousObj = null;
this._obj = null;
},
}
_onInsert() {
let obj = this._obj;
this.close();
this._lookingGlass.insertObject(obj);
},
}
_onBack() {
this.selectObject(this._previousObj, true);
}
});
var RedBorderEffect = new Lang.Class({
Name: 'RedBorderEffect',
Extends: Clutter.Effect,
};
var RedBorderEffect = GObject.registerClass(
class RedBorderEffect extends Clutter.Effect {
vfunc_paint() {
let actor = this.get_actor();
actor.continue_paint();
@ -496,23 +481,24 @@ var RedBorderEffect = new Lang.Class({
geom.width - width, geom.height - width);
Cogl.rectangle(0, geom.height - width,
width, width);
},
}
});
var Inspector = new Lang.Class({
Name: 'Inspector',
var Inspector = GObject.registerClass({
Signals: { 'closed': {},
'target': { param_types: [Clutter.Actor.$gtype, GObject.TYPE_DOUBLE, GObject.TYPE_DOUBLE] } },
}, class Inspector extends Clutter.Actor {
_init(lookingGlass) {
let container = new Shell.GenericContainer({ width: 0,
height: 0 });
container.connect('allocate', this._allocate.bind(this));
Main.uiGroup.add_actor(container);
super._init({ width: 0,
height: 0 });
Main.uiGroup.add_actor(this);
let eventHandler = new St.BoxLayout({ name: 'LookingGlassDialog',
vertical: false,
reactive: true });
this._eventHandler = eventHandler;
container.add_actor(eventHandler);
this.add_actor(eventHandler);
this._displayText = new St.Label();
eventHandler.add(this._displayText, { expand: true });
@ -532,9 +518,11 @@ var Inspector = new Lang.Class({
this._pointerTarget = null;
this._lookingGlass = lookingGlass;
},
}
vfunc_allocate(box, flags) {
this.set_allocation(box, flags);
_allocate(actor, box, flags) {
if (!this._eventHandler)
return;
@ -549,7 +537,7 @@ var Inspector = new Lang.Class({
childBox.y1 = primary.y + Math.floor((primary.height - natHeight) / 2);
childBox.y2 = childBox.y1 + natHeight;
this._eventHandler.allocate(childBox, flags);
},
}
_close() {
Clutter.ungrab_pointer();
@ -557,13 +545,13 @@ var Inspector = new Lang.Class({
this._eventHandler.destroy();
this._eventHandler = null;
this.emit('closed');
},
}
_onKeyPressEvent(actor, event) {
if (event.get_key_symbol() == Clutter.Escape)
this._close();
return Clutter.EVENT_STOP;
},
}
_onButtonPressEvent(actor, event) {
if (this._target) {
@ -572,7 +560,7 @@ var Inspector = new Lang.Class({
}
this._close();
return Clutter.EVENT_STOP;
},
}
_onScrollEvent(actor, event) {
switch (event.get_scroll_direction()) {
@ -606,12 +594,12 @@ var Inspector = new Lang.Class({
break;
}
return Clutter.EVENT_STOP;
},
}
_onMotionEvent(actor, event) {
this._update(event);
return Clutter.EVENT_STOP;
},
}
_update(event) {
let [stageX, stageY] = event.get_coords();
@ -631,12 +619,8 @@ var Inspector = new Lang.Class({
}
});
Signals.addSignalMethods(Inspector.prototype);
var Extensions = new Lang.Class({
Name: 'Extensions',
_init(lookingGlass) {
var Extensions = class Extensions {
constructor(lookingGlass) {
this._lookingGlass = lookingGlass;
this.actor = new St.BoxLayout({ vertical: true,
name: 'lookingGlassExtensions' });
@ -653,7 +637,7 @@ var Extensions = new Lang.Class({
ExtensionSystem.connect('extension-loaded',
this._loadExtension.bind(this));
},
}
_loadExtension(o, uuid) {
let extension = ExtensionUtils.extensions[uuid];
@ -668,20 +652,20 @@ var Extensions = new Lang.Class({
this._numExtensions ++;
this._extensionsList.add(extensionDisplay);
},
}
_onViewSource(actor) {
let extension = actor._extension;
let uri = extension.dir.get_uri();
Gio.app_info_launch_default_for_uri(uri, global.create_app_launch_context(0, -1));
this._lookingGlass.close();
},
}
_onWebPage(actor) {
let extension = actor._extension;
Gio.app_info_launch_default_for_uri(extension.metadata.url, global.create_app_launch_context(0, -1));
this._lookingGlass.close();
},
}
_onViewErrors(actor) {
let extension = actor._extension;
@ -709,7 +693,7 @@ var Extensions = new Lang.Class({
}
actor._isShowing = shouldShow;
},
}
_stateToString(extensionState) {
switch (extensionState) {
@ -726,7 +710,7 @@ var Extensions = new Lang.Class({
return _("Downloading");
}
return 'Unknown'; // Not translated, shouldn't appear
},
}
_createExtensionDisplay(extension) {
let box = new St.BoxLayout({ style_class: 'lg-extension', vertical: true });
@ -774,12 +758,10 @@ var Extensions = new Lang.Class({
return box;
}
});
};
var LookingGlass = new Lang.Class({
Name: 'LookingGlass',
_init() {
var LookingGlass = class LookingGlass {
constructor() {
this._borderPaintTarget = null;
this._redBorderEffect = new RedBorderEffect();
@ -913,7 +895,7 @@ var LookingGlass = new Lang.Class({
});
this._resize();
},
}
_updateFont() {
let fontName = this._interfaceSettings.get_string('monospace-font-name');
@ -923,7 +905,7 @@ var LookingGlass = new Lang.Class({
this.actor.style =
'font-size: ' + fontDesc.get_size() / 1024. + (fontDesc.get_size_is_absolute() ? 'px' : 'pt') + ';'
+ 'font-family: "' + fontDesc.get_family() + '";';
},
}
setBorderPaintTarget(obj) {
if (this._borderPaintTarget != null)
@ -931,7 +913,7 @@ var LookingGlass = new Lang.Class({
this._borderPaintTarget = obj;
if (this._borderPaintTarget != null)
this._borderPaintTarget.add_effect(this._redBorderEffect);
},
}
_pushResult(command, obj) {
let index = this._results.length + this._offset;
@ -951,7 +933,7 @@ var LookingGlass = new Lang.Class({
// Scroll to bottom
this._notebook.scrollToBottom(0);
},
}
_showCompletions(completions) {
if (!this._completionActor) {
@ -980,7 +962,7 @@ var LookingGlass = new Lang.Class({
opacity: 255
});
}
},
}
_hideCompletions() {
if (this._completionActor) {
@ -994,46 +976,49 @@ var LookingGlass = new Lang.Class({
}
});
}
},
}
_evaluate(command) {
this._history.addItem(command);
let fullCmd = commandHeader + command;
let lines = command.split(';');
lines.push(`return ${lines.pop()}`);
let fullCmd = commandHeader + lines.join(';');
let resultObj;
try {
resultObj = eval(fullCmd);
resultObj = Function(fullCmd)();
} catch (e) {
resultObj = '<exception ' + e + '>';
}
this._pushResult(command, resultObj);
this._entry.text = '';
},
}
inspect(x, y) {
return global.stage.get_actor_at_pos(Clutter.PickMode.REACTIVE, x, y);
},
}
getIt() {
return this._it;
},
}
getResult(idx) {
return this._results[idx - this._offset].o;
},
}
toggle() {
if (this._open)
this.close();
else
this.open();
},
}
_queueResize() {
Meta.later_add(Meta.LaterType.BEFORE_REDRAW, () => { this._resize(); });
},
}
_resize() {
let primary = Main.layoutManager.primaryMonitor;
@ -1049,16 +1034,16 @@ var LookingGlass = new Lang.Class({
this._objInspector.actor.set_size(Math.floor(myWidth * 0.8), Math.floor(myHeight * 0.8));
this._objInspector.actor.set_position(this.actor.x + Math.floor(myWidth * 0.1),
this._targetY + Math.floor(myHeight * 0.1));
},
}
insertObject(obj) {
this._pushResult('<insert>', obj);
},
}
inspectObject(obj, sourceActor) {
this._objInspector.open(sourceActor);
this._objInspector.selectObject(obj);
},
}
// Handle key events which are relevant for all tabs of the LookingGlass
_globalKeyPressEvent(actor, event) {
@ -1081,7 +1066,7 @@ var LookingGlass = new Lang.Class({
}
}
return Clutter.EVENT_PROPAGATE;
},
}
open() {
if (this._open)
@ -1103,7 +1088,7 @@ var LookingGlass = new Lang.Class({
transition: 'easeOutQuad',
y: this._targetY
});
},
}
close() {
if (!this._open)
@ -1126,5 +1111,5 @@ var LookingGlass = new Lang.Class({
}
});
}
});
};
Signals.addSignalMethods(LookingGlass.prototype);

View File

@ -7,7 +7,6 @@ const Gio = imports.gi.Gio;
const GLib = imports.gi.GLib;
const Shell = imports.gi.Shell;
const St = imports.gi.St;
const Lang = imports.lang;
const Mainloop = imports.mainloop;
const Meta = imports.gi.Meta;
const Signals = imports.signals;
@ -53,10 +52,8 @@ const CROSS_HAIRS_CLIP_KEY = 'cross-hairs-clip';
let magDBusService = null;
var Magnifier = new Lang.Class({
Name: 'Magnifier',
_init() {
var Magnifier = class Magnifier {
constructor() {
// Magnifier is a manager of ZoomRegions.
this._zoomRegions = [];
@ -84,7 +81,7 @@ var Magnifier = new Lang.Class({
// Export to dbus.
magDBusService = new MagnifierDBus.ShellMagnifier();
this.setActive(showAtLaunch);
},
}
/**
* showSystemCursor:
@ -92,7 +89,7 @@ var Magnifier = new Lang.Class({
*/
showSystemCursor() {
this._cursorTracker.set_pointer_visible(true);
},
}
/**
* hideSystemCursor:
@ -100,7 +97,7 @@ var Magnifier = new Lang.Class({
*/
hideSystemCursor() {
this._cursorTracker.set_pointer_visible(false);
},
}
/**
* setActive:
@ -131,7 +128,7 @@ var Magnifier = new Lang.Class({
// Notify interested parties of this change
this.emit('active-changed', activate);
},
}
/**
* isActive:
@ -144,7 +141,7 @@ var Magnifier = new Lang.Class({
return false;
else
return this._zoomRegions[0].isActive();
},
}
/**
* startTrackingMouse:
@ -155,7 +152,7 @@ var Magnifier = new Lang.Class({
let interval = 1000 / Clutter.get_default_frame_rate();
this._pointerWatch = PointerWatcher.getPointerWatcher().addWatch(interval, this.scrollToMousePos.bind(this));
}
},
}
/**
* stopTrackingMouse:
@ -166,7 +163,7 @@ var Magnifier = new Lang.Class({
this._pointerWatch.remove();
this._pointerWatch = null;
},
}
/**
* isTrackingMouse:
@ -174,7 +171,7 @@ var Magnifier = new Lang.Class({
*/
isTrackingMouse() {
return !!this._mouseTrackingId;
},
}
/**
* scrollToMousePos:
@ -200,7 +197,7 @@ var Magnifier = new Lang.Class({
this.showSystemCursor();
}
return true;
},
}
/**
* createZoomRegion:
@ -229,7 +226,7 @@ var Magnifier = new Lang.Class({
zoomRegion.addCrosshairs(this._crossHairs);
return zoomRegion;
},
}
/**
* addZoomRegion:
@ -243,7 +240,7 @@ var Magnifier = new Lang.Class({
if (!this.isTrackingMouse())
this.startTrackingMouse();
}
},
}
/**
* getZoomRegions:
@ -252,7 +249,7 @@ var Magnifier = new Lang.Class({
*/
getZoomRegions() {
return this._zoomRegions;
},
}
/**
* clearAllZoomRegions:
@ -265,7 +262,7 @@ var Magnifier = new Lang.Class({
this._zoomRegions.length = 0;
this.stopTrackingMouse();
this.showSystemCursor();
},
}
/**
* addCrosshairs:
@ -291,7 +288,7 @@ var Magnifier = new Lang.Class({
this._zoomRegions.forEach ((zoomRegion, index, array) => {
zoomRegion.addCrosshairs(theCrossHairs);
});
},
}
/**
* setCrosshairsVisible:
@ -308,7 +305,7 @@ var Magnifier = new Lang.Class({
if (this._crossHairs)
this._crossHairs.hide();
}
},
}
/**
* setCrosshairsColor:
@ -320,7 +317,7 @@ var Magnifier = new Lang.Class({
let [res, clutterColor] = Clutter.Color.from_string(color);
this._crossHairs.setColor(clutterColor);
}
},
}
/**
* getCrosshairsColor:
@ -334,7 +331,7 @@ var Magnifier = new Lang.Class({
}
else
return '#00000000';
},
}
/**
* setCrosshairsThickness:
@ -345,7 +342,7 @@ var Magnifier = new Lang.Class({
setCrosshairsThickness(thickness) {
if (this._crossHairs)
this._crossHairs.setThickness(thickness);
},
}
/**
* getCrosshairsThickness:
@ -358,7 +355,7 @@ var Magnifier = new Lang.Class({
return this._crossHairs.getThickness();
else
return 0;
},
}
/**
* setCrosshairsOpacity:
@ -367,7 +364,7 @@ var Magnifier = new Lang.Class({
setCrosshairsOpacity(opacity) {
if (this._crossHairs)
this._crossHairs.setOpacity(opacity * 255);
},
}
/**
* getCrosshairsOpacity:
@ -378,7 +375,7 @@ var Magnifier = new Lang.Class({
return this._crossHairs.getOpacity() / 255.0;
else
return 0.0;
},
}
/**
* setCrosshairsLength:
@ -389,7 +386,7 @@ var Magnifier = new Lang.Class({
setCrosshairsLength(length) {
if (this._crossHairs)
this._crossHairs.setLength(length);
},
}
/**
* getCrosshairsLength:
@ -402,7 +399,7 @@ var Magnifier = new Lang.Class({
return this._crossHairs.getLength();
else
return 0;
},
}
/**
* setCrosshairsClip:
@ -420,7 +417,7 @@ var Magnifier = new Lang.Class({
if (this._crossHairs)
this._crossHairs.setClip([0, 0]);
}
},
}
/**
* getCrosshairsClip:
@ -434,7 +431,7 @@ var Magnifier = new Lang.Class({
}
else
return false;
},
}
//// Private methods ////
@ -442,7 +439,7 @@ var Magnifier = new Lang.Class({
Shell.util_cursor_tracker_to_clutter(this._cursorTracker, this._mouseSprite);
let [xHot, yHot] = this._cursorTracker.get_hot();
this._mouseSprite.set_anchor_point(xHot, yHot);
},
}
_settingsInit(zoomRegion) {
this._appSettings = new Gio.Settings({ schema_id: APPLICATIONS_SCHEMA });
@ -560,7 +557,7 @@ var Magnifier = new Lang.Class({
this.setCrosshairsVisible(showCrosshairs);
return this._appSettings.get_boolean(SHOW_KEY);
},
}
_updateScreenPosition() {
// Applies only to the first zoom region.
@ -570,7 +567,7 @@ var Magnifier = new Lang.Class({
if (position != GDesktopEnums.MagnifierScreenPosition.FULL_SCREEN)
this._updateLensMode();
}
},
}
_updateMagFactor() {
// Applies only to the first zoom region.
@ -579,14 +576,14 @@ var Magnifier = new Lang.Class({
let magFactor = parseFloat(this._settings.get_double(MAG_FACTOR_KEY).toFixed(2));
this._zoomRegions[0].setMagFactor(magFactor, magFactor);
}
},
}
_updateLensMode() {
// Applies only to the first zoom region.
if (this._zoomRegions.length) {
this._zoomRegions[0].setLensMode(this._settings.get_boolean(LENS_MODE_KEY));
}
},
}
_updateClampMode() {
// Applies only to the first zoom region.
@ -595,7 +592,7 @@ var Magnifier = new Lang.Class({
!this._settings.get_boolean(CLAMP_MODE_KEY)
);
}
},
}
_updateMouseTrackingMode() {
// Applies only to the first zoom region.
@ -604,7 +601,7 @@ var Magnifier = new Lang.Class({
this._settings.get_enum(MOUSE_TRACKING_KEY)
);
}
},
}
_updateFocusTrackingMode() {
// Applies only to the first zoom region.
@ -613,7 +610,7 @@ var Magnifier = new Lang.Class({
this._settings.get_enum(FOCUS_TRACKING_KEY)
);
}
},
}
_updateCaretTrackingMode() {
// Applies only to the first zoom region.
@ -622,7 +619,7 @@ var Magnifier = new Lang.Class({
this._settings.get_enum(CARET_TRACKING_KEY)
);
}
},
}
_updateInvertLightness() {
// Applies only to the first zoom region.
@ -631,7 +628,7 @@ var Magnifier = new Lang.Class({
this._settings.get_boolean(INVERT_LIGHTNESS_KEY)
);
}
},
}
_updateColorSaturation() {
// Applies only to the first zoom region.
@ -640,7 +637,7 @@ var Magnifier = new Lang.Class({
this._settings.get_double(COLOR_SATURATION_KEY)
);
}
},
}
_updateBrightness() {
// Applies only to the first zoom region.
@ -651,7 +648,7 @@ var Magnifier = new Lang.Class({
brightness.b = this._settings.get_double(BRIGHT_BLUE_KEY);
this._zoomRegions[0].setBrightness(brightness);
}
},
}
_updateContrast() {
// Applies only to the first zoom region.
@ -663,13 +660,11 @@ var Magnifier = new Lang.Class({
this._zoomRegions[0].setContrast(contrast);
}
}
});
};
Signals.addSignalMethods(Magnifier.prototype);
var ZoomRegion = new Lang.Class({
Name: 'ZoomRegion',
_init(magnifier, mouseSourceActor) {
var ZoomRegion = class ZoomRegion {
constructor(magnifier, mouseSourceActor) {
this._magnifier = magnifier;
this._focusCaretTracker = new FocusCaretTracker.FocusCaretTracker();
@ -715,7 +710,7 @@ var ZoomRegion = new Lang.Class({
this._updateCaret.bind(this));
this._focusCaretTracker.connect('focus-changed',
this._updateFocus.bind(this));
},
}
_updateFocus(caller, event) {
let component = event.source.get_component_iface();
@ -732,7 +727,7 @@ var ZoomRegion = new Lang.Class({
[this._xFocus, this._yFocus] = [extents.x + (extents.width / 2),
extents.y + (extents.height / 2)];
this._centerFromFocusPosition();
},
}
_updateCaret(caller, event) {
let text = event.source.get_text_iface();
@ -748,7 +743,7 @@ var ZoomRegion = new Lang.Class({
[this._xCaret, this._yCaret] = [extents.x, extents.y];
this._centerFromCaretPosition();
},
}
/**
* setActive:
@ -771,7 +766,7 @@ var ZoomRegion = new Lang.Class({
this._syncCaretTracking();
this._syncFocusTracking();
},
}
/**
* isActive:
@ -779,7 +774,7 @@ var ZoomRegion = new Lang.Class({
*/
isActive() {
return this._magView != null;
},
}
/**
* setMagFactor:
@ -793,7 +788,7 @@ var ZoomRegion = new Lang.Class({
this._changeROI({ xMagFactor: xMagFactor,
yMagFactor: yMagFactor,
redoCursorTracking: this._followingCursor });
},
}
/**
* getMagFactor:
@ -804,7 +799,7 @@ var ZoomRegion = new Lang.Class({
*/
getMagFactor() {
return [this._xMagFactor, this._yMagFactor];
},
}
/**
* setMouseTrackingMode
@ -814,7 +809,7 @@ var ZoomRegion = new Lang.Class({
if (mode >= GDesktopEnums.MagnifierMouseTrackingMode.NONE &&
mode <= GDesktopEnums.MagnifierMouseTrackingMode.PUSH)
this._mouseTrackingMode = mode;
},
}
/**
* getMouseTrackingMode
@ -822,7 +817,7 @@ var ZoomRegion = new Lang.Class({
*/
getMouseTrackingMode() {
return this._mouseTrackingMode;
},
}
/**
* setFocusTrackingMode
@ -831,7 +826,7 @@ var ZoomRegion = new Lang.Class({
setFocusTrackingMode(mode) {
this._focusTrackingMode = mode;
this._syncFocusTracking();
},
}
/**
* setCaretTrackingMode
@ -840,7 +835,7 @@ var ZoomRegion = new Lang.Class({
setCaretTrackingMode(mode) {
this._caretTrackingMode = mode;
this._syncCaretTracking();
},
}
_syncFocusTracking() {
let enabled = this._focusTrackingMode != GDesktopEnums.MagnifierFocusTrackingMode.NONE &&
@ -850,7 +845,7 @@ var ZoomRegion = new Lang.Class({
this._focusCaretTracker.registerFocusListener();
else
this._focusCaretTracker.deregisterFocusListener();
},
}
_syncCaretTracking() {
let enabled = this._caretTrackingMode != GDesktopEnums.MagnifierCaretTrackingMode.NONE &&
@ -860,7 +855,7 @@ var ZoomRegion = new Lang.Class({
this._focusCaretTracker.registerCaretListener();
else
this._focusCaretTracker.deregisterCaretListener();
},
}
/**
* setViewPort
@ -872,7 +867,7 @@ var ZoomRegion = new Lang.Class({
setViewPort(viewPort) {
this._setViewPort(viewPort);
this._screenPosition = GDesktopEnums.MagnifierScreenPosition.NONE;
},
}
/**
* setROI
@ -890,7 +885,7 @@ var ZoomRegion = new Lang.Class({
yMagFactor: this._viewPortHeight / roi.height,
xCenter: roi.x + roi.width / 2,
yCenter: roi.y + roi.height / 2 });
},
}
/**
* getROI:
@ -907,7 +902,7 @@ var ZoomRegion = new Lang.Class({
return [this._xCenter - roiWidth / 2,
this._yCenter - roiHeight / 2,
roiWidth, roiHeight];
},
}
/**
* setLensMode:
@ -919,7 +914,7 @@ var ZoomRegion = new Lang.Class({
this._lensMode = lensMode;
if (!this._lensMode)
this.setScreenPosition (this._screenPosition);
},
}
/**
* isLensMode:
@ -928,7 +923,7 @@ var ZoomRegion = new Lang.Class({
*/
isLensMode() {
return this._lensMode;
},
}
/**
* setClampScrollingAtEdges:
@ -940,7 +935,7 @@ var ZoomRegion = new Lang.Class({
this._clampScrollingAtEdges = clamp;
if (clamp)
this._changeROI();
},
}
/**
* setTopHalf:
@ -954,7 +949,7 @@ var ZoomRegion = new Lang.Class({
viewPort.height = global.screen_height/2;
this._setViewPort(viewPort);
this._screenPosition = GDesktopEnums.MagnifierScreenPosition.TOP_HALF;
},
}
/**
* setBottomHalf:
@ -968,7 +963,7 @@ var ZoomRegion = new Lang.Class({
viewPort.height = global.screen_height/2;
this._setViewPort(viewPort);
this._screenPosition = GDesktopEnums.MagnifierScreenPosition.BOTTOM_HALF;
},
}
/**
* setLeftHalf:
@ -982,7 +977,7 @@ var ZoomRegion = new Lang.Class({
viewPort.height = global.screen_height;
this._setViewPort(viewPort);
this._screenPosition = GDesktopEnums.MagnifierScreenPosition.LEFT_HALF;
},
}
/**
* setRightHalf:
@ -996,7 +991,7 @@ var ZoomRegion = new Lang.Class({
viewPort.height = global.screen_height;
this._setViewPort(viewPort);
this._screenPosition = GDesktopEnums.MagnifierScreenPosition.RIGHT_HALF;
},
}
/**
* setFullScreenMode:
@ -1012,7 +1007,7 @@ var ZoomRegion = new Lang.Class({
this.setViewPort(viewPort);
this._screenPosition = GDesktopEnums.MagnifierScreenPosition.FULL_SCREEN;
},
}
/**
* setScreenPosition:
@ -1040,7 +1035,7 @@ var ZoomRegion = new Lang.Class({
this.setRightHalf();
break;
}
},
}
/**
* getScreenPosition:
@ -1050,7 +1045,7 @@ var ZoomRegion = new Lang.Class({
*/
getScreenPosition() {
return this._screenPosition;
},
}
/**
* scrollToMousePos:
@ -1066,14 +1061,14 @@ var ZoomRegion = new Lang.Class({
// Determine whether the system mouse pointer is over this zoom region.
return this._isMouseOverRegion();
},
}
_clearScrollContentsTimer() {
if (this._scrollContentsTimerId != 0) {
Mainloop.source_remove(this._scrollContentsTimerId);
this._scrollContentsTimerId = 0;
}
},
}
_scrollContentsToDelayed(x, y) {
if (this._pointerIdleMonitor.get_idletime() >= POINTER_REST_TIME) {
@ -1086,7 +1081,7 @@ var ZoomRegion = new Lang.Class({
this._scrollContentsToDelayed(x, y);
return GLib.SOURCE_REMOVE;
});
},
}
/**
* scrollContentsTo:
@ -1101,7 +1096,7 @@ var ZoomRegion = new Lang.Class({
this._followingCursor = false;
this._changeROI({ xCenter: x,
yCenter: y });
},
}
/**
* addCrosshairs:
@ -1116,7 +1111,7 @@ var ZoomRegion = new Lang.Class({
if (crossHairs && this.isActive()) {
this._crossHairsActor = crossHairs.addToZoomRegion(this, this._mouseActor);
}
},
}
/**
* setInvertLightness:
@ -1127,7 +1122,7 @@ var ZoomRegion = new Lang.Class({
this._invertLightness = flag;
if (this._magShaderEffects)
this._magShaderEffects.setInvertLightness(this._invertLightness);
},
}
/**
* getInvertLightness:
@ -1136,7 +1131,7 @@ var ZoomRegion = new Lang.Class({
*/
getInvertLightness() {
return this._invertLightness;
},
}
/**
* setColorSaturation:
@ -1149,7 +1144,7 @@ var ZoomRegion = new Lang.Class({
this._colorSaturation = saturation;
if (this._magShaderEffects)
this._magShaderEffects.setColorSaturation(this._colorSaturation);
},
}
/**
* getColorSaturation:
@ -1157,7 +1152,7 @@ var ZoomRegion = new Lang.Class({
*/
getColorSaturation() {
return this._colorSaturation;
},
}
/**
* setBrightness:
@ -1173,7 +1168,7 @@ var ZoomRegion = new Lang.Class({
this._brightness.b = brightness.b;
if (this._magShaderEffects)
this._magShaderEffects.setBrightness(this._brightness);
},
}
/**
* setContrast:
@ -1189,7 +1184,7 @@ var ZoomRegion = new Lang.Class({
this._contrast.b = contrast.b;
if (this._magShaderEffects)
this._magShaderEffects.setContrast(this._contrast);
},
}
/**
* getContrast:
@ -1203,7 +1198,7 @@ var ZoomRegion = new Lang.Class({
contrast.g = this._contrast.g;
contrast.b = this._contrast.b;
return contrast;
},
}
//// Private methods ////
@ -1249,7 +1244,7 @@ var ZoomRegion = new Lang.Class({
this._magShaderEffects.setInvertLightness(this._invertLightness);
this._magShaderEffects.setBrightness(this._brightness);
this._magShaderEffects.setContrast(this._contrast);
},
}
_destroyActors() {
if (this._mouseActor == this._mouseSourceActor)
@ -1265,7 +1260,7 @@ var ZoomRegion = new Lang.Class({
this._uiGroupClone = null;
this._mouseActor = null;
this._crossHairsActor = null;
},
}
_setViewPort(viewPort, fromROIUpdate) {
// Sets the position of the zoom region on the screen
@ -1290,7 +1285,7 @@ var ZoomRegion = new Lang.Class({
if (this.isActive() && this._isMouseOverRegion())
this._magnifier.hideSystemCursor();
},
}
_changeROI(params) {
// Updates the area we are viewing; the magnification factors
@ -1341,7 +1336,7 @@ var ZoomRegion = new Lang.Class({
this._updateCloneGeometry();
this._updateMousePosition();
},
}
_isMouseOverRegion() {
// Return whether the system mouse sprite is over this ZoomRegion. If the
@ -1357,7 +1352,7 @@ var ZoomRegion = new Lang.Class({
);
}
return mouseIsOver;
},
}
_isFullScreen() {
// Does the magnified view occupy the whole screen? Note that this
@ -1370,7 +1365,7 @@ var ZoomRegion = new Lang.Class({
this._viewPortHeight != global.screen_height)
return false;
return true;
},
}
_centerFromMousePosition() {
// Determines where the center should be given the current cursor
@ -1390,7 +1385,7 @@ var ZoomRegion = new Lang.Class({
}
return null; // Should never be hit
},
}
_centerFromCaretPosition() {
let xCaret = this._xCaret;
@ -1404,7 +1399,7 @@ var ZoomRegion = new Lang.Class({
[xCaret, yCaret] = this._centerFromPointCentered(xCaret, yCaret);
this._scrollContentsToDelayed(xCaret, yCaret);
},
}
_centerFromFocusPosition() {
let xFocus = this._xFocus;
@ -1418,7 +1413,7 @@ var ZoomRegion = new Lang.Class({
[xFocus, yFocus] = this._centerFromPointCentered(xFocus, yFocus);
this._scrollContentsToDelayed(xFocus, yFocus);
},
}
_centerFromPointPush(xPoint, yPoint) {
let [xRoi, yRoi, widthRoi, heightRoi] = this.getROI();
@ -1439,7 +1434,7 @@ var ZoomRegion = new Lang.Class({
yPos += (yPoint - yRoiBottom);
return [xPos, yPos];
},
}
_centerFromPointProportional(xPoint, yPoint) {
let [xRoi, yRoi, widthRoi, heightRoi] = this.getROI();
@ -1456,18 +1451,18 @@ var ZoomRegion = new Lang.Class({
let yPos = yPoint - yProportion * (heightRoi /2 - yPadding);
return [xPos, yPos];
},
}
_centerFromPointCentered(xPoint, yPoint) {
return [xPoint, yPoint];
},
}
_screenToViewPort(screenX, screenY) {
// Converts coordinates relative to the (unmagnified) screen to coordinates
// relative to the origin of this._magView
return [this._viewPortWidth / 2 + (screenX - this._xCenter) * this._xMagFactor,
this._viewPortHeight / 2 + (screenY - this._yCenter) * this._yMagFactor];
},
}
_updateMagViewGeometry() {
if (!this.isActive())
@ -1480,7 +1475,7 @@ var ZoomRegion = new Lang.Class({
this._magView.set_size(this._viewPortWidth, this._viewPortHeight);
this._magView.set_position(this._viewPortX, this._viewPortY);
},
}
_updateCloneGeometry() {
if (!this.isActive())
@ -1493,7 +1488,7 @@ var ZoomRegion = new Lang.Class({
this._uiGroupClone.set_position(Math.round(x), Math.round(y));
this._updateMousePosition();
},
}
_updateMousePosition() {
if (!this.isActive())
@ -1512,7 +1507,7 @@ var ZoomRegion = new Lang.Class({
this._crossHairsActor.set_position(xMagMouse - groupWidth / 2,
yMagMouse - groupHeight / 2);
}
},
}
_monitorsChanged() {
if (!this.isActive())
@ -1528,12 +1523,10 @@ var ZoomRegion = new Lang.Class({
else
this.setScreenPosition(this._screenPosition);
}
});
};
var Crosshairs = new Lang.Class({
Name: 'Crosshairs',
_init() {
var Crosshairs = class Crosshairs {
constructor() {
// Set the group containing the crosshairs to three times the desktop
// size in case the crosshairs need to appear to be infinite in
@ -1560,12 +1553,12 @@ var Crosshairs = new Lang.Class({
Main.layoutManager.connect('monitors-changed',
this._monitorsChanged.bind(this));
},
}
_monitorsChanged() {
this._actor.set_size(global.screen_width * 3, global.screen_height * 3);
this.reCenter();
},
}
/**
* addToZoomRegion
@ -1599,7 +1592,7 @@ var Crosshairs = new Lang.Class({
}
}
return crosshairsActor;
},
}
/**
* removeFromParent:
@ -1612,7 +1605,7 @@ var Crosshairs = new Lang.Class({
childActor.get_parent().remove_actor(childActor);
else
childActor.destroy();
},
}
/**
* setColor:
@ -1624,7 +1617,7 @@ var Crosshairs = new Lang.Class({
this._horizRightHair.background_color = clutterColor;
this._vertTopHair.background_color = clutterColor;
this._vertBottomHair.background_color = clutterColor;
},
}
/**
* getColor:
@ -1633,7 +1626,7 @@ var Crosshairs = new Lang.Class({
*/
getColor() {
return this._horizLeftHair.get_color();
},
}
/**
* setThickness:
@ -1646,7 +1639,7 @@ var Crosshairs = new Lang.Class({
this._vertTopHair.set_width(thickness);
this._vertBottomHair.set_width(thickness);
this.reCenter();
},
}
/**
* getThickness:
@ -1655,7 +1648,7 @@ var Crosshairs = new Lang.Class({
*/
getThickness() {
return this._horizLeftHair.get_height();
},
}
/**
* setOpacity:
@ -1674,7 +1667,7 @@ var Crosshairs = new Lang.Class({
this._horizRightHair.set_opacity(opacity);
this._vertTopHair.set_opacity(opacity);
this._vertBottomHair.set_opacity(opacity);
},
}
/**
* setLength:
@ -1687,7 +1680,7 @@ var Crosshairs = new Lang.Class({
this._vertTopHair.set_height(length);
this._vertBottomHair.set_height(length);
this.reCenter();
},
}
/**
* getLength:
@ -1696,7 +1689,7 @@ var Crosshairs = new Lang.Class({
*/
getLength() {
return this._horizLeftHair.get_width();
},
}
/**
* setClip:
@ -1717,7 +1710,7 @@ var Crosshairs = new Lang.Class({
this._clipSize = [0, 0];
this.reCenter();
}
},
}
/**
* show:
@ -1728,7 +1721,7 @@ var Crosshairs = new Lang.Class({
// Clones don't share visibility.
for (let i = 0; i < this._clones.length; i++)
this._clones[i].show();
},
}
/**
* hide:
@ -1739,7 +1732,7 @@ var Crosshairs = new Lang.Class({
// Clones don't share visibility.
for (let i = 0; i < this._clones.length; i++)
this._clones[i].hide();
},
}
/**
* reCenter:
@ -1773,12 +1766,10 @@ var Crosshairs = new Lang.Class({
this._vertTopHair.set_position((groupWidth - thickness) / 2, top);
this._vertBottomHair.set_position((groupWidth - thickness) / 2, bottom);
}
});
};
var MagShaderEffects = new Lang.Class({
Name: 'MagShaderEffects',
_init(uiGroupClone) {
var MagShaderEffects = class MagShaderEffects {
constructor(uiGroupClone) {
this._inverse = new Shell.InvertLightnessEffect();
this._brightnessContrast = new Clutter.BrightnessContrastEffect();
this._colorDesaturation = new Clutter.DesaturateEffect();
@ -1789,7 +1780,7 @@ var MagShaderEffects = new Lang.Class({
this._magView.add_effect(this._inverse);
this._magView.add_effect(this._brightnessContrast);
this._magView.add_effect(this._colorDesaturation);
},
}
/**
* destroyEffects:
@ -1803,7 +1794,7 @@ var MagShaderEffects = new Lang.Class({
this._brightnessContrast = null;
this._inverse = null;
this._magView = null;
},
}
/**
* setInvertLightness:
@ -1812,11 +1803,11 @@ var MagShaderEffects = new Lang.Class({
*/
setInvertLightness(invertFlag) {
this._inverse.set_enabled(invertFlag);
},
}
setColorSaturation(factor) {
this._colorDesaturation.set_factor(1.0 - factor);
},
}
/**
* setBrightness:
@ -1840,7 +1831,7 @@ var MagShaderEffects = new Lang.Class({
(bRed != NO_CHANGE || bGreen != NO_CHANGE || bBlue != NO_CHANGE ||
cRed != NO_CHANGE || cGreen != NO_CHANGE || cBlue != NO_CHANGE)
);
},
}
/**
* Set the contrast of the magnified view.
@ -1865,5 +1856,5 @@ var MagShaderEffects = new Lang.Class({
cRed != NO_CHANGE || cGreen != NO_CHANGE || cBlue != NO_CHANGE ||
bRed != NO_CHANGE || bGreen != NO_CHANGE || bBlue != NO_CHANGE
);
},
});
}
};

View File

@ -1,7 +1,6 @@
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
const Gio = imports.gi.Gio;
const Lang = imports.lang;
const Main = imports.ui.main;
const { loadInterfaceXML } = imports.misc.fileUtils;
@ -22,15 +21,13 @@ const ZoomRegionIface = loadInterfaceXML('org.gnome.Magnifier.ZoomRegion');
// '/org/gnome/Magnifier/ZoomRegion/zoomer1', etc.
let _zoomRegionInstanceCount = 0;
var ShellMagnifier = new Lang.Class({
Name: 'ShellMagnifier',
_init() {
var ShellMagnifier = class ShellMagnifier {
constructor() {
this._zoomers = {};
this._dbusImpl = Gio.DBusExportedObject.wrapJSObject(MagnifierIface, this);
this._dbusImpl.export(Gio.DBus.session, MAG_SERVICE_PATH);
},
}
/**
* setActive:
@ -38,7 +35,7 @@ var ShellMagnifier = new Lang.Class({
*/
setActive(activate) {
Main.magnifier.setActive(activate);
},
}
/**
* isActive:
@ -46,7 +43,7 @@ var ShellMagnifier = new Lang.Class({
*/
isActive() {
return Main.magnifier.isActive();
},
}
/**
* showCursor:
@ -54,7 +51,7 @@ var ShellMagnifier = new Lang.Class({
*/
showCursor() {
Main.magnifier.showSystemCursor();
},
}
/**
* hideCursor:
@ -62,7 +59,7 @@ var ShellMagnifier = new Lang.Class({
*/
hideCursor() {
Main.magnifier.hideSystemCursor();
},
}
/**
* createZoomRegion:
@ -97,7 +94,7 @@ var ShellMagnifier = new Lang.Class({
proxyAndZoomRegion.zoomRegion = realZoomRegion;
this._zoomers[objectPath] = proxyAndZoomRegion;
return objectPath;
},
}
/**
* addZoomRegion:
@ -112,7 +109,7 @@ var ShellMagnifier = new Lang.Class({
}
else
return false;
},
}
/**
* getZoomRegions:
@ -150,7 +147,7 @@ var ShellMagnifier = new Lang.Class({
}
});
return objectPaths;
},
}
/**
* clearAllZoomRegions:
@ -166,7 +163,7 @@ var ShellMagnifier = new Lang.Class({
delete this._zoomers[objectPath];
}
this._zoomers = {};
},
}
/**
* fullScreenCapable:
@ -175,7 +172,7 @@ var ShellMagnifier = new Lang.Class({
*/
fullScreenCapable() {
return true;
},
}
/**
* setCrosswireSize:
@ -184,7 +181,7 @@ var ShellMagnifier = new Lang.Class({
*/
setCrosswireSize(size) {
Main.magnifier.setCrosshairsThickness(size);
},
}
/**
* getCrosswireSize:
@ -193,7 +190,7 @@ var ShellMagnifier = new Lang.Class({
*/
getCrosswireSize() {
return Main.magnifier.getCrosshairsThickness();
},
}
/**
* setCrosswireLength:
@ -202,7 +199,7 @@ var ShellMagnifier = new Lang.Class({
*/
setCrosswireLength(length) {
Main.magnifier.setCrosshairsLength(length);
},
}
/**
* setCrosswireSize:
@ -211,7 +208,7 @@ var ShellMagnifier = new Lang.Class({
*/
getCrosswireLength() {
return Main.magnifier.getCrosshairsLength();
},
}
/**
* setCrosswireClip:
@ -220,7 +217,7 @@ var ShellMagnifier = new Lang.Class({
*/
setCrosswireClip(clip) {
Main.magnifier.setCrosshairsClip(clip);
},
}
/**
* getCrosswireClip:
@ -229,7 +226,7 @@ var ShellMagnifier = new Lang.Class({
*/
getCrosswireClip() {
return Main.magnifier.getCrosshairsClip();
},
}
/**
* setCrosswireColor:
@ -238,7 +235,7 @@ var ShellMagnifier = new Lang.Class({
*/
setCrosswireColor(color) {
Main.magnifier.setCrosshairsColor('#%08x'.format(color));
},
}
/**
* getCrosswireClip:
@ -250,7 +247,7 @@ var ShellMagnifier = new Lang.Class({
// Drop the leading '#'.
return parseInt(colorString.slice(1), 16);
}
});
};
/**
* ShellMagnifierZoomRegion:
@ -258,15 +255,13 @@ var ShellMagnifier = new Lang.Class({
* @zoomerObjectPath: String that is the path to a DBus ZoomRegion.
* @zoomRegion: The actual zoom region associated with the object path.
*/
var ShellMagnifierZoomRegion = new Lang.Class({
Name: 'ShellMagnifierZoomRegion',
_init(zoomerObjectPath, zoomRegion) {
var ShellMagnifierZoomRegion = class ShellMagnifierZoomRegion {
constructor(zoomerObjectPath, zoomRegion) {
this._zoomRegion = zoomRegion;
this._dbusImpl = Gio.DBusExportedObject.wrapJSObject(ZoomRegionIface, this);
this._dbusImpl.export(Gio.DBus.session, zoomerObjectPath);
},
}
/**
* setMagFactor:
@ -278,7 +273,7 @@ var ShellMagnifierZoomRegion = new Lang.Class({
*/
setMagFactor(xMagFactor, yMagFactor) {
this._zoomRegion.setMagFactor(xMagFactor, yMagFactor);
},
}
/**
* getMagFactor:
@ -289,7 +284,7 @@ var ShellMagnifierZoomRegion = new Lang.Class({
*/
getMagFactor() {
return this._zoomRegion.getMagFactor();
},
}
/**
* setRoi:
@ -301,7 +296,7 @@ var ShellMagnifierZoomRegion = new Lang.Class({
setRoi(roi) {
let roiObject = { x: roi[0], y: roi[1], width: roi[2] - roi[0], height: roi[3] - roi[1] };
this._zoomRegion.setROI(roiObject);
},
}
/**
* getRoi:
@ -316,7 +311,7 @@ var ShellMagnifierZoomRegion = new Lang.Class({
roi[2] += roi[0];
roi[3] += roi[1];
return roi;
},
}
/**
* Set the "region of interest" by centering the given screen coordinate
@ -329,7 +324,7 @@ var ShellMagnifierZoomRegion = new Lang.Class({
shiftContentsTo(x, y) {
this._zoomRegion.scrollContentsTo(x, y);
return true;
},
}
/**
* moveResize
@ -340,9 +335,9 @@ var ShellMagnifierZoomRegion = new Lang.Class({
moveResize(viewPort) {
let viewRect = { x: viewPort[0], y: viewPort[1], width: viewPort[2] - viewPort[0], height: viewPort[3] - viewPort[1] };
this._zoomRegion.setViewPort(viewRect);
},
}
destroy() {
this._dbusImpl.unexport();
}
});
};

View File

@ -5,7 +5,6 @@ const Gdk = imports.gi.Gdk;
const Gio = imports.gi.Gio;
const GLib = imports.gi.GLib;
const Gtk = imports.gi.Gtk;
const Lang = imports.lang;
const Mainloop = imports.mainloop;
const Meta = imports.gi.Meta;
const Shell = imports.gi.Shell;
@ -20,6 +19,7 @@ const Environment = imports.ui.environment;
const ExtensionSystem = imports.ui.extensionSystem;
const ExtensionDownloader = imports.ui.extensionDownloader;
const InputMethod = imports.misc.inputMethod;
const Introspect = imports.misc.introspect;
const Keyboard = imports.ui.keyboard;
const MessageTray = imports.ui.messageTray;
const ModalDialog = imports.ui.modalDialog;
@ -82,6 +82,7 @@ var keyboard = null;
var layoutManager = null;
var kbdA11yDialog = null;
var inputMethod = null;
var introspectService = null;
let _startDate;
let _defaultCssStylesheet = null;
let _cssStylesheet = null;
@ -187,6 +188,8 @@ function _initializeUI() {
windowAttentionHandler = new WindowAttentionHandler.WindowAttentionHandler();
componentManager = new Components.ComponentManager();
introspectService = new Introspect.IntrospectService();
layoutManager.init();
overview.init();
@ -696,15 +699,12 @@ function queueDeferredWork(workId) {
}
}
var RestartMessage = new Lang.Class({
Name: 'RestartMessage',
Extends: ModalDialog.ModalDialog,
_init(message) {
this.parent({ shellReactive: true,
styleClass: 'restart-message headline',
shouldFadeIn: false,
destroyOnClose: true });
var RestartMessage = class extends ModalDialog.ModalDialog {
constructor(message) {
super({ shellReactive: true,
styleClass: 'restart-message headline',
shouldFadeIn: false,
destroyOnClose: true });
let label = new St.Label({ text: message });
@ -714,7 +714,7 @@ var RestartMessage = new Lang.Class({
y_align: St.Align.MIDDLE });
this.buttonLayout.hide();
}
});
};
function showRestartMessage(message) {
let restartMessage = new RestartMessage(message);

View File

@ -3,7 +3,6 @@ const Clutter = imports.gi.Clutter;
const Gio = imports.gi.Gio;
const GLib = imports.gi.GLib;
const GObject = imports.gi.GObject;
const Lang = imports.lang;
const Main = imports.ui.main;
const MessageTray = imports.ui.messageTray;
const Meta = imports.gi.Meta;
@ -40,10 +39,8 @@ function _fixMarkup(text, allowMarkup) {
return GLib.markup_escape_text(text, -1);
}
var URLHighlighter = new Lang.Class({
Name: 'URLHighlighter',
_init(text, lineWrap, allowMarkup) {
var URLHighlighter = class URLHighlighter {
constructor(text, lineWrap, allowMarkup) {
if (!text)
text = '';
this.actor = new St.Label({ reactive: true, style_class: 'url-highlighter',
@ -114,7 +111,7 @@ var URLHighlighter = new Lang.Class({
}
return Clutter.EVENT_PROPAGATE;
});
},
}
setMarkup(text, allowMarkup) {
text = text ? _fixMarkup(text, allowMarkup) : '';
@ -124,7 +121,7 @@ var URLHighlighter = new Lang.Class({
/* clutter_text.text contain text without markup */
this._urls = Util.findUrls(this.actor.clutter_text.text);
this._highlightUrls();
},
}
_highlightUrls() {
// text here contain markup
@ -139,7 +136,7 @@ var URLHighlighter = new Lang.Class({
}
markup += this._text.substr(pos);
this.actor.clutter_text.set_markup(markup);
},
}
_findUrlAtPos(event) {
let success;
@ -160,16 +157,14 @@ var URLHighlighter = new Lang.Class({
}
return -1;
}
});
var ScaleLayout = new Lang.Class({
Name: 'ScaleLayout',
Extends: Clutter.BinLayout,
};
var ScaleLayout = new GObject.registerClass(
class ScaleLayout extends Clutter.BinLayout {
_init(params) {
this._container = null;
this.parent(params);
},
super._init(params);
}
_connectContainer(container) {
if (this._container == container)
@ -189,45 +184,43 @@ var ScaleLayout = new Lang.Class({
});
this._signals.push(id);
}
},
}
vfunc_get_preferred_width(container, forHeight) {
this._connectContainer(container);
let [min, nat] = this.parent(container, forHeight);
let [min, nat] = super.vfunc_get_preferred_width(container, forHeight);
return [Math.floor(min * container.scale_x),
Math.floor(nat * container.scale_x)];
},
}
vfunc_get_preferred_height(container, forWidth) {
this._connectContainer(container);
let [min, nat] = this.parent(container, forWidth);
let [min, nat] = super.vfunc_get_preferred_height(container, forWidth);
return [Math.floor(min * container.scale_y),
Math.floor(nat * container.scale_y)];
}
});
var LabelExpanderLayout = new Lang.Class({
Name: 'LabelExpanderLayout',
Extends: Clutter.LayoutManager,
var LabelExpanderLayout = GObject.registerClass({
Properties: { 'expansion': GObject.ParamSpec.double('expansion',
'Expansion',
'Expansion of the layout, between 0 (collapsed) ' +
'and 1 (fully expanded',
GObject.ParamFlags.READABLE | GObject.ParamFlags.WRITABLE,
0, 1, 0)},
}, class LabelExpanderLayout extends Clutter.LayoutManager {
_init(params) {
this._expansion = 0;
this._expandLines = DEFAULT_EXPAND_LINES;
this.parent(params);
},
super._init(params);
}
get expansion() {
return this._expansion;
},
}
set expansion(v) {
if (v == this._expansion)
@ -240,7 +233,7 @@ var LabelExpanderLayout = new Lang.Class({
this._container.get_child_at_index(i).visible = (i == visibleIndex);
this.layout_changed();
},
}
set expandLines(v) {
if (v == this._expandLines)
@ -248,11 +241,11 @@ var LabelExpanderLayout = new Lang.Class({
this._expandLines = v;
if (this._expansion > 0)
this.layout_changed();
},
}
vfunc_set_container(container) {
this._container = container;
},
}
vfunc_get_preferred_width(container, forHeight) {
let [min, nat] = [0, 0];
@ -267,7 +260,7 @@ var LabelExpanderLayout = new Lang.Class({
}
return [min, nat];
},
}
vfunc_get_preferred_height(container, forWidth) {
let [min, nat] = [0, 0];
@ -285,7 +278,7 @@ var LabelExpanderLayout = new Lang.Class({
}
return [min, nat];
},
}
vfunc_allocate(container, box, flags) {
for (let i = 0; i < container.get_n_children(); i++) {
@ -298,10 +291,8 @@ var LabelExpanderLayout = new Lang.Class({
}
});
var Message = new Lang.Class({
Name: 'Message',
_init(title, body) {
var Message = class Message {
constructor(title, body) {
this.expanded = false;
this._useBodyMarkup = false;
@ -368,25 +359,25 @@ var Message = new Lang.Class({
this.actor.connect('clicked', this._onClicked.bind(this));
this.actor.connect('destroy', this._onDestroy.bind(this));
this._sync();
},
}
close() {
this.emit('close');
},
}
setIcon(actor) {
this._iconBin.child = actor;
this._iconBin.visible = (actor != null);
},
}
setSecondaryActor(actor) {
this._secondaryBin.child = actor;
},
}
setTitle(text) {
let title = text ? _fixMarkup(text.replace(/\n/g, ' '), false) : '';
this.titleLabel.clutter_text.set_markup(title);
},
}
setBody(text) {
this._bodyText = text;
@ -394,7 +385,7 @@ var Message = new Lang.Class({
this._useBodyMarkup);
if (this._expandedLabel)
this._expandedLabel.setMarkup(text, this._useBodyMarkup);
},
}
setUseBodyMarkup(enable) {
if (this._useBodyMarkup === enable)
@ -402,7 +393,7 @@ var Message = new Lang.Class({
this._useBodyMarkup = enable;
if (this.bodyLabel)
this.setBody(this._bodyText);
},
}
setActionArea(actor) {
if (actor == null) {
@ -416,7 +407,7 @@ var Message = new Lang.Class({
this._actionBin.add_actor(actor);
this._actionBin.visible = this.expanded;
},
}
addMediaControl(iconName, callback) {
let icon = new St.Icon({ icon_name: iconName, icon_size: 16 });
@ -425,7 +416,7 @@ var Message = new Lang.Class({
button.connect('clicked', callback);
this._mediaControls.add_actor(button);
return button;
},
}
setExpandedBody(actor) {
if (actor == null) {
@ -438,11 +429,11 @@ var Message = new Lang.Class({
throw new Error('Message already has an expanded body actor');
this._bodyStack.insert_child_at_index(actor, 1);
},
}
setExpandedLines(nLines) {
this._bodyStack.layout_manager.expandLines = nLines;
},
}
expand(animate) {
this.expanded = true;
@ -471,7 +462,7 @@ var Message = new Lang.Class({
}
this.emit('expanded');
},
}
unexpand(animate) {
if (animate) {
@ -495,23 +486,23 @@ var Message = new Lang.Class({
}
this.emit('unexpanded');
},
}
canClose() {
return this._mediaControls.get_n_children() == 0;
},
return false;
}
_sync() {
let visible = this.actor.hover && this.canClose();
this._closeButton.opacity = visible ? 255 : 0;
this._closeButton.reactive = visible;
},
}
_onClicked() {
},
}
_onDestroy() {
},
}
_onKeyPressed(a, event) {
let keysym = event.get_key_symbol();
@ -523,13 +514,11 @@ var Message = new Lang.Class({
}
return Clutter.EVENT_PROPAGATE;
}
});
};
Signals.addSignalMethods(Message.prototype);
var MessageListSection = new Lang.Class({
Name: 'MessageListSection',
_init() {
var MessageListSection = class MessageListSection {
constructor() {
this.actor = new St.BoxLayout({ style_class: 'message-list-section',
clip_to_allocation: true,
x_expand: true, vertical: true });
@ -552,26 +541,26 @@ var MessageListSection = new Lang.Class({
this.empty = true;
this.canClear = false;
this._sync();
},
}
_onKeyFocusIn(actor) {
this.emit('key-focus-in', actor);
},
}
get allowed() {
return true;
},
}
setDate(date) {
if (Calendar.sameDay(date, this._date))
return;
this._date = date;
this._sync();
},
}
addMessage(message, animate) {
this.addMessageAtIndex(message, -1, animate);
},
}
addMessageAtIndex(message, index, animate) {
let obj = {
@ -604,7 +593,7 @@ var MessageListSection = new Lang.Class({
scale_y: 1,
time: MESSAGE_ANIMATION_TIME,
transition: 'easeOutQuad' });
},
}
moveMessage(message, index, animate) {
let obj = this._messages.get(message);
@ -626,7 +615,7 @@ var MessageListSection = new Lang.Class({
time: MESSAGE_ANIMATION_TIME,
transition: 'easeOutQuad',
onComplete: onComplete });
},
}
removeMessage(message, animate) {
let obj = this._messages.get(message);
@ -649,7 +638,7 @@ var MessageListSection = new Lang.Class({
obj.container.destroy();
global.sync_pointer();
}
},
}
clear() {
let messages = [...this._messages.keys()].filter(msg => msg.canClose());
@ -677,18 +666,18 @@ var MessageListSection = new Lang.Class({
}});
}
}
},
}
_canClear() {
for (let message of this._messages.keys())
if (message.canClose())
return true;
return false;
},
}
_shouldShow() {
return !this.empty;
},
}
_sync() {
let empty = this._list.get_n_children() == 0;
@ -707,5 +696,5 @@ var MessageListSection = new Lang.Class({
this.actor.visible = this.allowed && this._shouldShow();
}
});
};
Signals.addSignalMethods(MessageListSection.prototype);

File diff suppressed because it is too large Load Diff

View File

@ -4,7 +4,6 @@ const Clutter = imports.gi.Clutter;
const Gdk = imports.gi.Gdk;
const Gio = imports.gi.Gio;
const GLib = imports.gi.GLib;
const Lang = imports.lang;
const Meta = imports.gi.Meta;
const Pango = imports.gi.Pango;
const St = imports.gi.St;
@ -31,10 +30,8 @@ var State = {
FADED_OUT: 4
};
var ModalDialog = new Lang.Class({
Name: 'ModalDialog',
_init(params) {
var ModalDialog = class {
constructor(params) {
params = Params.parse(params, { shellReactive: false,
styleClass: null,
actionMode: Shell.ActionMode.SYSTEM_MODAL,
@ -87,30 +84,30 @@ var ModalDialog = new Lang.Class({
this._initialKeyFocus = null;
this._initialKeyFocusDestroyId = 0;
this._savedKeyFocus = null;
},
}
destroy() {
this._group.destroy();
},
}
clearButtons() {
this.dialogLayout.clearButtons();
},
}
setButtons(buttons) {
this.clearButtons();
for (let buttonInfo of buttons)
this.addButton(buttonInfo);
},
}
addButton(buttonInfo) {
return this.dialogLayout.addButton(buttonInfo);
},
}
_onGroupDestroy() {
this.emit('destroy');
},
}
_fadeOpen(onPrimary) {
if (onPrimary)
@ -134,7 +131,7 @@ var ModalDialog = new Lang.Class({
this.emit('opened');
}
});
},
}
setInitialKeyFocus(actor) {
if (this._initialKeyFocusDestroyId)
@ -146,7 +143,7 @@ var ModalDialog = new Lang.Class({
this._initialKeyFocus = null;
this._initialKeyFocusDestroyId = 0;
});
},
}
open(timestamp, onPrimary) {
if (this.state == State.OPENED || this.state == State.OPENING)
@ -157,7 +154,7 @@ var ModalDialog = new Lang.Class({
this._fadeOpen(onPrimary);
return true;
},
}
_closeComplete() {
this.state = State.CLOSED;
@ -166,7 +163,7 @@ var ModalDialog = new Lang.Class({
if (this._destroyOnClose)
this.destroy();
},
}
close(timestamp) {
if (this.state == State.CLOSED || this.state == State.CLOSING)
@ -185,7 +182,7 @@ var ModalDialog = new Lang.Class({
})
else
this._closeComplete();
},
}
// Drop modal status without closing the dialog; this makes the
// dialog insensitive as well, so it needs to be followed shortly
@ -205,7 +202,7 @@ var ModalDialog = new Lang.Class({
if (!this._shellReactive)
this._eventBlocker.raise_top();
},
}
pushModal(timestamp) {
if (this._hasModal)
@ -229,7 +226,7 @@ var ModalDialog = new Lang.Class({
if (!this._shellReactive)
this._eventBlocker.lower_bottom();
return true;
},
}
// This method is like close, but fades the dialog out much slower,
// and leaves the lightbox in place. Once in the faded out state,
@ -259,5 +256,5 @@ var ModalDialog = new Lang.Class({
}
});
}
});
};
Signals.addSignalMethods(ModalDialog.prototype);

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