[Pkg-mozext-commits] [firetray] 08/38: Use environment desktop id as a criteria for enabling appindicator.

David Prévot taffit at moszumanska.debian.org
Mon Apr 6 15:58:19 UTC 2015


This is an automated email from the git hooks/post-receive script.

taffit pushed a commit to branch master
in repository firetray.

commit 317f56728f65a31971ebdb0e00a36a603af2418f
Author: foudfou <foudil.newbie+git at gmail.com>
Date:   Mon Feb 9 15:43:25 2015 +0100

    Use environment desktop id as a criteria for enabling appindicator.
    
    XGetSelectionOwner'ing for _NET_SYSTEM_TRAY_Sn is unfortunately unsufficient,
    as not all desktops respect this convention (unity/compiz looking at you again).
---
 src/modules/ctypes/linux/libc.jsm        |   3 +
 src/modules/linux/FiretrayStatusIcon.jsm | 118 ++++++++++++++++++-------------
 testing/Makefile                         |   6 +-
 testing/xgetselectionowner.c             |  35 +++++++++
 4 files changed, 111 insertions(+), 51 deletions(-)

diff --git a/src/modules/ctypes/linux/libc.jsm b/src/modules/ctypes/linux/libc.jsm
index d3ae68a..a50c37a 100644
--- a/src/modules/ctypes/linux/libc.jsm
+++ b/src/modules/ctypes/linux/libc.jsm
@@ -23,6 +23,9 @@ function libc_defines(lib) {
   lib.lazy_bind("fflush", ctypes.int32_t, this.FILE.ptr);
   lib.lazy_bind("getpid", this.pid_t);
   lib.lazy_bind("strcmp", ctypes.int, ctypes.char.ptr, ctypes.char.ptr);
+  lib.lazy_bind("popen", this.FILE.ptr, ctypes.char.ptr, ctypes.char.ptr);
+  lib.lazy_bind("pclose", ctypes.int, this.FILE.ptr);
+  lib.lazy_bind("fread", ctypes.size_t, ctypes.voidptr_t, ctypes.size_t, ctypes.size_t, this.FILE.ptr);
 };
 
 var libc = new ctypes_library(LIBC_LIBNAME, LIBC_ABIS, libc_defines, this);
diff --git a/src/modules/linux/FiretrayStatusIcon.jsm b/src/modules/linux/FiretrayStatusIcon.jsm
index 5c33db4..cb5acae 100644
--- a/src/modules/linux/FiretrayStatusIcon.jsm
+++ b/src/modules/linux/FiretrayStatusIcon.jsm
@@ -10,7 +10,9 @@ Cu.import("resource://firetray/ctypes/linux/gdk.jsm");
 Cu.import("resource://firetray/ctypes/linux/gio.jsm");
 Cu.import("resource://firetray/ctypes/linux/glib.jsm");
 Cu.import("resource://firetray/ctypes/linux/gobject.jsm");
+Cu.import("resource://firetray/ctypes/linux/libc.jsm");
 Cu.import("resource://firetray/ctypes/linux/x11.jsm");
+Cu.import("resource://gre/modules/ctypes.jsm");
 Cu.import("resource://firetray/commons.js");
 firetray.Handler.subscribeLibsForClosing([gdk, gio, glib, gobject]);
 
@@ -32,6 +34,8 @@ firetray.StatusIcon = {
   init: function() {
     this.defineIconNames();
 
+    let systray = this.XSystemtrayReady();
+    log.debug("systray="+systray);
     // PopupMenu g_connect's some Handler functions. As these are overridden is
     // StatusIcon implementations, PopupMenu must be initialized *after*
     // implemenations are imported.
@@ -39,13 +43,18 @@ firetray.StatusIcon = {
     this.canAppIndicator =
       (appind3.available() && this.dbusNotificationWatcherReady());
     log.info("canAppIndicator="+this.canAppIndicator);
-    // Can we detect if EWMH icons handled ?
-    // For ex. if gtk_status_icon_new returns NULL ? NO
-    // XGetSelectionOwner(_NET_SYSTEM_TRAY_Sn) ?
-    let xtray = this.xSystemtrayReady();
-    log.warn("xtray="+xtray);
+    /* We can't reliably detect if xembed tray icons are handled, because, for
+     instance, Unity/compiz falsely claims to have support for it through
+     _NET_SYSTEM_TRAY_Sn (compiz). We could also check the root window WM_NAME,
+     except that Unity has "compiz"... So we end up using the desktop id as a
+     criteria for enabling appindicator. */
+    let desktop = this.getDesktop();
+    log.info("desktop="+JSON.stringify(desktop));
+
     if (firetray.Utils.prefService.getBoolPref('with_appindicator') &&
-        this.canAppIndicator) {
+        this.canAppIndicator &&
+        (desktop.name === 'unity' ||
+         (desktop.name === 'kde-plasma' && desktop.ver > 4))) {
       /* FIXME: Ubuntu14.04/Unity: successfully closing appind3 crashes FF/TB
        during exit, in Ubuntu's unity-menubar.patch's code.
        https://bugs.launchpad.net/ubuntu/+source/firefox/+bug/1393256 */
@@ -104,51 +113,60 @@ firetray.StatusIcon = {
 
   loadImageCustom: function() { }, // done in setIconImageCustom
 
-  xSystemtrayReady: function() {
-    /*
-     GdkScreen * screen = gtk_widget_get_screen(GTK_WIDGET(p->panel->topgwin));
-     GdkDisplay * display = gdk_screen_get_display(screen);
-
-     char * selection_atom_name = g_strdup_printf("_NET_SYSTEM_TRAY_S%d", gdk_screen_get_number(screen));
-     Atom selection_atom = gdk_x11_get_xatom_by_name_for_display(display, selection_atom_name);
-     g_free(selection_atom_name);
-
-     if (XGetSelectionOwner(GDK_DISPLAY_XDISPLAY(display), selection_atom) != None)
-     {
-     ERR("tray: another systray already running\n");
-     return 1;
-     }
-     */
-
-    let dpy = x11.XOpenDisplay(null);
-    log.warn("dpy="+dpy);
-
-    // let screen = gdk.gdk_screen_get_default();
-    // let display = gdk.gdk_screen_get_display(screen);
-    // let selection_atom_name = "_NET_SYSTEM_TRAY_S"+gdk.gdk_screen_get_number(screen);
-    // log.warn("selection_atom_name="+selection_atom_name);
-    // let selection_atom = gdk.gdk_x11_get_xatom_by_name_for_display(display, selection_atom_name);
-    // log.warn("selection_atom="+selection_atom);
-
-    let intern_atom = x11.XInternAtom(dpy, "_NET_SYSTEM_TRAY_S0", 0);
-    log.warn("intern_atom="+intern_atom);
-
-    // let xdisplay = gdk.gdk_x11_display_get_xdisplay(display);
-    // log.warn("xdisplay="+xdisplay+" "+"Display="+x11.current.Display);
-    // let name = x11.XGetAtomName(xdisplay, selection_atom).readString();
-    // log.warn("name="+name);
-
-    // let rv = x11.XGetSelectionOwner(xdisplay, selection_atom);
-    // let rv = x11.XGetSelectionOwner(x11.current.Display, selection_atom);
-    let rv = x11.XGetSelectionOwner(dpy, intern_atom);
-    log.warn(rv);
-    log.warn(rv.value);
-    log.warn(rv.toSource());
-    log.warn(rv.toString());
-    log.warn(x11.None);
-
-    x11.XCloseDisplay(dpy);
+  getDesktop: function() {
+    let env = Cc["@mozilla.org/process/environment;1"].
+      createInstance(Ci.nsIEnvironment);
+    let XDG_CURRENT_DESKTOP = env.get("XDG_CURRENT_DESKTOP").toLowerCase();
+    let DESKTOP_SESSION = env.get("DESKTOP_SESSION").toLowerCase();
+
+    let desktop = {name:'unknown', ver:null};
+    if (XDG_CURRENT_DESKTOP === 'unity' || DESKTOP_SESSION === 'ubuntu') {
+      desktop.name = 'unity';
+    }
+    else if (DESKTOP_SESSION === 'kde-plasma' || XDG_CURRENT_DESKTOP === 'kde') {
+      desktop.name = 'kde-plasma';
+      let plasmaVer = this.processRead('plasma-desktop --version').
+        match(/Plasma Desktop Shell: (\d+)\./);
+      if (plasmaVer) desktop.ver = parseInt(plasmaVer[1], 10);
+    }
+    else if (DESKTOP_SESSION) {
+      desktop = DESKTOP_SESSION;
+    }
+    else if (XDG_CURRENT_DESKTOP) {
+      desktop = XDG_CURRENT_DESKTOP;
+    }
+
+    return desktop;
+  },
+
+  // thx noitidart https://ask.mozilla.org/question/1086
+  processRead: function(cmd) {
+    const BUFSIZE = 1024;
+    let buffer = ctypes.char.array(BUFSIZE)();
+    let size = BUFSIZE;
+    let out = "";
+    let fd = libc.popen(cmd, 'r');
+    while (size == BUFSIZE) {
+      size = libc.fread(buffer, 1, BUFSIZE, fd);
+      out = out + buffer.readString();
+    }
+    libc.pclose(fd);
+    return out;
+  },
 
+  XSystemtrayReady: function() {
+    let screen = gdk.gdk_screen_get_default();
+    let display = gdk.gdk_screen_get_display(screen); // = x11.current.Display
+    let selection_atom_name = "_NET_SYSTEM_TRAY_S" +
+          gdk.gdk_screen_get_number(screen);
+    log.debug("selection_atom_name="+selection_atom_name);
+    let selection_atom = gdk.gdk_x11_get_xatom_by_name_for_display(
+      display, selection_atom_name); // = XInternAtom() + cache
+    log.debug("selection_atom="+selection_atom);
+
+    let xdisplay = gdk.gdk_x11_display_get_xdisplay(display);
+    let rv = x11.XGetSelectionOwner(xdisplay, selection_atom);
+    log.debug(rv.toSource());
     return rv;
   },
 
diff --git a/testing/Makefile b/testing/Makefile
index 8c94a14..e932519 100644
--- a/testing/Makefile
+++ b/testing/Makefile
@@ -1,7 +1,8 @@
 includes_gtk := $(shell pkg-config --libs --cflags gtk+-2.0)
 includes_gdk_gtk := $(shell pkg-config --libs --cflags gdk-2.0 gtk+-2.0)
 executables :=  gtk_icon_example trayicon hide xtypes x11XGetWindowProp \
-	window_state_event xev_desktop teststatusicon gtk-version
+	window_state_event xev_desktop xgetselectionowner teststatusicon \
+	gtk-version
 
 .PHONY: all
 all: $(executables)
@@ -31,6 +32,9 @@ window_state_event: window_state_event.c
 xev_desktop: xev_desktop.c
 	gcc -lXm -lXt -lX11 -o xev_desktop xev_desktop.c
 
+xgetselectionowner: xgetselectionowner.c
+	gcc -lX11 -o xgetselectionowner xgetselectionowner.c
+
 teststatusicon: teststatusicon.c prop-editor.c
 	gcc $(includes_gtk) -o teststatusicon teststatusicon.c prop-editor.c
 
diff --git a/testing/xgetselectionowner.c b/testing/xgetselectionowner.c
new file mode 100644
index 0000000..aa28dd9
--- /dev/null
+++ b/testing/xgetselectionowner.c
@@ -0,0 +1,35 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <unistd.h>
+#include <err.h>
+
+#include <X11/Xlib.h>
+
+int
+main(int argc, char **argv)
+{
+	Display *dpy;
+	Window window;
+	Atom atom;
+
+	if (argc < 2) {
+		fprintf(stderr, "usage: xgetselectionowner <selection_name>\n");
+		exit(1);
+	}
+
+	dpy = XOpenDisplay(NULL);
+	if (dpy == NULL)
+		errx(1, "failed to open X display");
+
+	atom = XInternAtom(dpy, argv[1], False);
+	printf("atom=%i, display=%p\n", atom, (void *) dpy);
+	window = XGetSelectionOwner(dpy, atom);
+
+	printf("window=%p\n", (void *) window);
+
+	XCloseDisplay(dpy);
+
+	return 0;
+}

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-mozext/firetray.git



More information about the Pkg-mozext-commits mailing list