782
782
height = input.top + input.bottom;
784
XMoveResizeWindow (screen->dpy (), frame, x, y, width, height);
784
/* Geometry is the same, so we're not going to get a ConfigureNotify
785
* event when the window is configured, which means that other plugins
786
* won't know that the client, frame and wrapper windows got shifted
787
* around (and might result in display corruption, eg in OpenGL */
788
if (geometry.x () - input.left == x &&
789
geometry.y () - input.top == y &&
790
geometry.width () + input.left + input.right + bw == width &&
791
geometry.height () + input.top + input.bottom + bw == height)
795
xev.type = ConfigureNotify;
796
xev.event = screen->root ();
797
xev.window = priv->frame;
803
xev.border_width = window->priv->attrib.border_width;
805
xev.above = (window->prev) ? ROOTPARENT (window->prev) : None;
806
xev.override_redirect = window->priv->attrib.override_redirect;
808
XSendEvent (screen->dpy (), screen->root (), false,
809
SubstructureNotifyMask, (XEvent *) &xev);
812
XMoveResizeWindow (screen->dpy (), frame, x, y, width, height);
787
816
XUnmapWindow (screen->dpy (), wrapper);
823
852
XMoveResizeWindow (screen->dpy (), wrapper, 0, 0,
824
853
serverGeometry.width (), serverGeometry.height ());
826
856
XMoveResizeWindow (screen->dpy (), id, 0, 0,
827
857
serverGeometry.width (), serverGeometry.height ());
828
858
window->sendConfigureNotify ();
829
859
frameRegion = CompRegion ();
830
860
window->windowNotify (CompWindowNotifyFrameUpdate);
833
862
window->recalcActions ();
1314
1342
if (priv->mapNum)
1315
1343
priv->mapNum = 0;
1345
/* Even though we're still keeping the backing
1346
* pixmap of the window around, it's safe to
1347
* unmap the frame window since there's no use
1348
* for it at this point anyways and it just blocks
1351
XUnmapWindow (screen->dpy (), priv->wrapper);
1352
XUnmapWindow (screen->dpy (), priv->frame);
1317
1354
priv->unmapRefCnt--;
1318
1355
if (priv->unmapRefCnt > 0)
1426
1463
CompWindow::resize (CompWindow::Geometry gm)
1428
if (priv->geometry.x () != gm.width () ||
1429
priv->geometry.y () != gm.height () ||
1465
if (priv->geometry.width () != gm.width () ||
1466
priv->geometry.height () != gm.height () ||
1430
1467
priv->geometry.border () != gm.border ())
2042
CompWindowList dockWindows;
2004
2046
screen->priv->nextActiveWindow = priv->id;
2048
/* Ensure that docks are stacked in the right place
2050
* When a normal window gets the focus and is above a
2051
* fullscreen window, restack the docks to be above
2052
* the highest level mapped and visible normal window,
2053
* otherwise put them above the highest fullscreen window
2055
if (PrivateWindow::stackDocks (this, dockWindows, &xwc, &mask))
2057
Window sibling = xwc.sibling;
2058
xwc.stack_mode = Above;
2060
/* Then update the dock windows */
2061
foreach (CompWindow *dw, dockWindows)
2063
xwc.sibling = sibling;
2064
dw->configureXWindow (mask, &xwc);
2006
2069
if (!setFocus && !modalTransient)
2008
2071
CompWindow *ancestor;
2190
2253
/* fullscreen and normal layer */
2191
if (!(below->priv->type & belowMask))
2254
if (!(below->priv->type & belowMask))
2192
2256
if (stackLayerCheck (w, clientLeader, below))
2532
PrivateWindow::stackDocks (CompWindow *w,
2533
CompWindowList &updateList,
2534
XWindowChanges *xwc,
2537
CompWindow *firstFullscreenWindow = NULL;
2538
CompWindow *belowDocks = NULL;
2540
foreach (CompWindow *dw, screen->windows ())
2542
/* fullscreen window found */
2543
if (firstFullscreenWindow)
2545
/* If there is another toplevel window above the fullscreen one
2546
* then we need to stack above that */
2548
!PrivateWindow::isAncestorTo (w, dw) &&
2549
!(dw->type () & (CompWindowTypeFullscreenMask |
2550
CompWindowTypeDockMask)) &&
2551
!dw->overrideRedirect () &&
2552
dw->defaultViewport () == screen->vp () &&
2558
else if (dw->type () & CompWindowTypeFullscreenMask)
2560
/* First fullscreen window found when checking up the stack
2561
* now go back down to find a suitable candidate client
2562
* window to put the docks above */
2563
firstFullscreenWindow = dw;
2564
for (CompWindow *dww = dw->prev; dww; dww = dww->prev)
2566
if (!(dww->type () & (CompWindowTypeFullscreenMask |
2567
CompWindowTypeDockMask)) &&
2568
!dww->overrideRedirect () &&
2569
dww->defaultViewport () == screen->vp () &&
2581
*mask = CWSibling | CWStackMode;
2582
xwc->sibling = ROOTPARENT (belowDocks);
2584
/* Collect all dock windows first */
2585
foreach (CompWindow *dw, screen->windows ())
2586
if (dw->priv->type & CompWindowTypeDockMask)
2587
updateList.push_front (dw);
2467
2596
PrivateWindow::stackTransients (CompWindow *w,
2468
2597
CompWindow *avoid,
2469
2598
XWindowChanges *xwc,
2577
2706
CompWindowList transients;
2578
2707
CompWindowList ancestors;
2579
CompWindow *siblingToThisWindow;
2580
unsigned int stackMode;
2708
CompWindowList docks;
2582
2710
/* Since the window list is being reordered in reconfigureXWindow
2583
2711
the list of windows which need to be restacked must be stored
2599
2727
xwc->sibling = ROOTPARENT (*w);
2602
/* First restack this window */
2603
2730
this->priv->reconfigureXWindow (valueMask, xwc);
2604
siblingToThisWindow = screen->findTopLevelWindow (xwc->sibling);
2605
stackMode = xwc->stack_mode;
2607
2731
xwc->sibling = ROOTPARENT (this);
2609
/* Now restack the transient children above */
2610
2733
for (CompWindowList::reverse_iterator w = transients.rbegin ();
2611
2734
w != transients.rend (); w++)
2614
2737
xwc->sibling = ROOTPARENT (*w);
2617
if (siblingToThisWindow && stackMode == Above)
2740
if (PrivateWindow::stackDocks (this, docks, xwc, &valueMask))
2619
/* a normal window can be stacked above fullscreen windows but we
2620
don't want normal windows to be stacked above dock window so if
2621
the sibling we're stacking above is a fullscreen window we also
2622
update all dock windows. */
2623
if ((siblingToThisWindow->priv->type & CompWindowTypeFullscreenMask) &&
2624
(!(this->priv-> type & (CompWindowTypeFullscreenMask |
2625
CompWindowTypeDockMask))) &&
2626
!PrivateWindow::isAncestorTo (this, siblingToThisWindow))
2628
XWindowChanges dxwc;
2629
unsigned int dmask = CWSibling | CWStackMode;
2632
/* Find the sibling fullscreen window */
2633
for (dw = screen->windows ().back (); dw; dw = dw->prev)
2634
if (dw == siblingToThisWindow)
2637
/* Collect all dock windows first */
2638
CompWindowList dockWindows;
2639
for (; dw; dw = dw->prev)
2640
if (dw->priv->type & CompWindowTypeDockMask)
2641
dockWindows.push_back (dw);
2643
/* Then update the dock windows */
2644
foreach (CompWindow *dw, dockWindows)
2646
/* Stack above the window being stacked above the docks */
2647
dxwc.stack_mode = Above;
2648
dxwc.sibling = ROOTPARENT (this);
2650
dw->configureXWindow (dmask, &dxwc);
2742
Window sibling = xwc->sibling;
2743
xwc->stack_mode = Above;
2745
/* Then update the dock windows */
2746
foreach (CompWindow *dw, docks)
2748
xwc->sibling = sibling;
2749
dw->priv->reconfigureXWindow (valueMask, xwc);
2878
2976
case WestGravity:
2879
2977
case SouthWestGravity:
2880
2978
if (xwcm & CWX)
2881
newX += priv->input.left * direction;
2979
newX += priv->border.left * direction;
2884
2982
case NorthGravity:
2885
2983
case CenterGravity:
2886
2984
case SouthGravity:
2887
2985
if (xwcm & CWX)
2888
newX -= (xwc->width / 2 - priv->input.left +
2889
(priv->input.left + priv->input.right) / 2) * direction;
2986
newX -= (xwc->width / 2 - priv->border.left +
2987
(priv->border.left + priv->border.right) / 2) * direction;
2891
2989
newX -= (xwc->width - priv->serverGeometry.width ()) * direction;
3096
XLowerWindow (screen->dpy (), id);
3098
3195
XLowerWindow (screen->dpy (), frame);
3196
XLowerWindow (screen->dpy (), id);
3100
3198
/* Restacking of compiz's window list happens
3101
3199
* immediately and since this path doesn't call
3338
3436
/* put active or soon-to-be-active fullscreen windows over
3339
3437
all others in their layer */
3340
if (priv->id == screen->activeWindow ())
3438
if (priv->id == screen->activeWindow () ||
3439
priv->id == screen->priv->nextActiveWindow)
3342
3441
aboveFs = true;
4710
4808
window->updateAttributes (stackingMode);
4712
/* Window was either minimized by us, or it was mapped again
4713
* since it has gone from withdrawn to iconic state, so
4715
if (window->minimized () && (window->pendingMaps () || wasManaged))
4810
if (window->minimized ())
4716
4811
window->unminimize ();
4718
4813
screen->leaveShowDesktopMode (window);
5171
5266
return priv->syncAlarm;
5174
CompWindow::CompWindow (Window aboveId,
5270
CoreWindow::manage (Window aboveId, XWindowAttributes &wa)
5272
return new CompWindow (aboveId, wa, priv);
5275
CoreWindow::CoreWindow (Window id)
5277
priv = new PrivateWindow ();
5282
CompWindow::CompWindow (Window aboveId,
5175
5283
XWindowAttributes &wa,
5176
PrivateWindow *priv) :
5284
PrivateWindow *priv) :
5177
5285
PluginClassStorage (windowPluginClassIndices),
5325
5434
else if (!overrideRedirect ())
5327
if (screen->priv->getWmState (priv->id) == IconicState ||
5328
(priv->hints && priv->hints->initial_state == IconicState))
5436
if (screen->priv->getWmState (priv->id) == IconicState)
5330
5438
// before everything else in maprequest
5331
5439
if (!priv->frame)
5332
5440
priv->reparent ();
5334
/* Not managed until map processing is done here
5335
* since to go from Withdrawn -> Iconic the client
5336
* needs to map the window again */
5337
priv->managed = false;
5338
priv->placed = !(priv->hints && priv->hints->initial_state == IconicState);
5341
/* FIXME: CompWindowStateShadedMask can't be set
5342
* at this time anyways, so any window that wants
5343
* to start out shaded will have to be minimized instead */
5344
if (priv->state & CompWindowStateShadedMask)
5345
priv->shaded = true;
5347
priv->minimized = true;
5441
priv->managed = true;
5442
priv->placed = true;
5444
if (priv->state & CompWindowStateHiddenMask)
5446
if (priv->state & CompWindowStateShadedMask)
5447
priv->shaded = true;
5449
priv->minimized = true;
5369
CoreWindow::manage (Window aboveId, XWindowAttributes &wa)
5371
return new CompWindow (aboveId, wa, priv);
5374
CoreWindow::CoreWindow (Window id)
5376
priv = new PrivateWindow ();
5381
5471
CompWindow::~CompWindow ()
5383
5473
screen->unhookWindow (this);
5722
5812
Atoms::frameExtents,
5723
5813
XA_CARDINAL, 32, PropModeReplace,
5724
5814
(unsigned char *) data, 4);
5725
5816
priv->updateSize ();
5726
5817
priv->updateFrameWindow ();
5834
5925
/* Reparent the client into the wrapper window */
5835
5926
XReparentWindow (dpy, id, wrapper, 0, 0);
5837
attr.event_mask = PropertyChangeMask | FocusChangeMask |
5838
EnterWindowMask | LeaveWindowMask;
5928
/* Restore events */
5929
attr.event_mask = attrib.your_event_mask;
5840
5931
/* We don't care about client events on the frame, and listening for them
5841
5932
* will probably end up fighting the client anyways, so disable them */
5948
6044
XUnmapWindow (dpy, frame);
5950
XSelectInput (dpy, id, PropertyChangeMask | EnterWindowMask |
6046
XSelectInput (dpy, id, wa.your_event_mask);
5953
6048
XSelectInput (dpy, screen->root (),
5954
6049
SubstructureRedirectMask |