Window selector refinements
* Remove window icons * Add a close button to window previews * Position caption underneath the window * Port caption from Big.Box to St.Label https://bugzilla.gnome.org/show_bug.cgi?id=598324
This commit is contained in:
parent
8ac97fe1a0
commit
bb366f8fbe
@ -25,6 +25,7 @@ themedir = $(pkgdatadir)/theme
|
|||||||
dist_theme_DATA = \
|
dist_theme_DATA = \
|
||||||
theme/gnome-shell.css \
|
theme/gnome-shell.css \
|
||||||
theme/close.svg \
|
theme/close.svg \
|
||||||
|
theme/close-window.svg \
|
||||||
theme/scroll-button-down.png \
|
theme/scroll-button-down.png \
|
||||||
theme/scroll-button-down-hover.png \
|
theme/scroll-button-down-hover.png \
|
||||||
theme/scroll-button-up.png \
|
theme/scroll-button-up.png \
|
||||||
|
76
data/theme/close-window.svg
Normal file
76
data/theme/close-window.svg
Normal file
@ -0,0 +1,76 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
|
<!-- Generator: Adobe Illustrator 13.0.2, SVG Export Plug-In . SVG Version: 6.00 Build 14948) -->
|
||||||
|
<svg
|
||||||
|
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||||
|
xmlns:cc="http://creativecommons.org/ns#"
|
||||||
|
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||||
|
xmlns:svg="http://www.w3.org/2000/svg"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||||
|
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||||
|
version="1.0"
|
||||||
|
id="Foreground"
|
||||||
|
x="0px"
|
||||||
|
y="0px"
|
||||||
|
width="22"
|
||||||
|
height="22"
|
||||||
|
viewBox="0 0 16 16"
|
||||||
|
enable-background="new 0 0 16 16"
|
||||||
|
xml:space="preserve"
|
||||||
|
sodipodi:version="0.32"
|
||||||
|
inkscape:version="0.46"
|
||||||
|
sodipodi:docname="close-window.svg"
|
||||||
|
inkscape:output_extension="org.inkscape.output.svg.inkscape"><metadata
|
||||||
|
id="metadata2399"><rdf:RDF><cc:Work
|
||||||
|
rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
|
||||||
|
rdf:resource="http://purl.org/dc/dcmitype/StillImage" /><dc:title /></cc:Work></rdf:RDF></metadata><defs
|
||||||
|
id="defs2397"><linearGradient
|
||||||
|
id="linearGradient3173"><stop
|
||||||
|
style="stop-color:#c4c4c4;stop-opacity:1;"
|
||||||
|
offset="0"
|
||||||
|
id="stop3175" /><stop
|
||||||
|
style="stop-color:#ffffff;stop-opacity:1;"
|
||||||
|
offset="1"
|
||||||
|
id="stop3177" /></linearGradient><inkscape:perspective
|
||||||
|
sodipodi:type="inkscape:persp3d"
|
||||||
|
inkscape:vp_x="0 : 8 : 1"
|
||||||
|
inkscape:vp_y="0 : 1000 : 0"
|
||||||
|
inkscape:vp_z="16 : 8 : 1"
|
||||||
|
inkscape:persp3d-origin="8 : 5.3333333 : 1"
|
||||||
|
id="perspective2401" /></defs><sodipodi:namedview
|
||||||
|
inkscape:window-height="999"
|
||||||
|
inkscape:window-width="1680"
|
||||||
|
inkscape:pageshadow="2"
|
||||||
|
inkscape:pageopacity="1"
|
||||||
|
guidetolerance="10.0"
|
||||||
|
gridtolerance="10.0"
|
||||||
|
objecttolerance="10.0"
|
||||||
|
borderopacity="1.0"
|
||||||
|
bordercolor="#666666"
|
||||||
|
pagecolor="#000000"
|
||||||
|
id="base"
|
||||||
|
showgrid="false"
|
||||||
|
inkscape:zoom="25.648691"
|
||||||
|
inkscape:cx="8.8097603"
|
||||||
|
inkscape:cy="9.0472789"
|
||||||
|
inkscape:window-x="0"
|
||||||
|
inkscape:window-y="26"
|
||||||
|
inkscape:current-layer="Foreground"
|
||||||
|
showguides="true"
|
||||||
|
inkscape:guide-bbox="true" />
|
||||||
|
|
||||||
|
<g
|
||||||
|
id="g3175"><path
|
||||||
|
sodipodi:nodetypes="csssc"
|
||||||
|
style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#ffffff;stroke-width:1.59217799;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||||
|
id="path2394"
|
||||||
|
d="M 0.83987936,8.0425327 C 0.83987936,4.0805265 4.0712155,0.86823453 8.0567103,0.86823453 C 12.042205,0.86823453 15.273542,4.0805265 15.273542,8.0425327 C 15.273542,12.004539 12.042205,15.216831 8.0567103,15.216831 C 4.0712155,15.216831 0.83987936,12.004539 0.83987936,8.0425327 z"
|
||||||
|
clip-rule="evenodd" /><g
|
||||||
|
id="g3172"><path
|
||||||
|
style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:#ffffff;stroke-width:1.67127273;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||||
|
d="M 5.4242673,5.3313047 L 10.515414,10.421272 L 10.714004,10.646491"
|
||||||
|
id="path3152" /></g></g><path
|
||||||
|
style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:#ffffff;stroke-width:1.67127273;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||||
|
d="M 5.4402527,10.650392 L 10.688082,5.3573033"
|
||||||
|
id="path3154"
|
||||||
|
sodipodi:nodetypes="cc" /></svg>
|
After Width: | Height: | Size: 3.2 KiB |
@ -81,6 +81,28 @@ StTooltip {
|
|||||||
background-color: #314a6c;
|
background-color: #314a6c;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Overlay */
|
||||||
|
|
||||||
|
.workspaces {
|
||||||
|
color: white;
|
||||||
|
}
|
||||||
|
|
||||||
|
.window-caption {
|
||||||
|
background: rgba(0,0,0,0.8);
|
||||||
|
border: 1px solid rgba(128,128,128,0.40);
|
||||||
|
border-radius: 10px;
|
||||||
|
font-size: 12px;
|
||||||
|
padding: 2px 8px;
|
||||||
|
-shell-caption-spacing: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.window-close {
|
||||||
|
background-image: url("close-window.svg");
|
||||||
|
height: 24px;
|
||||||
|
width: 24px;
|
||||||
|
-shell-close-overlap: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
/* Dash */
|
/* Dash */
|
||||||
|
|
||||||
#dash {
|
#dash {
|
||||||
|
@ -9,6 +9,7 @@ const Mainloop = imports.mainloop;
|
|||||||
const Meta = imports.gi.Meta;
|
const Meta = imports.gi.Meta;
|
||||||
const Pango = imports.gi.Pango;
|
const Pango = imports.gi.Pango;
|
||||||
const Shell = imports.gi.Shell;
|
const Shell = imports.gi.Shell;
|
||||||
|
const St = imports.gi.St;
|
||||||
const Signals = imports.signals;
|
const Signals = imports.signals;
|
||||||
|
|
||||||
const DND = imports.ui.dnd;
|
const DND = imports.ui.dnd;
|
||||||
@ -20,10 +21,6 @@ const Tweener = imports.ui.tweener;
|
|||||||
|
|
||||||
const FOCUS_ANIMATION_TIME = 0.15;
|
const FOCUS_ANIMATION_TIME = 0.15;
|
||||||
|
|
||||||
const WINDOWCLONE_BG_COLOR = new Clutter.Color();
|
|
||||||
WINDOWCLONE_BG_COLOR.from_pixel(0x000000f0);
|
|
||||||
const WINDOWCLONE_TITLE_COLOR = new Clutter.Color();
|
|
||||||
WINDOWCLONE_TITLE_COLOR.from_pixel(0xffffffff);
|
|
||||||
const FRAME_COLOR = new Clutter.Color();
|
const FRAME_COLOR = new Clutter.Color();
|
||||||
FRAME_COLOR.from_pixel(0xffffffff);
|
FRAME_COLOR.from_pixel(0xffffffff);
|
||||||
|
|
||||||
@ -113,8 +110,6 @@ WindowClone.prototype = {
|
|||||||
|
|
||||||
this._stackAbove = null;
|
this._stackAbove = null;
|
||||||
|
|
||||||
this._title = null;
|
|
||||||
|
|
||||||
this.actor.connect('button-release-event',
|
this.actor.connect('button-release-event',
|
||||||
Lang.bind(this, this._onButtonRelease));
|
Lang.bind(this, this._onButtonRelease));
|
||||||
|
|
||||||
@ -135,18 +130,6 @@ WindowClone.prototype = {
|
|||||||
this._zooming = false;
|
this._zooming = false;
|
||||||
},
|
},
|
||||||
|
|
||||||
setVisibleWithChrome: function(visible) {
|
|
||||||
if (visible) {
|
|
||||||
this.actor.show();
|
|
||||||
if (this._title)
|
|
||||||
this._title.show();
|
|
||||||
} else {
|
|
||||||
this.actor.hide();
|
|
||||||
if (this._title)
|
|
||||||
this._title.hide();
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
setStackAbove: function (actor) {
|
setStackAbove: function (actor) {
|
||||||
this._stackAbove = actor;
|
this._stackAbove = actor;
|
||||||
if (this._inDrag || this._zooming)
|
if (this._inDrag || this._zooming)
|
||||||
@ -157,8 +140,6 @@ WindowClone.prototype = {
|
|||||||
|
|
||||||
destroy: function () {
|
destroy: function () {
|
||||||
this.actor.destroy();
|
this.actor.destroy();
|
||||||
if (this._title)
|
|
||||||
this._title.destroy();
|
|
||||||
},
|
},
|
||||||
|
|
||||||
_onEnter: function (actor, event) {
|
_onEnter: function (actor, event) {
|
||||||
@ -168,8 +149,6 @@ WindowClone.prototype = {
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
this._havePointer = true;
|
this._havePointer = true;
|
||||||
|
|
||||||
this._updateTitle();
|
|
||||||
},
|
},
|
||||||
|
|
||||||
_onLeave: function (actor, event) {
|
_onLeave: function (actor, event) {
|
||||||
@ -179,7 +158,6 @@ WindowClone.prototype = {
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
this._havePointer = false;
|
this._havePointer = false;
|
||||||
this._updateTitle();
|
|
||||||
|
|
||||||
if (this._zoomStep)
|
if (this._zoomStep)
|
||||||
this._zoomEnd();
|
this._zoomEnd();
|
||||||
@ -218,6 +196,7 @@ WindowClone.prototype = {
|
|||||||
|
|
||||||
_zoomStart : function () {
|
_zoomStart : function () {
|
||||||
this._zooming = true;
|
this._zooming = true;
|
||||||
|
this.emit('zoom-start');
|
||||||
|
|
||||||
this._zoomLightbox = new Lightbox.Lightbox(global.stage);
|
this._zoomLightbox = new Lightbox.Lightbox(global.stage);
|
||||||
|
|
||||||
@ -246,6 +225,7 @@ WindowClone.prototype = {
|
|||||||
|
|
||||||
_zoomEnd : function () {
|
_zoomEnd : function () {
|
||||||
this._zooming = false;
|
this._zooming = false;
|
||||||
|
this.emit('zoom-end');
|
||||||
|
|
||||||
this.actor.reparent(this._origParent);
|
this.actor.reparent(this._origParent);
|
||||||
this.actor.raise(this._stackAbove);
|
this.actor.raise(this._stackAbove);
|
||||||
@ -253,8 +233,6 @@ WindowClone.prototype = {
|
|||||||
[this.actor.x, this.actor.y] = this._zoomLocalOrig.getPosition();
|
[this.actor.x, this.actor.y] = this._zoomLocalOrig.getPosition();
|
||||||
[this.actor.scale_x, this.actor.scale_y] = this._zoomLocalOrig.getScale();
|
[this.actor.scale_x, this.actor.scale_y] = this._zoomLocalOrig.getScale();
|
||||||
|
|
||||||
this._adjustTitle();
|
|
||||||
|
|
||||||
this._zoomLightbox.destroy();
|
this._zoomLightbox.destroy();
|
||||||
Main.overview.disconnect(this._hideEventId);
|
Main.overview.disconnect(this._hideEventId);
|
||||||
|
|
||||||
@ -273,7 +251,6 @@ WindowClone.prototype = {
|
|||||||
|
|
||||||
_onDragBegin : function (draggable, time) {
|
_onDragBegin : function (draggable, time) {
|
||||||
this._inDrag = true;
|
this._inDrag = true;
|
||||||
this._updateTitle();
|
|
||||||
this.emit('drag-begin');
|
this.emit('drag-begin');
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -295,86 +272,6 @@ WindowClone.prototype = {
|
|||||||
this.actor.raise(this._stackAbove);
|
this.actor.raise(this._stackAbove);
|
||||||
|
|
||||||
this.emit('drag-end');
|
this.emit('drag-end');
|
||||||
},
|
|
||||||
|
|
||||||
// Called by Tweener
|
|
||||||
onAnimationStart : function () {
|
|
||||||
this._updateTitle();
|
|
||||||
},
|
|
||||||
|
|
||||||
// Called by Tweener
|
|
||||||
onAnimationComplete : function () {
|
|
||||||
this._updateTitle();
|
|
||||||
},
|
|
||||||
|
|
||||||
_createTitle : function () {
|
|
||||||
let window = this.realWindow;
|
|
||||||
|
|
||||||
let box = new Big.Box({ background_color : WINDOWCLONE_BG_COLOR,
|
|
||||||
y_align: Big.BoxAlignment.CENTER,
|
|
||||||
corner_radius: 5,
|
|
||||||
padding: 4,
|
|
||||||
spacing: 4,
|
|
||||||
orientation: Big.BoxOrientation.HORIZONTAL });
|
|
||||||
|
|
||||||
let title = new Clutter.Text({ color: WINDOWCLONE_TITLE_COLOR,
|
|
||||||
font_name: "Sans 12",
|
|
||||||
text: this.metaWindow.title,
|
|
||||||
ellipsize: Pango.EllipsizeMode.END
|
|
||||||
});
|
|
||||||
box.append(title, Big.BoxPackFlags.EXPAND);
|
|
||||||
// Get and cache the expected width (just the icon), with spacing, plus title
|
|
||||||
box.fullWidth = box.width;
|
|
||||||
box.hide(); // Hidden by default, show on mouseover
|
|
||||||
this._title = box;
|
|
||||||
|
|
||||||
// Make the title a sibling of the window
|
|
||||||
this.actor.get_parent().add_actor(box);
|
|
||||||
},
|
|
||||||
|
|
||||||
_adjustTitle : function () {
|
|
||||||
let title = this._title;
|
|
||||||
if (!title)
|
|
||||||
return;
|
|
||||||
|
|
||||||
let [cloneScreenWidth, cloneScreenHeight] = this.actor.get_transformed_size();
|
|
||||||
let [titleScreenWidth, titleScreenHeight] = title.get_transformed_size();
|
|
||||||
|
|
||||||
// Titles are supposed to be "full-size", so adjust its
|
|
||||||
// scale to counteract the scaling of its ancestor actors.
|
|
||||||
title.set_scale(title.width / titleScreenWidth * title.scale_x,
|
|
||||||
title.height / titleScreenHeight * title.scale_y);
|
|
||||||
|
|
||||||
title.width = Math.min(title.fullWidth, cloneScreenWidth);
|
|
||||||
let xoff = ((cloneScreenWidth - title.width) / 2) * title.scale_x;
|
|
||||||
title.set_position(this.actor.x + xoff, this.actor.y);
|
|
||||||
},
|
|
||||||
|
|
||||||
_showTitle : function () {
|
|
||||||
if (!this._title)
|
|
||||||
this._createTitle();
|
|
||||||
|
|
||||||
this._adjustTitle();
|
|
||||||
this._title.show();
|
|
||||||
this._title.raise(this.actor);
|
|
||||||
},
|
|
||||||
|
|
||||||
_hideTitle : function () {
|
|
||||||
if (!this._title)
|
|
||||||
return;
|
|
||||||
|
|
||||||
this._title.hide();
|
|
||||||
},
|
|
||||||
|
|
||||||
_updateTitle : function () {
|
|
||||||
let shouldShow = (this._havePointer &&
|
|
||||||
!this._inDrag &&
|
|
||||||
!Tweener.isTweening(this.actor));
|
|
||||||
|
|
||||||
if (shouldShow)
|
|
||||||
this._showTitle();
|
|
||||||
else
|
|
||||||
this._hideTitle();
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -409,6 +306,144 @@ DesktopClone.prototype = {
|
|||||||
Signals.addSignalMethods(DesktopClone.prototype);
|
Signals.addSignalMethods(DesktopClone.prototype);
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @windowClone: Corresponding window clone
|
||||||
|
* @parentActor: The actor which will be the parent of all overlay items
|
||||||
|
* such as app icon and window caption
|
||||||
|
*/
|
||||||
|
function WindowOverlay(windowClone, parentActor) {
|
||||||
|
this._init(windowClone, parentActor);
|
||||||
|
}
|
||||||
|
|
||||||
|
WindowOverlay.prototype = {
|
||||||
|
_init : function(windowClone, parentActor) {
|
||||||
|
let metaWindow = windowClone.metaWindow;
|
||||||
|
|
||||||
|
this._parentActor = parentActor;
|
||||||
|
|
||||||
|
let title = new St.Label({ style_class: "window-caption",
|
||||||
|
text : metaWindow.title });
|
||||||
|
title.connect('style-changed',
|
||||||
|
Lang.bind(this, this._onStyleChanged));
|
||||||
|
title.clutter_text.ellipsize = Pango.EllipsizeMode.END;
|
||||||
|
title._spacing = 0;
|
||||||
|
|
||||||
|
let button = new St.Bin({ style_class: "window-close",
|
||||||
|
reactive: true });
|
||||||
|
button.connect('style-changed',
|
||||||
|
Lang.bind(this, this._onStyleChanged));
|
||||||
|
button._overlap = 0;
|
||||||
|
|
||||||
|
windowClone.actor.connect('notify::allocation',
|
||||||
|
Lang.bind(this, this._positionItems));
|
||||||
|
windowClone.actor.connect('enter-event',
|
||||||
|
Lang.bind(this, this._onEnter));
|
||||||
|
windowClone.actor.connect('leave-event',
|
||||||
|
Lang.bind(this, this._onLeave));
|
||||||
|
|
||||||
|
button.connect('enter-event', Lang.bind(this, this._onEnter));
|
||||||
|
button.connect('leave-event', Lang.bind(this, this._onLeave));
|
||||||
|
button.connect('button-release-event',
|
||||||
|
Lang.bind(this, function(actor, event) {
|
||||||
|
metaWindow.delete(event.get_time());
|
||||||
|
}));
|
||||||
|
|
||||||
|
windowClone.connect('zoom-start', Lang.bind(this, this.hide));
|
||||||
|
windowClone.connect('zoom-end', Lang.bind(this, this.show));
|
||||||
|
|
||||||
|
button.hide();
|
||||||
|
|
||||||
|
this.title = title;
|
||||||
|
this.closeButton = button;
|
||||||
|
|
||||||
|
parentActor.add_actor(this.title);
|
||||||
|
parentActor.add_actor(this.closeButton);
|
||||||
|
},
|
||||||
|
|
||||||
|
hide: function() {
|
||||||
|
this.closeButton.hide();
|
||||||
|
this.title.hide();
|
||||||
|
},
|
||||||
|
|
||||||
|
show: function() {
|
||||||
|
this.title.show();
|
||||||
|
},
|
||||||
|
|
||||||
|
fadeIn: function() {
|
||||||
|
this.title.opacity = 0;
|
||||||
|
this.title.show();
|
||||||
|
this.title.raise_top();
|
||||||
|
Tweener.addTween(this.title,
|
||||||
|
{ opacity: 255,
|
||||||
|
time: Overview.ANIMATION_TIME,
|
||||||
|
transition: "easeOutQuad" });
|
||||||
|
},
|
||||||
|
|
||||||
|
destroy: function() {
|
||||||
|
this.title.destroy();
|
||||||
|
this.closeButton.destroy();
|
||||||
|
},
|
||||||
|
|
||||||
|
chromeWidth: function () {
|
||||||
|
return this.closeButton.width - this.closeButton._overlap;
|
||||||
|
},
|
||||||
|
|
||||||
|
chromeHeight: function () {
|
||||||
|
return this.closeButton.height - this.closeButton._overlap +
|
||||||
|
this.title.height + this.title._spacing;
|
||||||
|
},
|
||||||
|
|
||||||
|
_positionItems: function(win) {
|
||||||
|
let button = this.closeButton;
|
||||||
|
let title = this.title;
|
||||||
|
|
||||||
|
let [x, y] = win.get_transformed_position();
|
||||||
|
let [w, h] = win.get_transformed_size();
|
||||||
|
|
||||||
|
let buttonX = x + w - button._overlap;
|
||||||
|
let buttonY = y - button.height + button._overlap;
|
||||||
|
button.set_position(Math.floor(buttonX), Math.floor(buttonY));
|
||||||
|
|
||||||
|
if (!title.fullWidth)
|
||||||
|
title.fullWidth = title.width;
|
||||||
|
title.width = Math.min(title.fullWidth, w);
|
||||||
|
|
||||||
|
let titleX = x + (w - title.width) / 2;
|
||||||
|
let titleY = y + h + title._spacing;
|
||||||
|
title.set_position(Math.floor(titleX), Math.floor(titleY));
|
||||||
|
},
|
||||||
|
|
||||||
|
_onEnter: function() {
|
||||||
|
this.closeButton.raise_top();
|
||||||
|
this.closeButton.show();
|
||||||
|
},
|
||||||
|
|
||||||
|
_onLeave: function() {
|
||||||
|
this.closeButton.hide();
|
||||||
|
},
|
||||||
|
|
||||||
|
_onStyleChanged: function() {
|
||||||
|
let titleNode = this.title.get_theme_node();
|
||||||
|
|
||||||
|
let [success, len] = titleNode.get_length('-shell-caption-spacing',
|
||||||
|
false);
|
||||||
|
if (success)
|
||||||
|
this.title._spacing = len;
|
||||||
|
|
||||||
|
let closeNode = this.closeButton.get_theme_node();
|
||||||
|
|
||||||
|
let [success, len] = closeNode.get_length('-shell-close-overlap',
|
||||||
|
false);
|
||||||
|
if (success)
|
||||||
|
this.closeButton._overlap = len;
|
||||||
|
|
||||||
|
this._parentActor.queue_relayout();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
Signals.addSignalMethods(WindowOverlay.prototype);
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @workspaceNum: Workspace index
|
* @workspaceNum: Workspace index
|
||||||
* @parentActor: The actor which will be the parent of this workspace;
|
* @parentActor: The actor which will be the parent of this workspace;
|
||||||
@ -460,7 +495,7 @@ Workspace.prototype = {
|
|||||||
// Create clones for remaining windows that should be
|
// Create clones for remaining windows that should be
|
||||||
// visible in the Overview
|
// visible in the Overview
|
||||||
this._windows = [this._desktop];
|
this._windows = [this._desktop];
|
||||||
this._windowIcons = [ null ];
|
this._windowOverlays = [ null ];
|
||||||
for (let i = 0; i < windows.length; i++) {
|
for (let i = 0; i < windows.length; i++) {
|
||||||
if (this._isOverviewWindow(windows[i])) {
|
if (this._isOverviewWindow(windows[i])) {
|
||||||
this._addWindowClone(windows[i]);
|
this._addWindowClone(windows[i]);
|
||||||
@ -676,13 +711,13 @@ Workspace.prototype = {
|
|||||||
_resetCloneVisibility: function () {
|
_resetCloneVisibility: function () {
|
||||||
for (let i = 1; i < this._windows.length; i++) {
|
for (let i = 1; i < this._windows.length; i++) {
|
||||||
let clone = this._windows[i];
|
let clone = this._windows[i];
|
||||||
let icon = this._windowIcons[i];
|
let overlay = this._windowOverlays[i];
|
||||||
|
|
||||||
if (!this._isCloneVisible(clone)) {
|
if (!this._isCloneVisible(clone)) {
|
||||||
clone.setVisibleWithChrome(false);
|
clone.actor.hide();
|
||||||
icon.hide();
|
overlay.hide();
|
||||||
} else {
|
} else {
|
||||||
clone.setVisibleWithChrome(true);
|
clone.actor.show();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -888,14 +923,17 @@ Workspace.prototype = {
|
|||||||
let rect = new Meta.Rectangle();
|
let rect = new Meta.Rectangle();
|
||||||
metaWindow.get_outer_rect(rect);
|
metaWindow.get_outer_rect(rect);
|
||||||
|
|
||||||
let desiredWidth = global.screen_width * fraction;
|
let chromeHeight = this._windowOverlays[1].chromeHeight() / this.scale;
|
||||||
let desiredHeight = global.screen_height * fraction;
|
let chromeWidth = this._windowOverlays[1].chromeWidth() / this.scale;
|
||||||
let scale = Math.min(desiredWidth / rect.width,
|
|
||||||
desiredHeight / rect.height,
|
let desiredWidth = (global.screen_width - chromeWidth) * fraction;
|
||||||
|
let desiredHeight = (global.screen_height - chromeHeight) * fraction;
|
||||||
|
let scale = Math.min(desiredWidth / (rect.width + chromeWidth),
|
||||||
|
desiredHeight / (rect.height + chromeHeight),
|
||||||
1.0 / this.scale);
|
1.0 / this.scale);
|
||||||
|
|
||||||
let x = xCenter - 0.5 * scale * rect.width;
|
let x = xCenter - 0.5 * scale * (rect.width + chromeWidth);
|
||||||
let y = yCenter - 0.5 * scale * rect.height;
|
let y = yCenter - 0.5 * scale * (rect.height + chromeHeight);
|
||||||
|
|
||||||
return [x, y, scale];
|
return [x, y, scale];
|
||||||
},
|
},
|
||||||
@ -918,11 +956,11 @@ Workspace.prototype = {
|
|||||||
let metaWindow = visibleWindows[i];
|
let metaWindow = visibleWindows[i];
|
||||||
let mainIndex = this._lookupIndex(metaWindow);
|
let mainIndex = this._lookupIndex(metaWindow);
|
||||||
let clone = metaWindow._delegate;
|
let clone = metaWindow._delegate;
|
||||||
let icon = this._windowIcons[mainIndex];
|
let overlay = this._windowOverlays[mainIndex];
|
||||||
|
|
||||||
let [x, y, scale] = this._computeWindowRelativeLayout(metaWindow, slot);
|
let [x, y, scale] = this._computeWindowRelativeLayout(metaWindow, slot);
|
||||||
|
|
||||||
icon.hide();
|
overlay.hide();
|
||||||
Tweener.addTween(clone.actor,
|
Tweener.addTween(clone.actor,
|
||||||
{ x: x,
|
{ x: x,
|
||||||
y: y,
|
y: y,
|
||||||
@ -932,7 +970,7 @@ Workspace.prototype = {
|
|||||||
time: Overview.ANIMATION_TIME,
|
time: Overview.ANIMATION_TIME,
|
||||||
transition: "easeOutQuad",
|
transition: "easeOutQuad",
|
||||||
onComplete: Lang.bind(this, function() {
|
onComplete: Lang.bind(this, function() {
|
||||||
this._fadeInWindowIcon(clone, icon);
|
overlay.fadeIn();
|
||||||
})
|
})
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -956,49 +994,20 @@ Workspace.prototype = {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
_fadeInWindowIcon: function (clone, icon) {
|
_fadeInAllOverlays: function() {
|
||||||
icon.opacity = 0;
|
|
||||||
icon.show();
|
|
||||||
// This is a little messy and complicated because when we
|
|
||||||
// start the fade-in we may not have done the final positioning
|
|
||||||
// of the workspaces. (Tweener doesn't necessarily finish
|
|
||||||
// all animations before calling onComplete callbacks.)
|
|
||||||
// So we need to manually compute where the window will
|
|
||||||
// be after the workspace animation finishes.
|
|
||||||
let [parentX, parentY] = icon.get_parent().get_position();
|
|
||||||
let [cloneX, cloneY] = clone.actor.get_position();
|
|
||||||
let [cloneWidth, cloneHeight] = clone.actor.get_size();
|
|
||||||
cloneX = this.gridX + this.scale * cloneX;
|
|
||||||
cloneY = this.gridY + this.scale * cloneY;
|
|
||||||
cloneWidth = this.scale * clone.actor.scale_x * cloneWidth;
|
|
||||||
cloneHeight = this.scale * clone.actor.scale_y * cloneHeight;
|
|
||||||
// Note we only round the first part, because we're still going to be
|
|
||||||
// positioned relative to the parent. By subtracting a possibly
|
|
||||||
// non-integral parent X/Y we cancel it out.
|
|
||||||
let x = Math.round(cloneX + cloneWidth - icon.width) - parentX;
|
|
||||||
let y = Math.round(cloneY + cloneHeight - icon.height) - parentY;
|
|
||||||
icon.set_position(x, y);
|
|
||||||
icon.raise(this.actor);
|
|
||||||
Tweener.addTween(icon,
|
|
||||||
{ opacity: 255,
|
|
||||||
time: Overview.ANIMATION_TIME,
|
|
||||||
transition: "easeOutQuad" });
|
|
||||||
},
|
|
||||||
|
|
||||||
_fadeInAllIcons: function () {
|
|
||||||
for (let i = 1; i < this._windows.length; i++) {
|
for (let i = 1; i < this._windows.length; i++) {
|
||||||
let clone = this._windows[i];
|
let clone = this._windows[i];
|
||||||
let icon = this._windowIcons[i];
|
let overlay = this._windowOverlays[i];
|
||||||
if (this._showOnlyWindows != null && !(clone.metaWindow in this._showOnlyWindows))
|
if (this._showOnlyWindows != null && !(clone.metaWindow in this._showOnlyWindows))
|
||||||
continue;
|
continue;
|
||||||
this._fadeInWindowIcon(clone, icon);
|
overlay.fadeIn();
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
_hideAllIcons: function () {
|
_hideAllOverlays: function() {
|
||||||
for (let i = 1; i < this._windows.length; i++) {
|
for (let i = 1; i< this._windows.length; i++) {
|
||||||
let icon = this._windowIcons[i];
|
let overlay = this._windowOverlays[i];
|
||||||
icon.hide();
|
overlay.hide();
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -1012,10 +1021,10 @@ Workspace.prototype = {
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
let clone = this._windows[index];
|
let clone = this._windows[index];
|
||||||
let icon = this._windowIcons[index];
|
let overlay = this._windowOverlays[index];
|
||||||
|
|
||||||
this._windows.splice(index, 1);
|
this._windows.splice(index, 1);
|
||||||
this._windowIcons.splice(index, 1);
|
this._windowOverlays.splice(index, 1);
|
||||||
|
|
||||||
// If metaWin.get_compositor_private() returned non-NULL, that
|
// If metaWin.get_compositor_private() returned non-NULL, that
|
||||||
// means the window still exists (and is just being moved to
|
// means the window still exists (and is just being moved to
|
||||||
@ -1033,7 +1042,7 @@ Workspace.prototype = {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
clone.destroy();
|
clone.destroy();
|
||||||
icon.destroy();
|
overlay.destroy();
|
||||||
|
|
||||||
this.positionWindows(false);
|
this.positionWindows(false);
|
||||||
this.updateRemovable();
|
this.updateRemovable();
|
||||||
@ -1103,7 +1112,7 @@ Workspace.prototype = {
|
|||||||
zoomFromOverview : function() {
|
zoomFromOverview : function() {
|
||||||
this.leavingOverview = true;
|
this.leavingOverview = true;
|
||||||
|
|
||||||
this._hideAllIcons();
|
this._hideAllOverlays();
|
||||||
|
|
||||||
Main.overview.connect('hidden', Lang.bind(this,
|
Main.overview.connect('hidden', Lang.bind(this,
|
||||||
this._doneLeavingOverview));
|
this._doneLeavingOverview));
|
||||||
@ -1140,7 +1149,7 @@ Workspace.prototype = {
|
|||||||
// Animates grid shrinking/expanding when a row or column
|
// Animates grid shrinking/expanding when a row or column
|
||||||
// of workspaces is added or removed
|
// of workspaces is added or removed
|
||||||
resizeToGrid : function (oldScale) {
|
resizeToGrid : function (oldScale) {
|
||||||
this._hideAllIcons();
|
this._hideAllOverlays();
|
||||||
Tweener.addTween(this.actor,
|
Tweener.addTween(this.actor,
|
||||||
{ x: this.gridX,
|
{ x: this.gridX,
|
||||||
y: this.gridY,
|
y: this.gridY,
|
||||||
@ -1148,7 +1157,7 @@ Workspace.prototype = {
|
|||||||
scale_y: this.scale,
|
scale_y: this.scale,
|
||||||
time: Overview.ANIMATION_TIME,
|
time: Overview.ANIMATION_TIME,
|
||||||
transition: "easeOutQuad",
|
transition: "easeOutQuad",
|
||||||
onComplete: Lang.bind(this, this._fadeInAllIcons)
|
onComplete: Lang.bind(this, this._fadeInAllOverlays)
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -1177,7 +1186,7 @@ Workspace.prototype = {
|
|||||||
slideOut : function(onComplete) {
|
slideOut : function(onComplete) {
|
||||||
let destX = this.actor.x, destY = this.actor.y;
|
let destX = this.actor.x, destY = this.actor.y;
|
||||||
|
|
||||||
this._hideAllIcons();
|
this._hideAllOverlays();
|
||||||
|
|
||||||
if (this.gridCol > this.gridRow)
|
if (this.gridCol > this.gridRow)
|
||||||
destX = global.screen_width;
|
destX = global.screen_width;
|
||||||
@ -1226,46 +1235,26 @@ Workspace.prototype = {
|
|||||||
return tracker.is_window_interesting(win.get_meta_window());
|
return tracker.is_window_interesting(win.get_meta_window());
|
||||||
},
|
},
|
||||||
|
|
||||||
_createWindowIcon: function(window) {
|
|
||||||
let tracker = Shell.WindowTracker.get_default()
|
|
||||||
let app = tracker.get_window_app(window.metaWindow);
|
|
||||||
let iconTexture = null;
|
|
||||||
// The design is application based, so prefer the application
|
|
||||||
// icon here if we have it. FIXME - should move this fallback code
|
|
||||||
// into ShellAppMonitor.
|
|
||||||
if (app) {
|
|
||||||
iconTexture = app.create_icon_texture(48);
|
|
||||||
} else {
|
|
||||||
let icon = window.metaWindow.icon;
|
|
||||||
iconTexture = new Clutter.Texture({ width: 48,
|
|
||||||
height: 48,
|
|
||||||
keep_aspect_ratio: true });
|
|
||||||
Shell.clutter_texture_set_from_pixbuf(iconTexture, icon);
|
|
||||||
}
|
|
||||||
return iconTexture;
|
|
||||||
},
|
|
||||||
|
|
||||||
// Create a clone of a (non-desktop) window and add it to the window list
|
// Create a clone of a (non-desktop) window and add it to the window list
|
||||||
_addWindowClone : function(win) {
|
_addWindowClone : function(win) {
|
||||||
let icon = this._createWindowIcon(win);
|
|
||||||
this.parentActor.add_actor(icon);
|
|
||||||
|
|
||||||
let clone = new WindowClone(win);
|
let clone = new WindowClone(win);
|
||||||
|
let overlay = new WindowOverlay(clone, this.parentActor);
|
||||||
|
|
||||||
clone.connect('selected',
|
clone.connect('selected',
|
||||||
Lang.bind(this, this._onCloneSelected));
|
Lang.bind(this, this._onCloneSelected));
|
||||||
clone.connect('drag-begin',
|
clone.connect('drag-begin',
|
||||||
Lang.bind(this, function() {
|
Lang.bind(this, function() {
|
||||||
icon.hide();
|
overlay.hide();
|
||||||
}));
|
}));
|
||||||
clone.connect('drag-end',
|
clone.connect('drag-end',
|
||||||
Lang.bind(this, function() {
|
Lang.bind(this, function() {
|
||||||
icon.show();
|
overlay.show();
|
||||||
}));
|
}));
|
||||||
|
|
||||||
this.actor.add_actor(clone.actor);
|
this.actor.add_actor(clone.actor);
|
||||||
|
|
||||||
this._windows.push(clone);
|
this._windows.push(clone);
|
||||||
this._windowIcons.push(icon);
|
this._windowOverlays.push(overlay);
|
||||||
|
|
||||||
return clone;
|
return clone;
|
||||||
},
|
},
|
||||||
@ -1345,7 +1334,10 @@ function Workspaces(width, height, x, y) {
|
|||||||
|
|
||||||
Workspaces.prototype = {
|
Workspaces.prototype = {
|
||||||
_init : function(width, height, x, y) {
|
_init : function(width, height, x, y) {
|
||||||
this.actor = new Clutter.Group();
|
this.actor = new St.Bin({ style_class: "workspaces" });
|
||||||
|
this._actor = new Clutter.Group();
|
||||||
|
|
||||||
|
this.actor.add_actor(this._actor);
|
||||||
|
|
||||||
this._width = width;
|
this._width = width;
|
||||||
this._height = height;
|
this._height = height;
|
||||||
@ -1654,9 +1646,9 @@ Workspaces.prototype = {
|
|||||||
},
|
},
|
||||||
|
|
||||||
_addWorkspaceActor : function(workspaceNum) {
|
_addWorkspaceActor : function(workspaceNum) {
|
||||||
let workspace = new Workspace(workspaceNum, this.actor);
|
let workspace = new Workspace(workspaceNum, this._actor);
|
||||||
this._workspaces[workspaceNum] = workspace;
|
this._workspaces[workspaceNum] = workspace;
|
||||||
this.actor.add_actor(workspace.actor);
|
this._actor.add_actor(workspace.actor);
|
||||||
},
|
},
|
||||||
|
|
||||||
_onRestacked: function() {
|
_onRestacked: function() {
|
||||||
|
Loading…
Reference in New Issue
Block a user