Compare commits
62 Commits
3.30.2
...
wip/jimmac
Author | SHA1 | Date | |
---|---|---|---|
19dcfa6912 | |||
361cc6cf92 | |||
5fb8d4f730 | |||
a98ed08a54 | |||
80a7547129 | |||
ca3f4cfb41 | |||
551e827841 | |||
4dc2039859 | |||
f1195ecb01 | |||
127ba318fd | |||
72fa44d0fd | |||
b96cc9a161 | |||
5f2c167947 | |||
86a78c340f | |||
1acdff822a | |||
a5e6dd52d2 | |||
14953041cc | |||
4e422a527f | |||
c0b561dd4a | |||
0f542c2e16 | |||
cff9eaf5aa | |||
468117583a | |||
7026a6fd32 | |||
ceed3e07e4 | |||
a0dc8dc7ef | |||
b405ed6442 | |||
8566ec2ee5 | |||
ae7dd5e2db | |||
9f3c85fdc8 | |||
aa685310bb | |||
76117fd306 | |||
8855622666 | |||
655234e6c3 | |||
38c1ebba62 | |||
557b232c89 | |||
b719744e75 | |||
038f8b6ea5 | |||
2ee321e0d8 | |||
b4c674900f | |||
3fa19e58ac | |||
f460f2748d | |||
8b215b2446 | |||
0c0d76f7d6 | |||
dd225713a1 | |||
f4682748fa | |||
b058e89166 | |||
ac314cfb05 | |||
fc342fe8c5 | |||
dd4709bb27 | |||
e9f4f2e8ae | |||
197c0eee29 | |||
034a723677 | |||
efb3025d8c | |||
81ec8215a0 | |||
4be66ecf01 | |||
2717ca9d08 | |||
c6cea277eb | |||
9a47b4b343 | |||
0ec36fc5cf | |||
a315e75e95 | |||
e82c68accd | |||
286ffbe2b6 |
14
HACKING.md
14
HACKING.md
@ -10,15 +10,15 @@ Life isn't fun if you can't break the rules. If a rule seems unnecessarily
|
||||
restrictive while you're coding, ignore it, and let the patch reviewer decide
|
||||
what to do.
|
||||
|
||||
## Indentation and whitespace
|
||||
## Indentation, braces and whitespace
|
||||
|
||||
Use four-space indents. Braces are on the same line as their associated
|
||||
statements. You should only omit braces if *both* sides of the statement are
|
||||
on one line.
|
||||
* Use four-space indents.
|
||||
* Braces are on the same line as their associated statements.
|
||||
* You should only omit braces if *both* sides of the statement are on one line.
|
||||
* One space after the `function` keyword.
|
||||
* No space between the function name in a declaration or a call.
|
||||
* One space before the parens in the `if` statements, or `while`, or `for` loops.
|
||||
|
||||
* One space after the `function` keyword. No space between the function name
|
||||
* in a declaration or a call. One space before the parens in the `if`
|
||||
* statements, or `while`, or `for` loops.
|
||||
```javascript
|
||||
function foo(a, b) {
|
||||
let bar;
|
||||
|
21
NEWS
21
NEWS
@ -1,24 +1,3 @@
|
||||
3.30.2
|
||||
======
|
||||
* popupMenu: Fix keyboard activation when numlock is active [Andrea; #550]
|
||||
* Do not block all shortcuts while app folders are expanded [Florian; #648]
|
||||
* Fix regression in handling new input sources [Carlos; #691]
|
||||
* Improve performance of app icon animations [Daniel; !253, !261]
|
||||
* Respect natural-scroll setting for workspace swipe gesture [Erik; #516]
|
||||
* notifications: Support icon theme names in 'image-path' hint [Marco; !285]
|
||||
* Confine window preview titles to workspace area [Florian; !214]
|
||||
* Misc. bug fixes [Florian, Cosimo; #602, #693, #768, #430, !286]
|
||||
|
||||
Contributors:
|
||||
Andrea Azzarone, Cosimo Cecchi, Erik Duxstad, Carlos Garnacho,
|
||||
Florian Müllner, Didier Roche, Marco Trevisan (Treviño), verdre,
|
||||
Daniel van Vugt
|
||||
|
||||
Translators:
|
||||
Rūdolfs Mazurs [lv], Kristjan SCHMIDT [eo], Milo Casagrande [it],
|
||||
Dušan Kazik [sk], gogo [hr], Anish Sheela [ml], Rafael Fontenelle [pt_BR],
|
||||
Daniel Mustieles [es]
|
||||
|
||||
3.30.1
|
||||
======
|
||||
* Cancel search on overview hiding [Marco; !205]
|
||||
|
@ -57,8 +57,8 @@ stage {
|
||||
border-right-width: 1px;
|
||||
@include button(normal);
|
||||
&:insensitive { @include button(insensitive); }
|
||||
&:focus { @include button(focus); }
|
||||
&:hover { @include button(hover); }
|
||||
&:focus { @include button(focus); }
|
||||
&:active { @include button(active); }
|
||||
padding: 12px;
|
||||
|
||||
@ -1287,7 +1287,7 @@ StScrollBar {
|
||||
}
|
||||
.list-search-results { spacing: 3px; }
|
||||
|
||||
.search-section-separator { height: 2px; background-color: rgba(255, 255, 255, 0.2); }
|
||||
.search-section-separator { margin-top: 16px; height: 2px; background-color: rgba(255, 255, 255, 0.2); }
|
||||
|
||||
.list-search-result-content { spacing: 30px; }
|
||||
.list-search-result-title { color: darken($osd_fg_color,5%); spacing: 12px; }
|
||||
@ -1344,7 +1344,7 @@ StScrollBar {
|
||||
-shell-grid-horizontal-item-size: 136px;
|
||||
-shell-grid-vertical-item-size: 136px;
|
||||
|
||||
.overview-icon { icon-size: 96px; }
|
||||
.overview-icon { icon-size: 128px; }
|
||||
}
|
||||
//.app-display { spacing: 20px; }
|
||||
|
||||
|
@ -17,7 +17,6 @@
|
||||
|
||||
<chapter>
|
||||
<title>Actors</title>
|
||||
<xi:include href="xml/shell-generic-container.xml"/>
|
||||
<xi:include href="xml/shell-stack.xml"/>
|
||||
</chapter>
|
||||
<chapter>
|
||||
|
@ -408,16 +408,18 @@ Signals.addSignalMethods(SessionMenuButton.prototype);
|
||||
|
||||
var LoginDialog = new Lang.Class({
|
||||
Name: 'LoginDialog',
|
||||
Extends: St.Widget,
|
||||
Signals: { 'failed': {} },
|
||||
|
||||
_init(parentActor) {
|
||||
this.actor = new Shell.GenericContainer({ style_class: 'login-dialog',
|
||||
visible: false });
|
||||
this.actor.get_accessible().set_role(Atk.Role.WINDOW);
|
||||
this.parent({ style_class: 'login-dialog',
|
||||
visible: false });
|
||||
|
||||
this.actor.add_constraint(new Layout.MonitorConstraint({ primary: true }));
|
||||
this.actor.connect('allocate', this._onAllocate.bind(this));
|
||||
this.actor.connect('destroy', this._onDestroy.bind(this));
|
||||
parentActor.add_child(this.actor);
|
||||
this.get_accessible().set_role(Atk.Role.WINDOW);
|
||||
|
||||
this.add_constraint(new Layout.MonitorConstraint({ primary: true }));
|
||||
this.connect('destroy', this._onDestroy.bind(this));
|
||||
parentActor.add_child(this);
|
||||
|
||||
this._userManager = AccountsService.UserManager.get_default()
|
||||
this._gdmClient = new Gdm.Client();
|
||||
@ -442,7 +444,7 @@ var LoginDialog = new Lang.Class({
|
||||
y_align: Clutter.ActorAlign.CENTER,
|
||||
vertical: true,
|
||||
visible: false });
|
||||
this.actor.add_child(this._userSelectionBox);
|
||||
this.add_child(this._userSelectionBox);
|
||||
|
||||
this._userList = new UserList();
|
||||
this._userSelectionBox.add(this._userList.actor,
|
||||
@ -454,7 +456,7 @@ var LoginDialog = new Lang.Class({
|
||||
this._authPrompt.connect('prompted', this._onPrompted.bind(this));
|
||||
this._authPrompt.connect('reset', this._onReset.bind(this));
|
||||
this._authPrompt.hide();
|
||||
this.actor.add_child(this._authPrompt.actor);
|
||||
this.add_child(this._authPrompt.actor);
|
||||
|
||||
// translators: this message is shown below the user list on the
|
||||
// login screen. It can be activated to reveal an entry for
|
||||
@ -482,7 +484,7 @@ var LoginDialog = new Lang.Class({
|
||||
opacity: 0,
|
||||
vscrollbar_policy: Gtk.PolicyType.AUTOMATIC,
|
||||
hscrollbar_policy: Gtk.PolicyType.NEVER });
|
||||
this.actor.add_child(this._bannerView);
|
||||
this.add_child(this._bannerView);
|
||||
|
||||
let bannerBox = new St.BoxLayout({ vertical: true });
|
||||
|
||||
@ -497,7 +499,7 @@ var LoginDialog = new Lang.Class({
|
||||
this._logoBin = new St.Widget({ style_class: 'login-dialog-logo-bin',
|
||||
x_align: Clutter.ActorAlign.CENTER,
|
||||
y_align: Clutter.ActorAlign.END });
|
||||
this.actor.add_child(this._logoBin);
|
||||
this.add_child(this._logoBin);
|
||||
this._updateLogo();
|
||||
|
||||
this._userList.connect('activate', (userList, item) => {
|
||||
@ -576,7 +578,12 @@ var LoginDialog = new Lang.Class({
|
||||
return actorBox;
|
||||
},
|
||||
|
||||
_onAllocate(actor, dialogBox, flags) {
|
||||
vfunc_allocate(dialogBox, flags) {
|
||||
this.set_allocation(dialogBox, flags);
|
||||
|
||||
let themeNode = this.get_theme_node();
|
||||
dialogBox = themeNode.get_content_box(dialogBox);
|
||||
|
||||
let dialogWidth = dialogBox.x2 - dialogBox.x1;
|
||||
let dialogHeight = dialogBox.y2 - dialogBox.y1;
|
||||
|
||||
@ -919,10 +926,10 @@ var LoginDialog = new Lang.Class({
|
||||
},
|
||||
|
||||
_loginScreenSessionActivated() {
|
||||
if (this.actor.opacity == 255 && this._authPrompt.verificationStatus == AuthPrompt.AuthPromptStatus.NOT_VERIFYING)
|
||||
if (this.opacity == 255 && this._authPrompt.verificationStatus == AuthPrompt.AuthPromptStatus.NOT_VERIFYING)
|
||||
return;
|
||||
|
||||
Tweener.addTween(this.actor,
|
||||
Tweener.addTween(this,
|
||||
{ opacity: 255,
|
||||
time: _FADE_ANIMATION_TIME,
|
||||
transition: 'easeOutQuad',
|
||||
@ -931,7 +938,7 @@ var LoginDialog = new Lang.Class({
|
||||
|
||||
for (let i = 0; i < children.length; i++) {
|
||||
if (children[i] != Main.layoutManager.screenShieldGroup)
|
||||
children[i].opacity = this.actor.opacity;
|
||||
children[i].opacity = this.opacity;
|
||||
}
|
||||
},
|
||||
onUpdateScope: this,
|
||||
@ -952,7 +959,7 @@ var LoginDialog = new Lang.Class({
|
||||
},
|
||||
|
||||
_startSession(serviceName) {
|
||||
Tweener.addTween(this.actor,
|
||||
Tweener.addTween(this,
|
||||
{ opacity: 0,
|
||||
time: _FADE_ANIMATION_TIME,
|
||||
transition: 'easeOutQuad',
|
||||
@ -961,7 +968,7 @@ var LoginDialog = new Lang.Class({
|
||||
|
||||
for (let i = 0; i < children.length; i++) {
|
||||
if (children[i] != Main.layoutManager.screenShieldGroup)
|
||||
children[i].opacity = this.actor.opacity;
|
||||
children[i].opacity = this.opacity;
|
||||
}
|
||||
},
|
||||
onUpdateScope: this,
|
||||
@ -1230,17 +1237,17 @@ var LoginDialog = new Lang.Class({
|
||||
},
|
||||
|
||||
open() {
|
||||
Main.ctrlAltTabManager.addGroup(this.actor,
|
||||
Main.ctrlAltTabManager.addGroup(this,
|
||||
_("Login Window"),
|
||||
'dialog-password-symbolic',
|
||||
{ sortGroup: CtrlAltTab.SortGroup.MIDDLE });
|
||||
this._userList.actor.grab_key_focus();
|
||||
this.actor.show();
|
||||
this.actor.opacity = 0;
|
||||
this.show();
|
||||
this.opacity = 0;
|
||||
|
||||
Main.pushModal(this.actor, { actionMode: Shell.ActionMode.LOGIN_SCREEN });
|
||||
Main.pushModal(this, { actionMode: Shell.ActionMode.LOGIN_SCREEN });
|
||||
|
||||
Tweener.addTween(this.actor,
|
||||
Tweener.addTween(this,
|
||||
{ opacity: 255,
|
||||
time: 1,
|
||||
transition: 'easeInQuad' });
|
||||
@ -1249,8 +1256,8 @@ var LoginDialog = new Lang.Class({
|
||||
},
|
||||
|
||||
close() {
|
||||
Main.popModal(this.actor);
|
||||
Main.ctrlAltTabManager.removeGroup(this.actor);
|
||||
Main.popModal(this);
|
||||
Main.ctrlAltTabManager.removeGroup(this);
|
||||
},
|
||||
|
||||
cancel() {
|
||||
@ -1265,4 +1272,3 @@ var LoginDialog = new Lang.Class({
|
||||
this._authPrompt.finish(onComplete);
|
||||
},
|
||||
});
|
||||
Signals.addSignalMethods(LoginDialog.prototype);
|
||||
|
@ -243,13 +243,13 @@ function formatTime(time, params) {
|
||||
followed by a time string in 24h format.
|
||||
i.e. "May 25, 14:30" */
|
||||
// xgettext:no-c-format
|
||||
format = N_("%B %d, %H\u2236%M");
|
||||
format = N_("%B %-d, %H\u2236%M");
|
||||
else
|
||||
/* Translators: this is the month name, day number, year
|
||||
number followed by a time string in 24h format.
|
||||
i.e. "May 25 2012, 14:30" */
|
||||
// xgettext:no-c-format
|
||||
format = N_("%B %d %Y, %H\u2236%M");
|
||||
format = N_("%B %-d %Y, %H\u2236%M");
|
||||
} else {
|
||||
// Show only the time if date is on today
|
||||
if (daysAgo < 1 || params.timeOnly)
|
||||
@ -272,13 +272,13 @@ function formatTime(time, params) {
|
||||
followed by a time string in 12h format.
|
||||
i.e. "May 25, 2:30 pm" */
|
||||
// xgettext:no-c-format
|
||||
format = N_("%B %d, %l\u2236%M %p");
|
||||
format = N_("%B %-d, %l\u2236%M %p");
|
||||
else
|
||||
/* Translators: this is the month name, day number, year
|
||||
number followed by a time string in 12h format.
|
||||
i.e. "May 25 2012, 2:30 pm"*/
|
||||
// xgettext:no-c-format
|
||||
format = N_("%B %d %Y, %l\u2236%M %p");
|
||||
format = N_("%B %-d %Y, %l\u2236%M %p");
|
||||
}
|
||||
|
||||
let formattedTime = date.format(Shell.util_translate_time_string(format));
|
||||
|
183
js/ui/altTab.js
183
js/ui/altTab.js
@ -3,6 +3,7 @@
|
||||
const Clutter = imports.gi.Clutter;
|
||||
const Gio = imports.gi.Gio;
|
||||
const GLib = imports.gi.GLib;
|
||||
const GObject = imports.gi.GObject;
|
||||
const Lang = imports.lang;
|
||||
const Mainloop = imports.mainloop;
|
||||
const Meta = imports.gi.Meta;
|
||||
@ -21,10 +22,10 @@ var THUMBNAIL_POPUP_TIME = 500; // milliseconds
|
||||
var THUMBNAIL_FADE_TIME = 0.1; // seconds
|
||||
|
||||
var WINDOW_PREVIEW_SIZE = 128;
|
||||
var APP_ICON_SIZE = 96;
|
||||
var APP_ICON_SIZE = 128;
|
||||
var APP_ICON_SIZE_SMALL = 48;
|
||||
|
||||
const baseIconSizes = [96, 64, 48, 32, 22];
|
||||
const baseIconSizes = [128, 64, 48, 32, 22];
|
||||
|
||||
var AppIconMode = {
|
||||
THUMBNAIL_ONLY: 1,
|
||||
@ -80,41 +81,41 @@ var AppSwitcherPopup = new Lang.Class({
|
||||
this._items = this._switcherList.icons;
|
||||
},
|
||||
|
||||
_allocate(actor, box, flags) {
|
||||
this.parent(actor, box, flags);
|
||||
vfunc_allocate(box, flags) {
|
||||
this.parent(box, flags);
|
||||
|
||||
// Allocate the thumbnails
|
||||
// We try to avoid overflowing the screen so we base the resulting size on
|
||||
// those calculations
|
||||
if (this._thumbnails) {
|
||||
let childBox = this._switcherList.actor.get_allocation_box();
|
||||
let childBox = this._switcherList.get_allocation_box();
|
||||
let primary = Main.layoutManager.primaryMonitor;
|
||||
|
||||
let leftPadding = this.actor.get_theme_node().get_padding(St.Side.LEFT);
|
||||
let rightPadding = this.actor.get_theme_node().get_padding(St.Side.RIGHT);
|
||||
let bottomPadding = this.actor.get_theme_node().get_padding(St.Side.BOTTOM);
|
||||
let leftPadding = this.get_theme_node().get_padding(St.Side.LEFT);
|
||||
let rightPadding = this.get_theme_node().get_padding(St.Side.RIGHT);
|
||||
let bottomPadding = this.get_theme_node().get_padding(St.Side.BOTTOM);
|
||||
let hPadding = leftPadding + rightPadding;
|
||||
|
||||
let icon = this._items[this._selectedIndex].actor;
|
||||
let icon = this._items[this._selectedIndex];
|
||||
let [posX, posY] = icon.get_transformed_position();
|
||||
let thumbnailCenter = posX + icon.width / 2;
|
||||
let [childMinWidth, childNaturalWidth] = this._thumbnails.actor.get_preferred_width(-1);
|
||||
let [childMinWidth, childNaturalWidth] = this._thumbnails.get_preferred_width(-1);
|
||||
childBox.x1 = Math.max(primary.x + leftPadding, Math.floor(thumbnailCenter - childNaturalWidth / 2));
|
||||
if (childBox.x1 + childNaturalWidth > primary.x + primary.width - hPadding) {
|
||||
let offset = childBox.x1 + childNaturalWidth - primary.width + hPadding;
|
||||
childBox.x1 = Math.max(primary.x + leftPadding, childBox.x1 - offset - hPadding);
|
||||
}
|
||||
|
||||
let spacing = this.actor.get_theme_node().get_length('spacing');
|
||||
let spacing = this.get_theme_node().get_length('spacing');
|
||||
|
||||
childBox.x2 = childBox.x1 + childNaturalWidth;
|
||||
if (childBox.x2 > primary.x + primary.width - rightPadding)
|
||||
childBox.x2 = primary.x + primary.width - rightPadding;
|
||||
childBox.y1 = this._switcherList.actor.allocation.y2 + spacing;
|
||||
childBox.y1 = this._switcherList.allocation.y2 + spacing;
|
||||
this._thumbnails.addClones(primary.y + primary.height - bottomPadding - childBox.y1);
|
||||
let [childMinHeight, childNaturalHeight] = this._thumbnails.actor.get_preferred_height(-1);
|
||||
let [childMinHeight, childNaturalHeight] = this._thumbnails.get_preferred_height(-1);
|
||||
childBox.y2 = childBox.y1 + childNaturalHeight;
|
||||
this._thumbnails.actor.allocate(childBox, flags);
|
||||
this._thumbnails.allocate(childBox, flags);
|
||||
}
|
||||
},
|
||||
|
||||
@ -262,7 +263,7 @@ var AppSwitcherPopup = new Lang.Class({
|
||||
_windowActivated(thumbnailList, n) {
|
||||
let appIcon = this._items[this._selectedIndex];
|
||||
Main.activateWindow(appIcon.cachedWindows[n]);
|
||||
this.destroy();
|
||||
this.fadeAndDestroy();
|
||||
},
|
||||
|
||||
_windowEntered(thumbnailList, n) {
|
||||
@ -367,7 +368,7 @@ var AppSwitcherPopup = new Lang.Class({
|
||||
},
|
||||
|
||||
_destroyThumbnails() {
|
||||
let thumbnailsActor = this._thumbnails.actor;
|
||||
let thumbnailsActor = this._thumbnails;
|
||||
Tweener.addTween(thumbnailsActor,
|
||||
{ opacity: 0,
|
||||
time: THUMBNAIL_FADE_TIME,
|
||||
@ -387,19 +388,19 @@ var AppSwitcherPopup = new Lang.Class({
|
||||
this._thumbnails.connect('item-activated', this._windowActivated.bind(this));
|
||||
this._thumbnails.connect('item-entered', this._windowEntered.bind(this));
|
||||
this._thumbnails.connect('item-removed', this._windowRemoved.bind(this));
|
||||
this._thumbnails.actor.connect('destroy', () => {
|
||||
this._thumbnails.connect('destroy', () => {
|
||||
this._thumbnails = null;
|
||||
this._thumbnailsFocused = false;
|
||||
});
|
||||
|
||||
this.actor.add_actor(this._thumbnails.actor);
|
||||
this.add_actor(this._thumbnails);
|
||||
|
||||
// Need to force an allocation so we can figure out whether we
|
||||
// need to scroll when selecting
|
||||
this._thumbnails.actor.get_allocation_box();
|
||||
this._thumbnails.get_allocation_box();
|
||||
|
||||
this._thumbnails.actor.opacity = 0;
|
||||
Tweener.addTween(this._thumbnails.actor,
|
||||
this._thumbnails.opacity = 0;
|
||||
Tweener.addTween(this._thumbnails,
|
||||
{ opacity: 255,
|
||||
time: THUMBNAIL_FADE_TIME,
|
||||
transition: 'easeOutQuad',
|
||||
@ -471,6 +472,21 @@ var CyclerHighlight = new Lang.Class({
|
||||
}
|
||||
});
|
||||
|
||||
// We don't show an actual popup, so just provide what SwitcherPopup
|
||||
// expects instead of inheriting from SwitcherList
|
||||
var CyclerList = new Lang.Class({
|
||||
Name: 'CyclerList',
|
||||
Extends: St.Widget,
|
||||
Signals: { 'item-activated': { param_types: [GObject.TYPE_INT] },
|
||||
'item-entered': { param_types: [GObject.TYPE_INT] },
|
||||
'item-removed': { param_types: [GObject.TYPE_INT] },
|
||||
'item-highlighted': { param_types: [GObject.TYPE_INT] } },
|
||||
|
||||
highlight(index, justOutline) {
|
||||
this.emit('item-highlighted', index);
|
||||
}
|
||||
});
|
||||
|
||||
var CyclerPopup = new Lang.Class({
|
||||
Name: 'CyclerPopup',
|
||||
Extends: SwitcherPopup.SwitcherPopup,
|
||||
@ -487,11 +503,10 @@ var CyclerPopup = new Lang.Class({
|
||||
this._highlight = new CyclerHighlight();
|
||||
global.window_group.add_actor(this._highlight.actor);
|
||||
|
||||
// We don't show an actual popup, so just provide what SwitcherPopup
|
||||
// expects instead of inheriting from SwitcherList
|
||||
this._switcherList = { actor: new St.Widget(),
|
||||
highlight: this._highlightItem.bind(this),
|
||||
connect() {} };
|
||||
this._switcherList = new CyclerList();
|
||||
this._switcherList.connect('item-highlighted', (list, index) => {
|
||||
this._highlightItem(index);
|
||||
});
|
||||
},
|
||||
|
||||
_highlightItem(index, justOutline) {
|
||||
@ -653,22 +668,32 @@ var WindowCyclerPopup = new Lang.Class({
|
||||
|
||||
var AppIcon = new Lang.Class({
|
||||
Name: 'AppIcon',
|
||||
Extends: St.BoxLayout,
|
||||
|
||||
_init(app) {
|
||||
this.parent({ style_class: 'alt-tab-app',
|
||||
vertical: true });
|
||||
|
||||
this.app = app;
|
||||
this.actor = new St.BoxLayout({ style_class: 'alt-tab-app',
|
||||
vertical: true });
|
||||
this.icon = null;
|
||||
this._iconBin = new St.Bin({ x_fill: true, y_fill: true });
|
||||
|
||||
this.actor.add(this._iconBin, { x_fill: false, y_fill: false } );
|
||||
this.add(this._iconBin, { x_fill: false, y_fill: false } );
|
||||
this.label = new St.Label({ text: this.app.get_name() });
|
||||
this.actor.add(this.label, { x_fill: false });
|
||||
this.add(this.label, { x_fill: false });
|
||||
},
|
||||
|
||||
set_size(size) {
|
||||
this.icon = this.app.create_icon_texture(size);
|
||||
this._iconBin.child = this.icon;
|
||||
this._iconBin.set_size(size, size);
|
||||
},
|
||||
|
||||
vfunc_get_preferred_width(forHeight) {
|
||||
let [minWidth, ] = this.parent(forHeight);
|
||||
|
||||
minWidth = Math.max(minWidth, forHeight);
|
||||
return [minWidth, minWidth];
|
||||
}
|
||||
});
|
||||
|
||||
@ -707,11 +732,10 @@ var AppSwitcher = new Lang.Class({
|
||||
}
|
||||
|
||||
this._curApp = -1;
|
||||
this._iconSize = 0;
|
||||
this._altTabPopup = altTabPopup;
|
||||
this._mouseTimeOutId = 0;
|
||||
|
||||
this.actor.connect('destroy', this._onDestroy.bind(this));
|
||||
this.connect('destroy', this._onDestroy.bind(this));
|
||||
},
|
||||
|
||||
_onDestroy() {
|
||||
@ -738,17 +762,16 @@ var AppSwitcher = new Lang.Class({
|
||||
|
||||
// We just assume the whole screen here due to weirdness happing with the passed width
|
||||
let primary = Main.layoutManager.primaryMonitor;
|
||||
let parentPadding = this.actor.get_parent().get_theme_node().get_horizontal_padding();
|
||||
let availWidth = primary.width - parentPadding - this.actor.get_theme_node().get_horizontal_padding();
|
||||
let parentPadding = this.get_parent().get_theme_node().get_horizontal_padding();
|
||||
let availWidth = primary.width - parentPadding - this.get_theme_node().get_horizontal_padding();
|
||||
|
||||
let scaleFactor = St.ThemeContext.get_for_stage(global.stage).scale_factor;
|
||||
let iconSizes = baseIconSizes.map(s => s * scaleFactor);
|
||||
let iconSize = baseIconSizes[0];
|
||||
|
||||
if (this._items.length == 1) {
|
||||
this._iconSize = baseIconSizes[0];
|
||||
} else {
|
||||
if (this._items.length > 1) {
|
||||
for(let i = 0; i < baseIconSizes.length; i++) {
|
||||
this._iconSize = baseIconSizes[i];
|
||||
iconSize = baseIconSizes[i];
|
||||
let height = iconSizes[i] + iconSpacing;
|
||||
let w = height * this._items.length + totalSpacing;
|
||||
if (w <= availWidth)
|
||||
@ -756,32 +779,36 @@ var AppSwitcher = new Lang.Class({
|
||||
}
|
||||
}
|
||||
|
||||
this._iconSize = iconSize;
|
||||
|
||||
for(let i = 0; i < this.icons.length; i++) {
|
||||
if (this.icons[i].icon != null)
|
||||
break;
|
||||
this.icons[i].set_size(this._iconSize);
|
||||
this.icons[i].set_size(iconSize);
|
||||
}
|
||||
},
|
||||
|
||||
_getPreferredHeight(actor, forWidth, alloc) {
|
||||
vfunc_get_preferred_height(forWidth) {
|
||||
this._setIconSize();
|
||||
this.parent(actor, forWidth, alloc);
|
||||
return this.parent(forWidth);
|
||||
},
|
||||
|
||||
_allocate(actor, box, flags) {
|
||||
vfunc_allocate(box, flags) {
|
||||
// Allocate the main list items
|
||||
this.parent(actor, box, flags);
|
||||
this.parent(box, flags);
|
||||
|
||||
let arrowHeight = Math.floor(this.actor.get_theme_node().get_padding(St.Side.BOTTOM) / 3);
|
||||
let contentBox = this.get_theme_node().get_content_box(box);
|
||||
|
||||
let arrowHeight = Math.floor(this.get_theme_node().get_padding(St.Side.BOTTOM) / 3);
|
||||
let arrowWidth = arrowHeight * 2;
|
||||
|
||||
// Now allocate each arrow underneath its item
|
||||
let childBox = new Clutter.ActorBox();
|
||||
for (let i = 0; i < this._items.length; i++) {
|
||||
let itemBox = this._items[i].allocation;
|
||||
childBox.x1 = Math.floor(itemBox.x1 + (itemBox.x2 - itemBox.x1 - arrowWidth) / 2);
|
||||
childBox.x1 = contentBox.x1 + Math.floor(itemBox.x1 + (itemBox.x2 - itemBox.x1 - arrowWidth) / 2);
|
||||
childBox.x2 = childBox.x1 + arrowWidth;
|
||||
childBox.y1 = itemBox.y2 + arrowHeight;
|
||||
childBox.y1 = contentBox.y1 + itemBox.y2 + arrowHeight;
|
||||
childBox.y2 = childBox.y1 + arrowHeight;
|
||||
this._arrows[i].allocate(childBox, flags);
|
||||
}
|
||||
@ -839,7 +866,7 @@ var AppSwitcher = new Lang.Class({
|
||||
|
||||
_addIcon(appIcon) {
|
||||
this.icons.push(appIcon);
|
||||
let item = this.addItem(appIcon.actor, appIcon.label);
|
||||
let item = this.addItem(appIcon, appIcon.label);
|
||||
|
||||
appIcon._stateChangedId = appIcon.app.connect('notify::state', app => {
|
||||
if (app.state != Shell.AppState.RUNNING)
|
||||
@ -849,7 +876,7 @@ var AppSwitcher = new Lang.Class({
|
||||
let n = this._arrows.length;
|
||||
let arrow = new St.DrawingArea({ style_class: 'switcher-arrow' });
|
||||
arrow.connect('repaint', () => { SwitcherPopup.drawArrow(arrow, St.Side.BOTTOM); });
|
||||
this._list.add_actor(arrow);
|
||||
this.add_actor(arrow);
|
||||
this._arrows.push(arrow);
|
||||
|
||||
if (appIcon.cachedWindows.length == 1)
|
||||
@ -907,21 +934,21 @@ var ThumbnailList = new Lang.Class({
|
||||
|
||||
}
|
||||
|
||||
this.actor.connect('destroy', this._onDestroy.bind(this));
|
||||
this.connect('destroy', this._onDestroy.bind(this));
|
||||
},
|
||||
|
||||
addClones(availHeight) {
|
||||
if (!this._thumbnailBins.length)
|
||||
return;
|
||||
let totalPadding = this._items[0].get_theme_node().get_horizontal_padding() + this._items[0].get_theme_node().get_vertical_padding();
|
||||
totalPadding += this.actor.get_theme_node().get_horizontal_padding() + this.actor.get_theme_node().get_vertical_padding();
|
||||
totalPadding += this.get_theme_node().get_horizontal_padding() + this.get_theme_node().get_vertical_padding();
|
||||
let [labelMinHeight, labelNaturalHeight] = this._labels[0].get_preferred_height(-1);
|
||||
let spacing = this._items[0].child.get_theme_node().get_length('spacing');
|
||||
let scaleFactor = St.ThemeContext.get_for_stage(global.stage).scale_factor;
|
||||
let thumbnailSize = THUMBNAIL_DEFAULT_SIZE * scaleFactor;
|
||||
|
||||
availHeight = Math.min(availHeight - labelNaturalHeight - totalPadding - spacing, thumbnailSize);
|
||||
let binHeight = availHeight + this._items[0].get_theme_node().get_vertical_padding() + this.actor.get_theme_node().get_vertical_padding() - spacing;
|
||||
let binHeight = availHeight + this._items[0].get_theme_node().get_vertical_padding() + this.get_theme_node().get_vertical_padding() - spacing;
|
||||
binHeight = Math.min(thumbnailSize, binHeight);
|
||||
|
||||
for (let i = 0; i < this._thumbnailBins.length; i++) {
|
||||
@ -956,7 +983,7 @@ var ThumbnailList = new Lang.Class({
|
||||
if (this._clones.length > 0)
|
||||
this.highlight(SwitcherPopup.mod(index, this._clones.length));
|
||||
else
|
||||
this.actor.destroy();
|
||||
this.destroy();
|
||||
},
|
||||
|
||||
_onDestroy() {
|
||||
@ -970,15 +997,17 @@ var ThumbnailList = new Lang.Class({
|
||||
|
||||
var WindowIcon = new Lang.Class({
|
||||
Name: 'WindowIcon',
|
||||
Extends: St.BoxLayout,
|
||||
|
||||
_init(window, mode) {
|
||||
this.parent({ style_class: 'alt-tab-app',
|
||||
vertical: true });
|
||||
|
||||
this.window = window;
|
||||
|
||||
this.actor = new St.BoxLayout({ style_class: 'alt-tab-app',
|
||||
vertical: true });
|
||||
this._icon = new St.Widget({ layout_manager: new Clutter.BinLayout() });
|
||||
|
||||
this.actor.add(this._icon, { x_fill: false, y_fill: false } );
|
||||
this.add(this._icon, { x_fill: false, y_fill: false } );
|
||||
this.label = new St.Label({ text: window.get_title() });
|
||||
|
||||
let tracker = Shell.WindowTracker.get_default();
|
||||
@ -1034,7 +1063,7 @@ var WindowList = new Lang.Class({
|
||||
|
||||
this._label = new St.Label({ x_align: Clutter.ActorAlign.CENTER,
|
||||
y_align: Clutter.ActorAlign.CENTER });
|
||||
this.actor.add_actor(this._label);
|
||||
this.add_actor(this._label);
|
||||
|
||||
this.windows = windows;
|
||||
this.icons = [];
|
||||
@ -1043,7 +1072,7 @@ var WindowList = new Lang.Class({
|
||||
let win = windows[i];
|
||||
let icon = new WindowIcon(win, mode);
|
||||
|
||||
this.addItem(icon.actor, icon.label);
|
||||
this.addItem(icon, icon.label);
|
||||
this.icons.push(icon);
|
||||
|
||||
icon._unmanagedSignalId = icon.window.connect('unmanaged', (window) => {
|
||||
@ -1051,7 +1080,7 @@ var WindowList = new Lang.Class({
|
||||
});
|
||||
}
|
||||
|
||||
this.actor.connect('destroy', () => { this._onDestroy(); });
|
||||
this.connect('destroy', this._onDestroy.bind(this));
|
||||
},
|
||||
|
||||
_onDestroy() {
|
||||
@ -1060,26 +1089,40 @@ var WindowList = new Lang.Class({
|
||||
});
|
||||
},
|
||||
|
||||
_getPreferredHeight(actor, forWidth, alloc) {
|
||||
this.parent(actor, forWidth, alloc);
|
||||
vfunc_get_preferred_height(forWidth) {
|
||||
let [minHeight, natHeight] = this.parent(forWidth);
|
||||
|
||||
let spacing = this.actor.get_theme_node().get_padding(St.Side.BOTTOM);
|
||||
let spacing = this.get_theme_node().get_padding(St.Side.BOTTOM);
|
||||
let [labelMin, labelNat] = this._label.get_preferred_height(-1);
|
||||
alloc.min_size += labelMin + spacing;
|
||||
alloc.natural_size += labelNat + spacing;
|
||||
|
||||
minHeight += labelMin + spacing;
|
||||
natHeight += labelNat + spacing;
|
||||
|
||||
return [minHeight, natHeight];
|
||||
},
|
||||
|
||||
_allocateTop(actor, box, flags) {
|
||||
vfunc_allocate(box, flags) {
|
||||
let themeNode = this.get_theme_node();
|
||||
let contentBox = themeNode.get_content_box(box);
|
||||
|
||||
let childBox = new Clutter.ActorBox();
|
||||
childBox.x1 = box.x1;
|
||||
childBox.x2 = box.x2;
|
||||
childBox.y2 = box.y2;
|
||||
childBox.x1 = contentBox.x1;
|
||||
childBox.x2 = contentBox.x2;
|
||||
childBox.y2 = contentBox.y2;
|
||||
childBox.y1 = childBox.y2 - this._label.height;
|
||||
this._label.allocate(childBox, flags);
|
||||
|
||||
let spacing = this.actor.get_theme_node().get_padding(St.Side.BOTTOM);
|
||||
box.y2 -= this._label.height + spacing;
|
||||
this.parent(actor, box, flags);
|
||||
let totalLabelHeight = this._label.height + themeNode.get_padding(St.Side.BOTTOM)
|
||||
childBox.x1 = box.x1;
|
||||
childBox.x2 = box.x2;
|
||||
childBox.y1 = box.y1;
|
||||
childBox.y2 = box.y2 - totalLabelHeight;
|
||||
this.parent(childBox, flags);
|
||||
|
||||
// Hooking up the parent vfunc will call this.set_allocation() with
|
||||
// the height without the label height, so call it again with the
|
||||
// correct size here.
|
||||
this.set_allocation(box, flags);
|
||||
},
|
||||
|
||||
highlight(index, justOutline) {
|
||||
|
@ -126,17 +126,17 @@ var BaseAppView = new Lang.Class({
|
||||
else
|
||||
this._grid = new IconGrid.IconGrid(gridParams);
|
||||
|
||||
this._grid.connect('key-focus-in', (grid, actor) => {
|
||||
this._keyFocusIn(actor);
|
||||
this._grid.connect('child-focused', (grid, actor) => {
|
||||
this._childFocused(actor);
|
||||
});
|
||||
// Standard hack for ClutterBinLayout
|
||||
this._grid.actor.x_expand = true;
|
||||
this._grid.x_expand = true;
|
||||
|
||||
this._items = {};
|
||||
this._allItems = [];
|
||||
},
|
||||
|
||||
_keyFocusIn(actor) {
|
||||
_childFocused(actor) {
|
||||
// Nothing by default
|
||||
},
|
||||
|
||||
@ -203,7 +203,7 @@ var BaseAppView = new Lang.Class({
|
||||
},
|
||||
|
||||
_doSpringAnimation(animationDirection) {
|
||||
this._grid.actor.opacity = 255;
|
||||
this._grid.opacity = 255;
|
||||
this._grid.animateSpring(animationDirection,
|
||||
Main.overview.getShowAppsButton());
|
||||
},
|
||||
@ -217,8 +217,8 @@ var BaseAppView = new Lang.Class({
|
||||
}
|
||||
|
||||
if (animationDirection == IconGrid.AnimationDirection.IN) {
|
||||
let id = this._grid.actor.connect('paint', () => {
|
||||
this._grid.actor.disconnect(id);
|
||||
let id = this._grid.connect('paint', () => {
|
||||
this._grid.disconnect(id);
|
||||
this._doSpringAnimation(animationDirection);
|
||||
});
|
||||
} else {
|
||||
@ -228,7 +228,7 @@ var BaseAppView = new Lang.Class({
|
||||
|
||||
animateSwitch(animationDirection) {
|
||||
Tweener.removeTweens(this.actor);
|
||||
Tweener.removeTweens(this._grid.actor);
|
||||
Tweener.removeTweens(this._grid);
|
||||
|
||||
let params = { time: VIEWS_SWITCH_TIME,
|
||||
transition: 'easeOutQuad' };
|
||||
@ -242,7 +242,7 @@ var BaseAppView = new Lang.Class({
|
||||
params.onComplete = () => { this.actor.hide(); };
|
||||
}
|
||||
|
||||
Tweener.addTween(this._grid.actor, params);
|
||||
Tweener.addTween(this._grid, params);
|
||||
}
|
||||
});
|
||||
Signals.addSignalMethods(BaseAppView.prototype);
|
||||
@ -396,7 +396,7 @@ var AllView = new Lang.Class({
|
||||
let box = new St.BoxLayout({ vertical: true });
|
||||
|
||||
this._grid.currentPage = 0;
|
||||
this._stack.add_actor(this._grid.actor);
|
||||
this._stack.add_actor(this._grid);
|
||||
this._eventBlocker = new St.Widget({ x_expand: true, y_expand: true });
|
||||
this._stack.add_actor(this._eventBlocker);
|
||||
|
||||
@ -717,7 +717,7 @@ var AllView = new Lang.Class({
|
||||
});
|
||||
},
|
||||
|
||||
_keyFocusIn(icon) {
|
||||
_childFocused(icon) {
|
||||
let itemPage = this._grid.getItemPage(icon);
|
||||
this.goToPage(itemPage);
|
||||
},
|
||||
@ -745,7 +745,7 @@ var AllView = new Lang.Class({
|
||||
box.y2 = height;
|
||||
box = this.actor.get_theme_node().get_content_box(box);
|
||||
box = this._scrollView.get_theme_node().get_content_box(box);
|
||||
box = this._grid.actor.get_theme_node().get_content_box(box);
|
||||
box = this._grid.get_theme_node().get_content_box(box);
|
||||
let availWidth = box.x2 - box.x1;
|
||||
let availHeight = box.y2 - box.y1;
|
||||
let oldNPages = this._grid.nPages();
|
||||
@ -794,9 +794,9 @@ var FrequentView = new Lang.Class({
|
||||
y_align: Clutter.ActorAlign.CENTER,
|
||||
y_expand: true });
|
||||
|
||||
this._grid.actor.y_expand = true;
|
||||
this._grid.y_expand = true;
|
||||
|
||||
this.actor.add_actor(this._grid.actor);
|
||||
this.actor.add_actor(this._grid);
|
||||
this.actor.add_actor(this._noFrequentAppsLabel);
|
||||
this._noFrequentAppsLabel.hide();
|
||||
|
||||
@ -843,7 +843,7 @@ var FrequentView = new Lang.Class({
|
||||
box.x2 = width;
|
||||
box.y2 = height;
|
||||
box = this.actor.get_theme_node().get_content_box(box);
|
||||
box = this._grid.actor.get_theme_node().get_content_box(box);
|
||||
box = this._grid.get_theme_node().get_content_box(box);
|
||||
let availWidth = box.x2 - box.x1;
|
||||
let availHeight = box.y2 - box.y1;
|
||||
this._grid.adaptToSize(availWidth, availHeight);
|
||||
@ -1141,12 +1141,12 @@ var FolderView = new Lang.Class({
|
||||
this.parent(null, null);
|
||||
// If it not expand, the parent doesn't take into account its preferred_width when allocating
|
||||
// the second time it allocates, so we apply the "Standard hack for ClutterBinLayout"
|
||||
this._grid.actor.x_expand = true;
|
||||
this._grid.x_expand = true;
|
||||
|
||||
this.actor = new St.ScrollView({ overlay_scrollbars: true });
|
||||
this.actor.set_policy(Gtk.PolicyType.NEVER, Gtk.PolicyType.AUTOMATIC);
|
||||
let scrollableContainer = new St.BoxLayout({ vertical: true, reactive: true });
|
||||
scrollableContainer.add_actor(this._grid.actor);
|
||||
scrollableContainer.add_actor(this._grid);
|
||||
this.actor.add_actor(scrollableContainer);
|
||||
|
||||
let action = new Clutter.PanAction({ interpolate: true });
|
||||
@ -1154,7 +1154,7 @@ var FolderView = new Lang.Class({
|
||||
this.actor.add_action(action);
|
||||
},
|
||||
|
||||
_keyFocusIn(actor) {
|
||||
_childFocused(actor) {
|
||||
Util.ensureActorVisibleInScrollView(this.actor, actor);
|
||||
},
|
||||
|
||||
@ -1267,7 +1267,7 @@ var FolderIcon = new Lang.Class({
|
||||
this._popupInvalidated = false;
|
||||
|
||||
this.icon = new IconGrid.BaseIcon('', { createIcon: this._createIcon.bind(this), setSizeManually: true });
|
||||
this.actor.set_child(this.icon.actor);
|
||||
this.actor.set_child(this.icon);
|
||||
this.actor.label_actor = this.icon.label;
|
||||
|
||||
this.view = new FolderView();
|
||||
@ -1369,7 +1369,7 @@ var FolderIcon = new Lang.Class({
|
||||
|
||||
_updatePopupSize() {
|
||||
// StWidget delays style calculation until needed, make sure we use the correct values
|
||||
this.view._grid.actor.ensure_style();
|
||||
this.view._grid.ensure_style();
|
||||
|
||||
let offsetForEachSide = Math.ceil((this._popup.getOffset(St.Side.TOP) +
|
||||
this._popup.getOffset(St.Side.BOTTOM) -
|
||||
@ -1537,7 +1537,7 @@ var AppFolderPopup = new Lang.Class({
|
||||
// is completed so we can animate the icons after as we like without
|
||||
// showing them while boxpointer is animating.
|
||||
this._view.actor.opacity = 0;
|
||||
this._boxPointer.show(BoxPointer.PopupAnimation.FADE |
|
||||
this._boxPointer.open(BoxPointer.PopupAnimation.FADE |
|
||||
BoxPointer.PopupAnimation.SLIDE,
|
||||
() => {
|
||||
this._view.actor.opacity = 255;
|
||||
@ -1553,8 +1553,8 @@ var AppFolderPopup = new Lang.Class({
|
||||
|
||||
this._grabHelper.ungrab({ actor: this.actor });
|
||||
|
||||
this._boxPointer.hide(BoxPointer.PopupAnimation.FADE |
|
||||
BoxPointer.PopupAnimation.SLIDE);
|
||||
this._boxPointer.close(BoxPointer.PopupAnimation.FADE |
|
||||
BoxPointer.PopupAnimation.SLIDE);
|
||||
this._isOpen = false;
|
||||
this.emit('open-state-changed', false);
|
||||
},
|
||||
@ -1617,7 +1617,7 @@ var AppIcon = new Lang.Class({
|
||||
iconParams['createIcon'] = this._createIcon.bind(this);
|
||||
iconParams['setSizeManually'] = true;
|
||||
this.icon = new IconGrid.BaseIcon(app.get_name(), iconParams);
|
||||
this._iconContainer.add_child(this.icon.actor);
|
||||
this._iconContainer.add_child(this.icon);
|
||||
|
||||
this.actor.label_actor = this.icon.label;
|
||||
|
||||
|
@ -34,25 +34,25 @@ var POPUP_ANIMATION_TIME = 0.15;
|
||||
*/
|
||||
var BoxPointer = new Lang.Class({
|
||||
Name: 'BoxPointer',
|
||||
Extends: St.Widget,
|
||||
Signals: { 'arrow-side-changed': {} },
|
||||
|
||||
_init(arrowSide, binProperties) {
|
||||
this.parent();
|
||||
|
||||
this.actor = this;
|
||||
|
||||
this.set_offscreen_redirect(Clutter.OffscreenRedirect.ALWAYS);
|
||||
|
||||
this._arrowSide = arrowSide;
|
||||
this._userArrowSide = arrowSide;
|
||||
this._arrowOrigin = 0;
|
||||
this._arrowActor = null;
|
||||
this.actor = new St.Bin({ x_fill: true,
|
||||
y_fill: true });
|
||||
this._container = new Shell.GenericContainer();
|
||||
this.actor.set_child(this._container);
|
||||
this.actor.set_offscreen_redirect(Clutter.OffscreenRedirect.ALWAYS);
|
||||
this._container.connect('get-preferred-width', this._getPreferredWidth.bind(this));
|
||||
this._container.connect('get-preferred-height', this._getPreferredHeight.bind(this));
|
||||
this._container.connect('allocate', this._allocate.bind(this));
|
||||
this.bin = new St.Bin(binProperties);
|
||||
this._container.add_actor(this.bin);
|
||||
this.add_actor(this.bin);
|
||||
this._border = new St.DrawingArea();
|
||||
this._border.connect('repaint', this._drawBorder.bind(this));
|
||||
this._container.add_actor(this._border);
|
||||
this.add_actor(this._border);
|
||||
this.bin.raise(this._border);
|
||||
this._xOffset = 0;
|
||||
this._yOffset = 0;
|
||||
@ -69,19 +69,49 @@ var BoxPointer = new Lang.Class({
|
||||
|
||||
_muteInput() {
|
||||
if (this._capturedEventId == 0)
|
||||
this._capturedEventId = this.actor.connect('captured-event',
|
||||
() => Clutter.EVENT_STOP);
|
||||
this._capturedEventId = this.connect('captured-event',
|
||||
() => Clutter.EVENT_STOP);
|
||||
},
|
||||
|
||||
_unmuteInput() {
|
||||
if (this._capturedEventId != 0) {
|
||||
this.actor.disconnect(this._capturedEventId);
|
||||
this.disconnect(this._capturedEventId);
|
||||
this._capturedEventId = 0;
|
||||
}
|
||||
},
|
||||
|
||||
// BoxPointer.show() and BoxPointer.hide() are here for only compatibility
|
||||
// purposes, and will be removed in 3.32.
|
||||
show(animate, onComplete) {
|
||||
let themeNode = this.actor.get_theme_node();
|
||||
if (animate !== undefined) {
|
||||
try {
|
||||
throw new Error('BoxPointer.show() has been moved to BoxPointer.open(), this code will break in the future.');
|
||||
} catch(e) {
|
||||
logError(e);
|
||||
this.open(animate, onComplete);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
this.visible = true;
|
||||
},
|
||||
|
||||
hide(animate, onComplete) {
|
||||
if (animate !== undefined) {
|
||||
try {
|
||||
throw new Error('BoxPointer.hide() has been moved to BoxPointer.close(), this code will break in the future.');
|
||||
} catch(e) {
|
||||
logError(e);
|
||||
this.close(animate, onComplete);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
this.visible = false;
|
||||
},
|
||||
|
||||
open(animate, onComplete) {
|
||||
let themeNode = this.get_theme_node();
|
||||
let rise = themeNode.get_length('-arrow-rise');
|
||||
let animationTime = (animate & PopupAnimation.FULL) ? POPUP_ANIMATION_TIME : 0;
|
||||
|
||||
@ -90,7 +120,7 @@ var BoxPointer = new Lang.Class({
|
||||
else
|
||||
this.opacity = 255;
|
||||
|
||||
this.actor.show();
|
||||
this.show();
|
||||
|
||||
if (animate & PopupAnimation.SLIDE) {
|
||||
switch (this._arrowSide) {
|
||||
@ -121,13 +151,13 @@ var BoxPointer = new Lang.Class({
|
||||
time: animationTime });
|
||||
},
|
||||
|
||||
hide(animate, onComplete) {
|
||||
if (!this.actor.visible)
|
||||
close(animate, onComplete) {
|
||||
if (!this.visible)
|
||||
return;
|
||||
|
||||
let xOffset = 0;
|
||||
let yOffset = 0;
|
||||
let themeNode = this.actor.get_theme_node();
|
||||
let themeNode = this.get_theme_node();
|
||||
let rise = themeNode.get_length('-arrow-rise');
|
||||
let fade = (animate & PopupAnimation.FADE);
|
||||
let animationTime = (animate & PopupAnimation.FULL) ? POPUP_ANIMATION_TIME : 0;
|
||||
@ -158,7 +188,7 @@ var BoxPointer = new Lang.Class({
|
||||
transition: 'linear',
|
||||
time: animationTime,
|
||||
onComplete: () => {
|
||||
this.actor.hide();
|
||||
this.hide();
|
||||
this.opacity = 0;
|
||||
this.xOffset = 0;
|
||||
this.yOffset = 0;
|
||||
@ -168,37 +198,48 @@ var BoxPointer = new Lang.Class({
|
||||
});
|
||||
},
|
||||
|
||||
_adjustAllocationForArrow(isWidth, alloc) {
|
||||
let themeNode = this.actor.get_theme_node();
|
||||
_adjustAllocationForArrow(isWidth, minSize, natSize) {
|
||||
let themeNode = this.get_theme_node();
|
||||
let borderWidth = themeNode.get_length('-arrow-border-width');
|
||||
alloc.min_size += borderWidth * 2;
|
||||
alloc.natural_size += borderWidth * 2;
|
||||
minSize += borderWidth * 2;
|
||||
natSize += borderWidth * 2;
|
||||
if ((!isWidth && (this._arrowSide == St.Side.TOP || this._arrowSide == St.Side.BOTTOM))
|
||||
|| (isWidth && (this._arrowSide == St.Side.LEFT || this._arrowSide == St.Side.RIGHT))) {
|
||||
let rise = themeNode.get_length('-arrow-rise');
|
||||
alloc.min_size += rise;
|
||||
alloc.natural_size += rise;
|
||||
minSize += rise;
|
||||
natSize += rise;
|
||||
}
|
||||
|
||||
return [minSize, natSize];
|
||||
},
|
||||
|
||||
_getPreferredWidth(actor, forHeight, alloc) {
|
||||
let [minInternalSize, natInternalSize] = this.bin.get_preferred_width(forHeight);
|
||||
alloc.min_size = minInternalSize;
|
||||
alloc.natural_size = natInternalSize;
|
||||
this._adjustAllocationForArrow(true, alloc);
|
||||
vfunc_get_preferred_width(forHeight) {
|
||||
let themeNode = this.get_theme_node();
|
||||
forHeight = themeNode.adjust_for_height(forHeight);
|
||||
|
||||
let width = this.bin.get_preferred_width(forHeight);
|
||||
width = this._adjustAllocationForArrow(true, ...width);
|
||||
|
||||
return themeNode.adjust_preferred_width(...width);
|
||||
},
|
||||
|
||||
_getPreferredHeight(actor, forWidth, alloc) {
|
||||
let themeNode = this.actor.get_theme_node();
|
||||
vfunc_get_preferred_height(forWidth) {
|
||||
let themeNode = this.get_theme_node();
|
||||
let borderWidth = themeNode.get_length('-arrow-border-width');
|
||||
let [minSize, naturalSize] = this.bin.get_preferred_height(forWidth - 2 * borderWidth);
|
||||
alloc.min_size = minSize;
|
||||
alloc.natural_size = naturalSize;
|
||||
this._adjustAllocationForArrow(false, alloc);
|
||||
forWidth = themeNode.adjust_for_width(forWidth);
|
||||
|
||||
let height = this.bin.get_preferred_height(forWidth - 2 * borderWidth);
|
||||
height = this._adjustAllocationForArrow(false, ...height);
|
||||
|
||||
return themeNode.adjust_preferred_height(...height);
|
||||
},
|
||||
|
||||
_allocate(actor, box, flags) {
|
||||
let themeNode = this.actor.get_theme_node();
|
||||
vfunc_allocate(box, flags) {
|
||||
this.set_allocation(box, flags);
|
||||
|
||||
let themeNode = this.get_theme_node();
|
||||
box = themeNode.get_content_box(box);
|
||||
|
||||
let borderWidth = themeNode.get_length('-arrow-border-width');
|
||||
let rise = themeNode.get_length('-arrow-rise');
|
||||
let childBox = new Clutter.ActorBox();
|
||||
@ -238,12 +279,12 @@ var BoxPointer = new Lang.Class({
|
||||
},
|
||||
|
||||
_drawBorder(area) {
|
||||
let themeNode = this.actor.get_theme_node();
|
||||
let themeNode = this.get_theme_node();
|
||||
|
||||
if (this._arrowActor) {
|
||||
let [sourceX, sourceY] = this._arrowActor.get_transformed_position();
|
||||
let [sourceWidth, sourceHeight] = this._arrowActor.get_transformed_size();
|
||||
let [absX, absY] = this.actor.get_transformed_position();
|
||||
let [absX, absY] = this.get_transformed_position();
|
||||
|
||||
if (this._arrowSide == St.Side.TOP ||
|
||||
this._arrowSide == St.Side.BOTTOM) {
|
||||
@ -422,7 +463,7 @@ var BoxPointer = new Lang.Class({
|
||||
setPosition(sourceActor, alignment) {
|
||||
// We need to show it now to force an allocation,
|
||||
// so that we can query the correct size.
|
||||
this.actor.show();
|
||||
this.show();
|
||||
|
||||
this._sourceActor = sourceActor;
|
||||
this._arrowAlignment = alignment;
|
||||
@ -450,13 +491,13 @@ var BoxPointer = new Lang.Class({
|
||||
let sourceAllocation = Shell.util_get_transformed_allocation(sourceActor);
|
||||
let sourceCenterX = sourceAllocation.x1 + sourceContentBox.x1 + (sourceContentBox.x2 - sourceContentBox.x1) * this._sourceAlignment;
|
||||
let sourceCenterY = sourceAllocation.y1 + sourceContentBox.y1 + (sourceContentBox.y2 - sourceContentBox.y1) * this._sourceAlignment;
|
||||
let [minWidth, minHeight, natWidth, natHeight] = this.actor.get_preferred_size();
|
||||
let [minWidth, minHeight, natWidth, natHeight] = this.get_preferred_size();
|
||||
|
||||
// We also want to keep it onscreen, and separated from the
|
||||
// edge by the same distance as the main part of the box is
|
||||
// separated from its sourceActor
|
||||
let monitor = Main.layoutManager.findMonitorForActor(sourceActor);
|
||||
let themeNode = this.actor.get_theme_node();
|
||||
let themeNode = this.get_theme_node();
|
||||
let borderWidth = themeNode.get_length('-arrow-border-width');
|
||||
let arrowBase = themeNode.get_length('-arrow-base');
|
||||
let borderRadius = themeNode.get_length('-arrow-border-radius');
|
||||
@ -542,7 +583,7 @@ var BoxPointer = new Lang.Class({
|
||||
|
||||
this.setArrowOrigin(arrowOrigin);
|
||||
|
||||
let parent = this.actor.get_parent();
|
||||
let parent = this.get_parent();
|
||||
let success, x, y;
|
||||
while (!success) {
|
||||
[success, x, y] = parent.transform_stage_point(resX, resY);
|
||||
@ -581,16 +622,16 @@ var BoxPointer = new Lang.Class({
|
||||
// allocation loops and warnings. Instead we do the positioning via
|
||||
// the anchor point, which is independent of allocation, and leave
|
||||
// x == y == 0.
|
||||
this.actor.set_anchor_point(-(this._xPosition + this._xOffset),
|
||||
-(this._yPosition + this._yOffset));
|
||||
this.set_anchor_point(-(this._xPosition + this._xOffset),
|
||||
-(this._yPosition + this._yOffset));
|
||||
},
|
||||
|
||||
_calculateArrowSide(arrowSide) {
|
||||
let sourceAllocation = Shell.util_get_transformed_allocation(this._sourceActor);
|
||||
let [minWidth, minHeight, boxWidth, boxHeight] = this._container.get_preferred_size();
|
||||
let [minWidth, minHeight, boxWidth, boxHeight] = this.get_preferred_size();
|
||||
let monitorActor = this.sourceActor;
|
||||
if (!monitorActor)
|
||||
monitorActor = this.actor;
|
||||
monitorActor = this;
|
||||
let monitor = Main.layoutManager.findMonitorForActor(monitorActor);
|
||||
|
||||
switch (arrowSide) {
|
||||
@ -625,7 +666,7 @@ var BoxPointer = new Lang.Class({
|
||||
this._arrowSide = arrowSide;
|
||||
this._reposition();
|
||||
Meta.later_add(Meta.LaterType.BEFORE_REDRAW, () => {
|
||||
this._container.queue_relayout();
|
||||
this.queue_relayout();
|
||||
return false;
|
||||
});
|
||||
|
||||
@ -651,14 +692,6 @@ var BoxPointer = new Lang.Class({
|
||||
return this._yOffset;
|
||||
},
|
||||
|
||||
set opacity(opacity) {
|
||||
this.actor.opacity = opacity;
|
||||
},
|
||||
|
||||
get opacity() {
|
||||
return this.actor.opacity;
|
||||
},
|
||||
|
||||
updateArrowSide(side) {
|
||||
this._arrowSide = side;
|
||||
this._border.queue_repaint();
|
||||
@ -671,7 +704,6 @@ var BoxPointer = new Lang.Class({
|
||||
},
|
||||
|
||||
getArrowHeight() {
|
||||
return this.actor.get_theme_node().get_length('-arrow-rise');
|
||||
return this.get_theme_node().get_length('-arrow-rise');
|
||||
}
|
||||
});
|
||||
Signals.addSignalMethods(BoxPointer.prototype);
|
||||
|
@ -773,9 +773,11 @@ var NotificationMessage = new Lang.Class({
|
||||
|
||||
this.connect('close', () => {
|
||||
this._closed = true;
|
||||
this.notification.destroy(MessageTray.NotificationDestroyedReason.DISMISSED);
|
||||
if (this.notification)
|
||||
this.notification.destroy(MessageTray.NotificationDestroyedReason.DISMISSED);
|
||||
});
|
||||
this._destroyId = notification.connect('destroy', () => {
|
||||
this.notification = null;
|
||||
if (!this._closed)
|
||||
this.close();
|
||||
});
|
||||
@ -866,11 +868,11 @@ var EventsSection = new Lang.Class({
|
||||
if (sameYear(this._date, now))
|
||||
/* Translators: Shown on calendar heading when selected day occurs on current year */
|
||||
dayFormat = Shell.util_translate_time_string(NC_("calendar heading",
|
||||
"%A, %B %d"));
|
||||
"%A, %B %-d"));
|
||||
else
|
||||
/* Translators: Shown on calendar heading when selected day occurs on different year */
|
||||
dayFormat = Shell.util_translate_time_string(NC_("calendar heading",
|
||||
"%A, %B %d, %Y"));
|
||||
"%A, %B %-d, %Y"));
|
||||
this._title.label = this._date.toLocaleFormat(dayFormat);
|
||||
},
|
||||
|
||||
|
@ -197,9 +197,13 @@ var AutomountManager = new Lang.Class({
|
||||
this._closeOperation(volume);
|
||||
} catch (e) {
|
||||
// FIXME: we will always get G_IO_ERROR_FAILED from the gvfs udisks
|
||||
// backend in this case, see
|
||||
// https://bugs.freedesktop.org/show_bug.cgi?id=51271
|
||||
if (e.message.indexOf('No key available with this passphrase') != -1) {
|
||||
// backend, see https://bugs.freedesktop.org/show_bug.cgi?id=51271
|
||||
// To reask the password if the user input was empty or wrong, we
|
||||
// will check for corresponding error messages. However, these
|
||||
// error strings are not unique for the cases in the comments below.
|
||||
if (e.message.includes('No key available with this passphrase') || // cryptsetup
|
||||
e.message.includes('No key available to unlock device') || // udisks (no password)
|
||||
e.message.includes('Error unlocking')) { // udisks (wrong password)
|
||||
this._reaskPassword(volume);
|
||||
} else {
|
||||
if (!e.matches(Gio.IOErrorEnum, Gio.IOErrorEnum.FAILED_HANDLED))
|
||||
|
@ -12,7 +12,7 @@ const SwitcherPopup = imports.ui.switcherPopup;
|
||||
const Params = imports.misc.params;
|
||||
const Tweener = imports.ui.tweener;
|
||||
|
||||
var POPUP_APPICON_SIZE = 96;
|
||||
var POPUP_APPICON_SIZE = 128;
|
||||
var POPUP_FADE_TIME = 0.1; // seconds
|
||||
|
||||
var SortGroup = {
|
||||
@ -125,10 +125,10 @@ var CtrlAltTabManager = new Lang.Class({
|
||||
this._popup = new CtrlAltTabPopup(items);
|
||||
this._popup.show(backward, binding, mask);
|
||||
|
||||
this._popup.actor.connect('destroy',
|
||||
() => {
|
||||
this._popup = null;
|
||||
});
|
||||
this._popup.connect('destroy',
|
||||
() => {
|
||||
this._popup = null;
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
|
@ -38,7 +38,10 @@ var DashItemContainer = new Lang.Class({
|
||||
Extends: St.Widget,
|
||||
|
||||
_init() {
|
||||
this.parent({ style_class: 'dash-item-container' });
|
||||
this.parent({ style_class: 'dash-item-container',
|
||||
pivot_point: new Clutter.Point({ x: .5, y: .5 }),
|
||||
x_expand: true,
|
||||
x_align: Clutter.ActorAlign.CENTER });
|
||||
|
||||
this._labelText = "";
|
||||
this.label = new St.Label({ style_class: 'dash-label'});
|
||||
@ -56,52 +59,20 @@ var DashItemContainer = new Lang.Class({
|
||||
});
|
||||
},
|
||||
|
||||
vfunc_allocate(box, flags) {
|
||||
this.set_allocation(box, flags);
|
||||
|
||||
if (this.child == null)
|
||||
return;
|
||||
|
||||
let availWidth = box.x2 - box.x1;
|
||||
let availHeight = box.y2 - box.y1;
|
||||
let [minChildWidth, minChildHeight, natChildWidth, natChildHeight] =
|
||||
this.child.get_preferred_size();
|
||||
let [childScaleX, childScaleY] = this.child.get_scale();
|
||||
|
||||
let childWidth = Math.min(natChildWidth * childScaleX, availWidth);
|
||||
let childHeight = Math.min(natChildHeight * childScaleY, availHeight);
|
||||
|
||||
let childBox = new Clutter.ActorBox();
|
||||
childBox.x1 = (availWidth - childWidth) / 2;
|
||||
childBox.y1 = (availHeight - childHeight) / 2;
|
||||
childBox.x2 = childBox.x1 + childWidth;
|
||||
childBox.y2 = childBox.y1 + childHeight;
|
||||
|
||||
this.child.allocate(childBox, flags);
|
||||
},
|
||||
|
||||
vfunc_get_preferred_height(forWidth) {
|
||||
let themeNode = this.get_theme_node();
|
||||
|
||||
if (this.child == null)
|
||||
return [0, 0];
|
||||
|
||||
forWidth = themeNode.adjust_for_width(forWidth);
|
||||
let [minHeight, natHeight] = this.child.get_preferred_height(forWidth);
|
||||
return themeNode.adjust_preferred_height(minHeight * this.child.scale_y,
|
||||
natHeight * this.child.scale_y);
|
||||
let [minHeight, natHeight] = this.parent(forWidth);
|
||||
return themeNode.adjust_preferred_height(minHeight * this.scale_y,
|
||||
natHeight * this.scale_y);
|
||||
},
|
||||
|
||||
vfunc_get_preferred_width(forHeight) {
|
||||
let themeNode = this.get_theme_node();
|
||||
|
||||
if (this.child == null)
|
||||
return [0, 0];
|
||||
|
||||
forHeight = themeNode.adjust_for_height(forHeight);
|
||||
let [minWidth, natWidth] = this.child.get_preferred_width(forHeight);
|
||||
return themeNode.adjust_preferred_width(minWidth * this.child.scale_y,
|
||||
natWidth * this.child.scale_y);
|
||||
let [minWidth, natWidth] = this.parent(forHeight);
|
||||
return themeNode.adjust_preferred_width(minWidth * this.scale_x,
|
||||
natWidth * this.scale_x);
|
||||
},
|
||||
|
||||
showLabel() {
|
||||
@ -163,9 +134,8 @@ var DashItemContainer = new Lang.Class({
|
||||
this.child = actor;
|
||||
this.add_actor(this.child);
|
||||
|
||||
this.child.set_scale_with_gravity(this._childScale, this._childScale,
|
||||
Clutter.Gravity.CENTER);
|
||||
this.child.set_opacity(this._childOpacity);
|
||||
this.set_scale(this._childScale, this._childScale);
|
||||
this.set_opacity(this._childOpacity);
|
||||
},
|
||||
|
||||
show(animate) {
|
||||
@ -204,11 +174,7 @@ var DashItemContainer = new Lang.Class({
|
||||
set childScale(scale) {
|
||||
this._childScale = scale;
|
||||
|
||||
if (this.child == null)
|
||||
return;
|
||||
|
||||
this.child.set_scale_with_gravity(scale, scale,
|
||||
Clutter.Gravity.CENTER);
|
||||
this.set_scale(scale, scale);
|
||||
this.queue_relayout();
|
||||
},
|
||||
|
||||
@ -219,10 +185,7 @@ var DashItemContainer = new Lang.Class({
|
||||
set childOpacity(opacity) {
|
||||
this._childOpacity = opacity;
|
||||
|
||||
if (this.child == null)
|
||||
return;
|
||||
|
||||
this.child.set_opacity(opacity);
|
||||
this.set_opacity(opacity);
|
||||
this.queue_redraw();
|
||||
},
|
||||
|
||||
@ -247,7 +210,7 @@ var ShowAppsIcon = new Lang.Class({
|
||||
{ setSizeManually: true,
|
||||
showLabel: false,
|
||||
createIcon: this._createIcon.bind(this) });
|
||||
this.toggleButton.add_actor(this.icon.actor);
|
||||
this.toggleButton.add_actor(this.icon);
|
||||
this.toggleButton._delegate = this;
|
||||
|
||||
this.setChild(this.toggleButton);
|
||||
@ -643,10 +606,10 @@ var Dash = new Lang.Class({
|
||||
|
||||
// Enforce the current icon size during the size request
|
||||
firstIcon.icon.ensure_style();
|
||||
let [currentWidth, currentHeight] = firstIcon.icon.get_size();
|
||||
firstIcon.icon.set_size(this.iconSize * scaleFactor, this.iconSize * scaleFactor);
|
||||
let [, currentHeight] = firstIcon.icon.get_size();
|
||||
firstIcon.icon.set_height(this.iconSize * scaleFactor);
|
||||
[minHeight, natHeight] = firstButton.get_preferred_height(-1);
|
||||
firstIcon.icon.set_size(currentWidth, currentHeight);
|
||||
firstIcon.icon.set_height(currentHeight);
|
||||
|
||||
// Subtract icon padding and box spacing from the available height
|
||||
availHeight -= iconChildren.length * (natHeight - this.iconSize * scaleFactor) +
|
||||
|
@ -69,9 +69,11 @@ var TodayButton = new Lang.Class({
|
||||
this._dayLabel.set_text(date.toLocaleFormat('%A'));
|
||||
|
||||
/* Translators: This is the date format to use when the calendar popup is
|
||||
* shown - it is shown just below the time in the shell (e.g. "Tue 9:29 AM").
|
||||
* shown - it is shown just below the time in the top bar (e.g.,
|
||||
* "Tue 9:29 AM"). The string itself should become a full date, e.g.,
|
||||
* "February 17 2015".
|
||||
*/
|
||||
let dateFormat = Shell.util_translate_time_string (N_("%B %e %Y"));
|
||||
let dateFormat = Shell.util_translate_time_string (N_("%B %-d %Y"));
|
||||
this._dateLabel.set_text(date.toLocaleFormat(dateFormat));
|
||||
|
||||
/* Translators: This is the accessible name of the date button shown
|
||||
|
@ -133,9 +133,9 @@ var CandidatePopup = new Lang.Class({
|
||||
|
||||
_init() {
|
||||
this._boxPointer = new BoxPointer.BoxPointer(St.Side.TOP);
|
||||
this._boxPointer.actor.visible = false;
|
||||
this._boxPointer.actor.style_class = 'candidate-popup-boxpointer';
|
||||
Main.layoutManager.addChrome(this._boxPointer.actor);
|
||||
this._boxPointer.visible = false;
|
||||
this._boxPointer.style_class = 'candidate-popup-boxpointer';
|
||||
Main.layoutManager.addChrome(this._boxPointer);
|
||||
|
||||
let box = new St.BoxLayout({ style_class: 'candidate-popup-content',
|
||||
vertical: true });
|
||||
@ -272,7 +272,7 @@ var CandidatePopup = new Lang.Class({
|
||||
this._updateVisibility();
|
||||
});
|
||||
panelService.connect('focus-out', ps => {
|
||||
this._boxPointer.hide(BoxPointer.PopupAnimation.NONE);
|
||||
this._boxPointer.close(BoxPointer.PopupAnimation.NONE);
|
||||
Main.keyboard.resetSuggestions();
|
||||
});
|
||||
},
|
||||
@ -291,10 +291,10 @@ var CandidatePopup = new Lang.Class({
|
||||
|
||||
if (isVisible) {
|
||||
this._boxPointer.setPosition(Main.layoutManager.dummyCursor, 0);
|
||||
this._boxPointer.show(BoxPointer.PopupAnimation.NONE);
|
||||
this._boxPointer.open(BoxPointer.PopupAnimation.NONE);
|
||||
this._boxPointer.actor.raise_top();
|
||||
} else {
|
||||
this._boxPointer.hide(BoxPointer.PopupAnimation.NONE);
|
||||
this._boxPointer.close(BoxPointer.PopupAnimation.NONE);
|
||||
}
|
||||
},
|
||||
|
||||
|
@ -12,8 +12,8 @@ const Params = imports.misc.params;
|
||||
const Tweener = imports.ui.tweener;
|
||||
const Main = imports.ui.main;
|
||||
|
||||
var ICON_SIZE = 96;
|
||||
var MIN_ICON_SIZE = 16;
|
||||
var ICON_SIZE = 128;
|
||||
var MIN_ICON_SIZE = 32;
|
||||
|
||||
var EXTRA_SPACE_ANIMATION_TIME = 0.25;
|
||||
|
||||
@ -36,6 +36,7 @@ var APPICON_ANIMATION_OUT_TIME = 0.25;
|
||||
|
||||
var BaseIcon = new Lang.Class({
|
||||
Name: 'BaseIcon',
|
||||
Extends: St.Bin,
|
||||
|
||||
_init(label, params) {
|
||||
params = Params.parse(params, { createIcon: null,
|
||||
@ -46,32 +47,26 @@ var BaseIcon = new Lang.Class({
|
||||
if (params.showLabel)
|
||||
styleClass += ' overview-icon-with-label';
|
||||
|
||||
this.actor = new St.Bin({ style_class: styleClass,
|
||||
x_fill: true,
|
||||
y_fill: true });
|
||||
this.actor._delegate = this;
|
||||
this.actor.connect('style-changed', this._onStyleChanged.bind(this));
|
||||
this.actor.connect('destroy', this._onDestroy.bind(this));
|
||||
this.parent({ style_class: styleClass,
|
||||
x_fill: true,
|
||||
y_fill: true });
|
||||
|
||||
this._spacing = 0;
|
||||
this.actor = this;
|
||||
|
||||
let box = new Shell.GenericContainer();
|
||||
box.connect('allocate', this._allocate.bind(this));
|
||||
box.connect('get-preferred-width',
|
||||
this._getPreferredWidth.bind(this));
|
||||
box.connect('get-preferred-height',
|
||||
this._getPreferredHeight.bind(this));
|
||||
this.actor.set_child(box);
|
||||
this.connect('destroy', this._onDestroy.bind(this));
|
||||
|
||||
this._box = new St.BoxLayout({ vertical: true });
|
||||
this.set_child(this._box);
|
||||
|
||||
this.iconSize = ICON_SIZE;
|
||||
this._iconBin = new St.Bin({ x_align: St.Align.MIDDLE,
|
||||
y_align: St.Align.MIDDLE });
|
||||
|
||||
box.add_actor(this._iconBin);
|
||||
this._box.add_actor(this._iconBin);
|
||||
|
||||
if (params.showLabel) {
|
||||
this.label = new St.Label({ text: label });
|
||||
box.add_actor(this.label);
|
||||
this._box.add_actor(this.label);
|
||||
} else {
|
||||
this.label = null;
|
||||
}
|
||||
@ -86,54 +81,9 @@ var BaseIcon = new Lang.Class({
|
||||
this._iconThemeChangedId = cache.connect('icon-theme-changed', this._onIconThemeChanged.bind(this));
|
||||
},
|
||||
|
||||
_allocate(actor, box, flags) {
|
||||
let availWidth = box.x2 - box.x1;
|
||||
let availHeight = box.y2 - box.y1;
|
||||
|
||||
let iconSize = availHeight;
|
||||
|
||||
let [iconMinHeight, iconNatHeight] = this._iconBin.get_preferred_height(-1);
|
||||
let [iconMinWidth, iconNatWidth] = this._iconBin.get_preferred_width(-1);
|
||||
let preferredHeight = iconNatHeight;
|
||||
|
||||
let childBox = new Clutter.ActorBox();
|
||||
|
||||
if (this.label) {
|
||||
let [labelMinHeight, labelNatHeight] = this.label.get_preferred_height(-1);
|
||||
preferredHeight += this._spacing + labelNatHeight;
|
||||
|
||||
let labelHeight = availHeight >= preferredHeight ? labelNatHeight
|
||||
: labelMinHeight;
|
||||
iconSize -= this._spacing + labelHeight;
|
||||
|
||||
childBox.x1 = 0;
|
||||
childBox.x2 = availWidth;
|
||||
childBox.y1 = iconSize + this._spacing;
|
||||
childBox.y2 = childBox.y1 + labelHeight;
|
||||
this.label.allocate(childBox, flags);
|
||||
}
|
||||
|
||||
childBox.x1 = Math.floor((availWidth - iconNatWidth) / 2);
|
||||
childBox.y1 = Math.floor((iconSize - iconNatHeight) / 2);
|
||||
childBox.x2 = childBox.x1 + iconNatWidth;
|
||||
childBox.y2 = childBox.y1 + iconNatHeight;
|
||||
this._iconBin.allocate(childBox, flags);
|
||||
},
|
||||
|
||||
_getPreferredWidth(actor, forHeight, alloc) {
|
||||
this._getPreferredHeight(actor, -1, alloc);
|
||||
},
|
||||
|
||||
_getPreferredHeight(actor, forWidth, alloc) {
|
||||
let [iconMinHeight, iconNatHeight] = this._iconBin.get_preferred_height(forWidth);
|
||||
alloc.min_size = iconMinHeight;
|
||||
alloc.natural_size = iconNatHeight;
|
||||
|
||||
if (this.label) {
|
||||
let [labelMinHeight, labelNatHeight] = this.label.get_preferred_height(forWidth);
|
||||
alloc.min_size += this._spacing + labelMinHeight;
|
||||
alloc.natural_size += this._spacing + labelNatHeight;
|
||||
}
|
||||
vfunc_get_preferred_width(forHeight) {
|
||||
// Return the actual height to keep the squared aspect
|
||||
return this.get_preferred_height(-1);
|
||||
},
|
||||
|
||||
// This can be overridden by a subclass, or by the createIcon
|
||||
@ -161,9 +111,8 @@ var BaseIcon = new Lang.Class({
|
||||
this._iconBin.child = this.icon;
|
||||
},
|
||||
|
||||
_onStyleChanged() {
|
||||
let node = this.actor.get_theme_node();
|
||||
this._spacing = node.get_length('spacing');
|
||||
vfunc_style_changed() {
|
||||
let node = this.get_theme_node();
|
||||
|
||||
let size;
|
||||
if (this._setSizeManually) {
|
||||
@ -195,7 +144,7 @@ var BaseIcon = new Lang.Class({
|
||||
// Animate only the child instead of the entire actor, so the
|
||||
// styles like hover and running are not applied while
|
||||
// animating.
|
||||
zoomOutActor(this.actor.child);
|
||||
zoomOutActor(this.child);
|
||||
}
|
||||
});
|
||||
|
||||
@ -240,8 +189,16 @@ function zoomOutActor(actor) {
|
||||
|
||||
var IconGrid = new Lang.Class({
|
||||
Name: 'IconGrid',
|
||||
Extends: St.Widget,
|
||||
Signals: {'animation-done': {},
|
||||
'child-focused': { param_types: [Clutter.Actor.$gtype]} },
|
||||
|
||||
_init(params) {
|
||||
this.parent({ style_class: 'icon-grid',
|
||||
y_align: Clutter.ActorAlign.START });
|
||||
|
||||
this.actor = this;
|
||||
|
||||
params = Params.parse(params, { rowLimit: null,
|
||||
columnLimit: null,
|
||||
minRows: 1,
|
||||
@ -262,34 +219,27 @@ var IconGrid = new Lang.Class({
|
||||
this.rightPadding = 0;
|
||||
this.leftPadding = 0;
|
||||
|
||||
this.actor = new St.BoxLayout({ style_class: 'icon-grid',
|
||||
vertical: true });
|
||||
this._items = [];
|
||||
this._clonesAnimating = [];
|
||||
// Pulled from CSS, but hardcode some defaults here
|
||||
this._spacing = 0;
|
||||
this._hItemSize = this._vItemSize = ICON_SIZE;
|
||||
this._fixedHItemSize = this._fixedVItemSize = undefined;
|
||||
this._grid = new Shell.GenericContainer();
|
||||
this.actor.add(this._grid, { expand: true, y_align: St.Align.START });
|
||||
this.actor.connect('style-changed', this._onStyleChanged.bind(this));
|
||||
this.connect('style-changed', this._onStyleChanged.bind(this));
|
||||
|
||||
// Cancel animations when hiding the overview, to avoid icons
|
||||
// swarming into the void ...
|
||||
this.actor.connect('notify::mapped', () => {
|
||||
if (!this.actor.mapped)
|
||||
this.connect('notify::mapped', () => {
|
||||
if (!this.mapped)
|
||||
this._cancelAnimation();
|
||||
});
|
||||
|
||||
this._grid.connect('get-preferred-width', this._getPreferredWidth.bind(this));
|
||||
this._grid.connect('get-preferred-height', this._getPreferredHeight.bind(this));
|
||||
this._grid.connect('allocate', this._allocate.bind(this));
|
||||
this._grid.connect('actor-added', this._childAdded.bind(this));
|
||||
this._grid.connect('actor-removed', this._childRemoved.bind(this));
|
||||
this.connect('actor-added', this._childAdded.bind(this));
|
||||
this.connect('actor-removed', this._childRemoved.bind(this));
|
||||
},
|
||||
|
||||
_keyFocusIn(actor) {
|
||||
this.emit('key-focus-in', actor);
|
||||
this.emit('child-focused', actor);
|
||||
},
|
||||
|
||||
_childAdded(grid, child) {
|
||||
@ -300,13 +250,13 @@ var IconGrid = new Lang.Class({
|
||||
child.disconnect(child._iconGridKeyFocusInId);
|
||||
},
|
||||
|
||||
_getPreferredWidth(grid, forHeight, alloc) {
|
||||
vfunc_get_preferred_width(forHeight) {
|
||||
if (this._fillParent)
|
||||
// Ignore all size requests of children and request a size of 0;
|
||||
// later we'll allocate as many children as fit the parent
|
||||
return;
|
||||
return [0, 0];
|
||||
|
||||
let nChildren = this._grid.get_n_children();
|
||||
let nChildren = this.get_n_children();
|
||||
let nColumns = this._colLimit ? Math.min(this._colLimit,
|
||||
nChildren)
|
||||
: nChildren;
|
||||
@ -314,22 +264,28 @@ var IconGrid = new Lang.Class({
|
||||
// Kind of a lie, but not really an issue right now. If
|
||||
// we wanted to support some sort of hidden/overflow that would
|
||||
// need higher level design
|
||||
alloc.min_size = this._getHItemSize() + this.leftPadding + this.rightPadding;
|
||||
alloc.natural_size = nColumns * this._getHItemSize() + totalSpacing + this.leftPadding + this.rightPadding;
|
||||
let minSize = this._getHItemSize() + this.leftPadding + this.rightPadding;
|
||||
let natSize = nColumns * this._getHItemSize() + totalSpacing + this.leftPadding + this.rightPadding;
|
||||
|
||||
return this.get_theme_node().adjust_preferred_width(minSize, natSize);
|
||||
},
|
||||
|
||||
_getVisibleChildren() {
|
||||
return this._grid.get_children().filter(actor => actor.visible);
|
||||
return this.get_children().filter(actor => actor.visible);
|
||||
},
|
||||
|
||||
_getPreferredHeight(grid, forWidth, alloc) {
|
||||
vfunc_get_preferred_height(forWidth) {
|
||||
if (this._fillParent)
|
||||
// Ignore all size requests of children and request a size of 0;
|
||||
// later we'll allocate as many children as fit the parent
|
||||
return;
|
||||
return [0, 0];
|
||||
|
||||
let themeNode = this.get_theme_node();
|
||||
let children = this._getVisibleChildren();
|
||||
let nColumns;
|
||||
|
||||
forWidth = themeNode.adjust_for_width(forWidth);
|
||||
|
||||
if (forWidth < 0)
|
||||
nColumns = children.length;
|
||||
else
|
||||
@ -344,16 +300,21 @@ var IconGrid = new Lang.Class({
|
||||
nRows = Math.min(nRows, this._rowLimit);
|
||||
let totalSpacing = Math.max(0, nRows - 1) * this._getSpacing();
|
||||
let height = nRows * this._getVItemSize() + totalSpacing + this.topPadding + this.bottomPadding;
|
||||
alloc.min_size = height;
|
||||
alloc.natural_size = height;
|
||||
|
||||
return themeNode.adjust_preferred_height(height, height);
|
||||
},
|
||||
|
||||
_allocate(grid, box, flags) {
|
||||
vfunc_allocate(box, flags) {
|
||||
this.set_allocation(box, flags);
|
||||
|
||||
let themeNode = this.get_theme_node();
|
||||
box = themeNode.get_content_box(box);
|
||||
|
||||
if (this._fillParent) {
|
||||
// Reset the passed in box to fill the parent
|
||||
let parentBox = this.actor.get_parent().allocation;
|
||||
let gridBox = this.actor.get_theme_node().get_content_box(parentBox);
|
||||
box = this._grid.get_theme_node().get_content_box(gridBox);
|
||||
let parentBox = this.get_parent().allocation;
|
||||
let gridBox = themeNode.get_content_box(parentBox);
|
||||
box = themeNode.get_content_box(gridBox);
|
||||
}
|
||||
|
||||
let children = this._getVisibleChildren();
|
||||
@ -383,10 +344,10 @@ var IconGrid = new Lang.Class({
|
||||
|
||||
if (this._rowLimit && rowIndex >= this._rowLimit ||
|
||||
this._fillParent && childBox.y2 > availHeight - this.bottomPadding) {
|
||||
this._grid.set_skip_paint(children[i], true);
|
||||
children[i]._skipPaint = true;
|
||||
} else {
|
||||
children[i].allocate(childBox, flags);
|
||||
this._grid.set_skip_paint(children[i], false);
|
||||
children[i]._skipPaint = false;
|
||||
}
|
||||
|
||||
columnIndex++;
|
||||
@ -404,6 +365,66 @@ var IconGrid = new Lang.Class({
|
||||
}
|
||||
},
|
||||
|
||||
vfunc_paint() {
|
||||
this.paint_background();
|
||||
|
||||
this.get_children().forEach(c => {
|
||||
if (!c._skipPaint)
|
||||
c.paint();
|
||||
});
|
||||
},
|
||||
|
||||
vfunc_pick(color) {
|
||||
this.parent(color);
|
||||
|
||||
this.get_children().forEach(c => {
|
||||
if (!c._skipPaint)
|
||||
c.paint();
|
||||
});
|
||||
},
|
||||
|
||||
vfunc_get_paint_volume(paintVolume) {
|
||||
// Setting the paint volume does not make sense when we don't have
|
||||
// any allocation
|
||||
if (!this.has_allocation())
|
||||
return false;
|
||||
|
||||
let themeNode = this.get_theme_node();
|
||||
let allocationBox = this.get_allocation_box();
|
||||
let paintBox = themeNode.get_paint_box(allocationBox);
|
||||
|
||||
let origin = new Clutter.Vertex();
|
||||
origin.x = paintBox.x1 - allocationBox.x1;
|
||||
origin.y = paintBox.y1 - allocationBox.y1;
|
||||
origin.z = 0.0;
|
||||
|
||||
paintVolume.set_origin(origin);
|
||||
paintVolume.set_width(paintBox.x2 - paintBox.x1);
|
||||
paintVolume.set_height(paintBox.y2 - paintBox.y1);
|
||||
|
||||
if (this.get_clip_to_allocation())
|
||||
return true;
|
||||
|
||||
for (let child = this.get_first_child();
|
||||
child != null;
|
||||
child = child.get_next_sibling()) {
|
||||
|
||||
if (!child.visible)
|
||||
continue;
|
||||
|
||||
if (child._skipPaint)
|
||||
continue;
|
||||
|
||||
let childVolume = child.get_transformed_paint_volume(this);
|
||||
if (!childVolume)
|
||||
return false
|
||||
|
||||
paintVolume.union(childVolume);
|
||||
}
|
||||
|
||||
return true;
|
||||
},
|
||||
|
||||
/**
|
||||
* Intended to be override by subclasses if they need a different
|
||||
* set of items to be animated.
|
||||
@ -629,11 +650,11 @@ var IconGrid = new Lang.Class({
|
||||
},
|
||||
|
||||
_onStyleChanged() {
|
||||
let themeNode = this.actor.get_theme_node();
|
||||
let themeNode = this.get_theme_node();
|
||||
this._spacing = themeNode.get_length('spacing');
|
||||
this._hItemSize = themeNode.get_length('-shell-grid-horizontal-item-size') || ICON_SIZE;
|
||||
this._vItemSize = themeNode.get_length('-shell-grid-vertical-item-size') || ICON_SIZE;
|
||||
this._grid.queue_relayout();
|
||||
this.queue_relayout();
|
||||
},
|
||||
|
||||
nRows(forWidth) {
|
||||
@ -665,12 +686,12 @@ var IconGrid = new Lang.Class({
|
||||
|
||||
removeAll() {
|
||||
this._items = [];
|
||||
this._grid.remove_all_children();
|
||||
this.remove_all_children();
|
||||
},
|
||||
|
||||
destroyAll() {
|
||||
this._items = [];
|
||||
this._grid.destroy_all_children();
|
||||
this.destroy_all_children();
|
||||
},
|
||||
|
||||
addItem(item, index) {
|
||||
@ -679,21 +700,21 @@ var IconGrid = new Lang.Class({
|
||||
|
||||
this._items.push(item);
|
||||
if (index !== undefined)
|
||||
this._grid.insert_child_at_index(item.actor, index);
|
||||
this.insert_child_at_index(item.actor, index);
|
||||
else
|
||||
this._grid.add_actor(item.actor);
|
||||
this.add_actor(item.actor);
|
||||
},
|
||||
|
||||
removeItem(item) {
|
||||
this._grid.remove_child(item.actor);
|
||||
this.remove_child(item.actor);
|
||||
},
|
||||
|
||||
getItemAtIndex(index) {
|
||||
return this._grid.get_child_at_index(index);
|
||||
return this.get_child_at_index(index);
|
||||
},
|
||||
|
||||
visibleItemsCount() {
|
||||
return this._grid.get_n_children() - this._grid.get_n_skip_paint();
|
||||
return this.get_children().filter(c => !c._skipPaint).length;
|
||||
},
|
||||
|
||||
setSpacing(spacing) {
|
||||
@ -779,11 +800,12 @@ var IconGrid = new Lang.Class({
|
||||
}
|
||||
}
|
||||
});
|
||||
Signals.addSignalMethods(IconGrid.prototype);
|
||||
|
||||
var PaginatedIconGrid = new Lang.Class({
|
||||
Name: 'PaginatedIconGrid',
|
||||
Extends: IconGrid,
|
||||
Signals: {'space-opened': {},
|
||||
'space-closed': {} },
|
||||
|
||||
_init(params) {
|
||||
this.parent(params);
|
||||
@ -794,20 +816,22 @@ var PaginatedIconGrid = new Lang.Class({
|
||||
this._childrenPerPage = 0;
|
||||
},
|
||||
|
||||
_getPreferredHeight(grid, forWidth, alloc) {
|
||||
alloc.min_size = (this._availableHeightPerPageForItems() + this.bottomPadding + this.topPadding) * this._nPages + this._spaceBetweenPages * this._nPages;
|
||||
alloc.natural_size = (this._availableHeightPerPageForItems() + this.bottomPadding + this.topPadding) * this._nPages + this._spaceBetweenPages * this._nPages;
|
||||
vfunc_get_preferred_height(forWidth) {
|
||||
let height = (this._availableHeightPerPageForItems() + this.bottomPadding + this.topPadding) * this._nPages + this._spaceBetweenPages * this._nPages;
|
||||
return [height, height];
|
||||
},
|
||||
|
||||
_allocate(grid, box, flags) {
|
||||
vfunc_allocate(box, flags) {
|
||||
if (this._childrenPerPage == 0)
|
||||
log('computePages() must be called before allocate(); pagination will not work.');
|
||||
|
||||
this.set_allocation(box, flags);
|
||||
|
||||
if (this._fillParent) {
|
||||
// Reset the passed in box to fill the parent
|
||||
let parentBox = this.actor.get_parent().allocation;
|
||||
let gridBox = this.actor.get_theme_node().get_content_box(parentBox);
|
||||
box = this._grid.get_theme_node().get_content_box(gridBox);
|
||||
let parentBox = this.get_parent().allocation;
|
||||
let gridBox = this.get_theme_node().get_content_box(parentBox);
|
||||
box = this.get_theme_node().get_content_box(gridBox);
|
||||
}
|
||||
let children = this._getVisibleChildren();
|
||||
let availWidth = box.x2 - box.x1;
|
||||
@ -835,7 +859,7 @@ var PaginatedIconGrid = new Lang.Class({
|
||||
for (let i = 0; i < children.length; i++) {
|
||||
let childBox = this._calculateChildBox(children[i], x, y, box);
|
||||
children[i].allocate(childBox, flags);
|
||||
this._grid.set_skip_paint(children[i], false);
|
||||
children[i]._skipPaint = false;
|
||||
|
||||
columnIndex++;
|
||||
if (columnIndex == nColumns) {
|
||||
@ -1006,4 +1030,3 @@ var PaginatedIconGrid = new Lang.Class({
|
||||
}
|
||||
}
|
||||
});
|
||||
Signals.addSignalMethods(PaginatedIconGrid.prototype);
|
||||
|
@ -269,7 +269,7 @@ var Key = new Lang.Class({
|
||||
|
||||
_onDestroy() {
|
||||
if (this._boxPointer) {
|
||||
this._boxPointer.actor.destroy();
|
||||
this._boxPointer.destroy();
|
||||
this._boxPointer = null;
|
||||
}
|
||||
},
|
||||
@ -282,7 +282,7 @@ var Key = new Lang.Class({
|
||||
{ x_fill: true,
|
||||
y_fill: true,
|
||||
x_align: St.Align.START });
|
||||
this._boxPointer.actor.hide();
|
||||
this._boxPointer.hide();
|
||||
Main.layoutManager.addChrome(this._boxPointer.actor);
|
||||
this._boxPointer.setPosition(this.keyButton, 0.5);
|
||||
|
||||
@ -356,7 +356,7 @@ var Key = new Lang.Class({
|
||||
},
|
||||
|
||||
_showSubkeys() {
|
||||
this._boxPointer.show(BoxPointer.PopupAnimation.FULL);
|
||||
this._boxPointer.open(BoxPointer.PopupAnimation.FULL);
|
||||
this._capturedEventId = global.stage.connect('captured-event',
|
||||
this._onCapturedEvent.bind(this));
|
||||
this._unmapId = this.keyButton.connect('notify::mapped', () => {
|
||||
@ -367,7 +367,7 @@ var Key = new Lang.Class({
|
||||
|
||||
_hideSubkeys() {
|
||||
if (this._boxPointer)
|
||||
this._boxPointer.hide(BoxPointer.PopupAnimation.FULL);
|
||||
this._boxPointer.close(BoxPointer.PopupAnimation.FULL);
|
||||
if (this._capturedEventId) {
|
||||
global.stage.disconnect(this._capturedEventId);
|
||||
this._capturedEventId = 0;
|
||||
|
@ -177,8 +177,16 @@ const defaultParams = {
|
||||
|
||||
var LayoutManager = new Lang.Class({
|
||||
Name: 'LayoutManager',
|
||||
Extends: GObject.Object,
|
||||
Signals: { 'hot-corners-changed': {},
|
||||
'startup-complete': {},
|
||||
'startup-prepared': {},
|
||||
'monitors-changed': {},
|
||||
'keyboard-visible-changed': { param_types: [GObject.TYPE_BOOLEAN] } },
|
||||
|
||||
_init() {
|
||||
this.parent();
|
||||
|
||||
this._rtl = (Clutter.get_default_text_direction() == Clutter.TextDirection.RTL);
|
||||
this.monitors = [];
|
||||
this.primaryMonitor = null;
|
||||
@ -203,21 +211,12 @@ var LayoutManager = new Lang.Class({
|
||||
global.stage.no_clear_hint = true;
|
||||
|
||||
// Set up stage hierarchy to group all UI actors under one container.
|
||||
this.uiGroup = new Shell.GenericContainer({ name: 'uiGroup' });
|
||||
this.uiGroup = new St.Widget({ name: 'uiGroup' });
|
||||
this.uiGroup.set_flags(Clutter.ActorFlags.NO_LAYOUT);
|
||||
this.uiGroup.connect('allocate', (actor, box, flags) => {
|
||||
let children = actor.get_children();
|
||||
for (let i = 0; i < children.length; i++)
|
||||
children[i].allocate_preferred_size(flags);
|
||||
});
|
||||
this.uiGroup.connect('get-preferred-width', (actor, forHeight, alloc) => {
|
||||
let width = global.stage.width;
|
||||
[alloc.min_size, alloc.natural_size] = [width, width];
|
||||
});
|
||||
this.uiGroup.connect('get-preferred-height', (actor, forWidth, alloc) => {
|
||||
let height = global.stage.height;
|
||||
[alloc.min_size, alloc.natural_size] = [height, height];
|
||||
});
|
||||
this.uiGroup.add_constraint(new Clutter.BindConstraint({
|
||||
source: global.stage,
|
||||
coordinate: Clutter.BindCoordinate.ALL,
|
||||
}));
|
||||
|
||||
global.stage.remove_actor(global.window_group);
|
||||
this.uiGroup.add_actor(global.window_group);
|
||||
@ -1078,7 +1077,6 @@ var LayoutManager = new Lang.Class({
|
||||
this._queueUpdateRegions();
|
||||
},
|
||||
});
|
||||
Signals.addSignalMethods(LayoutManager.prototype);
|
||||
|
||||
|
||||
// HotCorner:
|
||||
|
@ -4,6 +4,7 @@ const Clutter = imports.gi.Clutter;
|
||||
const Cogl = imports.gi.Cogl;
|
||||
const GLib = imports.gi.GLib;
|
||||
const Gio = imports.gi.Gio;
|
||||
const GObject = imports.gi.GObject;
|
||||
const Gtk = imports.gi.Gtk;
|
||||
const Meta = imports.gi.Meta;
|
||||
const Pango = imports.gi.Pango;
|
||||
@ -501,18 +502,21 @@ var RedBorderEffect = new Lang.Class({
|
||||
|
||||
var Inspector = new Lang.Class({
|
||||
Name: 'Inspector',
|
||||
Extends: Clutter.Actor,
|
||||
Signals: { 'closed': {},
|
||||
'target': { param_types: [Clutter.Actor.$gtype, GObject.TYPE_DOUBLE, GObject.TYPE_DOUBLE] } },
|
||||
|
||||
_init(lookingGlass) {
|
||||
let container = new Shell.GenericContainer({ width: 0,
|
||||
height: 0 });
|
||||
container.connect('allocate', this._allocate.bind(this));
|
||||
Main.uiGroup.add_actor(container);
|
||||
this.parent({ width: 0,
|
||||
height: 0 });
|
||||
|
||||
Main.uiGroup.add_actor(this);
|
||||
|
||||
let eventHandler = new St.BoxLayout({ name: 'LookingGlassDialog',
|
||||
vertical: false,
|
||||
reactive: true });
|
||||
this._eventHandler = eventHandler;
|
||||
container.add_actor(eventHandler);
|
||||
this.add_actor(eventHandler);
|
||||
this._displayText = new St.Label();
|
||||
eventHandler.add(this._displayText, { expand: true });
|
||||
|
||||
@ -534,7 +538,9 @@ var Inspector = new Lang.Class({
|
||||
this._lookingGlass = lookingGlass;
|
||||
},
|
||||
|
||||
_allocate(actor, box, flags) {
|
||||
vfunc_allocate(box, flags) {
|
||||
this.set_allocation(box, flags);
|
||||
|
||||
if (!this._eventHandler)
|
||||
return;
|
||||
|
||||
@ -631,8 +637,6 @@ var Inspector = new Lang.Class({
|
||||
}
|
||||
});
|
||||
|
||||
Signals.addSignalMethods(Inspector.prototype);
|
||||
|
||||
var Extensions = new Lang.Class({
|
||||
Name: 'Extensions',
|
||||
|
||||
|
@ -50,12 +50,15 @@ var State = {
|
||||
// These reasons are useful when we destroy the notifications received through
|
||||
// the notification daemon. We use EXPIRED for notifications that we dismiss
|
||||
// and the user did not interact with, DISMISSED for all other notifications
|
||||
// that were destroyed as a result of a user action, and SOURCE_CLOSED for the
|
||||
// notifications that were requested to be destroyed by the associated source.
|
||||
// that were destroyed as a result of a user action, SOURCE_CLOSED for the
|
||||
// notifications that were requested to be destroyed by the associated source,
|
||||
// and REPLACED for notifications that were destroyed as a consequence of a
|
||||
// newer version having replaced them.
|
||||
var NotificationDestroyedReason = {
|
||||
EXPIRED: 1,
|
||||
DISMISSED: 2,
|
||||
SOURCE_CLOSED: 3
|
||||
SOURCE_CLOSED: 3,
|
||||
REPLACED: 4
|
||||
};
|
||||
|
||||
// Message tray has its custom Urgency enumeration. LOW, NORMAL and CRITICAL
|
||||
@ -587,16 +590,16 @@ var NotificationBanner = new Lang.Class({
|
||||
|
||||
var SourceActor = new Lang.Class({
|
||||
Name: 'SourceActor',
|
||||
Extends: St.Widget,
|
||||
|
||||
_init(source, size) {
|
||||
this.parent();
|
||||
|
||||
this._source = source;
|
||||
this._size = size;
|
||||
|
||||
this.actor = new Shell.GenericContainer();
|
||||
this.actor.connect('get-preferred-width', this._getPreferredWidth.bind(this));
|
||||
this.actor.connect('get-preferred-height', this._getPreferredHeight.bind(this));
|
||||
this.actor.connect('allocate', this._allocate.bind(this));
|
||||
this.actor.connect('destroy', () => {
|
||||
this.actor = this;
|
||||
this.connect('destroy', () => {
|
||||
this._source.disconnect(this._iconUpdatedId);
|
||||
this._actorDestroyed = true;
|
||||
});
|
||||
@ -604,10 +607,11 @@ var SourceActor = new Lang.Class({
|
||||
|
||||
let scale_factor = St.ThemeContext.get_for_stage(global.stage).scale_factor;
|
||||
this._iconBin = new St.Bin({ x_fill: true,
|
||||
x_expand: true,
|
||||
height: size * scale_factor,
|
||||
width: size * scale_factor });
|
||||
|
||||
this.actor.add_actor(this._iconBin);
|
||||
this.add_actor(this._iconBin);
|
||||
|
||||
this._iconUpdatedId = this._source.connect('icon-updated', this._updateIcon.bind(this));
|
||||
this._updateIcon();
|
||||
@ -618,21 +622,6 @@ var SourceActor = new Lang.Class({
|
||||
this._iconSet = true;
|
||||
},
|
||||
|
||||
_getPreferredWidth(actor, forHeight, alloc) {
|
||||
let [min, nat] = this._iconBin.get_preferred_width(forHeight);
|
||||
alloc.min_size = min; alloc.nat_size = nat;
|
||||
},
|
||||
|
||||
_getPreferredHeight(actor, forWidth, alloc) {
|
||||
let [min, nat] = this._iconBin.get_preferred_height(forWidth);
|
||||
alloc.min_size = min; alloc.nat_size = nat;
|
||||
},
|
||||
|
||||
_allocate(actor, box, flags) {
|
||||
// the iconBin should fill our entire box
|
||||
this._iconBin.allocate(box, flags);
|
||||
},
|
||||
|
||||
_updateIcon() {
|
||||
if (this._actorDestroyed)
|
||||
return;
|
||||
@ -665,23 +654,23 @@ var SourceActorWithLabel = new Lang.Class({
|
||||
this._counterBin.translation_y = themeNode.get_length('-shell-counter-overlap-y');
|
||||
});
|
||||
|
||||
this.actor.add_actor(this._counterBin);
|
||||
this.add_actor(this._counterBin);
|
||||
|
||||
this._countUpdatedId = this._source.connect('count-updated', this._updateCount.bind(this));
|
||||
this._updateCount();
|
||||
|
||||
this.actor.connect('destroy', () => {
|
||||
this.connect('destroy', () => {
|
||||
this._source.disconnect(this._countUpdatedId);
|
||||
});
|
||||
},
|
||||
|
||||
_allocate(actor, box, flags) {
|
||||
this.parent(actor, box, flags);
|
||||
vfunc_allocate(box, flags) {
|
||||
this.parent(box, flags);
|
||||
|
||||
let childBox = new Clutter.ActorBox();
|
||||
|
||||
let [minWidth, minHeight, naturalWidth, naturalHeight] = this._counterBin.get_preferred_size();
|
||||
let direction = this.actor.get_text_direction();
|
||||
let direction = this.get_text_direction();
|
||||
|
||||
if (direction == Clutter.TextDirection.LTR) {
|
||||
// allocate on the right in LTR
|
||||
|
@ -77,8 +77,10 @@ var FdoNotificationDaemon = new Lang.Class({
|
||||
bitsPerSample, nChannels, data] = hints['image-data'];
|
||||
return Shell.util_create_pixbuf_from_data(data, GdkPixbuf.Colorspace.RGB, hasAlpha,
|
||||
bitsPerSample, width, height, rowStride);
|
||||
} else if (hints['image-path']) {
|
||||
return new Gio.FileIcon({ file: Gio.File.new_for_path(hints['image-path']) });
|
||||
}
|
||||
return this._iconForNotificationData(hints['image-path']);
|
||||
return null;
|
||||
},
|
||||
|
||||
_fallbackIconForNotificationData(hints) {
|
||||
@ -658,6 +660,10 @@ var GtkNotificationDaemonAppSource = new Lang.Class({
|
||||
return new FdoApplicationProxy(Gio.DBus.session, this._appId, this._objectPath, callback);
|
||||
},
|
||||
|
||||
_createNotification(params) {
|
||||
return new GtkNotificationDaemonNotification(this, params);
|
||||
},
|
||||
|
||||
activateAction(actionId, target) {
|
||||
this._createApp((app, error) => {
|
||||
if (error == null)
|
||||
@ -684,9 +690,9 @@ var GtkNotificationDaemonAppSource = new Lang.Class({
|
||||
this._notificationPending = true;
|
||||
|
||||
if (this._notifications[notificationId])
|
||||
this._notifications[notificationId].destroy();
|
||||
this._notifications[notificationId].destroy(MessageTray.NotificationDestroyedReason.REPLACED);
|
||||
|
||||
let notification = new GtkNotificationDaemonNotification(this, notificationParams);
|
||||
let notification = this._createNotification(notificationParams);
|
||||
notification.connect('destroy', () => {
|
||||
delete this._notifications[notificationId];
|
||||
});
|
||||
|
@ -226,7 +226,7 @@ var Overview = new Lang.Class({
|
||||
|
||||
// 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.actor }),
|
||||
this._panelGhost = new St.Bin({ child: new Clutter.Clone({ source: Main.panel }),
|
||||
reactive: false,
|
||||
opacity: 0 });
|
||||
this._overview.add_actor(this._panelGhost);
|
||||
|
@ -250,7 +250,7 @@ var ThumbnailsSlider = new Lang.Class({
|
||||
this.actor.request_mode = Clutter.RequestMode.WIDTH_FOR_HEIGHT;
|
||||
this.actor.reactive = true;
|
||||
this.actor.track_hover = true;
|
||||
this.actor.add_actor(this._thumbnailsBox.actor);
|
||||
this.actor.add_actor(this._thumbnailsBox);
|
||||
|
||||
Main.layoutManager.connect('monitors-changed', this._updateSlide.bind(this));
|
||||
global.workspace_manager.connect('active-workspace-changed',
|
||||
@ -258,7 +258,7 @@ var ThumbnailsSlider = new Lang.Class({
|
||||
global.workspace_manager.connect('notify::n-workspaces',
|
||||
this._updateSlide.bind(this));
|
||||
this.actor.connect('notify::hover', this._updateSlide.bind(this));
|
||||
this._thumbnailsBox.actor.bind_property('visible', this.actor, 'visible', GObject.BindingFlags.SYNC_CREATE);
|
||||
this._thumbnailsBox.bind_property('visible', this.actor, 'visible', GObject.BindingFlags.SYNC_CREATE);
|
||||
},
|
||||
|
||||
_getAlwaysZoomOut() {
|
||||
|
@ -86,6 +86,7 @@ function _unpremultiply(color) {
|
||||
var AppMenuButton = new Lang.Class({
|
||||
Name: 'AppMenuButton',
|
||||
Extends: PanelMenu.Button,
|
||||
Signals: {'changed': {}},
|
||||
|
||||
_init(panel) {
|
||||
this.parent(0.0, null, true);
|
||||
@ -127,7 +128,7 @@ var AppMenuButton = new Lang.Class({
|
||||
this._visible = this._gtkSettings.gtk_shell_shows_app_menu &&
|
||||
!Main.overview.visible;
|
||||
if (!this._visible)
|
||||
this.actor.hide();
|
||||
this.hide();
|
||||
this._overviewHidingId = Main.overview.connect('hiding', this._sync.bind(this));
|
||||
this._overviewShowingId = Main.overview.connect('showing', this._sync.bind(this));
|
||||
this._showsAppMenuId = this._gtkSettings.connect('notify::gtk-shell-shows-app-menu',
|
||||
@ -149,13 +150,13 @@ var AppMenuButton = new Lang.Class({
|
||||
this._sync();
|
||||
},
|
||||
|
||||
show() {
|
||||
fadeIn() {
|
||||
if (this._visible)
|
||||
return;
|
||||
|
||||
this._visible = true;
|
||||
this.actor.reactive = true;
|
||||
this.actor.show();
|
||||
this.show();
|
||||
Tweener.removeTweens(this.actor);
|
||||
Tweener.addTween(this.actor,
|
||||
{ opacity: 255,
|
||||
@ -163,7 +164,7 @@ var AppMenuButton = new Lang.Class({
|
||||
transition: 'easeOutQuad' });
|
||||
},
|
||||
|
||||
hide() {
|
||||
fadeOut() {
|
||||
if (!this._visible)
|
||||
return;
|
||||
|
||||
@ -175,7 +176,7 @@ var AppMenuButton = new Lang.Class({
|
||||
time: Overview.ANIMATION_TIME,
|
||||
transition: 'easeOutQuad',
|
||||
onComplete() {
|
||||
this.actor.hide();
|
||||
this.hide();
|
||||
},
|
||||
onCompleteScope: this });
|
||||
},
|
||||
@ -314,9 +315,9 @@ var AppMenuButton = new Lang.Class({
|
||||
shellShowsAppMenu &&
|
||||
!Main.overview.visibleTarget);
|
||||
if (visible)
|
||||
this.show();
|
||||
this.fadeIn();
|
||||
else
|
||||
this.hide();
|
||||
this.fadeOut();
|
||||
|
||||
let isBusy = (this._targetApp != null &&
|
||||
(this._targetApp.get_state() == Shell.AppState.STARTING ||
|
||||
@ -366,7 +367,7 @@ var AppMenuButton = new Lang.Class({
|
||||
this._menuManager.addMenu(menu);
|
||||
},
|
||||
|
||||
destroy() {
|
||||
_onDestroy() {
|
||||
if (this._appStateChangedSignalId > 0) {
|
||||
let appSys = Shell.AppSystem.get_default();
|
||||
appSys.disconnect(this._appStateChangedSignalId);
|
||||
@ -398,8 +399,6 @@ var AppMenuButton = new Lang.Class({
|
||||
}
|
||||
});
|
||||
|
||||
Signals.addSignalMethods(AppMenuButton.prototype);
|
||||
|
||||
var ActivitiesButton = new Lang.Class({
|
||||
Name: 'ActivitiesButton',
|
||||
Extends: PanelMenu.Button,
|
||||
@ -774,12 +773,16 @@ const PANEL_ITEM_IMPLEMENTATIONS = {
|
||||
|
||||
var Panel = new Lang.Class({
|
||||
Name: 'Panel',
|
||||
Extends: St.Widget,
|
||||
|
||||
_init() {
|
||||
this.actor = new Shell.GenericContainer({ name: 'panel',
|
||||
reactive: true });
|
||||
this.actor._delegate = this;
|
||||
this.actor.set_offscreen_redirect(Clutter.OffscreenRedirect.ALWAYS);
|
||||
this.parent({ name: 'panel',
|
||||
reactive: true });
|
||||
|
||||
// For compatibility with extensions that still use the
|
||||
// this.actor field
|
||||
this.actor = this;
|
||||
this.set_offscreen_redirect(Clutter.OffscreenRedirect.ALWAYS);
|
||||
|
||||
this._sessionStyle = null;
|
||||
|
||||
@ -788,36 +791,33 @@ var Panel = new Lang.Class({
|
||||
this.menuManager = new PopupMenu.PopupMenuManager(this);
|
||||
|
||||
this._leftBox = new St.BoxLayout({ name: 'panelLeft' });
|
||||
this.actor.add_actor(this._leftBox);
|
||||
this.add_child(this._leftBox);
|
||||
this._centerBox = new St.BoxLayout({ name: 'panelCenter' });
|
||||
this.actor.add_actor(this._centerBox);
|
||||
this.add_child(this._centerBox);
|
||||
this._rightBox = new St.BoxLayout({ name: 'panelRight' });
|
||||
this.actor.add_actor(this._rightBox);
|
||||
this.add_child(this._rightBox);
|
||||
|
||||
this._leftCorner = new PanelCorner(St.Side.LEFT);
|
||||
this.actor.add_actor(this._leftCorner.actor);
|
||||
this.add_child(this._leftCorner.actor);
|
||||
|
||||
this._rightCorner = new PanelCorner(St.Side.RIGHT);
|
||||
this.actor.add_actor(this._rightCorner.actor);
|
||||
this.add_child(this._rightCorner.actor);
|
||||
|
||||
this.actor.connect('get-preferred-width', this._getPreferredWidth.bind(this));
|
||||
this.actor.connect('get-preferred-height', this._getPreferredHeight.bind(this));
|
||||
this.actor.connect('allocate', this._allocate.bind(this));
|
||||
this.actor.connect('button-press-event', this._onButtonPress.bind(this));
|
||||
this.actor.connect('touch-event', this._onButtonPress.bind(this));
|
||||
this.actor.connect('key-press-event', this._onKeyPress.bind(this));
|
||||
this.connect('button-press-event', this._onButtonPress.bind(this));
|
||||
this.connect('touch-event', this._onButtonPress.bind(this));
|
||||
this.connect('key-press-event', this._onKeyPress.bind(this));
|
||||
|
||||
Main.overview.connect('showing', () => {
|
||||
this.actor.add_style_pseudo_class('overview');
|
||||
this.add_style_pseudo_class('overview');
|
||||
this._updateSolidStyle();
|
||||
});
|
||||
Main.overview.connect('hiding', () => {
|
||||
this.actor.remove_style_pseudo_class('overview');
|
||||
this.remove_style_pseudo_class('overview');
|
||||
this._updateSolidStyle();
|
||||
});
|
||||
|
||||
Main.layoutManager.panelBox.add(this.actor);
|
||||
Main.ctrlAltTabManager.addGroup(this.actor, _("Top Bar"), 'focus-top-bar-symbolic',
|
||||
Main.layoutManager.panelBox.add(this);
|
||||
Main.ctrlAltTabManager.addGroup(this, _("Top Bar"), 'focus-top-bar-symbolic',
|
||||
{ sortGroup: CtrlAltTab.SortGroup.TOP });
|
||||
|
||||
Main.sessionMode.connect('updated', this._updatePanel.bind(this));
|
||||
@ -827,7 +827,7 @@ var Panel = new Lang.Class({
|
||||
global.window_group.connect('actor-removed', this._onWindowActorRemoved.bind(this));
|
||||
global.window_manager.connect('switch-workspace', this._updateSolidStyle.bind(this));
|
||||
|
||||
global.display.connect('workareas-changed', () => { this.actor.queue_relayout(); });
|
||||
global.display.connect('workareas-changed', () => { this.queue_relayout(); });
|
||||
this._updatePanel();
|
||||
},
|
||||
|
||||
@ -847,24 +847,18 @@ var Panel = new Lang.Class({
|
||||
this._updateSolidStyle();
|
||||
},
|
||||
|
||||
_getPreferredWidth(actor, forHeight, alloc) {
|
||||
vfunc_get_preferred_width(actor, forHeight) {
|
||||
let primaryMonitor = Main.layoutManager.primaryMonitor;
|
||||
|
||||
alloc.min_size = -1;
|
||||
|
||||
if (primaryMonitor)
|
||||
alloc.natural_size = primaryMonitor.width;
|
||||
else
|
||||
alloc.natural_size = -1;
|
||||
return [0, primaryMonitor.width];
|
||||
|
||||
return [0, 0];
|
||||
},
|
||||
|
||||
_getPreferredHeight(actor, forWidth, alloc) {
|
||||
// We don't need to implement this; it's forced by the CSS
|
||||
alloc.min_size = -1;
|
||||
alloc.natural_size = -1;
|
||||
},
|
||||
vfunc_allocate(box, flags) {
|
||||
this.parent(box, flags);
|
||||
|
||||
_allocate(actor, box, flags) {
|
||||
let allocWidth = box.x2 - box.x1;
|
||||
let allocHeight = box.y2 - box.y1;
|
||||
|
||||
@ -876,7 +870,7 @@ var Panel = new Lang.Class({
|
||||
centerWidth = centerNaturalWidth;
|
||||
|
||||
// get workspace area and center date entry relative to it
|
||||
let monitor = Main.layoutManager.findMonitorForActor(actor);
|
||||
let monitor = Main.layoutManager.findMonitorForActor(this);
|
||||
let centerOffset = 0;
|
||||
if (monitor) {
|
||||
let workArea = Main.layoutManager.getWorkAreaForMonitor(monitor.index);
|
||||
@ -889,7 +883,7 @@ var Panel = new Lang.Class({
|
||||
|
||||
childBox.y1 = 0;
|
||||
childBox.y2 = allocHeight;
|
||||
if (this.actor.get_text_direction() == Clutter.TextDirection.RTL) {
|
||||
if (this.get_text_direction() == Clutter.TextDirection.RTL) {
|
||||
childBox.x1 = Math.max(allocWidth - Math.min(Math.floor(sideWidth),
|
||||
leftNaturalWidth),
|
||||
0);
|
||||
@ -909,7 +903,7 @@ var Panel = new Lang.Class({
|
||||
|
||||
childBox.y1 = 0;
|
||||
childBox.y2 = allocHeight;
|
||||
if (this.actor.get_text_direction() == Clutter.TextDirection.RTL) {
|
||||
if (this.get_text_direction() == Clutter.TextDirection.RTL) {
|
||||
childBox.x1 = 0;
|
||||
childBox.x2 = Math.min(Math.floor(sideWidth),
|
||||
rightNaturalWidth);
|
||||
@ -1069,7 +1063,7 @@ var Panel = new Lang.Class({
|
||||
if (this._sessionStyle)
|
||||
this._addStyleClassName(this._sessionStyle);
|
||||
|
||||
if (this.actor.get_text_direction() == Clutter.TextDirection.RTL) {
|
||||
if (this.get_text_direction() == Clutter.TextDirection.RTL) {
|
||||
this._leftCorner.setStyleParent(this._rightBox);
|
||||
this._rightCorner.setStyleParent(this._leftBox);
|
||||
} else {
|
||||
@ -1079,7 +1073,7 @@ var Panel = new Lang.Class({
|
||||
},
|
||||
|
||||
_updateSolidStyle() {
|
||||
if (this.actor.has_style_pseudo_class('overview') || !Main.sessionMode.hasWindows) {
|
||||
if (this.has_style_pseudo_class('overview') || !Main.sessionMode.hasWindows) {
|
||||
this._removeStyleClassName('solid');
|
||||
return;
|
||||
}
|
||||
@ -1098,8 +1092,8 @@ var Panel = new Lang.Class({
|
||||
});
|
||||
|
||||
/* Check if at least one window is near enough to the panel */
|
||||
let [, panelTop] = this.actor.get_transformed_position();
|
||||
let panelBottom = panelTop + this.actor.get_height();
|
||||
let [, panelTop] = this.get_transformed_position();
|
||||
let panelBottom = panelTop + this.get_height();
|
||||
let scale = St.ThemeContext.get_for_stage(global.stage).scale_factor;
|
||||
let isNearEnough = windows.some(metaWindow => {
|
||||
let verticalPosition = metaWindow.get_frame_rect().y;
|
||||
@ -1165,7 +1159,6 @@ var Panel = new Lang.Class({
|
||||
let destroyId = indicator.connect('destroy', emitter => {
|
||||
delete this.statusArea[role];
|
||||
emitter.disconnect(destroyId);
|
||||
container.destroy();
|
||||
});
|
||||
indicator.connect('menu-set', this._onMenuSet.bind(this));
|
||||
this._onMenuSet(indicator);
|
||||
@ -1191,13 +1184,13 @@ var Panel = new Lang.Class({
|
||||
},
|
||||
|
||||
_addStyleClassName(className) {
|
||||
this.actor.add_style_class_name(className);
|
||||
this.add_style_class_name(className);
|
||||
this._rightCorner.actor.add_style_class_name(className);
|
||||
this._leftCorner.actor.add_style_class_name(className);
|
||||
},
|
||||
|
||||
_removeStyleClassName(className) {
|
||||
this.actor.remove_style_class_name(className);
|
||||
this.remove_style_class_name(className);
|
||||
this._rightCorner.actor.remove_style_class_name(className);
|
||||
this._leftCorner.actor.remove_style_class_name(className);
|
||||
},
|
||||
|
@ -15,21 +15,23 @@ const PopupMenu = imports.ui.popupMenu;
|
||||
|
||||
var ButtonBox = new Lang.Class({
|
||||
Name: 'ButtonBox',
|
||||
Extends: St.Widget,
|
||||
|
||||
_init(params) {
|
||||
params = Params.parse(params, { style_class: 'panel-button' }, true);
|
||||
this.actor = new Shell.GenericContainer(params);
|
||||
this.actor._delegate = this;
|
||||
|
||||
this.parent(params);
|
||||
|
||||
this.actor = this;
|
||||
this._delegate = this;
|
||||
|
||||
this.container = new St.Bin({ y_fill: true,
|
||||
x_fill: true,
|
||||
child: this.actor });
|
||||
|
||||
this.actor.connect('get-preferred-width', this._getPreferredWidth.bind(this));
|
||||
this.actor.connect('get-preferred-height', this._getPreferredHeight.bind(this));
|
||||
this.actor.connect('allocate', this._allocate.bind(this));
|
||||
this.connect('style-changed', this._onStyleChanged.bind(this));
|
||||
this.connect('destroy', this._onDestroy.bind(this));
|
||||
|
||||
this.actor.connect('style-changed', this._onStyleChanged.bind(this));
|
||||
this._minHPadding = this._natHPadding = 0.0;
|
||||
},
|
||||
|
||||
@ -40,31 +42,34 @@ var ButtonBox = new Lang.Class({
|
||||
this._natHPadding = themeNode.get_length('-natural-hpadding');
|
||||
},
|
||||
|
||||
_getPreferredWidth(actor, forHeight, alloc) {
|
||||
let child = actor.get_first_child();
|
||||
vfunc_get_preferred_width(forHeight) {
|
||||
let child = this.get_first_child();
|
||||
let minimumSize, naturalSize;
|
||||
|
||||
if (child) {
|
||||
[alloc.min_size, alloc.natural_size] = child.get_preferred_width(-1);
|
||||
} else {
|
||||
alloc.min_size = alloc.natural_size = 0;
|
||||
}
|
||||
if (child)
|
||||
[minimumSize, naturalSize] = child.get_preferred_width(-1);
|
||||
else
|
||||
minimumSize = naturalSize = 0;
|
||||
|
||||
alloc.min_size += 2 * this._minHPadding;
|
||||
alloc.natural_size += 2 * this._natHPadding;
|
||||
minimumSize += 2 * this._minHPadding;
|
||||
naturalSize += 2 * this._natHPadding;
|
||||
|
||||
return [minimumSize, naturalSize];
|
||||
},
|
||||
|
||||
_getPreferredHeight(actor, forWidth, alloc) {
|
||||
let child = actor.get_first_child();
|
||||
vfunc_get_preferred_height(forWidth) {
|
||||
let child = this.get_first_child();
|
||||
|
||||
if (child) {
|
||||
[alloc.min_size, alloc.natural_size] = child.get_preferred_height(-1);
|
||||
} else {
|
||||
alloc.min_size = alloc.natural_size = 0;
|
||||
}
|
||||
if (child)
|
||||
return child.get_preferred_height(-1);
|
||||
|
||||
return [0, 0];
|
||||
},
|
||||
|
||||
_allocate(actor, box, flags) {
|
||||
let child = actor.get_first_child();
|
||||
vfunc_allocate(box, flags) {
|
||||
this.set_allocation(box, flags);
|
||||
|
||||
let child = this.get_first_child();
|
||||
if (!child)
|
||||
return;
|
||||
|
||||
@ -87,11 +92,17 @@ var ButtonBox = new Lang.Class({
|
||||
|
||||
child.allocate(childBox, flags);
|
||||
},
|
||||
|
||||
_onDestroy() {
|
||||
this.container.child = null;
|
||||
this.container.destroy();
|
||||
},
|
||||
});
|
||||
|
||||
var Button = new Lang.Class({
|
||||
Name: 'PanelMenuButton',
|
||||
Extends: ButtonBox,
|
||||
Signals: {'menu-set': {} },
|
||||
|
||||
_init(menuAlignment, nameText, dontCreateMenu) {
|
||||
this.parent({ reactive: true,
|
||||
@ -100,8 +111,8 @@ var Button = new Lang.Class({
|
||||
accessible_name: nameText ? nameText : "",
|
||||
accessible_role: Atk.Role.MENU });
|
||||
|
||||
this.actor.connect('event', this._onEvent.bind(this));
|
||||
this.actor.connect('notify::visible', this._onVisibilityChanged.bind(this));
|
||||
this.connect('event', this._onEvent.bind(this));
|
||||
this.connect('notify::visible', this._onVisibilityChanged.bind(this));
|
||||
|
||||
if (dontCreateMenu)
|
||||
this.menu = new PopupMenu.PopupDummyMenu(this.actor);
|
||||
@ -110,9 +121,9 @@ var Button = new Lang.Class({
|
||||
},
|
||||
|
||||
setSensitive(sensitive) {
|
||||
this.actor.reactive = sensitive;
|
||||
this.actor.can_focus = sensitive;
|
||||
this.actor.track_hover = sensitive;
|
||||
this.reactive = sensitive;
|
||||
this.can_focus = sensitive;
|
||||
this.track_hover = sensitive;
|
||||
},
|
||||
|
||||
setMenu(menu) {
|
||||
@ -184,17 +195,13 @@ var Button = new Lang.Class({
|
||||
this.menu.actor.style = ('max-height: %spx;').format(maxHeight);
|
||||
},
|
||||
|
||||
destroy() {
|
||||
this.actor._delegate = null;
|
||||
_onDestroy() {
|
||||
this.parent();
|
||||
|
||||
if (this.menu)
|
||||
this.menu.destroy();
|
||||
this.actor.destroy();
|
||||
|
||||
this.emit('destroy');
|
||||
}
|
||||
});
|
||||
Signals.addSignalMethods(Button.prototype);
|
||||
|
||||
/* SystemIndicator:
|
||||
*
|
||||
|
@ -783,7 +783,7 @@ var PopupMenu = new Lang.Class({
|
||||
{ x_fill: true,
|
||||
y_fill: true,
|
||||
x_align: St.Align.START });
|
||||
this.actor = this._boxPointer.actor;
|
||||
this.actor = this._boxPointer;
|
||||
this.actor._delegate = this;
|
||||
this.actor.style_class = 'popup-menu-boxpointer';
|
||||
|
||||
@ -874,7 +874,7 @@ var PopupMenu = new Lang.Class({
|
||||
this.isOpen = true;
|
||||
|
||||
this._boxPointer.setPosition(this.sourceActor, this._arrowAlignment);
|
||||
this._boxPointer.show(animate);
|
||||
this._boxPointer.open(animate);
|
||||
|
||||
this.actor.raise_top();
|
||||
|
||||
@ -886,7 +886,7 @@ var PopupMenu = new Lang.Class({
|
||||
this._activeMenuItem.setActive(false);
|
||||
|
||||
if (this._boxPointer.actor.visible) {
|
||||
this._boxPointer.hide(animate, () => {
|
||||
this._boxPointer.close(animate, () => {
|
||||
this.emit('menu-closed');
|
||||
});
|
||||
}
|
||||
|
@ -150,7 +150,7 @@ var NotificationsBox = new Lang.Class({
|
||||
|
||||
_makeNotificationSource(source, box) {
|
||||
let sourceActor = new MessageTray.SourceActor(source, SUMMARY_ICON_SIZE);
|
||||
box.add(sourceActor.actor, { y_fill: true });
|
||||
box.add(sourceActor, { y_fill: true });
|
||||
|
||||
let textBox = new St.BoxLayout({ vertical: true });
|
||||
box.add(textBox, { y_fill: false, y_align: St.Align.START });
|
||||
@ -172,7 +172,7 @@ var NotificationsBox = new Lang.Class({
|
||||
let sourceActor = new MessageTray.SourceActor(source, SUMMARY_ICON_SIZE);
|
||||
let sourceBin = new St.Bin({ y_align: St.Align.START,
|
||||
x_align: St.Align.START,
|
||||
child: sourceActor.actor });
|
||||
child: sourceActor });
|
||||
box.add(sourceBin);
|
||||
|
||||
let textBox = new St.BoxLayout({ vertical: true });
|
||||
|
@ -147,7 +147,7 @@ var GridSearchResult = new Lang.Class({
|
||||
|
||||
this.icon = new IconGrid.BaseIcon(this.metaInfo['name'],
|
||||
{ createIcon: this.metaInfo['createIcon'] });
|
||||
let content = new St.Bin({ child: this.icon.actor });
|
||||
let content = new St.Bin({ child: this.icon });
|
||||
this.actor.set_child(content);
|
||||
this.actor.label_actor = this.icon.label;
|
||||
}
|
||||
@ -363,8 +363,9 @@ var GridSearchResults = new Lang.Class({
|
||||
|
||||
this._grid = new IconGrid.IconGrid({ rowLimit: MAX_GRID_SEARCH_RESULTS_ROWS,
|
||||
xAlign: St.Align.START });
|
||||
|
||||
this._bin = new St.Bin({ x_align: St.Align.MIDDLE });
|
||||
this._bin.set_child(this._grid.actor);
|
||||
this._bin.set_child(this._grid);
|
||||
|
||||
this._resultDisplayBin.set_child(this._bin);
|
||||
},
|
||||
|
@ -360,11 +360,14 @@ var InputSourceManager = new Lang.Class({
|
||||
this._settings.connect('per-window-changed', this._sourcesPerWindowChanged.bind(this));
|
||||
this._sourcesPerWindowChanged();
|
||||
this._disableIBus = false;
|
||||
this._reloading = false;
|
||||
},
|
||||
|
||||
reload() {
|
||||
this._reloading = true;
|
||||
this._keyboardManager.setKeyboardOptions(this._settings.keyboardOptions);
|
||||
this._inputSourcesChanged();
|
||||
this._reloading = false;
|
||||
},
|
||||
|
||||
_ibusReadyCallback(im, ready) {
|
||||
@ -414,7 +417,7 @@ var InputSourceManager = new Lang.Class({
|
||||
|
||||
let popup = new InputSourcePopup(this._mruSources, this._keybindingAction, this._keybindingActionBackward);
|
||||
if (!popup.show(binding.is_reversed(), binding.get_name(), binding.get_mask()))
|
||||
popup.destroy();
|
||||
popup.fadeAndDestroy();
|
||||
},
|
||||
|
||||
_keyboardOptionsChanged() {
|
||||
@ -458,7 +461,15 @@ var InputSourceManager = new Lang.Class({
|
||||
},
|
||||
|
||||
activateInputSource(is, interactive) {
|
||||
KeyboardManager.holdKeyboard();
|
||||
// The focus changes during holdKeyboard/releaseKeyboard may trick
|
||||
// the client into hiding UI containing the currently focused entry.
|
||||
// So holdKeyboard/releaseKeyboard are not called when
|
||||
// 'set-content-type' signal is received.
|
||||
// E.g. Focusing on a password entry in a popup in Xorg Firefox
|
||||
// will emit 'set-content-type' signal.
|
||||
// https://gitlab.gnome.org/GNOME/gnome-shell/issues/391
|
||||
if (!this._reloading)
|
||||
KeyboardManager.holdKeyboard();
|
||||
this._keyboardManager.apply(is.xkbId);
|
||||
|
||||
// All the "xkb:..." IBus engines simply "echo" back symbols,
|
||||
@ -473,7 +484,10 @@ var InputSourceManager = new Lang.Class({
|
||||
else
|
||||
engine = 'xkb:us::eng';
|
||||
|
||||
this._ibusManager.setEngine(engine, KeyboardManager.releaseKeyboard);
|
||||
if (!this._reloading)
|
||||
this._ibusManager.setEngine(engine, KeyboardManager.releaseKeyboard);
|
||||
else
|
||||
this._ibusManager.setEngine(engine);
|
||||
this._currentInputSourceChanged(is);
|
||||
|
||||
if (interactive)
|
||||
@ -773,6 +787,44 @@ function getInputSourceManager() {
|
||||
return _inputSourceManager;
|
||||
}
|
||||
|
||||
var InputSourceIndicatorContainer = new Lang.Class({
|
||||
Name: 'InputSourceIndicatorContainer',
|
||||
Extends: St.Widget,
|
||||
|
||||
vfunc_get_preferred_width(forHeight) {
|
||||
// Here, and in vfunc_get_preferred_height, we need to query
|
||||
// for the height of all children, but we ignore the results
|
||||
// for those we don't actually display.
|
||||
return this.get_children().reduce((maxWidth, child) => {
|
||||
let width = child.get_preferred_width(forHeight);
|
||||
return [Math.max(maxWidth[0], width[0]),
|
||||
Math.max(maxWidth[1], width[1])];
|
||||
}, [0, 0]);
|
||||
},
|
||||
|
||||
vfunc_get_preferred_height(forWidth) {
|
||||
return this.get_children().reduce((maxHeight, child) => {
|
||||
let height = child.get_preferred_height(forWidth);
|
||||
return [Math.max(maxHeight[0], height[0]),
|
||||
Math.max(maxHeight[1], height[1])];
|
||||
}, [0, 0]);
|
||||
},
|
||||
|
||||
vfunc_allocate(box, flags) {
|
||||
this.set_allocation(box, flags);
|
||||
|
||||
// translate box to (0, 0)
|
||||
box.x2 -= box.x1;
|
||||
box.x1 = 0;
|
||||
box.y2 -= box.y1;
|
||||
box.y1 = 0;
|
||||
|
||||
this.get_children().forEach(c => {
|
||||
c.allocate_align_fill(box, 0.5, 0.5, false, false, flags);
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
var InputSourceIndicator = new Lang.Class({
|
||||
Name: 'InputSourceIndicator',
|
||||
Extends: PanelMenu.Button,
|
||||
@ -783,10 +835,7 @@ var InputSourceIndicator = new Lang.Class({
|
||||
this._menuItems = {};
|
||||
this._indicatorLabels = {};
|
||||
|
||||
this._container = new Shell.GenericContainer();
|
||||
this._container.connect('get-preferred-width', this._containerGetPreferredWidth.bind(this));
|
||||
this._container.connect('get-preferred-height', this._containerGetPreferredHeight.bind(this));
|
||||
this._container.connect('allocate', this._containerAllocate.bind(this));
|
||||
this._container = new InputSourceIndicatorContainer();
|
||||
|
||||
this._hbox = new St.BoxLayout({ style_class: 'panel-status-menu-box' });
|
||||
this._hbox.add_child(this._container);
|
||||
@ -1021,48 +1070,4 @@ var InputSourceIndicator = new Lang.Class({
|
||||
|
||||
Util.spawn(['gkbd-keyboard-display', '-l', description]);
|
||||
},
|
||||
|
||||
_containerGetPreferredWidth(container, for_height, alloc) {
|
||||
// Here, and in _containerGetPreferredHeight, we need to query
|
||||
// for the height of all children, but we ignore the results
|
||||
// for those we don't actually display.
|
||||
let max_min_width = 0, max_natural_width = 0;
|
||||
|
||||
for (let i in this._inputSourceManager.inputSources) {
|
||||
let label = this._indicatorLabels[i];
|
||||
let [min_width, natural_width] = label.get_preferred_width(for_height);
|
||||
max_min_width = Math.max(max_min_width, min_width);
|
||||
max_natural_width = Math.max(max_natural_width, natural_width);
|
||||
}
|
||||
|
||||
alloc.min_size = max_min_width;
|
||||
alloc.natural_size = max_natural_width;
|
||||
},
|
||||
|
||||
_containerGetPreferredHeight(container, for_width, alloc) {
|
||||
let max_min_height = 0, max_natural_height = 0;
|
||||
|
||||
for (let i in this._inputSourceManager.inputSources) {
|
||||
let label = this._indicatorLabels[i];
|
||||
let [min_height, natural_height] = label.get_preferred_height(for_width);
|
||||
max_min_height = Math.max(max_min_height, min_height);
|
||||
max_natural_height = Math.max(max_natural_height, natural_height);
|
||||
}
|
||||
|
||||
alloc.min_size = max_min_height;
|
||||
alloc.natural_size = max_natural_height;
|
||||
},
|
||||
|
||||
_containerAllocate(container, box, flags) {
|
||||
// translate box to (0, 0)
|
||||
box.x2 -= box.x1;
|
||||
box.x1 = 0;
|
||||
box.y2 -= box.y1;
|
||||
box.y1 = 0;
|
||||
|
||||
for (let i in this._inputSourceManager.inputSources) {
|
||||
let label = this._indicatorLabels[i];
|
||||
label.allocate_align_fill(box, 0.5, 0.5, false, false, flags);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
@ -2,6 +2,7 @@
|
||||
|
||||
const Clutter = imports.gi.Clutter;
|
||||
const GLib = imports.gi.GLib;
|
||||
const GObject = imports.gi.GObject;
|
||||
const Gtk = imports.gi.Gtk;
|
||||
const Lang = imports.lang;
|
||||
const Mainloop = imports.mainloop;
|
||||
@ -39,23 +40,22 @@ function primaryModifier(mask) {
|
||||
|
||||
var SwitcherPopup = new Lang.Class({
|
||||
Name: 'SwitcherPopup',
|
||||
Extends: St.Widget,
|
||||
Abstract: true,
|
||||
|
||||
_init(items) {
|
||||
this.parent({ style_class: 'switcher-popup',
|
||||
reactive: true,
|
||||
visible: false });
|
||||
|
||||
this._switcherList = null;
|
||||
|
||||
this._items = items || [];
|
||||
this._selectedIndex = 0;
|
||||
|
||||
this.actor = new Shell.GenericContainer({ style_class: 'switcher-popup',
|
||||
reactive: true,
|
||||
visible: false });
|
||||
this.actor.connect('get-preferred-width', this._getPreferredWidth.bind(this));
|
||||
this.actor.connect('get-preferred-height', this._getPreferredHeight.bind(this));
|
||||
this.actor.connect('allocate', this._allocate.bind(this));
|
||||
this.actor.connect('destroy', this._onDestroy.bind(this));
|
||||
this.connect('destroy', this._onDestroy.bind(this));
|
||||
|
||||
Main.uiGroup.add_actor(this.actor);
|
||||
Main.uiGroup.add_actor(this);
|
||||
|
||||
this._haveModal = false;
|
||||
this._modifierMask = 0;
|
||||
@ -64,42 +64,35 @@ var SwitcherPopup = new Lang.Class({
|
||||
this._initialDelayTimeoutId = 0;
|
||||
this._noModsTimeoutId = 0;
|
||||
|
||||
this.add_constraint(new Clutter.BindConstraint({
|
||||
source: global.stage,
|
||||
coordinate: Clutter.BindCoordinate.ALL,
|
||||
}));
|
||||
|
||||
// Initially disable hover so we ignore the enter-event if
|
||||
// the switcher appears underneath the current pointer location
|
||||
this._disableHover();
|
||||
},
|
||||
|
||||
_getPreferredWidth(actor, forHeight, alloc) {
|
||||
let primary = Main.layoutManager.primaryMonitor;
|
||||
vfunc_allocate(box, flags) {
|
||||
this.set_allocation(box, flags);
|
||||
|
||||
alloc.min_size = primary.width;
|
||||
alloc.natural_size = primary.width;
|
||||
},
|
||||
|
||||
_getPreferredHeight(actor, forWidth, alloc) {
|
||||
let primary = Main.layoutManager.primaryMonitor;
|
||||
|
||||
alloc.min_size = primary.height;
|
||||
alloc.natural_size = primary.height;
|
||||
},
|
||||
|
||||
_allocate(actor, box, flags) {
|
||||
let childBox = new Clutter.ActorBox();
|
||||
let primary = Main.layoutManager.primaryMonitor;
|
||||
|
||||
let leftPadding = this.actor.get_theme_node().get_padding(St.Side.LEFT);
|
||||
let rightPadding = this.actor.get_theme_node().get_padding(St.Side.RIGHT);
|
||||
let leftPadding = this.get_theme_node().get_padding(St.Side.LEFT);
|
||||
let rightPadding = this.get_theme_node().get_padding(St.Side.RIGHT);
|
||||
let hPadding = leftPadding + rightPadding;
|
||||
|
||||
// Allocate the switcherList
|
||||
// We select a size based on an icon size that does not overflow the screen
|
||||
let [childMinHeight, childNaturalHeight] = this._switcherList.actor.get_preferred_height(primary.width - hPadding);
|
||||
let [childMinWidth, childNaturalWidth] = this._switcherList.actor.get_preferred_width(childNaturalHeight);
|
||||
let [childMinHeight, childNaturalHeight] = this._switcherList.get_preferred_height(primary.width - hPadding);
|
||||
let [childMinWidth, childNaturalWidth] = this._switcherList.get_preferred_width(childNaturalHeight);
|
||||
childBox.x1 = Math.max(primary.x + leftPadding, primary.x + Math.floor((primary.width - childNaturalWidth) / 2));
|
||||
childBox.x2 = Math.min(primary.x + primary.width - rightPadding, childBox.x1 + childNaturalWidth);
|
||||
childBox.y1 = primary.y + Math.floor((primary.height - childNaturalHeight) / 2);
|
||||
childBox.y2 = childBox.y1 + childNaturalHeight;
|
||||
this._switcherList.actor.allocate(childBox, flags);
|
||||
this._switcherList.allocate(childBox, flags);
|
||||
},
|
||||
|
||||
_initialSelection(backward, binding) {
|
||||
@ -115,31 +108,30 @@ var SwitcherPopup = new Lang.Class({
|
||||
if (this._items.length == 0)
|
||||
return false;
|
||||
|
||||
if (!Main.pushModal(this.actor)) {
|
||||
if (!Main.pushModal(this)) {
|
||||
// Probably someone else has a pointer grab, try again with keyboard only
|
||||
if (!Main.pushModal(this.actor, { options: Meta.ModalOptions.POINTER_ALREADY_GRABBED })) {
|
||||
if (!Main.pushModal(this, { options: Meta.ModalOptions.POINTER_ALREADY_GRABBED }))
|
||||
return false;
|
||||
}
|
||||
}
|
||||
this._haveModal = true;
|
||||
this._modifierMask = primaryModifier(mask);
|
||||
|
||||
this.actor.connect('key-press-event', this._keyPressEvent.bind(this));
|
||||
this.actor.connect('key-release-event', this._keyReleaseEvent.bind(this));
|
||||
this.connect('key-press-event', this._keyPressEvent.bind(this));
|
||||
this.connect('key-release-event', this._keyReleaseEvent.bind(this));
|
||||
|
||||
this.actor.connect('button-press-event', this._clickedOutside.bind(this));
|
||||
this.actor.connect('scroll-event', this._scrollEvent.bind(this));
|
||||
this.connect('button-press-event', this._clickedOutside.bind(this));
|
||||
this.connect('scroll-event', this._scrollEvent.bind(this));
|
||||
|
||||
this.actor.add_actor(this._switcherList.actor);
|
||||
this.add_actor(this._switcherList);
|
||||
this._switcherList.connect('item-activated', this._itemActivated.bind(this));
|
||||
this._switcherList.connect('item-entered', this._itemEntered.bind(this));
|
||||
this._switcherList.connect('item-removed', this._itemRemoved.bind(this));
|
||||
|
||||
// Need to force an allocation so we can figure out whether we
|
||||
// need to scroll when selecting
|
||||
this.actor.opacity = 0;
|
||||
this.actor.show();
|
||||
this.actor.get_allocation_box();
|
||||
this.opacity = 0;
|
||||
this.visible = true;
|
||||
this.get_allocation_box();
|
||||
|
||||
this._initialSelection(backward, binding);
|
||||
|
||||
@ -163,7 +155,7 @@ var SwitcherPopup = new Lang.Class({
|
||||
this._initialDelayTimeoutId = Mainloop.timeout_add(POPUP_DELAY_TIMEOUT,
|
||||
() => {
|
||||
Main.osdWindowManager.hideAll();
|
||||
this.actor.opacity = 255;
|
||||
this.opacity = 255;
|
||||
this._initialDelayTimeoutId = 0;
|
||||
return GLib.SOURCE_REMOVE;
|
||||
});
|
||||
@ -195,7 +187,7 @@ var SwitcherPopup = new Lang.Class({
|
||||
// Note: pressing one of the below keys will destroy the popup only if
|
||||
// that key is not used by the active popup's keyboard shortcut
|
||||
if (keysym == Clutter.Escape || keysym == Clutter.Tab)
|
||||
this.destroy();
|
||||
this.fadeAndDestroy();
|
||||
|
||||
return Clutter.EVENT_STOP;
|
||||
},
|
||||
@ -215,7 +207,7 @@ var SwitcherPopup = new Lang.Class({
|
||||
},
|
||||
|
||||
_clickedOutside(actor, event) {
|
||||
this.destroy();
|
||||
this.fadeAndDestroy();
|
||||
return Clutter.EVENT_PROPAGATE;
|
||||
},
|
||||
|
||||
@ -255,7 +247,7 @@ var SwitcherPopup = new Lang.Class({
|
||||
let newIndex = Math.min(n, this._items.length - 1);
|
||||
this._select(newIndex);
|
||||
} else {
|
||||
this.actor.destroy();
|
||||
this.fadeAndDestroy();
|
||||
}
|
||||
},
|
||||
|
||||
@ -293,28 +285,29 @@ var SwitcherPopup = new Lang.Class({
|
||||
|
||||
_popModal() {
|
||||
if (this._haveModal) {
|
||||
Main.popModal(this.actor);
|
||||
Main.popModal(this);
|
||||
this._haveModal = false;
|
||||
}
|
||||
},
|
||||
|
||||
destroy() {
|
||||
fadeAndDestroy() {
|
||||
this._popModal();
|
||||
if (this.actor.visible) {
|
||||
Tweener.addTween(this.actor,
|
||||
if (this.visible) {
|
||||
Tweener.addTween(this,
|
||||
{ opacity: 0,
|
||||
time: POPUP_FADE_OUT_TIME,
|
||||
transition: 'easeOutQuad',
|
||||
onComplete: () => {
|
||||
this.actor.destroy();
|
||||
this.destroy();
|
||||
}
|
||||
});
|
||||
} else
|
||||
this.actor.destroy();
|
||||
} else {
|
||||
this.destroy();
|
||||
}
|
||||
},
|
||||
|
||||
_finish(timestamp) {
|
||||
this.destroy();
|
||||
this.fadeAndDestroy();
|
||||
},
|
||||
|
||||
_onDestroy() {
|
||||
@ -334,35 +327,53 @@ var SwitcherPopup = new Lang.Class({
|
||||
}
|
||||
});
|
||||
|
||||
var SwitcherButton = new Lang.Class({
|
||||
Name: 'SwitcherButton',
|
||||
Extends: St.Button,
|
||||
|
||||
_init(square) {
|
||||
this.parent({ style_class: 'item-box',
|
||||
reactive: true });
|
||||
|
||||
this._square = square;
|
||||
},
|
||||
|
||||
vfunc_get_preferred_width(forHeight) {
|
||||
if (this._square)
|
||||
return this.get_preferred_height(-1);
|
||||
else
|
||||
return this.parent(forHeight);
|
||||
}
|
||||
});
|
||||
|
||||
var SwitcherList = new Lang.Class({
|
||||
Name: 'SwitcherList',
|
||||
Extends: St.Widget,
|
||||
Signals: { 'item-activated': { param_types: [GObject.TYPE_INT] },
|
||||
'item-entered': { param_types: [GObject.TYPE_INT] },
|
||||
'item-removed': { param_types: [GObject.TYPE_INT] } },
|
||||
|
||||
_init(squareItems) {
|
||||
this.actor = new Shell.GenericContainer({ style_class: 'switcher-list' });
|
||||
this.actor.connect('get-preferred-width', this._getPreferredWidth.bind(this));
|
||||
this.actor.connect('get-preferred-height', this._getPreferredHeight.bind(this));
|
||||
this.actor.connect('allocate', this._allocateTop.bind(this));
|
||||
this.parent({ style_class: 'switcher-list' });
|
||||
|
||||
this._list = new St.BoxLayout({ style_class: 'switcher-list-item-container',
|
||||
vertical: false,
|
||||
x_expand: true,
|
||||
y_expand: true });
|
||||
|
||||
let layoutManager = this._list.get_layout_manager();
|
||||
|
||||
// Here we use a GenericContainer so that we can force all the
|
||||
// children to have the same width.
|
||||
this._list = new Shell.GenericContainer({ style_class: 'switcher-list-item-container' });
|
||||
this._list.spacing = 0;
|
||||
this._list.connect('style-changed', () => {
|
||||
this._list.spacing = this._list.get_theme_node().get_length('spacing');
|
||||
});
|
||||
|
||||
this._list.connect('get-preferred-width', this._getPreferredWidth.bind(this));
|
||||
this._list.connect('get-preferred-height', this._getPreferredHeight.bind(this));
|
||||
this._list.connect('allocate', this._allocate.bind(this));
|
||||
|
||||
this._scrollView = new St.ScrollView({ style_class: 'hfade',
|
||||
enable_mouse_scrolling: false });
|
||||
this._scrollView.set_policy(Gtk.PolicyType.NEVER, Gtk.PolicyType.NEVER);
|
||||
|
||||
let scrollBox = new St.BoxLayout();
|
||||
scrollBox.add_actor(this._list);
|
||||
this._scrollView.add_actor(scrollBox);
|
||||
this.actor.add_actor(this._scrollView);
|
||||
this._scrollView.add_actor(this._list);
|
||||
this.add_actor(this._scrollView);
|
||||
|
||||
// Those arrows indicate whether scrolling in one direction is possible
|
||||
this._leftArrow = new St.DrawingArea({ style_class: 'switcher-arrow',
|
||||
@ -376,50 +387,20 @@ var SwitcherList = new Lang.Class({
|
||||
drawArrow(this._rightArrow, St.Side.RIGHT);
|
||||
});
|
||||
|
||||
this.actor.add_actor(this._leftArrow);
|
||||
this.actor.add_actor(this._rightArrow);
|
||||
this.add_actor(this._leftArrow);
|
||||
this.add_actor(this._rightArrow);
|
||||
|
||||
this._items = [];
|
||||
this._highlighted = -1;
|
||||
this._squareItems = squareItems;
|
||||
this._minSize = 0;
|
||||
this._scrollableRight = true;
|
||||
this._scrollableLeft = false;
|
||||
},
|
||||
|
||||
_allocateTop(actor, box, flags) {
|
||||
let leftPadding = this.actor.get_theme_node().get_padding(St.Side.LEFT);
|
||||
let rightPadding = this.actor.get_theme_node().get_padding(St.Side.RIGHT);
|
||||
|
||||
let childBox = new Clutter.ActorBox();
|
||||
let scrollable = this._minSize > box.x2 - box.x1;
|
||||
|
||||
box.y1 -= this.actor.get_theme_node().get_padding(St.Side.TOP);
|
||||
box.y2 += this.actor.get_theme_node().get_padding(St.Side.BOTTOM);
|
||||
this._scrollView.allocate(box, flags);
|
||||
|
||||
let arrowWidth = Math.floor(leftPadding / 3);
|
||||
let arrowHeight = arrowWidth * 2;
|
||||
childBox.x1 = leftPadding / 2;
|
||||
childBox.y1 = this.actor.height / 2 - arrowWidth;
|
||||
childBox.x2 = childBox.x1 + arrowWidth;
|
||||
childBox.y2 = childBox.y1 + arrowHeight;
|
||||
this._leftArrow.allocate(childBox, flags);
|
||||
this._leftArrow.opacity = (this._scrollableLeft && scrollable) ? 255 : 0;
|
||||
|
||||
arrowWidth = Math.floor(rightPadding / 3);
|
||||
arrowHeight = arrowWidth * 2;
|
||||
childBox.x1 = this.actor.width - arrowWidth - rightPadding / 2;
|
||||
childBox.y1 = this.actor.height / 2 - arrowWidth;
|
||||
childBox.x2 = childBox.x1 + arrowWidth;
|
||||
childBox.y2 = childBox.y1 + arrowHeight;
|
||||
this._rightArrow.allocate(childBox, flags);
|
||||
this._rightArrow.opacity = (this._scrollableRight && scrollable) ? 255 : 0;
|
||||
layoutManager.homogeneous = squareItems;
|
||||
},
|
||||
|
||||
addItem(item, label) {
|
||||
let bbox = new St.Button({ style_class: 'item-box',
|
||||
reactive: true });
|
||||
let bbox = new SwitcherButton(this._squareItems);
|
||||
|
||||
bbox.set_child(item);
|
||||
this._list.add_actor(bbox);
|
||||
@ -472,8 +453,8 @@ var SwitcherList = new Lang.Class({
|
||||
let adjustment = this._scrollView.hscroll.adjustment;
|
||||
let [value, lower, upper, stepIncrement, pageIncrement, pageSize] = adjustment.get_values();
|
||||
let [absItemX, absItemY] = this._items[index].get_transformed_position();
|
||||
let [result, posX, posY] = this.actor.transform_stage_point(absItemX, 0);
|
||||
let [containerWidth, containerHeight] = this.actor.get_transformed_size();
|
||||
let [result, posX, posY] = this.transform_stage_point(absItemX, 0);
|
||||
let [containerWidth, containerHeight] = this.get_transformed_size();
|
||||
if (posX + this._items[index].get_width() > containerWidth)
|
||||
this._scrollToRight();
|
||||
else if (this._items[index].allocation.x1 - value < 0)
|
||||
@ -500,7 +481,7 @@ var SwitcherList = new Lang.Class({
|
||||
onComplete: () => {
|
||||
if (this._highlighted == 0)
|
||||
this._scrollableLeft = false;
|
||||
this.actor.queue_relayout();
|
||||
this.queue_relayout();
|
||||
}
|
||||
});
|
||||
},
|
||||
@ -524,7 +505,7 @@ var SwitcherList = new Lang.Class({
|
||||
onComplete: () => {
|
||||
if (this._highlighted == this._items.length - 1)
|
||||
this._scrollableRight = false;
|
||||
this.actor.queue_relayout();
|
||||
this.queue_relayout();
|
||||
}
|
||||
});
|
||||
},
|
||||
@ -556,16 +537,15 @@ var SwitcherList = new Lang.Class({
|
||||
return [maxChildMin, maxChildNat];
|
||||
},
|
||||
|
||||
_getPreferredWidth(actor, forHeight, alloc) {
|
||||
let [maxChildMin, maxChildNat] = this._maxChildWidth(forHeight);
|
||||
vfunc_get_preferred_width(forHeight) {
|
||||
let themeNode = this.get_theme_node();
|
||||
let [maxChildMin, ] = this._maxChildWidth(forHeight);
|
||||
let [minListWidth, ] = this._list.get_preferred_width(forHeight);
|
||||
|
||||
let totalSpacing = Math.max(this._list.spacing * (this._items.length - 1), 0);
|
||||
alloc.min_size = this._items.length * maxChildMin + totalSpacing;
|
||||
alloc.natural_size = alloc.min_size;
|
||||
this._minSize = alloc.min_size;
|
||||
return themeNode.adjust_preferred_width(maxChildMin, minListWidth);
|
||||
},
|
||||
|
||||
_getPreferredHeight(actor, forWidth, alloc) {
|
||||
vfunc_get_preferred_height(forWidth) {
|
||||
let maxChildMin = 0;
|
||||
let maxChildNat = 0;
|
||||
|
||||
@ -581,44 +561,46 @@ var SwitcherList = new Lang.Class({
|
||||
maxChildNat = maxChildMin;
|
||||
}
|
||||
|
||||
alloc.min_size = maxChildMin;
|
||||
alloc.natural_size = maxChildNat;
|
||||
let themeNode = this.get_theme_node();
|
||||
return themeNode.adjust_preferred_height(maxChildMin, maxChildNat);
|
||||
},
|
||||
|
||||
_allocate(actor, box, flags) {
|
||||
let childHeight = box.y2 - box.y1;
|
||||
vfunc_allocate(box, flags) {
|
||||
this.set_allocation(box, flags);
|
||||
|
||||
let [maxChildMin, maxChildNat] = this._maxChildWidth(childHeight);
|
||||
let totalSpacing = Math.max(this._list.spacing * (this._items.length - 1), 0);
|
||||
let contentBox = this.get_theme_node().get_content_box(box);
|
||||
let width = contentBox.x2 - contentBox.x1;
|
||||
let height = contentBox.y2 - contentBox.y1;
|
||||
|
||||
let childWidth = Math.floor(Math.max(0, box.x2 - box.x1 - totalSpacing) / this._items.length);
|
||||
let leftPadding = this.get_theme_node().get_padding(St.Side.LEFT);
|
||||
let rightPadding = this.get_theme_node().get_padding(St.Side.RIGHT);
|
||||
|
||||
let [, natScrollViewWidth] = this._scrollView.get_preferred_width(height);
|
||||
|
||||
let x = 0;
|
||||
let children = this._list.get_children();
|
||||
let childBox = new Clutter.ActorBox();
|
||||
let scrollable = natScrollViewWidth > width;
|
||||
|
||||
let primary = Main.layoutManager.primaryMonitor;
|
||||
let parentRightPadding = this.actor.get_parent().get_theme_node().get_padding(St.Side.RIGHT);
|
||||
this._scrollView.allocate(contentBox, flags);
|
||||
|
||||
for (let i = 0; i < children.length; i++) {
|
||||
if (this._items.indexOf(children[i]) != -1) {
|
||||
let [childMin, childNat] = children[i].get_preferred_height(childWidth);
|
||||
let vSpacing = (childHeight - childNat) / 2;
|
||||
childBox.x1 = x;
|
||||
childBox.y1 = vSpacing;
|
||||
childBox.x2 = x + childWidth;
|
||||
childBox.y2 = childBox.y1 + childNat;
|
||||
children[i].allocate(childBox, flags);
|
||||
let arrowWidth = Math.floor(leftPadding / 3);
|
||||
let arrowHeight = arrowWidth * 2;
|
||||
childBox.x1 = leftPadding / 2;
|
||||
childBox.y1 = this.height / 2 - arrowWidth;
|
||||
childBox.x2 = childBox.x1 + arrowWidth;
|
||||
childBox.y2 = childBox.y1 + arrowHeight;
|
||||
this._leftArrow.allocate(childBox, flags);
|
||||
this._leftArrow.opacity = (this._scrollableLeft && scrollable) ? 255 : 0;
|
||||
|
||||
x += this._list.spacing + childWidth;
|
||||
} else {
|
||||
// Something else, eg, AppSwitcher's arrows;
|
||||
// we don't allocate it.
|
||||
}
|
||||
}
|
||||
arrowWidth = Math.floor(rightPadding / 3);
|
||||
arrowHeight = arrowWidth * 2;
|
||||
childBox.x1 = this.width - arrowWidth - rightPadding / 2;
|
||||
childBox.y1 = this.height / 2 - arrowWidth;
|
||||
childBox.x2 = childBox.x1 + arrowWidth;
|
||||
childBox.y2 = childBox.y1 + arrowHeight;
|
||||
this._rightArrow.allocate(childBox, flags);
|
||||
this._rightArrow.opacity = (this._scrollableRight && scrollable) ? 255 : 0;
|
||||
}
|
||||
});
|
||||
Signals.addSignalMethods(SwitcherList.prototype);
|
||||
|
||||
function drawArrow(area, side) {
|
||||
let themeNode = area.get_theme_node();
|
||||
|
@ -478,7 +478,6 @@ var TouchpadWorkspaceSwitchAction = new Lang.Class({
|
||||
this._dx = 0;
|
||||
this._dy = 0;
|
||||
actor.connect('captured-event', this._handleEvent.bind(this));
|
||||
this._touchpadSettings = new Gio.Settings({schema_id: 'org.gnome.desktop.peripherals.touchpad'});
|
||||
},
|
||||
|
||||
_checkActivated() {
|
||||
@ -516,11 +515,7 @@ var TouchpadWorkspaceSwitchAction = new Lang.Class({
|
||||
|
||||
// Scale deltas up a bit to make it feel snappier
|
||||
this._dx += dx * 2;
|
||||
if(!(this._touchpadSettings.get_boolean('natural-scroll')))
|
||||
this._dy -= dy * 2;
|
||||
else
|
||||
this._dy += dy * 2;
|
||||
|
||||
this._dy += dy * 2;
|
||||
this.emit('motion', this._dx, this._dy);
|
||||
} else {
|
||||
if ((event.get_gesture_phase() == Clutter.TouchpadGesturePhase.END && ! this._checkActivated()) ||
|
||||
@ -1801,11 +1796,11 @@ var WindowManager = new Lang.Class({
|
||||
if (direction == Meta.MotionDirection.UP ||
|
||||
direction == Meta.MotionDirection.UP_LEFT ||
|
||||
direction == Meta.MotionDirection.UP_RIGHT)
|
||||
yDest = -global.screen_height + Main.panel.actor.height;
|
||||
yDest = -global.screen_height + Main.panel.height;
|
||||
else if (direction == Meta.MotionDirection.DOWN ||
|
||||
direction == Meta.MotionDirection.DOWN_LEFT ||
|
||||
direction == Meta.MotionDirection.DOWN_RIGHT)
|
||||
yDest = global.screen_height - Main.panel.actor.height;
|
||||
yDest = global.screen_height - Main.panel.height;
|
||||
|
||||
if (direction == Meta.MotionDirection.LEFT ||
|
||||
direction == Meta.MotionDirection.UP_LEFT ||
|
||||
|
@ -465,8 +465,6 @@ var WindowOverlay = new Lang.Class({
|
||||
title.clutter_text.ellipsize = Pango.EllipsizeMode.END;
|
||||
windowClone.actor.label_actor = title;
|
||||
|
||||
this._maxTitleWidth = -1;
|
||||
|
||||
this._updateCaptionId = metaWindow.connect('notify::title', w => {
|
||||
this.title.text = w.title;
|
||||
this.title.text = this._getCaption();
|
||||
@ -530,13 +528,6 @@ var WindowOverlay = new Lang.Class({
|
||||
Math.max(this.borderSize, this.closeButton.width - this.closeButton._overlap)];
|
||||
},
|
||||
|
||||
setMaxChromeWidth(max) {
|
||||
if (this._maxTitleWidth == max)
|
||||
return;
|
||||
|
||||
this._maxTitleWidth = max;
|
||||
},
|
||||
|
||||
relayout(animate) {
|
||||
let button = this.closeButton;
|
||||
let title = this.title;
|
||||
@ -563,26 +554,13 @@ var WindowOverlay = new Lang.Class({
|
||||
else
|
||||
button.set_position(Math.floor(buttonX), Math.floor(buttonY));
|
||||
|
||||
// Clutter.Actor.get_preferred_width() will return the fixed width if
|
||||
// one is set, so we need to reset the width by calling set_width(-1),
|
||||
// to forward the call down to StLabel.
|
||||
// We also need to save and restore the current width, otherwise the
|
||||
// animation starts from the wrong point.
|
||||
let prevTitleWidth = title.width;
|
||||
title.set_width(-1);
|
||||
|
||||
let [titleMinWidth, titleNatWidth] = title.get_preferred_width(-1);
|
||||
let titleWidth = Math.max(titleMinWidth,
|
||||
Math.min(titleNatWidth, this._maxTitleWidth));
|
||||
title.width = prevTitleWidth;
|
||||
|
||||
let titleX = cloneX + (cloneWidth - titleWidth) / 2;
|
||||
let titleX = cloneX + (cloneWidth - title.width) / 2;
|
||||
let titleY = cloneY + cloneHeight - (title.height - this.borderSize) / 2;
|
||||
|
||||
if (animate) {
|
||||
this._animateOverlayActor(title, Math.floor(titleX), Math.floor(titleY), titleWidth);
|
||||
this._animateOverlayActor(title, Math.floor(titleX), Math.floor(titleY), title.width);
|
||||
} else {
|
||||
title.width = titleWidth;
|
||||
title.width = title.width;
|
||||
title.set_position(Math.floor(titleX), Math.floor(titleY));
|
||||
}
|
||||
|
||||
@ -1328,12 +1306,6 @@ var Workspace = new Lang.Class({
|
||||
let cloneHeight = clone.actor.height * scale;
|
||||
clone.slot = [x, y, cloneWidth, cloneHeight];
|
||||
|
||||
let cloneCenter = x + cloneWidth / 2;
|
||||
let maxChromeWidth = 2 * Math.min(
|
||||
cloneCenter - area.x,
|
||||
area.x + area.width - cloneCenter);
|
||||
overlay.setMaxChromeWidth(Math.round(maxChromeWidth));
|
||||
|
||||
if (overlay && (initialPositioning || !clone.positioned))
|
||||
overlay.hide();
|
||||
|
||||
|
@ -15,59 +15,33 @@ const Tweener = imports.ui.tweener;
|
||||
var ANIMATION_TIME = 0.1;
|
||||
var DISPLAY_TIMEOUT = 600;
|
||||
|
||||
var WorkspaceSwitcherPopup = new Lang.Class({
|
||||
Name: 'WorkspaceSwitcherPopup',
|
||||
var WorkspaceSwitcherPopupList = new Lang.Class({
|
||||
Name: 'WorkspaceSwitcherPopupList',
|
||||
Extends: St.Widget,
|
||||
|
||||
_init() {
|
||||
this.actor = new St.Widget({ x: 0,
|
||||
y: 0,
|
||||
width: global.screen_width,
|
||||
height: global.screen_height,
|
||||
style_class: 'workspace-switcher-group' });
|
||||
Main.uiGroup.add_actor(this.actor);
|
||||
this.parent({ style_class: 'workspace-switcher' });
|
||||
|
||||
this._container = new St.BoxLayout({ style_class: 'workspace-switcher-container' });
|
||||
this._list = new Shell.GenericContainer({ style_class: 'workspace-switcher' });
|
||||
this._itemSpacing = 0;
|
||||
this._childHeight = 0;
|
||||
this._childWidth = 0;
|
||||
this._timeoutId = 0;
|
||||
this._list.connect('style-changed', () => {
|
||||
this._itemSpacing = this._list.get_theme_node().get_length('spacing');
|
||||
|
||||
this.connect('style-changed', () => {
|
||||
this._itemSpacing = this.get_theme_node().get_length('spacing');
|
||||
});
|
||||
|
||||
this._list.connect('get-preferred-width', this._getPreferredWidth.bind(this));
|
||||
this._list.connect('get-preferred-height', this._getPreferredHeight.bind(this));
|
||||
this._list.connect('allocate', this._allocate.bind(this));
|
||||
this._container.add(this._list);
|
||||
|
||||
this.actor.add_actor(this._container);
|
||||
|
||||
this._redisplay();
|
||||
|
||||
this.actor.hide();
|
||||
|
||||
let workspaceManager = global.workspace_manager;
|
||||
this._workspaceManagerSignals = [];
|
||||
this._workspaceManagerSignals.push(workspaceManager.connect('workspace-added',
|
||||
this._redisplay.bind(this)));
|
||||
this._workspaceManagerSignals.push(workspaceManager.connect('workspace-removed',
|
||||
this._redisplay.bind(this)));
|
||||
},
|
||||
|
||||
_getPreferredHeight(actor, forWidth, alloc) {
|
||||
let children = this._list.get_children();
|
||||
vfunc_get_preferred_height(forWidth) {
|
||||
let workArea = Main.layoutManager.getWorkAreaForMonitor(Main.layoutManager.primaryIndex);
|
||||
let themeNode = this.get_theme_node();
|
||||
|
||||
let availHeight = workArea.height;
|
||||
availHeight -= this.actor.get_theme_node().get_vertical_padding();
|
||||
availHeight -= this._container.get_theme_node().get_vertical_padding();
|
||||
availHeight -= this._list.get_theme_node().get_vertical_padding();
|
||||
availHeight -= themeNode.get_vertical_padding();
|
||||
|
||||
let height = 0;
|
||||
for (let i = 0; i < children.length; i++) {
|
||||
let [childMinHeight, childNaturalHeight] = children[i].get_preferred_height(-1);
|
||||
let [childMinWidth, childNaturalWidth] = children[i].get_preferred_width(childNaturalHeight);
|
||||
for (let child of this.get_children()) {
|
||||
let [childMinHeight, childNaturalHeight] = child.get_preferred_height(-1);
|
||||
let [childMinWidth, childNaturalWidth] = child.get_preferred_width(childNaturalHeight);
|
||||
height += childNaturalHeight * workArea.width / workArea.height;
|
||||
}
|
||||
|
||||
@ -78,34 +52,74 @@ var WorkspaceSwitcherPopup = new Lang.Class({
|
||||
|
||||
this._childHeight = (height - spacing) / workspaceManager.n_workspaces;
|
||||
|
||||
alloc.min_size = height;
|
||||
alloc.natural_size = height;
|
||||
return themeNode.adjust_preferred_height(height, height);
|
||||
},
|
||||
|
||||
_getPreferredWidth(actor, forHeight, alloc) {
|
||||
vfunc_get_preferred_width(forHeight) {
|
||||
let workArea = Main.layoutManager.getWorkAreaForMonitor(Main.layoutManager.primaryIndex);
|
||||
this._childWidth = Math.round(this._childHeight * workArea.width / workArea.height);
|
||||
|
||||
alloc.min_size = this._childWidth;
|
||||
alloc.natural_size = this._childWidth;
|
||||
return [this._childWidth, this._childWidth];
|
||||
},
|
||||
|
||||
_allocate(actor, box, flags) {
|
||||
let children = this._list.get_children();
|
||||
vfunc_allocate(box, flags) {
|
||||
this.set_allocation(box, flags);
|
||||
|
||||
let themeNode = this.get_theme_node();
|
||||
box = themeNode.get_content_box(box);
|
||||
|
||||
let childBox = new Clutter.ActorBox();
|
||||
|
||||
let y = box.y1;
|
||||
let prevChildBoxY2 = box.y1 - this._itemSpacing;
|
||||
for (let i = 0; i < children.length; i++) {
|
||||
for (let child of this.get_children()) {
|
||||
childBox.x1 = box.x1;
|
||||
childBox.x2 = box.x1 + this._childWidth;
|
||||
childBox.y1 = prevChildBoxY2 + this._itemSpacing;
|
||||
childBox.y2 = Math.round(y + this._childHeight);
|
||||
y += this._childHeight + this._itemSpacing;
|
||||
prevChildBoxY2 = childBox.y2;
|
||||
children[i].allocate(childBox, flags);
|
||||
child.allocate(childBox, flags);
|
||||
}
|
||||
},
|
||||
});
|
||||
|
||||
var WorkspaceSwitcherPopup = new Lang.Class({
|
||||
Name: 'WorkspaceSwitcherPopup',
|
||||
Extends: St.Widget,
|
||||
|
||||
_init() {
|
||||
this.parent({ x: 0,
|
||||
y: 0,
|
||||
width: global.screen_width,
|
||||
height: global.screen_height,
|
||||
style_class: 'workspace-switcher-group' });
|
||||
|
||||
this.actor = this;
|
||||
|
||||
Main.uiGroup.add_actor(this);
|
||||
|
||||
this._timeoutId = 0;
|
||||
|
||||
this._container = new St.BoxLayout({ style_class: 'workspace-switcher-container' });
|
||||
this.add_child(this._container);
|
||||
|
||||
this._list = new WorkspaceSwitcherPopupList();
|
||||
this._container.add_child(this._list);
|
||||
|
||||
this._redisplay();
|
||||
|
||||
this.hide();
|
||||
|
||||
let workspaceManager = global.workspace_manager;
|
||||
this._workspaceManagerSignals = [];
|
||||
this._workspaceManagerSignals.push(workspaceManager.connect('workspace-added',
|
||||
this._redisplay.bind(this)));
|
||||
this._workspaceManagerSignals.push(workspaceManager.connect('workspace-removed',
|
||||
this._redisplay.bind(this)));
|
||||
|
||||
this.connect('destroy', this._onDestroy.bind(this));
|
||||
},
|
||||
|
||||
_redisplay() {
|
||||
let workspaceManager = global.workspace_manager;
|
||||
@ -165,7 +179,7 @@ var WorkspaceSwitcherPopup = new Lang.Class({
|
||||
return GLib.SOURCE_REMOVE;
|
||||
},
|
||||
|
||||
destroy() {
|
||||
_onDestroy() {
|
||||
if (this._timeoutId)
|
||||
Mainloop.source_remove(this._timeoutId);
|
||||
this._timeoutId = 0;
|
||||
@ -174,9 +188,6 @@ var WorkspaceSwitcherPopup = new Lang.Class({
|
||||
for (let i = 0; i < this._workspaceManagerSignals.length; i++)
|
||||
workspaceManager.disconnect(this._workspaceManagerSignals[i]);
|
||||
|
||||
this.actor.destroy();
|
||||
|
||||
this.emit('destroy');
|
||||
this._workspaceManagerSignals = [];
|
||||
}
|
||||
});
|
||||
Signals.addSignalMethods(WorkspaceSwitcherPopup.prototype);
|
||||
|
@ -615,14 +615,14 @@ Signals.addSignalMethods(WorkspaceThumbnail.prototype);
|
||||
|
||||
var ThumbnailsBox = new Lang.Class({
|
||||
Name: 'ThumbnailsBox',
|
||||
Extends: St.Widget,
|
||||
|
||||
_init() {
|
||||
this.actor = new Shell.GenericContainer({ reactive: true,
|
||||
style_class: 'workspace-thumbnails',
|
||||
request_mode: Clutter.RequestMode.WIDTH_FOR_HEIGHT });
|
||||
this.actor.connect('get-preferred-width', this._getPreferredWidth.bind(this));
|
||||
this.actor.connect('get-preferred-height', this._getPreferredHeight.bind(this));
|
||||
this.actor.connect('allocate', this._allocate.bind(this));
|
||||
this.parent({ reactive: true,
|
||||
style_class: 'workspace-thumbnails',
|
||||
request_mode: Clutter.RequestMode.WIDTH_FOR_HEIGHT });
|
||||
|
||||
this.actor = this;
|
||||
this.actor._delegate = this;
|
||||
|
||||
let indicator = new St.Bin({ style_class: 'workspace-thumbnail-indicator' });
|
||||
@ -631,12 +631,12 @@ var ThumbnailsBox = new Lang.Class({
|
||||
Shell.util_set_hidden_from_pick(indicator, true);
|
||||
|
||||
this._indicator = indicator;
|
||||
this.actor.add_actor(indicator);
|
||||
this.add_actor(indicator);
|
||||
|
||||
this._dropWorkspace = -1;
|
||||
this._dropPlaceholderPos = -1;
|
||||
this._dropPlaceholder = new St.Bin({ style_class: 'placeholder' });
|
||||
this.actor.add_actor(this._dropPlaceholder);
|
||||
this.add_actor(this._dropPlaceholder);
|
||||
this._spliceIndex = -1;
|
||||
|
||||
this._targetScale = 0;
|
||||
@ -652,9 +652,9 @@ var ThumbnailsBox = new Lang.Class({
|
||||
|
||||
this._thumbnails = [];
|
||||
|
||||
this.actor.connect('button-press-event', () => Clutter.EVENT_STOP);
|
||||
this.actor.connect('button-release-event', this._onButtonRelease.bind(this));
|
||||
this.actor.connect('touch-event', this._onTouchEvent.bind(this));
|
||||
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));
|
||||
@ -693,13 +693,13 @@ var ThumbnailsBox = new Lang.Class({
|
||||
_updateSwitcherVisibility() {
|
||||
let workspaceManager = global.workspace_manager;
|
||||
|
||||
this.actor.visible =
|
||||
this.visible =
|
||||
this._settings.get_boolean('dynamic-workspaces') ||
|
||||
workspaceManager.n_workspaces > 1;
|
||||
},
|
||||
|
||||
_activateThumbnailAtPoint(stageX, stageY, time) {
|
||||
let [r, x, y] = this.actor.transform_stage_point(stageX, stageY);
|
||||
let [r, x, y] = this.transform_stage_point(stageX, stageY);
|
||||
|
||||
for (let i = 0; i < this._thumbnails.length; i++) {
|
||||
let thumbnail = this._thumbnails[i]
|
||||
@ -753,7 +753,7 @@ var ThumbnailsBox = new Lang.Class({
|
||||
},
|
||||
|
||||
_onDragMotion(dragEvent) {
|
||||
if (!this.actor.contains(dragEvent.targetActor))
|
||||
if (!this.contains(dragEvent.targetActor))
|
||||
this._onLeave();
|
||||
return DND.DragMotionResult.CONTINUE;
|
||||
},
|
||||
@ -767,7 +767,7 @@ var ThumbnailsBox = new Lang.Class({
|
||||
return;
|
||||
|
||||
this._dropPlaceholderPos = -1;
|
||||
this.actor.queue_relayout();
|
||||
this.queue_relayout();
|
||||
},
|
||||
|
||||
// Draggable target interface
|
||||
@ -776,7 +776,7 @@ var ThumbnailsBox = new Lang.Class({
|
||||
return DND.DragMotionResult.CONTINUE;
|
||||
|
||||
let canCreateWorkspaces = Meta.prefs_get_dynamic_workspaces();
|
||||
let spacing = this.actor.get_theme_node().get_length('spacing');
|
||||
let spacing = this.get_theme_node().get_length('spacing');
|
||||
|
||||
this._dropWorkspace = -1;
|
||||
let placeholderPos = -1;
|
||||
@ -814,7 +814,7 @@ var ThumbnailsBox = new Lang.Class({
|
||||
|
||||
if (this._dropPlaceholderPos != placeholderPos) {
|
||||
this._dropPlaceholderPos = placeholderPos;
|
||||
this.actor.queue_relayout();
|
||||
this.queue_relayout();
|
||||
}
|
||||
|
||||
if (this._dropWorkspace != -1)
|
||||
@ -962,7 +962,7 @@ var ThumbnailsBox = new Lang.Class({
|
||||
thumbnail.setPorthole(this._porthole.x, this._porthole.y,
|
||||
this._porthole.width, this._porthole.height);
|
||||
this._thumbnails.push(thumbnail);
|
||||
this.actor.add_actor(thumbnail.actor);
|
||||
this.add_actor(thumbnail.actor);
|
||||
|
||||
if (start > 0 && this._spliceIndex == -1) {
|
||||
// not the initial fill, and not splicing via DND
|
||||
@ -1011,7 +1011,7 @@ var ThumbnailsBox = new Lang.Class({
|
||||
|
||||
set scale(scale) {
|
||||
this._scale = scale;
|
||||
this.actor.queue_relayout();
|
||||
this.queue_relayout();
|
||||
},
|
||||
|
||||
get scale() {
|
||||
@ -1020,7 +1020,7 @@ var ThumbnailsBox = new Lang.Class({
|
||||
|
||||
set indicatorY(indicatorY) {
|
||||
this._indicatorY = indicatorY;
|
||||
this.actor.queue_relayout();
|
||||
this.queue_relayout();
|
||||
},
|
||||
|
||||
get indicatorY() {
|
||||
@ -1080,7 +1080,6 @@ var ThumbnailsBox = new Lang.Class({
|
||||
|
||||
// Once that's complete, we can start scaling to the new size and collapse any removed thumbnails
|
||||
this._iterateStateThumbnails(ThumbnailState.ANIMATED_OUT, thumbnail => {
|
||||
this.actor.set_skip_paint(thumbnail.actor, true);
|
||||
this._setThumbnailState(thumbnail, ThumbnailState.COLLAPSING);
|
||||
Tweener.addTween(thumbnail,
|
||||
{ collapseFraction: 1,
|
||||
@ -1132,39 +1131,36 @@ var ThumbnailsBox = new Lang.Class({
|
||||
this._stateUpdateQueued = true;
|
||||
},
|
||||
|
||||
_getPreferredHeight(actor, forWidth, alloc) {
|
||||
vfunc_get_preferred_height(forWidth) {
|
||||
// Note that for getPreferredWidth/Height we cheat a bit and skip propagating
|
||||
// the size request to our children because we know how big they are and know
|
||||
// that the actors aren't depending on the virtual functions being called.
|
||||
|
||||
if (!this._ensurePorthole()) {
|
||||
alloc.min_size = -1;
|
||||
alloc.natural_size = -1;
|
||||
return;
|
||||
}
|
||||
if (!this._ensurePorthole())
|
||||
return [0, 0];
|
||||
|
||||
let workspaceManager = global.workspace_manager;
|
||||
let themeNode = this.actor.get_theme_node();
|
||||
let themeNode = this.get_theme_node();
|
||||
|
||||
let spacing = themeNode.get_length('spacing');
|
||||
let nWorkspaces = workspaceManager.n_workspaces;
|
||||
let totalSpacing = (nWorkspaces - 1) * spacing;
|
||||
|
||||
alloc.min_size = totalSpacing;
|
||||
alloc.natural_size = totalSpacing + nWorkspaces * this._porthole.height * MAX_THUMBNAIL_SCALE;
|
||||
let naturalHeight = totalSpacing + nWorkspaces * this._porthole.height * MAX_THUMBNAIL_SCALE;
|
||||
|
||||
return themeNode.adjust_preferred_height(totalSpacing, naturalHeight);
|
||||
},
|
||||
|
||||
_getPreferredWidth(actor, forHeight, alloc) {
|
||||
if (!this._ensurePorthole()) {
|
||||
alloc.min_size = -1;
|
||||
alloc.natural_size = -1;
|
||||
return;
|
||||
}
|
||||
vfunc_get_preferred_width(forHeight) {
|
||||
if (!this._ensurePorthole())
|
||||
return [0, 0];
|
||||
|
||||
let workspaceManager = global.workspace_manager;
|
||||
let themeNode = this.actor.get_theme_node();
|
||||
let themeNode = this.get_theme_node();
|
||||
|
||||
let spacing = this.actor.get_theme_node().get_length('spacing');
|
||||
forHeight = themeNode.adjust_for_height(forHeight);
|
||||
|
||||
let spacing = themeNode.get_length('spacing');
|
||||
let nWorkspaces = workspaceManager.n_workspaces;
|
||||
let totalSpacing = (nWorkspaces - 1) * spacing;
|
||||
|
||||
@ -1174,8 +1170,8 @@ var ThumbnailsBox = new Lang.Class({
|
||||
scale = Math.min(scale, MAX_THUMBNAIL_SCALE);
|
||||
|
||||
let width = Math.round(this._porthole.width * scale);
|
||||
alloc.min_size = width;
|
||||
alloc.natural_size = width;
|
||||
|
||||
return themeNode.adjust_preferred_width(width, width);
|
||||
},
|
||||
|
||||
// The "porthole" is the portion of the screen that we show in the
|
||||
@ -1190,14 +1186,18 @@ var ThumbnailsBox = new Lang.Class({
|
||||
return true;
|
||||
},
|
||||
|
||||
_allocate(actor, box, flags) {
|
||||
vfunc_allocate(box, flags) {
|
||||
this.set_allocation(box, flags);
|
||||
|
||||
let rtl = (Clutter.get_default_text_direction () == Clutter.TextDirection.RTL);
|
||||
|
||||
if (this._thumbnails.length == 0) // not visible
|
||||
return;
|
||||
|
||||
let workspaceManager = global.workspace_manager;
|
||||
let themeNode = this.actor.get_theme_node();
|
||||
let themeNode = this.get_theme_node();
|
||||
|
||||
box = themeNode.get_content_box(box);
|
||||
|
||||
let portholeWidth = this._porthole.width;
|
||||
let portholeHeight = this._porthole.height;
|
||||
|
@ -1,5 +1,5 @@
|
||||
project('gnome-shell', 'c',
|
||||
version: '3.30.2',
|
||||
version: '3.30.1',
|
||||
meson_version: '>= 0.47.0',
|
||||
license: 'GPLv2+'
|
||||
)
|
||||
|
18
po/sk.po
18
po/sk.po
@ -8,7 +8,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: gnome-shell\n"
|
||||
"Report-Msgid-Bugs-To: https://gitlab.gnome.org/GNOME/gnome-shell/issues\n"
|
||||
"POT-Creation-Date: 2018-10-10 19:07+0000\n"
|
||||
"POT-Creation-Date: 2018-10-08 12:48+0000\n"
|
||||
"PO-Revision-Date: 2018-09-16 08:42+0200\n"
|
||||
"Last-Translator: Dušan Kazik <prescott66@gmail.com>\n"
|
||||
"Language-Team: Slovak <gnome-sk-list@gnome.org>\n"
|
||||
@ -686,12 +686,12 @@ msgstr "Pridať do obľúbených"
|
||||
msgid "Show Details"
|
||||
msgstr "Zobraziť podrobnosti"
|
||||
|
||||
#: js/ui/appFavorites.js:140
|
||||
#: js/ui/appFavorites.js:141
|
||||
#, javascript-format
|
||||
msgid "%s has been added to your favorites."
|
||||
msgstr "Aplikácia %s bola pridaná medzi obľúbené."
|
||||
|
||||
#: js/ui/appFavorites.js:174
|
||||
#: js/ui/appFavorites.js:175
|
||||
#, javascript-format
|
||||
msgid "%s has been removed from your favorites."
|
||||
msgstr "Aplikácia %s bola odstránená z obľúbených."
|
||||
@ -855,12 +855,12 @@ msgid "Clear All"
|
||||
msgstr "Vymazať všetko"
|
||||
|
||||
#. Translators: %s is an application name
|
||||
#: js/ui/closeDialog.js:50
|
||||
#: js/ui/closeDialog.js:47
|
||||
#, javascript-format
|
||||
msgid "“%s” is not responding."
|
||||
msgstr "Aplikácia „%s“ neodpovedá."
|
||||
|
||||
#: js/ui/closeDialog.js:51
|
||||
#: js/ui/closeDialog.js:48
|
||||
msgid ""
|
||||
"You may choose to wait a short while for it to continue or force the "
|
||||
"application to quit entirely."
|
||||
@ -868,19 +868,19 @@ msgstr ""
|
||||
"Môžete chvíľu počkať na pokračovanie aplikácie, alebo vynútiť úplné "
|
||||
"ukončenie aplikácie."
|
||||
|
||||
#: js/ui/closeDialog.js:67
|
||||
#: js/ui/closeDialog.js:64
|
||||
msgid "Force Quit"
|
||||
msgstr "Vynútiť ukončenie"
|
||||
|
||||
#: js/ui/closeDialog.js:70
|
||||
#: js/ui/closeDialog.js:67
|
||||
msgid "Wait"
|
||||
msgstr "Počkať"
|
||||
|
||||
#: js/ui/components/automountManager.js:91
|
||||
#: js/ui/components/automountManager.js:90
|
||||
msgid "External drive connected"
|
||||
msgstr "Externá jednotka bola pripojená"
|
||||
|
||||
#: js/ui/components/automountManager.js:102
|
||||
#: js/ui/components/automountManager.js:101
|
||||
msgid "External drive disconnected"
|
||||
msgstr "Externá jednotka bola odpojená"
|
||||
|
||||
|
@ -108,7 +108,6 @@ libshell_public_headers = [
|
||||
'shell-app-system.h',
|
||||
'shell-app-usage.h',
|
||||
'shell-embedded-window.h',
|
||||
'shell-generic-container.h',
|
||||
'shell-glsl-quad.h',
|
||||
'shell-gtk-embed.h',
|
||||
'shell-global.h',
|
||||
@ -144,7 +143,6 @@ libshell_sources = [
|
||||
'shell-app-usage.c',
|
||||
'shell-embedded-window.c',
|
||||
'shell-embedded-window-private.h',
|
||||
'shell-generic-container.c',
|
||||
'shell-global.c',
|
||||
'shell-glsl-quad.c',
|
||||
'shell-gtk-embed.c',
|
||||
|
@ -1,433 +0,0 @@
|
||||
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
|
||||
|
||||
/**
|
||||
* SECTION:shell-generic-container
|
||||
* @short_description: A container class with signals for allocation
|
||||
*
|
||||
* #ShellGenericContainer is mainly a workaround for the current
|
||||
* lack of GObject subclassing + vfunc overrides in gjs. We
|
||||
* implement the container interface, but proxy the virtual functions
|
||||
* into signals, which gjs can catch.
|
||||
*
|
||||
* #ShellGenericContainer is an #StWidget, and automatically takes its
|
||||
* borders and padding into account during size request and allocation.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "shell-generic-container.h"
|
||||
|
||||
#include <clutter/clutter.h>
|
||||
#include <gtk/gtk.h>
|
||||
#include <girepository.h>
|
||||
|
||||
static void shell_generic_container_iface_init (ClutterContainerIface *iface);
|
||||
|
||||
typedef struct _ShellGenericContainerPrivate ShellGenericContainerPrivate;
|
||||
|
||||
struct _ShellGenericContainer
|
||||
{
|
||||
StWidget parent;
|
||||
|
||||
ShellGenericContainerPrivate *priv;
|
||||
};
|
||||
|
||||
struct _ShellGenericContainerPrivate {
|
||||
GHashTable *skip_paint;
|
||||
};
|
||||
|
||||
G_DEFINE_TYPE_WITH_CODE(ShellGenericContainer,
|
||||
shell_generic_container,
|
||||
ST_TYPE_WIDGET,
|
||||
G_ADD_PRIVATE (ShellGenericContainer)
|
||||
G_IMPLEMENT_INTERFACE (CLUTTER_TYPE_CONTAINER,
|
||||
shell_generic_container_iface_init));
|
||||
|
||||
/* Signals */
|
||||
enum
|
||||
{
|
||||
GET_PREFERRED_WIDTH,
|
||||
GET_PREFERRED_HEIGHT,
|
||||
ALLOCATE,
|
||||
LAST_SIGNAL
|
||||
};
|
||||
|
||||
static guint shell_generic_container_signals [LAST_SIGNAL] = { 0 };
|
||||
|
||||
static gpointer
|
||||
shell_generic_container_allocation_ref (ShellGenericContainerAllocation *alloc)
|
||||
{
|
||||
alloc->_refcount++;
|
||||
return alloc;
|
||||
}
|
||||
|
||||
static void
|
||||
shell_generic_container_allocation_unref (ShellGenericContainerAllocation *alloc)
|
||||
{
|
||||
if (--alloc->_refcount == 0)
|
||||
g_slice_free (ShellGenericContainerAllocation, alloc);
|
||||
}
|
||||
|
||||
static void
|
||||
shell_generic_container_allocate (ClutterActor *self,
|
||||
const ClutterActorBox *box,
|
||||
ClutterAllocationFlags flags)
|
||||
{
|
||||
StThemeNode *theme_node;
|
||||
ClutterActorBox content_box;
|
||||
|
||||
clutter_actor_set_allocation (self, box, flags);
|
||||
|
||||
theme_node = st_widget_get_theme_node (ST_WIDGET (self));
|
||||
st_theme_node_get_content_box (theme_node, box, &content_box);
|
||||
|
||||
g_signal_emit (G_OBJECT (self), shell_generic_container_signals[ALLOCATE], 0,
|
||||
&content_box, flags);
|
||||
}
|
||||
|
||||
static void
|
||||
shell_generic_container_get_preferred_width (ClutterActor *actor,
|
||||
gfloat for_height,
|
||||
gfloat *min_width_p,
|
||||
gfloat *natural_width_p)
|
||||
{
|
||||
ShellGenericContainerAllocation *alloc = g_slice_new0 (ShellGenericContainerAllocation);
|
||||
StThemeNode *theme_node = st_widget_get_theme_node (ST_WIDGET (actor));
|
||||
|
||||
st_theme_node_adjust_for_height (theme_node, &for_height);
|
||||
|
||||
alloc->_refcount = 1;
|
||||
g_signal_emit (G_OBJECT (actor), shell_generic_container_signals[GET_PREFERRED_WIDTH], 0,
|
||||
for_height, alloc);
|
||||
if (min_width_p)
|
||||
*min_width_p = alloc->min_size;
|
||||
if (natural_width_p)
|
||||
*natural_width_p = alloc->natural_size;
|
||||
shell_generic_container_allocation_unref (alloc);
|
||||
|
||||
st_theme_node_adjust_preferred_width (theme_node, min_width_p, natural_width_p);
|
||||
}
|
||||
|
||||
static void
|
||||
shell_generic_container_get_preferred_height (ClutterActor *actor,
|
||||
gfloat for_width,
|
||||
gfloat *min_height_p,
|
||||
gfloat *natural_height_p)
|
||||
{
|
||||
ShellGenericContainerAllocation *alloc = g_slice_new0 (ShellGenericContainerAllocation);
|
||||
StThemeNode *theme_node = st_widget_get_theme_node (ST_WIDGET (actor));
|
||||
|
||||
st_theme_node_adjust_for_width (theme_node, &for_width);
|
||||
|
||||
alloc->_refcount = 1;
|
||||
g_signal_emit (G_OBJECT (actor), shell_generic_container_signals[GET_PREFERRED_HEIGHT], 0,
|
||||
for_width, alloc);
|
||||
if (min_height_p)
|
||||
*min_height_p = alloc->min_size;
|
||||
if (natural_height_p)
|
||||
*natural_height_p = alloc->natural_size;
|
||||
shell_generic_container_allocation_unref (alloc);
|
||||
|
||||
st_theme_node_adjust_preferred_height (theme_node, min_height_p, natural_height_p);
|
||||
}
|
||||
|
||||
static void
|
||||
shell_generic_container_paint (ClutterActor *actor)
|
||||
{
|
||||
ShellGenericContainer *self = (ShellGenericContainer*) actor;
|
||||
ClutterActor *child;
|
||||
|
||||
st_widget_paint_background (ST_WIDGET (actor));
|
||||
|
||||
for (child = clutter_actor_get_first_child (actor);
|
||||
child != NULL;
|
||||
child = clutter_actor_get_next_sibling (child))
|
||||
{
|
||||
if (g_hash_table_lookup (self->priv->skip_paint, child))
|
||||
continue;
|
||||
|
||||
clutter_actor_paint (child);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
shell_generic_container_pick (ClutterActor *actor,
|
||||
const ClutterColor *color)
|
||||
{
|
||||
ShellGenericContainer *self = (ShellGenericContainer*) actor;
|
||||
ClutterActor *child;
|
||||
|
||||
CLUTTER_ACTOR_CLASS (shell_generic_container_parent_class)->pick (actor, color);
|
||||
|
||||
for (child = clutter_actor_get_first_child (actor);
|
||||
child != NULL;
|
||||
child = clutter_actor_get_next_sibling (child))
|
||||
{
|
||||
if (g_hash_table_lookup (self->priv->skip_paint, child))
|
||||
continue;
|
||||
|
||||
clutter_actor_paint (child);
|
||||
}
|
||||
}
|
||||
|
||||
static GList *
|
||||
shell_generic_container_get_focus_chain (StWidget *widget)
|
||||
{
|
||||
ShellGenericContainer *self = SHELL_GENERIC_CONTAINER (widget);
|
||||
ClutterActor *child;
|
||||
GList *focus_chain;
|
||||
|
||||
focus_chain = NULL;
|
||||
for (child = clutter_actor_get_first_child (CLUTTER_ACTOR (self));
|
||||
child != NULL;
|
||||
child = clutter_actor_get_next_sibling (child))
|
||||
{
|
||||
if (clutter_actor_is_visible (child) &&
|
||||
!shell_generic_container_get_skip_paint (self, child))
|
||||
focus_chain = g_list_prepend (focus_chain, child);
|
||||
}
|
||||
|
||||
return g_list_reverse (focus_chain);
|
||||
}
|
||||
|
||||
/**
|
||||
* shell_generic_container_get_n_skip_paint:
|
||||
* @self: A #ShellGenericContainer
|
||||
*
|
||||
* Returns: Number of children which will not be painted.
|
||||
*/
|
||||
guint
|
||||
shell_generic_container_get_n_skip_paint (ShellGenericContainer *self)
|
||||
{
|
||||
return g_hash_table_size (self->priv->skip_paint);
|
||||
}
|
||||
|
||||
/**
|
||||
* shell_generic_container_get_skip_paint:
|
||||
* @self: A #ShellGenericContainer
|
||||
* @child: Child #ClutterActor
|
||||
*
|
||||
* Gets whether or not @actor is skipped when painting.
|
||||
*
|
||||
* Return value: %TRUE or %FALSE
|
||||
*/
|
||||
gboolean
|
||||
shell_generic_container_get_skip_paint (ShellGenericContainer *self,
|
||||
ClutterActor *child)
|
||||
{
|
||||
return g_hash_table_lookup (self->priv->skip_paint, child) != NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* shell_generic_container_set_skip_paint:
|
||||
* @self: A #ShellGenericContainer
|
||||
* @child: Child #ClutterActor
|
||||
* @skip: %TRUE if we should skip painting
|
||||
*
|
||||
* Set whether or not we should skip painting @actor. Workaround for
|
||||
* lack of gjs ability to override _paint vfunc.
|
||||
*/
|
||||
void
|
||||
shell_generic_container_set_skip_paint (ShellGenericContainer *self,
|
||||
ClutterActor *child,
|
||||
gboolean skip)
|
||||
{
|
||||
gboolean currently_skipping;
|
||||
|
||||
currently_skipping = g_hash_table_lookup (self->priv->skip_paint, child) != NULL;
|
||||
if ((!!skip) == currently_skipping)
|
||||
return;
|
||||
|
||||
if (!skip)
|
||||
g_hash_table_remove (self->priv->skip_paint, child);
|
||||
else
|
||||
g_hash_table_insert (self->priv->skip_paint, child, child);
|
||||
|
||||
clutter_actor_queue_redraw (CLUTTER_ACTOR (self));
|
||||
}
|
||||
|
||||
static gboolean
|
||||
shell_generic_container_get_paint_volume (ClutterActor *self,
|
||||
ClutterPaintVolume *volume)
|
||||
{
|
||||
ClutterActorBox paint_box, alloc_box;
|
||||
StThemeNode *theme_node;
|
||||
ClutterVertex origin;
|
||||
|
||||
/* Setting the paint volume does not make sense when we don't have any allocation */
|
||||
if (!clutter_actor_has_allocation (self))
|
||||
return FALSE;
|
||||
|
||||
theme_node = st_widget_get_theme_node (ST_WIDGET (self));
|
||||
clutter_actor_get_allocation_box (self, &alloc_box);
|
||||
|
||||
st_theme_node_get_paint_box (theme_node, &alloc_box, &paint_box);
|
||||
|
||||
origin.x = paint_box.x1 - alloc_box.x1;
|
||||
origin.y = paint_box.y1 - alloc_box.y1;
|
||||
origin.z = 0.0f;
|
||||
|
||||
clutter_paint_volume_set_origin (volume, &origin);
|
||||
clutter_paint_volume_set_width (volume, paint_box.x2 - paint_box.x1);
|
||||
clutter_paint_volume_set_height (volume, paint_box.y2 - paint_box.y1);
|
||||
|
||||
if (!clutter_actor_get_clip_to_allocation (self))
|
||||
{
|
||||
ClutterActor *child;
|
||||
/* Based on ClutterGroup/ClutterBox; include the children's
|
||||
* paint volumes, since they may paint outside our allocation.
|
||||
*/
|
||||
for (child = clutter_actor_get_first_child (self);
|
||||
child != NULL;
|
||||
child = clutter_actor_get_next_sibling (child))
|
||||
{
|
||||
const ClutterPaintVolume *child_volume;
|
||||
|
||||
if (!clutter_actor_is_visible (child))
|
||||
continue;
|
||||
|
||||
if (shell_generic_container_get_skip_paint (SHELL_GENERIC_CONTAINER (self), child))
|
||||
continue;
|
||||
|
||||
child_volume = clutter_actor_get_transformed_paint_volume (child, self);
|
||||
if (!child_volume)
|
||||
return FALSE;
|
||||
|
||||
clutter_paint_volume_union (volume, child_volume);
|
||||
}
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
shell_generic_container_finalize (GObject *object)
|
||||
{
|
||||
ShellGenericContainer *self = (ShellGenericContainer*) object;
|
||||
|
||||
g_hash_table_destroy (self->priv->skip_paint);
|
||||
|
||||
G_OBJECT_CLASS (shell_generic_container_parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
static void
|
||||
shell_generic_container_class_init (ShellGenericContainerClass *klass)
|
||||
{
|
||||
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
|
||||
ClutterActorClass *actor_class = CLUTTER_ACTOR_CLASS (klass);
|
||||
StWidgetClass *widget_class = ST_WIDGET_CLASS (klass);
|
||||
|
||||
gobject_class->finalize = shell_generic_container_finalize;
|
||||
|
||||
actor_class->get_preferred_width = shell_generic_container_get_preferred_width;
|
||||
actor_class->get_preferred_height = shell_generic_container_get_preferred_height;
|
||||
actor_class->allocate = shell_generic_container_allocate;
|
||||
actor_class->paint = shell_generic_container_paint;
|
||||
actor_class->pick = shell_generic_container_pick;
|
||||
actor_class->get_paint_volume = shell_generic_container_get_paint_volume;
|
||||
|
||||
widget_class->get_focus_chain = shell_generic_container_get_focus_chain;
|
||||
|
||||
/**
|
||||
* ShellGenericContainer::get-preferred-width:
|
||||
* @self: the #ShellGenericContainer
|
||||
* @for_height: as in clutter_actor_get_preferred_width()
|
||||
* @alloc: a #ShellGenericContainerAllocation to be filled in
|
||||
*
|
||||
* Emitted when clutter_actor_get_preferred_width() is called
|
||||
* on @self. You should fill in the fields of @alloc with the
|
||||
* your minimum and natural widths. #ShellGenericContainer
|
||||
* will deal with taking its borders and padding into account
|
||||
* for you.
|
||||
*
|
||||
* @alloc's fields are initialized to 0, so unless you have a fixed
|
||||
* width specified (via #ClutterActor:width or CSS), you must
|
||||
* connect to this signal and fill in the values.
|
||||
*/
|
||||
shell_generic_container_signals[GET_PREFERRED_WIDTH] =
|
||||
g_signal_new ("get-preferred-width",
|
||||
G_TYPE_FROM_CLASS (klass),
|
||||
G_SIGNAL_RUN_LAST,
|
||||
0,
|
||||
NULL, NULL, NULL,
|
||||
G_TYPE_NONE, 2, G_TYPE_FLOAT, SHELL_TYPE_GENERIC_CONTAINER_ALLOCATION);
|
||||
|
||||
/**
|
||||
* ShellGenericContainer::get-preferred-height:
|
||||
* @self: the #ShellGenericContainer
|
||||
* @for_width: as in clutter_actor_get_preferred_height()
|
||||
* @alloc: a #ShellGenericContainerAllocation to be filled in
|
||||
*
|
||||
* Emitted when clutter_actor_get_preferred_height() is called
|
||||
* on @self. You should fill in the fields of @alloc with the
|
||||
* your minimum and natural heights. #ShellGenericContainer
|
||||
* will deal with taking its borders and padding into account
|
||||
* for you.
|
||||
*
|
||||
* @alloc's fields are initialized to 0, so unless you have a fixed
|
||||
* height specified (via #ClutterActor:height or CSS), you must
|
||||
* connect to this signal and fill in the values.
|
||||
*/
|
||||
shell_generic_container_signals[GET_PREFERRED_HEIGHT] =
|
||||
g_signal_new ("get-preferred-height",
|
||||
G_TYPE_FROM_CLASS (klass),
|
||||
G_SIGNAL_RUN_LAST,
|
||||
0,
|
||||
NULL, NULL, NULL,
|
||||
G_TYPE_NONE, 2, G_TYPE_FLOAT, SHELL_TYPE_GENERIC_CONTAINER_ALLOCATION);
|
||||
|
||||
/**
|
||||
* ShellGenericContainer::allocate:
|
||||
* @self: the #ShellGenericContainer
|
||||
* @box: @self's content box
|
||||
* @flags: the allocation flags.
|
||||
*
|
||||
* Emitted when @self is allocated, after chaining up to the parent
|
||||
* allocate method.
|
||||
*
|
||||
* Note that @box is @self's content box (qv
|
||||
* st_theme_node_get_content_box()), NOT its allocation.
|
||||
*/
|
||||
shell_generic_container_signals[ALLOCATE] =
|
||||
g_signal_new ("allocate",
|
||||
G_TYPE_FROM_CLASS (klass),
|
||||
G_SIGNAL_RUN_LAST,
|
||||
0,
|
||||
NULL, NULL, NULL,
|
||||
G_TYPE_NONE, 2, CLUTTER_TYPE_ACTOR_BOX, CLUTTER_TYPE_ALLOCATION_FLAGS);
|
||||
}
|
||||
|
||||
static void
|
||||
shell_generic_container_actor_removed (ClutterContainer *container,
|
||||
ClutterActor *actor)
|
||||
{
|
||||
ShellGenericContainerPrivate *priv = SHELL_GENERIC_CONTAINER (container)->priv;
|
||||
|
||||
g_hash_table_remove (priv->skip_paint, actor);
|
||||
}
|
||||
|
||||
static void
|
||||
shell_generic_container_iface_init (ClutterContainerIface *iface)
|
||||
{
|
||||
iface->actor_removed = shell_generic_container_actor_removed;
|
||||
}
|
||||
|
||||
static void
|
||||
shell_generic_container_init (ShellGenericContainer *area)
|
||||
{
|
||||
area->priv = shell_generic_container_get_instance_private (area);
|
||||
area->priv->skip_paint = g_hash_table_new (NULL, NULL);
|
||||
}
|
||||
|
||||
GType
|
||||
shell_generic_container_allocation_get_type (void)
|
||||
{
|
||||
static GType gtype = G_TYPE_INVALID;
|
||||
if (gtype == G_TYPE_INVALID)
|
||||
{
|
||||
gtype = g_boxed_type_register_static ("ShellGenericContainerAllocation",
|
||||
(GBoxedCopyFunc)shell_generic_container_allocation_ref,
|
||||
(GBoxedFreeFunc)shell_generic_container_allocation_unref);
|
||||
}
|
||||
return gtype;
|
||||
}
|
@ -1,30 +0,0 @@
|
||||
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
|
||||
#ifndef __SHELL_GENERIC_CONTAINER_H__
|
||||
#define __SHELL_GENERIC_CONTAINER_H__
|
||||
|
||||
#include "st.h"
|
||||
|
||||
#define SHELL_TYPE_GENERIC_CONTAINER (shell_generic_container_get_type ())
|
||||
G_DECLARE_FINAL_TYPE (ShellGenericContainer, shell_generic_container,
|
||||
SHELL, GENERIC_CONTAINER, StWidget)
|
||||
|
||||
typedef struct {
|
||||
float min_size;
|
||||
float natural_size;
|
||||
|
||||
/* <private> */
|
||||
guint _refcount;
|
||||
} ShellGenericContainerAllocation;
|
||||
|
||||
#define SHELL_TYPE_GENERIC_CONTAINER_ALLOCATION (shell_generic_container_allocation_get_type ())
|
||||
GType shell_generic_container_allocation_get_type (void);
|
||||
|
||||
guint shell_generic_container_get_n_skip_paint (ShellGenericContainer *self);
|
||||
|
||||
gboolean shell_generic_container_get_skip_paint (ShellGenericContainer *self,
|
||||
ClutterActor *child);
|
||||
void shell_generic_container_set_skip_paint (ShellGenericContainer *self,
|
||||
ClutterActor *child,
|
||||
gboolean skip);
|
||||
|
||||
#endif /* __SHELL_GENERIC_CONTAINER_H__ */
|
@ -10,8 +10,6 @@
|
||||
|
||||
#include <pwd.h>
|
||||
|
||||
#define POLKIT_AGENT_I_KNOW_API_IS_SUBJECT_TO_CHANGE
|
||||
#include <polkitagent/polkitagent.h>
|
||||
#include "shell-polkit-authentication-agent.h"
|
||||
|
||||
#include <glib/gi18n.h>
|
||||
@ -49,12 +47,6 @@ print_debug (const gchar *str, ...)
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
struct _ShellPolkitAuthenticationAgentClass
|
||||
{
|
||||
PolkitAgentListenerClass parent_class;
|
||||
};
|
||||
|
||||
struct _AuthRequest;
|
||||
typedef struct _AuthRequest AuthRequest;
|
||||
|
||||
@ -326,8 +318,11 @@ shell_polkit_authentication_agent_unregister (ShellPolkitAuthenticationAgent *ag
|
||||
if (agent->current_request != NULL)
|
||||
auth_request_dismiss (agent->current_request);
|
||||
|
||||
polkit_agent_listener_unregister (agent->handle);
|
||||
agent->handle = NULL;
|
||||
if (agent->handle)
|
||||
{
|
||||
polkit_agent_listener_unregister (agent->handle);
|
||||
agent->handle = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static void maybe_process_next_request (ShellPolkitAuthenticationAgent *agent);
|
||||
|
@ -6,25 +6,23 @@
|
||||
* Author: David Zeuthen <davidz@redhat.com>
|
||||
*/
|
||||
|
||||
#ifndef __SHELL_POLKIT_AUTHENTICATION_AGENT_H__
|
||||
#define __SHELL_POLKIT_AUTHENTICATION_AGENT_H__
|
||||
#pragma once
|
||||
|
||||
#define POLKIT_AGENT_I_KNOW_API_IS_SUBJECT_TO_CHANGE
|
||||
#include <polkitagent/polkitagent.h>
|
||||
#include <glib-object.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
typedef struct _ShellPolkitAuthenticationAgent ShellPolkitAuthenticationAgent;
|
||||
typedef struct _ShellPolkitAuthenticationAgentClass ShellPolkitAuthenticationAgentClass;
|
||||
/* Polkit doesn't have g_autoptr support, thus we have to manually set the autoptr function here */
|
||||
G_DEFINE_AUTOPTR_CLEANUP_FUNC (PolkitAgentListener, g_object_unref)
|
||||
|
||||
#define SHELL_TYPE_POLKIT_AUTHENTICATION_AGENT (shell_polkit_authentication_agent_get_type ())
|
||||
#define SHELL_POLKIT_AUTHENTICATION_AGENT(object) (G_TYPE_CHECK_INSTANCE_CAST ((object), SHELL_TYPE_POLKIT_AUTHENTICATION_AGENT, ShellPolkitAuthenticationAgent))
|
||||
#define SHELL_POLKIT_AUTHENTICATION_AGENT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), SHELL_TYPE_POLKIT_AUTHENTICATION_AGENT, ShellPolkitAuthenticationAgentClass))
|
||||
#define SHELL_IS_POLKIT_AUTHENTICATION_AGENT(object) (G_TYPE_CHECK_INSTANCE_TYPE ((object), SHELL_TYPE_POLKIT_AUTHENTICATION_AGENT))
|
||||
#define SHELL_IS_POLKIT_AUTHENTICATION_AGENT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), SHELL_TYPE_POLKIT_AUTHENTICATION_AGENT))
|
||||
#define SHELL_POLKIT_AUTHENTICATION_AGENT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), SHELL_TYPE_POLKIT_AUTHENTICATION_AGENT, ShellPolkitAuthenticationAgentClass))
|
||||
#define SHELL_TYPE_POLKIT_AUTHENTICATION_AGENT (shell_polkit_authentication_agent_get_type())
|
||||
|
||||
G_DECLARE_FINAL_TYPE (ShellPolkitAuthenticationAgent, shell_polkit_authentication_agent, SHELL, POLKIT_AUTHENTICATION_AGENT, PolkitAgentListener)
|
||||
|
||||
ShellPolkitAuthenticationAgent *shell_polkit_authentication_agent_new (void);
|
||||
|
||||
GType shell_polkit_authentication_agent_get_type (void) G_GNUC_CONST;
|
||||
ShellPolkitAuthenticationAgent *shell_polkit_authentication_agent_new (void);
|
||||
void shell_polkit_authentication_agent_complete (ShellPolkitAuthenticationAgent *agent,
|
||||
gboolean dismissed);
|
||||
void shell_polkit_authentication_agent_register (ShellPolkitAuthenticationAgent *agent,
|
||||
@ -33,4 +31,3 @@ void shell_polkit_authentication_agent_unregister (Sh
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __SHELL_POLKIT_AUTHENTICATION_AGENT_H__ */
|
||||
|
@ -177,15 +177,15 @@ st_bin_get_preferred_height (ClutterActor *self,
|
||||
}
|
||||
|
||||
static void
|
||||
st_bin_dispose (GObject *gobject)
|
||||
st_bin_destroy (ClutterActor *actor)
|
||||
{
|
||||
StBinPrivate *priv = st_bin_get_instance_private (ST_BIN (gobject));
|
||||
StBinPrivate *priv = st_bin_get_instance_private (ST_BIN (actor));
|
||||
|
||||
if (priv->child)
|
||||
clutter_actor_destroy (priv->child);
|
||||
g_assert (priv->child == NULL);
|
||||
|
||||
G_OBJECT_CLASS (st_bin_parent_class)->dispose (gobject);
|
||||
CLUTTER_ACTOR_CLASS (st_bin_parent_class)->destroy (actor);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -315,11 +315,11 @@ st_bin_class_init (StBinClass *klass)
|
||||
|
||||
gobject_class->set_property = st_bin_set_property;
|
||||
gobject_class->get_property = st_bin_get_property;
|
||||
gobject_class->dispose = st_bin_dispose;
|
||||
|
||||
actor_class->get_preferred_width = st_bin_get_preferred_width;
|
||||
actor_class->get_preferred_height = st_bin_get_preferred_height;
|
||||
actor_class->allocate = st_bin_allocate;
|
||||
actor_class->destroy = st_bin_destroy;
|
||||
|
||||
widget_class->popup_menu = st_bin_popup_menu;
|
||||
widget_class->navigate_focus = st_bin_navigate_focus;
|
||||
|
@ -282,13 +282,12 @@ st_box_layout_allocate (ClutterActor *actor,
|
||||
StBoxLayoutPrivate *priv = ST_BOX_LAYOUT (actor)->priv;
|
||||
StThemeNode *theme_node = st_widget_get_theme_node (ST_WIDGET (actor));
|
||||
ClutterLayoutManager *layout = clutter_actor_get_layout_manager (actor);
|
||||
ClutterActorBox viewport_content_box;
|
||||
ClutterActorBox content_box;
|
||||
gfloat avail_width, avail_height, min_width, natural_width, min_height, natural_height;
|
||||
|
||||
CLUTTER_ACTOR_CLASS (st_box_layout_parent_class)->allocate (actor, box, flags);
|
||||
|
||||
st_theme_node_get_content_box (theme_node, box, &content_box);
|
||||
clutter_actor_box_get_size (&content_box, &avail_width, &avail_height);
|
||||
st_theme_node_get_content_box (theme_node, box, &viewport_content_box);
|
||||
clutter_actor_box_get_size (&viewport_content_box, &avail_width, &avail_height);
|
||||
|
||||
clutter_layout_manager_get_preferred_width (layout, CLUTTER_CONTAINER (actor),
|
||||
avail_height,
|
||||
@ -297,6 +296,18 @@ st_box_layout_allocate (ClutterActor *actor,
|
||||
MAX (avail_width, min_width),
|
||||
&min_height, &natural_height);
|
||||
|
||||
/* Because StBoxLayout implements StScrollable, the allocation box passed here
|
||||
* may not match the minimum sizes reported by the layout manager. When that
|
||||
* happens, the content box needs to be adjusted to match the reported minimum
|
||||
* sizes before being passed to clutter_layout_manager_allocate() */
|
||||
clutter_actor_set_allocation (actor, box, flags);
|
||||
|
||||
content_box = viewport_content_box;
|
||||
content_box.x2 += MAX (0, min_width - avail_width);
|
||||
content_box.y2 += MAX (0, min_height - avail_height);
|
||||
|
||||
clutter_layout_manager_allocate (layout, CLUTTER_CONTAINER (actor),
|
||||
&content_box, flags);
|
||||
|
||||
/* update adjustments for scrolling */
|
||||
if (priv->vadjustment)
|
||||
|
@ -455,14 +455,13 @@ _st_create_shadow_pipeline_from_actor (StShadow *shadow_spec,
|
||||
CoglTexture *buffer;
|
||||
CoglOffscreen *offscreen;
|
||||
CoglFramebuffer *fb;
|
||||
CoglContext *ctx;
|
||||
CoglColor clear_color;
|
||||
CoglError *catch_error = NULL;
|
||||
float x, y;
|
||||
|
||||
buffer = cogl_texture_new_with_size (width,
|
||||
height,
|
||||
COGL_TEXTURE_NO_SLICING,
|
||||
COGL_PIXEL_FORMAT_ANY);
|
||||
ctx = clutter_backend_get_cogl_context (clutter_get_default_backend ());
|
||||
buffer = cogl_texture_2d_new_with_size (ctx, width, height);
|
||||
|
||||
if (buffer == NULL)
|
||||
return NULL;
|
||||
|
@ -66,10 +66,10 @@ st_scroll_view_fade_create_texture (ClutterOffscreenEffect *effect,
|
||||
gfloat min_width,
|
||||
gfloat min_height)
|
||||
{
|
||||
return cogl_texture_new_with_size (min_width,
|
||||
min_height,
|
||||
COGL_TEXTURE_NO_SLICING,
|
||||
COGL_PIXEL_FORMAT_RGBA_8888_PRE);
|
||||
CoglContext *ctx =
|
||||
clutter_backend_get_cogl_context (clutter_get_default_backend ());
|
||||
|
||||
return cogl_texture_2d_new_with_size (ctx, min_width, min_height);
|
||||
}
|
||||
|
||||
static char *
|
||||
|
@ -2220,12 +2220,15 @@ static void
|
||||
st_theme_node_prerender_shadow (StThemeNodePaintState *state)
|
||||
{
|
||||
StThemeNode *node = state->node;
|
||||
CoglContext *ctx;
|
||||
guint border_radius[4];
|
||||
int max_borders[4];
|
||||
int center_radius, corner_id;
|
||||
CoglHandle buffer, offscreen = COGL_INVALID_HANDLE;
|
||||
CoglError *error = NULL;
|
||||
|
||||
ctx = clutter_backend_get_cogl_context (clutter_get_default_backend ());
|
||||
|
||||
/* Get infos from the node */
|
||||
if (state->alloc_width < node->box_shadow_min_width ||
|
||||
state->alloc_height < node->box_shadow_min_height)
|
||||
@ -2261,10 +2264,9 @@ st_theme_node_prerender_shadow (StThemeNodePaintState *state)
|
||||
}
|
||||
|
||||
/* Render offscreen */
|
||||
buffer = cogl_texture_new_with_size (state->box_shadow_width,
|
||||
state->box_shadow_height,
|
||||
COGL_TEXTURE_NO_SLICING,
|
||||
COGL_PIXEL_FORMAT_ANY);
|
||||
buffer = cogl_texture_2d_new_with_size (ctx,
|
||||
state->box_shadow_width,
|
||||
state->box_shadow_height);
|
||||
if (buffer == NULL)
|
||||
return;
|
||||
|
||||
|
@ -240,12 +240,14 @@ setup_framebuffers (StThemeNodeTransition *transition,
|
||||
const ClutterActorBox *allocation)
|
||||
{
|
||||
StThemeNodeTransitionPrivate *priv = transition->priv;
|
||||
CoglContext *ctx;
|
||||
guint width, height;
|
||||
CoglError *catch_error = NULL;
|
||||
|
||||
/* template material to avoid unnecessary shader compilation */
|
||||
static CoglHandle material_template = COGL_INVALID_HANDLE;
|
||||
|
||||
ctx = clutter_backend_get_cogl_context (clutter_get_default_backend ());
|
||||
width = priv->offscreen_box.x2 - priv->offscreen_box.x1;
|
||||
height = priv->offscreen_box.y2 - priv->offscreen_box.y1;
|
||||
|
||||
@ -254,15 +256,11 @@ setup_framebuffers (StThemeNodeTransition *transition,
|
||||
|
||||
if (priv->old_texture)
|
||||
cogl_handle_unref (priv->old_texture);
|
||||
priv->old_texture = cogl_texture_new_with_size (width, height,
|
||||
COGL_TEXTURE_NO_SLICING,
|
||||
COGL_PIXEL_FORMAT_ANY);
|
||||
priv->old_texture = cogl_texture_2d_new_with_size (ctx, width, height);
|
||||
|
||||
if (priv->new_texture)
|
||||
cogl_handle_unref (priv->new_texture);
|
||||
priv->new_texture = cogl_texture_new_with_size (width, height,
|
||||
COGL_TEXTURE_NO_SLICING,
|
||||
COGL_PIXEL_FORMAT_ANY);
|
||||
priv->new_texture = cogl_texture_2d_new_with_size (ctx, width, height);
|
||||
|
||||
if (priv->old_texture == COGL_INVALID_HANDLE)
|
||||
return FALSE;
|
||||
|
@ -32,26 +32,22 @@ const BOX_WIDTHS = [
|
||||
|
||||
const SPACING = 10;
|
||||
|
||||
function FlowedBoxes() {
|
||||
this._init();
|
||||
}
|
||||
var FlowedBoxes = new Lang.Class({
|
||||
Name: 'FlowedBoxes',
|
||||
Extends: St.Widget,
|
||||
|
||||
FlowedBoxes.prototype = {
|
||||
_init() {
|
||||
this.actor = new Shell.GenericContainer();
|
||||
this.actor.connect('get-preferred-width', this._getPreferredWidth.bind(this));
|
||||
this.actor.connect('get-preferred-height', this._getPreferredHeight.bind(this));
|
||||
this.actor.connect('allocate', this._allocate.bind(this));
|
||||
this.parent();
|
||||
|
||||
for (let i = 0; i < BOX_WIDTHS.length; i++) {
|
||||
let child = new St.Bin({ width: BOX_WIDTHS[i], height: BOX_HEIGHT,
|
||||
style: 'border: 1px solid #444444; background: #00aa44' })
|
||||
this.actor.add_actor(child);
|
||||
this.add_actor(child);
|
||||
}
|
||||
},
|
||||
|
||||
_getPreferredWidth(actor, forHeight, alloc) {
|
||||
let children = this.actor.get_children();
|
||||
vfunc_get_preferred_width(forHeight) {
|
||||
let children = this.get_children();
|
||||
|
||||
let maxMinWidth = 0;
|
||||
let totalNaturalWidth = 0;
|
||||
@ -65,12 +61,11 @@ FlowedBoxes.prototype = {
|
||||
totalNaturalWidth += naturalWidth;
|
||||
}
|
||||
|
||||
alloc.min_size = maxMinWidth;
|
||||
alloc.natural_size = totalNaturalWidth;
|
||||
return [maxMinWidth, totalNaturalWidth];
|
||||
},
|
||||
|
||||
_layoutChildren(forWidth, callback) {
|
||||
let children = this.actor.get_children();
|
||||
let children = this.get_children();
|
||||
|
||||
let x = 0;
|
||||
let y = 0;
|
||||
@ -99,24 +94,26 @@ FlowedBoxes.prototype = {
|
||||
|
||||
},
|
||||
|
||||
_getPreferredHeight(actor, forWidth, alloc) {
|
||||
vfunc_get_preferred_height(forWidth) {
|
||||
let height = 0;
|
||||
this._layoutChildren(forWidth,
|
||||
function(child, x1, y1, x2, y2) {
|
||||
height = Math.max(height, y2);
|
||||
});
|
||||
|
||||
alloc.min_size = alloc.natural_size = height;
|
||||
return [height, height];
|
||||
},
|
||||
|
||||
_allocate(actor, box, flags) {
|
||||
vfunc_allocate(box, flags) {
|
||||
this.set_allocation(box, flags);
|
||||
|
||||
this._layoutChildren(box.x2 - box.x1,
|
||||
function(child, x1, y1, x2, y2) {
|
||||
child.allocate(new Clutter.ActorBox({ x1: x1, y1: y1, x2: x2, y2: y2 }),
|
||||
flags);
|
||||
});
|
||||
}
|
||||
};
|
||||
});
|
||||
|
||||
/****************************************************************************/
|
||||
|
||||
@ -127,39 +124,34 @@ FlowedBoxes.prototype = {
|
||||
//
|
||||
// This is currently only written for the case where the child is height-for-width
|
||||
|
||||
function SizingIllustrator() {
|
||||
this._init();
|
||||
}
|
||||
var SizingIllustrator = new Lang.Class({
|
||||
Name: 'SizingIllustrator',
|
||||
Extends: St.Widget,
|
||||
|
||||
SizingIllustrator.prototype = {
|
||||
_init() {
|
||||
this.actor = new Shell.GenericContainer();
|
||||
|
||||
this.actor.connect('get-preferred-width', this._getPreferredWidth.bind(this));
|
||||
this.actor.connect('get-preferred-height', this._getPreferredHeight.bind(this));
|
||||
this.actor.connect('allocate', this._allocate.bind(this));
|
||||
this.parent();
|
||||
|
||||
this.minWidthLine = new St.Bin({ style: 'background: red' });
|
||||
this.actor.add_actor(this.minWidthLine);
|
||||
this.add_actor(this.minWidthLine);
|
||||
this.minHeightLine = new St.Bin({ style: 'background: red' });
|
||||
this.actor.add_actor(this.minHeightLine);
|
||||
this.add_actor(this.minHeightLine);
|
||||
|
||||
this.naturalWidthLine = new St.Bin({ style: 'background: #4444ff' });
|
||||
this.actor.add_actor(this.naturalWidthLine);
|
||||
this.add_actor(this.naturalWidthLine);
|
||||
this.naturalHeightLine = new St.Bin({ style: 'background: #4444ff' });
|
||||
this.actor.add_actor(this.naturalHeightLine);
|
||||
this.add_actor(this.naturalHeightLine);
|
||||
|
||||
this.currentWidthLine = new St.Bin({ style: 'background: #aaaaaa' });
|
||||
this.actor.add_actor(this.currentWidthLine);
|
||||
this.add_actor(this.currentWidthLine);
|
||||
this.currentHeightLine = new St.Bin({ style: 'background: #aaaaaa' });
|
||||
this.actor.add_actor(this.currentHeightLine);
|
||||
this.add_actor(this.currentHeightLine);
|
||||
|
||||
this.handle = new St.Bin({ style: 'background: yellow; border: 1px solid black;',
|
||||
reactive: true });
|
||||
this.handle.connect('button-press-event', this._handlePressed.bind(this));
|
||||
this.handle.connect('button-release-event', this._handleReleased.bind(this));
|
||||
this.handle.connect('motion-event', this._handleMotion.bind(this));
|
||||
this.actor.add_actor(this.handle);
|
||||
this.add_actor(this.handle);
|
||||
|
||||
this._inDrag = false;
|
||||
|
||||
@ -168,13 +160,13 @@ SizingIllustrator.prototype = {
|
||||
},
|
||||
|
||||
add(child) {
|
||||
this.child = child;
|
||||
this.actor.add_actor(this.child);
|
||||
this.child.lower_bottom();
|
||||
this.child = child;
|
||||
this.add_child(child);
|
||||
this.child.lower_bottom();
|
||||
},
|
||||
|
||||
_getPreferredWidth(actor, forHeight, alloc) {
|
||||
let children = this.actor.get_children();
|
||||
vfunc_get_preferred_width(forHeight) {
|
||||
let children = this.get_children();
|
||||
for (let i = 0; i < children.length; i++) {
|
||||
let child = children[i];
|
||||
let [minWidth, naturalWidth] = child.get_preferred_width(-1);
|
||||
@ -184,27 +176,28 @@ SizingIllustrator.prototype = {
|
||||
}
|
||||
}
|
||||
|
||||
alloc.min_size = 0;
|
||||
alloc.natural_size = 400;
|
||||
return [0, 400];
|
||||
},
|
||||
|
||||
_getPreferredHeight(actor, forWidth, alloc) {
|
||||
let children = this.actor.get_children();
|
||||
vfunc_get_preferred_height(forWidth) {
|
||||
let children = this.get_children();
|
||||
for (let i = 0; i < children.length; i++) {
|
||||
let child = children[i];
|
||||
if (child == this.child) {
|
||||
[this.minHeight, this.naturalHeight] = child.get_preferred_height(this.width);
|
||||
} else {
|
||||
let [minWidth, naturalWidth] = child.get_preferred_width(-1);
|
||||
child.get_preferred_height(naturalWidth);
|
||||
let [minWidth, naturalWidth] = child.get_preferred_height(naturalWidth);
|
||||
}
|
||||
}
|
||||
|
||||
alloc.min_size = 0;
|
||||
alloc.natural_size = 400;
|
||||
return [0, 400];
|
||||
},
|
||||
|
||||
_allocate(actor, box, flags) {
|
||||
vfunc_allocate(box, flags) {
|
||||
this.set_allocation(box, flags);
|
||||
|
||||
box = this.get_theme_node().get_content_box(box);
|
||||
|
||||
let allocWidth = box.x2 - box.x1;
|
||||
let allocHeight = box.y2 - box.y1;
|
||||
|
||||
@ -244,13 +237,13 @@ SizingIllustrator.prototype = {
|
||||
_handleMotion(handle, event) {
|
||||
if (this._inDrag) {
|
||||
let [x, y] = event.get_coords();
|
||||
let [actorX, actorY] = this.actor.get_transformed_position();
|
||||
let [actorX, actorY] = this.get_transformed_position();
|
||||
this.width = x - this._dragX - actorX;
|
||||
this.height = y - this._dragY - actorY;
|
||||
this.actor.queue_relayout();
|
||||
this.queue_relayout();
|
||||
}
|
||||
}
|
||||
};
|
||||
});
|
||||
|
||||
/****************************************************************************/
|
||||
|
||||
@ -278,7 +271,7 @@ function test() {
|
||||
mainBox.add(bin, { x_fill: true, y_fill: true, expand: true });
|
||||
|
||||
let illustrator = new SizingIllustrator();
|
||||
bin.add_actor(illustrator.actor);
|
||||
bin.add_actor(illustrator);
|
||||
|
||||
let scrollView = new St.ScrollView();
|
||||
illustrator.add(scrollView);
|
||||
@ -287,7 +280,7 @@ function test() {
|
||||
scrollView.add_actor(box);
|
||||
|
||||
let flowedBoxes = new FlowedBoxes();
|
||||
box.add(flowedBoxes.actor, { expand: false, x_fill: true, y_fill: true });
|
||||
box.add(flowedBoxes, { expand: false, x_fill: true, y_fill: true });
|
||||
|
||||
let policyBox = new St.BoxLayout({ vertical: false });
|
||||
mainBox.add(policyBox);
|
||||
|
Reference in New Issue
Block a user