[gnome-shell/wip/sassWithSomeFixes: 6/8] appDisplay: Show a dot when application is running



commit 45723877df2d972cf69edbe8d7d80bd41c82962c
Author: Carlos Soriano <carlos soriano89 gmail com>
Date:   Thu Oct 16 19:51:30 2014 +0200

    appDisplay: Show a dot when application is running
    
    Show a dot in running applications.
    Design request.

 data/theme/gnome-shell.css |    3 ++
 js/ui/appDisplay.js        |   75 ++++++++++++++++++++++++++++++++------------
 js/ui/iconGrid.js          |   35 ++++++++++++--------
 js/ui/search.js            |    8 +++-
 4 files changed, 85 insertions(+), 36 deletions(-)
---
diff --git a/data/theme/gnome-shell.css b/data/theme/gnome-shell.css
index 4e32e80..5e48082 100644
--- a/data/theme/gnome-shell.css
+++ b/data/theme/gnome-shell.css
@@ -604,6 +604,9 @@
   background: #303030;
   border: 3px solid white; }
 
+.dash-item-container > StWidget {
+    padding: 4px 8px; }
+
 .keyboard-key:active {
   background: #808080; }
 
diff --git a/js/ui/appDisplay.js b/js/ui/appDisplay.js
index 1e94015..355ea7b 100644
--- a/js/ui/appDisplay.js
+++ b/js/ui/appDisplay.js
@@ -1519,13 +1519,33 @@ const AppIcon = new Lang.Class({
         this.id = app.get_id();
         this.name = app.get_name();
 
-        this.actor = new St.Button({ style_class: 'app-well-app',
+        // We need to make it track_hover so dash item can connect to
+        // the hover signal of the actor in _hookupLabel to call
+        // shouldShowTooltip when hovered.
+        this.actor = new St.Widget({ layout_manager: new Clutter.BinLayout(),
                                      reactive: true,
-                                     button_mask: St.ButtonMask.ONE | St.ButtonMask.TWO,
-                                     can_focus: true,
-                                     x_fill: true,
-                                     y_fill: true });
+                                     track_hover: true });
+
+        this._dot = new St.Widget({ style_class: 'app-well-app-running-dot',
+                                    layout_manager: new Clutter.BinLayout(),
+                                    x_expand: true, y_expand: true,
+                                    x_align: Clutter.ActorAlign.CENTER,
+                                    y_align: Clutter.ActorAlign.END });
+
+        this._dot.hide();
+
+        this._button = new St.Button({ style_class: 'app-well-app',
+                                       reactive: true,
+                                       button_mask: St.ButtonMask.ONE | St.ButtonMask.TWO,
+                                       can_focus: true,
+                                       x_fill: true,
+                                       y_fill: true });
+
+        this.actor.add_actor(this._button);
+        this.actor.add_actor(this._dot);
+
         this.actor._delegate = this;
+        this._button._delegate = this;
 
         if (!iconParams)
             iconParams = {};
@@ -1533,20 +1553,20 @@ const AppIcon = new Lang.Class({
         iconParams['createIcon'] = Lang.bind(this, this._createIcon);
         iconParams['setSizeManually'] = true;
         this.icon = new IconGrid.BaseIcon(app.get_name(), iconParams);
-        this.actor.set_child(this.icon.actor);
+        this._button.set_child(this.icon.actor);
 
         this.actor.label_actor = this.icon.label;
 
-        this.actor.connect('leave-event', Lang.bind(this, this._onLeaveEvent));
-        this.actor.connect('button-press-event', Lang.bind(this, this._onButtonPress));
-        this.actor.connect('touch-event', Lang.bind(this, this._onTouchEvent));
-        this.actor.connect('clicked', Lang.bind(this, this._onClicked));
-        this.actor.connect('popup-menu', Lang.bind(this, this._onKeyboardPopupMenu));
+        this._button.connect('leave-event', Lang.bind(this, this._onLeaveEvent));
+        this._button.connect('button-press-event', Lang.bind(this, this._onButtonPress));
+        this._button.connect('touch-event', Lang.bind(this, this._onTouchEvent));
+        this._button.connect('clicked', Lang.bind(this, this._onClicked));
+        this._button.connect('popup-menu', Lang.bind(this, this._onKeyboardPopupMenu));
 
         this._menu = null;
         this._menuManager = new PopupMenu.PopupMenuManager(this);
 
-        this._draggable = DND.makeDraggable(this.actor);
+        this._draggable = DND.makeDraggable(this._button);
         this._draggable.connect('drag-begin', Lang.bind(this,
             function () {
                 this._removeMenuTimeout();
@@ -1570,6 +1590,18 @@ const AppIcon = new Lang.Class({
         this._onStateChanged();
     },
 
+    // Needed for containers that want to track focus of the widget
+    // for i.e. scroll the container when navigating through items
+    getFocusReceiver: function () {
+        return this._button;
+    },
+
+    // Needed for containers that want to change style of the widget
+    // for i.e. set as selected when searching in shell
+    getStyleReceiver: function () {
+        return this._button;
+    },
+
     _onDestroy: function() {
         if (this._stateChangedId > 0)
             this.app.disconnect(this._stateChangedId);
@@ -1589,10 +1621,13 @@ const AppIcon = new Lang.Class({
     },
 
     _onStateChanged: function() {
-        if (this.app.state != Shell.AppState.STOPPED)
-            this.actor.add_style_class_name('running');
-        else
-            this.actor.remove_style_class_name('running');
+        if (this.app.state != Shell.AppState.STOPPED) {
+            this._button.add_style_class_name('running');
+            this._dot.show();
+        } else {
+            this._button.remove_style_class_name('running');
+            this._dot.hide();
+        }
     },
 
     _setPopupTimeout: function() {
@@ -1607,7 +1642,7 @@ const AppIcon = new Lang.Class({
     },
 
     _onLeaveEvent: function(actor, event) {
-        this.actor.fake_release();
+        this._button.fake_release();
         this._removeMenuTimeout();
     },
 
@@ -1645,7 +1680,7 @@ const AppIcon = new Lang.Class({
 
     popupMenu: function() {
         this._removeMenuTimeout();
-        this.actor.fake_release();
+        this._button.fake_release();
         this._draggable.fakeRelease();
 
         if (!this._menu) {
@@ -1664,7 +1699,7 @@ const AppIcon = new Lang.Class({
 
         this.emit('menu-state-changed', true);
 
-        this.actor.set_hover(true);
+        this._button.set_hover(true);
         this._menu.popup();
         this._menuManager.ignoreRelease();
         this.emit('sync-tooltip');
@@ -1681,7 +1716,7 @@ const AppIcon = new Lang.Class({
     },
 
     _onMenuPoppedDown: function() {
-        this.actor.sync_hover();
+        this._button.sync_hover();
         this.emit('menu-state-changed', false);
     },
 
diff --git a/js/ui/iconGrid.js b/js/ui/iconGrid.js
index 8754501..38fe16c 100644
--- a/js/ui/iconGrid.js
+++ b/js/ui/iconGrid.js
@@ -278,20 +278,6 @@ const IconGrid = new Lang.Class({
         this._grid.connect('get-preferred-width', Lang.bind(this, this._getPreferredWidth));
         this._grid.connect('get-preferred-height', Lang.bind(this, this._getPreferredHeight));
         this._grid.connect('allocate', Lang.bind(this, this._allocate));
-        this._grid.connect('actor-added', Lang.bind(this, this._childAdded));
-        this._grid.connect('actor-removed', Lang.bind(this, this._childRemoved));
-    },
-
-    _keyFocusIn: function(actor) {
-        this.emit('key-focus-in', actor);
-    },
-
-    _childAdded: function(grid, child) {
-        child._iconGridKeyFocusInId = child.connect('key-focus-in', Lang.bind(this, this._keyFocusIn));
-    },
-
-    _childRemoved: function(grid, child) {
-        child.disconnect(child._iconGridKeyFocusInId);
     },
 
     _getPreferredWidth: function (grid, forHeight, alloc) {
@@ -682,6 +668,10 @@ const IconGrid = new Lang.Class({
         this._grid.destroy_all_children();
     },
 
+    _keyFocusIn: function(actor) {
+        this.emit('key-focus-in', actor._associatedItem);
+    },
+
     addItem: function(item, index) {
         if (!item.icon instanceof BaseIcon)
             throw new Error('Only items with a BaseIcon icon property can be added to IconGrid');
@@ -691,9 +681,26 @@ const IconGrid = new Lang.Class({
             this._grid.insert_child_at_index(item.actor, index);
         else
             this._grid.add_actor(item.actor);
+
+        // Maybe the item actor acts as a container, so ask the item if
+        // it has a specific actor to track focus
+        let focusReceiver = item.actor;
+        if (item.getFocusReceiver)
+            focusReceiver = item.getFocusReceiver();
+
+        focusReceiver._associatedItem = item.actor;
+        focusReceiver._iconGridKeyFocusInId = focusReceiver.connect('key-focus-in', Lang.bind(this, 
this._keyFocusIn));
     },
 
     removeItem: function(item) {
+        let focusReceiver = item.actor;
+        if (item.getFocusReceiver)
+            focusReceiver = item.getFocusReceiver();
+
+
+        focusReceiver._associatedItem = null;
+        focusReceiver.disconnect(focusReceiver._iconGridKeyFocusInId);
+
         this._grid.remove_child(item.actor);
     },
 
diff --git a/js/ui/search.js b/js/ui/search.js
index 2a8e0fd..acd8802 100644
--- a/js/ui/search.js
+++ b/js/ui/search.js
@@ -659,11 +659,15 @@ const SearchResults = new Lang.Class({
         if (!result)
             return;
 
+        let styleReceiver = result.actor;
+        if (result.getStyleReceiver)
+            styleReceiver = result.getStyleReceiver();
+
         if (selected) {
-            result.actor.add_style_pseudo_class('selected');
+            styleReceiver.add_style_pseudo_class('selected');
             Util.ensureActorVisibleInScrollView(this._scrollView, result.actor);
         } else {
-            result.actor.remove_style_pseudo_class('selected');
+            styleReceiver.remove_style_pseudo_class('selected');
         }
     }
 });


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