[Pkg-mozext-commits] [firetray] 106/399: another unsuccessful attempt to detect minimize event (failed interpreting XGetWindowProperty result)

David Prévot taffit at alioth.debian.org
Tue Oct 29 18:23:23 UTC 2013


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

taffit pushed a commit to branch dfsg-clean
in repository firetray.

commit b3b6d77c5b2c127816d771ce01e3a2bd981d6d77
Author: foudfou <foudil.newbie+git at gmail.com>
Date:   Sun Dec 11 21:44:39 2011 +0100

    another unsuccessful attempt to detect minimize event (failed interpreting
    XGetWindowProperty result)
---
 src/modules/FiretrayIconLinux.jsm |   87 +++++++++++++++++++------------------
 src/modules/commons.js            |   10 ++++-
 src/modules/x11.jsm               |   85 ++++++++++++++++++++++++------------
 3 files changed, 110 insertions(+), 72 deletions(-)

diff --git a/src/modules/FiretrayIconLinux.jsm b/src/modules/FiretrayIconLinux.jsm
index e73285d..d23576d 100644
--- a/src/modules/FiretrayIconLinux.jsm
+++ b/src/modules/FiretrayIconLinux.jsm
@@ -88,6 +88,8 @@ firetray.IconLinux = {
     try {
       let that = this;
       let filterData = gdkWin;
+      /* NOTE: We may have to do this with Gdk:
+         http://stackoverflow.com/questions/8018328/what-is-the-gtk-event-called-when-a-window-minimizes */
       firetray_filterWindowCb = gdk.GdkFilterFunc_t(that.filterWindow);
       gdk.gdk_window_add_filter(gdkWin, firetray_filterWindowCb, filterData);
     } catch(x) {
@@ -248,38 +250,21 @@ firetray.IconLinux = {
     return null;
   },
 
+  /**
+   * init X11 Display and handled XATOMS
+   */
   _initX11: function() {
     if (!isEmpty(this.X11))
       return true; // init only once
 
-    this.X11.MAX_NET_WM_STATES = 12;
     try {
       let gdkDisplay = gdk.gdk_display_get_default();
       this.X11.Display = gdk.gdk_x11_display_get_xdisplay(gdkDisplay);
       this.X11.Atoms = {};
-      let atoms = {
-        WM_DELETE_WINDOW: "WM_DELETE_WINDOW",
-        WM_STATE: "WM_STATE",
-        _NET_CLOSE_WINDOW: "_NET_CLOSE_WINDOW",
-        // don't forget to update firetray.IconLinux.X11.MAX_NET_WM_STATES
-        _NET_WM_STATE: "_NET_WM_STATE",
-        _NET_WM_STATE_MODAL: "_NET_WM_STATE_MODAL",
-        _NET_WM_STATE_STICKY: "_NET_WM_STATE_STICKY",
-        _NET_WM_STATE_MAXIMIZED_VERT: "_NET_WM_STATE_MAXIMIZED_VERT",
-        _NET_WM_STATE_MAXIMIZED_HORZ: "_NET_WM_STATE_MAXIMIZED_HORZ",
-        _NET_WM_STATE_SHADED: "_NET_WM_STATE_SHADED",
-        _NET_WM_STATE_SKIP_TASKBAR: "_NET_WM_STATE_SKIP_TASKBAR",
-        _NET_WM_STATE_SKIP_PAGER: "_NET_WM_STATE_SKIP_PAGER",
-        _NET_WM_STATE_HIDDEN: "_NET_WM_STATE_HIDDEN",
-        _NET_WM_STATE_FULLSCREEN: "_NET_WM_STATE_FULLSCREEN",
-        _NET_WM_STATE_ABOVE: "_NET_WM_STATE_ABOVE",
-        _NET_WM_STATE_BELOW: "_NET_WM_STATE_BELOW",
-        _NET_WM_STATE_DEMANDS_ATTENTION: "_NET_WM_STATE_DEMANDS_ATTENTION"
-      };
-      for (let atomName in atoms) {
-        this.X11.Atoms[atomName] = x11.XInternAtom(this.X11.Display, atoms[atomName], 0);
+      XATOMS.forEach(function(atomName, index, array) {
+        this.X11.Atoms[atomName] = x11.XInternAtom(this.X11.Display, atomName, 0);
         LOG("X11.Atoms."+atomName+"="+this.X11.Atoms[atomName]);
-      }
+      }, this);
       return true;
     } catch (x) {
       ERROR(x);
@@ -291,13 +276,21 @@ firetray.IconLinux = {
     if (!xev)
       return gdk.GDK_FILTER_CONTINUE;
 
-    let gdkWin = ctypes.cast(data, gdk.GdkWindow.ptr);
+    // let gdkWin = ctypes.cast(data, gdk.GdkWindow.ptr);
 
     try {
       let xany = ctypes.cast(xev, x11.XAnyEvent.ptr);
       let xwin = xany.contents.window;
 
       switch (xany.contents.type) {
+
+      // case x11.PropertyNotify:
+      //   let xproperty = ctypes.cast(xev, x11.XPropertyEvent.ptr);
+      //   let atom = xproperty.contents.atom;
+      //   if (strEquals(atom, firetray.IconLinux.X11.Atoms._NET_WM_STATE))
+      //     LOG("PropertyNotify atom="+atom);
+      //   break;
+
       case x11.MapNotify:
         LOG("MapNotify");
         break;
@@ -308,43 +301,52 @@ firetray.IconLinux = {
         let prop = firetray.IconLinux.X11.Atoms._NET_WM_STATE;
         LOG("prop="+prop);
 
-/*
+        /* we may need to provide a fixed array size for csting later with ctypes */
+        const MAX_SIZE = XATOMS_EWMH_WM_STATES.length;
+        let ulongArray_t = ctypes.unsigned_long.array(MAX_SIZE);
+
         // infos returned by XGetWindowProperty()
-        let actual_type = new ctypes.unsigned_long; // FIXME: let actual_type = new x11.Atom;
+        let actual_type = new x11.Atom;
         let actual_format = new ctypes.int;
         let nitems = new ctypes.unsigned_long;
         let bytes_after = new ctypes.unsigned_long;
-        let prop_value = new ctypes.unsigned_char.ptr;
+        // let prop_value = new ctypes.unsigned_char.ptr;
+        let prop_value = new ulongArray_t;
 
-        let res = x11.XGetWindowProperty(
-          firetray.IconLinux.X11.Display, xwin, prop, 0, firetray.IconLinux.X11.MAX_NET_WM_STATES, 0, x11.AnyPropertyType,
+        // look for _NET_WM_STATE_HIDDEN (408)
+        let res = x11.XGetWindowProperty( // FIXME: needs to be XFree'd
+          firetray.IconLinux.X11.Display, xwin, prop, 0, MAX_SIZE*ctypes.unsigned_long.size, 0, x11.AnyPropertyType,
           actual_type.address(), actual_format.address(), nitems.address(), bytes_after.address(), prop_value.address());
         LOG("XGetWindowProperty res="+res+", actual_type="+actual_type.value+", actual_format="+actual_format.value+", bytes_after="+bytes_after.value+", nitems="+nitems.value);
 
-        if (res.toString() !== x11.Success.toString()) {
+        if (!strEquals(res, x11.Success)) {
           ERROR("XGetWindowProperty failed");
           break;
         }
-        if (actual_type.value.toString() === x11.None.toString()) {
+        if (strEquals(actual_type.value, x11.None)) {
           WARN("property does not exist");
           break;
         }
 
-        LOG("prop_value="+prop_value);
+        LOG("prop_value="+prop_value+", size="+prop_value.constructor.size);
         // LOG("prop_value.str="+prop_value.readString());
-        // LOG("prop_value.size="+prop_value.size);
-        LOG("size="+ctypes.uint32_t.array(nitems.value).size);
-        let props;
-        // if (actual_format == 32)
-        //   props = ctypes.cast(prop_value, ctypes.uint32_t.array(nitems.value));
-        // LOG("props="+props);
+        /* If the returned format is 32, the property data will be stored as an
+         array of longs (which in a 64-bit application will be 64-bit values
+         that are padded in the upper 4 bytes). */
+        if (actual_format.value == 32) {
+          // var props = ctypes.cast(prop_value, ctypes.unsigned_char.array(nitems.value*2));
+          var props = ctypes.cast(prop_value, ctypes.unsigned_long.array(nitems.value));
+        } else
+          ERROR("unsupported format: "+actual_format.value);
+        LOG("props="+props+", size="+props.size);
+        LOG("props.length="+props.length);
+
         // for (let i=0; i<nitems.value; ++i) {
         //   // LOG(props[i]);
         //   // let p = props[i];
         //   // let p_ulong = ctypes.cast(p, ctypes.unsigned_long);
         //   // LOG(p_ulong);
         // }
-*/
 
         break;
 
@@ -352,12 +354,13 @@ firetray.IconLinux = {
         LOG("ClientMessage");
         let xclient = ctypes.cast(xev, x11.XClientMessageEvent.ptr);
         LOG("xclient.contents.data="+xclient.contents.data);
-        // NOTE: need toString() for comparison !
-        if (xclient.contents.data[0].toString() ===
-            firetray.IconLinux.X11.Atoms.WM_DELETE_WINDOW.toString()) {
+        if (strEquals(xclient.contents.data[0], firetray.IconLinux.X11.Atoms.WM_DELETE_WINDOW)) {
           LOG("Delete Window prevented");
           return gdk.GDK_FILTER_REMOVE;
         }
+        LOG("xclient.contents.send_event="+xclient.contents.send_event);
+        if (strEquals(xclient.contents.send_event, firetray.IconLinux.X11.Atoms.WM_CHANGE_STATE))
+          LOG("FOUDIL");
         break;
 
       default:
diff --git a/src/modules/commons.js b/src/modules/commons.js
index 60bb8d6..27a8ae8 100644
--- a/src/modules/commons.js
+++ b/src/modules/commons.js
@@ -1,8 +1,8 @@
 /* -*- Mode: js2; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 
 var EXPORTED_SYMBOLS =
-  [ "firetray", "LOG", "WARN", "ERROR", "FIREFOX_ID",
-    "THUNDERBIRD_ID", "SEAMONKEY_ID", "isArray", "isEmpty",
+  [ "firetray", "LOG", "WARN", "ERROR", "FIREFOX_ID", "THUNDERBIRD_ID",
+    "SEAMONKEY_ID", "isArray", "isEmpty", "strEquals",
     "FT_NOTIFICATION_DISABLED", "FT_NOTIFICATION_UNREAD_MESSAGE_COUNT",
     "FT_NOTIFICATION_NEWMAIL_ICON", "FT_NOTIFICATION_CUSTOM_ICON" ];
 
@@ -198,3 +198,9 @@ function isEmpty(obj) {
   }
   return true;
 }
+
+// values of different ctypes objects can never be compared. See:
+// https://developer.mozilla.org/en/js-ctypes/Using_js-ctypes/Working_with_data#Quirks_in_equality
+function strEquals(obj1, obj2) {
+  return obj1.toString() === obj2.toString();
+}
diff --git a/src/modules/x11.jsm b/src/modules/x11.jsm
index 9011cee..0091f04 100644
--- a/src/modules/x11.jsm
+++ b/src/modules/x11.jsm
@@ -1,6 +1,7 @@
 /* -*- Mode: javascript; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 
-var EXPORTED_SYMBOLS = [ "x11" ];
+var EXPORTED_SYMBOLS = [ "x11",
+  "XATOMS", "XATOMS_ICCCM", "XATOMS_EWMH_GENERAL", "XATOMS_EWMH_WM_STATES" ];
 
 const X11_LIBNAME = "X11";
 const X11_ABIS    = [ 6 ];
@@ -13,7 +14,41 @@ Cu.import("resource://gre/modules/Services.jsm");
 Cu.import("resource://gre/modules/ctypes.jsm");
 Cu.import("resource://firetray/ctypes-utils.jsm");
 
+
+const XATOMS_ICCCM = [ "WM_DELETE_WINDOW", "WM_STATE", "WM_CHANGE_STATE" ];
+const XATOMS_EWMH_GENERAL = [ "_NET_CLOSE_WINDOW", "_NET_WM_STATE",
+  "_NET_WM_NAME", "_NET_WM_VISIBLE_NAME", "_NET_WM_ICON_NAME",
+  "_NET_WM_VISIBLE_ICON_NAME", "_NET_WM_DESKTOP", "_NET_WM_WINDOW_TYPE",
+  "_NET_WM_STATE", "_NET_WM_ALLOWED_ACTIONS", "_NET_WM_STRUT",
+  "_NET_WM_STRUT_PARTIAL", "_NET_WM_ICON_GEOMETRY", "_NET_WM_ICON",
+  "_NET_WM_PID", "_NET_WM_HANDLED_ICONS", "_NET_WM_USER_TIME",
+  "_NET_FRAME_EXTENTS"
+];
+const XATOMS_EWMH_WM_STATES =  [
+  "_NET_WM_STATE_MODAL", "_NET_WM_STATE_STICKY",
+  "_NET_WM_STATE_MAXIMIZED_VERT", "_NET_WM_STATE_MAXIMIZED_HORZ",
+  "_NET_WM_STATE_SHADED", "_NET_WM_STATE_SKIP_TASKBAR",
+  "_NET_WM_STATE_SKIP_PAGER", "_NET_WM_STATE_HIDDEN",
+  "_NET_WM_STATE_FULLSCREEN", "_NET_WM_STATE_ABOVE", "_NET_WM_STATE_BELOW",
+  "_NET_WM_STATE_DEMANDS_ATTENTION"
+];
+const XATOMS = XATOMS_ICCCM.concat(XATOMS_EWMH_WM_STATES).concat(XATOMS_EWMH_GENERAL);
+
 function x11_defines(lib) {
+  /* fundamental types need to be guessed :-( */
+  // http://mxr.mozilla.org/mozilla-central/source/configure.in
+  if (/^(Alpha|hppa|ia64|ppc64|s390|x86_64)-/.test(Services.appinfo.XPCOMABI)) {
+    this.CARD32 = ctypes.unsigned_int;
+    this.Atom = ctypes.unsigned_long;
+    this.Window = ctypes.unsigned_long;
+    this.Time = ctypes.unsigned_long;
+  } else {
+    this.CARD32 = ctypes.unsigned_long;
+    this.Atom = this.CARD32;
+    this.Window = this.CARD32;
+    this.Time =  this.CARD32;
+  }
+
   // X.h
   this.Success = 0;
   this.None = 0;
@@ -23,9 +58,12 @@ function x11_defines(lib) {
   this.BadAtom = 5;
   this.BadMatch = 8;
   this.BadAlloc = 11;
+  this.PropertyNewValue = 0;
+  this.PropertyDelete = 1;
   // Event names
   this.UnmapNotify = 18;
   this.MapNotify = 19;
+  this.PropertyNotify = 28;
   this.ClientMessage = 33;
   // Xutils.h: definitions for initial window state
   this.WithdrawnState = 0;      /* for windows that are not mapped */
@@ -45,46 +83,37 @@ function x11_defines(lib) {
     { "serial": ctypes.unsigned_long },
     { "send_event": this.Bool },
     { "display": this.Display.ptr },
-    { "window": x11.Window }
+    { "window": this.Window }
   ]);
   this.XClientMessageEvent = ctypes.StructType("XClientMessageEvent", [
     { "type": ctypes.int },
     { "serial": ctypes.unsigned_long },
     { "send_event": this.Bool },
     { "display": this.Display.ptr },
-    { "window": x11.Window },
-    { "message_type": x11.Atom },
+    { "window": this.Window },
+    { "message_type": this.Atom },
     { "format": ctypes.int },
     { "data": ctypes.long.array(5) } // actually a union char b[20]; short s[10]; long l[5];
   ]);
+  this.XPropertyEvent = ctypes.StructType("XPropertyEvent", [
+    { "type": ctypes.int },
+    { "serial": ctypes.unsigned_long },
+    { "send_event": this.Bool },
+    { "display": this.Display.ptr },
+    { "window": this.Window },
+    { "atom": this.Atom },
+    { "time": this.Time },
+    { "state": ctypes.int }     /* NewValue or Deleted */
+  ]);
 
-  lib.lazy_bind("XInternAtom", x11.Atom, this.Display.ptr, ctypes.char.ptr, this.Bool); // only_if_exsits
-  lib.lazy_bind("XGetWindowProperty", ctypes.int, this.Display.ptr, x11.Window, x11.Atom, ctypes.long, ctypes.long, this.Bool, x11.Atom, x11.Atom.ptr, ctypes.int.ptr, ctypes.unsigned_long.ptr, ctypes.unsigned_long.ptr, ctypes.unsigned_char.ptr.ptr);
-  lib.lazy_bind("XChangeProperty", ctypes.int, this.Display.ptr, x11.Window, x11.Atom, x11.Atom, ctypes.int, ctypes.int, ctypes.unsigned_char.ptr, ctypes.int);
+  lib.lazy_bind("XFree", ctypes.int, ctypes.void_t.ptr);
+  lib.lazy_bind("XInternAtom", this.Atom, this.Display.ptr, ctypes.char.ptr, this.Bool); // only_if_exsits
+  lib.lazy_bind("XGetWindowProperty", ctypes.int, this.Display.ptr, this.Window, this.Atom, ctypes.long, ctypes.long, this.Bool, this.Atom, this.Atom.ptr, ctypes.int.ptr, ctypes.unsigned_long.ptr, ctypes.unsigned_long.ptr, ctypes.unsigned_long.array(XATOMS_EWMH_WM_STATES.length).ptr);
+  lib.lazy_bind("XChangeProperty", ctypes.int, this.Display.ptr, this.Window, this.Atom, this.Atom, ctypes.int, ctypes.int, ctypes.unsigned_char.ptr, ctypes.int);
 }
 
 if (!x11) {
-  var x11 = {};
-
-  guessX11TypeSizes();
-  x11 = new ctypes_library(X11_LIBNAME, X11_ABIS, x11_defines);
-}
-
-function guessX11TypeSizes() {
-  try {
-    // http://mxr.mozilla.org/mozilla-central/source/configure.in
-    if (/^(Alpha|hppa|ia64|ppc64|s390|x86_64)-/.test(Services.appinfo.XPCOMABI)) {
-      x11.CARD32 = ctypes.unsigned_int;
-      x11.Atom = ctypes.unsigned_long;
-      x11.Window = ctypes.unsigned_long;
-    } else {
-      x11.CARD32 = ctypes.unsigned_long;
-      x11.Atom = x11.CARD32;
-      x11.Window = x11.CARD32;
-    }
-  } catch(x) {
-    ERROR(x);
-  }
+  var x11 = new ctypes_library(X11_LIBNAME, X11_ABIS, x11_defines);
 }
 
 /* Xorg 1.10.4

-- 
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