Workspace: Highlight window clone and caption when hovered
Windows in the overview should be highlighted when hovered, to indicate they are an active target. Based on a patch by Marc Plano-Lesay <marc.planolesay@gmail.com> https://bugzilla.gnome.org/show_bug.cgi?id=665310
This commit is contained in:
parent
8a7c0313f6
commit
a370697385
@ -615,6 +615,7 @@ StScrollBar StButton#vhandle:active {
|
|||||||
border-radius: 8px;
|
border-radius: 8px;
|
||||||
padding: 4px 12px;
|
padding: 4px 12px;
|
||||||
-shell-caption-spacing: 12px;
|
-shell-caption-spacing: 12px;
|
||||||
|
border: 2px solid rgba(0, 0, 0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
.window-close, .notification-close {
|
.window-close, .notification-close {
|
||||||
@ -625,7 +626,16 @@ StScrollBar StButton#vhandle:active {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.window-close {
|
.window-close {
|
||||||
-shell-close-overlap: 20px;
|
-shell-close-overlap: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.window-caption:hover {
|
||||||
|
border: 2px solid rgba(255, 255, 255, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
.window-clone-border {
|
||||||
|
border: 4px solid rgba(255, 255, 255, 0.5);
|
||||||
|
border-radius: 4px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.notification-close {
|
.notification-close {
|
||||||
|
@ -445,6 +445,9 @@ const WindowOverlay = new Lang.Class({
|
|||||||
this._parentActor = parentActor;
|
this._parentActor = parentActor;
|
||||||
this._hidden = false;
|
this._hidden = false;
|
||||||
|
|
||||||
|
this.borderSize = 0;
|
||||||
|
this.border = new St.Bin({ style_class: 'window-clone-border' });
|
||||||
|
|
||||||
let title = new St.Label({ style_class: 'window-caption',
|
let title = new St.Label({ style_class: 'window-caption',
|
||||||
text: metaWindow.title });
|
text: metaWindow.title });
|
||||||
title.clutter_text.ellipsize = Pango.EllipsizeMode.END;
|
title.clutter_text.ellipsize = Pango.EllipsizeMode.END;
|
||||||
@ -482,11 +485,13 @@ const WindowOverlay = new Lang.Class({
|
|||||||
this.closeButton = button;
|
this.closeButton = button;
|
||||||
|
|
||||||
parentActor.add_actor(this.title);
|
parentActor.add_actor(this.title);
|
||||||
|
parentActor.add_actor(this.border);
|
||||||
parentActor.add_actor(this.closeButton);
|
parentActor.add_actor(this.closeButton);
|
||||||
title.connect('style-changed',
|
title.connect('style-changed',
|
||||||
Lang.bind(this, this._onStyleChanged));
|
Lang.bind(this, this._onStyleChanged));
|
||||||
button.connect('style-changed',
|
button.connect('style-changed',
|
||||||
Lang.bind(this, this._onStyleChanged));
|
Lang.bind(this, this._onStyleChanged));
|
||||||
|
this.border.connect('style-changed', Lang.bind(this, this._onStyleChanged));
|
||||||
// force a style change if we are already on a stage - otherwise
|
// force a style change if we are already on a stage - otherwise
|
||||||
// the signal will be emitted normally when we are added
|
// the signal will be emitted normally when we are added
|
||||||
if (parentActor.get_stage())
|
if (parentActor.get_stage())
|
||||||
@ -497,13 +502,17 @@ const WindowOverlay = new Lang.Class({
|
|||||||
this._hidden = true;
|
this._hidden = true;
|
||||||
this.closeButton.hide();
|
this.closeButton.hide();
|
||||||
this.title.hide();
|
this.title.hide();
|
||||||
|
this.title.remove_style_pseudo_class('hover');
|
||||||
|
|
||||||
|
this.border.hide();
|
||||||
},
|
},
|
||||||
|
|
||||||
show: function() {
|
show: function() {
|
||||||
this._hidden = false;
|
this._hidden = false;
|
||||||
if (this._windowClone.actor.has_pointer)
|
|
||||||
this.closeButton.show();
|
|
||||||
this.title.show();
|
this.title.show();
|
||||||
|
if (this._windowClone.actor.has_pointer)
|
||||||
|
this._animateVisible();
|
||||||
},
|
},
|
||||||
|
|
||||||
fadeIn: function() {
|
fadeIn: function() {
|
||||||
@ -520,10 +529,14 @@ const WindowOverlay = new Lang.Class({
|
|||||||
},
|
},
|
||||||
|
|
||||||
chromeHeights: function () {
|
chromeHeights: function () {
|
||||||
return [this.closeButton.height - this.closeButton._overlap,
|
return [Math.max(this.borderSize, this.closeButton.height - this.closeButton._overlap),
|
||||||
this.title.height + this.title._spacing];
|
this.title.height + this.title._spacing];
|
||||||
},
|
},
|
||||||
|
|
||||||
|
chromeWidths: function () {
|
||||||
|
return [this.borderSize, this.borderSize];
|
||||||
|
},
|
||||||
|
|
||||||
_repositionSelf: function() {
|
_repositionSelf: function() {
|
||||||
let [cloneX, cloneY, cloneWidth, cloneHeight] = this._windowClone.slot;
|
let [cloneX, cloneY, cloneWidth, cloneHeight] = this._windowClone.slot;
|
||||||
this.updatePositions(cloneX, cloneY, cloneWidth, cloneHeight, false);
|
this.updatePositions(cloneX, cloneY, cloneWidth, cloneHeight, false);
|
||||||
@ -578,16 +591,32 @@ const WindowOverlay = new Lang.Class({
|
|||||||
title.width = titleWidth;
|
title.width = titleWidth;
|
||||||
title.set_position(Math.floor(titleX), Math.floor(titleY));
|
title.set_position(Math.floor(titleX), Math.floor(titleY));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let borderX = cloneX - this.borderSize;
|
||||||
|
let borderY = cloneY - this.borderSize;
|
||||||
|
let borderWidth = cloneWidth + 2 * this.borderSize;
|
||||||
|
let borderHeight = cloneHeight + 2 * this.borderSize;
|
||||||
|
|
||||||
|
if (animate) {
|
||||||
|
this._animateOverlayActor(this.border, borderX, borderY,
|
||||||
|
borderWidth, borderHeight);
|
||||||
|
} else {
|
||||||
|
this.border.set_position(borderX, borderY);
|
||||||
|
this.border.set_size(borderWidth, borderHeight);
|
||||||
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
_animateOverlayActor: function(actor, x, y, width) {
|
_animateOverlayActor: function(actor, x, y, width, height) {
|
||||||
Tweener.addTween(actor,
|
let params = { x: x,
|
||||||
{ x: x,
|
y: y,
|
||||||
y: y,
|
width: width,
|
||||||
width: width,
|
time: Overview.ANIMATION_TIME,
|
||||||
time: Overview.ANIMATION_TIME,
|
transition: 'easeOutQuad' };
|
||||||
transition: 'easeOutQuad'
|
|
||||||
});
|
if (height !== undefined)
|
||||||
|
params.height = height;
|
||||||
|
|
||||||
|
Tweener.addTween(actor, params);
|
||||||
},
|
},
|
||||||
|
|
||||||
_closeWindow: function(actor) {
|
_closeWindow: function(actor) {
|
||||||
@ -630,6 +659,21 @@ const WindowOverlay = new Lang.Class({
|
|||||||
this._windowClone.metaWindow.disconnect(this._updateCaptionId);
|
this._windowClone.metaWindow.disconnect(this._updateCaptionId);
|
||||||
this.title.destroy();
|
this.title.destroy();
|
||||||
this.closeButton.destroy();
|
this.closeButton.destroy();
|
||||||
|
this.border.destroy();
|
||||||
|
},
|
||||||
|
|
||||||
|
_animateVisible: function() {
|
||||||
|
this._parentActor.raise_top();
|
||||||
|
this.closeButton.show();
|
||||||
|
|
||||||
|
this.border.show();
|
||||||
|
this.border.opacity = 0;
|
||||||
|
Tweener.addTween(this.border,
|
||||||
|
{ opacity: 255,
|
||||||
|
time: CLOSE_BUTTON_FADE_TIME,
|
||||||
|
transition: 'easeOutQuad' });
|
||||||
|
|
||||||
|
this.title.add_style_pseudo_class('hover');
|
||||||
},
|
},
|
||||||
|
|
||||||
_onEnter: function() {
|
_onEnter: function() {
|
||||||
@ -639,8 +683,8 @@ const WindowOverlay = new Lang.Class({
|
|||||||
// are shown again
|
// are shown again
|
||||||
if (this._hidden)
|
if (this._hidden)
|
||||||
return;
|
return;
|
||||||
this._parentActor.raise_top();
|
|
||||||
this.closeButton.show();
|
this._animateVisible();
|
||||||
this.emit('show-close-button');
|
this.emit('show-close-button');
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -652,9 +696,18 @@ const WindowOverlay = new Lang.Class({
|
|||||||
_idleToggleCloseButton: function() {
|
_idleToggleCloseButton: function() {
|
||||||
this._idleToggleCloseId = 0;
|
this._idleToggleCloseId = 0;
|
||||||
if (!this._windowClone.actor.has_pointer &&
|
if (!this._windowClone.actor.has_pointer &&
|
||||||
!this.closeButton.has_pointer)
|
!this.closeButton.has_pointer) {
|
||||||
this.closeButton.hide();
|
this.closeButton.hide();
|
||||||
|
|
||||||
|
this.border.opacity = 255;
|
||||||
|
Tweener.addTween(this.border,
|
||||||
|
{ opacity: 0,
|
||||||
|
time: CLOSE_BUTTON_FADE_TIME,
|
||||||
|
transition: 'easeInQuad' });
|
||||||
|
|
||||||
|
this.title.remove_style_pseudo_class('hover');
|
||||||
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -664,6 +717,8 @@ const WindowOverlay = new Lang.Class({
|
|||||||
this._idleToggleCloseId = 0;
|
this._idleToggleCloseId = 0;
|
||||||
}
|
}
|
||||||
this.closeButton.hide();
|
this.closeButton.hide();
|
||||||
|
this.border.hide();
|
||||||
|
this.title.remove_style_pseudo_class('hover');
|
||||||
},
|
},
|
||||||
|
|
||||||
_onStyleChanged: function() {
|
_onStyleChanged: function() {
|
||||||
@ -673,6 +728,9 @@ const WindowOverlay = new Lang.Class({
|
|||||||
let closeNode = this.closeButton.get_theme_node();
|
let closeNode = this.closeButton.get_theme_node();
|
||||||
this.closeButton._overlap = closeNode.get_length('-shell-close-overlap');
|
this.closeButton._overlap = closeNode.get_length('-shell-close-overlap');
|
||||||
|
|
||||||
|
let borderNode = this.border.get_theme_node();
|
||||||
|
this.borderSize = borderNode.get_border_width(St.Side.TOP);
|
||||||
|
|
||||||
this._parentActor.queue_relayout();
|
this._parentActor.queue_relayout();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@ -1623,20 +1681,25 @@ const Workspace = new Lang.Class({
|
|||||||
return [];
|
return [];
|
||||||
|
|
||||||
let closeButtonHeight, captionHeight;
|
let closeButtonHeight, captionHeight;
|
||||||
|
let leftBorder, rightBorder;
|
||||||
if (this._windowOverlays.length) {
|
if (this._windowOverlays.length) {
|
||||||
// All of the overlays have the same chrome sizes,
|
// All of the overlays have the same chrome sizes,
|
||||||
// so just pick the first one.
|
// so just pick the first one.
|
||||||
let overlay = this._windowOverlays[0];
|
let overlay = this._windowOverlays[0];
|
||||||
[closeButtonHeight, captionHeight] = overlay.chromeHeights();
|
[closeButtonHeight, captionHeight] = overlay.chromeHeights();
|
||||||
|
[leftBorder, rightBorder] = overlay.chromeWidths();
|
||||||
} else {
|
} else {
|
||||||
[closeButtonHeight, captionHeight] = [0, 0];
|
[closeButtonHeight, captionHeight] = [0, 0];
|
||||||
}
|
}
|
||||||
|
|
||||||
rowSpacing += captionHeight;
|
rowSpacing += captionHeight;
|
||||||
|
columnSpacing += rightBorder;
|
||||||
|
|
||||||
let area = { x: this._x, y: this._y, width: this._width, height: this._height };
|
let area = { x: this._x, y: this._y, width: this._width, height: this._height };
|
||||||
area.y += closeButtonHeight;
|
area.y += closeButtonHeight;
|
||||||
area.height -= closeButtonHeight;
|
area.height -= closeButtonHeight;
|
||||||
|
area.x += leftBorder;
|
||||||
|
area.width -= leftBorder;
|
||||||
|
|
||||||
if (!this._currentLayout)
|
if (!this._currentLayout)
|
||||||
this._currentLayout = this._computeLayout(windows, area, rowSpacing, columnSpacing, captionHeight);
|
this._currentLayout = this._computeLayout(windows, area, rowSpacing, columnSpacing, captionHeight);
|
||||||
|
Loading…
Reference in New Issue
Block a user