XRANDR support in HEAD too, so that curious people don't have to use

kwin_iii. It's still #ifdef-ed out by XRANDR_SUPPORT, just like elsewhere
in kdelibs/kdebase.

svn path=/trunk/kdebase/kwin/; revision=211041
icc-effect-5.14.5
Luboš Luňák 2003-03-03 14:03:56 +00:00
parent bb43159a79
commit 1f87831837
5 changed files with 109 additions and 14 deletions

View File

@ -581,6 +581,7 @@ Client::Client( Workspace *ws, WId w, QWidget *parent, const char *name, WFlags
may_close = TRUE;
is_fullscreen = FALSE;
skip_taskbar = FALSE;
is_fully_inside_workarea = FALSE;
Pdeletewindow = 0;
Ptakefocus = 0;
@ -920,6 +921,8 @@ bool Client::manage( bool isMapped, bool doNotShow, bool isInitial )
doNotShow = true;
bool showMe = (state == NormalState) && isOnDesktop( workspace()->currentDesktop() );
is_fully_inside_workarea = area.contains( geom ); // SELI TODO
workspace()->clientReady( this ); // will call Workspace::propagateClients()
@ -966,7 +969,61 @@ bool Client::manage( bool isMapped, bool doNotShow, bool isInitial )
return showMe;
}
void Client::checkWorkspacePosition()
{
QRect area = workspace()->clientArea( geom.center());
bool now_inside_workarea = area.contains( geom ); // SELI desktop # ?
QRect new_geom = geom;
// Try to be smart about keeping the clients visible.
// If the client was fully inside the workspace before, possibly
// moving it or making it smaller if possible.
// On the other hand, it it was partially moved outside of the workspace,
// don't do anything if it's still at least partially visible. If it's
// not visible anymore at all, make sure it's visible at least partially
// again (not fully, as that could(?) be potentionally annoying) by
// moving it slightly inside the workarea (those '+ area.width() / 10').
if( is_fully_inside_workarea && !now_inside_workarea )
{ // was fully inside workarea - try to make it fully visible again
if( may_resize )
{
QSize new_size = new_geom.size();
if( new_size.width() > area.width())
new_size.setWidth( area.width());
if( new_size.height() > area.height())
new_size.setHeight( area.height());
if( new_size != new_geom.size())
new_geom.setSize( adjustedSize( new_size ));
}
if( may_move )
{
if( new_geom.left() < area.left())
new_geom.moveLeft( area.left());
if( new_geom.right() > area.right())
new_geom.moveRight( area.right());
if( new_geom.top() < area.top())
new_geom.moveTop( area.top());
if( new_geom.bottom() > area.bottom())
new_geom.moveBottom( area.bottom());
}
}
else if( !area.intersects( new_geom ))
{ // not visible at all - try to make it at least partially visible
if( may_move )
{
if( new_geom.left() < area.left())
new_geom.moveRight( area.left() + area.width() / 10 );
if( new_geom.right() > area.right())
new_geom.moveLeft( area.right() - area.width() / 10 );
if( new_geom.top() < area.top())
new_geom.moveBottom( area.top() + area.height() / 10 );
if( new_geom.bottom() > area.bottom())
new_geom.moveTop( area.bottom() - area.height() / 10 );
}
}
if( new_geom != geom )
setGeometry( new_geom );
is_fully_inside_workarea = area.contains( geom );
}
/*!
Updates the user time on the client window. This is called inside
@ -1253,12 +1310,6 @@ bool Client::configureRequest( XConfigureRequestEvent& e )
if ( isResize() )
return TRUE; // we have better things to do right now
if ( isDesktop() ) {
setGeometry( workspace()->geometry() );
sendSyntheticConfigureNotify();
return TRUE;
}
if ( isShade() )
setShade( FALSE );
@ -1386,6 +1437,9 @@ bool Client::configureRequest( XConfigureRequestEvent& e )
if ( e.value_mask & (CWX | CWY | CWWidth | CWHeight ) )
sendSyntheticConfigureNotify();
// SELI TODO accept configure requests for isDesktop windows (because kdesktop
// may get XRANDR resize event before kwin), but check it's still at the bottom?
return TRUE;
}
@ -1862,6 +1916,7 @@ void Client::leaveEvent( QEvent * )
void Client::setGeometry( int x, int y, int w, int h )
{
QWidget::setGeometry(x, y, w, h);
is_fully_inside_workarea = workspace()->clientArea( geom.center()).contains( geom );
if ( !isResize() && isVisible() )
sendSyntheticConfigureNotify();
}

View File

@ -225,6 +225,8 @@ public:
const QPoint gravitate( bool invert ) const;
void NETMoveResize( int x_root, int y_root, NET::Direction direction );
void checkWorkspacePosition();
public slots:
void iconify();
@ -339,6 +341,7 @@ private:
uint may_maximize : 1;
uint may_minimize : 1;
uint may_close : 1;
uint is_fully_inside_workarea : 1;
void getWMHints();
void getWindowProtocols();
QPixmap icon_pix;

View File

@ -136,6 +136,10 @@ Application::Application( )
Workspace* ws = new Workspace( isSessionRestored() );
syncX(); // trigger possible errors, there's still a chance to abort
#ifdef XRANDR_SUPPORT
connect( desktop(), SIGNAL( resized( int )), ws, SLOT( desktopResized()));
#endif
initting = FALSE; // startup done, we are up and running now.
dcopClient()->send( "ksplash", "", "upAndRunning(QString)", QString("wm started"));

View File

@ -400,13 +400,6 @@ Workspace::Workspace( bool restore )
void Workspace::init()
{
QRect r = QApplication::desktop()->geometry();
d->electricTop = r.top();
d->electricBottom = r.bottom();
d->electricLeft = r.left();
d->electricRight = r.right();
d->electric_current_border = 0;
if (options->electricBorders() == Options::ElectricAlways)
createBorderWindows();
@ -3092,6 +3085,40 @@ void Workspace::desktopPopupAboutToShow()
}
}
/*!
Resizes the workspace after an XRANDR screen size change
*/
void Workspace::desktopResized()
{
updateClientArea();
// Reposition clients
for ( ClientList::ConstIterator it = clients.begin(); it != clients.end(); ++it) {
Client* c = *it;
if (c->isFullScreen())
; // nothing
else if( c->isMaximized())
; // done in updateClientArea()
else if( c->isDock())
; // nothing
else if( c->isToolbar() || c->isMenu())
c->checkWorkspacePosition();
else if( c->isTopMenu())
; // nothing
else if( c->windowType() == NET::Override )
; // SELI I wish I knew what to do here :(
else { // NET::Utility, NET::Unknown, NET::Dialog, NET::Normal
c->checkWorkspacePosition();
}
}
// NET::Desktop - nothing
if (options->electricBorders() == Options::ElectricAlways)
{ // update electric borders
destroyBorderWindows();
createBorderWindows();
}
}
/*!
The client popup menu will become visible soon.
@ -4313,6 +4340,10 @@ void Workspace::createBorderWindows()
d->electric_current_border = 0;
QRect r = QApplication::desktop()->geometry();
d->electricTop = r.top();
d->electricBottom = r.bottom();
d->electricLeft = r.left();
d->electricRight = r.right();
XSetWindowAttributes attributes;
unsigned long valuemask;

View File

@ -329,6 +329,8 @@ public slots:
void slotGrabWindow();
void slotGrabDesktop();
void desktopResized();
private slots:
void desktopPopupAboutToShow();
void clientPopupAboutToShow();