From b3b6d77c5b2c127816d771ce01e3a2bd981d6d77 Mon Sep 17 00:00:00 2001 From: foudfou Date: Sun, 11 Dec 2011 21:44:39 +0100 Subject: [PATCH] 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