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:
parent
a02129828c
commit
ee9a0b6089
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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
30
src/modules/libc.jsm
Normal 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);
|
||||
}
|
Loading…
Reference in New Issue
Block a user