From ee1eac01b322d5eea36821a4103240f618716588 Mon Sep 17 00:00:00 2001 From: foudfou Date: Wed, 5 Sep 2012 13:45:02 +0200 Subject: [PATCH 1/2] fix wrong xid provision ("missing UnmapNotify") --- src/modules/ctypes/linux/gdk.jsm | 5 +++ src/modules/ctypes/linux/x11.jsm | 1 + src/modules/linux/FiretrayWindow.jsm | 56 ++++++++++++++++++++++++---- 3 files changed, 54 insertions(+), 8 deletions(-) diff --git a/src/modules/ctypes/linux/gdk.jsm b/src/modules/ctypes/linux/gdk.jsm index 13f31bc..073df19 100644 --- a/src/modules/ctypes/linux/gdk.jsm +++ b/src/modules/ctypes/linux/gdk.jsm @@ -248,6 +248,10 @@ function gdk_defines(lib) { ctypes.default_abi, this.GdkFilterReturn, [this.GdkXEvent.ptr, this.GdkEvent.ptr, gobject.gpointer]).ptr; + lib.lazy_bind("gdk_flush", ctypes.void_t); + lib.lazy_bind("gdk_error_trap_push", ctypes.void_t); + lib.lazy_bind("gdk_error_trap_pop", gobject.gint); + lib.lazy_bind("gdk_x11_drawable_get_xid", x11.XID, this.GdkDrawable.ptr); lib.lazy_bind("gdk_window_new", this.GdkWindow.ptr, this.GdkWindow.ptr, this.GdkWindowAttributes.ptr, gobject.gint); lib.lazy_bind("gdk_window_destroy", ctypes.void_t, this.GdkWindow.ptr); @@ -298,6 +302,7 @@ function gdk_defines(lib) { 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); + lib.lazy_bind("gdk_window_get_effective_toplevel", this.GdkWindow.ptr, this.GdkWindow.ptr); lib.lazy_bind("gdk_display_get_n_screens", gobject.gint, this.GdkDisplay.ptr); lib.lazy_bind("gdk_display_get_screen", this.GdkScreen.ptr, this.GdkDisplay.ptr, gobject.gint); diff --git a/src/modules/ctypes/linux/x11.jsm b/src/modules/ctypes/linux/x11.jsm index 6033e47..ab25c99 100644 --- a/src/modules/ctypes/linux/x11.jsm +++ b/src/modules/ctypes/linux/x11.jsm @@ -120,6 +120,7 @@ function x11_defines(lib) { this.StructureNotifyMask = 1<<17 this.SubstructureNotifyMask = 1<<19; this.SubstructureRedirectMask = 1<<20; + this.FocusChangeMask = 1<<21 this.PropertyChangeMask = 1<<22 this.Bool = ctypes.int; diff --git a/src/modules/linux/FiretrayWindow.jsm b/src/modules/linux/FiretrayWindow.jsm index 1f3163f..dfdec1c 100644 --- a/src/modules/linux/FiretrayWindow.jsm +++ b/src/modules/linux/FiretrayWindow.jsm @@ -162,6 +162,7 @@ firetray.Window = { getGdkWindowFromNativeHandle: function(nativeHandle) { let gdkw = new gdk.GdkWindow.ptr(ctypes.UInt64(nativeHandle)); // a new pointer to the GdkWindow + gdkw = gdk.gdk_window_get_effective_toplevel(gdkw); log.debug("gdkw="+gdkw+" *gdkw="+this.addrPointedByInHex(gdkw)); return gdkw; }, @@ -171,9 +172,6 @@ firetray.Window = { gdk.gdk_window_get_user_data(gdkWin, gptr.address()); log.debug("gptr="+gptr+" *gptr="+this.addrPointedByInHex(gptr)); let gtkw = ctypes.cast(gptr, gtk.GtkWindow.ptr); - let gtkw_voidp = ctypes.cast(gtkw, ctypes.void_t.ptr); - let gtkwid_top = gtk.gtk_widget_get_toplevel(ctypes.cast(gtkw, gtk.GtkWidget.ptr)); - gtkw = ctypes.cast(gtkwid_top, gtk.GtkWindow.ptr); log.debug("gtkw="+gtkw+" *gtkw="+this.addrPointedByInHex(gtkw)); return gtkw; }, @@ -494,17 +492,24 @@ firetray.Window = { return null; }, - checkSubscribedEventMasks: function(xid) { + checkSubscribedEventMasks: function(xid, gdkWin) { let xWindowAttributes = new x11.XWindowAttributes; let status = x11.XGetWindowAttributes(x11.current.Display, xid, xWindowAttributes.address()); log.debug("xWindowAttributes: "+xWindowAttributes); let xEventMask = xWindowAttributes.your_event_mask; - let xEventMaskNeeded = x11.VisibilityChangeMask|x11.StructureNotifyMask|x11.PropertyChangeMask; + let xEventMaskNeeded = x11.VisibilityChangeMask|x11.StructureNotifyMask| + x11.FocusChangeMask|x11.PropertyChangeMask; log.debug("xEventMask="+xEventMask+" xEventMaskNeeded="+xEventMaskNeeded); if ((xEventMask & xEventMaskNeeded) !== xEventMaskNeeded) { - log.warn("missing mandatory event-masks"); - // could try to subscribe here with XChangeWindowAttributes() + log.error("missing mandatory event-masks"); // change with gdk_window_set_events() } + + // TEST + let gdkEventMask = gdk.gdk_window_get_events(gdkWin); + log.info("gdkEventMask="+gdkEventMask); + gdk.gdk_window_set_events(gdkWin, 64514); + gdkEventMask = gdk.gdk_window_get_events(gdkWin); + log.info("gdkEventMask="+gdkEventMask); }, filterWindow: function(xev, gdkEv, data) { @@ -517,6 +522,7 @@ firetray.Window = { switch (xany.contents.type) { case x11.UnmapNotify: + log.info("UnmapNotify"); let gdkWinState = gdk.gdk_window_get_state(firetray.Handler.gdkWindows.get(xwin)); log.debug("gdkWinState="+gdkWinState+" for xid="+xwin); // NOTE: Gecko 8.0 provides the 'sizemodechange' event @@ -539,7 +545,37 @@ firetray.Window = { } return gdk.GDK_FILTER_CONTINUE; + }, + + // TEST + onUnmap: function(widget, event, data) { + log.debug("onUnmap"); + let gdkWin = ctypes.cast(data, gdk.GdkWindow.ptr); + let xid = firetray.Window.getXIDFromGdkWindow(gdkWin); + log.info("gdkWin="+gdkWin+" xid="+xid); + +try { + + let gdkWinState = gdk.gdk_window_get_state(gdkWin); + log.debug("gdkWinState="+gdkWinState); + // NOTE: Gecko 8.0 provides the 'sizemodechange' event + if (gdkWinState === gdk.GDK_WINDOW_STATE_ICONIFIED) { + log.debug("GOT ICONIFIED"); + let hides_on_minimize = firetray.Utils.prefService.getBoolPref('hides_on_minimize'); + let hides_single_window = firetray.Utils.prefService.getBoolPref('hides_single_window'); + if (hides_on_minimize) { + if (hides_single_window) + firetray.Handler.hideWindow(xid); + else + firetray.Handler.hideAllWindows(); + } + } + +} catch(error) {log.error(error);} + + return false; // do propagate } + }; // firetray.Window @@ -561,7 +597,7 @@ firetray.Handler.registerWindow = function(win) { this.windows[xid] = {}; this.windows[xid].chromeWin = win; this.windows[xid].baseWin = baseWin; - firetray.Window.checkSubscribedEventMasks(xid); + firetray.Window.checkSubscribedEventMasks(xid, gdkWin); try { this.gtkWindows.insert(xid, gtkWin); this.gdkWindows.insert(xid, gdkWin); @@ -588,6 +624,10 @@ firetray.Handler.registerWindow = function(win) { this.windows[xid].filterWindowCb = gdk.GdkFilterFunc_t(firetray.Window.filterWindow); gdk.gdk_window_add_filter(gdkWin, this.windows[xid].filterWindowCb, null); + // // TEST + // this.windows[xid].unmapEventCb = gtk.GCallbackWidgetFocuEvent_t(firetray.Window.onUnmap); + // gobject.g_signal_connect(gtkWin, "unmap-event", this.windows[xid].unmapEventCb, gdkWin); + if (firetray.Handler.appHasChat && firetray.Chat.initialized) { // missing import ok Cu.import("resource://firetray/linux/FiretrayChatStatusIcon.jsm"); firetray.ChatStatusIcon.attachOnFocusInCallback(xid); From c7562bdcdf0cf5be5e596f042528e94ea299ba2c Mon Sep 17 00:00:00 2001 From: foudfou Date: Wed, 5 Sep 2012 13:48:27 +0200 Subject: [PATCH 2/2] cleaning --- src/modules/linux/FiretrayWindow.jsm | 45 ++-------------------------- 1 file changed, 2 insertions(+), 43 deletions(-) diff --git a/src/modules/linux/FiretrayWindow.jsm b/src/modules/linux/FiretrayWindow.jsm index dfdec1c..a3952e7 100644 --- a/src/modules/linux/FiretrayWindow.jsm +++ b/src/modules/linux/FiretrayWindow.jsm @@ -492,7 +492,7 @@ firetray.Window = { return null; }, - checkSubscribedEventMasks: function(xid, gdkWin) { + checkSubscribedEventMasks: function(xid) { let xWindowAttributes = new x11.XWindowAttributes; let status = x11.XGetWindowAttributes(x11.current.Display, xid, xWindowAttributes.address()); log.debug("xWindowAttributes: "+xWindowAttributes); @@ -503,13 +503,6 @@ firetray.Window = { if ((xEventMask & xEventMaskNeeded) !== xEventMaskNeeded) { log.error("missing mandatory event-masks"); // change with gdk_window_set_events() } - - // TEST - let gdkEventMask = gdk.gdk_window_get_events(gdkWin); - log.info("gdkEventMask="+gdkEventMask); - gdk.gdk_window_set_events(gdkWin, 64514); - gdkEventMask = gdk.gdk_window_get_events(gdkWin); - log.info("gdkEventMask="+gdkEventMask); }, filterWindow: function(xev, gdkEv, data) { @@ -522,7 +515,6 @@ firetray.Window = { switch (xany.contents.type) { case x11.UnmapNotify: - log.info("UnmapNotify"); let gdkWinState = gdk.gdk_window_get_state(firetray.Handler.gdkWindows.get(xwin)); log.debug("gdkWinState="+gdkWinState+" for xid="+xwin); // NOTE: Gecko 8.0 provides the 'sizemodechange' event @@ -545,35 +537,6 @@ firetray.Window = { } return gdk.GDK_FILTER_CONTINUE; - }, - - // TEST - onUnmap: function(widget, event, data) { - log.debug("onUnmap"); - let gdkWin = ctypes.cast(data, gdk.GdkWindow.ptr); - let xid = firetray.Window.getXIDFromGdkWindow(gdkWin); - log.info("gdkWin="+gdkWin+" xid="+xid); - -try { - - let gdkWinState = gdk.gdk_window_get_state(gdkWin); - log.debug("gdkWinState="+gdkWinState); - // NOTE: Gecko 8.0 provides the 'sizemodechange' event - if (gdkWinState === gdk.GDK_WINDOW_STATE_ICONIFIED) { - log.debug("GOT ICONIFIED"); - let hides_on_minimize = firetray.Utils.prefService.getBoolPref('hides_on_minimize'); - let hides_single_window = firetray.Utils.prefService.getBoolPref('hides_single_window'); - if (hides_on_minimize) { - if (hides_single_window) - firetray.Handler.hideWindow(xid); - else - firetray.Handler.hideAllWindows(); - } - } - -} catch(error) {log.error(error);} - - return false; // do propagate } }; // firetray.Window @@ -597,7 +560,7 @@ firetray.Handler.registerWindow = function(win) { this.windows[xid] = {}; this.windows[xid].chromeWin = win; this.windows[xid].baseWin = baseWin; - firetray.Window.checkSubscribedEventMasks(xid, gdkWin); + firetray.Window.checkSubscribedEventMasks(xid); try { this.gtkWindows.insert(xid, gtkWin); this.gdkWindows.insert(xid, gdkWin); @@ -624,10 +587,6 @@ firetray.Handler.registerWindow = function(win) { this.windows[xid].filterWindowCb = gdk.GdkFilterFunc_t(firetray.Window.filterWindow); gdk.gdk_window_add_filter(gdkWin, this.windows[xid].filterWindowCb, null); - // // TEST - // this.windows[xid].unmapEventCb = gtk.GCallbackWidgetFocuEvent_t(firetray.Window.onUnmap); - // gobject.g_signal_connect(gtkWin, "unmap-event", this.windows[xid].unmapEventCb, gdkWin); - if (firetray.Handler.appHasChat && firetray.Chat.initialized) { // missing import ok Cu.import("resource://firetray/linux/FiretrayChatStatusIcon.jsm"); firetray.ChatStatusIcon.attachOnFocusInCallback(xid);