1
0
mirror of https://github.com/moparisthebest/FireTray synced 2024-11-10 19:15:08 -05:00

first attempt to get a window handle (GdkWindow*) from a nsIDOMWindow.

Elegant solution lifted from Nils Maier (MiniTrayR).
We need now to work on GdkWindows (instead of GtkWindows) to be able to
gdk_window_add_filter().
This commit is contained in:
foudfou 2011-09-20 17:44:12 +02:00
parent a02129828c
commit ee9a0b6089
4 changed files with 131 additions and 1 deletions

View File

@ -7,14 +7,24 @@ const Ci = Components.interfaces;
const Cu = Components.utils;
Cu.import("resource://gre/modules/Services.jsm");
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
Cu.import("resource://gre/modules/ctypes.jsm");
Cu.import("resource://moztray/cairo.jsm");
Cu.import("resource://moztray/gobject.jsm");
Cu.import("resource://moztray/gdk.jsm");
Cu.import("resource://moztray/gtk.jsm");
Cu.import("resource://moztray/libc.jsm");
Cu.import("resource://moztray/pango.jsm");
Cu.import("resource://moztray/commons.js");
const Services2 = {};
XPCOMUtils.defineLazyServiceGetter(
Services2,
"uuid",
"@mozilla.org/uuid-generator;1",
"nsIUUIDGenerator"
);
if ("undefined" == typeof(mozt.Handler))
ERROR("MoztIcon*.jsm MUST be imported from/after MoztHandler !");
@ -23,6 +33,16 @@ if ("undefined" == typeof(mozt.Handler))
var mozt_iconActivateCb;
var mozt_popupMenuCb;
var mozt_menuItemQuitActivateCb;
var mozt_findGtkWindowByTitleCb;
/**
* custum type used to pass data in to and out of mozt_findGtkWindowByTitleCb
*/
var _find_data_t = ctypes.StructType("_find_data_t", [
{ inTitle: ctypes.char.ptr },
{ outWindow: ctypes.void_t.ptr }
]);
mozt.IconLinux = {
tryIcon: null,
@ -66,6 +86,11 @@ mozt.IconLinux = {
return false;
}
// // TEST
// let win = Services.wm.getMostRecentWindow(null);
// let gtkWin = ctypes.cast(this._getGtkWindowHandle(win), gtk.GtkWindow.ptr);
// gtk.gtk_window_set_decorated(gtkWin, false);
return true;
},
@ -271,6 +296,78 @@ mozt.IconLinux = {
return false;
}
return true;
},
/**
* Iterate over all Gtk toplevel windows to find a window. We rely on
* Service.wm to watch windows correctly: we should find only one window.
*
* @author Nils Maier (stolen from MiniTrayR)
* @param window nsIDOMWindow from Services.wm
* @return a ctypes.void_t.ptr to a GtkWindow
*/
_getGtkWindowHandle: function(window) {
let baseWindow = window
.QueryInterface(Ci.nsIInterfaceRequestor)
.getInterface(Ci.nsIWebNavigation)
.QueryInterface(Ci.nsIBaseWindow);
// Tag the base window
let oldTitle = baseWindow.title;
baseWindow.title = Services2.uuid.generateUUID().toString();
try {
// Search the window by the *temporary* title
let tl = gtk.gtk_window_list_toplevels();
let that = this;
mozt_findGtkWindowByTitleCb = gobject.GFunc_t(that._findGtkWindowByTitle);
var userData = new _find_data_t(
ctypes.char.array()(baseWindow.title),
null
).address();
LOG("userData="+userData);
gobject.g_list_foreach(tl, mozt_findGtkWindowByTitleCb, userData);
gobject.g_list_free(tl);
if (userData.contents.outWindow.isNull()) {
throw new Error("Window not found!");
}
LOG("found window: "+userData.contents.outWindow);
} catch (x) {
ERROR(x);
} finally {
// Restore
baseWindow.title = oldTitle;
}
return userData.contents.outWindow;
},
/**
* compares a GtkWindow's title with a string passed in userData
* @param gtkWidget: GtkWidget from gtk_window_list_toplevels()
* @param userData: _find_data_t
*/
_findGtkWindowByTitle: function(gtkWidget, userData) {
LOG("GTK Window: "+gtkWidget+", "+userData);
let data = ctypes.cast(userData, _find_data_t.ptr);
let inTitle = data.contents.inTitle;
LOG("inTitle="+inTitle.readString());
let gtkWin = ctypes.cast(gtkWidget, gtk.GtkWindow.ptr);
let winTitle = gtk.gtk_window_get_title(gtkWin);
try {
if (!winTitle.isNull()) {
LOG(inTitle+" = "+winTitle);
if (libc.strcmp(inTitle, winTitle) == 0)
data.contents.outWindow = gtkWin;
}
} catch (x) {
ERROR(x);
}
}
}; // mozt.IconLinux

View File

@ -57,7 +57,7 @@ function gobject_defines(lib) {
this.guint32 = ctypes.uint32_t;
this.guint16 = ctypes.uint16_t;
this.gint = ctypes.int;
this.gchar = ctypes.unsigned_char;
this.gchar = ctypes.char;
this.guchar = ctypes.unsigned_char;
this.gboolean = this.gint;
this.gfloat = ctypes.float;

View File

@ -85,7 +85,10 @@ function gtk_defines(lib) {
lib.lazy_bind("gtk_widget_create_pango_layout", pango.PangoLayout.ptr, this.GtkWidget.ptr, gobject.gchar.ptr);
lib.lazy_bind("gtk_widget_destroy", ctypes.void_t, this.GtkWidget.ptr);
lib.lazy_bind("gtk_status_icon_set_from_pixbuf", ctypes.void_t, this.GtkStatusIcon.ptr, gdk.GdkPixbuf.ptr);
lib.lazy_bind("gtk_window_list_toplevels", gobject.GList.ptr);
lib.lazy_bind("gtk_window_get_title", gobject.gchar.ptr, this.GtkWindow.ptr);
lib.lazy_bind("gtk_window_set_decorated", ctypes.void_t, this.GtkWindow.ptr, gobject.gboolean);
}
if (!gtk) {

30
src/modules/libc.jsm Normal file
View File

@ -0,0 +1,30 @@
/* -*- Mode: javascript; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
var EXPORTED_SYMBOLS = [ "libc" ];
const LIBC_LIBNAME = "c";
const LIBC_ABIS = [ 6 ];
const Cu = Components.utils;
const Cc = Components.classes;
const Ci = Components.interfaces;
Cu.import("resource://gre/modules/ctypes.jsm");
Cu.import("resource://moztray/ctypes-utils.jsm");
function libc_defines(lib) {
this.FILE = ctypes.StructType("FILE");
// this.stderr = this.fdopen(2, "a");
this.pid_t = ctypes.int;
lib.lazy_bind("fdopen", this.FILE.ptr, ctypes.int, ctypes.char.ptr);
lib.lazy_bind("puts", ctypes.int32_t, ctypes.char.ptr);
lib.lazy_bind("fputs", ctypes.int32_t, ctypes.char.ptr, this.FILE.ptr);
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);
};
if (!libc) {
var libc = new ctypes_library(LIBC_LIBNAME, LIBC_ABIS, libc_defines);
}