22#include <tdeapplication.h>
28#include "notifications.h"
29#include "geometrytip.h"
42void Workspace::desktopResized()
45 TQRect geom = TDEApplication::desktop()->geometry();
46 NETSize desktop_geometry;
47 desktop_geometry.width = geom.width();
48 desktop_geometry.height = geom.height();
49 rootInfo->setDesktopGeometry( -1, desktop_geometry );
51 updateClientArea(
true );
52 destroyActiveBorders();
53 updateActiveBorders();
59void Workspace::kDestopResized()
76void Workspace::updateClientArea(
bool force )
78 TQDesktopWidget *desktopwidget = TDEApplication::desktop();
79 int nscreens = desktopwidget -> numScreens ();
81 TQRect* new_wareas =
new TQRect[ numberOfDesktops() + 1 ];
82 TQRect** new_sareas =
new TQRect*[ numberOfDesktops() + 1];
83 TQRect* screens =
new TQRect [ nscreens ];
84 TQRect desktopArea = desktopwidget -> geometry ();
89 screens [iS] = desktopwidget -> screenGeometry (iS);
92 i <= numberOfDesktops();
95 new_wareas[ i ] = desktopArea;
96 new_sareas[ i ] =
new TQRect [ nscreens ];
100 new_sareas[ i ][ iS ] = screens[ iS ];
102 for ( ClientList::ConstIterator it = clients.begin(); it != clients.end(); ++it)
104 if( !(*it)->hasStrut())
106 TQRect r = (*it)->adjustedClientArea( desktopArea, desktopArea );
107 if( (*it)->isOnAllDesktops())
109 i <= numberOfDesktops();
112 new_wareas[ i ] = new_wareas[ i ].intersect( r );
116 new_sareas[ i ][ iS ] =
117 new_sareas[ i ][ iS ].intersect(
118 (*it)->adjustedClientArea( desktopArea, screens[ iS ] )
123 new_wareas[ (*it)->desktop() ] = new_wareas[ (*it)->desktop() ].intersect( r );
129 new_sareas[ (*it)->desktop() ][ iS ] =
130 new_sareas[ (*it)->desktop() ][ iS ].intersect(
131 (*it)->adjustedClientArea( desktopArea, screens[ iS ] )
138 i <= numberOfDesktops();
144 kdDebug () <<
"new_sarea: " << new_sareas[ i ][ iS ] << endl;
148 if( topmenu_space != NULL )
150 TQRect topmenu_area = desktopArea;
151 topmenu_area.setTop( topMenuHeight());
153 i <= numberOfDesktops();
155 new_wareas[ i ] = new_wareas[ i ].intersect( topmenu_area );
158 bool changed = force;
164 !changed && i <= numberOfDesktops();
167 if( workarea[ i ] != new_wareas[ i ] )
172 if (new_sareas[ i ][ iS ] != screenarea [ i ][ iS ])
179 workarea = new_wareas;
182 screenarea = new_sareas;
185 for(
int i = 1; i <= numberOfDesktops(); i++)
187 r.pos.x = workarea[ i ].x();
188 r.pos.y = workarea[ i ].y();
189 r.size.width = workarea[ i ].width();
190 r.size.height = workarea[ i ].height();
191 rootInfo->setWorkArea( i, r );
194 updateTopMenuGeometry();
195 for( ClientList::ConstIterator it = clients.begin();
198 (*it)->checkWorkspacePosition();
199 for( ClientList::ConstIterator it = desktops.begin();
200 it != desktops.end();
202 (*it)->checkWorkspacePosition();
209void Workspace::updateClientArea()
211 updateClientArea(
false );
222TQRect Workspace::clientArea( clientAreaOption opt,
int screen,
int desktop )
const
224 if( desktop == NETWinInfo::OnAllDesktops || desktop == 0 )
225 desktop = currentDesktop();
226 TQDesktopWidget *desktopwidget = tdeApp->desktop();
227 TQRect sarea = screenarea
228 ? screenarea[ desktop ][ screen ]
229 : desktopwidget->screenGeometry( screen );
230 TQRect warea = workarea[ desktop ].isNull()
231 ? tdeApp->desktop()->geometry()
232 : workarea[ desktop ];
236 if (options->xineramaMaximizeEnabled)
237 if (desktopwidget->numScreens() < 2)
243 case MaximizeFullArea:
244 if (options->xineramaMaximizeEnabled)
245 if (desktopwidget->numScreens() < 2)
246 return desktopwidget->geometry();
248 return desktopwidget->screenGeometry( screen );
250 return desktopwidget->geometry();
252 if (options->xineramaFullscreenEnabled)
253 if (desktopwidget->numScreens() < 2)
254 return desktopwidget->geometry();
256 return desktopwidget->screenGeometry( screen );
258 return desktopwidget->geometry();
260 if (options->xineramaPlacementEnabled)
261 if (desktopwidget->numScreens() < 2)
268 if (options->xineramaMovementEnabled)
269 if (desktopwidget->numScreens() < 2)
270 return desktopwidget->geometry();
272 return desktopwidget->screenGeometry( screen );
274 return desktopwidget->geometry();
278 return desktopwidget->geometry();
280 if (desktopwidget->numScreens() < 2)
281 return desktopwidget->geometry();
283 return desktopwidget->screenGeometry( screen );
289TQRect Workspace::clientArea( clientAreaOption opt,
const TQPoint& p,
int desktop )
const
291 TQDesktopWidget *desktopwidget = TDEApplication::desktop();
292 int screen = desktopwidget->screenNumber( p );
294 screen = desktopwidget->primaryScreen();
295 return clientArea( opt, screen, desktop );
298TQRect Workspace::clientArea( clientAreaOption opt,
const Client* c )
const
300 return clientArea( opt, c->geometry().center(), c->desktop());
309TQPoint Workspace::adjustClientPosition( Client* c, TQPoint pos )
314 if (options->windowSnapZone || options->borderSnapZone )
316 const bool sOWO=options->snapOnlyWhenOverlapping;
317 const TQRect maxRect = clientArea(MovementArea, pos+c->rect().center(), c->desktop());
318 const int xmin = maxRect.left();
319 const int xmax = maxRect.right()+1;
320 const int ymin = maxRect.top();
321 const int ymax = maxRect.bottom()+1;
323 const int cx(pos.x());
324 const int cy(pos.y());
325 const int cw(c->width());
326 const int ch(c->height());
334 int lx, ly, lrx, lry;
337 int snap = options->borderSnapZone;
340 if ((sOWO?(cx<xmin):
true) && (TQABS(xmin-cx)<snap))
345 if ((sOWO?(rx>xmax):
true) && (TQABS(rx-xmax)<snap) && (TQABS(xmax-rx) < deltaX))
351 if ((sOWO?(cy<ymin):
true) && (TQABS(ymin-cy)<snap))
356 if ((sOWO?(ry>ymax):
true) && (TQABS(ry-ymax)<snap) && (TQABS(ymax-ry) < deltaY))
364 snap = options->windowSnapZone;
367 TQValueList<Client *>::ConstIterator l;
368 for (l = clients.begin();l != clients.end();++l )
370 if ((*l)->isOnDesktop(currentDesktop()) &&
376 lrx = lx + (*l)->width();
377 lry = ly + (*l)->height();
379 if ( (( cy <= lry ) && ( cy >= ly )) ||
380 (( ry >= ly ) && ( ry <= lry )) ||
381 (( cy <= ly ) && ( ry >= lry )) )
383 if ((sOWO?(cx<lrx):
true) && (TQABS(lrx-cx)<snap) && ( TQABS(lrx -cx) < deltaX) )
385 deltaX = TQABS( lrx - cx );
388 if ((sOWO?(rx>lx):
true) && (TQABS(rx-lx)<snap) && ( TQABS( rx - lx )<deltaX) )
390 deltaX = TQABS(rx - lx);
395 if ( (( cx <= lrx ) && ( cx >= lx )) ||
396 (( rx >= lx ) && ( rx <= lrx )) ||
397 (( cx <= lx ) && ( rx >= lrx )) )
399 if ((sOWO?(cy<lry):
true) && (TQABS(lry-cy)<snap) && (TQABS( lry -cy ) < deltaY))
401 deltaY = TQABS( lry - cy );
405 if ((sOWO?(ry>ly):
true) && (TQABS(ry-ly)<snap) && (TQABS( ry - ly ) < deltaY ))
407 deltaY = TQABS( ry - ly );
414 pos = TQPoint(nx, ny);
419TQRect Workspace::adjustClientSize( Client* c, TQRect moveResizeGeom,
int mode )
424 if ( options->windowSnapZone || options->borderSnapZone )
426 const bool sOWO=options->snapOnlyWhenOverlapping;
428 const TQRect maxRect = clientArea(MovementArea, c->rect().center(), c->desktop());
429 const int xmin = maxRect.left();
430 const int xmax = maxRect.right();
431 const int ymin = maxRect.top();
432 const int ymax = maxRect.bottom();
434 const int cx(moveResizeGeom.left());
435 const int cy(moveResizeGeom.top());
436 const int rx(moveResizeGeom.right());
437 const int ry(moveResizeGeom.bottom());
439 int newcx(cx), newcy(cy);
440 int newrx(rx), newry(ry);
444 int lx, ly, lrx, lry;
447 int snap = options->borderSnapZone;
453#define SNAP_BORDER_TOP \
454 if ((sOWO?(newcy<ymin):true) && (TQABS(ymin-newcy)<deltaY)) \
456 deltaY = TQABS(ymin-newcy); \
460#define SNAP_BORDER_BOTTOM \
461 if ((sOWO?(newry>ymax):true) && (TQABS(ymax-newry)<deltaY)) \
463 deltaY = TQABS(ymax-newcy); \
467#define SNAP_BORDER_LEFT \
468 if ((sOWO?(newcx<xmin):true) && (TQABS(xmin-newcx)<deltaX)) \
470 deltaX = TQABS(xmin-newcx); \
474#define SNAP_BORDER_RIGHT \
475 if ((sOWO?(newrx>xmax):true) && (TQABS(xmax-newrx)<deltaX)) \
477 deltaX = TQABS(xmax-newrx); \
482 case PositionBottomRight:
492 case PositionTopLeft:
502 case PositionTopRight:
506 case PositionBottomLeft:
519 snap = options->windowSnapZone;
524 TQValueList<Client *>::ConstIterator l;
525 for (l = clients.begin();l != clients.end();++l )
527 if ((*l)->isOnDesktop(currentDesktop()) &&
533 lrx =(*l)->x() + (*l)->width();
534 lry =(*l)->y() + (*l)->height();
536#define WITHIN_HEIGHT ((( newcy <= lry ) && ( newcy >= ly )) || \
537 (( newry >= ly ) && ( newry <= lry )) || \
538 (( newcy <= ly ) && ( newry >= lry )) )
540#define WITHIN_WIDTH ( (( cx <= lrx ) && ( cx >= lx )) || \
541 (( rx >= lx ) && ( rx <= lrx )) || \
542 (( cx <= lx ) && ( rx >= lrx )) )
544#define SNAP_WINDOW_TOP if ( (sOWO?(newcy<lry):true) \
546 && (TQABS( lry - newcy ) < deltaY) ) { \
547 deltaY = TQABS( lry - newcy ); \
551#define SNAP_WINDOW_BOTTOM if ( (sOWO?(newry>ly):true) \
553 && (TQABS( ly - newry ) < deltaY) ) { \
554 deltaY = TQABS( ly - newry ); \
558#define SNAP_WINDOW_LEFT if ( (sOWO?(newcx<lrx):true) \
560 && (TQABS( lrx - newcx ) < deltaX)) { \
561 deltaX = TQABS( lrx - newcx ); \
565#define SNAP_WINDOW_RIGHT if ( (sOWO?(newrx>lx):true) \
567 && (TQABS( lx - newrx ) < deltaX)) \
569 deltaX = TQABS( lx - newrx ); \
575 case PositionBottomRight:
585 case PositionTopLeft:
595 case PositionTopRight:
599 case PositionBottomLeft:
610 moveResizeGeom = TQRect(TQPoint(newcx, newcy), TQPoint(newrx, newry));
612 return moveResizeGeom;
618void Workspace::setClientIsMoving( Client *c )
620 Q_ASSERT(!c || !movingClient);
632void Workspace::cascadeDesktop()
635 Q_ASSERT( block_stacking_updates == 0 );
636 ClientList::ConstIterator it(stackingOrder().begin());
637 initPositioning->reinitCascading( currentDesktop());
638 TQRect area = clientArea( PlacementArea, TQPoint( 0, 0 ), currentDesktop());
639 for (; it != stackingOrder().end(); ++it)
641 if((!(*it)->isOnDesktop(currentDesktop())) ||
642 ((*it)->isMinimized()) ||
643 ((*it)->isOnAllDesktops()) ||
644 (!(*it)->isMovable()) )
646 initPositioning->placeCascaded(*it, area);
654void Workspace::unclutterDesktop()
656 ClientList::Iterator it(clients.fromLast());
657 for (; it != clients.end(); --it)
659 if((!(*it)->isOnDesktop(currentDesktop())) ||
660 ((*it)->isMinimized()) ||
661 ((*it)->isOnAllDesktops()) ||
662 (!(*it)->isMovable()) )
664 initPositioning->placeSmart(*it, TQRect());
669void Workspace::updateTopMenuGeometry( Client* c )
671 if( !managingTopMenus())
676 ev.xclient.display = tqt_xdisplay();
677 ev.xclient.type = ClientMessage;
678 ev.xclient.window = c->window();
679 static Atom msg_type_atom = XInternAtom( tqt_xdisplay(),
"_KDE_TOPMENU_MINSIZE", False );
680 ev.xclient.message_type = msg_type_atom;
681 ev.xclient.format = 32;
682 ev.xclient.data.l[0] = get_tqt_x_time();
683 ev.xclient.data.l[1] = topmenu_space->width();
684 ev.xclient.data.l[2] = topmenu_space->height();
685 ev.xclient.data.l[3] = 0;
686 ev.xclient.data.l[4] = 0;
687 XSendEvent( tqt_xdisplay(), c->window(), False, NoEventMask, &ev );
688 KWin::setStrut( c->window(), 0, 0, topmenu_height, 0 );
689 c->checkWorkspacePosition();
694 area = clientArea( MaximizeFullArea, TQPoint( 0, 0 ), 1 );
695 area.setHeight( topMenuHeight());
696 topmenu_space->setGeometry( area );
697 for( ClientList::ConstIterator it = topmenus.begin();
698 it != topmenus.end();
700 updateTopMenuGeometry( *it );
708void Client::keepInArea( TQRect area,
bool partial )
713 area.setLeft( TQMIN( area.left() - width() + 100, area.left()));
714 area.setTop( TQMIN( area.top() - height() + 100, area.top()));
715 area.setRight( TQMAX( area.right() + width() - 100, area.right()));
716 area.setBottom( TQMAX( area.bottom() + height() - 100, area.bottom()));
718 if ( geometry().right() > area.right() && width() < area.width() )
719 move( area.right() - width(), y() );
720 if ( geometry().bottom() > area.bottom() && height() < area.height() )
721 move( x(), area.bottom() - height() );
722 if( !area.contains( geometry().topLeft() ))
747 NETExtendedStrut str = strut();
748 TQRect stareaL = TQRect(
752 str . left_end - str . left_start + 1 );
753 TQRect stareaR = TQRect (
754 desktopArea . right () - str . right_width + 1,
757 str . right_end - str . right_start + 1 );
758 TQRect stareaT = TQRect (
761 str . top_end - str . top_start + 1,
763 TQRect stareaB = TQRect (
765 desktopArea . bottom () - str . bottom_width + 1,
766 str . bottom_end - str . bottom_start + 1,
769 NETExtendedStrut ext = info->extendedStrut();
770 if( ext.left_width == 0 && ext.right_width == 0 && ext.top_width == 0 && ext.bottom_width == 0
771 && ( str.left_width != 0 || str.right_width != 0 || str.top_width != 0 || str.bottom_width != 0 )) {
779 if (stareaT.top() == geometry().top() && stareaT.bottom() == geometry().bottom()) {
780 stareaT.setLeft(geometry().left());
781 stareaT.setRight(geometry().right());
784 if (stareaB.top() == geometry().top() && stareaB.bottom() == geometry().bottom()) {
785 stareaB.setLeft(geometry().left());
786 stareaB.setRight(geometry().right());
789 if (stareaL.left() == geometry().left() && stareaL.right() == geometry().right()) {
790 stareaL.setTop(geometry().top());
791 stareaL.setBottom(geometry().bottom());
794 if (stareaR.left() == geometry().left() && stareaR.right() == geometry().right()) {
795 stareaR.setTop(geometry().top());
796 stareaR.setBottom(geometry().bottom());
801 TQRect screenarea = workspace()->clientArea( ScreenArea,
this );
805 if( area == tdeApp->desktop()->geometry())
807 if( stareaL.left() < screenarea.left())
809 if( stareaR.right() > screenarea.right())
811 if( stareaT.top() < screenarea.top())
813 if( stareaB.bottom() < screenarea.bottom())
819 stareaL.setLeft( KMAX( stareaL.left(), screenarea.left()));
820 stareaR.setRight( KMIN( stareaR.right(), screenarea.right()));
821 stareaT.setTop( KMAX( stareaT.top(), screenarea.top()));
822 stareaB.setBottom( KMIN( stareaB.bottom(), screenarea.bottom()));
824 if (stareaL . intersects (area)) {
826 r . setLeft( stareaL . right() + 1 );
828 if (stareaR . intersects (area)) {
830 r . setRight( stareaR . left() - 1 );
832 if (stareaT . intersects (area)) {
834 r . setTop( stareaT . bottom() + 1 );
836 if (stareaB . intersects (area)) {
838 r . setBottom( stareaB . top() - 1 );
843NETExtendedStrut Client::strut()
const
845 NETExtendedStrut ext = info->extendedStrut();
846 NETStrut str = info->strut();
847 if( ext.left_width == 0 && ext.right_width == 0 && ext.top_width == 0 && ext.bottom_width == 0
848 && ( str.left != 0 || str.right != 0 || str.top != 0 || str.bottom != 0 ))
853 ext.left_width = str.left;
855 ext.left_end = XDisplayHeight( tqt_xdisplay(), DefaultScreen( tqt_xdisplay()));
859 ext.right_width = str.right;
861 ext.right_end = XDisplayHeight( tqt_xdisplay(), DefaultScreen( tqt_xdisplay()));
865 ext.top_width = str.top;
867 ext.top_end = XDisplayWidth( tqt_xdisplay(), DefaultScreen( tqt_xdisplay()));
869 if( str.bottom != 0 )
871 ext.bottom_width = str.bottom;
872 ext.bottom_start = 0;
873 ext.bottom_end = XDisplayWidth( tqt_xdisplay(), DefaultScreen( tqt_xdisplay()));
879bool Client::hasStrut()
const
881 NETExtendedStrut ext = strut();
882 if( ext.left_width == 0 && ext.right_width == 0 && ext.top_width == 0 && ext.bottom_width == 0 )
889void Client::updateWorkareaDiffs()
891 TQRect area = workspace()->clientArea( WorkArea,
this );
892 TQRect geom = geometry();
893 workarea_diff_x = computeWorkareaDiff( geom.left(), geom.right(), area.left(), area.right());
894 workarea_diff_y = computeWorkareaDiff( geom.top(), geom.bottom(), area.top(), area.bottom());
905int Client::computeWorkareaDiff(
int left,
int right,
int a_left,
int a_right )
907 int left_diff = left - a_left;
908 int right_diff = a_right - right;
909 if( left_diff < 0 || right_diff < 0 )
914 int max_diff = ( a_right - a_left ) / 10;
915 if( left_diff < right_diff )
916 return left_diff < max_diff ? -left_diff - 1 : INT_MAX;
917 else if( left_diff > right_diff )
918 return right_diff < max_diff ? right_diff + 1 : INT_MAX;
923void Client::checkWorkspacePosition()
927 TQRect area = workspace()->clientArea( FullArea,
this );
928 if( geometry() != area )
934 TQRect area = workspace()->clientArea( FullScreenArea,
this );
935 if( geometry() != area )
943 if( workspace()->managingTopMenus())
946 ClientList mainclients = mainClients();
947 if( mainclients.count() == 1 )
948 area = workspace()->clientArea( MaximizeFullArea, mainclients.first());
950 area = workspace()->clientArea( MaximizeFullArea, TQPoint( 0, 0 ),
desktop());
951 area.setHeight( workspace()->topMenuHeight());
958 if( maximizeMode() != MaximizeRestore )
960 changeMaximize(
false,
false,
true );
964 int old_diff_x = workarea_diff_x;
965 int old_diff_y = workarea_diff_y;
966 updateWorkareaDiffs();
973 if( workspace()->initializing())
976 TQRect area = workspace()->clientArea( WorkArea,
this );
977 TQRect new_geom = geometry();
978 TQRect tmp_rect_x( new_geom.left(), 0, new_geom.width(), 0 );
979 TQRect tmp_area_x( area.left(), 0, area.width(), 0 );
980 checkDirection( workarea_diff_x, old_diff_x, tmp_rect_x, tmp_area_x );
982 TQRect tmp_rect_y( new_geom.top(), 0, new_geom.height(), 0 );
983 TQRect tmp_area_y( area.top(), 0, area.height(), 0 );
984 checkDirection( workarea_diff_y, old_diff_y, tmp_rect_y, tmp_area_y );
985 new_geom = TQRect( tmp_rect_x.left(), tmp_rect_y.left(), tmp_rect_x.width(), tmp_rect_y.width());
986 TQRect final_geom( new_geom.topLeft(),
adjustedSize( new_geom.size()));
987 if( final_geom != new_geom )
989 if( old_diff_x != INT_MAX && old_diff_x > 0 )
990 final_geom.moveRight( area.right() - ( old_diff_x - 1 ));
991 if( old_diff_y != INT_MAX && old_diff_y > 0 )
992 final_geom.moveBottom( area.bottom() - ( old_diff_y - 1 ));
994 if( final_geom != geometry() )
1010void Client::checkDirection(
int new_diff,
int old_diff, TQRect& rect,
const TQRect& area )
1012 if( old_diff != INT_MIN )
1014 if( old_diff == INT_MAX )
1016 if( new_diff == INT_MIN )
1018 rect.setLeft( area.left());
1019 rect.setRight( area.right());
1026 rect.moveLeft( area.left() + ( -old_diff - 1 ));
1028 rect.moveRight( area.right() - ( old_diff - 1 ));
1033 rect.setLeft( area.left() + ( -old_diff - 1 ) );
1035 rect.setRight( area.right() - ( old_diff - 1 ));
1038 rect.setWidth( area.width());
1041 if( rect.left() < area.left())
1042 rect.moveLeft( area.left());
1043 else if( rect.right() > area.right())
1044 rect.moveRight( area.right());
1047 if( rect.right() < area.left() + 5 || rect.left() > area.right() - 5 )
1051 if( rect.left() < area.left() + 5 )
1052 rect.moveRight( area.left() + 5 );
1053 if( rect.right() > area.right() - 5 )
1054 rect.moveLeft( area.right() - 5 );
1057 if (!moveResizeMode && options->shadowEnabled(isActive()))
1062 drawIntersectingShadows();
1063 if (options->shadowEnabled(isActive()))
1064 drawDelayedShadow();
1071TQSize Client::adjustedSize(
const TQSize& frame, Sizemode mode )
const
1075 TQSize wsize( frame.width() - ( border_left + border_right ),
1076 frame.height() - ( border_top + border_bottom ));
1077 if( wsize.isEmpty())
1078 wsize = TQSize( 1, 1 );
1080 return sizeForClientSize( wsize, mode,
false );
1085TQSize Client::adjustedSize()
const
1087 return sizeForClientSize( clientSize());
1098TQSize Client::sizeForClientSize(
const TQSize& wsize, Sizemode mode,
bool noframe )
const
1100 int w = wsize.width();
1101 int h = wsize.height();
1102 if( w < 1 || h < 1 )
1104 kdWarning() <<
"sizeForClientSize() with empty size!" << endl;
1105 kdWarning() << kdBacktrace() << endl;
1112 TQSize min_size = minSize();
1113 TQSize max_size = maxSize();
1114 if( decoration != NULL )
1116 TQSize decominsize = decoration->minimumSize();
1117 TQSize border_size( border_left + border_right, border_top + border_bottom );
1118 if( border_size.width() > decominsize.width())
1119 decominsize.setWidth( border_size.width());
1120 if( border_size.height() > decominsize.height())
1121 decominsize.setHeight( border_size.height());
1122 if( decominsize.width() > min_size.width())
1123 min_size.setWidth( decominsize.width());
1124 if( decominsize.height() > min_size.height())
1125 min_size.setHeight( decominsize.height());
1127 w = TQMIN( max_size.width(), w );
1128 h = TQMIN( max_size.height(), h );
1129 w = TQMAX( min_size.width(), w );
1130 h = TQMAX( min_size.height(), h );
1134 int width_inc = xSizeHint.width_inc;
1135 int height_inc = xSizeHint.height_inc;
1137 int basew_inc = (xSizeHint.flags & PBaseSize) ? xSizeHint.base_width : xSizeHint.min_width;
1138 int baseh_inc = (xSizeHint.flags & PBaseSize) ? xSizeHint.base_height : xSizeHint.min_height;
1139 w = int(( w - basew_inc ) / width_inc ) * width_inc + basew_inc;
1140 h = int(( h - baseh_inc ) / height_inc ) * height_inc + baseh_inc;
1156 if( xSizeHint.flags & PAspect )
1158 double min_aspect_w = xSizeHint.min_aspect.x;
1159 double min_aspect_h = xSizeHint.min_aspect.y;
1160 double max_aspect_w = xSizeHint.max_aspect.x;
1161 double max_aspect_h = xSizeHint.max_aspect.y;
1165 w -= xSizeHint.base_width;
1166 h -= xSizeHint.base_height;
1167 int max_width = max_size.width() - xSizeHint.base_width;
1168 int min_width = min_size.width() - xSizeHint.base_width;
1169 int max_height = max_size.height() - xSizeHint.base_height;
1170 int min_height = min_size.height() - xSizeHint.base_height;
1171#define ASPECT_CHECK_GROW_W \
1172 if( min_aspect_w * h > min_aspect_h * w ) \
1174 int delta = int( min_aspect_w * h / min_aspect_h - w ) / width_inc * width_inc; \
1175 if( w + delta <= max_width ) \
1178#define ASPECT_CHECK_SHRINK_H_GROW_W \
1179 if( min_aspect_w * h > min_aspect_h * w ) \
1181 int delta = int( h - w * min_aspect_h / min_aspect_w ) / height_inc * height_inc; \
1182 if( h - delta >= min_height ) \
1186 int delta = int( min_aspect_w * h / min_aspect_h - w ) / width_inc * width_inc; \
1187 if( w + delta <= max_width ) \
1191#define ASPECT_CHECK_GROW_H \
1192 if( max_aspect_w * h < max_aspect_h * w ) \
1194 int delta = int( w * max_aspect_h / max_aspect_w - h ) / height_inc * height_inc; \
1195 if( h + delta <= max_height ) \
1198#define ASPECT_CHECK_SHRINK_W_GROW_H \
1199 if( max_aspect_w * h < max_aspect_h * w ) \
1201 int delta = int( w - max_aspect_w * h / max_aspect_h ) / width_inc * width_inc; \
1202 if( w - delta >= min_width ) \
1206 int delta = int( w * max_aspect_h / max_aspect_w - h ) / height_inc * height_inc; \
1207 if( h + delta <= max_height ) \
1217 ASPECT_CHECK_SHRINK_H_GROW_W
1218 ASPECT_CHECK_SHRINK_W_GROW_H
1224 case SizemodeFixedW:
1228 ASPECT_CHECK_SHRINK_H_GROW_W
1229 ASPECT_CHECK_SHRINK_W_GROW_H
1233 case SizemodeFixedH:
1236 ASPECT_CHECK_SHRINK_W_GROW_H
1237 ASPECT_CHECK_SHRINK_H_GROW_W
1244 ASPECT_CHECK_SHRINK_H_GROW_W
1245 ASPECT_CHECK_SHRINK_W_GROW_H
1251#undef ASPECT_CHECK_SHRINK_H_GROW_W
1252#undef ASPECT_CHECK_SHRINK_W_GROW_H
1253#undef ASPECT_CHECK_GROW_W
1254#undef ASPECT_CHECK_GROW_H
1255 w += xSizeHint.base_width;
1256 h += xSizeHint.base_height;
1258 if( !rules()->checkStrictGeometry(
false ))
1261 if( maximizeMode() & MaximizeHorizontal )
1263 if( maximizeMode() & MaximizeVertical )
1269 w += border_left + border_right;
1270 h += border_top + border_bottom;
1272 return rules()->checkSize( TQSize( w, h ));
1278void Client::getWmNormalHints()
1281 if (XGetWMNormalHints(tqt_xdisplay(), window(), &xSizeHint, &msize) == 0 )
1282 xSizeHint.flags = 0;
1285 if( ! ( xSizeHint.flags & PMinSize ))
1286 xSizeHint.min_width = xSizeHint.min_height = 0;
1287 if( xSizeHint.flags & PBaseSize )
1292 if( ! ( xSizeHint.flags & PMinSize ))
1294 xSizeHint.min_width = xSizeHint.base_width;
1295 xSizeHint.min_height = xSizeHint.base_height;
1299 xSizeHint.base_width = xSizeHint.base_height = 0;
1300 if( ! ( xSizeHint.flags & PMaxSize ))
1301 xSizeHint.max_width = xSizeHint.max_height = INT_MAX;
1304 xSizeHint.max_width = TQMAX( xSizeHint.max_width, 1 );
1305 xSizeHint.max_height = TQMAX( xSizeHint.max_height, 1 );
1307 if( xSizeHint.flags & PResizeInc )
1309 xSizeHint.width_inc = kMax( xSizeHint.width_inc, 1 );
1310 xSizeHint.height_inc = kMax( xSizeHint.height_inc, 1 );
1314 xSizeHint.width_inc = 1;
1315 xSizeHint.height_inc = 1;
1317 if( xSizeHint.flags & PAspect )
1319 xSizeHint.min_aspect.y = kMax( xSizeHint.min_aspect.y, 1 );
1320 xSizeHint.max_aspect.y = kMax( xSizeHint.max_aspect.y, 1 );
1324 xSizeHint.min_aspect.x = 1;
1325 xSizeHint.min_aspect.y = INT_MAX;
1326 xSizeHint.max_aspect.x = INT_MAX;
1327 xSizeHint.max_aspect.y = 1;
1329 if( ! ( xSizeHint.flags & PWinGravity ))
1330 xSizeHint.win_gravity = NorthWestGravity;
1334 if( new_size != size() && !isFullScreen())
1336 TQRect orig_geometry = geometry();
1337 resizeWithChecks( new_size );
1338 if( ( !isSpecialWindow() || isToolbar()) && !isFullScreen())
1342 TQRect area = workspace()->clientArea( MovementArea,
this );
1343 if( area.contains( orig_geometry ))
1345 area = workspace()->clientArea( WorkArea,
this );
1346 if( area.contains( orig_geometry ))
1351 updateAllowedActions();
1354TQSize Client::minSize()
const
1356 return rules()->checkMinSize( TQSize( xSizeHint.min_width, xSizeHint.min_height ));
1359TQSize Client::maxSize()
const
1361 return rules()->checkMaxSize( TQSize( xSizeHint.max_width, xSizeHint.max_height ));
1369void Client::sendSyntheticConfigureNotify()
1372 c.type = ConfigureNotify;
1373 c.send_event = True;
1375 c.window = window();
1376 c.x = x() + clientPos().x();
1377 c.y = y() + clientPos().y();
1378 c.width = clientSize().width();
1379 c.height = clientSize().height();
1382 c.override_redirect = 0;
1383 XSendEvent( tqt_xdisplay(), c.event, True, StructureNotifyMask, (XEvent*)&c );
1386const TQPoint Client::calculateGravitation(
bool invert,
int gravity )
const
1392 gravity = xSizeHint.win_gravity;
1397 case NorthWestGravity:
1406 case NorthEastGravity:
1424 case SouthWestGravity:
1426 dy = -border_bottom;
1430 dy = -border_bottom;
1432 case SouthEastGravity:
1434 dy = -border_bottom;
1437 if( gravity != CenterGravity )
1444 dx = - ( border_left + border_right ) / 2;
1445 dy = - ( border_top + border_bottom ) / 2;
1448 return TQPoint( x() + dx, y() + dy );
1450 return TQPoint( x() - dx, y() - dy );
1453void Client::configureRequest(
int value_mask,
int rx,
int ry,
int rw,
int rh,
int gravity,
bool from_tool )
1456 gravity = xSizeHint.win_gravity;
1457 if( value_mask & ( CWX | CWY ))
1459 TQPoint new_pos = calculateGravitation(
true, gravity );
1460 if ( value_mask & CWX )
1462 if ( value_mask & CWY )
1469 if ( new_pos.x() == x() + clientPos().x() && new_pos.y() == y() + clientPos().y()
1470 && gravity == NorthWestGravity && !from_tool )
1476 int nw = clientSize().width();
1477 int nh = clientSize().height();
1478 if ( value_mask & CWWidth )
1480 if ( value_mask & CWHeight )
1482 TQSize ns = sizeForClientSize( TQSize( nw, nh ) );
1483 new_pos = rules()->checkPosition( new_pos );
1486 if ( maximizeMode() != MaximizeFull
1489 TQRect orig_geometry = geometry();
1490 GeometryUpdatesPostponer blocker(
this );
1493 setGeometry( TQRect( calculateGravitation(
false, gravity ), size()));
1494 updateFullScreenHack( TQRect( new_pos, TQSize( nw, nh )));
1495 TQRect area = workspace()->clientArea( WorkArea,
this );
1496 if( !from_tool && ( !isSpecialWindow() || isToolbar()) && !isFullScreen()
1497 && area.contains( orig_geometry ))
1505 workspace() -> updateClientArea ();
1509 if ( value_mask & (CWWidth | CWHeight )
1510 && ! ( value_mask & ( CWX | CWY )) )
1512 int nw = clientSize().width();
1513 int nh = clientSize().height();
1514 if ( value_mask & CWWidth )
1516 if ( value_mask & CWHeight )
1518 TQSize ns = sizeForClientSize( TQSize( nw, nh ) );
1522 TQRect orig_geometry = geometry();
1523 GeometryUpdatesPostponer blocker(
this );
1524 int save_gravity = xSizeHint.win_gravity;
1525 xSizeHint.win_gravity = gravity;
1526 resizeWithChecks( ns );
1527 xSizeHint.win_gravity = save_gravity;
1528 updateFullScreenHack( TQRect( calculateGravitation(
true, xSizeHint.win_gravity ), TQSize( nw, nh )));
1529 if( !from_tool && ( !isSpecialWindow() || isToolbar()) && !isFullScreen())
1533 TQRect area = workspace()->clientArea( MovementArea,
this );
1534 if( area.contains( orig_geometry ))
1536 area = workspace()->clientArea( WorkArea,
this );
1537 if( area.contains( orig_geometry ))
1547void Client::resizeWithChecks(
int w,
int h, ForceGeometry_t force )
1549 if( shade_geometry_change )
1553 if( h == border_top + border_bottom )
1555 kdWarning() <<
"Shaded geometry passed for size:" << endl;
1556 kdWarning() << kdBacktrace() << endl;
1561 TQRect area = workspace()->clientArea( WorkArea,
this );
1563 if( w > area.width())
1565 if( h > area.height())
1570 switch( xSizeHint.win_gravity )
1572 case NorthWestGravity:
1576 newx = ( newx + width() / 2 ) - ( w / 2 );
1578 case NorthEastGravity:
1579 newx = newx + width() - w;
1582 newy = ( newy + height() / 2 ) - ( h / 2 );
1585 newx = ( newx + width() / 2 ) - ( w / 2 );
1586 newy = ( newy + height() / 2 ) - ( h / 2 );
1592 newx = newx + width() - w;
1593 newy = ( newy + height() / 2 ) - ( h / 2 );
1595 case SouthWestGravity:
1596 newy = newy + height() - h;
1599 newx = ( newx + width() / 2 ) - ( w / 2 );
1600 newy = newy + height() - h;
1602 case SouthEastGravity:
1603 newx = newx + width() - w;
1604 newy = newy + height() - h;
1609 if( workarea_diff_x != INT_MIN && w <= area.width())
1611 if( newx < area.left())
1613 if( newx + w > area.right() + 1 )
1614 newx = area.right() + 1 - w;
1615 assert( newx >= area.left() && newx + w <= area.right() + 1 );
1617 if( workarea_diff_y != INT_MIN && h <= area.height())
1619 if( newy < area.top())
1621 if( newy + h > area.bottom() + 1 )
1622 newy = area.bottom() + 1 - h;
1623 assert( newy >= area.top() && newy + h <= area.bottom() + 1 );
1629void Client::NETMoveResizeWindow(
int flags,
int x,
int y,
int width,
int height )
1631 int gravity = flags & 0xff;
1633 if( flags & ( 1 << 8 ))
1635 if( flags & ( 1 << 9 ))
1637 if( flags & ( 1 << 10 ))
1638 value_mask |= CWWidth;
1639 if( flags & ( 1 << 11 ))
1640 value_mask |= CWHeight;
1641 configureRequest( value_mask, x, y, width, height, gravity,
true );
1650 if( !motif_may_move || isFullScreen())
1652 if( isSpecialWindow() && !isSplash() && !isToolbar())
1654 if( maximizeMode() == MaximizeFull && !options->moveResizeMaximizedWindows() )
1656 if( rules()->checkPosition( invalidPoint ) != invalidPoint )
1666 if( !motif_may_resize || isFullScreen())
1668 if( isSpecialWindow() )
1670 if( maximizeMode() == MaximizeFull && !options->moveResizeMaximizedWindows() )
1672 if( rules()->checkSize( TQSize()).isValid())
1675 TQSize min = minSize();
1676 TQSize max = maxSize();
1677 return min.width() < max.width() || min.height() < max.height();
1683bool Client::isMaximizable()
const
1685 if( isModalSystemNotification())
1689 TemporaryAssign< MaximizeMode > tmp( max_mode, MaximizeRestore );
1693 if ( maximizeMode() != MaximizeRestore )
1695 TQSize max = maxSize();
1697 if( max.width() < 32767 || max.height() < 32767 )
1702 TQSize areasize = workspace()->clientArea( MaximizeArea,
this ).size();
1703 if( max.width() < areasize.width() || max.height() < areasize.height())
1726 if( shade_geometry_change )
1730 if( h == border_top + border_bottom )
1732 kdDebug() <<
"Shaded geometry passed for size:" << endl;
1733 kdDebug() << kdBacktrace() << endl;
1737 client_size = TQSize( w - border_left - border_right, h - border_top - border_bottom );
1738 h = border_top + border_bottom;
1743 client_size = TQSize( w - border_left - border_right, h - border_top - border_bottom );
1745 if( force == NormalGeometrySet && frame_geometry == TQRect( x, y, w, h ))
1747 frame_geometry = TQRect( x, y, w, h );
1748 updateWorkareaDiffs();
1749 if( postpone_geometry_updates != 0 )
1751 pending_geometry_update =
true;
1754 resizeDecoration( TQSize( w, h ));
1755 XMoveResizeWindow( tqt_xdisplay(), frameId(), x, y, w, h );
1759 TQSize cs = clientSize();
1760 XMoveResizeWindow( tqt_xdisplay(), wrapperId(), clientPos().x(), clientPos().y(),
1761 cs.width(), cs.height());
1762 XMoveResizeWindow( tqt_xdisplay(), window(), 0, 0, cs.width(), cs.height());
1766 updateWorkareaDiffs();
1767 sendSyntheticConfigureNotify();
1768 updateWindowRules();
1769 checkMaximizeGeometry();
1770 workspace()->checkActiveScreen(
this );
1773void Client::plainResize(
int w,
int h, ForceGeometry_t force )
1776 if( shade_geometry_change )
1780 if( h == border_top + border_bottom )
1782 kdDebug() <<
"Shaded geometry passed for size:" << endl;
1783 kdDebug() << kdBacktrace() << endl;
1787 client_size = TQSize( w - border_left - border_right, h - border_top - border_bottom );
1788 h = border_top + border_bottom;
1793 client_size = TQSize( w - border_left - border_right, h - border_top - border_bottom );
1795 if( TQSize( w, h ) != rules()->checkSize( TQSize( w, h )))
1797 kdDebug() <<
"forced size fail:" << TQSize( w,h ) <<
":" << rules()->checkSize( TQSize( w, h )) << endl;
1798 kdDebug() << kdBacktrace() << endl;
1800 if( force == NormalGeometrySet && frame_geometry.size() == TQSize( w, h ))
1802 frame_geometry.setSize( TQSize( w, h ));
1803 updateWorkareaDiffs();
1804 if( postpone_geometry_updates != 0 )
1806 pending_geometry_update =
true;
1809 resizeDecoration( TQSize( w, h ));
1810 XResizeWindow( tqt_xdisplay(), frameId(), w, h );
1814 TQSize cs = clientSize();
1815 XMoveResizeWindow( tqt_xdisplay(), wrapperId(), clientPos().x(), clientPos().y(),
1816 cs.width(), cs.height());
1817 XMoveResizeWindow( tqt_xdisplay(), window(), 0, 0, cs.width(), cs.height());
1820 updateWorkareaDiffs();
1821 sendSyntheticConfigureNotify();
1822 updateWindowRules();
1823 checkMaximizeGeometry();
1824 workspace()->checkActiveScreen(
this );
1832 if( force == NormalGeometrySet && frame_geometry.topLeft() == TQPoint( x, y ))
1834 frame_geometry.moveTopLeft( TQPoint( x, y ));
1835 updateWorkareaDiffs();
1836 if( postpone_geometry_updates != 0 )
1838 pending_geometry_update =
true;
1841 XMoveWindow( tqt_xdisplay(), frameId(), x, y );
1842 sendSyntheticConfigureNotify();
1843 updateWindowRules();
1844 checkMaximizeGeometry();
1845 workspace()->checkActiveScreen(
this );
1849void Client::postponeGeometryUpdates(
bool postpone )
1853 if( postpone_geometry_updates == 0 )
1854 pending_geometry_update =
false;
1855 ++postpone_geometry_updates;
1859 if( --postpone_geometry_updates == 0 )
1861 if( pending_geometry_update )
1864 setGeometry( TQRect( pos(), adjustedSize()), ForceGeometrySet );
1867 pending_geometry_update =
false;
1873void Client::maximize( MaximizeMode m )
1875 setMaximize( m & MaximizeVertical, m & MaximizeHorizontal );
1884 max_mode & MaximizeVertical ? !vertically : vertically,
1885 max_mode & MaximizeHorizontal ? !horizontally : horizontally,
1889void Client::changeMaximize(
bool vertical,
bool horizontal,
bool adjust )
1891 if( !isMaximizable())
1894 MaximizeMode old_mode = max_mode;
1899 max_mode = MaximizeMode( max_mode ^ MaximizeVertical );
1901 max_mode = MaximizeMode( max_mode ^ MaximizeHorizontal );
1904 max_mode = rules()->checkMaximize( max_mode );
1905 if( !adjust && max_mode == old_mode )
1908 GeometryUpdatesPostponer blocker(
this );
1911 Q_ASSERT( !( vertical && horizontal )
1912 || ((( max_mode & MaximizeVertical ) != 0 ) == (( max_mode & MaximizeHorizontal ) != 0 )));
1914 TQRect clientArea = workspace()->clientArea( MaximizeArea,
this );
1917 if( !adjust && !( y() == clientArea.top() && height() == clientArea.height()))
1919 geom_restore.setTop( y());
1920 geom_restore.setHeight( height());
1922 if( !adjust && !( x() == clientArea.left() && width() == clientArea.width()))
1924 geom_restore.setLeft( x());
1925 geom_restore.setWidth( width());
1930 if(( vertical && !(old_mode & MaximizeVertical ))
1931 || ( horizontal && !( old_mode & MaximizeHorizontal )))
1932 Notify::raise( Notify::Maximize );
1934 Notify::raise( Notify::UnMaximize );
1937 if( decoration != NULL )
1938 decoration->borders( border_left, border_right, border_top, border_bottom );
1941 if ( old_mode==MaximizeFull && max_mode==MaximizeRestore )
1943 if ( maximizeModeRestore()==MaximizeVertical )
1945 max_mode = MaximizeVertical;
1946 maxmode_restore = MaximizeRestore;
1948 if ( maximizeModeRestore()==MaximizeHorizontal )
1950 max_mode = MaximizeHorizontal;
1951 maxmode_restore = MaximizeRestore;
1958 case MaximizeVertical:
1960 if( old_mode & MaximizeHorizontal )
1962 if( geom_restore.width() == 0 )
1964 plainResize(
adjustedSize(TQSize(width(), clientArea.height()), SizemodeFixedH ));
1965 workspace()->placeSmart(
this, clientArea );
1968 setGeometry( TQRect(TQPoint( geom_restore.x(), clientArea.top()),
1969 adjustedSize(TQSize( geom_restore.width(), clientArea.height()), SizemodeFixedH )), ForceGeometrySet);
1972 setGeometry( TQRect(TQPoint(x(), clientArea.top()),
1973 adjustedSize(TQSize(width(), clientArea.height()), SizemodeFixedH )), ForceGeometrySet);
1974 info->setState( NET::MaxVert, NET::Max );
1978 case MaximizeHorizontal:
1980 if( old_mode & MaximizeVertical )
1982 if( geom_restore.height() == 0 )
1984 plainResize(
adjustedSize(TQSize(clientArea.width(), height()), SizemodeFixedW ));
1985 workspace()->placeSmart(
this, clientArea );
1988 setGeometry( TQRect( TQPoint(clientArea.left(), geom_restore.y()),
1989 adjustedSize(TQSize(clientArea.width(), geom_restore.height()), SizemodeFixedW )), ForceGeometrySet);
1992 setGeometry( TQRect( TQPoint(clientArea.left(), y()),
1993 adjustedSize(TQSize(clientArea.width(), height()), SizemodeFixedW )), ForceGeometrySet);
1994 info->setState( NET::MaxHoriz, NET::Max );
1998 case MaximizeRestore:
2000 TQRect restore = geometry();
2002 if( old_mode & MaximizeVertical )
2004 restore.setTop( geom_restore.top());
2005 restore.setBottom( geom_restore.bottom());
2007 if( old_mode & MaximizeHorizontal )
2009 restore.setLeft( geom_restore.left());
2010 restore.setRight( geom_restore.right());
2012 if( !restore.isValid())
2014 TQSize s = TQSize( clientArea.width()*2/3, clientArea.height()*2/3 );
2015 if( geom_restore.width() > 0 )
2016 s.setWidth( geom_restore.width());
2017 if( geom_restore.height() > 0 )
2018 s.setHeight( geom_restore.height());
2020 workspace()->placeSmart(
this, clientArea );
2021 restore = geometry();
2022 if( geom_restore.width() > 0 )
2023 restore.moveLeft( geom_restore.x());
2024 if( geom_restore.height() > 0 )
2025 restore.moveTop( geom_restore.y());
2028 info->setState( 0, NET::Max );
2036 if( old_mode & MaximizeVertical )
2037 maxmode_restore = MaximizeVertical;
2038 if( old_mode & MaximizeHorizontal )
2039 maxmode_restore = MaximizeHorizontal;
2041 TQSize adjSize =
adjustedSize(clientArea.size(), SizemodeMax );
2042 TQRect r = TQRect(clientArea.topLeft(), adjSize);
2044 info->setState( NET::Max, NET::Max );
2051 updateAllowedActions();
2052 if( decoration != NULL )
2053 decoration->maximizeChange();
2054 updateWindowRules();
2057void Client::resetMaximize()
2059 if( max_mode == MaximizeRestore )
2061 max_mode = MaximizeRestore;
2062 Notify::raise( Notify::UnMaximize );
2063 info->setState( 0, NET::Max );
2064 updateAllowedActions();
2065 if( decoration != NULL )
2066 decoration->borders( border_left, border_right, border_top, border_bottom );
2068 setGeometry( TQRect( pos(), sizeForClientSize( clientSize())), ForceGeometrySet );
2071 if( decoration != NULL )
2072 decoration->maximizeChange();
2075void Client::checkMaximizeGeometry()
2081 if( isMove() || isResize())
2084 static int recursion_protection = 0;
2085 if( recursion_protection > 3 )
2087 kdWarning( 1212 ) <<
"Check maximize overflow - you loose!" << endl;
2088 kdWarning( 1212 ) << kdBacktrace() << endl;
2091 ++recursion_protection;
2092 TQRect max_area = workspace()->clientArea( MaximizeArea,
this );
2093 if( geometry() == max_area )
2095 if( max_mode != MaximizeFull )
2096 maximize( MaximizeFull );
2098 else if( x() == max_area.left() && width() == max_area.width())
2100 if( max_mode != MaximizeHorizontal )
2101 maximize( MaximizeHorizontal );
2103 else if( y() == max_area.top() && height() == max_area.height())
2105 if( max_mode != MaximizeVertical )
2106 maximize( MaximizeVertical );
2108 else if( max_mode != MaximizeRestore )
2112 --recursion_protection;
2115bool Client::isFullScreenable(
bool fullscreen_hack )
const
2117 if( !rules()->checkFullScreen(
true ))
2119 if( fullscreen_hack )
2120 return isNormalWindow();
2121 if( rules()->checkStrictGeometry(
false ))
2124 TQRect fsarea = workspace()->clientArea( FullScreenArea,
this );
2125 if( sizeForClientSize( fsarea.size(), SizemodeAny,
true ) != fsarea.size())
2129 return !isSpecialWindow();
2132bool Client::userCanSetFullScreen()
const
2134 if( fullscreen_mode == FullScreenHack )
2136 if( !isFullScreenable(
false ))
2139 TemporaryAssign< FullScreenMode > tmp( fullscreen_mode, FullScreenNone );
2140 return isNormalWindow() && isMaximizable();
2143void Client::setFullScreen(
bool set,
bool user )
2145 if( !isFullScreen() && !set )
2147 if( fullscreen_mode == FullScreenHack )
2149 if( user && !userCanSetFullScreen())
2151 set = rules()->checkFullScreen( set );
2152 setShade( ShadeNone );
2153 bool was_fs = isFullScreen();
2155 geom_fs_restore = geometry();
2156 fullscreen_mode = set ? FullScreenNormal : FullScreenNone;
2157 if( was_fs == isFullScreen())
2159 StackingUpdatesBlocker blocker1( workspace());
2160 GeometryUpdatesPostponer blocker2(
this );
2161 workspace()->updateClientLayer(
this );
2162 info->setState( isFullScreen() ? NET::FullScreen : 0, NET::FullScreen );
2163 updateDecoration(
false,
false );
2165 setGeometry( workspace()->clientArea( FullScreenArea,
this ));
2168 if( !geom_fs_restore.isNull())
2173 setGeometry( workspace()->clientArea( MaximizeArea,
this ));
2176 updateWindowRules();
2179int Client::checkFullScreenHack(
const TQRect& geom )
const
2182 if( noBorder() && !isUserNoBorder() && isFullScreenable(
true ))
2184 if( geom.size() == workspace()->clientArea( FullArea, geom.center(),
desktop()).size())
2186 if( geom.size() == workspace()->clientArea( ScreenArea, geom.center(),
desktop()).size())
2192void Client::updateFullScreenHack(
const TQRect& geom )
2194 int type = checkFullScreenHack( geom );
2195 if( fullscreen_mode == FullScreenNone && type != 0 )
2197 fullscreen_mode = FullScreenHack;
2198 updateDecoration(
false,
false );
2200 if( rules()->checkStrictGeometry(
false ))
2203 ? workspace()->clientArea( FullArea, geom.center(),
desktop())
2204 : workspace()->clientArea( ScreenArea, geom.center(),
desktop());
2207 geom = workspace()->clientArea( FullScreenArea, geom.center(),
desktop());
2210 else if( fullscreen_mode == FullScreenHack && type == 0 )
2212 fullscreen_mode = FullScreenNone;
2213 updateDecoration(
false,
false );
2216 StackingUpdatesBlocker blocker( workspace());
2217 workspace()->updateClientLayer(
this );
2220static TQRect* visible_bound =
nullptr;
2221static GeometryTip* geometryTip =
nullptr;
2223void Client::drawbound(
const TQRect& geom )
2225 assert( visible_bound == NULL );
2226 visible_bound =
new TQRect( geom );
2227 doDrawbound( *visible_bound,
false );
2230void Client::clearbound()
2232 if( visible_bound == NULL )
2234 doDrawbound( *visible_bound,
true );
2235 delete visible_bound;
2239void Client::doDrawbound(
const TQRect& geom,
bool clear )
2241 if( decoration != NULL && decoration->drawbound( geom, clear ))
2243 TQPainter p ( workspace()->desktopWidget() );
2244 p.setPen( TQPen( TQt::white, 5 ) );
2245 p.setRasterOp( TQt::XorROP );
2251 g.setLeft( g.left() + 2 );
2252 g.setRight( g.right() - 2 );
2254 if( g.height() > 5 )
2256 g.setTop( g.top() + 2 );
2257 g.setBottom( g.bottom() - 2 );
2262void Client::positionGeometryTip() {
2263 assert(isMove() || isResize());
2266 if (options->showGeometryTip()) {
2269 bool save_under = ( isMove() && rules()->checkMoveResizeMode( options->moveMode ) != Options::Opaque )
2270 || ( isResize() && rules()->checkMoveResizeMode( options->resizeMode ) != Options::Opaque );
2271 geometryTip =
new GeometryTip( &xSizeHint, save_under );
2275 TQRect wgeom(isActiveBorderMaximizing() ? activeBorderMaximizeGeometry() : moveResizeGeom);
2276 wgeom.setWidth(wgeom.width() - (width() - clientSize().width()));
2277 wgeom.setHeight(isShade() ? 0 : wgeom.height() - (height() - clientSize().height()));
2279 geometryTip->setGeometry(wgeom);
2280 if (!geometryTip->isVisible()) {
2281 geometryTip->show();
2282 geometryTip->raise();
2287class EatAllPaintEvents
2291 virtual bool eventFilter( TQObject* o, TQEvent* e )
2292 {
return e->type() == TQEvent::Paint && o != geometryTip; }
2295static EatAllPaintEvents* eater = 0;
2297bool Client::startMoveResize()
2299 assert( !moveResizeMode );
2300 assert( TQWidget::keyboardGrabber() == NULL );
2301 assert( TQWidget::mouseGrabber() == NULL );
2302 if( TQApplication::activePopupWidget() != NULL )
2304 bool has_grab =
false;
2308 XSetWindowAttributes attrs;
2309 TQRect r = workspace()->clientArea( FullArea,
this );
2310 move_resize_grab_window = XCreateWindow( tqt_xdisplay(), workspace()->rootWin(), r.x(), r.y(),
2311 r.width(), r.height(), 0, CopyFromParent, InputOnly, CopyFromParent, 0, &attrs );
2312 XMapRaised( tqt_xdisplay(), move_resize_grab_window );
2313 if( XGrabPointer( tqt_xdisplay(), move_resize_grab_window, False,
2314 ButtonPressMask | ButtonReleaseMask | PointerMotionMask | EnterWindowMask | LeaveWindowMask,
2315 GrabModeAsync, GrabModeAsync, move_resize_grab_window, cursor.handle(), get_tqt_x_time() ) == Success )
2317 if( XGrabKeyboard( tqt_xdisplay(), frameId(), False, GrabModeAsync, GrabModeAsync, get_tqt_x_time() ) == Success )
2321 XDestroyWindow( tqt_xdisplay(), move_resize_grab_window );
2322 move_resize_grab_window = None;
2327 moveResizeMode =
true;
2328 initialMoveResizeGeom = geometry();
2330 if ( maximizeMode() != MaximizeRestore )
2332 if (options->resetMaximizedWindowGeometry() && isMove()) {
2338 geom_restore.moveLeft(TQCursor::pos().x() - (geom_restore.width() / 2));
2339 moveOffset.setX(TQCursor::pos().x() - geom_restore.x());
2343 maximize(MaximizeRestore);
2348 activeTiled =
false;
2351 moveResizeGeom = geometry();
2352 workspace()->setClientIsMoving(
this);
2353 checkUnrestrictedMoveResize();
2356 if ((isResize() && options->removeShadowsOnResize) || (isMove() && options->removeShadowsOnMove))
2361 if (rules()->checkMoveResizeMode( options->moveMode ) == Options::Opaque)
2363 savedOpacity_ = opacity_;
2364 setOpacity(options->translucentMovingWindows ? options->movingWindowOpacity : Opacity::Opaque);
2367 if ( ( isMove() && rules()->checkMoveResizeMode( options->moveMode ) != Options::Opaque )
2368 || ( isResize() && rules()->checkMoveResizeMode( options->resizeMode ) != Options::Opaque ) )
2371 tdeApp->sendPostedEvents();
2380 Notify::raise( isResize() ? Notify::ResizeStart : Notify::MoveStart );
2382 if (options->activeBorders() == Options::ActiveSwitchOnMove ||
2383 options->activeBorders() == Options::ActiveTileMaximize ||
2384 options->activeBorders() == Options::ActiveTileOnly)
2387 workspace()->reserveActiveBorderSwitching(
true);
2393void Client::finishMoveResize(
bool cancel )
2397 if (!isActiveBorderMaximizing()) {
2398 setGeometry(cancel ? initialMoveResizeGeom : moveResizeGeom);
2403 kdDebug() <<
"finishing moveresize in active mode, cancel is " << cancel << endl;
2404 activeMaximizing =
false;
2406 geom_restore = initialMoveResizeGeom;
2409 case ActiveMaximizeMode: {
2411 bool full = (maximizeMode() == MaximizeFull);
2418 : activeBorderMaximizeGeometry());
2422 checkMaximizeGeometry();
2424 Notify::raise( isResize() ? Notify::ResizeEnd : Notify::MoveEnd );
2427void Client::leaveMoveResize()
2430 if (rules()->checkMoveResizeMode( options->moveMode ) == Options::Opaque)
2431 setOpacity(savedOpacity_);
2432 if ((isResize() && options->removeShadowsOnResize) || (isMove() && options->removeShadowsOnMove))
2437 geometryTip->hide();
2441 if ( ( isMove() && rules()->checkMoveResizeMode( options->moveMode ) != Options::Opaque )
2442 || ( isResize() && rules()->checkMoveResizeMode( options->resizeMode ) != Options::Opaque ) )
2444 XUngrabKeyboard( tqt_xdisplay(), get_tqt_x_time() );
2445 XUngrabPointer( tqt_xdisplay(), get_tqt_x_time() );
2446 XDestroyWindow( tqt_xdisplay(), move_resize_grab_window );
2447 move_resize_grab_window = None;
2448 workspace()->setClientIsMoving(0);
2449 if( move_faked_activity )
2450 workspace()->unfakeActivity(
this );
2451 move_faked_activity =
false;
2452 moveResizeMode =
false;
2455 if (options->shadowEnabled(isActive()))
2457 drawIntersectingShadows();
2458 updateOpacityCache();
2461 if (options->activeBorders() == Options::ActiveSwitchOnMove ||
2462 options->activeBorders() == Options::ActiveTileMaximize ||
2463 options->activeBorders() == Options::ActiveTileOnly)
2465 workspace()->reserveActiveBorderSwitching(
false);
2473void Client::checkUnrestrictedMoveResize()
2475 if( unrestrictedMoveResize )
2477 TQRect desktopArea = workspace()->clientArea( WorkArea, moveResizeGeom.center(),
desktop());
2478 int left_marge, right_marge, top_marge, bottom_marge, titlebar_marge;
2481 left_marge = KMIN( 100 + border_right, moveResizeGeom.width());
2482 right_marge = KMIN( 100 + border_left, moveResizeGeom.width());
2484 titlebar_marge = initialMoveResizeGeom.height();
2485 top_marge = border_bottom;
2486 bottom_marge = border_top;
2489 if( moveResizeGeom.bottom() < desktopArea.top() + top_marge )
2490 unrestrictedMoveResize =
true;
2491 if( moveResizeGeom.top() > desktopArea.bottom() - bottom_marge )
2492 unrestrictedMoveResize =
true;
2493 if( moveResizeGeom.right() < desktopArea.left() + left_marge )
2494 unrestrictedMoveResize =
true;
2495 if( moveResizeGeom.left() > desktopArea.right() - right_marge )
2496 unrestrictedMoveResize =
true;
2497 if( !unrestrictedMoveResize && moveResizeGeom.top() < desktopArea.top() )
2498 unrestrictedMoveResize =
true;
2502 if( moveResizeGeom.bottom() < desktopArea.top() + titlebar_marge - 1 )
2503 unrestrictedMoveResize =
true;
2505 if( moveResizeGeom.top() > desktopArea.bottom() - bottom_marge )
2506 unrestrictedMoveResize =
true;
2507 if( moveResizeGeom.right() < desktopArea.left() + left_marge )
2508 unrestrictedMoveResize =
true;
2509 if( moveResizeGeom.left() > desktopArea.right() - right_marge )
2510 unrestrictedMoveResize =
true;
2514void Client::handleMoveResize(
int x,
int y,
int x_root,
int y_root) {
2515 if ( (mode == PositionCenter && !
isMovable())
2516 || (mode != PositionCenter && (isShade() || !
isResizable())) )
2519 if (!moveResizeMode) {
2520 TQPoint p(TQPoint( x, y ) - moveOffset);
2521 if (p.manhattanLength() >= 6) {
2522 if (!startMoveResize()) {
2532 if ( mode != PositionCenter && shade_mode != ShadeNone )
2533 setShade( ShadeNone );
2535 TQPoint globalPos( x_root, y_root );
2538 TQPoint topleft = globalPos - moveOffset;
2539 TQPoint bottomright = globalPos + invertedMoveOffset;
2540 TQRect previousMoveResizeGeom = moveResizeGeom;
2546 TQRect desktopArea = workspace()->clientArea( WorkArea, globalPos,
desktop());
2547 int left_marge, right_marge, top_marge, bottom_marge, titlebar_marge;
2548 if( unrestrictedMoveResize )
2549 left_marge = right_marge = top_marge = bottom_marge = titlebar_marge = 5;
2553 left_marge = KMIN( 100 + border_right, moveResizeGeom.width());
2554 right_marge = KMIN( 100 + border_left, moveResizeGeom.width());
2556 titlebar_marge = initialMoveResizeGeom.height();
2557 top_marge = border_bottom;
2558 bottom_marge = border_top;
2561 bool update =
false;
2565 TQRect orig = initialMoveResizeGeom;
2566 Sizemode sizemode = SizemodeAny;
2569 case PositionTopLeft:
2570 moveResizeGeom = TQRect( topleft, orig.bottomRight() ) ;
2572 case PositionBottomRight:
2573 moveResizeGeom = TQRect( orig.topLeft(), bottomright ) ;
2575 case PositionBottomLeft:
2576 moveResizeGeom = TQRect( TQPoint( topleft.x(), orig.y() ), TQPoint( orig.right(), bottomright.y()) ) ;
2578 case PositionTopRight:
2579 moveResizeGeom = TQRect( TQPoint( orig.x(), topleft.y() ), TQPoint( bottomright.x(), orig.bottom()) ) ;
2582 moveResizeGeom = TQRect( TQPoint( orig.left(), topleft.y() ), orig.bottomRight() ) ;
2583 sizemode = SizemodeFixedH;
2585 case PositionBottom:
2586 moveResizeGeom = TQRect( orig.topLeft(), TQPoint( orig.right(), bottomright.y() ) ) ;
2587 sizemode = SizemodeFixedH;
2590 moveResizeGeom = TQRect( TQPoint( topleft.x(), orig.top() ), orig.bottomRight() ) ;
2591 sizemode = SizemodeFixedW;
2594 moveResizeGeom = TQRect( orig.topLeft(), TQPoint( bottomright.x(), orig.bottom() ) ) ;
2595 sizemode = SizemodeFixedW;
2597 case PositionCenter:
2604 moveResizeGeom = workspace()->adjustClientSize(
this, moveResizeGeom, mode );
2607 if( moveResizeGeom.bottom() < desktopArea.top() + top_marge )
2608 moveResizeGeom.setBottom( desktopArea.top() + top_marge );
2609 if( moveResizeGeom.top() > desktopArea.bottom() - bottom_marge )
2610 moveResizeGeom.setTop( desktopArea.bottom() - bottom_marge );
2611 if( moveResizeGeom.right() < desktopArea.left() + left_marge )
2612 moveResizeGeom.setRight( desktopArea.left() + left_marge );
2613 if( moveResizeGeom.left() > desktopArea.right() - right_marge )
2614 moveResizeGeom.setLeft(desktopArea.right() - right_marge );
2615 if( !unrestrictedMoveResize && moveResizeGeom.top() < desktopArea.top() )
2616 moveResizeGeom.setTop( desktopArea.top());
2618 TQSize size =
adjustedSize( moveResizeGeom.size(), sizemode );
2620 topleft = TQPoint( moveResizeGeom.right() - size.width() + 1, moveResizeGeom.bottom() - size.height() + 1 );
2621 bottomright = TQPoint( moveResizeGeom.left() + size.width() - 1, moveResizeGeom.top() + size.height() - 1 );
2622 orig = moveResizeGeom;
2625 case PositionTopLeft:
2626 moveResizeGeom = TQRect( topleft, orig.bottomRight() ) ;
2628 case PositionBottomRight:
2629 moveResizeGeom = TQRect( orig.topLeft(), bottomright ) ;
2631 case PositionBottomLeft:
2632 moveResizeGeom = TQRect( TQPoint( topleft.x(), orig.y() ), TQPoint( orig.right(), bottomright.y()) ) ;
2634 case PositionTopRight:
2635 moveResizeGeom = TQRect( TQPoint( orig.x(), topleft.y() ), TQPoint( bottomright.x(), orig.bottom()) ) ;
2641 moveResizeGeom = TQRect( TQPoint( orig.left(), topleft.y() ), TQPoint( bottomright.x(), orig.bottom()) ) ;
2643 case PositionBottom:
2644 moveResizeGeom = TQRect( orig.topLeft(), TQPoint( bottomright.x(), bottomright.y() ) ) ;
2647 moveResizeGeom = TQRect( TQPoint( topleft.x(), orig.top() ), TQPoint( orig.right(), bottomright.y()));
2650 moveResizeGeom = TQRect( orig.topLeft(), TQPoint( bottomright.x(), bottomright.y() ) ) ;
2652 case PositionCenter:
2657 if (moveResizeGeom.size() != previousMoveResizeGeom.size())
2662 assert( mode == PositionCenter );
2664 moveResizeGeom.moveTopLeft( topleft );
2665 moveResizeGeom.moveTopLeft( workspace()->adjustClientPosition(
this, moveResizeGeom.topLeft() ) );
2667 if( moveResizeGeom.bottom() < desktopArea.top() + titlebar_marge - 1 )
2668 moveResizeGeom.moveBottom( desktopArea.top() + titlebar_marge - 1 );
2670 if( moveResizeGeom.top() > desktopArea.bottom() - bottom_marge )
2671 moveResizeGeom.moveTop( desktopArea.bottom() - bottom_marge );
2672 if( moveResizeGeom.right() < desktopArea.left() + left_marge )
2673 moveResizeGeom.moveRight( desktopArea.left() + left_marge );
2674 if( moveResizeGeom.left() > desktopArea.right() - right_marge )
2675 moveResizeGeom.moveLeft(desktopArea.right() - right_marge );
2676 if( moveResizeGeom.topLeft() != previousMoveResizeGeom.topLeft())
2684 bool active = isActiveBorderMaximizing();
2685 auto mode = active ? options->tilingMode
2686 : isResize() ? options->resizeMode : options->moveMode;
2688 if (rules()->checkMoveResizeMode(mode) == Options::Opaque)
2690 setGeometry(active ? activeBorderMaximizeGeometry() : moveResizeGeom);
2691 positionGeometryTip();
2693 else if (rules()->checkMoveResizeMode(mode) == Options::Transparent)
2701 positionGeometryTip();
2702 drawbound(active ? activeBorderMaximizeGeometry() : moveResizeGeom);
2706 workspace()->checkActiveBorder(globalPos, get_tqt_x_time());
2710void Client::setActiveBorderMode( ActiveMaximizingMode mode )
2715ActiveMaximizingMode Client::activeBorderMode()
const
2720void Client::setActiveBorderPos( TQPoint pos )
2725TQPoint Client::activeBorderPos()
const
2730void Client::setActiveBorder(ActiveBorder border) {
2731 currentActiveBorder = border;
2734ActiveBorder Client::activeBorder()
const {
2735 return currentActiveBorder;
2738bool Client::isActiveBorderMaximizing()
const
2740 return activeMaximizing;
2743void Client::setActiveBorderMaximizing(
bool maximizing )
2745 activeMaximizing = maximizing;
2746 bool opaque = rules()->checkMoveResizeMode(options->tilingMode) == Options::Opaque;
2748 if (maximizing || opaque) {
2752 if (maximizing && !opaque) {
2753 drawbound(activeBorderMaximizeGeometry());
2757void Client::cancelActiveBorderMaximizing() {
2758 if (!activeMaximizing)
return;
2759 activeMaximizing =
false;
2762 if (rules()->checkMoveResizeMode(options->tilingMode) == Options::Transparent) {
2767TQRect Client::activeBorderMaximizeGeometry()
2770 TQRect max = workspace()->clientArea(MaximizeArea, activePos, workspace()->currentDesktop());
2771 switch (activeBorderMode())
2773 case ActiveMaximizeMode:
2775 if (maximizeMode() == MaximizeFull)
2776 ret = geometryRestore();
2782 case ActiveTilingMode:
2784 switch (activeBorder())
2788 ret = TQRect( max.x(), max.y(), max.width()/2, max.height() );
2793 ret = TQRect( max.x() + max.width()/2, max.y(), max.width()/2, max.height() );
2798 ret = TQRect( max.x(), max.y(), max.width(), max.height()/2 );
2803 ret = TQRect( max.x(), max.y() + max.height()/2, max.width(), max.height()/2 );
2808 ret = TQRect( max.x(), max.y(), max.width()/2, max.height()/2 );
2811 case ActiveTopRight:
2813 ret = TQRect( max.x() + max.width()/2, max.y(), max.width()/2, max.height()/2 );
2816 case ActiveBottomLeft:
2818 ret = TQRect( max.x(), max.y() + max.height()/2, max.width()/2, max.height()/2 );
2821 case ActiveBottomRight:
2823 ret = TQRect( max.x() + max.width()/2, max.y() + max.height()/2, max.width()/2, max.height()/2);
2832void Client::tileToBorder(ActiveBorder border) {
2835 if (maximizeMode() == MaximizeRestore)
2836 geom_restore = geometry();
2837 setActiveBorderMode(ActiveTilingMode);
2838 setActiveBorderPos(TQCursor().pos());
2839 setActiveBorder(border);
2840 TQRect geo = activeBorderMaximizeGeometry();
2841 if (geo.isValid() && !geo.isEmpty()) {
2844 workspace()->raiseClient(
this);
TQRect adjustedClientArea(const TQRect &desktop, const TQRect &area) const
void setGeometry(int x, int y, int w, int h, ForceGeometry_t force=NormalGeometrySet)
TQSize adjustedSize(const TQSize &, Sizemode mode=SizemodeAny) const
void setMaximize(bool vertically, bool horizontally)
void move(int x, int y, ForceGeometry_t force=NormalGeometrySet)