[Pkg-mozext-commits] [firetray] 130/399: * add hides_on_minimize functionality * fix options UI

David Prévot taffit at alioth.debian.org
Tue Oct 29 18:23:27 UTC 2013


This is an automated email from the git hooks/post-receive script.

taffit pushed a commit to branch dfsg-clean
in repository firetray.

commit 075131f46c193ed3cd42e2d82ad23a6ce2cbfbd9
Author: foudfou <foudil.newbie+git at gmail.com>
Date:   Sun Jan 1 22:31:16 2012 +0100

    * add hides_on_minimize functionality
    * fix options UI
    
    Revert back to X11/EWMH to detect minimize event more accurately. Still have to
    fix the incorrect saved window state (STATE_MINIMIZED) when hiding from another
    virtual desktop.
---
 src/chrome/content/options.js       |   15 +++-
 src/chrome/content/options.xul      |   10 +--
 src/chrome/locale/en-US/options.dtd |    6 +-
 src/modules/gtk2/FiretrayWindow.jsm |  150 ++++++++++++++++++++++++++++++++---
 4 files changed, 156 insertions(+), 25 deletions(-)

diff --git a/src/chrome/content/options.js b/src/chrome/content/options.js
index f98200f..8bc5989 100644
--- a/src/chrome/content/options.js
+++ b/src/chrome/content/options.js
@@ -63,13 +63,20 @@ var firetrayUIOptions = {
   },
 
   initWindowAndIconControls: function() {
-    this.disableHidesOptions(!firetray.Utils.prefService.getBoolPref('hides_on_close'));
+    let doDisable = !(firetray.Utils.prefService.getBoolPref('hides_on_close') ||
+                    firetray.Utils.prefService.getBoolPref('hides_on_minimize'));
+    this.updateHidesOptions(doDisable);
   },
 
-  disableHidesOptions: function(doDisable) {
-    LOG("doDisable="+doDisable);
+  updateHidesOptions: function(doDisable) {
+    if ("undefined" === typeof(doDisable)) {
+      let hides_on_close    = document.getElementById("ui_hides_on_close").checked;
+      let hides_on_minimize = document.getElementById("ui_hides_on_minimize").checked;
+      LOG("hides_on_close="+hides_on_close+", hides_on_minimize="+hides_on_minimize);
+      doDisable = !hides_on_close && !hides_on_minimize;
+    }
+
     document.getElementById('ui_hides_single_window').disabled = doDisable;
-    // TODO: NOT IMPLEMENTED YET: document.getElementById('ui_hides_on_minimize').disabled = doDisable;
   },
 
   initMailControls: function() {
diff --git a/src/chrome/content/options.xul b/src/chrome/content/options.xul
index 0562fd4..629ffb2 100644
--- a/src/chrome/content/options.xul
+++ b/src/chrome/content/options.xul
@@ -43,15 +43,15 @@
             <checkbox id="ui_hides_on_close" preference="pref_bool_hides_on_close"
                       label="&bool_hides_on_close.label;"
                       accesskey="&bool_hides_on_close.accesskey;"
-                      onclick="firetrayUIOptions.disableHidesOptions(this.checked);"/>
+                      oncommand="firetrayUIOptions.updateHidesOptions();"/>
+            <checkbox id="ui_hides_on_minimize" preference="pref_bool_hides_on_minimize"
+                      label="&bool_hides_on_minimize.label;"
+                      accesskey="&bool_hides_on_minimize.accesskey;"
+                      oncommand="firetrayUIOptions.updateHidesOptions();"/>
             <checkbox id="ui_hides_single_window" preference="pref_bool_hides_single_window"
                       label="&bool_hides_single_window.label;"
                       accesskey="&bool_hides_single_window.accesskey;"
                       tooltiptext="&bool_hides_single_window.tooltip;"/>
-            <checkbox id="ui_hides_on_minimize" preference="pref_bool_hides_on_minimize"
-                      label="&bool_hides_on_minimize.label;"
-                      accesskey="&bool_hides_on_minimize.accesskey;"
-                      disabled="true" tooltiptext="&NOT_IMPLEMENTED_YET;"/>
           </groupbox>
 
         </tabpanel>
diff --git a/src/chrome/locale/en-US/options.dtd b/src/chrome/locale/en-US/options.dtd
index 89aca0e..df2ec9e 100644
--- a/src/chrome/locale/en-US/options.dtd
+++ b/src/chrome/locale/en-US/options.dtd
@@ -12,11 +12,11 @@
 
 <!ENTITY bool_hides_on_close.label "Closing window hides to tray">
 <!ENTITY bool_hides_on_close.accesskey "C">
-<!ENTITY bool_hides_single_window.label "Hide the current window only">
-<!ENTITY bool_hides_single_window.accesskey "H">
 <!ENTITY bool_hides_single_window.tooltip "not all windows at once">
-<!ENTITY bool_hides_on_minimize.label "Minimize window hides to tray">
+<!ENTITY bool_hides_on_minimize.label "Minimizing window hides to tray">
 <!ENTITY bool_hides_on_minimize.accesskey "M">
+<!ENTITY bool_hides_single_window.label "Hide the current window only">
+<!ENTITY bool_hides_single_window.accesskey "H">
 
 <!ENTITY mail_notification.label "Mail notification">
 <!ENTITY mail_notification_disabled.label "disabled">
diff --git a/src/modules/gtk2/FiretrayWindow.jsm b/src/modules/gtk2/FiretrayWindow.jsm
index 0dde823..a94fc36 100644
--- a/src/modules/gtk2/FiretrayWindow.jsm
+++ b/src/modules/gtk2/FiretrayWindow.jsm
@@ -21,6 +21,7 @@ Cu.import("resource://firetray/gobject.jsm");
 Cu.import("resource://firetray/gdk.jsm");
 Cu.import("resource://firetray/gtk.jsm");
 Cu.import("resource://firetray/libc.jsm");
+Cu.import("resource://firetray/x11.jsm");
 Cu.import("resource://firetray/commons.js");
 
 const Services2 = {};
@@ -203,26 +204,118 @@ firetray.Window = {
     LOG("restored WindowState: " + firetray.Handler.windows[xid].chromeWin.windowState);
   },
 
-  // http://www.gtkforums.com/viewtopic.php?t=1624
-  onWindowState: function(gtkWidget, gdkEventState, userData){
+/* KEPT FOR LATER USE
+  onWindowState: function(gtkWidget, gdkEventState, userData) {
     LOG("window-state-event: "+gdkEventState.contents.new_window_state);
 
     if (gdkEventState.contents.new_window_state & gdk.GDK_WINDOW_STATE_ICONIFIED) {
       let xid = firetray.Window.getXIDFromGtkWidget(gtkWidget);
       LOG(xid+" iconified: "+gdkEventState.contents.changed_mask+" "+gdkEventState.contents.new_window_state);
-
-      // 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.hideSingleWindow(xid);
-      //   } else
-      //     firetray.Handler.hideAllWindows();
-      // }
     }
 
     let stopPropagation = true; // not usefull
     return stopPropagation;
+  },
+*/
+
+  checkXWindowEWMState: function(xwin, prop) {
+    LOG("xwin="+xwin+" prop="+prop);
+
+    // infos returned by XGetWindowProperty()
+    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 bufSize = XATOMS_EWMH_WM_STATES.length*ctypes.unsigned_long.size;
+    let offset = 0;
+    let res = x11.XGetWindowProperty(
+      x11.current.Display, xwin, x11.current.Atoms._NET_WM_STATE, offset, bufSize, 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 (!strEquals(res, x11.Success)) {
+      ERROR("XGetWindowProperty failed");
+      return false;
+    }
+    if (strEquals(actual_type.value, x11.None)) {
+      WARN("property not found");
+      return false;
+    }
+
+    LOG("prop_value="+prop_value+", size="+prop_value.constructor.size);
+    /* 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). [man XGetWindowProperty] */
+    if (actual_format.value !== 32) {
+      ERROR("unsupported format: "+actual_format.value);
+      x11.XFree(prop_value);
+      return false;
+    }
+    LOG("format OK");
+    var props = ctypes.cast(prop_value, ctypes.unsigned_long.array(nitems.value).ptr);
+    LOG("props="+props+", size="+props.constructor.size);
+
+    for (let i=0; i<nitems.value; ++i) {
+      LOG(props.contents[i]);
+      if (strEquals(props.contents[i], prop))
+        return true;
+    }
+
+    x11.XFree(prop_value);
+
+    return false;
+  },
+
+  filterWindow: function(xev, gdkEv, data) {
+    if (!xev)
+      return gdk.GDK_FILTER_CONTINUE;
+
+    try {
+      let xany = ctypes.cast(xev, x11.XAnyEvent.ptr);
+      let xwin = xany.contents.window;
+
+      switch (xany.contents.type) {
+
+      case x11.UnmapNotify:
+        LOG("UnmapNotify");
+        let isHidden = firetray.Window.checkXWindowEWMState(xwin, x11.current.Atoms._NET_WM_STATE_HIDDEN);
+        LOG("isHidden="+isHidden);
+        if (isHidden) {
+          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.hideSingleWindow(xwin);
+            } else
+              firetray.Handler.hideAllWindows();
+          }
+        }
+        break;
+
+/* KEPT FOR LATER USE
+      case x11.ClientMessage:   // not very useful
+        LOG("ClientMessage");
+        let xclient = ctypes.cast(xev, x11.XClientMessageEvent.ptr);
+        LOG("xclient.data="+xclient.contents.data);
+        LOG("message_type="+xclient.contents.message_type+", format="+xclient.contents.format);
+        if (strEquals(xclient.contents.data[0], x11.current.Atoms.WM_DELETE_WINDOW)) {
+          LOG("Delete Window prevented");
+          return gdk.GDK_FILTER_REMOVE;
+        }
+        break;
+*/
+
+      default:
+        // LOG("xany.type="+xany.contents.type);
+        break;
+      }
+    } catch(x) {
+      ERROR(x);
+    }
+
+    return gdk.GDK_FILTER_CONTINUE;
   }
 
 }; // firetray.Window
@@ -273,11 +366,14 @@ firetray.Handler.registerWindow = function(win) {
      // delete_event_cb (in gtk2/nsWindow.cpp), but we prefer to use the
      // provided 'close' JS event
 
-    /* we'll catch minimize events with Gtk:
-       http://stackoverflow.com/questions/8018328/what-is-the-gtk-event-called-when-a-window-minimizes */
+/* KEPT FOR LATER USE
     this.windows[xid].onWindowStateCb = gtk.GCallbackWindowStateEvent_t(firetray.Window.onWindowState);
     this.windows[xid].onWindowStateCbId = gobject.g_signal_connect(gtkWin, "window-state-event", this.windows[xid].onWindowStateCb, null);
     LOG("g_connect window-state-event="+this.windows[xid].onWindowStateCbId);
+*/
+
+    this.windows[xid].filterWindowCb = gdk.GdkFilterFunc_t(firetray.Window.filterWindow);
+    gdk.gdk_window_add_filter(gdkWin, this.windows[xid].filterWindowCb, null);
 
   } catch (x) {
     this._unregisterWindowByXID(xid);
@@ -357,3 +453,31 @@ firetray.Handler.showHideAllWindows = function(gtkStatusIcon, userData) {
   let stopPropagation = true;
   return stopPropagation;
 };
+
+
+/**
+ * init X11 Display and handled XAtoms.
+ * Needs to be defined and called outside x11.jsm because: gdk already imports
+ * x11, and there is no means to get the default Display solely with Xlib
+ * without opening one...  :-(
+ */
+x11.init = function() {
+  if (!isEmpty(this.current))
+    return true; // init only once
+
+  this.current = {};
+  try {
+    let gdkDisplay = gdk.gdk_display_get_default();
+    this.current.Display = gdk.gdk_x11_display_get_xdisplay(gdkDisplay);
+    this.current.Atoms = {};
+    XATOMS.forEach(function(atomName, index, array) {
+      this.current.Atoms[atomName] = x11.XInternAtom(this.current.Display, atomName, 0);
+      LOG("x11.current.Atoms."+atomName+"="+this.current.Atoms[atomName]);
+    }, this);
+    return true;
+  } catch (x) {
+    ERROR(x);
+    return false;
+  }
+};
+x11.init();

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-mozext/firetray.git



More information about the Pkg-mozext-commits mailing list