[gnome-shell-extensions] XRandRIndicator: new extension



commit cbba2678c4ee9f23f9e15aef59054a3e7f40dbb3
Author: Giovanni Campagna <gcampagna src gnome org>
Date:   Wed Jan 12 21:06:51 2011 +0100

    XRandRIndicator: new extension
    
    Replace the GTK+ based indicator from gnome-settings-daemon with
    a native one. Allows to rotate the laptop monitor and to fast open
    display preferences.
    Depends on bug 621017.

 .gitignore                                 |    1 +
 configure.ac                               |    7 ++-
 extensions/Makefile.am                     |    2 +-
 extensions/alternate-tab/stylesheet.css    |    9 +--
 extensions/xrandr-indicator/Makefile.am    |    3 +
 extensions/xrandr-indicator/extension.js   |  135 ++++++++++++++++++++++++++++
 extensions/xrandr-indicator/extension.js~  |  132 +++++++++++++++++++++++++++
 extensions/xrandr-indicator/metadata.json  |    6 ++
 extensions/xrandr-indicator/stylesheet.css |    3 +
 9 files changed, 288 insertions(+), 10 deletions(-)
---
diff --git a/.gitignore b/.gitignore
index 523a48e..58b7e1b 100644
--- a/.gitignore
+++ b/.gitignore
@@ -10,3 +10,4 @@ autom4te.cache/
 m4/
 po/POTFILES
 po/stamp-it
+staging/
diff --git a/configure.ac b/configure.ac
index 73f040a..5a012ef 100644
--- a/configure.ac
+++ b/configure.ac
@@ -19,7 +19,7 @@ PKG_PROG_PKG_CONFIG([0.22])
 ADDITIONAL_PACKAGES=
 
 dnl keep this in sync with extensions/Makefile.am
-ALL_EXTENSIONS="example alternate-tab"
+ALL_EXTENSIONS="example alternate-tab xrandr-indicator"
 AC_ARG_ENABLE([extensions],
 	[AS_HELP_STRING([--enable-extensions],[Space separated list of extensions to enable. Default is that all extensions are built.])],
 	[],
@@ -28,6 +28,10 @@ AC_ARG_ENABLE([extensions],
 ENABLED_EXTENSIONS=
 for e in $enable_extensions; do
 	case $e in
+		xrandr-indicator)
+			ENABLED_EXTENSIONS="$ENABLED_EXTENSIONS $e"
+			ADDITIONAL_PACKAGES="gnome-desktop-3.0 >= 2.91.6"
+			;;
 		alternate-tab|example)
 			ENABLED_EXTENSIONS="$ENABLED_EXTENSIONS $e"
 			;;
@@ -50,6 +54,7 @@ AC_CONFIG_FILES([
   extensions/Makefile
   extensions/example/Makefile
   extensions/alternate-tab/Makefile
+  extensions/xrandr-indicator/Makefile
   po/Makefile.in
 ])
 AC_OUTPUT
diff --git a/extensions/Makefile.am b/extensions/Makefile.am
index a0471ec..b42f5d7 100644
--- a/extensions/Makefile.am
+++ b/extensions/Makefile.am
@@ -1,3 +1,3 @@
-DIST_SUBDIRS = example
+DIST_SUBDIRS = example alternate-tab xrandr-indicator
 
 SUBDIRS = $(ENABLED_EXTENSIONS)
diff --git a/extensions/alternate-tab/stylesheet.css b/extensions/alternate-tab/stylesheet.css
index a8dc980..25134b6 100644
--- a/extensions/alternate-tab/stylesheet.css
+++ b/extensions/alternate-tab/stylesheet.css
@@ -1,8 +1 @@
-/* Example stylesheet */
-.helloworld-label {
-    font-size: 36px;
-    font-weight: bold;
-    color: #ffffff;
-    background-color: rgba(10,10,10,0.7);
-    border-radius: 5px;
-}
+/* This extensions requires no special styling */
diff --git a/extensions/xrandr-indicator/Makefile.am b/extensions/xrandr-indicator/Makefile.am
new file mode 100644
index 0000000..56abe21
--- /dev/null
+++ b/extensions/xrandr-indicator/Makefile.am
@@ -0,0 +1,3 @@
+EXTENSION_ID = xrandr-indicator
+
+include ../../extension.mk
diff --git a/extensions/xrandr-indicator/extension.js b/extensions/xrandr-indicator/extension.js
new file mode 100644
index 0000000..6cc0bd2
--- /dev/null
+++ b/extensions/xrandr-indicator/extension.js
@@ -0,0 +1,135 @@
+/* -*- mode: js2; js2-basic-offset: 4; indent-tabs-mode: nil -*- */
+
+const DBus = imports.dbus;
+const Gdk = imports.gi.Gdk;
+const GLib = imports.gi.GLib;
+const GnomeDesktop = imports.gi.GnomeDesktop;
+const Lang = imports.lang;
+const Shell = imports.gi.Shell;
+const St = imports.gi.St;
+
+const Main = imports.ui.main;
+const PanelMenu = imports.ui.panelMenu;
+const PopupMenu = imports.ui.popupMenu;
+const Panel = imports.ui.panel;
+
+const Gettext = imports.gettext.domain('gnome-shell');
+const _ = Gettext.gettext;
+
+const possibleRotations = [ GnomeDesktop.RRRotation.ROTATION_0,
+			    GnomeDesktop.RRRotation.ROTATION_90,
+			    GnomeDesktop.RRRotation.ROTATION_180,
+			    GnomeDesktop.RRRotation.ROTATION_270
+			  ];
+
+let rotations = [ [ GnomeDesktop.RRRotation.ROTATION_0, _("Normal") ],
+		  [ GnomeDesktop.RRRotation.ROTATION_90, _("Left") ],
+		  [ GnomeDesktop.RRRotation.ROTATION_270, _("Right") ],
+		  [ GnomeDesktop.RRRotation.ROTATION_180, _("Upside-down") ]
+		];
+
+const XRandr2Iface = {
+    name: 'org.gnome.SettingsDaemon.XRANDR_2',
+    methods: [
+	{ name: 'ApplyConfiguration', inSignature: 'xx', outSignature: '' },
+    ]
+};
+let XRandr2 = DBus.makeProxyClass(XRandr2Iface);
+
+function Indicator() {
+    this._init.apply(this, arguments);
+}
+
+Indicator.prototype = {
+    __proto__: PanelMenu.SystemStatusButton.prototype,
+
+    _init: function() {
+        PanelMenu.SystemStatusButton.prototype._init.call(this, 'preferences-desktop-display');
+
+        this._proxy = new XRandr2(DBus.session, 'org.gnome.SettingsDaemon', '/org/gnome/SettingsDaemon/XRANDR');
+
+        try {
+            this._screen = new GnomeDesktop.RRScreen({ gdk_screen: Gdk.Screen.get_default() });
+            this._screen.init(null);
+        } catch(e) {
+            // an error means there is no XRandR extension
+            this.actor.hide();
+            return;
+        }
+
+        this._createMenu();
+        this._screen.connect('screen-changed', Lang.bind(this, this._randrEvent));
+    },
+
+    _randrEvent: function() {
+        this.menu.removeAll();
+        this._createMenu();
+    },
+
+    _createMenu: function() {
+        let config = GnomeDesktop.RRConfig.new_current(this._screen);
+        let outputs = config.get_outputs();
+        for (let i = 0; i < outputs.length; i++) {
+            if (outputs[i].get_connected())
+                this._addOutputItem(config, outputs[i]);
+        }
+        this.menu.addMenuItem(new PopupMenu.PopupSeparatorMenuItem());
+        this.menu.addAction(_("Configure display settings..."), function() {
+            GLib.spawn_command_line_async('gnome-control-center display');
+        });
+    },
+
+    _addOutputItem: function(config, output) {
+        let item = new PopupMenu.PopupMenuItem(output.get_display_name());
+        item.label.add_style_class_name('display-subtitle');
+        item.actor.reactive = false;
+        item.actor.can_focus = false;
+        this.menu.addMenuItem(item);
+
+        let allowedRotations = this._getAllowedRotations(config, output);
+        for (let i = 0; i < rotations.length; i++) {
+            let [bitmask, name] = rotations[i];
+            if (bitmask & allowedRotations) {
+                this.menu.addAction(name, Lang.bind(this, function(event) {
+                    /* ensure config is saved so we get a backup if anything goes wrong */
+                    config.save();
+
+                    output.set_rotation(bitmask);
+                    try {
+                        config.save();
+                        this._proxy.ApplyConfigurationRemote(global.stage_xwindow, event.get_time());
+                    } catch (e) {
+                        logError ('Could not save monitor configuration: ' + e);
+                    }
+                }));
+            }
+        }
+    },
+
+    _getAllowedRotations: function(config, output) {
+        let retval = 0;
+
+        let current = output.get_rotation();
+
+        for (let i = 0; i < possibleRotations.length; i++) {
+            output.set_rotation(possibleRotations[i]);
+            if (config.applicable(this._screen)) {
+                retval |= possibleRotations[i];
+            }
+        }
+
+        output.set_rotation(current);
+
+        if (retval.lenght == 0) {
+            // what, no rotation?
+            // what's current then?
+            retval = current;
+        }
+        return retval;
+    }
+}
+
+
+function main() {
+    Panel.STANDARD_TRAY_ICON_SHELL_IMPLEMENTATION['display'] = Indicator;
+}
diff --git a/extensions/xrandr-indicator/extension.js~ b/extensions/xrandr-indicator/extension.js~
new file mode 100644
index 0000000..c52ea15
--- /dev/null
+++ b/extensions/xrandr-indicator/extension.js~
@@ -0,0 +1,132 @@
+/* -*- mode: js2; js2-basic-offset: 4; indent-tabs-mode: nil -*- */
+
+const DBus = imports.dbus;
+const Gdk = imports.gi.Gdk;
+const GLib = imports.gi.GLib;
+const GnomeDesktop = imports.gi.GnomeDesktop;
+const Lang = imports.lang;
+const Shell = imports.gi.Shell;
+const St = imports.gi.St;
+
+const Main = imports.ui.main;
+const PanelMenu = imports.ui.panelMenu;
+const PopupMenu = imports.ui.popupMenu;
+const Panel = imports.ui.panel;
+
+const Gettext = imports.gettext.domain('gnome-shell');
+const _ = Gettext.gettext;
+
+const possibleRotations = [ GnomeDesktop.RRRotation.ROTATION_0,
+			    GnomeDesktop.RRRotation.ROTATION_90,
+			    GnomeDesktop.RRRotation.ROTATION_180,
+			    GnomeDesktop.RRRotation.ROTATION_270
+			  ];
+
+let rotations = [ [ GnomeDesktop.RRRotation.ROTATION_0, _("Normal") ],
+		  [ GnomeDesktop.RRRotation.ROTATION_90, _("Left") ],
+		  [ GnomeDesktop.RRRotation.ROTATION_270, _("Right") ],
+		  [ GnomeDesktop.RRRotation.ROTATION_180, _("Upside-down") ]
+		];
+
+const XRandr2Iface = {
+    name: 'org.gnome.SettingsDaemon.XRANDR_2',
+    methods: [
+	{ name: 'ApplyConfiguration', inSignature: 'xx', outSignature: '' },
+    ]
+};
+let XRandr2 = DBus.makeProxyClass(XRandr2Iface);
+
+function Indicator() {
+    this._init.apply(this, arguments);
+}
+
+Indicator.prototype = {
+    __proto__: PanelMenu.SystemStatusButton.prototype,
+
+    _init: function() {
+	PanelMenu.SystemStatusButton.prototype._init.call(this, 'preferences-desktop-display');
+
+	this._proxy = new XRandr2(DBus.session, 'org.gnome.SettingsDaemon', '/org/gnome/SettingsDaemon/XRANDR');
+
+	try {
+	    this._screen = new GnomeDesktop.RRScreen({ gdk_screen: Gdk.Screen.get_default() });
+        this._screen.init(null);
+	} catch(e) {
+	    // an error means there is no XRandR extension
+	    this.actor.hide();
+	    return;
+	}
+
+	this._createMenu();
+	this._screen.connect('screen-changed', Lang.bind(this, this._randrEvent));
+    },
+
+    _randrEvent: function() {
+	this.menu.removeAll();
+	this._createMenu();
+    },
+
+    _createMenu: function() {
+	let config = GnomeDesktop.RRConfig.new_current(this._screen);
+	let outputs = config.get_outputs();
+	for (let i = 0; i < outputs.length; i++) {
+            if (outputs[i].get_connected())
+	        this._addOutputItem(config, outputs[i]);
+        }
+	this.menu.addMenuItem(new PopupMenu.PopupSeparatorMenuItem());
+	this.menu.addAction(_("Configure display settings..."), function() {
+	    GLib.spawn_command_line_async('gnome-control-center display');
+	});
+    },
+
+    _addOutputItem: function(config, output) {
+	let item = new PopupMenu.PopupMenuItem(output.get_display_name());
+	item.label.add_style_class_name('display-subtitle');
+    item.actor.reactive = false;
+    item.actor.can_focus = false;
+	this.menu.addMenuItem(item);
+
+	let allowedRotations = this._getAllowedRotations(config, output);
+	for (let i = 0; i < rotations.length; i++) {
+	    let [bitmask, name] = rotations[i];
+	    if (bitmask & allowedRotations) {
+		this.menu.addAction(name, Lang.bind(this, function(event) {
+		    /* ensure config is saved so we get a backup if anything goes wrong */
+		    config.save();
+
+		    output.set_rotation(bitmask);
+		    try {
+			config.save();
+			this._proxy.ApplyConfigurationRemote(global.stage_xwindow, event.get_time());
+		    } catch (e) {
+			logError ('Could not save monitor configuration: ' + e);
+		    }
+		}));
+	    }
+	}
+    },
+
+    _getAllowedRotations: function(config, output) {
+	let retval = 0;
+
+	let current = output.get_rotation();
+
+	for (let i = 0; i < possibleRotations.length; i++) {
+	    output.set_rotation(possibleRotations[i]);
+	    if (config.applicable(this._screen)) {
+		retval |= possibleRotations[i];
+	    }
+	}
+
+	output.set_rotation(current);
+
+	if (retval.lenght == 0) {
+	    // what, no rotation?
+	    // what's current then?
+	    retval = current;
+	}
+	return retval;
+    }
+}
+
+Panel.STANDARD_TRAY_ICON_SHELL_IMPLEMENTATION['display'] = Indicator;
diff --git a/extensions/xrandr-indicator/metadata.json b/extensions/xrandr-indicator/metadata.json
new file mode 100644
index 0000000..1cc3c55
--- /dev/null
+++ b/extensions/xrandr-indicator/metadata.json
@@ -0,0 +1,6 @@
+{
+"uuid": "xrandr-indicator gnome-shell-extensions gnome org",
+"name": "Monitor Status Indicator",
+"description": "Add a systems status menu for rotating monitors (overrides what is currently provided by gnome-settings-daemon)"
+"shell-version": [ "2.91.5" ]
+}
diff --git a/extensions/xrandr-indicator/stylesheet.css b/extensions/xrandr-indicator/stylesheet.css
new file mode 100644
index 0000000..e263d70
--- /dev/null
+++ b/extensions/xrandr-indicator/stylesheet.css
@@ -0,0 +1,3 @@
+.display-subtitle {
+    font-weight: bold;
+}



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