Compare commits

..

23 Commits

Author SHA1 Message Date
Georges Basile Stavracas Neto
6fd0aafada authPrompt: Wiggle on failure
WIP
2019-10-15 21:34:35 +02:00
Georges Basile Stavracas Neto
e5091ff17c environment: Parse repeat-count and auto-reverse
Those are two useful ClutterTimeline properties and
will be needed for wiggling the search entry when
failing the password.

Add support for passing repeat-count and auto-reverse
to ClutterActor.ease and ClutterActor.ease_property.
2019-10-15 21:32:21 +02:00
Georges Basile Stavracas Neto
22534c4c64 unlockDialog: Show auth prompt on tap 2019-10-15 15:39:07 +02:00
Georges Basile Stavracas Neto
cd1c45731d fixup! sessonMode: Remove 'lock-screen' mode 2019-10-15 15:38:56 +02:00
Georges Basile Stavracas Neto
5380b06eb5 fixup! unlockDialog: Add UnlockDialogLayout 2019-10-15 15:37:46 +02:00
Georges Basile Stavracas Neto
be714f7401 fixup! screenShield: Blur background 2019-10-14 18:29:31 +02:00
Georges Basile Stavracas Neto
e71c249ea5 authPrompt: Refine entry width
The current entry has a hardcoded size of 320px,
which doesn't really fit the lock screen mockups.

Remove this hardcoded size from AuthPrompt entries
and make them horizontally expand.
2019-10-12 21:33:41 -03:00
Georges Basile Stavracas Neto
5b6deff977 authPrompt: Iconize the cancel button
Replace the "Cancel" label in the cancel button
by an arrow icon, and adjust the theme to make
it circular.
2019-10-12 21:12:45 -03:00
Georges Basile Stavracas Neto
6cd0c3f965 authPrompt: Move cancel button and cog to a single row
Move the cancel button and the user well actors (the cog
menu and the spinner) to a single row.

Ultimately the user well will be splitted out into a different
place, but moving it now at least gives some visual consistency.
2019-10-12 17:58:55 -03:00
Georges Basile Stavracas Neto
d529e222d7 unlockDialog: Add UnlockDialogLayout
This is a specialized layout manager to implement the
UI description of the new lock screen.
2019-10-12 17:49:40 -03:00
Georges Basile Stavracas Neto
2e23a0e6b8 authPrompt: Remove next button 2019-10-12 17:49:40 -03:00
Georges Basile Stavracas Neto
64aaa46333 unlockDialog: Adjust notification style
I think I can flip the development table and
become a designer now -- what else is needed
beyond figuring out spacing anyway?!
2019-10-12 17:49:40 -03:00
Georges Basile Stavracas Neto
d1f61e884d sessonMode: Remove 'lock-screen' mode
As per the latest mockups, the only session mode
related to locked screens will be the unlock dialog.
2019-10-12 17:49:40 -03:00
Georges Basile Stavracas Neto
fe3d55eb80 screenShield: Cleanup unused parameters 2019-10-12 17:49:40 -03:00
Georges Basile Stavracas Neto
7a90b2d908 screenShield: Remove _lockScreenGroup
Now, _lockDialogGroup will be responsible for being
the actual screenshield.
2019-10-12 17:49:40 -03:00
Georges Basile Stavracas Neto
137df4bc26 screenShield: Cleanup lock screen handling 2019-10-12 17:49:40 -03:00
Georges Basile Stavracas Neto
23abe4eb22 screenShield: Translate the dialog group
Instead of the screen lock group, which is now
empty and soon will be removed.
2019-10-12 17:49:40 -03:00
Georges Basile Stavracas Neto
b7feb71490 screenShield: Move notification box to UnlockDialog 2019-10-12 17:49:40 -03:00
Georges Basile Stavracas Neto
9aa9431a32 theme: Adjust unlock screen clock fonts
Designers plz help
2019-10-12 17:49:40 -03:00
Georges Basile Stavracas Neto
c9e2afcf65 screenShield: Move Clock to UnlockDialog
Move the clock to UnlockDialog, as per the latest mockups.
2019-10-12 17:49:40 -03:00
Georges Basile Stavracas Neto
be5ab24e97 screenShield: Remove arrows
They're not used anywhere in the new dialog
2019-10-12 17:49:40 -03:00
Georges Basile Stavracas Neto
caf0c8dd7d screenShield: Blur background
This is a moderately fast two-pass gaussian blur
implementation. It downscales the framebuffer by
half before applying the gaussian shader, which
cuts down rendering time quite considerably.

The blur shader takes 3 uniforms as input: the blur
radius; whether to blur vertically or horizontally;
and a brightness value.

The blur radius is treated as an integer in C land
to simplify calculations. The vertical parameter is
treated as an integer by the shader simply due to
Cogl not having proper boolean support in snippets.
At last, brightness is also added to avoid needing
to use an extra effect to achieve that.
2019-10-12 17:49:40 -03:00
Georges Basile Stavracas Neto
10a194e6ed screenShield: Move background to _screenDialogGroup 2019-10-09 19:42:40 -03:00
101 changed files with 4905 additions and 5234 deletions

View File

@@ -16,14 +16,8 @@ run_eslint() {
ARGS_LEGACY='--config lint/eslintrc-legacy.json' ARGS_LEGACY='--config lint/eslintrc-legacy.json'
local extra_args=ARGS_$1 local extra_args=ARGS_$1
local output_var=OUTPUT_$1 local output=OUTPUT_$1
local output=${!output_var} eslint -f unix ${!extra_args} -o ${!output} js
# ensure output exists even if eslint doesn't report any errors
mkdir -p $(dirname $output)
touch $output
eslint -f unix ${!extra_args} -o $output js
} }
list_commit_range_additions() { list_commit_range_additions() {
@@ -76,13 +70,10 @@ create_common() {
# non-legacy style just yet ... # non-legacy style just yet ...
unset CI_MERGE_REQUEST_TARGET_BRANCH_NAME unset CI_MERGE_REQUEST_TARGET_BRANCH_NAME
REMOTE=${1:-$CI_MERGE_REQUEST_PROJECT_URL.git} if [ "$CI_MERGE_REQUEST_TARGET_BRANCH_NAME" ]; then
BRANCH_NAME=${2:-$CI_MERGE_REQUEST_TARGET_BRANCH_NAME} git fetch $CI_MERGE_REQUEST_PROJECT_URL.git $CI_MERGE_REQUEST_TARGET_BRANCH_NAME
if [ "$BRANCH_NAME" ]; then
git fetch $REMOTE $BRANCH_NAME
branch_point=$(git merge-base HEAD FETCH_HEAD) branch_point=$(git merge-base HEAD FETCH_HEAD)
commit_range=$branch_point...HEAD commit_range=$branch_point...$CI_COMMIT_SHA
list_commit_range_additions $commit_range > $LINE_CHANGES list_commit_range_additions $commit_range > $LINE_CHANGES
@@ -105,7 +96,7 @@ if ! is_empty $OUTPUT_FINAL; then
fi fi
# Just show the report and succeed when not testing a MR # Just show the report and succeed when not testing a MR
if [ -z "$BRANCH_NAME" ]; then if [ -z "$CI_MERGE_REQUEST_TARGET_BRANCH_NAME" ]; then
exit 0 exit 0
fi fi

View File

@@ -186,27 +186,15 @@ and "double quotes" for strings that the user may see. This allows us to
quickly find untranslated or mistranslated strings by grepping through the quickly find untranslated or mistranslated strings by grepping through the
sources for double quotes without a gettext call around them. sources for double quotes without a gettext call around them.
## `actor` (deprecated) and `_delegate` ## `actor` and `_delegate`
gjs allows us to set so-called "expando properties" on introspected objects, gjs allows us to set so-called "expando properties" on introspected objects,
allowing us to treat them like any other. Because the Shell was built before allowing us to treat them like any other. Because the Shell was built before
you could inherit from GTypes natively in JS, in some cases we have a wrapper you could inherit from GTypes natively in JS, we usually have a wrapper class
class that has a property called `actor` (now deprecated). We call this that has a property called `actor`. We call this wrapper class the "delegate".
wrapper class the "delegate".
We sometimes use expando properties to set a property called `_delegate` on We sometimes use expando properties to set a property called `_delegate` on
the actor itself: the actor itself:
```javascript
var MyActor = GObject.registerClass(
class MyActor extends Clutter.Actor {
_init(params) {
super._init(params);
this._delegate = this;
}
});
```
Or using the deprecated `actor`:
```javascript ```javascript
var MyClass = class { var MyClass = class {
constructor() { constructor() {
@@ -227,7 +215,6 @@ delegate object from an associated actor. For instance, the drag and drop
system calls the `handleDragOver` function on the delegate of a "drop target" system calls the `handleDragOver` function on the delegate of a "drop target"
when the user drags an item over it. If you do not set the `_delegate` when the user drags an item over it. If you do not set the `_delegate`
property, your actor will not be able to be dropped onto. property, your actor will not be able to be dropped onto.
In case the class is an actor itself, the `_delegate` can be just set to `this`.
## Functional style ## Functional style

7
NEWS
View File

@@ -1,10 +1,3 @@
3.35.1
======
* Misc. bug fixes and cleanups [Marco; Matthias; !758, #701212]
Contributors:
Marco Trevisan (Treviño)
3.34.1 3.34.1
====== ======
* Fix "Frequent" view icons disappearing on hover [Jonas D.; #1502] * Fix "Frequent" view icons disappearing on hover [Jonas D.; #1502]

View File

@@ -50,7 +50,7 @@
</description> </description>
</key> </key>
<key name="favorite-apps" type="as"> <key name="favorite-apps" type="as">
<default>[ 'epiphany.desktop', 'evolution.desktop', 'rhythmbox.desktop', 'org.gnome.Shotwell.desktop', 'org.gnome.Nautilus.desktop', 'org.gnome.Software.desktop' ]</default> <default>[ 'epiphany.desktop', 'evolution.desktop', 'rhythmbox.desktop', 'shotwell.desktop', 'org.gnome.Nautilus.desktop', 'org.gnome.Software.desktop' ]</default>
<summary>List of desktop file IDs for favorite applications</summary> <summary>List of desktop file IDs for favorite applications</summary>
<description> <description>
The applications corresponding to these identifiers The applications corresponding to these identifiers

View File

@@ -1929,6 +1929,7 @@ StScrollBar {
StEntry { StEntry {
@extend %search_entry; @extend %search_entry;
width: -1px;
border-radius: $button_radius; border-radius: $button_radius;
@if $variant=='dark' { @if $variant=='dark' {
$_gdm_entry_bg: transparentize(lighten(desaturate(#241f31, 20%), 2%), 0.5); $_gdm_entry_bg: transparentize(lighten(desaturate(#241f31, 20%), 2%), 0.5);
@@ -1986,6 +1987,15 @@ StScrollBar {
} }
} }
} }
.cancel-button {
padding: 0;
border-radius: 16px;
width: 32px;
height: 32px;
StIcon { icon-size: 16px; }
}
} }
.login-dialog-logo-bin { padding: 24px 0px; } .login-dialog-logo-bin { padding: 24px 0px; }
@@ -2069,42 +2079,28 @@ StScrollBar {
$_screenshield_shadow: 0px 0px 6px rgba(0, 0, 0, 0.726); $_screenshield_shadow: 0px 0px 6px rgba(0, 0, 0, 0.726);
.screen-shield-arrows {
padding-bottom: 3em;
}
.screen-shield-arrows Gjs_Arrow {
color: white;
width: 80px;
height: 48px;
-arrow-thickness: 12px;
-arrow-shadow: $_screenshield_shadow;
}
.screen-shield-clock { .screen-shield-clock {
color: white; color: white;
text-shadow: $_screenshield_shadow;
font-weight: bold;
text-align: center; text-align: center;
padding-bottom: 1.5em; padding-bottom: 2.5em;
} }
.screen-shield-clock-time { .screen-shield-clock-time {
font-size: 72pt; font-size: 64pt;
text-shadow: $_screenshield_shadow; font-weight: 200;
padding-bottom: 24px;
font-feature-settings: "tnum"; font-feature-settings: "tnum";
} }
.screen-shield-clock-date { .screen-shield-clock-date {
font-size: 28pt; font-size: 16pt;
font-weight: normal; font-weight: bold;
} }
.screen-shield-notifications-container { .screen-shield-notifications-container {
spacing: 6px; spacing: 6px;
width: 30em;
background-color: transparent; background-color: transparent;
max-height: 500px; padding: 24px 0;
.summary-notification-stack-scrollview { .summary-notification-stack-scrollview {
padding-top: 0; padding-top: 0;
padding-bottom: 0; padding-bottom: 0;
@@ -2112,7 +2108,7 @@ $_screenshield_shadow: 0px 0px 6px rgba(0, 0, 0, 0.726);
.notification, .notification,
.screen-shield-notification-source { .screen-shield-notification-source {
padding: 12px 6px; padding: 12px;
border: 1px solid $osd_outer_borders_color; border: 1px solid $osd_outer_borders_color;
background-color: transparentize($osd_bg_color,0.5); background-color: transparentize($osd_bg_color,0.5);
color: $osd_fg_color; color: $osd_fg_color;

View File

@@ -31,34 +31,34 @@ its dependencies to build from tarballs.</description>
<programming-language>JavaScript</programming-language> <programming-language>JavaScript</programming-language>
<programming-language>C</programming-language> <programming-language>C</programming-language>
<author> <maintainer>
<foaf:Person> <foaf:Person>
<foaf:name>William Jon McCann</foaf:name> <foaf:name>William Jon McCann</foaf:name>
<foaf:mbox rdf:resource="mailto:jmccann@redhat.com" /> <foaf:mbox rdf:resource="mailto:jmccann@redhat.com" />
<gnome:userid>mccann</gnome:userid> <gnome:userid>mccann</gnome:userid>
</foaf:Person> </foaf:Person>
</author> </maintainer>
<author> <maintainer>
<foaf:Person> <foaf:Person>
<foaf:name>Owen Taylor</foaf:name> <foaf:name>Owen Taylor</foaf:name>
<foaf:mbox rdf:resource="mailto:otaylor@redhat.com" /> <foaf:mbox rdf:resource="mailto:otaylor@redhat.com" />
<gnome:userid>otaylor</gnome:userid> <gnome:userid>otaylor</gnome:userid>
</foaf:Person> </foaf:Person>
</author> </maintainer>
<author> <maintainer>
<foaf:Person> <foaf:Person>
<foaf:name>Colin Walters</foaf:name> <foaf:name>Colin Walters</foaf:name>
<foaf:mbox rdf:resource="mailto:walters@verbum.org" /> <foaf:mbox rdf:resource="mailto:walters@verbum.org" />
<gnome:userid>walters</gnome:userid> <gnome:userid>walters</gnome:userid>
</foaf:Person> </foaf:Person>
</author> </maintainer>
<author> <maintainer>
<foaf:Person> <foaf:Person>
<foaf:name>Marina Zhurakhinskaya</foaf:name> <foaf:name>Marina Zhurakhinskaya</foaf:name>
<foaf:mbox rdf:resource="mailto:marinaz@redhat.com" /> <foaf:mbox rdf:resource="mailto:marinaz@redhat.com" />
<gnome:userid>marinaz</gnome:userid> <gnome:userid>marinaz</gnome:userid>
</foaf:Person> </foaf:Person>
</author> </maintainer>
<maintainer> <maintainer>
<foaf:Person> <foaf:Person>
<foaf:name>Florian Müllner</foaf:name> <foaf:name>Florian Müllner</foaf:name>

View File

@@ -1,12 +1,11 @@
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*- // -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
/* exported AuthPrompt */
const { Clutter, GObject, Pango, Shell, St } = imports.gi; const { Clutter, Pango, Shell, St } = imports.gi;
const Signals = imports.signals;
const Animation = imports.ui.animation; const Animation = imports.ui.animation;
const Batch = imports.gdm.batch; const Batch = imports.gdm.batch;
const GdmUtil = imports.gdm.util; const GdmUtil = imports.gdm.util;
const Util = imports.misc.util;
const Params = imports.misc.params; const Params = imports.misc.params;
const ShellEntry = imports.ui.shellEntry; const ShellEntry = imports.ui.shellEntry;
const UserWidget = imports.ui.userWidget; const UserWidget = imports.ui.userWidget;
@@ -38,21 +37,8 @@ var BeginRequestType = {
DONT_PROVIDE_USERNAME: 1 DONT_PROVIDE_USERNAME: 1
}; };
var AuthPrompt = GObject.registerClass({ var AuthPrompt = class {
Signals: { constructor(gdmClient, mode) {
'cancelled': {},
'failed': {},
'next': {},
'prompted': {},
'reset': { param_types: [GObject.TYPE_UINT] },
}
}, class AuthPrompt extends St.BoxLayout {
_init(gdmClient, mode) {
super._init({
style_class: 'login-dialog-prompt-layout',
vertical: true
});
this.verificationStatus = AuthPromptStatus.NOT_VERIFYING; this.verificationStatus = AuthPromptStatus.NOT_VERIFYING;
this._gdmClient = gdmClient; this._gdmClient = gdmClient;
@@ -85,59 +71,37 @@ var AuthPrompt = GObject.registerClass({
} }
}); });
this.connect('destroy', this._onDestroy.bind(this)); this.actor = new St.BoxLayout({ style_class: 'login-dialog-prompt-layout',
vertical: true });
this._userWell = new St.Bin({ x_fill: true, x_align: St.Align.START }); this.actor.connect('destroy', this._onDestroy.bind(this));
this.add(this._userWell, { this.actor.connect('key-press-event', (actor, event) => {
x_align: St.Align.START, if (event.get_key_symbol() == Clutter.KEY_Escape)
x_fill: true, this.cancel();
y_fill: true, return Clutter.EVENT_PROPAGATE;
expand: true
}); });
this._userWell = new St.Bin({ x_fill: true,
x_align: St.Align.START });
this.actor.add(this._userWell,
{ x_align: St.Align.START,
x_fill: true,
y_fill: true,
expand: true });
this._label = new St.Label({ style_class: 'login-dialog-prompt-label' }); this._label = new St.Label({ style_class: 'login-dialog-prompt-label' });
this.add(this._label, { this.actor.add(this._label,
expand: true, { expand: true,
x_fill: false, x_fill: false,
y_fill: true, y_fill: true,
x_align: St.Align.START x_align: St.Align.START });
});
this._entry = new St.Entry({ style_class: 'login-dialog-prompt-entry',
can_focus: true });
ShellEntry.addContextMenu(this._entry, { isPassword: true, actionMode: Shell.ActionMode.NONE });
this.add(this._entry, { this._initEntryRow();
expand: true,
x_fill: true,
y_fill: false,
x_align: St.Align.START
});
this._entry.grab_key_focus();
this._message = new St.Label({ opacity: 0, this._message = new St.Label({ opacity: 0,
styleClass: 'login-dialog-message' }); styleClass: 'login-dialog-message' });
this._message.clutter_text.line_wrap = true; this._message.clutter_text.line_wrap = true;
this._message.clutter_text.ellipsize = Pango.EllipsizeMode.NONE; this._message.clutter_text.ellipsize = Pango.EllipsizeMode.NONE;
this.add(this._message, { x_fill: false, x_align: St.Align.START, y_align: St.Align.START }); this.actor.add(this._message, { x_fill: false, x_align: St.Align.START, y_align: St.Align.START });
this._buttonBox = new St.BoxLayout({ style_class: 'login-dialog-button-box',
vertical: false });
this.add(this._buttonBox, {
expand: true,
x_align: St.Align.MIDDLE,
y_align: St.Align.END
});
this._defaultButtonWell = new St.Widget({ layout_manager: new Clutter.BinLayout() });
this._defaultButtonWellActor = null;
this._initButtons();
this._spinner = new Animation.Spinner(DEFAULT_BUTTON_WELL_ICON_SIZE);
this._spinner.opacity = 0;
this._spinner.show();
this._defaultButtonWell.add_child(this._spinner);
} }
_onDestroy() { _onDestroy() {
@@ -145,58 +109,47 @@ var AuthPrompt = GObject.registerClass({
this._userVerifier = null; this._userVerifier = null;
} }
vfunc_key_press_event(keyPressEvent) { _initEntryRow() {
if (keyPressEvent.keyval == Clutter.KEY_Escape) let mainBox = new St.BoxLayout({
this.cancel(); style_class: 'login-dialog-button-box',
return Clutter.EVENT_PROPAGATE; vertical: false,
} });
this.actor.add_child(mainBox);
_initButtons() { this.cancelButton = new St.Button({
this.cancelButton = new St.Button({ style_class: 'modal-dialog-button button', style_class: 'modal-dialog-button button cancel-button',
button_mask: St.ButtonMask.ONE | St.ButtonMask.THREE, button_mask: St.ButtonMask.ONE | St.ButtonMask.THREE,
reactive: true, reactive: true,
can_focus: true, can_focus: true,
label: _("Cancel") }); child: new St.Icon({ icon_name: 'go-previous-symbolic' }),
});
this.cancelButton.connect('clicked', () => this.cancel()); this.cancelButton.connect('clicked', () => this.cancel());
this._buttonBox.add(this.cancelButton, mainBox.add_child(this.cancelButton);
{ expand: false,
x_fill: false,
y_fill: false,
x_align: St.Align.START,
y_align: St.Align.END });
this._buttonBox.add(this._defaultButtonWell, this._entry = new St.Entry({
{ expand: true, style_class: 'login-dialog-prompt-entry',
x_fill: false, can_focus: true,
y_fill: false, x_expand: true,
x_align: St.Align.END, });
y_align: St.Align.MIDDLE }); ShellEntry.addContextMenu(this._entry, { isPassword: true, actionMode: Shell.ActionMode.NONE });
this.nextButton = new St.Button({ style_class: 'modal-dialog-button button',
button_mask: St.ButtonMask.ONE | St.ButtonMask.THREE,
reactive: true,
can_focus: true,
label: _("Next") });
this.nextButton.connect('clicked', () => this.emit('next'));
this.nextButton.add_style_pseudo_class('default');
this._buttonBox.add(this.nextButton,
{ expand: false,
x_fill: false,
y_fill: false,
x_align: St.Align.END,
y_align: St.Align.END });
this._updateNextButtonSensitivity(this._entry.text.length > 0); mainBox.add_child(this._entry);
this._entry.grab_key_focus();
this._entry.clutter_text.connect('activate', () => this.emit('next'));
this._entry.clutter_text.connect('text-changed', () => { this._entry.clutter_text.connect('text-changed', () => {
if (!this._userVerifier.hasPendingMessages) if (!this._userVerifier.hasPendingMessages)
this._fadeOutMessage(); this._fadeOutMessage();
});
this._updateNextButtonSensitivity(this._entry.text.length > 0 || this.verificationStatus == AuthPromptStatus.VERIFYING); this._defaultButtonWell = new St.Widget({ layout_manager: new Clutter.BinLayout() });
}); this._defaultButtonWellActor = null;
this._entry.clutter_text.connect('activate', () => { mainBox.add_child(this._defaultButtonWell);
if (this.nextButton.reactive)
this.emit('next'); 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);
} }
_onAskQuestion(verifier, serviceName, question, passwordChar) { _onAskQuestion(verifier, serviceName, question, passwordChar) {
@@ -211,16 +164,6 @@ var AuthPrompt = GObject.registerClass({
} }
this.setPasswordChar(passwordChar); this.setPasswordChar(passwordChar);
this.setQuestion(question); this.setQuestion(question);
if (passwordChar) {
if (this._userVerifier.reauthenticating)
this.nextButton.label = _("Unlock");
else
this.nextButton.label = C_("button", "Sign In");
} else {
this.nextButton.label = _("Next");
}
this.updateSensitivity(true); this.updateSensitivity(true);
this.emit('prompted'); this.emit('prompted');
} }
@@ -262,10 +205,33 @@ var AuthPrompt = GObject.registerClass({
this.setActorInDefaultButtonWell(null); this.setActorInDefaultButtonWell(null);
this.verificationStatus = AuthPromptStatus.VERIFICATION_FAILED; this.verificationStatus = AuthPromptStatus.VERIFICATION_FAILED;
Util.wiggle(this._entry, { this._wiggle();
offset: WIGGLE_OFFSET, }
_wiggle() {
// Accelerate before wiggling
this._entry.ease({
translation_x: -WIGGLE_OFFSET,
duration: WIGGLE_DURATION, duration: WIGGLE_DURATION,
wiggleCount: N_WIGGLES, mode: Clutter.AnimationMode.EASE_OUT_QUAD,
onComplete: () => {
// Wiggle
this._entry.ease({
translation_x: WIGGLE_OFFSET,
duration: WIGGLE_DURATION,
mode: Clutter.AnimationMode.LINEAR,
repeat_count: N_WIGGLES,
auto_reverse: true,
onComplete: () => {
// Decelerate and return to the original position
this._entry.ease({
translation_x: 0,
duration: WIGGLE_DURATION,
mode: Clutter.AnimationMode.EASE_IN_QUAD,
});
}
});
}
}); });
} }
@@ -295,13 +261,13 @@ var AuthPrompt = GObject.registerClass({
oldActor.remove_all_transitions(); oldActor.remove_all_transitions();
let wasSpinner; let wasSpinner;
if (oldActor == this._spinner) if (oldActor == this._spinner.actor)
wasSpinner = true; wasSpinner = true;
else else
wasSpinner = false; wasSpinner = false;
let isSpinner; let isSpinner;
if (actor == this._spinner) if (actor == this._spinner.actor)
isSpinner = true; isSpinner = true;
else else
isSpinner = false; isSpinner = false;
@@ -349,7 +315,7 @@ var AuthPrompt = GObject.registerClass({
} }
startSpinning() { startSpinning() {
this.setActorInDefaultButtonWell(this._spinner, true); this.setActorInDefaultButtonWell(this._spinner.actor, true);
} }
stopSpinning() { stopSpinning() {
@@ -419,20 +385,14 @@ var AuthPrompt = GObject.registerClass({
} }
} }
_updateNextButtonSensitivity(sensitive) {
this.nextButton.reactive = sensitive;
this.nextButton.can_focus = sensitive;
}
updateSensitivity(sensitive) { updateSensitivity(sensitive) {
this._updateNextButtonSensitivity(sensitive && (this._entry.text.length > 0 || this.verificationStatus == AuthPromptStatus.VERIFYING));
this._entry.reactive = sensitive; this._entry.reactive = sensitive;
this._entry.clutter_text.editable = sensitive; this._entry.clutter_text.editable = sensitive;
} }
vfunc_hide() { hide() {
this.setActorInDefaultButtonWell(null, true); this.setActorInDefaultButtonWell(null, true);
super.vfunc_hide(); this.actor.hide();
this._message.opacity = 0; this._message.opacity = 0;
this.setUser(null); this.setUser(null);
@@ -448,7 +408,7 @@ var AuthPrompt = GObject.registerClass({
if (user) { if (user) {
let userWidget = new UserWidget.UserWidget(user); let userWidget = new UserWidget.UserWidget(user);
this._userWell.set_child(userWidget); this._userWell.set_child(userWidget.actor);
} }
} }
@@ -456,7 +416,6 @@ var AuthPrompt = GObject.registerClass({
let oldStatus = this.verificationStatus; let oldStatus = this.verificationStatus;
this.verificationStatus = AuthPromptStatus.NOT_VERIFYING; this.verificationStatus = AuthPromptStatus.NOT_VERIFYING;
this.cancelButton.reactive = true; this.cancelButton.reactive = true;
this.nextButton.label = _("Next");
this._preemptiveAnswer = null; this._preemptiveAnswer = null;
if (this._userVerifier) if (this._userVerifier)
@@ -533,4 +492,5 @@ var AuthPrompt = GObject.registerClass({
this.reset(); this.reset();
this.emit('cancelled'); this.emit('cancelled');
} }
}); };
Signals.addSignalMethods(AuthPrompt.prototype);

View File

@@ -19,6 +19,7 @@
const { AccountsService, Atk, Clutter, Gdm, Gio, const { AccountsService, Atk, Clutter, Gdm, Gio,
GLib, GObject, Meta, Pango, Shell, St } = imports.gi; GLib, GObject, Meta, Pango, Shell, St } = imports.gi;
const Signals = imports.signals;
const AuthPrompt = imports.gdm.authPrompt; const AuthPrompt = imports.gdm.authPrompt;
const Batch = imports.gdm.batch; const Batch = imports.gdm.batch;
@@ -38,80 +39,72 @@ const _TIMED_LOGIN_IDLE_THRESHOLD = 5.0;
const _LOGO_ICON_HEIGHT = 48; const _LOGO_ICON_HEIGHT = 48;
const _MAX_BOTTOM_MENU_ITEMS = 5; const _MAX_BOTTOM_MENU_ITEMS = 5;
var UserListItem = GObject.registerClass({ var UserListItem = class {
GTypeName: 'LoginDialog_UserListItem', constructor(user) {
Signals: { 'activate': {} }
}, class UserListItem extends St.Button {
_init(user) {
let layout = new St.BoxLayout({ vertical: true });
super._init({
style_class: 'login-dialog-user-list-item',
button_mask: St.ButtonMask.ONE | St.ButtonMask.THREE,
can_focus: true,
child: layout,
reactive: true,
x_align: St.Align.START,
x_fill: true
});
this.user = user; this.user = user;
this._userChangedId = this.user.connect('changed', this._userChangedId = this.user.connect('changed',
this._onUserChanged.bind(this)); this._onUserChanged.bind(this));
this.connect('destroy', this._onDestroy.bind(this)); let layout = new St.BoxLayout({ vertical: true });
this.connect('notify::hover', () => { this.actor = new St.Button({ style_class: 'login-dialog-user-list-item',
this._setSelected(this.hover); button_mask: St.ButtonMask.ONE | St.ButtonMask.THREE,
can_focus: true,
child: layout,
reactive: true,
x_align: St.Align.START,
x_fill: true });
this.actor.connect('destroy', this._onDestroy.bind(this));
this.actor.connect('key-focus-in', () => {
this._setSelected(true);
});
this.actor.connect('key-focus-out', () => {
this._setSelected(false);
});
this.actor.connect('notify::hover', () => {
this._setSelected(this.actor.hover);
}); });
this._userWidget = new UserWidget.UserWidget(this.user); this._userWidget = new UserWidget.UserWidget(this.user);
layout.add(this._userWidget); layout.add(this._userWidget.actor);
this._userWidget.bind_property('label-actor', this, 'label-actor', this._userWidget.actor.bind_property('label-actor', this.actor, 'label-actor',
GObject.BindingFlags.SYNC_CREATE); GObject.BindingFlags.SYNC_CREATE);
this._timedLoginIndicator = new St.Bin({ style_class: 'login-dialog-timed-login-indicator', this._timedLoginIndicator = new St.Bin({ style_class: 'login-dialog-timed-login-indicator',
scale_x: 0, scale_x: 0,
visible: false }); visible: false });
layout.add(this._timedLoginIndicator); layout.add(this._timedLoginIndicator);
this.actor.connect('clicked', this._onClicked.bind(this));
this._onUserChanged(); this._onUserChanged();
} }
vfunc_key_focus_in() {
super.vfunc_key_focus_in();
this._setSelected(true);
}
vfunc_key_focus_out() {
super.vfunc_key_focus_out();
this._setSelected(false);
}
_onUserChanged() { _onUserChanged() {
this._updateLoggedIn(); this._updateLoggedIn();
} }
_updateLoggedIn() { _updateLoggedIn() {
if (this.user.is_logged_in()) if (this.user.is_logged_in())
this.add_style_pseudo_class('logged-in'); this.actor.add_style_pseudo_class('logged-in');
else else
this.remove_style_pseudo_class('logged-in'); this.actor.remove_style_pseudo_class('logged-in');
} }
_onDestroy() { _onDestroy() {
this.user.disconnect(this._userChangedId); this.user.disconnect(this._userChangedId);
} }
vfunc_clicked() { _onClicked() {
this.emit('activate'); this.emit('activate');
} }
_setSelected(selected) { _setSelected(selected) {
if (selected) { if (selected) {
this.add_style_pseudo_class('selected'); this.actor.add_style_pseudo_class('selected');
this.grab_key_focus(); this.actor.grab_key_focus();
} else { } else {
this.remove_style_pseudo_class('selected'); this.actor.remove_style_pseudo_class('selected');
} }
} }
@@ -152,30 +145,23 @@ var UserListItem = GObject.registerClass({
this._timedLoginIndicator.visible = false; this._timedLoginIndicator.visible = false;
this._timedLoginIndicator.scale_x = 0.; this._timedLoginIndicator.scale_x = 0.;
} }
}); };
Signals.addSignalMethods(UserListItem.prototype);
var UserList = GObject.registerClass({ var UserList = class {
GTypeName: 'LoginDialog_UserList', constructor() {
Signals: { this.actor = new St.ScrollView({ style_class: 'login-dialog-user-list-view' });
'activate': { param_types: [UserListItem.$gtype] }, this.actor.set_policy(St.PolicyType.NEVER,
'item-added': { param_types: [UserListItem.$gtype] }, St.PolicyType.AUTOMATIC);
}
}, class UserList extends St.ScrollView {
_init() {
super._init({ style_class: 'login-dialog-user-list-view' });
this.set_policy(St.PolicyType.NEVER,
St.PolicyType.AUTOMATIC);
this._box = new St.BoxLayout({ vertical: true, this._box = new St.BoxLayout({ vertical: true,
style_class: 'login-dialog-user-list', style_class: 'login-dialog-user-list',
pseudo_class: 'expanded' }); pseudo_class: 'expanded' });
this.add_actor(this._box); this.actor.add_actor(this._box);
this._items = {}; this._items = {};
}
vfunc_key_focus_in() { this.actor.connect('key-focus-in', this._moveFocusToItems.bind(this));
this._moveFocusToItems();
} }
_moveFocusToItems() { _moveFocusToItems() {
@@ -184,10 +170,10 @@ var UserList = GObject.registerClass({
if (!hasItems) if (!hasItems)
return; return;
if (global.stage.get_key_focus() != this) if (global.stage.get_key_focus() != this.actor)
return; return;
let focusSet = this.navigate_focus(null, St.DirectionType.TAB_FORWARD, false); let focusSet = this.actor.navigate_focus(null, St.DirectionType.TAB_FORWARD, false);
if (!focusSet) { if (!focusSet) {
Meta.later_add(Meta.LaterType.BEFORE_REDRAW, () => { Meta.later_add(Meta.LaterType.BEFORE_REDRAW, () => {
this._moveFocusToItems(); this._moveFocusToItems();
@@ -208,14 +194,14 @@ var UserList = GObject.registerClass({
for (let userName in this._items) { for (let userName in this._items) {
let item = this._items[userName]; let item = this._items[userName];
item.sync_hover(); item.actor.sync_hover();
} }
} }
scrollToItem(item) { scrollToItem(item) {
let box = item.get_allocation_box(); let box = item.actor.get_allocation_box();
let adjustment = this.get_vscroll_bar().get_adjustment(); let adjustment = this.actor.get_vscroll_bar().get_adjustment();
let value = (box.y1 + adjustment.step_increment / 2.0) - (adjustment.page_size / 2.0); let value = (box.y1 + adjustment.step_increment / 2.0) - (adjustment.page_size / 2.0);
adjustment.ease(value, { adjustment.ease(value, {
@@ -225,9 +211,9 @@ var UserList = GObject.registerClass({
} }
jumpToItem(item) { jumpToItem(item) {
let box = item.get_allocation_box(); let box = item.actor.get_allocation_box();
let adjustment = this.get_vscroll_bar().get_adjustment(); let adjustment = this.actor.get_vscroll_bar().get_adjustment();
let value = (box.y1 + adjustment.step_increment / 2.0) - (adjustment.page_size / 2.0); let value = (box.y1 + adjustment.step_increment / 2.0) - (adjustment.page_size / 2.0);
@@ -265,14 +251,14 @@ var UserList = GObject.registerClass({
this.removeUser(user); this.removeUser(user);
let item = new UserListItem(user); let item = new UserListItem(user);
this._box.add(item, { x_fill: true }); this._box.add(item.actor, { x_fill: true });
this._items[userName] = item; this._items[userName] = item;
item.connect('activate', this._onItemActivated.bind(this)); item.connect('activate', this._onItemActivated.bind(this));
// Try to keep the focused item front-and-center // Try to keep the focused item front-and-center
item.connect('key-focus-in', () => this.scrollToItem(item)); item.actor.connect('key-focus-in', () => this.scrollToItem(item));
this._moveFocusToItems(); this._moveFocusToItems();
@@ -293,38 +279,33 @@ var UserList = GObject.registerClass({
if (!item) if (!item)
return; return;
item.destroy(); item.actor.destroy();
delete this._items[userName]; delete this._items[userName];
} }
numItems() { numItems() {
return Object.keys(this._items).length; return Object.keys(this._items).length;
} }
}); };
Signals.addSignalMethods(UserList.prototype);
var SessionMenuButton = GObject.registerClass({ var SessionMenuButton = class {
GTypeName: 'LoginDialog_SessionMenuButton', constructor() {
Signals: { 'session-activated': { param_types: [GObject.TYPE_STRING] } }
}, class SessionMenuButton extends St.Bin {
_init() {
let gearIcon = new St.Icon({ icon_name: 'emblem-system-symbolic' }); let gearIcon = new St.Icon({ icon_name: 'emblem-system-symbolic' });
let button = new St.Button({ this._button = new St.Button({ style_class: 'login-dialog-session-list-button',
style_class: 'login-dialog-session-list-button', reactive: true,
reactive: true, track_hover: true,
track_hover: true, can_focus: true,
can_focus: true, accessible_name: _("Choose Session"),
accessible_name: _("Choose Session"), accessible_role: Atk.Role.MENU,
accessible_role: Atk.Role.MENU, child: gearIcon });
child: gearIcon
});
super._init({ child: button }); this.actor = new St.Bin({ child: this._button });
this._button = button;
let side = St.Side.TOP; let side = St.Side.TOP;
let align = 0; let align = 0;
if (Gdm.get_session_ids().length > _MAX_BOTTOM_MENU_ITEMS) { if (Gdm.get_session_ids().length > _MAX_BOTTOM_MENU_ITEMS) {
if (this.text_direction == Clutter.TextDirection.RTL) if (this.actor.text_direction == Clutter.TextDirection.RTL)
side = St.Side.RIGHT; side = St.Side.RIGHT;
else else
side = St.Side.LEFT; side = St.Side.LEFT;
@@ -403,13 +384,15 @@ var SessionMenuButton = GObject.registerClass({
}); });
} }
} }
}); };
Signals.addSignalMethods(SessionMenuButton.prototype);
var LoginDialog = GObject.registerClass({ var LoginDialog = GObject.registerClass({
Signals: { 'failed': {} }, Signals: { 'failed': {} },
}, class LoginDialog extends St.Widget { }, class LoginDialog extends St.Widget {
_init(parentActor) { _init(parentActor) {
super._init({ style_class: 'login-dialog', visible: false }); super._init({ style_class: 'login-dialog',
visible: false });
this.get_accessible().set_role(Atk.Role.WINDOW); this.get_accessible().set_role(Atk.Role.WINDOW);
@@ -443,7 +426,7 @@ var LoginDialog = GObject.registerClass({
this.add_child(this._userSelectionBox); this.add_child(this._userSelectionBox);
this._userList = new UserList(); this._userList = new UserList();
this._userSelectionBox.add(this._userList, this._userSelectionBox.add(this._userList.actor,
{ expand: true, { expand: true,
x_fill: true, x_fill: true,
y_fill: true }); y_fill: true });
@@ -452,7 +435,7 @@ var LoginDialog = GObject.registerClass({
this._authPrompt.connect('prompted', this._onPrompted.bind(this)); this._authPrompt.connect('prompted', this._onPrompted.bind(this));
this._authPrompt.connect('reset', this._onReset.bind(this)); this._authPrompt.connect('reset', this._onReset.bind(this));
this._authPrompt.hide(); this._authPrompt.hide();
this.add_child(this._authPrompt); this.add_child(this._authPrompt.actor);
// translators: this message is shown below the user list on the // translators: this message is shown below the user list on the
// login screen. It can be activated to reveal an entry for // login screen. It can be activated to reveal an entry for
@@ -511,9 +494,9 @@ var LoginDialog = GObject.registerClass({
(list, sessionId) => { (list, sessionId) => {
this._greeter.call_select_session_sync (sessionId, null); this._greeter.call_select_session_sync (sessionId, null);
}); });
this._sessionMenuButton.opacity = 0; this._sessionMenuButton.actor.opacity = 0;
this._sessionMenuButton.show(); this._sessionMenuButton.actor.show();
this._authPrompt.addActorToDefaultButtonWell(this._sessionMenuButton); this._authPrompt.addActorToDefaultButtonWell(this._sessionMenuButton.actor);
this._disableUserList = undefined; this._disableUserList = undefined;
this._userListLoaded = false; this._userListLoaded = false;
@@ -596,8 +579,8 @@ var LoginDialog = GObject.registerClass({
let authPromptAllocation = null; let authPromptAllocation = null;
let authPromptWidth = 0; let authPromptWidth = 0;
if (this._authPrompt.visible) { if (this._authPrompt.actor.visible) {
authPromptAllocation = this._getCenterActorAllocation(dialogBox, this._authPrompt); authPromptAllocation = this._getCenterActorAllocation(dialogBox, this._authPrompt.actor);
authPromptWidth = authPromptAllocation.x2 - authPromptAllocation.x1; authPromptWidth = authPromptAllocation.x2 - authPromptAllocation.x1;
} }
@@ -707,7 +690,7 @@ var LoginDialog = GObject.registerClass({
} }
if (authPromptAllocation) if (authPromptAllocation)
this._authPrompt.allocate(authPromptAllocation, flags); this._authPrompt.actor.allocate(authPromptAllocation, flags);
if (userSelectionAllocation) if (userSelectionAllocation)
this._userSelectionBox.allocate(userSelectionAllocation, flags); this._userSelectionBox.allocate(userSelectionAllocation, flags);
@@ -811,7 +794,7 @@ var LoginDialog = GObject.registerClass({
_onPrompted() { _onPrompted() {
if (this._shouldShowSessionMenuButton()) { if (this._shouldShowSessionMenuButton()) {
this._sessionMenuButton.updateSensitivity(true); this._sessionMenuButton.updateSensitivity(true);
this._authPrompt.setActorInDefaultButtonWell(this._sessionMenuButton); this._authPrompt.setActorInDefaultButtonWell(this._sessionMenuButton.actor);
} else { } else {
this._sessionMenuButton.updateSensitivity(false); this._sessionMenuButton.updateSensitivity(false);
} }
@@ -871,11 +854,11 @@ var LoginDialog = GObject.registerClass({
} }
_showPrompt() { _showPrompt() {
if (this._authPrompt.visible) if (this._authPrompt.actor.visible)
return; return;
this._authPrompt.opacity = 0; this._authPrompt.actor.opacity = 0;
this._authPrompt.show(); this._authPrompt.actor.show();
this._authPrompt.ease({ this._authPrompt.actor.ease({
opacity: 255, opacity: 255,
duration: _FADE_ANIMATION_TIME, duration: _FADE_ANIMATION_TIME,
mode: Clutter.AnimationMode.EASE_OUT_QUAD mode: Clutter.AnimationMode.EASE_OUT_QUAD
@@ -1062,12 +1045,12 @@ var LoginDialog = GObject.registerClass({
() => { () => {
// If idle timeout is done, make sure the timed login indicator is shown // If idle timeout is done, make sure the timed login indicator is shown
if (delay > _TIMED_LOGIN_IDLE_THRESHOLD && if (delay > _TIMED_LOGIN_IDLE_THRESHOLD &&
this._authPrompt.visible) this._authPrompt.actor.visible)
this._authPrompt.cancel(); this._authPrompt.cancel();
if (delay > _TIMED_LOGIN_IDLE_THRESHOLD || firstRun) { if (delay > _TIMED_LOGIN_IDLE_THRESHOLD || firstRun) {
this._userList.scrollToItem(loginItem); this._userList.scrollToItem(loginItem);
loginItem.grab_key_focus(); loginItem.actor.grab_key_focus();
} }
}, },
@@ -1128,7 +1111,7 @@ var LoginDialog = GObject.registerClass({
this._sessionMenuButton.close(); this._sessionMenuButton.close();
this._setUserListExpanded(true); this._setUserListExpanded(true);
this._notListedButton.show(); this._notListedButton.show();
this._userList.grab_key_focus(); this._userList.actor.grab_key_focus();
} }
_beginVerificationForItem(item) { _beginVerificationForItem(item) {
@@ -1236,7 +1219,7 @@ var LoginDialog = GObject.registerClass({
_("Login Window"), _("Login Window"),
'dialog-password-symbolic', 'dialog-password-symbolic',
{ sortGroup: CtrlAltTab.SortGroup.MIDDLE }); { sortGroup: CtrlAltTab.SortGroup.MIDDLE });
this._userList.grab_key_focus(); this._userList.actor.grab_key_focus();
this.show(); this.show();
this.opacity = 0; this.opacity = 0;

View File

@@ -1,7 +1,7 @@
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*- // -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
/* exported findUrls, spawn, spawnCommandLine, spawnApp, trySpawnCommandLine, /* exported findUrls, spawn, spawnCommandLine, spawnApp, trySpawnCommandLine,
formatTime, formatTimeSpan, createTimeLabel, insertSorted, formatTime, formatTimeSpan, createTimeLabel, insertSorted,
makeCloseButton, ensureActorVisibleInScrollView, wiggle */ makeCloseButton, ensureActorVisibleInScrollView */
const { Clutter, Gio, GLib, GObject, Shell, St } = imports.gi; const { Clutter, Gio, GLib, GObject, Shell, St } = imports.gi;
const Gettext = imports.gettext; const Gettext = imports.gettext;
@@ -429,37 +429,3 @@ function ensureActorVisibleInScrollView(scrollView, actor) {
duration: SCROLL_TIME duration: SCROLL_TIME
}); });
} }
function wiggle(actor, params) {
params = Params.parse(params, {
offset: 0,
duration: 0,
wiggleCount: 0,
});
actor.translation_x = 0;
// Accelerate before wiggling
actor.ease({
translation_x: -params.offset,
duration: params.duration,
mode: Clutter.AnimationMode.EASE_OUT_QUAD,
onComplete: () => {
// Wiggle
actor.ease({
translation_x: params.offset,
duration: params.duration,
mode: Clutter.AnimationMode.LINEAR,
repeatCount: params.wiggleCount,
autoReverse: true,
onComplete: () => {
// Decelerate and return to the original position
actor.ease({
translation_x: 0,
duration: params.duration,
mode: Clutter.AnimationMode.EASE_IN_QUAD,
});
}
});
}
});
}

View File

@@ -127,11 +127,11 @@ function *run() {
for (let i = 0; i < 2; i++) { for (let i = 0; i < 2; i++) {
Scripting.scriptEvent('applicationsShowStart'); Scripting.scriptEvent('applicationsShowStart');
// eslint-disable-next-line require-atomic-updates // eslint-disable-next-line require-atomic-updates
Main.overview.dash.showAppsButton.checked = true; Main.overview._dash.showAppsButton.checked = true;
yield Scripting.waitLeisure(); yield Scripting.waitLeisure();
Scripting.scriptEvent('applicationsShowDone'); Scripting.scriptEvent('applicationsShowDone');
// eslint-disable-next-line require-atomic-updates // eslint-disable-next-line require-atomic-updates
Main.overview.dash.showAppsButton.checked = false; Main.overview._dash.showAppsButton.checked = false;
yield Scripting.waitLeisure(); yield Scripting.waitLeisure();
} }
} }

View File

@@ -127,7 +127,7 @@ function *run() {
Scripting.scriptEvent('applicationsShowStart'); Scripting.scriptEvent('applicationsShowStart');
// eslint-disable-next-line require-atomic-updates // eslint-disable-next-line require-atomic-updates
Main.overview.dash.showAppsButton.checked = true; Main.overview._dash.showAppsButton.checked = true;
yield Scripting.waitLeisure(); yield Scripting.waitLeisure();
Scripting.scriptEvent('applicationsShowDone'); Scripting.scriptEvent('applicationsShowDone');

View File

@@ -56,8 +56,8 @@ class AccessDialog extends ModalDialog.ModalDialog {
let check = new CheckBox.CheckBox(); let check = new CheckBox.CheckBox();
check.getLabelActor().text = name; check.getLabelActor().text = name;
check.checked = selected == "true"; check.actor.checked = selected == "true";
content.insertBeforeBody(check); content.insertBeforeBody(check.actor);
this._choices.set(id, check); this._choices.set(id, check);
} }
@@ -99,7 +99,7 @@ class AccessDialog extends ModalDialog.ModalDialog {
let results = {}; let results = {};
if (response == DialogResponse.OK) { if (response == DialogResponse.OK) {
for (let [id, check] of this._choices) { for (let [id, check] of this._choices) {
let checked = check.checked ? 'true' : 'false'; let checked = check.actor.checked ? 'true' : 'false';
results[id] = new GLib.Variant('s', checked); results[id] = new GLib.Variant('s', checked);
} }
} }

View File

@@ -405,26 +405,27 @@ class AppSwitcherPopup extends SwitcherPopup.SwitcherPopup {
} }
}); });
var CyclerHighlight = GObject.registerClass( class CyclerHighlight {
class CyclerHighlight extends St.Widget { constructor() {
_init() {
super._init({ layout_manager: new Clutter.BinLayout() });
this._window = null; this._window = null;
this.actor = new St.Widget({ layout_manager: new Clutter.BinLayout() });
this._clone = new Clutter.Clone(); this._clone = new Clutter.Clone();
this.add_actor(this._clone); this.actor.add_actor(this._clone);
this._highlight = new St.Widget({ style_class: 'cycler-highlight' }); this._highlight = new St.Widget({ style_class: 'cycler-highlight' });
this.add_actor(this._highlight); this.actor.add_actor(this._highlight);
let coordinate = Clutter.BindCoordinate.ALL; let coordinate = Clutter.BindCoordinate.ALL;
let constraint = new Clutter.BindConstraint({ coordinate: coordinate }); let constraint = new Clutter.BindConstraint({ coordinate: coordinate });
this._clone.bind_property('source', constraint, 'source', 0); this._clone.bind_property('source', constraint, 'source', 0);
this.add_constraint(constraint); this.actor.add_constraint(constraint);
this.connect('notify::allocation', this._onAllocationChanged.bind(this)); this.actor.connect('notify::allocation',
this.connect('destroy', this._onDestroy.bind(this)); this._onAllocationChanged.bind(this));
this.actor.connect('destroy', this._onDestroy.bind(this));
} }
set window(w) { set window(w) {
@@ -450,7 +451,7 @@ class CyclerHighlight extends St.Widget {
this._highlight.set_size(0, 0); this._highlight.set_size(0, 0);
this._highlight.hide(); this._highlight.hide();
} else { } else {
let [x, y] = this.allocation.get_origin(); let [x, y] = this.actor.allocation.get_origin();
let rect = this._window.get_frame_rect(); let rect = this._window.get_frame_rect();
this._highlight.set_size(rect.width, rect.height); this._highlight.set_size(rect.width, rect.height);
this._highlight.set_position(rect.x - x, rect.y - y); this._highlight.set_position(rect.x - x, rect.y - y);
@@ -461,7 +462,7 @@ class CyclerHighlight extends St.Widget {
_onDestroy() { _onDestroy() {
this.window = null; this.window = null;
} }
}); }
// We don't show an actual popup, so just provide what SwitcherPopup // We don't show an actual popup, so just provide what SwitcherPopup
// expects instead of inheriting from SwitcherList // expects instead of inheriting from SwitcherList
@@ -488,7 +489,7 @@ var CyclerPopup = GObject.registerClass({
return; return;
this._highlight = new CyclerHighlight(); this._highlight = new CyclerHighlight();
global.window_group.add_actor(this._highlight); global.window_group.add_actor(this._highlight.actor);
this._switcherList = new CyclerList(); this._switcherList = new CyclerList();
this._switcherList.connect('item-highlighted', (list, index) => { this._switcherList.connect('item-highlighted', (list, index) => {
@@ -498,7 +499,7 @@ var CyclerPopup = GObject.registerClass({
_highlightItem(index, _justOutline) { _highlightItem(index, _justOutline) {
this._highlight.window = this._items[index]; this._highlight.window = this._items[index];
global.window_group.set_child_above_sibling(this._highlight, null); global.window_group.set_child_above_sibling(this._highlight.actor, null);
} }
_finish() { _finish() {
@@ -528,7 +529,7 @@ var CyclerPopup = GObject.registerClass({
} }
_onDestroy() { _onDestroy() {
this._highlight.destroy(); this._highlight.actor.destroy();
super._onDestroy(); super._onDestroy();
} }

View File

@@ -1,18 +1,19 @@
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*- // -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
/* exported Animation, AnimatedIcon, Spinner */ /* exported Animation, AnimatedIcon, Spinner */
const { Clutter, GLib, GObject, Gio, St } = imports.gi; const { Clutter, GLib, Gio, St } = imports.gi;
var ANIMATED_ICON_UPDATE_TIMEOUT = 16; var ANIMATED_ICON_UPDATE_TIMEOUT = 16;
var SPINNER_ANIMATION_TIME = 300; var SPINNER_ANIMATION_TIME = 300;
var SPINNER_ANIMATION_DELAY = 1000; var SPINNER_ANIMATION_DELAY = 1000;
var Animation = GObject.registerClass( var Animation = class {
class Animation extends St.Bin { constructor(file, width, height, speed) {
_init(file, width, height, speed) { this.actor = new St.Bin();
super._init({ width: width, height: height }); this.actor.set_size(width, height);
this.connect('destroy', this._onDestroy.bind(this)); this.actor.connect('destroy', this._onDestroy.bind(this));
this.connect('resource-scale-changed', this.actor.connect('notify::size', this._syncAnimationSize.bind(this));
this.actor.connect('resource-scale-changed',
this._loadFile.bind(this, file, width, height)); this._loadFile.bind(this, file, width, height));
let themeContext = St.ThemeContext.get_for_stage(global.stage); let themeContext = St.ThemeContext.get_for_stage(global.stage);
@@ -51,14 +52,14 @@ class Animation extends St.Bin {
} }
_loadFile(file, width, height) { _loadFile(file, width, height) {
let [validResourceScale, resourceScale] = this.get_resource_scale(); let [validResourceScale, resourceScale] = this.actor.get_resource_scale();
let wasPlaying = this._isPlaying; let wasPlaying = this._isPlaying;
if (this._isPlaying) if (this._isPlaying)
this.stop(); this.stop();
this._isLoaded = false; this._isLoaded = false;
this.destroy_all_children(); this.actor.destroy_all_children();
if (!validResourceScale) { if (!validResourceScale) {
if (wasPlaying) if (wasPlaying)
@@ -71,7 +72,7 @@ class Animation extends St.Bin {
this._animations = textureCache.load_sliced_image(file, width, height, this._animations = textureCache.load_sliced_image(file, width, height,
scaleFactor, resourceScale, scaleFactor, resourceScale,
this._animationsLoaded.bind(this)); this._animationsLoaded.bind(this));
this.set_child(this._animations); this.actor.set_child(this._animations);
if (wasPlaying) if (wasPlaying)
this.play(); this.play();
@@ -98,7 +99,7 @@ class Animation extends St.Bin {
if (!this._isLoaded) if (!this._isLoaded)
return; return;
let [width, height] = this.get_size(); let [width, height] = this.actor.get_size();
for (let i = 0; i < this._animations.get_n_children(); ++i) for (let i = 0; i < this._animations.get_n_children(); ++i)
this._animations.get_child_at_index(i).set_size(width, height); this._animations.get_child_at_index(i).set_size(width, height);
@@ -121,22 +122,20 @@ class Animation extends St.Bin {
themeContext.disconnect(this._scaleChangedId); themeContext.disconnect(this._scaleChangedId);
this._scaleChangedId = 0; this._scaleChangedId = 0;
} }
}); };
var AnimatedIcon = GObject.registerClass( var AnimatedIcon = class extends Animation {
class AnimatedIcon extends Animation { constructor(file, size) {
_init(file, size) { super(file, size, size, ANIMATED_ICON_UPDATE_TIMEOUT);
super._init(file, size, size, ANIMATED_ICON_UPDATE_TIMEOUT);
} }
}); };
var Spinner = GObject.registerClass( var Spinner = class extends AnimatedIcon {
class Spinner extends AnimatedIcon { constructor(size, animate = false) {
_init(size, animate = false) {
let file = Gio.File.new_for_uri('resource:///org/gnome/shell/theme/process-working.svg'); let file = Gio.File.new_for_uri('resource:///org/gnome/shell/theme/process-working.svg');
super._init(file, size); super(file, size);
this.opacity = 0; this.actor.opacity = 0;
this._animate = animate; this._animate = animate;
} }
@@ -146,35 +145,35 @@ class Spinner extends AnimatedIcon {
} }
play() { play() {
this.remove_all_transitions(); this.actor.remove_all_transitions();
if (this._animate) { if (this._animate) {
super.play(); super.play();
this.ease({ this.actor.ease({
opacity: 255, opacity: 255,
delay: SPINNER_ANIMATION_DELAY, delay: SPINNER_ANIMATION_DELAY,
duration: SPINNER_ANIMATION_TIME, duration: SPINNER_ANIMATION_TIME,
mode: Clutter.AnimationMode.LINEAR mode: Clutter.AnimationMode.LINEAR
}); });
} else { } else {
this.opacity = 255; this.actor.opacity = 255;
super.play(); super.play();
} }
} }
stop() { stop() {
this.remove_all_transitions(); this.actor.remove_all_transitions();
if (this._animate) { if (this._animate) {
this.ease({ this.actor.ease({
opacity: 0, opacity: 0,
duration: SPINNER_ANIMATION_TIME, time: SPINNER_ANIMATION_TIME,
mode: Clutter.AnimationMode.LINEAR, transition: 'linear',
onComplete: () => super.stop() onComplete: () => super.stop()
}); });
} else { } else {
this.opacity = 0; this.actor.opacity = 0;
super.stop(); super.stop();
} }
} }
}); };

File diff suppressed because it is too large Load Diff

View File

@@ -55,7 +55,6 @@ const RENAMED_DESKTOP_IDS = {
'org.gnome.taquin.desktop': 'org.gnome.Taquin.desktop', 'org.gnome.taquin.desktop': 'org.gnome.Taquin.desktop',
'org.gnome.Weather.Application.desktop': 'org.gnome.Weather.desktop', 'org.gnome.Weather.Application.desktop': 'org.gnome.Weather.desktop',
'polari.desktop': 'org.gnome.Polari.desktop', 'polari.desktop': 'org.gnome.Polari.desktop',
'shotwell.desktop': 'org.gnome.Shotwell.desktop',
'tali.desktop': 'org.gnome.Tali.desktop', 'tali.desktop': 'org.gnome.Tali.desktop',
'totem.desktop': 'org.gnome.Totem.desktop', 'totem.desktop': 'org.gnome.Totem.desktop',
'evince.desktop': 'org.gnome.Evince.desktop', 'evince.desktop': 'org.gnome.Evince.desktop',

View File

@@ -1,5 +1,4 @@
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*- // -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
/* exported SystemBackground */
// READ THIS FIRST // READ THIS FIRST
// Background handling is a maze of objects, both objects in this file, and // Background handling is a maze of objects, both objects in this file, and
@@ -94,7 +93,7 @@
// MetaBackgroundImage MetaBackgroundImage // MetaBackgroundImage MetaBackgroundImage
// MetaBackgroundImage MetaBackgroundImage // MetaBackgroundImage MetaBackgroundImage
const { Clutter, GDesktopEnums, Gio, GLib, GObject, GnomeDesktop, Meta } = imports.gi; const { Clutter, GDesktopEnums, Gio, GLib, GnomeDesktop, Meta } = imports.gi;
const Signals = imports.signals; const Signals = imports.signals;
const LoginManager = imports.misc.loginManager; const LoginManager = imports.misc.loginManager;
@@ -221,17 +220,16 @@ function getBackgroundCache() {
return _backgroundCache; return _backgroundCache;
} }
var Background = GObject.registerClass({ var Background = class Background {
Signals: { 'loaded': {}, 'bg-changed': {} } constructor(params) {
}, class Background extends Meta.Background {
_init(params) {
params = Params.parse(params, { monitorIndex: 0, params = Params.parse(params, { monitorIndex: 0,
layoutManager: Main.layoutManager, layoutManager: Main.layoutManager,
settings: null, settings: null,
file: null, file: null,
style: null }); style: null });
super._init({ meta_display: global.display }); this.background = new Meta.Background({ meta_display: global.display });
this.background._delegate = this;
this._settings = params.settings; this._settings = params.settings;
this._file = params.file; this._file = params.file;
@@ -264,6 +262,8 @@ var Background = GObject.registerClass({
} }
destroy() { destroy() {
this.background = null;
this._cancellable.cancel(); this._cancellable.cancel();
this._removeAnimationTimeout(); this._removeAnimationTimeout();
@@ -300,11 +300,9 @@ var Background = GObject.registerClass({
this._changedIdleId = GLib.idle_add(GLib.PRIORITY_DEFAULT, () => { this._changedIdleId = GLib.idle_add(GLib.PRIORITY_DEFAULT, () => {
this._changedIdleId = 0; this._changedIdleId = 0;
this.emit('bg-changed'); this.emit('changed');
return GLib.SOURCE_REMOVE; return GLib.SOURCE_REMOVE;
}); });
GLib.Source.set_name_by_id(this._changedIdleId,
'[gnome-shell] Background._emitChangedSignal');
} }
updateResolution() { updateResolution() {
@@ -330,7 +328,7 @@ var Background = GObject.registerClass({
this.emit('loaded'); this.emit('loaded');
return GLib.SOURCE_REMOVE; return GLib.SOURCE_REMOVE;
}); });
GLib.Source.set_name_by_id(id, '[gnome-shell] Background._setLoaded Idle'); GLib.Source.set_name_by_id(id, '[gnome-shell] this.emit');
} }
_loadPattern() { _loadPattern() {
@@ -344,9 +342,9 @@ var Background = GObject.registerClass({
let shadingType = this._settings.get_enum(COLOR_SHADING_TYPE_KEY); let shadingType = this._settings.get_enum(COLOR_SHADING_TYPE_KEY);
if (shadingType == GDesktopEnums.BackgroundShading.SOLID) if (shadingType == GDesktopEnums.BackgroundShading.SOLID)
this.set_color(color); this.background.set_color(color);
else else
this.set_gradient(shadingType, color, secondColor); this.background.set_gradient(shadingType, color, secondColor);
} }
_watchFile(file) { _watchFile(file) {
@@ -382,13 +380,13 @@ var Background = GObject.registerClass({
let finish = () => { let finish = () => {
this._setLoaded(); this._setLoaded();
if (files.length > 1) { if (files.length > 1) {
this.set_blend(files[0], files[1], this.background.set_blend(files[0], files[1],
this._animation.transitionProgress, this._animation.transitionProgress,
this._style); this._style);
} else if (files.length > 0) { } else if (files.length > 0) {
this.set_file(files[0], this._style); this.background.set_file(files[0], this._style);
} else { } else {
this.set_file(null, this._style); this.background.set_file(null, this._style);
} }
this._queueUpdateAnimation(); this._queueUpdateAnimation();
}; };
@@ -461,7 +459,7 @@ var Background = GObject.registerClass({
} }
_loadImage(file) { _loadImage(file) {
this.set_file(file, this._style); this.background.set_file(file, this._style);
this._watchFile(file); this._watchFile(file);
let cache = Meta.BackgroundImageCache.get_default(); let cache = Meta.BackgroundImageCache.get_default();
@@ -495,14 +493,13 @@ var Background = GObject.registerClass({
this._loadFile(this._file); this._loadFile(this._file);
} }
}); };
Signals.addSignalMethods(Background.prototype);
let _systemBackground; let _systemBackground;
var SystemBackground = GObject.registerClass({ var SystemBackground = class SystemBackground {
Signals: { 'loaded': {} } constructor() {
}, class SystemBackground extends Meta.BackgroundActor {
_init() {
let file = Gio.File.new_for_uri('resource:///org/gnome/shell/theme/noise-texture.png'); let file = Gio.File.new_for_uri('resource:///org/gnome/shell/theme/noise-texture.png');
if (_systemBackground == null) { if (_systemBackground == null) {
@@ -511,11 +508,9 @@ var SystemBackground = GObject.registerClass({
_systemBackground.set_file(file, GDesktopEnums.BackgroundStyle.WALLPAPER); _systemBackground.set_file(file, GDesktopEnums.BackgroundStyle.WALLPAPER);
} }
super._init({ this.actor = new Meta.BackgroundActor({ meta_display: global.display,
meta_display: global.display, monitor: 0,
monitor: 0, background: _systemBackground });
background: _systemBackground
});
let cache = Meta.BackgroundImageCache.get_default(); let cache = Meta.BackgroundImageCache.get_default();
let image = cache.load(file); let image = cache.load(file);
@@ -534,7 +529,8 @@ var SystemBackground = GObject.registerClass({
}); });
} }
} }
}); };
Signals.addSignalMethods(SystemBackground.prototype);
var BackgroundSource = class BackgroundSource { var BackgroundSource = class BackgroundSource {
constructor(layoutManager, settingsSchema) { constructor(layoutManager, settingsSchema) {
@@ -570,7 +566,7 @@ var BackgroundSource = class BackgroundSource {
// We don't watch changes to settings here, // We don't watch changes to settings here,
// instead we rely on Background to watch those // instead we rely on Background to watch those
// and emit 'bg-changed' at the right time // and emit 'changed' at the right time
if (this._overrideImage != null) { if (this._overrideImage != null) {
file = Gio.File.new_for_path(this._overrideImage); file = Gio.File.new_for_path(this._overrideImage);
@@ -599,7 +595,7 @@ var BackgroundSource = class BackgroundSource {
style: style style: style
}); });
background._changedId = background.connect('bg-changed', () => { background._changedId = background.connect('changed', () => {
background.disconnect(background._changedId); background.disconnect(background._changedId);
background.destroy(); background.destroy();
delete this._backgrounds[monitorIndex]; delete this._backgrounds[monitorIndex];
@@ -736,7 +732,7 @@ var BackgroundManager = class BackgroundManager {
this._newBackgroundActor = newBackgroundActor; this._newBackgroundActor = newBackgroundActor;
let background = newBackgroundActor.background; let background = newBackgroundActor.background._delegate;
if (background.isLoaded) { if (background.isLoaded) {
this._swapBackgroundActor(); this._swapBackgroundActor();
@@ -756,7 +752,7 @@ var BackgroundManager = class BackgroundManager {
let backgroundActor = new Meta.BackgroundActor({ let backgroundActor = new Meta.BackgroundActor({
meta_display: global.display, meta_display: global.display,
monitor: this._monitorIndex, monitor: this._monitorIndex,
background, background: background.background,
vignette: this._vignette, vignette: this._vignette,
vignette_sharpness: 0.5, vignette_sharpness: 0.5,
brightness: 0.5, brightness: 0.5,
@@ -770,7 +766,7 @@ var BackgroundManager = class BackgroundManager {
backgroundActor.lower_bottom(); backgroundActor.lower_bottom();
} }
let changeSignalId = background.connect('bg-changed', () => { let changeSignalId = background.connect('changed', () => {
background.disconnect(changeSignalId); background.disconnect(changeSignalId);
changeSignalId = null; changeSignalId = null;
this._updateBackgroundActor(); this._updateBackgroundActor();

View File

@@ -46,18 +46,12 @@ var BoxPointer = GObject.registerClass({
this.add_actor(this._border); this.add_actor(this._border);
this.bin.raise(this._border); this.bin.raise(this._border);
this._sourceAlignment = 0.5; this._sourceAlignment = 0.5;
this._muteInput = true; this._capturedEventId = 0;
this._muteInput();
this.connect('destroy', this._onDestroy.bind(this)); this.connect('destroy', this._onDestroy.bind(this));
} }
vfunc_captured_event() {
if (this._muteInput)
return Clutter.EVENT_STOP;
return Clutter.EVENT_PROPAGATE;
}
_onDestroy() { _onDestroy() {
if (this._sourceActorDestroyId) { if (this._sourceActorDestroyId) {
this._sourceActor.disconnect(this._sourceActorDestroyId); this._sourceActor.disconnect(this._sourceActorDestroyId);
@@ -69,6 +63,19 @@ var BoxPointer = GObject.registerClass({
return this._arrowSide; return this._arrowSide;
} }
_muteInput() {
if (this._capturedEventId == 0)
this._capturedEventId = this.connect('captured-event',
() => Clutter.EVENT_STOP);
}
_unmuteInput() {
if (this._capturedEventId != 0) {
this.disconnect(this._capturedEventId);
this._capturedEventId = 0;
}
}
open(animate, onComplete) { open(animate, onComplete) {
let themeNode = this.get_theme_node(); let themeNode = this.get_theme_node();
let rise = themeNode.get_length('-arrow-rise'); let rise = themeNode.get_length('-arrow-rise');
@@ -105,7 +112,7 @@ var BoxPointer = GObject.registerClass({
duration: animationTime, duration: animationTime,
mode: Clutter.AnimationMode.LINEAR, mode: Clutter.AnimationMode.LINEAR,
onComplete: () => { onComplete: () => {
this._muteInput = false; this._unmuteInput();
if (onComplete) if (onComplete)
onComplete(); onComplete();
} }
@@ -140,7 +147,7 @@ var BoxPointer = GObject.registerClass({
} }
} }
this._muteInput = true; this._muteInput();
this.remove_all_transitions(); this.remove_all_transitions();
this.ease({ this.ease({

View File

@@ -313,10 +313,8 @@ var DBusEventSource = class DBusEventSource {
}; };
Signals.addSignalMethods(DBusEventSource.prototype); Signals.addSignalMethods(DBusEventSource.prototype);
var Calendar = GObject.registerClass({ var Calendar = class Calendar {
Signals: { 'selected-date-changed': { param_types: [GLib.DateTime.$gtype] } } constructor() {
}, class Calendar extends St.Widget {
_init() {
this._weekStart = Shell.util_get_week_start(); this._weekStart = Shell.util_get_week_start();
this._settings = new Gio.Settings({ schema_id: 'org.gnome.desktop.calendar' }); this._settings = new Gio.Settings({ schema_id: 'org.gnome.desktop.calendar' });
@@ -346,11 +344,12 @@ var Calendar = GObject.registerClass({
this._shouldDateGrabFocus = false; this._shouldDateGrabFocus = false;
super._init({ this.actor = new St.Widget({ style_class: 'calendar',
style_class: 'calendar', layout_manager: new Clutter.TableLayout(),
layout_manager: new Clutter.TableLayout(), reactive: true });
reactive: true
}); this.actor.connect('scroll-event',
this._onScroll.bind(this));
this._buildHeader (); this._buildHeader ();
} }
@@ -374,10 +373,7 @@ var Calendar = GObject.registerClass({
this._selectedDate = date; this._selectedDate = date;
this._update(); this._update();
this.emit('selected-date-changed', new Date(this._selectedDate));
let datetime = GLib.DateTime.new_from_unix_local(
this._selectedDate.getTime() / 1000);
this.emit('selected-date-changed', datetime);
} }
updateTimeZone() { updateTimeZone() {
@@ -388,9 +384,9 @@ var Calendar = GObject.registerClass({
} }
_buildHeader() { _buildHeader() {
let layout = this.layout_manager; let layout = this.actor.layout_manager;
let offsetCols = this._useWeekdate ? 1 : 0; let offsetCols = this._useWeekdate ? 1 : 0;
this.destroy_all_children(); this.actor.destroy_all_children();
// Top line of the calendar '<| September 2009 |>' // Top line of the calendar '<| September 2009 |>'
this._topBox = new St.BoxLayout(); this._topBox = new St.BoxLayout();
@@ -432,7 +428,7 @@ var Calendar = GObject.registerClass({
can_focus: true }); can_focus: true });
label.accessible_name = iter.toLocaleFormat('%A'); label.accessible_name = iter.toLocaleFormat('%A');
let col; let col;
if (this.get_text_direction() == Clutter.TextDirection.RTL) if (this.actor.get_text_direction() == Clutter.TextDirection.RTL)
col = 6 - (7 + iter.getDay() - this._weekStart) % 7; col = 6 - (7 + iter.getDay() - this._weekStart) % 7;
else else
col = offsetCols + (7 + iter.getDay() - this._weekStart) % 7; col = offsetCols + (7 + iter.getDay() - this._weekStart) % 7;
@@ -441,11 +437,11 @@ var Calendar = GObject.registerClass({
} }
// All the children after this are days, and get removed when we update the calendar // All the children after this are days, and get removed when we update the calendar
this._firstDayIndex = this.get_n_children(); this._firstDayIndex = this.actor.get_n_children();
} }
vfunc_scroll_event(scrollEvent) { _onScroll(actor, event) {
switch (scrollEvent.direction) { switch (event.get_scroll_direction()) {
case Clutter.ScrollDirection.UP: case Clutter.ScrollDirection.UP:
case Clutter.ScrollDirection.LEFT: case Clutter.ScrollDirection.LEFT:
this._onPrevMonthButtonClicked(); this._onPrevMonthButtonClicked();
@@ -515,7 +511,7 @@ var Calendar = GObject.registerClass({
let now = new Date(); let now = new Date();
// Remove everything but the topBox and the weekday labels // Remove everything but the topBox and the weekday labels
let children = this.get_children(); let children = this.actor.get_children();
for (let i = this._firstDayIndex; i < children.length; i++) for (let i = this._firstDayIndex; i < children.length; i++)
children[i].destroy(); children[i].destroy();
@@ -552,7 +548,7 @@ var Calendar = GObject.registerClass({
beginDate.setTime(beginDate.getTime() - (weekPadding + daysToWeekStart) * MSECS_IN_DAY); beginDate.setTime(beginDate.getTime() - (weekPadding + daysToWeekStart) * MSECS_IN_DAY);
let layout = this.layout_manager; let layout = this.actor.layout_manager;
let iter = new Date(beginDate); let iter = new Date(beginDate);
let row = 2; let row = 2;
// nRows here means 6 weeks + one header + one navbar // nRows here means 6 weeks + one header + one navbar
@@ -652,12 +648,12 @@ var Calendar = GObject.registerClass({
} }
}); });
} }
}); };
Signals.addSignalMethods(Calendar.prototype);
var EventMessage = GObject.registerClass( var EventMessage = class EventMessage extends MessageList.Message {
class EventMessage extends MessageList.Message { constructor(event, date) {
_init(event, date) { super('', event.summary);
super._init('', event.summary);
this._event = event; this._event = event;
this._date = date; this._date = date;
@@ -666,12 +662,11 @@ class EventMessage extends MessageList.Message {
this._icon = new St.Icon({ icon_name: 'x-office-calendar-symbolic' }); this._icon = new St.Icon({ icon_name: 'x-office-calendar-symbolic' });
this.setIcon(this._icon); this.setIcon(this._icon);
}
vfunc_style_changed() { this.actor.connect('style-changed', () => {
let iconVisible = this.get_parent().has_style_pseudo_class('first-child'); let iconVisible = this.actor.get_parent().has_style_pseudo_class('first-child');
this._icon.opacity = (iconVisible ? 255 : 0); this._icon.opacity = (iconVisible ? 255 : 0);
super.vfunc_style_changed(); });
} }
_formatEventTime() { _formatEventTime() {
@@ -707,12 +702,12 @@ class EventMessage extends MessageList.Message {
} }
return title; return title;
} }
}); };
var NotificationMessage = GObject.registerClass( var NotificationMessage =
class NotificationMessage extends MessageList.Message { class NotificationMessage extends MessageList.Message {
_init(notification) { constructor(notification) {
super._init(notification.title, notification.bannerBodyText); super(notification.title, notification.bannerBodyText);
this.setUseBodyMarkup(notification.bannerBodyMarkup); this.setUseBodyMarkup(notification.bannerBodyMarkup);
this.notification = notification; this.notification = notification;
@@ -749,7 +744,7 @@ class NotificationMessage extends MessageList.Message {
this.setUseBodyMarkup(n.bannerBodyMarkup); this.setUseBodyMarkup(n.bannerBodyMarkup);
} }
vfunc_clicked() { _onClicked() {
this.notification.activate(); this.notification.activate();
} }
@@ -771,12 +766,11 @@ class NotificationMessage extends MessageList.Message {
canClose() { canClose() {
return true; return true;
} }
}); };
var EventsSection = GObject.registerClass( var EventsSection = class EventsSection extends MessageList.MessageListSection {
class EventsSection extends MessageList.MessageListSection { constructor() {
_init() { super();
super._init();
this._desktopSettings = new Gio.Settings({ schema_id: 'org.gnome.desktop.interface' }); this._desktopSettings = new Gio.Settings({ schema_id: 'org.gnome.desktop.interface' });
this._desktopSettings.connect('changed', this._reloadEvents.bind(this)); this._desktopSettings.connect('changed', this._reloadEvents.bind(this));
@@ -788,7 +782,7 @@ class EventsSection extends MessageList.MessageListSection {
label: '', label: '',
x_align: St.Align.START, x_align: St.Align.START,
can_focus: true }); can_focus: true });
this.insert_child_below(this._title, null); this.actor.insert_child_below(this._title, null);
this._title.connect('clicked', this._onTitleClicked.bind(this)); this._title.connect('clicked', this._onTitleClicked.bind(this));
this._title.connect('key-focus-in', this._onKeyFocusIn.bind(this)); this._title.connect('key-focus-in', this._onKeyFocusIn.bind(this));
@@ -907,29 +901,12 @@ class EventsSection extends MessageList.MessageListSection {
super._sync(); super._sync();
} }
}); };
var TimeLabel = GObject.registerClass( var NotificationSection =
class NotificationTimeLabel extends St.Label {
_init(datetime) {
super._init({
style_class: 'event-time',
x_align: Clutter.ActorAlign.START,
y_align: Clutter.ActorAlign.END
});
this._datetime = datetime;
}
vfunc_map() {
this.text = Util.formatTimeSpan(this._datetime);
super.vfunc_map();
}
});
var NotificationSection = GObject.registerClass(
class NotificationSection extends MessageList.MessageListSection { class NotificationSection extends MessageList.MessageListSection {
_init() { constructor() {
super._init(); super();
this._sources = new Map(); this._sources = new Map();
this._nUrgent = 0; this._nUrgent = 0;
@@ -938,6 +915,8 @@ class NotificationSection extends MessageList.MessageListSection {
Main.messageTray.getSources().forEach(source => { Main.messageTray.getSources().forEach(source => {
this._sourceAdded(Main.messageTray, source); this._sourceAdded(Main.messageTray, source);
}); });
this.actor.connect('notify::mapped', this._onMapped.bind(this));
} }
get allowed() { get allowed() {
@@ -945,6 +924,17 @@ class NotificationSection extends MessageList.MessageListSection {
!Main.sessionMode.isGreeter; !Main.sessionMode.isGreeter;
} }
_createTimeLabel(datetime) {
let label = new St.Label({ style_class: 'event-time',
x_align: Clutter.ActorAlign.START,
y_align: Clutter.ActorAlign.END });
label.connect('notify::mapped', () => {
if (label.mapped)
label.text = Util.formatTimeSpan(datetime);
});
return label;
}
_sourceAdded(tray, source) { _sourceAdded(tray, source) {
let obj = { let obj = {
destroyId: 0, destroyId: 0,
@@ -962,13 +952,13 @@ class NotificationSection extends MessageList.MessageListSection {
_onNotificationAdded(source, notification) { _onNotificationAdded(source, notification) {
let message = new NotificationMessage(notification); let message = new NotificationMessage(notification);
message.setSecondaryActor(new TimeLabel(notification.datetime)); message.setSecondaryActor(this._createTimeLabel(notification.datetime));
let isUrgent = notification.urgency == MessageTray.Urgency.CRITICAL; let isUrgent = notification.urgency == MessageTray.Urgency.CRITICAL;
let updatedId = notification.connect('updated', () => { let updatedId = notification.connect('updated', () => {
message.setSecondaryActor(new TimeLabel(notification.datetime)); message.setSecondaryActor(this._createTimeLabel(notification.datetime));
this.moveMessage(message, isUrgent ? 0 : this._nUrgent, this.mapped); this.moveMessage(message, isUrgent ? 0 : this._nUrgent, this.actor.mapped);
}); });
let destroyId = notification.connect('destroy', () => { let destroyId = notification.connect('destroy', () => {
notification.disconnect(destroyId); notification.disconnect(destroyId);
@@ -988,7 +978,7 @@ class NotificationSection extends MessageList.MessageListSection {
} }
let index = isUrgent ? 0 : this._nUrgent; let index = isUrgent ? 0 : this._nUrgent;
this.addMessageAtIndex(message, index, this.mapped); this.addMessageAtIndex(message, index, this.actor.mapped);
} }
_onSourceDestroy(source, obj) { _onSourceDestroy(source, obj) {
@@ -998,23 +988,25 @@ class NotificationSection extends MessageList.MessageListSection {
this._sources.delete(source); this._sources.delete(source);
} }
vfunc_map() { _onMapped() {
this._messages.forEach(message => { if (!this.actor.mapped)
return;
for (let message of this._messages.keys())
if (message.notification.urgency != MessageTray.Urgency.CRITICAL) if (message.notification.urgency != MessageTray.Urgency.CRITICAL)
message.notification.acknowledged = true; message.notification.acknowledged = true;
});
super.vfunc_map();
} }
_shouldShow() { _shouldShow() {
return !this.empty && isToday(this._date); return !this.empty && isToday(this._date);
} }
}); };
var Placeholder = class Placeholder {
constructor() {
this.actor = new St.BoxLayout({ style_class: 'message-list-placeholder',
vertical: true });
var Placeholder = GObject.registerClass(
class Placeholder extends St.BoxLayout {
_init() {
super._init({ style_class: 'message-list-placeholder', vertical: true });
this._date = new Date(); this._date = new Date();
let todayFile = Gio.File.new_for_uri('resource:///org/gnome/shell/theme/no-notifications.svg'); let todayFile = Gio.File.new_for_uri('resource:///org/gnome/shell/theme/no-notifications.svg');
@@ -1023,10 +1015,10 @@ class Placeholder extends St.BoxLayout {
this._otherIcon = new Gio.FileIcon({ file: otherFile }); this._otherIcon = new Gio.FileIcon({ file: otherFile });
this._icon = new St.Icon(); this._icon = new St.Icon();
this.add_actor(this._icon); this.actor.add_actor(this._icon);
this._label = new St.Label(); this._label = new St.Label();
this.add_actor(this._label); this.actor.add_actor(this._label);
this._sync(); this._sync();
} }
@@ -1053,24 +1045,20 @@ class Placeholder extends St.BoxLayout {
this._label.text = _("No Events"); this._label.text = _("No Events");
} }
} }
}); };
var CalendarMessageList = GObject.registerClass( var CalendarMessageList = class CalendarMessageList {
class CalendarMessageList extends St.Widget { constructor() {
_init() { this.actor = new St.Widget({ style_class: 'message-list',
super._init({ layout_manager: new Clutter.BinLayout(),
style_class: 'message-list', x_expand: true, y_expand: true });
layout_manager: new Clutter.BinLayout(),
x_expand: true,
y_expand: true
});
this._placeholder = new Placeholder(); this._placeholder = new Placeholder();
this.add_actor(this._placeholder); this.actor.add_actor(this._placeholder.actor);
let box = new St.BoxLayout({ vertical: true, let box = new St.BoxLayout({ vertical: true,
x_expand: true, y_expand: true }); x_expand: true, y_expand: true });
this.add_actor(box); this.actor.add_actor(box);
this._scrollView = new St.ScrollView({ style_class: 'vfade', this._scrollView = new St.ScrollView({ style_class: 'vfade',
overlay_scrollbars: true, overlay_scrollbars: true,
@@ -1084,11 +1072,12 @@ class CalendarMessageList extends St.Widget {
can_focus: true }); can_focus: true });
this._clearButton.set_x_align(Clutter.ActorAlign.END); this._clearButton.set_x_align(Clutter.ActorAlign.END);
this._clearButton.connect('clicked', () => { this._clearButton.connect('clicked', () => {
this._sectionList.get_children().forEach(s => s.clear()); let sections = [...this._sections.keys()];
sections.forEach(s => s.clear());
}); });
box.add_actor(this._clearButton); box.add_actor(this._clearButton);
this._placeholder.bind_property('visible', this._placeholder.actor.bind_property('visible',
this._clearButton, 'visible', this._clearButton, 'visible',
GObject.BindingFlags.INVERT_BOOLEAN); GObject.BindingFlags.INVERT_BOOLEAN);
@@ -1096,9 +1085,8 @@ class CalendarMessageList extends St.Widget {
vertical: true, vertical: true,
y_expand: true, y_expand: true,
y_align: Clutter.ActorAlign.START }); y_align: Clutter.ActorAlign.START });
this._sectionList.connect('actor-added', this._sync.bind(this));
this._sectionList.connect('actor-removed', this._sync.bind(this));
this._scrollView.add_actor(this._sectionList); this._scrollView.add_actor(this._sectionList);
this._sections = new Map();
this._mediaSection = new Mpris.MediaSection(); this._mediaSection = new Mpris.MediaSection();
this._addSection(this._mediaSection); this._addSection(this._mediaSection);
@@ -1113,35 +1101,58 @@ class CalendarMessageList extends St.Widget {
} }
_addSection(section) { _addSection(section) {
let connectionsIds = []; let obj = {
destroyId: 0,
visibleId: 0,
emptyChangedId: 0,
canClearChangedId: 0,
keyFocusId: 0
};
obj.destroyId = section.actor.connect('destroy', () => {
this._removeSection(section);
});
obj.visibleId = section.actor.connect('notify::visible',
this._sync.bind(this));
obj.emptyChangedId = section.connect('empty-changed',
this._sync.bind(this));
obj.canClearChangedId = section.connect('can-clear-changed',
this._sync.bind(this));
obj.keyFocusId = section.connect('key-focus-in',
this._onKeyFocusIn.bind(this));
for (let prop of ['visible', 'empty', 'can-clear']) { this._sections.set(section, obj);
connectionsIds.push( this._sectionList.add_actor(section.actor);
section.connect(`notify::${prop}`, this._sync.bind(this))); this._sync();
} }
connectionsIds.push(section.connect('message-focused', (_s, messageActor) => {
Util.ensureActorVisibleInScrollView(this._scrollView, messageActor);
}));
connectionsIds.push(section.connect('destroy', (section) => { _removeSection(section) {
connectionsIds.forEach(id => section.disconnect(id)); let obj = this._sections.get(section);
this._sectionList.remove_actor(section); section.actor.disconnect(obj.destroyId);
})); section.actor.disconnect(obj.visibleId);
section.disconnect(obj.emptyChangedId);
section.disconnect(obj.canClearChangedId);
section.disconnect(obj.keyFocusId);
this._sectionList.add_actor(section); this._sections.delete(section);
this._sectionList.remove_actor(section.actor);
this._sync();
}
_onKeyFocusIn(section, actor) {
Util.ensureActorVisibleInScrollView(this._scrollView, actor);
} }
_sync() { _sync() {
let sections = this._sectionList.get_children(); let sections = [...this._sections.keys()];
let visible = sections.some(s => s.allowed); let visible = sections.some(s => s.allowed);
this.visible = visible; this.actor.visible = visible;
if (!visible) if (!visible)
return; return;
let empty = sections.every(s => s.empty || !s.visible); let empty = sections.every(s => s.empty || !s.actor.visible);
this._placeholder.visible = empty; this._placeholder.actor.visible = empty;
let canClear = sections.some(s => s.canClear && s.visible); let canClear = sections.some(s => s.canClear && s.actor.visible);
this._clearButton.reactive = canClear; this._clearButton.reactive = canClear;
} }
@@ -1150,7 +1161,8 @@ class CalendarMessageList extends St.Widget {
} }
setDate(date) { setDate(date) {
this._sectionList.get_children().forEach(s => s.setDate(date)); for (let section of this._sections.keys())
section.setDate(date);
this._placeholder.setDate(date); this._placeholder.setDate(date);
} }
}); };

View File

@@ -1,19 +1,16 @@
/* exported CheckBox */ /* exported CheckBox */
const { Clutter, GObject, Pango, St } = imports.gi; const { Clutter, Pango, St } = imports.gi;
var CheckBox = GObject.registerClass( var CheckBox = class CheckBox {
class CheckBox extends St.Button { constructor(label) {
_init(label) {
let container = new St.BoxLayout(); let container = new St.BoxLayout();
super._init({ this.actor = new St.Button({ style_class: 'check-box',
style_class: 'check-box', child: container,
child: container, button_mask: St.ButtonMask.ONE,
button_mask: St.ButtonMask.ONE, toggle_mode: true,
toggle_mode: true, can_focus: true,
can_focus: true, x_fill: true,
x_fill: true, y_fill: true });
y_fill: true
});
this._box = new St.Bin(); this._box = new St.Bin();
this._box.set_y_align(Clutter.ActorAlign.START); this._box.set_y_align(Clutter.ActorAlign.START);
@@ -35,4 +32,4 @@ class CheckBox extends St.Button {
getLabelActor() { getLabelActor() {
return this._label; return this._label;
} }
}); };

View File

@@ -1,7 +1,7 @@
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*- // -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
/* exported Component */ /* exported Component */
const { Gio, GObject, St } = imports.gi; const { Gio, St } = imports.gi;
const GnomeSession = imports.misc.gnomeSession; const GnomeSession = imports.misc.gnomeSession;
const Main = imports.ui.main; const Main = imports.ui.main;
@@ -272,10 +272,9 @@ var AutorunDispatcher = class {
} }
}; };
var AutorunSource = GObject.registerClass( var AutorunSource = class extends MessageTray.Source {
class AutorunSource extends MessageTray.Source { constructor(manager, mount, apps) {
_init(manager, mount, apps) { super(mount.get_name());
super._init(mount.get_name());
this._manager = manager; this._manager = manager;
this.mount = mount; this.mount = mount;
@@ -285,7 +284,7 @@ class AutorunSource extends MessageTray.Source {
// add ourselves as a source, and popup the notification // add ourselves as a source, and popup the notification
Main.messageTray.add(this); Main.messageTray.add(this);
this.showNotification(this._notification); this.notify(this._notification);
} }
getIcon() { getIcon() {
@@ -295,12 +294,11 @@ class AutorunSource extends MessageTray.Source {
_createPolicy() { _createPolicy() {
return new MessageTray.NotificationApplicationPolicy('org.gnome.Nautilus'); return new MessageTray.NotificationApplicationPolicy('org.gnome.Nautilus');
} }
}); };
var AutorunNotification = GObject.registerClass( var AutorunNotification = class extends MessageTray.Notification {
class AutorunNotification extends MessageTray.Notification { constructor(manager, source) {
_init(manager, source) { super(source, source.title);
super._init(source, source.title);
this._manager = manager; this._manager = manager;
this._mount = source.mount; this._mount = source.mount;
@@ -352,6 +350,6 @@ class AutorunNotification extends MessageTray.Notification {
let app = Gio.app_info_get_default_for_type('inode/directory', false); let app = Gio.app_info_get_default_for_type('inode/directory', false);
startAppForMount(app, this._mount); startAppForMount(app, this._mount);
} }
}); };
var Component = AutorunManager; var Component = AutorunManager;

View File

@@ -77,13 +77,13 @@ class KeyringDialog extends ModalDialog.ModalDialog {
this._workSpinner = new Animation.Spinner(WORK_SPINNER_ICON_SIZE, true); this._workSpinner = new Animation.Spinner(WORK_SPINNER_ICON_SIZE, true);
if (rtl) { if (rtl) {
layout.attach(this._workSpinner, 0, row, 1, 1); layout.attach(this._workSpinner.actor, 0, row, 1, 1);
layout.attach(this._passwordEntry, 1, row, 1, 1); layout.attach(this._passwordEntry, 1, row, 1, 1);
layout.attach(label, 2, row, 1, 1); layout.attach(label, 2, row, 1, 1);
} else { } else {
layout.attach(label, 0, row, 1, 1); layout.attach(label, 0, row, 1, 1);
layout.attach(this._passwordEntry, 1, row, 1, 1); layout.attach(this._passwordEntry, 1, row, 1, 1);
layout.attach(this._workSpinner, 2, row, 1, 1); layout.attach(this._workSpinner.actor, 2, row, 1, 1);
} }
row++; row++;
} else { } else {
@@ -121,8 +121,8 @@ class KeyringDialog extends ModalDialog.ModalDialog {
if (this.prompt.choice_visible) { if (this.prompt.choice_visible) {
let choice = new CheckBox.CheckBox(); let choice = new CheckBox.CheckBox();
this.prompt.bind_property('choice-label', choice.getLabelActor(), 'text', GObject.BindingFlags.SYNC_CREATE); this.prompt.bind_property('choice-label', choice.getLabelActor(), 'text', GObject.BindingFlags.SYNC_CREATE);
this.prompt.bind_property('choice-chosen', choice, 'checked', GObject.BindingFlags.SYNC_CREATE | GObject.BindingFlags.BIDIRECTIONAL); this.prompt.bind_property('choice-chosen', choice.actor, 'checked', GObject.BindingFlags.SYNC_CREATE | GObject.BindingFlags.BIDIRECTIONAL);
layout.attach(choice, rtl ? 0 : 1, row, 1, 1); layout.attach(choice.actor, rtl ? 0 : 1, row, 1, 1);
row++; row++;
} }

View File

@@ -734,7 +734,7 @@ var NetworkAgent = class {
}); });
Main.messageTray.add(source); Main.messageTray.add(source);
source.showNotification(notification); source.notify(notification);
} }
_newRequest(agent, requestId, connection, settingName, hints, flags) { _newRequest(agent, requestId, connection, settingName, hints, flags) {

View File

@@ -76,8 +76,8 @@ var AuthenticationDialog = GObject.registerClass({
this._userAvatar = new UserWidget.Avatar(this._user, this._userAvatar = new UserWidget.Avatar(this._user,
{ iconSize: DIALOG_ICON_SIZE, { iconSize: DIALOG_ICON_SIZE,
styleClass: 'polkit-dialog-user-icon' }); styleClass: 'polkit-dialog-user-icon' });
this._userAvatar.hide(); this._userAvatar.actor.hide();
userBox.add(this._userAvatar, userBox.add(this._userAvatar.actor,
{ x_fill: true, { x_fill: true,
y_fill: false, y_fill: false,
x_align: St.Align.END, x_align: St.Align.END,
@@ -106,7 +106,7 @@ var AuthenticationDialog = GObject.registerClass({
{ expand: true }); { expand: true });
this._workSpinner = new Animation.Spinner(WORK_SPINNER_ICON_SIZE, true); this._workSpinner = new Animation.Spinner(WORK_SPINNER_ICON_SIZE, true);
this._passwordBox.add(this._workSpinner); this._passwordBox.add(this._workSpinner.actor);
this.setInitialKeyFocus(this._passwordEntry); this.setInitialKeyFocus(this._passwordEntry);
this._passwordBox.hide(); this._passwordBox.hide();
@@ -305,7 +305,7 @@ var AuthenticationDialog = GObject.registerClass({
_onUserChanged() { _onUserChanged() {
if (this._user.is_loaded && this._userAvatar) { if (this._user.is_loaded && this._userAvatar) {
this._userAvatar.update(); this._userAvatar.update();
this._userAvatar.show(); this._userAvatar.actor.show();
} }
} }

View File

@@ -215,7 +215,7 @@ class TelepathyClient extends Tp.BaseClient {
// We are already handling the channel, display the source // We are already handling the channel, display the source
let source = this._chatSources[channel.get_object_path()]; let source = this._chatSources[channel.get_object_path()];
if (source) if (source)
source.showNotification(); source.notify();
} }
} }
} }
@@ -266,10 +266,9 @@ class TelepathyClient extends Tp.BaseClient {
} }
}) : null; }) : null;
var ChatSource = HAVE_TP ? GObject.registerClass( var ChatSource = class extends MessageTray.Source {
class ChatSource extends MessageTray.Source { constructor(account, conn, channel, contact, client) {
_init(account, conn, channel, contact, client) { super(contact.get_alias());
super._init(contact.get_alias());
this._account = account; this._account = account;
this._contact = contact; this._contact = contact;
@@ -327,7 +326,7 @@ class ChatSource extends MessageTray.Source {
// We ack messages when the user expands the new notification // We ack messages when the user expands the new notification
let id = this._banner.connect('expanded', this._ackMessages.bind(this)); let id = this._banner.connect('expanded', this._ackMessages.bind(this));
this._banner.connect('destroy', () => { this._banner.actor.connect('destroy', () => {
this._banner.disconnect(id); this._banner.disconnect(id);
this._banner = null; this._banner = null;
}); });
@@ -477,7 +476,7 @@ class ChatSource extends MessageTray.Source {
this._notification.appendMessage(pendingMessages[i], true); this._notification.appendMessage(pendingMessages[i], true);
if (pendingMessages.length > 0) if (pendingMessages.length > 0)
this.showNotification(); this.notify();
} }
destroy(reason) { destroy(reason) {
@@ -554,7 +553,7 @@ class ChatSource extends MessageTray.Source {
_notifyTimeout() { _notifyTimeout() {
if (this._pendingMessages.length != 0) if (this._pendingMessages.length != 0)
this.showNotification(); this.notify();
this._notifyTimeoutId = 0; this._notifyTimeoutId = 0;
@@ -569,8 +568,8 @@ class ChatSource extends MessageTray.Source {
this._notification.appendMessage(message); this._notification.appendMessage(message);
} }
showNotification() { notify() {
super.showNotification(this._notification); super.notify(this._notification);
} }
respond(text) { respond(text) {
@@ -626,18 +625,12 @@ class ChatSource extends MessageTray.Source {
// 'pending-message-removed' for each one. // 'pending-message-removed' for each one.
this._channel.ack_all_pending_messages_async(null); this._channel.ack_all_pending_messages_async(null);
} }
}) : null; };
var ChatNotification = HAVE_TP ? GObject.registerClass({ var ChatNotification = class extends MessageTray.Notification {
Signals: { constructor(source) {
'message-removed': { param_types: [Tp.Message.$gtype] }, super(source, source.title, null,
'message-added': { param_types: [Tp.Message.$gtype] }, { secondaryGIcon: source.getSecondaryIcon() });
'timestamp-changed': { param_types: [Tp.Message.$gtype] },
}
}, class ChatNotification extends MessageTray.Notification {
_init(source) {
super._init(source, source.title, null,
{ secondaryGIcon: source.getSecondaryIcon() });
this.setUrgency(MessageTray.Urgency.HIGH); this.setUrgency(MessageTray.Urgency.HIGH);
this.setResident(true); this.setResident(true);
@@ -789,7 +782,7 @@ var ChatNotification = HAVE_TP ? GObject.registerClass({
this._filterMessages(); this._filterMessages();
} }
}) : null; };
var ChatLineBox = GObject.registerClass( var ChatLineBox = GObject.registerClass(
class ChatLineBox extends St.BoxLayout { class ChatLineBox extends St.BoxLayout {
@@ -799,10 +792,9 @@ class ChatLineBox extends St.BoxLayout {
} }
}); });
var ChatNotificationBanner = GObject.registerClass( var ChatNotificationBanner = class extends MessageTray.NotificationBanner {
class ChatNotificationBanner extends MessageTray.NotificationBanner { constructor(notification) {
_init(notification) { super(notification);
super._init(notification);
this._responseEntry = new St.Entry({ style_class: 'chat-response', this._responseEntry = new St.Entry({ style_class: 'chat-response',
x_expand: true, x_expand: true,
@@ -887,7 +879,8 @@ class ChatNotificationBanner extends MessageTray.NotificationBanner {
} }
_addMessage(message) { _addMessage(message) {
let body = new MessageList.URLHighlighter(message.body, true, true); let highlighter = new MessageList.URLHighlighter(message.body, true, true);
let body = highlighter.actor;
let styles = message.styles; let styles = message.styles;
for (let i = 0; i < styles.length; i++) for (let i = 0; i < styles.length; i++)
@@ -975,6 +968,6 @@ class ChatNotificationBanner extends MessageTray.NotificationBanner {
this.notification.source.setChatState(Tp.ChannelChatState.ACTIVE); this.notification.source.setChatState(Tp.ChannelChatState.ACTIVE);
} }
} }
}); };
var Component = TelepathyComponent; var Component = TelepathyComponent;

View File

@@ -1,8 +1,8 @@
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*- // -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
/* exported Dash */ /* exported Dash */
const { Clutter, GLib, GObject, const { Clutter, GLib, GObject, Meta, Shell, St } = imports.gi;
Graphene, Meta, Shell, St } = imports.gi; const Signals = imports.signals;
const AppDisplay = imports.ui.appDisplay; const AppDisplay = imports.ui.appDisplay;
const AppFavorites = imports.ui.appFavorites; const AppFavorites = imports.ui.appFavorites;
@@ -23,10 +23,9 @@ function getAppFromSource(source) {
} }
} }
var DashIcon = GObject.registerClass( var DashIcon = class DashIcon extends AppDisplay.AppIcon {
class DashIcon extends AppDisplay.AppIcon { constructor(app) {
_init(app) { super(app, {
super._init(app, {
setSizeManually: true, setSizeManually: true,
showLabel: false showLabel: false
}); });
@@ -46,7 +45,7 @@ class DashIcon extends AppDisplay.AppIcon {
acceptDrop() { acceptDrop() {
return false; return false;
} }
}); };
// A container like StBin, but taking the child's scale into account // A container like StBin, but taking the child's scale into account
// when requesting a size // when requesting a size
@@ -54,7 +53,7 @@ var DashItemContainer = GObject.registerClass(
class DashItemContainer extends St.Widget { class DashItemContainer extends St.Widget {
_init() { _init() {
super._init({ style_class: 'dash-item-container', super._init({ style_class: 'dash-item-container',
pivot_point: new Graphene.Point({ x: .5, y: .5 }), pivot_point: new Clutter.Point({ x: .5, y: .5 }),
scale_x: 0, scale_x: 0,
scale_y: 0, scale_y: 0,
opacity: 0, opacity: 0,
@@ -331,10 +330,8 @@ class DashActor extends St.Widget {
const baseIconSizes = [16, 22, 24, 32, 48, 64]; const baseIconSizes = [16, 22, 24, 32, 48, 64];
var Dash = GObject.registerClass({ var Dash = class Dash {
Signals: { 'icon-size-changed': {} } constructor() {
}, class Dash extends St.Bin {
_init() {
this._maxHeight = -1; this._maxHeight = -1;
this.iconSize = 64; this.iconSize = 64;
this._shownInitially = false; this._shownInitially = false;
@@ -362,11 +359,11 @@ var Dash = GObject.registerClass({
this._container.add_actor(this._showAppsIcon); this._container.add_actor(this._showAppsIcon);
super._init({ child: this._container }); this.actor = new St.Bin({ child: this._container });
this.connect('notify::height', () => { this.actor.connect('notify::height', () => {
if (this._maxHeight != this.height) if (this._maxHeight != this.actor.height)
this._queueRedisplay(); this._queueRedisplay();
this._maxHeight = this.height; this._maxHeight = this.actor.height;
}); });
this._workId = Main.initializeDeferredWork(this._box, this._redisplay.bind(this)); this._workId = Main.initializeDeferredWork(this._box, this._redisplay.bind(this));
@@ -389,7 +386,7 @@ var Dash = GObject.registerClass({
// Translators: this is the name of the dock/favorites area on // Translators: this is the name of the dock/favorites area on
// the left of the overview // the left of the overview
Main.ctrlAltTabManager.addGroup(this, _("Dash"), 'user-bookmarks-symbolic'); Main.ctrlAltTabManager.addGroup(this.actor, _("Dash"), 'user-bookmarks-symbolic');
} }
_onDragBegin() { _onDragBegin() {
@@ -484,11 +481,11 @@ var Dash = GObject.registerClass({
}); });
let item = new DashItemContainer(); let item = new DashItemContainer();
item.setChild(appIcon); item.setChild(appIcon.actor);
// Override default AppIcon label_actor, now the // Override default AppIcon label_actor, now the
// accessible_name is set at DashItemContainer.setLabelText // accessible_name is set at DashItemContainer.setLabelText
appIcon.label_actor = null; appIcon.actor.label_actor = null;
item.setLabelText(app.get_name()); item.setLabelText(app.get_name());
appIcon.icon.setIconSize(this.iconSize); appIcon.icon.setIconSize(this.iconSize);
@@ -626,7 +623,7 @@ var Dash = GObject.registerClass({
icon.icon.ease({ icon.icon.ease({
width: targetWidth, width: targetWidth,
height: targetHeight, height: targetHeight,
duration: DASH_ANIMATION_TIME, time: DASH_ANIMATION_TIME,
mode: Clutter.AnimationMode.EASE_OUT_QUAD mode: Clutter.AnimationMode.EASE_OUT_QUAD
}); });
} }
@@ -905,4 +902,5 @@ var Dash = GObject.registerClass({
return true; return true;
} }
}); };
Signals.addSignalMethods(Dash.prototype);

View File

@@ -25,26 +25,24 @@ function _isToday(date) {
now.getDate() == date.getDate(); now.getDate() == date.getDate();
} }
function _gDateTimeToDate(datetime) { var TodayButton = class TodayButton {
return new Date(datetime.to_unix() * 1000 + datetime.get_microsecond() / 1000); constructor(calendar) {
}
var TodayButton = GObject.registerClass(
class TodayButton extends St.Button {
_init(calendar) {
// Having the ability to go to the current date if the user is already // 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 // on the current date can be confusing. So don't make the button reactive
// until the selected date changes. // until the selected date changes.
super._init({ this.actor = new St.Button({
style_class: 'datemenu-today-button', style_class: 'datemenu-today-button',
x_align: St.Align.START, x_align: St.Align.START,
x_expand: true, x_expand: true,
can_focus: true, can_focus: true,
reactive: false reactive: false,
});
this.actor.connect('clicked', () => {
this._calendar.setDate(new Date(), false);
}); });
let hbox = new St.BoxLayout({ vertical: true }); let hbox = new St.BoxLayout({ vertical: true });
this.add_actor(hbox); this.actor.add_actor(hbox);
this._dayLabel = new St.Label({ style_class: 'day-label', this._dayLabel = new St.Label({ style_class: 'day-label',
x_align: Clutter.ActorAlign.START }); x_align: Clutter.ActorAlign.START });
@@ -54,17 +52,13 @@ class TodayButton extends St.Button {
hbox.add_actor(this._dateLabel); hbox.add_actor(this._dateLabel);
this._calendar = calendar; this._calendar = calendar;
this._calendar.connect('selected-date-changed', (_calendar, datetime) => { this._calendar.connect('selected-date-changed', (calendar, date) => {
// Make the button reactive only if the selected date is not the // Make the button reactive only if the selected date is not the
// current date. // current date.
this.reactive = !_isToday(_gDateTimeToDate(datetime)); this.actor.reactive = !_isToday(date);
}); });
} }
vfunc_clicked() {
this._calendar.setDate(new Date(), false);
}
setDate(date) { setDate(date) {
this._dayLabel.set_text(date.toLocaleFormat('%A')); this._dayLabel.set_text(date.toLocaleFormat('%A'));
@@ -81,29 +75,34 @@ class TodayButton extends St.Button {
* date, e.g. "Tuesday February 17 2015". * date, e.g. "Tuesday February 17 2015".
*/ */
dateFormat = Shell.util_translate_time_string (N_("%A %B %e %Y")); dateFormat = Shell.util_translate_time_string (N_("%A %B %e %Y"));
this.accessible_name = date.toLocaleFormat(dateFormat); this.actor.accessible_name = date.toLocaleFormat(dateFormat);
} }
}); };
var WorldClocksSection = GObject.registerClass( var WorldClocksSection = class WorldClocksSection {
class WorldClocksSection extends St.Button { constructor() {
_init() {
super._init({
style_class: 'world-clocks-button',
x_fill: true,
can_focus: true
});
this._clock = new GnomeDesktop.WallClock(); this._clock = new GnomeDesktop.WallClock();
this._clockNotifyId = 0; this._clockNotifyId = 0;
this._locations = []; this._locations = [];
this.actor = new St.Button({ style_class: 'world-clocks-button',
x_fill: true,
can_focus: true });
this.actor.connect('clicked', () => {
if (this._clocksApp)
this._clocksApp.activate();
Main.overview.hide();
Main.panel.closeCalendar();
});
let layout = new Clutter.GridLayout({ orientation: Clutter.Orientation.VERTICAL }); let layout = new Clutter.GridLayout({ orientation: Clutter.Orientation.VERTICAL });
this._grid = new St.Widget({ style_class: 'world-clocks-grid', this._grid = new St.Widget({ style_class: 'world-clocks-grid',
layout_manager: layout }); layout_manager: layout });
layout.hookup_style(this._grid); layout.hookup_style(this._grid);
this.child = this._grid; this.actor.child = this._grid;
this._clocksApp = null; this._clocksApp = null;
this._clocksProxy = new ClocksProxy( this._clocksProxy = new ClocksProxy(
@@ -126,17 +125,9 @@ class WorldClocksSection extends St.Button {
this._sync(); this._sync();
} }
vfunc_clicked() {
if (this._clocksApp)
this._clocksApp.activate();
Main.overview.hide();
Main.panel.closeCalendar();
}
_sync() { _sync() {
this._clocksApp = this._appSystem.lookup_app('org.gnome.clocks.desktop'); this._clocksApp = this._appSystem.lookup_app('org.gnome.clocks.desktop');
this.visible = this._clocksApp != null; this.actor.visible = this._clocksApp != null;
} }
_clocksChanged() { _clocksChanged() {
@@ -164,7 +155,7 @@ class WorldClocksSection extends St.Button {
x_align: Clutter.ActorAlign.START, x_align: Clutter.ActorAlign.START,
text: title }); text: title });
layout.attach(header, 0, 0, 2, 1); layout.attach(header, 0, 0, 2, 1);
this.label_actor = header; this.actor.label_actor = header;
let localOffset = GLib.DateTime.new_now_local().get_utc_offset(); let localOffset = GLib.DateTime.new_now_local().get_utc_offset();
@@ -245,23 +236,30 @@ class WorldClocksSection extends St.Button {
this._settings.set_value('locations', this._settings.set_value('locations',
new GLib.Variant('av', this._clocksProxy.Locations)); new GLib.Variant('av', this._clocksProxy.Locations));
} }
}); };
var WeatherSection = GObject.registerClass(
class WeatherSection extends St.Button {
_init() {
super._init({
style_class: 'weather-button',
x_fill: true,
can_focus: true
});
var WeatherSection = class WeatherSection {
constructor() {
this._weatherClient = new Weather.WeatherClient(); this._weatherClient = new Weather.WeatherClient();
this.actor = new St.Button({ style_class: 'weather-button',
x_fill: true,
can_focus: true });
this.actor.connect('clicked', () => {
this._weatherClient.activateApp();
Main.overview.hide();
Main.panel.closeCalendar();
});
this.actor.connect('notify::mapped', () => {
if (this.actor.mapped)
this._weatherClient.update();
});
let box = new St.BoxLayout({ style_class: 'weather-box', let box = new St.BoxLayout({ style_class: 'weather-box',
vertical: true }); vertical: true });
this.child = box; this.actor.child = box;
let titleBox = new St.BoxLayout(); let titleBox = new St.BoxLayout();
titleBox.add_child(new St.Label({ style_class: 'weather-header', titleBox.add_child(new St.Label({ style_class: 'weather-header',
@@ -284,18 +282,6 @@ class WeatherSection extends St.Button {
this._sync(); this._sync();
} }
vfunc_map() {
this._weatherClient.update();
super.vfunc_map();
}
vfunc_clicked() {
this._weatherClient.activateApp();
Main.overview.hide();
Main.panel.closeCalendar();
}
_getInfos() { _getInfos() {
let info = this._weatherClient.info; let info = this._weatherClient.info;
let forecasts = info.get_forecast_list(); let forecasts = info.get_forecast_list();
@@ -386,27 +372,23 @@ class WeatherSection extends St.Button {
} }
_sync() { _sync() {
this.visible = this._weatherClient.available; this.actor.visible = this._weatherClient.available;
if (!this.visible) if (!this.actor.visible)
return; return;
this._titleLocation.visible = this._weatherClient.hasLocation; this._titleLocation.visible = this._weatherClient.hasLocation;
this._updateForecasts(); this._updateForecasts();
} }
}); };
var MessagesIndicator = GObject.registerClass( var MessagesIndicator = class MessagesIndicator {
class MessagesIndicator extends St.Icon { constructor() {
_init() { this.actor = new St.Icon({ icon_name: 'message-indicator-symbolic',
super._init({ icon_size: 16,
icon_name: 'message-indicator-symbolic', visible: false, y_expand: true,
icon_size: 16, y_align: Clutter.ActorAlign.CENTER });
visible: false,
y_expand: true,
y_align: Clutter.ActorAlign.CENTER
});
this._sources = []; this._sources = [];
@@ -419,7 +401,7 @@ class MessagesIndicator extends St.Icon {
} }
_onSourceAdded(tray, source) { _onSourceAdded(tray, source) {
source.connect('notify::count', this._updateCount.bind(this)); source.connect('count-updated', this._updateCount.bind(this));
this._sources.push(source); this._sources.push(source);
this._updateCount(); this._updateCount();
} }
@@ -434,9 +416,9 @@ class MessagesIndicator extends St.Icon {
this._sources.forEach(source => (count += source.unseenCount)); this._sources.forEach(source => (count += source.unseenCount));
count -= Main.messageTray.queueCount; count -= Main.messageTray.queueCount;
this.visible = (count > 0); this.actor.visible = (count > 0);
} }
}); };
var IndicatorPad = GObject.registerClass( var IndicatorPad = GObject.registerClass(
class IndicatorPad extends St.Widget { class IndicatorPad extends St.Widget {
@@ -529,9 +511,9 @@ class DateMenuButton extends PanelMenu.Button {
this._indicator = new MessagesIndicator(); this._indicator = new MessagesIndicator();
let box = new St.BoxLayout(); let box = new St.BoxLayout();
box.add_actor(new IndicatorPad(this._indicator)); box.add_actor(new IndicatorPad(this._indicator.actor));
box.add_actor(this._clockDisplay); box.add_actor(this._clockDisplay);
box.add_actor(this._indicator); box.add_actor(this._indicator.actor);
this.label_actor = this._clockDisplay; this.label_actor = this._clockDisplay;
this.add_actor(box); this.add_actor(box);
@@ -547,11 +529,11 @@ class DateMenuButton extends PanelMenu.Button {
bin.add_actor(hbox); bin.add_actor(hbox);
this._calendar = new Calendar.Calendar(); this._calendar = new Calendar.Calendar();
this._calendar.connect('selected-date-changed', (_calendar, datetime) => { this._calendar.connect('selected-date-changed',
let date = _gDateTimeToDate(datetime); (calendar, date) => {
layout.frozen = !_isToday(date); layout.frozen = !_isToday(date);
this._messageList.setDate(date); this._messageList.setDate(date);
}); });
this.menu.connect('open-state-changed', (menu, isOpen) => { this.menu.connect('open-state-changed', (menu, isOpen) => {
// Whenever the menu is opened, select today // Whenever the menu is opened, select today
@@ -565,19 +547,19 @@ class DateMenuButton extends PanelMenu.Button {
// Fill up the first column // Fill up the first column
this._messageList = new Calendar.CalendarMessageList(); this._messageList = new Calendar.CalendarMessageList();
hbox.add(this._messageList, { expand: true, y_fill: false, y_align: St.Align.START }); hbox.add(this._messageList.actor, { expand: true, y_fill: false, y_align: St.Align.START });
// Fill up the second column // Fill up the second column
let boxLayout = new CalendarColumnLayout(this._calendar); let boxLayout = new CalendarColumnLayout(this._calendar.actor);
vbox = new St.Widget({ style_class: 'datemenu-calendar-column', vbox = new St.Widget({ style_class: 'datemenu-calendar-column',
layout_manager: boxLayout }); layout_manager: boxLayout });
boxLayout.hookup_style(vbox); boxLayout.hookup_style(vbox);
hbox.add(vbox); hbox.add(vbox);
this._date = new TodayButton(this._calendar); this._date = new TodayButton(this._calendar);
vbox.add_actor(this._date); vbox.add_actor(this._date.actor);
vbox.add_actor(this._calendar); vbox.add_actor(this._calendar.actor);
this._displaysSection = new St.ScrollView({ style_class: 'datemenu-displays-section vfade', this._displaysSection = new St.ScrollView({ style_class: 'datemenu-displays-section vfade',
x_expand: true, x_fill: true, x_expand: true, x_fill: true,
@@ -590,10 +572,10 @@ class DateMenuButton extends PanelMenu.Button {
this._displaysSection.add_actor(displaysBox); this._displaysSection.add_actor(displaysBox);
this._clocksItem = new WorldClocksSection(); this._clocksItem = new WorldClocksSection();
displaysBox.add(this._clocksItem, { x_fill: true }); displaysBox.add(this._clocksItem.actor, { x_fill: true });
this._weatherItem = new WeatherSection(); this._weatherItem = new WeatherSection();
displaysBox.add(this._weatherItem, { x_fill: true }); displaysBox.add(this._weatherItem.actor, { x_fill: true });
// Done with hbox for calendar and event list // Done with hbox for calendar and event list

View File

@@ -573,15 +573,11 @@ var _Draggable = class _Draggable {
while (target) { while (target) {
if (target._delegate && target._delegate.acceptDrop) { if (target._delegate && target._delegate.acceptDrop) {
let [r_, targX, targY] = target.transform_stage_point(dropX, dropY); let [r_, targX, targY] = target.transform_stage_point(dropX, dropY);
let accepted = false; if (target._delegate.acceptDrop(this.actor._delegate,
try { this._dragActor,
accepted = target._delegate.acceptDrop(this.actor._delegate, targX,
this._dragActor, targX, targY, event.get_time()); targY,
} catch (e) { event.get_time())) {
// On error, skip this target
logError(e, "Skipping drag target");
}
if (accepted) {
// If it accepted the drop without taking the actor, // If it accepted the drop without taking the actor,
// handle it ourselves. // handle it ourselves.
if (this._dragActor && this._dragActor.get_parent() == Main.uiGroup) { if (this._dragActor && this._dragActor.get_parent() == Main.uiGroup) {

View File

@@ -207,10 +207,10 @@ function _setCheckBoxLabel(checkBox, text) {
if (text) { if (text) {
label.set_text(text); label.set_text(text);
checkBox.show(); checkBox.actor.show();
} else { } else {
label.set_text(''); label.set_text('');
checkBox.hide(); checkBox.actor.hide();
} }
} }
@@ -297,8 +297,8 @@ class EndSessionDialog extends ModalDialog.ModalDialog {
y_align: St.Align.START }); y_align: St.Align.START });
this._checkBox = new CheckBox.CheckBox(); this._checkBox = new CheckBox.CheckBox();
this._checkBox.connect('clicked', this._sync.bind(this)); this._checkBox.actor.connect('clicked', this._sync.bind(this));
messageLayout.add(this._checkBox); messageLayout.add(this._checkBox.actor);
this._batteryWarning = new St.Label({ style_class: 'end-session-dialog-warning', this._batteryWarning = new St.Label({ style_class: 'end-session-dialog-warning',
text: _("Running on battery power: please plug in before installing updates.") }); text: _("Running on battery power: please plug in before installing updates.") });
@@ -376,12 +376,12 @@ class EndSessionDialog extends ModalDialog.ModalDialog {
let subject = dialogContent.subject; let subject = dialogContent.subject;
// Use different title when we are installing updates // Use different title when we are installing updates
if (dialogContent.subjectWithUpdates && this._checkBox.checked) if (dialogContent.subjectWithUpdates && this._checkBox.actor.checked)
subject = dialogContent.subjectWithUpdates; subject = dialogContent.subjectWithUpdates;
if (dialogContent.showBatteryWarning) { if (dialogContent.showBatteryWarning) {
// Warn when running on battery power // Warn when running on battery power
if (this._powerProxy.OnBattery && this._checkBox.checked) if (this._powerProxy.OnBattery && this._checkBox.actor.checked)
this._batteryWarning.opacity = 255; this._batteryWarning.opacity = 255;
else else
this._batteryWarning.opacity = 0; this._batteryWarning.opacity = 0;
@@ -429,7 +429,7 @@ class EndSessionDialog extends ModalDialog.ModalDialog {
let avatarWidget = new UserWidget.Avatar(this._user, let avatarWidget = new UserWidget.Avatar(this._user,
{ iconSize: _DIALOG_ICON_SIZE, { iconSize: _DIALOG_ICON_SIZE,
styleClass: dialogContent.iconStyleClass }); styleClass: dialogContent.iconStyleClass });
this._iconBin.child = avatarWidget; this._iconBin.child = avatarWidget.actor;
avatarWidget.update(); avatarWidget.update();
} }
@@ -485,13 +485,13 @@ class EndSessionDialog extends ModalDialog.ModalDialog {
}; };
// Offline update not available; just emit the signal // Offline update not available; just emit the signal
if (!this._checkBox.visible) { if (!this._checkBox.actor.visible) {
callback(); callback();
return; return;
} }
// Trigger the offline update as requested // Trigger the offline update as requested
if (this._checkBox.checked) { if (this._checkBox.actor.checked) {
switch (signal) { switch (signal) {
case "ConfirmedReboot": case "ConfirmedReboot":
this._triggerOfflineUpdateReboot(callback); this._triggerOfflineUpdateReboot(callback);
@@ -656,7 +656,7 @@ class EndSessionDialog extends ModalDialog.ModalDialog {
let actor = new St.BoxLayout({ style_class: 'end-session-dialog-session-list-item', let actor = new St.BoxLayout({ style_class: 'end-session-dialog-session-list-item',
can_focus: true }); can_focus: true });
actor.add(avatar); actor.add(avatar.actor);
let nameLabel = new St.Label({ text: userLabelText, let nameLabel = new St.Label({ text: userLabelText,
style_class: 'end-session-dialog-session-list-item-name', style_class: 'end-session-dialog-session-list-item-name',
@@ -754,14 +754,14 @@ class EndSessionDialog extends ModalDialog.ModalDialog {
let updatesAllowed = this._updatesPermission && this._updatesPermission.allowed; let updatesAllowed = this._updatesPermission && this._updatesPermission.allowed;
_setCheckBoxLabel(this._checkBox, dialogContent.checkBoxText || ''); _setCheckBoxLabel(this._checkBox, dialogContent.checkBoxText || '');
this._checkBox.visible = (dialogContent.checkBoxText && updatePrepared && updatesAllowed); this._checkBox.actor.visible = (dialogContent.checkBoxText && updatePrepared && updatesAllowed);
this._checkBox.checked = (updatePrepared && updateTriggered); this._checkBox.actor.checked = (updatePrepared && updateTriggered);
// We show the warning either together with the checkbox, or when // We show the warning either together with the checkbox, or when
// updates have already been triggered, but the user doesn't have // updates have already been triggered, but the user doesn't have
// enough permissions to cancel them. // enough permissions to cancel them.
this._batteryWarning.visible = (dialogContent.showBatteryWarning && this._batteryWarning.visible = (dialogContent.showBatteryWarning &&
(this._checkBox.visible || updatePrepared && updateTriggered && !updatesAllowed)); (this._checkBox.actor.visible || updatePrepared && updateTriggered && !updatesAllowed));
this._updateButtons(); this._updateButtons();

View File

@@ -105,20 +105,22 @@ function _easeActor(actor, params) {
actor.set_easing_delay(params.delay); actor.set_easing_delay(params.delay);
delete params.delay; delete params.delay;
let repeatCount = 0; let repeat_count = 0;
if (params.repeatCount != undefined) if (params.repeat_count != undefined)
repeatCount = params.repeatCount; repeat_count = params.repeat_count;
delete params.repeatCount; delete params.repeat_count;
let autoReverse = false; let auto_reverse = false;
if (params.autoReverse != undefined) if (params.auto_reverse != undefined)
autoReverse = params.autoReverse; auto_reverse = params.auto_reverse;
delete params.autoReverse; delete params.auto_reverse;
if (params.mode != undefined) if (params.mode != undefined)
actor.set_easing_mode(params.mode); actor.set_easing_mode(params.mode);
delete params.mode; delete params.mode;
Meta.disable_unredirect_for_display(global.display);
let cleanup = () => Meta.enable_unredirect_for_display(global.display); let cleanup = () => Meta.enable_unredirect_for_display(global.display);
let callback = _makeEaseCallback(params, cleanup); let callback = _makeEaseCallback(params, cleanup);
@@ -132,13 +134,10 @@ function _easeActor(actor, params) {
let transition = animatedProps.map(p => actor.get_transition(p)) let transition = animatedProps.map(p => actor.get_transition(p))
.find(t => t !== null); .find(t => t !== null);
if (transition && transition.delay)
transition.connect('started', () => Meta.disable_unredirect_for_display(global.display));
else
Meta.disable_unredirect_for_display(global.display);
if (transition) { if (transition) {
transition.set({ repeatCount, autoReverse }); transition.repeat_count = repeat_count;
transition.auto_reverse = auto_reverse;
transition.connect('stopped', (t, finished) => callback(finished)); transition.connect('stopped', (t, finished) => callback(finished));
} else { } else {
callback(true); callback(true);
@@ -155,21 +154,23 @@ function _easeActorProperty(actor, propName, target, params) {
params.duration = adjustAnimationTime(params.duration); params.duration = adjustAnimationTime(params.duration);
let duration = Math.floor(params.duration || 0); let duration = Math.floor(params.duration || 0);
let repeatCount = 0; let repeat_count = 0;
if (params.repeatCount != undefined) if (params.repeat_count != undefined)
repeatCount = params.repeatCount; repeat_count = params.repeat_count;
delete params.repeatCount; delete params.repeat_count;
let autoReverse = false; let auto_reverse = false;
if (params.autoReverse != undefined) if (params.auto_reverse != undefined)
autoReverse = params.autoReverse; auto_reverse = params.auto_reverse;
delete params.autoReverse; delete params.auto_reverse;
// Copy Clutter's behavior for implicit animations, see // Copy Clutter's behavior for implicit animations, see
// should_skip_implicit_transition() // should_skip_implicit_transition()
if (actor instanceof Clutter.Actor && !actor.mapped) if (actor instanceof Clutter.Actor && !actor.mapped)
duration = 0; duration = 0;
Meta.disable_unredirect_for_display(global.display);
let cleanup = () => Meta.enable_unredirect_for_display(global.display); let cleanup = () => Meta.enable_unredirect_for_display(global.display);
let callback = _makeEaseCallback(params, cleanup); let callback = _makeEaseCallback(params, cleanup);
@@ -180,7 +181,6 @@ function _easeActorProperty(actor, propName, target, params) {
let [obj, prop] = _getPropertyTarget(actor, propName); let [obj, prop] = _getPropertyTarget(actor, propName);
obj[prop] = target; obj[prop] = target;
Meta.disable_unredirect_for_display(global.display);
callback(true); callback(true);
return; return;
@@ -191,18 +191,13 @@ function _easeActorProperty(actor, propName, target, params) {
property_name: propName, property_name: propName,
interval: new Clutter.Interval({ value_type: pspec.value_type }), interval: new Clutter.Interval({ value_type: pspec.value_type }),
remove_on_complete: true, remove_on_complete: true,
repeat_count: repeatCount, repeat_count: repeat_count,
auto_reverse: autoReverse, auto_reverse: auto_reverse,
}, params)); }, params));
actor.add_transition(propName, transition); actor.add_transition(propName, transition);
transition.set_to(target); transition.set_to(target);
if (transition.delay)
transition.connect('started', () => Meta.disable_unredirect_for_display(global.display));
else
Meta.disable_unredirect_for_display(global.display);
transition.connect('stopped', (t, finished) => callback(finished)); transition.connect('stopped', (t, finished) => callback(finished));
} }

View File

@@ -1,7 +1,8 @@
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*- // -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
/* exported CandidatePopup */ /* exported CandidatePopup */
const { Clutter, GObject, IBus, St } = imports.gi; const { Clutter, IBus, St } = imports.gi;
const Signals = imports.signals;
const BoxPointer = imports.ui.boxpointer; const BoxPointer = imports.ui.boxpointer;
const Main = imports.ui.main; const Main = imports.ui.main;
@@ -11,23 +12,11 @@ var MAX_CANDIDATES_PER_PAGE = 16;
var DEFAULT_INDEX_LABELS = ['1', '2', '3', '4', '5', '6', '7', '8', var DEFAULT_INDEX_LABELS = ['1', '2', '3', '4', '5', '6', '7', '8',
'9', '0', 'a', 'b', 'c', 'd', 'e', 'f']; '9', '0', 'a', 'b', 'c', 'd', 'e', 'f'];
var CandidateArea = GObject.registerClass({ var CandidateArea = class CandidateArea {
Signals: { constructor() {
'candidate-clicked': { param_types: [GObject.TYPE_UINT, this.actor = new St.BoxLayout({ vertical: true,
GObject.TYPE_UINT, reactive: true,
Clutter.ModifierType.$gtype] }, visible: false });
'cursor-down': {},
'cursor-up': {},
'next-page': {},
'previous-page': {},
}
}, class CandidateArea extends St.BoxLayout {
_init() {
super._init({
vertical: true,
reactive: true,
visible: false
});
this._candidateBoxes = []; this._candidateBoxes = [];
for (let i = 0; i < MAX_CANDIDATES_PER_PAGE; ++i) { for (let i = 0; i < MAX_CANDIDATES_PER_PAGE; ++i) {
let box = new St.BoxLayout({ style_class: 'candidate-box', let box = new St.BoxLayout({ style_class: 'candidate-box',
@@ -38,7 +27,7 @@ var CandidateArea = GObject.registerClass({
box.add(box._indexLabel, { y_fill: false }); box.add(box._indexLabel, { y_fill: false });
box.add(box._candidateLabel, { y_fill: false }); box.add(box._candidateLabel, { y_fill: false });
this._candidateBoxes.push(box); this._candidateBoxes.push(box);
this.add(box); this.actor.add(box);
let j = i; let j = i;
box.connect('button-release-event', (actor, event) => { box.connect('button-release-event', (actor, event) => {
@@ -47,6 +36,19 @@ var CandidateArea = GObject.registerClass({
}); });
} }
this.actor.connect('scroll-event', (actor, event) => {
let direction = event.get_scroll_direction();
switch (direction) {
case Clutter.ScrollDirection.UP:
this.emit('cursor-up');
break;
case Clutter.ScrollDirection.DOWN:
this.emit('cursor-down');
break;
}
return Clutter.EVENT_PROPAGATE;
});
this._buttonBox = new St.BoxLayout({ style_class: 'candidate-page-button-box' }); this._buttonBox = new St.BoxLayout({ style_class: 'candidate-page-button-box' });
this._previousButton = new St.Button({ style_class: 'candidate-page-button candidate-page-button-previous button' }); this._previousButton = new St.Button({ style_class: 'candidate-page-button candidate-page-button-previous button' });
@@ -57,7 +59,7 @@ var CandidateArea = GObject.registerClass({
this._nextButton.child = new St.Icon({ style_class: 'candidate-page-button-icon' }); this._nextButton.child = new St.Icon({ style_class: 'candidate-page-button-icon' });
this._buttonBox.add(this._nextButton, { expand: true }); this._buttonBox.add(this._nextButton, { expand: true });
this.add(this._buttonBox); this.actor.add(this._buttonBox);
this._previousButton.connect('clicked', () => { this._previousButton.connect('clicked', () => {
this.emit('previous-page'); this.emit('previous-page');
@@ -70,18 +72,6 @@ var CandidateArea = GObject.registerClass({
this._cursorPosition = 0; this._cursorPosition = 0;
} }
vfunc_scroll_event(scrollEvent) {
switch (scrollEvent.direction) {
case Clutter.ScrollDirection.UP:
this.emit('cursor-up');
break;
case Clutter.ScrollDirection.DOWN:
this.emit('cursor-down');
break;
}
return Clutter.EVENT_PROPAGATE;
}
setOrientation(orientation) { setOrientation(orientation) {
if (this._orientation == orientation) if (this._orientation == orientation)
return; return;
@@ -89,15 +79,15 @@ var CandidateArea = GObject.registerClass({
this._orientation = orientation; this._orientation = orientation;
if (this._orientation == IBus.Orientation.HORIZONTAL) { if (this._orientation == IBus.Orientation.HORIZONTAL) {
this.vertical = false; this.actor.vertical = false;
this.remove_style_class_name('vertical'); this.actor.remove_style_class_name('vertical');
this.add_style_class_name('horizontal'); this.actor.add_style_class_name('horizontal');
this._previousButton.child.icon_name = 'go-previous-symbolic'; this._previousButton.child.icon_name = 'go-previous-symbolic';
this._nextButton.child.icon_name = 'go-next-symbolic'; this._nextButton.child.icon_name = 'go-next-symbolic';
} else { // VERTICAL || SYSTEM } else { // VERTICAL || SYSTEM
this.vertical = true; this.actor.vertical = true;
this.add_style_class_name('vertical'); this.actor.add_style_class_name('vertical');
this.remove_style_class_name('horizontal'); this.actor.remove_style_class_name('horizontal');
this._previousButton.child.icon_name = 'go-up-symbolic'; this._previousButton.child.icon_name = 'go-up-symbolic';
this._nextButton.child.icon_name = 'go-down-symbolic'; this._nextButton.child.icon_name = 'go-down-symbolic';
} }
@@ -131,23 +121,22 @@ var CandidateArea = GObject.registerClass({
this._previousButton.reactive = wrapsAround || page > 0; this._previousButton.reactive = wrapsAround || page > 0;
this._nextButton.reactive = wrapsAround || page < nPages - 1; this._nextButton.reactive = wrapsAround || page < nPages - 1;
} }
}); };
Signals.addSignalMethods(CandidateArea.prototype);
var CandidatePopup = GObject.registerClass(
class IbusCandidatePopup extends BoxPointer.BoxPointer {
_init() {
super._init(St.Side.TOP);
this.visible = false;
this.style_class = 'candidate-popup-boxpointer';
var CandidatePopup = class CandidatePopup {
constructor() {
this._dummyCursor = new St.Widget({ opacity: 0 }); this._dummyCursor = new St.Widget({ opacity: 0 });
Main.layoutManager.uiGroup.add_actor(this._dummyCursor); Main.layoutManager.uiGroup.add_actor(this._dummyCursor);
Main.layoutManager.addChrome(this); this._boxPointer = new BoxPointer.BoxPointer(St.Side.TOP);
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', let box = new St.BoxLayout({ style_class: 'candidate-popup-content',
vertical: true }); vertical: true });
this.bin.set_child(box); this._boxPointer.bin.set_child(box);
this._preeditText = new St.Label({ style_class: 'candidate-popup-text', this._preeditText = new St.Label({ style_class: 'candidate-popup-text',
visible: false }); visible: false });
@@ -158,7 +147,7 @@ class IbusCandidatePopup extends BoxPointer.BoxPointer {
box.add(this._auxText); box.add(this._auxText);
this._candidateArea = new CandidateArea(); this._candidateArea = new CandidateArea();
box.add(this._candidateArea); box.add(this._candidateArea.actor);
this._candidateArea.connect('previous-page', () => { this._candidateArea.connect('previous-page', () => {
this._panelService.page_up(); this._panelService.page_up();
@@ -236,7 +225,7 @@ class IbusCandidatePopup extends BoxPointer.BoxPointer {
this._updateVisibility(); this._updateVisibility();
}); });
panelService.connect('update-lookup-table', (_ps, lookupTable, visible) => { panelService.connect('update-lookup-table', (_ps, lookupTable, visible) => {
this._candidateArea.visible = visible; this._candidateArea.actor.visible = visible;
this._updateVisibility(); this._updateVisibility();
let nCandidates = lookupTable.get_number_of_candidates(); let nCandidates = lookupTable.get_number_of_candidates();
@@ -272,15 +261,15 @@ class IbusCandidatePopup extends BoxPointer.BoxPointer {
this._candidateArea.updateButtons(lookupTable.is_round(), page, nPages); this._candidateArea.updateButtons(lookupTable.is_round(), page, nPages);
}); });
panelService.connect('show-lookup-table', () => { panelService.connect('show-lookup-table', () => {
this._candidateArea.show(); this._candidateArea.actor.show();
this._updateVisibility(); this._updateVisibility();
}); });
panelService.connect('hide-lookup-table', () => { panelService.connect('hide-lookup-table', () => {
this._candidateArea.hide(); this._candidateArea.actor.hide();
this._updateVisibility(); this._updateVisibility();
}); });
panelService.connect('focus-out', () => { panelService.connect('focus-out', () => {
this.close(BoxPointer.PopupAnimation.NONE); this._boxPointer.close(BoxPointer.PopupAnimation.NONE);
Main.keyboard.resetSuggestions(); Main.keyboard.resetSuggestions();
}); });
} }
@@ -289,22 +278,22 @@ class IbusCandidatePopup extends BoxPointer.BoxPointer {
this._dummyCursor.set_position(Math.round(x), Math.round(y)); this._dummyCursor.set_position(Math.round(x), Math.round(y));
this._dummyCursor.set_size(Math.round(w), Math.round(h)); this._dummyCursor.set_size(Math.round(w), Math.round(h));
if (this.visible) if (this._boxPointer.visible)
this.setPosition(this._dummyCursor, 0); this._boxPointer.setPosition(this._dummyCursor, 0);
} }
_updateVisibility() { _updateVisibility() {
let isVisible = (!Main.keyboard.visible && let isVisible = (!Main.keyboard.visible &&
(this._preeditText.visible || (this._preeditText.visible ||
this._auxText.visible || this._auxText.visible ||
this._candidateArea.visible)); this._candidateArea.actor.visible));
if (isVisible) { if (isVisible) {
this.setPosition(this._dummyCursor, 0); this._boxPointer.setPosition(this._dummyCursor, 0);
this.open(BoxPointer.PopupAnimation.NONE); this._boxPointer.open(BoxPointer.PopupAnimation.NONE);
this.raise_top(); this._boxPointer.raise_top();
} else { } else {
this.close(BoxPointer.PopupAnimation.NONE); this._boxPointer.close(BoxPointer.PopupAnimation.NONE);
} }
} }
@@ -314,4 +303,4 @@ class IbusCandidatePopup extends BoxPointer.BoxPointer {
if (attr.get_attr_type() == IBus.AttrType.BACKGROUND) if (attr.get_attr_type() == IBus.AttrType.BACKGROUND)
clutterText.set_selection(attr.get_start_index(), attr.get_end_index()); clutterText.set_selection(attr.get_start_index(), attr.get_end_index());
} }
}); };

View File

@@ -1,7 +1,7 @@
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*- // -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
/* exported BaseIcon, IconGrid, PaginatedIconGrid */ /* exported BaseIcon, IconGrid, PaginatedIconGrid */
const { Clutter, GLib, GObject, Graphene, Meta, St } = imports.gi; const { Clutter, GLib, GObject, Meta, St } = imports.gi;
const Params = imports.misc.params; const Params = imports.misc.params;
const Main = imports.ui.main; const Main = imports.ui.main;
@@ -231,18 +231,18 @@ var IconGrid = GObject.registerClass({
this._fixedHItemSize = this._fixedVItemSize = undefined; this._fixedHItemSize = this._fixedVItemSize = undefined;
this.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.connect('notify::mapped', () => {
if (!this.mapped)
this._resetAnimationActors();
});
this.connect('actor-added', this._childAdded.bind(this)); this.connect('actor-added', this._childAdded.bind(this));
this.connect('actor-removed', this._childRemoved.bind(this)); this.connect('actor-removed', this._childRemoved.bind(this));
this.connect('destroy', this._onDestroy.bind(this)); this.connect('destroy', this._onDestroy.bind(this));
} }
vfunc_unmap() {
// Cancel animations when hiding the overview, to avoid icons
// swarming into the void ...
this._resetAnimationActors();
super.vfunc_unmap();
}
_onDestroy() { _onDestroy() {
if (this._updateIconSizesLaterId) { if (this._updateIconSizesLaterId) {
Meta.later_remove (this._updateIconSizesLaterId); Meta.later_remove (this._updateIconSizesLaterId);
@@ -402,7 +402,7 @@ var IconGrid = GObject.registerClass({
let allocationBox = this.get_allocation_box(); let allocationBox = this.get_allocation_box();
let paintBox = themeNode.get_paint_box(allocationBox); let paintBox = themeNode.get_paint_box(allocationBox);
let origin = new Graphene.Point3D(); let origin = new Clutter.Vertex();
origin.x = paintBox.x1 - allocationBox.x1; origin.x = paintBox.x1 - allocationBox.x1;
origin.y = paintBox.y1 - allocationBox.y1; origin.y = paintBox.y1 - allocationBox.y1;
origin.z = 0.0; origin.z = 0.0;
@@ -717,13 +717,13 @@ var IconGrid = GObject.registerClass({
this._items.push(item); this._items.push(item);
if (index !== undefined) if (index !== undefined)
this.insert_child_at_index(item, index); this.insert_child_at_index(item.actor, index);
else else
this.add_actor(item); this.add_actor(item.actor);
} }
removeItem(item) { removeItem(item) {
this.remove_child(item); this.remove_child(item.actor);
} }
getItemAtIndex(index) { getItemAtIndex(index) {
@@ -963,7 +963,7 @@ var PaginatedIconGrid = GObject.registerClass({
*/ */
openExtraSpace(sourceItem, side, nRows) { openExtraSpace(sourceItem, side, nRows) {
let children = this._getVisibleChildren(); let children = this._getVisibleChildren();
let index = children.indexOf(sourceItem); let index = children.indexOf(sourceItem.actor);
if (index == -1) if (index == -1)
throw new Error('Item not found.'); throw new Error('Item not found.');

View File

@@ -1,5 +1,5 @@
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*- // -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
/* exported KeyboardManager */ /* exported Keyboard */
const { Clutter, Gio, GLib, GObject, Meta, St } = imports.gi; const { Clutter, Gio, GLib, GObject, Meta, St } = imports.gi;
const Signals = imports.signals; const Signals = imports.signals;
@@ -89,11 +89,8 @@ class KeyContainer extends St.Widget {
let gridLayout = new Clutter.GridLayout({ orientation: Clutter.Orientation.HORIZONTAL, let gridLayout = new Clutter.GridLayout({ orientation: Clutter.Orientation.HORIZONTAL,
column_homogeneous: true, column_homogeneous: true,
row_homogeneous: true }); row_homogeneous: true });
super._init({ super._init({ layout_manager: gridLayout,
layout_manager: gridLayout, x_expand: true, y_expand: true });
x_expand: true,
y_expand: true
});
this._gridLayout = gridLayout; this._gridLayout = gridLayout;
this._currentRow = 0; this._currentRow = 0;
this._currentCol = 0; this._currentCol = 0;
@@ -164,23 +161,24 @@ class KeyContainer extends St.Widget {
} }
}); });
var Suggestions = GObject.registerClass( var Suggestions = class {
class Suggestions extends St.BoxLayout { constructor() {
_init() { this.actor = new St.BoxLayout({ style_class: 'word-suggestions',
super._init({ style_class: 'word-suggestions', vertical: false }); vertical: false });
this.show(); this.actor.show();
} }
add(word, callback) { add(word, callback) {
let button = new St.Button({ label: word }); let button = new St.Button({ label: word });
button.connect('clicked', callback); button.connect('clicked', callback);
this.add(button); this.actor.add(button);
} }
clear() { clear() {
this.remove_all_children(); this.actor.remove_all_children();
} }
}); };
Signals.addSignalMethods(Suggestions.prototype);
var LanguageSelectionPopup = class extends PopupMenu.PopupMenu { var LanguageSelectionPopup = class extends PopupMenu.PopupMenu {
constructor(actor) { constructor(actor) {
@@ -245,25 +243,17 @@ var LanguageSelectionPopup = class extends PopupMenu.PopupMenu {
} }
}; };
var Key = GObject.registerClass({ var Key = class Key {
Signals: { constructor(key, extendedKeys) {
'activated': {},
'long-press': {},
'pressed': { param_types: [GObject.TYPE_UINT, GObject.TYPE_STRING] },
'released': { param_types: [GObject.TYPE_UINT, GObject.TYPE_STRING] },
}
}, class Key extends St.BoxLayout {
_init(key, extendedKeys) {
super._init({ style_class: 'key-container' });
this.key = key || ""; this.key = key || "";
this.keyButton = this._makeKey(this.key); this.keyButton = this._makeKey(this.key);
/* Add the key in a container, so keys can be padded without losing /* Add the key in a container, so keys can be padded without losing
* logical proportions between those. * logical proportions between those.
*/ */
this.add(this.keyButton, { expand: true, x_fill: true }); this.actor = new St.BoxLayout ({ style_class: 'key-container' });
this.connect('destroy', this._onDestroy.bind(this)); this.actor.add(this.keyButton, { expand: true, x_fill: true });
this.actor.connect('destroy', this._onDestroy.bind(this));
this._extended_keys = extendedKeys; this._extended_keys = extendedKeys;
this._extended_keyboard = null; this._extended_keyboard = null;
@@ -471,7 +461,8 @@ var Key = GObject.registerClass({
else else
this.keyButton.remove_style_pseudo_class('latched'); this.keyButton.remove_style_pseudo_class('latched');
} }
}); };
Signals.addSignalMethods(Key.prototype);
var KeyboardModel = class { var KeyboardModel = class {
constructor(groupName) { constructor(groupName) {
@@ -599,6 +590,7 @@ var EmojiPager = GObject.registerClass({
reactive: true, reactive: true,
clip_to_allocation: true clip_to_allocation: true
}); });
this._sections = sections; this._sections = sections;
this._nCols = nCols; this._nCols = nCols;
this._nRows = nRows; this._nRows = nRows;
@@ -809,7 +801,7 @@ var EmojiPager = GObject.registerClass({
this.emit('emoji', str); this.emit('emoji', str);
}); });
gridLayout.attach(key, col, row, 1, 1); gridLayout.attach(key.actor, col, row, 1, 1);
col++; col++;
if (col >= this._nCols) { if (col >= this._nCols) {
@@ -851,7 +843,7 @@ var EmojiPager = GObject.registerClass({
} }
let page = this._pages[nPage]; let page = this._pages[nPage];
this.emit('page-changed', page.section.label, page.page, page.nPages); this.emit('page-changed', page.section, page.page, page.nPages);
} }
setCurrentSection(section, nPage) { setCurrentSection(section, nPage) {
@@ -866,21 +858,8 @@ var EmojiPager = GObject.registerClass({
} }
}); });
var EmojiSelection = GObject.registerClass({ var EmojiSelection = class EmojiSelection {
Signals: { constructor() {
'emoji-selected': { param_types: [GObject.TYPE_STRING] },
'close-request': {},
'toggle': {},
}
}, class EmojiSelection extends St.BoxLayout {
_init() {
super._init({
style_class: 'emoji-panel',
x_expand: true,
y_expand: true,
vertical: true
});
this._sections = [ this._sections = [
{ first: 'grinning face', label: '🙂️' }, { first: 'grinning face', label: '🙂️' },
{ first: 'selfie', label: '👍️' }, { first: 'selfie', label: '👍️' },
@@ -895,44 +874,38 @@ var EmojiSelection = GObject.registerClass({
this._populateSections(); this._populateSections();
this.actor = new St.BoxLayout({ style_class: 'emoji-panel',
x_expand: true,
y_expand: true,
vertical: true });
this.actor.connect('notify::mapped', () => this._emojiPager.setCurrentPage(0));
this._emojiPager = new EmojiPager(this._sections, 11, 3); this._emojiPager = new EmojiPager(this._sections, 11, 3);
this._emojiPager.connect('page-changed', (pager, sectionLabel, page, nPages) => { this._emojiPager.connect('page-changed', (pager, section, page, nPages) => {
this._onPageChanged(sectionLabel, page, nPages); this._onPageChanged(section, page, nPages);
}); });
this._emojiPager.connect('emoji', (pager, str) => { this._emojiPager.connect('emoji', (pager, str) => {
this.emit('emoji-selected', str); this.emit('emoji-selected', str);
}); });
this.add(this._emojiPager, { expand: true }); this.actor.add(this._emojiPager.actor, { expand: true });
this._pageIndicator = new PageIndicators.PageIndicators( this._pageIndicator = new PageIndicators.PageIndicators(false);
Clutter.Orientation.HORIZONTAL this.actor.add(this._pageIndicator, { expand: true, x_fill: false, y_fill: false });
);
this.add(this._pageIndicator, { expand: true, x_fill: false, y_fill: false });
this._pageIndicator.setReactive(false); this._pageIndicator.setReactive(false);
let bottomRow = this._createBottomRow(); let bottomRow = this._createBottomRow();
this.add(bottomRow, { expand: true, x_fill: false, y_fill: false }); this.actor.add(bottomRow, { expand: true, x_fill: false, y_fill: false });
this._emojiPager.setCurrentPage(0); this._emojiPager.setCurrentPage(0);
} }
vfunc_map() { _onPageChanged(section, page, nPages) {
this._emojiPager.setCurrentPage(0);
super.vfunc_map();
}
vfunc_unmap() {
super.vfunc_unmap();
this._emojiPager.setCurrentPage(0);
}
_onPageChanged(sectionLabel, page, nPages) {
this._pageIndicator.setNPages(nPages); this._pageIndicator.setNPages(nPages);
this._pageIndicator.setCurrentPage(page); this._pageIndicator.setCurrentPage(page);
for (let i = 0; i < this._sections.length; i++) { for (let i = 0; i < this._sections.length; i++) {
let sect = this._sections[i]; let sect = this._sections[i];
sect.button.setLatched(sectionLabel == sect.label); sect.button.setLatched(section == sect);
} }
} }
@@ -988,14 +961,14 @@ var EmojiSelection = GObject.registerClass({
key = new Key('ABC', []); key = new Key('ABC', []);
key.keyButton.add_style_class_name('default-key'); key.keyButton.add_style_class_name('default-key');
key.connect('released', () => this.emit('toggle')); key.connect('released', () => this.emit('toggle'));
row.appendKey(key, 1.5); row.appendKey(key.actor, 1.5);
for (let i = 0; i < this._sections.length; i++) { for (let i = 0; i < this._sections.length; i++) {
let section = this._sections[i]; let section = this._sections[i];
key = new Key(section.label, []); key = new Key(section.label, []);
key.connect('released', () => this._emojiPager.setCurrentSection(section, 0)); key.connect('released', () => this._emojiPager.setCurrentSection(section, 0));
row.appendKey(key); row.appendKey(key.actor);
section.button = key; section.button = key;
} }
@@ -1004,9 +977,9 @@ var EmojiSelection = GObject.registerClass({
key.keyButton.add_style_class_name('default-key'); key.keyButton.add_style_class_name('default-key');
key.keyButton.add_style_class_name('hide-key'); key.keyButton.add_style_class_name('hide-key');
key.connect('released', () => { key.connect('released', () => {
this.emit('close-request'); this.emit('hide');
}); });
row.appendKey(key); row.appendKey(key.actor);
row.layoutButtons(); row.layoutButtons();
let actor = new AspectContainer({ layout_manager: new Clutter.BinLayout(), let actor = new AspectContainer({ layout_manager: new Clutter.BinLayout(),
@@ -1020,14 +993,11 @@ var EmojiSelection = GObject.registerClass({
return actor; return actor;
} }
}); };
Signals.addSignalMethods(EmojiSelection.prototype);
var Keypad = GObject.registerClass({ var Keypad = class Keypad {
Signals: { constructor() {
'keyval': { param_types: [GObject.TYPE_UINT] },
}
}, class Keypad extends AspectContainer {
_init() {
let keys = [ let keys = [
{ label: '1', keyval: Clutter.KEY_1, left: 0, top: 0 }, { label: '1', keyval: Clutter.KEY_1, left: 0, top: 0 },
{ label: '2', keyval: Clutter.KEY_2, left: 1, top: 0 }, { label: '2', keyval: Clutter.KEY_2, left: 1, top: 0 },
@@ -1043,17 +1013,14 @@ var Keypad = GObject.registerClass({
{ keyval: Clutter.KEY_Return, extraClassName: 'enter-key', left: 3, top: 1, height: 2 }, { keyval: Clutter.KEY_Return, extraClassName: 'enter-key', left: 3, top: 1, height: 2 },
]; ];
super._init({ this.actor = new AspectContainer({ layout_manager: new Clutter.BinLayout(),
layout_manager: new Clutter.BinLayout(), x_expand: true, y_expand: true });
x_expand: true,
y_expand: true
});
let gridLayout = new Clutter.GridLayout({ orientation: Clutter.Orientation.HORIZONTAL, let gridLayout = new Clutter.GridLayout({ orientation: Clutter.Orientation.HORIZONTAL,
column_homogeneous: true, column_homogeneous: true,
row_homogeneous: true }); row_homogeneous: true });
this._box = new St.Widget({ layout_manager: gridLayout, x_expand: true, y_expand: true }); this._box = new St.Widget({ layout_manager: gridLayout, x_expand: true, y_expand: true });
this.add_child(this._box); this.actor.add_child(this._box);
for (let i = 0; i < keys.length; i++) { for (let i = 0; i < keys.length; i++) {
let cur = keys[i]; let cur = keys[i];
@@ -1065,32 +1032,86 @@ var Keypad = GObject.registerClass({
let w, h; let w, h;
w = cur.width || 1; w = cur.width || 1;
h = cur.height || 1; h = cur.height || 1;
gridLayout.attach(key, cur.left, cur.top, w, h); gridLayout.attach(key.actor, cur.left, cur.top, w, h);
key.connect('released', () => { key.connect('released', () => {
this.emit('keyval', cur.keyval); this.emit('keyval', cur.keyval);
}); });
} }
} }
}); };
Signals.addSignalMethods(Keypad.prototype);
var KeyboardManager = class KeyBoardManager { var Keyboard = class Keyboard {
constructor() { constructor() {
this._keyboard = null; this.actor = null;
this._focusInExtendedKeys = false;
this._emojiActive = false;
this._languagePopup = null;
this._currentFocusWindow = null;
this._animFocusedWindow = null;
this._delayedAnimFocusWindow = null;
this._enableKeyboard = false; // a11y settings value
this._enabled = false; // enabled state (by setting or device type)
this._latched = false; // current level is latched
this._a11yApplicationsSettings = new Gio.Settings({ schema_id: A11Y_APPLICATIONS_SCHEMA }); this._a11yApplicationsSettings = new Gio.Settings({ schema_id: A11Y_APPLICATIONS_SCHEMA });
this._a11yApplicationsSettings.connect('changed', this._syncEnabled.bind(this)); this._a11yApplicationsSettings.connect('changed', this._syncEnabled.bind(this));
this._lastDeviceId = null; this._lastDeviceId = null;
Meta.get_backend().connect('last-device-changed', (backend, deviceId) => { this._suggestions = null;
let manager = Clutter.DeviceManager.get_default(); this._emojiKeyVisible = Meta.is_wayland_compositor();
let device = manager.get_device(deviceId);
if (device.get_device_name().indexOf('XTEST') < 0) { this._focusTracker = new FocusTracker();
this._lastDeviceId = deviceId; this._focusTracker.connect('position-changed', this._onFocusPositionChanged.bind(this));
this._syncEnabled(); this._focusTracker.connect('reset', () => {
} this._delayedAnimFocusWindow = null;
this._animFocusedWindow = null;
this._oskFocusWindow = null;
}); });
this._focusTracker.connect('focus-changed', (tracker, focused) => {
// Valid only for X11
if (Meta.is_wayland_compositor())
return;
if (focused)
this.show(Main.layoutManager.focusIndex);
else
this.hide();
});
Meta.get_backend().connect('last-device-changed',
(backend, deviceId) => {
let manager = Clutter.DeviceManager.get_default();
let device = manager.get_device(deviceId);
if (!device.get_device_name().includes('XTEST')) {
this._lastDeviceId = deviceId;
this._syncEnabled();
}
});
this._syncEnabled(); this._syncEnabled();
this._showIdleId = 0;
this._keyboardVisible = false;
Main.layoutManager.connect('keyboard-visible-changed', (o, visible) => {
this._keyboardVisible = visible;
});
this._keyboardRequested = false;
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() { _lastDeviceIsTouchscreen() {
@@ -1107,143 +1128,38 @@ var KeyboardManager = class KeyBoardManager {
} }
_syncEnabled() { _syncEnabled() {
let enableKeyboard = this._a11yApplicationsSettings.get_boolean(SHOW_KEYBOARD); let wasEnabled = this._enabled;
let enabled = enableKeyboard || this._lastDeviceIsTouchscreen(); this._enableKeyboard = this._a11yApplicationsSettings.get_boolean(SHOW_KEYBOARD);
if (!enabled && !this._keyboard) this._enabled = this._enableKeyboard || this._lastDeviceIsTouchscreen();
if (!this._enabled && !this._keyboardController)
return; return;
if (enabled && !this._keyboard) { if (this._enabled && !this._keyboardController)
this._keyboard = new Keyboard(); this._setupKeyboard();
} else if (!enabled && this._keyboard) { else if (!this._enabled)
this._keyboard.setCursorLocation(null); this.setCursorLocation(null);
if (!this._enabled && wasEnabled)
Main.layoutManager.hideKeyboard(true); Main.layoutManager.hideKeyboard(true);
this._keyboard.destroy();
this._keyboard = null;
}
} }
get keyboardActor() { _destroyKeyboard() {
return this._keyboard; if (this._keyboardNotifyId)
} this._keyboardController.disconnect(this._keyboardNotifyId);
if (this._keyboardGroupsChangedId)
get visible() { this._keyboardController.disconnect(this._keyboardGroupsChangedId);
return this._keyboard && this._keyboard.visible; if (this._keyboardStateId)
} this._keyboardController.disconnect(this._keyboardStateId);
if (this._emojiKeyVisibleId)
open(monitor) { this._keyboardController.disconnect(this._emojiKeyVisibleId);
if (this._keyboard) if (this._keypadVisibleId)
this._keyboard.open(monitor); this._keyboardController.disconnect(this._keypadVisibleId);
} if (this._focusNotifyId)
global.stage.disconnect(this._focusNotifyId);
close() {
if (this._keyboard)
this._keyboard.close();
}
addSuggestion(text, callback) {
if (this._keyboard)
this._keyboard.addSuggestion(text, callback);
}
resetSuggestions() {
if (this._keyboard)
this._keyboard.resetSuggestions();
}
shouldTakeEvent(event) {
if (!this._keyboard)
return false;
let actor = event.get_source();
return Main.layoutManager.keyboardBox.contains(actor) ||
!!actor._extended_keys || !!actor.extended_key;
}
};
var Keyboard = GObject.registerClass(
class Keyboard extends St.BoxLayout {
_init() {
super._init({ name: 'keyboard', vertical: true });
this._focusInExtendedKeys = false;
this._emojiActive = false;
this._languagePopup = null;
this._currentFocusWindow = null;
this._animFocusedWindow = null;
this._delayedAnimFocusWindow = null;
this._latched = false; // current level is latched
this._suggestions = null;
this._emojiKeyVisible = Meta.is_wayland_compositor();
this._focusTracker = new FocusTracker();
this._connectSignal(this._focusTracker, 'position-changed',
this._onFocusPositionChanged.bind(this));
this._connectSignal(this._focusTracker, 'reset', () => {
this._delayedAnimFocusWindow = null;
this._animFocusedWindow = null;
this._oskFocusWindow = null;
});
// Valid only for X11
if (!Meta.is_wayland_compositor()) {
this._connectSignal(this._focusTracker, 'focus-changed', (_tracker, focused) => {
if (focused)
this.open(Main.layoutManager.focusIndex);
else
this.close();
});
}
this._showIdleId = 0;
this._keyboardVisible = false;
this._connectSignal(Main.layoutManager, 'keyboard-visible-changed', (_lm, visible) => {
this._keyboardVisible = visible;
});
this._keyboardRequested = false;
this._keyboardRestingId = 0;
this._connectSignal(Main.layoutManager, 'monitors-changed', this._relayout.bind(this));
this._setupKeyboard();
this.connect('destroy', this._onDestroy.bind(this));
}
_connectSignal(obj, signal, callback) {
if (!this._connectionsIDs)
this._connectionsIDs = [];
let id = obj.connect(signal, callback);
this._connectionsIDs.push([obj, id]);
return id;
}
get visible() {
return this._keyboardVisible && super.visible;
}
_onFocusPositionChanged(focusTracker) {
let rect = focusTracker.getCurrentRect();
this.setCursorLocation(focusTracker.currentWindow, rect.x, rect.y, rect.width, rect.height);
}
_onDestroy() {
for (let [obj, id] of this._connectionsIDs)
obj.disconnect(id);
delete this._connectionsIDs;
this._clearShowIdle(); this._clearShowIdle();
this._keyboard = null;
this._keyboardController = null; this.actor.destroy();
this._suggestions = null; this.actor = null;
this._aspectContainer = null;
this._emojiSelection = null;
this._keypad = null;
Main.layoutManager.untrackChrome(this);
Main.layoutManager.keyboardBox.remove_actor(this);
if (this._languagePopup) { if (this._languagePopup) {
this._languagePopup.destroy(); this._languagePopup.destroy();
@@ -1252,8 +1168,9 @@ class Keyboard extends St.BoxLayout {
} }
_setupKeyboard() { _setupKeyboard() {
Main.layoutManager.keyboardBox.add_actor(this); this.actor = new St.BoxLayout({ name: 'keyboard', vertical: true, reactive: true });
Main.layoutManager.trackChrome(this); Main.layoutManager.keyboardBox.add_actor(this.actor);
Main.layoutManager.trackChrome(this.actor);
this._keyboardController = new KeyboardController(); this._keyboardController = new KeyboardController();
@@ -1261,28 +1178,30 @@ class Keyboard extends St.BoxLayout {
this._currentPage = null; this._currentPage = null;
this._suggestions = new Suggestions(); this._suggestions = new Suggestions();
this.add(this._suggestions, { x_align: St.Align.MIDDLE, x_fill: false }); this.actor.add(this._suggestions.actor,
{ x_align: St.Align.MIDDLE,
x_fill: false });
this._aspectContainer = new AspectContainer({ layout_manager: new Clutter.BinLayout() }); this._aspectContainer = new AspectContainer({ layout_manager: new Clutter.BinLayout() });
this.add(this._aspectContainer, { expand: true }); this.actor.add(this._aspectContainer, { expand: true });
this._emojiSelection = new EmojiSelection(); this._emojiSelection = new EmojiSelection();
this._emojiSelection.connect('toggle', this._toggleEmoji.bind(this)); this._emojiSelection.connect('toggle', this._toggleEmoji.bind(this));
this._emojiSelection.connect('close-request', () => this.close()); this._emojiSelection.connect('hide', () => this.hide());
this._emojiSelection.connect('emoji-selected', (selection, emoji) => { this._emojiSelection.connect('emoji-selected', (selection, emoji) => {
this._keyboardController.commitString(emoji); this._keyboardController.commitString(emoji);
}); });
this._aspectContainer.add_child(this._emojiSelection); this._aspectContainer.add_child(this._emojiSelection.actor);
this._emojiSelection.hide(); this._emojiSelection.actor.hide();
this._keypad = new Keypad(); this._keypad = new Keypad();
this._connectSignal(this._keypad, 'keyval', (_keypad, keyval) => { this._keypad.connect('keyval', (keypad, keyval) => {
this._keyboardController.keyvalPress(keyval); this._keyboardController.keyvalPress(keyval);
this._keyboardController.keyvalRelease(keyval); this._keyboardController.keyvalRelease(keyval);
}); });
this._aspectContainer.add_child(this._keypad); this._aspectContainer.add_child(this._keypad.actor);
this._keypad.hide(); this._keypad.actor.hide();
this._keypadVisible = false; this._keypadVisible = false;
this._ensureKeysForGroup(this._keyboardController.getCurrentGroup()); this._ensureKeysForGroup(this._keyboardController.getCurrentGroup());
@@ -1291,22 +1210,16 @@ class Keyboard extends St.BoxLayout {
// Keyboard models are defined in LTR, we must override // Keyboard models are defined in LTR, we must override
// the locale setting in order to avoid flipping the // the locale setting in order to avoid flipping the
// keyboard on RTL locales. // keyboard on RTL locales.
this.text_direction = Clutter.TextDirection.LTR; this.actor.text_direction = Clutter.TextDirection.LTR;
this._connectSignal(this._keyboardController, 'active-group', this._keyboardNotifyId = this._keyboardController.connect('active-group', this._onGroupChanged.bind(this));
this._onGroupChanged.bind(this)); this._keyboardGroupsChangedId = this._keyboardController.connect('groups-changed', this._onKeyboardGroupsChanged.bind(this));
this._connectSignal(this._keyboardController, 'groups-changed', this._keyboardStateId = this._keyboardController.connect('panel-state', this._onKeyboardStateChanged.bind(this));
this._onKeyboardGroupsChanged.bind(this)); this._keypadVisibleId = this._keyboardController.connect('keypad-visible', this._onKeypadVisible.bind(this));
this._connectSignal(this._keyboardController, 'panel-state', this._focusNotifyId = global.stage.connect('notify::key-focus', this._onKeyFocusChanged.bind(this));
this._onKeyboardStateChanged.bind(this));
this._connectSignal(this._keyboardController, 'keypad-visible',
this._onKeypadVisible.bind(this));
this._connectSignal(global.stage, 'notify::key-focus',
this._onKeyFocusChanged.bind(this));
if (Meta.is_wayland_compositor()) if (Meta.is_wayland_compositor())
this._connectSignal(this._keyboardController, 'emoji-visible', this._emojiKeyVisibleId = this._keyboardController.connect('emoji-visible', this._onEmojiKeyVisible.bind(this));
this._onEmojiKeyVisible.bind(this));
this._relayout(); this._relayout();
} }
@@ -1322,17 +1235,17 @@ class Keyboard extends St.BoxLayout {
return; return;
if (!(focus instanceof Clutter.Text)) { if (!(focus instanceof Clutter.Text)) {
this.close(); this.hide();
return; return;
} }
if (!this._showIdleId) { if (!this._showIdleId) {
this._showIdleId = GLib.idle_add(GLib.PRIORITY_DEFAULT_IDLE, () => { this._showIdleId = GLib.idle_add(GLib.PRIORITY_DEFAULT_IDLE, () => {
this.open(Main.layoutManager.focusIndex); this.show(Main.layoutManager.focusIndex);
this._showIdleId = 0; this._showIdleId = 0;
return GLib.SOURCE_REMOVE; return GLib.SOURCE_REMOVE;
}); });
GLib.Source.set_name_by_id(this._showIdleId, '[gnome-shell] this.open'); GLib.Source.set_name_by_id(this._showIdleId, '[gnome-shell] this.show');
} }
} }
@@ -1396,7 +1309,7 @@ class Keyboard extends St.BoxLayout {
this._setActiveLayer(0); this._setActiveLayer(0);
}); });
layout.appendKey(button, button.keyButton.keyWidth); layout.appendKey(button.actor, button.keyButton.keyWidth);
} }
} }
@@ -1444,7 +1357,7 @@ class Keyboard extends St.BoxLayout {
if (keyval != null) if (keyval != null)
this._keyboardController.keyvalRelease(keyval); this._keyboardController.keyvalRelease(keyval);
else if (action == 'hide') else if (action == 'hide')
this.close(); this.hide();
else if (action == 'languageMenu') else if (action == 'languageMenu')
this._popupLanguageMenu(actor); this._popupLanguageMenu(actor);
else if (action == 'emoji') else if (action == 'emoji')
@@ -1467,7 +1380,7 @@ class Keyboard extends St.BoxLayout {
/* Only hide the key actor, so the container still takes space */ /* Only hide the key actor, so the container still takes space */
extraButton.keyButton.hide(); extraButton.keyButton.hide();
} else { } else {
extraButton.hide(); extraButton.actor.hide();
} }
extraButton.setWidth(1.5); extraButton.setWidth(1.5);
} else if (key.right && numKeys > 8) { } else if (key.right && numKeys > 8) {
@@ -1478,7 +1391,7 @@ class Keyboard extends St.BoxLayout {
extraButton.setWidth(1.5); extraButton.setWidth(1.5);
} }
layout.appendKey(extraButton, extraButton.keyButton.keyWidth); layout.appendKey(extraButton.actor, extraButton.keyButton.keyWidth);
} }
} }
@@ -1489,7 +1402,7 @@ class Keyboard extends St.BoxLayout {
_setEmojiActive(active) { _setEmojiActive(active) {
this._emojiActive = active; this._emojiActive = active;
this._emojiSelection.visible = this._emojiActive; this._emojiSelection.actor.visible = this._emojiActive;
this._updateCurrentPageVisible(); this._updateCurrentPageVisible();
} }
@@ -1557,12 +1470,12 @@ class Keyboard extends St.BoxLayout {
_relayout() { _relayout() {
let monitor = Main.layoutManager.keyboardMonitor; let monitor = Main.layoutManager.keyboardMonitor;
if (!monitor) if (this.actor == null || monitor == null)
return; return;
let maxHeight = monitor.height / 3; let maxHeight = monitor.height / 3;
this.width = monitor.width; this.actor.width = monitor.width;
this.height = maxHeight; this.actor.height = maxHeight;
} }
_onGroupChanged() { _onGroupChanged() {
@@ -1571,7 +1484,7 @@ class Keyboard extends St.BoxLayout {
} }
_onKeyboardGroupsChanged() { _onKeyboardGroupsChanged() {
let nonGroupActors = [this._emojiSelection, this._keypad]; let nonGroupActors = [this._emojiSelection.actor, this._keypad.actor];
this._aspectContainer.get_children().filter(c => !nonGroupActors.includes(c)).forEach(c => { this._aspectContainer.get_children().filter(c => !nonGroupActors.includes(c)).forEach(c => {
c.destroy(); c.destroy();
}); });
@@ -1585,7 +1498,7 @@ class Keyboard extends St.BoxLayout {
return; return;
this._keypadVisible = visible; this._keypadVisible = visible;
this._keypad.visible = this._keypadVisible; this._keypad.actor.visible = this._keypadVisible;
this._updateCurrentPageVisible(); this._updateCurrentPageVisible();
} }
@@ -1610,9 +1523,9 @@ class Keyboard extends St.BoxLayout {
return; return;
if (enabled) if (enabled)
this.open(Main.layoutManager.focusIndex); this.show(Main.layoutManager.focusIndex);
else else
this.close(); this.hide();
} }
_setActiveLayer(activeLevel) { _setActiveLayer(activeLevel) {
@@ -1639,6 +1552,12 @@ class Keyboard extends St.BoxLayout {
this._updateCurrentPageVisible(); this._updateCurrentPageVisible();
} }
shouldTakeEvent(event) {
let actor = event.get_source();
return Main.layoutManager.keyboardBox.contains(actor) ||
!!actor._extended_keys || !!actor.extended_key;
}
_clearKeyboardRestTimer() { _clearKeyboardRestTimer() {
if (!this._keyboardRestingId) if (!this._keyboardRestingId)
return; return;
@@ -1646,7 +1565,10 @@ class Keyboard extends St.BoxLayout {
this._keyboardRestingId = 0; this._keyboardRestingId = 0;
} }
open(monitor) { show(monitor) {
if (!this._enabled)
return;
this._clearShowIdle(); this._clearShowIdle();
this._keyboardRequested = true; this._keyboardRequested = true;
@@ -1663,13 +1585,13 @@ class Keyboard extends St.BoxLayout {
KEYBOARD_REST_TIME, KEYBOARD_REST_TIME,
() => { () => {
this._clearKeyboardRestTimer(); this._clearKeyboardRestTimer();
this._open(monitor); this._show(monitor);
return GLib.SOURCE_REMOVE; return GLib.SOURCE_REMOVE;
}); });
GLib.Source.set_name_by_id(this._keyboardRestingId, '[gnome-shell] this._clearKeyboardRestTimer'); GLib.Source.set_name_by_id(this._keyboardRestingId, '[gnome-shell] this._clearKeyboardRestTimer');
} }
_open(monitor) { _show(monitor) {
if (!this._keyboardRequested) if (!this._keyboardRequested)
return; return;
@@ -1685,7 +1607,10 @@ class Keyboard extends St.BoxLayout {
} }
} }
close() { hide() {
if (!this._enabled)
return;
this._clearShowIdle(); this._clearShowIdle();
this._keyboardRequested = false; this._keyboardRequested = false;
@@ -1697,13 +1622,13 @@ class Keyboard extends St.BoxLayout {
KEYBOARD_REST_TIME, KEYBOARD_REST_TIME,
() => { () => {
this._clearKeyboardRestTimer(); this._clearKeyboardRestTimer();
this._close(); this._hide();
return GLib.SOURCE_REMOVE; return GLib.SOURCE_REMOVE;
}); });
GLib.Source.set_name_by_id(this._keyboardRestingId, '[gnome-shell] this._clearKeyboardRestTimer'); GLib.Source.set_name_by_id(this._keyboardRestingId, '[gnome-shell] this._clearKeyboardRestTimer');
} }
_close() { _hide() {
if (this._keyboardRequested) if (this._keyboardRequested)
return; return;
@@ -1720,7 +1645,7 @@ class Keyboard extends St.BoxLayout {
if (!this._suggestions) if (!this._suggestions)
return; return;
this._suggestions.add(text, callback); this._suggestions.add(text, callback);
this._suggestions.show(); this._suggestions.actor.show();
} }
_clearShowIdle() { _clearShowIdle() {
@@ -1797,7 +1722,7 @@ class Keyboard extends St.BoxLayout {
this._oskFocusWindow = window; this._oskFocusWindow = window;
} }
}); };
var KeyboardController = class { var KeyboardController = class {
constructor() { constructor() {

View File

@@ -606,17 +606,17 @@ var LayoutManager = GObject.registerClass({
return; return;
} }
this._systemBackground = new Background.SystemBackground(); this._systemBackground = new Background.SystemBackground();
this._systemBackground.hide(); this._systemBackground.actor.hide();
global.stage.insert_child_below(this._systemBackground, null); global.stage.insert_child_below(this._systemBackground.actor, null);
let constraint = new Clutter.BindConstraint({ source: global.stage, let constraint = new Clutter.BindConstraint({ source: global.stage,
coordinate: Clutter.BindCoordinate.ALL }); coordinate: Clutter.BindCoordinate.ALL });
this._systemBackground.add_constraint(constraint); this._systemBackground.actor.add_constraint(constraint);
let signalId = this._systemBackground.connect('loaded', () => { let signalId = this._systemBackground.connect('loaded', () => {
this._systemBackground.disconnect(signalId); this._systemBackground.disconnect(signalId);
this._systemBackground.show(); this._systemBackground.actor.show();
global.stage.show(); global.stage.show();
this._prepareStartupAnimation(); this._prepareStartupAnimation();
@@ -722,7 +722,7 @@ var LayoutManager = GObject.registerClass({
this._coverPane.destroy(); this._coverPane.destroy();
this._coverPane = null; this._coverPane = null;
this._systemBackground.destroy(); this._systemBackground.actor.destroy();
this._systemBackground = null; this._systemBackground = null;
this._startingUp = false; this._startingUp = false;
@@ -1112,11 +1112,8 @@ var LayoutManager = GObject.registerClass({
// //
// This class manages a "hot corner" that can toggle switching to // This class manages a "hot corner" that can toggle switching to
// overview. // overview.
var HotCorner = GObject.registerClass( var HotCorner = class HotCorner {
class HotCorner extends Clutter.Actor { constructor(layoutManager, monitor, x, y) {
_init(layoutManager, monitor, x, y) {
super._init();
// We use this flag to mark the case where the user has entered the // 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 // hot corner and has not left both the hot corner and a surrounding
// guard area (the "environs"). This avoids triggering the hot corner // guard area (the "environs"). This avoids triggering the hot corner
@@ -1145,8 +1142,6 @@ class HotCorner extends Clutter.Actor {
this._ripples = new Ripples.Ripples(px, py, 'ripple-box'); this._ripples = new Ripples.Ripples(px, py, 'ripple-box');
this._ripples.addTo(layoutManager.uiGroup); this._ripples.addTo(layoutManager.uiGroup);
this.connect('destroy', this._onDestroy.bind(this));
} }
setBarrierSize(size) { setBarrierSize(size) {
@@ -1186,14 +1181,11 @@ class HotCorner extends Clutter.Actor {
_setupFallbackCornerIfNeeded(layoutManager) { _setupFallbackCornerIfNeeded(layoutManager) {
if (!global.display.supports_extended_barriers()) { if (!global.display.supports_extended_barriers()) {
this.set({ this.actor = new Clutter.Actor({ name: 'hot-corner-environs',
name: 'hot-corner-environs', x: this._x, y: this._y,
x: this._x, width: 3,
y: this._y, height: 3,
width: 3, reactive: true });
height: 3,
reactive: true
});
this._corner = new Clutter.Actor({ name: 'hot-corner', this._corner = new Clutter.Actor({ name: 'hot-corner',
width: 1, width: 1,
@@ -1202,16 +1194,19 @@ class HotCorner extends Clutter.Actor {
reactive: true }); reactive: true });
this._corner._delegate = this; this._corner._delegate = this;
this.add_child(this._corner); this.actor.add_child(this._corner);
layoutManager.addChrome(this); layoutManager.addChrome(this.actor);
if (Clutter.get_default_text_direction() == Clutter.TextDirection.RTL) { if (Clutter.get_default_text_direction() == Clutter.TextDirection.RTL) {
this._corner.set_position(this.width - this._corner.width, 0); this._corner.set_position(this.actor.width - this._corner.width, 0);
this.set_anchor_point_from_gravity(Clutter.Gravity.NORTH_EAST); this.actor.set_anchor_point_from_gravity(Clutter.Gravity.NORTH_EAST);
} else { } else {
this._corner.set_position(0, 0); this._corner.set_position(0, 0);
} }
this.actor.connect('leave-event',
this._onEnvironsLeft.bind(this));
this._corner.connect('enter-event', this._corner.connect('enter-event',
this._onCornerEntered.bind(this)); this._onCornerEntered.bind(this));
this._corner.connect('leave-event', this._corner.connect('leave-event',
@@ -1219,11 +1214,14 @@ class HotCorner extends Clutter.Actor {
} }
} }
_onDestroy() { destroy() {
this.setBarrierSize(0); this.setBarrierSize(0);
this._pressureBarrier.destroy(); this._pressureBarrier.destroy();
this._pressureBarrier = null; this._pressureBarrier = null;
if (this.actor)
this.actor.destroy();
this._ripples.destroy(); this._ripples.destroy();
} }
@@ -1255,18 +1253,18 @@ class HotCorner extends Clutter.Actor {
} }
_onCornerLeft(actor, event) { _onCornerLeft(actor, event) {
if (event.get_related() != this) if (event.get_related() != this.actor)
this._entered = false; this._entered = false;
// Consume event, otherwise this will confuse onEnvironsLeft // Consume event, otherwise this will confuse onEnvironsLeft
return Clutter.EVENT_STOP; return Clutter.EVENT_STOP;
} }
vfunc_leave_event(crossingEvent) { _onEnvironsLeft(actor, event) {
if (crossingEvent.related != this._corner) if (event.get_related() != this._corner)
this._entered = false; this._entered = false;
return Clutter.EVENT_PROPAGATE; return Clutter.EVENT_PROPAGATE;
} }
}); };
var PressureBarrier = class PressureBarrier { var PressureBarrier = class PressureBarrier {
constructor(threshold, timeout, actionMode) { constructor(threshold, timeout, actionMode) {

View File

@@ -2,6 +2,7 @@
/* exported Lightbox */ /* exported Lightbox */
const { Clutter, GObject, Shell, St } = imports.gi; const { Clutter, GObject, Shell, St } = imports.gi;
const Signals = imports.signals;
const Params = imports.misc.params; const Params = imports.misc.params;
@@ -88,8 +89,8 @@ var RadialShaderEffect = GObject.registerClass({
* - inhibitEvents: whether to inhibit events for @container * - inhibitEvents: whether to inhibit events for @container
* - width: shade actor width * - width: shade actor width
* - height: shade actor height * - height: shade actor height
* - fadeFactor: fading opacity factor * - fadeInTime: milliseconds used to fade in
* - radialEffect: whether to enable the GLSL radial effect * - fadeOutTime: milliseconds used to fade out
* *
* Lightbox creates a dark translucent "shade" actor to hide the * Lightbox creates a dark translucent "shade" actor to hide the
* contents of @container, and allows you to specify particular actors * contents of @container, and allows you to specify particular actors
@@ -105,13 +106,8 @@ var RadialShaderEffect = GObject.registerClass({
* @container and will track any changes in its size. You can override * @container and will track any changes in its size. You can override
* this by passing an explicit width and height in @params. * this by passing an explicit width and height in @params.
*/ */
var Lightbox = GObject.registerClass({ var Lightbox = class Lightbox {
Properties: { constructor(container, params) {
'active': GObject.ParamSpec.boolean(
'active', 'active', 'active', GObject.ParamFlags.READABLE, false),
}
}, class Lightbox extends St.Bin {
_init(container, params) {
params = Params.parse(params, { params = Params.parse(params, {
inhibitEvents: false, inhibitEvents: false,
width: null, width: null,
@@ -120,34 +116,32 @@ var Lightbox = GObject.registerClass({
radialEffect: false, radialEffect: false,
}); });
super._init({
reactive: params.inhibitEvents,
width: params.width,
height: params.height,
visible: false
});
this._active = false;
this._container = container; this._container = container;
this._children = container.get_children(); this._children = container.get_children();
this._fadeFactor = params.fadeFactor; this._fadeFactor = params.fadeFactor;
this._radialEffect = Clutter.feature_available(Clutter.FeatureFlags.SHADERS_GLSL) && params.radialEffect; this._radialEffect = Clutter.feature_available(Clutter.FeatureFlags.SHADERS_GLSL) && params.radialEffect;
this.actor = new St.Bin({ reactive: params.inhibitEvents });
if (this._radialEffect) if (this._radialEffect)
this.add_effect(new RadialShaderEffect({ name: 'radial' })); this.actor.add_effect(new RadialShaderEffect({ name: 'radial' }));
else else
this.set({ opacity: 0, style_class: 'lightbox' }); this.actor.set({ opacity: 0, style_class: 'lightbox' });
container.add_actor(this); container.add_actor(this.actor);
this.raise_top(); this.actor.raise_top();
this.actor.hide();
this.shown = false;
this.connect('destroy', this._onDestroy.bind(this)); this.actor.connect('destroy', this._onDestroy.bind(this));
if (!params.width || !params.height) { if (params.width && params.height) {
this.add_constraint(new Clutter.BindConstraint({ this.actor.width = params.width;
source: container, this.actor.height = params.height;
coordinate: Clutter.BindCoordinate.ALL } else {
})); let constraint = new Clutter.BindConstraint({ source: container,
coordinate: Clutter.BindCoordinate.ALL });
this.actor.add_constraint(constraint);
} }
this._actorAddedSignalId = container.connect('actor-added', this._actorAdded.bind(this)); this._actorAddedSignalId = container.connect('actor-added', this._actorAdded.bind(this));
@@ -156,20 +150,16 @@ var Lightbox = GObject.registerClass({
this._highlighted = null; this._highlighted = null;
} }
get active() {
return this._active;
}
_actorAdded(container, newChild) { _actorAdded(container, newChild) {
let children = this._container.get_children(); let children = this._container.get_children();
let myIndex = children.indexOf(this); let myIndex = children.indexOf(this.actor);
let newChildIndex = children.indexOf(newChild); let newChildIndex = children.indexOf(newChild);
if (newChildIndex > myIndex) { if (newChildIndex > myIndex) {
// The child was added above the shade (presumably it was // The child was added above the shade (presumably it was
// made the new top-most child). Move it below the shade, // made the new top-most child). Move it below the shade,
// and add it to this._children as the new topmost actor. // and add it to this._children as the new topmost actor.
this._container.set_child_above_sibling(this, newChild); newChild.lower(this.actor);
this._children.push(newChild); this._children.push(newChild);
} else if (newChildIndex == 0) { } else if (newChildIndex == 0) {
// Bottom of stack // Bottom of stack
@@ -182,8 +172,8 @@ var Lightbox = GObject.registerClass({
} }
} }
lightOn(fadeInTime) { show(fadeInTime) {
this.remove_all_transitions(); this.actor.remove_all_transitions();
let easeProps = { let easeProps = {
duration: fadeInTime || 0, duration: fadeInTime || 0,
@@ -191,46 +181,44 @@ var Lightbox = GObject.registerClass({
}; };
let onComplete = () => { let onComplete = () => {
this._active = true; this.shown = true;
this.notify('active'); this.emit('shown');
}; };
this.show(); this.actor.show();
if (this._radialEffect) { if (this._radialEffect) {
this.ease_property( this.actor.ease_property(
'@effects.radial.brightness', VIGNETTE_BRIGHTNESS, easeProps); '@effects.radial.brightness', VIGNETTE_BRIGHTNESS, easeProps);
this.ease_property( this.actor.ease_property(
'@effects.radial.sharpness', VIGNETTE_SHARPNESS, '@effects.radial.sharpness', VIGNETTE_SHARPNESS,
Object.assign({ onComplete }, easeProps)); Object.assign({ onComplete }, easeProps));
} else { } else {
this.ease(Object.assign(easeProps, { this.actor.ease(Object.assign(easeProps, {
opacity: 255 * this._fadeFactor, opacity: 255 * this._fadeFactor,
onComplete onComplete
})); }));
} }
} }
lightOff(fadeOutTime) { hide(fadeOutTime) {
this.remove_all_transitions(); this.shown = false;
this.actor.remove_all_transitions();
this._active = false;
this.notify('active');
let easeProps = { let easeProps = {
duration: fadeOutTime || 0, duration: fadeOutTime || 0,
mode: Clutter.AnimationMode.EASE_OUT_QUAD mode: Clutter.AnimationMode.EASE_OUT_QUAD
}; };
let onComplete = () => this.hide(); let onComplete = () => this.actor.hide();
if (this._radialEffect) { if (this._radialEffect) {
this.ease_property( this.actor.ease_property(
'@effects.radial.brightness', 1.0, easeProps); '@effects.radial.brightness', 1.0, easeProps);
this.ease_property( this.actor.ease_property(
'@effects.radial.sharpness', 0.0, Object.assign({ onComplete }, easeProps)); '@effects.radial.sharpness', 0.0, Object.assign({ onComplete }, easeProps));
} else { } else {
this.ease(Object.assign(easeProps, { opacity: 0, onComplete })); this.actor.ease(Object.assign(easeProps, { opacity: 0, onComplete }));
} }
} }
@@ -261,7 +249,7 @@ var Lightbox = GObject.registerClass({
// case we may need to indicate some *other* actor as the new // case we may need to indicate some *other* actor as the new
// sibling of the to-be-lowered one. // sibling of the to-be-lowered one.
let below = this; let below = this.actor;
for (let i = this._children.length - 1; i >= 0; i--) { for (let i = this._children.length - 1; i >= 0; i--) {
if (this._children[i] == window) if (this._children[i] == window)
this._children[i].raise_top(); this._children[i].raise_top();
@@ -274,6 +262,15 @@ var Lightbox = GObject.registerClass({
this._highlighted = window; this._highlighted = window;
} }
/**
* destroy:
*
* Destroys the lightbox.
*/
destroy() {
this.actor.destroy();
}
/** /**
* _onDestroy: * _onDestroy:
* *
@@ -281,15 +278,10 @@ var Lightbox = GObject.registerClass({
* by destroying its container or by explicitly calling this.destroy(). * by destroying its container or by explicitly calling this.destroy().
*/ */
_onDestroy() { _onDestroy() {
if (this._actorAddedSignalId) { this._container.disconnect(this._actorAddedSignalId);
this._container.disconnect(this._actorAddedSignalId); this._container.disconnect(this._actorRemovedSignalId);
this._actorAddedSignalId = 0;
}
if (this._actorRemovedSignalId) {
this._container.disconnect(this._actorRemovedSignalId);
this._actorRemovedSignalId = 0;
}
this.highlight(null); this.highlight(null);
} }
}); };
Signals.addSignalMethods(Lightbox.prototype);

View File

@@ -1,8 +1,8 @@
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*- // -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
/* exported LookingGlass */ /* exported LookingGlass */
const { Clutter, Cogl, Gio, GLib, GObject, const { Clutter, Cogl, Gio, GLib,
Graphene, Meta, Pango, Shell, St } = imports.gi; GObject, Meta, Pango, Shell, St } = imports.gi;
const Signals = imports.signals; const Signals = imports.signals;
const System = imports.system; const System = imports.system;
@@ -110,11 +110,9 @@ var AutoComplete = class AutoComplete {
Signals.addSignalMethods(AutoComplete.prototype); Signals.addSignalMethods(AutoComplete.prototype);
var Notebook = GObject.registerClass({ var Notebook = class Notebook {
Signals: { 'selection': { param_types: [Clutter.Actor.$gtype] } }, constructor() {
}, class Notebook extends St.BoxLayout { this.actor = new St.BoxLayout({ vertical: true });
_init() {
super._init({ vertical: true });
this.tabControls = new St.BoxLayout({ style_class: 'labels' }); this.tabControls = new St.BoxLayout({ style_class: 'labels' });
@@ -145,7 +143,7 @@ var Notebook = GObject.registerClass({
_scrollToBottom: false }; _scrollToBottom: false };
this._tabs.push(tabData); this._tabs.push(tabData);
scrollview.hide(); scrollview.hide();
this.add(scrollview, { expand: true }); this.actor.add(scrollview, { expand: true });
let vAdjust = scrollview.vscroll.adjustment; let vAdjust = scrollview.vscroll.adjustment;
vAdjust.connect('changed', () => this._onAdjustScopeChanged(tabData)); vAdjust.connect('changed', () => this._onAdjustScopeChanged(tabData));
@@ -176,7 +174,7 @@ var Notebook = GObject.registerClass({
// Focus the new tab before unmapping the old one // Focus the new tab before unmapping the old one
let tabData = this._tabs[index]; let tabData = this._tabs[index];
if (!tabData.scrollView.navigate_focus(null, St.DirectionType.TAB_FORWARD, false)) if (!tabData.scrollView.navigate_focus(null, St.DirectionType.TAB_FORWARD, false))
this.grab_key_focus(); this.actor.grab_key_focus();
this._unselect(); this._unselect();
@@ -236,7 +234,8 @@ var Notebook = GObject.registerClass({
this.selectIndex(prevIndex); this.selectIndex(prevIndex);
} }
}); };
Signals.addSignalMethods(Notebook.prototype);
function objectToString(o) { function objectToString(o) {
if (typeof o == typeof objectToString) { if (typeof o == typeof objectToString) {
@@ -247,64 +246,57 @@ function objectToString(o) {
} }
} }
var ObjLink = GObject.registerClass( var ObjLink = class ObjLink {
class ObjLink extends St.Button { constructor(lookingGlass, o, title) {
_init(lookingGlass, o, title) {
let text; let text;
if (title) if (title)
text = title; text = title;
else else
text = objectToString(o); text = objectToString(o);
text = GLib.markup_escape_text(text, -1); text = GLib.markup_escape_text(text, -1);
super._init({
reactive: true,
track_hover: true,
style_class: 'shell-link',
label: text
});
this.get_child().single_line_mode = true;
this._obj = o; this._obj = o;
this.actor = new St.Button({ reactive: true,
track_hover: true,
style_class: 'shell-link',
label: text });
this.actor.get_child().single_line_mode = true;
this.actor.connect('clicked', this._onClicked.bind(this));
this._lookingGlass = lookingGlass; this._lookingGlass = lookingGlass;
} }
vfunc_clicked() { _onClicked() {
this._lookingGlass.inspectObject(this._obj, this); this._lookingGlass.inspectObject(this._obj, this.actor);
} }
}); };
var Result = GObject.registerClass({
GTypeName: 'LookingClass_Result'
}, class Result extends St.BoxLayout {
_init(lookingGlass, command, o, index) {
super._init({ vertical: true });
var Result = class Result {
constructor(lookingGlass, command, o, index) {
this.index = index; this.index = index;
this.o = o; this.o = o;
this.actor = new St.BoxLayout({ vertical: true });
this._lookingGlass = lookingGlass; this._lookingGlass = lookingGlass;
let cmdTxt = new St.Label({ text: command }); let cmdTxt = new St.Label({ text: command });
cmdTxt.clutter_text.ellipsize = Pango.EllipsizeMode.END; cmdTxt.clutter_text.ellipsize = Pango.EllipsizeMode.END;
this.add(cmdTxt); this.actor.add(cmdTxt);
let box = new St.BoxLayout({}); let box = new St.BoxLayout({});
this.add(box); this.actor.add(box);
let resultTxt = new St.Label({ text: `r(${index}) = ` }); let resultTxt = new St.Label({ text: `r(${index}) = ` });
resultTxt.clutter_text.ellipsize = Pango.EllipsizeMode.END; resultTxt.clutter_text.ellipsize = Pango.EllipsizeMode.END;
box.add(resultTxt); box.add(resultTxt);
let objLink = new ObjLink(this._lookingGlass, o); let objLink = new ObjLink(this._lookingGlass, o);
box.add(objLink); box.add(objLink.actor);
} }
}); };
var WindowList = GObject.registerClass({ var WindowList = class WindowList {
GTypeName: 'LookingClass_WindowList' constructor(lookingGlass) {
}, class WindowList extends St.BoxLayout { this.actor = new St.BoxLayout({ name: 'Windows', vertical: true, style: 'spacing: 8px' });
_init(lookingGlass) {
super._init({ name: 'Windows', vertical: true, style: 'spacing: 8px' });
let tracker = Shell.WindowTracker.get_default(); let tracker = Shell.WindowTracker.get_default();
this._updateId = Main.initializeDeferredWork(this, this._updateWindowList.bind(this)); this._updateId = Main.initializeDeferredWork(this.actor, this._updateWindowList.bind(this));
global.display.connect('window-created', this._updateWindowList.bind(this)); global.display.connect('window-created', this._updateWindowList.bind(this));
tracker.connect('tracked-windows-changed', this._updateWindowList.bind(this)); tracker.connect('tracked-windows-changed', this._updateWindowList.bind(this));
@@ -315,7 +307,7 @@ var WindowList = GObject.registerClass({
if (!this._lookingGlass.isOpen) if (!this._lookingGlass.isOpen)
return; return;
this.destroy_all_children(); this.actor.destroy_all_children();
let windows = global.get_window_actors(); let windows = global.get_window_actors();
let tracker = Shell.WindowTracker.get_default(); let tracker = Shell.WindowTracker.get_default();
for (let i = 0; i < windows.length; i++) { for (let i = 0; i < windows.length; i++) {
@@ -326,9 +318,9 @@ var WindowList = GObject.registerClass({
metaWindow._lookingGlassManaged = true; metaWindow._lookingGlassManaged = true;
} }
let box = new St.BoxLayout({ vertical: true }); let box = new St.BoxLayout({ vertical: true });
this.add(box); this.actor.add(box);
let windowLink = new ObjLink(this._lookingGlass, metaWindow, metaWindow.title); let windowLink = new ObjLink(this._lookingGlass, metaWindow, metaWindow.title);
box.add(windowLink, { x_align: St.Align.START, x_fill: false }); box.add(windowLink.actor, { x_align: St.Align.START, x_fill: false });
let propsBox = new St.BoxLayout({ vertical: true, style: 'padding-left: 6px;' }); let propsBox = new St.BoxLayout({ vertical: true, style: 'padding-left: 6px;' });
box.add(propsBox); box.add(propsBox);
propsBox.add(new St.Label({ text: `wmclass: ${metaWindow.get_wm_class()}` })); propsBox.add(new St.Label({ text: `wmclass: ${metaWindow.get_wm_class()}` }));
@@ -339,7 +331,7 @@ var WindowList = GObject.registerClass({
propsBox.add(propBox); propsBox.add(propBox);
propBox.add(new St.Label({ text: 'app: ' }), { y_fill: false }); propBox.add(new St.Label({ text: 'app: ' }), { y_fill: false });
let appLink = new ObjLink(this._lookingGlass, app, app.get_id()); let appLink = new ObjLink(this._lookingGlass, app, app.get_id());
propBox.add(appLink, { y_fill: false }); propBox.add(appLink.actor, { y_fill: false });
propBox.add(icon, { y_fill: false }); propBox.add(icon, { y_fill: false });
} else { } else {
propsBox.add(new St.Label({ text: '<untracked>' })); propsBox.add(new St.Label({ text: '<untracked>' }));
@@ -350,27 +342,23 @@ var WindowList = GObject.registerClass({
update() { update() {
this._updateWindowList(); this._updateWindowList();
} }
}); };
Signals.addSignalMethods(WindowList.prototype);
var ObjInspector = GObject.registerClass(
class ObjInspector extends St.ScrollView {
_init(lookingGlass) {
super._init({
pivot_point: new Graphene.Point({ x: 0.5, y: 0.5 }),
x_fill: true,
y_fill: true
});
var ObjInspector = class ObjInspector {
constructor(lookingGlass) {
this._obj = null; this._obj = null;
this._previousObj = null; this._previousObj = null;
this._parentList = []; this._parentList = [];
this.get_hscroll_bar().hide(); this.actor = new St.ScrollView({ pivot_point: new Clutter.Point({ x: 0.5, y: 0.5 }),
x_fill: true, y_fill: true });
this.actor.get_hscroll_bar().hide();
this._container = new St.BoxLayout({ name: 'LookingGlassPropertyInspector', this._container = new St.BoxLayout({ name: 'LookingGlassPropertyInspector',
style_class: 'lg-dialog', style_class: 'lg-dialog',
vertical: true }); vertical: true });
this.add_actor(this._container); this.actor.add_actor(this._container);
this._lookingGlass = lookingGlass; this._lookingGlass = lookingGlass;
} }
@@ -416,7 +404,7 @@ class ObjInspector extends St.ScrollView {
let link; let link;
try { try {
let prop = obj[propName]; let prop = obj[propName];
link = new ObjLink(this._lookingGlass, prop); link = new ObjLink(this._lookingGlass, prop).actor;
} catch (e) { } catch (e) {
link = new St.Label({ text: '<error>' }); link = new St.Label({ text: '<error>' });
} }
@@ -433,17 +421,17 @@ class ObjInspector extends St.ScrollView {
return; return;
this._previousObj = null; this._previousObj = null;
this._open = true; this._open = true;
this.show(); this.actor.show();
if (sourceActor) { if (sourceActor) {
this.set_scale(0, 0); this.actor.set_scale(0, 0);
this.ease({ this.actor.ease({
scale_x: 1, scale_x: 1,
scale_y: 1, scale_y: 1,
mode: Clutter.AnimationMode.EASE_OUT_QUAD, mode: Clutter.AnimationMode.EASE_OUT_QUAD,
duration: 200 time: 200
}); });
} else { } else {
this.set_scale(1, 1); this.actor.set_scale(1, 1);
} }
} }
@@ -451,7 +439,7 @@ class ObjInspector extends St.ScrollView {
if (!this._open) if (!this._open)
return; return;
this._open = false; this._open = false;
this.hide(); this.actor.hide();
this._previousObj = null; this._previousObj = null;
this._obj = null; this._obj = null;
} }
@@ -465,7 +453,7 @@ class ObjInspector extends St.ScrollView {
_onBack() { _onBack() {
this.selectObject(this._previousObj, true); this.selectObject(this._previousObj, true);
} }
}); };
var RedBorderEffect = GObject.registerClass( var RedBorderEffect = GObject.registerClass(
class RedBorderEffect extends Clutter.Effect { class RedBorderEffect extends Clutter.Effect {
@@ -477,16 +465,16 @@ class RedBorderEffect extends Clutter.Effect {
color.init_from_4ub(0xff, 0, 0, 0xc4); color.init_from_4ub(0xff, 0, 0, 0xc4);
Cogl.set_source_color(color); Cogl.set_source_color(color);
let alloc = actor.get_allocation_box(); let geom = actor.get_allocation_geometry();
let width = 2; let width = 2;
// clockwise order // clockwise order
Cogl.rectangle(0, 0, alloc.get_width(), width); Cogl.rectangle(0, 0, geom.width, width);
Cogl.rectangle(alloc.get_width() - width, width, Cogl.rectangle(geom.width - width, width,
alloc.get_width(), alloc.get_height()); geom.width, geom.height);
Cogl.rectangle(0, alloc.get_height(), Cogl.rectangle(0, geom.height,
alloc.get_width() - width, alloc.get_height() - width); geom.width - width, geom.height - width);
Cogl.rectangle(0, alloc.get_height() - width, Cogl.rectangle(0, geom.height - width,
width, width); width, width);
} }
}); });
@@ -496,7 +484,8 @@ var Inspector = GObject.registerClass({
'target': { param_types: [Clutter.Actor.$gtype, GObject.TYPE_DOUBLE, GObject.TYPE_DOUBLE] } }, 'target': { param_types: [Clutter.Actor.$gtype, GObject.TYPE_DOUBLE, GObject.TYPE_DOUBLE] } },
}, class Inspector extends Clutter.Actor { }, class Inspector extends Clutter.Actor {
_init(lookingGlass) { _init(lookingGlass) {
super._init({ width: 0, height: 0 }); super._init({ width: 0,
height: 0 });
Main.uiGroup.add_actor(this); Main.uiGroup.add_actor(this);
@@ -631,20 +620,18 @@ var Inspector = GObject.registerClass({
} }
}); });
var Extensions = GObject.registerClass({ var Extensions = class Extensions {
GTypeName: 'LookingClass_Extensions' constructor(lookingGlass) {
}, class Extensions extends St.BoxLayout {
_init(lookingGlass) {
super._init({ vertical: true, name: 'lookingGlassExtensions' });
this._lookingGlass = lookingGlass; this._lookingGlass = lookingGlass;
this.actor = new St.BoxLayout({ vertical: true,
name: 'lookingGlassExtensions' });
this._noExtensions = new St.Label({ style_class: 'lg-extensions-none', this._noExtensions = new St.Label({ style_class: 'lg-extensions-none',
text: _("No extensions installed") }); text: _("No extensions installed") });
this._numExtensions = 0; this._numExtensions = 0;
this._extensionsList = new St.BoxLayout({ vertical: true, this._extensionsList = new St.BoxLayout({ vertical: true,
style_class: 'lg-extensions-list' }); style_class: 'lg-extensions-list' });
this._extensionsList.add(this._noExtensions); this._extensionsList.add(this._noExtensions);
this.add(this._extensionsList); this.actor.add(this._extensionsList);
Main.extensionManager.getUuids().forEach(uuid => { Main.extensionManager.getUuids().forEach(uuid => {
this._loadExtension(null, uuid); this._loadExtension(null, uuid);
@@ -772,19 +759,10 @@ var Extensions = GObject.registerClass({
return box; return box;
} }
}); };
var LookingGlass = GObject.registerClass(
class LookingGlass extends St.BoxLayout {
_init() {
super._init({
name: 'LookingGlassDialog',
style_class: 'lg-dialog',
vertical: true,
visible: false,
reactive: true
});
var LookingGlass = class LookingGlass {
constructor() {
this._borderPaintTarget = null; this._borderPaintTarget = null;
this._redBorderEffect = new RedBorderEffect(); this._redBorderEffect = new RedBorderEffect();
@@ -792,18 +770,26 @@ class LookingGlass extends St.BoxLayout {
this._it = null; this._it = null;
this._offset = 0; this._offset = 0;
this._results = [];
// Sort of magic, but...eh. // Sort of magic, but...eh.
this._maxItems = 150; this._maxItems = 150;
this.actor = new St.BoxLayout({ name: 'LookingGlassDialog',
style_class: 'lg-dialog',
vertical: true,
visible: false,
reactive: true });
this.actor.connect('key-press-event', this._globalKeyPressEvent.bind(this));
this._interfaceSettings = new Gio.Settings({ schema_id: 'org.gnome.desktop.interface' }); this._interfaceSettings = new Gio.Settings({ schema_id: 'org.gnome.desktop.interface' });
this._interfaceSettings.connect('changed::monospace-font-name', this._interfaceSettings.connect('changed::monospace-font-name',
this._updateFont.bind(this)); this._updateFont.bind(this));
this._updateFont(); this._updateFont();
// We want it to appear to slide out from underneath the panel // We want it to appear to slide out from underneath the panel
Main.uiGroup.add_actor(this); Main.uiGroup.add_actor(this.actor);
Main.uiGroup.set_child_below_sibling(this, Main.uiGroup.set_child_below_sibling(this.actor,
Main.layoutManager.panelBox); Main.layoutManager.panelBox);
Main.layoutManager.panelBox.connect('allocation-changed', Main.layoutManager.panelBox.connect('allocation-changed',
this._queueResize.bind(this)); this._queueResize.bind(this));
@@ -811,11 +797,11 @@ class LookingGlass extends St.BoxLayout {
this._queueResize.bind(this)); this._queueResize.bind(this));
this._objInspector = new ObjInspector(this); this._objInspector = new ObjInspector(this);
Main.uiGroup.add_actor(this._objInspector); Main.uiGroup.add_actor(this._objInspector.actor);
this._objInspector.hide(); this._objInspector.actor.hide();
let toolbar = new St.BoxLayout({ name: 'Toolbar' }); let toolbar = new St.BoxLayout({ name: 'Toolbar' });
this.add_actor(toolbar); this.actor.add_actor(toolbar);
let inspectIcon = new St.Icon({ icon_name: 'gtk-color-picker', let inspectIcon = new St.Icon({ icon_name: 'gtk-color-picker',
icon_size: 24 }); icon_size: 24 });
toolbar.add_actor(inspectIcon); toolbar.add_actor(inspectIcon);
@@ -826,10 +812,10 @@ class LookingGlass extends St.BoxLayout {
this._pushResult(`inspect(${Math.round(stageX)}, ${Math.round(stageY)})`, target); this._pushResult(`inspect(${Math.round(stageX)}, ${Math.round(stageY)})`, target);
}); });
inspector.connect('closed', () => { inspector.connect('closed', () => {
this.show(); this.actor.show();
global.stage.set_key_focus(this._entry); global.stage.set_key_focus(this._entry);
}); });
this.hide(); this.actor.hide();
return Clutter.EVENT_STOP; return Clutter.EVENT_STOP;
}); });
@@ -851,7 +837,7 @@ class LookingGlass extends St.BoxLayout {
let notebook = new Notebook(); let notebook = new Notebook();
this._notebook = notebook; this._notebook = notebook;
this.add(notebook, { expand: true }); this.actor.add(notebook.actor, { expand: true });
let emptyBox = new St.Bin(); let emptyBox = new St.Bin();
toolbar.add(emptyBox, { expand: true }); toolbar.add(emptyBox, { expand: true });
@@ -874,10 +860,10 @@ class LookingGlass extends St.BoxLayout {
this._entryArea.add(this._entry, { expand: true }); this._entryArea.add(this._entry, { expand: true });
this._windowList = new WindowList(this); this._windowList = new WindowList(this);
notebook.appendPage('Windows', this._windowList); notebook.appendPage('Windows', this._windowList.actor);
this._extensions = new Extensions(this); this._extensions = new Extensions(this);
notebook.appendPage('Extensions', this._extensions); notebook.appendPage('Extensions', this._extensions.actor);
this._entry.clutter_text.connect('activate', (o, _e) => { this._entry.clutter_text.connect('activate', (o, _e) => {
// Hide any completions we are currently showing // Hide any completions we are currently showing
@@ -919,7 +905,7 @@ class LookingGlass extends St.BoxLayout {
// monospace font to be bold/oblique/etc. Could easily be added here. // monospace font to be bold/oblique/etc. Could easily be added here.
let size = fontDesc.get_size() / 1024.; let size = fontDesc.get_size() / 1024.;
let unit = fontDesc.get_size_is_absolute() ? 'px' : 'pt'; let unit = fontDesc.get_size_is_absolute() ? 'px' : 'pt';
this.style = ` this.actor.style = `
font-size: ${size}${unit}; font-size: ${size}${unit};
font-family: "${fontDesc.get_family()}";`; font-family: "${fontDesc.get_family()}";`;
} }
@@ -933,14 +919,17 @@ class LookingGlass extends St.BoxLayout {
} }
_pushResult(command, obj) { _pushResult(command, obj) {
let index = this._resultsArea.get_n_children() + this._offset; let index = this._results.length + this._offset;
let result = new Result(this, CHEVRON + command, obj, index); let result = new Result(this, CHEVRON + command, obj, index);
this._resultsArea.add(result); this._results.push(result);
this._resultsArea.add(result.actor);
if (obj instanceof Clutter.Actor) if (obj instanceof Clutter.Actor)
this.setBorderPaintTarget(obj); this.setBorderPaintTarget(obj);
if (this._resultsArea.get_n_children() > this._maxItems) { let children = this._resultsArea.get_children();
this._resultsArea.get_first_child().destroy(); if (children.length > this._maxItems) {
this._results.shift();
children[0].destroy();
this._offset++; this._offset++;
} }
this._it = obj; this._it = obj;
@@ -1027,7 +1016,7 @@ class LookingGlass extends St.BoxLayout {
getResult(idx) { getResult(idx) {
try { try {
return this._resultsArea.get_child_at_index(idx - this._offset).o; return this._results[idx - this._offset].o;
} catch (e) { } catch (e) {
throw new Error(`Unknown result at index ${idx}`); throw new Error(`Unknown result at index ${idx}`);
} }
@@ -1052,15 +1041,15 @@ class LookingGlass extends St.BoxLayout {
let myWidth = primary.width * 0.7; let myWidth = primary.width * 0.7;
let availableHeight = primary.height - Main.layoutManager.keyboardBox.height; let availableHeight = primary.height - Main.layoutManager.keyboardBox.height;
let myHeight = Math.min(primary.height * 0.7, availableHeight * 0.9); let myHeight = Math.min(primary.height * 0.7, availableHeight * 0.9);
this.x = primary.x + (primary.width - myWidth) / 2; this.actor.x = primary.x + (primary.width - myWidth) / 2;
this._hiddenY = primary.y + Main.layoutManager.panelBox.height - myHeight; this._hiddenY = primary.y + Main.layoutManager.panelBox.height - myHeight;
this._targetY = this._hiddenY + myHeight; this._targetY = this._hiddenY + myHeight;
this.y = this._hiddenY; this.actor.y = this._hiddenY;
this.width = myWidth; this.actor.width = myWidth;
this.height = myHeight; this.actor.height = myHeight;
this._objInspector.set_size(Math.floor(myWidth * 0.8), Math.floor(myHeight * 0.8)); this._objInspector.actor.set_size(Math.floor(myWidth * 0.8), Math.floor(myHeight * 0.8));
this._objInspector.set_position(this.x + Math.floor(myWidth * 0.1), this._objInspector.actor.set_position(this.actor.x + Math.floor(myWidth * 0.1),
this._targetY + Math.floor(myHeight * 0.1)); this._targetY + Math.floor(myHeight * 0.1));
} }
insertObject(obj) { insertObject(obj) {
@@ -1073,10 +1062,11 @@ class LookingGlass extends St.BoxLayout {
} }
// Handle key events which are relevant for all tabs of the LookingGlass // Handle key events which are relevant for all tabs of the LookingGlass
vfunc_key_press_event(keyPressEvent) { _globalKeyPressEvent(actor, event) {
let symbol = keyPressEvent.keyval; let symbol = event.get_key_symbol();
let modifierState = event.get_state();
if (symbol == Clutter.Escape) { if (symbol == Clutter.Escape) {
if (this._objInspector.visible) { if (this._objInspector.actor.visible) {
this._objInspector.close(); this._objInspector.close();
} else { } else {
this.close(); this.close();
@@ -1084,7 +1074,7 @@ class LookingGlass extends St.BoxLayout {
return Clutter.EVENT_STOP; return Clutter.EVENT_STOP;
} }
// Ctrl+PgUp and Ctrl+PgDown switches tabs in the notebook view // Ctrl+PgUp and Ctrl+PgDown switches tabs in the notebook view
if (keyPressEvent.modifier_state & Clutter.ModifierType.CONTROL_MASK) { if (modifierState & Clutter.ModifierType.CONTROL_MASK) {
if (symbol == Clutter.KEY_Page_Up) { if (symbol == Clutter.KEY_Page_Up) {
this._notebook.prevTab(); this._notebook.prevTab();
} else if (symbol == Clutter.KEY_Page_Down) { } else if (symbol == Clutter.KEY_Page_Down) {
@@ -1102,16 +1092,16 @@ class LookingGlass extends St.BoxLayout {
return; return;
this._notebook.selectIndex(0); this._notebook.selectIndex(0);
this.show(); this.actor.show();
this._open = true; this._open = true;
this._history.lastItem(); this._history.lastItem();
this.remove_all_transitions(); this.actor.remove_all_transitions();
// We inverse compensate for the slow-down so you can change the factor // We inverse compensate for the slow-down so you can change the factor
// through LookingGlass without long waits. // through LookingGlass without long waits.
let duration = LG_ANIMATION_TIME / St.Settings.get().slow_down_factor; let duration = LG_ANIMATION_TIME / St.Settings.get().slow_down_factor;
this.ease({ this.actor.ease({
y: this._targetY, y: this._targetY,
duration, duration,
mode: Clutter.AnimationMode.EASE_OUT_QUAD mode: Clutter.AnimationMode.EASE_OUT_QUAD
@@ -1124,10 +1114,10 @@ class LookingGlass extends St.BoxLayout {
if (!this._open) if (!this._open)
return; return;
this._objInspector.hide(); this._objInspector.actor.hide();
this._open = false; this._open = false;
this.remove_all_transitions(); this.actor.remove_all_transitions();
this.setBorderPaintTarget(null); this.setBorderPaintTarget(null);
@@ -1136,15 +1126,16 @@ class LookingGlass extends St.BoxLayout {
let settings = St.Settings.get(); let settings = St.Settings.get();
let duration = Math.min(LG_ANIMATION_TIME / settings.slow_down_factor, let duration = Math.min(LG_ANIMATION_TIME / settings.slow_down_factor,
LG_ANIMATION_TIME); LG_ANIMATION_TIME);
this.ease({ this.actor.ease({
y: this._hiddenY, y: this._hiddenY,
duration, duration,
mode: Clutter.AnimationMode.EASE_OUT_QUAD, mode: Clutter.AnimationMode.EASE_OUT_QUAD,
onComplete: () => this.hide() onComplete: () => this.actor.hide()
}); });
} }
get isOpen() { get isOpen() {
return this._open; return this._open;
} }
}); };
Signals.addSignalMethods(LookingGlass.prototype);

View File

@@ -1290,7 +1290,7 @@ var ZoomRegion = class ZoomRegion {
// Add a background for when the magnified uiGroup is scrolled // Add a background for when the magnified uiGroup is scrolled
// out of view (don't want to see desktop showing through). // out of view (don't want to see desktop showing through).
this._background = new Background.SystemBackground(); this._background = (new Background.SystemBackground()).actor;
mainGroup.add_actor(this._background); mainGroup.add_actor(this._background);
// Clone the group that contains all of UI on the screen. This is the // Clone the group that contains all of UI on the screen. This is the
@@ -1587,9 +1587,8 @@ var ZoomRegion = class ZoomRegion {
} }
}; };
var Crosshairs = GObject.registerClass( var Crosshairs = class Crosshairs {
class Crosshairs extends Clutter.Actor { constructor() {
_init() {
// Set the group containing the crosshairs to three times the desktop // Set the group containing the crosshairs to three times the desktop
// size in case the crosshairs need to appear to be infinite in // size in case the crosshairs need to appear to be infinite in
@@ -1597,7 +1596,7 @@ class Crosshairs extends Clutter.Actor {
let groupWidth = global.screen_width * 3; let groupWidth = global.screen_width * 3;
let groupHeight = global.screen_height * 3; let groupHeight = global.screen_height * 3;
super._init({ this._actor = new Clutter.Actor({
clip_to_allocation: false, clip_to_allocation: false,
width: groupWidth, width: groupWidth,
height: groupHeight height: groupHeight
@@ -1606,10 +1605,10 @@ class Crosshairs extends Clutter.Actor {
this._horizRightHair = new Clutter.Actor(); this._horizRightHair = new Clutter.Actor();
this._vertTopHair = new Clutter.Actor(); this._vertTopHair = new Clutter.Actor();
this._vertBottomHair = new Clutter.Actor(); this._vertBottomHair = new Clutter.Actor();
this.add_actor(this._horizLeftHair); this._actor.add_actor(this._horizLeftHair);
this.add_actor(this._horizRightHair); this._actor.add_actor(this._horizRightHair);
this.add_actor(this._vertTopHair); this._actor.add_actor(this._vertTopHair);
this.add_actor(this._vertBottomHair); this._actor.add_actor(this._vertBottomHair);
this._clipSize = [0, 0]; this._clipSize = [0, 0];
this._clones = []; this._clones = [];
this.reCenter(); this.reCenter();
@@ -1619,7 +1618,7 @@ class Crosshairs extends Clutter.Actor {
} }
_monitorsChanged() { _monitorsChanged() {
this.set_size(global.screen_width * 3, global.screen_height * 3); this._actor.set_size(global.screen_width * 3, global.screen_height * 3);
this.reCenter(); this.reCenter();
} }
@@ -1640,15 +1639,12 @@ class Crosshairs extends Clutter.Actor {
if (zoomRegion && magnifiedMouse) { if (zoomRegion && magnifiedMouse) {
let container = magnifiedMouse.get_parent(); let container = magnifiedMouse.get_parent();
if (container) { if (container) {
crosshairsActor = this; crosshairsActor = this._actor;
if (this.get_parent() != null) { if (this._actor.get_parent() != null) {
crosshairsActor = new Clutter.Clone({ source: this }); crosshairsActor = new Clutter.Clone({ source: this._actor });
this._clones.push(crosshairsActor); this._clones.push(crosshairsActor);
// Clones don't share visibility.
this.bind_property('visible', crosshairsActor, 'visible',
GObject.BindingFlags.SYNC_CREATE);
} }
crosshairsActor.visible = this._actor.visible;
container.add_actor(crosshairsActor); container.add_actor(crosshairsActor);
container.raise_child(magnifiedMouse, crosshairsActor); container.raise_child(magnifiedMouse, crosshairsActor);
@@ -1667,7 +1663,7 @@ class Crosshairs extends Clutter.Actor {
* child actor if it was just a clone of the crosshairs actor. * child actor if it was just a clone of the crosshairs actor.
*/ */
removeFromParent(childActor) { removeFromParent(childActor) {
if (childActor == this) if (childActor == this._actor)
childActor.get_parent().remove_actor(childActor); childActor.get_parent().remove_actor(childActor);
else else
childActor.destroy(); childActor.destroy();
@@ -1777,6 +1773,28 @@ class Crosshairs extends Clutter.Actor {
} }
} }
/**
* show:
* Show the crosshairs.
*/
show() {
this._actor.show();
// Clones don't share visibility.
for (let i = 0; i < this._clones.length; i++)
this._clones[i].show();
}
/**
* hide:
* Hide the crosshairs.
*/
hide() {
this._actor.hide();
// Clones don't share visibility.
for (let i = 0; i < this._clones.length; i++)
this._clones[i].hide();
}
/** /**
* reCenter: * reCenter:
* Reposition the horizontal and vertical hairs such that they cross at * Reposition the horizontal and vertical hairs such that they cross at
@@ -1785,7 +1803,7 @@ class Crosshairs extends Clutter.Actor {
* @clipSize: Optional. If present, an array of the form [width, height]. * @clipSize: Optional. If present, an array of the form [width, height].
*/ */
reCenter(clipSize) { reCenter(clipSize) {
let [groupWidth, groupHeight] = this.get_size(); let [groupWidth, groupHeight] = this._actor.get_size();
let leftLength = this._horizLeftHair.get_width(); let leftLength = this._horizLeftHair.get_width();
let topLength = this._vertTopHair.get_height(); let topLength = this._vertTopHair.get_height();
let thickness = this._horizLeftHair.get_height(); let thickness = this._horizLeftHair.get_height();
@@ -1807,7 +1825,7 @@ class Crosshairs extends Clutter.Actor {
this._vertTopHair.set_position((groupWidth - thickness) / 2, top); this._vertTopHair.set_position((groupWidth - thickness) / 2, top);
this._vertBottomHair.set_position((groupWidth - thickness) / 2, bottom); this._vertBottomHair.set_position((groupWidth - thickness) / 2, bottom);
} }
}); };
var MagShaderEffects = class MagShaderEffects { var MagShaderEffects = class MagShaderEffects {
constructor(uiGroupClone) { constructor(uiGroupClone) {

View File

@@ -189,7 +189,7 @@ function _initializeUI() {
messageTray = new MessageTray.MessageTray(); messageTray = new MessageTray.MessageTray();
panel = new Panel.Panel(); panel = new Panel.Panel();
keyboard = new Keyboard.KeyboardManager(); keyboard = new Keyboard.Keyboard();
notificationDaemon = new NotificationDaemon.NotificationDaemon(); notificationDaemon = new NotificationDaemon.NotificationDaemon();
windowAttentionHandler = new WindowAttentionHandler.WindowAttentionHandler(); windowAttentionHandler = new WindowAttentionHandler.WindowAttentionHandler();
componentManager = new Components.ComponentManager(); componentManager = new Components.ComponentManager();
@@ -262,19 +262,6 @@ function _initializeUI() {
}); });
} }
let credentials = new Gio.Credentials();
if (credentials.get_unix_user() === 0) {
notify(_('Logged in as a privileged user'),
_('Running a session as a privileged user should be avoided for security reasons. If possible, you should log in as a normal user.'));
}
if (sessionMode.currentMode !== 'gdm' &&
sessionMode.currentMode !== 'initial-setup' &&
screenShield === null) {
notify(_('Screen Lock disabled'),
_('Screen Locking requires the GNOME display manager.'));
}
LoginManager.registerSessionWithGDM(); LoginManager.registerSessionWithGDM();
let perfModuleName = GLib.getenv("SHELL_PERF_MODULE"); let perfModuleName = GLib.getenv("SHELL_PERF_MODULE");
@@ -403,7 +390,7 @@ function notify(msg, details) {
messageTray.add(source); messageTray.add(source);
let notification = new MessageTray.Notification(source, msg, details); let notification = new MessageTray.Notification(source, msg, details);
notification.setTransient(true); notification.setTransient(true);
source.showNotification(notification); source.notify(notification);
} }
/** /**

View File

@@ -1,8 +1,7 @@
/* exported MessageListSection */ const { Atk, Clutter, Gio, GLib, GObject, Meta, Pango, St } = imports.gi;
const { Atk, Clutter, Gio, GLib,
GObject, Graphene, Meta, Pango, St } = imports.gi;
const Main = imports.ui.main; const Main = imports.ui.main;
const MessageTray = imports.ui.messageTray; const MessageTray = imports.ui.messageTray;
const Signals = imports.signals;
const Calendar = imports.ui.calendar; const Calendar = imports.ui.calendar;
const Util = imports.misc.util; const Util = imports.misc.util;
@@ -32,18 +31,13 @@ function _fixMarkup(text, allowMarkup) {
return GLib.markup_escape_text(text, -1); return GLib.markup_escape_text(text, -1);
} }
var URLHighlighter = GObject.registerClass( var URLHighlighter = class URLHighlighter {
class URLHighlighter extends St.Label { constructor(text = '', lineWrap, allowMarkup) {
_init(text = '', lineWrap, allowMarkup) { this.actor = new St.Label({ reactive: true, style_class: 'url-highlighter',
super._init({ x_expand: true, x_align: Clutter.ActorAlign.START });
reactive: true,
style_class: 'url-highlighter',
x_expand: true,
x_align: Clutter.ActorAlign.START
});
this._linkColor = '#ccccff'; this._linkColor = '#ccccff';
this.connect('style-changed', () => { this.actor.connect('style-changed', () => {
let [hasColor, color] = this.get_theme_node().lookup_color('link-color', false); let [hasColor, color] = this.actor.get_theme_node().lookup_color('link-color', false);
if (hasColor) { if (hasColor) {
let linkColor = color.to_string().substr(0, 7); let linkColor = color.to_string().substr(0, 7);
if (linkColor != this._linkColor) { if (linkColor != this._linkColor) {
@@ -52,75 +46,70 @@ class URLHighlighter extends St.Label {
} }
} }
}); });
this.clutter_text.line_wrap = lineWrap; this.actor.clutter_text.line_wrap = lineWrap;
this.clutter_text.line_wrap_mode = Pango.WrapMode.WORD_CHAR; this.actor.clutter_text.line_wrap_mode = Pango.WrapMode.WORD_CHAR;
this.setMarkup(text, allowMarkup); this.setMarkup(text, allowMarkup);
} this.actor.connect('button-press-event', (actor, event) => {
// Don't try to URL highlight when invisible.
// The MessageTray doesn't actually hide us, so
// we need to check for paint opacities as well.
if (!actor.visible || actor.get_paint_opacity() == 0)
return Clutter.EVENT_PROPAGATE;
vfunc_button_press_event(buttonEvent) { // Keep Notification.actor from seeing this and taking
// Don't try to URL highlight when invisible. // a pointer grab, which would block our button-release-event
// The MessageTray doesn't actually hide us, so // handler, if an URL is clicked
// we need to check for paint opacities as well. return this._findUrlAtPos(event) != -1;
if (!this.visible || this.get_paint_opacity() == 0) });
this.actor.connect('button-release-event', (actor, event) => {
if (!actor.visible || actor.get_paint_opacity() == 0)
return Clutter.EVENT_PROPAGATE;
let urlId = this._findUrlAtPos(event);
if (urlId != -1) {
let url = this._urls[urlId].url;
if (!url.includes(':'))
url = 'http://' + url;
Gio.app_info_launch_default_for_uri(url, global.create_app_launch_context(0, -1));
return Clutter.EVENT_STOP;
}
return Clutter.EVENT_PROPAGATE; return Clutter.EVENT_PROPAGATE;
});
this.actor.connect('motion-event', (actor, event) => {
if (!actor.visible || actor.get_paint_opacity() == 0)
return Clutter.EVENT_PROPAGATE;
// Keep Notification from seeing this and taking let urlId = this._findUrlAtPos(event);
// a pointer grab, which would block our button-release-event if (urlId != -1 && !this._cursorChanged) {
// handler, if an URL is clicked global.display.set_cursor(Meta.Cursor.POINTING_HAND);
return this._findUrlAtPos(buttonEvent) != -1; this._cursorChanged = true;
} } else if (urlId == -1) {
global.display.set_cursor(Meta.Cursor.DEFAULT);
vfunc_button_release_event(buttonEvent) { this._cursorChanged = false;
if (!this.visible || this.get_paint_opacity() == 0) }
return Clutter.EVENT_PROPAGATE; return Clutter.EVENT_PROPAGATE;
});
this.actor.connect('leave-event', () => {
if (!this.actor.visible || this.actor.get_paint_opacity() == 0)
return Clutter.EVENT_PROPAGATE;
let urlId = this._findUrlAtPos(buttonEvent); if (this._cursorChanged) {
if (urlId != -1) { this._cursorChanged = false;
let url = this._urls[urlId].url; global.display.set_cursor(Meta.Cursor.DEFAULT);
if (!url.includes(':')) }
url = 'http://' + url;
Gio.app_info_launch_default_for_uri(
url, global.create_app_launch_context(0, -1));
return Clutter.EVENT_STOP;
}
return Clutter.EVENT_PROPAGATE;
}
vfunc_motion_event(motionEvent) {
if (!this.visible || this.get_paint_opacity() == 0)
return Clutter.EVENT_PROPAGATE; return Clutter.EVENT_PROPAGATE;
});
let urlId = this._findUrlAtPos(motionEvent);
if (urlId != -1 && !this._cursorChanged) {
global.display.set_cursor(Meta.Cursor.POINTING_HAND);
this._cursorChanged = true;
} else if (urlId == -1) {
global.display.set_cursor(Meta.Cursor.DEFAULT);
this._cursorChanged = false;
}
return Clutter.EVENT_PROPAGATE;
}
vfunc_leave_event(crossingEvent) {
if (!this.visible || this.get_paint_opacity() == 0)
return Clutter.EVENT_PROPAGATE;
if (this._cursorChanged) {
this._cursorChanged = false;
global.display.set_cursor(Meta.Cursor.DEFAULT);
}
return super.vfunc_leave_event(crossingEvent);
} }
setMarkup(text, allowMarkup) { setMarkup(text, allowMarkup) {
text = text ? _fixMarkup(text, allowMarkup) : ''; text = text ? _fixMarkup(text, allowMarkup) : '';
this._text = text; this._text = text;
this.clutter_text.set_markup(text); this.actor.clutter_text.set_markup(text);
/* clutter_text.text contain text without markup */ /* clutter_text.text contain text without markup */
this._urls = Util.findUrls(this.clutter_text.text); this._urls = Util.findUrls(this.actor.clutter_text.text);
this._highlightUrls(); this._highlightUrls();
} }
@@ -136,15 +125,16 @@ class URLHighlighter extends St.Label {
pos = url.pos + url.url.length; pos = url.pos + url.url.length;
} }
markup += this._text.substr(pos); markup += this._text.substr(pos);
this.clutter_text.set_markup(markup); this.actor.clutter_text.set_markup(markup);
} }
_findUrlAtPos(event) { _findUrlAtPos(event) {
let { x, y } = event; let success_;
[, x, y] = this.transform_stage_point(x, y); let [x, y] = event.get_coords();
[success_, x, y] = this.actor.transform_stage_point(x, y);
let findPos = -1; let findPos = -1;
for (let i = 0; i < this.clutter_text.text.length; i++) { for (let i = 0; i < this.actor.clutter_text.text.length; i++) {
let [, px, py, lineHeight] = this.clutter_text.position_to_coords(i); let [success_, px, py, lineHeight] = this.actor.clutter_text.position_to_coords(i);
if (py > y || py + lineHeight < y || x < px) if (py > y || py + lineHeight < y || x < px)
continue; continue;
findPos = i; findPos = i;
@@ -157,7 +147,7 @@ class URLHighlighter extends St.Label {
} }
return -1; return -1;
} }
}); };
var ScaleLayout = GObject.registerClass( var ScaleLayout = GObject.registerClass(
class ScaleLayout extends Clutter.BinLayout { class ScaleLayout extends Clutter.BinLayout {
@@ -293,29 +283,21 @@ var LabelExpanderLayout = GObject.registerClass({
} }
}); });
var Message = class Message {
var Message = GObject.registerClass({ constructor(title, body) {
GTypeName: 'MessageList_Message',
Signals: {
'close': {},
'expanded': {},
'unexpanded': {},
}
}, class Message extends St.Button {
_init(title, body) {
super._init({
style_class: 'message',
accessible_role: Atk.Role.NOTIFICATION,
can_focus: true,
x_expand: true,
x_fill: true
});
this.expanded = false; this.expanded = false;
this._useBodyMarkup = false; this._useBodyMarkup = false;
this.actor = new St.Button({ style_class: 'message',
accessible_role: Atk.Role.NOTIFICATION,
can_focus: true,
x_expand: true, x_fill: true });
this.actor.connect('key-press-event',
this._onKeyPressed.bind(this));
let vbox = new St.BoxLayout({ vertical: true }); let vbox = new St.BoxLayout({ vertical: true });
this.set_child(vbox); this.actor.set_child(vbox);
let hbox = new St.BoxLayout(); let hbox = new St.BoxLayout();
vbox.add_actor(hbox); vbox.add_actor(hbox);
@@ -359,14 +341,15 @@ var Message = GObject.registerClass({
contentBox.add_actor(this._bodyStack); contentBox.add_actor(this._bodyStack);
this.bodyLabel = new URLHighlighter('', false, this._useBodyMarkup); this.bodyLabel = new URLHighlighter('', false, this._useBodyMarkup);
this.bodyLabel.add_style_class_name('message-body'); this.bodyLabel.actor.add_style_class_name('message-body');
this._bodyStack.add_actor(this.bodyLabel); this._bodyStack.add_actor(this.bodyLabel.actor);
this.setBody(body); this.setBody(body);
this._closeButton.connect('clicked', this.close.bind(this)); this._closeButton.connect('clicked', this.close.bind(this));
let actorHoverId = this.connect('notify::hover', this._sync.bind(this)); let actorHoverId = this.actor.connect('notify::hover', this._sync.bind(this));
this._closeButton.connect('destroy', this.disconnect.bind(this, actorHoverId)); this._closeButton.connect('destroy', this.actor.disconnect.bind(this.actor, actorHoverId));
this.connect('destroy', this._onDestroy.bind(this)); this.actor.connect('clicked', this._onClicked.bind(this));
this.actor.connect('destroy', this._onDestroy.bind(this));
this._sync(); this._sync();
} }
@@ -452,7 +435,7 @@ var Message = GObject.registerClass({
if (this._bodyStack.get_n_children() < 2) { if (this._bodyStack.get_n_children() < 2) {
this._expandedLabel = new URLHighlighter(this._bodyText, this._expandedLabel = new URLHighlighter(this._bodyText,
true, this._useBodyMarkup); true, this._useBodyMarkup);
this.setExpandedBody(this._expandedLabel); this.setExpandedBody(this._expandedLabel.actor);
} }
if (animate) { if (animate) {
@@ -505,16 +488,19 @@ var Message = GObject.registerClass({
} }
_sync() { _sync() {
let visible = this.hover && this.canClose(); let visible = this.actor.hover && this.canClose();
this._closeButton.opacity = visible ? 255 : 0; this._closeButton.opacity = visible ? 255 : 0;
this._closeButton.reactive = visible; this._closeButton.reactive = visible;
} }
_onClicked() {
}
_onDestroy() { _onDestroy() {
} }
vfunc_key_press_event(keyEvent) { _onKeyPressed(a, event) {
let keysym = keyEvent.keyval; let keysym = event.get_key_symbol();
if (keysym == Clutter.KEY_Delete || if (keysym == Clutter.KEY_Delete ||
keysym == Clutter.KEY_KP_Delete) { keysym == Clutter.KEY_KP_Delete) {
@@ -523,66 +509,37 @@ var Message = GObject.registerClass({
} }
return Clutter.EVENT_PROPAGATE; return Clutter.EVENT_PROPAGATE;
} }
}); };
Signals.addSignalMethods(Message.prototype);
var MessageListSection = GObject.registerClass({ var MessageListSection = class MessageListSection {
Properties: { constructor() {
'can-clear': GObject.ParamSpec.boolean( this.actor = new St.BoxLayout({ style_class: 'message-list-section',
'can-clear', 'can-clear', 'can-clear', clip_to_allocation: true,
GObject.ParamFlags.READABLE, x_expand: true, vertical: true });
false),
'empty': GObject.ParamSpec.boolean(
'empty', 'empty', 'empty',
GObject.ParamFlags.READABLE,
true),
},
Signals: {
'can-clear-changed': {},
'empty-changed': {},
'message-focused': { param_types: [Message.$gtype] },
}
}, class MessageListSection extends St.BoxLayout {
_init() {
super._init({
style_class: 'message-list-section',
clip_to_allocation: true,
vertical: true,
x_expand: true
});
this._list = new St.BoxLayout({ style_class: 'message-list-section-list', this._list = new St.BoxLayout({ style_class: 'message-list-section-list',
vertical: true }); vertical: true });
this.add_actor(this._list); this.actor.add_actor(this._list);
this._list.connect('actor-added', this._sync.bind(this)); this._list.connect('actor-added', this._sync.bind(this));
this._list.connect('actor-removed', this._sync.bind(this)); this._list.connect('actor-removed', this._sync.bind(this));
let id = Main.sessionMode.connect('updated', let id = Main.sessionMode.connect('updated',
this._sync.bind(this)); this._sync.bind(this));
this.connect('destroy', () => { this.actor.connect('destroy', () => {
Main.sessionMode.disconnect(id); Main.sessionMode.disconnect(id);
}); });
this._messages = new Map();
this._date = new Date(); this._date = new Date();
this._empty = true; this.empty = true;
this._canClear = false; this.canClear = false;
this._sync(); this._sync();
} }
get empty() { _onKeyFocusIn(actor) {
return this._empty; this.emit('key-focus-in', actor);
}
get canClear() {
return this._canClear;
}
get _messages() {
return this._list.get_children().map(i => i.child);
}
_onKeyFocusIn(messageActor) {
this.emit('message-focused', messageActor);
} }
get allowed() { get allowed() {
@@ -601,62 +558,58 @@ var MessageListSection = GObject.registerClass({
} }
addMessageAtIndex(message, index, animate) { addMessageAtIndex(message, index, animate) {
if (this._messages.includes(message)) let obj = {
throw new Error('Message was already added previously'); container: null,
destroyId: 0,
let listItem = new St.Bin({ keyFocusId: 0,
child: message, closeId: 0
x_fill: true, };
y_fill: true, let pivot = new Clutter.Point({ x: .5, y: .5 });
layout_manager: new ScaleLayout(), let scale = animate ? 0 : 1;
pivot_point: new Graphene.Point({ x: .5, y: .5 }), obj.container = new St.Widget({ layout_manager: new ScaleLayout(),
pivot_point: pivot,
scale_x: scale, scale_y: scale });
obj.keyFocusId = message.actor.connect('key-focus-in',
this._onKeyFocusIn.bind(this));
obj.destroyId = message.actor.connect('destroy', () => {
this.removeMessage(message, false);
}); });
listItem._connectionsIds = []; obj.closeId = message.connect('close', () => {
listItem._connectionsIds.push(message.connect('key-focus-in',
this._onKeyFocusIn.bind(this)));
listItem._connectionsIds.push(message.connect('close', () => {
this.removeMessage(message, true); this.removeMessage(message, true);
})); });
listItem._connectionsIds.push(message.connect('destroy', () => {
listItem._connectionsIds.forEach(id => message.disconnect(id));
listItem.destroy();
}));
this._list.insert_child_at_index(listItem, index); this._messages.set(message, obj);
obj.container.add_actor(message.actor);
if (animate) { this._list.insert_child_at_index(obj.container, index);
listItem.set({ scale_x: 0, scale_y: 0 });
listItem.ease({ if (animate)
obj.container.ease({
scale_x: 1, scale_x: 1,
scale_y: 1, scale_y: 1,
duration: MESSAGE_ANIMATION_TIME, duration: MESSAGE_ANIMATION_TIME,
mode: Clutter.AnimationMode.EASE_OUT_QUAD mode: Clutter.AnimationMode.EASE_OUT_QUAD
}); });
}
} }
moveMessage(message, index, animate) { moveMessage(message, index, animate) {
if (!this._messages.includes(message)) let obj = this._messages.get(message);
throw new Error(`Impossible to move the untracked message ${message}`);
let listItem = message.get_parent();
if (!animate) { if (!animate) {
this._list.set_child_at_index(listItem, index); this._list.set_child_at_index(obj.container, index);
return; return;
} }
let onComplete = () => { let onComplete = () => {
this._list.set_child_at_index(listItem, index); this._list.set_child_at_index(obj.container, index);
listItem.ease({ obj.container.ease({
scale_x: 1, scale_x: 1,
scale_y: 1, scale_y: 1,
duration: MESSAGE_ANIMATION_TIME, duration: MESSAGE_ANIMATION_TIME,
mode: Clutter.AnimationMode.EASE_OUT_QUAD mode: Clutter.AnimationMode.EASE_OUT_QUAD
}); });
}; };
listItem.ease({ obj.container.ease({
scale_x: 0, scale_x: 0,
scale_y: 0, scale_y: 0,
duration: MESSAGE_ANIMATION_TIME, duration: MESSAGE_ANIMATION_TIME,
@@ -666,31 +619,33 @@ var MessageListSection = GObject.registerClass({
} }
removeMessage(message, animate) { removeMessage(message, animate) {
if (!this._messages.includes(message)) let obj = this._messages.get(message);
throw new Error(`Impossible to remove the untracked message ${message}`);
let listItem = message.get_parent(); message.actor.disconnect(obj.destroyId);
listItem._connectionsIds.forEach(id => message.disconnect(id)); message.actor.disconnect(obj.keyFocusId);
message.disconnect(obj.closeId);
this._messages.delete(message);
if (animate) { if (animate) {
listItem.ease({ obj.container.ease({
scale_x: 0, scale_x: 0,
scale_y: 0, scale_y: 0,
duration: MESSAGE_ANIMATION_TIME, duration: MESSAGE_ANIMATION_TIME,
mode: Clutter.AnimationMode.EASE_OUT_QUAD, mode: Clutter.AnimationMode.EASE_OUT_QUAD,
onComplete: () => { onComplete: () => {
listItem.destroy(); obj.container.destroy();
global.sync_pointer(); global.sync_pointer();
} }
}); });
} else { } else {
listItem.destroy(); obj.container.destroy();
global.sync_pointer(); global.sync_pointer();
} }
} }
clear() { clear() {
let messages = this._messages.filter(msg => msg.canClose()); let messages = [...this._messages.keys()].filter(msg => msg.canClose());
// If there are few messages, letting them all zoom out looks OK // If there are few messages, letting them all zoom out looks OK
if (messages.length < 2) { if (messages.length < 2) {
@@ -703,8 +658,9 @@ var MessageListSection = GObject.registerClass({
let delay = MESSAGE_ANIMATION_TIME / Math.max(messages.length, 5); let delay = MESSAGE_ANIMATION_TIME / Math.max(messages.length, 5);
for (let i = 0; i < messages.length; i++) { for (let i = 0; i < messages.length; i++) {
let message = messages[i]; let message = messages[i];
message.get_parent().ease({ let obj = this._messages.get(message);
translation_x: this._list.width, obj.container.ease({
anchor_x: this._list.width,
opacity: 0, opacity: 0,
duration: MESSAGE_ANIMATION_TIME, duration: MESSAGE_ANIMATION_TIME,
delay: i * delay, delay: i * delay,
@@ -715,25 +671,33 @@ var MessageListSection = GObject.registerClass({
} }
} }
_canClear() {
for (let message of this._messages.keys())
if (message.canClose())
return true;
return false;
}
_shouldShow() { _shouldShow() {
return !this.empty; return !this.empty;
} }
_sync() { _sync() {
let messages = this._messages; let empty = this._list.get_n_children() == 0;
let empty = messages.length == 0; let changed = this.empty !== empty;
this.empty = empty;
if (this._empty != empty) { if (changed)
this._empty = empty; this.emit('empty-changed');
this.notify('empty');
}
let canClear = messages.some(m => m.canClose()); let canClear = this._canClear();
if (this._canClear != canClear) { changed = this.canClear !== canClear;
this._canClear = canClear; this.canClear = canClear;
this.notify('can-clear');
}
this.visible = this.allowed && this._shouldShow(); if (changed)
this.emit('can-clear-changed');
this.actor.visible = this.allowed && this._shouldShow();
} }
}); };
Signals.addSignalMethods(MessageListSection.prototype);

View File

@@ -4,6 +4,7 @@
SystemNotificationSource, MessageTray */ SystemNotificationSource, MessageTray */
const { Clutter, Gio, GLib, GObject, Meta, Shell, St } = imports.gi; const { Clutter, Gio, GLib, GObject, Meta, Shell, St } = imports.gi;
const Signals = imports.signals;
const Calendar = imports.ui.calendar; const Calendar = imports.ui.calendar;
const GnomeSession = imports.misc.gnomeSession; const GnomeSession = imports.misc.gnomeSession;
@@ -133,84 +134,72 @@ var FocusGrabber = class FocusGrabber {
// source, such as whether to play sound or honour the critical bit. // source, such as whether to play sound or honour the critical bit.
// //
// A notification without a policy object will inherit the default one. // A notification without a policy object will inherit the default one.
var NotificationPolicy = GObject.registerClass({ var NotificationPolicy = class NotificationPolicy {
GTypeName: 'MessageTray_NotificationPolicy', constructor(params) {
Properties: { params = Params.parse(params, {
'enable': GObject.ParamSpec.boolean( enable: true,
'enable', 'enable', 'enable', enableSound: true,
GObject.ParamFlags.READWRITE | GObject.ParamFlags.CONSTRUCT_ONLY, showBanners: true,
true), forceExpanded: false,
'enable-sound': GObject.ParamSpec.boolean( showInLockScreen: true,
'enable-sound', 'enable-sound', 'enable-sound', detailsInLockScreen: false,
GObject.ParamFlags.READWRITE | GObject.ParamFlags.CONSTRUCT_ONLY, });
true), Object.getOwnPropertyNames(params).forEach(key => {
'show-banners': GObject.ParamSpec.boolean( let desc = Object.getOwnPropertyDescriptor(params, key);
'show-banners', 'show-banners', 'show-banners', Object.defineProperty(this, `_${key}`, desc);
GObject.ParamFlags.READWRITE | GObject.ParamFlags.CONSTRUCT_ONLY, });
true),
'force-expanded': GObject.ParamSpec.boolean(
'force-expanded', 'force-expanded', 'force-expanded',
GObject.ParamFlags.READWRITE | GObject.ParamFlags.CONSTRUCT_ONLY,
false),
'show-in-lock-screen': GObject.ParamSpec.boolean(
'show-in-lock-screen', 'show-in-lock-screen', 'show-in-lock-screen',
GObject.ParamFlags.READWRITE | GObject.ParamFlags.CONSTRUCT_ONLY,
false),
'details-in-lock-screen': GObject.ParamSpec.boolean(
'details-in-lock-screen', 'details-in-lock-screen', 'details-in-lock-screen',
GObject.ParamFlags.READWRITE | GObject.ParamFlags.CONSTRUCT_ONLY,
false),
} }
}, class NotificationPolicy extends GObject.Object {
// Do nothing for the default policy. These methods are only useful for the // Do nothing for the default policy. These methods are only useful for the
// GSettings policy. // GSettings policy.
store() { } store() { }
destroy() { destroy() { }
this.run_dispose();
get enable() {
return this._enable;
} }
get enableSound() { get enableSound() {
return this.enable_sound; return this._enableSound;
} }
get showBanners() { get showBanners() {
return this.show_banners; return this._showBanners;
} }
get forceExpanded() { get forceExpanded() {
return this.force_expanded; return this._forceExpanded;
} }
get showInLockScreen() { get showInLockScreen() {
return this.show_in_lock_screen; return this._showInLockScreen;
} }
get detailsInLockScreen() { get detailsInLockScreen() {
return this.details_in_lock_screen; return this._detailsInLockScreen;
} }
}); };
Signals.addSignalMethods(NotificationPolicy.prototype);
var NotificationGenericPolicy = GObject.registerClass({ var NotificationGenericPolicy =
GTypeName: 'MessageTray_NotificationGenericPolicy' class NotificationGenericPolicy extends NotificationPolicy {
}, class NotificationGenericPolicy extends NotificationPolicy { constructor() {
_init() { super();
super._init();
this.id = 'generic'; this.id = 'generic';
this._masterSettings = new Gio.Settings({ schema_id: 'org.gnome.desktop.notifications' }); this._masterSettings = new Gio.Settings({ schema_id: 'org.gnome.desktop.notifications' });
this._masterSettings.connect('changed', this._changed.bind(this)); this._masterSettings.connect('changed', this._changed.bind(this));
} }
store() { }
destroy() { destroy() {
this._masterSettings.run_dispose(); this._masterSettings.run_dispose();
super.destroy();
} }
_changed(settings, key) { _changed(settings, key) {
if (this.constructor.find_property(key)) this.emit('policy-changed', key);
this.notify(key);
} }
get showBanners() { get showBanners() {
@@ -220,13 +209,12 @@ var NotificationGenericPolicy = GObject.registerClass({
get showInLockScreen() { get showInLockScreen() {
return this._masterSettings.get_boolean('show-in-lock-screen'); return this._masterSettings.get_boolean('show-in-lock-screen');
} }
}); };
var NotificationApplicationPolicy = GObject.registerClass({ var NotificationApplicationPolicy =
GTypeName: 'MessageTray_NotificationApplicationPolicy' class NotificationApplicationPolicy extends NotificationPolicy {
}, class NotificationApplicationPolicy extends NotificationPolicy { constructor(id) {
_init(id) { super();
super._init();
this.id = id; this.id = id;
this._canonicalId = this._canonicalizeId(id); this._canonicalId = this._canonicalizeId(id);
@@ -252,13 +240,12 @@ var NotificationApplicationPolicy = GObject.registerClass({
destroy() { destroy() {
this._masterSettings.run_dispose(); this._masterSettings.run_dispose();
this._settings.run_dispose(); this._settings.run_dispose();
super.destroy();
} }
_changed(settings, key) { _changed(settings, key) {
if (this.constructor.find_property(key)) this.emit('policy-changed', key);
this.notify(key); if (key == 'enable')
this.emit('enable-changed');
} }
_canonicalizeId(id) { _canonicalizeId(id) {
@@ -292,7 +279,7 @@ var NotificationApplicationPolicy = GObject.registerClass({
get detailsInLockScreen() { get detailsInLockScreen() {
return this._settings.get_boolean('details-in-lock-screen'); return this._settings.get_boolean('details-in-lock-screen');
} }
}); };
// Notification: // Notification:
// @source: the notification's Source // @source: the notification's Source
@@ -349,26 +336,12 @@ var NotificationApplicationPolicy = GObject.registerClass({
// @source allows playing sounds). // @source allows playing sounds).
// //
// [1] https://developer.gnome.org/notification-spec/#markup // [1] https://developer.gnome.org/notification-spec/#markup
var Notification = GObject.registerClass({ var Notification = class Notification {
GTypeName: 'MessageTray_Notification', constructor(source, title, banner, params) {
Properties: {
'acknowledged': GObject.ParamSpec.boolean(
'acknowledged', 'acknowledged', 'acknowledged',
GObject.ParamFlags.READWRITE,
false),
},
Signals: {
'activated': {},
'destroy': { param_types: [GObject.TYPE_UINT] },
'updated': { param_types: [GObject.TYPE_BOOLEAN] },
}
}, class Notification extends GObject.Object {
_init(source, title, banner, params) {
super._init();
this.source = source; this.source = source;
this.title = title; this.title = title;
this.urgency = Urgency.NORMAL; this.urgency = Urgency.NORMAL;
this.resident = false;
// 'transient' is a reserved keyword in JS, so we have to use an alternate variable name // 'transient' is a reserved keyword in JS, so we have to use an alternate variable name
this.isTransient = false; this.isTransient = false;
this.privacyScope = PrivacyScope.USER; this.privacyScope = PrivacyScope.USER;
@@ -380,7 +353,6 @@ var Notification = GObject.registerClass({
this._soundFile = null; this._soundFile = null;
this._soundPlayed = false; this._soundPlayed = false;
this.actions = []; this.actions = [];
this.setResident(false);
// If called with only one argument we assume the caller // If called with only one argument we assume the caller
// will call .update() later on. This is the case of // will call .update() later on. This is the case of
@@ -450,7 +422,7 @@ var Notification = GObject.registerClass({
if (this._acknowledged == v) if (this._acknowledged == v)
return; return;
this._acknowledged = v; this._acknowledged = v;
this.notify('acknowledged'); this.emit('acknowledged-changed');
} }
setUrgency(urgency) { setUrgency(urgency) {
@@ -459,15 +431,6 @@ var Notification = GObject.registerClass({
setResident(resident) { setResident(resident) {
this.resident = resident; this.resident = resident;
if (this.resident) {
if (this._activatedId) {
this.disconnect(this._activatedId);
this._activatedId = 0;
}
} else if (!this._activatedId) {
this._activatedId = this.connect_after('activated', () => this.destroy());
}
} }
setTransient(isTransient) { setTransient(isTransient) {
@@ -509,30 +472,23 @@ var Notification = GObject.registerClass({
activate() { activate() {
this.emit('activated'); this.emit('activated');
if (!this.resident)
this.destroy();
} }
destroy(reason = NotificationDestroyedReason.DISMISSED) { destroy(reason = NotificationDestroyedReason.DISMISSED) {
if (this._activatedId) {
this.disconnect(this._activatedId);
delete this._activatedId;
}
this.emit('destroy', reason); this.emit('destroy', reason);
this.run_dispose();
} }
}); };
Signals.addSignalMethods(Notification.prototype);
var NotificationBanner = GObject.registerClass({ var NotificationBanner =
Signals: { class NotificationBanner extends Calendar.NotificationMessage {
'done-displaying': {}, constructor(notification) {
'unfocused': {}, super(notification);
}
}, class NotificationBanner extends Calendar.NotificationMessage {
_init(notification) {
super._init(notification);
this.can_focus = false; this.actor.can_focus = false;
this.add_style_class_name('notification-banner'); this.actor.add_style_class_name('notification-banner');
this._buttonBox = null; this._buttonBox = null;
@@ -619,7 +575,7 @@ var NotificationBanner = GObject.registerClass({
return this.addButton(button, callback); return this.addButton(button, callback);
} }
}); };
var SourceActor = GObject.registerClass( var SourceActor = GObject.registerClass(
class SourceActor extends St.Widget { class SourceActor extends St.Widget {
@@ -684,7 +640,7 @@ class SourceActorWithLabel extends SourceActor {
this.add_actor(this._counterBin); this.add_actor(this._counterBin);
this._countUpdatedId = this._source.connect('notify::count', this._updateCount.bind(this)); this._countUpdatedId = this._source.connect('count-updated', this._updateCount.bind(this));
this._updateCount(); this._updateCount();
this.connect('destroy', () => { this.connect('destroy', () => {
@@ -732,34 +688,11 @@ class SourceActorWithLabel extends SourceActor {
} }
}); });
var Source = GObject.registerClass({ var Source = class Source {
GTypeName: 'MessageTray_Source', constructor(title, iconName) {
Properties: {
'count': GObject.ParamSpec.int(
'count', 'count', 'count',
GObject.ParamFlags.READABLE,
0, GLib.MAXINT32, 0),
'policy': GObject.ParamSpec.object(
'policy', 'policy', 'policy',
GObject.ParamFlags.READWRITE,
NotificationPolicy.$gtype),
'title': GObject.ParamSpec.string(
'title', 'title', 'title',
GObject.ParamFlags.READWRITE,
null),
},
Signals: {
'destroy': { param_types: [GObject.TYPE_UINT] },
'icon-updated': {},
'notification-added': { param_types: [Notification.$gtype] },
'notification-show': { param_types: [Notification.$gtype] },
}
}, class Source extends GObject.Object {
_init(title, iconName) {
super._init({ title: title });
this.SOURCE_ICON_SIZE = 48; this.SOURCE_ICON_SIZE = 48;
this.title = title;
this.iconName = iconName; this.iconName = iconName;
this.isChat = false; this.isChat = false;
@@ -794,7 +727,7 @@ var Source = GObject.registerClass({
} }
countUpdated() { countUpdated() {
super.notify('count'); this.emit('count-updated');
} }
_createPolicy() { _createPolicy() {
@@ -808,11 +741,8 @@ var Source = GObject.registerClass({
} }
setTitle(newTitle) { setTitle(newTitle) {
if (this.title == newTitle)
return;
this.title = newTitle; this.title = newTitle;
this.notify('title'); this.emit('title-changed');
} }
createBanner(notification) { createBanner(notification) {
@@ -837,10 +767,10 @@ var Source = GObject.registerClass({
return; return;
this.notifications.splice(index, 1); this.notifications.splice(index, 1);
this.countUpdated();
if (this.notifications.length == 0) if (this.notifications.length == 0)
this.destroy(); this.destroy();
this.countUpdated();
} }
pushNotification(notification) { pushNotification(notification) {
@@ -851,39 +781,24 @@ var Source = GObject.registerClass({
this.notifications.shift().destroy(NotificationDestroyedReason.EXPIRED); this.notifications.shift().destroy(NotificationDestroyedReason.EXPIRED);
notification.connect('destroy', this._onNotificationDestroy.bind(this)); notification.connect('destroy', this._onNotificationDestroy.bind(this));
notification.connect('notify::acknowledged', this.countUpdated.bind(this)); notification.connect('acknowledged-changed', this.countUpdated.bind(this));
this.notifications.push(notification); this.notifications.push(notification);
this.emit('notification-added', notification); this.emit('notification-added', notification);
this.countUpdated(); this.countUpdated();
} }
showNotification(notification) { notify(notification) {
notification.acknowledged = false; notification.acknowledged = false;
this.pushNotification(notification); this.pushNotification(notification);
if (this.policy.showBanners || notification.urgency == Urgency.CRITICAL) { if (this.policy.showBanners || notification.urgency == Urgency.CRITICAL) {
this.emit('notification-show', notification); this.emit('notify', notification);
} else { } else {
notification.playSound(); notification.playSound();
} }
} }
notify(propName) {
if (propName instanceof Notification) {
try {
throw new Error('Source.notify() has been moved to Source.showNotification()' +
'this code will break in the future');
} catch (e) {
logError(e);
this.showNotification(propName);
return;
}
}
super.notify(propName);
}
destroy(reason) { destroy(reason) {
this.policy.destroy(); this.policy.destroy();
@@ -894,8 +809,6 @@ var Source = GObject.registerClass({
notifications[i].destroy(reason); notifications[i].destroy(reason);
this.emit('destroy', reason); this.emit('destroy', reason);
this.run_dispose();
} }
iconUpdated() { iconUpdated() {
@@ -910,23 +823,14 @@ var Source = GObject.registerClass({
for (let i = this.notifications.length - 1; i >= 0; i--) for (let i = this.notifications.length - 1; i >= 0; i--)
if (!this.notifications[i].resident) if (!this.notifications[i].resident)
this.notifications[i].destroy(); this.notifications[i].destroy();
}
});
var MessageTray = GObject.registerClass({ this.countUpdated();
Signals: {
'queue-changed': {},
'source-added': { param_types: [Source.$gtype] },
'source-removed': { param_types: [Source.$gtype] },
} }
}, class MessageTray extends St.Widget { };
_init() { Signals.addSignalMethods(Source.prototype);
super._init({
visible: false,
clip_to_allocation: true,
layout_manager: new Clutter.BinLayout()
});
var MessageTray = class MessageTray {
constructor() {
this._presence = new GnomeSession.Presence((proxy, _error) => { this._presence = new GnomeSession.Presence((proxy, _error) => {
this._onStatusChanged(proxy.status); this._onStatusChanged(proxy.status);
}); });
@@ -943,15 +847,18 @@ var MessageTray = GObject.registerClass({
// so fix up Clutter's view of the pointer position in // so fix up Clutter's view of the pointer position in
// that case. // that case.
let related = ev.get_related(); let related = ev.get_related();
if (!related || this.contains(related)) if (!related || this.actor.contains(related))
global.sync_pointer(); global.sync_pointer();
}); });
this.actor = new St.Widget({ visible: false,
clip_to_allocation: true,
layout_manager: new Clutter.BinLayout() });
let constraint = new Layout.MonitorConstraint({ primary: true }); let constraint = new Layout.MonitorConstraint({ primary: true });
Main.layoutManager.panelBox.bind_property('visible', Main.layoutManager.panelBox.bind_property('visible',
constraint, 'work-area', constraint, 'work-area',
GObject.BindingFlags.SYNC_CREATE); GObject.BindingFlags.SYNC_CREATE);
this.add_constraint(constraint); this.actor.add_constraint(constraint);
this._bannerBin = new St.Widget({ name: 'notification-container', this._bannerBin = new St.Widget({ name: 'notification-container',
reactive: true, reactive: true,
@@ -965,7 +872,7 @@ var MessageTray = GObject.registerClass({
this._onNotificationKeyRelease.bind(this)); this._onNotificationKeyRelease.bind(this));
this._bannerBin.connect('notify::hover', this._bannerBin.connect('notify::hover',
this._onNotificationHoverChanged.bind(this)); this._onNotificationHoverChanged.bind(this));
this.add_actor(this._bannerBin); this.actor.add_actor(this._bannerBin);
this._notificationFocusGrabber = new FocusGrabber(this._bannerBin); this._notificationFocusGrabber = new FocusGrabber(this._bannerBin);
this._notificationQueue = []; this._notificationQueue = [];
@@ -994,7 +901,7 @@ var MessageTray = GObject.registerClass({
this._notificationTimeoutId = 0; this._notificationTimeoutId = 0;
this._notificationRemoved = false; this._notificationRemoved = false;
Main.layoutManager.addChrome(this, { affectsInputRegion: false }); Main.layoutManager.addChrome(this.actor, { affectsInputRegion: false });
Main.layoutManager.trackChrome(this._bannerBin, { affectsInputRegion: true }); Main.layoutManager.trackChrome(this._bannerBin, { affectsInputRegion: true });
global.display.connect('in-fullscreen-changed', this._updateState.bind(this)); global.display.connect('in-fullscreen-changed', this._updateState.bind(this));
@@ -1037,11 +944,11 @@ var MessageTray = GObject.registerClass({
} }
_onDragBegin() { _onDragBegin() {
Shell.util_set_hidden_from_pick(this, true); Shell.util_set_hidden_from_pick(this.actor, true);
} }
_onDragEnd() { _onDragEnd() {
Shell.util_set_hidden_from_pick(this, false); Shell.util_set_hidden_from_pick(this.actor, false);
} }
get bannerAlignment() { get bannerAlignment() {
@@ -1090,22 +997,22 @@ var MessageTray = GObject.registerClass({
// Register that we got a notification for this source // Register that we got a notification for this source
source.policy.store(); source.policy.store();
source.policy.connect('notify::enable', () => { source.policy.connect('enable-changed', () => {
this._onSourceEnableChanged(source.policy, source); this._onSourceEnableChanged(source.policy, source);
}); });
source.policy.connect('notify', this._updateState.bind(this)); source.policy.connect('policy-changed', this._updateState.bind(this));
this._onSourceEnableChanged(source.policy, source); this._onSourceEnableChanged(source.policy, source);
} }
_addSource(source) { _addSource(source) {
let obj = { let obj = {
showId: 0, notifyId: 0,
destroyId: 0, destroyId: 0,
}; };
this._sources.set(source, obj); this._sources.set(source, obj);
obj.showId = source.connect('notification-show', this._onNotificationShow.bind(this)); obj.notifyId = source.connect('notify', this._onNotify.bind(this));
obj.destroyId = source.connect('destroy', this._onSourceDestroy.bind(this)); obj.destroyId = source.connect('destroy', this._onSourceDestroy.bind(this));
this.emit('source-added', source); this.emit('source-added', source);
@@ -1115,7 +1022,7 @@ var MessageTray = GObject.registerClass({
let obj = this._sources.get(source); let obj = this._sources.get(source);
this._sources.delete(source); this._sources.delete(source);
source.disconnect(obj.showId); source.disconnect(obj.notifyId);
source.disconnect(obj.destroyId); source.disconnect(obj.destroyId);
this.emit('source-removed', source); this.emit('source-removed', source);
@@ -1156,7 +1063,7 @@ var MessageTray = GObject.registerClass({
} }
} }
_onNotificationShow(_source, notification) { _onNotify(source, notification) {
if (this._notification == notification) { if (this._notification == notification) {
// If a notification that is being shown is updated, we update // If a notification that is being shown is updated, we update
// how it is shown and extend the time until it auto-hides. // how it is shown and extend the time until it auto-hides.
@@ -1288,7 +1195,7 @@ var MessageTray = GObject.registerClass({
// at the present time. // at the present time.
_updateState() { _updateState() {
let hasMonitor = Main.layoutManager.primaryMonitor != null; let hasMonitor = Main.layoutManager.primaryMonitor != null;
this.visible = !this._bannerBlocked && hasMonitor && this._banner != null; this.actor.visible = !this._bannerBlocked && hasMonitor && this._banner != null;
if (this._bannerBlocked || !hasMonitor) if (this._bannerBlocked || !hasMonitor)
return; return;
@@ -1368,11 +1275,11 @@ var MessageTray = GObject.registerClass({
this._updateState(); this._updateState();
}); });
this._bannerBin.add_actor(this._banner); this._bannerBin.add_actor(this._banner.actor);
this._bannerBin.opacity = 0; this._bannerBin.opacity = 0;
this._bannerBin.y = -this._banner.height; this._bannerBin.y = -this._banner.actor.height;
this.show(); this.actor.show();
Meta.disable_unredirect_for_display(global.display); Meta.disable_unredirect_for_display(global.display);
this._updateShowingNotification(); this._updateShowingNotification();
@@ -1519,16 +1426,16 @@ var MessageTray = GObject.registerClass({
_hideNotificationCompleted() { _hideNotificationCompleted() {
let notification = this._notification; let notification = this._notification;
this._notification = null; this._notification = null;
if (!this._notificationRemoved && notification.isTransient) if (notification.isTransient)
notification.destroy(NotificationDestroyedReason.EXPIRED); notification.destroy(NotificationDestroyedReason.EXPIRED);
this._pointerInNotification = false; this._pointerInNotification = false;
this._notificationRemoved = false; this._notificationRemoved = false;
Meta.enable_unredirect_for_display(global.display); Meta.enable_unredirect_for_display(global.display);
this._banner.destroy(); this._banner.actor.destroy();
this._banner = null; this._banner = null;
this.hide(); this.actor.hide();
} }
_expandActiveNotification() { _expandActiveNotification() {
@@ -1550,15 +1457,15 @@ var MessageTray = GObject.registerClass({
_ensureBannerFocused() { _ensureBannerFocused() {
this._notificationFocusGrabber.grabFocus(); this._notificationFocusGrabber.grabFocus();
} }
}); };
Signals.addSignalMethods(MessageTray.prototype);
var SystemNotificationSource = GObject.registerClass( var SystemNotificationSource = class SystemNotificationSource extends Source {
class SystemNotificationSource extends Source { constructor() {
_init() { super(_("System Information"), 'dialog-information-symbolic');
super._init(_("System Information"), 'dialog-information-symbolic');
} }
open() { open() {
this.destroy(); this.destroy();
} }
}); };

View File

@@ -121,7 +121,7 @@ var ModalDialog = GObject.registerClass({
this.dialogLayout.opacity = 255; this.dialogLayout.opacity = 255;
if (this._lightbox) if (this._lightbox)
this._lightbox.lightOn(); this._lightbox.show();
this.opacity = 0; this.opacity = 0;
this.show(); this.show();
this.ease({ this.ease({

View File

@@ -1,5 +1,5 @@
/* exported MediaSection */ /* exported MediaSection */
const { Gio, GObject, Shell, St } = imports.gi; const { Gio, Shell, St } = imports.gi;
const Signals = imports.signals; const Signals = imports.signals;
const Calendar = imports.ui.calendar; const Calendar = imports.ui.calendar;
@@ -19,10 +19,9 @@ const MprisPlayerProxy = Gio.DBusProxy.makeProxyWrapper(MprisPlayerIface);
const MPRIS_PLAYER_PREFIX = 'org.mpris.MediaPlayer2.'; const MPRIS_PLAYER_PREFIX = 'org.mpris.MediaPlayer2.';
var MediaMessage = GObject.registerClass( var MediaMessage = class MediaMessage extends MessageList.Message {
class MediaMessage extends MessageList.Message { constructor(player) {
_init(player) { super('', '');
super._init('', '');
this._player = player; this._player = player;
@@ -49,7 +48,7 @@ class MediaMessage extends MessageList.Message {
this._update(); this._update();
} }
vfunc_clicked() { _onClicked() {
this._player.raise(); this._player.raise();
Main.panel.closeCalendar(); Main.panel.closeCalendar();
} }
@@ -80,7 +79,7 @@ class MediaMessage extends MessageList.Message {
this._updateNavButton(this._prevButton, this._player.canGoPrevious); this._updateNavButton(this._prevButton, this._player.canGoPrevious);
this._updateNavButton(this._nextButton, this._player.canGoNext); this._updateNavButton(this._nextButton, this._player.canGoNext);
} }
}); };
var MprisPlayer = class MprisPlayer { var MprisPlayer = class MprisPlayer {
constructor(busName) { constructor(busName) {
@@ -195,10 +194,9 @@ var MprisPlayer = class MprisPlayer {
}; };
Signals.addSignalMethods(MprisPlayer.prototype); Signals.addSignalMethods(MprisPlayer.prototype);
var MediaSection = GObject.registerClass( var MediaSection = class MediaSection extends MessageList.MessageListSection {
class MediaSection extends MessageList.MessageListSection { constructor() {
_init() { super();
super._init();
this._players = new Map(); this._players = new Map();
@@ -249,4 +247,4 @@ class MediaSection extends MessageList.MessageListSection {
if (newOwner && !oldOwner) if (newOwner && !oldOwner)
this._addPlayer(name); this._addPlayer(name);
} }
}); };

View File

@@ -1,7 +1,7 @@
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*- // -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
/* exported NotificationDaemon */ /* exported NotificationDaemon */
const { GdkPixbuf, Gio, GLib, GObject, Shell, St } = imports.gi; const { GdkPixbuf, Gio, GLib, Shell, St } = imports.gi;
const Config = imports.misc.config; const Config = imports.misc.config;
const Main = imports.ui.main; const Main = imports.ui.main;
@@ -412,10 +412,10 @@ var FdoNotificationDaemon = class FdoNotificationDaemon {
} }
}; };
var FdoNotificationDaemonSource = GObject.registerClass( var FdoNotificationDaemonSource =
class FdoNotificationDaemonSource extends MessageTray.Source { class FdoNotificationDaemonSource extends MessageTray.Source {
_init(title, pid, sender, appId) { constructor(title, pid, sender, appId) {
super._init(title); super(title);
this.pid = pid; this.pid = pid;
this.app = this._getApp(appId); this.app = this._getApp(appId);
@@ -464,7 +464,7 @@ class FdoNotificationDaemonSource extends MessageTray.Source {
if (notification.resident && this.app && tracker.focus_app == this.app) if (notification.resident && this.app && tracker.focus_app == this.app)
this.pushNotification(notification); this.pushNotification(notification);
else else
this.showNotification(notification); this.notify(notification);
} }
_getApp(appId) { _getApp(appId) {
@@ -526,7 +526,7 @@ class FdoNotificationDaemonSource extends MessageTray.Source {
return null; return null;
} }
} }
}); };
const PRIORITY_URGENCY_MAP = { const PRIORITY_URGENCY_MAP = {
low: MessageTray.Urgency.LOW, low: MessageTray.Urgency.LOW,
@@ -535,10 +535,10 @@ const PRIORITY_URGENCY_MAP = {
urgent: MessageTray.Urgency.CRITICAL urgent: MessageTray.Urgency.CRITICAL
}; };
var GtkNotificationDaemonNotification = GObject.registerClass( var GtkNotificationDaemonNotification =
class GtkNotificationDaemonNotification extends MessageTray.Notification { class GtkNotificationDaemonNotification extends MessageTray.Notification {
_init(source, notification) { constructor(source, notification) {
super._init(source); super(source);
this._serialized = GLib.Variant.new('a{sv}', notification); this._serialized = GLib.Variant.new('a{sv}', notification);
let { title, let { title,
@@ -602,7 +602,7 @@ class GtkNotificationDaemonNotification extends MessageTray.Notification {
serialize() { serialize() {
return this._serialized; return this._serialized;
} }
}); };
const FdoApplicationIface = loadInterfaceXML('org.freedesktop.Application'); const FdoApplicationIface = loadInterfaceXML('org.freedesktop.Application');
const FdoApplicationProxy = Gio.DBusProxy.makeProxyWrapper(FdoApplicationIface); const FdoApplicationProxy = Gio.DBusProxy.makeProxyWrapper(FdoApplicationIface);
@@ -618,9 +618,9 @@ function getPlatformData() {
function InvalidAppError() {} function InvalidAppError() {}
var GtkNotificationDaemonAppSource = GObject.registerClass( var GtkNotificationDaemonAppSource =
class GtkNotificationDaemonAppSource extends MessageTray.Source { class GtkNotificationDaemonAppSource extends MessageTray.Source {
_init(appId) { constructor(appId) {
let objectPath = objectPathFromAppId(appId); let objectPath = objectPathFromAppId(appId);
if (!GLib.Variant.is_object_path(objectPath)) if (!GLib.Variant.is_object_path(objectPath))
throw new InvalidAppError(); throw new InvalidAppError();
@@ -629,7 +629,7 @@ class GtkNotificationDaemonAppSource extends MessageTray.Source {
if (!app) if (!app)
throw new InvalidAppError(); throw new InvalidAppError();
super._init(app.get_name()); super(app.get_name());
this._appId = appId; this._appId = appId;
this._app = app; this._app = app;
@@ -690,7 +690,7 @@ class GtkNotificationDaemonAppSource extends MessageTray.Source {
this._notifications[notificationId] = notification; this._notifications[notificationId] = notification;
if (showBanner) if (showBanner)
this.showNotification(notification); this.notify(notification);
else else
this.pushNotification(notification); this.pushNotification(notification);
@@ -716,7 +716,7 @@ class GtkNotificationDaemonAppSource extends MessageTray.Source {
} }
return [this._appId, notifications]; return [this._appId, notifications];
} }
}); };
const GtkNotificationsIface = loadInterfaceXML('org.gtk.Notifications'); const GtkNotificationsIface = loadInterfaceXML('org.gtk.Notifications');
@@ -742,7 +742,7 @@ var GtkNotificationDaemon = class GtkNotificationDaemon {
delete this._sources[appId]; delete this._sources[appId];
this._saveNotifications(); this._saveNotifications();
}); });
source.connect('notify::count', this._saveNotifications.bind(this)); source.connect('count-updated', this._saveNotifications.bind(this));
Main.messageTray.add(source); Main.messageTray.add(source);
this._sources[appId] = source; this._sources[appId] = source;
return source; return source;

View File

@@ -1,33 +1,30 @@
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*- // -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
/* exported OsdMonitorLabeler */ /* exported OsdMonitorLabeler */
const { Clutter, Gio, GObject, Meta, St } = imports.gi; const { Clutter, Gio, Meta, St } = imports.gi;
const Main = imports.ui.main; const Main = imports.ui.main;
var OsdMonitorLabel = GObject.registerClass( var OsdMonitorLabel = class {
class OsdMonitorLabel extends St.Widget { constructor(monitor, label) {
_init(monitor, label) { this._actor = new St.Widget({ x_expand: true,
super._init({ x_expand: true, y_expand: true }); y_expand: true });
this._monitor = monitor; this._monitor = monitor;
this._box = new St.BoxLayout({ style_class: 'osd-window', this._box = new St.BoxLayout({ style_class: 'osd-window',
vertical: true }); vertical: true });
this.add_actor(this._box); this._actor.add_actor(this._box);
this._label = new St.Label({ style_class: 'osd-monitor-label', this._label = new St.Label({ style_class: 'osd-monitor-label',
text: label }); text: label });
this._box.add(this._label); this._box.add(this._label);
Main.uiGroup.add_child(this); Main.uiGroup.add_child(this._actor);
Main.uiGroup.set_child_above_sibling(this, null); Main.uiGroup.set_child_above_sibling(this._actor, null);
this._position(); this._position();
Meta.disable_unredirect_for_display(global.display); Meta.disable_unredirect_for_display(global.display);
this.connect('destroy', () => {
Meta.enable_unredirect_for_display(global.display);
});
} }
_position() { _position() {
@@ -40,7 +37,12 @@ class OsdMonitorLabel extends St.Widget {
this._box.y = workArea.y; this._box.y = workArea.y;
} }
});
destroy() {
this._actor.destroy();
Meta.enable_unredirect_for_display(global.display);
}
};
var OsdMonitorLabeler = class { var OsdMonitorLabeler = class {
constructor() { constructor() {

View File

@@ -41,25 +41,22 @@ class OsdWindowConstraint extends Clutter.Constraint {
} }
}); });
var OsdWindow = GObject.registerClass( var OsdWindow = class {
class OsdWindow extends St.Widget { constructor(monitorIndex) {
_init(monitorIndex) { this.actor = new St.Widget({ x_expand: true,
super._init({ y_expand: true,
x_expand: true, x_align: Clutter.ActorAlign.CENTER,
y_expand: true, y_align: Clutter.ActorAlign.CENTER });
x_align: Clutter.ActorAlign.CENTER,
y_align: Clutter.ActorAlign.CENTER
});
this._monitorIndex = monitorIndex; this._monitorIndex = monitorIndex;
let constraint = new Layout.MonitorConstraint({ index: monitorIndex }); let constraint = new Layout.MonitorConstraint({ index: monitorIndex });
this.add_constraint(constraint); this.actor.add_constraint(constraint);
this._boxConstraint = new OsdWindowConstraint(); this._boxConstraint = new OsdWindowConstraint();
this._box = new St.BoxLayout({ style_class: 'osd-window', this._box = new St.BoxLayout({ style_class: 'osd-window',
vertical: true }); vertical: true });
this._box.add_constraint(this._boxConstraint); this._box.add_constraint(this._boxConstraint);
this.add_actor(this._box); this.actor.add_actor(this._box);
this._icon = new St.Icon(); this._icon = new St.Icon();
this._box.add(this._icon, { expand: true }); this._box.add(this._icon, { expand: true });
@@ -76,7 +73,7 @@ class OsdWindow extends St.Widget {
this._hideTimeoutId = 0; this._hideTimeoutId = 0;
this._reset(); this._reset();
this.connect('destroy', this._onDestroy.bind(this)); this.actor.connect('destroy', this._onDestroy.bind(this));
this._monitorsChangedId = this._monitorsChangedId =
Main.layoutManager.connect('monitors-changed', Main.layoutManager.connect('monitors-changed',
@@ -86,7 +83,7 @@ class OsdWindow extends St.Widget {
themeContext.connect('notify::scale-factor', themeContext.connect('notify::scale-factor',
this._relayout.bind(this)); this._relayout.bind(this));
this._relayout(); this._relayout();
Main.uiGroup.add_child(this); Main.uiGroup.add_child(this.actor);
} }
_onDestroy() { _onDestroy() {
@@ -113,7 +110,7 @@ class OsdWindow extends St.Widget {
setLevel(value) { setLevel(value) {
this._level.visible = (value != undefined); this._level.visible = (value != undefined);
if (value != undefined) { if (value != undefined) {
if (this.visible) if (this.actor.visible)
this._level.ease_property('value', value, { this._level.ease_property('value', value, {
mode: Clutter.AnimationMode.EASE_OUT_QUAD, mode: Clutter.AnimationMode.EASE_OUT_QUAD,
duration: LEVEL_ANIMATION_TIME duration: LEVEL_ANIMATION_TIME
@@ -131,13 +128,13 @@ class OsdWindow extends St.Widget {
if (!this._icon.gicon) if (!this._icon.gicon)
return; return;
if (!this.visible) { if (!this.actor.visible) {
Meta.disable_unredirect_for_display(global.display); Meta.disable_unredirect_for_display(global.display);
super.show(); this.actor.show();
this.opacity = 0; this.actor.opacity = 0;
this.get_parent().set_child_above_sibling(this, null); this.actor.get_parent().set_child_above_sibling(this.actor, null);
this.ease({ this.actor.ease({
opacity: 255, opacity: 255,
duration: FADE_TIME, duration: FADE_TIME,
mode: Clutter.AnimationMode.EASE_OUT_QUAD mode: Clutter.AnimationMode.EASE_OUT_QUAD
@@ -161,7 +158,7 @@ class OsdWindow extends St.Widget {
_hide() { _hide() {
this._hideTimeoutId = 0; this._hideTimeoutId = 0;
this.ease({ this.actor.ease({
opacity: 0, opacity: 0,
duration: FADE_TIME, duration: FADE_TIME,
mode: Clutter.AnimationMode.EASE_OUT_QUAD, mode: Clutter.AnimationMode.EASE_OUT_QUAD,
@@ -174,7 +171,7 @@ class OsdWindow extends St.Widget {
} }
_reset() { _reset() {
super.hide(); this.actor.hide();
this.setLabel(null); this.setLabel(null);
this.setMaxLevel(null); this.setMaxLevel(null);
this.setLevel(null); this.setLevel(null);
@@ -196,7 +193,7 @@ class OsdWindow extends St.Widget {
this._box.translation_y = Math.round(monitor.height / 4); this._box.translation_y = Math.round(monitor.height / 4);
this._boxConstraint.minSize = popupSize; this._boxConstraint.minSize = popupSize;
} }
}); };
var OsdWindowManager = class { var OsdWindowManager = class {
constructor() { constructor() {
@@ -213,7 +210,7 @@ var OsdWindowManager = class {
} }
for (let i = Main.layoutManager.monitors.length; i < this._osdWindows.length; i++) { for (let i = Main.layoutManager.monitors.length; i < this._osdWindows.length; i++) {
this._osdWindows[i].destroy(); this._osdWindows[i].actor.destroy();
this._osdWindows[i] = null; this._osdWindows[i] = null;
} }

View File

@@ -1,7 +1,7 @@
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*- // -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
/* exported Overview */ /* exported Overview */
const { Clutter, GLib, GObject, Meta, Shell, St } = imports.gi; const { Clutter, GLib, Meta, Shell, St } = imports.gi;
const Signals = imports.signals; const Signals = imports.signals;
const Background = imports.ui.background; const Background = imports.ui.background;
@@ -72,108 +72,36 @@ var ShellInfo = class {
if (undoCallback) if (undoCallback)
notification.addAction(_("Undo"), this._onUndoClicked.bind(this)); notification.addAction(_("Undo"), this._onUndoClicked.bind(this));
this._source.showNotification(notification); this._source.notify(notification);
} }
}; };
var OverviewActor = GObject.registerClass(
class OverviewActor extends St.BoxLayout {
_init() {
super._init({
name: 'overview',
/* Translators: This is the main view to select
activities. See also note for "Activities" string. */
accessible_name: _("Overview"),
vertical: true
});
this.add_constraint(new LayoutManager.MonitorConstraint({ primary: true }));
// Add a clone of the panel to the overview so spacing and such is
// automatic
let panelGhost = new St.Bin({
child: new Clutter.Clone({ source: Main.panel }),
reactive: false,
opacity: 0
});
this.add_actor(panelGhost);
this._searchEntry = new St.Entry({
style_class: 'search-entry',
/* Translators: this is the text displayed
in the search entry when no search is
active; it should not exceed ~30
characters. */
hint_text: _("Type to search…"),
track_hover: true,
can_focus: true
});
let searchEntryBin = new St.Bin({
child: this._searchEntry,
x_align: St.Align.MIDDLE
});
this.add_actor(searchEntryBin);
this._controls = new OverviewControls.ControlsManager(this._searchEntry);
// Add our same-line elements after the search entry
this.add(this._controls, { y_fill: true, expand: true });
}
get dash() {
return this._controls.dash;
}
get searchEntry() {
return this._searchEntry;
}
get viewSelector() {
return this._controls.viewSelector;
}
});
var Overview = class { var Overview = class {
constructor() { constructor() {
this._overviewCreated = false;
this._initCalled = false; this._initCalled = false;
Main.sessionMode.connect('updated', this._sessionUpdated.bind(this)); Main.sessionMode.connect('updated', this._sessionUpdated.bind(this));
this._sessionUpdated(); this._sessionUpdated();
} }
get dash() {
return this._overview.dash;
}
get dashIconSize() {
logError(new Error('Usage of Overview.\'dashIconSize\' is deprecated, ' +
'use \'dash.iconSize\' property instead'));
return this.dash.iconSize;
}
get viewSelector() {
return this._overview.viewSelector;
}
get animationInProgress() {
return this._animationInProgress;
}
get visible() {
return this._visible;
}
get visibleTarget() {
return this._visibleTarget;
}
_createOverview() { _createOverview() {
if (this._overview) if (this._overviewCreated)
return; return;
if (this.isDummy) if (this.isDummy)
return; return;
this._overviewCreated = true;
this._overview = new St.BoxLayout({ name: 'overview',
/* Translators: This is the main view to select
activities. See also note for "Activities" string. */
accessible_name: _("Overview"),
vertical: true });
this._overview.add_constraint(new LayoutManager.MonitorConstraint({ primary: true }));
this._overview._delegate = this;
// The main Background actors are inside global.window_group which are // The main Background actors are inside global.window_group which are
// hidden when displaying the overview, so we create a new // hidden when displaying the overview, so we create a new
// one. Instances of this class share a single CoglTexture behind the // one. Instances of this class share a single CoglTexture behind the
@@ -188,11 +116,11 @@ var Overview = class {
this._activationTime = 0; this._activationTime = 0;
this._visible = false; // animating to overview, in overview, animating out this.visible = false; // animating to overview, in overview, animating out
this._shown = false; // show() and not hide() this._shown = false; // show() and not hide()
this._modal = false; // have a modal grab this._modal = false; // have a modal grab
this._animationInProgress = false; this.animationInProgress = false;
this._visibleTarget = false; this.visibleTarget = false;
// During transitions, we raise this to the top to avoid having the overview // During transitions, we raise this to the top to avoid having the overview
// area be reactive; it causes too many issues such as double clicks on // area be reactive; it causes too many issues such as double clicks on
@@ -201,6 +129,9 @@ var Overview = class {
reactive: true }); reactive: true });
Main.layoutManager.overviewGroup.add_child(this._coverPane); Main.layoutManager.overviewGroup.add_child(this._coverPane);
this._coverPane.connect('event', () => Clutter.EVENT_STOP); this._coverPane.connect('event', () => Clutter.EVENT_STOP);
Main.layoutManager.overviewGroup.add_child(this._overview);
this._coverPane.hide(); this._coverPane.hide();
// XDND // XDND
@@ -282,12 +213,41 @@ var Overview = class {
if (this.isDummy) if (this.isDummy)
return; return;
this._overview = new OverviewActor();
this._overview._delegate = this;
Main.layoutManager.overviewGroup.add_child(this._overview);
this._shellInfo = new ShellInfo(); this._shellInfo = new ShellInfo();
// Add a clone of the panel to the overview so spacing and such is
// automatic
this._panelGhost = new St.Bin({ child: new Clutter.Clone({ source: Main.panel }),
reactive: false,
opacity: 0 });
this._overview.add_actor(this._panelGhost);
this._searchEntry = new St.Entry({ style_class: 'search-entry',
/* Translators: this is the text displayed
in the search entry when no search is
active; it should not exceed ~30
characters. */
hint_text: _("Type to search…"),
track_hover: true,
can_focus: true });
this._searchEntryBin = new St.Bin({ child: this._searchEntry,
x_align: St.Align.MIDDLE });
this._overview.add_actor(this._searchEntryBin);
// Create controls
this._controls = new OverviewControls.ControlsManager(this._searchEntry);
this._dash = this._controls.dash;
this.viewSelector = this._controls.viewSelector;
// Add our same-line elements after the search entry
this._overview.add(this._controls.actor, { y_fill: true, expand: true });
// TODO - recalculate everything when desktop size changes
this.dashIconSize = this._dash.iconSize;
this._dash.connect('icon-size-changed', () => {
this.dashIconSize = this._dash.iconSize;
});
Main.layoutManager.connect('monitors-changed', this._relayout.bind(this)); Main.layoutManager.connect('monitors-changed', this._relayout.bind(this));
this._relayout(); this._relayout();
} }
@@ -466,7 +426,7 @@ var Overview = class {
focusSearch() { focusSearch() {
this.show(); this.show();
this._overview.searchEntry.grab_key_focus(); this._searchEntry.grab_key_focus();
} }
fadeInDesktop() { fadeInDesktop() {
@@ -504,11 +464,11 @@ var Overview = class {
// the overview if the user both triggered the hot corner and // the overview if the user both triggered the hot corner and
// clicked the Activities button. // clicked the Activities button.
shouldToggleByCornerOrButton() { shouldToggleByCornerOrButton() {
if (this._animationInProgress) if (this.animationInProgress)
return false; return false;
if (this._inItemDrag || this._inWindowDrag) if (this._inItemDrag || this._inWindowDrag)
return false; return false;
if (!this._activationTime || if (this._activationTime == 0 ||
GLib.get_monotonic_time() / GLib.USEC_PER_SEC - this._activationTime > OVERVIEW_ACTIVATION_TIMEOUT) GLib.get_monotonic_time() / GLib.USEC_PER_SEC - this._activationTime > OVERVIEW_ACTIVATION_TIMEOUT)
return true; return true;
return false; return false;
@@ -518,7 +478,7 @@ var Overview = class {
// We delay grab changes during animation so that when removing the // We delay grab changes during animation so that when removing the
// overview we don't have a problem with the release of a press/release // overview we don't have a problem with the release of a press/release
// going to an application. // going to an application.
if (this._animationInProgress) if (this.animationInProgress)
return true; return true;
if (this._shown) { if (this._shown) {
@@ -560,12 +520,12 @@ var Overview = class {
_animateVisible() { _animateVisible() {
if (this._visible || this._animationInProgress) if (this.visible || this.animationInProgress)
return; return;
this._visible = true; this.visible = true;
this._animationInProgress = true; this.animationInProgress = true;
this._visibleTarget = true; this.visibleTarget = true;
this._activationTime = GLib.get_monotonic_time() / GLib.USEC_PER_SEC; this._activationTime = GLib.get_monotonic_time() / GLib.USEC_PER_SEC;
Meta.disable_unredirect_for_display(global.display); Meta.disable_unredirect_for_display(global.display);
@@ -586,7 +546,7 @@ var Overview = class {
} }
_showDone() { _showDone() {
this._animationInProgress = false; this.animationInProgress = false;
this._desktopFade.hide(); this._desktopFade.hide();
this._coverPane.hide(); this._coverPane.hide();
@@ -626,11 +586,11 @@ var Overview = class {
} }
_animateNotVisible() { _animateNotVisible() {
if (!this._visible || this._animationInProgress) if (!this.visible || this.animationInProgress)
return; return;
this._animationInProgress = true; this.animationInProgress = true;
this._visibleTarget = false; this.visibleTarget = false;
this.viewSelector.animateFromOverview(); this.viewSelector.animateFromOverview();
@@ -656,8 +616,8 @@ var Overview = class {
this._desktopFade.hide(); this._desktopFade.hide();
this._coverPane.hide(); this._coverPane.hide();
this._visible = false; this.visible = false;
this._animationInProgress = false; this.animationInProgress = false;
this.emit('hidden'); this.emit('hidden');
// Handle any calls to show* while we were hiding // Handle any calls to show* while we were hiding
@@ -673,17 +633,14 @@ var Overview = class {
if (this.isDummy) if (this.isDummy)
return; return;
if (this._visible) if (this.visible)
this.hide(); this.hide();
else else
this.show(); this.show();
} }
getShowAppsButton() { getShowAppsButton() {
logError(new Error('Usage of Overview.\'getShowAppsButton\' is deprecated, ' + return this._dash.showAppsButton;
'use \'dash.showAppsButton\' property instead'));
return this.dash.showAppsButton;
} }
}; };
Signals.addSignalMethods(Overview.prototype); Signals.addSignalMethods(Overview.prototype);

View File

@@ -118,22 +118,19 @@ var SlideLayout = GObject.registerClass({
} }
}); });
var SlidingControl = GObject.registerClass( var SlidingControl = class {
class SlidingControl extends St.Widget { constructor(params) {
_init(params) {
params = Params.parse(params, { slideDirection: SlideDirection.LEFT }); params = Params.parse(params, { slideDirection: SlideDirection.LEFT });
this.layout = new SlideLayout();
this.layout.slideDirection = params.slideDirection;
super._init({
layout_manager: this.layout,
style_class: 'overview-controls',
clip_to_allocation: true
});
this._visible = true; this._visible = true;
this._inDrag = false; this._inDrag = false;
this.layout = new SlideLayout();
this.layout.slideDirection = params.slideDirection;
this.actor = new St.Widget({ layout_manager: this.layout,
style_class: 'overview-controls',
clip_to_allocation: true });
Main.overview.connect('hiding', this._onOverviewHiding.bind(this)); Main.overview.connect('hiding', this._onOverviewHiding.bind(this));
Main.overview.connect('item-drag-begin', this._onDragBegin.bind(this)); Main.overview.connect('item-drag-begin', this._onDragBegin.bind(this));
@@ -150,20 +147,20 @@ class SlidingControl extends St.Widget {
} }
_updateSlide() { _updateSlide() {
this.ease_property('@layout.slide-x', this._getSlide(), { this.actor.ease_property('@layout.slide-x', this._getSlide(), {
mode: Clutter.AnimationMode.EASE_OUT_QUAD, mode: Clutter.AnimationMode.EASE_OUT_QUAD,
duration: SIDE_CONTROLS_ANIMATION_TIME, duration: SIDE_CONTROLS_ANIMATION_TIME,
}); });
} }
getVisibleWidth() { getVisibleWidth() {
let child = this.get_first_child(); let child = this.actor.get_first_child();
let [, , natWidth] = child.get_preferred_size(); let [, , natWidth] = child.get_preferred_size();
return natWidth; return natWidth;
} }
_getTranslation() { _getTranslation() {
let child = this.get_first_child(); let child = this.actor.get_first_child();
let direction = getRtlSlideDirection(this.layout.slideDirection, child); let direction = getRtlSlideDirection(this.layout.slideDirection, child);
let visibleWidth = this.getVisibleWidth(); let visibleWidth = this.getVisibleWidth();
@@ -189,7 +186,7 @@ class SlidingControl extends St.Widget {
return; return;
this.layout.translation_x = translationStart; this.layout.translation_x = translationStart;
this.ease_property('@layout.translation-x', translationEnd, { this.actor.ease_property('@layout.translation-x', translationEnd, {
mode: Clutter.AnimationMode.EASE_OUT_QUAD, mode: Clutter.AnimationMode.EASE_OUT_QUAD,
duration: SIDE_CONTROLS_ANIMATION_TIME, duration: SIDE_CONTROLS_ANIMATION_TIME,
}); });
@@ -221,7 +218,7 @@ class SlidingControl extends St.Widget {
} }
fadeIn() { fadeIn() {
this.ease({ this.actor.ease({
opacity: 255, opacity: 255,
duration: SIDE_CONTROLS_ANIMATION_TIME / 2, duration: SIDE_CONTROLS_ANIMATION_TIME / 2,
mode: Clutter.AnimationMode.EASE_IN_QUAD mode: Clutter.AnimationMode.EASE_IN_QUAD
@@ -229,7 +226,7 @@ class SlidingControl extends St.Widget {
} }
fadeHalf() { fadeHalf() {
this.ease({ this.actor.ease({
opacity: 128, opacity: 128,
duration: SIDE_CONTROLS_ANIMATION_TIME / 2, duration: SIDE_CONTROLS_ANIMATION_TIME / 2,
mode: Clutter.AnimationMode.EASE_OUT_QUAD mode: Clutter.AnimationMode.EASE_OUT_QUAD
@@ -252,38 +249,37 @@ class SlidingControl extends St.Widget {
// selector; this means we can now safely set the full slide for // selector; this means we can now safely set the full slide for
// the next page, since slideIn or slideOut might have been called, // the next page, since slideIn or slideOut might have been called,
// changing the visiblity // changing the visiblity
this.remove_transition('@layout.slide-x'); this.actor.remove_transition('@layout.slide-x');
this.layout.slide_x = this._getSlide(); this.layout.slide_x = this._getSlide();
this._updateTranslation(); this._updateTranslation();
} }
}); };
var ThumbnailsSlider = GObject.registerClass( var ThumbnailsSlider = class extends SlidingControl {
class ThumbnailsSlider extends SlidingControl { constructor(thumbnailsBox) {
_init(thumbnailsBox) { super({ slideDirection: SlideDirection.RIGHT });
super._init({ slideDirection: SlideDirection.RIGHT });
this._thumbnailsBox = thumbnailsBox; this._thumbnailsBox = thumbnailsBox;
this.request_mode = Clutter.RequestMode.WIDTH_FOR_HEIGHT; this.actor.request_mode = Clutter.RequestMode.WIDTH_FOR_HEIGHT;
this.reactive = true; this.actor.reactive = true;
this.track_hover = true; this.actor.track_hover = true;
this.add_actor(this._thumbnailsBox); this.actor.add_actor(this._thumbnailsBox);
Main.layoutManager.connect('monitors-changed', this._updateSlide.bind(this)); Main.layoutManager.connect('monitors-changed', this._updateSlide.bind(this));
global.workspace_manager.connect('active-workspace-changed', global.workspace_manager.connect('active-workspace-changed',
this._updateSlide.bind(this)); this._updateSlide.bind(this));
global.workspace_manager.connect('notify::n-workspaces', global.workspace_manager.connect('notify::n-workspaces',
this._updateSlide.bind(this)); this._updateSlide.bind(this));
this.connect('notify::hover', this._updateSlide.bind(this)); this.actor.connect('notify::hover', this._updateSlide.bind(this));
this._thumbnailsBox.bind_property('visible', this, 'visible', GObject.BindingFlags.SYNC_CREATE); this._thumbnailsBox.bind_property('visible', this.actor, 'visible', GObject.BindingFlags.SYNC_CREATE);
} }
_getAlwaysZoomOut() { _getAlwaysZoomOut() {
// Always show the pager on hover, during a drag, or if workspaces are // Always show the pager on hover, during a drag, or if workspaces are
// actually used, e.g. there are windows on any non-active workspace // actually used, e.g. there are windows on any non-active workspace
let workspaceManager = global.workspace_manager; let workspaceManager = global.workspace_manager;
let alwaysZoomOut = this.hover || let alwaysZoomOut = this.actor.hover ||
this._inDrag || this._inDrag ||
!Meta.prefs_get_dynamic_workspaces() || !Meta.prefs_get_dynamic_workspaces() ||
workspaceManager.n_workspaces > 2 || workspaceManager.n_workspaces > 2 ||
@@ -308,12 +304,12 @@ class ThumbnailsSlider extends SlidingControl {
} }
getNonExpandedWidth() { getNonExpandedWidth() {
let child = this.get_first_child(); let child = this.actor.get_first_child();
return child.get_theme_node().get_length('visible-width'); return child.get_theme_node().get_length('visible-width');
} }
_onDragEnd() { _onDragEnd() {
this.sync_hover(); this.actor.sync_hover();
super._onDragEnd(); super._onDragEnd();
} }
@@ -325,7 +321,7 @@ class ThumbnailsSlider extends SlidingControl {
if (alwaysZoomOut) if (alwaysZoomOut)
return 1; return 1;
let child = this.get_first_child(); let child = this.actor.get_first_child();
let preferredHeight = child.get_preferred_height(-1)[1]; let preferredHeight = child.get_preferred_height(-1)[1];
let expandedWidth = child.get_preferred_width(preferredHeight)[1]; let expandedWidth = child.get_preferred_width(preferredHeight)[1];
@@ -339,25 +335,24 @@ class ThumbnailsSlider extends SlidingControl {
else else
return this.getNonExpandedWidth(); return this.getNonExpandedWidth();
} }
}); };
var DashSlider = GObject.registerClass( var DashSlider = class extends SlidingControl {
class DashSlider extends SlidingControl { constructor(dash) {
_init(dash) { super({ slideDirection: SlideDirection.LEFT });
super._init({ slideDirection: SlideDirection.LEFT });
this._dash = dash; this._dash = dash;
// SlideLayout reads the actor's expand flags to decide // SlideLayout reads the actor's expand flags to decide
// whether to allocate the natural size to its child, or the whole // whether to allocate the natural size to its child, or the whole
// available allocation // available allocation
this._dash.x_expand = true; this._dash.actor.x_expand = true;
this.x_expand = true; this.actor.x_expand = true;
this.x_align = Clutter.ActorAlign.START; this.actor.x_align = Clutter.ActorAlign.START;
this.y_expand = true; this.actor.y_expand = true;
this.add_actor(this._dash); this.actor.add_actor(this._dash.actor);
this._dash.connect('icon-size-changed', this._updateSlide.bind(this)); this._dash.connect('icon-size-changed', this._updateSlide.bind(this));
} }
@@ -376,7 +371,7 @@ class DashSlider extends SlidingControl {
_onWindowDragEnd() { _onWindowDragEnd() {
this.fadeIn(); this.fadeIn();
} }
}); };
var DashSpacer = GObject.registerClass( var DashSpacer = GObject.registerClass(
class DashSpacer extends St.Widget { class DashSpacer extends St.Widget {
@@ -421,21 +416,12 @@ var ControlsLayout = GObject.registerClass({
} }
}); });
var ControlsManager = GObject.registerClass( var ControlsManager = class {
class ControlsManager extends St.Widget { constructor(searchEntry) {
_init(searchEntry) {
let layout = new ControlsLayout();
super._init({
layout_manager: layout,
x_expand: true,
y_expand: true,
clip_to_allocation: true
});
this.dash = new Dash.Dash(); this.dash = new Dash.Dash();
this._dashSlider = new DashSlider(this.dash); this._dashSlider = new DashSlider(this.dash);
this._dashSpacer = new DashSpacer(); this._dashSpacer = new DashSpacer();
this._dashSpacer.setDashActor(this._dashSlider); this._dashSpacer.setDashActor(this._dashSlider.actor);
this._thumbnailsBox = new WorkspaceThumbnail.ThumbnailsBox(); this._thumbnailsBox = new WorkspaceThumbnail.ThumbnailsBox();
this._thumbnailsSlider = new ThumbnailsSlider(this._thumbnailsBox); this._thumbnailsSlider = new ThumbnailsSlider(this._thumbnailsBox);
@@ -445,15 +431,20 @@ class ControlsManager extends St.Widget {
this.viewSelector.connect('page-changed', this._setVisibility.bind(this)); this.viewSelector.connect('page-changed', this._setVisibility.bind(this));
this.viewSelector.connect('page-empty', this._onPageEmpty.bind(this)); this.viewSelector.connect('page-empty', this._onPageEmpty.bind(this));
let layout = new ControlsLayout();
this.actor = new St.Widget({ layout_manager: layout,
x_expand: true, y_expand: true,
clip_to_allocation: true });
this._group = new St.BoxLayout({ name: 'overview-group', this._group = new St.BoxLayout({ name: 'overview-group',
x_expand: true, y_expand: true }); x_expand: true, y_expand: true });
this.add_actor(this._group); this.actor.add_actor(this._group);
this.add_actor(this._dashSlider); this.actor.add_actor(this._dashSlider.actor);
this._group.add_actor(this._dashSpacer); this._group.add_actor(this._dashSpacer);
this._group.add(this.viewSelector, { x_fill: true, expand: true }); this._group.add(this.viewSelector.actor, { x_fill: true,
this._group.add_actor(this._thumbnailsSlider); expand: true });
this._group.add_actor(this._thumbnailsSlider.actor);
layout.connect('allocation-changed', this._updateWorkspacesGeometry.bind(this)); layout.connect('allocation-changed', this._updateWorkspacesGeometry.bind(this));
@@ -461,18 +452,18 @@ class ControlsManager extends St.Widget {
} }
_updateWorkspacesGeometry() { _updateWorkspacesGeometry() {
let [x, y] = this.get_transformed_position(); let [x, y] = this.actor.get_transformed_position();
let [width, height] = this.get_transformed_size(); let [width, height] = this.actor.get_transformed_size();
let geometry = { x: x, y: y, width: width, height: height }; let geometry = { x: x, y: y, width: width, height: height };
let spacing = this.get_theme_node().get_length('spacing'); let spacing = this.actor.get_theme_node().get_length('spacing');
let dashWidth = this._dashSlider.getVisibleWidth() + spacing; let dashWidth = this._dashSlider.getVisibleWidth() + spacing;
let thumbnailsWidth = this._thumbnailsSlider.getNonExpandedWidth() + spacing; let thumbnailsWidth = this._thumbnailsSlider.getNonExpandedWidth() + spacing;
geometry.width -= dashWidth; geometry.width -= dashWidth;
geometry.width -= thumbnailsWidth; geometry.width -= thumbnailsWidth;
if (this.get_text_direction() == Clutter.TextDirection.LTR) if (this.actor.get_text_direction() == Clutter.TextDirection.LTR)
geometry.x += dashWidth; geometry.x += dashWidth;
else else
geometry.x += thumbnailsWidth; geometry.x += thumbnailsWidth;
@@ -519,4 +510,4 @@ class ControlsManager extends St.Widget {
this._updateSpacerVisibility(); this._updateSpacerVisibility();
} }
}); };

View File

@@ -1,5 +1,5 @@
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*- // -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
/* exported PadOsd, PadOsdService */ /* exported PadOsdService */
const { Atk, Clutter, GDesktopEnums, Gio, const { Atk, Clutter, GDesktopEnums, Gio,
GLib, GObject, Gtk, Meta, Rsvg, St } = imports.gi; GLib, GObject, Gtk, Meta, Rsvg, St } = imports.gi;
@@ -22,45 +22,40 @@ const CCW = 1;
const UP = 0; const UP = 0;
const DOWN = 1; const DOWN = 1;
var PadChooser = GObject.registerClass({ var PadChooser = class {
Signals: { 'pad-selected': { param_types: [Clutter.InputDevice.$gtype] } } constructor(device, groupDevices) {
}, class PadChooser extends St.Button { this.actor = new St.Button({ style_class: 'pad-chooser-button',
_init(device, groupDevices) { toggle_mode: true,
super._init({ x_fill: false,
style_class: 'pad-chooser-button', y_fill: false,
toggle_mode: true, x_align: St.Align.MIDDLE,
x_fill: false, y_align: St.Align.MIDDLE });
y_fill: false,
x_align: St.Align.MIDDLE,
y_align: St.Align.MIDDLE
});
this.currentDevice = device; this.currentDevice = device;
this._padChooserMenu = null; this._padChooserMenu = null;
let arrow = new St.Icon({ style_class: 'popup-menu-arrow', let arrow = new St.Icon({ style_class: 'popup-menu-arrow',
icon_name: 'pan-down-symbolic', icon_name: 'pan-down-symbolic',
accessible_role: Atk.Role.ARROW }); accessible_role: Atk.Role.ARROW });
this.set_child(arrow); this.actor.set_child(arrow);
this._ensureMenu(groupDevices); this._ensureMenu(groupDevices);
this.connect('destroy', this._onDestroy.bind(this)); this.actor.connect('destroy', this._onDestroy.bind(this));
} this.actor.connect('clicked', actor => {
if (actor.get_checked()) {
vfunc_clicked() { if (this._padChooserMenu != null)
if (this.get_checked()) { this._padChooserMenu.open(true);
if (this._padChooserMenu != null) else
this._padChooserMenu.open(true); this.set_checked(false);
else } else {
this.set_checked(false); this._padChooserMenu.close(true);
} else { }
this._padChooserMenu.close(true); });
}
} }
_ensureMenu(devices) { _ensureMenu(devices) {
this._padChooserMenu = new PopupMenu.PopupMenu(this, 0.5, St.Side.TOP); this._padChooserMenu = new PopupMenu.PopupMenu(this.actor, 0.5, St.Side.TOP);
this._padChooserMenu.connect('menu-closed', () => { this._padChooserMenu.connect('menu-closed', () => {
this.set_checked(false); this.actor.set_checked(false);
}); });
this._padChooserMenu.actor.hide(); this._padChooserMenu.actor.hide();
Main.uiGroup.add_actor(this._padChooserMenu.actor); Main.uiGroup.add_actor(this._padChooserMenu.actor);
@@ -83,20 +78,24 @@ var PadChooser = GObject.registerClass({
update(devices) { update(devices) {
if (this._padChooserMenu) if (this._padChooserMenu)
this._padChooserMenu.actor.destroy(); this._padChooserMenu.actor.destroy();
this.set_checked(false); this.actor.set_checked(false);
this._ensureMenu(devices); this._ensureMenu(devices);
} }
});
var KeybindingEntry = GObject.registerClass({ destroy() {
GTypeName: 'PadOsd_KeybindingEntry', this.actor.destroy();
Signals: { 'keybinding-edited': {} } }
}, class KeybindingEntry extends St.Entry { };
_init() { Signals.addSignalMethods(PadChooser.prototype);
super._init({ hint_text: _("New shortcut…"), style: 'width: 10em' });
var KeybindingEntry = class {
constructor() {
this.actor = new St.Entry({ hint_text: _("New shortcut…"),
style: 'width: 10em' });
this.actor.connect('captured-event', this._onCapturedEvent.bind(this));
} }
vfunc_captured_event(event) { _onCapturedEvent(actor, event) {
if (event.type() != Clutter.EventType.KEY_PRESS) if (event.type() != Clutter.EventType.KEY_PRESS)
return Clutter.EVENT_PROPAGATE; return Clutter.EVENT_PROPAGATE;
@@ -104,24 +103,23 @@ var KeybindingEntry = GObject.registerClass({
event.get_key_symbol(), event.get_key_symbol(),
event.get_key_code(), event.get_key_code(),
event.get_state()); event.get_state());
this.set_text(str); this.actor.set_text(str);
this.emit('keybinding-edited', str); this.emit('keybinding-edited', str);
return Clutter.EVENT_STOP; return Clutter.EVENT_STOP;
} }
}); };
Signals.addSignalMethods(KeybindingEntry.prototype);
var ActionComboBox = GObject.registerClass({ var ActionComboBox = class {
GTypeName: 'PadOsd_ActionComboBox', constructor() {
Signals: { 'action-selected': { param_types: [GObject.TYPE_INT] } } this.actor = new St.Button({ style_class: 'button' });
}, class ActionComboBox extends St.Button { this.actor.connect('clicked', this._onButtonClicked.bind(this));
_init() { this.actor.set_toggle_mode(true);
super._init({ style_class: 'button' });
this.set_toggle_mode(true);
let boxLayout = new Clutter.BoxLayout({ orientation: Clutter.Orientation.HORIZONTAL, let boxLayout = new Clutter.BoxLayout({ orientation: Clutter.Orientation.HORIZONTAL,
spacing: 6 }); spacing: 6 });
let box = new St.Widget({ layout_manager: boxLayout }); let box = new St.Widget({ layout_manager: boxLayout });
this.set_child(box); this.actor.set_child(box);
this._label = new St.Label({ style_class: 'combo-box-label' }); this._label = new St.Label({ style_class: 'combo-box-label' });
box.add_child(this._label); box.add_child(this._label);
@@ -133,9 +131,9 @@ var ActionComboBox = GObject.registerClass({
y_align: Clutter.ActorAlign.CENTER }); y_align: Clutter.ActorAlign.CENTER });
box.add_child(arrow); box.add_child(arrow);
this._editMenu = new PopupMenu.PopupMenu(this, 0, St.Side.TOP); this._editMenu = new PopupMenu.PopupMenu(this.actor, 0, St.Side.TOP);
this._editMenu.connect('menu-closed', () => { this._editMenu.connect('menu-closed', () => {
this.set_checked(false); this.actor.set_checked(false);
}); });
this._editMenu.actor.hide(); this._editMenu.actor.hide();
Main.uiGroup.add_actor(this._editMenu.actor); Main.uiGroup.add_actor(this._editMenu.actor);
@@ -181,8 +179,8 @@ var ActionComboBox = GObject.registerClass({
this._editMenu.close(true); this._editMenu.close(true);
} }
vfunc_clicked() { _onButtonClicked() {
if (this.get_checked()) if (this.actor.get_checked())
this.popup(); this.popup();
else else
this.popdown(); this.popdown();
@@ -191,40 +189,38 @@ var ActionComboBox = GObject.registerClass({
setButtonActionsActive(active) { setButtonActionsActive(active) {
this._buttonItems.forEach(item => item.setSensitive(active)); this._buttonItems.forEach(item => item.setSensitive(active));
} }
}); };
Signals.addSignalMethods(ActionComboBox.prototype);
var ActionEditor = GObject.registerClass({ var ActionEditor = class {
GTypeName: 'PadOsd_ActionEditor', constructor() {
Signals: { 'done': {} }
}, class ActionEditor extends St.Widget {
_init() {
let boxLayout = new Clutter.BoxLayout({ orientation: Clutter.Orientation.HORIZONTAL, let boxLayout = new Clutter.BoxLayout({ orientation: Clutter.Orientation.HORIZONTAL,
spacing: 12 }); spacing: 12 });
super._init({ layout_manager: boxLayout }); this.actor = new St.Widget({ layout_manager: boxLayout });
this._actionComboBox = new ActionComboBox(); this._actionComboBox = new ActionComboBox();
this._actionComboBox.connect('action-selected', this._onActionSelected.bind(this)); this._actionComboBox.connect('action-selected', this._onActionSelected.bind(this));
this.add_actor(this._actionComboBox); this.actor.add_actor(this._actionComboBox.actor);
this._keybindingEdit = new KeybindingEntry(); this._keybindingEdit = new KeybindingEntry();
this._keybindingEdit.connect('keybinding-edited', this._onKeybindingEdited.bind(this)); this._keybindingEdit.connect('keybinding-edited', this._onKeybindingEdited.bind(this));
this.add_actor(this._keybindingEdit); this.actor.add_actor(this._keybindingEdit.actor);
this._doneButton = new St.Button({ label: _("Done"), this._doneButton = new St.Button({ label: _("Done"),
style_class: 'button', style_class: 'button',
x_expand: false }); x_expand: false });
this._doneButton.connect('clicked', this._onEditingDone.bind(this)); this._doneButton.connect('clicked', this._onEditingDone.bind(this));
this.add_actor(this._doneButton); this.actor.add_actor(this._doneButton);
} }
_updateKeybindingEntryState() { _updateKeybindingEntryState() {
if (this._currentAction == GDesktopEnums.PadButtonAction.KEYBINDING) { if (this._currentAction == GDesktopEnums.PadButtonAction.KEYBINDING) {
this._keybindingEdit.set_text(this._currentKeybinding); this._keybindingEdit.actor.set_text(this._currentKeybinding);
this._keybindingEdit.show(); this._keybindingEdit.actor.show();
this._keybindingEdit.grab_key_focus(); this._keybindingEdit.actor.grab_key_focus();
} else { } else {
this._keybindingEdit.hide(); this._keybindingEdit.actor.hide();
} }
} }
@@ -242,7 +238,7 @@ var ActionEditor = GObject.registerClass({
close() { close() {
this._actionComboBox.popdown(); this._actionComboBox.popdown();
this.hide(); this.actor.hide();
} }
_onKeybindingEdited(entry, keybinding) { _onKeybindingEdited(entry, keybinding) {
@@ -276,7 +272,8 @@ var ActionEditor = GObject.registerClass({
this.close(); this.close();
this.emit('done'); this.emit('done');
} }
}); };
Signals.addSignalMethods(ActionEditor.prototype);
var PadDiagram = GObject.registerClass({ var PadDiagram = GObject.registerClass({
Properties: { Properties: {
@@ -618,18 +615,8 @@ var PadDiagram = GObject.registerClass({
} }
}); });
var PadOsd = GObject.registerClass({ var PadOsd = class {
Signals: { 'pad-selected': { param_types: [Clutter.InputDevice.$gtype] } } constructor(padDevice, settings, imagePath, editionMode, monitorIndex) {
}, class PadOsd extends St.BoxLayout {
_init(padDevice, settings, imagePath, editionMode, monitorIndex) {
super._init({
style_class: 'pad-osd-window',
vertical: true,
x_expand: true,
y_expand: true,
reactive: true
});
this.padDevice = padDevice; this.padDevice = padDevice;
this._groupPads = [padDevice]; this._groupPads = [padDevice];
this._settings = settings; this._settings = settings;
@@ -666,18 +653,23 @@ var PadOsd = GObject.registerClass({
this._groupPads.push(device); this._groupPads.push(device);
}); });
this.connect('destroy', this._onDestroy.bind(this)); this.actor = new St.BoxLayout({ style_class: 'pad-osd-window',
Main.uiGroup.add_actor(this); x_expand: true,
y_expand: true,
vertical: true,
reactive: true });
this.actor.connect('destroy', this._onDestroy.bind(this));
Main.uiGroup.add_actor(this.actor);
this._monitorIndex = monitorIndex; this._monitorIndex = monitorIndex;
let constraint = new Layout.MonitorConstraint({ index: monitorIndex }); let constraint = new Layout.MonitorConstraint({ index: monitorIndex });
this.add_constraint(constraint); this.actor.add_constraint(constraint);
this._titleBox = new St.BoxLayout({ style_class: 'pad-osd-title-box', this._titleBox = new St.BoxLayout({ style_class: 'pad-osd-title-box',
vertical: false, vertical: false,
x_expand: false, x_expand: false,
x_align: Clutter.ActorAlign.CENTER }); x_align: Clutter.ActorAlign.CENTER });
this.add_actor(this._titleBox); this.actor.add_actor(this._titleBox);
let labelBox = new St.BoxLayout({ style_class: 'pad-osd-title-menu-box', let labelBox = new St.BoxLayout({ style_class: 'pad-osd-title-menu-box',
vertical: true }); vertical: true });
@@ -698,10 +690,10 @@ var PadOsd = GObject.registerClass({
this._padDiagram = new PadDiagram({ image: this._imagePath, this._padDiagram = new PadDiagram({ image: this._imagePath,
left_handed: settings.get_boolean('left-handed'), left_handed: settings.get_boolean('left-handed'),
editor_actor: this._actionEditor, editor_actor: this._actionEditor.actor,
x_expand: true, x_expand: true,
y_expand: true }); y_expand: true });
this.add_actor(this._padDiagram); this.actor.add_actor(this._padDiagram);
// FIXME: Fix num buttons. // FIXME: Fix num buttons.
let i = 0; let i = 0;
@@ -732,7 +724,7 @@ var PadOsd = GObject.registerClass({
x_expand: true, x_expand: true,
x_align: Clutter.ActorAlign.CENTER, x_align: Clutter.ActorAlign.CENTER,
y_align: Clutter.ActorAlign.CENTER }); y_align: Clutter.ActorAlign.CENTER });
this.add_actor(buttonBox); this.actor.add_actor(buttonBox);
this._editButton = new St.Button({ label: _("Edit…"), this._editButton = new St.Button({ label: _("Edit…"),
style_class: 'button', style_class: 'button',
x_align: Clutter.ActorAlign.CENTER, x_align: Clutter.ActorAlign.CENTER,
@@ -743,7 +735,7 @@ var PadOsd = GObject.registerClass({
buttonBox.add_actor(this._editButton); buttonBox.add_actor(this._editButton);
this._syncEditionMode(); this._syncEditionMode();
Main.pushModal(this); Main.pushModal(this.actor);
} }
_updatePadChooser() { _updatePadChooser() {
@@ -753,7 +745,7 @@ var PadOsd = GObject.registerClass({
this._padChooser.connect('pad-selected', (chooser, pad) => { this._padChooser.connect('pad-selected', (chooser, pad) => {
this._requestForOtherPad(pad); this._requestForOtherPad(pad);
}); });
this._titleBox.add_child(this._padChooser); this._titleBox.add_child(this._padChooser.actor);
} else { } else {
this._padChooser.update(this._groupPads); this._padChooser.update(this._groupPads);
} }
@@ -926,8 +918,12 @@ var PadOsd = GObject.registerClass({
this._syncEditionMode(); this._syncEditionMode();
} }
destroy() {
this.actor.destroy();
}
_onDestroy() { _onDestroy() {
Main.popModal(this); Main.popModal(this.actor);
this._actionEditor.close(); this._actionEditor.close();
let deviceManager = Clutter.DeviceManager.get_default(); let deviceManager = Clutter.DeviceManager.get_default();
@@ -945,9 +941,11 @@ var PadOsd = GObject.registerClass({
this._capturedEventId = 0; this._capturedEventId = 0;
} }
this.actor = null;
this.emit('closed'); this.emit('closed');
} }
}); };
Signals.addSignalMethods(PadOsd.prototype);
const PadOsdIface = loadInterfaceXML('org.gnome.Shell.Wacom.PadOsd'); const PadOsdIface = loadInterfaceXML('org.gnome.Shell.Wacom.PadOsd');

View File

@@ -20,17 +20,14 @@ var ANIMATION_DELAY = 100;
var PageIndicators = GObject.registerClass({ var PageIndicators = GObject.registerClass({
Signals: { 'page-activated': { param_types: [GObject.TYPE_INT] } } Signals: { 'page-activated': { param_types: [GObject.TYPE_INT] } }
}, class PageIndicators extends St.BoxLayout { }, class PageIndicators extends St.BoxLayout {
_init(orientation = Clutter.Orientation.VERTICAL) { _init(vertical = true) {
let vertical = orientation == Clutter.Orientation.VERTICAL; super._init({ style_class: 'page-indicators',
super._init({ vertical,
style_class: 'page-indicators', x_expand: true, y_expand: true,
vertical, x_align: vertical ? Clutter.ActorAlign.END : Clutter.ActorAlign.CENTER,
x_expand: true, y_expand: true, y_align: vertical ? Clutter.ActorAlign.CENTER : Clutter.ActorAlign.END,
x_align: vertical ? Clutter.ActorAlign.END : Clutter.ActorAlign.CENTER, reactive: true,
y_align: vertical ? Clutter.ActorAlign.CENTER : Clutter.ActorAlign.END, clip_to_allocation: true });
reactive: true,
clip_to_allocation: true
});
this._nPages = 0; this._nPages = 0;
this._currentPage = undefined; this._currentPage = undefined;
this._reactive = true; this._reactive = true;
@@ -96,26 +93,18 @@ var PageIndicators = GObject.registerClass({
var AnimatedPageIndicators = GObject.registerClass( var AnimatedPageIndicators = GObject.registerClass(
class AnimatedPageIndicators extends PageIndicators { class AnimatedPageIndicators extends PageIndicators {
_init() { _init() {
super._init(); super._init(true);
this.connect('destroy', this._onDestroy.bind(this));
}
_onDestroy() { this.connect('notify::mapped', () => {
if (this.animateLater) { if (!this.mapped)
Meta.later_remove(this.animateLater); return;
this.animateLater = 0;
}
}
vfunc_map() { // Implicit animations are skipped for unmapped actors, and our
super.vfunc_map(); // children aren't mapped yet, so defer to a later handler
Meta.later_add(Meta.LaterType.BEFORE_REDRAW, () => {
// Implicit animations are skipped for unmapped actors, and our this.animateIndicators(AnimationDirection.IN);
// children aren't mapped yet, so defer to a later handler return GLib.SOURCE_REMOVE;
this.animateLater = Meta.later_add(Meta.LaterType.BEFORE_REDRAW, () => { });
this.animateLater = 0;
this.animateIndicators(AnimationDirection.IN);
return GLib.SOURCE_REMOVE;
}); });
} }

View File

@@ -235,7 +235,7 @@ var AppMenuButton = GObject.registerClass({
this._overviewShowingId = Main.overview.connect('showing', this._sync.bind(this)); this._overviewShowingId = Main.overview.connect('showing', this._sync.bind(this));
this._spinner = new Animation.Spinner(PANEL_ICON_SIZE, true); this._spinner = new Animation.Spinner(PANEL_ICON_SIZE, true);
this._container.add_actor(this._spinner); this._container.add_actor(this._spinner.actor);
let menu = new AppMenu(this); let menu = new AppMenu(this);
this.setMenu(menu); this.setMenu(menu);
@@ -430,6 +430,9 @@ class ActivitiesButton extends PanelMenu.Button {
this.label_actor = this._label; this.label_actor = this._label;
this.connect('captured-event', this._onCapturedEvent.bind(this));
this.connect_after('key-release-event', this._onKeyRelease.bind(this));
Main.overview.connect('showing', () => { Main.overview.connect('showing', () => {
this.add_style_pseudo_class('overview'); this.add_style_pseudo_class('overview');
this.add_accessible_state (Atk.StateType.CHECKED); this.add_accessible_state (Atk.StateType.CHECKED);
@@ -456,7 +459,7 @@ class ActivitiesButton extends PanelMenu.Button {
return DND.DragMotionResult.CONTINUE; return DND.DragMotionResult.CONTINUE;
} }
vfunc_captured_event(event) { _onCapturedEvent(actor, event) {
if (event.type() == Clutter.EventType.BUTTON_PRESS || if (event.type() == Clutter.EventType.BUTTON_PRESS ||
event.type() == Clutter.EventType.TOUCH_BEGIN) { event.type() == Clutter.EventType.TOUCH_BEGIN) {
if (!Main.overview.shouldToggleByCornerOrButton()) if (!Main.overview.shouldToggleByCornerOrButton())
@@ -465,7 +468,9 @@ class ActivitiesButton extends PanelMenu.Button {
return Clutter.EVENT_PROPAGATE; return Clutter.EVENT_PROPAGATE;
} }
vfunc_event(event) { _onEvent(actor, event) {
super._onEvent(actor, event);
if (event.type() == Clutter.EventType.TOUCH_END || if (event.type() == Clutter.EventType.TOUCH_END ||
event.type() == Clutter.EventType.BUTTON_RELEASE) event.type() == Clutter.EventType.BUTTON_RELEASE)
if (Main.overview.shouldToggleByCornerOrButton()) if (Main.overview.shouldToggleByCornerOrButton())
@@ -474,16 +479,13 @@ class ActivitiesButton extends PanelMenu.Button {
return Clutter.EVENT_PROPAGATE; return Clutter.EVENT_PROPAGATE;
} }
vfunc_key_release_event(keyEvent) { _onKeyRelease(actor, event) {
let ret = super.vfunc_key_release_event(keyEvent); let symbol = event.get_key_symbol();
if (ret == Clutter.EVENT_PROPAGATE) { if (symbol == Clutter.KEY_Return || symbol == Clutter.KEY_space) {
let symbol = keyEvent.keyval; if (Main.overview.shouldToggleByCornerOrButton())
if (symbol == Clutter.KEY_Return || symbol == Clutter.KEY_space) { Main.overview.toggle();
if (Main.overview.shouldToggleByCornerOrButton())
Main.overview.toggle();
}
} }
return ret; return Clutter.EVENT_PROPAGATE;
} }
_xdndToggleOverview() { _xdndToggleOverview() {
@@ -499,12 +501,13 @@ class ActivitiesButton extends PanelMenu.Button {
} }
}); });
var PanelCorner = GObject.registerClass( var PanelCorner = class {
class PanelCorner extends St.DrawingArea { constructor(side) {
_init(side) {
this._side = side; this._side = side;
super._init({ style_class: 'panel-corner' }); this.actor = new St.DrawingArea({ style_class: 'panel-corner' });
this.actor.connect('style-changed', this._styleChanged.bind(this));
this.actor.connect('repaint', this._repaint.bind(this));
} }
_findRightmostButton(container) { _findRightmostButton(container) {
@@ -594,7 +597,7 @@ class PanelCorner extends St.DrawingArea {
this._buttonStyleChangedSignalId = button.connect('style-changed', this._buttonStyleChangedSignalId = button.connect('style-changed',
() => { () => {
let pseudoClass = button.get_style_pseudo_class(); let pseudoClass = button.get_style_pseudo_class();
this.set_style_pseudo_class(pseudoClass); this.actor.set_style_pseudo_class(pseudoClass);
}); });
// The corner doesn't support theme transitions, so override // The corner doesn't support theme transitions, so override
@@ -603,8 +606,8 @@ class PanelCorner extends St.DrawingArea {
} }
} }
vfunc_repaint() { _repaint() {
let node = this.get_theme_node(); let node = this.actor.get_theme_node();
let cornerRadius = node.get_length("-panel-corner-radius"); let cornerRadius = node.get_length("-panel-corner-radius");
let borderWidth = node.get_length('-panel-corner-border-width'); let borderWidth = node.get_length('-panel-corner-border-width');
@@ -615,7 +618,7 @@ class PanelCorner extends St.DrawingArea {
let overlap = borderColor.alpha != 0; let overlap = borderColor.alpha != 0;
let offsetY = overlap ? 0 : borderWidth; let offsetY = overlap ? 0 : borderWidth;
let cr = this.get_context(); let cr = this.actor.get_context();
cr.setOperator(Cairo.Operator.SOURCE); cr.setOperator(Cairo.Operator.SOURCE);
cr.moveTo(0, offsetY); cr.moveTo(0, offsetY);
@@ -651,17 +654,16 @@ class PanelCorner extends St.DrawingArea {
cr.$dispose(); cr.$dispose();
} }
vfunc_style_changed() { _styleChanged() {
super.vfunc_style_changed(); let node = this.actor.get_theme_node();
let node = this.get_theme_node();
let cornerRadius = node.get_length("-panel-corner-radius"); let cornerRadius = node.get_length("-panel-corner-radius");
let borderWidth = node.get_length('-panel-corner-border-width'); let borderWidth = node.get_length('-panel-corner-border-width');
this.set_size(cornerRadius, borderWidth + cornerRadius); this.actor.set_size(cornerRadius, borderWidth + cornerRadius);
this.set_anchor_point(0, borderWidth); this.actor.set_anchor_point(0, borderWidth);
} }
}); };
var AggregateLayout = GObject.registerClass( var AggregateLayout = GObject.registerClass(
class AggregateLayout extends Clutter.BoxLayout { class AggregateLayout extends Clutter.BoxLayout {
@@ -726,20 +728,20 @@ class AggregateMenu extends PanelMenu.Button {
this._nightLight = new imports.ui.status.nightLight.Indicator(); this._nightLight = new imports.ui.status.nightLight.Indicator();
this._thunderbolt = new imports.ui.status.thunderbolt.Indicator(); this._thunderbolt = new imports.ui.status.thunderbolt.Indicator();
this._indicators.add_child(this._thunderbolt); this._indicators.add_child(this._thunderbolt.indicators);
this._indicators.add_child(this._screencast); this._indicators.add_child(this._screencast.indicators);
this._indicators.add_child(this._location); this._indicators.add_child(this._location.indicators);
this._indicators.add_child(this._nightLight); this._indicators.add_child(this._nightLight.indicators);
if (this._network) { if (this._network) {
this._indicators.add_child(this._network); this._indicators.add_child(this._network.indicators);
} }
if (this._bluetooth) { if (this._bluetooth) {
this._indicators.add_child(this._bluetooth); this._indicators.add_child(this._bluetooth.indicators);
} }
this._indicators.add_child(this._remoteAccess); this._indicators.add_child(this._remoteAccess.indicators);
this._indicators.add_child(this._rfkill); this._indicators.add_child(this._rfkill.indicators);
this._indicators.add_child(this._volume); this._indicators.add_child(this._volume.indicators);
this._indicators.add_child(this._power); this._indicators.add_child(this._power.indicators);
this._indicators.add_child(PopupMenu.arrowIcon(St.Side.BOTTOM)); this._indicators.add_child(PopupMenu.arrowIcon(St.Side.BOTTOM));
this.menu.addMenuItem(this._volume.menu); this.menu.addMenuItem(this._volume.menu);
@@ -797,10 +799,14 @@ class Panel extends St.Widget {
this.add_child(this._rightBox); this.add_child(this._rightBox);
this._leftCorner = new PanelCorner(St.Side.LEFT); this._leftCorner = new PanelCorner(St.Side.LEFT);
this.add_child(this._leftCorner); this.add_child(this._leftCorner.actor);
this._rightCorner = new PanelCorner(St.Side.RIGHT); this._rightCorner = new PanelCorner(St.Side.RIGHT);
this.add_child(this._rightCorner); this.add_child(this._rightCorner.actor);
this.connect('button-press-event', this._onButtonPress.bind(this));
this.connect('touch-event', this._onButtonPress.bind(this));
this.connect('key-press-event', this._onKeyPress.bind(this));
Main.overview.connect('showing', () => { Main.overview.connect('showing', () => {
this.add_style_pseudo_class('overview'); this.add_style_pseudo_class('overview');
@@ -889,65 +895,62 @@ class Panel extends St.Widget {
let cornerWidth, cornerHeight; let cornerWidth, cornerHeight;
[, cornerWidth] = this._leftCorner.get_preferred_width(-1); [, cornerWidth] = this._leftCorner.actor.get_preferred_width(-1);
[, cornerHeight] = this._leftCorner.get_preferred_height(-1); [, cornerHeight] = this._leftCorner.actor.get_preferred_height(-1);
childBox.x1 = 0; childBox.x1 = 0;
childBox.x2 = cornerWidth; childBox.x2 = cornerWidth;
childBox.y1 = allocHeight; childBox.y1 = allocHeight;
childBox.y2 = allocHeight + cornerHeight; childBox.y2 = allocHeight + cornerHeight;
this._leftCorner.allocate(childBox, flags); this._leftCorner.actor.allocate(childBox, flags);
[, cornerWidth] = this._rightCorner.get_preferred_width(-1); [, cornerWidth] = this._rightCorner.actor.get_preferred_width(-1);
[, cornerHeight] = this._rightCorner.get_preferred_height(-1); [, cornerHeight] = this._rightCorner.actor.get_preferred_height(-1);
childBox.x1 = allocWidth - cornerWidth; childBox.x1 = allocWidth - cornerWidth;
childBox.x2 = allocWidth; childBox.x2 = allocWidth;
childBox.y1 = allocHeight; childBox.y1 = allocHeight;
childBox.y2 = allocHeight + cornerHeight; childBox.y2 = allocHeight + cornerHeight;
this._rightCorner.allocate(childBox, flags); this._rightCorner.actor.allocate(childBox, flags);
} }
_tryDragWindow(event) { _onButtonPress(actor, event) {
if (Main.modalCount > 0) if (Main.modalCount > 0)
return Clutter.EVENT_PROPAGATE; return Clutter.EVENT_PROPAGATE;
if (event.source != this) if (event.get_source() != actor)
return Clutter.EVENT_PROPAGATE; return Clutter.EVENT_PROPAGATE;
let { x, y } = event; let type = event.type();
let dragWindow = this._getDraggableWindowForPosition(x); let isPress = type == Clutter.EventType.BUTTON_PRESS;
if (!isPress && type != Clutter.EventType.TOUCH_BEGIN)
return Clutter.EVENT_PROPAGATE;
let button = isPress ? event.get_button() : -1;
if (isPress && button != 1)
return Clutter.EVENT_PROPAGATE;
let [stageX, stageY] = event.get_coords();
let dragWindow = this._getDraggableWindowForPosition(stageX);
if (!dragWindow) if (!dragWindow)
return Clutter.EVENT_PROPAGATE; return Clutter.EVENT_PROPAGATE;
return global.display.begin_grab_op( global.display.begin_grab_op(dragWindow,
dragWindow, Meta.GrabOp.MOVING,
Meta.GrabOp.MOVING, false, /* pointer grab */
false, /* pointer grab */ true, /* frame action */
true, /* frame action */ button,
event.button || -1, event.get_state(),
event.modifier_state, event.get_time(),
event.time, stageX, stageY);
x, y) ? Clutter.EVENT_STOP : Clutter.EVENT_PROPAGATE;
return Clutter.EVENT_STOP;
} }
vfunc_button_press_event(buttonEvent) { _onKeyPress(actor, event) {
if (buttonEvent.button != 1) let symbol = event.get_key_symbol();
return Clutter.EVENT_PROPAGATE;
return this._tryDragWindow(buttonEvent);
}
vfunc_touch_event(touchEvent) {
if (touchEvent.type != Clutter.EventType.TOUCH_BEGIN)
return Clutter.EVENT_PROPAGATE;
return this._tryDragWindow(touchEvent);
}
vfunc_key_press_event(keyEvent) {
let symbol = keyEvent.keyval;
if (symbol == Clutter.KEY_Escape) { if (symbol == Clutter.KEY_Escape) {
global.display.focus_default_window(keyEvent.time); global.display.focus_default_window(event.get_time());
return Clutter.EVENT_STOP; return Clutter.EVENT_STOP;
} }
@@ -1111,14 +1114,14 @@ class Panel extends St.Widget {
_addStyleClassName(className) { _addStyleClassName(className) {
this.add_style_class_name(className); this.add_style_class_name(className);
this._rightCorner.add_style_class_name(className); this._rightCorner.actor.add_style_class_name(className);
this._leftCorner.add_style_class_name(className); this._leftCorner.actor.add_style_class_name(className);
} }
_removeStyleClassName(className) { _removeStyleClassName(className) {
this.remove_style_class_name(className); this.remove_style_class_name(className);
this._rightCorner.remove_style_class_name(className); this._rightCorner.actor.remove_style_class_name(className);
this._leftCorner.remove_style_class_name(className); this._leftCorner.actor.remove_style_class_name(className);
} }
_onMenuSet(indicator) { _onMenuSet(indicator) {

View File

@@ -2,6 +2,7 @@
/* exported Button, SystemIndicator */ /* exported Button, SystemIndicator */
const { Atk, Clutter, GObject, St } = imports.gi; const { Atk, Clutter, GObject, St } = imports.gi;
const Signals = imports.signals;
const Main = imports.ui.main; const Main = imports.ui.main;
const Params = imports.misc.params; const Params = imports.misc.params;
@@ -100,6 +101,9 @@ var Button = GObject.registerClass({
accessible_name: nameText ? nameText : "", accessible_name: nameText ? nameText : "",
accessible_role: Atk.Role.MENU }); accessible_role: Atk.Role.MENU });
this.connect('event', this._onEvent.bind(this));
this.connect('notify::visible', this._onVisibilityChanged.bind(this));
if (dontCreateMenu) if (dontCreateMenu)
this.menu = new PopupMenu.PopupDummyMenu(this); this.menu = new PopupMenu.PopupDummyMenu(this);
else else
@@ -128,7 +132,7 @@ var Button = GObject.registerClass({
this.emit('menu-set'); this.emit('menu-set');
} }
vfunc_event(event) { _onEvent(actor, event) {
if (this.menu && if (this.menu &&
(event.type() == Clutter.EventType.TOUCH_BEGIN || (event.type() == Clutter.EventType.TOUCH_BEGIN ||
event.type() == Clutter.EventType.BUTTON_PRESS)) event.type() == Clutter.EventType.BUTTON_PRESS))
@@ -137,10 +141,11 @@ var Button = GObject.registerClass({
return Clutter.EVENT_PROPAGATE; return Clutter.EVENT_PROPAGATE;
} }
vfunc_hide() { _onVisibilityChanged() {
super.vfunc_hide(); if (!this.menu)
return;
if (this.menu) if (!this.visible)
this.menu.close(); this.menu.close();
} }
@@ -195,34 +200,24 @@ var Button = GObject.registerClass({
* of an icon and a menu section, which will be composed into the * of an icon and a menu section, which will be composed into the
* aggregate menu. * aggregate menu.
*/ */
var SystemIndicator = GObject.registerClass({ var SystemIndicator = class {
GTypeName: 'PanelMenu_SystemIndicator', constructor() {
}, class SystemIndicator extends St.BoxLayout { this.indicators = new St.BoxLayout({ style_class: 'panel-status-indicators-box',
_init() { reactive: true });
super._init({ this.indicators.hide();
style_class: 'panel-status-indicators-box',
reactive: true,
visible: false
});
this.menu = new PopupMenu.PopupMenuSection(); this.menu = new PopupMenu.PopupMenuSection();
} }
get indicators() {
let klass = this.constructor.name;
let { stack } = new Error();
log(`Usage of indicator.indicators is deprecated for ${klass}\n${stack}`);
return this;
}
_syncIndicatorsVisible() { _syncIndicatorsVisible() {
this.visible = this.get_children().some(a => a.visible); this.indicators.visible = this.indicators.get_children().some(a => a.visible);
} }
_addIndicator() { _addIndicator() {
let icon = new St.Icon({ style_class: 'system-status-icon' }); let icon = new St.Icon({ style_class: 'system-status-icon' });
this.add_actor(icon); this.indicators.add_actor(icon);
icon.connect('notify::visible', this._syncIndicatorsVisible.bind(this)); icon.connect('notify::visible', this._syncIndicatorsVisible.bind(this));
this._syncIndicatorsVisible(); this._syncIndicatorsVisible();
return icon; return icon;
} }
}); };
Signals.addSignalMethods(SystemIndicator.prototype);

View File

@@ -3,7 +3,7 @@
PopupImageMenuItem, PopupMenu, PopupDummyMenu, PopupSubMenu, PopupImageMenuItem, PopupMenu, PopupDummyMenu, PopupSubMenu,
PopupMenuSection, PopupSubMenuMenuItem, PopupMenuManager */ PopupMenuSection, PopupSubMenuMenuItem, PopupMenuManager */
const { Atk, Clutter, Gio, GObject, Graphene, Shell, St } = imports.gi; const { Atk, Clutter, Gio, GObject, Shell, St } = imports.gi;
const Signals = imports.signals; const Signals = imports.signals;
const BoxPointer = imports.ui.boxpointer; const BoxPointer = imports.ui.boxpointer;
@@ -97,6 +97,12 @@ var PopupBaseMenuItem = GObject.registerClass({
if (params.style_class) if (params.style_class)
this.add_style_class_name(params.style_class); this.add_style_class_name(params.style_class);
if (this._activatable) {
this.connect('button-press-event', this._onButtonPressEvent.bind(this));
this.connect('button-release-event', this._onButtonReleaseEvent.bind(this));
this.connect('touch-event', this._onTouchEvent.bind(this));
this.connect('key-press-event', this._onKeyPressEvent.bind(this));
}
if (params.reactive && params.hover) if (params.reactive && params.hover)
this.bind_property('hover', this, 'active', GObject.BindingFlags.SYNC_CREATE); this.bind_property('hover', this, 'active', GObject.BindingFlags.SYNC_CREATE);
} }
@@ -118,44 +124,32 @@ var PopupBaseMenuItem = GObject.registerClass({
this._parent = parent; this._parent = parent;
} }
vfunc_button_press_event(buttonEvent) { _onButtonPressEvent() {
if (!this._activatable)
return super.vfunc_button_press_event(buttonEvent);
// This is the CSS active state // This is the CSS active state
this.add_style_pseudo_class('active'); this.add_style_pseudo_class('active');
return Clutter.EVENT_PROPAGATE; return Clutter.EVENT_PROPAGATE;
} }
vfunc_button_release_event(buttonEvent) { _onButtonReleaseEvent(actor, event) {
if (!this._activatable)
return super.vfunc_button_release_event(buttonEvent);
this.remove_style_pseudo_class('active'); this.remove_style_pseudo_class('active');
this.activate(Clutter.get_current_event()); this.activate(event);
return Clutter.EVENT_STOP; return Clutter.EVENT_STOP;
} }
vfunc_touch_event(touchEvent) { _onTouchEvent(actor, event) {
if (!this._activatable) if (event.type() == Clutter.EventType.TOUCH_END) {
return super.vfunc_touch_event(touchEvent);
if (touchEvent.type == Clutter.EventType.TOUCH_END) {
this.remove_style_pseudo_class('active'); this.remove_style_pseudo_class('active');
this.activate(Clutter.get_current_event()); this.activate(event);
return Clutter.EVENT_STOP; return Clutter.EVENT_STOP;
} else if (touchEvent.type == Clutter.EventType.TOUCH_BEGIN) { } else if (event.type() == Clutter.EventType.TOUCH_BEGIN) {
// This is the CSS active state // This is the CSS active state
this.add_style_pseudo_class('active'); this.add_style_pseudo_class('active');
} }
return Clutter.EVENT_PROPAGATE; return Clutter.EVENT_PROPAGATE;
} }
vfunc_key_press_event(keyEvent) { _onKeyPressEvent(actor, event) {
if (!this._activatable) let state = event.get_state();
return super.vfunc_key_press_event(keyEvent);
let state = keyEvent.modifier_state;
// if user has a modifier down (except capslock and numlock) // if user has a modifier down (except capslock and numlock)
// then don't handle the key press here // then don't handle the key press here
@@ -166,9 +160,9 @@ var PopupBaseMenuItem = GObject.registerClass({
if (state) if (state)
return Clutter.EVENT_PROPAGATE; return Clutter.EVENT_PROPAGATE;
let symbol = keyEvent.keyval; let symbol = event.get_key_symbol();
if (symbol == Clutter.KEY_space || symbol == Clutter.KEY_Return) { if (symbol == Clutter.KEY_space || symbol == Clutter.KEY_Return) {
this.activate(Clutter.get_current_event()); this.activate(event);
return Clutter.EVENT_STOP; return Clutter.EVENT_STOP;
} }
return Clutter.EVENT_PROPAGATE; return Clutter.EVENT_PROPAGATE;
@@ -1136,7 +1130,7 @@ class PopupSubMenuMenuItem extends PopupBaseMenuItem {
this.add(expander, { expand: true }); this.add(expander, { expand: true });
this._triangle = arrowIcon(St.Side.RIGHT); this._triangle = arrowIcon(St.Side.RIGHT);
this._triangle.pivot_point = new Graphene.Point({ x: 0.5, y: 0.6 }); this._triangle.pivot_point = new Clutter.Point({ x: 0.5, y: 0.6 });
this._triangleBin = new St.Widget({ y_expand: true, this._triangleBin = new St.Widget({ y_expand: true,
y_align: Clutter.ActorAlign.CENTER }); y_align: Clutter.ActorAlign.CENTER });
@@ -1191,8 +1185,8 @@ class PopupSubMenuMenuItem extends PopupBaseMenuItem {
return this.menu.isOpen; return this.menu.isOpen;
} }
vfunc_key_press_event(keyPressEvent) { _onKeyPressEvent(actor, event) {
let symbol = keyPressEvent.keyval; let symbol = event.get_key_symbol();
if (symbol == Clutter.KEY_Right) { if (symbol == Clutter.KEY_Right) {
this._setOpenState(true); this._setOpenState(true);
@@ -1203,14 +1197,14 @@ class PopupSubMenuMenuItem extends PopupBaseMenuItem {
return Clutter.EVENT_STOP; return Clutter.EVENT_STOP;
} }
return super.vfunc_key_press_event(keyPressEvent); return super._onKeyPressEvent(actor, event);
} }
activate(_event) { activate(_event) {
this._setOpenState(true); this._setOpenState(true);
} }
vfunc_button_release_event() { _onButtonReleaseEvent() {
// Since we override the parent, we need to manage what the parent does // Since we override the parent, we need to manage what the parent does
// with the active style class // with the active style class
this.remove_style_pseudo_class('active'); this.remove_style_pseudo_class('active');
@@ -1218,8 +1212,8 @@ class PopupSubMenuMenuItem extends PopupBaseMenuItem {
return Clutter.EVENT_PROPAGATE; return Clutter.EVENT_PROPAGATE;
} }
vfunc_touch_event(touchEvent) { _onTouchEvent(actor, event) {
if (touchEvent.type == Clutter.EventType.TOUCH_END) { if (event.type() == Clutter.EventType.TOUCH_END) {
// Since we override the parent, we need to manage what the parent does // Since we override the parent, we need to manage what the parent does
// with the active style class // with the active style class
this.remove_style_pseudo_class('active'); this.remove_style_pseudo_class('active');

File diff suppressed because it is too large Load Diff

View File

@@ -1,7 +1,8 @@
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*- // -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
/* exported ScreenshotService */ /* exported ScreenshotService */
const { Clutter, Graphene, Gio, GObject, GLib, Meta, Shell, St } = imports.gi; const { Clutter, Gio, GLib, Meta, Shell, St } = imports.gi;
const Signals = imports.signals;
const GrabHelper = imports.ui.grabHelper; const GrabHelper = imports.ui.grabHelper;
const Lightbox = imports.ui.lightbox; const Lightbox = imports.ui.lightbox;
@@ -197,7 +198,7 @@ var ScreenshotService = class {
let screenshot = this._createScreenshot(invocation, false); let screenshot = this._createScreenshot(invocation, false);
if (!screenshot) if (!screenshot)
return; return;
screenshot.pick_color(coords.x, coords.y, (_o, res) => { screenshot.pick_color(...coords, (o, res) => {
let [success_, color] = screenshot.pick_color_finish(res); let [success_, color] = screenshot.pick_color_finish(res);
let { red, green, blue } = color; let { red, green, blue } = color;
let retval = GLib.Variant.new('(a{sv})', [{ let retval = GLib.Variant.new('(a{sv})', [{
@@ -218,62 +219,62 @@ var ScreenshotService = class {
} }
}; };
var SelectArea = GObject.registerClass({ var SelectArea = class {
GTypeName: 'Screenshot_SelectArea', constructor() {
Signals: { 'finished': { param_types: [Meta.Rectangle.$gtype] } }
}, class SelectArea extends St.Widget {
_init() {
this._startX = -1; this._startX = -1;
this._startY = -1; this._startY = -1;
this._lastX = 0; this._lastX = 0;
this._lastY = 0; this._lastY = 0;
this._result = null; this._result = null;
super._init({ this._group = new St.Widget({ visible: false,
visible: false, reactive: true,
reactive: true, x: 0,
x: 0, y: 0 });
y: 0 Main.uiGroup.add_actor(this._group);
});
Main.uiGroup.add_actor(this);
this._grabHelper = new GrabHelper.GrabHelper(this); this._grabHelper = new GrabHelper.GrabHelper(this._group);
this._group.connect('button-press-event',
this._onButtonPress.bind(this));
this._group.connect('button-release-event',
this._onButtonRelease.bind(this));
this._group.connect('motion-event',
this._onMotionEvent.bind(this));
let constraint = new Clutter.BindConstraint({ source: global.stage, let constraint = new Clutter.BindConstraint({ source: global.stage,
coordinate: Clutter.BindCoordinate.ALL }); coordinate: Clutter.BindCoordinate.ALL });
this.add_constraint(constraint); this._group.add_constraint(constraint);
this._rubberband = new St.Widget({ this._rubberband = new St.Widget({
style_class: 'select-area-rubberband', style_class: 'select-area-rubberband',
visible: false visible: false
}); });
this.add_actor(this._rubberband); this._group.add_actor(this._rubberband);
} }
vfunc_show() { show() {
if (!this._grabHelper.grab({ actor: this, if (!this._grabHelper.grab({ actor: this._group,
onUngrab: this._onUngrab.bind(this) })) onUngrab: this._onUngrab.bind(this) }))
return; return;
global.display.set_cursor(Meta.Cursor.CROSSHAIR); global.display.set_cursor(Meta.Cursor.CROSSHAIR);
Main.uiGroup.set_child_above_sibling(this, null); Main.uiGroup.set_child_above_sibling(this._group, null);
super.vfunc_show(); this._group.visible = true;
} }
_getGeometry() { _getGeometry() {
return new Meta.Rectangle({ return { x: Math.min(this._startX, this._lastX),
x: Math.min(this._startX, this._lastX), y: Math.min(this._startY, this._lastY),
y: Math.min(this._startY, this._lastY), width: Math.abs(this._startX - this._lastX) + 1,
width: Math.abs(this._startX - this._lastX) + 1, height: Math.abs(this._startY - this._lastY) + 1 };
height: Math.abs(this._startY - this._lastY) + 1
});
} }
vfunc_motion_event(motionEvent) { _onMotionEvent(actor, event) {
if (this._startX == -1 || this._startY == -1 || this._result) if (this._startX == -1 || this._startY == -1 || this._result)
return Clutter.EVENT_PROPAGATE; return Clutter.EVENT_PROPAGATE;
[this._lastX, this._lastY] = [motionEvent.x, motionEvent.y]; [this._lastX, this._lastY] = event.get_coords();
this._lastX = Math.floor(this._lastX); this._lastX = Math.floor(this._lastX);
this._lastY = Math.floor(this._lastY); this._lastY = Math.floor(this._lastY);
let geometry = this._getGeometry(); let geometry = this._getGeometry();
@@ -285,8 +286,8 @@ var SelectArea = GObject.registerClass({
return Clutter.EVENT_PROPAGATE; return Clutter.EVENT_PROPAGATE;
} }
vfunc_button_press_event(buttonEvent) { _onButtonPress(actor, event) {
[this._startX, this._startY] = [buttonEvent.x, buttonEvent.y]; [this._startX, this._startY] = event.get_coords();
this._startX = Math.floor(this._startX); this._startX = Math.floor(this._startX);
this._startY = Math.floor(this._startY); this._startY = Math.floor(this._startY);
this._rubberband.set_position(this._startX, this._startY); this._rubberband.set_position(this._startX, this._startY);
@@ -294,9 +295,9 @@ var SelectArea = GObject.registerClass({
return Clutter.EVENT_PROPAGATE; return Clutter.EVENT_PROPAGATE;
} }
vfunc_button_release_event() { _onButtonRelease() {
this._result = this._getGeometry(); this._result = this._getGeometry();
this.ease({ this._group.ease({
opacity: 0, opacity: 0,
duration: 200, duration: 200,
mode: Clutter.AnimationMode.EASE_OUT_QUAD, mode: Clutter.AnimationMode.EASE_OUT_QUAD,
@@ -310,43 +311,43 @@ var SelectArea = GObject.registerClass({
this.emit('finished', this._result); this.emit('finished', this._result);
GLib.idle_add(GLib.PRIORITY_DEFAULT, () => { GLib.idle_add(GLib.PRIORITY_DEFAULT, () => {
this.destroy(); this._group.destroy();
return GLib.SOURCE_REMOVE; return GLib.SOURCE_REMOVE;
}); });
} }
}); };
Signals.addSignalMethods(SelectArea.prototype);
var PickPixel = GObject.registerClass({
GTypeName: 'Screenshot_PickPixel',
Signals: { 'finished': { param_types: [Graphene.Point.$gtype] } }
}, class PickPixel extends St.Widget {
_init() {
super._init({ visible: false, reactive: true });
var PickPixel = class {
constructor() {
this._result = null; this._result = null;
Main.uiGroup.add_actor(this); this._group = new St.Widget({ visible: false,
reactive: true });
Main.uiGroup.add_actor(this._group);
this._grabHelper = new GrabHelper.GrabHelper(this); this._grabHelper = new GrabHelper.GrabHelper(this._group);
this._group.connect('button-release-event',
this._onButtonRelease.bind(this));
let constraint = new Clutter.BindConstraint({ source: global.stage, let constraint = new Clutter.BindConstraint({ source: global.stage,
coordinate: Clutter.BindCoordinate.ALL }); coordinate: Clutter.BindCoordinate.ALL });
this.add_constraint(constraint); this._group.add_constraint(constraint);
} }
vfunc_show() { show() {
if (!this._grabHelper.grab({ actor: this, if (!this._grabHelper.grab({ actor: this._group,
onUngrab: this._onUngrab.bind(this) })) onUngrab: this._onUngrab.bind(this) }))
return; return;
global.display.set_cursor(Meta.Cursor.CROSSHAIR); global.display.set_cursor(Meta.Cursor.CROSSHAIR);
Main.uiGroup.set_child_above_sibling(this, null); Main.uiGroup.set_child_above_sibling(this._group, null);
super.vfunc_show(); this._group.visible = true;
} }
vfunc_button_release_event(buttonEvent) { _onButtonRelease(actor, event) {
let { x, y } = buttonEvent; this._result = event.get_coords();
this._result = new Graphene.Point({ x, y });
this._grabHelper.ungrab(); this._grabHelper.ungrab();
return Clutter.EVENT_PROPAGATE; return Clutter.EVENT_PROPAGATE;
} }
@@ -356,29 +357,29 @@ var PickPixel = GObject.registerClass({
this.emit('finished', this._result); this.emit('finished', this._result);
GLib.idle_add(GLib.PRIORITY_DEFAULT, () => { GLib.idle_add(GLib.PRIORITY_DEFAULT, () => {
this.destroy(); this._group.destroy();
return GLib.SOURCE_REMOVE; return GLib.SOURCE_REMOVE;
}); });
} }
}); };
Signals.addSignalMethods(PickPixel.prototype);
var FLASHSPOT_ANIMATION_OUT_TIME = 500; // milliseconds var FLASHSPOT_ANIMATION_OUT_TIME = 500; // milliseconds
var Flashspot = GObject.registerClass( var Flashspot = class extends Lightbox.Lightbox {
class Flashspot extends Lightbox.Lightbox { constructor(area) {
_init(area) { super(Main.uiGroup, { inhibitEvents: true,
super._init(Main.uiGroup, { width: area.width,
inhibitEvents: true, height: area.height });
width: area.width,
height: area.height this.actor.style_class = 'flashspot';
}); this.actor.set_position(area.x, area.y);
this.style_class = 'flashspot';
this.set_position(area.x, area.y);
} }
fire(doneCallback) { fire(doneCallback) {
this.set({ visible: true, opacity: 255 }); this.actor.show();
this.ease({ this.actor.opacity = 255;
this.actor.ease({
opacity: 0, opacity: 0,
duration: FLASHSPOT_ANIMATION_OUT_TIME, duration: FLASHSPOT_ANIMATION_OUT_TIME,
mode: Clutter.AnimationMode.EASE_OUT_QUAD, mode: Clutter.AnimationMode.EASE_OUT_QUAD,
@@ -389,4 +390,4 @@ class Flashspot extends Lightbox.Lightbox {
} }
}); });
} }
}); };

View File

@@ -1,7 +1,7 @@
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*- // -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
/* exported SearchResultsView */
const { Clutter, Gio, GLib, GObject, Meta, Shell, St } = imports.gi; const { Clutter, Gio, GLib, GObject, Meta, Shell, St } = imports.gi;
const Signals = imports.signals;
const AppDisplay = imports.ui.appDisplay; const AppDisplay = imports.ui.appDisplay;
const IconGrid = imports.ui.iconGrid; const IconGrid = imports.ui.iconGrid;
@@ -32,47 +32,39 @@ class MaxWidthBox extends St.BoxLayout {
} }
}); });
var SearchResult = GObject.registerClass( var SearchResult = class {
class SearchResult extends St.Button { constructor(provider, metaInfo, resultsView) {
_init(provider, metaInfo, resultsView) {
this.provider = provider; this.provider = provider;
this.metaInfo = metaInfo; this.metaInfo = metaInfo;
this._resultsView = resultsView; this._resultsView = resultsView;
super._init({ this.actor = new St.Button({ reactive: true,
reactive: true, can_focus: true,
can_focus: true, track_hover: true,
track_hover: true, x_align: St.Align.START,
x_align: St.Align.START, y_fill: true });
y_fill: true
});
}
vfunc_clicked() { this.actor._delegate = this;
this.activate(); this.actor.connect('clicked', this.activate.bind(this));
} }
activate() { activate() {
this.provider.activateResult(this.metaInfo.id, this._resultsView.terms); this.emit('activate', this.metaInfo.id);
if (this.metaInfo.clipboardText)
St.Clipboard.get_default().set_text(
St.ClipboardType.CLIPBOARD, this.metaInfo.clipboardText);
Main.overview.toggle();
} }
}); };
Signals.addSignalMethods(SearchResult.prototype);
var ListSearchResult = GObject.registerClass( var ListSearchResult = class extends SearchResult {
class ListSearchResult extends SearchResult {
_init(provider, metaInfo, resultsView) {
super._init(provider, metaInfo, resultsView);
this.style_class = 'list-search-result'; constructor(provider, metaInfo, resultsView) {
this.x_fill = true; super(provider, metaInfo, resultsView);
this.actor.style_class = 'list-search-result';
this.actor.x_fill = true;
let content = new St.BoxLayout({ style_class: 'list-search-result-content', let content = new St.BoxLayout({ style_class: 'list-search-result-content',
vertical: false }); vertical: false });
this.set_child(content); this.actor.set_child(content);
this._termsChangedId = 0; this._termsChangedId = 0;
@@ -95,7 +87,7 @@ class ListSearchResult extends SearchResult {
x_align: St.Align.START, x_align: St.Align.START,
y_align: St.Align.MIDDLE }); y_align: St.Align.MIDDLE });
this.label_actor = title; this.actor.label_actor = title;
if (this.metaInfo['description']) { if (this.metaInfo['description']) {
this._descriptionLabel = new St.Label({ style_class: 'list-search-result-description' }); this._descriptionLabel = new St.Label({ style_class: 'list-search-result-description' });
@@ -111,7 +103,7 @@ class ListSearchResult extends SearchResult {
this._highlightTerms(); this._highlightTerms();
} }
this.connect('destroy', this._onDestroy.bind(this)); this.actor.connect('destroy', this._onDestroy.bind(this));
} }
get ICON_SIZE() { get ICON_SIZE() {
@@ -128,53 +120,50 @@ class ListSearchResult extends SearchResult {
this._resultsView.disconnect(this._termsChangedId); this._resultsView.disconnect(this._termsChangedId);
this._termsChangedId = 0; this._termsChangedId = 0;
} }
}); };
var GridSearchResult = GObject.registerClass( var GridSearchResult = class extends SearchResult {
class GridSearchResult extends SearchResult { constructor(provider, metaInfo, resultsView) {
_init(provider, metaInfo, resultsView) { super(provider, metaInfo, resultsView);
super._init(provider, metaInfo, resultsView);
this.style_class = 'grid-search-result'; this.actor.style_class = 'grid-search-result';
this.icon = new IconGrid.BaseIcon(this.metaInfo['name'], this.icon = new IconGrid.BaseIcon(this.metaInfo['name'],
{ createIcon: this.metaInfo['createIcon'] }); { createIcon: this.metaInfo['createIcon'] });
let content = new St.Bin({ child: this.icon }); let content = new St.Bin({ child: this.icon });
this.set_child(content); this.actor.set_child(content);
this.label_actor = this.icon.label; this.actor.label_actor = this.icon.label;
} }
}); };
var SearchResultsBase = GObject.registerClass({
GTypeFlags: GObject.TypeFlags.ABSTRACT,
Properties: {
'focus-child': GObject.ParamSpec.object(
'focus-child', 'focus-child', 'focus-child',
GObject.ParamFlags.READABLE,
Clutter.Actor.$gtype),
}
}, class SearchResultsBase extends St.BoxLayout {
_init(provider, resultsView) {
super._init({ style_class: 'search-section', vertical: true });
var SearchResultsBase = class {
constructor(provider, resultsView) {
this.provider = provider; this.provider = provider;
this._resultsView = resultsView; this._resultsView = resultsView;
this._terms = []; this._terms = [];
this._focusChild = null;
this.actor = new St.BoxLayout({ style_class: 'search-section',
vertical: true });
this._resultDisplayBin = new St.Bin({ x_fill: true, this._resultDisplayBin = new St.Bin({ x_fill: true,
y_fill: true }); y_fill: true });
this.add(this._resultDisplayBin, { expand: true }); this.actor.add(this._resultDisplayBin, { expand: true });
let separator = new St.Widget({ style_class: 'search-section-separator' }); let separator = new St.Widget({ style_class: 'search-section-separator' });
this.add(separator); this.actor.add(separator);
this._resultDisplays = {}; this._resultDisplays = {};
this._clipboard = St.Clipboard.get_default();
this._cancellable = new Gio.Cancellable(); this._cancellable = new Gio.Cancellable();
this.connect('destroy', this._onDestroy.bind(this)); this.actor.connect('destroy', this._onDestroy.bind(this));
}
destroy() {
this.actor.destroy();
} }
_onDestroy() { _onDestroy() {
@@ -191,21 +180,21 @@ var SearchResultsBase = GObject.registerClass({
clear() { clear() {
this._cancellable.cancel(); this._cancellable.cancel();
for (let resultId in this._resultDisplays) for (let resultId in this._resultDisplays)
this._resultDisplays[resultId].destroy(); this._resultDisplays[resultId].actor.destroy();
this._resultDisplays = {}; this._resultDisplays = {};
this._clearResultDisplay(); this._clearResultDisplay();
this.hide(); this.actor.hide();
}
get focusChild() {
return this._focusChild;
} }
_keyFocusIn(actor) { _keyFocusIn(actor) {
if (this._focusChild == actor) this.emit('key-focus-in', actor);
return; }
this._focusChild = actor;
this.notify('focus-child'); _activateResult(result, id) {
this.provider.activateResult(id, this._terms);
if (result.metaInfo.clipboardText)
this._clipboard.set_text(St.ClipboardType.CLIPBOARD, result.metaInfo.clipboardText);
Main.overview.toggle();
} }
_setMoreCount(_count) { _setMoreCount(_count) {
@@ -244,7 +233,8 @@ var SearchResultsBase = GObject.registerClass({
metasNeeded.forEach((resultId, i) => { metasNeeded.forEach((resultId, i) => {
let meta = metas[i]; let meta = metas[i];
let display = this._createResultDisplay(meta); let display = this._createResultDisplay(meta);
display.connect('key-focus-in', this._keyFocusIn.bind(this)); display.connect('activate', this._activateResult.bind(this));
display.actor.connect('key-focus-in', this._keyFocusIn.bind(this));
this._resultDisplays[resultId] = display; this._resultDisplays[resultId] = display;
}); });
callback(true); callback(true);
@@ -256,7 +246,7 @@ var SearchResultsBase = GObject.registerClass({
this._terms = terms; this._terms = terms;
if (providerResults.length == 0) { if (providerResults.length == 0) {
this._clearResultDisplay(); this._clearResultDisplay();
this.hide(); this.actor.hide();
callback(); callback();
} else { } else {
let maxResults = this._getMaxDisplayedResults(); let maxResults = this._getMaxDisplayedResults();
@@ -275,23 +265,22 @@ var SearchResultsBase = GObject.registerClass({
// To avoid CSS transitions causing flickering when // To avoid CSS transitions causing flickering when
// the first search result stays the same, we hide the // the first search result stays the same, we hide the
// content while filling in the results. // content while filling in the results.
this.hide(); this.actor.hide();
this._clearResultDisplay(); this._clearResultDisplay();
results.forEach(resultId => { results.forEach(resultId => {
this._addItem(this._resultDisplays[resultId]); this._addItem(this._resultDisplays[resultId]);
}); });
this._setMoreCount(this.provider.canLaunchSearch ? moreCount : 0); this._setMoreCount(this.provider.canLaunchSearch ? moreCount : 0);
this.show(); this.actor.show();
callback(); callback();
}); });
} }
} }
}); };
var ListSearchResults = GObject.registerClass( var ListSearchResults = class extends SearchResultsBase {
class ListSearchResults extends SearchResultsBase { constructor(provider, resultsView) {
_init(provider, resultsView) { super(provider, resultsView);
super._init(provider, resultsView);
this._container = new St.BoxLayout({ style_class: 'search-section-content' }); this._container = new St.BoxLayout({ style_class: 'search-section-content' });
this.providerInfo = new ProviderInfo(provider); this.providerInfo = new ProviderInfo(provider);
@@ -332,21 +321,21 @@ class ListSearchResults extends SearchResultsBase {
} }
_addItem(display) { _addItem(display) {
this._content.add_actor(display); this._content.add_actor(display.actor);
} }
getFirstResult() { getFirstResult() {
if (this._content.get_n_children() > 0) if (this._content.get_n_children() > 0)
return this._content.get_child_at_index(0); return this._content.get_child_at_index(0)._delegate;
else else
return null; return null;
} }
}); };
Signals.addSignalMethods(ListSearchResults.prototype);
var GridSearchResults = GObject.registerClass( var GridSearchResults = class extends SearchResultsBase {
class GridSearchResults extends SearchResultsBase { constructor(provider, resultsView) {
_init(provider, resultsView) { super(provider, resultsView);
super._init(provider, resultsView);
this._grid = new IconGrid.IconGrid({ rowLimit: MAX_GRID_SEARCH_RESULTS_ROWS, this._grid = new IconGrid.IconGrid({ rowLimit: MAX_GRID_SEARCH_RESULTS_ROWS,
xAlign: St.Align.START }); xAlign: St.Align.START });
@@ -368,7 +357,7 @@ class GridSearchResults extends SearchResultsBase {
updateSearch(...args) { updateSearch(...args) {
if (this._notifyAllocationId) if (this._notifyAllocationId)
this.disconnect(this._notifyAllocationId); this.actor.disconnect(this._notifyAllocationId);
if (this._updateSearchLater) { if (this._updateSearchLater) {
Meta.later_remove(this._updateSearchLater); Meta.later_remove(this._updateSearchLater);
delete this._updateSearchLater; delete this._updateSearchLater;
@@ -376,7 +365,7 @@ class GridSearchResults extends SearchResultsBase {
// Make sure the maximum number of results calculated by // Make sure the maximum number of results calculated by
// _getMaxDisplayedResults() is updated after width changes. // _getMaxDisplayedResults() is updated after width changes.
this._notifyAllocationId = this.connect('notify::allocation', () => { this._notifyAllocationId = this.actor.connect('notify::allocation', () => {
if (this._updateSearchLater) if (this._updateSearchLater)
return; return;
this._updateSearchLater = Meta.later_add(Meta.LaterType.BEFORE_REDRAW, () => { this._updateSearchLater = Meta.later_add(Meta.LaterType.BEFORE_REDRAW, () => {
@@ -390,7 +379,7 @@ class GridSearchResults extends SearchResultsBase {
} }
_getMaxDisplayedResults() { _getMaxDisplayedResults() {
let width = this.allocation.get_width(); let width = this.actor.allocation.x2 - this.actor.allocation.x1;
if (width == 0) if (width == 0)
return -1; return -1;
@@ -413,17 +402,17 @@ class GridSearchResults extends SearchResultsBase {
getFirstResult() { getFirstResult() {
if (this._grid.visibleItemsCount() > 0) if (this._grid.visibleItemsCount() > 0)
return this._grid.getItemAtIndex(0); return this._grid.getItemAtIndex(0)._delegate;
else else
return null; return null;
} }
}); };
Signals.addSignalMethods(GridSearchResults.prototype);
var SearchResultsView = GObject.registerClass({ var SearchResults = class {
Signals: { 'terms-changed': {} } constructor() {
}, class SearchResultsView extends St.BoxLayout { this.actor = new St.BoxLayout({ name: 'searchResults',
_init() { vertical: true });
super._init({ name: 'searchResults', vertical: true });
this._content = new MaxWidthBox({ name: 'searchResultsContent', this._content = new MaxWidthBox({ name: 'searchResultsContent',
vertical: true }); vertical: true });
@@ -439,18 +428,16 @@ var SearchResultsView = GObject.registerClass({
action.connect('pan', this._onPan.bind(this)); action.connect('pan', this._onPan.bind(this));
this._scrollView.add_action(action); this._scrollView.add_action(action);
this.add(this._scrollView, { this.actor.add(this._scrollView, { x_fill: true,
x_fill: true, y_fill: true,
y_fill: true, expand: true,
expand: true, x_align: St.Align.START,
x_align: St.Align.START, y_align: St.Align.START });
y_align: St.Align.STAR
});
this._statusText = new St.Label({ style_class: 'search-statustext' }); this._statusText = new St.Label({ style_class: 'search-statustext' });
this._statusBin = new St.Bin({ x_align: St.Align.MIDDLE, this._statusBin = new St.Bin({ x_align: St.Align.MIDDLE,
y_align: St.Align.MIDDLE }); y_align: St.Align.MIDDLE });
this.add(this._statusBin, { expand: true }); this.actor.add(this._statusBin, { expand: true });
this._statusBin.add_actor(this._statusText); this._statusBin.add_actor(this._statusText);
this._highlightDefault = false; this._highlightDefault = false;
@@ -480,10 +467,6 @@ var SearchResultsView = GObject.registerClass({
this._reloadRemoteProviders(); this._reloadRemoteProviders();
} }
get terms() {
return this._terms;
}
_reloadRemoteProviders() { _reloadRemoteProviders() {
let remoteProviders = this._providers.filter(p => p.isRemoteProvider); let remoteProviders = this._providers.filter(p => p.isRemoteProvider);
remoteProviders.forEach(provider => { remoteProviders.forEach(provider => {
@@ -608,12 +591,12 @@ var SearchResultsView = GObject.registerClass({
_onPan(action) { _onPan(action) {
let [dist_, dx_, dy] = action.get_motion_delta(0); let [dist_, dx_, dy] = action.get_motion_delta(0);
let adjustment = this._scrollView.vscroll.adjustment; let adjustment = this._scrollView.vscroll.adjustment;
adjustment.value -= (dy / this.height) * adjustment.page_size; adjustment.value -= (dy / this.actor.height) * adjustment.page_size;
return false; return false;
} }
_focusChildChanged(provider) { _keyFocusIn(provider, actor) {
Util.ensureActorVisibleInScrollView(this._scrollView, provider.focusChild); Util.ensureActorVisibleInScrollView(this._scrollView, actor);
} }
_ensureProviderDisplay(provider) { _ensureProviderDisplay(provider) {
@@ -626,9 +609,9 @@ var SearchResultsView = GObject.registerClass({
else else
providerDisplay = new GridSearchResults(provider, this); providerDisplay = new GridSearchResults(provider, this);
providerDisplay.connect('notify::focus-child', this._focusChildChanged.bind(this)); providerDisplay.connect('key-focus-in', this._keyFocusIn.bind(this));
providerDisplay.hide(); providerDisplay.actor.hide();
this._content.add(providerDisplay); this._content.add(providerDisplay.actor);
provider.display = providerDisplay; provider.display = providerDisplay;
} }
@@ -646,7 +629,7 @@ var SearchResultsView = GObject.registerClass({
let provider = providers[i]; let provider = providers[i];
let display = provider.display; let display = provider.display;
if (!display.visible) if (!display.actor.visible)
continue; continue;
let firstResult = display.getFirstResult(); let firstResult = display.getFirstResult();
@@ -721,22 +704,22 @@ var SearchResultsView = GObject.registerClass({
this._doSearch(); this._doSearch();
if (this._defaultResult) if (this._defaultResult)
this._defaultResult.popup_menu(); this._defaultResult.actor.popup_menu();
} }
navigateFocus(direction) { navigateFocus(direction) {
let rtl = this.get_text_direction() == Clutter.TextDirection.RTL; let rtl = this.actor.get_text_direction() == Clutter.TextDirection.RTL;
if (direction == St.DirectionType.TAB_BACKWARD || if (direction == St.DirectionType.TAB_BACKWARD ||
direction == (rtl direction == (rtl
? St.DirectionType.RIGHT ? St.DirectionType.RIGHT
: St.DirectionType.LEFT) || : St.DirectionType.LEFT) ||
direction == St.DirectionType.UP) { direction == St.DirectionType.UP) {
this.navigate_focus(null, direction, false); this.actor.navigate_focus(null, direction, false);
return; return;
} }
let from = this._defaultResult ? this._defaultResult : null; let from = this._defaultResult ? this._defaultResult.actor : null;
this.navigate_focus(from, direction, false); this.actor.navigate_focus(from, direction, false);
} }
_setSelected(result, selected) { _setSelected(result, selected) {
@@ -744,10 +727,10 @@ var SearchResultsView = GObject.registerClass({
return; return;
if (selected) { if (selected) {
result.add_style_pseudo_class('selected'); result.actor.add_style_pseudo_class('selected');
Util.ensureActorVisibleInScrollView(this._scrollView, result); Util.ensureActorVisibleInScrollView(this._scrollView, result.actor);
} else { } else {
result.remove_style_pseudo_class('selected'); result.actor.remove_style_pseudo_class('selected');
} }
} }
@@ -760,7 +743,8 @@ var SearchResultsView = GObject.registerClass({
return description.replace(this._highlightRegex, '<b>$1</b>'); return description.replace(this._highlightRegex, '<b>$1</b>');
} }
}); };
Signals.addSignalMethods(SearchResults.prototype);
var ProviderInfo = GObject.registerClass( var ProviderInfo = GObject.registerClass(
class ProviderInfo extends St.Button { class ProviderInfo extends St.Button {

View File

@@ -53,19 +53,6 @@ const _modes = {
panelStyle: 'login-screen' panelStyle: 'login-screen'
}, },
'lock-screen': {
isLocked: true,
isGreeter: undefined,
unlockDialog: undefined,
components: ['polkitAgent', 'telepathyClient'],
panel: {
left: [],
center: [],
right: ['aggregateMenu']
},
panelStyle: 'lock-screen'
},
'unlock-dialog': { 'unlock-dialog': {
isLocked: true, isLocked: true,
unlockDialog: undefined, unlockDialog: undefined,

View File

@@ -2,6 +2,7 @@
/* exported ShellMountOperation, GnomeShellMountOpHandler */ /* exported ShellMountOperation, GnomeShellMountOpHandler */
const { Clutter, Gio, GLib, GObject, Pango, Shell, St } = imports.gi; const { Clutter, Gio, GLib, GObject, Pango, Shell, St } = imports.gi;
const Signals = imports.signals;
const Animation = imports.ui.animation; const Animation = imports.ui.animation;
const CheckBox = imports.ui.checkBox; const CheckBox = imports.ui.checkBox;
@@ -43,23 +44,19 @@ function _setLabelsForMessage(content, message) {
/* -------------------------------------------------------- */ /* -------------------------------------------------------- */
var ListItem = GObject.registerClass({ var ListItem = class {
GTypeName: 'ShellMountOperation_ListItem', constructor(app) {
Signals: { 'activate': {} }
}, class ListItem extends St.Button {
_init(app) {
let layout = new St.BoxLayout({ vertical: false });
super._init({
style_class: 'mount-dialog-app-list-item',
can_focus: true,
child: layout,
reactive: true,
x_align: St.Align.START,
x_fill: true
});
this._app = app; this._app = app;
let layout = new St.BoxLayout({ vertical: false });
this.actor = new St.Button({ style_class: 'mount-dialog-app-list-item',
can_focus: true,
child: layout,
reactive: true,
x_align: St.Align.START,
x_fill: true });
this._icon = this._app.create_icon_texture(LIST_ITEM_ICON_SIZE); this._icon = this._app.create_icon_texture(LIST_ITEM_ICON_SIZE);
let iconBin = new St.Bin({ style_class: 'mount-dialog-app-list-item-icon', let iconBin = new St.Bin({ style_class: 'mount-dialog-app-list-item-icon',
@@ -71,13 +68,16 @@ var ListItem = GObject.registerClass({
let labelBin = new St.Bin({ y_align: St.Align.MIDDLE, let labelBin = new St.Bin({ y_align: St.Align.MIDDLE,
child: this._nameLabel }); child: this._nameLabel });
layout.add(labelBin); layout.add(labelBin);
this.actor.connect('clicked', this._onClicked.bind(this));
} }
vfunc_clicked() { _onClicked() {
this.emit('activate'); this.emit('activate');
this._app.activate(); this._app.activate();
} }
}); };
Signals.addSignalMethods(ListItem.prototype);
var ShellMountOperation = class { var ShellMountOperation = class {
constructor(source, params) { constructor(source, params) {
@@ -219,10 +219,9 @@ var ShellMountOperation = class {
} }
}; };
var ShellUnmountNotifier = GObject.registerClass( var ShellUnmountNotifier = class extends MessageTray.Source {
class ShellUnmountNotifier extends MessageTray.Source { constructor() {
_init() { super('', 'media-removable');
super._init('', 'media-removable');
this._notification = null; this._notification = null;
Main.messageTray.add(this); Main.messageTray.add(this);
@@ -239,7 +238,7 @@ class ShellUnmountNotifier extends MessageTray.Source {
this._notification.update(header, text); this._notification.update(header, text);
} }
this.showNotification(this._notification); this.notify(this._notification);
} }
done(message) { done(message) {
@@ -252,10 +251,10 @@ class ShellUnmountNotifier extends MessageTray.Source {
let notification = new MessageTray.Notification(this, message, null); let notification = new MessageTray.Notification(this, message, null);
notification.setTransient(true); notification.setTransient(true);
this.showNotification(notification); this.notify(notification);
} }
} }
}); };
var ShellMountQuestionDialog = GObject.registerClass({ var ShellMountQuestionDialog = GObject.registerClass({
Signals: { 'response': { param_types: [GObject.TYPE_INT] } } Signals: { 'response': { param_types: [GObject.TYPE_INT] } }
@@ -304,14 +303,14 @@ var ShellMountPasswordDialog = GObject.registerClass({
visible: false })); visible: false }));
this._hiddenVolume = new CheckBox.CheckBox(_("Hidden Volume")); this._hiddenVolume = new CheckBox.CheckBox(_("Hidden Volume"));
content.messageBox.add(this._hiddenVolume); content.messageBox.add(this._hiddenVolume.actor);
this._systemVolume = new CheckBox.CheckBox(_("Windows System Volume")); this._systemVolume = new CheckBox.CheckBox(_("Windows System Volume"));
content.messageBox.add(this._systemVolume); content.messageBox.add(this._systemVolume.actor);
this._keyfilesCheckbox = new CheckBox.CheckBox(_("Uses Keyfiles")); this._keyfilesCheckbox = new CheckBox.CheckBox(_("Uses Keyfiles"));
this._keyfilesCheckbox.connect("clicked", this._onKeyfilesCheckboxClicked.bind(this)); this._keyfilesCheckbox.actor.connect("clicked", this._onKeyfilesCheckboxClicked.bind(this));
content.messageBox.add(this._keyfilesCheckbox); content.messageBox.add(this._keyfilesCheckbox.actor);
this._keyfilesLabel.clutter_text.set_markup( this._keyfilesLabel.clutter_text.set_markup(
/* Translators: %s is the Disks application */ /* Translators: %s is the Disks application */
@@ -361,7 +360,7 @@ var ShellMountPasswordDialog = GObject.registerClass({
ShellEntry.addContextMenu(this._passwordEntry, { isPassword: true }); ShellEntry.addContextMenu(this._passwordEntry, { isPassword: true });
this.setInitialKeyFocus(this._passwordEntry); this.setInitialKeyFocus(this._passwordEntry);
this._workSpinner = new Animation.Spinner(WORK_SPINNER_ICON_SIZE, true); this._workSpinner = new Animation.Spinner(WORK_SPINNER_ICON_SIZE, true);
this._passwordEntry.secondary_icon = this._workSpinner; this._passwordEntry.secondary_icon = this._workSpinner.actor;
if (rtl) { if (rtl) {
layout.attach(this._passwordEntry, 0, 1, 1, 1); layout.attach(this._passwordEntry, 0, 1, 1, 1);
@@ -382,9 +381,9 @@ var ShellMountPasswordDialog = GObject.registerClass({
if (flags & Gio.AskPasswordFlags.SAVING_SUPPORTED) { if (flags & Gio.AskPasswordFlags.SAVING_SUPPORTED) {
this._rememberChoice = new CheckBox.CheckBox(_("Remember Password")); this._rememberChoice = new CheckBox.CheckBox(_("Remember Password"));
this._rememberChoice.checked = this._rememberChoice.actor.checked =
global.settings.get_boolean(REMEMBER_MOUNT_PASSWORD_KEY); global.settings.get_boolean(REMEMBER_MOUNT_PASSWORD_KEY);
content.messageBox.add(this._rememberChoice); content.messageBox.add(this._rememberChoice.actor);
} else { } else {
this._rememberChoice = null; this._rememberChoice = null;
} }
@@ -440,22 +439,22 @@ var ShellMountPasswordDialog = GObject.registerClass({
} }
global.settings.set_boolean(REMEMBER_MOUNT_PASSWORD_KEY, global.settings.set_boolean(REMEMBER_MOUNT_PASSWORD_KEY,
this._rememberChoice && this._rememberChoice.checked); this._rememberChoice && this._rememberChoice.actor.checked);
this._workSpinner.play(); this._workSpinner.play();
this.emit('response', 1, this.emit('response', 1,
this._passwordEntry.get_text(), this._passwordEntry.get_text(),
this._rememberChoice && this._rememberChoice &&
this._rememberChoice.checked, this._rememberChoice.actor.checked,
this._hiddenVolume && this._hiddenVolume &&
this._hiddenVolume.checked, this._hiddenVolume.actor.checked,
this._systemVolume && this._systemVolume &&
this._systemVolume.checked, this._systemVolume.actor.checked,
parseInt(pim)); parseInt(pim));
} }
_onKeyfilesCheckboxClicked() { _onKeyfilesCheckboxClicked() {
let useKeyfiles = this._keyfilesCheckbox.checked; let useKeyfiles = this._keyfilesCheckbox.actor.checked;
this._passwordEntry.reactive = !useKeyfiles; this._passwordEntry.reactive = !useKeyfiles;
this._passwordEntry.can_focus = !useKeyfiles; this._passwordEntry.can_focus = !useKeyfiles;
this._passwordEntry.clutter_text.editable = !useKeyfiles; this._passwordEntry.clutter_text.editable = !useKeyfiles;
@@ -464,8 +463,8 @@ var ShellMountPasswordDialog = GObject.registerClass({
this._pimEntry.can_focus = !useKeyfiles; this._pimEntry.can_focus = !useKeyfiles;
this._pimEntry.clutter_text.editable = !useKeyfiles; this._pimEntry.clutter_text.editable = !useKeyfiles;
this._pimEntry.clutter_text.selectable = !useKeyfiles; this._pimEntry.clutter_text.selectable = !useKeyfiles;
this._rememberChoice.reactive = !useKeyfiles; this._rememberChoice.actor.reactive = !useKeyfiles;
this._rememberChoice.can_focus = !useKeyfiles; this._rememberChoice.actor.can_focus = !useKeyfiles;
this._keyfilesLabel.visible = useKeyfiles; this._keyfilesLabel.visible = useKeyfiles;
this.setButtons(useKeyfiles ? this._usesKeyfilesButtons : this._defaultButtons); this.setButtons(useKeyfiles ? this._usesKeyfilesButtons : this._defaultButtons);
} }
@@ -528,7 +527,7 @@ var ShellProcessesDialog = GObject.registerClass({
return; return;
let item = new ListItem(app); let item = new ListItem(app);
this._applicationList.add(item, { x_fill: true }); this._applicationList.add(item.actor, { x_fill: true });
item.connect('activate', () => { item.connect('activate', () => {
// use -1 to indicate Cancel // use -1 to indicate Cancel

View File

@@ -22,7 +22,12 @@ var Slider = GObject.registerClass({
accessible_role: Atk.Role.SLIDER accessible_role: Atk.Role.SLIDER
}); });
this._releaseId = 0; this.connect('button-press-event', this._startDragging.bind(this));
this.connect('touch-event', this._touchDragging.bind(this));
this.connect('scroll-event', this._onScrollEvent.bind(this));
this.connect('key-press-event', this.onKeyPressEvent.bind(this));
this._releaseId = this._motionId = 0;
this._dragging = false; this._dragging = false;
this._customAccessible.connect('get-minimum-increment', this._getMinimumIncrement.bind(this)); this._customAccessible.connect('get-minimum-increment', this._getMinimumIncrement.bind(this));
@@ -57,8 +62,8 @@ var Slider = GObject.registerClass({
cr.$dispose(); cr.$dispose();
} }
vfunc_button_press_event() { _startDragging(actor, event) {
return this.startDragging(Clutter.get_current_event()); return this.startDragging(event);
} }
startDragging(event) { startDragging(event) {
@@ -78,6 +83,11 @@ var Slider = GObject.registerClass({
this._grabbedDevice = device; this._grabbedDevice = device;
this._grabbedSequence = sequence; this._grabbedSequence = sequence;
if (sequence == null) {
this._releaseId = this.connect('button-release-event', this._endDragging.bind(this));
this._motionId = this.connect('motion-event', this._motionEvent.bind(this));
}
// We need to emit 'drag-begin' before moving the handle to make // We need to emit 'drag-begin' before moving the handle to make
// sure that no 'notify::value' signal is emitted before this one. // sure that no 'notify::value' signal is emitted before this one.
this.emit('drag-begin'); this.emit('drag-begin');
@@ -95,6 +105,11 @@ var Slider = GObject.registerClass({
this._releaseId = 0; this._releaseId = 0;
} }
if (this._motionId) {
this.disconnect(this._motionId);
this._motionId = 0;
}
if (this._grabbedSequence != null) if (this._grabbedSequence != null)
this._grabbedDevice.sequence_ungrab(this._grabbedSequence); this._grabbedDevice.sequence_ungrab(this._grabbedSequence);
else else
@@ -109,15 +124,7 @@ var Slider = GObject.registerClass({
return Clutter.EVENT_STOP; return Clutter.EVENT_STOP;
} }
vfunc_button_release_event() { _touchDragging(actor, event) {
if (this._dragging && !this._grabbedSequence)
return this._endDragging();
return Clutter.EVENT_PROPAGATE;
}
vfunc_touch_event() {
let event = Clutter.get_current_event();
let device = event.get_device(); let device = event.get_device();
let sequence = event.get_event_sequence(); let sequence = event.get_event_sequence();
@@ -125,9 +132,9 @@ var Slider = GObject.registerClass({
event.type() == Clutter.EventType.TOUCH_BEGIN) { event.type() == Clutter.EventType.TOUCH_BEGIN) {
this.startDragging(event); this.startDragging(event);
return Clutter.EVENT_STOP; return Clutter.EVENT_STOP;
} else if (device.sequence_get_grabbed_actor(sequence) == this) { } else if (device.sequence_get_grabbed_actor(sequence) == actor) {
if (event.type() == Clutter.EventType.TOUCH_UPDATE) if (event.type() == Clutter.EventType.TOUCH_UPDATE)
return this._motionEvent(this, event); return this._motionEvent(actor, event);
else if (event.type() == Clutter.EventType.TOUCH_END) else if (event.type() == Clutter.EventType.TOUCH_END)
return this._endDragging(); return this._endDragging();
} }
@@ -158,15 +165,8 @@ var Slider = GObject.registerClass({
return Clutter.EVENT_STOP; return Clutter.EVENT_STOP;
} }
vfunc_scroll_event() { _onScrollEvent(actor, event) {
return this.scroll(Clutter.get_current_event()); return this.scroll(event);
}
vfunc_motion_event() {
if (this._dragging && !this._grabbedSequence)
return this._motionEvent(this, Clutter.get_current_event());
return Clutter.EVENT_PROPAGATE;
} }
_motionEvent(actor, event) { _motionEvent(actor, event) {
@@ -176,8 +176,8 @@ var Slider = GObject.registerClass({
return Clutter.EVENT_STOP; return Clutter.EVENT_STOP;
} }
vfunc_key_press_event(keyPressEvent) { onKeyPressEvent(actor, event) {
let key = keyPressEvent.keyval; let key = event.get_key_symbol();
if (key == Clutter.KEY_Right || key == Clutter.KEY_Left) { if (key == Clutter.KEY_Right || key == Clutter.KEY_Left) {
let delta = key == Clutter.KEY_Right ? 0.1 : -0.1; let delta = key == Clutter.KEY_Right ? 0.1 : -0.1;
this.emit('drag-begin'); this.emit('drag-begin');

View File

@@ -102,7 +102,7 @@ class ATIndicator extends PanelMenu.Button {
_buildItemExtended(string, initialValue, writable, onSet) { _buildItemExtended(string, initialValue, writable, onSet) {
let widget = new PopupMenu.PopupSwitchMenuItem(string, initialValue); let widget = new PopupMenu.PopupSwitchMenuItem(string, initialValue);
if (!writable) if (!writable)
widget.reactive = false; widget.actor.reactive = false;
else else
widget.connect('toggled', item => { widget.connect('toggled', item => {
onSet(item.state); onSet(item.state);

View File

@@ -1,7 +1,7 @@
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*- // -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
/* exported Indicator */ /* exported Indicator */
const { Gio, GnomeBluetooth, GObject } = imports.gi; const { Gio, GnomeBluetooth } = imports.gi;
const Main = imports.ui.main; const Main = imports.ui.main;
const PanelMenu = imports.ui.panelMenu; const PanelMenu = imports.ui.panelMenu;
@@ -17,11 +17,9 @@ const RfkillManagerProxy = Gio.DBusProxy.makeProxyWrapper(RfkillManagerInterface
const HAD_BLUETOOTH_DEVICES_SETUP = 'had-bluetooth-devices-setup'; const HAD_BLUETOOTH_DEVICES_SETUP = 'had-bluetooth-devices-setup';
var Indicator = GObject.registerClass({ var Indicator = class extends PanelMenu.SystemIndicator {
GTypeName: 'Bluetooth_Indicator' constructor() {
}, class Indicator extends PanelMenu.SystemIndicator { super();
_init() {
super._init();
this._indicator = this._addIndicator(); this._indicator = this._addIndicator();
this._indicator.icon_name = 'bluetooth-active-symbolic'; this._indicator.icon_name = 'bluetooth-active-symbolic';
@@ -135,4 +133,4 @@ var Indicator = GObject.registerClass({
this._toggleItem.label.text = this._proxy.BluetoothAirplaneMode ? _("Turn On") : _("Turn Off"); this._toggleItem.label.text = this._proxy.BluetoothAirplaneMode ? _("Turn On") : _("Turn Off");
} }
}); };

View File

@@ -15,11 +15,9 @@ const OBJECT_PATH = '/org/gnome/SettingsDaemon/Power';
const BrightnessInterface = loadInterfaceXML('org.gnome.SettingsDaemon.Power.Screen'); const BrightnessInterface = loadInterfaceXML('org.gnome.SettingsDaemon.Power.Screen');
const BrightnessProxy = Gio.DBusProxy.makeProxyWrapper(BrightnessInterface); const BrightnessProxy = Gio.DBusProxy.makeProxyWrapper(BrightnessInterface);
var Indicator = GObject.registerClass({ var Indicator = class extends PanelMenu.SystemIndicator {
GTypeName: 'Brightness_Indicator' constructor() {
}, class Indicator extends PanelMenu.SystemIndicator { super('display-brightness-symbolic');
_init() {
super._init();
this._proxy = new BrightnessProxy(Gio.DBus.session, BUS_NAME, OBJECT_PATH, this._proxy = new BrightnessProxy(Gio.DBus.session, BUS_NAME, OBJECT_PATH,
(proxy, error) => { (proxy, error) => {
if (error) { if (error) {
@@ -47,7 +45,7 @@ var Indicator = GObject.registerClass({
return this._slider.startDragging(event); return this._slider.startDragging(event);
}); });
this._item.connect('key-press-event', (actor, event) => { this._item.connect('key-press-event', (actor, event) => {
return this._slider.emit('key-press-event', event); return this._slider.onKeyPressEvent(actor, event);
}); });
} }
@@ -69,4 +67,4 @@ var Indicator = GObject.registerClass({
if (visible) if (visible)
this._changeSlider(this._proxy.Brightness / 100.0); this._changeSlider(this._proxy.Brightness / 100.0);
} }
}); };

View File

@@ -923,7 +923,7 @@ class InputSourceIndicator extends PanelMenu.Button {
} }
_buildPropSection(properties) { _buildPropSection(properties) {
this._propSeparator.hide(); this._propSeparator.actor.hide();
this._propSection.actor.hide(); this._propSection.actor.hide();
this._propSection.removeAll(); this._propSection.removeAll();
@@ -931,7 +931,7 @@ class InputSourceIndicator extends PanelMenu.Button {
if (!this._propSection.isEmpty()) { if (!this._propSection.isEmpty()) {
this._propSection.actor.show(); this._propSection.actor.show();
this._propSeparator.show(); this._propSeparator.actor.show();
} }
} }

View File

@@ -42,11 +42,9 @@ const GeoclueManager = Gio.DBusProxy.makeProxyWrapper(GeoclueIface);
var AgentIface = loadInterfaceXML('org.freedesktop.GeoClue2.Agent'); var AgentIface = loadInterfaceXML('org.freedesktop.GeoClue2.Agent');
var Indicator = GObject.registerClass({ var Indicator = class extends PanelMenu.SystemIndicator {
GTypeName: 'Location_Indicator' constructor() {
}, class Indicator extends PanelMenu.SystemIndicator { super();
_init() {
super._init();
this._settings = new Gio.Settings({ schema_id: LOCATION_SCHEMA }); this._settings = new Gio.Settings({ schema_id: LOCATION_SCHEMA });
this._settings.connect(`changed::${ENABLED}`, this._settings.connect(`changed::${ENABLED}`,
@@ -224,7 +222,7 @@ var Indicator = GObject.registerClass({
this._permStoreProxy = proxy; this._permStoreProxy = proxy;
} }
}); };
function clamp(value, min, max) { function clamp(value, min, max) {
return Math.max(min, Math.min(max, value)); return Math.max(min, Math.min(max, value));

View File

@@ -630,6 +630,7 @@ var NMWirelessDialogItem = GObject.registerClass({
can_focus: true, can_focus: true,
reactive: true }); reactive: true });
this.connect('key-focus-in', () => this.emit('selected'));
let action = new Clutter.ClickAction(); let action = new Clutter.ClickAction();
action.connect('clicked', () => this.grab_key_focus()); action.connect('clicked', () => this.grab_key_focus());
this.add_action(action); this.add_action(action);
@@ -658,10 +659,6 @@ var NMWirelessDialogItem = GObject.registerClass({
this._sync(); this._sync();
} }
vfunc_key_focus_in() {
this.emit('selected');
}
_sync() { _sync() {
this._signalIcon.icon_name = this._getSignalIcon(); this._signalIcon.icon_name = this._getSignalIcon();
} }
@@ -863,7 +860,7 @@ class NMWirelessDialog extends ModalDialog.ModalDialog {
y_align: Clutter.ActorAlign.CENTER }); y_align: Clutter.ActorAlign.CENTER });
this._noNetworksSpinner = new Animation.Spinner(16); this._noNetworksSpinner = new Animation.Spinner(16);
this._noNetworksBox.add_actor(this._noNetworksSpinner); this._noNetworksBox.add_actor(this._noNetworksSpinner.actor);
this._noNetworksBox.add_actor(new St.Label({ style_class: 'no-networks-label', this._noNetworksBox.add_actor(new St.Label({ style_class: 'no-networks-label',
text: _("No Networks") })); text: _("No Networks") }));
this._stack.add_child(this._noNetworksBox); this._stack.add_child(this._noNetworksBox);
@@ -1591,11 +1588,9 @@ var DeviceCategory = class extends PopupMenu.PopupMenuSection {
} }
}; };
var NMApplet = GObject.registerClass({ var NMApplet = class extends PanelMenu.SystemIndicator {
GTypeName: 'Network_Indicator' constructor() {
}, class Indicator extends PanelMenu.SystemIndicator { super();
_init() {
super._init();
this._primaryIndicator = this._addIndicator(); this._primaryIndicator = this._addIndicator();
this._vpnIndicator = this._addIndicator(); this._vpnIndicator = this._addIndicator();
@@ -1711,7 +1706,7 @@ var NMApplet = GObject.registerClass({
this._notification.connect('destroy', () => { this._notification.connect('destroy', () => {
this._notification = null; this._notification = null;
}); });
this._source.showNotification(this._notification); this._source.notify(this._notification);
} }
_onActivationFailed(_device, _reason) { _onActivationFailed(_device, _reason) {
@@ -1944,7 +1939,7 @@ var NMApplet = GObject.registerClass({
} }
_syncNMState() { _syncNMState() {
this.visible = this._client.nm_running; this.indicators.visible = this._client.nm_running;
this.menu.actor.visible = this._client.networking_enabled; this.menu.actor.visible = this._client.networking_enabled;
this._updateIcon(); this._updateIcon();
@@ -2063,4 +2058,4 @@ var NMApplet = GObject.registerClass({
this._vpnIndicator.icon_name = this._vpnSection.getIndicatorIcon(); this._vpnIndicator.icon_name = this._vpnSection.getIndicatorIcon();
this._vpnIndicator.visible = (this._vpnIndicator.icon_name != ''); this._vpnIndicator.visible = (this._vpnIndicator.icon_name != '');
} }
}); };

View File

@@ -1,7 +1,7 @@
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*- // -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
/* exported Indicator */ /* exported Indicator */
const { Gio, GObject } = imports.gi; const Gio = imports.gi.Gio;
const Main = imports.ui.main; const Main = imports.ui.main;
const PanelMenu = imports.ui.panelMenu; const PanelMenu = imports.ui.panelMenu;
@@ -15,11 +15,9 @@ const OBJECT_PATH = '/org/gnome/SettingsDaemon/Color';
const ColorInterface = loadInterfaceXML('org.gnome.SettingsDaemon.Color'); const ColorInterface = loadInterfaceXML('org.gnome.SettingsDaemon.Color');
const ColorProxy = Gio.DBusProxy.makeProxyWrapper(ColorInterface); const ColorProxy = Gio.DBusProxy.makeProxyWrapper(ColorInterface);
var Indicator = GObject.registerClass({ var Indicator = class extends PanelMenu.SystemIndicator {
GTypeName: 'NightLight_Indicator' constructor() {
}, class Indicator extends PanelMenu.SystemIndicator { super();
_init() {
super._init();
this._indicator = this._addIndicator(); this._indicator = this._addIndicator();
this._indicator.icon_name = 'night-light-symbolic'; this._indicator.icon_name = 'night-light-symbolic';
@@ -68,4 +66,4 @@ var Indicator = GObject.registerClass({
: _("Disable Until Tomorrow"); : _("Disable Until Tomorrow");
this._item.visible = this._indicator.visible = visible; this._item.visible = this._indicator.visible = visible;
} }
}); };

View File

@@ -1,7 +1,7 @@
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*- // -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
/* exported Indicator */ /* exported Indicator */
const { Clutter, Gio, GObject, St, UPowerGlib: UPower } = imports.gi; const { Clutter, Gio, St, UPowerGlib: UPower } = imports.gi;
const Main = imports.ui.main; const Main = imports.ui.main;
const PanelMenu = imports.ui.panelMenu; const PanelMenu = imports.ui.panelMenu;
@@ -17,11 +17,9 @@ const PowerManagerProxy = Gio.DBusProxy.makeProxyWrapper(DisplayDeviceInterface)
const SHOW_BATTERY_PERCENTAGE = 'show-battery-percentage'; const SHOW_BATTERY_PERCENTAGE = 'show-battery-percentage';
var Indicator = GObject.registerClass({ var Indicator = class extends PanelMenu.SystemIndicator {
GTypeName: 'Power_Indicator' constructor() {
}, class Indicator extends PanelMenu.SystemIndicator { super();
_init() {
super._init();
this._desktopSettings = new Gio.Settings({ schema_id: 'org.gnome.desktop.interface' }); this._desktopSettings = new Gio.Settings({ schema_id: 'org.gnome.desktop.interface' });
this._desktopSettings.connect(`changed::${SHOW_BATTERY_PERCENTAGE}`, this._desktopSettings.connect(`changed::${SHOW_BATTERY_PERCENTAGE}`,
@@ -30,8 +28,8 @@ var Indicator = GObject.registerClass({
this._indicator = this._addIndicator(); this._indicator = this._addIndicator();
this._percentageLabel = new St.Label({ y_expand: true, this._percentageLabel = new St.Label({ y_expand: true,
y_align: Clutter.ActorAlign.CENTER }); y_align: Clutter.ActorAlign.CENTER });
this.add(this._percentageLabel, { expand: true, y_fill: true }); this.indicators.add(this._percentageLabel, { expand: true, y_fill: true });
this.add_style_class_name('power-status'); this.indicators.add_style_class_name('power-status');
this._proxy = new PowerManagerProxy(Gio.DBus.system, BUS_NAME, OBJECT_PATH, this._proxy = new PowerManagerProxy(Gio.DBus.system, BUS_NAME, OBJECT_PATH,
(proxy, error) => { (proxy, error) => {
@@ -142,4 +140,4 @@ var Indicator = GObject.registerClass({
// The status label // The status label
this._item.label.text = this._getStatus(); this._item.label.text = this._getStatus();
} }
}); };

View File

@@ -1,16 +1,14 @@
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*- // -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
/* exported RemoteAccessApplet */ /* exported RemoteAccessApplet */
const { GObject, Meta } = imports.gi; const Meta = imports.gi.Meta;
const PanelMenu = imports.ui.panelMenu; const PanelMenu = imports.ui.panelMenu;
const PopupMenu = imports.ui.popupMenu; const PopupMenu = imports.ui.popupMenu;
var RemoteAccessApplet = GObject.registerClass({ var RemoteAccessApplet = class extends PanelMenu.SystemIndicator {
GTypeName: 'RemoteAccess_Indicator' constructor() {
}, class RemoteAccessApplet extends PanelMenu.SystemIndicator { super();
_init() {
super._init();
let backend = Meta.get_backend(); let backend = Meta.get_backend();
let controller = backend.get_remote_access_controller(); let controller = backend.get_remote_access_controller();
@@ -77,4 +75,4 @@ var RemoteAccessApplet = GObject.registerClass({
this._sync(); this._sync();
} }
} }
}); };

View File

@@ -1,7 +1,7 @@
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*- // -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
/* exported Indicator */ /* exported Indicator */
const { Gio, GObject } = imports.gi; const Gio = imports.gi.Gio;
const Signals = imports.signals; const Signals = imports.signals;
const Main = imports.ui.main; const Main = imports.ui.main;
@@ -61,11 +61,9 @@ function getRfkillManager() {
return _manager; return _manager;
} }
var Indicator = GObject.registerClass({ var Indicator = class extends PanelMenu.SystemIndicator {
GTypeName: 'Rfkill_Indicator' constructor() {
}, class Indicator extends PanelMenu.SystemIndicator { super();
_init() {
super._init();
this._manager = getRfkillManager(); this._manager = getRfkillManager();
this._manager.connect('airplane-mode-changed', this._sync.bind(this)); this._manager.connect('airplane-mode-changed', this._sync.bind(this));
@@ -108,4 +106,4 @@ var Indicator = GObject.registerClass({
else else
this._offItem.label.text = _("Turn Off"); this._offItem.label.text = _("Turn Off");
} }
}); };

View File

@@ -1,16 +1,12 @@
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*- // -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
/* exported Indicator */ /* exported Indicator */
const GObject = imports.gi.GObject;
const Main = imports.ui.main; const Main = imports.ui.main;
const PanelMenu = imports.ui.panelMenu; const PanelMenu = imports.ui.panelMenu;
var Indicator = GObject.registerClass({ var Indicator = class extends PanelMenu.SystemIndicator {
GTypeName: 'Screencast_Indicator' constructor() {
}, class Indicator extends PanelMenu.SystemIndicator { super();
_init() {
super._init();
this._indicator = this._addIndicator(); this._indicator = this._addIndicator();
this._indicator.icon_name = 'media-record-symbolic'; this._indicator.icon_name = 'media-record-symbolic';
@@ -23,4 +19,4 @@ var Indicator = GObject.registerClass({
_sync() { _sync() {
this._indicator.visible = Main.screencastService.isRecording; this._indicator.visible = Main.screencastService.isRecording;
} }
}); };

View File

@@ -10,10 +10,8 @@ const PanelMenu = imports.ui.panelMenu;
const PopupMenu = imports.ui.popupMenu; const PopupMenu = imports.ui.popupMenu;
var AltSwitcher = GObject.registerClass( var AltSwitcher = class {
class AltSwitcher extends St.Bin { constructor(standard, alternate) {
_init(standard, alternate) {
super._init();
this._standard = standard; this._standard = standard;
this._standard.connect('notify::visible', this._sync.bind(this)); this._standard.connect('notify::visible', this._sync.bind(this));
if (this._standard instanceof St.Button) if (this._standard instanceof St.Button)
@@ -33,17 +31,9 @@ class AltSwitcher extends St.Bin {
this._clickAction = new Clutter.ClickAction(); this._clickAction = new Clutter.ClickAction();
this._clickAction.connect('long-press', this._onLongPress.bind(this)); this._clickAction.connect('long-press', this._onLongPress.bind(this));
this.connect('destroy', this._onDestroy.bind(this)); this.actor = new St.Bin();
} this.actor.connect('destroy', this._onDestroy.bind(this));
this.actor.connect('notify::mapped', () => (this._flipped = false));
vfunc_map() {
super.vfunc_map();
this._flipped = false;
}
vfunc_unmap() {
super.vfunc_unmap();
this._flipped = false;
} }
_sync() { _sync() {
@@ -61,11 +51,11 @@ class AltSwitcher extends St.Bin {
} else if (this._alternate.visible) { } else if (this._alternate.visible) {
childToShow = this._alternate; childToShow = this._alternate;
} else { } else {
this.hide(); this.actor.hide();
return; return;
} }
let childShown = this.get_child(); let childShown = this.actor.get_child();
if (childShown != childToShow) { if (childShown != childToShow) {
if (childShown) { if (childShown) {
if (childShown.fake_release) if (childShown.fake_release)
@@ -74,8 +64,8 @@ class AltSwitcher extends St.Bin {
} }
childToShow.add_action(this._clickAction); childToShow.add_action(this._clickAction);
let hasFocus = this.contains(global.stage.get_key_focus()); let hasFocus = this.actor.contains(global.stage.get_key_focus());
this.set_child(childToShow); this.actor.set_child(childToShow);
if (hasFocus) if (hasFocus)
childToShow.grab_key_focus(); childToShow.grab_key_focus();
@@ -84,7 +74,7 @@ class AltSwitcher extends St.Bin {
global.sync_pointer(); global.sync_pointer();
} }
this.show(); this.actor.show();
} }
_onDestroy() { _onDestroy() {
@@ -114,13 +104,11 @@ class AltSwitcher extends St.Bin {
this._sync(); this._sync();
return true; return true;
} }
}); };
var Indicator = GObject.registerClass({ var Indicator = class extends PanelMenu.SystemIndicator {
GTypeName: 'System_Indicator' constructor() {
}, class Indicator extends PanelMenu.SystemIndicator { super();
_init() {
super._init();
let userManager = AccountsService.UserManager.get_default(); let userManager = AccountsService.UserManager.get_default();
this._user = userManager.get_user(GLib.get_user_name()); this._user = userManager.get_user(GLib.get_user_name());
@@ -301,7 +289,7 @@ var Indicator = GObject.registerClass({
bindFlags); bindFlags);
this._altSwitcher = new AltSwitcher(this._powerOffAction, this._suspendAction); this._altSwitcher = new AltSwitcher(this._powerOffAction, this._suspendAction);
item.add(this._altSwitcher, { expand: true, x_fill: false }); item.add(this._altSwitcher.actor, { expand: true, x_fill: false });
this.menu.addMenuItem(item); this.menu.addMenuItem(item);
@@ -309,7 +297,7 @@ var Indicator = GObject.registerClass({
this._settingsAction, this._settingsAction,
this._orientationLockAction, this._orientationLockAction,
this._lockScreenAction, this._lockScreenAction,
this._altSwitcher, this._altSwitcher.actor,
]; ];
for (let actor of visibilityGroup) { for (let actor of visibilityGroup) {
@@ -324,4 +312,4 @@ var Indicator = GObject.registerClass({
Main.overview.hide(); Main.overview.hide();
this._settingsApp.activate(); this._settingsApp.activate();
} }
}); };

View File

@@ -3,7 +3,7 @@
// the following is a modified version of bolt/contrib/js/client.js // the following is a modified version of bolt/contrib/js/client.js
const { Gio, GLib, GObject, Polkit, Shell } = imports.gi; const { Gio, GLib, Polkit, Shell } = imports.gi;
const Signals = imports.signals; const Signals = imports.signals;
const Main = imports.ui.main; const Main = imports.ui.main;
@@ -221,11 +221,9 @@ Signals.addSignalMethods(AuthRobot.prototype);
/* eof client.js */ /* eof client.js */
var Indicator = GObject.registerClass({ var Indicator = class extends PanelMenu.SystemIndicator {
GTypeName: 'Thunderbolt_Indicator' constructor() {
}, class Indicator extends PanelMenu.SystemIndicator { super();
_init() {
super._init();
this._indicator = this._addIndicator(); this._indicator = this._addIndicator();
this._indicator.icon_name = 'thunderbolt-symbolic'; this._indicator.icon_name = 'thunderbolt-symbolic';
@@ -286,7 +284,7 @@ var Indicator = GObject.registerClass({
if (app) if (app)
app.activate(); app.activate();
}); });
this._source.showNotification(this._notification); this._source.notify(this._notification);
} }
/* Session callbacks */ /* Session callbacks */
@@ -336,4 +334,4 @@ var Indicator = GObject.registerClass({
const body = _("Could not authorize the Thunderbolt device: %s").format(error.message); const body = _("Could not authorize the Thunderbolt device: %s").format(error.message);
this._notify(title, body); this._notify(title, body);
} }
}); };

View File

@@ -47,7 +47,7 @@ var StreamSlider = class {
return this._slider.startDragging(event); return this._slider.startDragging(event);
}); });
this.item.connect('key-press-event', (actor, event) => { this.item.connect('key-press-event', (actor, event) => {
return this._slider.emit('key-press-event', event); return this._slider.onKeyPressEvent(actor, event);
}); });
this._stream = null; this._stream = null;
@@ -299,9 +299,6 @@ var VolumeMenu = class extends PopupMenu.PopupMenuSection {
this.addMenuItem(this._output.item); this.addMenuItem(this._output.item);
this._input = new InputStreamSlider(this._control); this._input = new InputStreamSlider(this._control);
this._input.item.connect('notify::visible', () => {
this.emit('input-visible-changed');
});
this.addMenuItem(this._input.item); this.addMenuItem(this._input.item);
this.addMenuItem(new PopupMenu.PopupSeparatorMenuItem()); this.addMenuItem(new PopupMenu.PopupSeparatorMenuItem());
@@ -341,44 +338,34 @@ var VolumeMenu = class extends PopupMenu.PopupMenuSection {
getMaxLevel() { getMaxLevel() {
return this._output.getMaxLevel(); return this._output.getMaxLevel();
} }
getInputVisible() {
return this._input.item.visible;
}
}; };
var Indicator = GObject.registerClass({ var Indicator = class extends PanelMenu.SystemIndicator {
GTypeName: 'Volume_Indicator' constructor() {
}, class Indicator extends PanelMenu.SystemIndicator { super();
_init() {
super._init();
this._primaryIndicator = this._addIndicator(); this._primaryIndicator = this._addIndicator();
this._inputIndicator = this._addIndicator();
this._control = getMixerControl(); this._control = getMixerControl();
this._volumeMenu = new VolumeMenu(this._control); this._volumeMenu = new VolumeMenu(this._control);
this._volumeMenu.connect('icon-changed', () => { this._volumeMenu.connect('icon-changed', () => {
let icon = this._volumeMenu.getIcon(); let icon = this._volumeMenu.getIcon();
if (icon != null) if (icon != null) {
this.indicators.show();
this._primaryIndicator.icon_name = icon; this._primaryIndicator.icon_name = icon;
this._primaryIndicator.visible = icon !== null; } else {
}); this.indicators.hide();
}
this._inputIndicator.set({
icon_name: 'audio-input-microphone-symbolic',
visible: this._volumeMenu.getInputVisible(),
});
this._volumeMenu.connect('input-visible-changed', () => {
this._inputIndicator.visible = this._volumeMenu.getInputVisible();
}); });
this.menu.addMenuItem(this._volumeMenu); this.menu.addMenuItem(this._volumeMenu);
this.indicators.connect('scroll-event', this._onScrollEvent.bind(this));
} }
vfunc_scroll_event() { _onScrollEvent(actor, event) {
let result = this._volumeMenu.scroll(Clutter.get_current_event()); let result = this._volumeMenu.scroll(event);
if (result == Clutter.EVENT_PROPAGATE || this.menu.actor.mapped) if (result == Clutter.EVENT_PROPAGATE || this.menu.actor.mapped)
return result; return result;
@@ -388,4 +375,4 @@ var Indicator = GObject.registerClass({
Main.osdWindowManager.show(-1, gicon, null, level, maxLevel); Main.osdWindowManager.show(-1, gicon, null, level, maxLevel);
return result; return result;
} }
}); };

View File

@@ -105,6 +105,12 @@ var SwitcherPopup = GObject.registerClass({
this._haveModal = true; this._haveModal = true;
this._modifierMask = primaryModifier(mask); this._modifierMask = primaryModifier(mask);
this.connect('key-press-event', this._keyPressEvent.bind(this));
this.connect('key-release-event', this._keyReleaseEvent.bind(this));
this.connect('button-press-event', this._clickedOutside.bind(this));
this.connect('scroll-event', this._scrollEvent.bind(this));
this.add_actor(this._switcherList); this.add_actor(this._switcherList);
this._switcherList.connect('item-activated', this._itemActivated.bind(this)); this._switcherList.connect('item-activated', this._itemActivated.bind(this));
this._switcherList.connect('item-entered', this._itemEntered.bind(this)); this._switcherList.connect('item-entered', this._itemEntered.bind(this));
@@ -160,10 +166,9 @@ var SwitcherPopup = GObject.registerClass({
throw new GObject.NotImplementedError(`_keyPressHandler in ${this.constructor.name}`); throw new GObject.NotImplementedError(`_keyPressHandler in ${this.constructor.name}`);
} }
vfunc_key_press_event(keyEvent) { _keyPressEvent(actor, event) {
let keysym = keyEvent.keyval; let keysym = event.get_key_symbol();
let action = global.display.get_keybinding_action( let action = global.display.get_keybinding_action(event.get_key_code(), event.get_state());
keyEvent.hardware_keycode, keyEvent.modifier_state);
this._disableHover(); this._disableHover();
@@ -178,13 +183,13 @@ var SwitcherPopup = GObject.registerClass({
return Clutter.EVENT_STOP; return Clutter.EVENT_STOP;
} }
vfunc_key_release_event(keyEvent) { _keyReleaseEvent(actor, event) {
if (this._modifierMask) { if (this._modifierMask) {
let [x_, y_, mods] = global.get_pointer(); let [x_, y_, mods] = global.get_pointer();
let state = mods & this._modifierMask; let state = mods & this._modifierMask;
if (state == 0) if (state == 0)
this._finish(keyEvent.time); this._finish(event.get_time());
} else { } else {
this._resetNoModsTimeout(); this._resetNoModsTimeout();
} }
@@ -192,8 +197,7 @@ var SwitcherPopup = GObject.registerClass({
return Clutter.EVENT_STOP; return Clutter.EVENT_STOP;
} }
vfunc_button_press_event() { _clickedOutside() {
/* We clicked outside */
this.fadeAndDestroy(); this.fadeAndDestroy();
return Clutter.EVENT_PROPAGATE; return Clutter.EVENT_PROPAGATE;
} }
@@ -205,8 +209,8 @@ var SwitcherPopup = GObject.registerClass({
this._select(this._next()); this._select(this._next());
} }
vfunc_scroll_event(scrollEvent) { _scrollEvent(actor, event) {
this._scrollHandler(scrollEvent.scroll_direction); this._scrollHandler(event.get_scroll_direction());
return Clutter.EVENT_PROPAGATE; return Clutter.EVENT_PROPAGATE;
} }

View File

@@ -1,17 +1,376 @@
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*- // -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
/* exported UnlockDialog */ /* exported UnlockDialog */
const { AccountsService, Atk, Clutter, const { AccountsService, Atk, Clutter, Gdm, Gio, GLib,
Gdm, Gio, GLib, GObject, Meta, Shell, St } = imports.gi; GnomeDesktop, GObject, Meta, Shell, St } = imports.gi;
const Layout = imports.ui.layout; const Layout = imports.ui.layout;
const Main = imports.ui.main; const Main = imports.ui.main;
const MessageTray = imports.ui.messageTray;
const Signals = imports.signals;
const AuthPrompt = imports.gdm.authPrompt; const AuthPrompt = imports.gdm.authPrompt;
// The timeout before going back automatically to the lock screen (in seconds) // The timeout before going back automatically to the lock screen (in seconds)
const IDLE_TIMEOUT = 2 * 60; const IDLE_TIMEOUT = 2 * 60;
var SUMMARY_ICON_SIZE = 24;
var Clock = class {
constructor() {
this.actor = new St.BoxLayout({
style_class: 'screen-shield-clock',
vertical: true,
});
this._time = new St.Label({ style_class: 'screen-shield-clock-time' });
this._date = new St.Label({ style_class: 'screen-shield-clock-date' });
this.actor.add(this._time, { x_align: St.Align.MIDDLE });
this.actor.add(this._date, { x_align: St.Align.MIDDLE });
this._wallClock = new GnomeDesktop.WallClock({ time_only: true });
this._wallClock.connect('notify::clock', this._updateClock.bind(this));
this._updateClock();
}
_updateClock() {
this._time.text = this._wallClock.clock;
let date = new Date();
/* Translators: This is a time format for a date in
long format */
let dateFormat = Shell.util_translate_time_string(N_("%A, %B %d"));
this._date.text = date.toLocaleFormat(dateFormat);
}
destroy() {
this.actor.destroy();
this._wallClock.run_dispose();
}
};
var NotificationsBox = class {
constructor() {
this.actor = new St.BoxLayout({ vertical: true,
name: 'screenShieldNotifications',
style_class: 'screen-shield-notifications-container' });
this._scrollView = new St.ScrollView({ x_fill: false, x_align: St.Align.START,
hscrollbar_policy: St.PolicyType.NEVER });
this._notificationBox = new St.BoxLayout({ vertical: true,
style_class: 'screen-shield-notifications-container' });
this._scrollView.add_actor(this._notificationBox);
this.actor.add(this._scrollView, { x_fill: true, x_align: St.Align.START });
this._sources = new Map();
Main.messageTray.getSources().forEach(source => {
this._sourceAdded(Main.messageTray, source, true);
});
this._updateVisibility();
this._sourceAddedId = Main.messageTray.connect('source-added', this._sourceAdded.bind(this));
}
destroy() {
if (this._sourceAddedId) {
Main.messageTray.disconnect(this._sourceAddedId);
this._sourceAddedId = 0;
}
let items = this._sources.entries();
for (let [source, obj] of items) {
this._removeSource(source, obj);
}
this.actor.destroy();
}
_updateVisibility() {
this._notificationBox.visible =
this._notificationBox.get_children().some(a => a.visible);
this.actor.visible = this._notificationBox.visible;
}
_makeNotificationSource(source, box) {
let sourceActor = new MessageTray.SourceActor(source, SUMMARY_ICON_SIZE);
box.add(sourceActor, { y_fill: true });
let title = new St.Label({
text: source.title,
style_class: 'screen-shield-notification-label',
x_expand: true,
y_align: Clutter.ActorAlign.START,
y_expand: true,
y_align: Clutter.ActorAlign.CENTER,
});
box.add_child(title);
let count = source.unseenCount;
let countLabel = new St.Label({
text: '%d'.format(count),
style_class: 'screen-shield-notification-count-text',
y_expand: true,
y_align: Clutter.ActorAlign.CENTER,
});
box.add_child(countLabel);
box.visible = count != 0;
return [title, countLabel];
}
_makeNotificationDetailedSource(source, box) {
let sourceActor = new MessageTray.SourceActor(source, SUMMARY_ICON_SIZE);
let sourceBin = new St.Bin({ y_align: St.Align.START,
x_align: St.Align.START,
child: sourceActor });
box.add(sourceBin);
let textBox = new St.BoxLayout({ vertical: true });
box.add(textBox, { y_fill: false, y_align: St.Align.START });
let title = new St.Label({ text: source.title,
style_class: 'screen-shield-notification-label' });
textBox.add(title);
let visible = false;
for (let i = 0; i < source.notifications.length; i++) {
let n = source.notifications[i];
if (n.acknowledged)
continue;
let body = '';
if (n.bannerBodyText) {
body = n.bannerBodyMarkup
? n.bannerBodyText
: GLib.markup_escape_text(n.bannerBodyText, -1);
}
let label = new St.Label({ style_class: 'screen-shield-notification-count-text' });
label.clutter_text.set_markup('<b>' + n.title + '</b> ' + body);
textBox.add(label);
visible = true;
}
box.visible = visible;
return [title, null];
}
_shouldShowDetails(source) {
return source.policy.detailsInLockScreen ||
source.narrowestPrivacyScope == MessageTray.PrivacyScope.SYSTEM;
}
_showSource(source, obj, box) {
if (obj.detailed) {
[obj.titleLabel, obj.countLabel] = this._makeNotificationDetailedSource(source, box);
} else {
[obj.titleLabel, obj.countLabel] = this._makeNotificationSource(source, box);
}
box.visible = obj.visible && (source.unseenCount > 0);
}
_sourceAdded(tray, source, initial) {
let obj = {
visible: source.policy.showInLockScreen,
detailed: this._shouldShowDetails(source),
sourceDestroyId: 0,
sourceCountChangedId: 0,
sourceTitleChangedId: 0,
sourceUpdatedId: 0,
sourceBox: null,
titleLabel: null,
countLabel: null,
};
obj.sourceBox = new St.BoxLayout({ style_class: 'screen-shield-notification-source',
x_expand: true });
this._showSource(source, obj, obj.sourceBox);
this._notificationBox.add(obj.sourceBox, { x_fill: false, x_align: St.Align.START });
obj.sourceCountChangedId = source.connect('count-updated', source => {
this._countChanged(source, obj);
});
obj.sourceTitleChangedId = source.connect('title-changed', source => {
this._titleChanged(source, obj);
});
obj.policyChangedId = source.policy.connect('policy-changed', (policy, key) => {
if (key == 'show-in-lock-screen')
this._visibleChanged(source, obj);
else
this._detailedChanged(source, obj);
});
obj.sourceDestroyId = source.connect('destroy', source => {
this._onSourceDestroy(source, obj);
});
this._sources.set(source, obj);
if (!initial) {
// block scrollbars while animating, if they're not needed now
let boxHeight = this._notificationBox.height;
if (this._scrollView.height >= boxHeight)
this._scrollView.vscrollbar_policy = St.PolicyType.NEVER;
let widget = obj.sourceBox;
let [, natHeight] = widget.get_preferred_height(-1);
widget.height = 0;
widget.ease({
height: natHeight,
mode: Clutter.AnimationMode.EASE_OUT_QUAD,
duration: 250,
onComplete: () => {
this._scrollView.vscrollbar_policy = St.PolicyType.AUTOMATIC;
widget.set_height(-1);
}
});
this._updateVisibility();
if (obj.sourceBox.visible)
this.emit('wake-up-screen');
}
}
_titleChanged(source, obj) {
obj.titleLabel.text = source.title;
}
_countChanged(source, obj) {
// A change in the number of notifications may change whether we show
// details.
let newDetailed = this._shouldShowDetails(source);
let oldDetailed = obj.detailed;
obj.detailed = newDetailed;
if (obj.detailed || oldDetailed != newDetailed) {
// A new notification was pushed, or a previous notification was destroyed.
// Give up, and build the list again.
obj.sourceBox.destroy_all_children();
obj.titleLabel = obj.countLabel = null;
this._showSource(source, obj, obj.sourceBox);
} else {
let count = source.unseenCount;
obj.countLabel.text = '%d'.format(count);
}
obj.sourceBox.visible = obj.visible && (source.unseenCount > 0);
this._updateVisibility();
if (obj.sourceBox.visible)
this.emit('wake-up-screen');
}
_visibleChanged(source, obj) {
if (obj.visible == source.policy.showInLockScreen)
return;
obj.visible = source.policy.showInLockScreen;
obj.sourceBox.visible = obj.visible && source.unseenCount > 0;
this._updateVisibility();
if (obj.sourceBox.visible)
this.emit('wake-up-screen');
}
_detailedChanged(source, obj) {
let newDetailed = this._shouldShowDetails(source);
if (obj.detailed == newDetailed)
return;
obj.detailed = newDetailed;
obj.sourceBox.destroy_all_children();
obj.titleLabel = obj.countLabel = null;
this._showSource(source, obj, obj.sourceBox);
}
_onSourceDestroy(source, obj) {
this._removeSource(source, obj);
this._updateVisibility();
}
_removeSource(source, obj) {
obj.sourceBox.destroy();
obj.sourceBox = obj.titleLabel = obj.countLabel = null;
source.disconnect(obj.sourceDestroyId);
source.disconnect(obj.sourceCountChangedId);
source.disconnect(obj.sourceTitleChangedId);
source.policy.disconnect(obj.policyChangedId);
this._sources.delete(source);
}
};
Signals.addSignalMethods(NotificationsBox.prototype);
var UnlockDialogLayout = GObject.registerClass(
class UnlockDialogLayout extends Clutter.LayoutManager {
_init(clockStack, notifications) {
super._init();
this._clockStack = clockStack;
this._notifications = notifications;
}
vfunc_get_preferred_width(container, forHeight) {
return this._clockStack.get_preferred_width(forHeight);
}
vfunc_get_preferred_height(container, forWidth) {
return this._clockStack.get_preferred_height(forWidth);
}
vfunc_allocate(container, box, flags) {
let [width, height] = box.get_size();
let tenthOfHeight = height / 10.0;
let thirdOfHeight = height / 3.0;
let [clockStackWidth, clockStackHeight] =
this._clockStack.get_preferred_size();
let [, , notificationsWidth, notificationsHeight] =
this._notifications.get_preferred_size();
let columnWidth = Math.max(clockStackWidth, notificationsWidth);
let columnX1 = Math.floor(width / 2.0 - columnWidth / 2.0);
let actorBox = new Clutter.ActorBox();
// Notifications
let maxNotificationsHeight = Math.min(
notificationsHeight,
height - tenthOfHeight - clockStackHeight);
actorBox.x1 = columnX1;
actorBox.y1 = height - maxNotificationsHeight;
actorBox.x2 = columnX1 + columnWidth;
actorBox.y2 = actorBox.y1 + maxNotificationsHeight;
this._notifications.allocate(actorBox, flags);
// Clock Stack
let clockStackY = Math.min(
thirdOfHeight,
height - clockStackHeight - maxNotificationsHeight);
actorBox.x1 = columnX1;
actorBox.y1 = clockStackY;
actorBox.x2 = columnX1 + columnWidth;
actorBox.y2 = clockStackY + clockStackHeight;
this._clockStack.allocate(actorBox, flags);
}
});
var UnlockDialog = GObject.registerClass({ var UnlockDialog = GObject.registerClass({
Signals: { 'failed': {} }, Signals: { 'failed': {} },
}, class UnlockDialog extends St.Widget { }, class UnlockDialog extends St.Widget {
@@ -19,10 +378,16 @@ var UnlockDialog = GObject.registerClass({
super._init({ super._init({
accessible_role: Atk.Role.WINDOW, accessible_role: Atk.Role.WINDOW,
style_class: 'login-dialog', style_class: 'login-dialog',
layout_manager: new Clutter.BoxLayout(), reactive: true,
visible: false, visible: false,
}); });
let tapAction = new Clutter.TapAction();
tapAction.connect('tap', () => {
this._showAuth();
})
this.add_action(tapAction);
this.add_constraint(new Layout.MonitorConstraint({ primary: true })); this.add_constraint(new Layout.MonitorConstraint({ primary: true }));
parentActor.add_child(this); parentActor.add_child(this);
@@ -30,21 +395,31 @@ var UnlockDialog = GObject.registerClass({
this._userName = GLib.get_user_name(); this._userName = GLib.get_user_name();
this._user = this._userManager.get_user(this._userName); this._user = this._userManager.get_user(this._userName);
this._promptBox = new St.BoxLayout({ vertical: true, let clockStack = new Shell.Stack();
x_align: Clutter.ActorAlign.CENTER, this.add_child(clockStack);
y_align: Clutter.ActorAlign.CENTER,
x_expand: true, this._clock = new Clock();
y_expand: true }); clockStack.add_child(this._clock.actor);
this.add_child(this._promptBox);
this._activePage = this._clock.actor;
this._authBox = new St.BoxLayout({
x_align: Clutter.ActorAlign.CENTER,
y_align: Clutter.ActorAlign.CENTER,
x_expand: true,
y_expand: true,
vertical: true,
visible: false,
});
clockStack.add_child(this._authBox);
this._authPrompt = new AuthPrompt.AuthPrompt(new Gdm.Client(), AuthPrompt.AuthPromptMode.UNLOCK_ONLY); this._authPrompt = new AuthPrompt.AuthPrompt(new Gdm.Client(), AuthPrompt.AuthPromptMode.UNLOCK_ONLY);
this._authPrompt.connect('failed', this._fail.bind(this)); this._authPrompt.connect('failed', this._fail.bind(this));
this._authPrompt.connect('cancelled', this._fail.bind(this)); this._authPrompt.connect('cancelled', this._fail.bind(this));
this._authPrompt.connect('reset', this._onReset.bind(this)); this._authPrompt.connect('reset', this._onReset.bind(this));
this._authPrompt.setPasswordChar('\u25cf'); this._authPrompt.setPasswordChar('\u25cf');
this._authPrompt.nextButton.label = _("Unlock");
this._promptBox.add_child(this._authPrompt); this._authBox.add_child(this._authPrompt.actor);
this.allowCancel = false; this.allowCancel = false;
@@ -59,11 +434,15 @@ var UnlockDialog = GObject.registerClass({
x_align: St.Align.START, x_align: St.Align.START,
x_fill: false }); x_fill: false });
this._otherUserButton.connect('clicked', this._otherUserClicked.bind(this)); this._otherUserButton.connect('clicked', this._otherUserClicked.bind(this));
this._promptBox.add_child(this._otherUserButton); this._authBox.add_child(this._otherUserButton);
} else { } else {
this._otherUserButton = null; this._otherUserButton = null;
} }
this._notificationsBox = new NotificationsBox();
this._wakeUpScreenId = this._notificationsBox.connect('wake-up-screen', this._wakeUpScreen.bind(this));
this.add_child(this._notificationsBox.actor);
this._authPrompt.reset(); this._authPrompt.reset();
this._updateSensitivity(true); this._updateSensitivity(true);
@@ -72,9 +451,81 @@ var UnlockDialog = GObject.registerClass({
this._idleMonitor = Meta.IdleMonitor.get_core(); this._idleMonitor = Meta.IdleMonitor.get_core();
this._idleWatchId = this._idleMonitor.add_idle_watch(IDLE_TIMEOUT * 1000, this._escape.bind(this)); this._idleWatchId = this._idleMonitor.add_idle_watch(IDLE_TIMEOUT * 1000, this._escape.bind(this));
this.layout_manager = new UnlockDialogLayout(
clockStack,
this._notificationsBox.actor);
this.connect('destroy', this._onDestroy.bind(this)); this.connect('destroy', this._onDestroy.bind(this));
} }
_showClock() {
if (this._activePage == this._clock.actor)
return;
this._activePage = this._clock.actor;
this._clock.actor.show();
this._authBox.ease({
opacity: 0,
duration: 300,
mode: Clutter.AnimationMode.EASE_OUT_QUAD,
onComplete: () => this._authBox.hide(),
});
this._clock.actor.ease({
opacity: 255,
duration: 300,
mode: Clutter.AnimationMode.EASE_OUT_QUAD,
});
}
_showAuth() {
if (this._activePage == this._authBox)
return;
this._activePage = this._authBox;
this._authBox.show();
this._clock.actor.ease({
opacity: 0,
duration: 300,
mode: Clutter.AnimationMode.EASE_OUT_QUAD,
onComplete: () => this._clock.actor.hide(),
});
this._authBox.ease({
opacity: 255,
duration: 300,
mode: Clutter.AnimationMode.EASE_OUT_QUAD,
});
}
vfunc_captured_event(event) {
if (event.type() != Clutter.EventType.KEY_PRESS)
return Clutter.EVENT_PROPAGATE;
if (this._activePage == this._authBox)
return Clutter.EVENT_PROPAGATE;
let symbol = event.get_key_symbol();
let unichar = event.get_key_unicode();
let isEnter = (symbol == Clutter.KEY_Return ||
symbol == Clutter.KEY_KP_Enter ||
symbol == Clutter.KEY_ISO_Enter);
let isEscape = (symbol == Clutter.KEY_Escape);
let isLiftChar = (GLib.unichar_isprint(unichar) &&
(this._activePage == this._clock.actor ||
!GLib.unichar_isgraph(unichar)));
if (!isEnter && !isEscape && !isLiftChar)
return Clutter.EVENT_PROPAGATE;
this._showAuth();
return Clutter.EVENT_PROPAGATE;
}
_updateSensitivity(sensitive) { _updateSensitivity(sensitive) {
this._authPrompt.updateSensitivity(sensitive); this._authPrompt.updateSensitivity(sensitive);
@@ -85,6 +536,7 @@ var UnlockDialog = GObject.registerClass({
} }
_fail() { _fail() {
this._showClock();
this.emit('failed'); this.emit('failed');
} }
@@ -111,9 +563,24 @@ var UnlockDialog = GObject.registerClass({
this._authPrompt.cancel(); this._authPrompt.cancel();
} }
_wakeUpScreen() {
// FIXME
//this._onUserBecameActive();
this.emit('wake-up-screen');
}
_onDestroy() { _onDestroy() {
this.popModal(); this.popModal();
if (this._notificationsBox) {
this._notificationsBox.disconnect(this._wakeUpScreenId);
this._notificationsBox.destroy();
this._notificationsBox = null;
}
this._clock.destroy();
this._clock = null;
if (this._idleWatchId) { if (this._idleWatchId) {
this._idleMonitor.remove_watch(this._idleWatchId); this._idleMonitor.remove_watch(this._idleWatchId);
this._idleWatchId = 0; this._idleWatchId = 0;
@@ -122,11 +589,10 @@ var UnlockDialog = GObject.registerClass({
cancel() { cancel() {
this._authPrompt.cancel(); this._authPrompt.cancel();
this.destroy();
} }
addCharacter(unichar) { addCharacter(unichar) {
this._showAuth();
this._authPrompt.addCharacter(unichar); this._authPrompt.addCharacter(unichar);
} }

View File

@@ -14,47 +14,29 @@ var AVATAR_ICON_SIZE = 64;
// Copyright (C) 2004-2005 James M. Cape <jcape@ignore-your.tv>. // Copyright (C) 2004-2005 James M. Cape <jcape@ignore-your.tv>.
// Copyright (C) 2008,2009 Red Hat, Inc. // Copyright (C) 2008,2009 Red Hat, Inc.
var Avatar = GObject.registerClass({ var Avatar = class {
GTypeName: 'UserWidget_Avatar' constructor(user, params) {
}, class Avatar extends St.Bin { this._user = user;
_init(user, params) {
let themeContext = St.ThemeContext.get_for_stage(global.stage);
params = Params.parse(params, { reactive: false, params = Params.parse(params, { reactive: false,
iconSize: AVATAR_ICON_SIZE, iconSize: AVATAR_ICON_SIZE,
styleClass: 'user-icon' }); styleClass: 'user-icon' });
super._init({
style_class: params.styleClass,
reactive: params.reactive,
width: params.iconSize * themeContext.scaleFactor,
height: params.iconSize * themeContext.scaleFactor
});
this._iconSize = params.iconSize; this._iconSize = params.iconSize;
this._user = user;
this.bind_property('reactive', this, 'track-hover', let scaleFactor = St.ThemeContext.get_for_stage(global.stage).scale_factor;
GObject.BindingFlags.SYNC_CREATE); this.actor = new St.Bin({ style_class: params.styleClass,
this.bind_property('reactive', this, 'can-focus', track_hover: params.reactive,
GObject.BindingFlags.SYNC_CREATE); reactive: params.reactive,
width: this._iconSize * scaleFactor,
height: this._iconSize * scaleFactor });
// Monitor the scaling factor to make sure we recreate the avatar when needed. // Monitor the scaling factor to make sure we recreate the avatar when needed.
this._scaleFactorChangeId = let themeContext = St.ThemeContext.get_for_stage(global.stage);
themeContext.connect('notify::scale-factor', this.update.bind(this)); themeContext.connect('notify::scale-factor', this.update.bind(this));
this.connect('destroy', this._onDestroy.bind(this));
}
_onDestroy() {
if (this._scaleFactorChangeId) {
let themeContext = St.ThemeContext.get_for_stage(global.stage);
themeContext.disconnect(this._scaleFactorChangeId);
delete this._scaleFactorChangeId;
}
} }
setSensitive(sensitive) { setSensitive(sensitive) {
this.reactive = sensitive; this.actor.can_focus = sensitive;
this.actor.reactive = sensitive;
} }
update() { update() {
@@ -63,21 +45,21 @@ var Avatar = GObject.registerClass({
iconFile = null; iconFile = null;
if (iconFile) { if (iconFile) {
this.child = null; this.actor.child = null;
let { scaleFactor } = St.ThemeContext.get_for_stage(global.stage); let { scaleFactor } = St.ThemeContext.get_for_stage(global.stage);
this.set_size( this.actor.set_size(
this._iconSize * scaleFactor, this._iconSize * scaleFactor,
this._iconSize * scaleFactor); this._iconSize * scaleFactor);
this.style = ` this.actor.style = `
background-image: url("${iconFile}"); background-image: url("${iconFile}");
background-size: cover;`; background-size: cover;`;
} else { } else {
this.style = null; this.actor.style = null;
this.child = new St.Icon({ icon_name: 'avatar-default-symbolic', this.actor.child = new St.Icon({ icon_name: 'avatar-default-symbolic',
icon_size: this._iconSize }); icon_size: this._iconSize });
} }
} }
}); };
var UserWidgetLabel = GObject.registerClass( var UserWidgetLabel = GObject.registerClass(
class UserWidgetLabel extends St.Widget { class UserWidgetLabel extends St.Widget {
@@ -158,22 +140,21 @@ class UserWidgetLabel extends St.Widget {
} }
}); });
var UserWidget = GObject.registerClass( var UserWidget = class {
class UserWidget extends St.BoxLayout { constructor(user) {
_init(user) {
super._init({ style_class: 'user-widget', vertical: false });
this._user = user; this._user = user;
this.connect('destroy', this._onDestroy.bind(this)); this.actor = new St.BoxLayout({ style_class: 'user-widget',
vertical: false });
this.actor.connect('destroy', this._onDestroy.bind(this));
this._avatar = new Avatar(user); this._avatar = new Avatar(user);
this.add_child(this._avatar); this.actor.add_child(this._avatar.actor);
this._label = new UserWidgetLabel(user); this._label = new UserWidgetLabel(user);
this.add_child(this._label); this.actor.add_child(this._label);
this._label.bind_property('label-actor', this, 'label-actor', this._label.bind_property('label-actor', this.actor, 'label-actor',
GObject.BindingFlags.SYNC_CREATE); GObject.BindingFlags.SYNC_CREATE);
this._userLoadedId = this._user.connect('notify::is-loaded', this._updateUser.bind(this)); this._userLoadedId = this._user.connect('notify::is-loaded', this._updateUser.bind(this));
@@ -196,4 +177,4 @@ class UserWidget extends St.BoxLayout {
_updateUser() { _updateUser() {
this._avatar.update(); this._avatar.update();
} }
}); };

View File

@@ -123,14 +123,9 @@ var ShowOverviewAction = GObject.registerClass({
} }
}); });
var ViewSelector = GObject.registerClass({ var ViewSelector = class {
Signals: { constructor(searchEntry, showAppsButton) {
'page-changed': {}, this.actor = new Shell.Stack({ name: 'viewSelector' });
'page-empty': {},
}
}, class ViewSelector extends Shell.Stack {
_init(searchEntry, showAppsButton) {
super._init({ name: 'viewSelector' });
this._showAppsButton = showAppsButton; this._showAppsButton = showAppsButton;
this._showAppsButton.connect('notify::checked', this._onShowAppsButtonToggled.bind(this)); this._showAppsButton.connect('notify::checked', this._onShowAppsButtonToggled.bind(this));
@@ -170,15 +165,15 @@ var ViewSelector = GObject.registerClass({
this._capturedEventId = 0; this._capturedEventId = 0;
this._workspacesDisplay = new WorkspacesView.WorkspacesDisplay(); this._workspacesDisplay = new WorkspacesView.WorkspacesDisplay();
this._workspacesPage = this._addPage(this._workspacesDisplay, this._workspacesPage = this._addPage(this._workspacesDisplay.actor,
_("Windows"), 'focus-windows-symbolic'); _("Windows"), 'focus-windows-symbolic');
this.appDisplay = new AppDisplay.AppDisplay(); this.appDisplay = new AppDisplay.AppDisplay();
this._appsPage = this._addPage(this.appDisplay, this._appsPage = this._addPage(this.appDisplay.actor,
_("Applications"), 'view-app-grid-symbolic'); _("Applications"), 'view-app-grid-symbolic');
this._searchResults = new Search.SearchResultsView(); this._searchResults = new Search.SearchResults();
this._searchPage = this._addPage(this._searchResults, this._searchPage = this._addPage(this._searchResults.actor,
_("Search"), 'edit-find-symbolic', _("Search"), 'edit-find-symbolic',
{ a11yFocus: this._entry }); { a11yFocus: this._entry });
@@ -189,9 +184,9 @@ var ViewSelector = GObject.registerClass({
this._focusTrap.connect('key-focus-in', () => { this._focusTrap.connect('key-focus-in', () => {
this._entry.grab_key_focus(); this._entry.grab_key_focus();
}); });
this._searchResults.add_actor(this._focusTrap); this._searchResults.actor.add_actor(this._focusTrap);
global.focus_manager.add_group(this._searchResults); global.focus_manager.add_group(this._searchResults.actor);
this._stageKeyPressId = 0; this._stageKeyPressId = 0;
Main.overview.connect('showing', () => { Main.overview.connect('showing', () => {
@@ -315,11 +310,11 @@ var ViewSelector = GObject.registerClass({
Main.ctrlAltTabManager.addGroup(params.a11yFocus, name, a11yIcon); Main.ctrlAltTabManager.addGroup(params.a11yFocus, name, a11yIcon);
else else
Main.ctrlAltTabManager.addGroup(actor, name, a11yIcon, { Main.ctrlAltTabManager.addGroup(actor, name, a11yIcon, {
proxy: this, proxy: this.actor,
focusCallback: () => this._a11yFocusPage(page), focusCallback: () => this._a11yFocusPage(page),
}); });
page.hide(); page.hide();
this.add_actor(page); this.actor.add_actor(page);
return page; return page;
} }
@@ -459,7 +454,7 @@ var ViewSelector = GObject.registerClass({
_onStageKeyFocusChanged() { _onStageKeyFocusChanged() {
let focus = global.stage.get_key_focus(); let focus = global.stage.get_key_focus();
let appearFocused = (this._entry.contains(focus) || let appearFocused = (this._entry.contains(focus) ||
this._searchResults.contains(focus)); this._searchResults.actor.contains(focus));
this._text.set_cursor_visible(appearFocused); this._text.set_cursor_visible(appearFocused);
@@ -604,4 +599,5 @@ var ViewSelector = GObject.registerClass({
else else
return ViewPage.SEARCH; return ViewPage.SEARCH;
} }
}); };
Signals.addSignalMethods(ViewSelector.prototype);

View File

@@ -1,7 +1,7 @@
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*- // -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
/* exported WindowAttentionHandler */ /* exported WindowAttentionHandler */
const { GObject, Shell } = imports.gi; const Shell = imports.gi.Shell;
const Main = imports.ui.main; const Main = imports.ui.main;
const MessageTray = imports.ui.messageTray; const MessageTray = imports.ui.messageTray;
@@ -34,7 +34,7 @@ var WindowAttentionHandler = class {
return; return;
let app = this._tracker.get_window_app(window); let app = this._tracker.get_window_app(window);
let source = new WindowAttentionSource(app, window); let source = new Source(app, window);
Main.messageTray.add(source); Main.messageTray.add(source);
let [title, banner] = this._getTitleAndBanner(app, window); let [title, banner] = this._getTitleAndBanner(app, window);
@@ -45,7 +45,7 @@ var WindowAttentionHandler = class {
}); });
notification.setForFeedback(true); notification.setForFeedback(true);
source.showNotification(notification); source.notify(notification);
source.signalIDs.push(window.connect('notify::title', () => { source.signalIDs.push(window.connect('notify::title', () => {
let [title, banner] = this._getTitleAndBanner(app, window); let [title, banner] = this._getTitleAndBanner(app, window);
@@ -54,10 +54,9 @@ var WindowAttentionHandler = class {
} }
}; };
var WindowAttentionSource = GObject.registerClass( var Source = class WindowAttentionSource extends MessageTray.Source {
class WindowAttentionSource extends MessageTray.Source { constructor(app, window) {
_init(app, window) { super(app.get_name());
super._init(app.get_name());
this._window = window; this._window = window;
this._app = app; this._app = app;
@@ -103,4 +102,4 @@ class WindowAttentionSource extends MessageTray.Source {
open() { open() {
Main.activateWindow(this._window); Main.activateWindow(this._window);
} }
}); };

View File

@@ -40,8 +40,6 @@ const GSD_WACOM_OBJECT_PATH = '/org/gnome/SettingsDaemon/Wacom';
const GsdWacomIface = loadInterfaceXML('org.gnome.SettingsDaemon.Wacom'); const GsdWacomIface = loadInterfaceXML('org.gnome.SettingsDaemon.Wacom');
const GsdWacomProxy = Gio.DBusProxy.makeProxyWrapper(GsdWacomIface); const GsdWacomProxy = Gio.DBusProxy.makeProxyWrapper(GsdWacomIface);
const WINDOW_DIMMER_EFFECT_NAME = "gnome-shell-window-dimmer";
var DisplayChangeDialog = GObject.registerClass( var DisplayChangeDialog = GObject.registerClass(
class DisplayChangeDialog extends ModalDialog.ModalDialog { class DisplayChangeDialog extends ModalDialog.ModalDialog {
_init(wm) { _init(wm) {
@@ -116,20 +114,21 @@ class DisplayChangeDialog extends ModalDialog.ModalDialog {
} }
}); });
var WindowDimmer = GObject.registerClass( var WindowDimmer = class {
class WindowDimmer extends Clutter.BrightnessContrastEffect { constructor(actor) {
_init() { this._brightnessEffect = new Clutter.BrightnessContrastEffect({
super._init({ name: 'dim',
name: WINDOW_DIMMER_EFFECT_NAME,
enabled: false enabled: false
}); });
actor.add_effect(this._brightnessEffect);
this.actor = actor;
this._enabled = true; this._enabled = true;
} }
_syncEnabled() { _syncEnabled() {
let animating = this.actor.get_transition(`@effects.${this.name}.brightness`) != null; let animating = this.actor.get_transition('@effects.dim.brightness') != null;
let dimmed = this.brightness.red != 127; let dimmed = this._brightnessEffect.brightness.red != 127;
this.enabled = this._enabled && (animating || dimmed); this._brightnessEffect.enabled = this._enabled && (animating || dimmed);
} }
setEnabled(enabled) { setEnabled(enabled) {
@@ -141,7 +140,7 @@ class WindowDimmer extends Clutter.BrightnessContrastEffect {
let val = 127 * (1 + (dimmed ? 1 : 0) * DIM_BRIGHTNESS); let val = 127 * (1 + (dimmed ? 1 : 0) * DIM_BRIGHTNESS);
let color = Clutter.Color.new(val, val, val, 255); let color = Clutter.Color.new(val, val, val, 255);
this.actor.ease_property(`@effects.${this.name}.brightness`, color, { this.actor.ease_property('@effects.dim.brightness', color, {
mode: Clutter.AnimationMode.LINEAR, mode: Clutter.AnimationMode.LINEAR,
duration: (dimmed ? DIM_TIME : UNDIM_TIME) * (animate ? 1 : 0), duration: (dimmed ? DIM_TIME : UNDIM_TIME) * (animate ? 1 : 0),
onComplete: () => this._syncEnabled() onComplete: () => this._syncEnabled()
@@ -149,19 +148,20 @@ class WindowDimmer extends Clutter.BrightnessContrastEffect {
this._syncEnabled(); this._syncEnabled();
} }
}); };
function getWindowDimmer(actor) { function getWindowDimmer(actor) {
let enabled = Meta.prefs_get_attach_modal_dialogs(); let enabled = Meta.prefs_get_attach_modal_dialogs();
let effect = actor.get_effect(WINDOW_DIMMER_EFFECT_NAME); if (actor._windowDimmer)
actor._windowDimmer.setEnabled(enabled);
if (effect) { if (enabled) {
effect.setEnabled(enabled); if (!actor._windowDimmer)
} else if (enabled) { actor._windowDimmer = new WindowDimmer(actor);
effect = new WindowDimmer(); return actor._windowDimmer;
actor.add_effect(effect); } else {
return null;
} }
return effect;
} }
/* /*
@@ -379,22 +379,21 @@ var WorkspaceTracker = class {
} }
}; };
var TilePreview = GObject.registerClass( var TilePreview = class {
class TilePreview extends St.Widget { constructor() {
_init() { this.actor = new St.Widget();
super._init(); global.window_group.add_actor(this.actor);
global.window_group.add_actor(this);
this._reset(); this._reset();
this._showing = false; this._showing = false;
} }
open(window, tileRect, monitorIndex) { show(window, tileRect, monitorIndex) {
let windowActor = window.get_compositor_private(); let windowActor = window.get_compositor_private();
if (!windowActor) if (!windowActor)
return; return;
global.window_group.set_child_below_sibling(this, windowActor); global.window_group.set_child_below_sibling(this.actor, windowActor);
if (this._rect && this._rect.equal(tileRect)) if (this._rect && this._rect.equal(tileRect))
return; return;
@@ -415,14 +414,14 @@ class TilePreview extends St.Widget {
width: monitor.width, width: monitor.width,
height: monitor.height }); height: monitor.height });
let [, rect] = window.get_frame_rect().intersect(monitorRect); let [, rect] = window.get_frame_rect().intersect(monitorRect);
this.set_size(rect.width, rect.height); this.actor.set_size(rect.width, rect.height);
this.set_position(rect.x, rect.y); this.actor.set_position(rect.x, rect.y);
this.opacity = 0; this.actor.opacity = 0;
} }
this._showing = true; this._showing = true;
this.show(); this.actor.show();
this.ease({ this.actor.ease({
x: tileRect.x, x: tileRect.x,
y: tileRect.y, y: tileRect.y,
width: tileRect.width, width: tileRect.width,
@@ -433,12 +432,12 @@ class TilePreview extends St.Widget {
}); });
} }
close() { hide() {
if (!this._showing) if (!this._showing)
return; return;
this._showing = false; this._showing = false;
this.ease({ this.actor.ease({
opacity: 0, opacity: 0,
duration: WINDOW_ANIMATION_TIME, duration: WINDOW_ANIMATION_TIME,
mode: Clutter.AnimationMode.EASE_OUT_QUAD, mode: Clutter.AnimationMode.EASE_OUT_QUAD,
@@ -447,7 +446,7 @@ class TilePreview extends St.Widget {
} }
_reset() { _reset() {
this.hide(); this.actor.hide();
this._rect = null; this._rect = null;
this._monitorIndex = -1; this._monitorIndex = -1;
} }
@@ -461,9 +460,9 @@ class TilePreview extends St.Widget {
if (this._rect.x + this._rect.width == monitor.x + monitor.width) if (this._rect.x + this._rect.width == monitor.x + monitor.width)
styles.push('tile-preview-right'); styles.push('tile-preview-right');
this.style_class = styles.join(' '); this.actor.style_class = styles.join(' ');
} }
}); };
var TouchpadWorkspaceSwitchAction = class { var TouchpadWorkspaceSwitchAction = class {
constructor(actor, allowedModes) { constructor(actor, allowedModes) {
@@ -670,16 +669,15 @@ var AppSwitchAction = GObject.registerClass({
} }
}); });
var ResizePopup = GObject.registerClass( var ResizePopup = class {
class ResizePopup extends St.Widget { constructor() {
_init() { this._widget = new St.Widget({ layout_manager: new Clutter.BinLayout() });
super._init({ layout_manager: new Clutter.BinLayout() });
this._label = new St.Label({ style_class: 'resize-popup', this._label = new St.Label({ style_class: 'resize-popup',
x_align: Clutter.ActorAlign.CENTER, x_align: Clutter.ActorAlign.CENTER,
y_align: Clutter.ActorAlign.CENTER, y_align: Clutter.ActorAlign.CENTER,
x_expand: true, y_expand: true }); x_expand: true, y_expand: true });
this.add_child(this._label); this._widget.add_child(this._label);
Main.uiGroup.add_actor(this); Main.uiGroup.add_actor(this._widget);
} }
set(rect, displayW, displayH) { set(rect, displayW, displayH) {
@@ -688,10 +686,15 @@ class ResizePopup extends St.Widget {
let text = _("%d × %d").format(displayW, displayH); let text = _("%d × %d").format(displayW, displayH);
this._label.set_text(text); this._label.set_text(text);
this.set_position(rect.x, rect.y); this._widget.set_position(rect.x, rect.y);
this.set_size(rect.width, rect.height); this._widget.set_size(rect.width, rect.height);
} }
});
destroy() {
this._widget.destroy();
this._widget = null;
}
};
var WindowManager = class { var WindowManager = class {
constructor() { constructor() {
@@ -1086,7 +1089,7 @@ var WindowManager = class {
let mode = Shell.ActionMode.ALL & ~Shell.ActionMode.LOCK_SCREEN; let mode = Shell.ActionMode.ALL & ~Shell.ActionMode.LOCK_SCREEN;
let bottomDragAction = new EdgeDragAction.EdgeDragAction(St.Side.BOTTOM, mode); let bottomDragAction = new EdgeDragAction.EdgeDragAction(St.Side.BOTTOM, mode);
bottomDragAction.connect('activated', () => { bottomDragAction.connect('activated', () => {
Main.keyboard.open(Main.layoutManager.bottomIndex); Main.keyboard.show(Main.layoutManager.bottomIndex);
}); });
Main.layoutManager.connect('keyboard-visible-changed', (manager, visible) => { Main.layoutManager.connect('keyboard-visible-changed', (manager, visible) => {
bottomDragAction.cancel(); bottomDragAction.cancel();
@@ -1116,7 +1119,7 @@ var WindowManager = class {
this._currentPadOsd = new PadOsd.PadOsd(device, settings, imagePath, editionMode, monitorIndex); this._currentPadOsd = new PadOsd.PadOsd(device, settings, imagePath, editionMode, monitorIndex);
this._currentPadOsd.connect('closed', () => (this._currentPadOsd = null)); this._currentPadOsd.connect('closed', () => (this._currentPadOsd = null));
return this._currentPadOsd; return this._currentPadOsd.actor;
} }
_switchWorkspaceMotion(action, xRel, yRel) { _switchWorkspaceMotion(action, xRel, yRel) {
@@ -2042,13 +2045,13 @@ var WindowManager = class {
_showTilePreview(shellwm, window, tileRect, monitorIndex) { _showTilePreview(shellwm, window, tileRect, monitorIndex) {
if (!this._tilePreview) if (!this._tilePreview)
this._tilePreview = new TilePreview(); this._tilePreview = new TilePreview();
this._tilePreview.open(window, tileRect, monitorIndex); this._tilePreview.show(window, tileRect, monitorIndex);
} }
_hideTilePreview() { _hideTilePreview() {
if (!this._tilePreview) if (!this._tilePreview)
return; return;
this._tilePreview.close(); this._tilePreview.hide();
} }
_showWindowMenu(shellwm, window, menu, rect) { _showWindowMenu(shellwm, window, menu, rect) {

View File

@@ -1,8 +1,7 @@
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*- // -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
/* exported Workspace */ /* exported Workspace */
const { Atk, Clutter, GLib, GObject, const { Atk, Clutter, GLib, GObject, Meta, Pango, Shell, St } = imports.gi;
Graphene, Meta, Pango, Shell, St } = imports.gi;
const Signals = imports.signals; const Signals = imports.signals;
const DND = imports.ui.dnd; const DND = imports.ui.dnd;
@@ -94,7 +93,6 @@ class WindowCloneLayout extends Clutter.LayoutManager {
}); });
var WindowClone = GObject.registerClass({ var WindowClone = GObject.registerClass({
GTypeName: 'Workspace_WindowClone',
Signals: { Signals: {
'drag-begin': {}, 'drag-begin': {},
'drag-cancelled': {}, 'drag-cancelled': {},
@@ -104,7 +102,7 @@ var WindowClone = GObject.registerClass({
'show-chrome': {}, 'show-chrome': {},
'size-changed': {} 'size-changed': {}
}, },
}, class WindowClone extends St.Widget { }, class WorkspaceWindowClone extends St.Widget {
_init(realWindow, workspace) { _init(realWindow, workspace) {
this.realWindow = realWindow; this.realWindow = realWindow;
this.metaWindow = realWindow.meta_window; this.metaWindow = realWindow.meta_window;
@@ -159,13 +157,18 @@ var WindowClone = GObject.registerClass({
this.x = this._boundingBox.x; this.x = this._boundingBox.x;
this.y = this._boundingBox.y; this.y = this._boundingBox.y;
this._computeWindowCenter();
let clickAction = new Clutter.ClickAction(); let clickAction = new Clutter.ClickAction();
clickAction.connect('clicked', this._onClicked.bind(this)); clickAction.connect('clicked', this._onClicked.bind(this));
clickAction.connect('long-press', this._onLongPress.bind(this)); clickAction.connect('long-press', this._onLongPress.bind(this));
this.add_action(clickAction); this.add_action(clickAction);
this.connect('destroy', this._onDestroy.bind(this)); this.connect('destroy', this._onDestroy.bind(this));
this.connect('key-press-event', this._onKeyPress.bind(this));
this.connect('enter-event', () => this.emit('show-chrome'));
this.connect('key-focus-in', () => this.emit('show-chrome'));
this.connect('leave-event', () => this.emit('hide-chrome'));
this.connect('key-focus-out', () => this.emit('hide-chrome'));
this._draggable = DND.makeDraggable(this, this._draggable = DND.makeDraggable(this,
{ restoreOnSuccess: true, { restoreOnSuccess: true,
@@ -296,18 +299,6 @@ var WindowClone = GObject.registerClass({
this.layout_manager.boundingBox = rect; this.layout_manager.boundingBox = rect;
} }
get windowCenter() {
return this._windowCenter;
}
_computeWindowCenter() {
let box = this.realWindow.get_allocation_box();
this._windowCenter = new Graphene.Point({
x: box.get_x() + box.get_width() / 2,
y: box.get_y() + box.get_height() / 2,
});
}
// Find the actor just below us, respecting reparenting done by DND code // Find the actor just below us, respecting reparenting done by DND code
getActualStackAbove() { getActualStackAbove() {
if (this._stackAbove == null) if (this._stackAbove == null)
@@ -377,28 +368,8 @@ var WindowClone = GObject.registerClass({
this.emit('selected', global.get_current_time()); this.emit('selected', global.get_current_time());
} }
vfunc_enter_event(crossingEvent) { _onKeyPress(actor, event) {
this.emit('show-chrome'); let symbol = event.get_key_symbol();
return super.vfunc_enter_event(crossingEvent);
}
vfunc_leave_event(crossingEvent) {
this.emit('hide-chrome');
return super.vfunc_leave_event(crossingEvent);
}
vfunc_key_focus_in() {
super.vfunc_key_focus_in();
this.emit('show-chrome');
}
vfunc_key_focus_out() {
super.vfunc_key_focus_out();
this.emit('hide-chrome');
}
vfunc_key_press_event(keyEvent) {
let symbol = keyEvent.keyval;
let isEnter = (symbol == Clutter.KEY_Return || symbol == Clutter.KEY_KP_Enter); let isEnter = (symbol == Clutter.KEY_Return || symbol == Clutter.KEY_KP_Enter);
if (isEnter) { if (isEnter) {
this._activate(); this._activate();
@@ -1032,7 +1003,11 @@ var UnalignedLayoutStrategy = class extends LayoutStrategy {
_sortRow(row) { _sortRow(row) {
// Sort windows horizontally to minimize travel distance. // Sort windows horizontally to minimize travel distance.
// This affects in what order the windows end up in a row. // This affects in what order the windows end up in a row.
row.windows.sort((a, b) => a.windowCenter.x - b.windowCenter.x); row.windows.sort((a, b) => {
let aCenter = a.realWindow.x + a.realWindow.width / 2;
let bCenter = b.realWindow.x + b.realWindow.width / 2;
return aCenter - bCenter;
});
} }
computeLayout(windows, layout) { computeLayout(windows, layout) {
@@ -1051,7 +1026,11 @@ var UnalignedLayoutStrategy = class extends LayoutStrategy {
// Sort windows vertically to minimize travel distance. // Sort windows vertically to minimize travel distance.
// This affects what rows the windows get placed in. // This affects what rows the windows get placed in.
let sortedWindows = windows.slice(); let sortedWindows = windows.slice();
sortedWindows.sort((a, b) => a.windowCenter.y - b.windowCenter.y); sortedWindows.sort((a, b) => {
let aCenter = a.realWindow.y + a.realWindow.height / 2;
let bCenter = b.realWindow.y + b.realWindow.height / 2;
return aCenter - bCenter;
});
let windowIdx = 0; let windowIdx = 0;
for (let i = 0; i < numRows; i++) { for (let i = 0; i < numRows; i++) {
@@ -1115,14 +1094,23 @@ function rectEqual(one, two) {
one.height == two.height); one.height == two.height);
} }
const WorkspaceActor = GObject.registerClass(
class WorkspaceActor extends St.Widget {
vfunc_get_focus_chain() {
return this.get_children().filter(c => c.visible).sort((a, b) => {
if (a instanceof WindowClone && b instanceof WindowClone)
return a.slotId - b.slotId;
return 0;
});
}
});
/** /**
* @metaWorkspace: a #Meta.Workspace, or null * @metaWorkspace: a #Meta.Workspace, or null
*/ */
var Workspace = GObject.registerClass( var Workspace = class {
class Workspace extends St.Widget { constructor(metaWorkspace, monitorIndex) {
_init(metaWorkspace, monitorIndex) {
super._init({ style_class: 'window-picker' });
// When dragging a window, we use this slot for reserve space. // When dragging a window, we use this slot for reserve space.
this._reservedSlot = null; this._reservedSlot = null;
this._reservedSlotWindow = null; this._reservedSlotWindow = null;
@@ -1148,17 +1136,18 @@ class Workspace extends St.Widget {
// Without this the drop area will be overlapped. // Without this the drop area will be overlapped.
this._windowOverlaysGroup.set_size(0, 0); this._windowOverlaysGroup.set_size(0, 0);
this.actor = new WorkspaceActor({ style_class: 'window-picker' });
if (monitorIndex != Main.layoutManager.primaryIndex) if (monitorIndex != Main.layoutManager.primaryIndex)
this.add_style_class_name('external-monitor'); this.actor.add_style_class_name('external-monitor');
this.set_size(0, 0); this.actor.set_size(0, 0);
this._dropRect = new Clutter.Actor({ opacity: 0 }); this._dropRect = new Clutter.Actor({ opacity: 0 });
this._dropRect._delegate = this; this._dropRect._delegate = this;
this.add_actor(this._dropRect); this.actor.add_actor(this._dropRect);
this.add_actor(this._windowOverlaysGroup); this.actor.add_actor(this._windowOverlaysGroup);
this.connect('destroy', this._onDestroy.bind(this)); this.actor.connect('destroy', this._onDestroy.bind(this));
let windows = global.get_window_actors().filter(this._isMyWindow, this); let windows = global.get_window_actors().filter(this._isMyWindow, this);
@@ -1188,19 +1177,10 @@ class Workspace extends St.Widget {
this._positionWindowsFlags = 0; this._positionWindowsFlags = 0;
this._positionWindowsId = 0; this._positionWindowsId = 0;
}
vfunc_map() { this.actor.connect('notify::mapped', () => {
super.vfunc_map(); if (this.actor.mapped)
this._syncActualGeometry(); this._syncActualGeometry();
}
vfunc_get_focus_chain() {
return this.get_children().filter(c => c.visible).sort((a, b) => {
if (a instanceof WindowClone && b instanceof WindowClone)
return a.slotId - b.slotId;
return 0;
}); });
} }
@@ -1210,7 +1190,7 @@ class Workspace extends St.Widget {
this._fullGeometry = geom; this._fullGeometry = geom;
if (this.mapped) if (this.actor.mapped)
this._recalculateWindowPositions(WindowPositionFlags.NONE); this._recalculateWindowPositions(WindowPositionFlags.NONE);
} }
@@ -1221,7 +1201,7 @@ class Workspace extends St.Widget {
this._actualGeometry = geom; this._actualGeometry = geom;
this._actualGeometryDirty = true; this._actualGeometryDirty = true;
if (this.mapped) if (this.actor.mapped)
this._syncActualGeometry(); this._syncActualGeometry();
} }
@@ -1233,7 +1213,7 @@ class Workspace extends St.Widget {
this._actualGeometryLater = Meta.later_add(Meta.LaterType.BEFORE_REDRAW, () => { this._actualGeometryLater = Meta.later_add(Meta.LaterType.BEFORE_REDRAW, () => {
this._actualGeometryLater = 0; this._actualGeometryLater = 0;
if (!this.mapped) if (!this.actor.mapped)
return false; return false;
let geom = this._actualGeometry; let geom = this._actualGeometry;
@@ -1524,7 +1504,8 @@ class Workspace extends St.Widget {
// Newly-created windows are added to a workspace before // Newly-created windows are added to a workspace before
// the compositor finds out about them... // the compositor finds out about them...
let id = GLib.idle_add(GLib.PRIORITY_DEFAULT, () => { let id = GLib.idle_add(GLib.PRIORITY_DEFAULT, () => {
if (metaWin.get_compositor_private() && if (this.actor &&
metaWin.get_compositor_private() &&
metaWin.get_workspace() == this.metaWorkspace) metaWin.get_workspace() == this.metaWorkspace)
this._doAddWindow(metaWin); this._doAddWindow(metaWin);
return GLib.SOURCE_REMOVE; return GLib.SOURCE_REMOVE;
@@ -1560,8 +1541,8 @@ class Workspace extends St.Widget {
let [clone, overlay_] = this._addWindowClone(win, false); let [clone, overlay_] = this._addWindowClone(win, false);
if (win._overviewHint) { if (win._overviewHint) {
let x = win._overviewHint.x - this.x; let x = win._overviewHint.x - this.actor.x;
let y = win._overviewHint.y - this.y; let y = win._overviewHint.y - this.actor.y;
let scale = win._overviewHint.scale; let scale = win._overviewHint.scale;
delete win._overviewHint; delete win._overviewHint;
@@ -1796,6 +1777,10 @@ class Workspace extends St.Widget {
} }
} }
destroy() {
this.actor.destroy();
}
_onDestroy() { _onDestroy() {
if (this._overviewHiddenId) { if (this._overviewHiddenId) {
Main.overview.disconnect(this._overviewHiddenId); Main.overview.disconnect(this._overviewHiddenId);
@@ -1876,11 +1861,11 @@ class Workspace extends St.Widget {
this._removeWindowClone(clone.metaWindow); this._removeWindowClone(clone.metaWindow);
}); });
this.add_actor(clone); this.actor.add_actor(clone);
overlay.connect('chrome-visible', () => { overlay.connect('chrome-visible', () => {
let focus = global.stage.key_focus; let focus = global.stage.key_focus;
if (focus == null || this.contains(focus)) if (focus == null || this.actor.contains(focus))
clone.grab_key_focus(); clone.grab_key_focus();
this._windowOverlays.forEach(o => { this._windowOverlays.forEach(o => {
@@ -1964,7 +1949,7 @@ class Workspace extends St.Widget {
} }
_getSpacingAndPadding() { _getSpacingAndPadding() {
let node = this.get_theme_node(); let node = this.actor.get_theme_node();
// Window grid spacing // Window grid spacing
let columnSpacing = node.get_length('-horizontal-spacing'); let columnSpacing = node.get_length('-horizontal-spacing');
@@ -2062,4 +2047,5 @@ class Workspace extends St.Widget {
return false; return false;
} }
}); };
Signals.addSignalMethods(Workspace.prototype);

View File

@@ -2,6 +2,7 @@
/* exported WorkspaceThumbnail, ThumbnailsBox */ /* exported WorkspaceThumbnail, ThumbnailsBox */
const { Clutter, Gio, GLib, GObject, Meta, Shell, St } = imports.gi; const { Clutter, Gio, GLib, GObject, Meta, Shell, St } = imports.gi;
const Signals = imports.signals;
const Background = imports.ui.background; const Background = imports.ui.background;
const DND = imports.ui.dnd; const DND = imports.ui.dnd;
@@ -43,40 +44,36 @@ class PrimaryActorLayout extends Clutter.FixedLayout {
} }
}); });
var WindowClone = GObject.registerClass({ var WindowClone = class {
GTypeName: 'WorkspaceThumbnail_WindowClone', constructor(realWindow) {
Signals: { this.clone = new Clutter.Clone({ source: realWindow });
'drag-begin': {},
'drag-cancelled': {},
'drag-end': {},
'selected': { param_types: [GObject.TYPE_UINT] },
}
}, class WindowClone extends Clutter.Actor {
_init(realWindow) {
let clone = new Clutter.Clone({ source: realWindow });
super._init({
layout_manager: new PrimaryActorLayout(clone),
reactive: true
});
this._delegate = this;
this.add_child(clone); /* Can't use a Shell.GenericContainer because of DND and reparenting... */
this.actor = new Clutter.Actor({ layout_manager: new PrimaryActorLayout(this.clone),
reactive: true });
this.actor._delegate = this;
this.actor.add_child(this.clone);
this.realWindow = realWindow; this.realWindow = realWindow;
this.metaWindow = realWindow.meta_window; this.metaWindow = realWindow.meta_window;
clone._updateId = this.realWindow.connect('notify::position', this.clone._updateId = this.realWindow.connect('notify::position',
this._onPositionChanged.bind(this)); this._onPositionChanged.bind(this));
clone._destroyId = this.realWindow.connect('destroy', () => { this.clone._destroyId = this.realWindow.connect('destroy', () => {
// First destroy the clone and then destroy everything // First destroy the clone and then destroy everything
// This will ensure that we never see it in the _disconnectSignals loop // This will ensure that we never see it in the _disconnectSignals loop
clone.destroy(); this.clone.destroy();
this.destroy(); this.destroy();
}); });
this._onPositionChanged(); this._onPositionChanged();
this.connect('destroy', this._onDestroy.bind(this)); this.actor.connect('button-release-event',
this._onButtonRelease.bind(this));
this.actor.connect('touch-event',
this._onTouchEvent.bind(this));
this._draggable = DND.makeDraggable(this, this.actor.connect('destroy', this._onDestroy.bind(this));
this._draggable = DND.makeDraggable(this.actor,
{ restoreOnSuccess: true, { restoreOnSuccess: true,
dragActorMaxSize: Workspace.WINDOW_DND_SIZE, dragActorMaxSize: Workspace.WINDOW_DND_SIZE,
dragActorOpacity: Workspace.DRAGGING_WINDOW_OPACITY }); dragActorOpacity: Workspace.DRAGGING_WINDOW_OPACITY });
@@ -127,9 +124,13 @@ var WindowClone = GObject.registerClass({
let actualAbove = this.getActualStackAbove(); let actualAbove = this.getActualStackAbove();
if (actualAbove == null) if (actualAbove == null)
this.lower_bottom(); this.actor.lower_bottom();
else else
this.raise(actualAbove); this.actor.raise(actualAbove);
}
destroy() {
this.actor.destroy();
} }
addAttachedDialog(win) { addAttachedDialog(win) {
@@ -146,7 +147,7 @@ var WindowClone = GObject.registerClass({
clone._destroyId = realDialog.connect('destroy', () => { clone._destroyId = realDialog.connect('destroy', () => {
clone.destroy(); clone.destroy();
}); });
this.add_child(clone); this.actor.add_child(clone);
} }
_updateDialogPosition(realDialog, cloneDialog) { _updateDialogPosition(realDialog, cloneDialog) {
@@ -158,11 +159,11 @@ var WindowClone = GObject.registerClass({
} }
_onPositionChanged() { _onPositionChanged() {
this.set_position(this.realWindow.x, this.realWindow.y); this.actor.set_position(this.realWindow.x, this.realWindow.y);
} }
_disconnectSignals() { _disconnectSignals() {
this.get_children().forEach(child => { this.actor.get_children().forEach(child => {
let realWindow = child.source; let realWindow = child.source;
realWindow.disconnect(child._updateId); realWindow.disconnect(child._updateId);
@@ -173,30 +174,28 @@ var WindowClone = GObject.registerClass({
_onDestroy() { _onDestroy() {
this._disconnectSignals(); this._disconnectSignals();
this._delegate = null; this.actor._delegate = null;
if (this.inDrag) { if (this.inDrag) {
this.emit('drag-end'); this.emit('drag-end');
this.inDrag = false; this.inDrag = false;
} }
this.disconnectAll();
} }
vfunc_button_press_event() { _onButtonRelease(actor, event) {
return Clutter.EVENT_STOP; this.emit('selected', event.get_time());
}
vfunc_button_release_event(buttonEvent) {
this.emit('selected', buttonEvent.time);
return Clutter.EVENT_STOP; return Clutter.EVENT_STOP;
} }
vfunc_touch_event(touchEvent) { _onTouchEvent(actor, event) {
if (touchEvent.type != Clutter.EventType.TOUCH_END || if (event.type() != Clutter.EventType.TOUCH_END ||
!global.display.is_pointer_emulating_sequence(touchEvent.sequence)) !global.display.is_pointer_emulating_sequence(event.get_event_sequence()))
return Clutter.EVENT_PROPAGATE; return Clutter.EVENT_PROPAGATE;
this.emit('selected', touchEvent.time); this.emit('selected', event.get_time());
return Clutter.EVENT_STOP; return Clutter.EVENT_STOP;
} }
@@ -215,17 +214,18 @@ var WindowClone = GObject.registerClass({
// We may not have a parent if DnD completed successfully, in // We may not have a parent if DnD completed successfully, in
// which case our clone will shortly be destroyed and replaced // which case our clone will shortly be destroyed and replaced
// with a new one on the target workspace. // with a new one on the target workspace.
if (this.get_parent() != null) { if (this.actor.get_parent() != null) {
if (this._stackAbove == null) if (this._stackAbove == null)
this.lower_bottom(); this.actor.lower_bottom();
else else
this.raise(this._stackAbove); this.actor.raise(this._stackAbove);
} }
this.emit('drag-end'); this.emit('drag-end');
} }
}); };
Signals.addSignalMethods(WindowClone.prototype);
var ThumbnailState = { var ThumbnailState = {
@@ -340,7 +340,7 @@ var WorkspaceThumbnail = GObject.registerClass({
clone.setStackAbove(this._bgManager.backgroundActor); clone.setStackAbove(this._bgManager.backgroundActor);
} else { } else {
let previousClone = this._windows[i - 1]; let previousClone = this._windows[i - 1];
clone.setStackAbove(previousClone); clone.setStackAbove(previousClone.actor);
} }
} }
} }
@@ -522,15 +522,15 @@ var WorkspaceThumbnail = GObject.registerClass({
clone.connect('drag-end', () => { clone.connect('drag-end', () => {
Main.overview.endWindowDrag(clone.metaWindow); Main.overview.endWindowDrag(clone.metaWindow);
}); });
clone.connect('destroy', () => { clone.actor.connect('destroy', () => {
this._removeWindowClone(clone.metaWindow); this._removeWindowClone(clone.metaWindow);
}); });
this._contents.add_actor(clone); this._contents.add_actor(clone.actor);
if (this._windows.length == 0) if (this._windows.length == 0)
clone.setStackAbove(this._bgManager.backgroundActor); clone.setStackAbove(this._bgManager.backgroundActor);
else else
clone.setStackAbove(this._windows[this._windows.length - 1]); clone.setStackAbove(this._windows[this._windows.length - 1].actor);
this._windows.push(clone); this._windows.push(clone);
@@ -668,6 +668,10 @@ var ThumbnailsBox = GObject.registerClass({
this._thumbnails = []; this._thumbnails = [];
this.connect('button-press-event', () => Clutter.EVENT_STOP);
this.connect('button-release-event', this._onButtonRelease.bind(this));
this.connect('touch-event', this._onTouchEvent.bind(this));
Main.overview.connect('showing', Main.overview.connect('showing',
this._createThumbnails.bind(this)); this._createThumbnails.bind(this));
Main.overview.connect('hidden', Main.overview.connect('hidden',
@@ -724,17 +728,17 @@ var ThumbnailsBox = GObject.registerClass({
thumbnail.activate(time); thumbnail.activate(time);
} }
vfunc_button_release_event(buttonEvent) { _onButtonRelease(actor, event) {
let { x, y } = buttonEvent; let [stageX, stageY] = event.get_coords();
this._activateThumbnailAtPoint(x, y, buttonEvent.time); this._activateThumbnailAtPoint(stageX, stageY, event.get_time());
return Clutter.EVENT_STOP; return Clutter.EVENT_STOP;
} }
vfunc_touch_event(touchEvent) { _onTouchEvent(actor, event) {
if (touchEvent.type == Clutter.EventType.TOUCH_END && if (event.type() == Clutter.EventType.TOUCH_END &&
global.display.is_pointer_emulating_sequence(touchEvent.sequence)) { global.display.is_pointer_emulating_sequence(event.get_event_sequence())) {
let { x, y } = touchEvent; let [stageX, stageY] = event.get_coords();
this._activateThumbnailAtPoint(x, y, touchEvent.time); this._activateThumbnailAtPoint(stageX, stageY, event.get_time());
} }
return Clutter.EVENT_STOP; return Clutter.EVENT_STOP;

View File

@@ -1,7 +1,8 @@
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*- // -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
/* exported WorkspacesView, WorkspacesDisplay */ /* exported WorkspacesView */
const { Clutter, Gio, GObject, Meta, Shell, St } = imports.gi; const { Clutter, Gio, GObject, Meta, Shell, St } = imports.gi;
const Signals = imports.signals;
const Main = imports.ui.main; const Main = imports.ui.main;
const WindowManager = imports.ui.windowManager; const WindowManager = imports.ui.windowManager;
@@ -16,16 +17,15 @@ var AnimationType = {
const MUTTER_SCHEMA = 'org.gnome.mutter'; const MUTTER_SCHEMA = 'org.gnome.mutter';
var WorkspacesViewBase = GObject.registerClass({ var WorkspacesViewBase = class {
GTypeFlags: GObject.TypeFlags.ABSTRACT constructor(monitorIndex) {
}, class WorkspacesViewBase extends St.Widget { this.actor = new St.Widget({ style_class: 'workspaces-view',
_init(monitorIndex) { reactive: true });
super._init({ style_class: 'workspaces-view', reactive: true }); this.actor.connect('destroy', this._onDestroy.bind(this));
this.connect('destroy', this._onDestroy.bind(this)); global.focus_manager.add_group(this.actor);
global.focus_manager.add_group(this);
// The actor itself isn't a drop target, so we don't want to pick on its area // The actor itself isn't a drop target, so we don't want to pick on its area
this.set_size(0, 0); this.actor.set_size(0, 0);
this._monitorIndex = monitorIndex; this._monitorIndex = monitorIndex;
@@ -60,6 +60,10 @@ var WorkspacesViewBase = GObject.registerClass({
this._setReservedSlot(null); this._setReservedSlot(null);
} }
destroy() {
this.actor.destroy();
}
setFullGeometry(geom) { setFullGeometry(geom) {
this._fullGeometry = geom; this._fullGeometry = geom;
this._syncFullGeometry(); this._syncFullGeometry();
@@ -69,14 +73,13 @@ var WorkspacesViewBase = GObject.registerClass({
this._actualGeometry = geom; this._actualGeometry = geom;
this._syncActualGeometry(); this._syncActualGeometry();
} }
}); };
var WorkspacesView = GObject.registerClass( var WorkspacesView = class extends WorkspacesViewBase {
class WorkspacesView extends WorkspacesViewBase { constructor(monitorIndex) {
_init(monitorIndex) {
let workspaceManager = global.workspace_manager; let workspaceManager = global.workspace_manager;
super._init(monitorIndex); super(monitorIndex);
this._animating = false; // tweening this._animating = false; // tweening
this._scrolling = false; // swipe-scrolling this._scrolling = false; // swipe-scrolling
@@ -109,8 +112,8 @@ class WorkspacesView extends WorkspacesViewBase {
this._overviewShownId = this._overviewShownId =
Main.overview.connect('shown', () => { Main.overview.connect('shown', () => {
this.set_clip(this._fullGeometry.x, this._fullGeometry.y, this.actor.set_clip(this._fullGeometry.x, this._fullGeometry.y,
this._fullGeometry.width, this._fullGeometry.height); this._fullGeometry.width, this._fullGeometry.height);
}); });
this._switchWorkspaceNotifyId = this._switchWorkspaceNotifyId =
@@ -150,7 +153,7 @@ class WorkspacesView extends WorkspacesViewBase {
} }
animateFromOverview(animationType) { animateFromOverview(animationType) {
this.remove_clip(); this.actor.remove_clip();
for (let w = 0; w < this._workspaces.length; w++) { for (let w = 0; w < this._workspaces.length; w++) {
if (animationType == AnimationType.ZOOM) if (animationType == AnimationType.ZOOM)
@@ -184,12 +187,12 @@ class WorkspacesView extends WorkspacesViewBase {
for (let w = 0; w < this._workspaces.length; w++) { for (let w = 0; w < this._workspaces.length; w++) {
let workspace = this._workspaces[w]; let workspace = this._workspaces[w];
workspace.remove_all_transitions(); workspace.actor.remove_all_transitions();
let params = {}; let params = {};
if (workspaceManager.layout_rows == -1) if (workspaceManager.layout_rows == -1)
params.y = (w - active) * this._fullGeometry.height; params.y = (w - active) * this._fullGeometry.height;
else if (this.text_direction == Clutter.TextDirection.RTL) else if (this.actor.text_direction == Clutter.TextDirection.RTL)
params.x = (active - w) * this._fullGeometry.width; params.x = (active - w) * this._fullGeometry.width;
else else
params.x = (w - active) * this._fullGeometry.width; params.x = (w - active) * this._fullGeometry.width;
@@ -209,9 +212,9 @@ class WorkspacesView extends WorkspacesViewBase {
this._updateVisibility(); this._updateVisibility();
}; };
} }
workspace.ease(easeParams); workspace.actor.ease(easeParams);
} else { } else {
workspace.set(params); workspace.actor.set(params);
if (w == 0) if (w == 0)
this._updateVisibility(); this._updateVisibility();
} }
@@ -225,12 +228,12 @@ class WorkspacesView extends WorkspacesViewBase {
for (let w = 0; w < this._workspaces.length; w++) { for (let w = 0; w < this._workspaces.length; w++) {
let workspace = this._workspaces[w]; let workspace = this._workspaces[w];
if (this._animating || this._scrolling || this._gestureActive) { if (this._animating || this._scrolling || this._gestureActive) {
workspace.show(); workspace.actor.show();
} else { } else {
if (this._inDrag) if (this._inDrag)
workspace.visible = (Math.abs(w - active) <= 1); workspace.actor.visible = (Math.abs(w - active) <= 1);
else else
workspace.visible = (w == active); workspace.actor.visible = (w == active);
} }
} }
} }
@@ -260,7 +263,7 @@ class WorkspacesView extends WorkspacesViewBase {
if (j >= this._workspaces.length) { /* added */ if (j >= this._workspaces.length) { /* added */
workspace = new Workspace.Workspace(metaWorkspace, this._monitorIndex); workspace = new Workspace.Workspace(metaWorkspace, this._monitorIndex);
this.add_actor(workspace); this.actor.add_actor(workspace.actor);
this._workspaces[j] = workspace; this._workspaces[j] = workspace;
} else { } else {
workspace = this._workspaces[j]; workspace = this._workspaces[j];
@@ -352,8 +355,8 @@ class WorkspacesView extends WorkspacesViewBase {
let last = this._workspaces.length - 1; let last = this._workspaces.length - 1;
if (workspaceManager.layout_rows == -1) { if (workspaceManager.layout_rows == -1) {
let firstWorkspaceY = this._workspaces[0].y; let firstWorkspaceY = this._workspaces[0].actor.y;
let lastWorkspaceY = this._workspaces[last].y; let lastWorkspaceY = this._workspaces[last].actor.y;
let workspacesHeight = lastWorkspaceY - firstWorkspaceY; let workspacesHeight = lastWorkspaceY - firstWorkspaceY;
let currentY = firstWorkspaceY; let currentY = firstWorkspaceY;
@@ -362,12 +365,12 @@ class WorkspacesView extends WorkspacesViewBase {
let dy = newY - currentY; let dy = newY - currentY;
for (let i = 0; i < this._workspaces.length; i++) { for (let i = 0; i < this._workspaces.length; i++) {
this._workspaces[i].visible = Math.abs(i - adj.value) <= 1; this._workspaces[i].actor.visible = Math.abs(i - adj.value) <= 1;
this._workspaces[i].y += dy; this._workspaces[i].actor.y += dy;
} }
} else { } else {
let firstWorkspaceX = this._workspaces[0].x; let firstWorkspaceX = this._workspaces[0].actor.x;
let lastWorkspaceX = this._workspaces[last].x; let lastWorkspaceX = this._workspaces[last].actor.x;
let workspacesWidth = lastWorkspaceX - firstWorkspaceX; let workspacesWidth = lastWorkspaceX - firstWorkspaceX;
let currentX = firstWorkspaceX; let currentX = firstWorkspaceX;
@@ -376,19 +379,19 @@ class WorkspacesView extends WorkspacesViewBase {
let dx = newX - currentX; let dx = newX - currentX;
for (let i = 0; i < this._workspaces.length; i++) { for (let i = 0; i < this._workspaces.length; i++) {
this._workspaces[i].visible = Math.abs(i - adj.value) <= 1; this._workspaces[i].actor.visible = Math.abs(i - adj.value) <= 1;
this._workspaces[i].x += dx; this._workspaces[i].actor.x += dx;
} }
} }
} }
}); };
Signals.addSignalMethods(WorkspacesView.prototype);
var ExtraWorkspaceView = GObject.registerClass( var ExtraWorkspaceView = class extends WorkspacesViewBase {
class ExtraWorkspaceView extends WorkspacesViewBase { constructor(monitorIndex) {
_init(monitorIndex) { super(monitorIndex);
super._init(monitorIndex);
this._workspace = new Workspace.Workspace(null, monitorIndex); this._workspace = new Workspace.Workspace(null, monitorIndex);
this.add_actor(this._workspace); this.actor.add_actor(this._workspace.actor);
} }
_setReservedSlot(window) { _setReservedSlot(window) {
@@ -436,13 +439,21 @@ class ExtraWorkspaceView extends WorkspacesViewBase {
endTouchGesture() { endTouchGesture() {
} }
};
var DelegateFocusNavigator = GObject.registerClass(
class DelegateFocusNavigator extends St.Widget {
vfunc_navigate_focus(from, direction) {
return this._delegate.navigateFocus(from, direction);
}
}); });
var WorkspacesDisplay = GObject.registerClass( var WorkspacesDisplay = class {
class WorkspacesDisplay extends St.Widget { constructor() {
_init() { this.actor = new DelegateFocusNavigator({ clip_to_allocation: true });
super._init({ clip_to_allocation: true }); this.actor._delegate = this;
this.connect('notify::allocation', this._updateWorkspacesActualGeometry.bind(this)); this.actor.connect('notify::allocation', this._updateWorkspacesActualGeometry.bind(this));
this.actor.connect('parent-set', this._parentSet.bind(this));
let clickAction = new Clutter.ClickAction(); let clickAction = new Clutter.ClickAction();
clickAction.connect('clicked', action => { clickAction.connect('clicked', action => {
@@ -456,7 +467,7 @@ class WorkspacesDisplay extends St.Widget {
Main.overview.hide(); Main.overview.hide();
}); });
Main.overview.addAction(clickAction); Main.overview.addAction(clickAction);
this.bind_property('mapped', clickAction, 'enabled', GObject.BindingFlags.SYNC_CREATE); this.actor.bind_property('mapped', clickAction, 'enabled', GObject.BindingFlags.SYNC_CREATE);
let panAction = new Clutter.PanAction({ threshold_trigger_edge: Clutter.GestureTriggerEdge.AFTER }); let panAction = new Clutter.PanAction({ threshold_trigger_edge: Clutter.GestureTriggerEdge.AFTER });
panAction.connect('pan', this._onPan.bind(this)); panAction.connect('pan', this._onPan.bind(this));
@@ -479,7 +490,7 @@ class WorkspacesDisplay extends St.Widget {
this._endSwipeScroll(); this._endSwipeScroll();
}); });
Main.overview.addAction(panAction); Main.overview.addAction(panAction);
this.bind_property('mapped', panAction, 'enabled', GObject.BindingFlags.SYNC_CREATE); this.actor.bind_property('mapped', panAction, 'enabled', GObject.BindingFlags.SYNC_CREATE);
let allowedModes = Shell.ActionMode.OVERVIEW; let allowedModes = Shell.ActionMode.OVERVIEW;
let switchGesture = new WindowManager.WorkspaceSwitchAction(allowedModes); let switchGesture = new WindowManager.WorkspaceSwitchAction(allowedModes);
@@ -487,15 +498,20 @@ class WorkspacesDisplay extends St.Widget {
switchGesture.connect('activated', this._onSwitchWorkspaceActivated.bind(this)); switchGesture.connect('activated', this._onSwitchWorkspaceActivated.bind(this));
switchGesture.connect('cancel', this._endTouchGesture.bind(this)); switchGesture.connect('cancel', this._endTouchGesture.bind(this));
Main.overview.addAction(switchGesture); Main.overview.addAction(switchGesture);
this.bind_property('mapped', switchGesture, 'enabled', GObject.BindingFlags.SYNC_CREATE); this.actor.bind_property('mapped', switchGesture, 'enabled', GObject.BindingFlags.SYNC_CREATE);
switchGesture = new WindowManager.TouchpadWorkspaceSwitchAction(global.stage, allowedModes); switchGesture = new WindowManager.TouchpadWorkspaceSwitchAction(global.stage, allowedModes);
switchGesture.connect('motion', this._onSwitchWorkspaceMotion.bind(this)); switchGesture.connect('motion', this._onSwitchWorkspaceMotion.bind(this));
switchGesture.connect('activated', this._onSwitchWorkspaceActivated.bind(this)); switchGesture.connect('activated', this._onSwitchWorkspaceActivated.bind(this));
switchGesture.connect('cancel', this._endTouchGesture.bind(this)); switchGesture.connect('cancel', this._endTouchGesture.bind(this));
this.actor.connect('notify::mapped', () => {
switchGesture.enabled = this.actor.mapped;
});
this._primaryIndex = Main.layoutManager.primaryIndex; this._primaryIndex = Main.layoutManager.primaryIndex;
this._workspacesViews = []; this._workspacesViews = [];
switchGesture.enabled = this.actor.mapped;
this._settings = new Gio.Settings({ schema_id: MUTTER_SCHEMA }); this._settings = new Gio.Settings({ schema_id: MUTTER_SCHEMA });
this._settings.connect('changed::workspaces-only-on-primary', this._settings.connect('changed::workspaces-only-on-primary',
@@ -509,12 +525,12 @@ class WorkspacesDisplay extends St.Widget {
this._fullGeometry = null; this._fullGeometry = null;
this.connect('destroy', this._onDestroy.bind(this)); this.actor.connect('destroy', this._onDestroy.bind(this));
} }
_onDestroy() { _onDestroy() {
if (this._notifyOpacityId) { if (this._notifyOpacityId) {
let parent = this.get_parent(); let parent = this.actor.get_parent();
if (parent) if (parent)
parent.disconnect(this._notifyOpacityId); parent.disconnect(this._notifyOpacityId);
this._notifyOpacityId = 0; this._notifyOpacityId = 0;
@@ -530,11 +546,11 @@ class WorkspacesDisplay extends St.Widget {
let [dist_, dx, dy] = action.get_motion_delta(0); let [dist_, dx, dy] = action.get_motion_delta(0);
let adjustment = this._scrollAdjustment; let adjustment = this._scrollAdjustment;
if (global.workspace_manager.layout_rows == -1) if (global.workspace_manager.layout_rows == -1)
adjustment.value -= (dy / this.height) * adjustment.page_size; adjustment.value -= (dy / this.actor.height) * adjustment.page_size;
else if (this.text_direction == Clutter.TextDirection.RTL) else if (this.actor.text_direction == Clutter.TextDirection.RTL)
adjustment.value += (dx / this.width) * adjustment.page_size; adjustment.value += (dx / this.actor.width) * adjustment.page_size;
else else
adjustment.value -= (dx / this.width) * adjustment.page_size; adjustment.value -= (dx / this.actor.width) * adjustment.page_size;
return false; return false;
} }
@@ -567,11 +583,11 @@ class WorkspacesDisplay extends St.Widget {
let active = workspaceManager.get_active_workspace_index(); let active = workspaceManager.get_active_workspace_index();
let adjustment = this._scrollAdjustment; let adjustment = this._scrollAdjustment;
if (workspaceManager.layout_rows == -1) if (workspaceManager.layout_rows == -1)
adjustment.value = (active - yRel / this.height) * adjustment.page_size; adjustment.value = (active - yRel / this.actor.height) * adjustment.page_size;
else if (this.text_direction == Clutter.TextDirection.RTL) else if (this.actor.text_direction == Clutter.TextDirection.RTL)
adjustment.value = (active + xRel / this.width) * adjustment.page_size; adjustment.value = (active + xRel / this.actor.width) * adjustment.page_size;
else else
adjustment.value = (active - xRel / this.width) * adjustment.page_size; adjustment.value = (active - xRel / this.actor.width) * adjustment.page_size;
} }
_onSwitchWorkspaceActivated(action, direction) { _onSwitchWorkspaceActivated(action, direction) {
@@ -584,8 +600,8 @@ class WorkspacesDisplay extends St.Widget {
this._endTouchGesture(); this._endTouchGesture();
} }
vfunc_navigate_focus(from, direction) { navigateFocus(from, direction) {
return this._getPrimaryView().navigate_focus(from, direction, false); return this._getPrimaryView().actor.navigate_focus(from, direction, false);
} }
show(fadeOnPrimary) { show(fadeOnPrimary) {
@@ -661,7 +677,7 @@ class WorkspacesDisplay extends St.Widget {
else else
view = new WorkspacesView(i); view = new WorkspacesView(i);
view.connect('scroll-event', this._onScrollEvent.bind(this)); view.actor.connect('scroll-event', this._onScrollEvent.bind(this));
if (i == this._primaryIndex) { if (i == this._primaryIndex) {
this._scrollAdjustment = view.scrollAdjustment; this._scrollAdjustment = view.scrollAdjustment;
this._scrollAdjustment.connect('notify::value', this._scrollAdjustment.connect('notify::value',
@@ -669,13 +685,13 @@ class WorkspacesDisplay extends St.Widget {
} }
// HACK: Avoid spurious allocation changes while updating views // HACK: Avoid spurious allocation changes while updating views
view.hide(); view.actor.hide();
this._workspacesViews.push(view); this._workspacesViews.push(view);
Main.layoutManager.overviewGroup.add_actor(view); Main.layoutManager.overviewGroup.add_actor(view.actor);
} }
this._workspacesViews.forEach(v => v.show()); this._workspacesViews.forEach(v => v.actor.show());
this._updateWorkspacesFullGeometry(); this._updateWorkspacesFullGeometry();
this._updateWorkspacesActualGeometry(); this._updateWorkspacesActualGeometry();
@@ -712,7 +728,7 @@ class WorkspacesDisplay extends St.Widget {
return this._getPrimaryView().getActiveWorkspace().hasMaximizedWindows(); return this._getPrimaryView().getActiveWorkspace().hasMaximizedWindows();
} }
vfunc_parent_set(oldParent) { _parentSet(actor, oldParent) {
if (oldParent && this._notifyOpacityId) if (oldParent && this._notifyOpacityId)
oldParent.disconnect(this._notifyOpacityId); oldParent.disconnect(this._notifyOpacityId);
this._notifyOpacityId = 0; this._notifyOpacityId = 0;
@@ -722,20 +738,20 @@ class WorkspacesDisplay extends St.Widget {
this._parentSetLater = Meta.later_add(Meta.LaterType.BEFORE_REDRAW, () => { this._parentSetLater = Meta.later_add(Meta.LaterType.BEFORE_REDRAW, () => {
this._parentSetLater = 0; this._parentSetLater = 0;
let newParent = this.get_parent(); let newParent = this.actor.get_parent();
if (!newParent) if (!newParent)
return; return;
// This is kinda hackish - we want the primary view to // This is kinda hackish - we want the primary view to
// appear as parent of this, though in reality it // appear as parent of this.actor, though in reality it
// is added directly to Main.layoutManager.overviewGroup // is added directly to Main.layoutManager.overviewGroup
this._notifyOpacityId = newParent.connect('notify::opacity', () => { this._notifyOpacityId = newParent.connect('notify::opacity', () => {
let opacity = this.get_parent().opacity; let opacity = this.actor.get_parent().opacity;
let primaryView = this._getPrimaryView(); let primaryView = this._getPrimaryView();
if (!primaryView) if (!primaryView)
return; return;
primaryView.opacity = opacity; primaryView.actor.opacity = opacity;
primaryView.visible = opacity != 0; primaryView.actor.visible = opacity != 0;
}); });
}); });
} }
@@ -763,8 +779,8 @@ class WorkspacesDisplay extends St.Widget {
if (!this._workspacesViews.length) if (!this._workspacesViews.length)
return; return;
let [x, y] = this.get_transformed_position(); let [x, y] = this.actor.get_transformed_position();
let allocation = this.allocation; let allocation = this.actor.allocation;
let width = allocation.x2 - allocation.x1; let width = allocation.x2 - allocation.x1;
let height = allocation.y2 - allocation.y1; let height = allocation.y2 - allocation.y1;
let primaryGeometry = { x: x, y: y, width: width, height: height }; let primaryGeometry = { x: x, y: y, width: width, height: height };
@@ -782,7 +798,7 @@ class WorkspacesDisplay extends St.Widget {
} }
_onScrollEvent(actor, event) { _onScrollEvent(actor, event) {
if (!this.mapped) if (!this.actor.mapped)
return Clutter.EVENT_PROPAGATE; return Clutter.EVENT_PROPAGATE;
if (this._workspacesOnlyOnPrimary && if (this._workspacesOnlyOnPrimary &&
@@ -813,7 +829,7 @@ class WorkspacesDisplay extends St.Widget {
} }
_onKeyPressEvent(actor, event) { _onKeyPressEvent(actor, event) {
if (!this.mapped) if (!this.actor.mapped)
return Clutter.EVENT_PROPAGATE; return Clutter.EVENT_PROPAGATE;
let workspaceManager = global.workspace_manager; let workspaceManager = global.workspace_manager;
let activeWs = workspaceManager.get_active_workspace(); let activeWs = workspaceManager.get_active_workspace();
@@ -831,4 +847,5 @@ class WorkspacesDisplay extends St.Widget {
Main.wm.actionMoveWorkspace(ws); Main.wm.actionMoveWorkspace(ws);
return Clutter.EVENT_STOP; return Clutter.EVENT_STOP;
} }
}); };
Signals.addSignalMethods(WorkspacesDisplay.prototype);

View File

@@ -1,5 +1,5 @@
project('gnome-shell', 'c', project('gnome-shell', 'c',
version: '3.35.1', version: '3.34.1',
meson_version: '>= 0.47.0', meson_version: '>= 0.47.0',
license: 'GPLv2+' license: 'GPLv2+'
) )
@@ -26,7 +26,7 @@ gio_req = '>= 2.56.0'
gi_req = '>= 1.49.1' gi_req = '>= 1.49.1'
gjs_req = '>= 1.57.3' gjs_req = '>= 1.57.3'
gtk_req = '>= 3.15.0' gtk_req = '>= 3.15.0'
mutter_req = '>= 3.35.1' mutter_req = '>= 3.34.0'
polkit_req = '>= 0.100' polkit_req = '>= 0.100'
schemas_req = '>= 3.33.1' schemas_req = '>= 3.33.1'
startup_req = '>= 0.11' startup_req = '>= 0.11'

477
po/es.po

File diff suppressed because it is too large Load Diff

980
po/fa.po

File diff suppressed because it is too large Load Diff

100
po/fur.po
View File

@@ -7,15 +7,15 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: video-subtitles master\n" "Project-Id-Version: video-subtitles master\n"
"Report-Msgid-Bugs-To: https://gitlab.gnome.org/GNOME/gnome-shell/issues\n" "Report-Msgid-Bugs-To: https://gitlab.gnome.org/GNOME/gnome-shell/issues\n"
"POT-Creation-Date: 2019-10-12 20:48+0000\n" "POT-Creation-Date: 2019-09-17 11:44+0000\n"
"PO-Revision-Date: 2019-10-17 15:53+0200\n" "PO-Revision-Date: 2019-09-26 16:19+0200\n"
"Last-Translator: Fabio Tomat <f.t.public@gmail.com>\n" "Last-Translator: Fabio Tomat <f.t.public@gmail.com>\n"
"Language-Team: Friulian <fur@li.org>\n" "Language-Team: Friulian <fur@li.org>\n"
"Language: fur\n" "Language: fur\n"
"MIME-Version: 1.0\n" "MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n" "Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n" "Content-Transfer-Encoding: 8bit\n"
"X-Generator: Poedit 2.2.4\n" "X-Generator: Poedit 2.2.3\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n"
#: data/50-gnome-shell-system.xml:6 #: data/50-gnome-shell-system.xml:6
@@ -467,7 +467,7 @@ msgid "Next"
msgstr "Indenant" msgstr "Indenant"
#: js/gdm/authPrompt.js:197 js/ui/shellMountOperation.js:396 #: js/gdm/authPrompt.js:197 js/ui/shellMountOperation.js:396
#: js/ui/unlockDialog.js:45 #: js/ui/unlockDialog.js:42
msgid "Unlock" msgid "Unlock"
msgstr "Sbloche" msgstr "Sbloche"
@@ -497,8 +497,8 @@ msgstr "(p.e., utent o %s)"
#. TTLS and PEAP are actually much more complicated, but this complication #. TTLS and PEAP are actually much more complicated, but this complication
#. is not visible here since we only care about phase2 authentication #. is not visible here since we only care about phase2 authentication
#. (and don't even care of which one) #. (and don't even care of which one)
#: js/gdm/loginDialog.js:884 js/ui/components/networkAgent.js:248 #: js/gdm/loginDialog.js:884 js/ui/components/networkAgent.js:247
#: js/ui/components/networkAgent.js:268 js/ui/components/networkAgent.js:286 #: js/ui/components/networkAgent.js:267 js/ui/components/networkAgent.js:285
msgid "Username: " msgid "Username: "
msgstr "Non utent: " msgstr "Non utent: "
@@ -760,32 +760,32 @@ msgstr "Dispès"
msgid "All" msgid "All"
msgstr "Dutis" msgstr "Dutis"
#: js/ui/appDisplay.js:1745 #: js/ui/appDisplay.js:1749
msgid "Rename" msgid "Rename"
msgstr "Cambie non" msgstr "Cambie non"
#. Translators: This is the heading of a list of open windows #. Translators: This is the heading of a list of open windows
#: js/ui/appDisplay.js:2418 js/ui/panel.js:76 #: js/ui/appDisplay.js:2397 js/ui/panel.js:76
msgid "Open Windows" msgid "Open Windows"
msgstr "Barcons vierts" msgstr "Barcons vierts"
#: js/ui/appDisplay.js:2437 js/ui/panel.js:83 #: js/ui/appDisplay.js:2416 js/ui/panel.js:83
msgid "New Window" msgid "New Window"
msgstr "Gnûf barcon" msgstr "Gnûf barcon"
#: js/ui/appDisplay.js:2449 #: js/ui/appDisplay.js:2428
msgid "Launch using Dedicated Graphics Card" msgid "Launch using Dedicated Graphics Card"
msgstr "Invie doprant une schede grafiche dedicade" msgstr "Invie doprant une schede grafiche dedicade"
#: js/ui/appDisplay.js:2478 js/ui/dash.js:239 #: js/ui/appDisplay.js:2457 js/ui/dash.js:239
msgid "Remove from Favorites" msgid "Remove from Favorites"
msgstr "Gjave dai preferîts" msgstr "Gjave dai preferîts"
#: js/ui/appDisplay.js:2484 #: js/ui/appDisplay.js:2463
msgid "Add to Favorites" msgid "Add to Favorites"
msgstr "Zonte tai preferîts" msgstr "Zonte tai preferîts"
#: js/ui/appDisplay.js:2494 js/ui/panel.js:94 #: js/ui/appDisplay.js:2473 js/ui/panel.js:94
msgid "Show Details" msgid "Show Details"
msgstr "Mostre Detais" msgstr "Mostre Detais"
@@ -1017,34 +1017,34 @@ msgid "Connect"
msgstr "Conet" msgstr "Conet"
#. Cisco LEAP #. Cisco LEAP
#: js/ui/components/networkAgent.js:217 js/ui/components/networkAgent.js:229 #: js/ui/components/networkAgent.js:216 js/ui/components/networkAgent.js:228
#: js/ui/components/networkAgent.js:251 js/ui/components/networkAgent.js:270 #: js/ui/components/networkAgent.js:250 js/ui/components/networkAgent.js:269
#: js/ui/components/networkAgent.js:290 js/ui/components/networkAgent.js:300 #: js/ui/components/networkAgent.js:289 js/ui/components/networkAgent.js:299
msgid "Password: " msgid "Password: "
msgstr "Password: " msgstr "Password: "
#. static WEP #. static WEP
#: js/ui/components/networkAgent.js:222 #: js/ui/components/networkAgent.js:221
msgid "Key: " msgid "Key: "
msgstr "Clâf: " msgstr "Clâf: "
#: js/ui/components/networkAgent.js:254 js/ui/components/networkAgent.js:276 #: js/ui/components/networkAgent.js:253 js/ui/components/networkAgent.js:275
msgid "Private key password: " msgid "Private key password: "
msgstr "Password di clâf privade: " msgstr "Password di clâf privade: "
#: js/ui/components/networkAgent.js:274 #: js/ui/components/networkAgent.js:273
msgid "Identity: " msgid "Identity: "
msgstr "Identitât: " msgstr "Identitât: "
#: js/ui/components/networkAgent.js:288 #: js/ui/components/networkAgent.js:287
msgid "Service: " msgid "Service: "
msgstr "Servizi: " msgstr "Servizi: "
#: js/ui/components/networkAgent.js:317 js/ui/components/networkAgent.js:692 #: js/ui/components/networkAgent.js:316 js/ui/components/networkAgent.js:691
msgid "Authentication required by wireless network" msgid "Authentication required by wireless network"
msgstr "La rêt cence fîl e domande autenticazion" msgstr "La rêt cence fîl e domande autenticazion"
#: js/ui/components/networkAgent.js:318 js/ui/components/networkAgent.js:693 #: js/ui/components/networkAgent.js:317 js/ui/components/networkAgent.js:692
#, javascript-format #, javascript-format
msgid "" msgid ""
"Passwords or encryption keys are required to access the wireless network " "Passwords or encryption keys are required to access the wireless network "
@@ -1053,41 +1053,41 @@ msgstr ""
"Si scugne meti une password o une clâf di cifradure par jentrâ te rêt cence " "Si scugne meti une password o une clâf di cifradure par jentrâ te rêt cence "
"fîl \"%s\"." "fîl \"%s\"."
#: js/ui/components/networkAgent.js:322 js/ui/components/networkAgent.js:697 #: js/ui/components/networkAgent.js:321 js/ui/components/networkAgent.js:696
msgid "Wired 802.1X authentication" msgid "Wired 802.1X authentication"
msgstr "Autenticazion vie fîl 802.1X" msgstr "Autenticazion vie fîl 802.1X"
#: js/ui/components/networkAgent.js:324 #: js/ui/components/networkAgent.js:323
msgid "Network name: " msgid "Network name: "
msgstr "Non rêt: " msgstr "Non rêt: "
#: js/ui/components/networkAgent.js:329 js/ui/components/networkAgent.js:701 #: js/ui/components/networkAgent.js:328 js/ui/components/networkAgent.js:700
msgid "DSL authentication" msgid "DSL authentication"
msgstr "Autenticazion DSL" msgstr "Autenticazion DSL"
#: js/ui/components/networkAgent.js:336 js/ui/components/networkAgent.js:706 #: js/ui/components/networkAgent.js:335 js/ui/components/networkAgent.js:705
msgid "PIN code required" msgid "PIN code required"
msgstr "Si pretint un codiç PIN" msgstr "Si pretint un codiç PIN"
#: js/ui/components/networkAgent.js:337 js/ui/components/networkAgent.js:707 #: js/ui/components/networkAgent.js:336 js/ui/components/networkAgent.js:706
msgid "PIN code is needed for the mobile broadband device" msgid "PIN code is needed for the mobile broadband device"
msgstr "Si scugne meti un codiç PIN pal dispositîf a bande largje mobil" msgstr "Si scugne meti un codiç PIN pal dispositîf a bande largje mobil"
#: js/ui/components/networkAgent.js:338 #: js/ui/components/networkAgent.js:337
msgid "PIN: " msgid "PIN: "
msgstr "PIN: " msgstr "PIN: "
#: js/ui/components/networkAgent.js:345 js/ui/components/networkAgent.js:713 #: js/ui/components/networkAgent.js:344 js/ui/components/networkAgent.js:712
msgid "Mobile broadband network password" msgid "Mobile broadband network password"
msgstr "Passowrd rêt mobil a bande largje" msgstr "Passowrd rêt mobil a bande largje"
#: js/ui/components/networkAgent.js:346 js/ui/components/networkAgent.js:698 #: js/ui/components/networkAgent.js:345 js/ui/components/networkAgent.js:697
#: js/ui/components/networkAgent.js:702 js/ui/components/networkAgent.js:714 #: js/ui/components/networkAgent.js:701 js/ui/components/networkAgent.js:713
#, javascript-format #, javascript-format
msgid "A password is required to connect to “%s”." msgid "A password is required to connect to “%s”."
msgstr "A covente une password par tacâsi a '%s'." msgstr "A covente une password par tacâsi a '%s'."
#: js/ui/components/networkAgent.js:681 js/ui/status/network.js:1675 #: js/ui/components/networkAgent.js:680 js/ui/status/network.js:1675
msgid "Network Manager" msgid "Network Manager"
msgstr "Ministradôr di rêt" msgstr "Ministradôr di rêt"
@@ -1475,26 +1475,6 @@ msgstr "Viôt sorzint"
msgid "Web Page" msgid "Web Page"
msgstr "Pagjine Web" msgstr "Pagjine Web"
#: js/ui/main.js:267
msgid "Logged in as a privileged user"
msgstr "Jentre come utent privilegjât"
#: js/ui/main.js:268
msgid ""
"Running a session as a privileged user should be avoided for security "
"reasons. If possible, you should log in as a normal user."
msgstr ""
"Si varès di evitâ di eseguî une session come utent privilegjât par resons di "
"sigurece. Se pussibil, tu varessis di jentrâ come utent normâl."
#: js/ui/main.js:274
msgid "Screen Lock disabled"
msgstr "Bloc dal schermi disabilitât"
#: js/ui/main.js:275
msgid "Screen Locking requires the GNOME display manager."
msgstr "Il bloc dal schermi al à bisugne dal gjestôr dai visôrs di GNOME."
#: js/ui/messageTray.js:1465 #: js/ui/messageTray.js:1465
msgid "System Information" msgid "System Information"
msgstr "Informazion di sisteme" msgstr "Informazion di sisteme"
@@ -2239,11 +2219,11 @@ msgstr "Dome esterni"
msgid "Built-in Only" msgid "Built-in Only"
msgstr "Dome incorporât" msgstr "Dome incorporât"
#: js/ui/unlockDialog.js:53 #: js/ui/unlockDialog.js:50
msgid "Log in as another user" msgid "Log in as another user"
msgstr "Jentre come altri utent" msgstr "Jentre come altri utent"
#: js/ui/unlockDialog.js:70 #: js/ui/unlockDialog.js:67
msgid "Unlock Window" msgid "Unlock Window"
msgstr "Sbloche barcon" msgstr "Sbloche barcon"
@@ -2286,7 +2266,7 @@ msgstr[1] ""
#. Translators: This represents the size of a window. The first number is #. Translators: This represents the size of a window. The first number is
#. * the width of the window and the second is the height. #. * the width of the window and the second is the height.
#: js/ui/windowManager.js:686 #: js/ui/windowManager.js:683
#, javascript-format #, javascript-format
msgid "%d × %d" msgid "%d × %d"
msgstr "%d × %d" msgstr "%d × %d"
@@ -2370,7 +2350,7 @@ msgstr ""
#: src/extensions-tool/command-create.c:192 src/extensions-tool/main.c:169 #: src/extensions-tool/command-create.c:192 src/extensions-tool/main.c:169
msgid "Name" msgid "Name"
msgstr "Non" msgstr "Non "
#: src/extensions-tool/command-create.c:203 #: src/extensions-tool/command-create.c:203
#, c-format #, c-format
@@ -2624,7 +2604,7 @@ msgstr "Comants:"
msgid "Print help" msgid "Print help"
msgstr "Stampe jutori" msgstr "Stampe jutori"
#: src/extensions-tool/main.c:248 src/main.c:460 #: src/extensions-tool/main.c:248 src/main.c:468
msgid "Print version" msgid "Print version"
msgstr "Stampe version" msgstr "Stampe version"
@@ -2673,15 +2653,15 @@ msgstr "Instale complès di estensions"
msgid "Use “%s” to get detailed help.\n" msgid "Use “%s” to get detailed help.\n"
msgstr "Dopre “%s” par vê un jutori detaiât.\n" msgstr "Dopre “%s” par vê un jutori detaiât.\n"
#: src/main.c:466 #: src/main.c:474
msgid "Mode used by GDM for login screen" msgid "Mode used by GDM for login screen"
msgstr "Modalitât doprade da GDM pe videade di acès" msgstr "Modalitât doprade da GDM pe videade di acès"
#: src/main.c:472 #: src/main.c:480
msgid "Use a specific mode, e.g. “gdm” for login screen" msgid "Use a specific mode, e.g. “gdm” for login screen"
msgstr "Dopre une modalitât specifiche, par esempli “gdm” pe videade di acès" msgstr "Dopre une modalitât specifiche, par esempli “gdm” pe videade di acès"
#: src/main.c:478 #: src/main.c:486
msgid "List possible modes" msgid "List possible modes"
msgstr "Liste modalitâts pussibilis" msgstr "Liste modalitâts pussibilis"

524
po/hr.po

File diff suppressed because it is too large Load Diff

View File

@@ -95,6 +95,7 @@ libshell_public_headers = [
'shell-app.h', 'shell-app.h',
'shell-app-system.h', 'shell-app-system.h',
'shell-app-usage.h', 'shell-app-usage.h',
'shell-blur-effect.h',
'shell-embedded-window.h', 'shell-embedded-window.h',
'shell-glsl-effect.h', 'shell-glsl-effect.h',
'shell-gtk-embed.h', 'shell-gtk-embed.h',
@@ -129,6 +130,7 @@ libshell_sources = [
'shell-app.c', 'shell-app.c',
'shell-app-system.c', 'shell-app-system.c',
'shell-app-usage.c', 'shell-app-usage.c',
'shell-blur-effect.c',
'shell-embedded-window.c', 'shell-embedded-window.c',
'shell-embedded-window-private.h', 'shell-embedded-window-private.h',
'shell-global.c', 'shell-global.c',

View File

@@ -509,7 +509,7 @@ shell_app_activate_full (ShellApp *app,
case SHELL_APP_STATE_STOPPED: case SHELL_APP_STATE_STOPPED:
{ {
GError *error = NULL; GError *error = NULL;
if (!shell_app_launch (app, timestamp, workspace, SHELL_APP_GPU_SELECTION_AUTO, &error)) if (!shell_app_launch (app, timestamp, workspace, FALSE, &error))
{ {
char *msg; char *msg;
msg = g_strdup_printf (_("Failed to launch “%s”"), shell_app_get_name (app)); msg = g_strdup_printf (_("Failed to launch “%s”"), shell_app_get_name (app));
@@ -584,7 +584,7 @@ shell_app_open_new_window (ShellApp *app,
* instance (Firefox). There are a few less-sensical cases such * instance (Firefox). There are a few less-sensical cases such
* as say Pidgin. * as say Pidgin.
*/ */
shell_app_launch (app, 0, workspace, SHELL_APP_GPU_SELECTION_AUTO, NULL); shell_app_launch (app, 0, workspace, FALSE, NULL);
} }
/** /**
@@ -1255,37 +1255,19 @@ wait_pid (GDesktopAppInfo *appinfo,
g_child_watch_add (pid, (GChildWatchFunc) g_spawn_close_pid, NULL); g_child_watch_add (pid, (GChildWatchFunc) g_spawn_close_pid, NULL);
} }
static gboolean
get_with_discrete_gpu (ShellApp *app,
ShellAppGpuSelection discrete_gpu)
{
switch (discrete_gpu)
{
case SHELL_APP_GPU_SELECTION_INTEGRATED:
return FALSE;
case SHELL_APP_GPU_SELECTION_DISCRETE:
return TRUE;
case SHELL_APP_GPU_SELECTION_AUTO:
return g_desktop_app_info_get_boolean (app->info, "PreferRunOnDiscreteGPU") ||
g_desktop_app_info_get_boolean (app->info, "X-KDE-RunOnDiscreteGpu");
default:
g_assert_not_reached();
}
}
/** /**
* shell_app_launch: * shell_app_launch:
* @timestamp: Event timestamp, or 0 for current event timestamp * @timestamp: Event timestamp, or 0 for current event timestamp
* @workspace: Start on this workspace, or -1 for default * @workspace: Start on this workspace, or -1 for default
* @discrete_gpu: the preferred GPU to launch the application on. * @discrete_gpu: Whether to start on the discrete GPU
* @error: A #GError * @error: A #GError
*/ */
gboolean gboolean
shell_app_launch (ShellApp *app, shell_app_launch (ShellApp *app,
guint timestamp, guint timestamp,
int workspace, int workspace,
ShellAppGpuSelection discrete_gpu, gboolean discrete_gpu,
GError **error) GError **error)
{ {
ShellGlobal *global; ShellGlobal *global;
GAppLaunchContext *context; GAppLaunchContext *context;
@@ -1307,13 +1289,8 @@ shell_app_launch (ShellApp *app,
global = shell_global_get (); global = shell_global_get ();
context = shell_global_create_app_launch_context (global, timestamp, workspace); context = shell_global_create_app_launch_context (global, timestamp, workspace);
/* FIXME: this should probably check whether we're on a dual-GPU system */ if (discrete_gpu)
if (get_with_discrete_gpu (app, discrete_gpu)) g_app_launch_context_setenv (context, "DRI_PRIME", "1");
{
g_app_launch_context_setenv (context, "DRI_PRIME", "1");
g_app_launch_context_setenv (context, "__NV_PRIME_RENDER_OFFLOAD", "1");
g_app_launch_context_setenv (context, "__GLX_VENDOR_LIBRARY_NAME", "nvidia");
}
/* Set LEAVE_DESCRIPTORS_OPEN in order to use an optimized gspawn /* Set LEAVE_DESCRIPTORS_OPEN in order to use an optimized gspawn
* codepath. The shell's open file descriptors should be marked CLOEXEC * codepath. The shell's open file descriptors should be marked CLOEXEC

View File

@@ -18,12 +18,6 @@ typedef enum {
SHELL_APP_STATE_RUNNING SHELL_APP_STATE_RUNNING
} ShellAppState; } ShellAppState;
typedef enum {
SHELL_APP_GPU_SELECTION_AUTO = -1,
SHELL_APP_GPU_SELECTION_INTEGRATED = 0,
SHELL_APP_GPU_SELECTION_DISCRETE = 1
} ShellAppGpuSelection;
const char *shell_app_get_id (ShellApp *app); const char *shell_app_get_id (ShellApp *app);
GDesktopAppInfo *shell_app_get_app_info (ShellApp *app); GDesktopAppInfo *shell_app_get_app_info (ShellApp *app);
@@ -57,11 +51,11 @@ GSList *shell_app_get_pids (ShellApp *app);
gboolean shell_app_is_on_workspace (ShellApp *app, MetaWorkspace *workspace); gboolean shell_app_is_on_workspace (ShellApp *app, MetaWorkspace *workspace);
gboolean shell_app_launch (ShellApp *app, gboolean shell_app_launch (ShellApp *app,
guint timestamp, guint timestamp,
int workspace, int workspace,
ShellAppGpuSelection discrete_gpu, gboolean discrete_gpu,
GError **error); GError **error);
void shell_app_launch_action (ShellApp *app, void shell_app_launch_action (ShellApp *app,
const char *action_name, const char *action_name,

506
src/shell-blur-effect.c Normal file
View File

@@ -0,0 +1,506 @@
/* shell-blur-effect.c
*
* Copyright 2019 Georges Basile Stavracas Neto <georges.stavracas@gmail.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* SPDX-License-Identifier: GPL-3.0-or-later
*/
#include "shell-blur-effect.h"
static const gchar *gaussian_blur_glsl_declarations =
"uniform float blur_radius; \n"
"uniform float brightness; \n"
"uniform float pixel_step; \n"
"uniform int vertical; \n"
" \n"
"float gaussian (float sigma, float x) { \n"
" return exp ( - (x * x) / (2.0 * sigma * sigma)); \n"
"} \n"
" \n";
static const gchar *gaussian_blur_glsl =
" float radius = blur_radius * 2.30348; \n"
" float total = 0.0; \n"
" vec4 ret = vec4 (0); \n"
" vec2 uv = vec2(cogl_tex_coord.st); \n"
" \n"
" int half_radius = max(int(radius / 2.0), 1); \n"
" \n"
" if (vertical != 0) { \n"
" for (int y = -half_radius; y < half_radius; y++) { \n"
" float fy = gaussian (radius / 2.0, float(y)); \n"
" float offset_y = float(y) * pixel_step; \n"
" \n"
" vec4 c = texture2D(cogl_sampler, uv + vec2(0.0, offset_y)); \n"
" total += fy; \n"
" ret += c * fy; \n"
" } \n"
" } else { \n"
" for (int x = -half_radius; x < half_radius; x++) { \n"
" float fx = gaussian (radius / 2.0, float(x)); \n"
" float offset_x = float(x) * pixel_step; \n"
" \n"
" vec4 c = texture2D(cogl_sampler, uv + vec2(offset_x, 0.0)); \n"
" total += fx; \n"
" ret += c * fx; \n"
" } \n"
" } \n"
" \n"
" cogl_texel = vec4 (ret / total); \n"
" cogl_texel.rgb *= brightness; \n";
#define DOWNSCALE_FACTOR 4.0
struct _ShellBlurEffect
{
ClutterOffscreenEffect parent_instance;
CoglPipeline *pipeline;
int blur_radius_uniform;
int brightness_uniform;
int pixel_step_uniform;
int vertical_uniform;
unsigned int tex_width;
unsigned int tex_height;
gboolean vertical;
float brightness;
int blur_radius;
};
G_DEFINE_TYPE (ShellBlurEffect, shell_blur_effect, CLUTTER_TYPE_OFFSCREEN_EFFECT)
enum {
PROP_0,
PROP_BLUR_RADIUS,
PROP_BRIGHTNESS,
PROP_VERTICAL,
N_PROPS
};
static GParamSpec *properties [N_PROPS] = { NULL, };
static CoglPipeline*
create_pipeline (void)
{
static CoglPipeline *base_pipeline = NULL;
if (G_UNLIKELY (base_pipeline == NULL))
{
CoglSnippet *snippet;
CoglContext *ctx =
clutter_backend_get_cogl_context (clutter_get_default_backend ());
base_pipeline = cogl_pipeline_new (ctx);
snippet = cogl_snippet_new (COGL_SNIPPET_HOOK_TEXTURE_LOOKUP,
gaussian_blur_glsl_declarations,
NULL);
cogl_snippet_set_replace (snippet, gaussian_blur_glsl);
cogl_pipeline_add_layer_snippet (base_pipeline, 0, snippet);
cogl_object_unref (snippet);
cogl_pipeline_set_layer_null_texture (base_pipeline, 0);
cogl_pipeline_set_layer_filters (base_pipeline,
0,
COGL_PIPELINE_FILTER_LINEAR,
COGL_PIPELINE_FILTER_LINEAR);
cogl_pipeline_set_layer_wrap_mode (base_pipeline,
0,
COGL_PIPELINE_WRAP_MODE_CLAMP_TO_EDGE);
}
return cogl_pipeline_copy (base_pipeline);
}
static void
queue_actor_repaint (ShellBlurEffect *self)
{
ClutterActor *actor =
clutter_actor_meta_get_actor (CLUTTER_ACTOR_META (self));
if (actor)
clutter_actor_queue_redraw (actor);
}
static void
update_uniforms (ShellBlurEffect *self)
{
ClutterOffscreenEffect *offscreen_effect =
CLUTTER_OFFSCREEN_EFFECT (self);
CoglHandle texture;
texture = clutter_offscreen_effect_get_texture (offscreen_effect);
self->tex_width = cogl_texture_get_width (texture) * DOWNSCALE_FACTOR;
self->tex_height = cogl_texture_get_height (texture) * DOWNSCALE_FACTOR;
if (self->pixel_step_uniform > -1)
{
ClutterRect rect;
float pixel_step;
clutter_offscreen_effect_get_target_rect (CLUTTER_OFFSCREEN_EFFECT (self),
&rect);
if (self->vertical)
pixel_step = 1.f / rect.size.height;
else
pixel_step = 1.f / rect.size.width;
cogl_pipeline_set_uniform_1f (self->pipeline,
self->pixel_step_uniform,
pixel_step / DOWNSCALE_FACTOR);
}
if (self->blur_radius_uniform > -1)
{
cogl_pipeline_set_uniform_1f (self->pipeline,
self->blur_radius_uniform,
self->blur_radius / DOWNSCALE_FACTOR);
}
if (self->brightness_uniform > -1)
{
cogl_pipeline_set_uniform_1f (self->pipeline,
self->brightness_uniform,
self->brightness);
}
if (self->vertical_uniform > -1)
{
cogl_pipeline_set_uniform_1i (self->pipeline,
self->vertical_uniform,
self->vertical);
}
cogl_pipeline_set_layer_texture (self->pipeline, 0, texture);
}
static gboolean
shell_blur_effect_pre_paint (ClutterEffect *effect)
{
gboolean success;
success = CLUTTER_EFFECT_CLASS (shell_blur_effect_parent_class)->pre_paint (effect);
if (success)
{
CoglFramebuffer *offscreen = cogl_get_draw_framebuffer ();
/* Texture is downscaled, draw downscaled as well */
cogl_framebuffer_scale (offscreen,
1.0 / DOWNSCALE_FACTOR,
1.0 / DOWNSCALE_FACTOR,
1.0);
}
return success;
}
static void
shell_blur_effect_paint_target (ClutterOffscreenEffect *effect)
{
ShellBlurEffect *self = SHELL_BLUR_EFFECT (effect);
CoglFramebuffer *framebuffer = cogl_get_draw_framebuffer ();
ClutterActor *actor;
float blur_radius_offset_h;
float blur_radius_offset_v;
guint8 paint_opacity;
update_uniforms (self);
actor = clutter_actor_meta_get_actor (CLUTTER_ACTOR_META (self));
paint_opacity = clutter_actor_get_paint_opacity (actor);
cogl_pipeline_set_color4ub (self->pipeline,
paint_opacity,
paint_opacity,
paint_opacity,
paint_opacity);
blur_radius_offset_h =
self->blur_radius / (float) self->tex_width / DOWNSCALE_FACTOR;
blur_radius_offset_v =
self->blur_radius / (float) self->tex_height / DOWNSCALE_FACTOR;
cogl_framebuffer_draw_textured_rectangle (framebuffer,
self->pipeline,
0, 0,
self->tex_width,
self->tex_height,
blur_radius_offset_h,
blur_radius_offset_v,
1.f - blur_radius_offset_h,
1.f - blur_radius_offset_v);
}
static void
shell_blur_effect_post_paint (ClutterEffect *effect)
{
CoglFramebuffer *offscreen = cogl_get_draw_framebuffer ();
cogl_framebuffer_scale (offscreen,
DOWNSCALE_FACTOR,
DOWNSCALE_FACTOR,
1.f);
CLUTTER_EFFECT_CLASS (shell_blur_effect_parent_class)->post_paint (effect);
}
static CoglTexture*
shell_blur_effect_create_texture (ClutterOffscreenEffect *effect,
float width,
float height)
{
CoglContext *ctx =
clutter_backend_get_cogl_context (clutter_get_default_backend ());
return cogl_texture_2d_new_with_size (ctx,
width / DOWNSCALE_FACTOR,
height / DOWNSCALE_FACTOR);
}
static gboolean
shell_blur_effect_modify_paint_volume (ClutterEffect *effect,
ClutterPaintVolume *volume)
{
ShellBlurEffect *self = SHELL_BLUR_EFFECT (effect);
ClutterVertex origin;
float width;
float height;
clutter_paint_volume_get_origin (volume, &origin);
width = clutter_paint_volume_get_width (volume);
height = clutter_paint_volume_get_height (volume);
if (self->vertical)
{
origin.y -= self->blur_radius;
height += 2 * self->blur_radius;
}
else
{
origin.x -= self->blur_radius;
width += 2 * self->blur_radius;
}
clutter_paint_volume_set_origin (volume, &origin);
clutter_paint_volume_set_width (volume, width);
clutter_paint_volume_set_height (volume, height);
return TRUE;
}
static void
shell_blur_effect_finalize (GObject *object)
{
ShellBlurEffect *self = (ShellBlurEffect *)object;
g_clear_pointer (&self->pipeline, cogl_object_unref);
G_OBJECT_CLASS (shell_blur_effect_parent_class)->finalize (object);
}
static void
shell_blur_effect_get_property (GObject *object,
guint prop_id,
GValue *value,
GParamSpec *pspec)
{
ShellBlurEffect *self = SHELL_BLUR_EFFECT (object);
switch (prop_id)
{
case PROP_BLUR_RADIUS:
g_value_set_int (value, self->blur_radius);
break;
case PROP_BRIGHTNESS:
g_value_set_int (value, self->brightness);
break;
case PROP_VERTICAL:
g_value_set_boolean (value, self->vertical);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
}
}
static void
shell_blur_effect_set_property (GObject *object,
guint prop_id,
const GValue *value,
GParamSpec *pspec)
{
ShellBlurEffect *self = SHELL_BLUR_EFFECT (object);
switch (prop_id)
{
case PROP_BLUR_RADIUS:
shell_blur_effect_set_blur_radius (self, g_value_get_int (value));
break;
case PROP_BRIGHTNESS:
shell_blur_effect_set_brightness (self, g_value_get_float (value));
break;
case PROP_VERTICAL:
shell_blur_effect_set_vertical (self, g_value_get_boolean (value));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
}
}
static void
shell_blur_effect_class_init (ShellBlurEffectClass *klass)
{
GObjectClass *object_class = G_OBJECT_CLASS (klass);
ClutterEffectClass *effect_class = CLUTTER_EFFECT_CLASS (klass);
ClutterOffscreenEffectClass *offscreen_class =
CLUTTER_OFFSCREEN_EFFECT_CLASS (klass);
object_class->finalize = shell_blur_effect_finalize;
object_class->get_property = shell_blur_effect_get_property;
object_class->set_property = shell_blur_effect_set_property;
effect_class->pre_paint = shell_blur_effect_pre_paint;
effect_class->post_paint = shell_blur_effect_post_paint;
effect_class->modify_paint_volume = shell_blur_effect_modify_paint_volume;
offscreen_class->paint_target = shell_blur_effect_paint_target;
offscreen_class->create_texture = shell_blur_effect_create_texture;
properties[PROP_BLUR_RADIUS] =
g_param_spec_int ("blur-radius",
"Blur radius",
"Blur radius",
0, G_MAXINT, 0,
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
properties[PROP_BRIGHTNESS] =
g_param_spec_float ("brightness",
"Brightness",
"Brightness",
0.f, 1.f, 1.f,
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
properties[PROP_VERTICAL] =
g_param_spec_boolean ("vertical",
"Vertical",
"Whether the blur is vertical or horizontal",
FALSE,
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
g_object_class_install_properties (object_class, N_PROPS, properties);
}
static void
shell_blur_effect_init (ShellBlurEffect *self)
{
self->blur_radius = 0;
self->brightness = 1.f;
self->vertical = FALSE;
self->pipeline = create_pipeline ();
self->blur_radius_uniform =
cogl_pipeline_get_uniform_location (self->pipeline, "blur_radius");
self->brightness_uniform =
cogl_pipeline_get_uniform_location (self->pipeline, "brightness");
self->pixel_step_uniform =
cogl_pipeline_get_uniform_location (self->pipeline, "pixel_step");
self->vertical_uniform =
cogl_pipeline_get_uniform_location (self->pipeline, "vertical");
}
ShellBlurEffect *
shell_blur_effect_new (void)
{
return g_object_new (SHELL_TYPE_BLUR_EFFECT, NULL);
}
int
shell_blur_effect_get_blur_radius (ShellBlurEffect *self)
{
g_return_val_if_fail (SHELL_IS_BLUR_EFFECT (self), -1);
return self->blur_radius;
}
void
shell_blur_effect_set_blur_radius (ShellBlurEffect *self,
int radius)
{
g_return_if_fail (SHELL_IS_BLUR_EFFECT (self));
if (self->blur_radius == radius)
return;
self->blur_radius = radius;
queue_actor_repaint (self);
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_BLUR_RADIUS]);
}
float
shell_blur_effect_get_brightness (ShellBlurEffect *self)
{
g_return_val_if_fail (SHELL_IS_BLUR_EFFECT (self), FALSE);
return self->brightness;
}
void
shell_blur_effect_set_brightness (ShellBlurEffect *self,
float brightness)
{
g_return_if_fail (SHELL_IS_BLUR_EFFECT (self));
if (self->brightness == brightness)
return;
self->brightness = brightness;
queue_actor_repaint (self);
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_BRIGHTNESS]);
}
gboolean
shell_blur_effect_get_vertical (ShellBlurEffect *self)
{
g_return_val_if_fail (SHELL_IS_BLUR_EFFECT (self), FALSE);
return self->vertical;
}
void
shell_blur_effect_set_vertical (ShellBlurEffect *self,
gboolean vertical)
{
g_return_if_fail (SHELL_IS_BLUR_EFFECT (self));
if (self->vertical == vertical)
return;
self->vertical = vertical;
queue_actor_repaint (self);
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_VERTICAL]);
}

45
src/shell-blur-effect.h Normal file
View File

@@ -0,0 +1,45 @@
/* shell-blur-effect.h
*
* Copyright 2019 Georges Basile Stavracas Neto <georges.stavracas@gmail.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* SPDX-License-Identifier: GPL-3.0-or-later
*/
#pragma once
#include <clutter/clutter.h>
G_BEGIN_DECLS
#define SHELL_TYPE_BLUR_EFFECT (shell_blur_effect_get_type())
G_DECLARE_FINAL_TYPE (ShellBlurEffect, shell_blur_effect, SHELL, BLUR_EFFECT, ClutterOffscreenEffect)
ShellBlurEffect *shell_blur_effect_new (void);
int shell_blur_effect_get_blur_radius (ShellBlurEffect *self);
void shell_blur_effect_set_blur_radius (ShellBlurEffect *self,
int radius);
float shell_blur_effect_get_brightness (ShellBlurEffect *self);
void shell_blur_effect_set_brightness (ShellBlurEffect *self,
float brightness);
gboolean shell_blur_effect_get_vertical (ShellBlurEffect *self);
void shell_blur_effect_set_vertical (ShellBlurEffect *self,
gboolean vertical);
G_END_DECLS

View File

@@ -457,6 +457,7 @@ grab_window_screenshot (ClutterActor *stage,
ClutterActor *window_actor; ClutterActor *window_actor;
gfloat actor_x, actor_y; gfloat actor_x, actor_y;
MetaRectangle rect; MetaRectangle rect;
cairo_rectangle_int_t clip;
window_actor = CLUTTER_ACTOR (meta_window_get_compositor_private (window)); window_actor = CLUTTER_ACTOR (meta_window_get_compositor_private (window));
clutter_actor_get_position (window_actor, &actor_x, &actor_y); clutter_actor_get_position (window_actor, &actor_x, &actor_y);
@@ -466,10 +467,16 @@ grab_window_screenshot (ClutterActor *stage,
if (!priv->include_frame) if (!priv->include_frame)
meta_window_frame_rect_to_client_rect (window, &rect, &rect); meta_window_frame_rect_to_client_rect (window, &rect, &rect);
priv->screenshot_area = rect; priv->screenshot_area.x = rect.x;
priv->screenshot_area.y = rect.y;
clip.x = rect.x - (gint) actor_x;
clip.y = rect.y - (gint) actor_y;
clip.width = priv->screenshot_area.width = rect.width;
clip.height = priv->screenshot_area.height = rect.height;
priv->image = meta_window_actor_get_image (META_WINDOW_ACTOR (window_actor), priv->image = meta_window_actor_get_image (META_WINDOW_ACTOR (window_actor),
NULL); &clip);
priv->datetime = g_date_time_new_now_local (); priv->datetime = g_date_time_new_now_local ();
if (priv->include_cursor) if (priv->include_cursor)

View File

@@ -35,7 +35,8 @@
#endif #endif
static void static void
stop_pick (ClutterActor *actor) stop_pick (ClutterActor *actor,
const ClutterColor *color)
{ {
g_signal_stop_emission_by_name (actor, "pick"); g_signal_stop_emission_by_name (actor, "pick");
} }
@@ -96,7 +97,7 @@ shell_util_get_transformed_allocation (ClutterActor *actor,
/* Code adapted from clutter-actor.c: /* Code adapted from clutter-actor.c:
* Copyright 2006, 2007, 2008 OpenedHand Ltd * Copyright 2006, 2007, 2008 OpenedHand Ltd
*/ */
graphene_point3d_t v[4]; ClutterVertex v[4];
gfloat x_min, x_max, y_min, y_max; gfloat x_min, x_max, y_min, y_max;
guint i; guint i;

View File

@@ -443,7 +443,8 @@ st_box_layout_paint (ClutterActor *actor)
} }
static void static void
st_box_layout_pick (ClutterActor *actor) st_box_layout_pick (ClutterActor *actor,
const ClutterColor *color)
{ {
StBoxLayout *self = ST_BOX_LAYOUT (actor); StBoxLayout *self = ST_BOX_LAYOUT (actor);
StBoxLayoutPrivate *priv = self->priv; StBoxLayoutPrivate *priv = self->priv;
@@ -461,7 +462,7 @@ st_box_layout_pick (ClutterActor *actor)
cogl_framebuffer_translate (fb, (int)x, (int)y, 0); cogl_framebuffer_translate (fb, (int)x, (int)y, 0);
} }
CLUTTER_ACTOR_CLASS (st_box_layout_parent_class)->pick (actor); CLUTTER_ACTOR_CLASS (st_box_layout_parent_class)->pick (actor, color);
if (x != 0 || y != 0) if (x != 0 || y != 0)
{ {
@@ -489,7 +490,7 @@ st_box_layout_pick (ClutterActor *actor)
for (child = clutter_actor_get_first_child (actor); for (child = clutter_actor_get_first_child (actor);
child != NULL; child != NULL;
child = clutter_actor_get_next_sibling (child)) child = clutter_actor_get_next_sibling (child))
clutter_actor_pick (child); clutter_actor_paint (child);
if (priv->hadjustment || priv->vadjustment) if (priv->hadjustment || priv->vadjustment)
cogl_framebuffer_pop_clip (fb); cogl_framebuffer_pop_clip (fb);
@@ -505,7 +506,7 @@ st_box_layout_get_paint_volume (ClutterActor *actor,
StThemeNode *theme_node = st_widget_get_theme_node (ST_WIDGET (actor)); StThemeNode *theme_node = st_widget_get_theme_node (ST_WIDGET (actor));
ClutterActorBox allocation_box; ClutterActorBox allocation_box;
ClutterActorBox content_box; ClutterActorBox content_box;
graphene_point3d_t origin; ClutterVertex origin;
/* Setting the paint volume does not make sense when we don't have any allocation */ /* Setting the paint volume does not make sense when we don't have any allocation */
if (!clutter_actor_has_allocation (actor)) if (!clutter_actor_has_allocation (actor))

View File

@@ -40,7 +40,7 @@ struct _StButtonClass
void (* transition) (StButton *button); void (* transition) (StButton *button);
/* signals */ /* signals */
void (* clicked) (StButton *button, int clicked_button); void (* clicked) (StButton *button);
}; };
StWidget *st_button_new (void); StWidget *st_button_new (void);

View File

@@ -48,19 +48,19 @@ static GParamSpec *props[N_PROPS] = { NULL, };
struct _StIconPrivate struct _StIconPrivate
{ {
ClutterActor *icon_texture; ClutterActor *icon_texture;
ClutterActor *pending_texture; ClutterActor *pending_texture;
guint opacity_handler_id; guint opacity_handler_id;
GIcon *gicon; GIcon *gicon;
gint prop_icon_size; /* icon size set as property */ gint prop_icon_size; /* icon size set as property */
gint theme_icon_size; /* icon size from theme node */ gint theme_icon_size; /* icon size from theme node */
gint icon_size; /* icon size we are using */ gint icon_size; /* icon size we are using */
GIcon *fallback_gicon; GIcon *fallback_gicon;
CoglPipeline *shadow_pipeline; CoglPipeline *shadow_pipeline;
StShadow *shadow_spec; StShadow *shadow_spec;
graphene_size_t shadow_size; ClutterSize shadow_size;
}; };
G_DEFINE_TYPE_WITH_PRIVATE (StIcon, st_icon, ST_TYPE_WIDGET) G_DEFINE_TYPE_WITH_PRIVATE (StIcon, st_icon, ST_TYPE_WIDGET)
@@ -290,7 +290,7 @@ st_icon_clear_shadow_pipeline (StIcon *icon)
StIconPrivate *priv = icon->priv; StIconPrivate *priv = icon->priv;
g_clear_pointer (&priv->shadow_pipeline, cogl_object_unref); g_clear_pointer (&priv->shadow_pipeline, cogl_object_unref);
graphene_size_init (&priv->shadow_size, 0, 0); clutter_size_init (&priv->shadow_size, 0, 0);
} }
static void static void
@@ -317,7 +317,7 @@ st_icon_update_shadow_pipeline (StIcon *icon)
priv->icon_texture); priv->icon_texture);
if (priv->shadow_pipeline) if (priv->shadow_pipeline)
graphene_size_init (&priv->shadow_size, width, height); clutter_size_init (&priv->shadow_size, width, height);
} }
} }
} }

View File

@@ -100,7 +100,7 @@ st_scroll_view_fade_paint_target (ClutterOffscreenEffect *effect)
float fade_area_topleft[2]; float fade_area_topleft[2];
float fade_area_bottomright[2]; float fade_area_bottomright[2];
graphene_point3d_t verts[4]; ClutterVertex verts[4];
clutter_actor_get_paint_box (self->actor, &paint_box); clutter_actor_get_paint_box (self->actor, &paint_box);
clutter_actor_get_abs_allocation_vertices (self->actor, verts); clutter_actor_get_abs_allocation_vertices (self->actor, verts);

View File

@@ -294,19 +294,20 @@ st_scroll_view_paint (ClutterActor *actor)
} }
static void static void
st_scroll_view_pick (ClutterActor *actor) st_scroll_view_pick (ClutterActor *actor,
const ClutterColor *color)
{ {
StScrollViewPrivate *priv = ST_SCROLL_VIEW (actor)->priv; StScrollViewPrivate *priv = ST_SCROLL_VIEW (actor)->priv;
/* Chain up so we get a bounding box pained (if we are reactive) */ /* Chain up so we get a bounding box pained (if we are reactive) */
CLUTTER_ACTOR_CLASS (st_scroll_view_parent_class)->pick (actor); CLUTTER_ACTOR_CLASS (st_scroll_view_parent_class)->pick (actor, color);
if (priv->child) if (priv->child)
clutter_actor_pick (priv->child); clutter_actor_paint (priv->child);
if (priv->hscrollbar_visible) if (priv->hscrollbar_visible)
clutter_actor_pick (priv->hscroll); clutter_actor_paint (priv->hscroll);
if (priv->vscrollbar_visible) if (priv->vscrollbar_visible)
clutter_actor_pick (priv->vscroll); clutter_actor_paint (priv->vscroll);
} }
static gboolean static gboolean
@@ -962,6 +963,23 @@ st_scroll_view_remove (ClutterContainer *container,
} }
} }
static void
st_scroll_view_foreach_with_internals (ClutterContainer *container,
ClutterCallback callback,
gpointer user_data)
{
StScrollViewPrivate *priv = ST_SCROLL_VIEW (container)->priv;
if (priv->child != NULL)
callback (priv->child, user_data);
if (priv->hscroll != NULL)
callback (priv->hscroll, user_data);
if (priv->vscroll != NULL)
callback (priv->vscroll, user_data);
}
static void static void
clutter_container_iface_init (ClutterContainerIface *iface) clutter_container_iface_init (ClutterContainerIface *iface)
{ {
@@ -973,6 +991,7 @@ clutter_container_iface_init (ClutterContainerIface *iface)
iface->add = st_scroll_view_add; iface->add = st_scroll_view_add;
iface->remove = st_scroll_view_remove; iface->remove = st_scroll_view_remove;
iface->foreach_with_internals = st_scroll_view_foreach_with_internals;
} }
StWidget * StWidget *

View File

@@ -762,7 +762,7 @@ st_widget_get_paint_volume (ClutterActor *self,
ClutterActorBox paint_box, alloc_box; ClutterActorBox paint_box, alloc_box;
StThemeNode *theme_node; StThemeNode *theme_node;
StWidgetPrivate *priv; StWidgetPrivate *priv;
graphene_point3d_t origin; ClutterVertex origin;
/* Setting the paint volume does not make sense when we don't have any allocation */ /* Setting the paint volume does not make sense when we don't have any allocation */
if (!clutter_actor_has_allocation (self)) if (!clutter_actor_has_allocation (self))
@@ -2062,7 +2062,7 @@ filter_by_position (GList *children,
StDirectionType direction) StDirectionType direction)
{ {
ClutterActorBox cbox; ClutterActorBox cbox;
graphene_point3d_t abs_vertices[4]; ClutterVertex abs_vertices[4];
GList *l, *ret; GList *l, *ret;
ClutterActor *child; ClutterActor *child;
@@ -2128,7 +2128,7 @@ get_distance (ClutterActor *actor,
{ {
int ax, ay, bx, by, dx, dy; int ax, ay, bx, by, dx, dy;
ClutterActorBox abox; ClutterActorBox abox;
graphene_point3d_t abs_vertices[4]; ClutterVertex abs_vertices[4];
clutter_actor_get_abs_allocation_vertices (actor, abs_vertices); clutter_actor_get_abs_allocation_vertices (actor, abs_vertices);
clutter_actor_box_from_vertices (&abox, abs_vertices); clutter_actor_box_from_vertices (&abox, abs_vertices);
@@ -2232,7 +2232,7 @@ st_widget_real_navigate_focus (StWidget *widget,
else /* direction is an arrow key, not tab */ else /* direction is an arrow key, not tab */
{ {
ClutterActorBox sort_box; ClutterActorBox sort_box;
graphene_point3d_t abs_vertices[4]; ClutterVertex abs_vertices[4];
/* Compute the allocation box of the previous focused actor. If there /* Compute the allocation box of the previous focused actor. If there
* was no previous focus, use the coordinates of the appropriate edge of * was no previous focus, use the coordinates of the appropriate edge of

View File

@@ -36,16 +36,16 @@ function test() {
obin.connect_after('paint', actor => { obin.connect_after('paint', actor => {
Cogl.set_source_color4f(0, 1, 0, 1); Cogl.set_source_color4f(0, 1, 0, 1);
let alloc = actor.get_allocation_box(); let geom = actor.get_allocation_geometry();
let width = 3; let width = 3;
// clockwise order // clockwise order
Cogl.rectangle(0, 0, alloc.get_width(), width); Cogl.rectangle(0, 0, geom.width, width);
Cogl.rectangle(alloc.get_width() - width, width, Cogl.rectangle(geom.width - width, width,
alloc.get_width(), alloc.get_height()); geom.width, geom.height);
Cogl.rectangle(0, alloc.get_height(), Cogl.rectangle(0, geom.height,
alloc.get_width() - width, alloc.get_height() - width); geom.width - width, geom.height - width);
Cogl.rectangle(0, alloc.get_height() - width, Cogl.rectangle(0, geom.height - width,
width, width); width, width);
}); });
tbox.add(obin); tbox.add(obin);

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