Compare commits
31 Commits
3.30.2
...
wip/fmuell
Author | SHA1 | Date | |
---|---|---|---|
![]() |
d0d0350a8c | ||
![]() |
e45e8a2a14 | ||
![]() |
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 |
@@ -729,7 +729,9 @@ StScrollBar {
|
||||
/* TOP BAR */
|
||||
|
||||
#panel {
|
||||
background-color: rgba(0, 0, 0, 0.35);
|
||||
background-gradient-start: rgba(0,0,0,0.3);
|
||||
background-gradient-end: rgba(0,0,0,0);
|
||||
background-gradient-direction: vertical;
|
||||
/* transition from solid to transparent */
|
||||
transition-duration: 500ms;
|
||||
font-weight: bold;
|
||||
@@ -748,7 +750,7 @@ StScrollBar {
|
||||
|
||||
.panel-corner {
|
||||
-panel-corner-radius: $panel-corner-radius;
|
||||
-panel-corner-background-color: rgba(0, 0, 0, 0.35);
|
||||
-panel-corner-background-color: rgba(0, 0, 0, 0);
|
||||
-panel-corner-border-width: 2px;
|
||||
-panel-corner-border-color: transparent;
|
||||
|
||||
@@ -768,7 +770,7 @@ StScrollBar {
|
||||
-minimum-hpadding: 6px;
|
||||
font-weight: bold;
|
||||
color: #eee;
|
||||
text-shadow: 0px 1px 2px rgba(0, 0, 0, 0.9);
|
||||
text-shadow: 0px 1px 2px rgba(0, 0, 0, 0.8);
|
||||
transition-duration: 100ms;
|
||||
|
||||
.app-menu-icon {
|
||||
@@ -781,17 +783,17 @@ StScrollBar {
|
||||
.system-status-icon,
|
||||
.app-menu-icon > StIcon,
|
||||
.popup-menu-arrow {
|
||||
icon-shadow: 0px 1px 2px rgba(0, 0, 0, 0.9);
|
||||
icon-shadow: 0px 1px 2px rgba(0, 0, 0, 0.8);
|
||||
}
|
||||
|
||||
&:hover {
|
||||
color: lighten($fg_color, 10%);
|
||||
text-shadow: 0px 1px 6px rgba(0, 0, 0, 1);
|
||||
text-shadow: 0px 1px 3px rgba(0, 0, 0, 1);
|
||||
|
||||
.system-status-icon,
|
||||
.app-menu-icon > StIcon,
|
||||
.popup-menu-arrow {
|
||||
icon-shadow: 0px 1px 6px rgba(0, 0, 0, 1);
|
||||
icon-shadow: 0px 1px 3px rgba(0, 0, 0, 1);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -830,6 +832,9 @@ StScrollBar {
|
||||
|
||||
&.solid {
|
||||
background-color: black;
|
||||
background-gradient-start: none;
|
||||
background-gradient-end: none;
|
||||
background-gradient-direction: none;
|
||||
/* transition from transparent to solid */
|
||||
transition-duration: 300ms;
|
||||
|
||||
|
@@ -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);
|
||||
|
179
js/ui/altTab.js
179
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;
|
||||
@@ -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) -
|
||||
@@ -1535,7 +1535,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;
|
||||
@@ -1551,8 +1551,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);
|
||||
},
|
||||
@@ -1615,7 +1615,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);
|
||||
|
@@ -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) +
|
||||
|
@@ -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);
|
||||
}
|
||||
},
|
||||
|
||||
|
@@ -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.
|
||||
@@ -640,11 +661,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) {
|
||||
@@ -676,12 +697,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) {
|
||||
@@ -690,21 +711,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) {
|
||||
@@ -790,11 +811,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);
|
||||
@@ -805,20 +827,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;
|
||||
@@ -846,7 +870,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) {
|
||||
@@ -1017,4 +1041,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;
|
||||
|
@@ -21,6 +21,8 @@ const Tweener = imports.ui.tweener;
|
||||
var STARTUP_ANIMATION_TIME = 0.5;
|
||||
var KEYBOARD_ANIMATION_TIME = 0.15;
|
||||
var BACKGROUND_FADE_ANIMATION_TIME = 1.0;
|
||||
var GRADIENT_FADE_IN_ANIMATION_TIME = 1.0;
|
||||
var GRADIENT_FADE_OUT_ANIMATION_TIME = 0.3;
|
||||
|
||||
var HOT_CORNER_PRESSURE_THRESHOLD = 100; // pixels
|
||||
var HOT_CORNER_PRESSURE_TIMEOUT = 1000; // ms
|
||||
@@ -177,8 +179,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 +213,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);
|
||||
@@ -302,8 +303,10 @@ var LayoutManager = new Lang.Class({
|
||||
// This is called by Main after everything else is constructed
|
||||
init() {
|
||||
Main.sessionMode.connect('updated', this._sessionUpdated.bind(this));
|
||||
Main.panel.connect('solid-style-changed', this._updatePrimaryBackground.bind(this));
|
||||
|
||||
this._loadBackground();
|
||||
this._updatePrimaryBackground();
|
||||
},
|
||||
|
||||
showOverview() {
|
||||
@@ -325,6 +328,29 @@ var LayoutManager = new Lang.Class({
|
||||
this._queueUpdateRegions();
|
||||
},
|
||||
|
||||
_updatePrimaryBackground() {
|
||||
let metaBackgroundActor = this._bgManagers[this.primaryIndex].backgroundActor;
|
||||
metaBackgroundActor.gradient = true;
|
||||
metaBackgroundActor.gradient_height = 3 * Main.panel.actor.get_height();
|
||||
if (Main.panel.solidStyle) {
|
||||
Tweener.addTween(metaBackgroundActor,
|
||||
{ gradient_max_darkness: 0,
|
||||
time: GRADIENT_FADE_OUT_ANIMATION_TIME,
|
||||
transition: 'easeOutQuad',
|
||||
onComplete: function() {
|
||||
metaBackgroundActor.gradient = false;
|
||||
}
|
||||
});
|
||||
} else {
|
||||
Tweener.removeTweens(metaBackgroundActor);
|
||||
Tweener.addTween(metaBackgroundActor,
|
||||
{ gradient_max_darkness: 0.4,
|
||||
time: GRADIENT_FADE_IN_ANIMATION_TIME,
|
||||
transition: 'easeOutQuad'
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
_updateMonitors() {
|
||||
let display = global.display;
|
||||
|
||||
@@ -1078,7 +1104,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',
|
||||
|
||||
|
@@ -587,16 +587,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 +604,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 +619,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 +651,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
|
||||
|
@@ -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() {
|
||||
|
108
js/ui/panel.js
108
js/ui/panel.js
@@ -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);
|
||||
@@ -1045,6 +1039,10 @@ var Panel = new Lang.Class({
|
||||
return this._leftBox.opacity;
|
||||
},
|
||||
|
||||
get solidStyle() {
|
||||
return this.actor.has_style_class_name('solid');
|
||||
},
|
||||
|
||||
_updatePanel() {
|
||||
let panel = Main.sessionMode.panel;
|
||||
this._hideIndicators();
|
||||
@@ -1069,7 +1067,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,8 +1077,12 @@ var Panel = new Lang.Class({
|
||||
},
|
||||
|
||||
_updateSolidStyle() {
|
||||
if (this.actor.has_style_pseudo_class('overview') || !Main.sessionMode.hasWindows) {
|
||||
let hadSolidStyle = this.solidStyle;
|
||||
|
||||
if (this.has_style_pseudo_class('overview') || !Main.sessionMode.hasWindows) {
|
||||
this._removeStyleClassName('solid');
|
||||
if (hadSolidStyle)
|
||||
this.emit('solid-style-changed');
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1097,8 +1099,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;
|
||||
@@ -1110,6 +1112,8 @@ var Panel = new Lang.Class({
|
||||
else
|
||||
this._removeStyleClassName('solid');
|
||||
|
||||
if (isNearEnough != hadSolidStyle)
|
||||
this.emit('solid-style-changed');
|
||||
},
|
||||
|
||||
_hideIndicators() {
|
||||
@@ -1164,7 +1168,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);
|
||||
@@ -1190,13 +1193,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);
|
||||
},
|
||||
@@ -1220,3 +1223,4 @@ var Panel = new Lang.Class({
|
||||
});
|
||||
}
|
||||
});
|
||||
Signals.addSignalMethods(Panel.prototype);
|
||||
|
@@ -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:
|
||||
*
|
||||
|
@@ -782,7 +782,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';
|
||||
|
||||
@@ -873,7 +873,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();
|
||||
|
||||
@@ -885,7 +885,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);
|
||||
},
|
||||
|
@@ -414,7 +414,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() {
|
||||
@@ -773,6 +773,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 +821,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 +1056,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;
|
||||
@@ -10,6 +11,7 @@ const Shell = imports.gi.Shell;
|
||||
const Signals = imports.signals;
|
||||
const St = imports.gi.St;
|
||||
|
||||
const Layout = imports.ui.layout;
|
||||
const Main = imports.ui.main;
|
||||
const Tweener = imports.ui.tweener;
|
||||
|
||||
@@ -39,23 +41,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 +65,32 @@ var SwitcherPopup = new Lang.Class({
|
||||
this._initialDelayTimeoutId = 0;
|
||||
this._noModsTimeoutId = 0;
|
||||
|
||||
this.add_constraint(new Layout.MonitorConstraint({ primary: true }));
|
||||
|
||||
// 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 +106,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 +153,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 +185,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 +205,7 @@ var SwitcherPopup = new Lang.Class({
|
||||
},
|
||||
|
||||
_clickedOutside(actor, event) {
|
||||
this.destroy();
|
||||
this.fadeAndDestroy();
|
||||
return Clutter.EVENT_PROPAGATE;
|
||||
},
|
||||
|
||||
@@ -255,7 +245,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 +283,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 +325,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 +385,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 +451,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 +479,7 @@ var SwitcherList = new Lang.Class({
|
||||
onComplete: () => {
|
||||
if (this._highlighted == 0)
|
||||
this._scrollableLeft = false;
|
||||
this.actor.queue_relayout();
|
||||
this.queue_relayout();
|
||||
}
|
||||
});
|
||||
},
|
||||
@@ -524,7 +503,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 +535,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 +559,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();
|
||||
|
@@ -1796,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 ||
|
||||
|
@@ -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;
|
||||
|
@@ -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)
|
||||
|
@@ -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