[Pkg-mozext-commits] [firetray] 134/399: restore window to its previous virtual desktop
David Prévot
taffit at alioth.debian.org
Tue Oct 29 18:23:28 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 5e4eaea614f037c1541a47ac58f5321dc71d914c
Author: foudfou <foudil.newbie+git at gmail.com>
Date: Mon Jan 9 22:13:27 2012 +0100
restore window to its previous virtual desktop
---
src/modules/ctypes/gdk.jsm | 7 +++
src/modules/ctypes/x11.jsm | 112 ++++++++++-------------------------
src/modules/gtk2/FiretrayWindow.jsm | 90 ++++++++++++++++++++++------
testing/Makefile | 6 +-
testing/xev_desktop.c | 60 +++++++++++++++++++
5 files changed, 175 insertions(+), 100 deletions(-)
diff --git a/src/modules/ctypes/gdk.jsm b/src/modules/ctypes/gdk.jsm
index 6cbeb48..5e5e600 100644
--- a/src/modules/ctypes/gdk.jsm
+++ b/src/modules/ctypes/gdk.jsm
@@ -108,6 +108,10 @@ function gdk_defines(lib) {
this.GDK_GRAB_BROKEN = 35;
this.GDK_DAMAGE = 36;
this.GDK_EVENT_LAST = 37; /* helper variable for decls */
+ this.GdkPropMode = ctypes.int; // enum
+ this.GDK_PROP_MODE_REPLACE = 0;
+ this.GDK_PROP_MODE_PREPEN = 1;
+ this.GDK_PROP_MODE_APPEND = 2;
this.GdkWindow = ctypes.StructType("GdkWindow");
this.GdkByteOrder = ctypes.int; // enum
@@ -176,6 +180,7 @@ function gdk_defines(lib) {
{ "changed_mask": this.GdkWindowState },
{ "new_window_state": this.GdkWindowState },
]);
+ this.GdkAtom = ctypes.StructType("GdkAtom");
this.GdkFilterFunc_t = ctypes.FunctionType(
ctypes.default_abi, this.GdkFilterReturn,
@@ -225,6 +230,8 @@ 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_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);
}
diff --git a/src/modules/ctypes/x11.jsm b/src/modules/ctypes/x11.jsm
index 72236b7..97c8a78 100644
--- a/src/modules/ctypes/x11.jsm
+++ b/src/modules/ctypes/x11.jsm
@@ -34,7 +34,8 @@ const XATOMS_EWMH_WM_STATES = [
"_NET_WM_STATE_FULLSCREEN", "_NET_WM_STATE_ABOVE", "_NET_WM_STATE_BELOW",
"_NET_WM_STATE_DEMANDS_ATTENTION"
];
-const XATOMS = XATOMS_ICCCM.concat(XATOMS_EWMH_WM_STATES).concat(XATOMS_EWMH_GENERAL);
+const XATOMS = XATOMS_ICCCM.concat(XATOMS_EWMH_WM_STATES)
+ .concat(XATOMS_EWMH_GENERAL).concat(["CARDINAL"]);
function x11_defines(lib) {
@@ -55,35 +56,43 @@ function x11_defines(lib) {
}
// X.h
- this.Success = 0;
- this.None = 0;
- this.AnyPropertyType = 0;
- this.BadValue = 2;
- this.BadWindow = 3;
- this.BadAtom = 5;
- this.BadMatch = 8;
- this.BadAlloc = 11;
+ this.Success = 0;
+ this.None = 0;
+ this.AnyPropertyType = 0;
+ this.BadValue = 2;
+ this.BadWindow = 3;
+ this.BadAtom = 5;
+ this.BadMatch = 8;
+ this.BadAlloc = 11;
this.PropertyNewValue = 0;
- this.PropertyDelete = 1;
+ this.PropertyDelete = 1;
+ this.PropModeReplace = 0;
+ this.PropModePrepend = 1;
+ this.PropModeAppend = 2;
// Event names
- this.DestroyNotify = 17;
- this.UnmapNotify = 18;
- this.MapNotify = 19;
+ this.DestroyNotify = 17;
+ this.UnmapNotify = 18;
+ this.MapNotify = 19;
this.PropertyNotify = 28;
- this.ClientMessage = 33;
+ this.ClientMessage = 33;
// Xutils.h: definitions for initial window state
this.WithdrawnState = 0; /* for windows that are not mapped */
- this.NormalState = 1; /* most applications want to start this way */
- this.IconicState = 3; /* application wants to start as an icon */
+ this.NormalState = 1; /* most applications want to start this way */
+ this.IconicState = 3; /* application wants to start as an icon */
// Xatom
- this.XA_ATOM = 4;
+ this.XA_ATOM = 4;
+ this.XA_CARDINAL = 6;
+ // Input Event Masks
+ this.SubstructureNotifyMask = 1<<19;
+ this.SubstructureRedirectMask = 1<<20;
this.Bool = ctypes.int;
+ this.Status = ctypes.int;
this.Display = ctypes.StructType("Display");
// union not supported by js-ctypes
// https://bugzilla.mozilla.org/show_bug.cgi?id=535378 "You can always
// typecast pointers, at least as long as you know which type is the biggest"
- this.XEvent = ctypes.void_t;
+ this.XEvent = ctypes.void_t; // union
this.XAnyEvent = ctypes.StructType("XAnyEvent", [
{ "type": ctypes.int },
{ "serial": ctypes.unsigned_long },
@@ -116,6 +125,9 @@ function x11_defines(lib) {
lib.lazy_bind("XInternAtom", this.Atom, this.Display.ptr, ctypes.char.ptr, this.Bool); // only_if_exsits
lib.lazy_bind("XGetWindowProperty", ctypes.int, this.Display.ptr, this.Window, this.Atom, ctypes.long, ctypes.long, this.Bool, this.Atom, this.Atom.ptr, ctypes.int.ptr, ctypes.unsigned_long.ptr, ctypes.unsigned_long.ptr, ctypes.unsigned_char.ptr.ptr);
lib.lazy_bind("XChangeProperty", ctypes.int, this.Display.ptr, this.Window, this.Atom, this.Atom, ctypes.int, ctypes.int, ctypes.unsigned_char.ptr, ctypes.int);
+ lib.lazy_bind("XDefaultRootWindow", this.Window, this.Display.ptr);
+ lib.lazy_bind("XSendEvent", this.Status, this.Display.ptr, this.Window, this.Bool, ctypes.long, this.XEvent.ptr);
+
}
if (!x11) {
@@ -149,67 +161,3 @@ typedef unsigned long Atom;
typedef CARD32 Atom;
# endif
*/
-
-/*
-XEvent {
- int type;
- XAnyEvent xany;
- XKeyEvent xkey;
- XButtonEvent xbutton;
- XMotionEvent xmotion;
- XCrossingEvent xcrossing;
- XFocusChangeEvent xfocus;
- XExposeEvent xexpose;
- XGraphicsExposeEvent xgraphicsexpose;
- XNoExposeEvent xnoexpose;
- XVisibilityEvent xvisibility;
- XCreateWindowEvent xcreatewindow;
- XDestroyWindowEvent xdestroywindow;
- XUnmapEvent xunmap;
- XMapEvent xmap;
- XMapRequestEvent xmaprequest;
- XReparentEvent xreparent;
- XConfigureEvent xconfigure;
- XGravityEvent xgravity;
- XResizeRequestEvent xresizerequest;
- XConfigureRequestEvent xconfigurerequest;
- XCirculateEvent xcirculate;
- XCirculateRequestEvent xcirculaterequest;
- XPropertyEvent xproperty;
- XSelectionClearEvent xselectionclear;
- XSelectionRequestEvent xselectionrequest;
- XSelectionEvent xselection;
- XColormapEvent xcolormap;
- XClientMessageEvent xclient;
- XMappingEvent xmapping;
- XErrorEvent xerror;
- XKeymapEvent xkeymap;
- XGenericEvent xgeneric;
- XGenericEventCookie xcookie;
- long pad[24];
-}
-
-GdkEvent {
- GdkEventType type;
- GdkEventAny any;
- GdkEventExpose expose;
- GdkEventNoExpose no_expose;
- GdkEventVisibility visibility;
- GdkEventMotion motion;
- GdkEventButton button;
- GdkEventScroll scroll;
- GdkEventKey key;
- GdkEventCrossing crossing;
- GdkEventFocus focus_change;
- GdkEventConfigure configure;
- GdkEventProperty property;
- GdkEventSelection selection;
- GdkEventOwnerChange owner_change;
- GdkEventProximity proximity;
- GdkEventClient client;
- GdkEventDND dnd;
- GdkEventWindowState window_state;
- GdkEventSetting setting;
- GdkEventGrabBroken grab_broken;
-};
-*/
diff --git a/src/modules/gtk2/FiretrayWindow.jsm b/src/modules/gtk2/FiretrayWindow.jsm
index 88b117e..7628114 100644
--- a/src/modules/gtk2/FiretrayWindow.jsm
+++ b/src/modules/gtk2/FiretrayWindow.jsm
@@ -176,18 +176,20 @@ firetray.Window = {
firetray.Handler.windows[xid].savedWidth,
firetray.Handler.windows[xid].savedHeight,
false); // repaint
+
+ ['savedX', 'savedX', 'savedWidth', 'savedHeight'].forEach(function(element, index, array) {
+ delete firetray.Handler.windows[xid][element];
+ });
},
saveWindowStates: function(xid) {
- // TODO: we may want to restore the window onto its original
- // desktop/monitor/etc.
let winStates = firetray.Window.getXWindowStates(x11.Window(xid));
- firetray.Handler.windows[xid].savedWindowStates = winStates;
+ firetray.Handler.windows[xid].savedStates = winStates;
LOG("save: windowStates="+winStates);
},
restoreWindowStates: function(xid) {
- let winStates = firetray.Handler.windows[xid].savedWindowStates;
+ let winStates = firetray.Handler.windows[xid].savedStates;
LOG("restored WindowStates: " + winStates);
if (winStates & FIRETRAY_XWINDOW_MAXIMIZED) {
firetray.Handler.windows[xid].chromeWin.maximize();
@@ -196,6 +198,36 @@ firetray.Window = {
if (!hides_on_minimize && (winStates & FIRETRAY_XWINDOW_HIDDEN)) {
firetray.Handler.windows[xid].chromeWin.minimize();
}
+
+ delete firetray.Handler.windows[xid].savedStates;
+ },
+
+ saveWindowDesktop: function(xid) {
+ let winDesktop = firetray.Window.getXWindowDesktop(x11.Window(xid));
+ firetray.Handler.windows[xid].savedDesktop = winDesktop;
+ LOG("save: windowDesktop="+winDesktop);
+ },
+
+ restoreWindowDesktop: function(xid) {
+ let desktopDest = firetray.Handler.windows[xid].savedDesktop;
+ if (desktopDest === null) return;
+
+ let xev = new x11.XClientMessageEvent;
+ xev.type = x11.ClientMessage;
+ xev.window = x11.Window(xid);
+ xev.message_type = x11.current.Atoms._NET_WM_DESKTOP;
+ xev.format = 32;
+ xev.data[0] = desktopDest;
+
+ let rootWin = x11.XDefaultRootWindow(x11.current.Display);
+ let propagate = false;
+ let mask = ctypes.long(x11.SubstructureNotifyMask|x11.SubstructureRedirectMask);
+ // fortunately, it's OK not to cast xev. ctypes.cast to a void_t doesn't work (length pb)
+ let status = x11.XSendEvent(x11.current.Display, rootWin, propagate, mask, xev.address());
+ // always returns 1 (BadRequest as a coincidence)
+
+ LOG("restored to desktop: "+desktopDest);
+ delete firetray.Handler.windows[xid].savedDesktop;
},
/* KEPT FOR LATER USE
@@ -213,12 +245,12 @@ firetray.Window = {
*/
/**
- * YOU MUST x11.XFree() THE VARIABLE RETURN BY THIS FUNCTION
+ * YOU MUST x11.XFree() THE VARIABLE RETURNED BY THIS FUNCTION
* @param xwin: a x11.Window
* @param prop: a x11.Atom
*/
getXWindowProperties: function(xwin, prop) {
- // infos returned by XGetWindowProperty()
+ // infos returned by XGetWindowProperty() - FIXME: should be freed ?
let actual_type = new x11.Atom;
let actual_format = new ctypes.int;
let nitems = new ctypes.unsigned_long;
@@ -229,7 +261,8 @@ firetray.Window = {
let offset = 0;
let res = x11.XGetWindowProperty(
x11.current.Display, xwin, prop, offset, bufSize, 0, x11.AnyPropertyType,
- actual_type.address(), actual_format.address(), nitems.address(), bytes_after.address(), prop_value.address());
+ 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)) {
@@ -264,19 +297,20 @@ firetray.Window = {
getXWindowStates: function(xwin) {
let winStates = 0;
- let [propsFound, nitems] = firetray.Window.getXWindowProperties(xwin, x11.current.Atoms._NET_WM_STATE);
+ let [propsFound, nitems] =
+ firetray.Window.getXWindowProperties(xwin, x11.current.Atoms._NET_WM_STATE);
LOG("propsFound, nitems="+propsFound+", "+nitems);
if (!propsFound) return 0;
let maximizedHorz = maximizedVert = false;
for (let i=0, len=nitems.value; i<len; ++i) {
LOG("i: "+propsFound.contents[i]);
- let foundProp = propsFound.contents[i].toString();
- if (strEquals(propsFound.contents[i], x11.current.Atoms['_NET_WM_STATE_HIDDEN']))
+ let currentProp = propsFound.contents[i];
+ if (strEquals(currentProp, x11.current.Atoms['_NET_WM_STATE_HIDDEN']))
winStates |= FIRETRAY_XWINDOW_HIDDEN;
- else if (strEquals(propsFound.contents[i], x11.current.Atoms['_NET_WM_STATE_MAXIMIZED_HORZ']))
+ else if (strEquals(currentProp, x11.current.Atoms['_NET_WM_STATE_MAXIMIZED_HORZ']))
maximizedHorz = true;
- else if (strEquals(propsFound.contents[i], x11.current.Atoms['_NET_WM_STATE_MAXIMIZED_VERT']))
+ else if (strEquals(currentProp, x11.current.Atoms['_NET_WM_STATE_MAXIMIZED_VERT']))
maximizedVert = true;
}
@@ -288,6 +322,25 @@ firetray.Window = {
return winStates;
},
+ getXWindowDesktop: function(xwin) {
+ let desktop = null;
+
+ let [propsFound, nitems] =
+ firetray.Window.getXWindowProperties(xwin, x11.current.Atoms._NET_WM_DESKTOP);
+ LOG("DESKTOP propsFound, nitems="+propsFound+", "+nitems);
+
+ if (strEquals(nitems.value, 0))
+ WARN("desktop number not found");
+ else if (strEquals(nitems.value, 1))
+ desktop = propsFound.contents[0];
+ else
+ throw new RangeError("more than one desktop found");
+
+ x11.XFree(propsFound);
+
+ return desktop;
+ },
+
filterWindow: function(xev, gdkEv, data) {
if (!xev)
return gdk.GDK_FILTER_CONTINUE;
@@ -301,7 +354,7 @@ firetray.Window = {
case x11.UnmapNotify:
LOG("UnmapNotify");
let winStates = firetray.Window.getXWindowStates(xwin);
- let isHidden = winStates & FIRETRAY_XWINDOW_HIDDEN;
+ let isHidden = winStates & FIRETRAY_XWINDOW_HIDDEN;
LOG("winStates="+winStates+", isHidden="+isHidden);
if (isHidden) {
let hides_on_minimize = firetray.Utils.prefService.getBoolPref('hides_on_minimize');
@@ -436,8 +489,10 @@ firetray.Handler.showSingleWindow = function(xid) {
// try to restore previous state. TODO: z-order respected ?
firetray.Window.restoreWindowPositionAndSize(xid);
- firetray.Window.restoreWindowStates(xid); // no need to be saved
+ firetray.Window.restoreWindowStates(xid);
firetray.Handler.windows[xid].baseWin.visibility = true; // show
+ firetray.Window.restoreWindowDesktop(xid); // after show
+ // TODO: we need want to restore to the original monitor (screen)
firetray.Handler.windows[xid].visibility = true;
firetray.Handler.visibleWindowsCount += 1;
@@ -450,6 +505,7 @@ firetray.Handler.hideSingleWindow = function(xid) {
firetray.Window.saveWindowPositionAndSize(xid);
firetray.Window.saveWindowStates(xid);
+ firetray.Window.saveWindowDesktop(xid);
firetray.Handler.windows[xid].baseWin.visibility = false; // hide
firetray.Handler.windows[xid].visibility = false;
@@ -477,9 +533,9 @@ firetray.Handler.showHideAllWindows = function(gtkStatusIcon, userData) {
/**
* 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... :-(
+ * Needs to be defined and called outside x11.jsm because: 1. gdk already
+ * imports x11, 2. there is no means to get the default Display solely with
+ * Xlib without opening one... :-(
*/
x11.init = function() {
if (!isEmpty(this.current))
diff --git a/testing/Makefile b/testing/Makefile
index b26eda4..da8150c 100644
--- a/testing/Makefile
+++ b/testing/Makefile
@@ -1,5 +1,6 @@
includes := $(shell pkg-config --libs --cflags gtk+-2.0)
-executables := gtk_icon_example trayicon hide xtypes x11XGetWindowProp window_state_event
+executables := gtk_icon_example trayicon hide xtypes x11XGetWindowProp \
+ window_state_event xev_desktop
.PHONY: all
all: $(executables)
@@ -25,3 +26,6 @@ x11XGetWindowProp: x11XGetWindowProp.c
window_state_event: window_state_event.c
gcc $(includes) -o window_state_event window_state_event.c
+
+xev_desktop: xev_desktop.c
+ gcc -lXm -lXt -lX11 -o xev_desktop xev_desktop.c
diff --git a/testing/xev_desktop.c b/testing/xev_desktop.c
new file mode 100644
index 0000000..eb2fb73
--- /dev/null
+++ b/testing/xev_desktop.c
@@ -0,0 +1,60 @@
+/**
+ * cc -o memo memo.c -lXm -lXt -lX11 -I/usr/X11R6/include/
+ -L/usr/X11R6/lib/
+*/
+
+
+#include <Xm/Xm.h>
+#include <X11/X.h>
+#include <Xm/Label.h>
+#include <X11/Xatom.h>
+#include <stdlib.h>
+#include <stdio.h>
+
+void main(int argc, char **argv)
+{
+ Widget shell, msg;
+ XtAppContext app;
+ XmString xmstr;
+ XClientMessageEvent xev;
+ Display *display;
+
+ shell = XtAppInitialize(&app, "Memo", NULL, 0, &argc, argv, NULL,
+ NULL, 0);
+
+ xmstr = XmStringCreateLtoR("move window test",
+ XmFONTLIST_DEFAULT_TAG);
+
+ msg =
+ XtVaCreateManagedWidget(
+ "message", xmLabelWidgetClass, shell, XmNlabelString, xmstr,
+ NULL);
+
+ XmStringFree(xmstr);
+
+ XtRealizeWidget(shell);
+
+
+/* Now move the window to a different area */
+ display = XtDisplay(shell);
+
+
+ xev.type = ClientMessage;
+ xev.window = XtWindow(shell);
+ xev.message_type = XInternAtom(display, "_NET_WM_DESKTOP", False);
+ xev.format = 32;
+
+/* Force into desktop 2 */
+ xev.data.l[0] = 2;
+
+
+ XSendEvent(
+ display,
+ RootWindowOfScreen(XtScreen(shell)),
+ False,
+ SubstructureNotifyMask|SubstructureRedirectMask,
+ (XEvent *) &xev);
+
+
+ XtAppMainLoop(app);
+}
--
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