[gnome-shell] layout: Add a standard dummy cursor



commit c8a58dcb6912fc82beeb761a4d68a51fb013dd38
Author: Jasper St. Pierre <jstpierre mecheye net>
Date:   Fri Feb 15 04:56:34 2013 -0500

    layout: Add a standard dummy cursor
    
    Right now we have three "dummy cursor" widgets between the background
    menu, the message tray menu, and the IBus candidate popup. Consolidate
    these into one "dummy cursor" widget which is tracked in the layout
    manager.

 js/ui/backgroundMenu.js     |   21 ++++++++-------------
 js/ui/ibusCandidatePopup.js |   10 +++-------
 js/ui/layout.js             |   19 +++++++++++++++++++
 3 files changed, 30 insertions(+), 20 deletions(-)
---
diff --git a/js/ui/backgroundMenu.js b/js/ui/backgroundMenu.js
index dcbbb39..71251e5 100644
--- a/js/ui/backgroundMenu.js
+++ b/js/ui/backgroundMenu.js
@@ -13,8 +13,8 @@ const BackgroundMenu = new Lang.Class({
     Name: 'BackgroundMenu',
     Extends: PopupMenu.PopupMenu,
 
-    _init: function(source, layoutManager) {
-        this.parent(source, 0, St.Side.TOP);
+    _init: function(layoutManager) {
+        this.parent(layoutManager.dummyCursor, 0, St.Side.TOP);
 
         this.addSettingsAction(_("Settings"), 'gnome-control-center.desktop');
         this.addMenuItem(new PopupMenu.PopupSeparatorMenuItem());
@@ -28,17 +28,14 @@ const BackgroundMenu = new Lang.Class({
 });
 
 function addBackgroundMenu(actor, layoutManager) {
-    let cursor = new St.Bin({ opacity: 0 });
-    layoutManager.uiGroup.add_actor(cursor);
-
     actor.reactive = true;
-    actor._backgroundMenu = new BackgroundMenu(cursor, layoutManager);
+    actor._backgroundMenu = new BackgroundMenu(layoutManager);
     actor._backgroundManager = new PopupMenu.PopupMenuManager({ actor: actor });
     actor._backgroundManager.addMenu(actor._backgroundMenu);
 
     function openMenu() {
         let [x, y] = global.get_pointer();
-        cursor.set_position(x, y);
+        Main.layoutManager.setDummyCursorPosition(x, y);
         actor._backgroundMenu.open(BoxPointer.PopupAnimation.NONE);
     }
 
@@ -59,10 +56,8 @@ function addBackgroundMenu(actor, layoutManager) {
     actor.add_action(clickAction);
 
     actor.connect('destroy', function() {
-                      actor._backgroundMenu.destroy();
-                      actor._backgroundMenu = null;
-                      actor._backgroundManager = null;
-
-                      cursor.destroy();
-                  });
+        actor._backgroundMenu.destroy();
+        actor._backgroundMenu = null;
+        actor._backgroundManager = null;
+    });
 }
diff --git a/js/ui/ibusCandidatePopup.js b/js/ui/ibusCandidatePopup.js
index 7c8db7a..01884f5 100644
--- a/js/ui/ibusCandidatePopup.js
+++ b/js/ui/ibusCandidatePopup.js
@@ -115,9 +115,6 @@ const CandidatePopup = new Lang.Class({
     Name: 'CandidatePopup',
 
     _init: function() {
-        this._cursor = new St.Bin({ opacity: 0 });
-        Main.uiGroup.add_actor(this._cursor);
-
         this._boxPointer = new BoxPointer.BoxPointer(St.Side.TOP);
         this._boxPointer.actor.visible = false;
         this._boxPointer.actor.style_class = 'candidate-popup-boxpointer';
@@ -158,10 +155,9 @@ const CandidatePopup = new Lang.Class({
 
         panelService.connect('set-cursor-location',
                              Lang.bind(this, function(ps, x, y, w, h) {
-                                 this._cursor.set_position(x, y);
-                                 this._cursor.set_size(w, h);
+                                 Main.layoutManager.setDummyCursorPosition(x, y);
                                  if (this._boxPointer.actor.visible)
-                                     this._boxPointer.setPosition(this._cursor, 0);
+                                     this._boxPointer.setPosition(Main.layoutManager.dummyCursor, 0);
                              }));
         panelService.connect('update-preedit-text',
                              Lang.bind(this, function(ps, text, cursorPosition, visible) {
@@ -253,7 +249,7 @@ const CandidatePopup = new Lang.Class({
                          this._candidateArea.actor.visible);
 
         if (isVisible) {
-            this._boxPointer.setPosition(this._cursor, 0);
+            this._boxPointer.setPosition(Main.layoutManager.dummyCursor, 0);
             this._boxPointer.show(BoxPointer.PopupAnimation.NONE);
             this._boxPointer.actor.raise_top();
         } else {
diff --git a/js/ui/layout.js b/js/ui/layout.js
index c1cf58b..0609ff2 100644
--- a/js/ui/layout.js
+++ b/js/ui/layout.js
@@ -219,6 +219,11 @@ const LayoutManager = new Lang.Class({
         this.addChrome(this.keyboardBox);
         this._keyboardHeightNotifyId = 0;
 
+        // A dummy actor that tracks the mouse or text cursor, based on the
+        // position set in setDummyCursorPosition.
+        this.dummyCursor = new St.Widget({ width: 0, height: 0 });
+        this.uiGroup.add_actor(this.dummyCursor);
+
         global.stage.remove_actor(global.top_window_group);
         this.uiGroup.add_actor(global.top_window_group);
 
@@ -720,6 +725,20 @@ const LayoutManager = new Lang.Class({
         this._updateRegions();
     },
 
+    // setDummyCursorPosition:
+    //
+    // The cursor dummy is a standard widget commonly used for popup
+    // menus and box pointers to track, as the box pointer API only
+    // tracks actors. If you want to pop up a menu based on where the
+    // user clicked, or where the text cursor is, the cursor dummy
+    // is what you should use. Given that the menu should not track
+    // the actual mouse pointer as it moves, you need to call this
+    // function before you show the menu to ensure it is at the right
+    // position.
+    setDummyCursorPosition: function(x, y) {
+        this.dummyCursor.set_position(Math.round(x), Math.round(y));
+    },
+
     // addChrome:
     // @actor: an actor to add to the chrome
     // @params: (optional) additional params


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