00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
#include "client.h"
00020
#include "workspace.h"
00021
00022
#include <kapplication.h>
00023
#include <kglobal.h>
00024
#include <qpainter.h>
00025
#include <kwin.h>
00026
00027
#include "placement.h"
00028
#include "notifications.h"
00029
#include "geometrytip.h"
00030
#include "rules.h"
00031
00032
extern Time qt_x_time;
00033
00034
namespace KWinInternal
00035 {
00036
00037
00038
00039
00040
00044
void Workspace::desktopResized()
00045 {
00046 updateClientArea();
00047 checkElectricBorders();
00048 }
00049
00062
void Workspace::updateClientArea(
bool force )
00063 {
00064 QDesktopWidget *desktopwidget = KApplication::desktop();
00065
int nscreens = desktopwidget -> numScreens ();
00066
00067 QRect* new_wareas =
new QRect[ numberOfDesktops() + 1 ];
00068 QRect** new_sareas =
new QRect*[ numberOfDesktops() + 1];
00069 QRect* screens =
new QRect [ nscreens ];
00070 QRect desktopArea = desktopwidget -> geometry ();
00071
for(
int iS = 0;
00072 iS < nscreens;
00073 iS ++ )
00074 {
00075 screens [iS] = desktopwidget -> screenGeometry (iS);
00076 }
00077
for(
int i = 1;
00078 i <= numberOfDesktops();
00079 ++i )
00080 {
00081 new_wareas[ i ] = desktopArea;
00082 new_sareas[ i ] =
new QRect [ nscreens ];
00083
for(
int iS = 0;
00084 iS < nscreens;
00085 iS ++ )
00086 new_sareas[ i ][ iS ] = screens[ iS ];
00087 }
00088
for ( ClientList::ConstIterator it = clients.begin(); it != clients.end(); ++it)
00089 {
00090 QRect r = (*it)->adjustedClientArea( desktopArea, desktopArea );
00091
if( r == desktopArea )
00092
continue;
00093
if( (*it)->isOnAllDesktops())
00094
for(
int i = 1;
00095 i <= numberOfDesktops();
00096 ++i )
00097 {
00098 new_wareas[ i ] = new_wareas[ i ].intersect( r );
00099
for(
int iS = 0;
00100 iS < nscreens;
00101 iS ++ )
00102 new_sareas[ i ][ iS ] =
00103 new_sareas[ i ][ iS ].intersect(
00104 (*it)->adjustedClientArea( desktopArea, screens[ iS ] )
00105 );
00106 }
00107
else
00108 {
00109 new_wareas[ (*it)->desktop() ] = new_wareas[ (*it)->desktop() ].intersect( r );
00110
for(
int iS = 0;
00111 iS < nscreens;
00112 iS ++ )
00113 {
00114
00115 new_sareas[ (*it)->desktop() ][ iS ] =
00116 new_sareas[ (*it)->desktop() ][ iS ].intersect(
00117 (*it)->adjustedClientArea( desktopArea, screens[ iS ] )
00118 );
00119 }
00120 }
00121 }
00122
#if 0
00123
for(
int i = 1;
00124 i <= numberOfDesktops();
00125 ++i )
00126 {
00127
for(
int iS = 0;
00128 iS < nscreens;
00129 iS ++ )
00130 kdDebug () <<
"new_sarea: " << new_sareas[ i ][ iS ] << endl;
00131 }
00132
#endif
00133
00134
if( topmenu_space != NULL )
00135 {
00136 QRect topmenu_area = desktopArea;
00137 topmenu_area.setTop( topMenuHeight());
00138
for(
int i = 1;
00139 i <= numberOfDesktops();
00140 ++i )
00141 new_wareas[ i ] = new_wareas[ i ].intersect( topmenu_area );
00142 }
00143
00144
bool changed = force;
00145
00146
if (! screenarea)
00147 changed =
true;
00148
00149
for(
int i = 1;
00150 !changed && i <= numberOfDesktops();
00151 ++i )
00152 {
00153
if( workarea[ i ] != new_wareas[ i ] )
00154 changed =
true;
00155
for(
int iS = 0;
00156 iS < nscreens;
00157 iS ++ )
00158
if (new_sareas[ i ][ iS ] != screenarea [ i ][ iS ])
00159 changed =
true;
00160 }
00161
00162
if ( changed )
00163 {
00164
delete[] workarea;
00165 workarea = new_wareas;
00166 new_wareas = NULL;
00167
delete[] screenarea;
00168 screenarea = new_sareas;
00169 new_sareas = NULL;
00170 NETRect r;
00171
for(
int i = 1; i <= numberOfDesktops(); i++)
00172 {
00173 r.pos.x = workarea[ i ].x();
00174 r.pos.y = workarea[ i ].y();
00175 r.size.width = workarea[ i ].width();
00176 r.size.height = workarea[ i ].height();
00177 rootInfo->setWorkArea( i, r );
00178 }
00179
00180 updateTopMenuGeometry();
00181
for( ClientList::ConstIterator it = clients.begin();
00182 it != clients.end();
00183 ++it)
00184 (*it)->checkWorkspacePosition();
00185 }
00186
delete[] screens;
00187
delete[] new_sareas;
00188
delete[] new_wareas;
00189 }
00190
00191
void Workspace::updateClientArea()
00192 {
00193 updateClientArea(
false );
00194 }
00195
00196
00204 QRect Workspace::clientArea( clientAreaOption opt,
const QPoint& p,
int desktop )
const
00205
{
00206
if( desktop == NETWinInfo::OnAllDesktops || desktop == 0 )
00207 desktop = currentDesktop();
00208 QDesktopWidget *desktopwidget = KApplication::desktop();
00209
int screen = desktopwidget->screenNumber( p );
00210
if( screen < 0 )
00211 screen = desktopwidget->primaryScreen();
00212 QRect sarea = screenarea
00213 ? screenarea[ desktop ][ screen ]
00214 : desktopwidget->screenGeometry( screen );
00215 QRect warea = workarea[ desktop ].isNull()
00216 ? QApplication::desktop()->geometry()
00217 : workarea[ desktop ];
00218
switch (opt)
00219 {
00220
case MaximizeArea:
00221
if (options->xineramaMaximizeEnabled)
00222
return sarea;
00223
else
00224
return warea;
00225
case MaximizeFullArea:
00226
if (options->xineramaMaximizeEnabled)
00227
return desktopwidget->screenGeometry( screen );
00228
else
00229
return desktopwidget->geometry();
00230
case FullScreenArea:
00231
if (options->xineramaFullscreenEnabled)
00232
return desktopwidget->screenGeometry( screen );
00233
else
00234
return desktopwidget->geometry();
00235
case PlacementArea:
00236
if (options->xineramaPlacementEnabled)
00237
return sarea;
00238
else
00239
return warea;
00240
case MovementArea:
00241
if (options->xineramaMovementEnabled)
00242
return desktopwidget->screenGeometry( screen );
00243
else
00244
return desktopwidget->geometry();
00245
case WorkArea:
00246
return warea;
00247
case FullArea:
00248
return desktopwidget->geometry();
00249
case ScreenArea:
00250
return sarea;
00251 }
00252 assert(
false );
00253
return QRect();
00254 }
00255
00256 QRect Workspace::clientArea( clientAreaOption opt,
const Client* c )
const
00257
{
00258
return clientArea( opt, c->geometry().center(), c->desktop());
00259 }
00260
00266 QPoint Workspace::adjustClientPosition( Client* c, QPoint pos )
00267 {
00268
00269
00270
00271
if (options->windowSnapZone || options->borderSnapZone )
00272 {
00273
const bool sOWO=options->snapOnlyWhenOverlapping;
00274
const QRect maxRect = clientArea(MovementArea, pos+c->rect().center(), c->desktop());
00275
const int xmin = maxRect.left();
00276
const int xmax = maxRect.right()+1;
00277
const int ymin = maxRect.top();
00278
const int ymax = maxRect.bottom()+1;
00279
00280
const int cx(pos.x());
00281
const int cy(pos.y());
00282
const int cw(c->width());
00283
const int ch(c->height());
00284
const int rx(cx+cw);
00285
const int ry(cy+ch);
00286
00287
int nx(cx), ny(cy);
00288
int deltaX(xmax);
00289
int deltaY(ymax);
00290
00291
int lx, ly, lrx, lry;
00292
00293
00294
int snap = options->borderSnapZone;
00295
if (snap)
00296 {
00297
if ((sOWO?(cx<xmin):
true) && (QABS(xmin-cx)<snap))
00298 {
00299 deltaX = xmin-cx;
00300 nx = xmin;
00301 }
00302
if ((sOWO?(rx>xmax):
true) && (QABS(rx-xmax)<snap) && (QABS(xmax-rx) < deltaX))
00303 {
00304 deltaX = rx-xmax;
00305 nx = xmax - cw;
00306 }
00307
00308
if ((sOWO?(cy<ymin):
true) && (QABS(ymin-cy)<snap))
00309 {
00310 deltaY = ymin-cy;
00311 ny = ymin;
00312 }
00313
if ((sOWO?(ry>ymax):
true) && (QABS(ry-ymax)<snap) && (QABS(ymax-ry) < deltaY))
00314 {
00315 deltaY =ry-ymax;
00316 ny = ymax - ch;
00317 }
00318 }
00319
00320
00321 snap = options->windowSnapZone;
00322
if (snap)
00323 {
00324 QValueList<Client *>::ConstIterator l;
00325
for (l = clients.begin();l != clients.end();++l )
00326 {
00327
if ((*l)->isOnDesktop(currentDesktop()) &&
00328 !(*l)->isMinimized()
00329 && (*l) != c )
00330 {
00331 lx = (*l)->x();
00332 ly = (*l)->y();
00333 lrx = lx + (*l)->width();
00334 lry = ly + (*l)->height();
00335
00336
if ( (( cy <= lry ) && ( cy >= ly )) ||
00337 (( ry >= ly ) && ( ry <= lry )) ||
00338 (( cy <= ly ) && ( ry >= lry )) )
00339 {
00340
if ((sOWO?(cx<lrx):
true) && (QABS(lrx-cx)<snap) && ( QABS(lrx -cx) < deltaX) )
00341 {
00342 deltaX = QABS( lrx - cx );
00343 nx = lrx;
00344 }
00345
if ((sOWO?(rx>lx):
true) && (QABS(rx-lx)<snap) && ( QABS( rx - lx )<deltaX) )
00346 {
00347 deltaX = QABS(rx - lx);
00348 nx = lx - cw;
00349 }
00350 }
00351
00352
if ( (( cx <= lrx ) && ( cx >= lx )) ||
00353 (( rx >= lx ) && ( rx <= lrx )) ||
00354 (( cx <= lx ) && ( rx >= lrx )) )
00355 {
00356
if ((sOWO?(cy<lry):
true) && (QABS(lry-cy)<snap) && (QABS( lry -cy ) < deltaY))
00357 {
00358 deltaY = QABS( lry - cy );
00359 ny = lry;
00360 }
00361
00362
if ((sOWO?(ry>ly):
true) && (QABS(ry-ly)<snap) && (QABS( ry - ly ) < deltaY ))
00363 {
00364 deltaY = QABS( ry - ly );
00365 ny = ly - ch;
00366 }
00367 }
00368 }
00369 }
00370 }
00371 pos = QPoint(nx, ny);
00372 }
00373
return pos;
00374 }
00375
00376 QRect Workspace::adjustClientSize( Client* c, QRect moveResizeGeom,
int mode )
00377 {
00378
00379
00380
00381
if ( options->windowSnapZone || options->borderSnapZone )
00382 {
00383
const bool sOWO=options->snapOnlyWhenOverlapping;
00384
00385
const QRect maxRect = clientArea(MovementArea, c->rect().center(), c->desktop());
00386
const int xmin = maxRect.left();
00387
const int xmax = maxRect.right();
00388
const int ymin = maxRect.top();
00389
const int ymax = maxRect.bottom();
00390
00391
const int cx(moveResizeGeom.left());
00392
const int cy(moveResizeGeom.top());
00393
const int rx(moveResizeGeom.right());
00394
const int ry(moveResizeGeom.bottom());
00395
00396
int newcx(cx), newcy(cy);
00397
int newrx(rx), newry(ry);
00398
int deltaX(xmax);
00399
int deltaY(ymax);
00400
00401
int lx, ly, lrx, lry;
00402
00403
00404
int snap = options->borderSnapZone;
00405
if (snap)
00406 {
00407 deltaX = int(snap);
00408 deltaY = int(snap);
00409
00410
#define SNAP_BORDER_TOP \
00411
if ((sOWO?(newcy<ymin):true) && (QABS(ymin-newcy)<deltaY)) \
00412
{ \
00413
deltaY = QABS(ymin-newcy); \
00414
newcy = ymin; \
00415
}
00416
00417
#define SNAP_BORDER_BOTTOM \
00418
if ((sOWO?(newry>ymax):true) && (QABS(ymax-newry)<deltaY)) \
00419
{ \
00420
deltaY = QABS(ymax-newcy); \
00421
newry = ymax; \
00422
}
00423
00424
#define SNAP_BORDER_LEFT \
00425
if ((sOWO?(newcx<xmin):true) && (QABS(xmin-newcx)<deltaX)) \
00426
{ \
00427
deltaX = QABS(xmin-newcx); \
00428
newcx = xmin; \
00429
}
00430
00431
#define SNAP_BORDER_RIGHT \
00432
if ((sOWO?(newrx>xmax):true) && (QABS(xmax-newrx)<deltaX)) \
00433
{ \
00434
deltaX = QABS(xmax-newrx); \
00435
newrx = xmax; \
00436
}
00437
switch ( mode )
00438 {
00439
case PositionBottomRight:
00440 SNAP_BORDER_BOTTOM
00441 SNAP_BORDER_RIGHT
00442
break;
00443
case PositionRight:
00444 SNAP_BORDER_RIGHT
00445
break;
00446
case PositionBottom:
00447 SNAP_BORDER_BOTTOM
00448
break;
00449
case PositionTopLeft:
00450 SNAP_BORDER_TOP
00451 SNAP_BORDER_LEFT
00452
break;
00453
case PositionLeft:
00454 SNAP_BORDER_LEFT
00455
break;
00456
case PositionTop:
00457 SNAP_BORDER_TOP
00458
break;
00459
case PositionTopRight:
00460 SNAP_BORDER_TOP
00461 SNAP_BORDER_RIGHT
00462
break;
00463
case PositionBottomLeft:
00464 SNAP_BORDER_BOTTOM
00465 SNAP_BORDER_LEFT
00466
break;
00467
default:
00468 assert(
false );
00469
break;
00470 }
00471
00472
00473 }
00474
00475
00476 snap = options->windowSnapZone;
00477
if (snap)
00478 {
00479 deltaX = int(snap);
00480 deltaY = int(snap);
00481 QValueList<Client *>::ConstIterator l;
00482
for (l = clients.begin();l != clients.end();++l )
00483 {
00484
if ((*l)->isOnDesktop(currentDesktop()) &&
00485 !(*l)->isMinimized()
00486 && (*l) != c )
00487 {
00488 lx = (*l)->x()-1;
00489 ly = (*l)->y()-1;
00490 lrx =(*l)->x() + (*l)->width();
00491 lry =(*l)->y() + (*l)->height();
00492
00493
#define WITHIN_HEIGHT ((( newcy <= lry ) && ( newcy >= ly )) || \
00494
(( newry >= ly ) && ( newry <= lry )) || \
00495
(( newcy <= ly ) && ( newry >= lry )) )
00496
00497
#define WITHIN_WIDTH ( (( cx <= lrx ) && ( cx >= lx )) || \
00498
(( rx >= lx ) && ( rx <= lrx )) || \
00499
(( cx <= lx ) && ( rx >= lrx )) )
00500
00501
#define SNAP_WINDOW_TOP if ( (sOWO?(newcy<lry):true) \
00502
&& WITHIN_WIDTH \
00503
&& (QABS( lry - newcy ) < deltaY) ) { \
00504
deltaY = QABS( lry - newcy ); \
00505
newcy=lry; \
00506
}
00507
00508
#define SNAP_WINDOW_BOTTOM if ( (sOWO?(newry>ly):true) \
00509
&& WITHIN_WIDTH \
00510
&& (QABS( ly - newry ) < deltaY) ) { \
00511
deltaY = QABS( ly - newry ); \
00512
newry=ly; \
00513
}
00514
00515
#define SNAP_WINDOW_LEFT if ( (sOWO?(newcx<lrx):true) \
00516
&& WITHIN_HEIGHT \
00517
&& (QABS( lrx - newcx ) < deltaX)) { \
00518
deltaX = QABS( lrx - newcx ); \
00519
newcx=lrx; \
00520
}
00521
00522
#define SNAP_WINDOW_RIGHT if ( (sOWO?(newrx>lx):true) \
00523
&& WITHIN_HEIGHT \
00524
&& (QABS( lx - newrx ) < deltaX)) \
00525
{ \
00526
deltaX = QABS( lx - newrx ); \
00527
newrx=lx; \
00528
}
00529
00530
switch ( mode )
00531 {
00532
case PositionBottomRight:
00533 SNAP_WINDOW_BOTTOM
00534 SNAP_WINDOW_RIGHT
00535
break;
00536
case PositionRight:
00537 SNAP_WINDOW_RIGHT
00538
break;
00539
case PositionBottom:
00540 SNAP_WINDOW_BOTTOM
00541
break;
00542
case PositionTopLeft:
00543 SNAP_WINDOW_TOP
00544 SNAP_WINDOW_LEFT
00545
break;
00546
case PositionLeft:
00547 SNAP_WINDOW_LEFT
00548
break;
00549
case PositionTop:
00550 SNAP_WINDOW_TOP
00551
break;
00552
case PositionTopRight:
00553 SNAP_WINDOW_TOP
00554 SNAP_WINDOW_RIGHT
00555
break;
00556
case PositionBottomLeft:
00557 SNAP_WINDOW_BOTTOM
00558 SNAP_WINDOW_LEFT
00559
break;
00560
default:
00561 assert(
false );
00562
break;
00563 }
00564 }
00565 }
00566 }
00567 moveResizeGeom = QRect(QPoint(newcx, newcy), QPoint(newrx, newry));
00568 }
00569
return moveResizeGeom;
00570 }
00571
00575
void Workspace::setClientIsMoving( Client *c )
00576 {
00577 Q_ASSERT(!c || !movingClient);
00578
00579 movingClient = c;
00580
if (movingClient)
00581 ++block_focus;
00582
else
00583 --block_focus;
00584 }
00585
00589
void Workspace::cascadeDesktop()
00590 {
00591
00592 Q_ASSERT( block_stacking_updates == 0 );
00593 ClientList::ConstIterator it(stackingOrder().begin());
00594
bool re_init_cascade_at_first_client =
true;
00595
for (; it != stackingOrder().end(); ++it)
00596 {
00597
if((!(*it)->isOnDesktop(currentDesktop())) ||
00598 ((*it)->isMinimized()) ||
00599 ((*it)->isOnAllDesktops()) ||
00600 (!(*it)->isMovable()) )
00601
continue;
00602 initPositioning->placeCascaded(*it, QRect(), re_init_cascade_at_first_client);
00603
00604
if (re_init_cascade_at_first_client)
00605 re_init_cascade_at_first_client =
false;
00606 }
00607 }
00608
00613
void Workspace::unclutterDesktop()
00614 {
00615 ClientList::Iterator it(clients.fromLast());
00616
for (; it != clients.end(); --it)
00617 {
00618
if((!(*it)->isOnDesktop(currentDesktop())) ||
00619 ((*it)->isMinimized()) ||
00620 ((*it)->isOnAllDesktops()) ||
00621 (!(*it)->isMovable()) )
00622
continue;
00623 initPositioning->placeSmart(*it, QRect());
00624 }
00625 }
00626
00627
00628
void Workspace::updateTopMenuGeometry( Client* c )
00629 {
00630
if( !managingTopMenus())
00631
return;
00632
if( c != NULL )
00633 {
00634 XEvent ev;
00635 ev.xclient.display = qt_xdisplay();
00636 ev.xclient.type = ClientMessage;
00637 ev.xclient.window = c->window();
00638
static Atom msg_type_atom = XInternAtom( qt_xdisplay(),
"_KDE_TOPMENU_MINSIZE", False );
00639 ev.xclient.message_type = msg_type_atom;
00640 ev.xclient.format = 32;
00641 ev.xclient.data.l[0] = qt_x_time;
00642 ev.xclient.data.l[1] = topmenu_space->width();
00643 ev.xclient.data.l[2] = topmenu_space->height();
00644 ev.xclient.data.l[3] = 0;
00645 ev.xclient.data.l[4] = 0;
00646 XSendEvent( qt_xdisplay(), c->window(), False, NoEventMask, &ev );
00647 KWin::setStrut( c->window(), 0, 0, topmenu_height, 0 );
00648 c->checkWorkspacePosition();
00649
return;
00650 }
00651
00652 QRect area;
00653 area = clientArea( MaximizeFullArea, QPoint( 0, 0 ), 1 );
00654 area.setHeight( topMenuHeight());
00655 topmenu_space->setGeometry( area );
00656
for( ClientList::ConstIterator it = topmenus.begin();
00657 it != topmenus.end();
00658 ++it )
00659 updateTopMenuGeometry( *it );
00660 }
00661
00662
00663
00664
00665
00666
00667
void Client::keepInArea(
const QRect& area )
00668 {
00669
if ( geometry().right() > area.right() && width() < area.width() )
00670
move( area.right() - width(), y() );
00671
if ( geometry().bottom() > area.bottom() && height() < area.height() )
00672
move( x(), area.bottom() - height() );
00673
if( !area.contains( geometry().topLeft() ))
00674 {
00675
int tx = x();
00676
int ty = y();
00677
if ( tx < area.x() )
00678 tx = area.x();
00679
if ( ty < area.y() )
00680 ty = area.y();
00681
move( tx, ty );
00682 }
00683 }
00684
00690
00691
00692 QRect Client::adjustedClientArea(
const QRect &desktopArea,
const QRect& area )
const
00693
{
00694 QRect r = area;
00695
00696
if( isTopMenu())
00697
return r;
00698 NETExtendedStrut str = strut();
00699 QRect stareaL = QRect(
00700 0,
00701 str . left_start,
00702 str . left_width,
00703 str . left_end - str . left_start + 1 );
00704 QRect stareaR = QRect (
00705 desktopArea . right () - str . right_width + 1,
00706 str . right_start,
00707 str . right_width,
00708 str . right_end - str . right_start + 1 );
00709 QRect stareaT = QRect (
00710 str . top_start,
00711 0,
00712 str . top_end - str . top_start + 1,
00713 str . top_width);
00714 QRect stareaB = QRect (
00715 str . bottom_start,
00716 desktopArea . bottom () - str . bottom_width + 1,
00717 str . bottom_end - str . bottom_start + 1,
00718 str . bottom_width);
00719
00720 NETExtendedStrut ext = info->extendedStrut();
00721
if( ext.left_width == 0 && ext.right_width == 0 && ext.top_width == 0 && ext.bottom_width == 0
00722 && ( str.left_width != 0 || str.right_width != 0 || str.top_width != 0 || str.bottom_width != 0 )) {
00723
00724
00725
00726
00727
00728
00729
00730
if (stareaT.top() == geometry().top() && stareaT.bottom() == geometry().bottom()) {
00731 stareaT.setLeft(geometry().left());
00732 stareaT.setRight(geometry().right());
00733
00734 }
00735
if (stareaB.top() == geometry().top() && stareaB.bottom() == geometry().bottom()) {
00736 stareaB.setLeft(geometry().left());
00737 stareaB.setRight(geometry().right());
00738
00739 }
00740
if (stareaL.left() == geometry().left() && stareaL.right() == geometry().right()) {
00741 stareaL.setTop(geometry().top());
00742 stareaL.setBottom(geometry().bottom());
00743
00744 }
00745
if (stareaR.left() == geometry().left() && stareaR.right() == geometry().right()) {
00746 stareaR.setTop(geometry().top());
00747 stareaR.setBottom(geometry().bottom());
00748
00749 }
00750 }
00751
if (stareaL . intersects (area)) {
00752
00753 r . setLeft( stareaL . right() + 1 );
00754 }
00755
if (stareaR . intersects (area)) {
00756
00757 r . setRight( stareaR . left() - 1 );
00758 }
00759
if (stareaT . intersects (area)) {
00760
00761 r . setTop( stareaT . bottom() + 1 );
00762 }
00763
if (stareaB . intersects (area)) {
00764
00765 r . setBottom( stareaB . top() - 1 );
00766 }
00767
return r;
00768 }
00769
00770 NETExtendedStrut Client::strut()
const
00771
{
00772 NETExtendedStrut ext = info->extendedStrut();
00773 NETStrut str = info->strut();
00774
if( ext.left_width == 0 && ext.right_width == 0 && ext.top_width == 0 && ext.bottom_width == 0
00775 && ( str.left != 0 || str.right != 0 || str.top != 0 || str.bottom != 0 ))
00776 {
00777
00778
if( str.left != 0 )
00779 {
00780 ext.left_width = str.left;
00781 ext.left_start = 0;
00782 ext.left_end = XDisplayHeight( qt_xdisplay(), DefaultScreen( qt_xdisplay()));
00783 }
00784
if( str.right != 0 )
00785 {
00786 ext.right_width = str.right;
00787 ext.right_start = 0;
00788 ext.right_end = XDisplayHeight( qt_xdisplay(), DefaultScreen( qt_xdisplay()));
00789 }
00790
if( str.top != 0 )
00791 {
00792 ext.top_width = str.top;
00793 ext.top_start = 0;
00794 ext.top_end = XDisplayWidth( qt_xdisplay(), DefaultScreen( qt_xdisplay()));
00795 }
00796
if( str.bottom != 0 )
00797 {
00798 ext.bottom_width = str.bottom;
00799 ext.bottom_start = 0;
00800 ext.bottom_end = XDisplayWidth( qt_xdisplay(), DefaultScreen( qt_xdisplay()));
00801 }
00802 }
00803
return ext;
00804 }
00805
bool Client::hasStrut()
const
00806
{
00807 NETExtendedStrut ext = strut();
00808
if( ext.left_width == 0 && ext.right_width == 0 && ext.top_width == 0 && ext.bottom_width == 0 )
00809 {
00810
return false;
00811 }
00812
return true;
00813 }
00814
00815
00816
00817
void Client::updateWorkareaDiffs()
00818 {
00819 QRect area = workspace()->clientArea( WorkArea,
this );
00820 QRect geom = geometry();
00821 workarea_diff_x = computeWorkareaDiff( geom.left(), geom.right(), area.left(), area.right());
00822 workarea_diff_y = computeWorkareaDiff( geom.top(), geom.bottom(), area.top(), area.bottom());
00823 }
00824
00825
00826
00827
00828
00829
00830
00831
00832
00833
int Client::computeWorkareaDiff(
int left,
int right,
int a_left,
int a_right )
00834 {
00835
int left_diff = left - a_left;
00836
int right_diff = a_right - right;
00837
if( left_diff < 0 || right_diff < 0 )
00838
return INT_MIN;
00839
else
00840 {
00841
00842
int max_diff = ( a_right - a_left ) / 10;
00843
if( left_diff < right_diff )
00844
return left_diff < max_diff ? -left_diff - 1 : INT_MAX;
00845
else if( left_diff > right_diff )
00846
return right_diff < max_diff ? right_diff + 1 : INT_MAX;
00847
return INT_MAX;
00848 }
00849 }
00850
00851
void Client::checkWorkspacePosition()
00852 {
00853
if( maximizeMode() !=
MaximizeRestore )
00854
00855 changeMaximize(
false,
false,
true );
00856
00857
if( isFullScreen())
00858 {
00859 QRect area = workspace()->clientArea( FullScreenArea,
this );
00860
if( geometry() != area )
00861
setGeometry( area );
00862
return;
00863 }
00864
if( isDock())
00865
return;
00866
if( isOverride())
00867
return;
00868
if( isTopMenu())
00869 {
00870
if( workspace()->managingTopMenus())
00871 {
00872 QRect area;
00873 ClientList mainclients = mainClients();
00874
if( mainclients.count() == 1 )
00875 area = workspace()->clientArea( MaximizeFullArea, mainclients.first());
00876
else
00877 area = workspace()->clientArea( MaximizeFullArea, QPoint( 0, 0 ),
desktop());
00878 area.setHeight( workspace()->topMenuHeight());
00879
00880
setGeometry( area );
00881 }
00882
return;
00883 }
00884
00885
if( !isShade())
00886 {
00887
int old_diff_x = workarea_diff_x;
00888
int old_diff_y = workarea_diff_y;
00889 updateWorkareaDiffs();
00890
00891
00892
00893
00894
00895
00896
if( workspace()->initializing())
00897
return;
00898
00899 QRect area = workspace()->clientArea( WorkArea,
this );
00900 QRect new_geom = geometry();
00901 QRect tmp_rect_x( new_geom.left(), 0, new_geom.width(), 0 );
00902 QRect tmp_area_x( area.left(), 0, area.width(), 0 );
00903 checkDirection( workarea_diff_x, old_diff_x, tmp_rect_x, tmp_area_x );
00904
00905 QRect tmp_rect_y( new_geom.top(), 0, new_geom.height(), 0 );
00906 QRect tmp_area_y( area.top(), 0, area.height(), 0 );
00907 checkDirection( workarea_diff_y, old_diff_y, tmp_rect_y, tmp_area_y );
00908 new_geom = QRect( tmp_rect_x.left(), tmp_rect_y.left(), tmp_rect_x.width(), tmp_rect_y.width());
00909 QRect final_geom( new_geom.topLeft(),
adjustedSize( new_geom.size()));
00910
if( final_geom != new_geom )
00911 {
00912
if( old_diff_x != INT_MAX && old_diff_x > 0 )
00913 final_geom.moveRight( area.right() - ( old_diff_x - 1 ));
00914
if( old_diff_y != INT_MAX && old_diff_y > 0 )
00915 final_geom.moveBottom( area.bottom() - ( old_diff_y - 1 ));
00916 }
00917
if( final_geom != geometry() )
00918
setGeometry( final_geom );
00919
00920 }
00921 }
00922
00923
00924
00925
00926
00927
00928
00929
00930
00931
00932
00933
void Client::checkDirection(
int new_diff,
int old_diff, QRect& rect,
const QRect& area )
00934 {
00935
if( old_diff != INT_MIN )
00936 {
00937
if( old_diff == INT_MAX )
00938 {
00939
if( new_diff == INT_MIN )
00940 {
00941 rect.setLeft( area.left());
00942 rect.setRight( area.right());
00943 }
00944
return;
00945 }
00946
if(
isResizable())
00947 {
00948
if( rect.width() > area.width())
00949 rect.setWidth( area.width());
00950
if( rect.width() >= area.width() / 2 )
00951 {
00952
if( old_diff < 0 )
00953 rect.setLeft( area.left() + ( -old_diff - 1 ) );
00954
else
00955 rect.setRight( area.right() - ( old_diff - 1 ));
00956 }
00957 }
00958
if(
isMovable())
00959 {
00960
if( old_diff < 0 )
00961 rect.moveLeft( area.left() + ( -old_diff - 1 ));
00962
else
00963 rect.moveRight( area.right() - ( old_diff - 1 ));
00964 }
00965
00966
00967
00968
if(
isResizable())
00969 {
00970
if( old_diff < 0 )
00971 rect.setLeft( area.left() + ( -old_diff - 1 ) );
00972
else
00973 rect.setRight( area.right() - ( old_diff - 1 ));
00974 }
00975 }
00976
if( rect.right() < area.left() + 5 || rect.left() > area.right() - 5 )
00977 {
00978
if(
isMovable())
00979 {
00980
if( rect.left() < area.left() + 5 )
00981 rect.moveRight( area.left() + 5 );
00982
if( rect.right() > area.right() - 5 )
00983 rect.moveLeft( area.right() - 5 );
00984 }
00985 }
00986 }
00987
00991 QSize Client::adjustedSize(
const QSize& frame, Sizemode mode )
const
00992
{
00993
00994
00995 QSize wsize( frame.width() - ( border_left + border_right ),
00996 frame.height() - ( border_top + border_bottom ));
00997
00998
return sizeForClientSize( wsize, mode );
00999 }
01000
01009 QSize Client::sizeForClientSize(
const QSize& wsize, Sizemode mode )
const
01010
{
01011
int w = wsize.width();
01012
int h = wsize.height();
01013
if (w<1) w = 1;
01014
if (h<1) h = 1;
01015
01016
01017
01018 QSize min_size = minSize();
01019 QSize max_size = maxSize();
01020
if( decoration != NULL )
01021 {
01022 QSize decominsize = decoration->
minimumSize();
01023 QSize border_size( border_left + border_right, border_top + border_bottom );
01024
if( border_size.width() > decominsize.width())
01025 decominsize.setWidth( border_size.width());
01026
if( border_size.height() > decominsize.height())
01027 decominsize.setHeight( border_size.height());
01028
if( decominsize.width() > min_size.width())
01029 min_size.setWidth( decominsize.width());
01030
if( decominsize.height() > min_size.height())
01031 min_size.setHeight( decominsize.height());
01032 }
01033 w = QMIN( max_size.width(), w );
01034 h = QMIN( max_size.height(), h );
01035 w = QMAX( min_size.width(), w );
01036 h = QMAX( min_size.height(), h );
01037
01038
int width_inc = xSizeHint.width_inc;
01039
int height_inc = xSizeHint.height_inc;
01040
int basew_inc = xSizeHint.min_width;
01041
int baseh_inc = xSizeHint.min_height;
01042 w = int(( w - basew_inc ) / width_inc ) * width_inc + basew_inc;
01043 h = int(( h - baseh_inc ) / height_inc ) * height_inc + baseh_inc;
01044
01045
01046
01047
01048
01049
01050
01051
01052
01053
01054
01055
01056
01057
01058
01059
if( xSizeHint.flags & PAspect )
01060 {
01061
double min_aspect_w = xSizeHint.min_aspect.x;
01062
double min_aspect_h = xSizeHint.min_aspect.y;
01063
double max_aspect_w = xSizeHint.max_aspect.x;
01064
double max_aspect_h = xSizeHint.max_aspect.y;
01065 w -= xSizeHint.base_width;
01066 h -= xSizeHint.base_height;
01067
int max_width = max_size.width() - xSizeHint.base_width;
01068
int min_width = min_size.width() - xSizeHint.base_width;
01069
int max_height = max_size.height() - xSizeHint.base_height;
01070
int min_height = min_size.height() - xSizeHint.base_height;
01071
#define ASPECT_CHECK_GROW_W \
01072
if( min_aspect_w * h > min_aspect_h * w ) \
01073
{ \
01074
int delta = int( min_aspect_w * h / min_aspect_h - w ) / width_inc * width_inc; \
01075
if( w + delta <= max_width ) \
01076
w += delta; \
01077
}
01078
#define ASPECT_CHECK_SHRINK_H_GROW_W \
01079
if( min_aspect_w * h > min_aspect_h * w ) \
01080
{ \
01081
int delta = int( h - w * min_aspect_h / min_aspect_w ) / height_inc * height_inc; \
01082
if( h - delta >= min_height ) \
01083
h -= delta; \
01084
else \
01085
{ \
01086
int delta = int( min_aspect_w * h / min_aspect_h - w ) / width_inc * width_inc; \
01087
if( w + delta <= max_width ) \
01088
w += delta; \
01089
} \
01090
}
01091
#define ASPECT_CHECK_GROW_H \
01092
if( max_aspect_w * h < max_aspect_h * w ) \
01093
{ \
01094
int delta = int( w * max_aspect_h / max_aspect_w - h ) / height_inc * height_inc; \
01095
if( h + delta <= max_height ) \
01096
h += delta; \
01097
}
01098
#define ASPECT_CHECK_SHRINK_W_GROW_H \
01099
if( max_aspect_w * h < max_aspect_h * w ) \
01100
{ \
01101
int delta = int( w - max_aspect_w * h / max_aspect_h ) / width_inc * width_inc; \
01102
if( w - delta >= min_width ) \
01103
w -= delta; \
01104
else \
01105
{ \
01106
int delta = int( w * max_aspect_h / max_aspect_w - h ) / height_inc * height_inc; \
01107
if( h + delta <= max_height ) \
01108
h += delta; \
01109
} \
01110
}
01111
switch( mode )
01112 {
01113
case SizemodeAny:
01114 {
01115 ASPECT_CHECK_SHRINK_H_GROW_W
01116 ASPECT_CHECK_SHRINK_W_GROW_H
01117 ASPECT_CHECK_GROW_H
01118 ASPECT_CHECK_GROW_W
01119
break;
01120 }
01121
case SizemodeFixedW:
01122 {
01123
01124 ASPECT_CHECK_GROW_H
01125 ASPECT_CHECK_SHRINK_H_GROW_W
01126 ASPECT_CHECK_SHRINK_W_GROW_H
01127 ASPECT_CHECK_GROW_W
01128
break;
01129 }
01130
case SizemodeFixedH:
01131 {
01132 ASPECT_CHECK_GROW_W
01133 ASPECT_CHECK_SHRINK_W_GROW_H
01134 ASPECT_CHECK_SHRINK_H_GROW_W
01135 ASPECT_CHECK_GROW_H
01136
break;
01137 }
01138
case SizemodeMax:
01139 {
01140
01141 ASPECT_CHECK_SHRINK_H_GROW_W
01142 ASPECT_CHECK_SHRINK_W_GROW_H
01143 ASPECT_CHECK_GROW_W
01144 ASPECT_CHECK_GROW_H
01145
break;
01146 }
01147
case SizemodeShaded:
01148
break;
01149 }
01150
#undef ASPECT_CHECK_SHRINK_H_GROW_W
01151
#undef ASPECT_CHECK_SHRINK_W_GROW_H
01152
#undef ASPECT_CHECK_GROW_W
01153
#undef ASPECT_CHECK_GROW_H
01154
w += xSizeHint.base_width;
01155 h += xSizeHint.base_height;
01156 }
01157
01158 w += border_left + border_right;
01159 h += border_top + border_bottom;
01160 QSize ret = rules()->checkSize( QSize( w, h ));
01161
if ( mode == SizemodeShaded && wsize.height() == 0 )
01162 ret.setHeight( border_top + border_bottom );
01163
return ret;
01164 }
01165
01169
void Client::getWmNormalHints()
01170 {
01171
long msize;
01172
if (XGetWMNormalHints(qt_xdisplay(), window(), &xSizeHint, &msize) == 0 )
01173 xSizeHint.flags = 0;
01174
01175
01176
01177
01178
01179
if( xSizeHint.flags & PBaseSize )
01180 {
01181
if( ! ( xSizeHint.flags & PMinSize ))
01182 {
01183 xSizeHint.flags |= PMinSize;
01184 xSizeHint.min_width = xSizeHint.base_width;
01185 xSizeHint.min_height = xSizeHint.base_height;
01186 }
01187 }
01188
else
01189 xSizeHint.base_width = xSizeHint.base_height = 0;
01190
if( ! ( xSizeHint.flags & PMinSize ))
01191 xSizeHint.min_width = xSizeHint.min_height = 0;
01192
if( ! ( xSizeHint.flags & PMaxSize ))
01193 xSizeHint.max_width = xSizeHint.max_height = INT_MAX;
01194
else
01195 {
01196 xSizeHint.max_width = QMAX( xSizeHint.max_width, 1 );
01197 xSizeHint.max_height = QMAX( xSizeHint.max_height, 1 );
01198 }
01199
if( xSizeHint.flags & PResizeInc )
01200 {
01201 xSizeHint.width_inc = kMax( xSizeHint.width_inc, 1 );
01202 xSizeHint.height_inc = kMax( xSizeHint.height_inc, 1 );
01203 }
01204
else
01205 {
01206 xSizeHint.width_inc = 1;
01207 xSizeHint.height_inc = 1;
01208 }
01209
if( xSizeHint.flags & PAspect )
01210 {
01211 xSizeHint.min_aspect.y = kMax( xSizeHint.min_aspect.y, 1 );
01212 xSizeHint.max_aspect.y = kMax( xSizeHint.max_aspect.y, 1 );
01213 }
01214
else
01215 {
01216 xSizeHint.min_aspect.x = 1;
01217 xSizeHint.min_aspect.y = INT_MAX;
01218 xSizeHint.max_aspect.x = INT_MAX;
01219 xSizeHint.max_aspect.y = 1;
01220 }
01221
if( ! ( xSizeHint.flags & PWinGravity ))
01222 xSizeHint.win_gravity = NorthWestGravity;
01223
if( isManaged())
01224 {
01225 QSize new_size =
adjustedSize( size());
01226
if( new_size != size() && !isShade())
01227 resizeWithChecks( new_size );
01228 }
01229 updateAllowedActions();
01230 }
01231
01232 QSize Client::minSize()
const
01233
{
01234
return rules()->checkMinSize( QSize( xSizeHint.min_width, xSizeHint.min_height ));
01235 }
01236
01237 QSize Client::maxSize()
const
01238
{
01239
return rules()->checkMaxSize( QSize( xSizeHint.max_width, xSizeHint.max_height ));
01240 }
01241
01247
void Client::sendSyntheticConfigureNotify()
01248 {
01249 XConfigureEvent c;
01250 c.type = ConfigureNotify;
01251 c.send_event = True;
01252 c.event = window();
01253 c.window = window();
01254 c.x = x() + clientPos().x();
01255 c.y = y() + clientPos().y();
01256 c.width = clientSize().width();
01257 c.height = clientSize().height();
01258 c.border_width = 0;
01259 c.above = None;
01260 c.override_redirect = 0;
01261 XSendEvent( qt_xdisplay(), c.event, TRUE, StructureNotifyMask, (XEvent*)&c );
01262 }
01263
01264
const QPoint Client::calculateGravitation(
bool invert,
int gravity )
const
01265
{
01266
int dx, dy;
01267 dx = dy = 0;
01268
01269
if( gravity == 0 )
01270 gravity = xSizeHint.win_gravity;
01271
01272
01273
switch (gravity)
01274 {
01275
case NorthWestGravity:
01276
default:
01277 dx = border_left;
01278 dy = border_top;
01279
break;
01280
case NorthGravity:
01281 dx = 0;
01282 dy = border_top;
01283
break;
01284
case NorthEastGravity:
01285 dx = -border_right;
01286 dy = border_top;
01287
break;
01288
case WestGravity:
01289 dx = border_left;
01290 dy = 0;
01291
break;
01292
case CenterGravity:
01293
break;
01294
case StaticGravity:
01295 dx = 0;
01296 dy = 0;
01297
break;
01298
case EastGravity:
01299 dx = -border_right;
01300 dy = 0;
01301
break;
01302
case SouthWestGravity:
01303 dx = border_left ;
01304 dy = -border_bottom;
01305
break;
01306
case SouthGravity:
01307 dx = 0;
01308 dy = -border_bottom;
01309
break;
01310
case SouthEastGravity:
01311 dx = -border_right;
01312 dy = -border_bottom;
01313
break;
01314 }
01315
if( gravity != CenterGravity )
01316 {
01317 dx -= border_left;
01318 dy -= border_top;
01319 }
01320
else
01321 {
01322 dx = - ( border_left + border_right ) / 2;
01323 dy = - ( border_top + border_bottom ) / 2;
01324 }
01325
if( !invert )
01326
return QPoint( x() + dx, y() + dy );
01327
else
01328
return QPoint( x() - dx, y() - dy );
01329 }
01330
01331
void Client::configureRequest(
int value_mask,
int rx,
int ry,
int rw,
int rh,
int gravity,
bool from_tool )
01332 {
01333
if( gravity == 0 )
01334 gravity = xSizeHint.win_gravity;
01335
if( value_mask & ( CWX | CWY ))
01336 {
01337 QPoint new_pos = calculateGravitation(
true, gravity );
01338
if ( value_mask & CWX )
01339 new_pos.setX( rx );
01340
if ( value_mask & CWY )
01341 new_pos.setY( ry );
01342
01343
01344
01345
01346
01347
if ( new_pos.x() == x() + clientPos().x() &&
01348 new_pos.y() == y() + clientPos().y() && gravity == NorthWestGravity )
01349 {
01350 new_pos.setX( x());
01351 new_pos.setY( y());
01352 }
01353
01354
int nw = clientSize().width();
01355
int nh = clientSize().height();
01356
if ( value_mask & CWWidth )
01357 nw = rw;
01358
if ( value_mask & CWHeight )
01359 nh = rh;
01360 QSize ns = sizeForClientSize( QSize( nw, nh ) );
01361
01362
01363
if ( maximizeMode() !=
MaximizeFull
01364 || ns != size())
01365 {
01366 QRect orig_geometry = geometry();
01367 ++block_geometry;
01368 resetMaximize();
01369
move( new_pos );
01370 plainResize( ns );
01371
setGeometry( QRect( calculateGravitation(
false, gravity ), size()));
01372 updateFullScreenHack( QRect( new_pos, QSize( nw, nh )));
01373 QRect area = workspace()->clientArea( WorkArea,
this );
01374
if( !from_tool && ( !isSpecialWindow() || isToolbar()) && !isFullScreen()
01375 && area.contains( orig_geometry ))
01376 keepInArea( area );
01377 --block_geometry;
01378
setGeometry( geometry(), ForceGeometrySet );
01379
01380
01381
01382
01383
01384
if (hasStrut ())
01385 workspace() -> updateClientArea ();
01386 }
01387 }
01388
01389
if ( value_mask & (CWWidth | CWHeight )
01390 && ! ( value_mask & ( CWX | CWY )) )
01391 {
01392
if ( isShade())
01393 setShade( ShadeNone );
01394
01395
int nw = clientSize().width();
01396
int nh = clientSize().height();
01397
if ( value_mask & CWWidth )
01398 nw = rw;
01399
if ( value_mask & CWHeight )
01400 nh = rh;
01401 QSize ns = sizeForClientSize( QSize( nw, nh ) );
01402
01403
if( ns != size())
01404 {
01405 QRect orig_geometry = geometry();
01406 ++block_geometry;
01407 resetMaximize();
01408
int save_gravity = xSizeHint.win_gravity;
01409 xSizeHint.win_gravity = gravity;
01410 resizeWithChecks( ns );
01411 xSizeHint.win_gravity = save_gravity;
01412 updateFullScreenHack( QRect( calculateGravitation(
true, xSizeHint.win_gravity ), QSize( nw, nh )));
01413 QRect area = workspace()->clientArea( WorkArea,
this );
01414
if( !from_tool && ( !isSpecialWindow() || isToolbar()) && !isFullScreen()
01415 && area.contains( orig_geometry ))
01416 keepInArea( area );
01417 --block_geometry;
01418
setGeometry( geometry(), ForceGeometrySet );
01419 }
01420 }
01421
01422
01423
01424 }
01425
01426
void Client::resizeWithChecks(
int w,
int h, ForceGeometry_t force )
01427 {
01428
int newx = x();
01429
int newy = y();
01430 QRect area = workspace()->clientArea( WorkArea,
this );
01431
01432
if( w > area.width())
01433 w = area.width();
01434
if( h > area.height())
01435 h = area.height();
01436 QSize tmp =
adjustedSize( QSize( w, h ));
01437 w = tmp.width();
01438 h = tmp.height();
01439
switch( xSizeHint.win_gravity )
01440 {
01441
case NorthWestGravity:
01442
default:
01443
break;
01444
case NorthGravity:
01445 newx = ( newx + width() / 2 ) - ( w / 2 );
01446
break;
01447
case NorthEastGravity:
01448 newx = newx + width() - w;
01449
break;
01450
case WestGravity:
01451 newy = ( newy + height() / 2 ) - ( h / 2 );
01452
break;
01453
case CenterGravity:
01454 newx = ( newx + width() / 2 ) - ( w / 2 );
01455 newy = ( newy + height() / 2 ) - ( h / 2 );
01456
break;
01457
case StaticGravity:
01458
01459
break;
01460
case EastGravity:
01461 newx = newx + width() - w;
01462 newy = ( newy + height() / 2 ) - ( h / 2 );
01463
break;
01464
case SouthWestGravity:
01465 newy = newy + height() - h;
01466
break;
01467
case SouthGravity:
01468 newx = ( newx + width() / 2 ) - ( w / 2 );
01469 newy = newy + height() - h;
01470
break;
01471
case SouthEastGravity:
01472 newx = newx + width() - w;
01473 newy = newy + height() - h;
01474
break;
01475 }
01476
01477
01478
if( workarea_diff_x != INT_MIN && w <= area.width())
01479 {
01480
if( newx < area.left())
01481 newx = area.left();
01482
if( newx + w > area.right() + 1 )
01483 newx = area.right() + 1 - w;
01484 assert( newx >= area.left() && newx + w <= area.right() + 1 );
01485 }
01486
if( workarea_diff_y != INT_MIN && h <= area.height())
01487 {
01488
if( newy < area.top())
01489 newy = area.top();
01490
if( newy + h > area.bottom() + 1 )
01491 newy = area.bottom() + 1 - h;
01492 assert( newy >= area.top() && newy + h <= area.bottom() + 1 );
01493 }
01494
setGeometry( newx, newy, w, h, force );
01495 }
01496
01497
01498
void Client::NETMoveResizeWindow(
int flags,
int x,
int y,
int width,
int height )
01499 {
01500
int gravity = flags & 0xff;
01501
int value_mask = 0;
01502
if( flags & ( 1 << 8 ))
01503 value_mask |= CWX;
01504
if( flags & ( 1 << 9 ))
01505 value_mask |= CWY;
01506
if( flags & ( 1 << 10 ))
01507 value_mask |= CWWidth;
01508
if( flags & ( 1 << 11 ))
01509 value_mask |= CWHeight;
01510 configureRequest( value_mask, x, y, width, height, gravity,
true );
01511 }
01512
01517 bool Client::isMovable()
const
01518
{
01519
if( !motif_may_move || isFullScreen())
01520
return false;
01521
if( isSpecialWindow() && !isOverride() && !isSplash() && !isToolbar())
01522
return false;
01523
01524
01525
if( rules()->checkPosition( invalidPoint ) != invalidPoint )
01526
return false;
01527
return true;
01528 }
01529
01533 bool Client::isResizable()
const
01534
{
01535
if( !motif_may_resize || isFullScreen())
01536
return false;
01537
if(( isSpecialWindow() || isSplash() || isToolbar()) && !isOverride())
01538
return false;
01539
#if KDE_IS_VERSION( 3, 3, 90 )
01540
#warning Rename the moveresize maximize option.
01541
#endif
01542
01543
01544
if( rules()->checkSize( QSize()).isValid())
01545
return false;
01546
01547 QSize min = minSize();
01548 QSize max = maxSize();
01549
return min.width() < max.width() || min.height() < max.height();
01550 }
01551
01552
01553
01554
01555
bool Client::isMaximizable()
const
01556
{
01557
if( !
isMovable() || !
isResizable() || isToolbar())
01558
return false;
01559
if ( maximizeMode() != MaximizeRestore )
01560
return TRUE;
01561 QSize max = maxSize();
01562
#if 0
01563
if( max.width() < 32767 || max.height() < 32767 )
01564
return false;
01565
#else
01566
01567
01568 QSize areasize = workspace()->clientArea( MaximizeArea,
this ).size();
01569
if( max.width() < areasize.width() || max.height() < areasize.height())
01570
return false;
01571
#endif
01572
return true;
01573 }
01574
01575
01579 void Client::setGeometry(
int x,
int y,
int w,
int h, ForceGeometry_t force )
01580 {
01581
if( force == NormalGeometrySet && frame_geometry == QRect( x, y, w, h ))
01582
return;
01583 frame_geometry = QRect( x, y, w, h );
01584
if( !isShade())
01585 client_size = QSize( w - border_left - border_right, h - border_top - border_bottom );
01586
else
01587 {
01588
01589
if( !shade_geometry_change && h != border_top + border_bottom )
01590 {
01591 kdDebug() <<
"h:" << h <<
":t:" << border_top <<
":b:" << border_bottom << endl;
01592 assert(
false );
01593 }
01594 client_size = QSize( w - border_left - border_right, client_size.height());
01595 }
01596 updateWorkareaDiffs();
01597
if( block_geometry == 0 )
01598 {
01599 XMoveResizeWindow( qt_xdisplay(), frameId(), x, y, w, h );
01600 resizeDecoration( QSize( w, h ));
01601
if( !isShade())
01602 {
01603 QSize cs = clientSize();
01604 XMoveResizeWindow( qt_xdisplay(), wrapperId(), clientPos().x(), clientPos().y(),
01605 cs.width(), cs.height());
01606
01607 XMoveResizeWindow( qt_xdisplay(), window(), 0, 0, cs.width(), cs.height());
01608 }
01609
if( shape())
01610 updateShape();
01611
01612 updateWorkareaDiffs();
01613 sendSyntheticConfigureNotify();
01614 updateWindowRules();
01615 }
01616 }
01617
01618
void Client::plainResize(
int w,
int h, ForceGeometry_t force )
01619 {
01620
if( QSize( w, h ) != rules()->checkSize( QSize( w, h )))
01621 {
01622 kdDebug() <<
"forced size fail:" << QSize( w,h ) <<
":" << rules()->checkSize( QSize( w, h )) << endl;
01623 kdDebug() << kdBacktrace() << endl;
01624 }
01625
if( force == NormalGeometrySet && frame_geometry.size() == QSize( w, h ))
01626
return;
01627 frame_geometry.setSize( QSize( w, h ));
01628
if( !isShade())
01629 client_size = QSize( w - border_left - border_right, h - border_top - border_bottom );
01630
else
01631 {
01632
01633
if( !shade_geometry_change && h != border_top + border_bottom )
01634 {
01635 kdDebug() <<
"h:" << h <<
":t:" << border_top <<
":b:" << border_bottom << endl;
01636 assert(
false );
01637 }
01638 client_size = QSize( w - border_left - border_right, client_size.height());
01639 }
01640 updateWorkareaDiffs();
01641
if( block_geometry == 0 )
01642 {
01643
01644 XResizeWindow( qt_xdisplay(), frameId(), w, h );
01645 resizeDecoration( QSize( w, h ));
01646
if( !isShade())
01647 {
01648 QSize cs = clientSize();
01649 XMoveResizeWindow( qt_xdisplay(), wrapperId(), clientPos().x(), clientPos().y(),
01650 cs.width(), cs.height());
01651 XMoveResizeWindow( qt_xdisplay(), window(), 0, 0, cs.width(), cs.height());
01652 }
01653
if( shape())
01654 updateShape();
01655 updateWorkareaDiffs();
01656 sendSyntheticConfigureNotify();
01657 updateWindowRules();
01658 }
01659 }
01660
01664 void Client::move(
int x,
int y, ForceGeometry_t force )
01665 {
01666
if( force == NormalGeometrySet && frame_geometry.topLeft() == QPoint( x, y ))
01667
return;
01668 frame_geometry.moveTopLeft( QPoint( x, y ));
01669 updateWorkareaDiffs();
01670
if( block_geometry == 0 )
01671 {
01672 XMoveWindow( qt_xdisplay(), frameId(), x, y );
01673 sendSyntheticConfigureNotify();
01674 updateWindowRules();
01675 }
01676 }
01677
01678
01679
void Client::maximize( MaximizeMode m )
01680 {
01681
setMaximize( m & MaximizeVertical, m & MaximizeHorizontal );
01682 }
01683
01687 void Client::setMaximize(
bool vertically,
bool horizontally )
01688 {
01689 changeMaximize(
01690 max_mode & MaximizeVertical ? !vertically : vertically,
01691 max_mode & MaximizeHorizontal ? !horizontally : horizontally,
01692
false );
01693 }
01694
01695
void Client::changeMaximize(
bool vertical,
bool horizontal,
bool adjust )
01696 {
01697
if( !isMaximizable())
01698
return;
01699
01700
if( isShade())
01701 setShade( ShadeNone );
01702
01703 MaximizeMode old_mode = max_mode;
01704
01705
if( !adjust )
01706 {
01707
if( vertical )
01708 max_mode =
MaximizeMode( max_mode ^ MaximizeVertical );
01709
if( horizontal )
01710 max_mode =
MaximizeMode( max_mode ^ MaximizeHorizontal );
01711 }
01712
01713 max_mode = rules()->checkMaximize( max_mode );
01714
if( !adjust && max_mode == old_mode )
01715
return;
01716
01717 ++block_geometry;
01718
01719
01720 Q_ASSERT( !( vertical && horizontal )
01721 || (( max_mode & MaximizeVertical != 0 ) == ( max_mode & MaximizeHorizontal != 0 )));
01722
01723
01724
bool maximalizing =
false;
01725
if( vertical && !(old_mode & MaximizeVertical ))
01726 {
01727 geom_restore.setTop( y());
01728 geom_restore.setHeight( height());
01729 maximalizing =
true;
01730 }
01731
if( horizontal && !( old_mode &
MaximizeHorizontal ))
01732 {
01733 geom_restore.setLeft( x());
01734 geom_restore.setWidth( width());
01735 maximalizing =
true;
01736 }
01737
01738
if( !adjust )
01739 {
01740
if( maximalizing )
01741 Notify::raise( Notify::Maximize );
01742
else
01743 Notify::raise( Notify::UnMaximize );
01744 }
01745
01746
if( decoration != NULL )
01747 decoration->
borders( border_left, border_right, border_top, border_bottom );
01748
01749 QRect clientArea = workspace()->clientArea( MaximizeArea,
this );
01750
01751
switch (max_mode)
01752 {
01753
01754
case MaximizeVertical:
01755 {
01756
if( old_mode &
MaximizeHorizontal )
01757 {
01758
if( geom_restore.width() == 0 )
01759 {
01760 plainResize(
adjustedSize(QSize(width(), clientArea.height()), SizemodeFixedH ));
01761 workspace()->placeSmart(
this, clientArea );
01762 }
01763
else
01764
setGeometry( QRect(QPoint( geom_restore.x(), clientArea.top()),
01765
adjustedSize(QSize( geom_restore.width(), clientArea.height()), SizemodeFixedH )));
01766 }
01767
else
01768
setGeometry( QRect(QPoint(x(), clientArea.top()),
01769
adjustedSize(QSize(width(), clientArea.height()), SizemodeFixedH )));
01770 info->setState( NET::MaxVert, NET::Max );
01771
break;
01772 }
01773
01774
case MaximizeHorizontal:
01775 {
01776
if( old_mode & MaximizeVertical )
01777 {
01778
if( geom_restore.height() == 0 )
01779 {
01780 plainResize(
adjustedSize(QSize(clientArea.width(), height()), SizemodeFixedW ));
01781 workspace()->placeSmart(
this, clientArea );
01782 }
01783
else
01784
setGeometry( QRect( QPoint(clientArea.left(), geom_restore.y()),
01785
adjustedSize(QSize(clientArea.width(), geom_restore.height()), SizemodeFixedW )));
01786 }
01787
else
01788
setGeometry( QRect( QPoint(clientArea.left(), y()),
01789
adjustedSize(QSize(clientArea.width(), height()), SizemodeFixedW )));
01790 info->setState( NET::MaxHoriz, NET::Max );
01791
break;
01792 }
01793
01794
case MaximizeRestore:
01795 {
01796 QRect restore = geometry();
01797
01798
if( old_mode & MaximizeVertical )
01799 {
01800 restore.setTop( geom_restore.top());
01801 restore.setBottom( geom_restore.bottom());
01802 }
01803
if( old_mode &
MaximizeHorizontal )
01804 {
01805 restore.setLeft( geom_restore.left());
01806 restore.setRight( geom_restore.right());
01807 }
01808
if( !restore.isValid())
01809 {
01810 QSize s = QSize( clientArea.width()*2/3, clientArea.height()*2/3 );
01811
if( geom_restore.width() > 0 )
01812 s.setWidth( geom_restore.width());
01813
if( geom_restore.height() > 0 )
01814 s.setHeight( geom_restore.height());
01815 plainResize(
adjustedSize( s ));
01816 workspace()->placeSmart(
this, clientArea );
01817 restore = geometry();
01818
if( geom_restore.width() > 0 )
01819 restore.moveLeft( geom_restore.x());
01820
if( geom_restore.height() > 0 )
01821 restore.moveTop( geom_restore.y());
01822 }
01823
setGeometry( restore );
01824 info->setState( 0, NET::Max );
01825
break;
01826 }
01827
01828
case MaximizeFull:
01829 {
01830 QSize adjSize =
adjustedSize(clientArea.size(), SizemodeMax );
01831 QRect r = QRect(clientArea.topLeft(), adjSize);
01832
setGeometry( r );
01833 info->setState( NET::Max, NET::Max );
01834
break;
01835 }
01836
default:
01837
break;
01838 }
01839
01840 --block_geometry;
01841
setGeometry( geometry(), ForceGeometrySet );
01842
01843 updateAllowedActions();
01844
if( decoration != NULL )
01845 decoration->
maximizeChange();
01846 updateWindowRules();
01847 }
01848
01849
void Client::resetMaximize()
01850 {
01851
if( max_mode ==
MaximizeRestore )
01852
return;
01853 max_mode =
MaximizeRestore;
01854 Notify::raise( Notify::UnMaximize );
01855 info->setState( 0, NET::Max );
01856 updateAllowedActions();
01857
if( decoration != NULL )
01858 decoration->
borders( border_left, border_right, border_top, border_bottom );
01859
setGeometry( geometry(), ForceGeometrySet );
01860
if( decoration != NULL )
01861 decoration->
maximizeChange();
01862 }
01863
01864
bool Client::isFullScreenable(
bool fullscreen_hack )
const
01865
{
01866
if( !rules()->checkFullScreen(
true ))
01867
return false;
01868
if( fullscreen_hack )
01869
return isNormalWindow() || isOverride();
01870
else
01871
return !isSpecialWindow();
01872 }
01873
01874
bool Client::userCanSetFullScreen()
const
01875
{
01876
return isNormalWindow() && fullscreen_mode != FullScreenHack
01877 && ( isMaximizable() || isFullScreen());
01878 }
01879
01880
void Client::setFullScreen(
bool set,
bool user )
01881 {
01882
if( !isFullScreen() && !set )
01883
return;
01884
if( fullscreen_mode == FullScreenHack )
01885
return;
01886
if( user && !userCanSetFullScreen())
01887
return;
01888 set = rules()->checkFullScreen( set );
01889 setShade( ShadeNone );
01890
bool was_fs = isFullScreen();
01891
if( !was_fs )
01892 geom_fs_restore = geometry();
01893 fullscreen_mode = set ? FullScreenNormal : FullScreenNone;
01894
if( was_fs == isFullScreen())
01895
return;
01896 StackingUpdatesBlocker blocker( workspace());
01897 workspace()->updateClientLayer(
this );
01898 info->setState( isFullScreen() ? NET::FullScreen : 0, NET::FullScreen );
01899 updateDecoration(
false,
false );
01900
if( isFullScreen())
01901
setGeometry( workspace()->clientArea( FullScreenArea,
this ));
01902
else
01903 {
01904
if( maximizeMode() != MaximizeRestore )
01905 changeMaximize(
false,
false,
true );
01906
else if( !geom_fs_restore.isNull())
01907
setGeometry( geom_fs_restore );
01908
01909
else
01910 {
01911
setGeometry( workspace()->clientArea( MaximizeArea,
this ));
01912 }
01913 }
01914 updateWindowRules();
01915 }
01916
01917
bool Client::checkFullScreenHack(
const QRect& geom )
const
01918
{
01919
01920
return (( geom.size() == workspace()->clientArea( FullArea, geom.center(),
desktop()).size()
01921 || geom.size() == workspace()->clientArea( ScreenArea, geom.center(),
desktop()).size())
01922 && noBorder() && !isUserNoBorder() && isFullScreenable(
true ));
01923 }
01924
01925
void Client::updateFullScreenHack(
const QRect& geom )
01926 {
01927
bool is_hack = checkFullScreenHack( geom );
01928
if( fullscreen_mode == FullScreenNone && is_hack )
01929 {
01930 fullscreen_mode = FullScreenHack;
01931 updateDecoration(
false,
false );
01932
setGeometry( workspace()->clientArea( FullScreenArea,
this ));
01933 }
01934
else if( fullscreen_mode == FullScreenHack && !is_hack )
01935 {
01936 fullscreen_mode = FullScreenNone;
01937 updateDecoration(
false,
false );
01938
01939 }
01940 StackingUpdatesBlocker blocker( workspace());
01941 workspace()->updateClientLayer(
this );
01942 }
01943
01944
static QRect* visible_bound = 0;
01945
static GeometryTip* geometryTip = 0;
01946
01947
void Client::drawbound(
const QRect& geom )
01948 {
01949 assert( visible_bound == NULL );
01950 visible_bound =
new QRect( geom );
01951 doDrawbound( *visible_bound,
false );
01952 }
01953
01954
void Client::clearbound()
01955 {
01956
if( visible_bound == NULL )
01957
return;
01958 doDrawbound( *visible_bound,
true );
01959
delete visible_bound;
01960 visible_bound = 0;
01961 }
01962
01963
void Client::doDrawbound(
const QRect& geom,
bool clear )
01964 {
01965
if( decoration != NULL && decoration->
drawbound( geom, clear ))
01966
return;
01967 QPainter p ( workspace()->desktopWidget() );
01968 p.setPen( QPen( Qt::white, 5 ) );
01969 p.setRasterOp( Qt::XorROP );
01970 p.drawRect( geom );
01971 }
01972
01973
void Client::positionGeometryTip()
01974 {
01975 assert( isMove() || isResize());
01976
01977
if (options->showGeometryTip())
01978 {
01979
if( !geometryTip )
01980 {
01981
bool save_under = ( isMove() && rules()->checkMoveResizeMode( options->moveMode ) != Options::Opaque )
01982 || ( isResize() && rules()->checkMoveResizeMode( options->resizeMode ) != Options::Opaque );
01983 geometryTip =
new GeometryTip( &xSizeHint, save_under );
01984 }
01985 QRect wgeom( moveResizeGeom );
01986 wgeom.setWidth( wgeom.width() - ( width() - clientSize().width()));
01987 wgeom.setHeight( wgeom.height() - ( height() - clientSize().height()));
01988
if( isShade())
01989 wgeom.setHeight( 0 );
01990 geometryTip->setGeometry( wgeom );
01991
if( !geometryTip->isVisible())
01992 {
01993 geometryTip->show();
01994 geometryTip->raise();
01995 }
01996 }
01997 }
01998
01999
class EatAllPaintEvents
02000 :
public QObject
02001 {
02002
protected:
02003
virtual bool eventFilter( QObject* o, QEvent* e )
02004 {
return e->type() == QEvent::Paint && o != geometryTip; }
02005 };
02006
02007
static EatAllPaintEvents* eater = 0;
02008
02009
bool Client::startMoveResize()
02010 {
02011 assert( !moveResizeMode );
02012 assert( QWidget::keyboardGrabber() == NULL );
02013 assert( QWidget::mouseGrabber() == NULL );
02014
if( QApplication::activePopupWidget() != NULL )
02015
return false;
02016
bool has_grab =
false;
02017
02018
02019
02020 XSetWindowAttributes attrs;
02021 QRect r = workspace()->clientArea( FullArea,
this );
02022 move_resize_grab_window = XCreateWindow( qt_xdisplay(), workspace()->rootWin(), r.x(), r.y(),
02023 r.width(), r.height(), 0, CopyFromParent, InputOnly, CopyFromParent, 0, &attrs );
02024 XMapRaised( qt_xdisplay(), move_resize_grab_window );
02025
if( XGrabPointer( qt_xdisplay(), move_resize_grab_window, False,
02026 ButtonPressMask | ButtonReleaseMask | PointerMotionMask | EnterWindowMask | LeaveWindowMask,
02027 GrabModeAsync, GrabModeAsync, None, cursor.handle(), qt_x_time ) == Success )
02028 has_grab =
true;
02029
if( XGrabKeyboard( qt_xdisplay(), frameId(), False, GrabModeAsync, GrabModeAsync, qt_x_time ) == Success )
02030 has_grab =
true;
02031
if( !has_grab )
02032 {
02033 XDestroyWindow( qt_xdisplay(), move_resize_grab_window );
02034 move_resize_grab_window = None;
02035
return false;
02036 }
02037
if ( maximizeMode() != MaximizeRestore )
02038 resetMaximize();
02039 moveResizeMode =
true;
02040 workspace()->setClientIsMoving(
this);
02041 initialMoveResizeGeom = moveResizeGeom = geometry();
02042 checkUnrestrictedMoveResize();
02043
if ( ( isMove() && rules()->checkMoveResizeMode( options->moveMode ) != Options::Opaque )
02044 || ( isResize() && rules()->checkMoveResizeMode( options->resizeMode ) != Options::Opaque ) )
02045 {
02046 grabXServer();
02047 kapp->sendPostedEvents();
02048
02049
02050
02051
02052
02053 eater =
new EatAllPaintEvents;
02054
02055 }
02056 Notify::raise( isResize() ? Notify::ResizeStart : Notify::MoveStart );
02057
return true;
02058 }
02059
02060
void Client::finishMoveResize(
bool cancel )
02061 {
02062 leaveMoveResize();
02063
if( cancel )
02064
setGeometry( initialMoveResizeGeom );
02065
else
02066
setGeometry( moveResizeGeom );
02067
02068 Notify::raise( isResize() ? Notify::ResizeEnd : Notify::MoveEnd );
02069 }
02070
02071
void Client::leaveMoveResize()
02072 {
02073 clearbound();
02074
if (geometryTip)
02075 {
02076 geometryTip->hide();
02077
delete geometryTip;
02078 geometryTip = NULL;
02079 }
02080
if ( ( isMove() && rules()->checkMoveResizeMode( options->moveMode ) != Options::Opaque )
02081 || ( isResize() && rules()->checkMoveResizeMode( options->resizeMode ) != Options::Opaque ) )
02082 ungrabXServer();
02083 XUngrabKeyboard( qt_xdisplay(), qt_x_time );
02084 XUngrabPointer( qt_xdisplay(), qt_x_time );
02085 XDestroyWindow( qt_xdisplay(), move_resize_grab_window );
02086 move_resize_grab_window = None;
02087 workspace()->setClientIsMoving(0);
02088
if( move_faked_activity )
02089 workspace()->unfakeActivity(
this );
02090 move_faked_activity =
false;
02091 moveResizeMode =
false;
02092
delete eater;
02093 eater = 0;
02094 }
02095
02096
02097
02098
02099
02100
void Client::checkUnrestrictedMoveResize()
02101 {
02102
if( unrestrictedMoveResize )
02103
return;
02104 QRect desktopArea = workspace()->clientArea( WorkArea, moveResizeGeom.center(),
desktop());
02105
int left_marge, right_marge, top_marge, bottom_marge, titlebar_marge;
02106
02107
02108 left_marge = KMIN( 100 + border_right, moveResizeGeom.width());
02109 right_marge = KMIN( 100 + border_left, moveResizeGeom.width());
02110
02111 titlebar_marge = initialMoveResizeGeom.height();
02112 top_marge = border_bottom;
02113 bottom_marge = border_top;
02114
if( isResize())
02115 {
02116
if( moveResizeGeom.bottom() < desktopArea.top() + top_marge )
02117 unrestrictedMoveResize =
true;
02118
if( moveResizeGeom.top() > desktopArea.bottom() - bottom_marge )
02119 unrestrictedMoveResize =
true;
02120
if( moveResizeGeom.right() < desktopArea.left() + left_marge )
02121 unrestrictedMoveResize =
true;
02122
if( moveResizeGeom.left() > desktopArea.right() - right_marge )
02123 unrestrictedMoveResize =
true;
02124
if( !unrestrictedMoveResize && moveResizeGeom.top() < desktopArea.top() )
02125 unrestrictedMoveResize =
true;
02126 }
02127
if( isMove())
02128 {
02129
if( moveResizeGeom.bottom() < desktopArea.top() + titlebar_marge - 1 )
02130 unrestrictedMoveResize =
true;
02131
02132
if( moveResizeGeom.top() > desktopArea.bottom() - bottom_marge )
02133 unrestrictedMoveResize =
true;
02134
if( moveResizeGeom.right() < desktopArea.left() + left_marge )
02135 unrestrictedMoveResize =
true;
02136
if( moveResizeGeom.left() > desktopArea.right() - right_marge )
02137 unrestrictedMoveResize =
true;
02138 }
02139 }
02140
02141
void Client::handleMoveResize(
int x,
int y,
int x_root,
int y_root )
02142 {
02143
if(( mode == PositionCenter && !
isMovable())
02144 || ( mode != PositionCenter && ( isShade() || !
isResizable())))
02145
return;
02146
02147
if ( !moveResizeMode )
02148 {
02149 QPoint p( QPoint( x, y ) - moveOffset );
02150
if (p.manhattanLength() >= 6)
02151 {
02152
if( !startMoveResize())
02153 {
02154 buttonDown =
false;
02155 setCursor( mode );
02156
return;
02157 }
02158 }
02159
else
02160
return;
02161 }
02162
02163
02164
if ( mode != PositionCenter && shade_mode != ShadeNone )
02165 setShade( ShadeNone );
02166
02167 QPoint globalPos( x_root, y_root );
02168
02169
02170 QPoint topleft = globalPos - moveOffset;
02171 QPoint bottomright = globalPos + invertedMoveOffset;
02172 QRect previousMoveResizeGeom = moveResizeGeom;
02173
02174
02175
02176
02177
02178 QRect desktopArea = workspace()->clientArea( WorkArea, globalPos,
desktop());
02179
int left_marge, right_marge, top_marge, bottom_marge, titlebar_marge;
02180
if( unrestrictedMoveResize )
02181 left_marge = right_marge = top_marge = bottom_marge = titlebar_marge = 5;
02182
else
02183 {
02184
02185 left_marge = KMIN( 100 + border_right, moveResizeGeom.width());
02186 right_marge = KMIN( 100 + border_left, moveResizeGeom.width());
02187
02188 titlebar_marge = initialMoveResizeGeom.height();
02189 top_marge = border_bottom;
02190 bottom_marge = border_top;
02191 }
02192
02193
bool update =
false;
02194
if( isResize())
02195 {
02196
02197 QRect orig = initialMoveResizeGeom;
02198 Sizemode sizemode = SizemodeAny;
02199
switch ( mode )
02200 {
02201
case PositionTopLeft:
02202 moveResizeGeom = QRect( topleft, orig.bottomRight() ) ;
02203
break;
02204
case PositionBottomRight:
02205 moveResizeGeom = QRect( orig.topLeft(), bottomright ) ;
02206
break;
02207
case PositionBottomLeft:
02208 moveResizeGeom = QRect( QPoint( topleft.x(), orig.y() ), QPoint( orig.right(), bottomright.y()) ) ;
02209
break;
02210
case PositionTopRight:
02211 moveResizeGeom = QRect( QPoint( orig.x(), topleft.y() ), QPoint( bottomright.x(), orig.bottom()) ) ;
02212
break;
02213
case PositionTop:
02214 moveResizeGeom = QRect( QPoint( orig.left(), topleft.y() ), orig.bottomRight() ) ;
02215 sizemode = SizemodeFixedH;
02216
break;
02217
case PositionBottom:
02218 moveResizeGeom = QRect( orig.topLeft(), QPoint( orig.right(), bottomright.y() ) ) ;
02219 sizemode = SizemodeFixedH;
02220
break;
02221
case PositionLeft:
02222 moveResizeGeom = QRect( QPoint( topleft.x(), orig.top() ), orig.bottomRight() ) ;
02223 sizemode = SizemodeFixedW;
02224
break;
02225
case PositionRight:
02226 moveResizeGeom = QRect( orig.topLeft(), QPoint( bottomright.x(), orig.bottom() ) ) ;
02227 sizemode = SizemodeFixedW;
02228
break;
02229
case PositionCenter:
02230
default:
02231 assert(
false );
02232
break;
02233 }
02234
02235
02236 moveResizeGeom = workspace()->adjustClientSize(
this, moveResizeGeom, mode );
02237
02238
02239
if( moveResizeGeom.bottom() < desktopArea.top() + top_marge )
02240 moveResizeGeom.setBottom( desktopArea.top() + top_marge );
02241
if( moveResizeGeom.top() > desktopArea.bottom() - bottom_marge )
02242 moveResizeGeom.setTop( desktopArea.bottom() - bottom_marge );
02243
if( moveResizeGeom.right() < desktopArea.left() + left_marge )
02244 moveResizeGeom.setRight( desktopArea.left() + left_marge );
02245
if( moveResizeGeom.left() > desktopArea.right() - right_marge )
02246 moveResizeGeom.setLeft(desktopArea.right() - right_marge );
02247
if( !unrestrictedMoveResize && moveResizeGeom.top() < desktopArea.top() )
02248 moveResizeGeom.setTop( desktopArea.top());
02249
02250 QSize size =
adjustedSize( moveResizeGeom.size(), sizemode );
02251
02252 topleft = QPoint( moveResizeGeom.right() - size.width() + 1, moveResizeGeom.bottom() - size.height() + 1 );
02253 bottomright = QPoint( moveResizeGeom.left() + size.width() - 1, moveResizeGeom.top() + size.height() - 1 );
02254 orig = moveResizeGeom;
02255
switch ( mode )
02256 {
02257
case PositionTopLeft:
02258 moveResizeGeom = QRect( topleft, orig.bottomRight() ) ;
02259
break;
02260
case PositionBottomRight:
02261 moveResizeGeom = QRect( orig.topLeft(), bottomright ) ;
02262
break;
02263
case PositionBottomLeft:
02264 moveResizeGeom = QRect( QPoint( topleft.x(), orig.y() ), QPoint( orig.right(), bottomright.y()) ) ;
02265
break;
02266
case PositionTopRight:
02267 moveResizeGeom = QRect( QPoint( orig.x(), topleft.y() ), QPoint( bottomright.x(), orig.bottom()) ) ;
02268
break;
02269
02270
02271
02272
case PositionTop:
02273 moveResizeGeom = QRect( QPoint( orig.left(), topleft.y() ), QPoint( bottomright.x(), orig.bottom()) ) ;
02274
break;
02275
case PositionBottom:
02276 moveResizeGeom = QRect( orig.topLeft(), QPoint( bottomright.x(), bottomright.y() ) ) ;
02277
break;
02278
case PositionLeft:
02279 moveResizeGeom = QRect( QPoint( topleft.x(), orig.top() ), QPoint( orig.right(), bottomright.y()));
02280
break;
02281
case PositionRight:
02282 moveResizeGeom = QRect( orig.topLeft(), QPoint( bottomright.x(), bottomright.y() ) ) ;
02283
break;
02284
case PositionCenter:
02285
default:
02286 assert(
false );
02287
break;
02288 }
02289
if( moveResizeGeom.size() != previousMoveResizeGeom.size())
02290 update =
true;
02291 }
02292
else if( isMove())
02293 {
02294 assert( mode == PositionCenter );
02295
02296 moveResizeGeom.moveTopLeft( topleft );
02297 moveResizeGeom.moveTopLeft( workspace()->adjustClientPosition(
this, moveResizeGeom.topLeft() ) );
02298
02299
if( moveResizeGeom.bottom() < desktopArea.top() + titlebar_marge - 1 )
02300 moveResizeGeom.moveBottom( desktopArea.top() + titlebar_marge - 1 );
02301
02302
if( moveResizeGeom.top() > desktopArea.bottom() - bottom_marge )
02303 moveResizeGeom.moveTop( desktopArea.bottom() - bottom_marge );
02304
if( moveResizeGeom.right() < desktopArea.left() + left_marge )
02305 moveResizeGeom.moveRight( desktopArea.left() + left_marge );
02306
if( moveResizeGeom.left() > desktopArea.right() - right_marge )
02307 moveResizeGeom.moveLeft(desktopArea.right() - right_marge );
02308
if( moveResizeGeom.topLeft() != previousMoveResizeGeom.topLeft())
02309 update =
true;
02310 }
02311
else
02312 assert(
false );
02313
02314
if( update )
02315 {
02316
if( rules()->checkMoveResizeMode
02317 ( isResize() ? options->resizeMode : options->moveMode ) == Options::Opaque )
02318 {
02319
setGeometry( moveResizeGeom );
02320 positionGeometryTip();
02321 }
02322
else if( rules()->checkMoveResizeMode
02323 ( isResize() ? options->resizeMode : options->moveMode ) == Options::Transparent )
02324 {
02325 clearbound();
02326 positionGeometryTip();
02327 drawbound( moveResizeGeom );
02328 }
02329 }
02330
if ( isMove() )
02331 workspace()->clientMoved(globalPos, qt_x_time);
02332 }
02333
02334
02335 }