restore window to its previous virtual desktop
This commit is contained in:
parent
4c3a1cfc89
commit
5e4eaea614
|
@ -108,6 +108,10 @@ function gdk_defines(lib) {
|
||||||
this.GDK_GRAB_BROKEN = 35;
|
this.GDK_GRAB_BROKEN = 35;
|
||||||
this.GDK_DAMAGE = 36;
|
this.GDK_DAMAGE = 36;
|
||||||
this.GDK_EVENT_LAST = 37; /* helper variable for decls */
|
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.GdkWindow = ctypes.StructType("GdkWindow");
|
||||||
this.GdkByteOrder = ctypes.int; // enum
|
this.GdkByteOrder = ctypes.int; // enum
|
||||||
|
@ -176,6 +180,7 @@ function gdk_defines(lib) {
|
||||||
{ "changed_mask": this.GdkWindowState },
|
{ "changed_mask": this.GdkWindowState },
|
||||||
{ "new_window_state": this.GdkWindowState },
|
{ "new_window_state": this.GdkWindowState },
|
||||||
]);
|
]);
|
||||||
|
this.GdkAtom = ctypes.StructType("GdkAtom");
|
||||||
|
|
||||||
this.GdkFilterFunc_t = ctypes.FunctionType(
|
this.GdkFilterFunc_t = ctypes.FunctionType(
|
||||||
ctypes.default_abi, this.GdkFilterReturn,
|
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_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_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_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);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -34,7 +34,8 @@ const XATOMS_EWMH_WM_STATES = [
|
||||||
"_NET_WM_STATE_FULLSCREEN", "_NET_WM_STATE_ABOVE", "_NET_WM_STATE_BELOW",
|
"_NET_WM_STATE_FULLSCREEN", "_NET_WM_STATE_ABOVE", "_NET_WM_STATE_BELOW",
|
||||||
"_NET_WM_STATE_DEMANDS_ATTENTION"
|
"_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) {
|
function x11_defines(lib) {
|
||||||
|
@ -55,35 +56,43 @@ function x11_defines(lib) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// X.h
|
// X.h
|
||||||
this.Success = 0;
|
this.Success = 0;
|
||||||
this.None = 0;
|
this.None = 0;
|
||||||
this.AnyPropertyType = 0;
|
this.AnyPropertyType = 0;
|
||||||
this.BadValue = 2;
|
this.BadValue = 2;
|
||||||
this.BadWindow = 3;
|
this.BadWindow = 3;
|
||||||
this.BadAtom = 5;
|
this.BadAtom = 5;
|
||||||
this.BadMatch = 8;
|
this.BadMatch = 8;
|
||||||
this.BadAlloc = 11;
|
this.BadAlloc = 11;
|
||||||
this.PropertyNewValue = 0;
|
this.PropertyNewValue = 0;
|
||||||
this.PropertyDelete = 1;
|
this.PropertyDelete = 1;
|
||||||
|
this.PropModeReplace = 0;
|
||||||
|
this.PropModePrepend = 1;
|
||||||
|
this.PropModeAppend = 2;
|
||||||
// Event names
|
// Event names
|
||||||
this.DestroyNotify = 17;
|
this.DestroyNotify = 17;
|
||||||
this.UnmapNotify = 18;
|
this.UnmapNotify = 18;
|
||||||
this.MapNotify = 19;
|
this.MapNotify = 19;
|
||||||
this.PropertyNotify = 28;
|
this.PropertyNotify = 28;
|
||||||
this.ClientMessage = 33;
|
this.ClientMessage = 33;
|
||||||
// Xutils.h: definitions for initial window state
|
// Xutils.h: definitions for initial window state
|
||||||
this.WithdrawnState = 0; /* for windows that are not mapped */
|
this.WithdrawnState = 0; /* for windows that are not mapped */
|
||||||
this.NormalState = 1; /* most applications want to start this way */
|
this.NormalState = 1; /* most applications want to start this way */
|
||||||
this.IconicState = 3; /* application wants to start as an icon */
|
this.IconicState = 3; /* application wants to start as an icon */
|
||||||
// Xatom
|
// 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.Bool = ctypes.int;
|
||||||
|
this.Status = ctypes.int;
|
||||||
this.Display = ctypes.StructType("Display");
|
this.Display = ctypes.StructType("Display");
|
||||||
// union not supported by js-ctypes
|
// union not supported by js-ctypes
|
||||||
// https://bugzilla.mozilla.org/show_bug.cgi?id=535378 "You can always
|
// 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"
|
// 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", [
|
this.XAnyEvent = ctypes.StructType("XAnyEvent", [
|
||||||
{ "type": ctypes.int },
|
{ "type": ctypes.int },
|
||||||
{ "serial": ctypes.unsigned_long },
|
{ "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("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("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("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) {
|
if (!x11) {
|
||||||
|
@ -149,67 +161,3 @@ typedef unsigned long Atom;
|
||||||
typedef CARD32 Atom;
|
typedef CARD32 Atom;
|
||||||
# endif
|
# 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;
|
|
||||||
};
|
|
||||||
*/
|
|
||||||
|
|
|
@ -176,18 +176,20 @@ firetray.Window = {
|
||||||
firetray.Handler.windows[xid].savedWidth,
|
firetray.Handler.windows[xid].savedWidth,
|
||||||
firetray.Handler.windows[xid].savedHeight,
|
firetray.Handler.windows[xid].savedHeight,
|
||||||
false); // repaint
|
false); // repaint
|
||||||
|
|
||||||
|
['savedX', 'savedX', 'savedWidth', 'savedHeight'].forEach(function(element, index, array) {
|
||||||
|
delete firetray.Handler.windows[xid][element];
|
||||||
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
saveWindowStates: function(xid) {
|
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));
|
let winStates = firetray.Window.getXWindowStates(x11.Window(xid));
|
||||||
firetray.Handler.windows[xid].savedWindowStates = winStates;
|
firetray.Handler.windows[xid].savedStates = winStates;
|
||||||
LOG("save: windowStates="+winStates);
|
LOG("save: windowStates="+winStates);
|
||||||
},
|
},
|
||||||
|
|
||||||
restoreWindowStates: function(xid) {
|
restoreWindowStates: function(xid) {
|
||||||
let winStates = firetray.Handler.windows[xid].savedWindowStates;
|
let winStates = firetray.Handler.windows[xid].savedStates;
|
||||||
LOG("restored WindowStates: " + winStates);
|
LOG("restored WindowStates: " + winStates);
|
||||||
if (winStates & FIRETRAY_XWINDOW_MAXIMIZED) {
|
if (winStates & FIRETRAY_XWINDOW_MAXIMIZED) {
|
||||||
firetray.Handler.windows[xid].chromeWin.maximize();
|
firetray.Handler.windows[xid].chromeWin.maximize();
|
||||||
|
@ -196,6 +198,36 @@ firetray.Window = {
|
||||||
if (!hides_on_minimize && (winStates & FIRETRAY_XWINDOW_HIDDEN)) {
|
if (!hides_on_minimize && (winStates & FIRETRAY_XWINDOW_HIDDEN)) {
|
||||||
firetray.Handler.windows[xid].chromeWin.minimize();
|
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
|
/* 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 xwin: a x11.Window
|
||||||
* @param prop: a x11.Atom
|
* @param prop: a x11.Atom
|
||||||
*/
|
*/
|
||||||
getXWindowProperties: function(xwin, prop) {
|
getXWindowProperties: function(xwin, prop) {
|
||||||
// infos returned by XGetWindowProperty()
|
// infos returned by XGetWindowProperty() - FIXME: should be freed ?
|
||||||
let actual_type = new x11.Atom;
|
let actual_type = new x11.Atom;
|
||||||
let actual_format = new ctypes.int;
|
let actual_format = new ctypes.int;
|
||||||
let nitems = new ctypes.unsigned_long;
|
let nitems = new ctypes.unsigned_long;
|
||||||
|
@ -229,7 +261,8 @@ firetray.Window = {
|
||||||
let offset = 0;
|
let offset = 0;
|
||||||
let res = x11.XGetWindowProperty(
|
let res = x11.XGetWindowProperty(
|
||||||
x11.current.Display, xwin, prop, offset, bufSize, 0, x11.AnyPropertyType,
|
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);
|
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)) {
|
if (!strEquals(res, x11.Success)) {
|
||||||
|
@ -264,19 +297,20 @@ firetray.Window = {
|
||||||
getXWindowStates: function(xwin) {
|
getXWindowStates: function(xwin) {
|
||||||
let winStates = 0;
|
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);
|
LOG("propsFound, nitems="+propsFound+", "+nitems);
|
||||||
if (!propsFound) return 0;
|
if (!propsFound) return 0;
|
||||||
|
|
||||||
let maximizedHorz = maximizedVert = false;
|
let maximizedHorz = maximizedVert = false;
|
||||||
for (let i=0, len=nitems.value; i<len; ++i) {
|
for (let i=0, len=nitems.value; i<len; ++i) {
|
||||||
LOG("i: "+propsFound.contents[i]);
|
LOG("i: "+propsFound.contents[i]);
|
||||||
let foundProp = propsFound.contents[i].toString();
|
let currentProp = propsFound.contents[i];
|
||||||
if (strEquals(propsFound.contents[i], x11.current.Atoms['_NET_WM_STATE_HIDDEN']))
|
if (strEquals(currentProp, x11.current.Atoms['_NET_WM_STATE_HIDDEN']))
|
||||||
winStates |= FIRETRAY_XWINDOW_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;
|
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;
|
maximizedVert = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -288,6 +322,25 @@ firetray.Window = {
|
||||||
return winStates;
|
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) {
|
filterWindow: function(xev, gdkEv, data) {
|
||||||
if (!xev)
|
if (!xev)
|
||||||
return gdk.GDK_FILTER_CONTINUE;
|
return gdk.GDK_FILTER_CONTINUE;
|
||||||
|
@ -301,7 +354,7 @@ firetray.Window = {
|
||||||
case x11.UnmapNotify:
|
case x11.UnmapNotify:
|
||||||
LOG("UnmapNotify");
|
LOG("UnmapNotify");
|
||||||
let winStates = firetray.Window.getXWindowStates(xwin);
|
let winStates = firetray.Window.getXWindowStates(xwin);
|
||||||
let isHidden = winStates & FIRETRAY_XWINDOW_HIDDEN;
|
let isHidden = winStates & FIRETRAY_XWINDOW_HIDDEN;
|
||||||
LOG("winStates="+winStates+", isHidden="+isHidden);
|
LOG("winStates="+winStates+", isHidden="+isHidden);
|
||||||
if (isHidden) {
|
if (isHidden) {
|
||||||
let hides_on_minimize = firetray.Utils.prefService.getBoolPref('hides_on_minimize');
|
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 ?
|
// try to restore previous state. TODO: z-order respected ?
|
||||||
firetray.Window.restoreWindowPositionAndSize(xid);
|
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.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.windows[xid].visibility = true;
|
||||||
firetray.Handler.visibleWindowsCount += 1;
|
firetray.Handler.visibleWindowsCount += 1;
|
||||||
|
@ -450,6 +505,7 @@ firetray.Handler.hideSingleWindow = function(xid) {
|
||||||
|
|
||||||
firetray.Window.saveWindowPositionAndSize(xid);
|
firetray.Window.saveWindowPositionAndSize(xid);
|
||||||
firetray.Window.saveWindowStates(xid);
|
firetray.Window.saveWindowStates(xid);
|
||||||
|
firetray.Window.saveWindowDesktop(xid);
|
||||||
firetray.Handler.windows[xid].baseWin.visibility = false; // hide
|
firetray.Handler.windows[xid].baseWin.visibility = false; // hide
|
||||||
|
|
||||||
firetray.Handler.windows[xid].visibility = false;
|
firetray.Handler.windows[xid].visibility = false;
|
||||||
|
@ -477,9 +533,9 @@ firetray.Handler.showHideAllWindows = function(gtkStatusIcon, userData) {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* init X11 Display and handled XAtoms.
|
* init X11 Display and handled XAtoms.
|
||||||
* Needs to be defined and called outside x11.jsm because: gdk already imports
|
* Needs to be defined and called outside x11.jsm because: 1. gdk already
|
||||||
* x11, and there is no means to get the default Display solely with Xlib
|
* imports x11, 2. there is no means to get the default Display solely with
|
||||||
* without opening one... :-(
|
* Xlib without opening one... :-(
|
||||||
*/
|
*/
|
||||||
x11.init = function() {
|
x11.init = function() {
|
||||||
if (!isEmpty(this.current))
|
if (!isEmpty(this.current))
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
includes := $(shell pkg-config --libs --cflags gtk+-2.0)
|
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
|
.PHONY: all
|
||||||
all: $(executables)
|
all: $(executables)
|
||||||
|
@ -25,3 +26,6 @@ x11XGetWindowProp: x11XGetWindowProp.c
|
||||||
|
|
||||||
window_state_event: window_state_event.c
|
window_state_event: window_state_event.c
|
||||||
gcc $(includes) -o 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
|
||||||
|
|
|
@ -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);
|
||||||
|
}
|
Loading…
Reference in New Issue