failed attempt to use baseWindow.nativeHandle (bug 760802 and bug760802.patch)

Although we can re-construct a gdk.GdkWindow.ptr from natvieHandle (address of
the actual GdkWindow), we can't seem to be able to use it. For ex.,
gdk_window_get_user_data(), which should return a pointer to the corresponding
GtkWindow, returns strange adresses with our re-constructed pointer (0x11,
0x19, 0x0, ...)

...and despite the fact that both the "original" gdk.GdkWindow.ptr and the
re-constructed one do point to the same address, and that GDK_IS_WINDOW (macro
here wrapped into an embedded lib) is returning true for both pointers...
This commit is contained in:
foudfou 2012-06-13 22:38:18 +02:00
parent e0f60f2981
commit 28f639d3d1
7 changed files with 276 additions and 0 deletions

View File

@ -2,6 +2,9 @@ content firetray chrome/content/
skin firetray classic/1.0 chrome/skin/
locale firetray en-US chrome/locale/en-US/
resource firetray modules/
resource firetray modules/
resource firetray-lib lib/linux/firetray_i686-gcc4.so abi=Linux_x86-gcc3
#resource firetray-lib lib/win32/addon.dll abi=WINNT_x86-msvc
overlay chrome://browser/content/browser.xul chrome://firetray/content/overlay.xul
overlay chrome://messenger/content/messenger.xul chrome://firetray/content/overlay.xul

33
src/lib/linux/Makefile Normal file
View File

@ -0,0 +1,33 @@
deps = gdk-2.0 gdk-pixbuf-2.0 atk
platform = $(shell uname -p)
CC = gcc
GCCVERSION = $(shell gcc -dumpversion | cut -f1 -d.)
CFLAGS += -O3 -fPIC -g -mtune=generic $(shell pkg-config --cflags $(deps))
LDFLAGS += -shared -rdynamic
#-Wl,--version-script -Wl,export-versionscript
#-Wl,-soname,libmystuff.so.1 -o libgnome.so.1.0.1
LIBS += $(shell pkg-config --libs $(deps))
libs = firetray_$(platform)-gcc$(GCCVERSION).so
all: $(libs)
$(libs): firetray.o
$(CC) $(CFLAGS) $(LDFLAGS) $< $(LIBS) -o $@
%.o: %.c
$(CC) $(CFLAGS) -c -o $@ $<
strip: $(libs)
strip $<
clean:
rm -rf $(libs) *.o
cp:
cp $(libs) ../../lib/
install: clean all strip cp
.PHONY: all clean strip cp install

8
src/lib/linux/firetray.c Normal file
View File

@ -0,0 +1,8 @@
/* pkg-config --libs --cflags gtk+-2.0 */
#include <gtk/gtk.h>
#include "firetray.h"
int gdk_is_window(void* obj) {
return GDK_IS_WINDOW(obj) ? 1 : 0;
}

1
src/lib/linux/firetray.h Normal file
View File

@ -0,0 +1 @@
extern int gdk_is_window(void* obj);

View File

@ -288,6 +288,7 @@ function gdk_defines(lib) {
lib.lazy_bind("gdk_drawable_get_size", ctypes.void_t, this.GdkDrawable.ptr, gobject.gint.ptr, gobject.gint.ptr);
// lib.lazy_bind("gdk_window_get_geometry", ctypes.void_t, this.GdkWindow.ptr, gobject.gint.ptr, gobject.gint.ptr, gobject.gint.ptr, gobject.gint.ptr, gobject.gint.ptr);
lib.lazy_bind("gdk_window_move_resize", ctypes.void_t, this.GdkWindow.ptr, gobject.gint, gobject.gint, gobject.gint, gobject.gint);
lib.lazy_bind("gdk_window_get_user_data", ctypes.void_t, this.GdkWindow.ptr, gobject.gpointer.ptr);
lib.lazy_bind("gdk_atom_intern", this.GdkAtom, gobject.gchar.ptr, gobject.gboolean);
lib.lazy_bind("gdk_property_change", ctypes.void_t, this.GdkWindow.ptr, this.GdkAtom, this.GdkAtom, gobject.gint, this.GdkPropMode, gobject.guchar.ptr, gobject.gint);

View File

@ -527,6 +527,83 @@ firetray.Handler.registerWindow = function(win) {
this.windows[xid] = {};
this.windows[xid].chromeWin = win;
this.windows[xid].baseWin = firetray.Handler.getWindowInterface(win, "nsIBaseWindow");
try { // TESTing nativeHandle
Cu.import("resource://firetray/ctypes/libfiretray.jsm");
libfiretray.init();
F.WARN("libfiretray available");
function addrPointedBy(ptr) {
return ctypes.cast(ptr, ctypes.uintptr_t.ptr).contents;
}
F.WARN("TEST gdkWin="+gdkWin+" gdkWin is actually a pointer to a GdkWindow");
F.WARN("TEST *gdkWin=0x"+addrPointedBy(gdkWin).toString(16));
let nativeHandle = this.windows[xid].baseWin.nativeHandle;
if ("undefined" === typeof(nativeHandle)) {
F.WARN("nativeHandle undefined");
} else {
F.WARN("TEST nativeHandle=0x"+nativeHandle.toString(16)+" this is the (address of the) actual GdkWindow !");
// actual check
if (firetray.js.strEquals(nativeHandle, addrPointedBy(gdkWin)))
F.WARN("OK: nativeHandle == *gdkWin");
else
F.WARN("NOT OK: nativeHandle != *gdkWin");
// construct GdkWindow.ptr from nativeHandle
// let gdkwPtr = ctypes.uintptr_t(nativeHandle).address();
// F.WARN(gdkwPtr);
// let gdkw = ctypes.cast(gdkwPtr, gdk.GdkWindow.ptr);
let gdkw = ctypes.cast(ctypes.uintptr_t(nativeHandle).address(), gdk.GdkWindow.ptr);
F.WARN("TEST gdkw="+gdkw+" a new pointer to a GdkWindow");
let isGdkWin = libfiretray.gdk_is_window(ctypes.cast(gdkw, ctypes.void_t.ptr));
F.WARN("gdkw isGdkWin="+isGdkWin);
libfiretray.shutdown();
// re-check
if (firetray.js.strEquals(addrPointedBy(gdkWin), addrPointedBy(gdkw)))
F.WARN("OK: Re-check");
else
F.WARN("NOT OK: Re-check");
F.WARN("gdkWin="+gdkWin+" gdkw="+gdkw+" *gdkWin=0x"+addrPointedBy(gdkWin).toString(16)+" *gdkw=0x"+addrPointedBy(gdkw).toString(16));
// gdk.gdk_window_set_title(gdkw, "FOUDIL WAS HERE");
// getting the GtkWin from GdkWindow user_data
F.WARN("TEST *gtkWin=0x"+addrPointedBy(gtkWin).toString(16)); // reference
let gptr = new gobject.gpointer;
gdk.gdk_window_get_user_data(gdkWin, gptr.address());
F.WARN("TEST gptr-gdkWin="+gptr);
F.WARN("TEST *gptr-gdkWin=0x"+addrPointedBy(gptr).toString(16));
gdk.gdk_window_get_user_data(gdkw, gptr.address());
F.WARN("TEST gptr-gdkw="+gptr);
// F.WARN("TEST *gptr-gdkWin="+addrPointedBy(gptr).toString(16));
// let gtkw = ctypes.cast(gptr, gtk.GtkWidget.ptr);
// F.WARN("TEST gtkw="+gtkw);
// F.WARN("TEST *gtkw="+ctypes.cast(gtkw, ctypes.uintptr_t.ptr).contents.toString(16));
F.WARN("OK");
}
} catch (x) {F.ERROR(x);}
// *** WARN firetray: libfiretray available
// *** WARN firetray: TEST gdkWin=GdkWindow.ptr(ctypes.UInt64("0x9387830")) gdkWin is actually a pointer to a GdkWindow
// *** WARN firetray: TEST *gdkWin=0x9113f00
// *** WARN firetray: TEST nativeHandle=0x9113f00 this is the (address of the) actual GdkWindow !
// *** WARN firetray: OK: nativeHandle == *gdkWin
// *** WARN firetray: TEST gdkw=GdkWindow.ptr(ctypes.UInt64("0x95f73d0")) a new pointer to a GdkWindow
// *** WARN firetray: gdkw isGdkWin=1
// *** WARN firetray: OK: Re-check
// *** WARN firetray: gdkWin=GdkWindow.ptr(ctypes.UInt64("0x9387830")) gdkw=GdkWindow.ptr(ctypes.UInt64("0x95f73d0")) *gdkWin=0x9113f00 *gdkw=0x9113f00
// *** WARN firetray: TEST *gtkWin=0x932b600
// *** WARN firetray: TEST gptr-gdkWin=ctypes.voidptr_t(ctypes.UInt64("0x93878e0"))
// *** WARN firetray: TEST *gptr-gdkWin=0x932b600
// *** WARN firetray: TEST gptr-gdkw=ctypes.voidptr_t(ctypes.UInt64("0x19"))
// *** WARN firetray: OK
try {
this.gtkWindows.insert(xid, gtkWin);
this.gdkWindows.insert(xid, gdkWin);

153
testing/bug760802.patch Normal file
View File

@ -0,0 +1,153 @@
diff --git a/docshell/base/nsDocShell.cpp b/docshell/base/nsDocShell.cpp
--- a/docshell/base/nsDocShell.cpp
+++ b/docshell/base/nsDocShell.cpp
@@ -4860,6 +4860,13 @@
}
NS_IMETHODIMP
+nsDocShell::GetNativeHandle(JSContext *cx, jsval *ret)
+{
+ NS_ASSERTION(false, "Not Yet Implemented: nsDocShell");
+ return NS_ERROR_NOT_IMPLEMENTED;
+}
+
+NS_IMETHODIMP
nsDocShell::GetVisibility(bool * aVisibility)
{
NS_ENSURE_ARG_POINTER(aVisibility);
diff --git a/embedding/browser/webBrowser/nsDocShellTreeOwner.cpp b/embedding/browser/webBrowser/nsDocShellTreeOwner.cpp
--- a/embedding/browser/webBrowser/nsDocShellTreeOwner.cpp
+++ b/embedding/browser/webBrowser/nsDocShellTreeOwner.cpp
@@ -584,6 +584,14 @@
}
NS_IMETHODIMP
+nsDocShellTreeOwner::GetNativeHandle(JSContext *cx, jsval *ret)
+{
+ //XXX First Check In
+ NS_ASSERTION(false, "You can't call this: nsDocShellTreeOwner");
+ return NS_ERROR_NULL_POINTER;
+}
+
+NS_IMETHODIMP
nsDocShellTreeOwner::GetVisibility(bool* aVisibility)
{
nsCOMPtr<nsIEmbeddingSiteWindow> ownerWin = GetOwnerWin();
diff --git a/embedding/browser/webBrowser/nsWebBrowser.cpp b/embedding/browser/webBrowser/nsWebBrowser.cpp
--- a/embedding/browser/webBrowser/nsWebBrowser.cpp
+++ b/embedding/browser/webBrowser/nsWebBrowser.cpp
@@ -7,6 +7,7 @@
#include "nsWebBrowser.h"
// Helper Classes
+#include "nsDOMJSUtils.h" //XXX for jsval
#include "nsGfxCIID.h"
#include "nsWidgetsCID.h"
@@ -1380,6 +1381,13 @@
return NS_OK;
}
+NS_IMETHODIMP nsWebBrowser::GetNativeHandle(JSContext *cx, jsval *ret)
+{
+ //XXX First Check In
+ NS_ASSERTION(false, "Not Yet Implemented");
+ return NS_OK;
+}
+
NS_IMETHODIMP nsWebBrowser::GetVisibility(bool* visibility)
{
NS_ENSURE_ARG_POINTER(visibility);
diff --git a/widget/nsIBaseWindow.idl b/widget/nsIBaseWindow.idl
--- a/widget/nsIBaseWindow.idl
+++ b/widget/nsIBaseWindow.idl
@@ -153,6 +153,14 @@
attribute nativeWindow parentNativeWindow;
/*
+ TODO:
+ https://bugzilla.mozilla.org/show_bug.cgi?id=760802
+ https://groups.google.com/d/msg/mozilla.dev.extensions/JXgOCHSK0ZU/bR5A2ZCZV3sJ
+ */
+ // readonly attribute jsval nativeHandle;
+ [implicit_jscontext] readonly attribute jsval nativeHandle;
+
+ /*
Attribute controls the visibility of the object behind this interface.
Setting this attribute to false will hide the control. Setting it to
true will show it.
diff --git a/xpfe/appshell/src/nsChromeTreeOwner.cpp b/xpfe/appshell/src/nsChromeTreeOwner.cpp
--- a/xpfe/appshell/src/nsChromeTreeOwner.cpp
+++ b/xpfe/appshell/src/nsChromeTreeOwner.cpp
@@ -9,6 +9,7 @@
#include "nsXULWindow.h"
// Helper Classes
+#include "nsDOMJSUtils.h" //XXX for jsval
#include "nsString.h"
#include "nsIEmbeddingSiteWindow.h"
#include "nsIEmbeddingSiteWindow2.h"
@@ -423,6 +424,12 @@
return NS_ERROR_NOT_IMPLEMENTED;
}
+NS_IMETHODIMP nsChromeTreeOwner::GetNativeHandle(JSContext *cx, jsval *ret)
+{
+ NS_ENSURE_STATE(mXULWindow);
+ return mXULWindow->GetNativeHandle(cx, ret);
+}
+
NS_IMETHODIMP nsChromeTreeOwner::GetVisibility(bool* aVisibility)
{
NS_ENSURE_STATE(mXULWindow);
diff --git a/xpfe/appshell/src/nsContentTreeOwner.cpp b/xpfe/appshell/src/nsContentTreeOwner.cpp
--- a/xpfe/appshell/src/nsContentTreeOwner.cpp
+++ b/xpfe/appshell/src/nsContentTreeOwner.cpp
@@ -10,6 +10,7 @@
#include "nsXULWindow.h"
// Helper Classes
+#include "nsDOMJSUtils.h" //XXX for jsval
#include "nsIServiceManager.h"
#include "nsAutoPtr.h"
@@ -637,6 +638,12 @@
return NS_ERROR_NOT_IMPLEMENTED;
}
+NS_IMETHODIMP nsContentTreeOwner::GetNativeHandle(JSContext *cx, jsval *ret)
+{
+ NS_ENSURE_STATE(mXULWindow);
+ return mXULWindow->GetNativeHandle(cx, ret);
+}
+
NS_IMETHODIMP nsContentTreeOwner::GetVisibility(bool* aVisibility)
{
NS_ENSURE_STATE(mXULWindow);
diff --git a/xpfe/appshell/src/nsXULWindow.cpp b/xpfe/appshell/src/nsXULWindow.cpp
--- a/xpfe/appshell/src/nsXULWindow.cpp
+++ b/xpfe/appshell/src/nsXULWindow.cpp
@@ -748,6 +748,23 @@
return NS_OK;
}
+NS_IMETHODIMP nsXULWindow::GetNativeHandle(JSContext *cx, jsval *ret)
+{
+ nsCOMPtr<nsIWidget> mainWidget;
+ NS_ENSURE_SUCCESS(GetMainWidget(getter_AddRefs(mainWidget)), NS_ERROR_FAILURE);
+
+ if (mainWidget) {
+ // this will return the actual address of the native window obj (not a
+ // pointer to it)
+ nativeWindow nativeWindowPtr = mainWidget->GetNativeData(NS_NATIVE_WINDOW);
+ uintptr_t ptr = *static_cast<uintptr_t*>(nativeWindowPtr);
+ if (!JS_NewNumberValue(cx, (double)ptr, ret)) // JSBool
+ return NS_ERROR_UNEXPECTED;
+ }
+
+ return NS_OK;
+}
+
NS_IMETHODIMP nsXULWindow::GetVisibility(bool* aVisibility)
{
NS_ENSURE_ARG_POINTER(aVisibility);