summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorSam Spilsbury <sam.spilsbury@canonical.com>2010-12-08 00:54:29 +0800
committerSam Spilsbury <sam.spilsbury@canonical.com>2010-12-08 00:54:29 +0800
commitabb087437f97baa09046b4d081c10a71de5f97ad (patch)
treefac3e67b4076d9d867d4e9e7f68c1b3fcaa1f33d /src
parent9211a51cf0cc98ae6fef4a33a4cc13c3f0959ac0 (diff)
parent4666435ec53105675c67225e6d5fd18101627353 (diff)
downloadcompiz-with-glib-mainloop-abb087437f97baa09046b4d081c10a71de5f97ad.tar.gz
compiz-with-glib-mainloop-abb087437f97baa09046b4d081c10a71de5f97ad.tar.bz2
Merge git://git.compiz.org/compiz/core into glibmm-experimental
Conflicts: include/core/screen.h
Diffstat (limited to 'src')
-rw-r--r--src/event.cpp1
-rw-r--r--src/main.cpp101
-rw-r--r--src/plugin.cpp22
-rw-r--r--src/privatescreen.h29
-rw-r--r--src/privatewindow.h3
-rw-r--r--src/screen.cpp239
-rw-r--r--src/window.cpp207
7 files changed, 406 insertions, 196 deletions
diff --git a/src/event.cpp b/src/event.cpp
index 4d7a2c6..ee4ddfd 100644
--- a/src/event.cpp
+++ b/src/event.cpp
@@ -1085,7 +1085,6 @@ CompScreen::handleEvent (XEvent *event)
priv->setWmState (WithdrawnState, w->id ());
w->priv->placed = false;
- w->priv->managed = false;
w->priv->unmanaging = true;
if (w->priv->frame)
{
diff --git a/src/main.cpp b/src/main.cpp
index ea8b509..a8e4445 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -57,10 +57,12 @@ bool useDesktopHints = false;
bool debugOutput = false;
bool useCow = true;
+std::list <CompString> initialPlugins;
+
unsigned int pluginClassHandlerIndex = 0;
-static void
-usage (void)
+void
+CompManager::usage ()
{
printf ("Usage: %s "
"[--replace] "
@@ -99,35 +101,20 @@ signalHandler (int sig)
}
}
-int
-main (int argc, char **argv)
+bool
+CompManager::parseArguments (int argc, char **argv)
{
- char *displayName = 0;
- std::vector<CompString> plugins;
- int i;
- bool disableSm = false;
- char *clientId = NULL;
-
- programName = argv[0];
- programArgc = argc;
- programArgv = argv;
-
- signal (SIGHUP, signalHandler);
- signal (SIGCHLD, signalHandler);
- signal (SIGINT, signalHandler);
- signal (SIGTERM, signalHandler);
-
- for (i = 1; i < argc; i++)
+ for (int i = 1; i < argc; i++)
{
if (!strcmp (argv[i], "--help"))
{
usage ();
- return 0;
+ return false;
}
else if (!strcmp (argv[i], "--version"))
{
printf (PACKAGE_STRING "\n");
- return 0;
+ return false;
}
else if (!strcmp (argv[i], "--debug"))
{
@@ -183,14 +170,34 @@ main (int argc, char **argv)
}
}
+ initialPlugins = plugins;
+
+ return true;
+}
+
+CompManager::CompManager () :
+ disableSm (false)
+{
+}
+
+bool
+CompManager::init ()
+{
screen = new CompScreen ();
- if (!screen)
- return 1;
+
+ if (!screen || !screen->priv)
+ return false;
+
+ if (screen->priv->createFailed ())
+ {
+ delete screen;
+ return false;
+ }
modHandler = new ModifierHandler ();
if (!modHandler)
- return 1;
+ return false;
if (!plugins.empty ())
{
@@ -210,21 +217,59 @@ main (int argc, char **argv)
o->set (value);
}
- if (!screen->init (displayName))
- return 1;
+ screen->priv->dirtyPluginList = true;
+ screen->priv->updatePlugins ();
- modHandler->updateModifierMappings ();
+ if (!screen->init (displayName))
+ return false;
if (!disableSm)
CompSession::init (clientId);
+ return true;
+}
+
+void
+CompManager::run ()
+{
screen->eventLoop ();
+}
+void
+CompManager::fini ()
+{
if (!disableSm)
CompSession::close ();
delete screen;
delete modHandler;
+}
+
+
+
+int
+main (int argc, char **argv)
+{
+ CompManager manager;
+
+ programName = argv[0];
+ programArgc = argc;
+ programArgv = argv;
+
+ signal (SIGHUP, signalHandler);
+ signal (SIGCHLD, signalHandler);
+ signal (SIGINT, signalHandler);
+ signal (SIGTERM, signalHandler);
+
+ if (!manager.parseArguments (argc, argv))
+ return 0;
+
+ if (!manager.init ())
+ return 1;
+
+ manager.run ();
+
+ manager.fini ();
if (restartSignal)
{
diff --git a/src/plugin.cpp b/src/plugin.cpp
index f9d8954..dd5bc7e8 100644
--- a/src/plugin.cpp
+++ b/src/plugin.cpp
@@ -264,8 +264,8 @@ UnloadPluginProc loaderUnloadPlugin = dlloaderUnloadPlugin;
ListPluginsProc loaderListPlugins = dlloaderListPlugins;
-static bool
-initPlugin (CompPlugin *p)
+bool
+CompManager::initPlugin (CompPlugin *p)
{
if (!p->vTable->init ())
@@ -275,7 +275,7 @@ initPlugin (CompPlugin *p)
return false;
}
- if (screen)
+ if (screen && screen->priv->initialized)
{
if (!p->vTable->initScreen (screen))
{
@@ -294,8 +294,8 @@ initPlugin (CompPlugin *p)
return true;
}
-static void
-finiPlugin (CompPlugin *p)
+void
+CompManager::finiPlugin (CompPlugin *p)
{
if (screen)
@@ -351,18 +351,18 @@ CompScreen::finiPluginForScreen (CompPlugin *p)
bool
CompPlugin::screenInitPlugins (CompScreen *s)
{
- CompPlugin::List::reverse_iterator rit = plugins.rbegin ();
+ CompPlugin::List::iterator it = plugins.begin ();
CompPlugin *p = NULL;
- while (rit != plugins.rend ())
+ while (it != plugins.end ())
{
- p = (*rit);
+ p = (*it);
if (p->vTable->initScreen (s))
s->initPluginForScreen (p);
- rit++;
+ it++;
}
return true;
@@ -491,7 +491,7 @@ CompPlugin::push (CompPlugin *p)
plugins.push_front (p);
- if (!initPlugin (p))
+ if (!CompManager::initPlugin (p))
{
compLogMessage ("core", CompLogLevelError,
"Couldn't activate plugin '%s'", name);
@@ -518,7 +518,7 @@ CompPlugin::pop (void)
pluginsMap.erase (p->vTable->name ().c_str ());
- finiPlugin (p);
+ CompManager::finiPlugin (p);
plugins.pop_front ();
diff --git a/src/privatescreen.h b/src/privatescreen.h
index 0f03d83..f6b9bb9 100644
--- a/src/privatescreen.h
+++ b/src/privatescreen.h
@@ -78,6 +78,8 @@ extern bool inHandleEvent;
extern CompScreen *targetScreen;
extern CompOutput *targetOutput;
+extern std::list <CompString> initialPlugins;
+
typedef struct _CompDelayedEdgeSettings
{
@@ -345,6 +347,9 @@ class PrivateScreen : public CoreOptions {
CompWindow *
focusTopMostWindow ();
+ bool
+ createFailed ();
+
public:
PrivateScreen *priv;
@@ -485,4 +490,28 @@ class PrivateScreen : public CoreOptions {
bool initialized;
};
+class CompManager
+{
+ public:
+
+ CompManager ();
+
+ bool init ();
+ void run ();
+ void fini ();
+
+ bool parseArguments (int, char **);
+ void usage ();
+
+ static bool initPlugin (CompPlugin *p);
+ static void finiPlugin (CompPlugin *p);
+
+ private:
+
+ std::list <CompString> plugins;
+ bool disableSm;
+ char *clientId;
+ char *displayName;
+};
+
#endif
diff --git a/src/privatewindow.h b/src/privatewindow.h
index 59521be..f750674 100644
--- a/src/privatewindow.h
+++ b/src/privatewindow.h
@@ -172,7 +172,8 @@ class PrivateWindow {
unsigned int adjustConfigureRequestForGravity (XWindowChanges *xwc,
unsigned int xwcm,
- int gravity);
+ int gravity,
+ int direction);
void updateSize ();
diff --git a/src/screen.cpp b/src/screen.cpp
index 4b7d95a..e296b03 100644
--- a/src/screen.cpp
+++ b/src/screen.cpp
@@ -868,48 +868,117 @@ PrivateScreen::processEvents ()
void
PrivateScreen::updatePlugins ()
{
- CompPlugin *p;
- unsigned int nPop, i, j;
- CompPlugin::List pop;
- bool failedPush;
+ CompPlugin *p;
+ unsigned int nPop, i, j, pListCount = 1;
+ CompOption::Value::Vector pList;
+ CompPlugin::List pop;
+ bool failedPush;
dirtyPluginList = false;
CompOption::Value::Vector &list = optionGetActivePlugins ();
- /* The old plugin list always begins with the core plugin. To make sure
- we don't unnecessarily unload plugins if the new plugin list does not
- contain the core plugin, we have to use an offset */
+ /* Determine the number of plugins, which is core +
+ * initial plugins + plugins in option list in addition
+ * to initial plugins */
+ foreach (CompString &pn, initialPlugins)
+ {
+ if (pn != "core")
+ pListCount++;
+ }
- if (list.size () > 0 && list[0].s () != "core")
- i = 0;
- else
- i = 1;
+ foreach (CompOption::Value &lp, list)
+ {
+ bool skip = false;
+ if (lp.s () == "core")
+ continue;
+
+ foreach (CompString &p, initialPlugins)
+ {
+ if (p == lp.s ())
+ {
+ skip = true;
+ break;
+ }
+ }
+
+ /* plugin not in initial list */
+ if (!skip)
+ pListCount++;
+ }
+
+ /* dupPluginCount is now the number of plugisn contained in both the
+ * initial and new plugins list */
+ pList.resize (pListCount);
+
+ if (pList.empty ())
+ {
+ screen->setOptionForPlugin ("core", "active_plugins", plugin);
+ return;
+ }
+
+ /* Must have core as first plugin */
+ pList.at (0) = "core";
+ j = 1;
+
+ /* Add initial plugins */
+ foreach (CompString &p, initialPlugins)
+ {
+ if (p == "core")
+ continue;
+ pList.at (j).set (p);
+ j++;
+ }
+
+ /* Add plugins not in the initial list */
+ foreach (CompOption::Value &opt, list)
+ {
+ std::list <CompString>::iterator it = initialPlugins.begin ();
+ bool skip = false;
+ if (opt.s () == "core")
+ continue;
+
+ for (; it != initialPlugins.end (); it++)
+ {
+ if ((*it) == opt.s ())
+ {
+ skip = true;
+ break;
+ }
+ }
+
+ if (!skip)
+ pList.at (j++).set (opt.s ());
+ }
+
+ assert (j == pList.size ());
/* j is initialized to 1 to make sure we never pop the core plugin */
- for (j = 1; j < plugin.list ().size () &&
- i < list.size (); i++, j++)
+ for (i = j = 1; j < plugin.list ().size () && i < pList.size (); i++, j++)
{
- if (plugin.list ()[j].s () != list[i].s ())
+ if (plugin.list ().at (j).s () != pList.at (i).s ())
break;
}
nPop = plugin.list ().size () - j;
- for (j = 0; j < nPop; j++)
+ if (nPop)
{
- pop.push_back (CompPlugin::pop ());
- plugin.list ().pop_back ();
+ for (j = 0; j < nPop; j++)
+ {
+ pop.push_back (CompPlugin::pop ());
+ plugin.list ().pop_back ();
+ }
}
- for (; i < list.size (); i++)
+ for (; i < pList.size (); i++)
{
p = NULL;
failedPush = false;
foreach (CompPlugin *pp, pop)
{
- if (list[i]. s () == pp->vTable->name ())
+ if (pList[i]. s () == pp->vTable->name ())
{
if (CompPlugin::push (pp))
{
@@ -930,7 +999,7 @@ PrivateScreen::updatePlugins ()
if (p == 0 && !failedPush)
{
- p = CompPlugin::load (list[i].s ().c_str ());
+ p = CompPlugin::load (pList[i].s ().c_str ());
if (p)
{
if (!CompPlugin::push (p))
@@ -4160,13 +4229,46 @@ CompScreen::screenInfo ()
return priv->screenInfo;
}
+bool
+PrivateScreen::createFailed ()
+{
+ return !screenInitalized;
+}
+
CompScreen::CompScreen ():
PluginClassStorage (screenPluginClassIndices),
priv (NULL)
{
+ CompPrivate p;
+ CompOption::Value::Vector vList;
+ CompPlugin *corePlugin;
+
priv = new PrivateScreen (this);
assert (priv);
+
screenInitalized = true;
+
+ corePlugin = CompPlugin::load ("core");
+ if (!corePlugin)
+ {
+ compLogMessage ("core", CompLogLevelFatal,
+ "Couldn't load core plugin");
+ screenInitalized = false;
+ }
+
+ if (!CompPlugin::push (corePlugin))
+ {
+ compLogMessage ("core", CompLogLevelFatal,
+ "Couldn't activate core plugin");
+ screenInitalized = false;
+ }
+
+ p.uval = CORE_ABIVERSION;
+ storeValue ("core_ABI", p);
+
+ vList.push_back ("core");
+
+ priv->plugin.set (CompOption::TypeString, vList);
}
bool
@@ -4195,31 +4297,6 @@ CompScreen::init (const char *name)
int nvisinfo;
XSetWindowAttributes attrib;
- CompOption::Value::Vector vList;
-
- CompPlugin *corePlugin = CompPlugin::load ("core");
- if (!corePlugin)
- {
- compLogMessage ("core", CompLogLevelFatal,
- "Couldn't load core plugin");
- return false;
- }
-
- if (!CompPlugin::push (corePlugin))
- {
- compLogMessage ("core", CompLogLevelFatal,
- "Couldn't activate core plugin");
- return false;
- }
-
- CompPrivate p;
- p.uval = CORE_ABIVERSION;
- storeValue ("core_ABI", p);
-
- vList.push_back ("core");
-
- priv->plugin.set (CompOption::TypeString, vList);
-
dpy = priv->dpy = XOpenDisplay (name);
if (!priv->dpy)
{
@@ -4363,6 +4440,8 @@ CompScreen::init (const char *name)
} while (event.type != DestroyNotify);
}
+ modHandler->updateModifierMappings ();
+
CompScreen::checkForError (dpy);
XGrabServer (dpy);
@@ -4391,9 +4470,6 @@ CompScreen::init (const char *name)
return false;
}
- priv->vpSize.setWidth (priv->optionGetHsize ());
- priv->vpSize.setHeight (priv->optionGetVsize ());
-
for (i = 0; i < SCREEN_EDGE_NUM; i++)
{
priv->screenEdge[i].id = None;
@@ -4470,24 +4546,6 @@ CompScreen::init (const char *name)
priv->getDesktopHints ();
- /* TODO: bailout properly when objectInitPlugins fails */
- assert (CompPlugin::screenInitPlugins (this));
-
- XQueryTree (dpy, priv->root,
- &rootReturn, &parentReturn,
- &children, &nchildren);
-
- for (unsigned int i = 0; i < nchildren; i++)
- new CompWindow (children[i], i ? children[i - 1] : 0);
-
- foreach (CompWindow *w, priv->windows)
- {
- if (w->isViewable ())
- w->priv->activeNum = priv->activeNum++;
- }
-
- XFree (children);
-
attrib.override_redirect = 1;
attrib.event_mask = PropertyChangeMask;
@@ -4535,6 +4593,47 @@ CompScreen::init (const char *name)
priv->setAudibleBell (priv->optionGetAudibleBell ());
+ priv->pingTimer.setTimes (priv->optionGetPingDelay (),
+ priv->optionGetPingDelay () + 500);
+
+ priv->pingTimer.start ();
+
+ priv->addScreenActions ();
+
+ priv->initialized = true;
+
+ /* TODO: Bailout properly when screenInitPlugins fails
+ * TODO: It would be nicer if this line could mean
+ * "init all the screens", but unfortunately it only inits
+ * plugins loaded on the command line screen's and then
+ * we need to call updatePlugins () to init the remaining
+ * screens from option changes */
+ assert (CompPlugin::screenInitPlugins (this));
+
+ /* The active plugins list might have been changed - load any
+ * new plugins */
+
+ if (priv->dirtyPluginList)
+ priv->updatePlugins ();
+
+ priv->vpSize.setWidth (priv->optionGetHsize ());
+ priv->vpSize.setHeight (priv->optionGetVsize ());
+
+ XQueryTree (dpy, priv->root,
+ &rootReturn, &parentReturn,
+ &children, &nchildren);
+
+ for (unsigned int i = 0; i < nchildren; i++)
+ new CompWindow (children[i], i ? children[i - 1] : 0);
+
+ foreach (CompWindow *w, priv->windows)
+ {
+ if (w->isViewable ())
+ w->priv->activeNum = priv->activeNum++;
+ }
+
+ XFree (children);
+
XGetInputFocus (dpy, &focus, &revertTo);
/* move input focus to root window so that we get a FocusIn event when
@@ -4556,14 +4655,6 @@ CompScreen::init (const char *name)
focusDefaultWindow ();
}
- priv->pingTimer.setTimes (priv->optionGetPingDelay (),
- priv->optionGetPingDelay () + 500);
-
- priv->pingTimer.start ();
-
- priv->initialized = true;
- priv->addScreenActions ();
-
return true;
}
diff --git a/src/window.cpp b/src/window.cpp
index dd8d24d..93b5c2c 100644
--- a/src/window.cpp
+++ b/src/window.cpp
@@ -1345,6 +1345,28 @@ CompWindow::unmap ()
if (priv->unmapRefCnt > 0)
return;
+ if (priv->managed && !priv->placed)
+ {
+ XWindowChanges xwc;
+ unsigned int xwcm;
+ int gravity = priv->sizeHints.win_gravity;
+
+ /* revert gravity adjustment made at MapNotify time */
+ xwc.x = priv->serverGeometry.x ();
+ xwc.y = priv->serverGeometry.y ();
+ xwc.width = 0;
+ xwc.height = 0;
+
+ xwcm = priv->adjustConfigureRequestForGravity (&xwc,
+ CWX | CWY,
+ gravity,
+ -1);
+ if (xwcm)
+ configureXWindow (xwcm, &xwc);
+
+ priv->managed = false;
+ }
+
if (priv->struts)
screen->updateWorkarea ();
@@ -1750,8 +1772,65 @@ void
CompWindow::validateResizeRequest (unsigned int &mask,
XWindowChanges *xwc,
unsigned int source)
+{
WRAPABLE_HND_FUNC (5, validateResizeRequest, mask, xwc, source)
+ if (!(priv->type & (CompWindowTypeDockMask |
+ CompWindowTypeFullscreenMask |
+ CompWindowTypeUnknownMask)))
+ {
+ if (mask & CWY)
+ {
+ int min, max;
+
+ min = screen->workArea ().y () + priv->input.top;
+ max = screen->workArea ().bottom ();
+
+ if (priv->state & CompWindowStateStickyMask &&
+ (xwc->y < min || xwc->y > max))
+ {
+ xwc->y = priv->serverGeometry.y ();
+ }
+ else
+ {
+ min -= screen->vp ().y () * screen->height ();
+ max += (screen->vpSize ().height () - screen->vp ().y () - 1) *
+ screen->height ();
+
+ if (xwc->y < min)
+ xwc->y = min;
+ else if (xwc->y > max)
+ xwc->y = max;
+ }
+ }
+
+ if (mask & CWX)
+ {
+ int min, max;
+
+ min = screen->workArea ().x () + priv->input.left;
+ max = screen->workArea ().right ();
+
+ if (priv->state & CompWindowStateStickyMask &&
+ (xwc->x < min || xwc->x > max))
+ {
+ xwc->x = priv->serverGeometry.x ();
+ }
+ else
+ {
+ min -= screen->vp ().x () * screen->width ();
+ max += (screen->vpSize ().width () - screen->vp ().x () - 1) *
+ screen->width ();
+
+ if (xwc->x < min)
+ xwc->x = min;
+ else if (xwc->x > max)
+ xwc->x = max;
+ }
+ }
+ }
+}
+
void
CompWindow::resizeNotify (int dx,
int dy,
@@ -2741,7 +2820,8 @@ PrivateWindow::addWindowSizeChanges (XWindowChanges *xwc,
unsigned int
PrivateWindow::adjustConfigureRequestForGravity (XWindowChanges *xwc,
unsigned int xwcm,
- int gravity)
+ int gravity,
+ int direction)
{
int newX, newY;
unsigned int mask = 0;
@@ -2756,26 +2836,26 @@ PrivateWindow::adjustConfigureRequestForGravity (XWindowChanges *xwc,
case WestGravity:
case SouthWestGravity:
if (xwcm & CWX)
- newX += priv->input.left;
+ newX += priv->input.left * direction;
break;
case NorthGravity:
case CenterGravity:
case SouthGravity:
if (xwcm & CWX)
- newX -= xwc->width / 2 - priv->input.left +
- (priv->input.left + priv->input.right) / 2;
+ newX -= (xwc->width / 2 - priv->input.left +
+ (priv->input.left + priv->input.right) / 2) * direction;
else
- newX -= (xwc->width - priv->serverGeometry.width ());
+ newX -= (xwc->width - priv->serverGeometry.width ()) * direction;
break;
case NorthEastGravity:
case EastGravity:
case SouthEastGravity:
if (xwcm & CWX)
- newX -= xwc->width + priv->input.right;
+ newX -= xwc->width + priv->input.right * direction;
else
- newX -= xwc->width - priv->serverGeometry.width ();
+ newX -= (xwc->width - priv->serverGeometry.width ()) * direction;
break;
case StaticGravity:
@@ -2791,26 +2871,26 @@ PrivateWindow::adjustConfigureRequestForGravity (XWindowChanges *xwc,
case NorthGravity:
case NorthEastGravity:
if (xwcm & CWY)
- newY = xwc->y + priv->input.top;
+ newY = xwc->y + priv->input.top * direction;
break;
case WestGravity:
case CenterGravity:
case EastGravity:
if (xwcm & CWY)
- newY -= xwc->height / 2 - priv->input.top +
- (priv->input.top + priv->input.bottom) / 2;
+ newY -= (xwc->height / 2 - priv->input.top +
+ (priv->input.top + priv->input.bottom) / 2) * direction;
else
- newY -= (xwc->height - priv->serverGeometry.height ()) / 2;
+ newY -= ((xwc->height - priv->serverGeometry.height ()) / 2) * direction;
break;
case SouthWestGravity:
case SouthGravity:
case SouthEastGravity:
if (xwcm & CWY)
- newY -= xwc->height + priv->input.bottom;
+ newY -= xwc->height + priv->input.bottom * direction;
else
- newY -= xwc->height - priv->serverGeometry.height ();
+ newY -= (xwc->height - priv->serverGeometry.height ()) * direction;
break;
case StaticGravity:
@@ -2877,62 +2957,7 @@ CompWindow::moveResize (XWindowChanges *xwc,
}
}
- xwcm |= priv->adjustConfigureRequestForGravity (xwc, xwcm, gravity);
-
- if (!(priv->type & (CompWindowTypeDockMask |
- CompWindowTypeFullscreenMask |
- CompWindowTypeUnknownMask)))
- {
- if (xwcm & CWY)
- {
- int min, max;
-
- min = screen->workArea ().y () + priv->input.top;
- max = screen->workArea ().bottom ();
-
- if (priv->state & CompWindowStateStickyMask &&
- (xwc->y < min || xwc->y > max))
- {
- xwc->y = priv->serverGeometry.y ();
- }
- else
- {
- min -= screen->vp ().y () * screen->height ();
- max += (screen->vpSize ().height () - screen->vp ().y () - 1) *
- screen->height ();
-
- if (xwc->y < min)
- xwc->y = min;
- else if (xwc->y > max)
- xwc->y = max;
- }
- }
-
- if (xwcm & CWX)
- {
- int min, max;
-
- min = screen->workArea ().x () + priv->input.left;
- max = screen->workArea ().right ();
-
- if (priv->state & CompWindowStateStickyMask &&
- (xwc->x < min || xwc->x > max))
- {
- xwc->x = priv->serverGeometry.x ();
- }
- else
- {
- min -= screen->vp ().x () * screen->width ();
- max += (screen->vpSize ().width () - screen->vp ().x () - 1) *
- screen->width ();
-
- if (xwc->x < min)
- xwc->x = min;
- else if (xwc->x > max)
- xwc->x = max;
- }
- }
- }
+ xwcm |= priv->adjustConfigureRequestForGravity (xwc, xwcm, gravity, 1);
validateResizeRequest (xwcm, xwc, source);
@@ -3151,10 +3176,10 @@ CompWindow::lower ()
the click-to-focus option is on */
if ((screen->getOption ("click_to_focus")->value ().b ()))
{
- Window aboveId = next ? next->id () : None;
+ Window aboveWindowId = prev ? prev->id () : None;
screen->unhookWindow (this);
CompWindow *focusedWindow = screen->priv->focusTopMostWindow ();
- screen->insertWindow (this , aboveId);
+ screen->insertWindow (this , aboveWindowId);
/* if the newly focused window is a desktop window,
give the focus back to w */
@@ -3191,6 +3216,21 @@ PrivateWindow::findValidStackSiblingBelow (CompWindow *w,
{
CompWindow *lowest, *last, *p;
+ /* check whether we're allowed to stack under a sibling by finding
+ * the above 'sibling' and checking whether or not we're allowed
+ * to stack under that - if not, then there is no valid sibling
+ * underneath it */
+
+ for (p = sibling; p; p = p->next)
+ {
+ if (!avoidStackingRelativeTo (p))
+ {
+ if (!validSiblingBelow (p, w))
+ return NULL;
+ break;
+ }
+ }
+
/* get lowest sibling we're allowed to stack above */
lowest = last = findLowestSiblingBelow (w);
@@ -3289,14 +3329,19 @@ CompWindow::updateAttributes (CompStackingUpdateMode stackingMode)
if (p->priv->id == screen->activeWindow ())
break;
- /* window is above active window so we should lower it */
- if (p)
+ /* window is above active window so we should lower it,
+ * assuing that is allowed (if, for example, our window has
+ * the "above" state, then lowering beneath the active
+ * window may not be allowed). */
+ if (p && PrivateWindow::validSiblingBelow (p, this))
+ {
p = PrivateWindow::findValidStackSiblingBelow (sibling, p);
- /* if we found a valid sibling under the active window, it's
- our new sibling we want to stack above */
- if (p)
- sibling = p;
+ /* if we found a valid sibling under the active window, it's
+ our new sibling we want to stack above */
+ if (p)
+ sibling = p;
+ }
}
mask |= priv->addWindowStackChanges (&xwc, sibling);
@@ -4587,13 +4632,13 @@ PrivateWindow::processMap ()
XWindowChanges xwc;
unsigned int xwcm;
- /* adjust for gravity */
+ /* adjust for gravity, but only for frame size */
xwc.x = priv->serverGeometry.x ();
xwc.y = priv->serverGeometry.y ();
- xwc.width = priv->serverGeometry.width ();
- xwc.height = priv->serverGeometry.height ();
+ xwc.width = 0;
+ xwc.height = 0;
- xwcm = adjustConfigureRequestForGravity (&xwc, CWX | CWY, gravity);
+ xwcm = adjustConfigureRequestForGravity (&xwc, CWX | CWY, gravity, 1);
window->validateResizeRequest (xwcm, &xwc, ClientTypeApplication);