Compare commits
56 Commits
3.35.1
...
wip/hadess
Author | SHA1 | Date | |
---|---|---|---|
752b1df659 | |||
366b06716d | |||
4d47b16d33 | |||
6526e9edf6 | |||
055c007ac2 | |||
43cf466d09 | |||
6965781d59 | |||
80680803aa | |||
51601f3ead | |||
b25a73c243 | |||
d0690c3952 | |||
f2466caef3 | |||
b1d22d2058 | |||
6f7e5976e2 | |||
29543f369f | |||
a144a1c76d | |||
d91927674d | |||
d12cd12e1b | |||
caa50dc1a3 | |||
55b57421dc | |||
320df13b65 | |||
e4920b2f80 | |||
c9fbae3408 | |||
a3c6217875 | |||
db7726c5bf | |||
0b91dee5a9 | |||
3838220961 | |||
9bb12f6f87 | |||
4dea1f801a | |||
91a5133116 | |||
c4c5c4fd5c | |||
f67b409fc1 | |||
22fe4e92c7 | |||
91eb84fa4e | |||
4e1492c926 | |||
ed97f61750 | |||
b5676a2a5c | |||
7059dcced3 | |||
c7e0c7eb79 | |||
ff775213a5 | |||
7f9c709c85 | |||
74d7d3e259 | |||
0353a5bf2c | |||
ab6a629955 | |||
6cad251187 | |||
d7c569c692 | |||
0615370930 | |||
7a92a9ba21 | |||
0199857c5b | |||
59e3a1a816 | |||
6533690fff | |||
d0d1845bb6 | |||
20f4fc7c87 | |||
b4128967a1 | |||
38ad1d7c13 | |||
f78136182f |
@ -16,8 +16,14 @@ run_eslint() {
|
||||
ARGS_LEGACY='--config lint/eslintrc-legacy.json'
|
||||
|
||||
local extra_args=ARGS_$1
|
||||
local output=OUTPUT_$1
|
||||
eslint -f unix ${!extra_args} -o ${!output} js
|
||||
local output_var=OUTPUT_$1
|
||||
local output=${!output_var}
|
||||
|
||||
# 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() {
|
||||
@ -70,10 +76,13 @@ create_common() {
|
||||
# non-legacy style just yet ...
|
||||
unset CI_MERGE_REQUEST_TARGET_BRANCH_NAME
|
||||
|
||||
if [ "$CI_MERGE_REQUEST_TARGET_BRANCH_NAME" ]; then
|
||||
git fetch $CI_MERGE_REQUEST_PROJECT_URL.git $CI_MERGE_REQUEST_TARGET_BRANCH_NAME
|
||||
REMOTE=${1:-$CI_MERGE_REQUEST_PROJECT_URL.git}
|
||||
BRANCH_NAME=${2:-$CI_MERGE_REQUEST_TARGET_BRANCH_NAME}
|
||||
|
||||
if [ "$BRANCH_NAME" ]; then
|
||||
git fetch $REMOTE $BRANCH_NAME
|
||||
branch_point=$(git merge-base HEAD FETCH_HEAD)
|
||||
commit_range=$branch_point...$CI_COMMIT_SHA
|
||||
commit_range=$branch_point...HEAD
|
||||
|
||||
list_commit_range_additions $commit_range > $LINE_CHANGES
|
||||
|
||||
@ -96,7 +105,7 @@ if ! is_empty $OUTPUT_FINAL; then
|
||||
fi
|
||||
|
||||
# Just show the report and succeed when not testing a MR
|
||||
if [ -z "$CI_MERGE_REQUEST_TARGET_BRANCH_NAME" ]; then
|
||||
if [ -z "$BRANCH_NAME" ]; then
|
||||
exit 0
|
||||
fi
|
||||
|
||||
|
19
HACKING.md
19
HACKING.md
@ -186,15 +186,27 @@ and "double quotes" for strings that the user may see. This allows us to
|
||||
quickly find untranslated or mistranslated strings by grepping through the
|
||||
sources for double quotes without a gettext call around them.
|
||||
|
||||
## `actor` and `_delegate`
|
||||
## `actor` (deprecated) and `_delegate`
|
||||
|
||||
gjs allows us to set so-called "expando properties" on introspected objects,
|
||||
allowing us to treat them like any other. Because the Shell was built before
|
||||
you could inherit from GTypes natively in JS, we usually have a wrapper class
|
||||
that has a property called `actor`. We call this wrapper class the "delegate".
|
||||
you could inherit from GTypes natively in JS, in some cases we have a wrapper
|
||||
class that has a property called `actor` (now deprecated). We call this
|
||||
wrapper class the "delegate".
|
||||
|
||||
We sometimes use expando properties to set a property called `_delegate` on
|
||||
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
|
||||
var MyClass = class {
|
||||
constructor() {
|
||||
@ -215,6 +227,7 @@ delegate object from an associated actor. For instance, the drag and drop
|
||||
system calls the `handleDragOver` function on the delegate of a "drop target"
|
||||
when the user drags an item over it. If you do not set the `_delegate`
|
||||
property, your actor will not be able to be dropped onto.
|
||||
In case the class is an actor itself, the `_delegate` can be just set to `this`.
|
||||
|
||||
## Functional style
|
||||
|
||||
|
@ -50,7 +50,7 @@
|
||||
</description>
|
||||
</key>
|
||||
<key name="favorite-apps" type="as">
|
||||
<default>[ 'epiphany.desktop', 'evolution.desktop', 'rhythmbox.desktop', 'shotwell.desktop', 'org.gnome.Nautilus.desktop', 'org.gnome.Software.desktop' ]</default>
|
||||
<default>[ 'epiphany.desktop', 'evolution.desktop', 'rhythmbox.desktop', 'org.gnome.Shotwell.desktop', 'org.gnome.Nautilus.desktop', 'org.gnome.Software.desktop' ]</default>
|
||||
<summary>List of desktop file IDs for favorite applications</summary>
|
||||
<description>
|
||||
The applications corresponding to these identifiers
|
||||
|
@ -31,34 +31,34 @@ its dependencies to build from tarballs.</description>
|
||||
<programming-language>JavaScript</programming-language>
|
||||
<programming-language>C</programming-language>
|
||||
|
||||
<maintainer>
|
||||
<author>
|
||||
<foaf:Person>
|
||||
<foaf:name>William Jon McCann</foaf:name>
|
||||
<foaf:mbox rdf:resource="mailto:jmccann@redhat.com" />
|
||||
<gnome:userid>mccann</gnome:userid>
|
||||
</foaf:Person>
|
||||
</maintainer>
|
||||
<maintainer>
|
||||
</author>
|
||||
<author>
|
||||
<foaf:Person>
|
||||
<foaf:name>Owen Taylor</foaf:name>
|
||||
<foaf:mbox rdf:resource="mailto:otaylor@redhat.com" />
|
||||
<gnome:userid>otaylor</gnome:userid>
|
||||
</foaf:Person>
|
||||
</maintainer>
|
||||
<maintainer>
|
||||
</author>
|
||||
<author>
|
||||
<foaf:Person>
|
||||
<foaf:name>Colin Walters</foaf:name>
|
||||
<foaf:mbox rdf:resource="mailto:walters@verbum.org" />
|
||||
<gnome:userid>walters</gnome:userid>
|
||||
</foaf:Person>
|
||||
</maintainer>
|
||||
<maintainer>
|
||||
</author>
|
||||
<author>
|
||||
<foaf:Person>
|
||||
<foaf:name>Marina Zhurakhinskaya</foaf:name>
|
||||
<foaf:mbox rdf:resource="mailto:marinaz@redhat.com" />
|
||||
<gnome:userid>marinaz</gnome:userid>
|
||||
</foaf:Person>
|
||||
</maintainer>
|
||||
</author>
|
||||
<maintainer>
|
||||
<foaf:Person>
|
||||
<foaf:name>Florian Müllner</foaf:name>
|
||||
|
@ -1,11 +1,12 @@
|
||||
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
|
||||
/* exported AuthPrompt */
|
||||
|
||||
const { Clutter, Pango, Shell, St } = imports.gi;
|
||||
const Signals = imports.signals;
|
||||
const { Clutter, GObject, Pango, Shell, St } = imports.gi;
|
||||
|
||||
const Animation = imports.ui.animation;
|
||||
const Batch = imports.gdm.batch;
|
||||
const GdmUtil = imports.gdm.util;
|
||||
const Util = imports.misc.util;
|
||||
const Params = imports.misc.params;
|
||||
const ShellEntry = imports.ui.shellEntry;
|
||||
const UserWidget = imports.ui.userWidget;
|
||||
@ -16,6 +17,10 @@ var DEFAULT_BUTTON_WELL_ANIMATION_TIME = 300;
|
||||
|
||||
var MESSAGE_FADE_OUT_ANIMATION_TIME = 500;
|
||||
|
||||
const WIGGLE_OFFSET = 6;
|
||||
const WIGGLE_DURATION = 65;
|
||||
const N_WIGGLES = 3;
|
||||
|
||||
var AuthPromptMode = {
|
||||
UNLOCK_ONLY: 0,
|
||||
UNLOCK_OR_LOG_IN: 1
|
||||
@ -33,8 +38,21 @@ var BeginRequestType = {
|
||||
DONT_PROVIDE_USERNAME: 1
|
||||
};
|
||||
|
||||
var AuthPrompt = class {
|
||||
constructor(gdmClient, mode) {
|
||||
var AuthPrompt = GObject.registerClass({
|
||||
Signals: {
|
||||
'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._gdmClient = gdmClient;
|
||||
@ -67,38 +85,33 @@ var AuthPrompt = class {
|
||||
}
|
||||
});
|
||||
|
||||
this.actor = new St.BoxLayout({ style_class: 'login-dialog-prompt-layout',
|
||||
vertical: true });
|
||||
this.actor.connect('destroy', this._onDestroy.bind(this));
|
||||
this.actor.connect('key-press-event', (actor, event) => {
|
||||
if (event.get_key_symbol() == Clutter.KEY_Escape)
|
||||
this.cancel();
|
||||
return Clutter.EVENT_PROPAGATE;
|
||||
});
|
||||
this.connect('destroy', this._onDestroy.bind(this));
|
||||
|
||||
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._userWell = new St.Bin({ x_fill: true, x_align: St.Align.START });
|
||||
this.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.actor.add(this._label,
|
||||
{ expand: true,
|
||||
x_fill: false,
|
||||
y_fill: true,
|
||||
x_align: St.Align.START });
|
||||
this.add(this._label, {
|
||||
expand: true,
|
||||
x_fill: false,
|
||||
y_fill: true,
|
||||
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.actor.add(this._entry,
|
||||
{ expand: true,
|
||||
x_fill: true,
|
||||
y_fill: false,
|
||||
x_align: St.Align.START });
|
||||
this.add(this._entry, {
|
||||
expand: true,
|
||||
x_fill: true,
|
||||
y_fill: false,
|
||||
x_align: St.Align.START
|
||||
});
|
||||
|
||||
this._entry.grab_key_focus();
|
||||
|
||||
@ -106,14 +119,15 @@ var AuthPrompt = class {
|
||||
styleClass: 'login-dialog-message' });
|
||||
this._message.clutter_text.line_wrap = true;
|
||||
this._message.clutter_text.ellipsize = Pango.EllipsizeMode.NONE;
|
||||
this.actor.add(this._message, { x_fill: false, x_align: St.Align.START, y_align: St.Align.START });
|
||||
this.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.actor.add(this._buttonBox,
|
||||
{ expand: true,
|
||||
x_align: St.Align.MIDDLE,
|
||||
y_align: St.Align.END });
|
||||
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;
|
||||
@ -121,9 +135,9 @@ var AuthPrompt = class {
|
||||
this._initButtons();
|
||||
|
||||
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);
|
||||
this._spinner.opacity = 0;
|
||||
this._spinner.show();
|
||||
this._defaultButtonWell.add_child(this._spinner);
|
||||
}
|
||||
|
||||
_onDestroy() {
|
||||
@ -131,6 +145,12 @@ var AuthPrompt = class {
|
||||
this._userVerifier = null;
|
||||
}
|
||||
|
||||
vfunc_key_press_event(keyPressEvent) {
|
||||
if (keyPressEvent.keyval == Clutter.KEY_Escape)
|
||||
this.cancel();
|
||||
return Clutter.EVENT_PROPAGATE;
|
||||
}
|
||||
|
||||
_initButtons() {
|
||||
this.cancelButton = new St.Button({ style_class: 'modal-dialog-button button',
|
||||
button_mask: St.ButtonMask.ONE | St.ButtonMask.THREE,
|
||||
@ -241,6 +261,12 @@ var AuthPrompt = class {
|
||||
this.updateSensitivity(canRetry);
|
||||
this.setActorInDefaultButtonWell(null);
|
||||
this.verificationStatus = AuthPromptStatus.VERIFICATION_FAILED;
|
||||
|
||||
Util.wiggle(this._entry, {
|
||||
offset: WIGGLE_OFFSET,
|
||||
duration: WIGGLE_DURATION,
|
||||
wiggleCount: N_WIGGLES,
|
||||
});
|
||||
}
|
||||
|
||||
_onVerificationComplete() {
|
||||
@ -269,13 +295,13 @@ var AuthPrompt = class {
|
||||
oldActor.remove_all_transitions();
|
||||
|
||||
let wasSpinner;
|
||||
if (oldActor == this._spinner.actor)
|
||||
if (oldActor == this._spinner)
|
||||
wasSpinner = true;
|
||||
else
|
||||
wasSpinner = false;
|
||||
|
||||
let isSpinner;
|
||||
if (actor == this._spinner.actor)
|
||||
if (actor == this._spinner)
|
||||
isSpinner = true;
|
||||
else
|
||||
isSpinner = false;
|
||||
@ -323,7 +349,7 @@ var AuthPrompt = class {
|
||||
}
|
||||
|
||||
startSpinning() {
|
||||
this.setActorInDefaultButtonWell(this._spinner.actor, true);
|
||||
this.setActorInDefaultButtonWell(this._spinner, true);
|
||||
}
|
||||
|
||||
stopSpinning() {
|
||||
@ -404,9 +430,9 @@ var AuthPrompt = class {
|
||||
this._entry.clutter_text.editable = sensitive;
|
||||
}
|
||||
|
||||
hide() {
|
||||
vfunc_hide() {
|
||||
this.setActorInDefaultButtonWell(null, true);
|
||||
this.actor.hide();
|
||||
super.vfunc_hide();
|
||||
this._message.opacity = 0;
|
||||
|
||||
this.setUser(null);
|
||||
@ -422,7 +448,7 @@ var AuthPrompt = class {
|
||||
|
||||
if (user) {
|
||||
let userWidget = new UserWidget.UserWidget(user);
|
||||
this._userWell.set_child(userWidget.actor);
|
||||
this._userWell.set_child(userWidget);
|
||||
}
|
||||
}
|
||||
|
||||
@ -507,5 +533,4 @@ var AuthPrompt = class {
|
||||
this.reset();
|
||||
this.emit('cancelled');
|
||||
}
|
||||
};
|
||||
Signals.addSignalMethods(AuthPrompt.prototype);
|
||||
});
|
||||
|
@ -19,7 +19,6 @@
|
||||
|
||||
const { AccountsService, Atk, Clutter, Gdm, Gio,
|
||||
GLib, GObject, Meta, Pango, Shell, St } = imports.gi;
|
||||
const Signals = imports.signals;
|
||||
|
||||
const AuthPrompt = imports.gdm.authPrompt;
|
||||
const Batch = imports.gdm.batch;
|
||||
@ -39,72 +38,80 @@ const _TIMED_LOGIN_IDLE_THRESHOLD = 5.0;
|
||||
const _LOGO_ICON_HEIGHT = 48;
|
||||
const _MAX_BOTTOM_MENU_ITEMS = 5;
|
||||
|
||||
var UserListItem = class {
|
||||
constructor(user) {
|
||||
var UserListItem = GObject.registerClass({
|
||||
GTypeName: 'LoginDialog_UserListItem',
|
||||
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._userChangedId = this.user.connect('changed',
|
||||
this._onUserChanged.bind(this));
|
||||
|
||||
let layout = new St.BoxLayout({ vertical: true });
|
||||
this.actor = new St.Button({ 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.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.connect('destroy', this._onDestroy.bind(this));
|
||||
this.connect('notify::hover', () => {
|
||||
this._setSelected(this.hover);
|
||||
});
|
||||
|
||||
this._userWidget = new UserWidget.UserWidget(this.user);
|
||||
layout.add(this._userWidget.actor);
|
||||
layout.add(this._userWidget);
|
||||
|
||||
this._userWidget.actor.bind_property('label-actor', this.actor, 'label-actor',
|
||||
GObject.BindingFlags.SYNC_CREATE);
|
||||
this._userWidget.bind_property('label-actor', this, 'label-actor',
|
||||
GObject.BindingFlags.SYNC_CREATE);
|
||||
|
||||
this._timedLoginIndicator = new St.Bin({ style_class: 'login-dialog-timed-login-indicator',
|
||||
scale_x: 0,
|
||||
visible: false });
|
||||
layout.add(this._timedLoginIndicator);
|
||||
|
||||
this.actor.connect('clicked', this._onClicked.bind(this));
|
||||
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() {
|
||||
this._updateLoggedIn();
|
||||
}
|
||||
|
||||
_updateLoggedIn() {
|
||||
if (this.user.is_logged_in())
|
||||
this.actor.add_style_pseudo_class('logged-in');
|
||||
this.add_style_pseudo_class('logged-in');
|
||||
else
|
||||
this.actor.remove_style_pseudo_class('logged-in');
|
||||
this.remove_style_pseudo_class('logged-in');
|
||||
}
|
||||
|
||||
_onDestroy() {
|
||||
this.user.disconnect(this._userChangedId);
|
||||
}
|
||||
|
||||
_onClicked() {
|
||||
vfunc_clicked() {
|
||||
this.emit('activate');
|
||||
}
|
||||
|
||||
_setSelected(selected) {
|
||||
if (selected) {
|
||||
this.actor.add_style_pseudo_class('selected');
|
||||
this.actor.grab_key_focus();
|
||||
this.add_style_pseudo_class('selected');
|
||||
this.grab_key_focus();
|
||||
} else {
|
||||
this.actor.remove_style_pseudo_class('selected');
|
||||
this.remove_style_pseudo_class('selected');
|
||||
}
|
||||
}
|
||||
|
||||
@ -145,23 +152,30 @@ var UserListItem = class {
|
||||
this._timedLoginIndicator.visible = false;
|
||||
this._timedLoginIndicator.scale_x = 0.;
|
||||
}
|
||||
};
|
||||
Signals.addSignalMethods(UserListItem.prototype);
|
||||
});
|
||||
|
||||
var UserList = class {
|
||||
constructor() {
|
||||
this.actor = new St.ScrollView({ style_class: 'login-dialog-user-list-view' });
|
||||
this.actor.set_policy(St.PolicyType.NEVER,
|
||||
St.PolicyType.AUTOMATIC);
|
||||
var UserList = GObject.registerClass({
|
||||
GTypeName: 'LoginDialog_UserList',
|
||||
Signals: {
|
||||
'activate': { param_types: [UserListItem.$gtype] },
|
||||
'item-added': { param_types: [UserListItem.$gtype] },
|
||||
}
|
||||
}, 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,
|
||||
style_class: 'login-dialog-user-list',
|
||||
pseudo_class: 'expanded' });
|
||||
|
||||
this.actor.add_actor(this._box);
|
||||
this.add_actor(this._box);
|
||||
this._items = {};
|
||||
}
|
||||
|
||||
this.actor.connect('key-focus-in', this._moveFocusToItems.bind(this));
|
||||
vfunc_key_focus_in() {
|
||||
this._moveFocusToItems();
|
||||
}
|
||||
|
||||
_moveFocusToItems() {
|
||||
@ -170,10 +184,10 @@ var UserList = class {
|
||||
if (!hasItems)
|
||||
return;
|
||||
|
||||
if (global.stage.get_key_focus() != this.actor)
|
||||
if (global.stage.get_key_focus() != this)
|
||||
return;
|
||||
|
||||
let focusSet = this.actor.navigate_focus(null, St.DirectionType.TAB_FORWARD, false);
|
||||
let focusSet = this.navigate_focus(null, St.DirectionType.TAB_FORWARD, false);
|
||||
if (!focusSet) {
|
||||
Meta.later_add(Meta.LaterType.BEFORE_REDRAW, () => {
|
||||
this._moveFocusToItems();
|
||||
@ -194,14 +208,14 @@ var UserList = class {
|
||||
|
||||
for (let userName in this._items) {
|
||||
let item = this._items[userName];
|
||||
item.actor.sync_hover();
|
||||
item.sync_hover();
|
||||
}
|
||||
}
|
||||
|
||||
scrollToItem(item) {
|
||||
let box = item.actor.get_allocation_box();
|
||||
let box = item.get_allocation_box();
|
||||
|
||||
let adjustment = this.actor.get_vscroll_bar().get_adjustment();
|
||||
let adjustment = this.get_vscroll_bar().get_adjustment();
|
||||
|
||||
let value = (box.y1 + adjustment.step_increment / 2.0) - (adjustment.page_size / 2.0);
|
||||
adjustment.ease(value, {
|
||||
@ -211,9 +225,9 @@ var UserList = class {
|
||||
}
|
||||
|
||||
jumpToItem(item) {
|
||||
let box = item.actor.get_allocation_box();
|
||||
let box = item.get_allocation_box();
|
||||
|
||||
let adjustment = this.actor.get_vscroll_bar().get_adjustment();
|
||||
let adjustment = this.get_vscroll_bar().get_adjustment();
|
||||
|
||||
let value = (box.y1 + adjustment.step_increment / 2.0) - (adjustment.page_size / 2.0);
|
||||
|
||||
@ -251,14 +265,14 @@ var UserList = class {
|
||||
this.removeUser(user);
|
||||
|
||||
let item = new UserListItem(user);
|
||||
this._box.add(item.actor, { x_fill: true });
|
||||
this._box.add(item, { x_fill: true });
|
||||
|
||||
this._items[userName] = item;
|
||||
|
||||
item.connect('activate', this._onItemActivated.bind(this));
|
||||
|
||||
// Try to keep the focused item front-and-center
|
||||
item.actor.connect('key-focus-in', () => this.scrollToItem(item));
|
||||
item.connect('key-focus-in', () => this.scrollToItem(item));
|
||||
|
||||
this._moveFocusToItems();
|
||||
|
||||
@ -279,33 +293,38 @@ var UserList = class {
|
||||
if (!item)
|
||||
return;
|
||||
|
||||
item.actor.destroy();
|
||||
item.destroy();
|
||||
delete this._items[userName];
|
||||
}
|
||||
|
||||
numItems() {
|
||||
return Object.keys(this._items).length;
|
||||
}
|
||||
};
|
||||
Signals.addSignalMethods(UserList.prototype);
|
||||
});
|
||||
|
||||
var SessionMenuButton = class {
|
||||
constructor() {
|
||||
var SessionMenuButton = GObject.registerClass({
|
||||
GTypeName: 'LoginDialog_SessionMenuButton',
|
||||
Signals: { 'session-activated': { param_types: [GObject.TYPE_STRING] } }
|
||||
}, class SessionMenuButton extends St.Bin {
|
||||
_init() {
|
||||
let gearIcon = new St.Icon({ icon_name: 'emblem-system-symbolic' });
|
||||
this._button = new St.Button({ style_class: 'login-dialog-session-list-button',
|
||||
reactive: true,
|
||||
track_hover: true,
|
||||
can_focus: true,
|
||||
accessible_name: _("Choose Session"),
|
||||
accessible_role: Atk.Role.MENU,
|
||||
child: gearIcon });
|
||||
let button = new St.Button({
|
||||
style_class: 'login-dialog-session-list-button',
|
||||
reactive: true,
|
||||
track_hover: true,
|
||||
can_focus: true,
|
||||
accessible_name: _("Choose Session"),
|
||||
accessible_role: Atk.Role.MENU,
|
||||
child: gearIcon
|
||||
});
|
||||
|
||||
this.actor = new St.Bin({ child: this._button });
|
||||
super._init({ child: button });
|
||||
this._button = button;
|
||||
|
||||
let side = St.Side.TOP;
|
||||
let align = 0;
|
||||
if (Gdm.get_session_ids().length > _MAX_BOTTOM_MENU_ITEMS) {
|
||||
if (this.actor.text_direction == Clutter.TextDirection.RTL)
|
||||
if (this.text_direction == Clutter.TextDirection.RTL)
|
||||
side = St.Side.RIGHT;
|
||||
else
|
||||
side = St.Side.LEFT;
|
||||
@ -384,15 +403,13 @@ var SessionMenuButton = class {
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
||||
Signals.addSignalMethods(SessionMenuButton.prototype);
|
||||
});
|
||||
|
||||
var LoginDialog = GObject.registerClass({
|
||||
Signals: { 'failed': {} },
|
||||
}, class LoginDialog extends St.Widget {
|
||||
_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);
|
||||
|
||||
@ -426,7 +443,7 @@ var LoginDialog = GObject.registerClass({
|
||||
this.add_child(this._userSelectionBox);
|
||||
|
||||
this._userList = new UserList();
|
||||
this._userSelectionBox.add(this._userList.actor,
|
||||
this._userSelectionBox.add(this._userList,
|
||||
{ expand: true,
|
||||
x_fill: true,
|
||||
y_fill: true });
|
||||
@ -435,7 +452,7 @@ var LoginDialog = GObject.registerClass({
|
||||
this._authPrompt.connect('prompted', this._onPrompted.bind(this));
|
||||
this._authPrompt.connect('reset', this._onReset.bind(this));
|
||||
this._authPrompt.hide();
|
||||
this.add_child(this._authPrompt.actor);
|
||||
this.add_child(this._authPrompt);
|
||||
|
||||
// translators: this message is shown below the user list on the
|
||||
// login screen. It can be activated to reveal an entry for
|
||||
@ -494,9 +511,9 @@ var LoginDialog = GObject.registerClass({
|
||||
(list, sessionId) => {
|
||||
this._greeter.call_select_session_sync (sessionId, null);
|
||||
});
|
||||
this._sessionMenuButton.actor.opacity = 0;
|
||||
this._sessionMenuButton.actor.show();
|
||||
this._authPrompt.addActorToDefaultButtonWell(this._sessionMenuButton.actor);
|
||||
this._sessionMenuButton.opacity = 0;
|
||||
this._sessionMenuButton.show();
|
||||
this._authPrompt.addActorToDefaultButtonWell(this._sessionMenuButton);
|
||||
|
||||
this._disableUserList = undefined;
|
||||
this._userListLoaded = false;
|
||||
@ -579,8 +596,8 @@ var LoginDialog = GObject.registerClass({
|
||||
|
||||
let authPromptAllocation = null;
|
||||
let authPromptWidth = 0;
|
||||
if (this._authPrompt.actor.visible) {
|
||||
authPromptAllocation = this._getCenterActorAllocation(dialogBox, this._authPrompt.actor);
|
||||
if (this._authPrompt.visible) {
|
||||
authPromptAllocation = this._getCenterActorAllocation(dialogBox, this._authPrompt);
|
||||
authPromptWidth = authPromptAllocation.x2 - authPromptAllocation.x1;
|
||||
}
|
||||
|
||||
@ -690,7 +707,7 @@ var LoginDialog = GObject.registerClass({
|
||||
}
|
||||
|
||||
if (authPromptAllocation)
|
||||
this._authPrompt.actor.allocate(authPromptAllocation, flags);
|
||||
this._authPrompt.allocate(authPromptAllocation, flags);
|
||||
|
||||
if (userSelectionAllocation)
|
||||
this._userSelectionBox.allocate(userSelectionAllocation, flags);
|
||||
@ -794,7 +811,7 @@ var LoginDialog = GObject.registerClass({
|
||||
_onPrompted() {
|
||||
if (this._shouldShowSessionMenuButton()) {
|
||||
this._sessionMenuButton.updateSensitivity(true);
|
||||
this._authPrompt.setActorInDefaultButtonWell(this._sessionMenuButton.actor);
|
||||
this._authPrompt.setActorInDefaultButtonWell(this._sessionMenuButton);
|
||||
} else {
|
||||
this._sessionMenuButton.updateSensitivity(false);
|
||||
}
|
||||
@ -854,11 +871,11 @@ var LoginDialog = GObject.registerClass({
|
||||
}
|
||||
|
||||
_showPrompt() {
|
||||
if (this._authPrompt.actor.visible)
|
||||
if (this._authPrompt.visible)
|
||||
return;
|
||||
this._authPrompt.actor.opacity = 0;
|
||||
this._authPrompt.actor.show();
|
||||
this._authPrompt.actor.ease({
|
||||
this._authPrompt.opacity = 0;
|
||||
this._authPrompt.show();
|
||||
this._authPrompt.ease({
|
||||
opacity: 255,
|
||||
duration: _FADE_ANIMATION_TIME,
|
||||
mode: Clutter.AnimationMode.EASE_OUT_QUAD
|
||||
@ -1045,12 +1062,12 @@ var LoginDialog = GObject.registerClass({
|
||||
() => {
|
||||
// If idle timeout is done, make sure the timed login indicator is shown
|
||||
if (delay > _TIMED_LOGIN_IDLE_THRESHOLD &&
|
||||
this._authPrompt.actor.visible)
|
||||
this._authPrompt.visible)
|
||||
this._authPrompt.cancel();
|
||||
|
||||
if (delay > _TIMED_LOGIN_IDLE_THRESHOLD || firstRun) {
|
||||
this._userList.scrollToItem(loginItem);
|
||||
loginItem.actor.grab_key_focus();
|
||||
loginItem.grab_key_focus();
|
||||
}
|
||||
},
|
||||
|
||||
@ -1111,7 +1128,7 @@ var LoginDialog = GObject.registerClass({
|
||||
this._sessionMenuButton.close();
|
||||
this._setUserListExpanded(true);
|
||||
this._notListedButton.show();
|
||||
this._userList.actor.grab_key_focus();
|
||||
this._userList.grab_key_focus();
|
||||
}
|
||||
|
||||
_beginVerificationForItem(item) {
|
||||
@ -1219,7 +1236,7 @@ var LoginDialog = GObject.registerClass({
|
||||
_("Login Window"),
|
||||
'dialog-password-symbolic',
|
||||
{ sortGroup: CtrlAltTab.SortGroup.MIDDLE });
|
||||
this._userList.actor.grab_key_focus();
|
||||
this._userList.grab_key_focus();
|
||||
this.show();
|
||||
this.opacity = 0;
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
|
||||
/* exported findUrls, spawn, spawnCommandLine, spawnApp, trySpawnCommandLine,
|
||||
formatTime, formatTimeSpan, createTimeLabel, insertSorted,
|
||||
makeCloseButton, ensureActorVisibleInScrollView */
|
||||
makeCloseButton, ensureActorVisibleInScrollView, wiggle */
|
||||
|
||||
const { Clutter, Gio, GLib, GObject, Shell, St } = imports.gi;
|
||||
const Gettext = imports.gettext;
|
||||
@ -429,3 +429,37 @@ function ensureActorVisibleInScrollView(scrollView, actor) {
|
||||
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,
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
@ -127,11 +127,11 @@ function *run() {
|
||||
for (let i = 0; i < 2; i++) {
|
||||
Scripting.scriptEvent('applicationsShowStart');
|
||||
// eslint-disable-next-line require-atomic-updates
|
||||
Main.overview._dash.showAppsButton.checked = true;
|
||||
Main.overview.dash.showAppsButton.checked = true;
|
||||
yield Scripting.waitLeisure();
|
||||
Scripting.scriptEvent('applicationsShowDone');
|
||||
// eslint-disable-next-line require-atomic-updates
|
||||
Main.overview._dash.showAppsButton.checked = false;
|
||||
Main.overview.dash.showAppsButton.checked = false;
|
||||
yield Scripting.waitLeisure();
|
||||
}
|
||||
}
|
||||
|
@ -127,7 +127,7 @@ function *run() {
|
||||
|
||||
Scripting.scriptEvent('applicationsShowStart');
|
||||
// eslint-disable-next-line require-atomic-updates
|
||||
Main.overview._dash.showAppsButton.checked = true;
|
||||
Main.overview.dash.showAppsButton.checked = true;
|
||||
|
||||
yield Scripting.waitLeisure();
|
||||
Scripting.scriptEvent('applicationsShowDone');
|
||||
|
@ -56,8 +56,8 @@ class AccessDialog extends ModalDialog.ModalDialog {
|
||||
|
||||
let check = new CheckBox.CheckBox();
|
||||
check.getLabelActor().text = name;
|
||||
check.actor.checked = selected == "true";
|
||||
content.insertBeforeBody(check.actor);
|
||||
check.checked = selected == "true";
|
||||
content.insertBeforeBody(check);
|
||||
|
||||
this._choices.set(id, check);
|
||||
}
|
||||
@ -99,7 +99,7 @@ class AccessDialog extends ModalDialog.ModalDialog {
|
||||
let results = {};
|
||||
if (response == DialogResponse.OK) {
|
||||
for (let [id, check] of this._choices) {
|
||||
let checked = check.actor.checked ? 'true' : 'false';
|
||||
let checked = check.checked ? 'true' : 'false';
|
||||
results[id] = new GLib.Variant('s', checked);
|
||||
}
|
||||
}
|
||||
|
@ -405,27 +405,26 @@ class AppSwitcherPopup extends SwitcherPopup.SwitcherPopup {
|
||||
}
|
||||
});
|
||||
|
||||
class CyclerHighlight {
|
||||
constructor() {
|
||||
var CyclerHighlight = GObject.registerClass(
|
||||
class CyclerHighlight extends St.Widget {
|
||||
_init() {
|
||||
super._init({ layout_manager: new Clutter.BinLayout() });
|
||||
this._window = null;
|
||||
|
||||
this.actor = new St.Widget({ layout_manager: new Clutter.BinLayout() });
|
||||
|
||||
this._clone = new Clutter.Clone();
|
||||
this.actor.add_actor(this._clone);
|
||||
this.add_actor(this._clone);
|
||||
|
||||
this._highlight = new St.Widget({ style_class: 'cycler-highlight' });
|
||||
this.actor.add_actor(this._highlight);
|
||||
this.add_actor(this._highlight);
|
||||
|
||||
let coordinate = Clutter.BindCoordinate.ALL;
|
||||
let constraint = new Clutter.BindConstraint({ coordinate: coordinate });
|
||||
this._clone.bind_property('source', constraint, 'source', 0);
|
||||
|
||||
this.actor.add_constraint(constraint);
|
||||
this.add_constraint(constraint);
|
||||
|
||||
this.actor.connect('notify::allocation',
|
||||
this._onAllocationChanged.bind(this));
|
||||
this.actor.connect('destroy', this._onDestroy.bind(this));
|
||||
this.connect('notify::allocation', this._onAllocationChanged.bind(this));
|
||||
this.connect('destroy', this._onDestroy.bind(this));
|
||||
}
|
||||
|
||||
set window(w) {
|
||||
@ -451,7 +450,7 @@ class CyclerHighlight {
|
||||
this._highlight.set_size(0, 0);
|
||||
this._highlight.hide();
|
||||
} else {
|
||||
let [x, y] = this.actor.allocation.get_origin();
|
||||
let [x, y] = this.allocation.get_origin();
|
||||
let rect = this._window.get_frame_rect();
|
||||
this._highlight.set_size(rect.width, rect.height);
|
||||
this._highlight.set_position(rect.x - x, rect.y - y);
|
||||
@ -462,7 +461,7 @@ class CyclerHighlight {
|
||||
_onDestroy() {
|
||||
this.window = null;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// We don't show an actual popup, so just provide what SwitcherPopup
|
||||
// expects instead of inheriting from SwitcherList
|
||||
@ -489,7 +488,7 @@ var CyclerPopup = GObject.registerClass({
|
||||
return;
|
||||
|
||||
this._highlight = new CyclerHighlight();
|
||||
global.window_group.add_actor(this._highlight.actor);
|
||||
global.window_group.add_actor(this._highlight);
|
||||
|
||||
this._switcherList = new CyclerList();
|
||||
this._switcherList.connect('item-highlighted', (list, index) => {
|
||||
@ -499,7 +498,7 @@ var CyclerPopup = GObject.registerClass({
|
||||
|
||||
_highlightItem(index, _justOutline) {
|
||||
this._highlight.window = this._items[index];
|
||||
global.window_group.set_child_above_sibling(this._highlight.actor, null);
|
||||
global.window_group.set_child_above_sibling(this._highlight, null);
|
||||
}
|
||||
|
||||
_finish() {
|
||||
@ -529,7 +528,7 @@ var CyclerPopup = GObject.registerClass({
|
||||
}
|
||||
|
||||
_onDestroy() {
|
||||
this._highlight.actor.destroy();
|
||||
this._highlight.destroy();
|
||||
|
||||
super._onDestroy();
|
||||
}
|
||||
|
@ -1,19 +1,18 @@
|
||||
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
|
||||
/* exported Animation, AnimatedIcon, Spinner */
|
||||
|
||||
const { Clutter, GLib, Gio, St } = imports.gi;
|
||||
const { Clutter, GLib, GObject, Gio, St } = imports.gi;
|
||||
|
||||
var ANIMATED_ICON_UPDATE_TIMEOUT = 16;
|
||||
var SPINNER_ANIMATION_TIME = 300;
|
||||
var SPINNER_ANIMATION_DELAY = 1000;
|
||||
|
||||
var Animation = class {
|
||||
constructor(file, width, height, speed) {
|
||||
this.actor = new St.Bin();
|
||||
this.actor.set_size(width, height);
|
||||
this.actor.connect('destroy', this._onDestroy.bind(this));
|
||||
this.actor.connect('notify::size', this._syncAnimationSize.bind(this));
|
||||
this.actor.connect('resource-scale-changed',
|
||||
var Animation = GObject.registerClass(
|
||||
class Animation extends St.Bin {
|
||||
_init(file, width, height, speed) {
|
||||
super._init({ width: width, height: height });
|
||||
this.connect('destroy', this._onDestroy.bind(this));
|
||||
this.connect('resource-scale-changed',
|
||||
this._loadFile.bind(this, file, width, height));
|
||||
|
||||
let themeContext = St.ThemeContext.get_for_stage(global.stage);
|
||||
@ -52,14 +51,14 @@ var Animation = class {
|
||||
}
|
||||
|
||||
_loadFile(file, width, height) {
|
||||
let [validResourceScale, resourceScale] = this.actor.get_resource_scale();
|
||||
let [validResourceScale, resourceScale] = this.get_resource_scale();
|
||||
let wasPlaying = this._isPlaying;
|
||||
|
||||
if (this._isPlaying)
|
||||
this.stop();
|
||||
|
||||
this._isLoaded = false;
|
||||
this.actor.destroy_all_children();
|
||||
this.destroy_all_children();
|
||||
|
||||
if (!validResourceScale) {
|
||||
if (wasPlaying)
|
||||
@ -72,7 +71,7 @@ var Animation = class {
|
||||
this._animations = textureCache.load_sliced_image(file, width, height,
|
||||
scaleFactor, resourceScale,
|
||||
this._animationsLoaded.bind(this));
|
||||
this.actor.set_child(this._animations);
|
||||
this.set_child(this._animations);
|
||||
|
||||
if (wasPlaying)
|
||||
this.play();
|
||||
@ -99,7 +98,7 @@ var Animation = class {
|
||||
if (!this._isLoaded)
|
||||
return;
|
||||
|
||||
let [width, height] = this.actor.get_size();
|
||||
let [width, height] = this.get_size();
|
||||
|
||||
for (let i = 0; i < this._animations.get_n_children(); ++i)
|
||||
this._animations.get_child_at_index(i).set_size(width, height);
|
||||
@ -122,20 +121,22 @@ var Animation = class {
|
||||
themeContext.disconnect(this._scaleChangedId);
|
||||
this._scaleChangedId = 0;
|
||||
}
|
||||
};
|
||||
});
|
||||
|
||||
var AnimatedIcon = class extends Animation {
|
||||
constructor(file, size) {
|
||||
super(file, size, size, ANIMATED_ICON_UPDATE_TIMEOUT);
|
||||
var AnimatedIcon = GObject.registerClass(
|
||||
class AnimatedIcon extends Animation {
|
||||
_init(file, size) {
|
||||
super._init(file, size, size, ANIMATED_ICON_UPDATE_TIMEOUT);
|
||||
}
|
||||
};
|
||||
});
|
||||
|
||||
var Spinner = class extends AnimatedIcon {
|
||||
constructor(size, animate = false) {
|
||||
var Spinner = GObject.registerClass(
|
||||
class Spinner extends AnimatedIcon {
|
||||
_init(size, animate = false) {
|
||||
let file = Gio.File.new_for_uri('resource:///org/gnome/shell/theme/process-working.svg');
|
||||
super(file, size);
|
||||
super._init(file, size);
|
||||
|
||||
this.actor.opacity = 0;
|
||||
this.opacity = 0;
|
||||
this._animate = animate;
|
||||
}
|
||||
|
||||
@ -145,35 +146,35 @@ var Spinner = class extends AnimatedIcon {
|
||||
}
|
||||
|
||||
play() {
|
||||
this.actor.remove_all_transitions();
|
||||
this.remove_all_transitions();
|
||||
|
||||
if (this._animate) {
|
||||
super.play();
|
||||
this.actor.ease({
|
||||
this.ease({
|
||||
opacity: 255,
|
||||
delay: SPINNER_ANIMATION_DELAY,
|
||||
duration: SPINNER_ANIMATION_TIME,
|
||||
mode: Clutter.AnimationMode.LINEAR
|
||||
});
|
||||
} else {
|
||||
this.actor.opacity = 255;
|
||||
this.opacity = 255;
|
||||
super.play();
|
||||
}
|
||||
}
|
||||
|
||||
stop() {
|
||||
this.actor.remove_all_transitions();
|
||||
this.remove_all_transitions();
|
||||
|
||||
if (this._animate) {
|
||||
this.actor.ease({
|
||||
this.ease({
|
||||
opacity: 0,
|
||||
duration: SPINNER_ANIMATION_TIME,
|
||||
mode: Clutter.AnimationMode.LINEAR,
|
||||
onComplete: () => super.stop()
|
||||
});
|
||||
} else {
|
||||
this.actor.opacity = 0;
|
||||
this.opacity = 0;
|
||||
super.stop();
|
||||
}
|
||||
}
|
||||
};
|
||||
});
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -55,6 +55,7 @@ const RENAMED_DESKTOP_IDS = {
|
||||
'org.gnome.taquin.desktop': 'org.gnome.Taquin.desktop',
|
||||
'org.gnome.Weather.Application.desktop': 'org.gnome.Weather.desktop',
|
||||
'polari.desktop': 'org.gnome.Polari.desktop',
|
||||
'shotwell.desktop': 'org.gnome.Shotwell.desktop',
|
||||
'tali.desktop': 'org.gnome.Tali.desktop',
|
||||
'totem.desktop': 'org.gnome.Totem.desktop',
|
||||
'evince.desktop': 'org.gnome.Evince.desktop',
|
||||
|
@ -1,4 +1,5 @@
|
||||
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
|
||||
/* exported SystemBackground */
|
||||
|
||||
// READ THIS FIRST
|
||||
// Background handling is a maze of objects, both objects in this file, and
|
||||
@ -93,7 +94,7 @@
|
||||
// MetaBackgroundImage MetaBackgroundImage
|
||||
// MetaBackgroundImage MetaBackgroundImage
|
||||
|
||||
const { Clutter, GDesktopEnums, Gio, GLib, GnomeDesktop, Meta } = imports.gi;
|
||||
const { Clutter, GDesktopEnums, Gio, GLib, GObject, GnomeDesktop, Meta } = imports.gi;
|
||||
const Signals = imports.signals;
|
||||
|
||||
const LoginManager = imports.misc.loginManager;
|
||||
@ -220,16 +221,17 @@ function getBackgroundCache() {
|
||||
return _backgroundCache;
|
||||
}
|
||||
|
||||
var Background = class Background {
|
||||
constructor(params) {
|
||||
var Background = GObject.registerClass({
|
||||
Signals: { 'loaded': {}, 'bg-changed': {} }
|
||||
}, class Background extends Meta.Background {
|
||||
_init(params) {
|
||||
params = Params.parse(params, { monitorIndex: 0,
|
||||
layoutManager: Main.layoutManager,
|
||||
settings: null,
|
||||
file: null,
|
||||
style: null });
|
||||
|
||||
this.background = new Meta.Background({ meta_display: global.display });
|
||||
this.background._delegate = this;
|
||||
super._init({ meta_display: global.display });
|
||||
|
||||
this._settings = params.settings;
|
||||
this._file = params.file;
|
||||
@ -262,8 +264,6 @@ var Background = class Background {
|
||||
}
|
||||
|
||||
destroy() {
|
||||
this.background = null;
|
||||
|
||||
this._cancellable.cancel();
|
||||
this._removeAnimationTimeout();
|
||||
|
||||
@ -300,9 +300,11 @@ var Background = class Background {
|
||||
|
||||
this._changedIdleId = GLib.idle_add(GLib.PRIORITY_DEFAULT, () => {
|
||||
this._changedIdleId = 0;
|
||||
this.emit('changed');
|
||||
this.emit('bg-changed');
|
||||
return GLib.SOURCE_REMOVE;
|
||||
});
|
||||
GLib.Source.set_name_by_id(this._changedIdleId,
|
||||
'[gnome-shell] Background._emitChangedSignal');
|
||||
}
|
||||
|
||||
updateResolution() {
|
||||
@ -328,7 +330,7 @@ var Background = class Background {
|
||||
this.emit('loaded');
|
||||
return GLib.SOURCE_REMOVE;
|
||||
});
|
||||
GLib.Source.set_name_by_id(id, '[gnome-shell] this.emit');
|
||||
GLib.Source.set_name_by_id(id, '[gnome-shell] Background._setLoaded Idle');
|
||||
}
|
||||
|
||||
_loadPattern() {
|
||||
@ -342,9 +344,9 @@ var Background = class Background {
|
||||
let shadingType = this._settings.get_enum(COLOR_SHADING_TYPE_KEY);
|
||||
|
||||
if (shadingType == GDesktopEnums.BackgroundShading.SOLID)
|
||||
this.background.set_color(color);
|
||||
this.set_color(color);
|
||||
else
|
||||
this.background.set_gradient(shadingType, color, secondColor);
|
||||
this.set_gradient(shadingType, color, secondColor);
|
||||
}
|
||||
|
||||
_watchFile(file) {
|
||||
@ -380,13 +382,13 @@ var Background = class Background {
|
||||
let finish = () => {
|
||||
this._setLoaded();
|
||||
if (files.length > 1) {
|
||||
this.background.set_blend(files[0], files[1],
|
||||
this._animation.transitionProgress,
|
||||
this._style);
|
||||
this.set_blend(files[0], files[1],
|
||||
this._animation.transitionProgress,
|
||||
this._style);
|
||||
} else if (files.length > 0) {
|
||||
this.background.set_file(files[0], this._style);
|
||||
this.set_file(files[0], this._style);
|
||||
} else {
|
||||
this.background.set_file(null, this._style);
|
||||
this.set_file(null, this._style);
|
||||
}
|
||||
this._queueUpdateAnimation();
|
||||
};
|
||||
@ -459,7 +461,7 @@ var Background = class Background {
|
||||
}
|
||||
|
||||
_loadImage(file) {
|
||||
this.background.set_file(file, this._style);
|
||||
this.set_file(file, this._style);
|
||||
this._watchFile(file);
|
||||
|
||||
let cache = Meta.BackgroundImageCache.get_default();
|
||||
@ -493,13 +495,14 @@ var Background = class Background {
|
||||
|
||||
this._loadFile(this._file);
|
||||
}
|
||||
};
|
||||
Signals.addSignalMethods(Background.prototype);
|
||||
});
|
||||
|
||||
let _systemBackground;
|
||||
|
||||
var SystemBackground = class SystemBackground {
|
||||
constructor() {
|
||||
var SystemBackground = GObject.registerClass({
|
||||
Signals: { 'loaded': {} }
|
||||
}, class SystemBackground extends Meta.BackgroundActor {
|
||||
_init() {
|
||||
let file = Gio.File.new_for_uri('resource:///org/gnome/shell/theme/noise-texture.png');
|
||||
|
||||
if (_systemBackground == null) {
|
||||
@ -508,9 +511,11 @@ var SystemBackground = class SystemBackground {
|
||||
_systemBackground.set_file(file, GDesktopEnums.BackgroundStyle.WALLPAPER);
|
||||
}
|
||||
|
||||
this.actor = new Meta.BackgroundActor({ meta_display: global.display,
|
||||
monitor: 0,
|
||||
background: _systemBackground });
|
||||
super._init({
|
||||
meta_display: global.display,
|
||||
monitor: 0,
|
||||
background: _systemBackground
|
||||
});
|
||||
|
||||
let cache = Meta.BackgroundImageCache.get_default();
|
||||
let image = cache.load(file);
|
||||
@ -529,8 +534,7 @@ var SystemBackground = class SystemBackground {
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
||||
Signals.addSignalMethods(SystemBackground.prototype);
|
||||
});
|
||||
|
||||
var BackgroundSource = class BackgroundSource {
|
||||
constructor(layoutManager, settingsSchema) {
|
||||
@ -566,7 +570,7 @@ var BackgroundSource = class BackgroundSource {
|
||||
|
||||
// We don't watch changes to settings here,
|
||||
// instead we rely on Background to watch those
|
||||
// and emit 'changed' at the right time
|
||||
// and emit 'bg-changed' at the right time
|
||||
|
||||
if (this._overrideImage != null) {
|
||||
file = Gio.File.new_for_path(this._overrideImage);
|
||||
@ -595,7 +599,7 @@ var BackgroundSource = class BackgroundSource {
|
||||
style: style
|
||||
});
|
||||
|
||||
background._changedId = background.connect('changed', () => {
|
||||
background._changedId = background.connect('bg-changed', () => {
|
||||
background.disconnect(background._changedId);
|
||||
background.destroy();
|
||||
delete this._backgrounds[monitorIndex];
|
||||
@ -732,7 +736,7 @@ var BackgroundManager = class BackgroundManager {
|
||||
|
||||
this._newBackgroundActor = newBackgroundActor;
|
||||
|
||||
let background = newBackgroundActor.background._delegate;
|
||||
let background = newBackgroundActor.background;
|
||||
|
||||
if (background.isLoaded) {
|
||||
this._swapBackgroundActor();
|
||||
@ -752,7 +756,7 @@ var BackgroundManager = class BackgroundManager {
|
||||
let backgroundActor = new Meta.BackgroundActor({
|
||||
meta_display: global.display,
|
||||
monitor: this._monitorIndex,
|
||||
background: background.background,
|
||||
background,
|
||||
vignette: this._vignette,
|
||||
vignette_sharpness: 0.5,
|
||||
brightness: 0.5,
|
||||
@ -766,7 +770,7 @@ var BackgroundManager = class BackgroundManager {
|
||||
backgroundActor.lower_bottom();
|
||||
}
|
||||
|
||||
let changeSignalId = background.connect('changed', () => {
|
||||
let changeSignalId = background.connect('bg-changed', () => {
|
||||
background.disconnect(changeSignalId);
|
||||
changeSignalId = null;
|
||||
this._updateBackgroundActor();
|
||||
|
@ -46,12 +46,18 @@ var BoxPointer = GObject.registerClass({
|
||||
this.add_actor(this._border);
|
||||
this.bin.raise(this._border);
|
||||
this._sourceAlignment = 0.5;
|
||||
this._capturedEventId = 0;
|
||||
this._muteInput();
|
||||
this._muteInput = true;
|
||||
|
||||
this.connect('destroy', this._onDestroy.bind(this));
|
||||
}
|
||||
|
||||
vfunc_captured_event() {
|
||||
if (this._muteInput)
|
||||
return Clutter.EVENT_STOP;
|
||||
|
||||
return Clutter.EVENT_PROPAGATE;
|
||||
}
|
||||
|
||||
_onDestroy() {
|
||||
if (this._sourceActorDestroyId) {
|
||||
this._sourceActor.disconnect(this._sourceActorDestroyId);
|
||||
@ -63,19 +69,6 @@ var BoxPointer = GObject.registerClass({
|
||||
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) {
|
||||
let themeNode = this.get_theme_node();
|
||||
let rise = themeNode.get_length('-arrow-rise');
|
||||
@ -112,7 +105,7 @@ var BoxPointer = GObject.registerClass({
|
||||
duration: animationTime,
|
||||
mode: Clutter.AnimationMode.LINEAR,
|
||||
onComplete: () => {
|
||||
this._unmuteInput();
|
||||
this._muteInput = false;
|
||||
if (onComplete)
|
||||
onComplete();
|
||||
}
|
||||
@ -147,7 +140,7 @@ var BoxPointer = GObject.registerClass({
|
||||
}
|
||||
}
|
||||
|
||||
this._muteInput();
|
||||
this._muteInput = true;
|
||||
|
||||
this.remove_all_transitions();
|
||||
this.ease({
|
||||
|
@ -313,8 +313,10 @@ var DBusEventSource = class DBusEventSource {
|
||||
};
|
||||
Signals.addSignalMethods(DBusEventSource.prototype);
|
||||
|
||||
var Calendar = class Calendar {
|
||||
constructor() {
|
||||
var Calendar = GObject.registerClass({
|
||||
Signals: { 'selected-date-changed': { param_types: [GLib.DateTime.$gtype] } }
|
||||
}, class Calendar extends St.Widget {
|
||||
_init() {
|
||||
this._weekStart = Shell.util_get_week_start();
|
||||
this._settings = new Gio.Settings({ schema_id: 'org.gnome.desktop.calendar' });
|
||||
|
||||
@ -344,12 +346,11 @@ var Calendar = class Calendar {
|
||||
|
||||
this._shouldDateGrabFocus = false;
|
||||
|
||||
this.actor = new St.Widget({ style_class: 'calendar',
|
||||
layout_manager: new Clutter.TableLayout(),
|
||||
reactive: true });
|
||||
|
||||
this.actor.connect('scroll-event',
|
||||
this._onScroll.bind(this));
|
||||
super._init({
|
||||
style_class: 'calendar',
|
||||
layout_manager: new Clutter.TableLayout(),
|
||||
reactive: true
|
||||
});
|
||||
|
||||
this._buildHeader ();
|
||||
}
|
||||
@ -373,7 +374,10 @@ var Calendar = class Calendar {
|
||||
|
||||
this._selectedDate = date;
|
||||
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() {
|
||||
@ -384,9 +388,9 @@ var Calendar = class Calendar {
|
||||
}
|
||||
|
||||
_buildHeader() {
|
||||
let layout = this.actor.layout_manager;
|
||||
let layout = this.layout_manager;
|
||||
let offsetCols = this._useWeekdate ? 1 : 0;
|
||||
this.actor.destroy_all_children();
|
||||
this.destroy_all_children();
|
||||
|
||||
// Top line of the calendar '<| September 2009 |>'
|
||||
this._topBox = new St.BoxLayout();
|
||||
@ -428,7 +432,7 @@ var Calendar = class Calendar {
|
||||
can_focus: true });
|
||||
label.accessible_name = iter.toLocaleFormat('%A');
|
||||
let col;
|
||||
if (this.actor.get_text_direction() == Clutter.TextDirection.RTL)
|
||||
if (this.get_text_direction() == Clutter.TextDirection.RTL)
|
||||
col = 6 - (7 + iter.getDay() - this._weekStart) % 7;
|
||||
else
|
||||
col = offsetCols + (7 + iter.getDay() - this._weekStart) % 7;
|
||||
@ -437,11 +441,11 @@ var Calendar = class Calendar {
|
||||
}
|
||||
|
||||
// All the children after this are days, and get removed when we update the calendar
|
||||
this._firstDayIndex = this.actor.get_n_children();
|
||||
this._firstDayIndex = this.get_n_children();
|
||||
}
|
||||
|
||||
_onScroll(actor, event) {
|
||||
switch (event.get_scroll_direction()) {
|
||||
vfunc_scroll_event(scrollEvent) {
|
||||
switch (scrollEvent.direction) {
|
||||
case Clutter.ScrollDirection.UP:
|
||||
case Clutter.ScrollDirection.LEFT:
|
||||
this._onPrevMonthButtonClicked();
|
||||
@ -511,7 +515,7 @@ var Calendar = class Calendar {
|
||||
let now = new Date();
|
||||
|
||||
// Remove everything but the topBox and the weekday labels
|
||||
let children = this.actor.get_children();
|
||||
let children = this.get_children();
|
||||
for (let i = this._firstDayIndex; i < children.length; i++)
|
||||
children[i].destroy();
|
||||
|
||||
@ -548,7 +552,7 @@ var Calendar = class Calendar {
|
||||
|
||||
beginDate.setTime(beginDate.getTime() - (weekPadding + daysToWeekStart) * MSECS_IN_DAY);
|
||||
|
||||
let layout = this.actor.layout_manager;
|
||||
let layout = this.layout_manager;
|
||||
let iter = new Date(beginDate);
|
||||
let row = 2;
|
||||
// nRows here means 6 weeks + one header + one navbar
|
||||
@ -648,12 +652,12 @@ var Calendar = class Calendar {
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
Signals.addSignalMethods(Calendar.prototype);
|
||||
});
|
||||
|
||||
var EventMessage = class EventMessage extends MessageList.Message {
|
||||
constructor(event, date) {
|
||||
super('', event.summary);
|
||||
var EventMessage = GObject.registerClass(
|
||||
class EventMessage extends MessageList.Message {
|
||||
_init(event, date) {
|
||||
super._init('', event.summary);
|
||||
|
||||
this._event = event;
|
||||
this._date = date;
|
||||
@ -662,11 +666,12 @@ var EventMessage = class EventMessage extends MessageList.Message {
|
||||
|
||||
this._icon = new St.Icon({ icon_name: 'x-office-calendar-symbolic' });
|
||||
this.setIcon(this._icon);
|
||||
}
|
||||
|
||||
this.actor.connect('style-changed', () => {
|
||||
let iconVisible = this.actor.get_parent().has_style_pseudo_class('first-child');
|
||||
this._icon.opacity = (iconVisible ? 255 : 0);
|
||||
});
|
||||
vfunc_style_changed() {
|
||||
let iconVisible = this.get_parent().has_style_pseudo_class('first-child');
|
||||
this._icon.opacity = (iconVisible ? 255 : 0);
|
||||
super.vfunc_style_changed();
|
||||
}
|
||||
|
||||
_formatEventTime() {
|
||||
@ -702,12 +707,12 @@ var EventMessage = class EventMessage extends MessageList.Message {
|
||||
}
|
||||
return title;
|
||||
}
|
||||
};
|
||||
});
|
||||
|
||||
var NotificationMessage =
|
||||
var NotificationMessage = GObject.registerClass(
|
||||
class NotificationMessage extends MessageList.Message {
|
||||
constructor(notification) {
|
||||
super(notification.title, notification.bannerBodyText);
|
||||
_init(notification) {
|
||||
super._init(notification.title, notification.bannerBodyText);
|
||||
this.setUseBodyMarkup(notification.bannerBodyMarkup);
|
||||
|
||||
this.notification = notification;
|
||||
@ -744,7 +749,7 @@ class NotificationMessage extends MessageList.Message {
|
||||
this.setUseBodyMarkup(n.bannerBodyMarkup);
|
||||
}
|
||||
|
||||
_onClicked() {
|
||||
vfunc_clicked() {
|
||||
this.notification.activate();
|
||||
}
|
||||
|
||||
@ -766,11 +771,12 @@ class NotificationMessage extends MessageList.Message {
|
||||
canClose() {
|
||||
return true;
|
||||
}
|
||||
};
|
||||
});
|
||||
|
||||
var EventsSection = class EventsSection extends MessageList.MessageListSection {
|
||||
constructor() {
|
||||
super();
|
||||
var EventsSection = GObject.registerClass(
|
||||
class EventsSection extends MessageList.MessageListSection {
|
||||
_init() {
|
||||
super._init();
|
||||
|
||||
this._desktopSettings = new Gio.Settings({ schema_id: 'org.gnome.desktop.interface' });
|
||||
this._desktopSettings.connect('changed', this._reloadEvents.bind(this));
|
||||
@ -782,7 +788,7 @@ var EventsSection = class EventsSection extends MessageList.MessageListSection {
|
||||
label: '',
|
||||
x_align: St.Align.START,
|
||||
can_focus: true });
|
||||
this.actor.insert_child_below(this._title, null);
|
||||
this.insert_child_below(this._title, null);
|
||||
|
||||
this._title.connect('clicked', this._onTitleClicked.bind(this));
|
||||
this._title.connect('key-focus-in', this._onKeyFocusIn.bind(this));
|
||||
@ -901,12 +907,29 @@ var EventsSection = class EventsSection extends MessageList.MessageListSection {
|
||||
|
||||
super._sync();
|
||||
}
|
||||
};
|
||||
});
|
||||
|
||||
var NotificationSection =
|
||||
var TimeLabel = GObject.registerClass(
|
||||
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 {
|
||||
constructor() {
|
||||
super();
|
||||
_init() {
|
||||
super._init();
|
||||
|
||||
this._sources = new Map();
|
||||
this._nUrgent = 0;
|
||||
@ -915,8 +938,6 @@ class NotificationSection extends MessageList.MessageListSection {
|
||||
Main.messageTray.getSources().forEach(source => {
|
||||
this._sourceAdded(Main.messageTray, source);
|
||||
});
|
||||
|
||||
this.actor.connect('notify::mapped', this._onMapped.bind(this));
|
||||
}
|
||||
|
||||
get allowed() {
|
||||
@ -924,17 +945,6 @@ class NotificationSection extends MessageList.MessageListSection {
|
||||
!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) {
|
||||
let obj = {
|
||||
destroyId: 0,
|
||||
@ -952,13 +962,13 @@ class NotificationSection extends MessageList.MessageListSection {
|
||||
|
||||
_onNotificationAdded(source, notification) {
|
||||
let message = new NotificationMessage(notification);
|
||||
message.setSecondaryActor(this._createTimeLabel(notification.datetime));
|
||||
message.setSecondaryActor(new TimeLabel(notification.datetime));
|
||||
|
||||
let isUrgent = notification.urgency == MessageTray.Urgency.CRITICAL;
|
||||
|
||||
let updatedId = notification.connect('updated', () => {
|
||||
message.setSecondaryActor(this._createTimeLabel(notification.datetime));
|
||||
this.moveMessage(message, isUrgent ? 0 : this._nUrgent, this.actor.mapped);
|
||||
message.setSecondaryActor(new TimeLabel(notification.datetime));
|
||||
this.moveMessage(message, isUrgent ? 0 : this._nUrgent, this.mapped);
|
||||
});
|
||||
let destroyId = notification.connect('destroy', () => {
|
||||
notification.disconnect(destroyId);
|
||||
@ -978,7 +988,7 @@ class NotificationSection extends MessageList.MessageListSection {
|
||||
}
|
||||
|
||||
let index = isUrgent ? 0 : this._nUrgent;
|
||||
this.addMessageAtIndex(message, index, this.actor.mapped);
|
||||
this.addMessageAtIndex(message, index, this.mapped);
|
||||
}
|
||||
|
||||
_onSourceDestroy(source, obj) {
|
||||
@ -988,25 +998,23 @@ class NotificationSection extends MessageList.MessageListSection {
|
||||
this._sources.delete(source);
|
||||
}
|
||||
|
||||
_onMapped() {
|
||||
if (!this.actor.mapped)
|
||||
return;
|
||||
|
||||
for (let message of this._messages.keys())
|
||||
vfunc_map() {
|
||||
this._messages.forEach(message => {
|
||||
if (message.notification.urgency != MessageTray.Urgency.CRITICAL)
|
||||
message.notification.acknowledged = true;
|
||||
});
|
||||
super.vfunc_map();
|
||||
}
|
||||
|
||||
_shouldShow() {
|
||||
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();
|
||||
|
||||
let todayFile = Gio.File.new_for_uri('resource:///org/gnome/shell/theme/no-notifications.svg');
|
||||
@ -1015,10 +1023,10 @@ var Placeholder = class Placeholder {
|
||||
this._otherIcon = new Gio.FileIcon({ file: otherFile });
|
||||
|
||||
this._icon = new St.Icon();
|
||||
this.actor.add_actor(this._icon);
|
||||
this.add_actor(this._icon);
|
||||
|
||||
this._label = new St.Label();
|
||||
this.actor.add_actor(this._label);
|
||||
this.add_actor(this._label);
|
||||
|
||||
this._sync();
|
||||
}
|
||||
@ -1045,20 +1053,24 @@ var Placeholder = class Placeholder {
|
||||
this._label.text = _("No Events");
|
||||
}
|
||||
}
|
||||
};
|
||||
});
|
||||
|
||||
var CalendarMessageList = class CalendarMessageList {
|
||||
constructor() {
|
||||
this.actor = new St.Widget({ style_class: 'message-list',
|
||||
layout_manager: new Clutter.BinLayout(),
|
||||
x_expand: true, y_expand: true });
|
||||
var CalendarMessageList = GObject.registerClass(
|
||||
class CalendarMessageList extends St.Widget {
|
||||
_init() {
|
||||
super._init({
|
||||
style_class: 'message-list',
|
||||
layout_manager: new Clutter.BinLayout(),
|
||||
x_expand: true,
|
||||
y_expand: true
|
||||
});
|
||||
|
||||
this._placeholder = new Placeholder();
|
||||
this.actor.add_actor(this._placeholder.actor);
|
||||
this.add_actor(this._placeholder);
|
||||
|
||||
let box = new St.BoxLayout({ vertical: true,
|
||||
x_expand: true, y_expand: true });
|
||||
this.actor.add_actor(box);
|
||||
this.add_actor(box);
|
||||
|
||||
this._scrollView = new St.ScrollView({ style_class: 'vfade',
|
||||
overlay_scrollbars: true,
|
||||
@ -1072,12 +1084,11 @@ var CalendarMessageList = class CalendarMessageList {
|
||||
can_focus: true });
|
||||
this._clearButton.set_x_align(Clutter.ActorAlign.END);
|
||||
this._clearButton.connect('clicked', () => {
|
||||
let sections = [...this._sections.keys()];
|
||||
sections.forEach(s => s.clear());
|
||||
this._sectionList.get_children().forEach(s => s.clear());
|
||||
});
|
||||
box.add_actor(this._clearButton);
|
||||
|
||||
this._placeholder.actor.bind_property('visible',
|
||||
this._placeholder.bind_property('visible',
|
||||
this._clearButton, 'visible',
|
||||
GObject.BindingFlags.INVERT_BOOLEAN);
|
||||
|
||||
@ -1085,8 +1096,9 @@ var CalendarMessageList = class CalendarMessageList {
|
||||
vertical: true,
|
||||
y_expand: true,
|
||||
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._sections = new Map();
|
||||
|
||||
this._mediaSection = new Mpris.MediaSection();
|
||||
this._addSection(this._mediaSection);
|
||||
@ -1101,58 +1113,35 @@ var CalendarMessageList = class CalendarMessageList {
|
||||
}
|
||||
|
||||
_addSection(section) {
|
||||
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));
|
||||
let connectionsIds = [];
|
||||
|
||||
this._sections.set(section, obj);
|
||||
this._sectionList.add_actor(section.actor);
|
||||
this._sync();
|
||||
}
|
||||
for (let prop of ['visible', 'empty', 'can-clear']) {
|
||||
connectionsIds.push(
|
||||
section.connect(`notify::${prop}`, this._sync.bind(this)));
|
||||
}
|
||||
connectionsIds.push(section.connect('message-focused', (_s, messageActor) => {
|
||||
Util.ensureActorVisibleInScrollView(this._scrollView, messageActor);
|
||||
}));
|
||||
|
||||
_removeSection(section) {
|
||||
let obj = this._sections.get(section);
|
||||
section.actor.disconnect(obj.destroyId);
|
||||
section.actor.disconnect(obj.visibleId);
|
||||
section.disconnect(obj.emptyChangedId);
|
||||
section.disconnect(obj.canClearChangedId);
|
||||
section.disconnect(obj.keyFocusId);
|
||||
connectionsIds.push(section.connect('destroy', (section) => {
|
||||
connectionsIds.forEach(id => section.disconnect(id));
|
||||
this._sectionList.remove_actor(section);
|
||||
}));
|
||||
|
||||
this._sections.delete(section);
|
||||
this._sectionList.remove_actor(section.actor);
|
||||
this._sync();
|
||||
}
|
||||
|
||||
_onKeyFocusIn(section, actor) {
|
||||
Util.ensureActorVisibleInScrollView(this._scrollView, actor);
|
||||
this._sectionList.add_actor(section);
|
||||
}
|
||||
|
||||
_sync() {
|
||||
let sections = [...this._sections.keys()];
|
||||
let sections = this._sectionList.get_children();
|
||||
let visible = sections.some(s => s.allowed);
|
||||
this.actor.visible = visible;
|
||||
this.visible = visible;
|
||||
if (!visible)
|
||||
return;
|
||||
|
||||
let empty = sections.every(s => s.empty || !s.actor.visible);
|
||||
this._placeholder.actor.visible = empty;
|
||||
let empty = sections.every(s => s.empty || !s.visible);
|
||||
this._placeholder.visible = empty;
|
||||
|
||||
let canClear = sections.some(s => s.canClear && s.actor.visible);
|
||||
let canClear = sections.some(s => s.canClear && s.visible);
|
||||
this._clearButton.reactive = canClear;
|
||||
}
|
||||
|
||||
@ -1161,8 +1150,7 @@ var CalendarMessageList = class CalendarMessageList {
|
||||
}
|
||||
|
||||
setDate(date) {
|
||||
for (let section of this._sections.keys())
|
||||
section.setDate(date);
|
||||
this._sectionList.get_children().forEach(s => s.setDate(date));
|
||||
this._placeholder.setDate(date);
|
||||
}
|
||||
};
|
||||
});
|
||||
|
@ -1,16 +1,19 @@
|
||||
/* exported CheckBox */
|
||||
const { Clutter, Pango, St } = imports.gi;
|
||||
const { Clutter, GObject, Pango, St } = imports.gi;
|
||||
|
||||
var CheckBox = class CheckBox {
|
||||
constructor(label) {
|
||||
var CheckBox = GObject.registerClass(
|
||||
class CheckBox extends St.Button {
|
||||
_init(label) {
|
||||
let container = new St.BoxLayout();
|
||||
this.actor = new St.Button({ style_class: 'check-box',
|
||||
child: container,
|
||||
button_mask: St.ButtonMask.ONE,
|
||||
toggle_mode: true,
|
||||
can_focus: true,
|
||||
x_fill: true,
|
||||
y_fill: true });
|
||||
super._init({
|
||||
style_class: 'check-box',
|
||||
child: container,
|
||||
button_mask: St.ButtonMask.ONE,
|
||||
toggle_mode: true,
|
||||
can_focus: true,
|
||||
x_fill: true,
|
||||
y_fill: true
|
||||
});
|
||||
|
||||
this._box = new St.Bin();
|
||||
this._box.set_y_align(Clutter.ActorAlign.START);
|
||||
@ -32,4 +35,4 @@ var CheckBox = class CheckBox {
|
||||
getLabelActor() {
|
||||
return this._label;
|
||||
}
|
||||
};
|
||||
});
|
||||
|
@ -1,7 +1,7 @@
|
||||
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
|
||||
/* exported Component */
|
||||
|
||||
const { Gio, St } = imports.gi;
|
||||
const { Gio, GObject, St } = imports.gi;
|
||||
|
||||
const GnomeSession = imports.misc.gnomeSession;
|
||||
const Main = imports.ui.main;
|
||||
@ -272,9 +272,10 @@ var AutorunDispatcher = class {
|
||||
}
|
||||
};
|
||||
|
||||
var AutorunSource = class extends MessageTray.Source {
|
||||
constructor(manager, mount, apps) {
|
||||
super(mount.get_name());
|
||||
var AutorunSource = GObject.registerClass(
|
||||
class AutorunSource extends MessageTray.Source {
|
||||
_init(manager, mount, apps) {
|
||||
super._init(mount.get_name());
|
||||
|
||||
this._manager = manager;
|
||||
this.mount = mount;
|
||||
@ -284,7 +285,7 @@ var AutorunSource = class extends MessageTray.Source {
|
||||
|
||||
// add ourselves as a source, and popup the notification
|
||||
Main.messageTray.add(this);
|
||||
this.notify(this._notification);
|
||||
this.showNotification(this._notification);
|
||||
}
|
||||
|
||||
getIcon() {
|
||||
@ -294,11 +295,12 @@ var AutorunSource = class extends MessageTray.Source {
|
||||
_createPolicy() {
|
||||
return new MessageTray.NotificationApplicationPolicy('org.gnome.Nautilus');
|
||||
}
|
||||
};
|
||||
});
|
||||
|
||||
var AutorunNotification = class extends MessageTray.Notification {
|
||||
constructor(manager, source) {
|
||||
super(source, source.title);
|
||||
var AutorunNotification = GObject.registerClass(
|
||||
class AutorunNotification extends MessageTray.Notification {
|
||||
_init(manager, source) {
|
||||
super._init(source, source.title);
|
||||
|
||||
this._manager = manager;
|
||||
this._mount = source.mount;
|
||||
@ -350,6 +352,6 @@ var AutorunNotification = class extends MessageTray.Notification {
|
||||
let app = Gio.app_info_get_default_for_type('inode/directory', false);
|
||||
startAppForMount(app, this._mount);
|
||||
}
|
||||
};
|
||||
});
|
||||
|
||||
var Component = AutorunManager;
|
||||
|
@ -77,13 +77,13 @@ class KeyringDialog extends ModalDialog.ModalDialog {
|
||||
this._workSpinner = new Animation.Spinner(WORK_SPINNER_ICON_SIZE, true);
|
||||
|
||||
if (rtl) {
|
||||
layout.attach(this._workSpinner.actor, 0, row, 1, 1);
|
||||
layout.attach(this._workSpinner, 0, row, 1, 1);
|
||||
layout.attach(this._passwordEntry, 1, row, 1, 1);
|
||||
layout.attach(label, 2, row, 1, 1);
|
||||
} else {
|
||||
layout.attach(label, 0, row, 1, 1);
|
||||
layout.attach(this._passwordEntry, 1, row, 1, 1);
|
||||
layout.attach(this._workSpinner.actor, 2, row, 1, 1);
|
||||
layout.attach(this._workSpinner, 2, row, 1, 1);
|
||||
}
|
||||
row++;
|
||||
} else {
|
||||
@ -121,8 +121,8 @@ class KeyringDialog extends ModalDialog.ModalDialog {
|
||||
if (this.prompt.choice_visible) {
|
||||
let choice = new CheckBox.CheckBox();
|
||||
this.prompt.bind_property('choice-label', choice.getLabelActor(), 'text', GObject.BindingFlags.SYNC_CREATE);
|
||||
this.prompt.bind_property('choice-chosen', choice.actor, 'checked', GObject.BindingFlags.SYNC_CREATE | GObject.BindingFlags.BIDIRECTIONAL);
|
||||
layout.attach(choice.actor, rtl ? 0 : 1, row, 1, 1);
|
||||
this.prompt.bind_property('choice-chosen', choice, 'checked', GObject.BindingFlags.SYNC_CREATE | GObject.BindingFlags.BIDIRECTIONAL);
|
||||
layout.attach(choice, rtl ? 0 : 1, row, 1, 1);
|
||||
row++;
|
||||
}
|
||||
|
||||
|
@ -734,7 +734,7 @@ var NetworkAgent = class {
|
||||
});
|
||||
|
||||
Main.messageTray.add(source);
|
||||
source.notify(notification);
|
||||
source.showNotification(notification);
|
||||
}
|
||||
|
||||
_newRequest(agent, requestId, connection, settingName, hints, flags) {
|
||||
|
@ -76,8 +76,8 @@ var AuthenticationDialog = GObject.registerClass({
|
||||
this._userAvatar = new UserWidget.Avatar(this._user,
|
||||
{ iconSize: DIALOG_ICON_SIZE,
|
||||
styleClass: 'polkit-dialog-user-icon' });
|
||||
this._userAvatar.actor.hide();
|
||||
userBox.add(this._userAvatar.actor,
|
||||
this._userAvatar.hide();
|
||||
userBox.add(this._userAvatar,
|
||||
{ x_fill: true,
|
||||
y_fill: false,
|
||||
x_align: St.Align.END,
|
||||
@ -106,7 +106,7 @@ var AuthenticationDialog = GObject.registerClass({
|
||||
{ expand: true });
|
||||
|
||||
this._workSpinner = new Animation.Spinner(WORK_SPINNER_ICON_SIZE, true);
|
||||
this._passwordBox.add(this._workSpinner.actor);
|
||||
this._passwordBox.add(this._workSpinner);
|
||||
|
||||
this.setInitialKeyFocus(this._passwordEntry);
|
||||
this._passwordBox.hide();
|
||||
@ -305,7 +305,7 @@ var AuthenticationDialog = GObject.registerClass({
|
||||
_onUserChanged() {
|
||||
if (this._user.is_loaded && this._userAvatar) {
|
||||
this._userAvatar.update();
|
||||
this._userAvatar.actor.show();
|
||||
this._userAvatar.show();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -215,7 +215,7 @@ class TelepathyClient extends Tp.BaseClient {
|
||||
// We are already handling the channel, display the source
|
||||
let source = this._chatSources[channel.get_object_path()];
|
||||
if (source)
|
||||
source.notify();
|
||||
source.showNotification();
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -266,9 +266,10 @@ class TelepathyClient extends Tp.BaseClient {
|
||||
}
|
||||
}) : null;
|
||||
|
||||
var ChatSource = class extends MessageTray.Source {
|
||||
constructor(account, conn, channel, contact, client) {
|
||||
super(contact.get_alias());
|
||||
var ChatSource = HAVE_TP ? GObject.registerClass(
|
||||
class ChatSource extends MessageTray.Source {
|
||||
_init(account, conn, channel, contact, client) {
|
||||
super._init(contact.get_alias());
|
||||
|
||||
this._account = account;
|
||||
this._contact = contact;
|
||||
@ -326,7 +327,7 @@ var ChatSource = class extends MessageTray.Source {
|
||||
|
||||
// We ack messages when the user expands the new notification
|
||||
let id = this._banner.connect('expanded', this._ackMessages.bind(this));
|
||||
this._banner.actor.connect('destroy', () => {
|
||||
this._banner.connect('destroy', () => {
|
||||
this._banner.disconnect(id);
|
||||
this._banner = null;
|
||||
});
|
||||
@ -476,7 +477,7 @@ var ChatSource = class extends MessageTray.Source {
|
||||
this._notification.appendMessage(pendingMessages[i], true);
|
||||
|
||||
if (pendingMessages.length > 0)
|
||||
this.notify();
|
||||
this.showNotification();
|
||||
}
|
||||
|
||||
destroy(reason) {
|
||||
@ -553,7 +554,7 @@ var ChatSource = class extends MessageTray.Source {
|
||||
|
||||
_notifyTimeout() {
|
||||
if (this._pendingMessages.length != 0)
|
||||
this.notify();
|
||||
this.showNotification();
|
||||
|
||||
this._notifyTimeoutId = 0;
|
||||
|
||||
@ -568,8 +569,8 @@ var ChatSource = class extends MessageTray.Source {
|
||||
this._notification.appendMessage(message);
|
||||
}
|
||||
|
||||
notify() {
|
||||
super.notify(this._notification);
|
||||
showNotification() {
|
||||
super.showNotification(this._notification);
|
||||
}
|
||||
|
||||
respond(text) {
|
||||
@ -625,12 +626,18 @@ var ChatSource = class extends MessageTray.Source {
|
||||
// 'pending-message-removed' for each one.
|
||||
this._channel.ack_all_pending_messages_async(null);
|
||||
}
|
||||
};
|
||||
}) : null;
|
||||
|
||||
var ChatNotification = class extends MessageTray.Notification {
|
||||
constructor(source) {
|
||||
super(source, source.title, null,
|
||||
{ secondaryGIcon: source.getSecondaryIcon() });
|
||||
var ChatNotification = HAVE_TP ? GObject.registerClass({
|
||||
Signals: {
|
||||
'message-removed': { param_types: [Tp.Message.$gtype] },
|
||||
'message-added': { param_types: [Tp.Message.$gtype] },
|
||||
'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.setResident(true);
|
||||
|
||||
@ -782,7 +789,7 @@ var ChatNotification = class extends MessageTray.Notification {
|
||||
|
||||
this._filterMessages();
|
||||
}
|
||||
};
|
||||
}) : null;
|
||||
|
||||
var ChatLineBox = GObject.registerClass(
|
||||
class ChatLineBox extends St.BoxLayout {
|
||||
@ -792,9 +799,10 @@ class ChatLineBox extends St.BoxLayout {
|
||||
}
|
||||
});
|
||||
|
||||
var ChatNotificationBanner = class extends MessageTray.NotificationBanner {
|
||||
constructor(notification) {
|
||||
super(notification);
|
||||
var ChatNotificationBanner = GObject.registerClass(
|
||||
class ChatNotificationBanner extends MessageTray.NotificationBanner {
|
||||
_init(notification) {
|
||||
super._init(notification);
|
||||
|
||||
this._responseEntry = new St.Entry({ style_class: 'chat-response',
|
||||
x_expand: true,
|
||||
@ -879,8 +887,7 @@ var ChatNotificationBanner = class extends MessageTray.NotificationBanner {
|
||||
}
|
||||
|
||||
_addMessage(message) {
|
||||
let highlighter = new MessageList.URLHighlighter(message.body, true, true);
|
||||
let body = highlighter.actor;
|
||||
let body = new MessageList.URLHighlighter(message.body, true, true);
|
||||
|
||||
let styles = message.styles;
|
||||
for (let i = 0; i < styles.length; i++)
|
||||
@ -968,6 +975,6 @@ var ChatNotificationBanner = class extends MessageTray.NotificationBanner {
|
||||
this.notification.source.setChatState(Tp.ChannelChatState.ACTIVE);
|
||||
}
|
||||
}
|
||||
};
|
||||
});
|
||||
|
||||
var Component = TelepathyComponent;
|
||||
|
@ -1,8 +1,8 @@
|
||||
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
|
||||
/* exported Dash */
|
||||
|
||||
const { Clutter, GLib, GObject, Meta, Shell, St } = imports.gi;
|
||||
const Signals = imports.signals;
|
||||
const { Clutter, GLib, GObject,
|
||||
Graphene, Meta, Shell, St } = imports.gi;
|
||||
|
||||
const AppDisplay = imports.ui.appDisplay;
|
||||
const AppFavorites = imports.ui.appFavorites;
|
||||
@ -23,9 +23,10 @@ function getAppFromSource(source) {
|
||||
}
|
||||
}
|
||||
|
||||
var DashIcon = class DashIcon extends AppDisplay.AppIcon {
|
||||
constructor(app) {
|
||||
super(app, {
|
||||
var DashIcon = GObject.registerClass(
|
||||
class DashIcon extends AppDisplay.AppIcon {
|
||||
_init(app) {
|
||||
super._init(app, {
|
||||
setSizeManually: true,
|
||||
showLabel: false
|
||||
});
|
||||
@ -45,7 +46,7 @@ var DashIcon = class DashIcon extends AppDisplay.AppIcon {
|
||||
acceptDrop() {
|
||||
return false;
|
||||
}
|
||||
};
|
||||
});
|
||||
|
||||
// A container like StBin, but taking the child's scale into account
|
||||
// when requesting a size
|
||||
@ -53,7 +54,7 @@ var DashItemContainer = GObject.registerClass(
|
||||
class DashItemContainer extends St.Widget {
|
||||
_init() {
|
||||
super._init({ style_class: 'dash-item-container',
|
||||
pivot_point: new Clutter.Point({ x: .5, y: .5 }),
|
||||
pivot_point: new Graphene.Point({ x: .5, y: .5 }),
|
||||
scale_x: 0,
|
||||
scale_y: 0,
|
||||
opacity: 0,
|
||||
@ -330,8 +331,10 @@ class DashActor extends St.Widget {
|
||||
|
||||
const baseIconSizes = [16, 22, 24, 32, 48, 64];
|
||||
|
||||
var Dash = class Dash {
|
||||
constructor() {
|
||||
var Dash = GObject.registerClass({
|
||||
Signals: { 'icon-size-changed': {} }
|
||||
}, class Dash extends St.Bin {
|
||||
_init() {
|
||||
this._maxHeight = -1;
|
||||
this.iconSize = 64;
|
||||
this._shownInitially = false;
|
||||
@ -359,11 +362,11 @@ var Dash = class Dash {
|
||||
|
||||
this._container.add_actor(this._showAppsIcon);
|
||||
|
||||
this.actor = new St.Bin({ child: this._container });
|
||||
this.actor.connect('notify::height', () => {
|
||||
if (this._maxHeight != this.actor.height)
|
||||
super._init({ child: this._container });
|
||||
this.connect('notify::height', () => {
|
||||
if (this._maxHeight != this.height)
|
||||
this._queueRedisplay();
|
||||
this._maxHeight = this.actor.height;
|
||||
this._maxHeight = this.height;
|
||||
});
|
||||
|
||||
this._workId = Main.initializeDeferredWork(this._box, this._redisplay.bind(this));
|
||||
@ -386,7 +389,7 @@ var Dash = class Dash {
|
||||
|
||||
// Translators: this is the name of the dock/favorites area on
|
||||
// the left of the overview
|
||||
Main.ctrlAltTabManager.addGroup(this.actor, _("Dash"), 'user-bookmarks-symbolic');
|
||||
Main.ctrlAltTabManager.addGroup(this, _("Dash"), 'user-bookmarks-symbolic');
|
||||
}
|
||||
|
||||
_onDragBegin() {
|
||||
@ -481,11 +484,11 @@ var Dash = class Dash {
|
||||
});
|
||||
|
||||
let item = new DashItemContainer();
|
||||
item.setChild(appIcon.actor);
|
||||
item.setChild(appIcon);
|
||||
|
||||
// Override default AppIcon label_actor, now the
|
||||
// accessible_name is set at DashItemContainer.setLabelText
|
||||
appIcon.actor.label_actor = null;
|
||||
appIcon.label_actor = null;
|
||||
item.setLabelText(app.get_name());
|
||||
|
||||
appIcon.icon.setIconSize(this.iconSize);
|
||||
@ -902,5 +905,4 @@ var Dash = class Dash {
|
||||
|
||||
return true;
|
||||
}
|
||||
};
|
||||
Signals.addSignalMethods(Dash.prototype);
|
||||
});
|
||||
|
@ -25,24 +25,26 @@ function _isToday(date) {
|
||||
now.getDate() == date.getDate();
|
||||
}
|
||||
|
||||
var TodayButton = class TodayButton {
|
||||
constructor(calendar) {
|
||||
function _gDateTimeToDate(datetime) {
|
||||
return new Date(datetime.to_unix() * 1000 + datetime.get_microsecond() / 1000);
|
||||
}
|
||||
|
||||
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
|
||||
// on the current date can be confusing. So don't make the button reactive
|
||||
// until the selected date changes.
|
||||
this.actor = new St.Button({
|
||||
super._init({
|
||||
style_class: 'datemenu-today-button',
|
||||
x_align: St.Align.START,
|
||||
x_expand: true,
|
||||
can_focus: true,
|
||||
reactive: false,
|
||||
});
|
||||
this.actor.connect('clicked', () => {
|
||||
this._calendar.setDate(new Date(), false);
|
||||
reactive: false
|
||||
});
|
||||
|
||||
let hbox = new St.BoxLayout({ vertical: true });
|
||||
this.actor.add_actor(hbox);
|
||||
this.add_actor(hbox);
|
||||
|
||||
this._dayLabel = new St.Label({ style_class: 'day-label',
|
||||
x_align: Clutter.ActorAlign.START });
|
||||
@ -52,13 +54,17 @@ var TodayButton = class TodayButton {
|
||||
hbox.add_actor(this._dateLabel);
|
||||
|
||||
this._calendar = calendar;
|
||||
this._calendar.connect('selected-date-changed', (calendar, date) => {
|
||||
this._calendar.connect('selected-date-changed', (_calendar, datetime) => {
|
||||
// Make the button reactive only if the selected date is not the
|
||||
// current date.
|
||||
this.actor.reactive = !_isToday(date);
|
||||
this.reactive = !_isToday(_gDateTimeToDate(datetime));
|
||||
});
|
||||
}
|
||||
|
||||
vfunc_clicked() {
|
||||
this._calendar.setDate(new Date(), false);
|
||||
}
|
||||
|
||||
setDate(date) {
|
||||
this._dayLabel.set_text(date.toLocaleFormat('%A'));
|
||||
|
||||
@ -75,34 +81,29 @@ var TodayButton = class TodayButton {
|
||||
* date, e.g. "Tuesday February 17 2015".
|
||||
*/
|
||||
dateFormat = Shell.util_translate_time_string (N_("%A %B %e %Y"));
|
||||
this.actor.accessible_name = date.toLocaleFormat(dateFormat);
|
||||
this.accessible_name = date.toLocaleFormat(dateFormat);
|
||||
}
|
||||
};
|
||||
});
|
||||
|
||||
var WorldClocksSection = class WorldClocksSection {
|
||||
constructor() {
|
||||
var WorldClocksSection = GObject.registerClass(
|
||||
class WorldClocksSection extends St.Button {
|
||||
_init() {
|
||||
super._init({
|
||||
style_class: 'world-clocks-button',
|
||||
x_fill: true,
|
||||
can_focus: true
|
||||
});
|
||||
this._clock = new GnomeDesktop.WallClock();
|
||||
this._clockNotifyId = 0;
|
||||
|
||||
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 });
|
||||
this._grid = new St.Widget({ style_class: 'world-clocks-grid',
|
||||
layout_manager: layout });
|
||||
layout.hookup_style(this._grid);
|
||||
|
||||
this.actor.child = this._grid;
|
||||
this.child = this._grid;
|
||||
|
||||
this._clocksApp = null;
|
||||
this._clocksProxy = new ClocksProxy(
|
||||
@ -125,9 +126,17 @@ var WorldClocksSection = class WorldClocksSection {
|
||||
this._sync();
|
||||
}
|
||||
|
||||
vfunc_clicked() {
|
||||
if (this._clocksApp)
|
||||
this._clocksApp.activate();
|
||||
|
||||
Main.overview.hide();
|
||||
Main.panel.closeCalendar();
|
||||
}
|
||||
|
||||
_sync() {
|
||||
this._clocksApp = this._appSystem.lookup_app('org.gnome.clocks.desktop');
|
||||
this.actor.visible = this._clocksApp != null;
|
||||
this.visible = this._clocksApp != null;
|
||||
}
|
||||
|
||||
_clocksChanged() {
|
||||
@ -155,7 +164,7 @@ var WorldClocksSection = class WorldClocksSection {
|
||||
x_align: Clutter.ActorAlign.START,
|
||||
text: title });
|
||||
layout.attach(header, 0, 0, 2, 1);
|
||||
this.actor.label_actor = header;
|
||||
this.label_actor = header;
|
||||
|
||||
let localOffset = GLib.DateTime.new_now_local().get_utc_offset();
|
||||
|
||||
@ -236,30 +245,23 @@ var WorldClocksSection = class WorldClocksSection {
|
||||
this._settings.set_value('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.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',
|
||||
vertical: true });
|
||||
|
||||
this.actor.child = box;
|
||||
this.child = box;
|
||||
|
||||
let titleBox = new St.BoxLayout();
|
||||
titleBox.add_child(new St.Label({ style_class: 'weather-header',
|
||||
@ -282,6 +284,18 @@ var WeatherSection = class WeatherSection {
|
||||
this._sync();
|
||||
}
|
||||
|
||||
vfunc_map() {
|
||||
this._weatherClient.update();
|
||||
super.vfunc_map();
|
||||
}
|
||||
|
||||
vfunc_clicked() {
|
||||
this._weatherClient.activateApp();
|
||||
|
||||
Main.overview.hide();
|
||||
Main.panel.closeCalendar();
|
||||
}
|
||||
|
||||
_getInfos() {
|
||||
let info = this._weatherClient.info;
|
||||
let forecasts = info.get_forecast_list();
|
||||
@ -372,23 +386,27 @@ var WeatherSection = class WeatherSection {
|
||||
}
|
||||
|
||||
_sync() {
|
||||
this.actor.visible = this._weatherClient.available;
|
||||
this.visible = this._weatherClient.available;
|
||||
|
||||
if (!this.actor.visible)
|
||||
if (!this.visible)
|
||||
return;
|
||||
|
||||
this._titleLocation.visible = this._weatherClient.hasLocation;
|
||||
|
||||
this._updateForecasts();
|
||||
}
|
||||
};
|
||||
});
|
||||
|
||||
var MessagesIndicator = class MessagesIndicator {
|
||||
constructor() {
|
||||
this.actor = new St.Icon({ icon_name: 'message-indicator-symbolic',
|
||||
icon_size: 16,
|
||||
visible: false, y_expand: true,
|
||||
y_align: Clutter.ActorAlign.CENTER });
|
||||
var MessagesIndicator = GObject.registerClass(
|
||||
class MessagesIndicator extends St.Icon {
|
||||
_init() {
|
||||
super._init({
|
||||
icon_name: 'message-indicator-symbolic',
|
||||
icon_size: 16,
|
||||
visible: false,
|
||||
y_expand: true,
|
||||
y_align: Clutter.ActorAlign.CENTER
|
||||
});
|
||||
|
||||
this._sources = [];
|
||||
|
||||
@ -401,7 +419,7 @@ var MessagesIndicator = class MessagesIndicator {
|
||||
}
|
||||
|
||||
_onSourceAdded(tray, source) {
|
||||
source.connect('count-updated', this._updateCount.bind(this));
|
||||
source.connect('notify::count', this._updateCount.bind(this));
|
||||
this._sources.push(source);
|
||||
this._updateCount();
|
||||
}
|
||||
@ -416,9 +434,9 @@ var MessagesIndicator = class MessagesIndicator {
|
||||
this._sources.forEach(source => (count += source.unseenCount));
|
||||
count -= Main.messageTray.queueCount;
|
||||
|
||||
this.actor.visible = (count > 0);
|
||||
this.visible = (count > 0);
|
||||
}
|
||||
};
|
||||
});
|
||||
|
||||
var IndicatorPad = GObject.registerClass(
|
||||
class IndicatorPad extends St.Widget {
|
||||
@ -511,9 +529,9 @@ class DateMenuButton extends PanelMenu.Button {
|
||||
this._indicator = new MessagesIndicator();
|
||||
|
||||
let box = new St.BoxLayout();
|
||||
box.add_actor(new IndicatorPad(this._indicator.actor));
|
||||
box.add_actor(new IndicatorPad(this._indicator));
|
||||
box.add_actor(this._clockDisplay);
|
||||
box.add_actor(this._indicator.actor);
|
||||
box.add_actor(this._indicator);
|
||||
|
||||
this.label_actor = this._clockDisplay;
|
||||
this.add_actor(box);
|
||||
@ -529,11 +547,11 @@ class DateMenuButton extends PanelMenu.Button {
|
||||
bin.add_actor(hbox);
|
||||
|
||||
this._calendar = new Calendar.Calendar();
|
||||
this._calendar.connect('selected-date-changed',
|
||||
(calendar, date) => {
|
||||
layout.frozen = !_isToday(date);
|
||||
this._messageList.setDate(date);
|
||||
});
|
||||
this._calendar.connect('selected-date-changed', (_calendar, datetime) => {
|
||||
let date = _gDateTimeToDate(datetime);
|
||||
layout.frozen = !_isToday(date);
|
||||
this._messageList.setDate(date);
|
||||
});
|
||||
|
||||
this.menu.connect('open-state-changed', (menu, isOpen) => {
|
||||
// Whenever the menu is opened, select today
|
||||
@ -547,19 +565,19 @@ class DateMenuButton extends PanelMenu.Button {
|
||||
|
||||
// Fill up the first column
|
||||
this._messageList = new Calendar.CalendarMessageList();
|
||||
hbox.add(this._messageList.actor, { expand: true, y_fill: false, y_align: St.Align.START });
|
||||
hbox.add(this._messageList, { expand: true, y_fill: false, y_align: St.Align.START });
|
||||
|
||||
// Fill up the second column
|
||||
let boxLayout = new CalendarColumnLayout(this._calendar.actor);
|
||||
let boxLayout = new CalendarColumnLayout(this._calendar);
|
||||
vbox = new St.Widget({ style_class: 'datemenu-calendar-column',
|
||||
layout_manager: boxLayout });
|
||||
boxLayout.hookup_style(vbox);
|
||||
hbox.add(vbox);
|
||||
|
||||
this._date = new TodayButton(this._calendar);
|
||||
vbox.add_actor(this._date.actor);
|
||||
vbox.add_actor(this._date);
|
||||
|
||||
vbox.add_actor(this._calendar.actor);
|
||||
vbox.add_actor(this._calendar);
|
||||
|
||||
this._displaysSection = new St.ScrollView({ style_class: 'datemenu-displays-section vfade',
|
||||
x_expand: true, x_fill: true,
|
||||
@ -572,10 +590,10 @@ class DateMenuButton extends PanelMenu.Button {
|
||||
this._displaysSection.add_actor(displaysBox);
|
||||
|
||||
this._clocksItem = new WorldClocksSection();
|
||||
displaysBox.add(this._clocksItem.actor, { x_fill: true });
|
||||
displaysBox.add(this._clocksItem, { x_fill: true });
|
||||
|
||||
this._weatherItem = new WeatherSection();
|
||||
displaysBox.add(this._weatherItem.actor, { x_fill: true });
|
||||
displaysBox.add(this._weatherItem, { x_fill: true });
|
||||
|
||||
// Done with hbox for calendar and event list
|
||||
|
||||
|
14
js/ui/dnd.js
14
js/ui/dnd.js
@ -573,11 +573,15 @@ var _Draggable = class _Draggable {
|
||||
while (target) {
|
||||
if (target._delegate && target._delegate.acceptDrop) {
|
||||
let [r_, targX, targY] = target.transform_stage_point(dropX, dropY);
|
||||
if (target._delegate.acceptDrop(this.actor._delegate,
|
||||
this._dragActor,
|
||||
targX,
|
||||
targY,
|
||||
event.get_time())) {
|
||||
let accepted = false;
|
||||
try {
|
||||
accepted = target._delegate.acceptDrop(this.actor._delegate,
|
||||
this._dragActor, targX, targY, event.get_time());
|
||||
} catch (e) {
|
||||
// On error, skip this target
|
||||
logError(e, "Skipping drag target");
|
||||
}
|
||||
if (accepted) {
|
||||
// If it accepted the drop without taking the actor,
|
||||
// handle it ourselves.
|
||||
if (this._dragActor && this._dragActor.get_parent() == Main.uiGroup) {
|
||||
|
@ -207,10 +207,10 @@ function _setCheckBoxLabel(checkBox, text) {
|
||||
|
||||
if (text) {
|
||||
label.set_text(text);
|
||||
checkBox.actor.show();
|
||||
checkBox.show();
|
||||
} else {
|
||||
label.set_text('');
|
||||
checkBox.actor.hide();
|
||||
checkBox.hide();
|
||||
}
|
||||
}
|
||||
|
||||
@ -297,8 +297,8 @@ class EndSessionDialog extends ModalDialog.ModalDialog {
|
||||
y_align: St.Align.START });
|
||||
|
||||
this._checkBox = new CheckBox.CheckBox();
|
||||
this._checkBox.actor.connect('clicked', this._sync.bind(this));
|
||||
messageLayout.add(this._checkBox.actor);
|
||||
this._checkBox.connect('clicked', this._sync.bind(this));
|
||||
messageLayout.add(this._checkBox);
|
||||
|
||||
this._batteryWarning = new St.Label({ style_class: 'end-session-dialog-warning',
|
||||
text: _("Running on battery power: please plug in before installing updates.") });
|
||||
@ -376,12 +376,12 @@ class EndSessionDialog extends ModalDialog.ModalDialog {
|
||||
let subject = dialogContent.subject;
|
||||
|
||||
// Use different title when we are installing updates
|
||||
if (dialogContent.subjectWithUpdates && this._checkBox.actor.checked)
|
||||
if (dialogContent.subjectWithUpdates && this._checkBox.checked)
|
||||
subject = dialogContent.subjectWithUpdates;
|
||||
|
||||
if (dialogContent.showBatteryWarning) {
|
||||
// Warn when running on battery power
|
||||
if (this._powerProxy.OnBattery && this._checkBox.actor.checked)
|
||||
if (this._powerProxy.OnBattery && this._checkBox.checked)
|
||||
this._batteryWarning.opacity = 255;
|
||||
else
|
||||
this._batteryWarning.opacity = 0;
|
||||
@ -429,7 +429,7 @@ class EndSessionDialog extends ModalDialog.ModalDialog {
|
||||
let avatarWidget = new UserWidget.Avatar(this._user,
|
||||
{ iconSize: _DIALOG_ICON_SIZE,
|
||||
styleClass: dialogContent.iconStyleClass });
|
||||
this._iconBin.child = avatarWidget.actor;
|
||||
this._iconBin.child = avatarWidget;
|
||||
avatarWidget.update();
|
||||
}
|
||||
|
||||
@ -485,13 +485,13 @@ class EndSessionDialog extends ModalDialog.ModalDialog {
|
||||
};
|
||||
|
||||
// Offline update not available; just emit the signal
|
||||
if (!this._checkBox.actor.visible) {
|
||||
if (!this._checkBox.visible) {
|
||||
callback();
|
||||
return;
|
||||
}
|
||||
|
||||
// Trigger the offline update as requested
|
||||
if (this._checkBox.actor.checked) {
|
||||
if (this._checkBox.checked) {
|
||||
switch (signal) {
|
||||
case "ConfirmedReboot":
|
||||
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',
|
||||
can_focus: true });
|
||||
actor.add(avatar.actor);
|
||||
actor.add(avatar);
|
||||
|
||||
let nameLabel = new St.Label({ text: userLabelText,
|
||||
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;
|
||||
|
||||
_setCheckBoxLabel(this._checkBox, dialogContent.checkBoxText || '');
|
||||
this._checkBox.actor.visible = (dialogContent.checkBoxText && updatePrepared && updatesAllowed);
|
||||
this._checkBox.actor.checked = (updatePrepared && updateTriggered);
|
||||
this._checkBox.visible = (dialogContent.checkBoxText && updatePrepared && updatesAllowed);
|
||||
this._checkBox.checked = (updatePrepared && updateTriggered);
|
||||
|
||||
// We show the warning either together with the checkbox, or when
|
||||
// updates have already been triggered, but the user doesn't have
|
||||
// enough permissions to cancel them.
|
||||
this._batteryWarning.visible = (dialogContent.showBatteryWarning &&
|
||||
(this._checkBox.actor.visible || updatePrepared && updateTriggered && !updatesAllowed));
|
||||
(this._checkBox.visible || updatePrepared && updateTriggered && !updatesAllowed));
|
||||
|
||||
this._updateButtons();
|
||||
|
||||
|
@ -105,12 +105,20 @@ function _easeActor(actor, params) {
|
||||
actor.set_easing_delay(params.delay);
|
||||
delete params.delay;
|
||||
|
||||
let repeatCount = 0;
|
||||
if (params.repeatCount != undefined)
|
||||
repeatCount = params.repeatCount;
|
||||
delete params.repeatCount;
|
||||
|
||||
let autoReverse = false;
|
||||
if (params.autoReverse != undefined)
|
||||
autoReverse = params.autoReverse;
|
||||
delete params.autoReverse;
|
||||
|
||||
if (params.mode != undefined)
|
||||
actor.set_easing_mode(params.mode);
|
||||
delete params.mode;
|
||||
|
||||
Meta.disable_unredirect_for_display(global.display);
|
||||
|
||||
let cleanup = () => Meta.enable_unredirect_for_display(global.display);
|
||||
let callback = _makeEaseCallback(params, cleanup);
|
||||
|
||||
@ -124,10 +132,17 @@ function _easeActor(actor, params) {
|
||||
let transition = animatedProps.map(p => actor.get_transition(p))
|
||||
.find(t => t !== null);
|
||||
|
||||
if (transition)
|
||||
transition.connect('stopped', (t, finished) => callback(finished));
|
||||
if (transition && transition.delay)
|
||||
transition.connect('started', () => Meta.disable_unredirect_for_display(global.display));
|
||||
else
|
||||
Meta.disable_unredirect_for_display(global.display);
|
||||
|
||||
if (transition) {
|
||||
transition.set({ repeatCount, autoReverse });
|
||||
transition.connect('stopped', (t, finished) => callback(finished));
|
||||
} else {
|
||||
callback(true);
|
||||
}
|
||||
}
|
||||
|
||||
function _easeActorProperty(actor, propName, target, params) {
|
||||
@ -140,13 +155,21 @@ function _easeActorProperty(actor, propName, target, params) {
|
||||
params.duration = adjustAnimationTime(params.duration);
|
||||
let duration = Math.floor(params.duration || 0);
|
||||
|
||||
let repeatCount = 0;
|
||||
if (params.repeatCount != undefined)
|
||||
repeatCount = params.repeatCount;
|
||||
delete params.repeatCount;
|
||||
|
||||
let autoReverse = false;
|
||||
if (params.autoReverse != undefined)
|
||||
autoReverse = params.autoReverse;
|
||||
delete params.autoReverse;
|
||||
|
||||
// Copy Clutter's behavior for implicit animations, see
|
||||
// should_skip_implicit_transition()
|
||||
if (actor instanceof Clutter.Actor && !actor.mapped)
|
||||
duration = 0;
|
||||
|
||||
Meta.disable_unredirect_for_display(global.display);
|
||||
|
||||
let cleanup = () => Meta.enable_unredirect_for_display(global.display);
|
||||
let callback = _makeEaseCallback(params, cleanup);
|
||||
|
||||
@ -157,6 +180,7 @@ function _easeActorProperty(actor, propName, target, params) {
|
||||
let [obj, prop] = _getPropertyTarget(actor, propName);
|
||||
obj[prop] = target;
|
||||
|
||||
Meta.disable_unredirect_for_display(global.display);
|
||||
callback(true);
|
||||
|
||||
return;
|
||||
@ -166,12 +190,19 @@ function _easeActorProperty(actor, propName, target, params) {
|
||||
let transition = new Clutter.PropertyTransition(Object.assign({
|
||||
property_name: propName,
|
||||
interval: new Clutter.Interval({ value_type: pspec.value_type }),
|
||||
remove_on_complete: true
|
||||
remove_on_complete: true,
|
||||
repeat_count: repeatCount,
|
||||
auto_reverse: autoReverse,
|
||||
}, params));
|
||||
actor.add_transition(propName, transition);
|
||||
|
||||
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));
|
||||
}
|
||||
|
||||
|
@ -1,8 +1,7 @@
|
||||
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
|
||||
/* exported CandidatePopup */
|
||||
|
||||
const { Clutter, IBus, St } = imports.gi;
|
||||
const Signals = imports.signals;
|
||||
const { Clutter, GObject, IBus, St } = imports.gi;
|
||||
|
||||
const BoxPointer = imports.ui.boxpointer;
|
||||
const Main = imports.ui.main;
|
||||
@ -12,11 +11,23 @@ var MAX_CANDIDATES_PER_PAGE = 16;
|
||||
var DEFAULT_INDEX_LABELS = ['1', '2', '3', '4', '5', '6', '7', '8',
|
||||
'9', '0', 'a', 'b', 'c', 'd', 'e', 'f'];
|
||||
|
||||
var CandidateArea = class CandidateArea {
|
||||
constructor() {
|
||||
this.actor = new St.BoxLayout({ vertical: true,
|
||||
reactive: true,
|
||||
visible: false });
|
||||
var CandidateArea = GObject.registerClass({
|
||||
Signals: {
|
||||
'candidate-clicked': { param_types: [GObject.TYPE_UINT,
|
||||
GObject.TYPE_UINT,
|
||||
Clutter.ModifierType.$gtype] },
|
||||
'cursor-down': {},
|
||||
'cursor-up': {},
|
||||
'next-page': {},
|
||||
'previous-page': {},
|
||||
}
|
||||
}, class CandidateArea extends St.BoxLayout {
|
||||
_init() {
|
||||
super._init({
|
||||
vertical: true,
|
||||
reactive: true,
|
||||
visible: false
|
||||
});
|
||||
this._candidateBoxes = [];
|
||||
for (let i = 0; i < MAX_CANDIDATES_PER_PAGE; ++i) {
|
||||
let box = new St.BoxLayout({ style_class: 'candidate-box',
|
||||
@ -27,7 +38,7 @@ var CandidateArea = class CandidateArea {
|
||||
box.add(box._indexLabel, { y_fill: false });
|
||||
box.add(box._candidateLabel, { y_fill: false });
|
||||
this._candidateBoxes.push(box);
|
||||
this.actor.add(box);
|
||||
this.add(box);
|
||||
|
||||
let j = i;
|
||||
box.connect('button-release-event', (actor, event) => {
|
||||
@ -36,19 +47,6 @@ var CandidateArea = class CandidateArea {
|
||||
});
|
||||
}
|
||||
|
||||
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._previousButton = new St.Button({ style_class: 'candidate-page-button candidate-page-button-previous button' });
|
||||
@ -59,7 +57,7 @@ var CandidateArea = class CandidateArea {
|
||||
this._nextButton.child = new St.Icon({ style_class: 'candidate-page-button-icon' });
|
||||
this._buttonBox.add(this._nextButton, { expand: true });
|
||||
|
||||
this.actor.add(this._buttonBox);
|
||||
this.add(this._buttonBox);
|
||||
|
||||
this._previousButton.connect('clicked', () => {
|
||||
this.emit('previous-page');
|
||||
@ -72,6 +70,18 @@ var CandidateArea = class CandidateArea {
|
||||
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) {
|
||||
if (this._orientation == orientation)
|
||||
return;
|
||||
@ -79,15 +89,15 @@ var CandidateArea = class CandidateArea {
|
||||
this._orientation = orientation;
|
||||
|
||||
if (this._orientation == IBus.Orientation.HORIZONTAL) {
|
||||
this.actor.vertical = false;
|
||||
this.actor.remove_style_class_name('vertical');
|
||||
this.actor.add_style_class_name('horizontal');
|
||||
this.vertical = false;
|
||||
this.remove_style_class_name('vertical');
|
||||
this.add_style_class_name('horizontal');
|
||||
this._previousButton.child.icon_name = 'go-previous-symbolic';
|
||||
this._nextButton.child.icon_name = 'go-next-symbolic';
|
||||
} else { // VERTICAL || SYSTEM
|
||||
this.actor.vertical = true;
|
||||
this.actor.add_style_class_name('vertical');
|
||||
this.actor.remove_style_class_name('horizontal');
|
||||
this.vertical = true;
|
||||
this.add_style_class_name('vertical');
|
||||
this.remove_style_class_name('horizontal');
|
||||
this._previousButton.child.icon_name = 'go-up-symbolic';
|
||||
this._nextButton.child.icon_name = 'go-down-symbolic';
|
||||
}
|
||||
@ -121,22 +131,23 @@ var CandidateArea = class CandidateArea {
|
||||
this._previousButton.reactive = wrapsAround || page > 0;
|
||||
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 });
|
||||
Main.layoutManager.uiGroup.add_actor(this._dummyCursor);
|
||||
|
||||
this._boxPointer = new BoxPointer.BoxPointer(St.Side.TOP);
|
||||
this._boxPointer.visible = false;
|
||||
this._boxPointer.style_class = 'candidate-popup-boxpointer';
|
||||
Main.layoutManager.addChrome(this._boxPointer);
|
||||
Main.layoutManager.addChrome(this);
|
||||
|
||||
let box = new St.BoxLayout({ style_class: 'candidate-popup-content',
|
||||
vertical: true });
|
||||
this._boxPointer.bin.set_child(box);
|
||||
this.bin.set_child(box);
|
||||
|
||||
this._preeditText = new St.Label({ style_class: 'candidate-popup-text',
|
||||
visible: false });
|
||||
@ -147,7 +158,7 @@ var CandidatePopup = class CandidatePopup {
|
||||
box.add(this._auxText);
|
||||
|
||||
this._candidateArea = new CandidateArea();
|
||||
box.add(this._candidateArea.actor);
|
||||
box.add(this._candidateArea);
|
||||
|
||||
this._candidateArea.connect('previous-page', () => {
|
||||
this._panelService.page_up();
|
||||
@ -225,7 +236,7 @@ var CandidatePopup = class CandidatePopup {
|
||||
this._updateVisibility();
|
||||
});
|
||||
panelService.connect('update-lookup-table', (_ps, lookupTable, visible) => {
|
||||
this._candidateArea.actor.visible = visible;
|
||||
this._candidateArea.visible = visible;
|
||||
this._updateVisibility();
|
||||
|
||||
let nCandidates = lookupTable.get_number_of_candidates();
|
||||
@ -261,15 +272,15 @@ var CandidatePopup = class CandidatePopup {
|
||||
this._candidateArea.updateButtons(lookupTable.is_round(), page, nPages);
|
||||
});
|
||||
panelService.connect('show-lookup-table', () => {
|
||||
this._candidateArea.actor.show();
|
||||
this._candidateArea.show();
|
||||
this._updateVisibility();
|
||||
});
|
||||
panelService.connect('hide-lookup-table', () => {
|
||||
this._candidateArea.actor.hide();
|
||||
this._candidateArea.hide();
|
||||
this._updateVisibility();
|
||||
});
|
||||
panelService.connect('focus-out', () => {
|
||||
this._boxPointer.close(BoxPointer.PopupAnimation.NONE);
|
||||
this.close(BoxPointer.PopupAnimation.NONE);
|
||||
Main.keyboard.resetSuggestions();
|
||||
});
|
||||
}
|
||||
@ -278,22 +289,22 @@ var CandidatePopup = class CandidatePopup {
|
||||
this._dummyCursor.set_position(Math.round(x), Math.round(y));
|
||||
this._dummyCursor.set_size(Math.round(w), Math.round(h));
|
||||
|
||||
if (this._boxPointer.visible)
|
||||
this._boxPointer.setPosition(this._dummyCursor, 0);
|
||||
if (this.visible)
|
||||
this.setPosition(this._dummyCursor, 0);
|
||||
}
|
||||
|
||||
_updateVisibility() {
|
||||
let isVisible = (!Main.keyboard.visible &&
|
||||
(this._preeditText.visible ||
|
||||
this._auxText.visible ||
|
||||
this._candidateArea.actor.visible));
|
||||
this._candidateArea.visible));
|
||||
|
||||
if (isVisible) {
|
||||
this._boxPointer.setPosition(this._dummyCursor, 0);
|
||||
this._boxPointer.open(BoxPointer.PopupAnimation.NONE);
|
||||
this._boxPointer.raise_top();
|
||||
this.setPosition(this._dummyCursor, 0);
|
||||
this.open(BoxPointer.PopupAnimation.NONE);
|
||||
this.raise_top();
|
||||
} else {
|
||||
this._boxPointer.close(BoxPointer.PopupAnimation.NONE);
|
||||
this.close(BoxPointer.PopupAnimation.NONE);
|
||||
}
|
||||
}
|
||||
|
||||
@ -303,4 +314,4 @@ var CandidatePopup = class CandidatePopup {
|
||||
if (attr.get_attr_type() == IBus.AttrType.BACKGROUND)
|
||||
clutterText.set_selection(attr.get_start_index(), attr.get_end_index());
|
||||
}
|
||||
};
|
||||
});
|
||||
|
@ -1,7 +1,7 @@
|
||||
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
|
||||
/* exported BaseIcon, IconGrid, PaginatedIconGrid */
|
||||
|
||||
const { Clutter, GLib, GObject, Meta, St } = imports.gi;
|
||||
const { Clutter, GLib, GObject, Graphene, Meta, St } = imports.gi;
|
||||
|
||||
const Params = imports.misc.params;
|
||||
const Main = imports.ui.main;
|
||||
@ -231,18 +231,18 @@ var IconGrid = GObject.registerClass({
|
||||
this._fixedHItemSize = this._fixedVItemSize = undefined;
|
||||
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-removed', this._childRemoved.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() {
|
||||
if (this._updateIconSizesLaterId) {
|
||||
Meta.later_remove (this._updateIconSizesLaterId);
|
||||
@ -402,7 +402,7 @@ var IconGrid = GObject.registerClass({
|
||||
let allocationBox = this.get_allocation_box();
|
||||
let paintBox = themeNode.get_paint_box(allocationBox);
|
||||
|
||||
let origin = new Clutter.Vertex();
|
||||
let origin = new Graphene.Point3D();
|
||||
origin.x = paintBox.x1 - allocationBox.x1;
|
||||
origin.y = paintBox.y1 - allocationBox.y1;
|
||||
origin.z = 0.0;
|
||||
@ -717,13 +717,13 @@ var IconGrid = GObject.registerClass({
|
||||
|
||||
this._items.push(item);
|
||||
if (index !== undefined)
|
||||
this.insert_child_at_index(item.actor, index);
|
||||
this.insert_child_at_index(item, index);
|
||||
else
|
||||
this.add_actor(item.actor);
|
||||
this.add_actor(item);
|
||||
}
|
||||
|
||||
removeItem(item) {
|
||||
this.remove_child(item.actor);
|
||||
this.remove_child(item);
|
||||
}
|
||||
|
||||
getItemAtIndex(index) {
|
||||
@ -963,7 +963,7 @@ var PaginatedIconGrid = GObject.registerClass({
|
||||
*/
|
||||
openExtraSpace(sourceItem, side, nRows) {
|
||||
let children = this._getVisibleChildren();
|
||||
let index = children.indexOf(sourceItem.actor);
|
||||
let index = children.indexOf(sourceItem);
|
||||
if (index == -1)
|
||||
throw new Error('Item not found.');
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
|
||||
/* exported Keyboard */
|
||||
/* exported KeyboardManager */
|
||||
|
||||
const { Clutter, Gio, GLib, GObject, Meta, St } = imports.gi;
|
||||
const Signals = imports.signals;
|
||||
@ -89,8 +89,11 @@ class KeyContainer extends St.Widget {
|
||||
let gridLayout = new Clutter.GridLayout({ orientation: Clutter.Orientation.HORIZONTAL,
|
||||
column_homogeneous: true,
|
||||
row_homogeneous: true });
|
||||
super._init({ layout_manager: gridLayout,
|
||||
x_expand: true, y_expand: true });
|
||||
super._init({
|
||||
layout_manager: gridLayout,
|
||||
x_expand: true,
|
||||
y_expand: true
|
||||
});
|
||||
this._gridLayout = gridLayout;
|
||||
this._currentRow = 0;
|
||||
this._currentCol = 0;
|
||||
@ -161,24 +164,23 @@ class KeyContainer extends St.Widget {
|
||||
}
|
||||
});
|
||||
|
||||
var Suggestions = class {
|
||||
constructor() {
|
||||
this.actor = new St.BoxLayout({ style_class: 'word-suggestions',
|
||||
vertical: false });
|
||||
this.actor.show();
|
||||
var Suggestions = GObject.registerClass(
|
||||
class Suggestions extends St.BoxLayout {
|
||||
_init() {
|
||||
super._init({ style_class: 'word-suggestions', vertical: false });
|
||||
this.show();
|
||||
}
|
||||
|
||||
add(word, callback) {
|
||||
let button = new St.Button({ label: word });
|
||||
button.connect('clicked', callback);
|
||||
this.actor.add(button);
|
||||
this.add(button);
|
||||
}
|
||||
|
||||
clear() {
|
||||
this.actor.remove_all_children();
|
||||
this.remove_all_children();
|
||||
}
|
||||
};
|
||||
Signals.addSignalMethods(Suggestions.prototype);
|
||||
});
|
||||
|
||||
var LanguageSelectionPopup = class extends PopupMenu.PopupMenu {
|
||||
constructor(actor) {
|
||||
@ -243,17 +245,25 @@ var LanguageSelectionPopup = class extends PopupMenu.PopupMenu {
|
||||
}
|
||||
};
|
||||
|
||||
var Key = class Key {
|
||||
constructor(key, extendedKeys) {
|
||||
var Key = GObject.registerClass({
|
||||
Signals: {
|
||||
'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.keyButton = this._makeKey(this.key);
|
||||
|
||||
/* Add the key in a container, so keys can be padded without losing
|
||||
* logical proportions between those.
|
||||
*/
|
||||
this.actor = new St.BoxLayout ({ style_class: 'key-container' });
|
||||
this.actor.add(this.keyButton, { expand: true, x_fill: true });
|
||||
this.actor.connect('destroy', this._onDestroy.bind(this));
|
||||
this.add(this.keyButton, { expand: true, x_fill: true });
|
||||
this.connect('destroy', this._onDestroy.bind(this));
|
||||
|
||||
this._extended_keys = extendedKeys;
|
||||
this._extended_keyboard = null;
|
||||
@ -461,8 +471,7 @@ var Key = class Key {
|
||||
else
|
||||
this.keyButton.remove_style_pseudo_class('latched');
|
||||
}
|
||||
};
|
||||
Signals.addSignalMethods(Key.prototype);
|
||||
});
|
||||
|
||||
var KeyboardModel = class {
|
||||
constructor(groupName) {
|
||||
@ -590,7 +599,6 @@ var EmojiPager = GObject.registerClass({
|
||||
reactive: true,
|
||||
clip_to_allocation: true
|
||||
});
|
||||
|
||||
this._sections = sections;
|
||||
this._nCols = nCols;
|
||||
this._nRows = nRows;
|
||||
@ -801,7 +809,7 @@ var EmojiPager = GObject.registerClass({
|
||||
this.emit('emoji', str);
|
||||
});
|
||||
|
||||
gridLayout.attach(key.actor, col, row, 1, 1);
|
||||
gridLayout.attach(key, col, row, 1, 1);
|
||||
|
||||
col++;
|
||||
if (col >= this._nCols) {
|
||||
@ -843,7 +851,7 @@ var EmojiPager = GObject.registerClass({
|
||||
}
|
||||
|
||||
let page = this._pages[nPage];
|
||||
this.emit('page-changed', page.section, page.page, page.nPages);
|
||||
this.emit('page-changed', page.section.label, page.page, page.nPages);
|
||||
}
|
||||
|
||||
setCurrentSection(section, nPage) {
|
||||
@ -858,8 +866,21 @@ var EmojiPager = GObject.registerClass({
|
||||
}
|
||||
});
|
||||
|
||||
var EmojiSelection = class EmojiSelection {
|
||||
constructor() {
|
||||
var EmojiSelection = GObject.registerClass({
|
||||
Signals: {
|
||||
'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 = [
|
||||
{ first: 'grinning face', label: '🙂️' },
|
||||
{ first: 'selfie', label: '👍️' },
|
||||
@ -874,38 +895,44 @@ var EmojiSelection = class EmojiSelection {
|
||||
|
||||
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.connect('page-changed', (pager, section, page, nPages) => {
|
||||
this._onPageChanged(section, page, nPages);
|
||||
this._emojiPager.connect('page-changed', (pager, sectionLabel, page, nPages) => {
|
||||
this._onPageChanged(sectionLabel, page, nPages);
|
||||
});
|
||||
this._emojiPager.connect('emoji', (pager, str) => {
|
||||
this.emit('emoji-selected', str);
|
||||
});
|
||||
this.actor.add(this._emojiPager.actor, { expand: true });
|
||||
this.add(this._emojiPager, { expand: true });
|
||||
|
||||
this._pageIndicator = new PageIndicators.PageIndicators(false);
|
||||
this.actor.add(this._pageIndicator, { expand: true, x_fill: false, y_fill: false });
|
||||
this._pageIndicator = new PageIndicators.PageIndicators(
|
||||
Clutter.Orientation.HORIZONTAL
|
||||
);
|
||||
this.add(this._pageIndicator, { expand: true, x_fill: false, y_fill: false });
|
||||
this._pageIndicator.setReactive(false);
|
||||
|
||||
let bottomRow = this._createBottomRow();
|
||||
this.actor.add(bottomRow, { expand: true, x_fill: false, y_fill: false });
|
||||
this.add(bottomRow, { expand: true, x_fill: false, y_fill: false });
|
||||
|
||||
this._emojiPager.setCurrentPage(0);
|
||||
}
|
||||
|
||||
_onPageChanged(section, page, nPages) {
|
||||
vfunc_map() {
|
||||
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.setCurrentPage(page);
|
||||
|
||||
for (let i = 0; i < this._sections.length; i++) {
|
||||
let sect = this._sections[i];
|
||||
sect.button.setLatched(section == sect);
|
||||
sect.button.setLatched(sectionLabel == sect.label);
|
||||
}
|
||||
}
|
||||
|
||||
@ -961,14 +988,14 @@ var EmojiSelection = class EmojiSelection {
|
||||
key = new Key('ABC', []);
|
||||
key.keyButton.add_style_class_name('default-key');
|
||||
key.connect('released', () => this.emit('toggle'));
|
||||
row.appendKey(key.actor, 1.5);
|
||||
row.appendKey(key, 1.5);
|
||||
|
||||
for (let i = 0; i < this._sections.length; i++) {
|
||||
let section = this._sections[i];
|
||||
|
||||
key = new Key(section.label, []);
|
||||
key.connect('released', () => this._emojiPager.setCurrentSection(section, 0));
|
||||
row.appendKey(key.actor);
|
||||
row.appendKey(key);
|
||||
|
||||
section.button = key;
|
||||
}
|
||||
@ -977,9 +1004,9 @@ var EmojiSelection = class EmojiSelection {
|
||||
key.keyButton.add_style_class_name('default-key');
|
||||
key.keyButton.add_style_class_name('hide-key');
|
||||
key.connect('released', () => {
|
||||
this.emit('hide');
|
||||
this.emit('close-request');
|
||||
});
|
||||
row.appendKey(key.actor);
|
||||
row.appendKey(key);
|
||||
row.layoutButtons();
|
||||
|
||||
let actor = new AspectContainer({ layout_manager: new Clutter.BinLayout(),
|
||||
@ -993,11 +1020,14 @@ var EmojiSelection = class EmojiSelection {
|
||||
|
||||
return actor;
|
||||
}
|
||||
};
|
||||
Signals.addSignalMethods(EmojiSelection.prototype);
|
||||
});
|
||||
|
||||
var Keypad = class Keypad {
|
||||
constructor() {
|
||||
var Keypad = GObject.registerClass({
|
||||
Signals: {
|
||||
'keyval': { param_types: [GObject.TYPE_UINT] },
|
||||
}
|
||||
}, class Keypad extends AspectContainer {
|
||||
_init() {
|
||||
let keys = [
|
||||
{ label: '1', keyval: Clutter.KEY_1, left: 0, top: 0 },
|
||||
{ label: '2', keyval: Clutter.KEY_2, left: 1, top: 0 },
|
||||
@ -1013,14 +1043,17 @@ var Keypad = class Keypad {
|
||||
{ keyval: Clutter.KEY_Return, extraClassName: 'enter-key', left: 3, top: 1, height: 2 },
|
||||
];
|
||||
|
||||
this.actor = new AspectContainer({ layout_manager: new Clutter.BinLayout(),
|
||||
x_expand: true, y_expand: true });
|
||||
super._init({
|
||||
layout_manager: new Clutter.BinLayout(),
|
||||
x_expand: true,
|
||||
y_expand: true
|
||||
});
|
||||
|
||||
let gridLayout = new Clutter.GridLayout({ orientation: Clutter.Orientation.HORIZONTAL,
|
||||
column_homogeneous: true,
|
||||
row_homogeneous: true });
|
||||
this._box = new St.Widget({ layout_manager: gridLayout, x_expand: true, y_expand: true });
|
||||
this.actor.add_child(this._box);
|
||||
this.add_child(this._box);
|
||||
|
||||
for (let i = 0; i < keys.length; i++) {
|
||||
let cur = keys[i];
|
||||
@ -1032,86 +1065,32 @@ var Keypad = class Keypad {
|
||||
let w, h;
|
||||
w = cur.width || 1;
|
||||
h = cur.height || 1;
|
||||
gridLayout.attach(key.actor, cur.left, cur.top, w, h);
|
||||
gridLayout.attach(key, cur.left, cur.top, w, h);
|
||||
|
||||
key.connect('released', () => {
|
||||
this.emit('keyval', cur.keyval);
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
||||
Signals.addSignalMethods(Keypad.prototype);
|
||||
});
|
||||
|
||||
var Keyboard = class Keyboard {
|
||||
var KeyboardManager = class KeyBoardManager {
|
||||
constructor() {
|
||||
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._keyboard = null;
|
||||
this._a11yApplicationsSettings = new Gio.Settings({ schema_id: A11Y_APPLICATIONS_SCHEMA });
|
||||
this._a11yApplicationsSettings.connect('changed', this._syncEnabled.bind(this));
|
||||
|
||||
this._lastDeviceId = null;
|
||||
this._suggestions = null;
|
||||
this._emojiKeyVisible = Meta.is_wayland_compositor();
|
||||
Meta.get_backend().connect('last-device-changed', (backend, deviceId) => {
|
||||
let manager = Clutter.DeviceManager.get_default();
|
||||
let device = manager.get_device(deviceId);
|
||||
|
||||
this._focusTracker = new FocusTracker();
|
||||
this._focusTracker.connect('position-changed', this._onFocusPositionChanged.bind(this));
|
||||
this._focusTracker.connect('reset', () => {
|
||||
this._delayedAnimFocusWindow = null;
|
||||
this._animFocusedWindow = null;
|
||||
this._oskFocusWindow = null;
|
||||
if (device.get_device_name().indexOf('XTEST') < 0) {
|
||||
this._lastDeviceId = deviceId;
|
||||
this._syncEnabled();
|
||||
}
|
||||
});
|
||||
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._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() {
|
||||
@ -1128,38 +1107,143 @@ var Keyboard = class Keyboard {
|
||||
}
|
||||
|
||||
_syncEnabled() {
|
||||
let wasEnabled = this._enabled;
|
||||
this._enableKeyboard = this._a11yApplicationsSettings.get_boolean(SHOW_KEYBOARD);
|
||||
this._enabled = this._enableKeyboard || this._lastDeviceIsTouchscreen();
|
||||
if (!this._enabled && !this._keyboardController)
|
||||
let enableKeyboard = this._a11yApplicationsSettings.get_boolean(SHOW_KEYBOARD);
|
||||
let enabled = enableKeyboard || this._lastDeviceIsTouchscreen();
|
||||
if (!enabled && !this._keyboard)
|
||||
return;
|
||||
|
||||
if (this._enabled && !this._keyboardController)
|
||||
this._setupKeyboard();
|
||||
else if (!this._enabled)
|
||||
this.setCursorLocation(null);
|
||||
|
||||
if (!this._enabled && wasEnabled)
|
||||
if (enabled && !this._keyboard) {
|
||||
this._keyboard = new Keyboard();
|
||||
} else if (!enabled && this._keyboard) {
|
||||
this._keyboard.setCursorLocation(null);
|
||||
Main.layoutManager.hideKeyboard(true);
|
||||
this._keyboard.destroy();
|
||||
this._keyboard = null;
|
||||
}
|
||||
}
|
||||
|
||||
_destroyKeyboard() {
|
||||
if (this._keyboardNotifyId)
|
||||
this._keyboardController.disconnect(this._keyboardNotifyId);
|
||||
if (this._keyboardGroupsChangedId)
|
||||
this._keyboardController.disconnect(this._keyboardGroupsChangedId);
|
||||
if (this._keyboardStateId)
|
||||
this._keyboardController.disconnect(this._keyboardStateId);
|
||||
if (this._emojiKeyVisibleId)
|
||||
this._keyboardController.disconnect(this._emojiKeyVisibleId);
|
||||
if (this._keypadVisibleId)
|
||||
this._keyboardController.disconnect(this._keypadVisibleId);
|
||||
if (this._focusNotifyId)
|
||||
global.stage.disconnect(this._focusNotifyId);
|
||||
get keyboardActor() {
|
||||
return this._keyboard;
|
||||
}
|
||||
|
||||
get visible() {
|
||||
return this._keyboard && this._keyboard.visible;
|
||||
}
|
||||
|
||||
open(monitor) {
|
||||
if (this._keyboard)
|
||||
this._keyboard.open(monitor);
|
||||
}
|
||||
|
||||
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._keyboard = null;
|
||||
this.actor.destroy();
|
||||
this.actor = null;
|
||||
|
||||
this._keyboardController = null;
|
||||
this._suggestions = null;
|
||||
this._aspectContainer = null;
|
||||
this._emojiSelection = null;
|
||||
this._keypad = null;
|
||||
|
||||
Main.layoutManager.untrackChrome(this);
|
||||
Main.layoutManager.keyboardBox.remove_actor(this);
|
||||
|
||||
if (this._languagePopup) {
|
||||
this._languagePopup.destroy();
|
||||
@ -1168,9 +1252,8 @@ var Keyboard = class Keyboard {
|
||||
}
|
||||
|
||||
_setupKeyboard() {
|
||||
this.actor = new St.BoxLayout({ name: 'keyboard', vertical: true, reactive: true });
|
||||
Main.layoutManager.keyboardBox.add_actor(this.actor);
|
||||
Main.layoutManager.trackChrome(this.actor);
|
||||
Main.layoutManager.keyboardBox.add_actor(this);
|
||||
Main.layoutManager.trackChrome(this);
|
||||
|
||||
this._keyboardController = new KeyboardController();
|
||||
|
||||
@ -1178,30 +1261,28 @@ var Keyboard = class Keyboard {
|
||||
this._currentPage = null;
|
||||
|
||||
this._suggestions = new Suggestions();
|
||||
this.actor.add(this._suggestions.actor,
|
||||
{ x_align: St.Align.MIDDLE,
|
||||
x_fill: false });
|
||||
this.add(this._suggestions, { x_align: St.Align.MIDDLE, x_fill: false });
|
||||
|
||||
this._aspectContainer = new AspectContainer({ layout_manager: new Clutter.BinLayout() });
|
||||
this.actor.add(this._aspectContainer, { expand: true });
|
||||
this.add(this._aspectContainer, { expand: true });
|
||||
|
||||
this._emojiSelection = new EmojiSelection();
|
||||
this._emojiSelection.connect('toggle', this._toggleEmoji.bind(this));
|
||||
this._emojiSelection.connect('hide', () => this.hide());
|
||||
this._emojiSelection.connect('close-request', () => this.close());
|
||||
this._emojiSelection.connect('emoji-selected', (selection, emoji) => {
|
||||
this._keyboardController.commitString(emoji);
|
||||
});
|
||||
|
||||
this._aspectContainer.add_child(this._emojiSelection.actor);
|
||||
this._emojiSelection.actor.hide();
|
||||
this._aspectContainer.add_child(this._emojiSelection);
|
||||
this._emojiSelection.hide();
|
||||
|
||||
this._keypad = new Keypad();
|
||||
this._keypad.connect('keyval', (keypad, keyval) => {
|
||||
this._connectSignal(this._keypad, 'keyval', (_keypad, keyval) => {
|
||||
this._keyboardController.keyvalPress(keyval);
|
||||
this._keyboardController.keyvalRelease(keyval);
|
||||
});
|
||||
this._aspectContainer.add_child(this._keypad.actor);
|
||||
this._keypad.actor.hide();
|
||||
this._aspectContainer.add_child(this._keypad);
|
||||
this._keypad.hide();
|
||||
this._keypadVisible = false;
|
||||
|
||||
this._ensureKeysForGroup(this._keyboardController.getCurrentGroup());
|
||||
@ -1210,16 +1291,22 @@ var Keyboard = class Keyboard {
|
||||
// Keyboard models are defined in LTR, we must override
|
||||
// the locale setting in order to avoid flipping the
|
||||
// keyboard on RTL locales.
|
||||
this.actor.text_direction = Clutter.TextDirection.LTR;
|
||||
this.text_direction = Clutter.TextDirection.LTR;
|
||||
|
||||
this._keyboardNotifyId = this._keyboardController.connect('active-group', this._onGroupChanged.bind(this));
|
||||
this._keyboardGroupsChangedId = this._keyboardController.connect('groups-changed', this._onKeyboardGroupsChanged.bind(this));
|
||||
this._keyboardStateId = this._keyboardController.connect('panel-state', this._onKeyboardStateChanged.bind(this));
|
||||
this._keypadVisibleId = this._keyboardController.connect('keypad-visible', this._onKeypadVisible.bind(this));
|
||||
this._focusNotifyId = global.stage.connect('notify::key-focus', this._onKeyFocusChanged.bind(this));
|
||||
this._connectSignal(this._keyboardController, 'active-group',
|
||||
this._onGroupChanged.bind(this));
|
||||
this._connectSignal(this._keyboardController, 'groups-changed',
|
||||
this._onKeyboardGroupsChanged.bind(this));
|
||||
this._connectSignal(this._keyboardController, 'panel-state',
|
||||
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())
|
||||
this._emojiKeyVisibleId = this._keyboardController.connect('emoji-visible', this._onEmojiKeyVisible.bind(this));
|
||||
this._connectSignal(this._keyboardController, 'emoji-visible',
|
||||
this._onEmojiKeyVisible.bind(this));
|
||||
|
||||
this._relayout();
|
||||
}
|
||||
@ -1235,17 +1322,17 @@ var Keyboard = class Keyboard {
|
||||
return;
|
||||
|
||||
if (!(focus instanceof Clutter.Text)) {
|
||||
this.hide();
|
||||
this.close();
|
||||
return;
|
||||
}
|
||||
|
||||
if (!this._showIdleId) {
|
||||
this._showIdleId = GLib.idle_add(GLib.PRIORITY_DEFAULT_IDLE, () => {
|
||||
this.show(Main.layoutManager.focusIndex);
|
||||
this.open(Main.layoutManager.focusIndex);
|
||||
this._showIdleId = 0;
|
||||
return GLib.SOURCE_REMOVE;
|
||||
});
|
||||
GLib.Source.set_name_by_id(this._showIdleId, '[gnome-shell] this.show');
|
||||
GLib.Source.set_name_by_id(this._showIdleId, '[gnome-shell] this.open');
|
||||
}
|
||||
}
|
||||
|
||||
@ -1309,7 +1396,7 @@ var Keyboard = class Keyboard {
|
||||
this._setActiveLayer(0);
|
||||
});
|
||||
|
||||
layout.appendKey(button.actor, button.keyButton.keyWidth);
|
||||
layout.appendKey(button, button.keyButton.keyWidth);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1357,7 +1444,7 @@ var Keyboard = class Keyboard {
|
||||
if (keyval != null)
|
||||
this._keyboardController.keyvalRelease(keyval);
|
||||
else if (action == 'hide')
|
||||
this.hide();
|
||||
this.close();
|
||||
else if (action == 'languageMenu')
|
||||
this._popupLanguageMenu(actor);
|
||||
else if (action == 'emoji')
|
||||
@ -1380,7 +1467,7 @@ var Keyboard = class Keyboard {
|
||||
/* Only hide the key actor, so the container still takes space */
|
||||
extraButton.keyButton.hide();
|
||||
} else {
|
||||
extraButton.actor.hide();
|
||||
extraButton.hide();
|
||||
}
|
||||
extraButton.setWidth(1.5);
|
||||
} else if (key.right && numKeys > 8) {
|
||||
@ -1391,7 +1478,7 @@ var Keyboard = class Keyboard {
|
||||
extraButton.setWidth(1.5);
|
||||
}
|
||||
|
||||
layout.appendKey(extraButton.actor, extraButton.keyButton.keyWidth);
|
||||
layout.appendKey(extraButton, extraButton.keyButton.keyWidth);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1402,7 +1489,7 @@ var Keyboard = class Keyboard {
|
||||
|
||||
_setEmojiActive(active) {
|
||||
this._emojiActive = active;
|
||||
this._emojiSelection.actor.visible = this._emojiActive;
|
||||
this._emojiSelection.visible = this._emojiActive;
|
||||
this._updateCurrentPageVisible();
|
||||
}
|
||||
|
||||
@ -1470,12 +1557,12 @@ var Keyboard = class Keyboard {
|
||||
_relayout() {
|
||||
let monitor = Main.layoutManager.keyboardMonitor;
|
||||
|
||||
if (this.actor == null || monitor == null)
|
||||
if (!monitor)
|
||||
return;
|
||||
|
||||
let maxHeight = monitor.height / 3;
|
||||
this.actor.width = monitor.width;
|
||||
this.actor.height = maxHeight;
|
||||
this.width = monitor.width;
|
||||
this.height = maxHeight;
|
||||
}
|
||||
|
||||
_onGroupChanged() {
|
||||
@ -1484,7 +1571,7 @@ var Keyboard = class Keyboard {
|
||||
}
|
||||
|
||||
_onKeyboardGroupsChanged() {
|
||||
let nonGroupActors = [this._emojiSelection.actor, this._keypad.actor];
|
||||
let nonGroupActors = [this._emojiSelection, this._keypad];
|
||||
this._aspectContainer.get_children().filter(c => !nonGroupActors.includes(c)).forEach(c => {
|
||||
c.destroy();
|
||||
});
|
||||
@ -1498,7 +1585,7 @@ var Keyboard = class Keyboard {
|
||||
return;
|
||||
|
||||
this._keypadVisible = visible;
|
||||
this._keypad.actor.visible = this._keypadVisible;
|
||||
this._keypad.visible = this._keypadVisible;
|
||||
this._updateCurrentPageVisible();
|
||||
}
|
||||
|
||||
@ -1523,9 +1610,9 @@ var Keyboard = class Keyboard {
|
||||
return;
|
||||
|
||||
if (enabled)
|
||||
this.show(Main.layoutManager.focusIndex);
|
||||
this.open(Main.layoutManager.focusIndex);
|
||||
else
|
||||
this.hide();
|
||||
this.close();
|
||||
}
|
||||
|
||||
_setActiveLayer(activeLevel) {
|
||||
@ -1552,12 +1639,6 @@ var Keyboard = class Keyboard {
|
||||
this._updateCurrentPageVisible();
|
||||
}
|
||||
|
||||
shouldTakeEvent(event) {
|
||||
let actor = event.get_source();
|
||||
return Main.layoutManager.keyboardBox.contains(actor) ||
|
||||
!!actor._extended_keys || !!actor.extended_key;
|
||||
}
|
||||
|
||||
_clearKeyboardRestTimer() {
|
||||
if (!this._keyboardRestingId)
|
||||
return;
|
||||
@ -1565,10 +1646,7 @@ var Keyboard = class Keyboard {
|
||||
this._keyboardRestingId = 0;
|
||||
}
|
||||
|
||||
show(monitor) {
|
||||
if (!this._enabled)
|
||||
return;
|
||||
|
||||
open(monitor) {
|
||||
this._clearShowIdle();
|
||||
this._keyboardRequested = true;
|
||||
|
||||
@ -1585,13 +1663,13 @@ var Keyboard = class Keyboard {
|
||||
KEYBOARD_REST_TIME,
|
||||
() => {
|
||||
this._clearKeyboardRestTimer();
|
||||
this._show(monitor);
|
||||
this._open(monitor);
|
||||
return GLib.SOURCE_REMOVE;
|
||||
});
|
||||
GLib.Source.set_name_by_id(this._keyboardRestingId, '[gnome-shell] this._clearKeyboardRestTimer');
|
||||
}
|
||||
|
||||
_show(monitor) {
|
||||
_open(monitor) {
|
||||
if (!this._keyboardRequested)
|
||||
return;
|
||||
|
||||
@ -1607,10 +1685,7 @@ var Keyboard = class Keyboard {
|
||||
}
|
||||
}
|
||||
|
||||
hide() {
|
||||
if (!this._enabled)
|
||||
return;
|
||||
|
||||
close() {
|
||||
this._clearShowIdle();
|
||||
this._keyboardRequested = false;
|
||||
|
||||
@ -1622,13 +1697,13 @@ var Keyboard = class Keyboard {
|
||||
KEYBOARD_REST_TIME,
|
||||
() => {
|
||||
this._clearKeyboardRestTimer();
|
||||
this._hide();
|
||||
this._close();
|
||||
return GLib.SOURCE_REMOVE;
|
||||
});
|
||||
GLib.Source.set_name_by_id(this._keyboardRestingId, '[gnome-shell] this._clearKeyboardRestTimer');
|
||||
}
|
||||
|
||||
_hide() {
|
||||
_close() {
|
||||
if (this._keyboardRequested)
|
||||
return;
|
||||
|
||||
@ -1645,7 +1720,7 @@ var Keyboard = class Keyboard {
|
||||
if (!this._suggestions)
|
||||
return;
|
||||
this._suggestions.add(text, callback);
|
||||
this._suggestions.actor.show();
|
||||
this._suggestions.show();
|
||||
}
|
||||
|
||||
_clearShowIdle() {
|
||||
@ -1722,7 +1797,7 @@ var Keyboard = class Keyboard {
|
||||
|
||||
this._oskFocusWindow = window;
|
||||
}
|
||||
};
|
||||
});
|
||||
|
||||
var KeyboardController = class {
|
||||
constructor() {
|
||||
|
@ -606,17 +606,17 @@ var LayoutManager = GObject.registerClass({
|
||||
return;
|
||||
}
|
||||
this._systemBackground = new Background.SystemBackground();
|
||||
this._systemBackground.actor.hide();
|
||||
this._systemBackground.hide();
|
||||
|
||||
global.stage.insert_child_below(this._systemBackground.actor, null);
|
||||
global.stage.insert_child_below(this._systemBackground, null);
|
||||
|
||||
let constraint = new Clutter.BindConstraint({ source: global.stage,
|
||||
coordinate: Clutter.BindCoordinate.ALL });
|
||||
this._systemBackground.actor.add_constraint(constraint);
|
||||
this._systemBackground.add_constraint(constraint);
|
||||
|
||||
let signalId = this._systemBackground.connect('loaded', () => {
|
||||
this._systemBackground.disconnect(signalId);
|
||||
this._systemBackground.actor.show();
|
||||
this._systemBackground.show();
|
||||
global.stage.show();
|
||||
|
||||
this._prepareStartupAnimation();
|
||||
@ -722,7 +722,7 @@ var LayoutManager = GObject.registerClass({
|
||||
this._coverPane.destroy();
|
||||
this._coverPane = null;
|
||||
|
||||
this._systemBackground.actor.destroy();
|
||||
this._systemBackground.destroy();
|
||||
this._systemBackground = null;
|
||||
|
||||
this._startingUp = false;
|
||||
@ -1112,8 +1112,11 @@ var LayoutManager = GObject.registerClass({
|
||||
//
|
||||
// This class manages a "hot corner" that can toggle switching to
|
||||
// overview.
|
||||
var HotCorner = class HotCorner {
|
||||
constructor(layoutManager, monitor, x, y) {
|
||||
var HotCorner = GObject.registerClass(
|
||||
class HotCorner extends Clutter.Actor {
|
||||
_init(layoutManager, monitor, x, y) {
|
||||
super._init();
|
||||
|
||||
// We use this flag to mark the case where the user has entered the
|
||||
// hot corner and has not left both the hot corner and a surrounding
|
||||
// guard area (the "environs"). This avoids triggering the hot corner
|
||||
@ -1142,6 +1145,8 @@ var HotCorner = class HotCorner {
|
||||
|
||||
this._ripples = new Ripples.Ripples(px, py, 'ripple-box');
|
||||
this._ripples.addTo(layoutManager.uiGroup);
|
||||
|
||||
this.connect('destroy', this._onDestroy.bind(this));
|
||||
}
|
||||
|
||||
setBarrierSize(size) {
|
||||
@ -1181,11 +1186,14 @@ var HotCorner = class HotCorner {
|
||||
|
||||
_setupFallbackCornerIfNeeded(layoutManager) {
|
||||
if (!global.display.supports_extended_barriers()) {
|
||||
this.actor = new Clutter.Actor({ name: 'hot-corner-environs',
|
||||
x: this._x, y: this._y,
|
||||
width: 3,
|
||||
height: 3,
|
||||
reactive: true });
|
||||
this.set({
|
||||
name: 'hot-corner-environs',
|
||||
x: this._x,
|
||||
y: this._y,
|
||||
width: 3,
|
||||
height: 3,
|
||||
reactive: true
|
||||
});
|
||||
|
||||
this._corner = new Clutter.Actor({ name: 'hot-corner',
|
||||
width: 1,
|
||||
@ -1194,19 +1202,16 @@ var HotCorner = class HotCorner {
|
||||
reactive: true });
|
||||
this._corner._delegate = this;
|
||||
|
||||
this.actor.add_child(this._corner);
|
||||
layoutManager.addChrome(this.actor);
|
||||
this.add_child(this._corner);
|
||||
layoutManager.addChrome(this);
|
||||
|
||||
if (Clutter.get_default_text_direction() == Clutter.TextDirection.RTL) {
|
||||
this._corner.set_position(this.actor.width - this._corner.width, 0);
|
||||
this.actor.set_anchor_point_from_gravity(Clutter.Gravity.NORTH_EAST);
|
||||
this._corner.set_position(this.width - this._corner.width, 0);
|
||||
this.set_anchor_point_from_gravity(Clutter.Gravity.NORTH_EAST);
|
||||
} else {
|
||||
this._corner.set_position(0, 0);
|
||||
}
|
||||
|
||||
this.actor.connect('leave-event',
|
||||
this._onEnvironsLeft.bind(this));
|
||||
|
||||
this._corner.connect('enter-event',
|
||||
this._onCornerEntered.bind(this));
|
||||
this._corner.connect('leave-event',
|
||||
@ -1214,14 +1219,11 @@ var HotCorner = class HotCorner {
|
||||
}
|
||||
}
|
||||
|
||||
destroy() {
|
||||
_onDestroy() {
|
||||
this.setBarrierSize(0);
|
||||
this._pressureBarrier.destroy();
|
||||
this._pressureBarrier = null;
|
||||
|
||||
if (this.actor)
|
||||
this.actor.destroy();
|
||||
|
||||
this._ripples.destroy();
|
||||
}
|
||||
|
||||
@ -1253,18 +1255,18 @@ var HotCorner = class HotCorner {
|
||||
}
|
||||
|
||||
_onCornerLeft(actor, event) {
|
||||
if (event.get_related() != this.actor)
|
||||
if (event.get_related() != this)
|
||||
this._entered = false;
|
||||
// Consume event, otherwise this will confuse onEnvironsLeft
|
||||
return Clutter.EVENT_STOP;
|
||||
}
|
||||
|
||||
_onEnvironsLeft(actor, event) {
|
||||
if (event.get_related() != this._corner)
|
||||
vfunc_leave_event(crossingEvent) {
|
||||
if (crossingEvent.related != this._corner)
|
||||
this._entered = false;
|
||||
return Clutter.EVENT_PROPAGATE;
|
||||
}
|
||||
};
|
||||
});
|
||||
|
||||
var PressureBarrier = class PressureBarrier {
|
||||
constructor(threshold, timeout, actionMode) {
|
||||
|
@ -2,7 +2,6 @@
|
||||
/* exported Lightbox */
|
||||
|
||||
const { Clutter, GObject, Shell, St } = imports.gi;
|
||||
const Signals = imports.signals;
|
||||
|
||||
const Params = imports.misc.params;
|
||||
|
||||
@ -89,8 +88,8 @@ var RadialShaderEffect = GObject.registerClass({
|
||||
* - inhibitEvents: whether to inhibit events for @container
|
||||
* - width: shade actor width
|
||||
* - height: shade actor height
|
||||
* - fadeInTime: milliseconds used to fade in
|
||||
* - fadeOutTime: milliseconds used to fade out
|
||||
* - fadeFactor: fading opacity factor
|
||||
* - radialEffect: whether to enable the GLSL radial effect
|
||||
*
|
||||
* Lightbox creates a dark translucent "shade" actor to hide the
|
||||
* contents of @container, and allows you to specify particular actors
|
||||
@ -106,8 +105,13 @@ var RadialShaderEffect = GObject.registerClass({
|
||||
* @container and will track any changes in its size. You can override
|
||||
* this by passing an explicit width and height in @params.
|
||||
*/
|
||||
var Lightbox = class Lightbox {
|
||||
constructor(container, params) {
|
||||
var Lightbox = GObject.registerClass({
|
||||
Properties: {
|
||||
'active': GObject.ParamSpec.boolean(
|
||||
'active', 'active', 'active', GObject.ParamFlags.READABLE, false),
|
||||
}
|
||||
}, class Lightbox extends St.Bin {
|
||||
_init(container, params) {
|
||||
params = Params.parse(params, {
|
||||
inhibitEvents: false,
|
||||
width: null,
|
||||
@ -116,32 +120,34 @@ var Lightbox = class Lightbox {
|
||||
radialEffect: false,
|
||||
});
|
||||
|
||||
super._init({
|
||||
reactive: params.inhibitEvents,
|
||||
width: params.width,
|
||||
height: params.height,
|
||||
visible: false
|
||||
});
|
||||
|
||||
this._active = false;
|
||||
this._container = container;
|
||||
this._children = container.get_children();
|
||||
this._fadeFactor = params.fadeFactor;
|
||||
this._radialEffect = Clutter.feature_available(Clutter.FeatureFlags.SHADERS_GLSL) && params.radialEffect;
|
||||
|
||||
this.actor = new St.Bin({ reactive: params.inhibitEvents });
|
||||
|
||||
if (this._radialEffect)
|
||||
this.actor.add_effect(new RadialShaderEffect({ name: 'radial' }));
|
||||
this.add_effect(new RadialShaderEffect({ name: 'radial' }));
|
||||
else
|
||||
this.actor.set({ opacity: 0, style_class: 'lightbox' });
|
||||
this.set({ opacity: 0, style_class: 'lightbox' });
|
||||
|
||||
container.add_actor(this.actor);
|
||||
this.actor.raise_top();
|
||||
this.actor.hide();
|
||||
this.shown = false;
|
||||
container.add_actor(this);
|
||||
this.raise_top();
|
||||
|
||||
this.actor.connect('destroy', this._onDestroy.bind(this));
|
||||
this.connect('destroy', this._onDestroy.bind(this));
|
||||
|
||||
if (params.width && params.height) {
|
||||
this.actor.width = params.width;
|
||||
this.actor.height = params.height;
|
||||
} else {
|
||||
let constraint = new Clutter.BindConstraint({ source: container,
|
||||
coordinate: Clutter.BindCoordinate.ALL });
|
||||
this.actor.add_constraint(constraint);
|
||||
if (!params.width || !params.height) {
|
||||
this.add_constraint(new Clutter.BindConstraint({
|
||||
source: container,
|
||||
coordinate: Clutter.BindCoordinate.ALL
|
||||
}));
|
||||
}
|
||||
|
||||
this._actorAddedSignalId = container.connect('actor-added', this._actorAdded.bind(this));
|
||||
@ -150,16 +156,20 @@ var Lightbox = class Lightbox {
|
||||
this._highlighted = null;
|
||||
}
|
||||
|
||||
get active() {
|
||||
return this._active;
|
||||
}
|
||||
|
||||
_actorAdded(container, newChild) {
|
||||
let children = this._container.get_children();
|
||||
let myIndex = children.indexOf(this.actor);
|
||||
let myIndex = children.indexOf(this);
|
||||
let newChildIndex = children.indexOf(newChild);
|
||||
|
||||
if (newChildIndex > myIndex) {
|
||||
// The child was added above the shade (presumably it was
|
||||
// made the new top-most child). Move it below the shade,
|
||||
// and add it to this._children as the new topmost actor.
|
||||
newChild.lower(this.actor);
|
||||
this._container.set_child_above_sibling(this, newChild);
|
||||
this._children.push(newChild);
|
||||
} else if (newChildIndex == 0) {
|
||||
// Bottom of stack
|
||||
@ -172,8 +182,8 @@ var Lightbox = class Lightbox {
|
||||
}
|
||||
}
|
||||
|
||||
show(fadeInTime) {
|
||||
this.actor.remove_all_transitions();
|
||||
lightOn(fadeInTime) {
|
||||
this.remove_all_transitions();
|
||||
|
||||
let easeProps = {
|
||||
duration: fadeInTime || 0,
|
||||
@ -181,44 +191,46 @@ var Lightbox = class Lightbox {
|
||||
};
|
||||
|
||||
let onComplete = () => {
|
||||
this.shown = true;
|
||||
this.emit('shown');
|
||||
this._active = true;
|
||||
this.notify('active');
|
||||
};
|
||||
|
||||
this.actor.show();
|
||||
this.show();
|
||||
|
||||
if (this._radialEffect) {
|
||||
this.actor.ease_property(
|
||||
this.ease_property(
|
||||
'@effects.radial.brightness', VIGNETTE_BRIGHTNESS, easeProps);
|
||||
this.actor.ease_property(
|
||||
this.ease_property(
|
||||
'@effects.radial.sharpness', VIGNETTE_SHARPNESS,
|
||||
Object.assign({ onComplete }, easeProps));
|
||||
} else {
|
||||
this.actor.ease(Object.assign(easeProps, {
|
||||
this.ease(Object.assign(easeProps, {
|
||||
opacity: 255 * this._fadeFactor,
|
||||
onComplete
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
hide(fadeOutTime) {
|
||||
this.shown = false;
|
||||
this.actor.remove_all_transitions();
|
||||
lightOff(fadeOutTime) {
|
||||
this.remove_all_transitions();
|
||||
|
||||
this._active = false;
|
||||
this.notify('active');
|
||||
|
||||
let easeProps = {
|
||||
duration: fadeOutTime || 0,
|
||||
mode: Clutter.AnimationMode.EASE_OUT_QUAD
|
||||
};
|
||||
|
||||
let onComplete = () => this.actor.hide();
|
||||
let onComplete = () => this.hide();
|
||||
|
||||
if (this._radialEffect) {
|
||||
this.actor.ease_property(
|
||||
this.ease_property(
|
||||
'@effects.radial.brightness', 1.0, easeProps);
|
||||
this.actor.ease_property(
|
||||
this.ease_property(
|
||||
'@effects.radial.sharpness', 0.0, Object.assign({ onComplete }, easeProps));
|
||||
} else {
|
||||
this.actor.ease(Object.assign(easeProps, { opacity: 0, onComplete }));
|
||||
this.ease(Object.assign(easeProps, { opacity: 0, onComplete }));
|
||||
}
|
||||
}
|
||||
|
||||
@ -249,7 +261,7 @@ var Lightbox = class Lightbox {
|
||||
// case we may need to indicate some *other* actor as the new
|
||||
// sibling of the to-be-lowered one.
|
||||
|
||||
let below = this.actor;
|
||||
let below = this;
|
||||
for (let i = this._children.length - 1; i >= 0; i--) {
|
||||
if (this._children[i] == window)
|
||||
this._children[i].raise_top();
|
||||
@ -262,15 +274,6 @@ var Lightbox = class Lightbox {
|
||||
this._highlighted = window;
|
||||
}
|
||||
|
||||
/**
|
||||
* destroy:
|
||||
*
|
||||
* Destroys the lightbox.
|
||||
*/
|
||||
destroy() {
|
||||
this.actor.destroy();
|
||||
}
|
||||
|
||||
/**
|
||||
* _onDestroy:
|
||||
*
|
||||
@ -278,10 +281,15 @@ var Lightbox = class Lightbox {
|
||||
* by destroying its container or by explicitly calling this.destroy().
|
||||
*/
|
||||
_onDestroy() {
|
||||
this._container.disconnect(this._actorAddedSignalId);
|
||||
this._container.disconnect(this._actorRemovedSignalId);
|
||||
if (this._actorAddedSignalId) {
|
||||
this._container.disconnect(this._actorAddedSignalId);
|
||||
this._actorAddedSignalId = 0;
|
||||
}
|
||||
if (this._actorRemovedSignalId) {
|
||||
this._container.disconnect(this._actorRemovedSignalId);
|
||||
this._actorRemovedSignalId = 0;
|
||||
}
|
||||
|
||||
this.highlight(null);
|
||||
}
|
||||
};
|
||||
Signals.addSignalMethods(Lightbox.prototype);
|
||||
});
|
||||
|
@ -1,8 +1,8 @@
|
||||
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
|
||||
/* exported LookingGlass */
|
||||
|
||||
const { Clutter, Cogl, Gio, GLib,
|
||||
GObject, Meta, Pango, Shell, St } = imports.gi;
|
||||
const { Clutter, Cogl, Gio, GLib, GObject,
|
||||
Graphene, Meta, Pango, Shell, St } = imports.gi;
|
||||
const Signals = imports.signals;
|
||||
const System = imports.system;
|
||||
|
||||
@ -110,9 +110,11 @@ var AutoComplete = class AutoComplete {
|
||||
Signals.addSignalMethods(AutoComplete.prototype);
|
||||
|
||||
|
||||
var Notebook = class Notebook {
|
||||
constructor() {
|
||||
this.actor = new St.BoxLayout({ vertical: true });
|
||||
var Notebook = GObject.registerClass({
|
||||
Signals: { 'selection': { param_types: [Clutter.Actor.$gtype] } },
|
||||
}, class Notebook extends St.BoxLayout {
|
||||
_init() {
|
||||
super._init({ vertical: true });
|
||||
|
||||
this.tabControls = new St.BoxLayout({ style_class: 'labels' });
|
||||
|
||||
@ -143,7 +145,7 @@ var Notebook = class Notebook {
|
||||
_scrollToBottom: false };
|
||||
this._tabs.push(tabData);
|
||||
scrollview.hide();
|
||||
this.actor.add(scrollview, { expand: true });
|
||||
this.add(scrollview, { expand: true });
|
||||
|
||||
let vAdjust = scrollview.vscroll.adjustment;
|
||||
vAdjust.connect('changed', () => this._onAdjustScopeChanged(tabData));
|
||||
@ -174,7 +176,7 @@ var Notebook = class Notebook {
|
||||
// Focus the new tab before unmapping the old one
|
||||
let tabData = this._tabs[index];
|
||||
if (!tabData.scrollView.navigate_focus(null, St.DirectionType.TAB_FORWARD, false))
|
||||
this.actor.grab_key_focus();
|
||||
this.grab_key_focus();
|
||||
|
||||
this._unselect();
|
||||
|
||||
@ -234,8 +236,7 @@ var Notebook = class Notebook {
|
||||
|
||||
this.selectIndex(prevIndex);
|
||||
}
|
||||
};
|
||||
Signals.addSignalMethods(Notebook.prototype);
|
||||
});
|
||||
|
||||
function objectToString(o) {
|
||||
if (typeof o == typeof objectToString) {
|
||||
@ -246,57 +247,64 @@ function objectToString(o) {
|
||||
}
|
||||
}
|
||||
|
||||
var ObjLink = class ObjLink {
|
||||
constructor(lookingGlass, o, title) {
|
||||
var ObjLink = GObject.registerClass(
|
||||
class ObjLink extends St.Button {
|
||||
_init(lookingGlass, o, title) {
|
||||
let text;
|
||||
if (title)
|
||||
text = title;
|
||||
else
|
||||
text = objectToString(o);
|
||||
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.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;
|
||||
}
|
||||
|
||||
_onClicked() {
|
||||
this._lookingGlass.inspectObject(this._obj, this.actor);
|
||||
vfunc_clicked() {
|
||||
this._lookingGlass.inspectObject(this._obj, this);
|
||||
}
|
||||
};
|
||||
});
|
||||
|
||||
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.o = o;
|
||||
|
||||
this.actor = new St.BoxLayout({ vertical: true });
|
||||
this._lookingGlass = lookingGlass;
|
||||
|
||||
let cmdTxt = new St.Label({ text: command });
|
||||
cmdTxt.clutter_text.ellipsize = Pango.EllipsizeMode.END;
|
||||
this.actor.add(cmdTxt);
|
||||
this.add(cmdTxt);
|
||||
let box = new St.BoxLayout({});
|
||||
this.actor.add(box);
|
||||
this.add(box);
|
||||
let resultTxt = new St.Label({ text: `r(${index}) = ` });
|
||||
resultTxt.clutter_text.ellipsize = Pango.EllipsizeMode.END;
|
||||
box.add(resultTxt);
|
||||
let objLink = new ObjLink(this._lookingGlass, o);
|
||||
box.add(objLink.actor);
|
||||
box.add(objLink);
|
||||
}
|
||||
};
|
||||
});
|
||||
|
||||
var WindowList = class WindowList {
|
||||
constructor(lookingGlass) {
|
||||
this.actor = new St.BoxLayout({ name: 'Windows', vertical: true, style: 'spacing: 8px' });
|
||||
var WindowList = GObject.registerClass({
|
||||
GTypeName: 'LookingClass_WindowList'
|
||||
}, class WindowList extends St.BoxLayout {
|
||||
_init(lookingGlass) {
|
||||
super._init({ name: 'Windows', vertical: true, style: 'spacing: 8px' });
|
||||
let tracker = Shell.WindowTracker.get_default();
|
||||
this._updateId = Main.initializeDeferredWork(this.actor, this._updateWindowList.bind(this));
|
||||
this._updateId = Main.initializeDeferredWork(this, this._updateWindowList.bind(this));
|
||||
global.display.connect('window-created', this._updateWindowList.bind(this));
|
||||
tracker.connect('tracked-windows-changed', this._updateWindowList.bind(this));
|
||||
|
||||
@ -307,7 +315,7 @@ var WindowList = class WindowList {
|
||||
if (!this._lookingGlass.isOpen)
|
||||
return;
|
||||
|
||||
this.actor.destroy_all_children();
|
||||
this.destroy_all_children();
|
||||
let windows = global.get_window_actors();
|
||||
let tracker = Shell.WindowTracker.get_default();
|
||||
for (let i = 0; i < windows.length; i++) {
|
||||
@ -318,9 +326,9 @@ var WindowList = class WindowList {
|
||||
metaWindow._lookingGlassManaged = true;
|
||||
}
|
||||
let box = new St.BoxLayout({ vertical: true });
|
||||
this.actor.add(box);
|
||||
this.add(box);
|
||||
let windowLink = new ObjLink(this._lookingGlass, metaWindow, metaWindow.title);
|
||||
box.add(windowLink.actor, { x_align: St.Align.START, x_fill: false });
|
||||
box.add(windowLink, { x_align: St.Align.START, x_fill: false });
|
||||
let propsBox = new St.BoxLayout({ vertical: true, style: 'padding-left: 6px;' });
|
||||
box.add(propsBox);
|
||||
propsBox.add(new St.Label({ text: `wmclass: ${metaWindow.get_wm_class()}` }));
|
||||
@ -331,7 +339,7 @@ var WindowList = class WindowList {
|
||||
propsBox.add(propBox);
|
||||
propBox.add(new St.Label({ text: 'app: ' }), { y_fill: false });
|
||||
let appLink = new ObjLink(this._lookingGlass, app, app.get_id());
|
||||
propBox.add(appLink.actor, { y_fill: false });
|
||||
propBox.add(appLink, { y_fill: false });
|
||||
propBox.add(icon, { y_fill: false });
|
||||
} else {
|
||||
propsBox.add(new St.Label({ text: '<untracked>' }));
|
||||
@ -342,23 +350,27 @@ var WindowList = class WindowList {
|
||||
update() {
|
||||
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._previousObj = null;
|
||||
|
||||
this._parentList = [];
|
||||
|
||||
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.get_hscroll_bar().hide();
|
||||
this._container = new St.BoxLayout({ name: 'LookingGlassPropertyInspector',
|
||||
style_class: 'lg-dialog',
|
||||
vertical: true });
|
||||
this.actor.add_actor(this._container);
|
||||
this.add_actor(this._container);
|
||||
|
||||
this._lookingGlass = lookingGlass;
|
||||
}
|
||||
@ -404,7 +416,7 @@ var ObjInspector = class ObjInspector {
|
||||
let link;
|
||||
try {
|
||||
let prop = obj[propName];
|
||||
link = new ObjLink(this._lookingGlass, prop).actor;
|
||||
link = new ObjLink(this._lookingGlass, prop);
|
||||
} catch (e) {
|
||||
link = new St.Label({ text: '<error>' });
|
||||
}
|
||||
@ -421,17 +433,17 @@ var ObjInspector = class ObjInspector {
|
||||
return;
|
||||
this._previousObj = null;
|
||||
this._open = true;
|
||||
this.actor.show();
|
||||
this.show();
|
||||
if (sourceActor) {
|
||||
this.actor.set_scale(0, 0);
|
||||
this.actor.ease({
|
||||
this.set_scale(0, 0);
|
||||
this.ease({
|
||||
scale_x: 1,
|
||||
scale_y: 1,
|
||||
mode: Clutter.AnimationMode.EASE_OUT_QUAD,
|
||||
duration: 200
|
||||
});
|
||||
} else {
|
||||
this.actor.set_scale(1, 1);
|
||||
this.set_scale(1, 1);
|
||||
}
|
||||
}
|
||||
|
||||
@ -439,7 +451,7 @@ var ObjInspector = class ObjInspector {
|
||||
if (!this._open)
|
||||
return;
|
||||
this._open = false;
|
||||
this.actor.hide();
|
||||
this.hide();
|
||||
this._previousObj = null;
|
||||
this._obj = null;
|
||||
}
|
||||
@ -453,7 +465,7 @@ var ObjInspector = class ObjInspector {
|
||||
_onBack() {
|
||||
this.selectObject(this._previousObj, true);
|
||||
}
|
||||
};
|
||||
});
|
||||
|
||||
var RedBorderEffect = GObject.registerClass(
|
||||
class RedBorderEffect extends Clutter.Effect {
|
||||
@ -465,16 +477,16 @@ class RedBorderEffect extends Clutter.Effect {
|
||||
color.init_from_4ub(0xff, 0, 0, 0xc4);
|
||||
Cogl.set_source_color(color);
|
||||
|
||||
let geom = actor.get_allocation_geometry();
|
||||
let alloc = actor.get_allocation_box();
|
||||
let width = 2;
|
||||
|
||||
// clockwise order
|
||||
Cogl.rectangle(0, 0, geom.width, width);
|
||||
Cogl.rectangle(geom.width - width, width,
|
||||
geom.width, geom.height);
|
||||
Cogl.rectangle(0, geom.height,
|
||||
geom.width - width, geom.height - width);
|
||||
Cogl.rectangle(0, geom.height - width,
|
||||
Cogl.rectangle(0, 0, alloc.get_width(), width);
|
||||
Cogl.rectangle(alloc.get_width() - width, width,
|
||||
alloc.get_width(), alloc.get_height());
|
||||
Cogl.rectangle(0, alloc.get_height(),
|
||||
alloc.get_width() - width, alloc.get_height() - width);
|
||||
Cogl.rectangle(0, alloc.get_height() - width,
|
||||
width, width);
|
||||
}
|
||||
});
|
||||
@ -484,8 +496,7 @@ var Inspector = GObject.registerClass({
|
||||
'target': { param_types: [Clutter.Actor.$gtype, GObject.TYPE_DOUBLE, GObject.TYPE_DOUBLE] } },
|
||||
}, class Inspector extends Clutter.Actor {
|
||||
_init(lookingGlass) {
|
||||
super._init({ width: 0,
|
||||
height: 0 });
|
||||
super._init({ width: 0, height: 0 });
|
||||
|
||||
Main.uiGroup.add_actor(this);
|
||||
|
||||
@ -620,18 +631,20 @@ var Inspector = GObject.registerClass({
|
||||
}
|
||||
});
|
||||
|
||||
var Extensions = class Extensions {
|
||||
constructor(lookingGlass) {
|
||||
var Extensions = GObject.registerClass({
|
||||
GTypeName: 'LookingClass_Extensions'
|
||||
}, class Extensions extends St.BoxLayout {
|
||||
_init(lookingGlass) {
|
||||
super._init({ vertical: true, name: 'lookingGlassExtensions' });
|
||||
|
||||
this._lookingGlass = lookingGlass;
|
||||
this.actor = new St.BoxLayout({ vertical: true,
|
||||
name: 'lookingGlassExtensions' });
|
||||
this._noExtensions = new St.Label({ style_class: 'lg-extensions-none',
|
||||
text: _("No extensions installed") });
|
||||
this._numExtensions = 0;
|
||||
this._extensionsList = new St.BoxLayout({ vertical: true,
|
||||
style_class: 'lg-extensions-list' });
|
||||
this._extensionsList.add(this._noExtensions);
|
||||
this.actor.add(this._extensionsList);
|
||||
this.add(this._extensionsList);
|
||||
|
||||
Main.extensionManager.getUuids().forEach(uuid => {
|
||||
this._loadExtension(null, uuid);
|
||||
@ -759,10 +772,19 @@ var Extensions = class Extensions {
|
||||
|
||||
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._redBorderEffect = new RedBorderEffect();
|
||||
|
||||
@ -770,26 +792,18 @@ var LookingGlass = class LookingGlass {
|
||||
|
||||
this._it = null;
|
||||
this._offset = 0;
|
||||
this._results = [];
|
||||
|
||||
// Sort of magic, but...eh.
|
||||
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.connect('changed::monospace-font-name',
|
||||
this._updateFont.bind(this));
|
||||
this._updateFont();
|
||||
|
||||
// We want it to appear to slide out from underneath the panel
|
||||
Main.uiGroup.add_actor(this.actor);
|
||||
Main.uiGroup.set_child_below_sibling(this.actor,
|
||||
Main.uiGroup.add_actor(this);
|
||||
Main.uiGroup.set_child_below_sibling(this,
|
||||
Main.layoutManager.panelBox);
|
||||
Main.layoutManager.panelBox.connect('allocation-changed',
|
||||
this._queueResize.bind(this));
|
||||
@ -797,11 +811,11 @@ var LookingGlass = class LookingGlass {
|
||||
this._queueResize.bind(this));
|
||||
|
||||
this._objInspector = new ObjInspector(this);
|
||||
Main.uiGroup.add_actor(this._objInspector.actor);
|
||||
this._objInspector.actor.hide();
|
||||
Main.uiGroup.add_actor(this._objInspector);
|
||||
this._objInspector.hide();
|
||||
|
||||
let toolbar = new St.BoxLayout({ name: 'Toolbar' });
|
||||
this.actor.add_actor(toolbar);
|
||||
this.add_actor(toolbar);
|
||||
let inspectIcon = new St.Icon({ icon_name: 'gtk-color-picker',
|
||||
icon_size: 24 });
|
||||
toolbar.add_actor(inspectIcon);
|
||||
@ -812,10 +826,10 @@ var LookingGlass = class LookingGlass {
|
||||
this._pushResult(`inspect(${Math.round(stageX)}, ${Math.round(stageY)})`, target);
|
||||
});
|
||||
inspector.connect('closed', () => {
|
||||
this.actor.show();
|
||||
this.show();
|
||||
global.stage.set_key_focus(this._entry);
|
||||
});
|
||||
this.actor.hide();
|
||||
this.hide();
|
||||
return Clutter.EVENT_STOP;
|
||||
});
|
||||
|
||||
@ -837,7 +851,7 @@ var LookingGlass = class LookingGlass {
|
||||
|
||||
let notebook = new Notebook();
|
||||
this._notebook = notebook;
|
||||
this.actor.add(notebook.actor, { expand: true });
|
||||
this.add(notebook, { expand: true });
|
||||
|
||||
let emptyBox = new St.Bin();
|
||||
toolbar.add(emptyBox, { expand: true });
|
||||
@ -860,10 +874,10 @@ var LookingGlass = class LookingGlass {
|
||||
this._entryArea.add(this._entry, { expand: true });
|
||||
|
||||
this._windowList = new WindowList(this);
|
||||
notebook.appendPage('Windows', this._windowList.actor);
|
||||
notebook.appendPage('Windows', this._windowList);
|
||||
|
||||
this._extensions = new Extensions(this);
|
||||
notebook.appendPage('Extensions', this._extensions.actor);
|
||||
notebook.appendPage('Extensions', this._extensions);
|
||||
|
||||
this._entry.clutter_text.connect('activate', (o, _e) => {
|
||||
// Hide any completions we are currently showing
|
||||
@ -905,7 +919,7 @@ var LookingGlass = class LookingGlass {
|
||||
// monospace font to be bold/oblique/etc. Could easily be added here.
|
||||
let size = fontDesc.get_size() / 1024.;
|
||||
let unit = fontDesc.get_size_is_absolute() ? 'px' : 'pt';
|
||||
this.actor.style = `
|
||||
this.style = `
|
||||
font-size: ${size}${unit};
|
||||
font-family: "${fontDesc.get_family()}";`;
|
||||
}
|
||||
@ -919,17 +933,14 @@ var LookingGlass = class LookingGlass {
|
||||
}
|
||||
|
||||
_pushResult(command, obj) {
|
||||
let index = this._results.length + this._offset;
|
||||
let index = this._resultsArea.get_n_children() + this._offset;
|
||||
let result = new Result(this, CHEVRON + command, obj, index);
|
||||
this._results.push(result);
|
||||
this._resultsArea.add(result.actor);
|
||||
this._resultsArea.add(result);
|
||||
if (obj instanceof Clutter.Actor)
|
||||
this.setBorderPaintTarget(obj);
|
||||
|
||||
let children = this._resultsArea.get_children();
|
||||
if (children.length > this._maxItems) {
|
||||
this._results.shift();
|
||||
children[0].destroy();
|
||||
if (this._resultsArea.get_n_children() > this._maxItems) {
|
||||
this._resultsArea.get_first_child().destroy();
|
||||
this._offset++;
|
||||
}
|
||||
this._it = obj;
|
||||
@ -1016,7 +1027,7 @@ var LookingGlass = class LookingGlass {
|
||||
|
||||
getResult(idx) {
|
||||
try {
|
||||
return this._results[idx - this._offset].o;
|
||||
return this._resultsArea.get_child_at_index(idx - this._offset).o;
|
||||
} catch (e) {
|
||||
throw new Error(`Unknown result at index ${idx}`);
|
||||
}
|
||||
@ -1041,15 +1052,15 @@ var LookingGlass = class LookingGlass {
|
||||
let myWidth = primary.width * 0.7;
|
||||
let availableHeight = primary.height - Main.layoutManager.keyboardBox.height;
|
||||
let myHeight = Math.min(primary.height * 0.7, availableHeight * 0.9);
|
||||
this.actor.x = primary.x + (primary.width - myWidth) / 2;
|
||||
this.x = primary.x + (primary.width - myWidth) / 2;
|
||||
this._hiddenY = primary.y + Main.layoutManager.panelBox.height - myHeight;
|
||||
this._targetY = this._hiddenY + myHeight;
|
||||
this.actor.y = this._hiddenY;
|
||||
this.actor.width = myWidth;
|
||||
this.actor.height = myHeight;
|
||||
this._objInspector.actor.set_size(Math.floor(myWidth * 0.8), Math.floor(myHeight * 0.8));
|
||||
this._objInspector.actor.set_position(this.actor.x + Math.floor(myWidth * 0.1),
|
||||
this._targetY + Math.floor(myHeight * 0.1));
|
||||
this.y = this._hiddenY;
|
||||
this.width = myWidth;
|
||||
this.height = myHeight;
|
||||
this._objInspector.set_size(Math.floor(myWidth * 0.8), Math.floor(myHeight * 0.8));
|
||||
this._objInspector.set_position(this.x + Math.floor(myWidth * 0.1),
|
||||
this._targetY + Math.floor(myHeight * 0.1));
|
||||
}
|
||||
|
||||
insertObject(obj) {
|
||||
@ -1062,11 +1073,10 @@ var LookingGlass = class LookingGlass {
|
||||
}
|
||||
|
||||
// Handle key events which are relevant for all tabs of the LookingGlass
|
||||
_globalKeyPressEvent(actor, event) {
|
||||
let symbol = event.get_key_symbol();
|
||||
let modifierState = event.get_state();
|
||||
vfunc_key_press_event(keyPressEvent) {
|
||||
let symbol = keyPressEvent.keyval;
|
||||
if (symbol == Clutter.Escape) {
|
||||
if (this._objInspector.actor.visible) {
|
||||
if (this._objInspector.visible) {
|
||||
this._objInspector.close();
|
||||
} else {
|
||||
this.close();
|
||||
@ -1074,7 +1084,7 @@ var LookingGlass = class LookingGlass {
|
||||
return Clutter.EVENT_STOP;
|
||||
}
|
||||
// Ctrl+PgUp and Ctrl+PgDown switches tabs in the notebook view
|
||||
if (modifierState & Clutter.ModifierType.CONTROL_MASK) {
|
||||
if (keyPressEvent.modifier_state & Clutter.ModifierType.CONTROL_MASK) {
|
||||
if (symbol == Clutter.KEY_Page_Up) {
|
||||
this._notebook.prevTab();
|
||||
} else if (symbol == Clutter.KEY_Page_Down) {
|
||||
@ -1092,16 +1102,16 @@ var LookingGlass = class LookingGlass {
|
||||
return;
|
||||
|
||||
this._notebook.selectIndex(0);
|
||||
this.actor.show();
|
||||
this.show();
|
||||
this._open = true;
|
||||
this._history.lastItem();
|
||||
|
||||
this.actor.remove_all_transitions();
|
||||
this.remove_all_transitions();
|
||||
|
||||
// We inverse compensate for the slow-down so you can change the factor
|
||||
// through LookingGlass without long waits.
|
||||
let duration = LG_ANIMATION_TIME / St.Settings.get().slow_down_factor;
|
||||
this.actor.ease({
|
||||
this.ease({
|
||||
y: this._targetY,
|
||||
duration,
|
||||
mode: Clutter.AnimationMode.EASE_OUT_QUAD
|
||||
@ -1114,10 +1124,10 @@ var LookingGlass = class LookingGlass {
|
||||
if (!this._open)
|
||||
return;
|
||||
|
||||
this._objInspector.actor.hide();
|
||||
this._objInspector.hide();
|
||||
|
||||
this._open = false;
|
||||
this.actor.remove_all_transitions();
|
||||
this.remove_all_transitions();
|
||||
|
||||
this.setBorderPaintTarget(null);
|
||||
|
||||
@ -1126,16 +1136,15 @@ var LookingGlass = class LookingGlass {
|
||||
let settings = St.Settings.get();
|
||||
let duration = Math.min(LG_ANIMATION_TIME / settings.slow_down_factor,
|
||||
LG_ANIMATION_TIME);
|
||||
this.actor.ease({
|
||||
this.ease({
|
||||
y: this._hiddenY,
|
||||
duration,
|
||||
mode: Clutter.AnimationMode.EASE_OUT_QUAD,
|
||||
onComplete: () => this.actor.hide()
|
||||
onComplete: () => this.hide()
|
||||
});
|
||||
}
|
||||
|
||||
get isOpen() {
|
||||
return this._open;
|
||||
}
|
||||
};
|
||||
Signals.addSignalMethods(LookingGlass.prototype);
|
||||
});
|
||||
|
@ -1290,7 +1290,7 @@ var ZoomRegion = class ZoomRegion {
|
||||
|
||||
// Add a background for when the magnified uiGroup is scrolled
|
||||
// out of view (don't want to see desktop showing through).
|
||||
this._background = (new Background.SystemBackground()).actor;
|
||||
this._background = new Background.SystemBackground();
|
||||
mainGroup.add_actor(this._background);
|
||||
|
||||
// Clone the group that contains all of UI on the screen. This is the
|
||||
@ -1587,8 +1587,9 @@ var ZoomRegion = class ZoomRegion {
|
||||
}
|
||||
};
|
||||
|
||||
var Crosshairs = class Crosshairs {
|
||||
constructor() {
|
||||
var Crosshairs = GObject.registerClass(
|
||||
class Crosshairs extends Clutter.Actor {
|
||||
_init() {
|
||||
|
||||
// Set the group containing the crosshairs to three times the desktop
|
||||
// size in case the crosshairs need to appear to be infinite in
|
||||
@ -1596,7 +1597,7 @@ var Crosshairs = class Crosshairs {
|
||||
let groupWidth = global.screen_width * 3;
|
||||
let groupHeight = global.screen_height * 3;
|
||||
|
||||
this._actor = new Clutter.Actor({
|
||||
super._init({
|
||||
clip_to_allocation: false,
|
||||
width: groupWidth,
|
||||
height: groupHeight
|
||||
@ -1605,10 +1606,10 @@ var Crosshairs = class Crosshairs {
|
||||
this._horizRightHair = new Clutter.Actor();
|
||||
this._vertTopHair = new Clutter.Actor();
|
||||
this._vertBottomHair = new Clutter.Actor();
|
||||
this._actor.add_actor(this._horizLeftHair);
|
||||
this._actor.add_actor(this._horizRightHair);
|
||||
this._actor.add_actor(this._vertTopHair);
|
||||
this._actor.add_actor(this._vertBottomHair);
|
||||
this.add_actor(this._horizLeftHair);
|
||||
this.add_actor(this._horizRightHair);
|
||||
this.add_actor(this._vertTopHair);
|
||||
this.add_actor(this._vertBottomHair);
|
||||
this._clipSize = [0, 0];
|
||||
this._clones = [];
|
||||
this.reCenter();
|
||||
@ -1618,7 +1619,7 @@ var Crosshairs = class Crosshairs {
|
||||
}
|
||||
|
||||
_monitorsChanged() {
|
||||
this._actor.set_size(global.screen_width * 3, global.screen_height * 3);
|
||||
this.set_size(global.screen_width * 3, global.screen_height * 3);
|
||||
this.reCenter();
|
||||
}
|
||||
|
||||
@ -1639,12 +1640,15 @@ var Crosshairs = class Crosshairs {
|
||||
if (zoomRegion && magnifiedMouse) {
|
||||
let container = magnifiedMouse.get_parent();
|
||||
if (container) {
|
||||
crosshairsActor = this._actor;
|
||||
if (this._actor.get_parent() != null) {
|
||||
crosshairsActor = new Clutter.Clone({ source: this._actor });
|
||||
crosshairsActor = this;
|
||||
if (this.get_parent() != null) {
|
||||
crosshairsActor = new Clutter.Clone({ source: this });
|
||||
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.raise_child(magnifiedMouse, crosshairsActor);
|
||||
@ -1663,7 +1667,7 @@ var Crosshairs = class Crosshairs {
|
||||
* child actor if it was just a clone of the crosshairs actor.
|
||||
*/
|
||||
removeFromParent(childActor) {
|
||||
if (childActor == this._actor)
|
||||
if (childActor == this)
|
||||
childActor.get_parent().remove_actor(childActor);
|
||||
else
|
||||
childActor.destroy();
|
||||
@ -1773,28 +1777,6 @@ var Crosshairs = class Crosshairs {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 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:
|
||||
* Reposition the horizontal and vertical hairs such that they cross at
|
||||
@ -1803,7 +1785,7 @@ var Crosshairs = class Crosshairs {
|
||||
* @clipSize: Optional. If present, an array of the form [width, height].
|
||||
*/
|
||||
reCenter(clipSize) {
|
||||
let [groupWidth, groupHeight] = this._actor.get_size();
|
||||
let [groupWidth, groupHeight] = this.get_size();
|
||||
let leftLength = this._horizLeftHair.get_width();
|
||||
let topLength = this._vertTopHair.get_height();
|
||||
let thickness = this._horizLeftHair.get_height();
|
||||
@ -1825,7 +1807,7 @@ var Crosshairs = class Crosshairs {
|
||||
this._vertTopHair.set_position((groupWidth - thickness) / 2, top);
|
||||
this._vertBottomHair.set_position((groupWidth - thickness) / 2, bottom);
|
||||
}
|
||||
};
|
||||
});
|
||||
|
||||
var MagShaderEffects = class MagShaderEffects {
|
||||
constructor(uiGroupClone) {
|
||||
|
@ -189,7 +189,7 @@ function _initializeUI() {
|
||||
|
||||
messageTray = new MessageTray.MessageTray();
|
||||
panel = new Panel.Panel();
|
||||
keyboard = new Keyboard.Keyboard();
|
||||
keyboard = new Keyboard.KeyboardManager();
|
||||
notificationDaemon = new NotificationDaemon.NotificationDaemon();
|
||||
windowAttentionHandler = new WindowAttentionHandler.WindowAttentionHandler();
|
||||
componentManager = new Components.ComponentManager();
|
||||
@ -403,7 +403,7 @@ function notify(msg, details) {
|
||||
messageTray.add(source);
|
||||
let notification = new MessageTray.Notification(source, msg, details);
|
||||
notification.setTransient(true);
|
||||
source.notify(notification);
|
||||
source.showNotification(notification);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1,7 +1,8 @@
|
||||
const { Atk, Clutter, Gio, GLib, GObject, Meta, Pango, St } = imports.gi;
|
||||
/* exported MessageListSection */
|
||||
const { Atk, Clutter, Gio, GLib,
|
||||
GObject, Graphene, Meta, Pango, St } = imports.gi;
|
||||
const Main = imports.ui.main;
|
||||
const MessageTray = imports.ui.messageTray;
|
||||
const Signals = imports.signals;
|
||||
|
||||
const Calendar = imports.ui.calendar;
|
||||
const Util = imports.misc.util;
|
||||
@ -31,13 +32,18 @@ function _fixMarkup(text, allowMarkup) {
|
||||
return GLib.markup_escape_text(text, -1);
|
||||
}
|
||||
|
||||
var URLHighlighter = class URLHighlighter {
|
||||
constructor(text = '', lineWrap, allowMarkup) {
|
||||
this.actor = new St.Label({ reactive: true, style_class: 'url-highlighter',
|
||||
x_expand: true, x_align: Clutter.ActorAlign.START });
|
||||
var URLHighlighter = GObject.registerClass(
|
||||
class URLHighlighter extends St.Label {
|
||||
_init(text = '', lineWrap, allowMarkup) {
|
||||
super._init({
|
||||
reactive: true,
|
||||
style_class: 'url-highlighter',
|
||||
x_expand: true,
|
||||
x_align: Clutter.ActorAlign.START
|
||||
});
|
||||
this._linkColor = '#ccccff';
|
||||
this.actor.connect('style-changed', () => {
|
||||
let [hasColor, color] = this.actor.get_theme_node().lookup_color('link-color', false);
|
||||
this.connect('style-changed', () => {
|
||||
let [hasColor, color] = this.get_theme_node().lookup_color('link-color', false);
|
||||
if (hasColor) {
|
||||
let linkColor = color.to_string().substr(0, 7);
|
||||
if (linkColor != this._linkColor) {
|
||||
@ -46,70 +52,75 @@ var URLHighlighter = class URLHighlighter {
|
||||
}
|
||||
}
|
||||
});
|
||||
this.actor.clutter_text.line_wrap = lineWrap;
|
||||
this.actor.clutter_text.line_wrap_mode = Pango.WrapMode.WORD_CHAR;
|
||||
this.clutter_text.line_wrap = lineWrap;
|
||||
this.clutter_text.line_wrap_mode = Pango.WrapMode.WORD_CHAR;
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
// Keep Notification.actor from seeing this and taking
|
||||
// a pointer grab, which would block our button-release-event
|
||||
// handler, if an URL is clicked
|
||||
return this._findUrlAtPos(event) != -1;
|
||||
});
|
||||
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;
|
||||
}
|
||||
vfunc_button_press_event(buttonEvent) {
|
||||
// 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 (!this.visible || this.get_paint_opacity() == 0)
|
||||
return Clutter.EVENT_PROPAGATE;
|
||||
});
|
||||
this.actor.connect('motion-event', (actor, event) => {
|
||||
if (!actor.visible || actor.get_paint_opacity() == 0)
|
||||
return Clutter.EVENT_PROPAGATE;
|
||||
|
||||
let urlId = this._findUrlAtPos(event);
|
||||
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;
|
||||
});
|
||||
this.actor.connect('leave-event', () => {
|
||||
if (!this.actor.visible || this.actor.get_paint_opacity() == 0)
|
||||
return Clutter.EVENT_PROPAGATE;
|
||||
// Keep Notification from seeing this and taking
|
||||
// a pointer grab, which would block our button-release-event
|
||||
// handler, if an URL is clicked
|
||||
return this._findUrlAtPos(buttonEvent) != -1;
|
||||
}
|
||||
|
||||
if (this._cursorChanged) {
|
||||
this._cursorChanged = false;
|
||||
global.display.set_cursor(Meta.Cursor.DEFAULT);
|
||||
}
|
||||
vfunc_button_release_event(buttonEvent) {
|
||||
if (!this.visible || this.get_paint_opacity() == 0)
|
||||
return Clutter.EVENT_PROPAGATE;
|
||||
});
|
||||
|
||||
let urlId = this._findUrlAtPos(buttonEvent);
|
||||
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;
|
||||
}
|
||||
|
||||
vfunc_motion_event(motionEvent) {
|
||||
if (!this.visible || this.get_paint_opacity() == 0)
|
||||
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) {
|
||||
text = text ? _fixMarkup(text, allowMarkup) : '';
|
||||
this._text = text;
|
||||
|
||||
this.actor.clutter_text.set_markup(text);
|
||||
this.clutter_text.set_markup(text);
|
||||
/* clutter_text.text contain text without markup */
|
||||
this._urls = Util.findUrls(this.actor.clutter_text.text);
|
||||
this._urls = Util.findUrls(this.clutter_text.text);
|
||||
this._highlightUrls();
|
||||
}
|
||||
|
||||
@ -125,16 +136,15 @@ var URLHighlighter = class URLHighlighter {
|
||||
pos = url.pos + url.url.length;
|
||||
}
|
||||
markup += this._text.substr(pos);
|
||||
this.actor.clutter_text.set_markup(markup);
|
||||
this.clutter_text.set_markup(markup);
|
||||
}
|
||||
|
||||
_findUrlAtPos(event) {
|
||||
let success_;
|
||||
let [x, y] = event.get_coords();
|
||||
[success_, x, y] = this.actor.transform_stage_point(x, y);
|
||||
let { x, y } = event;
|
||||
[, x, y] = this.transform_stage_point(x, y);
|
||||
let findPos = -1;
|
||||
for (let i = 0; i < this.actor.clutter_text.text.length; i++) {
|
||||
let [success_, px, py, lineHeight] = this.actor.clutter_text.position_to_coords(i);
|
||||
for (let i = 0; i < this.clutter_text.text.length; i++) {
|
||||
let [, px, py, lineHeight] = this.clutter_text.position_to_coords(i);
|
||||
if (py > y || py + lineHeight < y || x < px)
|
||||
continue;
|
||||
findPos = i;
|
||||
@ -147,7 +157,7 @@ var URLHighlighter = class URLHighlighter {
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
};
|
||||
});
|
||||
|
||||
var ScaleLayout = GObject.registerClass(
|
||||
class ScaleLayout extends Clutter.BinLayout {
|
||||
@ -283,21 +293,29 @@ var LabelExpanderLayout = GObject.registerClass({
|
||||
}
|
||||
});
|
||||
|
||||
var Message = class Message {
|
||||
constructor(title, body) {
|
||||
this.expanded = false;
|
||||
|
||||
var Message = GObject.registerClass({
|
||||
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._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 });
|
||||
this.actor.set_child(vbox);
|
||||
this.set_child(vbox);
|
||||
|
||||
let hbox = new St.BoxLayout();
|
||||
vbox.add_actor(hbox);
|
||||
@ -341,15 +359,14 @@ var Message = class Message {
|
||||
contentBox.add_actor(this._bodyStack);
|
||||
|
||||
this.bodyLabel = new URLHighlighter('', false, this._useBodyMarkup);
|
||||
this.bodyLabel.actor.add_style_class_name('message-body');
|
||||
this._bodyStack.add_actor(this.bodyLabel.actor);
|
||||
this.bodyLabel.add_style_class_name('message-body');
|
||||
this._bodyStack.add_actor(this.bodyLabel);
|
||||
this.setBody(body);
|
||||
|
||||
this._closeButton.connect('clicked', this.close.bind(this));
|
||||
let actorHoverId = this.actor.connect('notify::hover', this._sync.bind(this));
|
||||
this._closeButton.connect('destroy', this.actor.disconnect.bind(this.actor, actorHoverId));
|
||||
this.actor.connect('clicked', this._onClicked.bind(this));
|
||||
this.actor.connect('destroy', this._onDestroy.bind(this));
|
||||
let actorHoverId = this.connect('notify::hover', this._sync.bind(this));
|
||||
this._closeButton.connect('destroy', this.disconnect.bind(this, actorHoverId));
|
||||
this.connect('destroy', this._onDestroy.bind(this));
|
||||
this._sync();
|
||||
}
|
||||
|
||||
@ -435,7 +452,7 @@ var Message = class Message {
|
||||
if (this._bodyStack.get_n_children() < 2) {
|
||||
this._expandedLabel = new URLHighlighter(this._bodyText,
|
||||
true, this._useBodyMarkup);
|
||||
this.setExpandedBody(this._expandedLabel.actor);
|
||||
this.setExpandedBody(this._expandedLabel);
|
||||
}
|
||||
|
||||
if (animate) {
|
||||
@ -488,19 +505,16 @@ var Message = class Message {
|
||||
}
|
||||
|
||||
_sync() {
|
||||
let visible = this.actor.hover && this.canClose();
|
||||
let visible = this.hover && this.canClose();
|
||||
this._closeButton.opacity = visible ? 255 : 0;
|
||||
this._closeButton.reactive = visible;
|
||||
}
|
||||
|
||||
_onClicked() {
|
||||
}
|
||||
|
||||
_onDestroy() {
|
||||
}
|
||||
|
||||
_onKeyPressed(a, event) {
|
||||
let keysym = event.get_key_symbol();
|
||||
vfunc_key_press_event(keyEvent) {
|
||||
let keysym = keyEvent.keyval;
|
||||
|
||||
if (keysym == Clutter.KEY_Delete ||
|
||||
keysym == Clutter.KEY_KP_Delete) {
|
||||
@ -509,37 +523,66 @@ var Message = class Message {
|
||||
}
|
||||
return Clutter.EVENT_PROPAGATE;
|
||||
}
|
||||
};
|
||||
Signals.addSignalMethods(Message.prototype);
|
||||
});
|
||||
|
||||
var MessageListSection = class MessageListSection {
|
||||
constructor() {
|
||||
this.actor = new St.BoxLayout({ style_class: 'message-list-section',
|
||||
clip_to_allocation: true,
|
||||
x_expand: true, vertical: true });
|
||||
var MessageListSection = GObject.registerClass({
|
||||
Properties: {
|
||||
'can-clear': GObject.ParamSpec.boolean(
|
||||
'can-clear', 'can-clear', 'can-clear',
|
||||
GObject.ParamFlags.READABLE,
|
||||
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',
|
||||
vertical: true });
|
||||
this.actor.add_actor(this._list);
|
||||
this.add_actor(this._list);
|
||||
|
||||
this._list.connect('actor-added', this._sync.bind(this));
|
||||
this._list.connect('actor-removed', this._sync.bind(this));
|
||||
|
||||
let id = Main.sessionMode.connect('updated',
|
||||
this._sync.bind(this));
|
||||
this.actor.connect('destroy', () => {
|
||||
this.connect('destroy', () => {
|
||||
Main.sessionMode.disconnect(id);
|
||||
});
|
||||
|
||||
this._messages = new Map();
|
||||
this._date = new Date();
|
||||
this.empty = true;
|
||||
this.canClear = false;
|
||||
this._empty = true;
|
||||
this._canClear = false;
|
||||
this._sync();
|
||||
}
|
||||
|
||||
_onKeyFocusIn(actor) {
|
||||
this.emit('key-focus-in', actor);
|
||||
get empty() {
|
||||
return this._empty;
|
||||
}
|
||||
|
||||
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() {
|
||||
@ -558,58 +601,62 @@ var MessageListSection = class MessageListSection {
|
||||
}
|
||||
|
||||
addMessageAtIndex(message, index, animate) {
|
||||
let obj = {
|
||||
container: null,
|
||||
destroyId: 0,
|
||||
keyFocusId: 0,
|
||||
closeId: 0
|
||||
};
|
||||
let pivot = new Clutter.Point({ x: .5, y: .5 });
|
||||
let scale = animate ? 0 : 1;
|
||||
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);
|
||||
if (this._messages.includes(message))
|
||||
throw new Error('Message was already added previously');
|
||||
|
||||
let listItem = new St.Bin({
|
||||
child: message,
|
||||
x_fill: true,
|
||||
y_fill: true,
|
||||
layout_manager: new ScaleLayout(),
|
||||
pivot_point: new Graphene.Point({ x: .5, y: .5 }),
|
||||
});
|
||||
obj.closeId = message.connect('close', () => {
|
||||
listItem._connectionsIds = [];
|
||||
|
||||
listItem._connectionsIds.push(message.connect('key-focus-in',
|
||||
this._onKeyFocusIn.bind(this)));
|
||||
listItem._connectionsIds.push(message.connect('close', () => {
|
||||
this.removeMessage(message, true);
|
||||
});
|
||||
}));
|
||||
listItem._connectionsIds.push(message.connect('destroy', () => {
|
||||
listItem._connectionsIds.forEach(id => message.disconnect(id));
|
||||
listItem.destroy();
|
||||
}));
|
||||
|
||||
this._messages.set(message, obj);
|
||||
obj.container.add_actor(message.actor);
|
||||
this._list.insert_child_at_index(listItem, index);
|
||||
|
||||
this._list.insert_child_at_index(obj.container, index);
|
||||
|
||||
if (animate)
|
||||
obj.container.ease({
|
||||
if (animate) {
|
||||
listItem.set({ scale_x: 0, scale_y: 0 });
|
||||
listItem.ease({
|
||||
scale_x: 1,
|
||||
scale_y: 1,
|
||||
duration: MESSAGE_ANIMATION_TIME,
|
||||
mode: Clutter.AnimationMode.EASE_OUT_QUAD
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
moveMessage(message, index, animate) {
|
||||
let obj = this._messages.get(message);
|
||||
if (!this._messages.includes(message))
|
||||
throw new Error(`Impossible to move the untracked message ${message}`);
|
||||
|
||||
let listItem = message.get_parent();
|
||||
|
||||
if (!animate) {
|
||||
this._list.set_child_at_index(obj.container, index);
|
||||
this._list.set_child_at_index(listItem, index);
|
||||
return;
|
||||
}
|
||||
|
||||
let onComplete = () => {
|
||||
this._list.set_child_at_index(obj.container, index);
|
||||
obj.container.ease({
|
||||
this._list.set_child_at_index(listItem, index);
|
||||
listItem.ease({
|
||||
scale_x: 1,
|
||||
scale_y: 1,
|
||||
duration: MESSAGE_ANIMATION_TIME,
|
||||
mode: Clutter.AnimationMode.EASE_OUT_QUAD
|
||||
});
|
||||
};
|
||||
obj.container.ease({
|
||||
listItem.ease({
|
||||
scale_x: 0,
|
||||
scale_y: 0,
|
||||
duration: MESSAGE_ANIMATION_TIME,
|
||||
@ -619,33 +666,31 @@ var MessageListSection = class MessageListSection {
|
||||
}
|
||||
|
||||
removeMessage(message, animate) {
|
||||
let obj = this._messages.get(message);
|
||||
if (!this._messages.includes(message))
|
||||
throw new Error(`Impossible to remove the untracked message ${message}`);
|
||||
|
||||
message.actor.disconnect(obj.destroyId);
|
||||
message.actor.disconnect(obj.keyFocusId);
|
||||
message.disconnect(obj.closeId);
|
||||
|
||||
this._messages.delete(message);
|
||||
let listItem = message.get_parent();
|
||||
listItem._connectionsIds.forEach(id => message.disconnect(id));
|
||||
|
||||
if (animate) {
|
||||
obj.container.ease({
|
||||
listItem.ease({
|
||||
scale_x: 0,
|
||||
scale_y: 0,
|
||||
duration: MESSAGE_ANIMATION_TIME,
|
||||
mode: Clutter.AnimationMode.EASE_OUT_QUAD,
|
||||
onComplete: () => {
|
||||
obj.container.destroy();
|
||||
listItem.destroy();
|
||||
global.sync_pointer();
|
||||
}
|
||||
});
|
||||
} else {
|
||||
obj.container.destroy();
|
||||
listItem.destroy();
|
||||
global.sync_pointer();
|
||||
}
|
||||
}
|
||||
|
||||
clear() {
|
||||
let messages = [...this._messages.keys()].filter(msg => msg.canClose());
|
||||
let messages = this._messages.filter(msg => msg.canClose());
|
||||
|
||||
// If there are few messages, letting them all zoom out looks OK
|
||||
if (messages.length < 2) {
|
||||
@ -658,9 +703,8 @@ var MessageListSection = class MessageListSection {
|
||||
let delay = MESSAGE_ANIMATION_TIME / Math.max(messages.length, 5);
|
||||
for (let i = 0; i < messages.length; i++) {
|
||||
let message = messages[i];
|
||||
let obj = this._messages.get(message);
|
||||
obj.container.ease({
|
||||
anchor_x: this._list.width,
|
||||
message.get_parent().ease({
|
||||
translation_x: this._list.width,
|
||||
opacity: 0,
|
||||
duration: MESSAGE_ANIMATION_TIME,
|
||||
delay: i * delay,
|
||||
@ -671,33 +715,25 @@ var MessageListSection = class MessageListSection {
|
||||
}
|
||||
}
|
||||
|
||||
_canClear() {
|
||||
for (let message of this._messages.keys())
|
||||
if (message.canClose())
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
_shouldShow() {
|
||||
return !this.empty;
|
||||
}
|
||||
|
||||
_sync() {
|
||||
let empty = this._list.get_n_children() == 0;
|
||||
let changed = this.empty !== empty;
|
||||
this.empty = empty;
|
||||
let messages = this._messages;
|
||||
let empty = messages.length == 0;
|
||||
|
||||
if (changed)
|
||||
this.emit('empty-changed');
|
||||
if (this._empty != empty) {
|
||||
this._empty = empty;
|
||||
this.notify('empty');
|
||||
}
|
||||
|
||||
let canClear = this._canClear();
|
||||
changed = this.canClear !== canClear;
|
||||
this.canClear = canClear;
|
||||
let canClear = messages.some(m => m.canClose());
|
||||
if (this._canClear != canClear) {
|
||||
this._canClear = canClear;
|
||||
this.notify('can-clear');
|
||||
}
|
||||
|
||||
if (changed)
|
||||
this.emit('can-clear-changed');
|
||||
|
||||
this.actor.visible = this.allowed && this._shouldShow();
|
||||
this.visible = this.allowed && this._shouldShow();
|
||||
}
|
||||
};
|
||||
Signals.addSignalMethods(MessageListSection.prototype);
|
||||
});
|
||||
|
@ -4,7 +4,6 @@
|
||||
SystemNotificationSource, MessageTray */
|
||||
|
||||
const { Clutter, Gio, GLib, GObject, Meta, Shell, St } = imports.gi;
|
||||
const Signals = imports.signals;
|
||||
|
||||
const Calendar = imports.ui.calendar;
|
||||
const GnomeSession = imports.misc.gnomeSession;
|
||||
@ -134,72 +133,84 @@ var FocusGrabber = class FocusGrabber {
|
||||
// source, such as whether to play sound or honour the critical bit.
|
||||
//
|
||||
// A notification without a policy object will inherit the default one.
|
||||
var NotificationPolicy = class NotificationPolicy {
|
||||
constructor(params) {
|
||||
params = Params.parse(params, {
|
||||
enable: true,
|
||||
enableSound: true,
|
||||
showBanners: true,
|
||||
forceExpanded: false,
|
||||
showInLockScreen: true,
|
||||
detailsInLockScreen: false,
|
||||
});
|
||||
Object.getOwnPropertyNames(params).forEach(key => {
|
||||
let desc = Object.getOwnPropertyDescriptor(params, key);
|
||||
Object.defineProperty(this, `_${key}`, desc);
|
||||
});
|
||||
var NotificationPolicy = GObject.registerClass({
|
||||
GTypeName: 'MessageTray_NotificationPolicy',
|
||||
Properties: {
|
||||
'enable': GObject.ParamSpec.boolean(
|
||||
'enable', 'enable', 'enable',
|
||||
GObject.ParamFlags.READWRITE | GObject.ParamFlags.CONSTRUCT_ONLY,
|
||||
true),
|
||||
'enable-sound': GObject.ParamSpec.boolean(
|
||||
'enable-sound', 'enable-sound', 'enable-sound',
|
||||
GObject.ParamFlags.READWRITE | GObject.ParamFlags.CONSTRUCT_ONLY,
|
||||
true),
|
||||
'show-banners': GObject.ParamSpec.boolean(
|
||||
'show-banners', 'show-banners', 'show-banners',
|
||||
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
|
||||
// GSettings policy.
|
||||
store() { }
|
||||
|
||||
destroy() { }
|
||||
|
||||
get enable() {
|
||||
return this._enable;
|
||||
destroy() {
|
||||
this.run_dispose();
|
||||
}
|
||||
|
||||
get enableSound() {
|
||||
return this._enableSound;
|
||||
return this.enable_sound;
|
||||
}
|
||||
|
||||
get showBanners() {
|
||||
return this._showBanners;
|
||||
return this.show_banners;
|
||||
}
|
||||
|
||||
get forceExpanded() {
|
||||
return this._forceExpanded;
|
||||
return this.force_expanded;
|
||||
}
|
||||
|
||||
get showInLockScreen() {
|
||||
return this._showInLockScreen;
|
||||
return this.show_in_lock_screen;
|
||||
}
|
||||
|
||||
get detailsInLockScreen() {
|
||||
return this._detailsInLockScreen;
|
||||
return this.details_in_lock_screen;
|
||||
}
|
||||
};
|
||||
Signals.addSignalMethods(NotificationPolicy.prototype);
|
||||
});
|
||||
|
||||
var NotificationGenericPolicy =
|
||||
class NotificationGenericPolicy extends NotificationPolicy {
|
||||
constructor() {
|
||||
super();
|
||||
var NotificationGenericPolicy = GObject.registerClass({
|
||||
GTypeName: 'MessageTray_NotificationGenericPolicy'
|
||||
}, class NotificationGenericPolicy extends NotificationPolicy {
|
||||
_init() {
|
||||
super._init();
|
||||
this.id = 'generic';
|
||||
|
||||
this._masterSettings = new Gio.Settings({ schema_id: 'org.gnome.desktop.notifications' });
|
||||
this._masterSettings.connect('changed', this._changed.bind(this));
|
||||
}
|
||||
|
||||
store() { }
|
||||
|
||||
destroy() {
|
||||
this._masterSettings.run_dispose();
|
||||
|
||||
super.destroy();
|
||||
}
|
||||
|
||||
_changed(settings, key) {
|
||||
this.emit('policy-changed', key);
|
||||
if (this.constructor.find_property(key))
|
||||
this.notify(key);
|
||||
}
|
||||
|
||||
get showBanners() {
|
||||
@ -209,12 +220,13 @@ class NotificationGenericPolicy extends NotificationPolicy {
|
||||
get showInLockScreen() {
|
||||
return this._masterSettings.get_boolean('show-in-lock-screen');
|
||||
}
|
||||
};
|
||||
});
|
||||
|
||||
var NotificationApplicationPolicy =
|
||||
class NotificationApplicationPolicy extends NotificationPolicy {
|
||||
constructor(id) {
|
||||
super();
|
||||
var NotificationApplicationPolicy = GObject.registerClass({
|
||||
GTypeName: 'MessageTray_NotificationApplicationPolicy'
|
||||
}, class NotificationApplicationPolicy extends NotificationPolicy {
|
||||
_init(id) {
|
||||
super._init();
|
||||
|
||||
this.id = id;
|
||||
this._canonicalId = this._canonicalizeId(id);
|
||||
@ -240,12 +252,13 @@ class NotificationApplicationPolicy extends NotificationPolicy {
|
||||
destroy() {
|
||||
this._masterSettings.run_dispose();
|
||||
this._settings.run_dispose();
|
||||
|
||||
super.destroy();
|
||||
}
|
||||
|
||||
_changed(settings, key) {
|
||||
this.emit('policy-changed', key);
|
||||
if (key == 'enable')
|
||||
this.emit('enable-changed');
|
||||
if (this.constructor.find_property(key))
|
||||
this.notify(key);
|
||||
}
|
||||
|
||||
_canonicalizeId(id) {
|
||||
@ -279,7 +292,7 @@ class NotificationApplicationPolicy extends NotificationPolicy {
|
||||
get detailsInLockScreen() {
|
||||
return this._settings.get_boolean('details-in-lock-screen');
|
||||
}
|
||||
};
|
||||
});
|
||||
|
||||
// Notification:
|
||||
// @source: the notification's Source
|
||||
@ -336,12 +349,26 @@ class NotificationApplicationPolicy extends NotificationPolicy {
|
||||
// @source allows playing sounds).
|
||||
//
|
||||
// [1] https://developer.gnome.org/notification-spec/#markup
|
||||
var Notification = class Notification {
|
||||
constructor(source, title, banner, params) {
|
||||
var Notification = GObject.registerClass({
|
||||
GTypeName: 'MessageTray_Notification',
|
||||
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.title = title;
|
||||
this.urgency = Urgency.NORMAL;
|
||||
this.resident = false;
|
||||
// 'transient' is a reserved keyword in JS, so we have to use an alternate variable name
|
||||
this.isTransient = false;
|
||||
this.privacyScope = PrivacyScope.USER;
|
||||
@ -353,6 +380,7 @@ var Notification = class Notification {
|
||||
this._soundFile = null;
|
||||
this._soundPlayed = false;
|
||||
this.actions = [];
|
||||
this.setResident(false);
|
||||
|
||||
// If called with only one argument we assume the caller
|
||||
// will call .update() later on. This is the case of
|
||||
@ -422,7 +450,7 @@ var Notification = class Notification {
|
||||
if (this._acknowledged == v)
|
||||
return;
|
||||
this._acknowledged = v;
|
||||
this.emit('acknowledged-changed');
|
||||
this.notify('acknowledged');
|
||||
}
|
||||
|
||||
setUrgency(urgency) {
|
||||
@ -431,6 +459,15 @@ var Notification = class Notification {
|
||||
|
||||
setResident(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) {
|
||||
@ -472,23 +509,30 @@ var Notification = class Notification {
|
||||
|
||||
activate() {
|
||||
this.emit('activated');
|
||||
if (!this.resident)
|
||||
this.destroy();
|
||||
}
|
||||
|
||||
destroy(reason = NotificationDestroyedReason.DISMISSED) {
|
||||
if (this._activatedId) {
|
||||
this.disconnect(this._activatedId);
|
||||
delete this._activatedId;
|
||||
}
|
||||
|
||||
this.emit('destroy', reason);
|
||||
this.run_dispose();
|
||||
}
|
||||
};
|
||||
Signals.addSignalMethods(Notification.prototype);
|
||||
});
|
||||
|
||||
var NotificationBanner =
|
||||
class NotificationBanner extends Calendar.NotificationMessage {
|
||||
constructor(notification) {
|
||||
super(notification);
|
||||
var NotificationBanner = GObject.registerClass({
|
||||
Signals: {
|
||||
'done-displaying': {},
|
||||
'unfocused': {},
|
||||
}
|
||||
}, class NotificationBanner extends Calendar.NotificationMessage {
|
||||
_init(notification) {
|
||||
super._init(notification);
|
||||
|
||||
this.actor.can_focus = false;
|
||||
this.actor.add_style_class_name('notification-banner');
|
||||
this.can_focus = false;
|
||||
this.add_style_class_name('notification-banner');
|
||||
|
||||
this._buttonBox = null;
|
||||
|
||||
@ -575,7 +619,7 @@ class NotificationBanner extends Calendar.NotificationMessage {
|
||||
|
||||
return this.addButton(button, callback);
|
||||
}
|
||||
};
|
||||
});
|
||||
|
||||
var SourceActor = GObject.registerClass(
|
||||
class SourceActor extends St.Widget {
|
||||
@ -640,7 +684,7 @@ class SourceActorWithLabel extends SourceActor {
|
||||
|
||||
this.add_actor(this._counterBin);
|
||||
|
||||
this._countUpdatedId = this._source.connect('count-updated', this._updateCount.bind(this));
|
||||
this._countUpdatedId = this._source.connect('notify::count', this._updateCount.bind(this));
|
||||
this._updateCount();
|
||||
|
||||
this.connect('destroy', () => {
|
||||
@ -688,11 +732,34 @@ class SourceActorWithLabel extends SourceActor {
|
||||
}
|
||||
});
|
||||
|
||||
var Source = class Source {
|
||||
constructor(title, iconName) {
|
||||
var Source = GObject.registerClass({
|
||||
GTypeName: 'MessageTray_Source',
|
||||
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.title = title;
|
||||
this.iconName = iconName;
|
||||
|
||||
this.isChat = false;
|
||||
@ -727,7 +794,7 @@ var Source = class Source {
|
||||
}
|
||||
|
||||
countUpdated() {
|
||||
this.emit('count-updated');
|
||||
super.notify('count');
|
||||
}
|
||||
|
||||
_createPolicy() {
|
||||
@ -741,8 +808,11 @@ var Source = class Source {
|
||||
}
|
||||
|
||||
setTitle(newTitle) {
|
||||
if (this.title == newTitle)
|
||||
return;
|
||||
|
||||
this.title = newTitle;
|
||||
this.emit('title-changed');
|
||||
this.notify('title');
|
||||
}
|
||||
|
||||
createBanner(notification) {
|
||||
@ -767,10 +837,10 @@ var Source = class Source {
|
||||
return;
|
||||
|
||||
this.notifications.splice(index, 1);
|
||||
this.countUpdated();
|
||||
|
||||
if (this.notifications.length == 0)
|
||||
this.destroy();
|
||||
|
||||
this.countUpdated();
|
||||
}
|
||||
|
||||
pushNotification(notification) {
|
||||
@ -781,24 +851,39 @@ var Source = class Source {
|
||||
this.notifications.shift().destroy(NotificationDestroyedReason.EXPIRED);
|
||||
|
||||
notification.connect('destroy', this._onNotificationDestroy.bind(this));
|
||||
notification.connect('acknowledged-changed', this.countUpdated.bind(this));
|
||||
notification.connect('notify::acknowledged', this.countUpdated.bind(this));
|
||||
this.notifications.push(notification);
|
||||
this.emit('notification-added', notification);
|
||||
|
||||
this.countUpdated();
|
||||
}
|
||||
|
||||
notify(notification) {
|
||||
showNotification(notification) {
|
||||
notification.acknowledged = false;
|
||||
this.pushNotification(notification);
|
||||
|
||||
if (this.policy.showBanners || notification.urgency == Urgency.CRITICAL) {
|
||||
this.emit('notify', notification);
|
||||
this.emit('notification-show', notification);
|
||||
} else {
|
||||
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) {
|
||||
this.policy.destroy();
|
||||
|
||||
@ -809,6 +894,8 @@ var Source = class Source {
|
||||
notifications[i].destroy(reason);
|
||||
|
||||
this.emit('destroy', reason);
|
||||
|
||||
this.run_dispose();
|
||||
}
|
||||
|
||||
iconUpdated() {
|
||||
@ -823,14 +910,23 @@ var Source = class Source {
|
||||
for (let i = this.notifications.length - 1; i >= 0; i--)
|
||||
if (!this.notifications[i].resident)
|
||||
this.notifications[i].destroy();
|
||||
|
||||
this.countUpdated();
|
||||
}
|
||||
};
|
||||
Signals.addSignalMethods(Source.prototype);
|
||||
});
|
||||
|
||||
var MessageTray = GObject.registerClass({
|
||||
Signals: {
|
||||
'queue-changed': {},
|
||||
'source-added': { param_types: [Source.$gtype] },
|
||||
'source-removed': { param_types: [Source.$gtype] },
|
||||
}
|
||||
}, class MessageTray extends St.Widget {
|
||||
_init() {
|
||||
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._onStatusChanged(proxy.status);
|
||||
});
|
||||
@ -847,18 +943,15 @@ var MessageTray = class MessageTray {
|
||||
// so fix up Clutter's view of the pointer position in
|
||||
// that case.
|
||||
let related = ev.get_related();
|
||||
if (!related || this.actor.contains(related))
|
||||
if (!related || this.contains(related))
|
||||
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 });
|
||||
Main.layoutManager.panelBox.bind_property('visible',
|
||||
constraint, 'work-area',
|
||||
GObject.BindingFlags.SYNC_CREATE);
|
||||
this.actor.add_constraint(constraint);
|
||||
this.add_constraint(constraint);
|
||||
|
||||
this._bannerBin = new St.Widget({ name: 'notification-container',
|
||||
reactive: true,
|
||||
@ -872,7 +965,7 @@ var MessageTray = class MessageTray {
|
||||
this._onNotificationKeyRelease.bind(this));
|
||||
this._bannerBin.connect('notify::hover',
|
||||
this._onNotificationHoverChanged.bind(this));
|
||||
this.actor.add_actor(this._bannerBin);
|
||||
this.add_actor(this._bannerBin);
|
||||
|
||||
this._notificationFocusGrabber = new FocusGrabber(this._bannerBin);
|
||||
this._notificationQueue = [];
|
||||
@ -901,7 +994,7 @@ var MessageTray = class MessageTray {
|
||||
this._notificationTimeoutId = 0;
|
||||
this._notificationRemoved = false;
|
||||
|
||||
Main.layoutManager.addChrome(this.actor, { affectsInputRegion: false });
|
||||
Main.layoutManager.addChrome(this, { affectsInputRegion: false });
|
||||
Main.layoutManager.trackChrome(this._bannerBin, { affectsInputRegion: true });
|
||||
|
||||
global.display.connect('in-fullscreen-changed', this._updateState.bind(this));
|
||||
@ -944,11 +1037,11 @@ var MessageTray = class MessageTray {
|
||||
}
|
||||
|
||||
_onDragBegin() {
|
||||
Shell.util_set_hidden_from_pick(this.actor, true);
|
||||
Shell.util_set_hidden_from_pick(this, true);
|
||||
}
|
||||
|
||||
_onDragEnd() {
|
||||
Shell.util_set_hidden_from_pick(this.actor, false);
|
||||
Shell.util_set_hidden_from_pick(this, false);
|
||||
}
|
||||
|
||||
get bannerAlignment() {
|
||||
@ -997,22 +1090,22 @@ var MessageTray = class MessageTray {
|
||||
// Register that we got a notification for this source
|
||||
source.policy.store();
|
||||
|
||||
source.policy.connect('enable-changed', () => {
|
||||
source.policy.connect('notify::enable', () => {
|
||||
this._onSourceEnableChanged(source.policy, source);
|
||||
});
|
||||
source.policy.connect('policy-changed', this._updateState.bind(this));
|
||||
source.policy.connect('notify', this._updateState.bind(this));
|
||||
this._onSourceEnableChanged(source.policy, source);
|
||||
}
|
||||
|
||||
_addSource(source) {
|
||||
let obj = {
|
||||
notifyId: 0,
|
||||
showId: 0,
|
||||
destroyId: 0,
|
||||
};
|
||||
|
||||
this._sources.set(source, obj);
|
||||
|
||||
obj.notifyId = source.connect('notify', this._onNotify.bind(this));
|
||||
obj.showId = source.connect('notification-show', this._onNotificationShow.bind(this));
|
||||
obj.destroyId = source.connect('destroy', this._onSourceDestroy.bind(this));
|
||||
|
||||
this.emit('source-added', source);
|
||||
@ -1022,7 +1115,7 @@ var MessageTray = class MessageTray {
|
||||
let obj = this._sources.get(source);
|
||||
this._sources.delete(source);
|
||||
|
||||
source.disconnect(obj.notifyId);
|
||||
source.disconnect(obj.showId);
|
||||
source.disconnect(obj.destroyId);
|
||||
|
||||
this.emit('source-removed', source);
|
||||
@ -1063,7 +1156,7 @@ var MessageTray = class MessageTray {
|
||||
}
|
||||
}
|
||||
|
||||
_onNotify(source, notification) {
|
||||
_onNotificationShow(_source, notification) {
|
||||
if (this._notification == notification) {
|
||||
// If a notification that is being shown is updated, we update
|
||||
// how it is shown and extend the time until it auto-hides.
|
||||
@ -1195,7 +1288,7 @@ var MessageTray = class MessageTray {
|
||||
// at the present time.
|
||||
_updateState() {
|
||||
let hasMonitor = Main.layoutManager.primaryMonitor != null;
|
||||
this.actor.visible = !this._bannerBlocked && hasMonitor && this._banner != null;
|
||||
this.visible = !this._bannerBlocked && hasMonitor && this._banner != null;
|
||||
if (this._bannerBlocked || !hasMonitor)
|
||||
return;
|
||||
|
||||
@ -1275,11 +1368,11 @@ var MessageTray = class MessageTray {
|
||||
this._updateState();
|
||||
});
|
||||
|
||||
this._bannerBin.add_actor(this._banner.actor);
|
||||
this._bannerBin.add_actor(this._banner);
|
||||
|
||||
this._bannerBin.opacity = 0;
|
||||
this._bannerBin.y = -this._banner.actor.height;
|
||||
this.actor.show();
|
||||
this._bannerBin.y = -this._banner.height;
|
||||
this.show();
|
||||
|
||||
Meta.disable_unredirect_for_display(global.display);
|
||||
this._updateShowingNotification();
|
||||
@ -1426,16 +1519,16 @@ var MessageTray = class MessageTray {
|
||||
_hideNotificationCompleted() {
|
||||
let notification = this._notification;
|
||||
this._notification = null;
|
||||
if (notification.isTransient)
|
||||
if (!this._notificationRemoved && notification.isTransient)
|
||||
notification.destroy(NotificationDestroyedReason.EXPIRED);
|
||||
|
||||
this._pointerInNotification = false;
|
||||
this._notificationRemoved = false;
|
||||
Meta.enable_unredirect_for_display(global.display);
|
||||
|
||||
this._banner.actor.destroy();
|
||||
this._banner.destroy();
|
||||
this._banner = null;
|
||||
this.actor.hide();
|
||||
this.hide();
|
||||
}
|
||||
|
||||
_expandActiveNotification() {
|
||||
@ -1457,15 +1550,15 @@ var MessageTray = class MessageTray {
|
||||
_ensureBannerFocused() {
|
||||
this._notificationFocusGrabber.grabFocus();
|
||||
}
|
||||
};
|
||||
Signals.addSignalMethods(MessageTray.prototype);
|
||||
});
|
||||
|
||||
var SystemNotificationSource = class SystemNotificationSource extends Source {
|
||||
constructor() {
|
||||
super(_("System Information"), 'dialog-information-symbolic');
|
||||
var SystemNotificationSource = GObject.registerClass(
|
||||
class SystemNotificationSource extends Source {
|
||||
_init() {
|
||||
super._init(_("System Information"), 'dialog-information-symbolic');
|
||||
}
|
||||
|
||||
open() {
|
||||
this.destroy();
|
||||
}
|
||||
};
|
||||
});
|
||||
|
@ -121,7 +121,7 @@ var ModalDialog = GObject.registerClass({
|
||||
|
||||
this.dialogLayout.opacity = 255;
|
||||
if (this._lightbox)
|
||||
this._lightbox.show();
|
||||
this._lightbox.lightOn();
|
||||
this.opacity = 0;
|
||||
this.show();
|
||||
this.ease({
|
||||
|
@ -1,5 +1,5 @@
|
||||
/* exported MediaSection */
|
||||
const { Gio, Shell, St } = imports.gi;
|
||||
const { Gio, GObject, Shell, St } = imports.gi;
|
||||
const Signals = imports.signals;
|
||||
|
||||
const Calendar = imports.ui.calendar;
|
||||
@ -19,9 +19,10 @@ const MprisPlayerProxy = Gio.DBusProxy.makeProxyWrapper(MprisPlayerIface);
|
||||
|
||||
const MPRIS_PLAYER_PREFIX = 'org.mpris.MediaPlayer2.';
|
||||
|
||||
var MediaMessage = class MediaMessage extends MessageList.Message {
|
||||
constructor(player) {
|
||||
super('', '');
|
||||
var MediaMessage = GObject.registerClass(
|
||||
class MediaMessage extends MessageList.Message {
|
||||
_init(player) {
|
||||
super._init('', '');
|
||||
|
||||
this._player = player;
|
||||
|
||||
@ -48,7 +49,7 @@ var MediaMessage = class MediaMessage extends MessageList.Message {
|
||||
this._update();
|
||||
}
|
||||
|
||||
_onClicked() {
|
||||
vfunc_clicked() {
|
||||
this._player.raise();
|
||||
Main.panel.closeCalendar();
|
||||
}
|
||||
@ -79,7 +80,7 @@ var MediaMessage = class MediaMessage extends MessageList.Message {
|
||||
this._updateNavButton(this._prevButton, this._player.canGoPrevious);
|
||||
this._updateNavButton(this._nextButton, this._player.canGoNext);
|
||||
}
|
||||
};
|
||||
});
|
||||
|
||||
var MprisPlayer = class MprisPlayer {
|
||||
constructor(busName) {
|
||||
@ -194,9 +195,10 @@ var MprisPlayer = class MprisPlayer {
|
||||
};
|
||||
Signals.addSignalMethods(MprisPlayer.prototype);
|
||||
|
||||
var MediaSection = class MediaSection extends MessageList.MessageListSection {
|
||||
constructor() {
|
||||
super();
|
||||
var MediaSection = GObject.registerClass(
|
||||
class MediaSection extends MessageList.MessageListSection {
|
||||
_init() {
|
||||
super._init();
|
||||
|
||||
this._players = new Map();
|
||||
|
||||
@ -247,4 +249,4 @@ var MediaSection = class MediaSection extends MessageList.MessageListSection {
|
||||
if (newOwner && !oldOwner)
|
||||
this._addPlayer(name);
|
||||
}
|
||||
};
|
||||
});
|
||||
|
@ -1,7 +1,7 @@
|
||||
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
|
||||
/* exported NotificationDaemon */
|
||||
|
||||
const { GdkPixbuf, Gio, GLib, Shell, St } = imports.gi;
|
||||
const { GdkPixbuf, Gio, GLib, GObject, Shell, St } = imports.gi;
|
||||
|
||||
const Config = imports.misc.config;
|
||||
const Main = imports.ui.main;
|
||||
@ -412,10 +412,10 @@ var FdoNotificationDaemon = class FdoNotificationDaemon {
|
||||
}
|
||||
};
|
||||
|
||||
var FdoNotificationDaemonSource =
|
||||
var FdoNotificationDaemonSource = GObject.registerClass(
|
||||
class FdoNotificationDaemonSource extends MessageTray.Source {
|
||||
constructor(title, pid, sender, appId) {
|
||||
super(title);
|
||||
_init(title, pid, sender, appId) {
|
||||
super._init(title);
|
||||
|
||||
this.pid = pid;
|
||||
this.app = this._getApp(appId);
|
||||
@ -464,7 +464,7 @@ class FdoNotificationDaemonSource extends MessageTray.Source {
|
||||
if (notification.resident && this.app && tracker.focus_app == this.app)
|
||||
this.pushNotification(notification);
|
||||
else
|
||||
this.notify(notification);
|
||||
this.showNotification(notification);
|
||||
}
|
||||
|
||||
_getApp(appId) {
|
||||
@ -526,7 +526,7 @@ class FdoNotificationDaemonSource extends MessageTray.Source {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
};
|
||||
});
|
||||
|
||||
const PRIORITY_URGENCY_MAP = {
|
||||
low: MessageTray.Urgency.LOW,
|
||||
@ -535,10 +535,10 @@ const PRIORITY_URGENCY_MAP = {
|
||||
urgent: MessageTray.Urgency.CRITICAL
|
||||
};
|
||||
|
||||
var GtkNotificationDaemonNotification =
|
||||
var GtkNotificationDaemonNotification = GObject.registerClass(
|
||||
class GtkNotificationDaemonNotification extends MessageTray.Notification {
|
||||
constructor(source, notification) {
|
||||
super(source);
|
||||
_init(source, notification) {
|
||||
super._init(source);
|
||||
this._serialized = GLib.Variant.new('a{sv}', notification);
|
||||
|
||||
let { title,
|
||||
@ -602,7 +602,7 @@ class GtkNotificationDaemonNotification extends MessageTray.Notification {
|
||||
serialize() {
|
||||
return this._serialized;
|
||||
}
|
||||
};
|
||||
});
|
||||
|
||||
const FdoApplicationIface = loadInterfaceXML('org.freedesktop.Application');
|
||||
const FdoApplicationProxy = Gio.DBusProxy.makeProxyWrapper(FdoApplicationIface);
|
||||
@ -618,9 +618,9 @@ function getPlatformData() {
|
||||
|
||||
function InvalidAppError() {}
|
||||
|
||||
var GtkNotificationDaemonAppSource =
|
||||
var GtkNotificationDaemonAppSource = GObject.registerClass(
|
||||
class GtkNotificationDaemonAppSource extends MessageTray.Source {
|
||||
constructor(appId) {
|
||||
_init(appId) {
|
||||
let objectPath = objectPathFromAppId(appId);
|
||||
if (!GLib.Variant.is_object_path(objectPath))
|
||||
throw new InvalidAppError();
|
||||
@ -629,7 +629,7 @@ class GtkNotificationDaemonAppSource extends MessageTray.Source {
|
||||
if (!app)
|
||||
throw new InvalidAppError();
|
||||
|
||||
super(app.get_name());
|
||||
super._init(app.get_name());
|
||||
|
||||
this._appId = appId;
|
||||
this._app = app;
|
||||
@ -690,7 +690,7 @@ class GtkNotificationDaemonAppSource extends MessageTray.Source {
|
||||
this._notifications[notificationId] = notification;
|
||||
|
||||
if (showBanner)
|
||||
this.notify(notification);
|
||||
this.showNotification(notification);
|
||||
else
|
||||
this.pushNotification(notification);
|
||||
|
||||
@ -716,7 +716,7 @@ class GtkNotificationDaemonAppSource extends MessageTray.Source {
|
||||
}
|
||||
return [this._appId, notifications];
|
||||
}
|
||||
};
|
||||
});
|
||||
|
||||
const GtkNotificationsIface = loadInterfaceXML('org.gtk.Notifications');
|
||||
|
||||
@ -742,7 +742,7 @@ var GtkNotificationDaemon = class GtkNotificationDaemon {
|
||||
delete this._sources[appId];
|
||||
this._saveNotifications();
|
||||
});
|
||||
source.connect('count-updated', this._saveNotifications.bind(this));
|
||||
source.connect('notify::count', this._saveNotifications.bind(this));
|
||||
Main.messageTray.add(source);
|
||||
this._sources[appId] = source;
|
||||
return source;
|
||||
|
@ -1,30 +1,33 @@
|
||||
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
|
||||
/* exported OsdMonitorLabeler */
|
||||
|
||||
const { Clutter, Gio, Meta, St } = imports.gi;
|
||||
const { Clutter, Gio, GObject, Meta, St } = imports.gi;
|
||||
|
||||
const Main = imports.ui.main;
|
||||
|
||||
var OsdMonitorLabel = class {
|
||||
constructor(monitor, label) {
|
||||
this._actor = new St.Widget({ x_expand: true,
|
||||
y_expand: true });
|
||||
var OsdMonitorLabel = GObject.registerClass(
|
||||
class OsdMonitorLabel extends St.Widget {
|
||||
_init(monitor, label) {
|
||||
super._init({ x_expand: true, y_expand: true });
|
||||
|
||||
this._monitor = monitor;
|
||||
|
||||
this._box = new St.BoxLayout({ style_class: 'osd-window',
|
||||
vertical: true });
|
||||
this._actor.add_actor(this._box);
|
||||
this.add_actor(this._box);
|
||||
|
||||
this._label = new St.Label({ style_class: 'osd-monitor-label',
|
||||
text: label });
|
||||
this._box.add(this._label);
|
||||
|
||||
Main.uiGroup.add_child(this._actor);
|
||||
Main.uiGroup.set_child_above_sibling(this._actor, null);
|
||||
Main.uiGroup.add_child(this);
|
||||
Main.uiGroup.set_child_above_sibling(this, null);
|
||||
this._position();
|
||||
|
||||
Meta.disable_unredirect_for_display(global.display);
|
||||
this.connect('destroy', () => {
|
||||
Meta.enable_unredirect_for_display(global.display);
|
||||
});
|
||||
}
|
||||
|
||||
_position() {
|
||||
@ -37,12 +40,7 @@ var OsdMonitorLabel = class {
|
||||
|
||||
this._box.y = workArea.y;
|
||||
}
|
||||
|
||||
destroy() {
|
||||
this._actor.destroy();
|
||||
Meta.enable_unredirect_for_display(global.display);
|
||||
}
|
||||
};
|
||||
});
|
||||
|
||||
var OsdMonitorLabeler = class {
|
||||
constructor() {
|
||||
|
@ -41,22 +41,25 @@ class OsdWindowConstraint extends Clutter.Constraint {
|
||||
}
|
||||
});
|
||||
|
||||
var OsdWindow = class {
|
||||
constructor(monitorIndex) {
|
||||
this.actor = new St.Widget({ x_expand: true,
|
||||
y_expand: true,
|
||||
x_align: Clutter.ActorAlign.CENTER,
|
||||
y_align: Clutter.ActorAlign.CENTER });
|
||||
var OsdWindow = GObject.registerClass(
|
||||
class OsdWindow extends St.Widget {
|
||||
_init(monitorIndex) {
|
||||
super._init({
|
||||
x_expand: true,
|
||||
y_expand: true,
|
||||
x_align: Clutter.ActorAlign.CENTER,
|
||||
y_align: Clutter.ActorAlign.CENTER
|
||||
});
|
||||
|
||||
this._monitorIndex = monitorIndex;
|
||||
let constraint = new Layout.MonitorConstraint({ index: monitorIndex });
|
||||
this.actor.add_constraint(constraint);
|
||||
this.add_constraint(constraint);
|
||||
|
||||
this._boxConstraint = new OsdWindowConstraint();
|
||||
this._box = new St.BoxLayout({ style_class: 'osd-window',
|
||||
vertical: true });
|
||||
this._box.add_constraint(this._boxConstraint);
|
||||
this.actor.add_actor(this._box);
|
||||
this.add_actor(this._box);
|
||||
|
||||
this._icon = new St.Icon();
|
||||
this._box.add(this._icon, { expand: true });
|
||||
@ -73,7 +76,7 @@ var OsdWindow = class {
|
||||
this._hideTimeoutId = 0;
|
||||
this._reset();
|
||||
|
||||
this.actor.connect('destroy', this._onDestroy.bind(this));
|
||||
this.connect('destroy', this._onDestroy.bind(this));
|
||||
|
||||
this._monitorsChangedId =
|
||||
Main.layoutManager.connect('monitors-changed',
|
||||
@ -83,7 +86,7 @@ var OsdWindow = class {
|
||||
themeContext.connect('notify::scale-factor',
|
||||
this._relayout.bind(this));
|
||||
this._relayout();
|
||||
Main.uiGroup.add_child(this.actor);
|
||||
Main.uiGroup.add_child(this);
|
||||
}
|
||||
|
||||
_onDestroy() {
|
||||
@ -110,7 +113,7 @@ var OsdWindow = class {
|
||||
setLevel(value) {
|
||||
this._level.visible = (value != undefined);
|
||||
if (value != undefined) {
|
||||
if (this.actor.visible)
|
||||
if (this.visible)
|
||||
this._level.ease_property('value', value, {
|
||||
mode: Clutter.AnimationMode.EASE_OUT_QUAD,
|
||||
duration: LEVEL_ANIMATION_TIME
|
||||
@ -128,13 +131,13 @@ var OsdWindow = class {
|
||||
if (!this._icon.gicon)
|
||||
return;
|
||||
|
||||
if (!this.actor.visible) {
|
||||
if (!this.visible) {
|
||||
Meta.disable_unredirect_for_display(global.display);
|
||||
this.actor.show();
|
||||
this.actor.opacity = 0;
|
||||
this.actor.get_parent().set_child_above_sibling(this.actor, null);
|
||||
super.show();
|
||||
this.opacity = 0;
|
||||
this.get_parent().set_child_above_sibling(this, null);
|
||||
|
||||
this.actor.ease({
|
||||
this.ease({
|
||||
opacity: 255,
|
||||
duration: FADE_TIME,
|
||||
mode: Clutter.AnimationMode.EASE_OUT_QUAD
|
||||
@ -158,7 +161,7 @@ var OsdWindow = class {
|
||||
|
||||
_hide() {
|
||||
this._hideTimeoutId = 0;
|
||||
this.actor.ease({
|
||||
this.ease({
|
||||
opacity: 0,
|
||||
duration: FADE_TIME,
|
||||
mode: Clutter.AnimationMode.EASE_OUT_QUAD,
|
||||
@ -171,7 +174,7 @@ var OsdWindow = class {
|
||||
}
|
||||
|
||||
_reset() {
|
||||
this.actor.hide();
|
||||
super.hide();
|
||||
this.setLabel(null);
|
||||
this.setMaxLevel(null);
|
||||
this.setLevel(null);
|
||||
@ -193,7 +196,7 @@ var OsdWindow = class {
|
||||
this._box.translation_y = Math.round(monitor.height / 4);
|
||||
this._boxConstraint.minSize = popupSize;
|
||||
}
|
||||
};
|
||||
});
|
||||
|
||||
var OsdWindowManager = class {
|
||||
constructor() {
|
||||
@ -210,7 +213,7 @@ var OsdWindowManager = class {
|
||||
}
|
||||
|
||||
for (let i = Main.layoutManager.monitors.length; i < this._osdWindows.length; i++) {
|
||||
this._osdWindows[i].actor.destroy();
|
||||
this._osdWindows[i].destroy();
|
||||
this._osdWindows[i] = null;
|
||||
}
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
|
||||
/* exported Overview */
|
||||
|
||||
const { Clutter, GLib, Meta, Shell, St } = imports.gi;
|
||||
const { Clutter, GLib, GObject, Meta, Shell, St } = imports.gi;
|
||||
const Signals = imports.signals;
|
||||
|
||||
const Background = imports.ui.background;
|
||||
@ -72,36 +72,108 @@ var ShellInfo = class {
|
||||
if (undoCallback)
|
||||
notification.addAction(_("Undo"), this._onUndoClicked.bind(this));
|
||||
|
||||
this._source.notify(notification);
|
||||
this._source.showNotification(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 {
|
||||
constructor() {
|
||||
this._overviewCreated = false;
|
||||
this._initCalled = false;
|
||||
|
||||
Main.sessionMode.connect('updated', this._sessionUpdated.bind(this));
|
||||
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() {
|
||||
if (this._overviewCreated)
|
||||
if (this._overview)
|
||||
return;
|
||||
|
||||
if (this.isDummy)
|
||||
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
|
||||
// hidden when displaying the overview, so we create a new
|
||||
// one. Instances of this class share a single CoglTexture behind the
|
||||
@ -116,11 +188,11 @@ var Overview = class {
|
||||
|
||||
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._modal = false; // have a modal grab
|
||||
this.animationInProgress = false;
|
||||
this.visibleTarget = false;
|
||||
this._animationInProgress = false;
|
||||
this._visibleTarget = false;
|
||||
|
||||
// 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
|
||||
@ -129,9 +201,6 @@ var Overview = class {
|
||||
reactive: true });
|
||||
Main.layoutManager.overviewGroup.add_child(this._coverPane);
|
||||
this._coverPane.connect('event', () => Clutter.EVENT_STOP);
|
||||
|
||||
Main.layoutManager.overviewGroup.add_child(this._overview);
|
||||
|
||||
this._coverPane.hide();
|
||||
|
||||
// XDND
|
||||
@ -213,41 +282,12 @@ var Overview = class {
|
||||
if (this.isDummy)
|
||||
return;
|
||||
|
||||
this._overview = new OverviewActor();
|
||||
this._overview._delegate = this;
|
||||
Main.layoutManager.overviewGroup.add_child(this._overview);
|
||||
|
||||
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));
|
||||
this._relayout();
|
||||
}
|
||||
@ -426,7 +466,7 @@ var Overview = class {
|
||||
|
||||
focusSearch() {
|
||||
this.show();
|
||||
this._searchEntry.grab_key_focus();
|
||||
this._overview.searchEntry.grab_key_focus();
|
||||
}
|
||||
|
||||
fadeInDesktop() {
|
||||
@ -464,11 +504,11 @@ var Overview = class {
|
||||
// the overview if the user both triggered the hot corner and
|
||||
// clicked the Activities button.
|
||||
shouldToggleByCornerOrButton() {
|
||||
if (this.animationInProgress)
|
||||
if (this._animationInProgress)
|
||||
return false;
|
||||
if (this._inItemDrag || this._inWindowDrag)
|
||||
return false;
|
||||
if (this._activationTime == 0 ||
|
||||
if (!this._activationTime ||
|
||||
GLib.get_monotonic_time() / GLib.USEC_PER_SEC - this._activationTime > OVERVIEW_ACTIVATION_TIMEOUT)
|
||||
return true;
|
||||
return false;
|
||||
@ -478,7 +518,7 @@ var Overview = class {
|
||||
// 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
|
||||
// going to an application.
|
||||
if (this.animationInProgress)
|
||||
if (this._animationInProgress)
|
||||
return true;
|
||||
|
||||
if (this._shown) {
|
||||
@ -520,12 +560,12 @@ var Overview = class {
|
||||
|
||||
|
||||
_animateVisible() {
|
||||
if (this.visible || this.animationInProgress)
|
||||
if (this._visible || this._animationInProgress)
|
||||
return;
|
||||
|
||||
this.visible = true;
|
||||
this.animationInProgress = true;
|
||||
this.visibleTarget = true;
|
||||
this._visible = true;
|
||||
this._animationInProgress = true;
|
||||
this._visibleTarget = true;
|
||||
this._activationTime = GLib.get_monotonic_time() / GLib.USEC_PER_SEC;
|
||||
|
||||
Meta.disable_unredirect_for_display(global.display);
|
||||
@ -546,7 +586,7 @@ var Overview = class {
|
||||
}
|
||||
|
||||
_showDone() {
|
||||
this.animationInProgress = false;
|
||||
this._animationInProgress = false;
|
||||
this._desktopFade.hide();
|
||||
this._coverPane.hide();
|
||||
|
||||
@ -586,11 +626,11 @@ var Overview = class {
|
||||
}
|
||||
|
||||
_animateNotVisible() {
|
||||
if (!this.visible || this.animationInProgress)
|
||||
if (!this._visible || this._animationInProgress)
|
||||
return;
|
||||
|
||||
this.animationInProgress = true;
|
||||
this.visibleTarget = false;
|
||||
this._animationInProgress = true;
|
||||
this._visibleTarget = false;
|
||||
|
||||
this.viewSelector.animateFromOverview();
|
||||
|
||||
@ -616,8 +656,8 @@ var Overview = class {
|
||||
this._desktopFade.hide();
|
||||
this._coverPane.hide();
|
||||
|
||||
this.visible = false;
|
||||
this.animationInProgress = false;
|
||||
this._visible = false;
|
||||
this._animationInProgress = false;
|
||||
|
||||
this.emit('hidden');
|
||||
// Handle any calls to show* while we were hiding
|
||||
@ -633,14 +673,17 @@ var Overview = class {
|
||||
if (this.isDummy)
|
||||
return;
|
||||
|
||||
if (this.visible)
|
||||
if (this._visible)
|
||||
this.hide();
|
||||
else
|
||||
this.show();
|
||||
}
|
||||
|
||||
getShowAppsButton() {
|
||||
return this._dash.showAppsButton;
|
||||
logError(new Error('Usage of Overview.\'getShowAppsButton\' is deprecated, ' +
|
||||
'use \'dash.showAppsButton\' property instead'));
|
||||
|
||||
return this.dash.showAppsButton;
|
||||
}
|
||||
};
|
||||
Signals.addSignalMethods(Overview.prototype);
|
||||
|
@ -118,18 +118,21 @@ var SlideLayout = GObject.registerClass({
|
||||
}
|
||||
});
|
||||
|
||||
var SlidingControl = class {
|
||||
constructor(params) {
|
||||
var SlidingControl = GObject.registerClass(
|
||||
class SlidingControl extends St.Widget {
|
||||
_init(params) {
|
||||
params = Params.parse(params, { slideDirection: SlideDirection.LEFT });
|
||||
|
||||
this._visible = true;
|
||||
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 });
|
||||
super._init({
|
||||
layout_manager: this.layout,
|
||||
style_class: 'overview-controls',
|
||||
clip_to_allocation: true
|
||||
});
|
||||
|
||||
this._visible = true;
|
||||
this._inDrag = false;
|
||||
|
||||
Main.overview.connect('hiding', this._onOverviewHiding.bind(this));
|
||||
|
||||
@ -147,20 +150,20 @@ var SlidingControl = class {
|
||||
}
|
||||
|
||||
_updateSlide() {
|
||||
this.actor.ease_property('@layout.slide-x', this._getSlide(), {
|
||||
this.ease_property('@layout.slide-x', this._getSlide(), {
|
||||
mode: Clutter.AnimationMode.EASE_OUT_QUAD,
|
||||
duration: SIDE_CONTROLS_ANIMATION_TIME,
|
||||
});
|
||||
}
|
||||
|
||||
getVisibleWidth() {
|
||||
let child = this.actor.get_first_child();
|
||||
let child = this.get_first_child();
|
||||
let [, , natWidth] = child.get_preferred_size();
|
||||
return natWidth;
|
||||
}
|
||||
|
||||
_getTranslation() {
|
||||
let child = this.actor.get_first_child();
|
||||
let child = this.get_first_child();
|
||||
let direction = getRtlSlideDirection(this.layout.slideDirection, child);
|
||||
let visibleWidth = this.getVisibleWidth();
|
||||
|
||||
@ -186,7 +189,7 @@ var SlidingControl = class {
|
||||
return;
|
||||
|
||||
this.layout.translation_x = translationStart;
|
||||
this.actor.ease_property('@layout.translation-x', translationEnd, {
|
||||
this.ease_property('@layout.translation-x', translationEnd, {
|
||||
mode: Clutter.AnimationMode.EASE_OUT_QUAD,
|
||||
duration: SIDE_CONTROLS_ANIMATION_TIME,
|
||||
});
|
||||
@ -218,7 +221,7 @@ var SlidingControl = class {
|
||||
}
|
||||
|
||||
fadeIn() {
|
||||
this.actor.ease({
|
||||
this.ease({
|
||||
opacity: 255,
|
||||
duration: SIDE_CONTROLS_ANIMATION_TIME / 2,
|
||||
mode: Clutter.AnimationMode.EASE_IN_QUAD
|
||||
@ -226,7 +229,7 @@ var SlidingControl = class {
|
||||
}
|
||||
|
||||
fadeHalf() {
|
||||
this.actor.ease({
|
||||
this.ease({
|
||||
opacity: 128,
|
||||
duration: SIDE_CONTROLS_ANIMATION_TIME / 2,
|
||||
mode: Clutter.AnimationMode.EASE_OUT_QUAD
|
||||
@ -249,37 +252,38 @@ var SlidingControl = class {
|
||||
// selector; this means we can now safely set the full slide for
|
||||
// the next page, since slideIn or slideOut might have been called,
|
||||
// changing the visiblity
|
||||
this.actor.remove_transition('@layout.slide-x');
|
||||
this.remove_transition('@layout.slide-x');
|
||||
this.layout.slide_x = this._getSlide();
|
||||
this._updateTranslation();
|
||||
}
|
||||
};
|
||||
});
|
||||
|
||||
var ThumbnailsSlider = class extends SlidingControl {
|
||||
constructor(thumbnailsBox) {
|
||||
super({ slideDirection: SlideDirection.RIGHT });
|
||||
var ThumbnailsSlider = GObject.registerClass(
|
||||
class ThumbnailsSlider extends SlidingControl {
|
||||
_init(thumbnailsBox) {
|
||||
super._init({ slideDirection: SlideDirection.RIGHT });
|
||||
|
||||
this._thumbnailsBox = thumbnailsBox;
|
||||
|
||||
this.actor.request_mode = Clutter.RequestMode.WIDTH_FOR_HEIGHT;
|
||||
this.actor.reactive = true;
|
||||
this.actor.track_hover = true;
|
||||
this.actor.add_actor(this._thumbnailsBox);
|
||||
this.request_mode = Clutter.RequestMode.WIDTH_FOR_HEIGHT;
|
||||
this.reactive = true;
|
||||
this.track_hover = true;
|
||||
this.add_actor(this._thumbnailsBox);
|
||||
|
||||
Main.layoutManager.connect('monitors-changed', this._updateSlide.bind(this));
|
||||
global.workspace_manager.connect('active-workspace-changed',
|
||||
this._updateSlide.bind(this));
|
||||
global.workspace_manager.connect('notify::n-workspaces',
|
||||
this._updateSlide.bind(this));
|
||||
this.actor.connect('notify::hover', this._updateSlide.bind(this));
|
||||
this._thumbnailsBox.bind_property('visible', this.actor, 'visible', GObject.BindingFlags.SYNC_CREATE);
|
||||
this.connect('notify::hover', this._updateSlide.bind(this));
|
||||
this._thumbnailsBox.bind_property('visible', this, 'visible', GObject.BindingFlags.SYNC_CREATE);
|
||||
}
|
||||
|
||||
_getAlwaysZoomOut() {
|
||||
// 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
|
||||
let workspaceManager = global.workspace_manager;
|
||||
let alwaysZoomOut = this.actor.hover ||
|
||||
let alwaysZoomOut = this.hover ||
|
||||
this._inDrag ||
|
||||
!Meta.prefs_get_dynamic_workspaces() ||
|
||||
workspaceManager.n_workspaces > 2 ||
|
||||
@ -304,12 +308,12 @@ var ThumbnailsSlider = class extends SlidingControl {
|
||||
}
|
||||
|
||||
getNonExpandedWidth() {
|
||||
let child = this.actor.get_first_child();
|
||||
let child = this.get_first_child();
|
||||
return child.get_theme_node().get_length('visible-width');
|
||||
}
|
||||
|
||||
_onDragEnd() {
|
||||
this.actor.sync_hover();
|
||||
this.sync_hover();
|
||||
super._onDragEnd();
|
||||
}
|
||||
|
||||
@ -321,7 +325,7 @@ var ThumbnailsSlider = class extends SlidingControl {
|
||||
if (alwaysZoomOut)
|
||||
return 1;
|
||||
|
||||
let child = this.actor.get_first_child();
|
||||
let child = this.get_first_child();
|
||||
let preferredHeight = child.get_preferred_height(-1)[1];
|
||||
let expandedWidth = child.get_preferred_width(preferredHeight)[1];
|
||||
|
||||
@ -335,24 +339,25 @@ var ThumbnailsSlider = class extends SlidingControl {
|
||||
else
|
||||
return this.getNonExpandedWidth();
|
||||
}
|
||||
};
|
||||
});
|
||||
|
||||
var DashSlider = class extends SlidingControl {
|
||||
constructor(dash) {
|
||||
super({ slideDirection: SlideDirection.LEFT });
|
||||
var DashSlider = GObject.registerClass(
|
||||
class DashSlider extends SlidingControl {
|
||||
_init(dash) {
|
||||
super._init({ slideDirection: SlideDirection.LEFT });
|
||||
|
||||
this._dash = dash;
|
||||
|
||||
// SlideLayout reads the actor's expand flags to decide
|
||||
// whether to allocate the natural size to its child, or the whole
|
||||
// available allocation
|
||||
this._dash.actor.x_expand = true;
|
||||
this._dash.x_expand = true;
|
||||
|
||||
this.actor.x_expand = true;
|
||||
this.actor.x_align = Clutter.ActorAlign.START;
|
||||
this.actor.y_expand = true;
|
||||
this.x_expand = true;
|
||||
this.x_align = Clutter.ActorAlign.START;
|
||||
this.y_expand = true;
|
||||
|
||||
this.actor.add_actor(this._dash.actor);
|
||||
this.add_actor(this._dash);
|
||||
|
||||
this._dash.connect('icon-size-changed', this._updateSlide.bind(this));
|
||||
}
|
||||
@ -371,7 +376,7 @@ var DashSlider = class extends SlidingControl {
|
||||
_onWindowDragEnd() {
|
||||
this.fadeIn();
|
||||
}
|
||||
};
|
||||
});
|
||||
|
||||
var DashSpacer = GObject.registerClass(
|
||||
class DashSpacer extends St.Widget {
|
||||
@ -416,12 +421,21 @@ var ControlsLayout = GObject.registerClass({
|
||||
}
|
||||
});
|
||||
|
||||
var ControlsManager = class {
|
||||
constructor(searchEntry) {
|
||||
var ControlsManager = GObject.registerClass(
|
||||
class ControlsManager extends St.Widget {
|
||||
_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._dashSlider = new DashSlider(this.dash);
|
||||
this._dashSpacer = new DashSpacer();
|
||||
this._dashSpacer.setDashActor(this._dashSlider.actor);
|
||||
this._dashSpacer.setDashActor(this._dashSlider);
|
||||
|
||||
this._thumbnailsBox = new WorkspaceThumbnail.ThumbnailsBox();
|
||||
this._thumbnailsSlider = new ThumbnailsSlider(this._thumbnailsBox);
|
||||
@ -431,20 +445,15 @@ var ControlsManager = class {
|
||||
this.viewSelector.connect('page-changed', this._setVisibility.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',
|
||||
x_expand: true, y_expand: true });
|
||||
this.actor.add_actor(this._group);
|
||||
this.add_actor(this._group);
|
||||
|
||||
this.actor.add_actor(this._dashSlider.actor);
|
||||
this.add_actor(this._dashSlider);
|
||||
|
||||
this._group.add_actor(this._dashSpacer);
|
||||
this._group.add(this.viewSelector.actor, { x_fill: true,
|
||||
expand: true });
|
||||
this._group.add_actor(this._thumbnailsSlider.actor);
|
||||
this._group.add(this.viewSelector, { x_fill: true, expand: true });
|
||||
this._group.add_actor(this._thumbnailsSlider);
|
||||
|
||||
layout.connect('allocation-changed', this._updateWorkspacesGeometry.bind(this));
|
||||
|
||||
@ -452,18 +461,18 @@ var ControlsManager = class {
|
||||
}
|
||||
|
||||
_updateWorkspacesGeometry() {
|
||||
let [x, y] = this.actor.get_transformed_position();
|
||||
let [width, height] = this.actor.get_transformed_size();
|
||||
let [x, y] = this.get_transformed_position();
|
||||
let [width, height] = this.get_transformed_size();
|
||||
let geometry = { x: x, y: y, width: width, height: height };
|
||||
|
||||
let spacing = this.actor.get_theme_node().get_length('spacing');
|
||||
let spacing = this.get_theme_node().get_length('spacing');
|
||||
let dashWidth = this._dashSlider.getVisibleWidth() + spacing;
|
||||
let thumbnailsWidth = this._thumbnailsSlider.getNonExpandedWidth() + spacing;
|
||||
|
||||
geometry.width -= dashWidth;
|
||||
geometry.width -= thumbnailsWidth;
|
||||
|
||||
if (this.actor.get_text_direction() == Clutter.TextDirection.LTR)
|
||||
if (this.get_text_direction() == Clutter.TextDirection.LTR)
|
||||
geometry.x += dashWidth;
|
||||
else
|
||||
geometry.x += thumbnailsWidth;
|
||||
@ -510,4 +519,4 @@ var ControlsManager = class {
|
||||
|
||||
this._updateSpacerVisibility();
|
||||
}
|
||||
};
|
||||
});
|
||||
|
178
js/ui/padOsd.js
178
js/ui/padOsd.js
@ -1,5 +1,5 @@
|
||||
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
|
||||
/* exported PadOsdService */
|
||||
/* exported PadOsd, PadOsdService */
|
||||
|
||||
const { Atk, Clutter, GDesktopEnums, Gio,
|
||||
GLib, GObject, Gtk, Meta, Rsvg, St } = imports.gi;
|
||||
@ -22,40 +22,45 @@ const CCW = 1;
|
||||
const UP = 0;
|
||||
const DOWN = 1;
|
||||
|
||||
var PadChooser = class {
|
||||
constructor(device, groupDevices) {
|
||||
this.actor = new St.Button({ style_class: 'pad-chooser-button',
|
||||
toggle_mode: true,
|
||||
x_fill: false,
|
||||
y_fill: false,
|
||||
x_align: St.Align.MIDDLE,
|
||||
y_align: St.Align.MIDDLE });
|
||||
var PadChooser = GObject.registerClass({
|
||||
Signals: { 'pad-selected': { param_types: [Clutter.InputDevice.$gtype] } }
|
||||
}, class PadChooser extends St.Button {
|
||||
_init(device, groupDevices) {
|
||||
super._init({
|
||||
style_class: 'pad-chooser-button',
|
||||
toggle_mode: true,
|
||||
x_fill: false,
|
||||
y_fill: false,
|
||||
x_align: St.Align.MIDDLE,
|
||||
y_align: St.Align.MIDDLE
|
||||
});
|
||||
this.currentDevice = device;
|
||||
this._padChooserMenu = null;
|
||||
|
||||
let arrow = new St.Icon({ style_class: 'popup-menu-arrow',
|
||||
icon_name: 'pan-down-symbolic',
|
||||
accessible_role: Atk.Role.ARROW });
|
||||
this.actor.set_child(arrow);
|
||||
this.set_child(arrow);
|
||||
this._ensureMenu(groupDevices);
|
||||
|
||||
this.actor.connect('destroy', this._onDestroy.bind(this));
|
||||
this.actor.connect('clicked', actor => {
|
||||
if (actor.get_checked()) {
|
||||
if (this._padChooserMenu != null)
|
||||
this._padChooserMenu.open(true);
|
||||
else
|
||||
this.set_checked(false);
|
||||
} else {
|
||||
this._padChooserMenu.close(true);
|
||||
}
|
||||
});
|
||||
this.connect('destroy', this._onDestroy.bind(this));
|
||||
}
|
||||
|
||||
vfunc_clicked() {
|
||||
if (this.get_checked()) {
|
||||
if (this._padChooserMenu != null)
|
||||
this._padChooserMenu.open(true);
|
||||
else
|
||||
this.set_checked(false);
|
||||
} else {
|
||||
this._padChooserMenu.close(true);
|
||||
}
|
||||
}
|
||||
|
||||
_ensureMenu(devices) {
|
||||
this._padChooserMenu = new PopupMenu.PopupMenu(this.actor, 0.5, St.Side.TOP);
|
||||
this._padChooserMenu = new PopupMenu.PopupMenu(this, 0.5, St.Side.TOP);
|
||||
this._padChooserMenu.connect('menu-closed', () => {
|
||||
this.actor.set_checked(false);
|
||||
this.set_checked(false);
|
||||
});
|
||||
this._padChooserMenu.actor.hide();
|
||||
Main.uiGroup.add_actor(this._padChooserMenu.actor);
|
||||
@ -78,24 +83,20 @@ var PadChooser = class {
|
||||
update(devices) {
|
||||
if (this._padChooserMenu)
|
||||
this._padChooserMenu.actor.destroy();
|
||||
this.actor.set_checked(false);
|
||||
this.set_checked(false);
|
||||
this._ensureMenu(devices);
|
||||
}
|
||||
});
|
||||
|
||||
destroy() {
|
||||
this.actor.destroy();
|
||||
}
|
||||
};
|
||||
Signals.addSignalMethods(PadChooser.prototype);
|
||||
|
||||
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));
|
||||
var KeybindingEntry = GObject.registerClass({
|
||||
GTypeName: 'PadOsd_KeybindingEntry',
|
||||
Signals: { 'keybinding-edited': {} }
|
||||
}, class KeybindingEntry extends St.Entry {
|
||||
_init() {
|
||||
super._init({ hint_text: _("New shortcut…"), style: 'width: 10em' });
|
||||
}
|
||||
|
||||
_onCapturedEvent(actor, event) {
|
||||
vfunc_captured_event(event) {
|
||||
if (event.type() != Clutter.EventType.KEY_PRESS)
|
||||
return Clutter.EVENT_PROPAGATE;
|
||||
|
||||
@ -103,23 +104,24 @@ var KeybindingEntry = class {
|
||||
event.get_key_symbol(),
|
||||
event.get_key_code(),
|
||||
event.get_state());
|
||||
this.actor.set_text(str);
|
||||
this.set_text(str);
|
||||
this.emit('keybinding-edited', str);
|
||||
return Clutter.EVENT_STOP;
|
||||
}
|
||||
};
|
||||
Signals.addSignalMethods(KeybindingEntry.prototype);
|
||||
});
|
||||
|
||||
var ActionComboBox = class {
|
||||
constructor() {
|
||||
this.actor = new St.Button({ style_class: 'button' });
|
||||
this.actor.connect('clicked', this._onButtonClicked.bind(this));
|
||||
this.actor.set_toggle_mode(true);
|
||||
var ActionComboBox = GObject.registerClass({
|
||||
GTypeName: 'PadOsd_ActionComboBox',
|
||||
Signals: { 'action-selected': { param_types: [GObject.TYPE_INT] } }
|
||||
}, class ActionComboBox extends St.Button {
|
||||
_init() {
|
||||
super._init({ style_class: 'button' });
|
||||
this.set_toggle_mode(true);
|
||||
|
||||
let boxLayout = new Clutter.BoxLayout({ orientation: Clutter.Orientation.HORIZONTAL,
|
||||
spacing: 6 });
|
||||
let box = new St.Widget({ layout_manager: boxLayout });
|
||||
this.actor.set_child(box);
|
||||
this.set_child(box);
|
||||
|
||||
this._label = new St.Label({ style_class: 'combo-box-label' });
|
||||
box.add_child(this._label);
|
||||
@ -131,9 +133,9 @@ var ActionComboBox = class {
|
||||
y_align: Clutter.ActorAlign.CENTER });
|
||||
box.add_child(arrow);
|
||||
|
||||
this._editMenu = new PopupMenu.PopupMenu(this.actor, 0, St.Side.TOP);
|
||||
this._editMenu = new PopupMenu.PopupMenu(this, 0, St.Side.TOP);
|
||||
this._editMenu.connect('menu-closed', () => {
|
||||
this.actor.set_checked(false);
|
||||
this.set_checked(false);
|
||||
});
|
||||
this._editMenu.actor.hide();
|
||||
Main.uiGroup.add_actor(this._editMenu.actor);
|
||||
@ -179,8 +181,8 @@ var ActionComboBox = class {
|
||||
this._editMenu.close(true);
|
||||
}
|
||||
|
||||
_onButtonClicked() {
|
||||
if (this.actor.get_checked())
|
||||
vfunc_clicked() {
|
||||
if (this.get_checked())
|
||||
this.popup();
|
||||
else
|
||||
this.popdown();
|
||||
@ -189,38 +191,40 @@ var ActionComboBox = class {
|
||||
setButtonActionsActive(active) {
|
||||
this._buttonItems.forEach(item => item.setSensitive(active));
|
||||
}
|
||||
};
|
||||
Signals.addSignalMethods(ActionComboBox.prototype);
|
||||
});
|
||||
|
||||
var ActionEditor = class {
|
||||
constructor() {
|
||||
var ActionEditor = GObject.registerClass({
|
||||
GTypeName: 'PadOsd_ActionEditor',
|
||||
Signals: { 'done': {} }
|
||||
}, class ActionEditor extends St.Widget {
|
||||
_init() {
|
||||
let boxLayout = new Clutter.BoxLayout({ orientation: Clutter.Orientation.HORIZONTAL,
|
||||
spacing: 12 });
|
||||
|
||||
this.actor = new St.Widget({ layout_manager: boxLayout });
|
||||
super._init({ layout_manager: boxLayout });
|
||||
|
||||
this._actionComboBox = new ActionComboBox();
|
||||
this._actionComboBox.connect('action-selected', this._onActionSelected.bind(this));
|
||||
this.actor.add_actor(this._actionComboBox.actor);
|
||||
this.add_actor(this._actionComboBox);
|
||||
|
||||
this._keybindingEdit = new KeybindingEntry();
|
||||
this._keybindingEdit.connect('keybinding-edited', this._onKeybindingEdited.bind(this));
|
||||
this.actor.add_actor(this._keybindingEdit.actor);
|
||||
this.add_actor(this._keybindingEdit);
|
||||
|
||||
this._doneButton = new St.Button({ label: _("Done"),
|
||||
style_class: 'button',
|
||||
x_expand: false });
|
||||
this._doneButton.connect('clicked', this._onEditingDone.bind(this));
|
||||
this.actor.add_actor(this._doneButton);
|
||||
this.add_actor(this._doneButton);
|
||||
}
|
||||
|
||||
_updateKeybindingEntryState() {
|
||||
if (this._currentAction == GDesktopEnums.PadButtonAction.KEYBINDING) {
|
||||
this._keybindingEdit.actor.set_text(this._currentKeybinding);
|
||||
this._keybindingEdit.actor.show();
|
||||
this._keybindingEdit.actor.grab_key_focus();
|
||||
this._keybindingEdit.set_text(this._currentKeybinding);
|
||||
this._keybindingEdit.show();
|
||||
this._keybindingEdit.grab_key_focus();
|
||||
} else {
|
||||
this._keybindingEdit.actor.hide();
|
||||
this._keybindingEdit.hide();
|
||||
}
|
||||
}
|
||||
|
||||
@ -238,7 +242,7 @@ var ActionEditor = class {
|
||||
|
||||
close() {
|
||||
this._actionComboBox.popdown();
|
||||
this.actor.hide();
|
||||
this.hide();
|
||||
}
|
||||
|
||||
_onKeybindingEdited(entry, keybinding) {
|
||||
@ -272,8 +276,7 @@ var ActionEditor = class {
|
||||
this.close();
|
||||
this.emit('done');
|
||||
}
|
||||
};
|
||||
Signals.addSignalMethods(ActionEditor.prototype);
|
||||
});
|
||||
|
||||
var PadDiagram = GObject.registerClass({
|
||||
Properties: {
|
||||
@ -615,8 +618,18 @@ var PadDiagram = GObject.registerClass({
|
||||
}
|
||||
});
|
||||
|
||||
var PadOsd = class {
|
||||
constructor(padDevice, settings, imagePath, editionMode, monitorIndex) {
|
||||
var PadOsd = GObject.registerClass({
|
||||
Signals: { 'pad-selected': { param_types: [Clutter.InputDevice.$gtype] } }
|
||||
}, 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._groupPads = [padDevice];
|
||||
this._settings = settings;
|
||||
@ -653,23 +666,18 @@ var PadOsd = class {
|
||||
this._groupPads.push(device);
|
||||
});
|
||||
|
||||
this.actor = new St.BoxLayout({ style_class: 'pad-osd-window',
|
||||
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.connect('destroy', this._onDestroy.bind(this));
|
||||
Main.uiGroup.add_actor(this);
|
||||
|
||||
this._monitorIndex = monitorIndex;
|
||||
let constraint = new Layout.MonitorConstraint({ index: monitorIndex });
|
||||
this.actor.add_constraint(constraint);
|
||||
this.add_constraint(constraint);
|
||||
|
||||
this._titleBox = new St.BoxLayout({ style_class: 'pad-osd-title-box',
|
||||
vertical: false,
|
||||
x_expand: false,
|
||||
x_align: Clutter.ActorAlign.CENTER });
|
||||
this.actor.add_actor(this._titleBox);
|
||||
this.add_actor(this._titleBox);
|
||||
|
||||
let labelBox = new St.BoxLayout({ style_class: 'pad-osd-title-menu-box',
|
||||
vertical: true });
|
||||
@ -690,10 +698,10 @@ var PadOsd = class {
|
||||
|
||||
this._padDiagram = new PadDiagram({ image: this._imagePath,
|
||||
left_handed: settings.get_boolean('left-handed'),
|
||||
editor_actor: this._actionEditor.actor,
|
||||
editor_actor: this._actionEditor,
|
||||
x_expand: true,
|
||||
y_expand: true });
|
||||
this.actor.add_actor(this._padDiagram);
|
||||
this.add_actor(this._padDiagram);
|
||||
|
||||
// FIXME: Fix num buttons.
|
||||
let i = 0;
|
||||
@ -724,7 +732,7 @@ var PadOsd = class {
|
||||
x_expand: true,
|
||||
x_align: Clutter.ActorAlign.CENTER,
|
||||
y_align: Clutter.ActorAlign.CENTER });
|
||||
this.actor.add_actor(buttonBox);
|
||||
this.add_actor(buttonBox);
|
||||
this._editButton = new St.Button({ label: _("Edit…"),
|
||||
style_class: 'button',
|
||||
x_align: Clutter.ActorAlign.CENTER,
|
||||
@ -735,7 +743,7 @@ var PadOsd = class {
|
||||
buttonBox.add_actor(this._editButton);
|
||||
|
||||
this._syncEditionMode();
|
||||
Main.pushModal(this.actor);
|
||||
Main.pushModal(this);
|
||||
}
|
||||
|
||||
_updatePadChooser() {
|
||||
@ -745,7 +753,7 @@ var PadOsd = class {
|
||||
this._padChooser.connect('pad-selected', (chooser, pad) => {
|
||||
this._requestForOtherPad(pad);
|
||||
});
|
||||
this._titleBox.add_child(this._padChooser.actor);
|
||||
this._titleBox.add_child(this._padChooser);
|
||||
} else {
|
||||
this._padChooser.update(this._groupPads);
|
||||
}
|
||||
@ -918,12 +926,8 @@ var PadOsd = class {
|
||||
this._syncEditionMode();
|
||||
}
|
||||
|
||||
destroy() {
|
||||
this.actor.destroy();
|
||||
}
|
||||
|
||||
_onDestroy() {
|
||||
Main.popModal(this.actor);
|
||||
Main.popModal(this);
|
||||
this._actionEditor.close();
|
||||
|
||||
let deviceManager = Clutter.DeviceManager.get_default();
|
||||
@ -941,11 +945,9 @@ var PadOsd = class {
|
||||
this._capturedEventId = 0;
|
||||
}
|
||||
|
||||
this.actor = null;
|
||||
this.emit('closed');
|
||||
}
|
||||
};
|
||||
Signals.addSignalMethods(PadOsd.prototype);
|
||||
});
|
||||
|
||||
const PadOsdIface = loadInterfaceXML('org.gnome.Shell.Wacom.PadOsd');
|
||||
|
||||
|
@ -20,14 +20,17 @@ var ANIMATION_DELAY = 100;
|
||||
var PageIndicators = GObject.registerClass({
|
||||
Signals: { 'page-activated': { param_types: [GObject.TYPE_INT] } }
|
||||
}, class PageIndicators extends St.BoxLayout {
|
||||
_init(vertical = true) {
|
||||
super._init({ style_class: 'page-indicators',
|
||||
vertical,
|
||||
x_expand: true, y_expand: true,
|
||||
x_align: vertical ? Clutter.ActorAlign.END : Clutter.ActorAlign.CENTER,
|
||||
y_align: vertical ? Clutter.ActorAlign.CENTER : Clutter.ActorAlign.END,
|
||||
reactive: true,
|
||||
clip_to_allocation: true });
|
||||
_init(orientation = Clutter.Orientation.VERTICAL) {
|
||||
let vertical = orientation == Clutter.Orientation.VERTICAL;
|
||||
super._init({
|
||||
style_class: 'page-indicators',
|
||||
vertical,
|
||||
x_expand: true, y_expand: true,
|
||||
x_align: vertical ? Clutter.ActorAlign.END : Clutter.ActorAlign.CENTER,
|
||||
y_align: vertical ? Clutter.ActorAlign.CENTER : Clutter.ActorAlign.END,
|
||||
reactive: true,
|
||||
clip_to_allocation: true
|
||||
});
|
||||
this._nPages = 0;
|
||||
this._currentPage = undefined;
|
||||
this._reactive = true;
|
||||
@ -93,18 +96,26 @@ var PageIndicators = GObject.registerClass({
|
||||
var AnimatedPageIndicators = GObject.registerClass(
|
||||
class AnimatedPageIndicators extends PageIndicators {
|
||||
_init() {
|
||||
super._init(true);
|
||||
super._init();
|
||||
this.connect('destroy', this._onDestroy.bind(this));
|
||||
}
|
||||
|
||||
this.connect('notify::mapped', () => {
|
||||
if (!this.mapped)
|
||||
return;
|
||||
_onDestroy() {
|
||||
if (this.animateLater) {
|
||||
Meta.later_remove(this.animateLater);
|
||||
this.animateLater = 0;
|
||||
}
|
||||
}
|
||||
|
||||
// Implicit animations are skipped for unmapped actors, and our
|
||||
// children aren't mapped yet, so defer to a later handler
|
||||
Meta.later_add(Meta.LaterType.BEFORE_REDRAW, () => {
|
||||
this.animateIndicators(AnimationDirection.IN);
|
||||
return GLib.SOURCE_REMOVE;
|
||||
});
|
||||
vfunc_map() {
|
||||
super.vfunc_map();
|
||||
|
||||
// Implicit animations are skipped for unmapped actors, and our
|
||||
// children aren't mapped yet, so defer to a later handler
|
||||
this.animateLater = Meta.later_add(Meta.LaterType.BEFORE_REDRAW, () => {
|
||||
this.animateLater = 0;
|
||||
this.animateIndicators(AnimationDirection.IN);
|
||||
return GLib.SOURCE_REMOVE;
|
||||
});
|
||||
}
|
||||
|
||||
|
159
js/ui/panel.js
159
js/ui/panel.js
@ -235,7 +235,7 @@ var AppMenuButton = GObject.registerClass({
|
||||
this._overviewShowingId = Main.overview.connect('showing', this._sync.bind(this));
|
||||
|
||||
this._spinner = new Animation.Spinner(PANEL_ICON_SIZE, true);
|
||||
this._container.add_actor(this._spinner.actor);
|
||||
this._container.add_actor(this._spinner);
|
||||
|
||||
let menu = new AppMenu(this);
|
||||
this.setMenu(menu);
|
||||
@ -430,9 +430,6 @@ class ActivitiesButton extends PanelMenu.Button {
|
||||
|
||||
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', () => {
|
||||
this.add_style_pseudo_class('overview');
|
||||
this.add_accessible_state (Atk.StateType.CHECKED);
|
||||
@ -459,7 +456,7 @@ class ActivitiesButton extends PanelMenu.Button {
|
||||
return DND.DragMotionResult.CONTINUE;
|
||||
}
|
||||
|
||||
_onCapturedEvent(actor, event) {
|
||||
vfunc_captured_event(event) {
|
||||
if (event.type() == Clutter.EventType.BUTTON_PRESS ||
|
||||
event.type() == Clutter.EventType.TOUCH_BEGIN) {
|
||||
if (!Main.overview.shouldToggleByCornerOrButton())
|
||||
@ -468,9 +465,7 @@ class ActivitiesButton extends PanelMenu.Button {
|
||||
return Clutter.EVENT_PROPAGATE;
|
||||
}
|
||||
|
||||
_onEvent(actor, event) {
|
||||
super._onEvent(actor, event);
|
||||
|
||||
vfunc_event(event) {
|
||||
if (event.type() == Clutter.EventType.TOUCH_END ||
|
||||
event.type() == Clutter.EventType.BUTTON_RELEASE)
|
||||
if (Main.overview.shouldToggleByCornerOrButton())
|
||||
@ -479,13 +474,16 @@ class ActivitiesButton extends PanelMenu.Button {
|
||||
return Clutter.EVENT_PROPAGATE;
|
||||
}
|
||||
|
||||
_onKeyRelease(actor, event) {
|
||||
let symbol = event.get_key_symbol();
|
||||
if (symbol == Clutter.KEY_Return || symbol == Clutter.KEY_space) {
|
||||
if (Main.overview.shouldToggleByCornerOrButton())
|
||||
Main.overview.toggle();
|
||||
vfunc_key_release_event(keyEvent) {
|
||||
let ret = super.vfunc_key_release_event(keyEvent);
|
||||
if (ret == Clutter.EVENT_PROPAGATE) {
|
||||
let symbol = keyEvent.keyval;
|
||||
if (symbol == Clutter.KEY_Return || symbol == Clutter.KEY_space) {
|
||||
if (Main.overview.shouldToggleByCornerOrButton())
|
||||
Main.overview.toggle();
|
||||
}
|
||||
}
|
||||
return Clutter.EVENT_PROPAGATE;
|
||||
return ret;
|
||||
}
|
||||
|
||||
_xdndToggleOverview() {
|
||||
@ -501,13 +499,12 @@ class ActivitiesButton extends PanelMenu.Button {
|
||||
}
|
||||
});
|
||||
|
||||
var PanelCorner = class {
|
||||
constructor(side) {
|
||||
var PanelCorner = GObject.registerClass(
|
||||
class PanelCorner extends St.DrawingArea {
|
||||
_init(side) {
|
||||
this._side = side;
|
||||
|
||||
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));
|
||||
super._init({ style_class: 'panel-corner' });
|
||||
}
|
||||
|
||||
_findRightmostButton(container) {
|
||||
@ -597,7 +594,7 @@ var PanelCorner = class {
|
||||
this._buttonStyleChangedSignalId = button.connect('style-changed',
|
||||
() => {
|
||||
let pseudoClass = button.get_style_pseudo_class();
|
||||
this.actor.set_style_pseudo_class(pseudoClass);
|
||||
this.set_style_pseudo_class(pseudoClass);
|
||||
});
|
||||
|
||||
// The corner doesn't support theme transitions, so override
|
||||
@ -606,8 +603,8 @@ var PanelCorner = class {
|
||||
}
|
||||
}
|
||||
|
||||
_repaint() {
|
||||
let node = this.actor.get_theme_node();
|
||||
vfunc_repaint() {
|
||||
let node = this.get_theme_node();
|
||||
|
||||
let cornerRadius = node.get_length("-panel-corner-radius");
|
||||
let borderWidth = node.get_length('-panel-corner-border-width');
|
||||
@ -618,7 +615,7 @@ var PanelCorner = class {
|
||||
let overlap = borderColor.alpha != 0;
|
||||
let offsetY = overlap ? 0 : borderWidth;
|
||||
|
||||
let cr = this.actor.get_context();
|
||||
let cr = this.get_context();
|
||||
cr.setOperator(Cairo.Operator.SOURCE);
|
||||
|
||||
cr.moveTo(0, offsetY);
|
||||
@ -654,16 +651,17 @@ var PanelCorner = class {
|
||||
cr.$dispose();
|
||||
}
|
||||
|
||||
_styleChanged() {
|
||||
let node = this.actor.get_theme_node();
|
||||
vfunc_style_changed() {
|
||||
super.vfunc_style_changed();
|
||||
let node = this.get_theme_node();
|
||||
|
||||
let cornerRadius = node.get_length("-panel-corner-radius");
|
||||
let borderWidth = node.get_length('-panel-corner-border-width');
|
||||
|
||||
this.actor.set_size(cornerRadius, borderWidth + cornerRadius);
|
||||
this.actor.set_anchor_point(0, borderWidth);
|
||||
this.set_size(cornerRadius, borderWidth + cornerRadius);
|
||||
this.set_anchor_point(0, borderWidth);
|
||||
}
|
||||
};
|
||||
});
|
||||
|
||||
var AggregateLayout = GObject.registerClass(
|
||||
class AggregateLayout extends Clutter.BoxLayout {
|
||||
@ -728,20 +726,20 @@ class AggregateMenu extends PanelMenu.Button {
|
||||
this._nightLight = new imports.ui.status.nightLight.Indicator();
|
||||
this._thunderbolt = new imports.ui.status.thunderbolt.Indicator();
|
||||
|
||||
this._indicators.add_child(this._thunderbolt.indicators);
|
||||
this._indicators.add_child(this._screencast.indicators);
|
||||
this._indicators.add_child(this._location.indicators);
|
||||
this._indicators.add_child(this._nightLight.indicators);
|
||||
this._indicators.add_child(this._thunderbolt);
|
||||
this._indicators.add_child(this._screencast);
|
||||
this._indicators.add_child(this._location);
|
||||
this._indicators.add_child(this._nightLight);
|
||||
if (this._network) {
|
||||
this._indicators.add_child(this._network.indicators);
|
||||
this._indicators.add_child(this._network);
|
||||
}
|
||||
if (this._bluetooth) {
|
||||
this._indicators.add_child(this._bluetooth.indicators);
|
||||
this._indicators.add_child(this._bluetooth);
|
||||
}
|
||||
this._indicators.add_child(this._remoteAccess.indicators);
|
||||
this._indicators.add_child(this._rfkill.indicators);
|
||||
this._indicators.add_child(this._volume.indicators);
|
||||
this._indicators.add_child(this._power.indicators);
|
||||
this._indicators.add_child(this._remoteAccess);
|
||||
this._indicators.add_child(this._rfkill);
|
||||
this._indicators.add_child(this._volume);
|
||||
this._indicators.add_child(this._power);
|
||||
this._indicators.add_child(PopupMenu.arrowIcon(St.Side.BOTTOM));
|
||||
|
||||
this.menu.addMenuItem(this._volume.menu);
|
||||
@ -799,14 +797,10 @@ class Panel extends St.Widget {
|
||||
this.add_child(this._rightBox);
|
||||
|
||||
this._leftCorner = new PanelCorner(St.Side.LEFT);
|
||||
this.add_child(this._leftCorner.actor);
|
||||
this.add_child(this._leftCorner);
|
||||
|
||||
this._rightCorner = new PanelCorner(St.Side.RIGHT);
|
||||
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));
|
||||
this.add_child(this._rightCorner);
|
||||
|
||||
Main.overview.connect('showing', () => {
|
||||
this.add_style_pseudo_class('overview');
|
||||
@ -895,62 +889,65 @@ class Panel extends St.Widget {
|
||||
|
||||
let cornerWidth, cornerHeight;
|
||||
|
||||
[, cornerWidth] = this._leftCorner.actor.get_preferred_width(-1);
|
||||
[, cornerHeight] = this._leftCorner.actor.get_preferred_height(-1);
|
||||
[, cornerWidth] = this._leftCorner.get_preferred_width(-1);
|
||||
[, cornerHeight] = this._leftCorner.get_preferred_height(-1);
|
||||
childBox.x1 = 0;
|
||||
childBox.x2 = cornerWidth;
|
||||
childBox.y1 = allocHeight;
|
||||
childBox.y2 = allocHeight + cornerHeight;
|
||||
this._leftCorner.actor.allocate(childBox, flags);
|
||||
this._leftCorner.allocate(childBox, flags);
|
||||
|
||||
[, cornerWidth] = this._rightCorner.actor.get_preferred_width(-1);
|
||||
[, cornerHeight] = this._rightCorner.actor.get_preferred_height(-1);
|
||||
[, cornerWidth] = this._rightCorner.get_preferred_width(-1);
|
||||
[, cornerHeight] = this._rightCorner.get_preferred_height(-1);
|
||||
childBox.x1 = allocWidth - cornerWidth;
|
||||
childBox.x2 = allocWidth;
|
||||
childBox.y1 = allocHeight;
|
||||
childBox.y2 = allocHeight + cornerHeight;
|
||||
this._rightCorner.actor.allocate(childBox, flags);
|
||||
this._rightCorner.allocate(childBox, flags);
|
||||
}
|
||||
|
||||
_onButtonPress(actor, event) {
|
||||
_tryDragWindow(event) {
|
||||
if (Main.modalCount > 0)
|
||||
return Clutter.EVENT_PROPAGATE;
|
||||
|
||||
if (event.get_source() != actor)
|
||||
if (event.source != this)
|
||||
return Clutter.EVENT_PROPAGATE;
|
||||
|
||||
let type = event.type();
|
||||
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);
|
||||
let { x, y } = event;
|
||||
let dragWindow = this._getDraggableWindowForPosition(x);
|
||||
|
||||
if (!dragWindow)
|
||||
return Clutter.EVENT_PROPAGATE;
|
||||
|
||||
global.display.begin_grab_op(dragWindow,
|
||||
Meta.GrabOp.MOVING,
|
||||
false, /* pointer grab */
|
||||
true, /* frame action */
|
||||
button,
|
||||
event.get_state(),
|
||||
event.get_time(),
|
||||
stageX, stageY);
|
||||
|
||||
return Clutter.EVENT_STOP;
|
||||
return global.display.begin_grab_op(
|
||||
dragWindow,
|
||||
Meta.GrabOp.MOVING,
|
||||
false, /* pointer grab */
|
||||
true, /* frame action */
|
||||
event.button || -1,
|
||||
event.modifier_state,
|
||||
event.time,
|
||||
x, y) ? Clutter.EVENT_STOP : Clutter.EVENT_PROPAGATE;
|
||||
}
|
||||
|
||||
_onKeyPress(actor, event) {
|
||||
let symbol = event.get_key_symbol();
|
||||
vfunc_button_press_event(buttonEvent) {
|
||||
if (buttonEvent.button != 1)
|
||||
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) {
|
||||
global.display.focus_default_window(event.get_time());
|
||||
global.display.focus_default_window(keyEvent.time);
|
||||
return Clutter.EVENT_STOP;
|
||||
}
|
||||
|
||||
@ -1114,14 +1111,14 @@ class Panel extends St.Widget {
|
||||
|
||||
_addStyleClassName(className) {
|
||||
this.add_style_class_name(className);
|
||||
this._rightCorner.actor.add_style_class_name(className);
|
||||
this._leftCorner.actor.add_style_class_name(className);
|
||||
this._rightCorner.add_style_class_name(className);
|
||||
this._leftCorner.add_style_class_name(className);
|
||||
}
|
||||
|
||||
_removeStyleClassName(className) {
|
||||
this.remove_style_class_name(className);
|
||||
this._rightCorner.actor.remove_style_class_name(className);
|
||||
this._leftCorner.actor.remove_style_class_name(className);
|
||||
this._rightCorner.remove_style_class_name(className);
|
||||
this._leftCorner.remove_style_class_name(className);
|
||||
}
|
||||
|
||||
_onMenuSet(indicator) {
|
||||
|
@ -2,7 +2,6 @@
|
||||
/* exported Button, SystemIndicator */
|
||||
|
||||
const { Atk, Clutter, GObject, St } = imports.gi;
|
||||
const Signals = imports.signals;
|
||||
|
||||
const Main = imports.ui.main;
|
||||
const Params = imports.misc.params;
|
||||
@ -101,9 +100,6 @@ var Button = GObject.registerClass({
|
||||
accessible_name: nameText ? nameText : "",
|
||||
accessible_role: Atk.Role.MENU });
|
||||
|
||||
this.connect('event', this._onEvent.bind(this));
|
||||
this.connect('notify::visible', this._onVisibilityChanged.bind(this));
|
||||
|
||||
if (dontCreateMenu)
|
||||
this.menu = new PopupMenu.PopupDummyMenu(this);
|
||||
else
|
||||
@ -132,7 +128,7 @@ var Button = GObject.registerClass({
|
||||
this.emit('menu-set');
|
||||
}
|
||||
|
||||
_onEvent(actor, event) {
|
||||
vfunc_event(event) {
|
||||
if (this.menu &&
|
||||
(event.type() == Clutter.EventType.TOUCH_BEGIN ||
|
||||
event.type() == Clutter.EventType.BUTTON_PRESS))
|
||||
@ -141,11 +137,10 @@ var Button = GObject.registerClass({
|
||||
return Clutter.EVENT_PROPAGATE;
|
||||
}
|
||||
|
||||
_onVisibilityChanged() {
|
||||
if (!this.menu)
|
||||
return;
|
||||
vfunc_hide() {
|
||||
super.vfunc_hide();
|
||||
|
||||
if (!this.visible)
|
||||
if (this.menu)
|
||||
this.menu.close();
|
||||
}
|
||||
|
||||
@ -200,24 +195,34 @@ var Button = GObject.registerClass({
|
||||
* of an icon and a menu section, which will be composed into the
|
||||
* aggregate menu.
|
||||
*/
|
||||
var SystemIndicator = class {
|
||||
constructor() {
|
||||
this.indicators = new St.BoxLayout({ style_class: 'panel-status-indicators-box',
|
||||
reactive: true });
|
||||
this.indicators.hide();
|
||||
var SystemIndicator = GObject.registerClass({
|
||||
GTypeName: 'PanelMenu_SystemIndicator',
|
||||
}, class SystemIndicator extends St.BoxLayout {
|
||||
_init() {
|
||||
super._init({
|
||||
style_class: 'panel-status-indicators-box',
|
||||
reactive: true,
|
||||
visible: false
|
||||
});
|
||||
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() {
|
||||
this.indicators.visible = this.indicators.get_children().some(a => a.visible);
|
||||
this.visible = this.get_children().some(a => a.visible);
|
||||
}
|
||||
|
||||
_addIndicator() {
|
||||
let icon = new St.Icon({ style_class: 'system-status-icon' });
|
||||
this.indicators.add_actor(icon);
|
||||
this.add_actor(icon);
|
||||
icon.connect('notify::visible', this._syncIndicatorsVisible.bind(this));
|
||||
this._syncIndicatorsVisible();
|
||||
return icon;
|
||||
}
|
||||
};
|
||||
Signals.addSignalMethods(SystemIndicator.prototype);
|
||||
});
|
||||
|
@ -3,7 +3,7 @@
|
||||
PopupImageMenuItem, PopupMenu, PopupDummyMenu, PopupSubMenu,
|
||||
PopupMenuSection, PopupSubMenuMenuItem, PopupMenuManager */
|
||||
|
||||
const { Atk, Clutter, Gio, GObject, Shell, St } = imports.gi;
|
||||
const { Atk, Clutter, Gio, GObject, Graphene, Shell, St } = imports.gi;
|
||||
const Signals = imports.signals;
|
||||
|
||||
const BoxPointer = imports.ui.boxpointer;
|
||||
@ -97,12 +97,6 @@ var PopupBaseMenuItem = GObject.registerClass({
|
||||
if (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)
|
||||
this.bind_property('hover', this, 'active', GObject.BindingFlags.SYNC_CREATE);
|
||||
}
|
||||
@ -124,32 +118,44 @@ var PopupBaseMenuItem = GObject.registerClass({
|
||||
this._parent = parent;
|
||||
}
|
||||
|
||||
_onButtonPressEvent() {
|
||||
vfunc_button_press_event(buttonEvent) {
|
||||
if (!this._activatable)
|
||||
return super.vfunc_button_press_event(buttonEvent);
|
||||
|
||||
// This is the CSS active state
|
||||
this.add_style_pseudo_class('active');
|
||||
return Clutter.EVENT_PROPAGATE;
|
||||
}
|
||||
|
||||
_onButtonReleaseEvent(actor, event) {
|
||||
vfunc_button_release_event(buttonEvent) {
|
||||
if (!this._activatable)
|
||||
return super.vfunc_button_release_event(buttonEvent);
|
||||
|
||||
this.remove_style_pseudo_class('active');
|
||||
this.activate(event);
|
||||
this.activate(Clutter.get_current_event());
|
||||
return Clutter.EVENT_STOP;
|
||||
}
|
||||
|
||||
_onTouchEvent(actor, event) {
|
||||
if (event.type() == Clutter.EventType.TOUCH_END) {
|
||||
vfunc_touch_event(touchEvent) {
|
||||
if (!this._activatable)
|
||||
return super.vfunc_touch_event(touchEvent);
|
||||
|
||||
if (touchEvent.type == Clutter.EventType.TOUCH_END) {
|
||||
this.remove_style_pseudo_class('active');
|
||||
this.activate(event);
|
||||
this.activate(Clutter.get_current_event());
|
||||
return Clutter.EVENT_STOP;
|
||||
} else if (event.type() == Clutter.EventType.TOUCH_BEGIN) {
|
||||
} else if (touchEvent.type == Clutter.EventType.TOUCH_BEGIN) {
|
||||
// This is the CSS active state
|
||||
this.add_style_pseudo_class('active');
|
||||
}
|
||||
return Clutter.EVENT_PROPAGATE;
|
||||
}
|
||||
|
||||
_onKeyPressEvent(actor, event) {
|
||||
let state = event.get_state();
|
||||
vfunc_key_press_event(keyEvent) {
|
||||
if (!this._activatable)
|
||||
return super.vfunc_key_press_event(keyEvent);
|
||||
|
||||
let state = keyEvent.modifier_state;
|
||||
|
||||
// if user has a modifier down (except capslock and numlock)
|
||||
// then don't handle the key press here
|
||||
@ -160,9 +166,9 @@ var PopupBaseMenuItem = GObject.registerClass({
|
||||
if (state)
|
||||
return Clutter.EVENT_PROPAGATE;
|
||||
|
||||
let symbol = event.get_key_symbol();
|
||||
let symbol = keyEvent.keyval;
|
||||
if (symbol == Clutter.KEY_space || symbol == Clutter.KEY_Return) {
|
||||
this.activate(event);
|
||||
this.activate(Clutter.get_current_event());
|
||||
return Clutter.EVENT_STOP;
|
||||
}
|
||||
return Clutter.EVENT_PROPAGATE;
|
||||
@ -1130,7 +1136,7 @@ class PopupSubMenuMenuItem extends PopupBaseMenuItem {
|
||||
this.add(expander, { expand: true });
|
||||
|
||||
this._triangle = arrowIcon(St.Side.RIGHT);
|
||||
this._triangle.pivot_point = new Clutter.Point({ x: 0.5, y: 0.6 });
|
||||
this._triangle.pivot_point = new Graphene.Point({ x: 0.5, y: 0.6 });
|
||||
|
||||
this._triangleBin = new St.Widget({ y_expand: true,
|
||||
y_align: Clutter.ActorAlign.CENTER });
|
||||
@ -1185,8 +1191,8 @@ class PopupSubMenuMenuItem extends PopupBaseMenuItem {
|
||||
return this.menu.isOpen;
|
||||
}
|
||||
|
||||
_onKeyPressEvent(actor, event) {
|
||||
let symbol = event.get_key_symbol();
|
||||
vfunc_key_press_event(keyPressEvent) {
|
||||
let symbol = keyPressEvent.keyval;
|
||||
|
||||
if (symbol == Clutter.KEY_Right) {
|
||||
this._setOpenState(true);
|
||||
@ -1197,14 +1203,14 @@ class PopupSubMenuMenuItem extends PopupBaseMenuItem {
|
||||
return Clutter.EVENT_STOP;
|
||||
}
|
||||
|
||||
return super._onKeyPressEvent(actor, event);
|
||||
return super.vfunc_key_press_event(keyPressEvent);
|
||||
}
|
||||
|
||||
activate(_event) {
|
||||
this._setOpenState(true);
|
||||
}
|
||||
|
||||
_onButtonReleaseEvent() {
|
||||
vfunc_button_release_event() {
|
||||
// Since we override the parent, we need to manage what the parent does
|
||||
// with the active style class
|
||||
this.remove_style_pseudo_class('active');
|
||||
@ -1212,8 +1218,8 @@ class PopupSubMenuMenuItem extends PopupBaseMenuItem {
|
||||
return Clutter.EVENT_PROPAGATE;
|
||||
}
|
||||
|
||||
_onTouchEvent(actor, event) {
|
||||
if (event.type() == Clutter.EventType.TOUCH_END) {
|
||||
vfunc_touch_event(touchEvent) {
|
||||
if (touchEvent.type == Clutter.EventType.TOUCH_END) {
|
||||
// Since we override the parent, we need to manage what the parent does
|
||||
// with the active style class
|
||||
this.remove_style_pseudo_class('active');
|
||||
|
@ -1,7 +1,7 @@
|
||||
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
|
||||
|
||||
const { AccountsService, Clutter, Cogl, Gio, GLib,
|
||||
GnomeDesktop, GObject, Meta, Shell, St } = imports.gi;
|
||||
GnomeDesktop, GObject, Graphene, Meta, Shell, St } = imports.gi;
|
||||
const Cairo = imports.cairo;
|
||||
const Signals = imports.signals;
|
||||
|
||||
@ -17,6 +17,8 @@ const MessageTray = imports.ui.messageTray;
|
||||
const ShellDBus = imports.ui.shellDBus;
|
||||
const SmartcardManager = imports.misc.smartcardManager;
|
||||
|
||||
const { adjustAnimationTime } = imports.ui.environment;
|
||||
|
||||
const SCREENSAVER_SCHEMA = 'org.gnome.desktop.screensaver';
|
||||
const LOCK_ENABLED_KEY = 'lock-enabled';
|
||||
const LOCK_DELAY_KEY = 'lock-delay';
|
||||
@ -46,21 +48,23 @@ var STANDARD_FADE_TIME = 10000;
|
||||
var MANUAL_FADE_TIME = 300;
|
||||
var CURTAIN_SLIDE_TIME = 300;
|
||||
|
||||
var Clock = class {
|
||||
constructor() {
|
||||
this.actor = new St.BoxLayout({ style_class: 'screen-shield-clock',
|
||||
vertical: true });
|
||||
var Clock = GObject.registerClass(
|
||||
class ScreenShieldClock extends St.BoxLayout {
|
||||
_init() {
|
||||
super._init({ 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.add(this._time, { x_align: St.Align.MIDDLE });
|
||||
this.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();
|
||||
|
||||
this.connect('destroy', this._onDestroy.bind(this));
|
||||
}
|
||||
|
||||
_updateClock() {
|
||||
@ -73,17 +77,20 @@ var Clock = class {
|
||||
this._date.text = date.toLocaleFormat(dateFormat);
|
||||
}
|
||||
|
||||
destroy() {
|
||||
this.actor.destroy();
|
||||
_onDestroy() {
|
||||
this._wallClock.run_dispose();
|
||||
}
|
||||
};
|
||||
});
|
||||
|
||||
var NotificationsBox = class {
|
||||
constructor() {
|
||||
this.actor = new St.BoxLayout({ vertical: true,
|
||||
name: 'screenShieldNotifications',
|
||||
style_class: 'screen-shield-notifications-container' });
|
||||
var NotificationsBox = GObject.registerClass({
|
||||
Signals: { 'wake-up-screen': {} }
|
||||
}, class NotificationsBox extends St.BoxLayout {
|
||||
_init() {
|
||||
super._init({
|
||||
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 });
|
||||
@ -91,7 +98,7 @@ var NotificationsBox = class {
|
||||
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.add(this._scrollView, { x_fill: true, x_align: St.Align.START });
|
||||
|
||||
this._sources = new Map();
|
||||
Main.messageTray.getSources().forEach(source => {
|
||||
@ -100,9 +107,11 @@ var NotificationsBox = class {
|
||||
this._updateVisibility();
|
||||
|
||||
this._sourceAddedId = Main.messageTray.connect('source-added', this._sourceAdded.bind(this));
|
||||
|
||||
this.connect('destroy', this._onDestroy.bind(this));
|
||||
}
|
||||
|
||||
destroy() {
|
||||
_onDestroy() {
|
||||
if (this._sourceAddedId) {
|
||||
Main.messageTray.disconnect(this._sourceAddedId);
|
||||
this._sourceAddedId = 0;
|
||||
@ -112,15 +121,13 @@ var NotificationsBox = class {
|
||||
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;
|
||||
this.visible = this._notificationBox.visible;
|
||||
}
|
||||
|
||||
_makeNotificationCountText(count, isChat) {
|
||||
@ -222,14 +229,14 @@ var NotificationsBox = class {
|
||||
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 => {
|
||||
obj.sourceCountChangedId = source.connect('notify::count', source => {
|
||||
this._countChanged(source, obj);
|
||||
});
|
||||
obj.sourceTitleChangedId = source.connect('title-changed', source => {
|
||||
obj.sourceTitleChangedId = source.connect('notify::title', source => {
|
||||
this._titleChanged(source, obj);
|
||||
});
|
||||
obj.policyChangedId = source.policy.connect('policy-changed', (policy, key) => {
|
||||
if (key == 'show-in-lock-screen')
|
||||
obj.policyChangedId = source.policy.connect('notify', (policy, pspec) => {
|
||||
if (pspec.name == 'show-in-lock-screen')
|
||||
this._visibleChanged(source, obj);
|
||||
else
|
||||
this._detailedChanged(source, obj);
|
||||
@ -336,8 +343,7 @@ var NotificationsBox = class {
|
||||
|
||||
this._sources.delete(source);
|
||||
}
|
||||
};
|
||||
Signals.addSignalMethods(NotificationsBox.prototype);
|
||||
});
|
||||
|
||||
var Arrow = GObject.registerClass(
|
||||
class ScreenShieldArrow extends St.Bin {
|
||||
@ -486,7 +492,7 @@ var ScreenShield = class {
|
||||
this._lockDialogGroup = new St.Widget({ x_expand: true,
|
||||
y_expand: true,
|
||||
reactive: true,
|
||||
pivot_point: new Clutter.Point({ x: 0.5, y: 0.5 }),
|
||||
pivot_point: new Graphene.Point({ x: 0.5, y: 0.5 }),
|
||||
name: 'lockDialogGroup' });
|
||||
|
||||
this.actor.add_actor(this._lockDialogGroup);
|
||||
@ -557,11 +563,11 @@ var ScreenShield = class {
|
||||
this._longLightbox = new Lightbox.Lightbox(Main.uiGroup,
|
||||
{ inhibitEvents: true,
|
||||
fadeFactor: 1 });
|
||||
this._longLightbox.connect('shown', this._onLongLightboxShown.bind(this));
|
||||
this._longLightbox.connect('notify::active', this._onLongLightbox.bind(this));
|
||||
this._shortLightbox = new Lightbox.Lightbox(Main.uiGroup,
|
||||
{ inhibitEvents: true,
|
||||
fadeFactor: 1 });
|
||||
this._shortLightbox.connect('shown', this._onShortLightboxShown.bind(this));
|
||||
this._shortLightbox.connect('notify::active', this._onShortLightbox.bind(this));
|
||||
|
||||
this.idleMonitor = Meta.IdleMonitor.get_core();
|
||||
this._cursorTracker = Meta.CursorTracker.get_for_display(global.display);
|
||||
@ -807,7 +813,7 @@ var ScreenShield = class {
|
||||
|
||||
this._maybeCancelDialog();
|
||||
|
||||
if (this._longLightbox.actor.visible) {
|
||||
if (this._longLightbox.visible) {
|
||||
// We're in the process of showing.
|
||||
return;
|
||||
}
|
||||
@ -832,7 +838,7 @@ var ScreenShield = class {
|
||||
|
||||
if (shouldLock) {
|
||||
let lockTimeout = Math.max(
|
||||
STANDARD_FADE_TIME,
|
||||
adjustAnimationTime(STANDARD_FADE_TIME),
|
||||
this._settings.get_uint(LOCK_DELAY_KEY) * 1000);
|
||||
this._lockTimeoutId = GLib.timeout_add(
|
||||
GLib.PRIORITY_DEFAULT,
|
||||
@ -849,8 +855,8 @@ var ScreenShield = class {
|
||||
}
|
||||
|
||||
_activateFade(lightbox, time) {
|
||||
Main.uiGroup.set_child_above_sibling(lightbox.actor, null);
|
||||
lightbox.show(time);
|
||||
Main.uiGroup.set_child_above_sibling(lightbox, null);
|
||||
lightbox.lightOn(time);
|
||||
|
||||
if (this._becameActiveId == 0)
|
||||
this._becameActiveId = this.idleMonitor.add_user_active_watch(this._onUserBecameActive.bind(this));
|
||||
@ -879,19 +885,21 @@ var ScreenShield = class {
|
||||
this._becameActiveId = 0;
|
||||
|
||||
if (this._isActive || this._isLocked) {
|
||||
this._longLightbox.hide();
|
||||
this._shortLightbox.hide();
|
||||
this._longLightbox.lightOff();
|
||||
this._shortLightbox.lightOff();
|
||||
} else {
|
||||
this.deactivate(false);
|
||||
}
|
||||
}
|
||||
|
||||
_onLongLightboxShown() {
|
||||
this.activate(false);
|
||||
_onLongLightbox(lightBox) {
|
||||
if (lightBox.active)
|
||||
this.activate(false);
|
||||
}
|
||||
|
||||
_onShortLightboxShown() {
|
||||
this._completeLockScreenShown();
|
||||
_onShortLightbox(lightBox) {
|
||||
if (lightBox.active)
|
||||
this._completeLockScreenShown();
|
||||
}
|
||||
|
||||
showDialog() {
|
||||
@ -965,7 +973,6 @@ var ScreenShield = class {
|
||||
|
||||
this._dialog = new constructor(this._lockDialogGroup);
|
||||
|
||||
|
||||
let time = global.get_current_time();
|
||||
if (!this._dialog.open(time, onPrimary)) {
|
||||
// This is kind of an impossible error: we're already modal
|
||||
@ -1131,16 +1138,20 @@ var ScreenShield = class {
|
||||
vertical: true,
|
||||
style_class: 'screen-shield-contents-box' });
|
||||
this._clock = new Clock();
|
||||
this._lockScreenContentsBox.add(this._clock.actor, { x_fill: true,
|
||||
y_fill: true });
|
||||
this._lockScreenContentsBox.add(this._clock, {
|
||||
x_fill: true,
|
||||
y_fill: true
|
||||
});
|
||||
|
||||
this._lockScreenContents.add_actor(this._lockScreenContentsBox);
|
||||
|
||||
this._notificationsBox = new NotificationsBox();
|
||||
this._wakeUpScreenId = this._notificationsBox.connect('wake-up-screen', this._wakeUpScreen.bind(this));
|
||||
this._lockScreenContentsBox.add(this._notificationsBox.actor, { x_fill: true,
|
||||
y_fill: true,
|
||||
expand: true });
|
||||
this._lockScreenContentsBox.add(this._notificationsBox, {
|
||||
x_fill: true,
|
||||
y_fill: true,
|
||||
expand: true
|
||||
});
|
||||
|
||||
this._hasLockScreen = true;
|
||||
}
|
||||
@ -1233,8 +1244,8 @@ var ScreenShield = class {
|
||||
this._dialog = null;
|
||||
}
|
||||
|
||||
this._longLightbox.hide();
|
||||
this._shortLightbox.hide();
|
||||
this._longLightbox.lightOff();
|
||||
this._shortLightbox.lightOff();
|
||||
this.actor.hide();
|
||||
|
||||
if (this._becameActiveId != 0) {
|
||||
|
@ -1,8 +1,7 @@
|
||||
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
|
||||
/* exported ScreenshotService */
|
||||
|
||||
const { Clutter, Gio, GLib, Meta, Shell, St } = imports.gi;
|
||||
const Signals = imports.signals;
|
||||
const { Clutter, Graphene, Gio, GObject, GLib, Meta, Shell, St } = imports.gi;
|
||||
|
||||
const GrabHelper = imports.ui.grabHelper;
|
||||
const Lightbox = imports.ui.lightbox;
|
||||
@ -198,7 +197,7 @@ var ScreenshotService = class {
|
||||
let screenshot = this._createScreenshot(invocation, false);
|
||||
if (!screenshot)
|
||||
return;
|
||||
screenshot.pick_color(...coords, (o, res) => {
|
||||
screenshot.pick_color(coords.x, coords.y, (_o, res) => {
|
||||
let [success_, color] = screenshot.pick_color_finish(res);
|
||||
let { red, green, blue } = color;
|
||||
let retval = GLib.Variant.new('(a{sv})', [{
|
||||
@ -219,62 +218,62 @@ var ScreenshotService = class {
|
||||
}
|
||||
};
|
||||
|
||||
var SelectArea = class {
|
||||
constructor() {
|
||||
var SelectArea = GObject.registerClass({
|
||||
GTypeName: 'Screenshot_SelectArea',
|
||||
Signals: { 'finished': { param_types: [Meta.Rectangle.$gtype] } }
|
||||
}, class SelectArea extends St.Widget {
|
||||
_init() {
|
||||
this._startX = -1;
|
||||
this._startY = -1;
|
||||
this._lastX = 0;
|
||||
this._lastY = 0;
|
||||
this._result = null;
|
||||
|
||||
this._group = new St.Widget({ visible: false,
|
||||
reactive: true,
|
||||
x: 0,
|
||||
y: 0 });
|
||||
Main.uiGroup.add_actor(this._group);
|
||||
super._init({
|
||||
visible: false,
|
||||
reactive: true,
|
||||
x: 0,
|
||||
y: 0
|
||||
});
|
||||
Main.uiGroup.add_actor(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));
|
||||
this._grabHelper = new GrabHelper.GrabHelper(this);
|
||||
|
||||
let constraint = new Clutter.BindConstraint({ source: global.stage,
|
||||
coordinate: Clutter.BindCoordinate.ALL });
|
||||
this._group.add_constraint(constraint);
|
||||
this.add_constraint(constraint);
|
||||
|
||||
this._rubberband = new St.Widget({
|
||||
style_class: 'select-area-rubberband',
|
||||
visible: false
|
||||
});
|
||||
this._group.add_actor(this._rubberband);
|
||||
this.add_actor(this._rubberband);
|
||||
}
|
||||
|
||||
show() {
|
||||
if (!this._grabHelper.grab({ actor: this._group,
|
||||
vfunc_show() {
|
||||
if (!this._grabHelper.grab({ actor: this,
|
||||
onUngrab: this._onUngrab.bind(this) }))
|
||||
return;
|
||||
|
||||
global.display.set_cursor(Meta.Cursor.CROSSHAIR);
|
||||
Main.uiGroup.set_child_above_sibling(this._group, null);
|
||||
this._group.visible = true;
|
||||
Main.uiGroup.set_child_above_sibling(this, null);
|
||||
super.vfunc_show();
|
||||
}
|
||||
|
||||
_getGeometry() {
|
||||
return { x: Math.min(this._startX, this._lastX),
|
||||
y: Math.min(this._startY, this._lastY),
|
||||
width: Math.abs(this._startX - this._lastX) + 1,
|
||||
height: Math.abs(this._startY - this._lastY) + 1 };
|
||||
return new Meta.Rectangle({
|
||||
x: Math.min(this._startX, this._lastX),
|
||||
y: Math.min(this._startY, this._lastY),
|
||||
width: Math.abs(this._startX - this._lastX) + 1,
|
||||
height: Math.abs(this._startY - this._lastY) + 1
|
||||
});
|
||||
}
|
||||
|
||||
_onMotionEvent(actor, event) {
|
||||
vfunc_motion_event(motionEvent) {
|
||||
if (this._startX == -1 || this._startY == -1 || this._result)
|
||||
return Clutter.EVENT_PROPAGATE;
|
||||
|
||||
[this._lastX, this._lastY] = event.get_coords();
|
||||
[this._lastX, this._lastY] = [motionEvent.x, motionEvent.y];
|
||||
this._lastX = Math.floor(this._lastX);
|
||||
this._lastY = Math.floor(this._lastY);
|
||||
let geometry = this._getGeometry();
|
||||
@ -286,8 +285,8 @@ var SelectArea = class {
|
||||
return Clutter.EVENT_PROPAGATE;
|
||||
}
|
||||
|
||||
_onButtonPress(actor, event) {
|
||||
[this._startX, this._startY] = event.get_coords();
|
||||
vfunc_button_press_event(buttonEvent) {
|
||||
[this._startX, this._startY] = [buttonEvent.x, buttonEvent.y];
|
||||
this._startX = Math.floor(this._startX);
|
||||
this._startY = Math.floor(this._startY);
|
||||
this._rubberband.set_position(this._startX, this._startY);
|
||||
@ -295,9 +294,9 @@ var SelectArea = class {
|
||||
return Clutter.EVENT_PROPAGATE;
|
||||
}
|
||||
|
||||
_onButtonRelease() {
|
||||
vfunc_button_release_event() {
|
||||
this._result = this._getGeometry();
|
||||
this._group.ease({
|
||||
this.ease({
|
||||
opacity: 0,
|
||||
duration: 200,
|
||||
mode: Clutter.AnimationMode.EASE_OUT_QUAD,
|
||||
@ -311,43 +310,43 @@ var SelectArea = class {
|
||||
this.emit('finished', this._result);
|
||||
|
||||
GLib.idle_add(GLib.PRIORITY_DEFAULT, () => {
|
||||
this._group.destroy();
|
||||
this.destroy();
|
||||
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._group = new St.Widget({ visible: false,
|
||||
reactive: true });
|
||||
Main.uiGroup.add_actor(this._group);
|
||||
Main.uiGroup.add_actor(this);
|
||||
|
||||
this._grabHelper = new GrabHelper.GrabHelper(this._group);
|
||||
|
||||
this._group.connect('button-release-event',
|
||||
this._onButtonRelease.bind(this));
|
||||
this._grabHelper = new GrabHelper.GrabHelper(this);
|
||||
|
||||
let constraint = new Clutter.BindConstraint({ source: global.stage,
|
||||
coordinate: Clutter.BindCoordinate.ALL });
|
||||
this._group.add_constraint(constraint);
|
||||
this.add_constraint(constraint);
|
||||
}
|
||||
|
||||
show() {
|
||||
if (!this._grabHelper.grab({ actor: this._group,
|
||||
vfunc_show() {
|
||||
if (!this._grabHelper.grab({ actor: this,
|
||||
onUngrab: this._onUngrab.bind(this) }))
|
||||
return;
|
||||
|
||||
global.display.set_cursor(Meta.Cursor.CROSSHAIR);
|
||||
Main.uiGroup.set_child_above_sibling(this._group, null);
|
||||
this._group.visible = true;
|
||||
Main.uiGroup.set_child_above_sibling(this, null);
|
||||
super.vfunc_show();
|
||||
}
|
||||
|
||||
_onButtonRelease(actor, event) {
|
||||
this._result = event.get_coords();
|
||||
vfunc_button_release_event(buttonEvent) {
|
||||
let { x, y } = buttonEvent;
|
||||
this._result = new Graphene.Point({ x, y });
|
||||
this._grabHelper.ungrab();
|
||||
return Clutter.EVENT_PROPAGATE;
|
||||
}
|
||||
@ -357,29 +356,29 @@ var PickPixel = class {
|
||||
this.emit('finished', this._result);
|
||||
|
||||
GLib.idle_add(GLib.PRIORITY_DEFAULT, () => {
|
||||
this._group.destroy();
|
||||
this.destroy();
|
||||
return GLib.SOURCE_REMOVE;
|
||||
});
|
||||
}
|
||||
};
|
||||
Signals.addSignalMethods(PickPixel.prototype);
|
||||
});
|
||||
|
||||
var FLASHSPOT_ANIMATION_OUT_TIME = 500; // milliseconds
|
||||
|
||||
var Flashspot = class extends Lightbox.Lightbox {
|
||||
constructor(area) {
|
||||
super(Main.uiGroup, { inhibitEvents: true,
|
||||
width: area.width,
|
||||
height: area.height });
|
||||
|
||||
this.actor.style_class = 'flashspot';
|
||||
this.actor.set_position(area.x, area.y);
|
||||
var Flashspot = GObject.registerClass(
|
||||
class Flashspot extends Lightbox.Lightbox {
|
||||
_init(area) {
|
||||
super._init(Main.uiGroup, {
|
||||
inhibitEvents: true,
|
||||
width: area.width,
|
||||
height: area.height
|
||||
});
|
||||
this.style_class = 'flashspot';
|
||||
this.set_position(area.x, area.y);
|
||||
}
|
||||
|
||||
fire(doneCallback) {
|
||||
this.actor.show();
|
||||
this.actor.opacity = 255;
|
||||
this.actor.ease({
|
||||
this.set({ visible: true, opacity: 255 });
|
||||
this.ease({
|
||||
opacity: 0,
|
||||
duration: FLASHSPOT_ANIMATION_OUT_TIME,
|
||||
mode: Clutter.AnimationMode.EASE_OUT_QUAD,
|
||||
@ -390,4 +389,4 @@ var Flashspot = class extends Lightbox.Lightbox {
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
});
|
||||
|
222
js/ui/search.js
222
js/ui/search.js
@ -1,7 +1,7 @@
|
||||
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
|
||||
/* exported SearchResultsView */
|
||||
|
||||
const { Clutter, Gio, GLib, GObject, Meta, Shell, St } = imports.gi;
|
||||
const Signals = imports.signals;
|
||||
|
||||
const AppDisplay = imports.ui.appDisplay;
|
||||
const IconGrid = imports.ui.iconGrid;
|
||||
@ -32,39 +32,47 @@ class MaxWidthBox extends St.BoxLayout {
|
||||
}
|
||||
});
|
||||
|
||||
var SearchResult = class {
|
||||
constructor(provider, metaInfo, resultsView) {
|
||||
var SearchResult = GObject.registerClass(
|
||||
class SearchResult extends St.Button {
|
||||
_init(provider, metaInfo, resultsView) {
|
||||
this.provider = provider;
|
||||
this.metaInfo = metaInfo;
|
||||
this._resultsView = resultsView;
|
||||
|
||||
this.actor = new St.Button({ reactive: true,
|
||||
can_focus: true,
|
||||
track_hover: true,
|
||||
x_align: St.Align.START,
|
||||
y_fill: true });
|
||||
super._init({
|
||||
reactive: true,
|
||||
can_focus: true,
|
||||
track_hover: true,
|
||||
x_align: St.Align.START,
|
||||
y_fill: true
|
||||
});
|
||||
}
|
||||
|
||||
this.actor._delegate = this;
|
||||
this.actor.connect('clicked', this.activate.bind(this));
|
||||
vfunc_clicked() {
|
||||
this.activate();
|
||||
}
|
||||
|
||||
activate() {
|
||||
this.emit('activate', this.metaInfo.id);
|
||||
this.provider.activateResult(this.metaInfo.id, this._resultsView.terms);
|
||||
|
||||
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 = class extends SearchResult {
|
||||
var ListSearchResult = GObject.registerClass(
|
||||
class ListSearchResult extends SearchResult {
|
||||
_init(provider, metaInfo, resultsView) {
|
||||
super._init(provider, metaInfo, resultsView);
|
||||
|
||||
constructor(provider, metaInfo, resultsView) {
|
||||
super(provider, metaInfo, resultsView);
|
||||
|
||||
this.actor.style_class = 'list-search-result';
|
||||
this.actor.x_fill = true;
|
||||
this.style_class = 'list-search-result';
|
||||
this.x_fill = true;
|
||||
|
||||
let content = new St.BoxLayout({ style_class: 'list-search-result-content',
|
||||
vertical: false });
|
||||
this.actor.set_child(content);
|
||||
this.set_child(content);
|
||||
|
||||
this._termsChangedId = 0;
|
||||
|
||||
@ -87,7 +95,7 @@ var ListSearchResult = class extends SearchResult {
|
||||
x_align: St.Align.START,
|
||||
y_align: St.Align.MIDDLE });
|
||||
|
||||
this.actor.label_actor = title;
|
||||
this.label_actor = title;
|
||||
|
||||
if (this.metaInfo['description']) {
|
||||
this._descriptionLabel = new St.Label({ style_class: 'list-search-result-description' });
|
||||
@ -103,7 +111,7 @@ var ListSearchResult = class extends SearchResult {
|
||||
this._highlightTerms();
|
||||
}
|
||||
|
||||
this.actor.connect('destroy', this._onDestroy.bind(this));
|
||||
this.connect('destroy', this._onDestroy.bind(this));
|
||||
}
|
||||
|
||||
get ICON_SIZE() {
|
||||
@ -120,50 +128,53 @@ var ListSearchResult = class extends SearchResult {
|
||||
this._resultsView.disconnect(this._termsChangedId);
|
||||
this._termsChangedId = 0;
|
||||
}
|
||||
};
|
||||
});
|
||||
|
||||
var GridSearchResult = class extends SearchResult {
|
||||
constructor(provider, metaInfo, resultsView) {
|
||||
super(provider, metaInfo, resultsView);
|
||||
var GridSearchResult = GObject.registerClass(
|
||||
class GridSearchResult extends SearchResult {
|
||||
_init(provider, metaInfo, resultsView) {
|
||||
super._init(provider, metaInfo, resultsView);
|
||||
|
||||
this.actor.style_class = 'grid-search-result';
|
||||
this.style_class = 'grid-search-result';
|
||||
|
||||
this.icon = new IconGrid.BaseIcon(this.metaInfo['name'],
|
||||
{ createIcon: this.metaInfo['createIcon'] });
|
||||
let content = new St.Bin({ child: this.icon });
|
||||
this.actor.set_child(content);
|
||||
this.actor.label_actor = this.icon.label;
|
||||
this.set_child(content);
|
||||
this.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._resultsView = resultsView;
|
||||
|
||||
this._terms = [];
|
||||
|
||||
this.actor = new St.BoxLayout({ style_class: 'search-section',
|
||||
vertical: true });
|
||||
this._focusChild = null;
|
||||
|
||||
this._resultDisplayBin = new St.Bin({ x_fill: true,
|
||||
y_fill: true });
|
||||
this.actor.add(this._resultDisplayBin, { expand: true });
|
||||
this.add(this._resultDisplayBin, { expand: true });
|
||||
|
||||
let separator = new St.Widget({ style_class: 'search-section-separator' });
|
||||
this.actor.add(separator);
|
||||
this.add(separator);
|
||||
|
||||
this._resultDisplays = {};
|
||||
|
||||
this._clipboard = St.Clipboard.get_default();
|
||||
|
||||
this._cancellable = new Gio.Cancellable();
|
||||
|
||||
this.actor.connect('destroy', this._onDestroy.bind(this));
|
||||
}
|
||||
|
||||
destroy() {
|
||||
this.actor.destroy();
|
||||
this.connect('destroy', this._onDestroy.bind(this));
|
||||
}
|
||||
|
||||
_onDestroy() {
|
||||
@ -180,21 +191,21 @@ var SearchResultsBase = class {
|
||||
clear() {
|
||||
this._cancellable.cancel();
|
||||
for (let resultId in this._resultDisplays)
|
||||
this._resultDisplays[resultId].actor.destroy();
|
||||
this._resultDisplays[resultId].destroy();
|
||||
this._resultDisplays = {};
|
||||
this._clearResultDisplay();
|
||||
this.actor.hide();
|
||||
this.hide();
|
||||
}
|
||||
|
||||
get focusChild() {
|
||||
return this._focusChild;
|
||||
}
|
||||
|
||||
_keyFocusIn(actor) {
|
||||
this.emit('key-focus-in', actor);
|
||||
}
|
||||
|
||||
_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();
|
||||
if (this._focusChild == actor)
|
||||
return;
|
||||
this._focusChild = actor;
|
||||
this.notify('focus-child');
|
||||
}
|
||||
|
||||
_setMoreCount(_count) {
|
||||
@ -233,8 +244,7 @@ var SearchResultsBase = class {
|
||||
metasNeeded.forEach((resultId, i) => {
|
||||
let meta = metas[i];
|
||||
let display = this._createResultDisplay(meta);
|
||||
display.connect('activate', this._activateResult.bind(this));
|
||||
display.actor.connect('key-focus-in', this._keyFocusIn.bind(this));
|
||||
display.connect('key-focus-in', this._keyFocusIn.bind(this));
|
||||
this._resultDisplays[resultId] = display;
|
||||
});
|
||||
callback(true);
|
||||
@ -246,7 +256,7 @@ var SearchResultsBase = class {
|
||||
this._terms = terms;
|
||||
if (providerResults.length == 0) {
|
||||
this._clearResultDisplay();
|
||||
this.actor.hide();
|
||||
this.hide();
|
||||
callback();
|
||||
} else {
|
||||
let maxResults = this._getMaxDisplayedResults();
|
||||
@ -265,22 +275,23 @@ var SearchResultsBase = class {
|
||||
// To avoid CSS transitions causing flickering when
|
||||
// the first search result stays the same, we hide the
|
||||
// content while filling in the results.
|
||||
this.actor.hide();
|
||||
this.hide();
|
||||
this._clearResultDisplay();
|
||||
results.forEach(resultId => {
|
||||
this._addItem(this._resultDisplays[resultId]);
|
||||
});
|
||||
this._setMoreCount(this.provider.canLaunchSearch ? moreCount : 0);
|
||||
this.actor.show();
|
||||
this.show();
|
||||
callback();
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
||||
});
|
||||
|
||||
var ListSearchResults = class extends SearchResultsBase {
|
||||
constructor(provider, resultsView) {
|
||||
super(provider, resultsView);
|
||||
var ListSearchResults = GObject.registerClass(
|
||||
class ListSearchResults extends SearchResultsBase {
|
||||
_init(provider, resultsView) {
|
||||
super._init(provider, resultsView);
|
||||
|
||||
this._container = new St.BoxLayout({ style_class: 'search-section-content' });
|
||||
this.providerInfo = new ProviderInfo(provider);
|
||||
@ -321,21 +332,21 @@ var ListSearchResults = class extends SearchResultsBase {
|
||||
}
|
||||
|
||||
_addItem(display) {
|
||||
this._content.add_actor(display.actor);
|
||||
this._content.add_actor(display);
|
||||
}
|
||||
|
||||
getFirstResult() {
|
||||
if (this._content.get_n_children() > 0)
|
||||
return this._content.get_child_at_index(0)._delegate;
|
||||
return this._content.get_child_at_index(0);
|
||||
else
|
||||
return null;
|
||||
}
|
||||
};
|
||||
Signals.addSignalMethods(ListSearchResults.prototype);
|
||||
});
|
||||
|
||||
var GridSearchResults = class extends SearchResultsBase {
|
||||
constructor(provider, resultsView) {
|
||||
super(provider, resultsView);
|
||||
var GridSearchResults = GObject.registerClass(
|
||||
class GridSearchResults extends SearchResultsBase {
|
||||
_init(provider, resultsView) {
|
||||
super._init(provider, resultsView);
|
||||
|
||||
this._grid = new IconGrid.IconGrid({ rowLimit: MAX_GRID_SEARCH_RESULTS_ROWS,
|
||||
xAlign: St.Align.START });
|
||||
@ -357,7 +368,7 @@ var GridSearchResults = class extends SearchResultsBase {
|
||||
|
||||
updateSearch(...args) {
|
||||
if (this._notifyAllocationId)
|
||||
this.actor.disconnect(this._notifyAllocationId);
|
||||
this.disconnect(this._notifyAllocationId);
|
||||
if (this._updateSearchLater) {
|
||||
Meta.later_remove(this._updateSearchLater);
|
||||
delete this._updateSearchLater;
|
||||
@ -365,7 +376,7 @@ var GridSearchResults = class extends SearchResultsBase {
|
||||
|
||||
// Make sure the maximum number of results calculated by
|
||||
// _getMaxDisplayedResults() is updated after width changes.
|
||||
this._notifyAllocationId = this.actor.connect('notify::allocation', () => {
|
||||
this._notifyAllocationId = this.connect('notify::allocation', () => {
|
||||
if (this._updateSearchLater)
|
||||
return;
|
||||
this._updateSearchLater = Meta.later_add(Meta.LaterType.BEFORE_REDRAW, () => {
|
||||
@ -379,7 +390,7 @@ var GridSearchResults = class extends SearchResultsBase {
|
||||
}
|
||||
|
||||
_getMaxDisplayedResults() {
|
||||
let width = this.actor.allocation.x2 - this.actor.allocation.x1;
|
||||
let width = this.allocation.get_width();
|
||||
if (width == 0)
|
||||
return -1;
|
||||
|
||||
@ -402,17 +413,17 @@ var GridSearchResults = class extends SearchResultsBase {
|
||||
|
||||
getFirstResult() {
|
||||
if (this._grid.visibleItemsCount() > 0)
|
||||
return this._grid.getItemAtIndex(0)._delegate;
|
||||
return this._grid.getItemAtIndex(0);
|
||||
else
|
||||
return null;
|
||||
}
|
||||
};
|
||||
Signals.addSignalMethods(GridSearchResults.prototype);
|
||||
});
|
||||
|
||||
var SearchResults = class {
|
||||
constructor() {
|
||||
this.actor = new St.BoxLayout({ name: 'searchResults',
|
||||
vertical: true });
|
||||
var SearchResultsView = GObject.registerClass({
|
||||
Signals: { 'terms-changed': {} }
|
||||
}, class SearchResultsView extends St.BoxLayout {
|
||||
_init() {
|
||||
super._init({ name: 'searchResults', vertical: true });
|
||||
|
||||
this._content = new MaxWidthBox({ name: 'searchResultsContent',
|
||||
vertical: true });
|
||||
@ -428,16 +439,18 @@ var SearchResults = class {
|
||||
action.connect('pan', this._onPan.bind(this));
|
||||
this._scrollView.add_action(action);
|
||||
|
||||
this.actor.add(this._scrollView, { x_fill: true,
|
||||
y_fill: true,
|
||||
expand: true,
|
||||
x_align: St.Align.START,
|
||||
y_align: St.Align.START });
|
||||
this.add(this._scrollView, {
|
||||
x_fill: true,
|
||||
y_fill: true,
|
||||
expand: true,
|
||||
x_align: St.Align.START,
|
||||
y_align: St.Align.STAR
|
||||
});
|
||||
|
||||
this._statusText = new St.Label({ style_class: 'search-statustext' });
|
||||
this._statusBin = new St.Bin({ x_align: St.Align.MIDDLE,
|
||||
y_align: St.Align.MIDDLE });
|
||||
this.actor.add(this._statusBin, { expand: true });
|
||||
this.add(this._statusBin, { expand: true });
|
||||
this._statusBin.add_actor(this._statusText);
|
||||
|
||||
this._highlightDefault = false;
|
||||
@ -467,6 +480,10 @@ var SearchResults = class {
|
||||
this._reloadRemoteProviders();
|
||||
}
|
||||
|
||||
get terms() {
|
||||
return this._terms;
|
||||
}
|
||||
|
||||
_reloadRemoteProviders() {
|
||||
let remoteProviders = this._providers.filter(p => p.isRemoteProvider);
|
||||
remoteProviders.forEach(provider => {
|
||||
@ -591,12 +608,12 @@ var SearchResults = class {
|
||||
_onPan(action) {
|
||||
let [dist_, dx_, dy] = action.get_motion_delta(0);
|
||||
let adjustment = this._scrollView.vscroll.adjustment;
|
||||
adjustment.value -= (dy / this.actor.height) * adjustment.page_size;
|
||||
adjustment.value -= (dy / this.height) * adjustment.page_size;
|
||||
return false;
|
||||
}
|
||||
|
||||
_keyFocusIn(provider, actor) {
|
||||
Util.ensureActorVisibleInScrollView(this._scrollView, actor);
|
||||
_focusChildChanged(provider) {
|
||||
Util.ensureActorVisibleInScrollView(this._scrollView, provider.focusChild);
|
||||
}
|
||||
|
||||
_ensureProviderDisplay(provider) {
|
||||
@ -609,9 +626,9 @@ var SearchResults = class {
|
||||
else
|
||||
providerDisplay = new GridSearchResults(provider, this);
|
||||
|
||||
providerDisplay.connect('key-focus-in', this._keyFocusIn.bind(this));
|
||||
providerDisplay.actor.hide();
|
||||
this._content.add(providerDisplay.actor);
|
||||
providerDisplay.connect('notify::focus-child', this._focusChildChanged.bind(this));
|
||||
providerDisplay.hide();
|
||||
this._content.add(providerDisplay);
|
||||
provider.display = providerDisplay;
|
||||
}
|
||||
|
||||
@ -629,7 +646,7 @@ var SearchResults = class {
|
||||
let provider = providers[i];
|
||||
let display = provider.display;
|
||||
|
||||
if (!display.actor.visible)
|
||||
if (!display.visible)
|
||||
continue;
|
||||
|
||||
let firstResult = display.getFirstResult();
|
||||
@ -704,22 +721,22 @@ var SearchResults = class {
|
||||
this._doSearch();
|
||||
|
||||
if (this._defaultResult)
|
||||
this._defaultResult.actor.popup_menu();
|
||||
this._defaultResult.popup_menu();
|
||||
}
|
||||
|
||||
navigateFocus(direction) {
|
||||
let rtl = this.actor.get_text_direction() == Clutter.TextDirection.RTL;
|
||||
let rtl = this.get_text_direction() == Clutter.TextDirection.RTL;
|
||||
if (direction == St.DirectionType.TAB_BACKWARD ||
|
||||
direction == (rtl
|
||||
? St.DirectionType.RIGHT
|
||||
: St.DirectionType.LEFT) ||
|
||||
direction == St.DirectionType.UP) {
|
||||
this.actor.navigate_focus(null, direction, false);
|
||||
this.navigate_focus(null, direction, false);
|
||||
return;
|
||||
}
|
||||
|
||||
let from = this._defaultResult ? this._defaultResult.actor : null;
|
||||
this.actor.navigate_focus(from, direction, false);
|
||||
let from = this._defaultResult ? this._defaultResult : null;
|
||||
this.navigate_focus(from, direction, false);
|
||||
}
|
||||
|
||||
_setSelected(result, selected) {
|
||||
@ -727,10 +744,10 @@ var SearchResults = class {
|
||||
return;
|
||||
|
||||
if (selected) {
|
||||
result.actor.add_style_pseudo_class('selected');
|
||||
Util.ensureActorVisibleInScrollView(this._scrollView, result.actor);
|
||||
result.add_style_pseudo_class('selected');
|
||||
Util.ensureActorVisibleInScrollView(this._scrollView, result);
|
||||
} else {
|
||||
result.actor.remove_style_pseudo_class('selected');
|
||||
result.remove_style_pseudo_class('selected');
|
||||
}
|
||||
}
|
||||
|
||||
@ -743,8 +760,7 @@ var SearchResults = class {
|
||||
|
||||
return description.replace(this._highlightRegex, '<b>$1</b>');
|
||||
}
|
||||
};
|
||||
Signals.addSignalMethods(SearchResults.prototype);
|
||||
});
|
||||
|
||||
var ProviderInfo = GObject.registerClass(
|
||||
class ProviderInfo extends St.Button {
|
||||
|
@ -2,7 +2,6 @@
|
||||
/* exported ShellMountOperation, GnomeShellMountOpHandler */
|
||||
|
||||
const { Clutter, Gio, GLib, GObject, Pango, Shell, St } = imports.gi;
|
||||
const Signals = imports.signals;
|
||||
|
||||
const Animation = imports.ui.animation;
|
||||
const CheckBox = imports.ui.checkBox;
|
||||
@ -44,18 +43,22 @@ function _setLabelsForMessage(content, message) {
|
||||
|
||||
/* -------------------------------------------------------- */
|
||||
|
||||
var ListItem = class {
|
||||
constructor(app) {
|
||||
this._app = app;
|
||||
|
||||
var ListItem = GObject.registerClass({
|
||||
GTypeName: 'ShellMountOperation_ListItem',
|
||||
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.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._app = app;
|
||||
|
||||
this._icon = this._app.create_icon_texture(LIST_ITEM_ICON_SIZE);
|
||||
|
||||
@ -68,16 +71,13 @@ var ListItem = class {
|
||||
let labelBin = new St.Bin({ y_align: St.Align.MIDDLE,
|
||||
child: this._nameLabel });
|
||||
layout.add(labelBin);
|
||||
|
||||
this.actor.connect('clicked', this._onClicked.bind(this));
|
||||
}
|
||||
|
||||
_onClicked() {
|
||||
vfunc_clicked() {
|
||||
this.emit('activate');
|
||||
this._app.activate();
|
||||
}
|
||||
};
|
||||
Signals.addSignalMethods(ListItem.prototype);
|
||||
});
|
||||
|
||||
var ShellMountOperation = class {
|
||||
constructor(source, params) {
|
||||
@ -219,9 +219,10 @@ var ShellMountOperation = class {
|
||||
}
|
||||
};
|
||||
|
||||
var ShellUnmountNotifier = class extends MessageTray.Source {
|
||||
constructor() {
|
||||
super('', 'media-removable');
|
||||
var ShellUnmountNotifier = GObject.registerClass(
|
||||
class ShellUnmountNotifier extends MessageTray.Source {
|
||||
_init() {
|
||||
super._init('', 'media-removable');
|
||||
|
||||
this._notification = null;
|
||||
Main.messageTray.add(this);
|
||||
@ -238,7 +239,7 @@ var ShellUnmountNotifier = class extends MessageTray.Source {
|
||||
this._notification.update(header, text);
|
||||
}
|
||||
|
||||
this.notify(this._notification);
|
||||
this.showNotification(this._notification);
|
||||
}
|
||||
|
||||
done(message) {
|
||||
@ -251,10 +252,10 @@ var ShellUnmountNotifier = class extends MessageTray.Source {
|
||||
let notification = new MessageTray.Notification(this, message, null);
|
||||
notification.setTransient(true);
|
||||
|
||||
this.notify(notification);
|
||||
this.showNotification(notification);
|
||||
}
|
||||
}
|
||||
};
|
||||
});
|
||||
|
||||
var ShellMountQuestionDialog = GObject.registerClass({
|
||||
Signals: { 'response': { param_types: [GObject.TYPE_INT] } }
|
||||
@ -303,14 +304,14 @@ var ShellMountPasswordDialog = GObject.registerClass({
|
||||
visible: false }));
|
||||
|
||||
this._hiddenVolume = new CheckBox.CheckBox(_("Hidden Volume"));
|
||||
content.messageBox.add(this._hiddenVolume.actor);
|
||||
content.messageBox.add(this._hiddenVolume);
|
||||
|
||||
this._systemVolume = new CheckBox.CheckBox(_("Windows System Volume"));
|
||||
content.messageBox.add(this._systemVolume.actor);
|
||||
content.messageBox.add(this._systemVolume);
|
||||
|
||||
this._keyfilesCheckbox = new CheckBox.CheckBox(_("Uses Keyfiles"));
|
||||
this._keyfilesCheckbox.actor.connect("clicked", this._onKeyfilesCheckboxClicked.bind(this));
|
||||
content.messageBox.add(this._keyfilesCheckbox.actor);
|
||||
this._keyfilesCheckbox.connect("clicked", this._onKeyfilesCheckboxClicked.bind(this));
|
||||
content.messageBox.add(this._keyfilesCheckbox);
|
||||
|
||||
this._keyfilesLabel.clutter_text.set_markup(
|
||||
/* Translators: %s is the Disks application */
|
||||
@ -360,7 +361,7 @@ var ShellMountPasswordDialog = GObject.registerClass({
|
||||
ShellEntry.addContextMenu(this._passwordEntry, { isPassword: true });
|
||||
this.setInitialKeyFocus(this._passwordEntry);
|
||||
this._workSpinner = new Animation.Spinner(WORK_SPINNER_ICON_SIZE, true);
|
||||
this._passwordEntry.secondary_icon = this._workSpinner.actor;
|
||||
this._passwordEntry.secondary_icon = this._workSpinner;
|
||||
|
||||
if (rtl) {
|
||||
layout.attach(this._passwordEntry, 0, 1, 1, 1);
|
||||
@ -381,9 +382,9 @@ var ShellMountPasswordDialog = GObject.registerClass({
|
||||
|
||||
if (flags & Gio.AskPasswordFlags.SAVING_SUPPORTED) {
|
||||
this._rememberChoice = new CheckBox.CheckBox(_("Remember Password"));
|
||||
this._rememberChoice.actor.checked =
|
||||
this._rememberChoice.checked =
|
||||
global.settings.get_boolean(REMEMBER_MOUNT_PASSWORD_KEY);
|
||||
content.messageBox.add(this._rememberChoice.actor);
|
||||
content.messageBox.add(this._rememberChoice);
|
||||
} else {
|
||||
this._rememberChoice = null;
|
||||
}
|
||||
@ -439,22 +440,22 @@ var ShellMountPasswordDialog = GObject.registerClass({
|
||||
}
|
||||
|
||||
global.settings.set_boolean(REMEMBER_MOUNT_PASSWORD_KEY,
|
||||
this._rememberChoice && this._rememberChoice.actor.checked);
|
||||
this._rememberChoice && this._rememberChoice.checked);
|
||||
|
||||
this._workSpinner.play();
|
||||
this.emit('response', 1,
|
||||
this._passwordEntry.get_text(),
|
||||
this._rememberChoice &&
|
||||
this._rememberChoice.actor.checked,
|
||||
this._rememberChoice.checked,
|
||||
this._hiddenVolume &&
|
||||
this._hiddenVolume.actor.checked,
|
||||
this._hiddenVolume.checked,
|
||||
this._systemVolume &&
|
||||
this._systemVolume.actor.checked,
|
||||
this._systemVolume.checked,
|
||||
parseInt(pim));
|
||||
}
|
||||
|
||||
_onKeyfilesCheckboxClicked() {
|
||||
let useKeyfiles = this._keyfilesCheckbox.actor.checked;
|
||||
let useKeyfiles = this._keyfilesCheckbox.checked;
|
||||
this._passwordEntry.reactive = !useKeyfiles;
|
||||
this._passwordEntry.can_focus = !useKeyfiles;
|
||||
this._passwordEntry.clutter_text.editable = !useKeyfiles;
|
||||
@ -463,8 +464,8 @@ var ShellMountPasswordDialog = GObject.registerClass({
|
||||
this._pimEntry.can_focus = !useKeyfiles;
|
||||
this._pimEntry.clutter_text.editable = !useKeyfiles;
|
||||
this._pimEntry.clutter_text.selectable = !useKeyfiles;
|
||||
this._rememberChoice.actor.reactive = !useKeyfiles;
|
||||
this._rememberChoice.actor.can_focus = !useKeyfiles;
|
||||
this._rememberChoice.reactive = !useKeyfiles;
|
||||
this._rememberChoice.can_focus = !useKeyfiles;
|
||||
this._keyfilesLabel.visible = useKeyfiles;
|
||||
this.setButtons(useKeyfiles ? this._usesKeyfilesButtons : this._defaultButtons);
|
||||
}
|
||||
@ -527,7 +528,7 @@ var ShellProcessesDialog = GObject.registerClass({
|
||||
return;
|
||||
|
||||
let item = new ListItem(app);
|
||||
this._applicationList.add(item.actor, { x_fill: true });
|
||||
this._applicationList.add(item, { x_fill: true });
|
||||
|
||||
item.connect('activate', () => {
|
||||
// use -1 to indicate Cancel
|
||||
|
@ -22,12 +22,7 @@ var Slider = GObject.registerClass({
|
||||
accessible_role: Atk.Role.SLIDER
|
||||
});
|
||||
|
||||
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._releaseId = 0;
|
||||
this._dragging = false;
|
||||
|
||||
this._customAccessible.connect('get-minimum-increment', this._getMinimumIncrement.bind(this));
|
||||
@ -62,8 +57,8 @@ var Slider = GObject.registerClass({
|
||||
cr.$dispose();
|
||||
}
|
||||
|
||||
_startDragging(actor, event) {
|
||||
return this.startDragging(event);
|
||||
vfunc_button_press_event() {
|
||||
return this.startDragging(Clutter.get_current_event());
|
||||
}
|
||||
|
||||
startDragging(event) {
|
||||
@ -83,11 +78,6 @@ var Slider = GObject.registerClass({
|
||||
this._grabbedDevice = device;
|
||||
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
|
||||
// sure that no 'notify::value' signal is emitted before this one.
|
||||
this.emit('drag-begin');
|
||||
@ -105,11 +95,6 @@ var Slider = GObject.registerClass({
|
||||
this._releaseId = 0;
|
||||
}
|
||||
|
||||
if (this._motionId) {
|
||||
this.disconnect(this._motionId);
|
||||
this._motionId = 0;
|
||||
}
|
||||
|
||||
if (this._grabbedSequence != null)
|
||||
this._grabbedDevice.sequence_ungrab(this._grabbedSequence);
|
||||
else
|
||||
@ -124,7 +109,15 @@ var Slider = GObject.registerClass({
|
||||
return Clutter.EVENT_STOP;
|
||||
}
|
||||
|
||||
_touchDragging(actor, event) {
|
||||
vfunc_button_release_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 sequence = event.get_event_sequence();
|
||||
|
||||
@ -132,9 +125,9 @@ var Slider = GObject.registerClass({
|
||||
event.type() == Clutter.EventType.TOUCH_BEGIN) {
|
||||
this.startDragging(event);
|
||||
return Clutter.EVENT_STOP;
|
||||
} else if (device.sequence_get_grabbed_actor(sequence) == actor) {
|
||||
} else if (device.sequence_get_grabbed_actor(sequence) == this) {
|
||||
if (event.type() == Clutter.EventType.TOUCH_UPDATE)
|
||||
return this._motionEvent(actor, event);
|
||||
return this._motionEvent(this, event);
|
||||
else if (event.type() == Clutter.EventType.TOUCH_END)
|
||||
return this._endDragging();
|
||||
}
|
||||
@ -165,8 +158,15 @@ var Slider = GObject.registerClass({
|
||||
return Clutter.EVENT_STOP;
|
||||
}
|
||||
|
||||
_onScrollEvent(actor, event) {
|
||||
return this.scroll(event);
|
||||
vfunc_scroll_event() {
|
||||
return this.scroll(Clutter.get_current_event());
|
||||
}
|
||||
|
||||
vfunc_motion_event() {
|
||||
if (this._dragging && !this._grabbedSequence)
|
||||
return this._motionEvent(this, Clutter.get_current_event());
|
||||
|
||||
return Clutter.EVENT_PROPAGATE;
|
||||
}
|
||||
|
||||
_motionEvent(actor, event) {
|
||||
@ -176,8 +176,8 @@ var Slider = GObject.registerClass({
|
||||
return Clutter.EVENT_STOP;
|
||||
}
|
||||
|
||||
onKeyPressEvent(actor, event) {
|
||||
let key = event.get_key_symbol();
|
||||
vfunc_key_press_event(keyPressEvent) {
|
||||
let key = keyPressEvent.keyval;
|
||||
if (key == Clutter.KEY_Right || key == Clutter.KEY_Left) {
|
||||
let delta = key == Clutter.KEY_Right ? 0.1 : -0.1;
|
||||
this.emit('drag-begin');
|
||||
|
@ -102,7 +102,7 @@ class ATIndicator extends PanelMenu.Button {
|
||||
_buildItemExtended(string, initialValue, writable, onSet) {
|
||||
let widget = new PopupMenu.PopupSwitchMenuItem(string, initialValue);
|
||||
if (!writable)
|
||||
widget.actor.reactive = false;
|
||||
widget.reactive = false;
|
||||
else
|
||||
widget.connect('toggled', item => {
|
||||
onSet(item.state);
|
||||
|
@ -1,7 +1,7 @@
|
||||
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
|
||||
/* exported Indicator */
|
||||
|
||||
const { Gio, GnomeBluetooth } = imports.gi;
|
||||
const { Gio, GnomeBluetooth, GObject } = imports.gi;
|
||||
|
||||
const Main = imports.ui.main;
|
||||
const PanelMenu = imports.ui.panelMenu;
|
||||
@ -17,9 +17,11 @@ const RfkillManagerProxy = Gio.DBusProxy.makeProxyWrapper(RfkillManagerInterface
|
||||
|
||||
const HAD_BLUETOOTH_DEVICES_SETUP = 'had-bluetooth-devices-setup';
|
||||
|
||||
var Indicator = class extends PanelMenu.SystemIndicator {
|
||||
constructor() {
|
||||
super();
|
||||
var Indicator = GObject.registerClass({
|
||||
GTypeName: 'Bluetooth_Indicator'
|
||||
}, class Indicator extends PanelMenu.SystemIndicator {
|
||||
_init() {
|
||||
super._init();
|
||||
|
||||
this._indicator = this._addIndicator();
|
||||
this._indicator.icon_name = 'bluetooth-active-symbolic';
|
||||
@ -133,4 +135,4 @@ var Indicator = class extends PanelMenu.SystemIndicator {
|
||||
|
||||
this._toggleItem.label.text = this._proxy.BluetoothAirplaneMode ? _("Turn On") : _("Turn Off");
|
||||
}
|
||||
};
|
||||
});
|
||||
|
@ -15,9 +15,11 @@ const OBJECT_PATH = '/org/gnome/SettingsDaemon/Power';
|
||||
const BrightnessInterface = loadInterfaceXML('org.gnome.SettingsDaemon.Power.Screen');
|
||||
const BrightnessProxy = Gio.DBusProxy.makeProxyWrapper(BrightnessInterface);
|
||||
|
||||
var Indicator = class extends PanelMenu.SystemIndicator {
|
||||
constructor() {
|
||||
super('display-brightness-symbolic');
|
||||
var Indicator = GObject.registerClass({
|
||||
GTypeName: 'Brightness_Indicator'
|
||||
}, class Indicator extends PanelMenu.SystemIndicator {
|
||||
_init() {
|
||||
super._init();
|
||||
this._proxy = new BrightnessProxy(Gio.DBus.session, BUS_NAME, OBJECT_PATH,
|
||||
(proxy, error) => {
|
||||
if (error) {
|
||||
@ -45,7 +47,7 @@ var Indicator = class extends PanelMenu.SystemIndicator {
|
||||
return this._slider.startDragging(event);
|
||||
});
|
||||
this._item.connect('key-press-event', (actor, event) => {
|
||||
return this._slider.onKeyPressEvent(actor, event);
|
||||
return this._slider.emit('key-press-event', event);
|
||||
});
|
||||
|
||||
}
|
||||
@ -67,4 +69,4 @@ var Indicator = class extends PanelMenu.SystemIndicator {
|
||||
if (visible)
|
||||
this._changeSlider(this._proxy.Brightness / 100.0);
|
||||
}
|
||||
};
|
||||
});
|
||||
|
@ -923,7 +923,7 @@ class InputSourceIndicator extends PanelMenu.Button {
|
||||
}
|
||||
|
||||
_buildPropSection(properties) {
|
||||
this._propSeparator.actor.hide();
|
||||
this._propSeparator.hide();
|
||||
this._propSection.actor.hide();
|
||||
this._propSection.removeAll();
|
||||
|
||||
@ -931,7 +931,7 @@ class InputSourceIndicator extends PanelMenu.Button {
|
||||
|
||||
if (!this._propSection.isEmpty()) {
|
||||
this._propSection.actor.show();
|
||||
this._propSeparator.actor.show();
|
||||
this._propSeparator.show();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -42,9 +42,11 @@ const GeoclueManager = Gio.DBusProxy.makeProxyWrapper(GeoclueIface);
|
||||
|
||||
var AgentIface = loadInterfaceXML('org.freedesktop.GeoClue2.Agent');
|
||||
|
||||
var Indicator = class extends PanelMenu.SystemIndicator {
|
||||
constructor() {
|
||||
super();
|
||||
var Indicator = GObject.registerClass({
|
||||
GTypeName: 'Location_Indicator'
|
||||
}, class Indicator extends PanelMenu.SystemIndicator {
|
||||
_init() {
|
||||
super._init();
|
||||
|
||||
this._settings = new Gio.Settings({ schema_id: LOCATION_SCHEMA });
|
||||
this._settings.connect(`changed::${ENABLED}`,
|
||||
@ -222,7 +224,7 @@ var Indicator = class extends PanelMenu.SystemIndicator {
|
||||
|
||||
this._permStoreProxy = proxy;
|
||||
}
|
||||
};
|
||||
});
|
||||
|
||||
function clamp(value, min, max) {
|
||||
return Math.max(min, Math.min(max, value));
|
||||
|
@ -630,7 +630,6 @@ var NMWirelessDialogItem = GObject.registerClass({
|
||||
can_focus: true,
|
||||
reactive: true });
|
||||
|
||||
this.connect('key-focus-in', () => this.emit('selected'));
|
||||
let action = new Clutter.ClickAction();
|
||||
action.connect('clicked', () => this.grab_key_focus());
|
||||
this.add_action(action);
|
||||
@ -659,6 +658,10 @@ var NMWirelessDialogItem = GObject.registerClass({
|
||||
this._sync();
|
||||
}
|
||||
|
||||
vfunc_key_focus_in() {
|
||||
this.emit('selected');
|
||||
}
|
||||
|
||||
_sync() {
|
||||
this._signalIcon.icon_name = this._getSignalIcon();
|
||||
}
|
||||
@ -860,7 +863,7 @@ class NMWirelessDialog extends ModalDialog.ModalDialog {
|
||||
y_align: Clutter.ActorAlign.CENTER });
|
||||
|
||||
this._noNetworksSpinner = new Animation.Spinner(16);
|
||||
this._noNetworksBox.add_actor(this._noNetworksSpinner.actor);
|
||||
this._noNetworksBox.add_actor(this._noNetworksSpinner);
|
||||
this._noNetworksBox.add_actor(new St.Label({ style_class: 'no-networks-label',
|
||||
text: _("No Networks") }));
|
||||
this._stack.add_child(this._noNetworksBox);
|
||||
@ -1588,9 +1591,11 @@ var DeviceCategory = class extends PopupMenu.PopupMenuSection {
|
||||
}
|
||||
};
|
||||
|
||||
var NMApplet = class extends PanelMenu.SystemIndicator {
|
||||
constructor() {
|
||||
super();
|
||||
var NMApplet = GObject.registerClass({
|
||||
GTypeName: 'Network_Indicator'
|
||||
}, class Indicator extends PanelMenu.SystemIndicator {
|
||||
_init() {
|
||||
super._init();
|
||||
|
||||
this._primaryIndicator = this._addIndicator();
|
||||
this._vpnIndicator = this._addIndicator();
|
||||
@ -1706,7 +1711,7 @@ var NMApplet = class extends PanelMenu.SystemIndicator {
|
||||
this._notification.connect('destroy', () => {
|
||||
this._notification = null;
|
||||
});
|
||||
this._source.notify(this._notification);
|
||||
this._source.showNotification(this._notification);
|
||||
}
|
||||
|
||||
_onActivationFailed(_device, _reason) {
|
||||
@ -1939,7 +1944,7 @@ var NMApplet = class extends PanelMenu.SystemIndicator {
|
||||
}
|
||||
|
||||
_syncNMState() {
|
||||
this.indicators.visible = this._client.nm_running;
|
||||
this.visible = this._client.nm_running;
|
||||
this.menu.actor.visible = this._client.networking_enabled;
|
||||
|
||||
this._updateIcon();
|
||||
@ -2058,4 +2063,4 @@ var NMApplet = class extends PanelMenu.SystemIndicator {
|
||||
this._vpnIndicator.icon_name = this._vpnSection.getIndicatorIcon();
|
||||
this._vpnIndicator.visible = (this._vpnIndicator.icon_name != '');
|
||||
}
|
||||
};
|
||||
});
|
||||
|
@ -1,7 +1,7 @@
|
||||
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
|
||||
/* exported Indicator */
|
||||
|
||||
const Gio = imports.gi.Gio;
|
||||
const { Gio, GObject } = imports.gi;
|
||||
|
||||
const Main = imports.ui.main;
|
||||
const PanelMenu = imports.ui.panelMenu;
|
||||
@ -15,9 +15,11 @@ const OBJECT_PATH = '/org/gnome/SettingsDaemon/Color';
|
||||
const ColorInterface = loadInterfaceXML('org.gnome.SettingsDaemon.Color');
|
||||
const ColorProxy = Gio.DBusProxy.makeProxyWrapper(ColorInterface);
|
||||
|
||||
var Indicator = class extends PanelMenu.SystemIndicator {
|
||||
constructor() {
|
||||
super();
|
||||
var Indicator = GObject.registerClass({
|
||||
GTypeName: 'NightLight_Indicator'
|
||||
}, class Indicator extends PanelMenu.SystemIndicator {
|
||||
_init() {
|
||||
super._init();
|
||||
|
||||
this._indicator = this._addIndicator();
|
||||
this._indicator.icon_name = 'night-light-symbolic';
|
||||
@ -66,4 +68,4 @@ var Indicator = class extends PanelMenu.SystemIndicator {
|
||||
: _("Disable Until Tomorrow");
|
||||
this._item.visible = this._indicator.visible = visible;
|
||||
}
|
||||
};
|
||||
});
|
||||
|
@ -1,7 +1,7 @@
|
||||
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
|
||||
/* exported Indicator */
|
||||
|
||||
const { Clutter, Gio, St, UPowerGlib: UPower } = imports.gi;
|
||||
const { Clutter, Gio, GObject, St, UPowerGlib: UPower } = imports.gi;
|
||||
|
||||
const Main = imports.ui.main;
|
||||
const PanelMenu = imports.ui.panelMenu;
|
||||
@ -17,9 +17,11 @@ const PowerManagerProxy = Gio.DBusProxy.makeProxyWrapper(DisplayDeviceInterface)
|
||||
|
||||
const SHOW_BATTERY_PERCENTAGE = 'show-battery-percentage';
|
||||
|
||||
var Indicator = class extends PanelMenu.SystemIndicator {
|
||||
constructor() {
|
||||
super();
|
||||
var Indicator = GObject.registerClass({
|
||||
GTypeName: 'Power_Indicator'
|
||||
}, class Indicator extends PanelMenu.SystemIndicator {
|
||||
_init() {
|
||||
super._init();
|
||||
|
||||
this._desktopSettings = new Gio.Settings({ schema_id: 'org.gnome.desktop.interface' });
|
||||
this._desktopSettings.connect(`changed::${SHOW_BATTERY_PERCENTAGE}`,
|
||||
@ -28,8 +30,8 @@ var Indicator = class extends PanelMenu.SystemIndicator {
|
||||
this._indicator = this._addIndicator();
|
||||
this._percentageLabel = new St.Label({ y_expand: true,
|
||||
y_align: Clutter.ActorAlign.CENTER });
|
||||
this.indicators.add(this._percentageLabel, { expand: true, y_fill: true });
|
||||
this.indicators.add_style_class_name('power-status');
|
||||
this.add(this._percentageLabel, { expand: true, y_fill: true });
|
||||
this.add_style_class_name('power-status');
|
||||
|
||||
this._proxy = new PowerManagerProxy(Gio.DBus.system, BUS_NAME, OBJECT_PATH,
|
||||
(proxy, error) => {
|
||||
@ -140,4 +142,4 @@ var Indicator = class extends PanelMenu.SystemIndicator {
|
||||
// The status label
|
||||
this._item.label.text = this._getStatus();
|
||||
}
|
||||
};
|
||||
});
|
||||
|
@ -1,14 +1,16 @@
|
||||
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
|
||||
/* exported RemoteAccessApplet */
|
||||
|
||||
const Meta = imports.gi.Meta;
|
||||
const { GObject, Meta } = imports.gi;
|
||||
|
||||
const PanelMenu = imports.ui.panelMenu;
|
||||
const PopupMenu = imports.ui.popupMenu;
|
||||
|
||||
var RemoteAccessApplet = class extends PanelMenu.SystemIndicator {
|
||||
constructor() {
|
||||
super();
|
||||
var RemoteAccessApplet = GObject.registerClass({
|
||||
GTypeName: 'RemoteAccess_Indicator'
|
||||
}, class RemoteAccessApplet extends PanelMenu.SystemIndicator {
|
||||
_init() {
|
||||
super._init();
|
||||
|
||||
let backend = Meta.get_backend();
|
||||
let controller = backend.get_remote_access_controller();
|
||||
@ -75,4 +77,4 @@ var RemoteAccessApplet = class extends PanelMenu.SystemIndicator {
|
||||
this._sync();
|
||||
}
|
||||
}
|
||||
};
|
||||
});
|
||||
|
@ -1,7 +1,7 @@
|
||||
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
|
||||
/* exported Indicator */
|
||||
|
||||
const Gio = imports.gi.Gio;
|
||||
const { Gio, GObject } = imports.gi;
|
||||
const Signals = imports.signals;
|
||||
|
||||
const Main = imports.ui.main;
|
||||
@ -61,9 +61,11 @@ function getRfkillManager() {
|
||||
return _manager;
|
||||
}
|
||||
|
||||
var Indicator = class extends PanelMenu.SystemIndicator {
|
||||
constructor() {
|
||||
super();
|
||||
var Indicator = GObject.registerClass({
|
||||
GTypeName: 'Rfkill_Indicator'
|
||||
}, class Indicator extends PanelMenu.SystemIndicator {
|
||||
_init() {
|
||||
super._init();
|
||||
|
||||
this._manager = getRfkillManager();
|
||||
this._manager.connect('airplane-mode-changed', this._sync.bind(this));
|
||||
@ -106,4 +108,4 @@ var Indicator = class extends PanelMenu.SystemIndicator {
|
||||
else
|
||||
this._offItem.label.text = _("Turn Off");
|
||||
}
|
||||
};
|
||||
});
|
||||
|
@ -1,12 +1,16 @@
|
||||
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
|
||||
/* exported Indicator */
|
||||
|
||||
const GObject = imports.gi.GObject;
|
||||
|
||||
const Main = imports.ui.main;
|
||||
const PanelMenu = imports.ui.panelMenu;
|
||||
|
||||
var Indicator = class extends PanelMenu.SystemIndicator {
|
||||
constructor() {
|
||||
super();
|
||||
var Indicator = GObject.registerClass({
|
||||
GTypeName: 'Screencast_Indicator'
|
||||
}, class Indicator extends PanelMenu.SystemIndicator {
|
||||
_init() {
|
||||
super._init();
|
||||
|
||||
this._indicator = this._addIndicator();
|
||||
this._indicator.icon_name = 'media-record-symbolic';
|
||||
@ -19,4 +23,4 @@ var Indicator = class extends PanelMenu.SystemIndicator {
|
||||
_sync() {
|
||||
this._indicator.visible = Main.screencastService.isRecording;
|
||||
}
|
||||
};
|
||||
});
|
||||
|
@ -10,8 +10,10 @@ const PanelMenu = imports.ui.panelMenu;
|
||||
const PopupMenu = imports.ui.popupMenu;
|
||||
|
||||
|
||||
var AltSwitcher = class {
|
||||
constructor(standard, alternate) {
|
||||
var AltSwitcher = GObject.registerClass(
|
||||
class AltSwitcher extends St.Bin {
|
||||
_init(standard, alternate) {
|
||||
super._init();
|
||||
this._standard = standard;
|
||||
this._standard.connect('notify::visible', this._sync.bind(this));
|
||||
if (this._standard instanceof St.Button)
|
||||
@ -31,9 +33,17 @@ var AltSwitcher = class {
|
||||
this._clickAction = new Clutter.ClickAction();
|
||||
this._clickAction.connect('long-press', this._onLongPress.bind(this));
|
||||
|
||||
this.actor = new St.Bin();
|
||||
this.actor.connect('destroy', this._onDestroy.bind(this));
|
||||
this.actor.connect('notify::mapped', () => (this._flipped = false));
|
||||
this.connect('destroy', this._onDestroy.bind(this));
|
||||
}
|
||||
|
||||
vfunc_map() {
|
||||
super.vfunc_map();
|
||||
this._flipped = false;
|
||||
}
|
||||
|
||||
vfunc_unmap() {
|
||||
super.vfunc_unmap();
|
||||
this._flipped = false;
|
||||
}
|
||||
|
||||
_sync() {
|
||||
@ -51,11 +61,11 @@ var AltSwitcher = class {
|
||||
} else if (this._alternate.visible) {
|
||||
childToShow = this._alternate;
|
||||
} else {
|
||||
this.actor.hide();
|
||||
this.hide();
|
||||
return;
|
||||
}
|
||||
|
||||
let childShown = this.actor.get_child();
|
||||
let childShown = this.get_child();
|
||||
if (childShown != childToShow) {
|
||||
if (childShown) {
|
||||
if (childShown.fake_release)
|
||||
@ -64,8 +74,8 @@ var AltSwitcher = class {
|
||||
}
|
||||
childToShow.add_action(this._clickAction);
|
||||
|
||||
let hasFocus = this.actor.contains(global.stage.get_key_focus());
|
||||
this.actor.set_child(childToShow);
|
||||
let hasFocus = this.contains(global.stage.get_key_focus());
|
||||
this.set_child(childToShow);
|
||||
if (hasFocus)
|
||||
childToShow.grab_key_focus();
|
||||
|
||||
@ -74,7 +84,7 @@ var AltSwitcher = class {
|
||||
global.sync_pointer();
|
||||
}
|
||||
|
||||
this.actor.show();
|
||||
this.show();
|
||||
}
|
||||
|
||||
_onDestroy() {
|
||||
@ -104,11 +114,13 @@ var AltSwitcher = class {
|
||||
this._sync();
|
||||
return true;
|
||||
}
|
||||
};
|
||||
});
|
||||
|
||||
var Indicator = class extends PanelMenu.SystemIndicator {
|
||||
constructor() {
|
||||
super();
|
||||
var Indicator = GObject.registerClass({
|
||||
GTypeName: 'System_Indicator'
|
||||
}, class Indicator extends PanelMenu.SystemIndicator {
|
||||
_init() {
|
||||
super._init();
|
||||
|
||||
let userManager = AccountsService.UserManager.get_default();
|
||||
this._user = userManager.get_user(GLib.get_user_name());
|
||||
@ -289,7 +301,7 @@ var Indicator = class extends PanelMenu.SystemIndicator {
|
||||
bindFlags);
|
||||
|
||||
this._altSwitcher = new AltSwitcher(this._powerOffAction, this._suspendAction);
|
||||
item.add(this._altSwitcher.actor, { expand: true, x_fill: false });
|
||||
item.add(this._altSwitcher, { expand: true, x_fill: false });
|
||||
|
||||
this.menu.addMenuItem(item);
|
||||
|
||||
@ -297,7 +309,7 @@ var Indicator = class extends PanelMenu.SystemIndicator {
|
||||
this._settingsAction,
|
||||
this._orientationLockAction,
|
||||
this._lockScreenAction,
|
||||
this._altSwitcher.actor,
|
||||
this._altSwitcher,
|
||||
];
|
||||
|
||||
for (let actor of visibilityGroup) {
|
||||
@ -312,4 +324,4 @@ var Indicator = class extends PanelMenu.SystemIndicator {
|
||||
Main.overview.hide();
|
||||
this._settingsApp.activate();
|
||||
}
|
||||
};
|
||||
});
|
||||
|
@ -3,7 +3,7 @@
|
||||
|
||||
// the following is a modified version of bolt/contrib/js/client.js
|
||||
|
||||
const { Gio, GLib, Polkit, Shell } = imports.gi;
|
||||
const { Gio, GLib, GObject, Polkit, Shell } = imports.gi;
|
||||
const Signals = imports.signals;
|
||||
|
||||
const Main = imports.ui.main;
|
||||
@ -221,9 +221,11 @@ Signals.addSignalMethods(AuthRobot.prototype);
|
||||
|
||||
/* eof client.js */
|
||||
|
||||
var Indicator = class extends PanelMenu.SystemIndicator {
|
||||
constructor() {
|
||||
super();
|
||||
var Indicator = GObject.registerClass({
|
||||
GTypeName: 'Thunderbolt_Indicator'
|
||||
}, class Indicator extends PanelMenu.SystemIndicator {
|
||||
_init() {
|
||||
super._init();
|
||||
|
||||
this._indicator = this._addIndicator();
|
||||
this._indicator.icon_name = 'thunderbolt-symbolic';
|
||||
@ -284,7 +286,7 @@ var Indicator = class extends PanelMenu.SystemIndicator {
|
||||
if (app)
|
||||
app.activate();
|
||||
});
|
||||
this._source.notify(this._notification);
|
||||
this._source.showNotification(this._notification);
|
||||
}
|
||||
|
||||
/* Session callbacks */
|
||||
@ -334,4 +336,4 @@ var Indicator = class extends PanelMenu.SystemIndicator {
|
||||
const body = _("Could not authorize the Thunderbolt device: %s").format(error.message);
|
||||
this._notify(title, body);
|
||||
}
|
||||
};
|
||||
});
|
||||
|
@ -47,7 +47,7 @@ var StreamSlider = class {
|
||||
return this._slider.startDragging(event);
|
||||
});
|
||||
this.item.connect('key-press-event', (actor, event) => {
|
||||
return this._slider.onKeyPressEvent(actor, event);
|
||||
return this._slider.emit('key-press-event', event);
|
||||
});
|
||||
|
||||
this._stream = null;
|
||||
@ -299,6 +299,9 @@ var VolumeMenu = class extends PopupMenu.PopupMenuSection {
|
||||
this.addMenuItem(this._output.item);
|
||||
|
||||
this._input = new InputStreamSlider(this._control);
|
||||
this._input.item.connect('notify::visible', () => {
|
||||
this.emit('input-visible-changed');
|
||||
});
|
||||
this.addMenuItem(this._input.item);
|
||||
|
||||
this.addMenuItem(new PopupMenu.PopupSeparatorMenuItem());
|
||||
@ -338,34 +341,44 @@ var VolumeMenu = class extends PopupMenu.PopupMenuSection {
|
||||
getMaxLevel() {
|
||||
return this._output.getMaxLevel();
|
||||
}
|
||||
|
||||
getInputVisible() {
|
||||
return this._input.item.visible;
|
||||
}
|
||||
};
|
||||
|
||||
var Indicator = class extends PanelMenu.SystemIndicator {
|
||||
constructor() {
|
||||
super();
|
||||
var Indicator = GObject.registerClass({
|
||||
GTypeName: 'Volume_Indicator'
|
||||
}, class Indicator extends PanelMenu.SystemIndicator {
|
||||
_init() {
|
||||
super._init();
|
||||
|
||||
this._primaryIndicator = this._addIndicator();
|
||||
this._inputIndicator = this._addIndicator();
|
||||
|
||||
this._control = getMixerControl();
|
||||
this._volumeMenu = new VolumeMenu(this._control);
|
||||
this._volumeMenu.connect('icon-changed', () => {
|
||||
let icon = this._volumeMenu.getIcon();
|
||||
|
||||
if (icon != null) {
|
||||
this.indicators.show();
|
||||
if (icon != null)
|
||||
this._primaryIndicator.icon_name = icon;
|
||||
} else {
|
||||
this.indicators.hide();
|
||||
}
|
||||
this._primaryIndicator.visible = icon !== null;
|
||||
});
|
||||
|
||||
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.indicators.connect('scroll-event', this._onScrollEvent.bind(this));
|
||||
}
|
||||
|
||||
_onScrollEvent(actor, event) {
|
||||
let result = this._volumeMenu.scroll(event);
|
||||
vfunc_scroll_event() {
|
||||
let result = this._volumeMenu.scroll(Clutter.get_current_event());
|
||||
if (result == Clutter.EVENT_PROPAGATE || this.menu.actor.mapped)
|
||||
return result;
|
||||
|
||||
@ -375,4 +388,4 @@ var Indicator = class extends PanelMenu.SystemIndicator {
|
||||
Main.osdWindowManager.show(-1, gicon, null, level, maxLevel);
|
||||
return result;
|
||||
}
|
||||
};
|
||||
});
|
||||
|
@ -105,12 +105,6 @@ var SwitcherPopup = GObject.registerClass({
|
||||
this._haveModal = true;
|
||||
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._switcherList.connect('item-activated', this._itemActivated.bind(this));
|
||||
this._switcherList.connect('item-entered', this._itemEntered.bind(this));
|
||||
@ -166,9 +160,10 @@ var SwitcherPopup = GObject.registerClass({
|
||||
throw new GObject.NotImplementedError(`_keyPressHandler in ${this.constructor.name}`);
|
||||
}
|
||||
|
||||
_keyPressEvent(actor, event) {
|
||||
let keysym = event.get_key_symbol();
|
||||
let action = global.display.get_keybinding_action(event.get_key_code(), event.get_state());
|
||||
vfunc_key_press_event(keyEvent) {
|
||||
let keysym = keyEvent.keyval;
|
||||
let action = global.display.get_keybinding_action(
|
||||
keyEvent.hardware_keycode, keyEvent.modifier_state);
|
||||
|
||||
this._disableHover();
|
||||
|
||||
@ -183,13 +178,13 @@ var SwitcherPopup = GObject.registerClass({
|
||||
return Clutter.EVENT_STOP;
|
||||
}
|
||||
|
||||
_keyReleaseEvent(actor, event) {
|
||||
vfunc_key_release_event(keyEvent) {
|
||||
if (this._modifierMask) {
|
||||
let [x_, y_, mods] = global.get_pointer();
|
||||
let state = mods & this._modifierMask;
|
||||
|
||||
if (state == 0)
|
||||
this._finish(event.get_time());
|
||||
this._finish(keyEvent.time);
|
||||
} else {
|
||||
this._resetNoModsTimeout();
|
||||
}
|
||||
@ -197,7 +192,8 @@ var SwitcherPopup = GObject.registerClass({
|
||||
return Clutter.EVENT_STOP;
|
||||
}
|
||||
|
||||
_clickedOutside() {
|
||||
vfunc_button_press_event() {
|
||||
/* We clicked outside */
|
||||
this.fadeAndDestroy();
|
||||
return Clutter.EVENT_PROPAGATE;
|
||||
}
|
||||
@ -209,8 +205,8 @@ var SwitcherPopup = GObject.registerClass({
|
||||
this._select(this._next());
|
||||
}
|
||||
|
||||
_scrollEvent(actor, event) {
|
||||
this._scrollHandler(event.get_scroll_direction());
|
||||
vfunc_scroll_event(scrollEvent) {
|
||||
this._scrollHandler(scrollEvent.scroll_direction);
|
||||
return Clutter.EVENT_PROPAGATE;
|
||||
}
|
||||
|
||||
|
@ -44,7 +44,7 @@ var UnlockDialog = GObject.registerClass({
|
||||
this._authPrompt.setPasswordChar('\u25cf');
|
||||
this._authPrompt.nextButton.label = _("Unlock");
|
||||
|
||||
this._promptBox.add_child(this._authPrompt.actor);
|
||||
this._promptBox.add_child(this._authPrompt);
|
||||
|
||||
this.allowCancel = false;
|
||||
|
||||
|
@ -14,29 +14,47 @@ var AVATAR_ICON_SIZE = 64;
|
||||
// Copyright (C) 2004-2005 James M. Cape <jcape@ignore-your.tv>.
|
||||
// Copyright (C) 2008,2009 Red Hat, Inc.
|
||||
|
||||
var Avatar = class {
|
||||
constructor(user, params) {
|
||||
this._user = user;
|
||||
var Avatar = GObject.registerClass({
|
||||
GTypeName: 'UserWidget_Avatar'
|
||||
}, class Avatar extends St.Bin {
|
||||
_init(user, params) {
|
||||
let themeContext = St.ThemeContext.get_for_stage(global.stage);
|
||||
params = Params.parse(params, { reactive: false,
|
||||
iconSize: AVATAR_ICON_SIZE,
|
||||
styleClass: 'user-icon' });
|
||||
this._iconSize = params.iconSize;
|
||||
|
||||
let scaleFactor = St.ThemeContext.get_for_stage(global.stage).scale_factor;
|
||||
this.actor = new St.Bin({ style_class: params.styleClass,
|
||||
track_hover: params.reactive,
|
||||
reactive: params.reactive,
|
||||
width: this._iconSize * scaleFactor,
|
||||
height: this._iconSize * scaleFactor });
|
||||
super._init({
|
||||
style_class: params.styleClass,
|
||||
reactive: params.reactive,
|
||||
width: params.iconSize * themeContext.scaleFactor,
|
||||
height: params.iconSize * themeContext.scaleFactor
|
||||
});
|
||||
|
||||
this._iconSize = params.iconSize;
|
||||
this._user = user;
|
||||
|
||||
this.bind_property('reactive', this, 'track-hover',
|
||||
GObject.BindingFlags.SYNC_CREATE);
|
||||
this.bind_property('reactive', this, 'can-focus',
|
||||
GObject.BindingFlags.SYNC_CREATE);
|
||||
|
||||
// Monitor the scaling factor to make sure we recreate the avatar when needed.
|
||||
let themeContext = St.ThemeContext.get_for_stage(global.stage);
|
||||
themeContext.connect('notify::scale-factor', this.update.bind(this));
|
||||
this._scaleFactorChangeId =
|
||||
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) {
|
||||
this.actor.can_focus = sensitive;
|
||||
this.actor.reactive = sensitive;
|
||||
this.reactive = sensitive;
|
||||
}
|
||||
|
||||
update() {
|
||||
@ -45,21 +63,21 @@ var Avatar = class {
|
||||
iconFile = null;
|
||||
|
||||
if (iconFile) {
|
||||
this.actor.child = null;
|
||||
this.child = null;
|
||||
let { scaleFactor } = St.ThemeContext.get_for_stage(global.stage);
|
||||
this.actor.set_size(
|
||||
this.set_size(
|
||||
this._iconSize * scaleFactor,
|
||||
this._iconSize * scaleFactor);
|
||||
this.actor.style = `
|
||||
this.style = `
|
||||
background-image: url("${iconFile}");
|
||||
background-size: cover;`;
|
||||
} else {
|
||||
this.actor.style = null;
|
||||
this.actor.child = new St.Icon({ icon_name: 'avatar-default-symbolic',
|
||||
icon_size: this._iconSize });
|
||||
this.style = null;
|
||||
this.child = new St.Icon({ icon_name: 'avatar-default-symbolic',
|
||||
icon_size: this._iconSize });
|
||||
}
|
||||
}
|
||||
};
|
||||
});
|
||||
|
||||
var UserWidgetLabel = GObject.registerClass(
|
||||
class UserWidgetLabel extends St.Widget {
|
||||
@ -140,21 +158,22 @@ class UserWidgetLabel extends St.Widget {
|
||||
}
|
||||
});
|
||||
|
||||
var UserWidget = class {
|
||||
constructor(user) {
|
||||
var UserWidget = GObject.registerClass(
|
||||
class UserWidget extends St.BoxLayout {
|
||||
_init(user) {
|
||||
super._init({ style_class: 'user-widget', vertical: false });
|
||||
|
||||
this._user = user;
|
||||
|
||||
this.actor = new St.BoxLayout({ style_class: 'user-widget',
|
||||
vertical: false });
|
||||
this.actor.connect('destroy', this._onDestroy.bind(this));
|
||||
this.connect('destroy', this._onDestroy.bind(this));
|
||||
|
||||
this._avatar = new Avatar(user);
|
||||
this.actor.add_child(this._avatar.actor);
|
||||
this.add_child(this._avatar);
|
||||
|
||||
this._label = new UserWidgetLabel(user);
|
||||
this.actor.add_child(this._label);
|
||||
this.add_child(this._label);
|
||||
|
||||
this._label.bind_property('label-actor', this.actor, 'label-actor',
|
||||
this._label.bind_property('label-actor', this, 'label-actor',
|
||||
GObject.BindingFlags.SYNC_CREATE);
|
||||
|
||||
this._userLoadedId = this._user.connect('notify::is-loaded', this._updateUser.bind(this));
|
||||
@ -177,4 +196,4 @@ var UserWidget = class {
|
||||
_updateUser() {
|
||||
this._avatar.update();
|
||||
}
|
||||
};
|
||||
});
|
||||
|
@ -123,9 +123,14 @@ var ShowOverviewAction = GObject.registerClass({
|
||||
}
|
||||
});
|
||||
|
||||
var ViewSelector = class {
|
||||
constructor(searchEntry, showAppsButton) {
|
||||
this.actor = new Shell.Stack({ name: 'viewSelector' });
|
||||
var ViewSelector = GObject.registerClass({
|
||||
Signals: {
|
||||
'page-changed': {},
|
||||
'page-empty': {},
|
||||
}
|
||||
}, class ViewSelector extends Shell.Stack {
|
||||
_init(searchEntry, showAppsButton) {
|
||||
super._init({ name: 'viewSelector' });
|
||||
|
||||
this._showAppsButton = showAppsButton;
|
||||
this._showAppsButton.connect('notify::checked', this._onShowAppsButtonToggled.bind(this));
|
||||
@ -165,15 +170,15 @@ var ViewSelector = class {
|
||||
this._capturedEventId = 0;
|
||||
|
||||
this._workspacesDisplay = new WorkspacesView.WorkspacesDisplay();
|
||||
this._workspacesPage = this._addPage(this._workspacesDisplay.actor,
|
||||
this._workspacesPage = this._addPage(this._workspacesDisplay,
|
||||
_("Windows"), 'focus-windows-symbolic');
|
||||
|
||||
this.appDisplay = new AppDisplay.AppDisplay();
|
||||
this._appsPage = this._addPage(this.appDisplay.actor,
|
||||
this._appsPage = this._addPage(this.appDisplay,
|
||||
_("Applications"), 'view-app-grid-symbolic');
|
||||
|
||||
this._searchResults = new Search.SearchResults();
|
||||
this._searchPage = this._addPage(this._searchResults.actor,
|
||||
this._searchResults = new Search.SearchResultsView();
|
||||
this._searchPage = this._addPage(this._searchResults,
|
||||
_("Search"), 'edit-find-symbolic',
|
||||
{ a11yFocus: this._entry });
|
||||
|
||||
@ -184,9 +189,9 @@ var ViewSelector = class {
|
||||
this._focusTrap.connect('key-focus-in', () => {
|
||||
this._entry.grab_key_focus();
|
||||
});
|
||||
this._searchResults.actor.add_actor(this._focusTrap);
|
||||
this._searchResults.add_actor(this._focusTrap);
|
||||
|
||||
global.focus_manager.add_group(this._searchResults.actor);
|
||||
global.focus_manager.add_group(this._searchResults);
|
||||
|
||||
this._stageKeyPressId = 0;
|
||||
Main.overview.connect('showing', () => {
|
||||
@ -310,11 +315,11 @@ var ViewSelector = class {
|
||||
Main.ctrlAltTabManager.addGroup(params.a11yFocus, name, a11yIcon);
|
||||
else
|
||||
Main.ctrlAltTabManager.addGroup(actor, name, a11yIcon, {
|
||||
proxy: this.actor,
|
||||
proxy: this,
|
||||
focusCallback: () => this._a11yFocusPage(page),
|
||||
});
|
||||
page.hide();
|
||||
this.actor.add_actor(page);
|
||||
this.add_actor(page);
|
||||
return page;
|
||||
}
|
||||
|
||||
@ -454,7 +459,7 @@ var ViewSelector = class {
|
||||
_onStageKeyFocusChanged() {
|
||||
let focus = global.stage.get_key_focus();
|
||||
let appearFocused = (this._entry.contains(focus) ||
|
||||
this._searchResults.actor.contains(focus));
|
||||
this._searchResults.contains(focus));
|
||||
|
||||
this._text.set_cursor_visible(appearFocused);
|
||||
|
||||
@ -599,5 +604,4 @@ var ViewSelector = class {
|
||||
else
|
||||
return ViewPage.SEARCH;
|
||||
}
|
||||
};
|
||||
Signals.addSignalMethods(ViewSelector.prototype);
|
||||
});
|
||||
|
@ -1,7 +1,7 @@
|
||||
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
|
||||
/* exported WindowAttentionHandler */
|
||||
|
||||
const Shell = imports.gi.Shell;
|
||||
const { GObject, Shell } = imports.gi;
|
||||
|
||||
const Main = imports.ui.main;
|
||||
const MessageTray = imports.ui.messageTray;
|
||||
@ -34,7 +34,7 @@ var WindowAttentionHandler = class {
|
||||
return;
|
||||
|
||||
let app = this._tracker.get_window_app(window);
|
||||
let source = new Source(app, window);
|
||||
let source = new WindowAttentionSource(app, window);
|
||||
Main.messageTray.add(source);
|
||||
|
||||
let [title, banner] = this._getTitleAndBanner(app, window);
|
||||
@ -45,7 +45,7 @@ var WindowAttentionHandler = class {
|
||||
});
|
||||
notification.setForFeedback(true);
|
||||
|
||||
source.notify(notification);
|
||||
source.showNotification(notification);
|
||||
|
||||
source.signalIDs.push(window.connect('notify::title', () => {
|
||||
let [title, banner] = this._getTitleAndBanner(app, window);
|
||||
@ -54,9 +54,10 @@ var WindowAttentionHandler = class {
|
||||
}
|
||||
};
|
||||
|
||||
var Source = class WindowAttentionSource extends MessageTray.Source {
|
||||
constructor(app, window) {
|
||||
super(app.get_name());
|
||||
var WindowAttentionSource = GObject.registerClass(
|
||||
class WindowAttentionSource extends MessageTray.Source {
|
||||
_init(app, window) {
|
||||
super._init(app.get_name());
|
||||
|
||||
this._window = window;
|
||||
this._app = app;
|
||||
@ -102,4 +103,4 @@ var Source = class WindowAttentionSource extends MessageTray.Source {
|
||||
open() {
|
||||
Main.activateWindow(this._window);
|
||||
}
|
||||
};
|
||||
});
|
||||
|
@ -40,6 +40,8 @@ const GSD_WACOM_OBJECT_PATH = '/org/gnome/SettingsDaemon/Wacom';
|
||||
const GsdWacomIface = loadInterfaceXML('org.gnome.SettingsDaemon.Wacom');
|
||||
const GsdWacomProxy = Gio.DBusProxy.makeProxyWrapper(GsdWacomIface);
|
||||
|
||||
const WINDOW_DIMMER_EFFECT_NAME = "gnome-shell-window-dimmer";
|
||||
|
||||
var DisplayChangeDialog = GObject.registerClass(
|
||||
class DisplayChangeDialog extends ModalDialog.ModalDialog {
|
||||
_init(wm) {
|
||||
@ -114,21 +116,20 @@ class DisplayChangeDialog extends ModalDialog.ModalDialog {
|
||||
}
|
||||
});
|
||||
|
||||
var WindowDimmer = class {
|
||||
constructor(actor) {
|
||||
this._brightnessEffect = new Clutter.BrightnessContrastEffect({
|
||||
name: 'dim',
|
||||
var WindowDimmer = GObject.registerClass(
|
||||
class WindowDimmer extends Clutter.BrightnessContrastEffect {
|
||||
_init() {
|
||||
super._init({
|
||||
name: WINDOW_DIMMER_EFFECT_NAME,
|
||||
enabled: false
|
||||
});
|
||||
actor.add_effect(this._brightnessEffect);
|
||||
this.actor = actor;
|
||||
this._enabled = true;
|
||||
}
|
||||
|
||||
_syncEnabled() {
|
||||
let animating = this.actor.get_transition('@effects.dim.brightness') != null;
|
||||
let dimmed = this._brightnessEffect.brightness.red != 127;
|
||||
this._brightnessEffect.enabled = this._enabled && (animating || dimmed);
|
||||
let animating = this.actor.get_transition(`@effects.${this.name}.brightness`) != null;
|
||||
let dimmed = this.brightness.red != 127;
|
||||
this.enabled = this._enabled && (animating || dimmed);
|
||||
}
|
||||
|
||||
setEnabled(enabled) {
|
||||
@ -140,7 +141,7 @@ var WindowDimmer = class {
|
||||
let val = 127 * (1 + (dimmed ? 1 : 0) * DIM_BRIGHTNESS);
|
||||
let color = Clutter.Color.new(val, val, val, 255);
|
||||
|
||||
this.actor.ease_property('@effects.dim.brightness', color, {
|
||||
this.actor.ease_property(`@effects.${this.name}.brightness`, color, {
|
||||
mode: Clutter.AnimationMode.LINEAR,
|
||||
duration: (dimmed ? DIM_TIME : UNDIM_TIME) * (animate ? 1 : 0),
|
||||
onComplete: () => this._syncEnabled()
|
||||
@ -148,20 +149,19 @@ var WindowDimmer = class {
|
||||
|
||||
this._syncEnabled();
|
||||
}
|
||||
};
|
||||
});
|
||||
|
||||
function getWindowDimmer(actor) {
|
||||
let enabled = Meta.prefs_get_attach_modal_dialogs();
|
||||
if (actor._windowDimmer)
|
||||
actor._windowDimmer.setEnabled(enabled);
|
||||
let effect = actor.get_effect(WINDOW_DIMMER_EFFECT_NAME);
|
||||
|
||||
if (enabled) {
|
||||
if (!actor._windowDimmer)
|
||||
actor._windowDimmer = new WindowDimmer(actor);
|
||||
return actor._windowDimmer;
|
||||
} else {
|
||||
return null;
|
||||
if (effect) {
|
||||
effect.setEnabled(enabled);
|
||||
} else if (enabled) {
|
||||
effect = new WindowDimmer();
|
||||
actor.add_effect(effect);
|
||||
}
|
||||
return effect;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -379,21 +379,22 @@ var WorkspaceTracker = class {
|
||||
}
|
||||
};
|
||||
|
||||
var TilePreview = class {
|
||||
constructor() {
|
||||
this.actor = new St.Widget();
|
||||
global.window_group.add_actor(this.actor);
|
||||
var TilePreview = GObject.registerClass(
|
||||
class TilePreview extends St.Widget {
|
||||
_init() {
|
||||
super._init();
|
||||
global.window_group.add_actor(this);
|
||||
|
||||
this._reset();
|
||||
this._showing = false;
|
||||
}
|
||||
|
||||
show(window, tileRect, monitorIndex) {
|
||||
open(window, tileRect, monitorIndex) {
|
||||
let windowActor = window.get_compositor_private();
|
||||
if (!windowActor)
|
||||
return;
|
||||
|
||||
global.window_group.set_child_below_sibling(this.actor, windowActor);
|
||||
global.window_group.set_child_below_sibling(this, windowActor);
|
||||
|
||||
if (this._rect && this._rect.equal(tileRect))
|
||||
return;
|
||||
@ -414,14 +415,14 @@ var TilePreview = class {
|
||||
width: monitor.width,
|
||||
height: monitor.height });
|
||||
let [, rect] = window.get_frame_rect().intersect(monitorRect);
|
||||
this.actor.set_size(rect.width, rect.height);
|
||||
this.actor.set_position(rect.x, rect.y);
|
||||
this.actor.opacity = 0;
|
||||
this.set_size(rect.width, rect.height);
|
||||
this.set_position(rect.x, rect.y);
|
||||
this.opacity = 0;
|
||||
}
|
||||
|
||||
this._showing = true;
|
||||
this.actor.show();
|
||||
this.actor.ease({
|
||||
this.show();
|
||||
this.ease({
|
||||
x: tileRect.x,
|
||||
y: tileRect.y,
|
||||
width: tileRect.width,
|
||||
@ -432,12 +433,12 @@ var TilePreview = class {
|
||||
});
|
||||
}
|
||||
|
||||
hide() {
|
||||
close() {
|
||||
if (!this._showing)
|
||||
return;
|
||||
|
||||
this._showing = false;
|
||||
this.actor.ease({
|
||||
this.ease({
|
||||
opacity: 0,
|
||||
duration: WINDOW_ANIMATION_TIME,
|
||||
mode: Clutter.AnimationMode.EASE_OUT_QUAD,
|
||||
@ -446,7 +447,7 @@ var TilePreview = class {
|
||||
}
|
||||
|
||||
_reset() {
|
||||
this.actor.hide();
|
||||
this.hide();
|
||||
this._rect = null;
|
||||
this._monitorIndex = -1;
|
||||
}
|
||||
@ -460,9 +461,9 @@ var TilePreview = class {
|
||||
if (this._rect.x + this._rect.width == monitor.x + monitor.width)
|
||||
styles.push('tile-preview-right');
|
||||
|
||||
this.actor.style_class = styles.join(' ');
|
||||
this.style_class = styles.join(' ');
|
||||
}
|
||||
};
|
||||
});
|
||||
|
||||
var TouchpadWorkspaceSwitchAction = class {
|
||||
constructor(actor, allowedModes) {
|
||||
@ -669,15 +670,16 @@ var AppSwitchAction = GObject.registerClass({
|
||||
}
|
||||
});
|
||||
|
||||
var ResizePopup = class {
|
||||
constructor() {
|
||||
this._widget = new St.Widget({ layout_manager: new Clutter.BinLayout() });
|
||||
var ResizePopup = GObject.registerClass(
|
||||
class ResizePopup extends St.Widget {
|
||||
_init() {
|
||||
super._init({ layout_manager: new Clutter.BinLayout() });
|
||||
this._label = new St.Label({ style_class: 'resize-popup',
|
||||
x_align: Clutter.ActorAlign.CENTER,
|
||||
y_align: Clutter.ActorAlign.CENTER,
|
||||
x_expand: true, y_expand: true });
|
||||
this._widget.add_child(this._label);
|
||||
Main.uiGroup.add_actor(this._widget);
|
||||
this.add_child(this._label);
|
||||
Main.uiGroup.add_actor(this);
|
||||
}
|
||||
|
||||
set(rect, displayW, displayH) {
|
||||
@ -686,15 +688,10 @@ var ResizePopup = class {
|
||||
let text = _("%d × %d").format(displayW, displayH);
|
||||
this._label.set_text(text);
|
||||
|
||||
this._widget.set_position(rect.x, rect.y);
|
||||
this._widget.set_size(rect.width, rect.height);
|
||||
this.set_position(rect.x, rect.y);
|
||||
this.set_size(rect.width, rect.height);
|
||||
}
|
||||
|
||||
destroy() {
|
||||
this._widget.destroy();
|
||||
this._widget = null;
|
||||
}
|
||||
};
|
||||
});
|
||||
|
||||
var WindowManager = class {
|
||||
constructor() {
|
||||
@ -1089,7 +1086,7 @@ var WindowManager = class {
|
||||
let mode = Shell.ActionMode.ALL & ~Shell.ActionMode.LOCK_SCREEN;
|
||||
let bottomDragAction = new EdgeDragAction.EdgeDragAction(St.Side.BOTTOM, mode);
|
||||
bottomDragAction.connect('activated', () => {
|
||||
Main.keyboard.show(Main.layoutManager.bottomIndex);
|
||||
Main.keyboard.open(Main.layoutManager.bottomIndex);
|
||||
});
|
||||
Main.layoutManager.connect('keyboard-visible-changed', (manager, visible) => {
|
||||
bottomDragAction.cancel();
|
||||
@ -1119,7 +1116,7 @@ var WindowManager = class {
|
||||
this._currentPadOsd = new PadOsd.PadOsd(device, settings, imagePath, editionMode, monitorIndex);
|
||||
this._currentPadOsd.connect('closed', () => (this._currentPadOsd = null));
|
||||
|
||||
return this._currentPadOsd.actor;
|
||||
return this._currentPadOsd;
|
||||
}
|
||||
|
||||
_switchWorkspaceMotion(action, xRel, yRel) {
|
||||
@ -2045,13 +2042,13 @@ var WindowManager = class {
|
||||
_showTilePreview(shellwm, window, tileRect, monitorIndex) {
|
||||
if (!this._tilePreview)
|
||||
this._tilePreview = new TilePreview();
|
||||
this._tilePreview.show(window, tileRect, monitorIndex);
|
||||
this._tilePreview.open(window, tileRect, monitorIndex);
|
||||
}
|
||||
|
||||
_hideTilePreview() {
|
||||
if (!this._tilePreview)
|
||||
return;
|
||||
this._tilePreview.hide();
|
||||
this._tilePreview.close();
|
||||
}
|
||||
|
||||
_showWindowMenu(shellwm, window, menu, rect) {
|
||||
|
@ -1,7 +1,8 @@
|
||||
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
|
||||
/* exported Workspace */
|
||||
|
||||
const { Atk, Clutter, GLib, GObject, Meta, Pango, Shell, St } = imports.gi;
|
||||
const { Atk, Clutter, GLib, GObject,
|
||||
Graphene, Meta, Pango, Shell, St } = imports.gi;
|
||||
const Signals = imports.signals;
|
||||
|
||||
const DND = imports.ui.dnd;
|
||||
@ -93,6 +94,7 @@ class WindowCloneLayout extends Clutter.LayoutManager {
|
||||
});
|
||||
|
||||
var WindowClone = GObject.registerClass({
|
||||
GTypeName: 'Workspace_WindowClone',
|
||||
Signals: {
|
||||
'drag-begin': {},
|
||||
'drag-cancelled': {},
|
||||
@ -102,7 +104,7 @@ var WindowClone = GObject.registerClass({
|
||||
'show-chrome': {},
|
||||
'size-changed': {}
|
||||
},
|
||||
}, class WorkspaceWindowClone extends St.Widget {
|
||||
}, class WindowClone extends St.Widget {
|
||||
_init(realWindow, workspace) {
|
||||
this.realWindow = realWindow;
|
||||
this.metaWindow = realWindow.meta_window;
|
||||
@ -157,18 +159,13 @@ var WindowClone = GObject.registerClass({
|
||||
this.x = this._boundingBox.x;
|
||||
this.y = this._boundingBox.y;
|
||||
|
||||
this._computeWindowCenter();
|
||||
|
||||
let clickAction = new Clutter.ClickAction();
|
||||
clickAction.connect('clicked', this._onClicked.bind(this));
|
||||
clickAction.connect('long-press', this._onLongPress.bind(this));
|
||||
this.add_action(clickAction);
|
||||
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,
|
||||
{ restoreOnSuccess: true,
|
||||
@ -299,6 +296,18 @@ var WindowClone = GObject.registerClass({
|
||||
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
|
||||
getActualStackAbove() {
|
||||
if (this._stackAbove == null)
|
||||
@ -368,8 +377,28 @@ var WindowClone = GObject.registerClass({
|
||||
this.emit('selected', global.get_current_time());
|
||||
}
|
||||
|
||||
_onKeyPress(actor, event) {
|
||||
let symbol = event.get_key_symbol();
|
||||
vfunc_enter_event(crossingEvent) {
|
||||
this.emit('show-chrome');
|
||||
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);
|
||||
if (isEnter) {
|
||||
this._activate();
|
||||
@ -1003,11 +1032,7 @@ var UnalignedLayoutStrategy = class extends LayoutStrategy {
|
||||
_sortRow(row) {
|
||||
// Sort windows horizontally to minimize travel distance.
|
||||
// This affects in what order the windows end up in a row.
|
||||
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;
|
||||
});
|
||||
row.windows.sort((a, b) => a.windowCenter.x - b.windowCenter.x);
|
||||
}
|
||||
|
||||
computeLayout(windows, layout) {
|
||||
@ -1026,11 +1051,7 @@ var UnalignedLayoutStrategy = class extends LayoutStrategy {
|
||||
// Sort windows vertically to minimize travel distance.
|
||||
// This affects what rows the windows get placed in.
|
||||
let sortedWindows = windows.slice();
|
||||
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;
|
||||
});
|
||||
sortedWindows.sort((a, b) => a.windowCenter.y - b.windowCenter.y);
|
||||
|
||||
let windowIdx = 0;
|
||||
for (let i = 0; i < numRows; i++) {
|
||||
@ -1094,23 +1115,14 @@ function rectEqual(one, two) {
|
||||
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
|
||||
*/
|
||||
var Workspace = class {
|
||||
constructor(metaWorkspace, monitorIndex) {
|
||||
var Workspace = GObject.registerClass(
|
||||
class Workspace extends St.Widget {
|
||||
_init(metaWorkspace, monitorIndex) {
|
||||
super._init({ style_class: 'window-picker' });
|
||||
|
||||
// When dragging a window, we use this slot for reserve space.
|
||||
this._reservedSlot = null;
|
||||
this._reservedSlotWindow = null;
|
||||
@ -1136,18 +1148,17 @@ var Workspace = class {
|
||||
// Without this the drop area will be overlapped.
|
||||
this._windowOverlaysGroup.set_size(0, 0);
|
||||
|
||||
this.actor = new WorkspaceActor({ style_class: 'window-picker' });
|
||||
if (monitorIndex != Main.layoutManager.primaryIndex)
|
||||
this.actor.add_style_class_name('external-monitor');
|
||||
this.actor.set_size(0, 0);
|
||||
this.add_style_class_name('external-monitor');
|
||||
this.set_size(0, 0);
|
||||
|
||||
this._dropRect = new Clutter.Actor({ opacity: 0 });
|
||||
this._dropRect._delegate = this;
|
||||
|
||||
this.actor.add_actor(this._dropRect);
|
||||
this.actor.add_actor(this._windowOverlaysGroup);
|
||||
this.add_actor(this._dropRect);
|
||||
this.add_actor(this._windowOverlaysGroup);
|
||||
|
||||
this.actor.connect('destroy', this._onDestroy.bind(this));
|
||||
this.connect('destroy', this._onDestroy.bind(this));
|
||||
|
||||
let windows = global.get_window_actors().filter(this._isMyWindow, this);
|
||||
|
||||
@ -1177,10 +1188,19 @@ var Workspace = class {
|
||||
|
||||
this._positionWindowsFlags = 0;
|
||||
this._positionWindowsId = 0;
|
||||
}
|
||||
|
||||
this.actor.connect('notify::mapped', () => {
|
||||
if (this.actor.mapped)
|
||||
this._syncActualGeometry();
|
||||
vfunc_map() {
|
||||
super.vfunc_map();
|
||||
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;
|
||||
});
|
||||
}
|
||||
|
||||
@ -1190,7 +1210,7 @@ var Workspace = class {
|
||||
|
||||
this._fullGeometry = geom;
|
||||
|
||||
if (this.actor.mapped)
|
||||
if (this.mapped)
|
||||
this._recalculateWindowPositions(WindowPositionFlags.NONE);
|
||||
}
|
||||
|
||||
@ -1201,7 +1221,7 @@ var Workspace = class {
|
||||
this._actualGeometry = geom;
|
||||
this._actualGeometryDirty = true;
|
||||
|
||||
if (this.actor.mapped)
|
||||
if (this.mapped)
|
||||
this._syncActualGeometry();
|
||||
}
|
||||
|
||||
@ -1213,7 +1233,7 @@ var Workspace = class {
|
||||
|
||||
this._actualGeometryLater = Meta.later_add(Meta.LaterType.BEFORE_REDRAW, () => {
|
||||
this._actualGeometryLater = 0;
|
||||
if (!this.actor.mapped)
|
||||
if (!this.mapped)
|
||||
return false;
|
||||
|
||||
let geom = this._actualGeometry;
|
||||
@ -1504,8 +1524,7 @@ var Workspace = class {
|
||||
// Newly-created windows are added to a workspace before
|
||||
// the compositor finds out about them...
|
||||
let id = GLib.idle_add(GLib.PRIORITY_DEFAULT, () => {
|
||||
if (this.actor &&
|
||||
metaWin.get_compositor_private() &&
|
||||
if (metaWin.get_compositor_private() &&
|
||||
metaWin.get_workspace() == this.metaWorkspace)
|
||||
this._doAddWindow(metaWin);
|
||||
return GLib.SOURCE_REMOVE;
|
||||
@ -1541,8 +1560,8 @@ var Workspace = class {
|
||||
let [clone, overlay_] = this._addWindowClone(win, false);
|
||||
|
||||
if (win._overviewHint) {
|
||||
let x = win._overviewHint.x - this.actor.x;
|
||||
let y = win._overviewHint.y - this.actor.y;
|
||||
let x = win._overviewHint.x - this.x;
|
||||
let y = win._overviewHint.y - this.y;
|
||||
let scale = win._overviewHint.scale;
|
||||
delete win._overviewHint;
|
||||
|
||||
@ -1777,10 +1796,6 @@ var Workspace = class {
|
||||
}
|
||||
}
|
||||
|
||||
destroy() {
|
||||
this.actor.destroy();
|
||||
}
|
||||
|
||||
_onDestroy() {
|
||||
if (this._overviewHiddenId) {
|
||||
Main.overview.disconnect(this._overviewHiddenId);
|
||||
@ -1861,11 +1876,11 @@ var Workspace = class {
|
||||
this._removeWindowClone(clone.metaWindow);
|
||||
});
|
||||
|
||||
this.actor.add_actor(clone);
|
||||
this.add_actor(clone);
|
||||
|
||||
overlay.connect('chrome-visible', () => {
|
||||
let focus = global.stage.key_focus;
|
||||
if (focus == null || this.actor.contains(focus))
|
||||
if (focus == null || this.contains(focus))
|
||||
clone.grab_key_focus();
|
||||
|
||||
this._windowOverlays.forEach(o => {
|
||||
@ -1949,7 +1964,7 @@ var Workspace = class {
|
||||
}
|
||||
|
||||
_getSpacingAndPadding() {
|
||||
let node = this.actor.get_theme_node();
|
||||
let node = this.get_theme_node();
|
||||
|
||||
// Window grid spacing
|
||||
let columnSpacing = node.get_length('-horizontal-spacing');
|
||||
@ -2047,5 +2062,4 @@ var Workspace = class {
|
||||
|
||||
return false;
|
||||
}
|
||||
};
|
||||
Signals.addSignalMethods(Workspace.prototype);
|
||||
});
|
||||
|
@ -2,7 +2,6 @@
|
||||
/* exported WorkspaceThumbnail, ThumbnailsBox */
|
||||
|
||||
const { Clutter, Gio, GLib, GObject, Meta, Shell, St } = imports.gi;
|
||||
const Signals = imports.signals;
|
||||
|
||||
const Background = imports.ui.background;
|
||||
const DND = imports.ui.dnd;
|
||||
@ -44,36 +43,40 @@ class PrimaryActorLayout extends Clutter.FixedLayout {
|
||||
}
|
||||
});
|
||||
|
||||
var WindowClone = class {
|
||||
constructor(realWindow) {
|
||||
this.clone = new Clutter.Clone({ source: realWindow });
|
||||
var WindowClone = GObject.registerClass({
|
||||
GTypeName: 'WorkspaceThumbnail_WindowClone',
|
||||
Signals: {
|
||||
'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;
|
||||
|
||||
/* 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.add_child(clone);
|
||||
this.realWindow = realWindow;
|
||||
this.metaWindow = realWindow.meta_window;
|
||||
|
||||
this.clone._updateId = this.realWindow.connect('notify::position',
|
||||
this._onPositionChanged.bind(this));
|
||||
this.clone._destroyId = this.realWindow.connect('destroy', () => {
|
||||
clone._updateId = this.realWindow.connect('notify::position',
|
||||
this._onPositionChanged.bind(this));
|
||||
clone._destroyId = this.realWindow.connect('destroy', () => {
|
||||
// First destroy the clone and then destroy everything
|
||||
// This will ensure that we never see it in the _disconnectSignals loop
|
||||
this.clone.destroy();
|
||||
clone.destroy();
|
||||
this.destroy();
|
||||
});
|
||||
this._onPositionChanged();
|
||||
|
||||
this.actor.connect('button-release-event',
|
||||
this._onButtonRelease.bind(this));
|
||||
this.actor.connect('touch-event',
|
||||
this._onTouchEvent.bind(this));
|
||||
this.connect('destroy', this._onDestroy.bind(this));
|
||||
|
||||
this.actor.connect('destroy', this._onDestroy.bind(this));
|
||||
|
||||
this._draggable = DND.makeDraggable(this.actor,
|
||||
this._draggable = DND.makeDraggable(this,
|
||||
{ restoreOnSuccess: true,
|
||||
dragActorMaxSize: Workspace.WINDOW_DND_SIZE,
|
||||
dragActorOpacity: Workspace.DRAGGING_WINDOW_OPACITY });
|
||||
@ -124,13 +127,9 @@ var WindowClone = class {
|
||||
|
||||
let actualAbove = this.getActualStackAbove();
|
||||
if (actualAbove == null)
|
||||
this.actor.lower_bottom();
|
||||
this.lower_bottom();
|
||||
else
|
||||
this.actor.raise(actualAbove);
|
||||
}
|
||||
|
||||
destroy() {
|
||||
this.actor.destroy();
|
||||
this.raise(actualAbove);
|
||||
}
|
||||
|
||||
addAttachedDialog(win) {
|
||||
@ -147,7 +146,7 @@ var WindowClone = class {
|
||||
clone._destroyId = realDialog.connect('destroy', () => {
|
||||
clone.destroy();
|
||||
});
|
||||
this.actor.add_child(clone);
|
||||
this.add_child(clone);
|
||||
}
|
||||
|
||||
_updateDialogPosition(realDialog, cloneDialog) {
|
||||
@ -159,11 +158,11 @@ var WindowClone = class {
|
||||
}
|
||||
|
||||
_onPositionChanged() {
|
||||
this.actor.set_position(this.realWindow.x, this.realWindow.y);
|
||||
this.set_position(this.realWindow.x, this.realWindow.y);
|
||||
}
|
||||
|
||||
_disconnectSignals() {
|
||||
this.actor.get_children().forEach(child => {
|
||||
this.get_children().forEach(child => {
|
||||
let realWindow = child.source;
|
||||
|
||||
realWindow.disconnect(child._updateId);
|
||||
@ -174,28 +173,30 @@ var WindowClone = class {
|
||||
_onDestroy() {
|
||||
this._disconnectSignals();
|
||||
|
||||
this.actor._delegate = null;
|
||||
this._delegate = null;
|
||||
|
||||
if (this.inDrag) {
|
||||
this.emit('drag-end');
|
||||
this.inDrag = false;
|
||||
}
|
||||
|
||||
this.disconnectAll();
|
||||
}
|
||||
|
||||
_onButtonRelease(actor, event) {
|
||||
this.emit('selected', event.get_time());
|
||||
vfunc_button_press_event() {
|
||||
return Clutter.EVENT_STOP;
|
||||
}
|
||||
|
||||
vfunc_button_release_event(buttonEvent) {
|
||||
this.emit('selected', buttonEvent.time);
|
||||
|
||||
return Clutter.EVENT_STOP;
|
||||
}
|
||||
|
||||
_onTouchEvent(actor, event) {
|
||||
if (event.type() != Clutter.EventType.TOUCH_END ||
|
||||
!global.display.is_pointer_emulating_sequence(event.get_event_sequence()))
|
||||
vfunc_touch_event(touchEvent) {
|
||||
if (touchEvent.type != Clutter.EventType.TOUCH_END ||
|
||||
!global.display.is_pointer_emulating_sequence(touchEvent.sequence))
|
||||
return Clutter.EVENT_PROPAGATE;
|
||||
|
||||
this.emit('selected', event.get_time());
|
||||
this.emit('selected', touchEvent.time);
|
||||
return Clutter.EVENT_STOP;
|
||||
}
|
||||
|
||||
@ -214,18 +215,17 @@ var WindowClone = class {
|
||||
// We may not have a parent if DnD completed successfully, in
|
||||
// which case our clone will shortly be destroyed and replaced
|
||||
// with a new one on the target workspace.
|
||||
if (this.actor.get_parent() != null) {
|
||||
if (this.get_parent() != null) {
|
||||
if (this._stackAbove == null)
|
||||
this.actor.lower_bottom();
|
||||
this.lower_bottom();
|
||||
else
|
||||
this.actor.raise(this._stackAbove);
|
||||
this.raise(this._stackAbove);
|
||||
}
|
||||
|
||||
|
||||
this.emit('drag-end');
|
||||
}
|
||||
};
|
||||
Signals.addSignalMethods(WindowClone.prototype);
|
||||
});
|
||||
|
||||
|
||||
var ThumbnailState = {
|
||||
@ -340,7 +340,7 @@ var WorkspaceThumbnail = GObject.registerClass({
|
||||
clone.setStackAbove(this._bgManager.backgroundActor);
|
||||
} else {
|
||||
let previousClone = this._windows[i - 1];
|
||||
clone.setStackAbove(previousClone.actor);
|
||||
clone.setStackAbove(previousClone);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -522,15 +522,15 @@ var WorkspaceThumbnail = GObject.registerClass({
|
||||
clone.connect('drag-end', () => {
|
||||
Main.overview.endWindowDrag(clone.metaWindow);
|
||||
});
|
||||
clone.actor.connect('destroy', () => {
|
||||
clone.connect('destroy', () => {
|
||||
this._removeWindowClone(clone.metaWindow);
|
||||
});
|
||||
this._contents.add_actor(clone.actor);
|
||||
this._contents.add_actor(clone);
|
||||
|
||||
if (this._windows.length == 0)
|
||||
clone.setStackAbove(this._bgManager.backgroundActor);
|
||||
else
|
||||
clone.setStackAbove(this._windows[this._windows.length - 1].actor);
|
||||
clone.setStackAbove(this._windows[this._windows.length - 1]);
|
||||
|
||||
this._windows.push(clone);
|
||||
|
||||
@ -668,10 +668,6 @@ var ThumbnailsBox = GObject.registerClass({
|
||||
|
||||
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',
|
||||
this._createThumbnails.bind(this));
|
||||
Main.overview.connect('hidden',
|
||||
@ -728,17 +724,17 @@ var ThumbnailsBox = GObject.registerClass({
|
||||
thumbnail.activate(time);
|
||||
}
|
||||
|
||||
_onButtonRelease(actor, event) {
|
||||
let [stageX, stageY] = event.get_coords();
|
||||
this._activateThumbnailAtPoint(stageX, stageY, event.get_time());
|
||||
vfunc_button_release_event(buttonEvent) {
|
||||
let { x, y } = buttonEvent;
|
||||
this._activateThumbnailAtPoint(x, y, buttonEvent.time);
|
||||
return Clutter.EVENT_STOP;
|
||||
}
|
||||
|
||||
_onTouchEvent(actor, event) {
|
||||
if (event.type() == Clutter.EventType.TOUCH_END &&
|
||||
global.display.is_pointer_emulating_sequence(event.get_event_sequence())) {
|
||||
let [stageX, stageY] = event.get_coords();
|
||||
this._activateThumbnailAtPoint(stageX, stageY, event.get_time());
|
||||
vfunc_touch_event(touchEvent) {
|
||||
if (touchEvent.type == Clutter.EventType.TOUCH_END &&
|
||||
global.display.is_pointer_emulating_sequence(touchEvent.sequence)) {
|
||||
let { x, y } = touchEvent;
|
||||
this._activateThumbnailAtPoint(x, y, touchEvent.time);
|
||||
}
|
||||
|
||||
return Clutter.EVENT_STOP;
|
||||
|
@ -1,8 +1,7 @@
|
||||
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
|
||||
/* exported WorkspacesView */
|
||||
/* exported WorkspacesView, WorkspacesDisplay */
|
||||
|
||||
const { Clutter, Gio, GObject, Meta, Shell, St } = imports.gi;
|
||||
const Signals = imports.signals;
|
||||
|
||||
const Main = imports.ui.main;
|
||||
const WindowManager = imports.ui.windowManager;
|
||||
@ -17,15 +16,16 @@ var AnimationType = {
|
||||
|
||||
const MUTTER_SCHEMA = 'org.gnome.mutter';
|
||||
|
||||
var WorkspacesViewBase = class {
|
||||
constructor(monitorIndex) {
|
||||
this.actor = new St.Widget({ style_class: 'workspaces-view',
|
||||
reactive: true });
|
||||
this.actor.connect('destroy', this._onDestroy.bind(this));
|
||||
global.focus_manager.add_group(this.actor);
|
||||
var WorkspacesViewBase = GObject.registerClass({
|
||||
GTypeFlags: GObject.TypeFlags.ABSTRACT
|
||||
}, class WorkspacesViewBase extends St.Widget {
|
||||
_init(monitorIndex) {
|
||||
super._init({ style_class: 'workspaces-view', reactive: true });
|
||||
this.connect('destroy', this._onDestroy.bind(this));
|
||||
global.focus_manager.add_group(this);
|
||||
|
||||
// The actor itself isn't a drop target, so we don't want to pick on its area
|
||||
this.actor.set_size(0, 0);
|
||||
this.set_size(0, 0);
|
||||
|
||||
this._monitorIndex = monitorIndex;
|
||||
|
||||
@ -60,10 +60,6 @@ var WorkspacesViewBase = class {
|
||||
this._setReservedSlot(null);
|
||||
}
|
||||
|
||||
destroy() {
|
||||
this.actor.destroy();
|
||||
}
|
||||
|
||||
setFullGeometry(geom) {
|
||||
this._fullGeometry = geom;
|
||||
this._syncFullGeometry();
|
||||
@ -73,13 +69,14 @@ var WorkspacesViewBase = class {
|
||||
this._actualGeometry = geom;
|
||||
this._syncActualGeometry();
|
||||
}
|
||||
};
|
||||
});
|
||||
|
||||
var WorkspacesView = class extends WorkspacesViewBase {
|
||||
constructor(monitorIndex) {
|
||||
var WorkspacesView = GObject.registerClass(
|
||||
class WorkspacesView extends WorkspacesViewBase {
|
||||
_init(monitorIndex) {
|
||||
let workspaceManager = global.workspace_manager;
|
||||
|
||||
super(monitorIndex);
|
||||
super._init(monitorIndex);
|
||||
|
||||
this._animating = false; // tweening
|
||||
this._scrolling = false; // swipe-scrolling
|
||||
@ -112,8 +109,8 @@ var WorkspacesView = class extends WorkspacesViewBase {
|
||||
|
||||
this._overviewShownId =
|
||||
Main.overview.connect('shown', () => {
|
||||
this.actor.set_clip(this._fullGeometry.x, this._fullGeometry.y,
|
||||
this._fullGeometry.width, this._fullGeometry.height);
|
||||
this.set_clip(this._fullGeometry.x, this._fullGeometry.y,
|
||||
this._fullGeometry.width, this._fullGeometry.height);
|
||||
});
|
||||
|
||||
this._switchWorkspaceNotifyId =
|
||||
@ -153,7 +150,7 @@ var WorkspacesView = class extends WorkspacesViewBase {
|
||||
}
|
||||
|
||||
animateFromOverview(animationType) {
|
||||
this.actor.remove_clip();
|
||||
this.remove_clip();
|
||||
|
||||
for (let w = 0; w < this._workspaces.length; w++) {
|
||||
if (animationType == AnimationType.ZOOM)
|
||||
@ -187,12 +184,12 @@ var WorkspacesView = class extends WorkspacesViewBase {
|
||||
for (let w = 0; w < this._workspaces.length; w++) {
|
||||
let workspace = this._workspaces[w];
|
||||
|
||||
workspace.actor.remove_all_transitions();
|
||||
workspace.remove_all_transitions();
|
||||
|
||||
let params = {};
|
||||
if (workspaceManager.layout_rows == -1)
|
||||
params.y = (w - active) * this._fullGeometry.height;
|
||||
else if (this.actor.text_direction == Clutter.TextDirection.RTL)
|
||||
else if (this.text_direction == Clutter.TextDirection.RTL)
|
||||
params.x = (active - w) * this._fullGeometry.width;
|
||||
else
|
||||
params.x = (w - active) * this._fullGeometry.width;
|
||||
@ -212,9 +209,9 @@ var WorkspacesView = class extends WorkspacesViewBase {
|
||||
this._updateVisibility();
|
||||
};
|
||||
}
|
||||
workspace.actor.ease(easeParams);
|
||||
workspace.ease(easeParams);
|
||||
} else {
|
||||
workspace.actor.set(params);
|
||||
workspace.set(params);
|
||||
if (w == 0)
|
||||
this._updateVisibility();
|
||||
}
|
||||
@ -228,12 +225,12 @@ var WorkspacesView = class extends WorkspacesViewBase {
|
||||
for (let w = 0; w < this._workspaces.length; w++) {
|
||||
let workspace = this._workspaces[w];
|
||||
if (this._animating || this._scrolling || this._gestureActive) {
|
||||
workspace.actor.show();
|
||||
workspace.show();
|
||||
} else {
|
||||
if (this._inDrag)
|
||||
workspace.actor.visible = (Math.abs(w - active) <= 1);
|
||||
workspace.visible = (Math.abs(w - active) <= 1);
|
||||
else
|
||||
workspace.actor.visible = (w == active);
|
||||
workspace.visible = (w == active);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -263,7 +260,7 @@ var WorkspacesView = class extends WorkspacesViewBase {
|
||||
|
||||
if (j >= this._workspaces.length) { /* added */
|
||||
workspace = new Workspace.Workspace(metaWorkspace, this._monitorIndex);
|
||||
this.actor.add_actor(workspace.actor);
|
||||
this.add_actor(workspace);
|
||||
this._workspaces[j] = workspace;
|
||||
} else {
|
||||
workspace = this._workspaces[j];
|
||||
@ -355,8 +352,8 @@ var WorkspacesView = class extends WorkspacesViewBase {
|
||||
let last = this._workspaces.length - 1;
|
||||
|
||||
if (workspaceManager.layout_rows == -1) {
|
||||
let firstWorkspaceY = this._workspaces[0].actor.y;
|
||||
let lastWorkspaceY = this._workspaces[last].actor.y;
|
||||
let firstWorkspaceY = this._workspaces[0].y;
|
||||
let lastWorkspaceY = this._workspaces[last].y;
|
||||
let workspacesHeight = lastWorkspaceY - firstWorkspaceY;
|
||||
|
||||
let currentY = firstWorkspaceY;
|
||||
@ -365,12 +362,12 @@ var WorkspacesView = class extends WorkspacesViewBase {
|
||||
let dy = newY - currentY;
|
||||
|
||||
for (let i = 0; i < this._workspaces.length; i++) {
|
||||
this._workspaces[i].actor.visible = Math.abs(i - adj.value) <= 1;
|
||||
this._workspaces[i].actor.y += dy;
|
||||
this._workspaces[i].visible = Math.abs(i - adj.value) <= 1;
|
||||
this._workspaces[i].y += dy;
|
||||
}
|
||||
} else {
|
||||
let firstWorkspaceX = this._workspaces[0].actor.x;
|
||||
let lastWorkspaceX = this._workspaces[last].actor.x;
|
||||
let firstWorkspaceX = this._workspaces[0].x;
|
||||
let lastWorkspaceX = this._workspaces[last].x;
|
||||
let workspacesWidth = lastWorkspaceX - firstWorkspaceX;
|
||||
|
||||
let currentX = firstWorkspaceX;
|
||||
@ -379,19 +376,19 @@ var WorkspacesView = class extends WorkspacesViewBase {
|
||||
let dx = newX - currentX;
|
||||
|
||||
for (let i = 0; i < this._workspaces.length; i++) {
|
||||
this._workspaces[i].actor.visible = Math.abs(i - adj.value) <= 1;
|
||||
this._workspaces[i].actor.x += dx;
|
||||
this._workspaces[i].visible = Math.abs(i - adj.value) <= 1;
|
||||
this._workspaces[i].x += dx;
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
Signals.addSignalMethods(WorkspacesView.prototype);
|
||||
});
|
||||
|
||||
var ExtraWorkspaceView = class extends WorkspacesViewBase {
|
||||
constructor(monitorIndex) {
|
||||
super(monitorIndex);
|
||||
var ExtraWorkspaceView = GObject.registerClass(
|
||||
class ExtraWorkspaceView extends WorkspacesViewBase {
|
||||
_init(monitorIndex) {
|
||||
super._init(monitorIndex);
|
||||
this._workspace = new Workspace.Workspace(null, monitorIndex);
|
||||
this.actor.add_actor(this._workspace.actor);
|
||||
this.add_actor(this._workspace);
|
||||
}
|
||||
|
||||
_setReservedSlot(window) {
|
||||
@ -439,21 +436,13 @@ var ExtraWorkspaceView = class extends WorkspacesViewBase {
|
||||
|
||||
endTouchGesture() {
|
||||
}
|
||||
};
|
||||
|
||||
var DelegateFocusNavigator = GObject.registerClass(
|
||||
class DelegateFocusNavigator extends St.Widget {
|
||||
vfunc_navigate_focus(from, direction) {
|
||||
return this._delegate.navigateFocus(from, direction);
|
||||
}
|
||||
});
|
||||
|
||||
var WorkspacesDisplay = class {
|
||||
constructor() {
|
||||
this.actor = new DelegateFocusNavigator({ clip_to_allocation: true });
|
||||
this.actor._delegate = this;
|
||||
this.actor.connect('notify::allocation', this._updateWorkspacesActualGeometry.bind(this));
|
||||
this.actor.connect('parent-set', this._parentSet.bind(this));
|
||||
var WorkspacesDisplay = GObject.registerClass(
|
||||
class WorkspacesDisplay extends St.Widget {
|
||||
_init() {
|
||||
super._init({ clip_to_allocation: true });
|
||||
this.connect('notify::allocation', this._updateWorkspacesActualGeometry.bind(this));
|
||||
|
||||
let clickAction = new Clutter.ClickAction();
|
||||
clickAction.connect('clicked', action => {
|
||||
@ -467,7 +456,7 @@ var WorkspacesDisplay = class {
|
||||
Main.overview.hide();
|
||||
});
|
||||
Main.overview.addAction(clickAction);
|
||||
this.actor.bind_property('mapped', clickAction, 'enabled', GObject.BindingFlags.SYNC_CREATE);
|
||||
this.bind_property('mapped', clickAction, 'enabled', GObject.BindingFlags.SYNC_CREATE);
|
||||
|
||||
let panAction = new Clutter.PanAction({ threshold_trigger_edge: Clutter.GestureTriggerEdge.AFTER });
|
||||
panAction.connect('pan', this._onPan.bind(this));
|
||||
@ -490,7 +479,7 @@ var WorkspacesDisplay = class {
|
||||
this._endSwipeScroll();
|
||||
});
|
||||
Main.overview.addAction(panAction);
|
||||
this.actor.bind_property('mapped', panAction, 'enabled', GObject.BindingFlags.SYNC_CREATE);
|
||||
this.bind_property('mapped', panAction, 'enabled', GObject.BindingFlags.SYNC_CREATE);
|
||||
|
||||
let allowedModes = Shell.ActionMode.OVERVIEW;
|
||||
let switchGesture = new WindowManager.WorkspaceSwitchAction(allowedModes);
|
||||
@ -498,20 +487,15 @@ var WorkspacesDisplay = class {
|
||||
switchGesture.connect('activated', this._onSwitchWorkspaceActivated.bind(this));
|
||||
switchGesture.connect('cancel', this._endTouchGesture.bind(this));
|
||||
Main.overview.addAction(switchGesture);
|
||||
this.actor.bind_property('mapped', switchGesture, 'enabled', GObject.BindingFlags.SYNC_CREATE);
|
||||
this.bind_property('mapped', switchGesture, 'enabled', GObject.BindingFlags.SYNC_CREATE);
|
||||
|
||||
switchGesture = new WindowManager.TouchpadWorkspaceSwitchAction(global.stage, allowedModes);
|
||||
switchGesture.connect('motion', this._onSwitchWorkspaceMotion.bind(this));
|
||||
switchGesture.connect('activated', this._onSwitchWorkspaceActivated.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._workspacesViews = [];
|
||||
switchGesture.enabled = this.actor.mapped;
|
||||
|
||||
this._settings = new Gio.Settings({ schema_id: MUTTER_SCHEMA });
|
||||
this._settings.connect('changed::workspaces-only-on-primary',
|
||||
@ -525,12 +509,12 @@ var WorkspacesDisplay = class {
|
||||
|
||||
this._fullGeometry = null;
|
||||
|
||||
this.actor.connect('destroy', this._onDestroy.bind(this));
|
||||
this.connect('destroy', this._onDestroy.bind(this));
|
||||
}
|
||||
|
||||
_onDestroy() {
|
||||
if (this._notifyOpacityId) {
|
||||
let parent = this.actor.get_parent();
|
||||
let parent = this.get_parent();
|
||||
if (parent)
|
||||
parent.disconnect(this._notifyOpacityId);
|
||||
this._notifyOpacityId = 0;
|
||||
@ -546,11 +530,11 @@ var WorkspacesDisplay = class {
|
||||
let [dist_, dx, dy] = action.get_motion_delta(0);
|
||||
let adjustment = this._scrollAdjustment;
|
||||
if (global.workspace_manager.layout_rows == -1)
|
||||
adjustment.value -= (dy / this.actor.height) * adjustment.page_size;
|
||||
else if (this.actor.text_direction == Clutter.TextDirection.RTL)
|
||||
adjustment.value += (dx / this.actor.width) * adjustment.page_size;
|
||||
adjustment.value -= (dy / this.height) * adjustment.page_size;
|
||||
else if (this.text_direction == Clutter.TextDirection.RTL)
|
||||
adjustment.value += (dx / this.width) * adjustment.page_size;
|
||||
else
|
||||
adjustment.value -= (dx / this.actor.width) * adjustment.page_size;
|
||||
adjustment.value -= (dx / this.width) * adjustment.page_size;
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -583,11 +567,11 @@ var WorkspacesDisplay = class {
|
||||
let active = workspaceManager.get_active_workspace_index();
|
||||
let adjustment = this._scrollAdjustment;
|
||||
if (workspaceManager.layout_rows == -1)
|
||||
adjustment.value = (active - yRel / this.actor.height) * adjustment.page_size;
|
||||
else if (this.actor.text_direction == Clutter.TextDirection.RTL)
|
||||
adjustment.value = (active + xRel / this.actor.width) * adjustment.page_size;
|
||||
adjustment.value = (active - yRel / this.height) * adjustment.page_size;
|
||||
else if (this.text_direction == Clutter.TextDirection.RTL)
|
||||
adjustment.value = (active + xRel / this.width) * adjustment.page_size;
|
||||
else
|
||||
adjustment.value = (active - xRel / this.actor.width) * adjustment.page_size;
|
||||
adjustment.value = (active - xRel / this.width) * adjustment.page_size;
|
||||
}
|
||||
|
||||
_onSwitchWorkspaceActivated(action, direction) {
|
||||
@ -600,8 +584,8 @@ var WorkspacesDisplay = class {
|
||||
this._endTouchGesture();
|
||||
}
|
||||
|
||||
navigateFocus(from, direction) {
|
||||
return this._getPrimaryView().actor.navigate_focus(from, direction, false);
|
||||
vfunc_navigate_focus(from, direction) {
|
||||
return this._getPrimaryView().navigate_focus(from, direction, false);
|
||||
}
|
||||
|
||||
show(fadeOnPrimary) {
|
||||
@ -677,7 +661,7 @@ var WorkspacesDisplay = class {
|
||||
else
|
||||
view = new WorkspacesView(i);
|
||||
|
||||
view.actor.connect('scroll-event', this._onScrollEvent.bind(this));
|
||||
view.connect('scroll-event', this._onScrollEvent.bind(this));
|
||||
if (i == this._primaryIndex) {
|
||||
this._scrollAdjustment = view.scrollAdjustment;
|
||||
this._scrollAdjustment.connect('notify::value',
|
||||
@ -685,13 +669,13 @@ var WorkspacesDisplay = class {
|
||||
}
|
||||
|
||||
// HACK: Avoid spurious allocation changes while updating views
|
||||
view.actor.hide();
|
||||
view.hide();
|
||||
|
||||
this._workspacesViews.push(view);
|
||||
Main.layoutManager.overviewGroup.add_actor(view.actor);
|
||||
Main.layoutManager.overviewGroup.add_actor(view);
|
||||
}
|
||||
|
||||
this._workspacesViews.forEach(v => v.actor.show());
|
||||
this._workspacesViews.forEach(v => v.show());
|
||||
|
||||
this._updateWorkspacesFullGeometry();
|
||||
this._updateWorkspacesActualGeometry();
|
||||
@ -728,7 +712,7 @@ var WorkspacesDisplay = class {
|
||||
return this._getPrimaryView().getActiveWorkspace().hasMaximizedWindows();
|
||||
}
|
||||
|
||||
_parentSet(actor, oldParent) {
|
||||
vfunc_parent_set(oldParent) {
|
||||
if (oldParent && this._notifyOpacityId)
|
||||
oldParent.disconnect(this._notifyOpacityId);
|
||||
this._notifyOpacityId = 0;
|
||||
@ -738,20 +722,20 @@ var WorkspacesDisplay = class {
|
||||
|
||||
this._parentSetLater = Meta.later_add(Meta.LaterType.BEFORE_REDRAW, () => {
|
||||
this._parentSetLater = 0;
|
||||
let newParent = this.actor.get_parent();
|
||||
let newParent = this.get_parent();
|
||||
if (!newParent)
|
||||
return;
|
||||
|
||||
// This is kinda hackish - we want the primary view to
|
||||
// appear as parent of this.actor, though in reality it
|
||||
// appear as parent of this, though in reality it
|
||||
// is added directly to Main.layoutManager.overviewGroup
|
||||
this._notifyOpacityId = newParent.connect('notify::opacity', () => {
|
||||
let opacity = this.actor.get_parent().opacity;
|
||||
let opacity = this.get_parent().opacity;
|
||||
let primaryView = this._getPrimaryView();
|
||||
if (!primaryView)
|
||||
return;
|
||||
primaryView.actor.opacity = opacity;
|
||||
primaryView.actor.visible = opacity != 0;
|
||||
primaryView.opacity = opacity;
|
||||
primaryView.visible = opacity != 0;
|
||||
});
|
||||
});
|
||||
}
|
||||
@ -779,8 +763,8 @@ var WorkspacesDisplay = class {
|
||||
if (!this._workspacesViews.length)
|
||||
return;
|
||||
|
||||
let [x, y] = this.actor.get_transformed_position();
|
||||
let allocation = this.actor.allocation;
|
||||
let [x, y] = this.get_transformed_position();
|
||||
let allocation = this.allocation;
|
||||
let width = allocation.x2 - allocation.x1;
|
||||
let height = allocation.y2 - allocation.y1;
|
||||
let primaryGeometry = { x: x, y: y, width: width, height: height };
|
||||
@ -798,7 +782,7 @@ var WorkspacesDisplay = class {
|
||||
}
|
||||
|
||||
_onScrollEvent(actor, event) {
|
||||
if (!this.actor.mapped)
|
||||
if (!this.mapped)
|
||||
return Clutter.EVENT_PROPAGATE;
|
||||
|
||||
if (this._workspacesOnlyOnPrimary &&
|
||||
@ -829,7 +813,7 @@ var WorkspacesDisplay = class {
|
||||
}
|
||||
|
||||
_onKeyPressEvent(actor, event) {
|
||||
if (!this.actor.mapped)
|
||||
if (!this.mapped)
|
||||
return Clutter.EVENT_PROPAGATE;
|
||||
let workspaceManager = global.workspace_manager;
|
||||
let activeWs = workspaceManager.get_active_workspace();
|
||||
@ -847,5 +831,4 @@ var WorkspacesDisplay = class {
|
||||
Main.wm.actionMoveWorkspace(ws);
|
||||
return Clutter.EVENT_STOP;
|
||||
}
|
||||
};
|
||||
Signals.addSignalMethods(WorkspacesDisplay.prototype);
|
||||
});
|
||||
|
100
po/fur.po
100
po/fur.po
@ -7,15 +7,15 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: video-subtitles master\n"
|
||||
"Report-Msgid-Bugs-To: https://gitlab.gnome.org/GNOME/gnome-shell/issues\n"
|
||||
"POT-Creation-Date: 2019-09-17 11:44+0000\n"
|
||||
"PO-Revision-Date: 2019-09-26 16:19+0200\n"
|
||||
"POT-Creation-Date: 2019-10-12 20:48+0000\n"
|
||||
"PO-Revision-Date: 2019-10-17 15:53+0200\n"
|
||||
"Last-Translator: Fabio Tomat <f.t.public@gmail.com>\n"
|
||||
"Language-Team: Friulian <fur@li.org>\n"
|
||||
"Language: fur\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"X-Generator: Poedit 2.2.3\n"
|
||||
"X-Generator: Poedit 2.2.4\n"
|
||||
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
|
||||
|
||||
#: data/50-gnome-shell-system.xml:6
|
||||
@ -467,7 +467,7 @@ msgid "Next"
|
||||
msgstr "Indenant"
|
||||
|
||||
#: js/gdm/authPrompt.js:197 js/ui/shellMountOperation.js:396
|
||||
#: js/ui/unlockDialog.js:42
|
||||
#: js/ui/unlockDialog.js:45
|
||||
msgid "Unlock"
|
||||
msgstr "Sbloche"
|
||||
|
||||
@ -497,8 +497,8 @@ msgstr "(p.e., utent o %s)"
|
||||
#. TTLS and PEAP are actually much more complicated, but this complication
|
||||
#. is not visible here since we only care about phase2 authentication
|
||||
#. (and don't even care of which one)
|
||||
#: js/gdm/loginDialog.js:884 js/ui/components/networkAgent.js:247
|
||||
#: js/ui/components/networkAgent.js:267 js/ui/components/networkAgent.js:285
|
||||
#: js/gdm/loginDialog.js:884 js/ui/components/networkAgent.js:248
|
||||
#: js/ui/components/networkAgent.js:268 js/ui/components/networkAgent.js:286
|
||||
msgid "Username: "
|
||||
msgstr "Non utent: "
|
||||
|
||||
@ -760,32 +760,32 @@ msgstr "Dispès"
|
||||
msgid "All"
|
||||
msgstr "Dutis"
|
||||
|
||||
#: js/ui/appDisplay.js:1749
|
||||
#: js/ui/appDisplay.js:1745
|
||||
msgid "Rename"
|
||||
msgstr "Cambie non"
|
||||
|
||||
#. Translators: This is the heading of a list of open windows
|
||||
#: js/ui/appDisplay.js:2397 js/ui/panel.js:76
|
||||
#: js/ui/appDisplay.js:2418 js/ui/panel.js:76
|
||||
msgid "Open Windows"
|
||||
msgstr "Barcons vierts"
|
||||
|
||||
#: js/ui/appDisplay.js:2416 js/ui/panel.js:83
|
||||
#: js/ui/appDisplay.js:2437 js/ui/panel.js:83
|
||||
msgid "New Window"
|
||||
msgstr "Gnûf barcon"
|
||||
|
||||
#: js/ui/appDisplay.js:2428
|
||||
#: js/ui/appDisplay.js:2449
|
||||
msgid "Launch using Dedicated Graphics Card"
|
||||
msgstr "Invie doprant une schede grafiche dedicade"
|
||||
|
||||
#: js/ui/appDisplay.js:2457 js/ui/dash.js:239
|
||||
#: js/ui/appDisplay.js:2478 js/ui/dash.js:239
|
||||
msgid "Remove from Favorites"
|
||||
msgstr "Gjave dai preferîts"
|
||||
|
||||
#: js/ui/appDisplay.js:2463
|
||||
#: js/ui/appDisplay.js:2484
|
||||
msgid "Add to Favorites"
|
||||
msgstr "Zonte tai preferîts"
|
||||
|
||||
#: js/ui/appDisplay.js:2473 js/ui/panel.js:94
|
||||
#: js/ui/appDisplay.js:2494 js/ui/panel.js:94
|
||||
msgid "Show Details"
|
||||
msgstr "Mostre Detais"
|
||||
|
||||
@ -1017,34 +1017,34 @@ msgid "Connect"
|
||||
msgstr "Conet"
|
||||
|
||||
#. Cisco LEAP
|
||||
#: js/ui/components/networkAgent.js:216 js/ui/components/networkAgent.js:228
|
||||
#: js/ui/components/networkAgent.js:250 js/ui/components/networkAgent.js:269
|
||||
#: js/ui/components/networkAgent.js:289 js/ui/components/networkAgent.js:299
|
||||
#: js/ui/components/networkAgent.js:217 js/ui/components/networkAgent.js:229
|
||||
#: js/ui/components/networkAgent.js:251 js/ui/components/networkAgent.js:270
|
||||
#: js/ui/components/networkAgent.js:290 js/ui/components/networkAgent.js:300
|
||||
msgid "Password: "
|
||||
msgstr "Password: "
|
||||
|
||||
#. static WEP
|
||||
#: js/ui/components/networkAgent.js:221
|
||||
#: js/ui/components/networkAgent.js:222
|
||||
msgid "Key: "
|
||||
msgstr "Clâf: "
|
||||
|
||||
#: js/ui/components/networkAgent.js:253 js/ui/components/networkAgent.js:275
|
||||
#: js/ui/components/networkAgent.js:254 js/ui/components/networkAgent.js:276
|
||||
msgid "Private key password: "
|
||||
msgstr "Password di clâf privade: "
|
||||
|
||||
#: js/ui/components/networkAgent.js:273
|
||||
#: js/ui/components/networkAgent.js:274
|
||||
msgid "Identity: "
|
||||
msgstr "Identitât: "
|
||||
|
||||
#: js/ui/components/networkAgent.js:287
|
||||
#: js/ui/components/networkAgent.js:288
|
||||
msgid "Service: "
|
||||
msgstr "Servizi: "
|
||||
|
||||
#: js/ui/components/networkAgent.js:316 js/ui/components/networkAgent.js:691
|
||||
#: js/ui/components/networkAgent.js:317 js/ui/components/networkAgent.js:692
|
||||
msgid "Authentication required by wireless network"
|
||||
msgstr "La rêt cence fîl e domande autenticazion"
|
||||
|
||||
#: js/ui/components/networkAgent.js:317 js/ui/components/networkAgent.js:692
|
||||
#: js/ui/components/networkAgent.js:318 js/ui/components/networkAgent.js:693
|
||||
#, javascript-format
|
||||
msgid ""
|
||||
"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 "
|
||||
"fîl \"%s\"."
|
||||
|
||||
#: js/ui/components/networkAgent.js:321 js/ui/components/networkAgent.js:696
|
||||
#: js/ui/components/networkAgent.js:322 js/ui/components/networkAgent.js:697
|
||||
msgid "Wired 802.1X authentication"
|
||||
msgstr "Autenticazion vie fîl 802.1X"
|
||||
|
||||
#: js/ui/components/networkAgent.js:323
|
||||
#: js/ui/components/networkAgent.js:324
|
||||
msgid "Network name: "
|
||||
msgstr "Non rêt: "
|
||||
|
||||
#: js/ui/components/networkAgent.js:328 js/ui/components/networkAgent.js:700
|
||||
#: js/ui/components/networkAgent.js:329 js/ui/components/networkAgent.js:701
|
||||
msgid "DSL authentication"
|
||||
msgstr "Autenticazion DSL"
|
||||
|
||||
#: js/ui/components/networkAgent.js:335 js/ui/components/networkAgent.js:705
|
||||
#: js/ui/components/networkAgent.js:336 js/ui/components/networkAgent.js:706
|
||||
msgid "PIN code required"
|
||||
msgstr "Si pretint un codiç PIN"
|
||||
|
||||
#: js/ui/components/networkAgent.js:336 js/ui/components/networkAgent.js:706
|
||||
#: js/ui/components/networkAgent.js:337 js/ui/components/networkAgent.js:707
|
||||
msgid "PIN code is needed for the mobile broadband device"
|
||||
msgstr "Si scugne meti un codiç PIN pal dispositîf a bande largje mobil"
|
||||
|
||||
#: js/ui/components/networkAgent.js:337
|
||||
#: js/ui/components/networkAgent.js:338
|
||||
msgid "PIN: "
|
||||
msgstr "PIN: "
|
||||
|
||||
#: js/ui/components/networkAgent.js:344 js/ui/components/networkAgent.js:712
|
||||
#: js/ui/components/networkAgent.js:345 js/ui/components/networkAgent.js:713
|
||||
msgid "Mobile broadband network password"
|
||||
msgstr "Passowrd rêt mobil a bande largje"
|
||||
|
||||
#: js/ui/components/networkAgent.js:345 js/ui/components/networkAgent.js:697
|
||||
#: js/ui/components/networkAgent.js:701 js/ui/components/networkAgent.js:713
|
||||
#: js/ui/components/networkAgent.js:346 js/ui/components/networkAgent.js:698
|
||||
#: js/ui/components/networkAgent.js:702 js/ui/components/networkAgent.js:714
|
||||
#, javascript-format
|
||||
msgid "A password is required to connect to “%s”."
|
||||
msgstr "A covente une password par tacâsi a '%s'."
|
||||
|
||||
#: js/ui/components/networkAgent.js:680 js/ui/status/network.js:1675
|
||||
#: js/ui/components/networkAgent.js:681 js/ui/status/network.js:1675
|
||||
msgid "Network Manager"
|
||||
msgstr "Ministradôr di rêt"
|
||||
|
||||
@ -1475,6 +1475,26 @@ msgstr "Viôt sorzint"
|
||||
msgid "Web Page"
|
||||
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
|
||||
msgid "System Information"
|
||||
msgstr "Informazion di sisteme"
|
||||
@ -2219,11 +2239,11 @@ msgstr "Dome esterni"
|
||||
msgid "Built-in Only"
|
||||
msgstr "Dome incorporât"
|
||||
|
||||
#: js/ui/unlockDialog.js:50
|
||||
#: js/ui/unlockDialog.js:53
|
||||
msgid "Log in as another user"
|
||||
msgstr "Jentre come altri utent"
|
||||
|
||||
#: js/ui/unlockDialog.js:67
|
||||
#: js/ui/unlockDialog.js:70
|
||||
msgid "Unlock Window"
|
||||
msgstr "Sbloche barcon"
|
||||
|
||||
@ -2266,7 +2286,7 @@ msgstr[1] ""
|
||||
|
||||
#. Translators: This represents the size of a window. The first number is
|
||||
#. * the width of the window and the second is the height.
|
||||
#: js/ui/windowManager.js:683
|
||||
#: js/ui/windowManager.js:686
|
||||
#, javascript-format
|
||||
msgid "%d × %d"
|
||||
msgstr "%d × %d"
|
||||
@ -2350,7 +2370,7 @@ msgstr ""
|
||||
|
||||
#: src/extensions-tool/command-create.c:192 src/extensions-tool/main.c:169
|
||||
msgid "Name"
|
||||
msgstr "Non "
|
||||
msgstr "Non"
|
||||
|
||||
#: src/extensions-tool/command-create.c:203
|
||||
#, c-format
|
||||
@ -2604,7 +2624,7 @@ msgstr "Comants:"
|
||||
msgid "Print help"
|
||||
msgstr "Stampe jutori"
|
||||
|
||||
#: src/extensions-tool/main.c:248 src/main.c:468
|
||||
#: src/extensions-tool/main.c:248 src/main.c:460
|
||||
msgid "Print version"
|
||||
msgstr "Stampe version"
|
||||
|
||||
@ -2653,15 +2673,15 @@ msgstr "Instale complès di estensions"
|
||||
msgid "Use “%s” to get detailed help.\n"
|
||||
msgstr "Dopre “%s” par vê un jutori detaiât.\n"
|
||||
|
||||
#: src/main.c:474
|
||||
#: src/main.c:466
|
||||
msgid "Mode used by GDM for login screen"
|
||||
msgstr "Modalitât doprade da GDM pe videade di acès"
|
||||
|
||||
#: src/main.c:480
|
||||
#: src/main.c:472
|
||||
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"
|
||||
|
||||
#: src/main.c:486
|
||||
#: src/main.c:478
|
||||
msgid "List possible modes"
|
||||
msgstr "Liste modalitâts pussibilis"
|
||||
|
||||
|
@ -509,7 +509,7 @@ shell_app_activate_full (ShellApp *app,
|
||||
case SHELL_APP_STATE_STOPPED:
|
||||
{
|
||||
GError *error = NULL;
|
||||
if (!shell_app_launch (app, timestamp, workspace, FALSE, &error))
|
||||
if (!shell_app_launch (app, timestamp, workspace, SHELL_APP_GPU_SELECTION_AUTO, &error))
|
||||
{
|
||||
char *msg;
|
||||
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
|
||||
* as say Pidgin.
|
||||
*/
|
||||
shell_app_launch (app, 0, workspace, FALSE, NULL);
|
||||
shell_app_launch (app, 0, workspace, SHELL_APP_GPU_SELECTION_AUTO, NULL);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1255,19 +1255,37 @@ wait_pid (GDesktopAppInfo *appinfo,
|
||||
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:
|
||||
* @timestamp: Event timestamp, or 0 for current event timestamp
|
||||
* @workspace: Start on this workspace, or -1 for default
|
||||
* @discrete_gpu: Whether to start on the discrete GPU
|
||||
* @discrete_gpu: the preferred GPU to launch the application on.
|
||||
* @error: A #GError
|
||||
*/
|
||||
gboolean
|
||||
shell_app_launch (ShellApp *app,
|
||||
guint timestamp,
|
||||
int workspace,
|
||||
gboolean discrete_gpu,
|
||||
GError **error)
|
||||
shell_app_launch (ShellApp *app,
|
||||
guint timestamp,
|
||||
int workspace,
|
||||
ShellAppGpuSelection discrete_gpu,
|
||||
GError **error)
|
||||
{
|
||||
ShellGlobal *global;
|
||||
GAppLaunchContext *context;
|
||||
@ -1289,8 +1307,13 @@ shell_app_launch (ShellApp *app,
|
||||
|
||||
global = shell_global_get ();
|
||||
context = shell_global_create_app_launch_context (global, timestamp, workspace);
|
||||
if (discrete_gpu)
|
||||
g_app_launch_context_setenv (context, "DRI_PRIME", "1");
|
||||
/* FIXME: this should probably check whether we're on a dual-GPU system */
|
||||
if (get_with_discrete_gpu (app, discrete_gpu))
|
||||
{
|
||||
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
|
||||
* codepath. The shell's open file descriptors should be marked CLOEXEC
|
||||
|
@ -18,6 +18,12 @@ typedef enum {
|
||||
SHELL_APP_STATE_RUNNING
|
||||
} 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);
|
||||
|
||||
GDesktopAppInfo *shell_app_get_app_info (ShellApp *app);
|
||||
@ -51,11 +57,11 @@ GSList *shell_app_get_pids (ShellApp *app);
|
||||
|
||||
gboolean shell_app_is_on_workspace (ShellApp *app, MetaWorkspace *workspace);
|
||||
|
||||
gboolean shell_app_launch (ShellApp *app,
|
||||
guint timestamp,
|
||||
int workspace,
|
||||
gboolean discrete_gpu,
|
||||
GError **error);
|
||||
gboolean shell_app_launch (ShellApp *app,
|
||||
guint timestamp,
|
||||
int workspace,
|
||||
ShellAppGpuSelection discrete_gpu,
|
||||
GError **error);
|
||||
|
||||
void shell_app_launch_action (ShellApp *app,
|
||||
const char *action_name,
|
||||
|
@ -457,7 +457,6 @@ grab_window_screenshot (ClutterActor *stage,
|
||||
ClutterActor *window_actor;
|
||||
gfloat actor_x, actor_y;
|
||||
MetaRectangle rect;
|
||||
cairo_rectangle_int_t clip;
|
||||
|
||||
window_actor = CLUTTER_ACTOR (meta_window_get_compositor_private (window));
|
||||
clutter_actor_get_position (window_actor, &actor_x, &actor_y);
|
||||
@ -467,16 +466,10 @@ grab_window_screenshot (ClutterActor *stage,
|
||||
if (!priv->include_frame)
|
||||
meta_window_frame_rect_to_client_rect (window, &rect, &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->screenshot_area = rect;
|
||||
|
||||
priv->image = meta_window_actor_get_image (META_WINDOW_ACTOR (window_actor),
|
||||
&clip);
|
||||
NULL);
|
||||
priv->datetime = g_date_time_new_now_local ();
|
||||
|
||||
if (priv->include_cursor)
|
||||
|
@ -35,8 +35,7 @@
|
||||
#endif
|
||||
|
||||
static void
|
||||
stop_pick (ClutterActor *actor,
|
||||
const ClutterColor *color)
|
||||
stop_pick (ClutterActor *actor)
|
||||
{
|
||||
g_signal_stop_emission_by_name (actor, "pick");
|
||||
}
|
||||
@ -97,7 +96,7 @@ shell_util_get_transformed_allocation (ClutterActor *actor,
|
||||
/* Code adapted from clutter-actor.c:
|
||||
* Copyright 2006, 2007, 2008 OpenedHand Ltd
|
||||
*/
|
||||
ClutterVertex v[4];
|
||||
graphene_point3d_t v[4];
|
||||
gfloat x_min, x_max, y_min, y_max;
|
||||
guint i;
|
||||
|
||||
|
@ -443,8 +443,7 @@ st_box_layout_paint (ClutterActor *actor)
|
||||
}
|
||||
|
||||
static void
|
||||
st_box_layout_pick (ClutterActor *actor,
|
||||
const ClutterColor *color)
|
||||
st_box_layout_pick (ClutterActor *actor)
|
||||
{
|
||||
StBoxLayout *self = ST_BOX_LAYOUT (actor);
|
||||
StBoxLayoutPrivate *priv = self->priv;
|
||||
@ -462,7 +461,7 @@ st_box_layout_pick (ClutterActor *actor,
|
||||
cogl_framebuffer_translate (fb, (int)x, (int)y, 0);
|
||||
}
|
||||
|
||||
CLUTTER_ACTOR_CLASS (st_box_layout_parent_class)->pick (actor, color);
|
||||
CLUTTER_ACTOR_CLASS (st_box_layout_parent_class)->pick (actor);
|
||||
|
||||
if (x != 0 || y != 0)
|
||||
{
|
||||
@ -490,7 +489,7 @@ st_box_layout_pick (ClutterActor *actor,
|
||||
for (child = clutter_actor_get_first_child (actor);
|
||||
child != NULL;
|
||||
child = clutter_actor_get_next_sibling (child))
|
||||
clutter_actor_paint (child);
|
||||
clutter_actor_pick (child);
|
||||
|
||||
if (priv->hadjustment || priv->vadjustment)
|
||||
cogl_framebuffer_pop_clip (fb);
|
||||
@ -506,7 +505,7 @@ st_box_layout_get_paint_volume (ClutterActor *actor,
|
||||
StThemeNode *theme_node = st_widget_get_theme_node (ST_WIDGET (actor));
|
||||
ClutterActorBox allocation_box;
|
||||
ClutterActorBox content_box;
|
||||
ClutterVertex origin;
|
||||
graphene_point3d_t origin;
|
||||
|
||||
/* Setting the paint volume does not make sense when we don't have any allocation */
|
||||
if (!clutter_actor_has_allocation (actor))
|
||||
|
@ -40,7 +40,7 @@ struct _StButtonClass
|
||||
void (* transition) (StButton *button);
|
||||
|
||||
/* signals */
|
||||
void (* clicked) (StButton *button);
|
||||
void (* clicked) (StButton *button, int clicked_button);
|
||||
};
|
||||
|
||||
StWidget *st_button_new (void);
|
||||
|
@ -48,19 +48,19 @@ static GParamSpec *props[N_PROPS] = { NULL, };
|
||||
|
||||
struct _StIconPrivate
|
||||
{
|
||||
ClutterActor *icon_texture;
|
||||
ClutterActor *pending_texture;
|
||||
guint opacity_handler_id;
|
||||
ClutterActor *icon_texture;
|
||||
ClutterActor *pending_texture;
|
||||
guint opacity_handler_id;
|
||||
|
||||
GIcon *gicon;
|
||||
gint prop_icon_size; /* icon size set as property */
|
||||
gint theme_icon_size; /* icon size from theme node */
|
||||
gint icon_size; /* icon size we are using */
|
||||
GIcon *fallback_gicon;
|
||||
GIcon *gicon;
|
||||
gint prop_icon_size; /* icon size set as property */
|
||||
gint theme_icon_size; /* icon size from theme node */
|
||||
gint icon_size; /* icon size we are using */
|
||||
GIcon *fallback_gicon;
|
||||
|
||||
CoglPipeline *shadow_pipeline;
|
||||
StShadow *shadow_spec;
|
||||
ClutterSize shadow_size;
|
||||
CoglPipeline *shadow_pipeline;
|
||||
StShadow *shadow_spec;
|
||||
graphene_size_t shadow_size;
|
||||
};
|
||||
|
||||
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;
|
||||
|
||||
g_clear_pointer (&priv->shadow_pipeline, cogl_object_unref);
|
||||
clutter_size_init (&priv->shadow_size, 0, 0);
|
||||
graphene_size_init (&priv->shadow_size, 0, 0);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -317,7 +317,7 @@ st_icon_update_shadow_pipeline (StIcon *icon)
|
||||
priv->icon_texture);
|
||||
|
||||
if (priv->shadow_pipeline)
|
||||
clutter_size_init (&priv->shadow_size, width, height);
|
||||
graphene_size_init (&priv->shadow_size, width, height);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -100,7 +100,7 @@ st_scroll_view_fade_paint_target (ClutterOffscreenEffect *effect)
|
||||
|
||||
float fade_area_topleft[2];
|
||||
float fade_area_bottomright[2];
|
||||
ClutterVertex verts[4];
|
||||
graphene_point3d_t verts[4];
|
||||
|
||||
clutter_actor_get_paint_box (self->actor, &paint_box);
|
||||
clutter_actor_get_abs_allocation_vertices (self->actor, verts);
|
||||
|
@ -294,20 +294,19 @@ st_scroll_view_paint (ClutterActor *actor)
|
||||
}
|
||||
|
||||
static void
|
||||
st_scroll_view_pick (ClutterActor *actor,
|
||||
const ClutterColor *color)
|
||||
st_scroll_view_pick (ClutterActor *actor)
|
||||
{
|
||||
StScrollViewPrivate *priv = ST_SCROLL_VIEW (actor)->priv;
|
||||
|
||||
/* Chain up so we get a bounding box pained (if we are reactive) */
|
||||
CLUTTER_ACTOR_CLASS (st_scroll_view_parent_class)->pick (actor, color);
|
||||
CLUTTER_ACTOR_CLASS (st_scroll_view_parent_class)->pick (actor);
|
||||
|
||||
if (priv->child)
|
||||
clutter_actor_paint (priv->child);
|
||||
clutter_actor_pick (priv->child);
|
||||
if (priv->hscrollbar_visible)
|
||||
clutter_actor_paint (priv->hscroll);
|
||||
clutter_actor_pick (priv->hscroll);
|
||||
if (priv->vscrollbar_visible)
|
||||
clutter_actor_paint (priv->vscroll);
|
||||
clutter_actor_pick (priv->vscroll);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
@ -963,23 +962,6 @@ 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
|
||||
clutter_container_iface_init (ClutterContainerIface *iface)
|
||||
{
|
||||
@ -991,7 +973,6 @@ clutter_container_iface_init (ClutterContainerIface *iface)
|
||||
|
||||
iface->add = st_scroll_view_add;
|
||||
iface->remove = st_scroll_view_remove;
|
||||
iface->foreach_with_internals = st_scroll_view_foreach_with_internals;
|
||||
}
|
||||
|
||||
StWidget *
|
||||
|
@ -762,7 +762,7 @@ st_widget_get_paint_volume (ClutterActor *self,
|
||||
ClutterActorBox paint_box, alloc_box;
|
||||
StThemeNode *theme_node;
|
||||
StWidgetPrivate *priv;
|
||||
ClutterVertex origin;
|
||||
graphene_point3d_t origin;
|
||||
|
||||
/* Setting the paint volume does not make sense when we don't have any allocation */
|
||||
if (!clutter_actor_has_allocation (self))
|
||||
@ -2062,7 +2062,7 @@ filter_by_position (GList *children,
|
||||
StDirectionType direction)
|
||||
{
|
||||
ClutterActorBox cbox;
|
||||
ClutterVertex abs_vertices[4];
|
||||
graphene_point3d_t abs_vertices[4];
|
||||
GList *l, *ret;
|
||||
ClutterActor *child;
|
||||
|
||||
@ -2128,7 +2128,7 @@ get_distance (ClutterActor *actor,
|
||||
{
|
||||
int ax, ay, bx, by, dx, dy;
|
||||
ClutterActorBox abox;
|
||||
ClutterVertex abs_vertices[4];
|
||||
graphene_point3d_t abs_vertices[4];
|
||||
|
||||
clutter_actor_get_abs_allocation_vertices (actor, 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 */
|
||||
{
|
||||
ClutterActorBox sort_box;
|
||||
ClutterVertex abs_vertices[4];
|
||||
graphene_point3d_t abs_vertices[4];
|
||||
|
||||
/* Compute the allocation box of the previous focused actor. If there
|
||||
* was no previous focus, use the coordinates of the appropriate edge of
|
||||
|
@ -36,16 +36,16 @@ function test() {
|
||||
obin.connect_after('paint', actor => {
|
||||
Cogl.set_source_color4f(0, 1, 0, 1);
|
||||
|
||||
let geom = actor.get_allocation_geometry();
|
||||
let alloc = actor.get_allocation_box();
|
||||
let width = 3;
|
||||
|
||||
// clockwise order
|
||||
Cogl.rectangle(0, 0, geom.width, width);
|
||||
Cogl.rectangle(geom.width - width, width,
|
||||
geom.width, geom.height);
|
||||
Cogl.rectangle(0, geom.height,
|
||||
geom.width - width, geom.height - width);
|
||||
Cogl.rectangle(0, geom.height - width,
|
||||
Cogl.rectangle(0, 0, alloc.get_width(), width);
|
||||
Cogl.rectangle(alloc.get_width() - width, width,
|
||||
alloc.get_width(), alloc.get_height());
|
||||
Cogl.rectangle(0, alloc.get_height(),
|
||||
alloc.get_width() - width, alloc.get_height() - width);
|
||||
Cogl.rectangle(0, alloc.get_height() - width,
|
||||
width, width);
|
||||
});
|
||||
tbox.add(obin);
|
||||
|
@ -17,7 +17,7 @@ function test() {
|
||||
// Calendar can only be imported after Environment.init()
|
||||
const Calendar = imports.ui.calendar;
|
||||
let calendar = new Calendar.Calendar();
|
||||
vbox.add(calendar.actor,
|
||||
vbox.add(calendar,
|
||||
{ expand: true,
|
||||
x_fill: false, x_align: St.Align.MIDDLE,
|
||||
y_fill: false, y_align: St.Align.START });
|
||||
|
Reference in New Issue
Block a user