[gnome-shell] Workspace: Highlight window clone and caption when hovered



commit a370697385a6a94f296874485af7481fdc9dd8fe
Author: Giovanni Campagna <gcampagna src gnome org>
Date:   Sat Oct 27 18:18:54 2012 +0200

    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

 data/theme/gnome-shell.css |   12 +++++-
 js/ui/workspace.js         |   91 +++++++++++++++++++++++++++++++++++++-------
 2 files changed, 88 insertions(+), 15 deletions(-)
---
diff --git a/data/theme/gnome-shell.css b/data/theme/gnome-shell.css
index 86b447d..4038120 100644
--- a/data/theme/gnome-shell.css
+++ b/data/theme/gnome-shell.css
@@ -615,6 +615,7 @@ StScrollBar StButton#vhandle:active {
     border-radius: 8px;
     padding: 4px 12px;
     -shell-caption-spacing: 12px;
+    border: 2px solid rgba(0, 0, 0, 0);
 }
 
 .window-close, .notification-close {
@@ -625,7 +626,16 @@ StScrollBar StButton#vhandle:active {
 }
 
 .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 {
diff --git a/js/ui/workspace.js b/js/ui/workspace.js
index 3005c8d..c2583ed 100644
--- a/js/ui/workspace.js
+++ b/js/ui/workspace.js
@@ -445,6 +445,9 @@ const WindowOverlay = new Lang.Class({
         this._parentActor = parentActor;
         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',
                                    text: metaWindow.title });
         title.clutter_text.ellipsize = Pango.EllipsizeMode.END;
@@ -482,11 +485,13 @@ const WindowOverlay = new Lang.Class({
         this.closeButton = button;
 
         parentActor.add_actor(this.title);
+        parentActor.add_actor(this.border);
         parentActor.add_actor(this.closeButton);
         title.connect('style-changed',
                       Lang.bind(this, this._onStyleChanged));
         button.connect('style-changed',
                        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
         // the signal will be emitted normally when we are added
         if (parentActor.get_stage())
@@ -497,13 +502,17 @@ const WindowOverlay = new Lang.Class({
         this._hidden = true;
         this.closeButton.hide();
         this.title.hide();
+        this.title.remove_style_pseudo_class('hover');
+
+        this.border.hide();
     },
 
     show: function() {
         this._hidden = false;
-        if (this._windowClone.actor.has_pointer)
-            this.closeButton.show();
+
         this.title.show();
+        if (this._windowClone.actor.has_pointer)
+            this._animateVisible();
     },
 
     fadeIn: function() {
@@ -520,10 +529,14 @@ const WindowOverlay = new Lang.Class({
     },
 
     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];
     },
 
+    chromeWidths: function () {
+        return [this.borderSize, this.borderSize];
+    },
+
     _repositionSelf: function() {
         let [cloneX, cloneY, cloneWidth, cloneHeight] = this._windowClone.slot;
         this.updatePositions(cloneX, cloneY, cloneWidth, cloneHeight, false);
@@ -578,16 +591,32 @@ const WindowOverlay = new Lang.Class({
             title.width = titleWidth;
             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) {
-        Tweener.addTween(actor,
-                         { x: x,
-                           y: y,
-                           width: width,
-                           time: Overview.ANIMATION_TIME,
-                           transition: 'easeOutQuad'
-                         });
+    _animateOverlayActor: function(actor, x, y, width, height) {
+        let params = { x: x,
+                       y: y,
+                       width: width,
+                       time: Overview.ANIMATION_TIME,
+                       transition: 'easeOutQuad' };
+
+        if (height !== undefined)
+            params.height = height;
+
+        Tweener.addTween(actor, params);
     },
 
     _closeWindow: function(actor) {
@@ -630,6 +659,21 @@ const WindowOverlay = new Lang.Class({
         this._windowClone.metaWindow.disconnect(this._updateCaptionId);
         this.title.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() {
@@ -639,8 +683,8 @@ const WindowOverlay = new Lang.Class({
         // are shown again
         if (this._hidden)
             return;
-        this._parentActor.raise_top();
-        this.closeButton.show();
+
+        this._animateVisible();
         this.emit('show-close-button');
     },
 
@@ -652,9 +696,18 @@ const WindowOverlay = new Lang.Class({
     _idleToggleCloseButton: function() {
         this._idleToggleCloseId = 0;
         if (!this._windowClone.actor.has_pointer &&
-            !this.closeButton.has_pointer)
+            !this.closeButton.has_pointer) {
             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;
     },
 
@@ -664,6 +717,8 @@ const WindowOverlay = new Lang.Class({
             this._idleToggleCloseId = 0;
         }
         this.closeButton.hide();
+        this.border.hide();
+        this.title.remove_style_pseudo_class('hover');
     },
 
     _onStyleChanged: function() {
@@ -673,6 +728,9 @@ const WindowOverlay = new Lang.Class({
         let closeNode = this.closeButton.get_theme_node();
         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();
     }
 });
@@ -1623,20 +1681,25 @@ const Workspace = new Lang.Class({
             return [];
 
         let closeButtonHeight, captionHeight;
+        let leftBorder, rightBorder;
         if (this._windowOverlays.length) {
             // All of the overlays have the same chrome sizes,
             // so just pick the first one.
             let overlay = this._windowOverlays[0];
             [closeButtonHeight, captionHeight] = overlay.chromeHeights();
+            [leftBorder, rightBorder] = overlay.chromeWidths();
         } else {
             [closeButtonHeight, captionHeight] = [0, 0];
         }
 
         rowSpacing += captionHeight;
+        columnSpacing += rightBorder;
 
         let area = { x: this._x, y: this._y, width: this._width, height: this._height };
         area.y += closeButtonHeight;
         area.height -= closeButtonHeight;
+        area.x += leftBorder;
+        area.width -= leftBorder;
 
         if (!this._currentLayout)
             this._currentLayout = this._computeLayout(windows, area, rowSpacing, columnSpacing, captionHeight);



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]