diff options
Diffstat (limited to 'twin/client.cpp')
-rw-r--r-- | twin/client.cpp | 173 |
1 files changed, 107 insertions, 66 deletions
diff --git a/twin/client.cpp b/twin/client.cpp index b57cab35f..b8f00746e 100644 --- a/twin/client.cpp +++ b/twin/client.cpp @@ -27,6 +27,11 @@ License. See the file "COPYING" for the exact licensing terms. #include <tdelocale.h> #include <stdlib.h> +#ifdef Q_OS_SOLARIS +#include <procfs.h> +#include <libgen.h> +#endif /* SunOS */ + #include "bridge.h" #include "group.h" #include "workspace.h" @@ -94,6 +99,7 @@ Client::Client( Workspace *ws ) decoration( NULL ), wspace( ws ), bridge( new Bridge( this )), + inhibitConfigureRequests(false), move_faked_activity( false ), move_resize_grab_window( None ), transient_for( NULL ), @@ -115,18 +121,23 @@ Client::Client( Workspace *ws ) border_top( 0 ), border_bottom( 0 ), opacity_( 0 ), - demandAttentionKNotifyTimer( NULL ) + demandAttentionKNotifyTimer( NULL ), + activeMaximizing(false), + activeTiled(false) // SELI do all as initialization { autoRaiseTimer = 0; shadeHoverTimer = 0; + configureRequestTimer = new TQTimer(this); + connect(configureRequestTimer, TQ_SIGNAL(timeout()), TQ_SLOT(configureRequestTimeout())); + shadowDelayTimer = new TQTimer(this); opacityCache = &activeOpacityCache; shadowAfterClient = NULL; shadowWidget = NULL; shadowMe = true; - connect(shadowDelayTimer, TQT_SIGNAL(timeout()), TQT_SLOT(drawShadow())); + connect(shadowDelayTimer, TQ_SIGNAL(timeout()), TQ_SLOT(drawShadow())); // set the initial mapping state mapping_state = WithdrawnState; @@ -171,7 +182,7 @@ Client::Client( Workspace *ws ) max_mode = MaximizeRestore; maxmode_restore = MaximizeRestore; - + cmap = None; frame_geometry = TQRect( 0, 0, 100, 100 ); // so that decorations don't start with size being (0,0) @@ -255,7 +266,7 @@ void Client::releaseWindow( bool on_shutdown ) { // Make sure it's not mapped if the app unmapped it (#65279). The app // may do map+unmap before we initially map the window by calling rawShow() from manage(). - XUnmapWindow( tqt_xdisplay(), client ); + XUnmapWindow( tqt_xdisplay(), client ); } client = None; XDestroyWindow( tqt_xdisplay(), wrapper ); @@ -519,7 +530,7 @@ bool Client::isModalSystemNotification() const void Client::updateShape() { // workaround for #19644 - shaped windows shouldn't have decoration - if( shape() && !noBorder()) + if( shape() && !noBorder()) { noborder = true; updateDecoration( true ); @@ -598,7 +609,7 @@ TQRegion Client::mask() const return TQRegion( 0, 0, width(), height()); return _mask; } - + void Client::setShapable(bool b) { long tmp = b?1:0; @@ -740,12 +751,12 @@ void Client::animateMinimizeOrUnminimize( bool minimize ) TQPixmap pm = animationPixmap( minimize ? width() : icongeom.width() ); TQRect before, after; - if ( minimize ) + if ( minimize ) { before = TQRect( x(), y(), width(), pm.height() ); after = TQRect( icongeom.x(), icongeom.y(), icongeom.width(), pm.height() ); } - else + else { before = TQRect( icongeom.x(), icongeom.y(), icongeom.width(), pm.height() ); after = TQRect( x(), y(), width(), pm.height() ); @@ -769,14 +780,14 @@ void Client::animateMinimizeOrUnminimize( bool minimize ) TQPainter p ( workspace()->desktopWidget() ); bool need_to_clear = FALSE; TQPixmap pm3; - do + do { if (area2 != area) { pm = animationPixmap( area.width() ); pm2 = TQPixmap::grabWindow( tqt_xrootwin(), area.x(), area.y(), area.width(), area.height() ); p.drawPixmap( area.x(), area.y(), pm ); - if ( need_to_clear ) + if ( need_to_clear ) { p.drawPixmap( area2.x(), area2.y(), pm3 ); need_to_clear = FALSE; @@ -792,11 +803,11 @@ void Client::animateMinimizeOrUnminimize( bool minimize ) area.setRight(before.right() + int(diff*rf)); area.setTop(before.top() + int(diff*tf)); area.setBottom(before.bottom() + int(diff*bf)); - if (area2 != area ) + if (area2 != area ) { if ( area2.intersects( area ) ) p.drawPixmap( area2.x(), area2.y(), pm2 ); - else + else { // no overlap, we can clear later to avoid flicker pm3 = pm2; need_to_clear = TRUE; @@ -870,7 +881,7 @@ void Client::setShade( ShadeMode mode ) int as = options->animateShade? 10 : 1; // TODO all this unmapping, resizing etc. feels too much duplicated from elsewhere - if ( isShade()) + if ( isShade()) { // shade_mode == ShadeNormal // we're about to shade, texx xcompmgr to prepare long _shade = 1; @@ -884,13 +895,13 @@ void Client::setShade( ShadeMode mode ) XUnmapWindow( tqt_xdisplay(), wrapper ); XUnmapWindow( tqt_xdisplay(), client ); XSelectInput( tqt_xdisplay(), wrapper, ClientWinMask | SubstructureNotifyMask ); - //as we hid the unmap event, xcompmgr didn't recognize the client wid has vanished, so we'll extra inform it + //as we hid the unmap event, xcompmgr didn't recognize the client wid has vanished, so we'll extra inform it //done xcompmgr workaround // FRAME repaint( FALSE ); // bool wasStaticContents = testWFlags( WStaticContents ); // setWFlags( WStaticContents ); - int step = TQMAX( 4, QABS( h - s.height() ) / as )+1; - do + int step = TQMAX( 4, TQABS( h - s.height() ) / as )+1; + do { h -= step; XResizeWindow( tqt_xdisplay(), frameId(), s.width(), h ); @@ -910,17 +921,17 @@ void Client::setShade( ShadeMode mode ) } // tell xcompmgr shade's done _shade = 2; - XChangeProperty(tqt_xdisplay(), frameId(), atoms->net_wm_window_shade, XA_CARDINAL, 32, PropModeReplace, (unsigned char *) &_shade, 1L); + XChangeProperty(tqt_xdisplay(), frameId(), atoms->net_wm_window_shade, XA_CARDINAL, 32, PropModeReplace, (unsigned char *) &_shade, 1L); } - else + else { int h = height(); shade_geometry_change = true; TQSize s( sizeForClientSize( clientSize())); // FRAME bool wasStaticContents = testWFlags( WStaticContents ); // setWFlags( WStaticContents ); - int step = TQMAX( 4, QABS( h - s.height() ) / as )+1; - do + int step = TQMAX( 4, TQABS( h - s.height() ) / as )+1; + do { h += step; XResizeWindow( tqt_xdisplay(), frameId(), s.width(), h ); @@ -962,6 +973,12 @@ void Client::setShade( ShadeMode mode ) updateWindowRules(); } +void Client::configureRequestTimeout() + { + inhibitConfigureRequests = false; + sendSyntheticConfigureNotify(); + } + void Client::shadeHover() { setShade( ShadeHover ); @@ -1193,7 +1210,7 @@ void Client::drawDelayedShadow() void Client::drawShadowAfter(Client *after) { shadowAfterClient = after; - connect(after, TQT_SIGNAL(shadowDrawn()), TQT_SLOT(drawShadow())); + connect(after, TQ_SIGNAL(shadowDrawn()), TQ_SLOT(drawShadow())); } /*! @@ -1207,7 +1224,7 @@ void Client::drawShadow() // If we are waiting for another Client's shadow to be drawn, stop waiting now if (shadowAfterClient != NULL) { - disconnect(shadowAfterClient, TQT_SIGNAL(shadowDrawn()), this, TQT_SLOT(drawShadow())); + disconnect(shadowAfterClient, TQ_SIGNAL(shadowDrawn()), this, TQ_SLOT(drawShadow())); shadowAfterClient = NULL; } @@ -1253,7 +1270,7 @@ void Client::drawShadow() removeShadow(); - TQMemArray<QRgb> pixelData; + TQMemArray<TQRgb> pixelData; TQPixmap shadowPixmap; TQRect shadow; TQRegion exposedRegion; @@ -1426,7 +1443,7 @@ TQRegion Client::getExposedRegion(TQRegion occludedRegion, int x, int y, int w, */ void Client::imposeCachedShadow(TQPixmap &pixmap, TQRegion exposed) { - QRgb pixel; + TQRgb pixel; double opacity; int red, green, blue, pixelRed, pixelGreen, pixelBlue; int subW, subH, w, x, y, zeroX, zeroY; @@ -1483,7 +1500,7 @@ void Client::imposeRegionShadow(TQPixmap &pixmap, TQRegion occluded, TQRegion exposed, int thickness, double maxOpacity) { int distance, intersectCount, i, j, x, y; - QRgb pixel; + TQRgb pixel; double decay, factor, opacity; int red, green, blue, pixelRed, pixelGreen, pixelBlue; int lineIntersects, maxIntersects, maxY; @@ -1697,7 +1714,7 @@ void Client::sendClientMessage(Window w, Atom a, Atom protocol, long data1, long ev.xclient.message_type = a; ev.xclient.format = 32; ev.xclient.data.l[0] = protocol; - ev.xclient.data.l[1] = GET_QT_X_TIME(); + ev.xclient.data.l[1] = get_tqt_x_time(); ev.xclient.data.l[2] = data1; ev.xclient.data.l[3] = data2; ev.xclient.data.l[4] = data3; @@ -1726,14 +1743,14 @@ void Client::closeWindow() if( !isCloseable()) return; // Update user time, because the window may create a confirming dialog. - updateUserTime(); + updateUserTime(); if ( Pdeletewindow ) { Notify::raise( Notify::Close ); sendClientMessage( window(), atoms->wm_protocols, atoms->wm_delete_window); pingWindow(); } - else + else { // client will not react on wm_delete_window. We have not choice // but destroy his connection to the XServer. @@ -1774,9 +1791,9 @@ void Client::pingWindow() if( ping_timer != NULL ) return; // pinging already ping_timer = new TQTimer( this ); - connect( ping_timer, TQT_SIGNAL( timeout()), TQT_SLOT( pingTimeout())); + connect( ping_timer, TQ_SIGNAL( timeout()), TQ_SLOT( pingTimeout())); ping_timer->start( options->killPingTimeout, true ); - ping_timestamp = GET_QT_X_TIME(); + ping_timestamp = get_tqt_x_time(); workspace()->sendPingToWindow( window(), ping_timestamp ); } @@ -1833,8 +1850,8 @@ void Client::killProcess( bool ask, Time timestamp ) << "--applicationname" << resourceClass() << "--wid" << TQCString().setNum( window()) << "--timestamp" << TQCString().setNum( timestamp ); - connect( process_killer, TQT_SIGNAL( processExited( TDEProcess* )), - TQT_SLOT( processKillerExited())); + connect( process_killer, TQ_SIGNAL( processExited( TDEProcess* )), + TQ_SLOT( processKillerExited())); if( !process_killer->start( TDEProcess::NotifyOnExit )) { delete process_killer; @@ -1860,15 +1877,30 @@ bool Client::isSuspendable() const } else { +#ifdef Q_OS_SOLARIS + TQFile procStatFile(TQString("/proc/%1/lwp/1/lwpsinfo").arg(pid)); +#else /* default */ TQFile procStatFile(TQString("/proc/%1/stat").arg(pid)); +#endif if (procStatFile.open(IO_ReadOnly)) { TQByteArray statRaw = procStatFile.readAll(); procStatFile.close(); +#ifdef Q_OS_SOLARIS + lwpsinfo_t *inf = (lwpsinfo_t *)statRaw.data(); + char tbuf[PATH_MAX]; + TQString tcomm; + TQString state(TQChar(inf->pr_sname)); + + readlink(TQString("/proc/%1/path/a.out").arg(pid).latin1(), + tbuf, sizeof(tbuf)); + tcomm = basename(tbuf); +#else /* default */ TQString statString(statRaw); TQStringList statFields = TQStringList::split(" ", statString, TRUE); TQString tcomm = statFields[1]; TQString state = statFields[2]; +#endif /* default */ if( state != "T" ) { // Make sure no windows of this process are special @@ -1921,15 +1953,24 @@ bool Client::isResumeable() const } else { +#ifdef Q_OS_SOLARIS + TQFile procStatFile(TQString("/proc/%1/lwp/1/lwpsinfo").arg(pid)); +#else /* default */ TQFile procStatFile(TQString("/proc/%1/stat").arg(pid)); +#endif if (procStatFile.open(IO_ReadOnly)) { TQByteArray statRaw = procStatFile.readAll(); procStatFile.close(); +#ifdef Q_OS_SOLARIS + lwpsinfo_t *inf = (lwpsinfo_t *)statRaw.data(); + TQString state(TQChar(inf->pr_sname)); +#else /* default */ TQString statString(statRaw); TQStringList statFields = TQStringList::split(" ", statString, TRUE); TQString tcomm = statFields[1]; TQString state = statFields[2]; +#endif /* default */ if( state == "T" ) { return true; @@ -1961,8 +2002,8 @@ bool Client::queryUserSuspendedResume() << "--windowname" << caption().utf8() << "--applicationname" << resourceClass() << "--wid" << TQCString().setNum( window()); - connect( process_resumer, TQT_SIGNAL( processExited( TDEProcess* )), - TQT_SLOT( processResumerExited())); + connect( process_resumer, TQ_SIGNAL( processExited( TDEProcess* )), + TQ_SLOT( processResumerExited())); if( !process_resumer->start( TDEProcess::NotifyOnExit )) { delete process_resumer; @@ -2172,15 +2213,15 @@ void Client::takeActivity( int flags, bool handled, allowed_t ) #ifndef NDEBUG static Time previous_activity_timestamp; static Client* previous_client; - if( previous_activity_timestamp == GET_QT_X_TIME() && previous_client != this ) + if( previous_activity_timestamp == get_tqt_x_time() && previous_client != this ) { kdDebug( 1212 ) << "Repeated use of the same X timestamp for activity" << endl; kdDebug( 1212 ) << kdBacktrace() << endl; } - previous_activity_timestamp = GET_QT_X_TIME(); + previous_activity_timestamp = get_tqt_x_time(); previous_client = this; #endif - workspace()->sendTakeActivity( this, GET_QT_X_TIME(), flags ); + workspace()->sendTakeActivity( this, get_tqt_x_time(), flags ); } // performs the actual focusing of the window using XSetInputFocus and WM_TAKE_FOCUS @@ -2189,17 +2230,17 @@ void Client::takeFocus( allowed_t ) #ifndef NDEBUG static Time previous_focus_timestamp; static Client* previous_client; - if( previous_focus_timestamp == GET_QT_X_TIME() && previous_client != this ) + if( previous_focus_timestamp == get_tqt_x_time() && previous_client != this ) { kdDebug( 1212 ) << "Repeated use of the same X timestamp for focus" << endl; kdDebug( 1212 ) << kdBacktrace() << endl; } - previous_focus_timestamp = GET_QT_X_TIME(); + previous_focus_timestamp = get_tqt_x_time(); previous_client = this; #endif if ( rules()->checkAcceptFocus( input )) { - XSetInputFocus( tqt_xdisplay(), window(), RevertToPointerRoot, GET_QT_X_TIME() ); + XSetInputFocus( tqt_xdisplay(), window(), RevertToPointerRoot, get_tqt_x_time() ); // Work around opacity bug bool activePrev = active; active = true; @@ -2236,7 +2277,7 @@ bool Client::providesContextHelp() const */ void Client::showContextHelp() { - if ( Pcontexthelp ) + if ( Pcontexthelp ) { sendClientMessage(window(), atoms->wm_protocols, atoms->net_wm_context_help); TQWhatsThis::enterWhatsThisMode(); // SELI? @@ -2255,17 +2296,17 @@ void Client::fetchName() TQString Client::readName() const { - if ( info->name() && info->name()[ 0 ] != '\0' ) + if ( info->name() && info->name()[ 0 ] != '\0' ) return TQString::fromUtf8( info->name() ); - else + else return KWin::readNameProperty( window(), XA_WM_NAME ); } - + KWIN_COMPARE_PREDICATE( FetchNameInternalPredicate, const Client*, (!cl->isSpecialWindow() || cl->isToolbar()) && cl != value && cl->caption() == value->caption()); void Client::setCaption( const TQString& s, bool force ) { - if ( s != cap_normal || force ) + if ( s != cap_normal || force ) { bool reset_name = force; for( unsigned int i = 0; @@ -2280,10 +2321,10 @@ void Client::setCaption( const TQString& s, bool force ) machine_suffix = " <@" + wmClientMachine( true ) + ">"; TQString shortcut_suffix = !shortcut().isNull() ? ( " {" + shortcut().toString() + "}" ) : ""; cap_suffix = machine_suffix + shortcut_suffix; - if ( ( !isSpecialWindow() || isToolbar()) && workspace()->findClient( FetchNameInternalPredicate( this ))) + if ( ( !isSpecialWindow() || isToolbar()) && workspace()->findClient( FetchNameInternalPredicate( this ))) { int i = 2; - do + do { cap_suffix = machine_suffix + " <" + TQString::number(i) + ">" + shortcut_suffix; i++; @@ -2313,11 +2354,11 @@ void Client::updateCaption() void Client::fetchIconicName() { TQString s; - if ( info->iconName() && info->iconName()[ 0 ] != '\0' ) + if ( info->iconName() && info->iconName()[ 0 ] != '\0' ) s = TQString::fromUtf8( info->iconName() ); - else + else s = KWin::readNameProperty( window(), XA_WM_ICON_NAME ); - if ( s != cap_iconic ) + if ( s != cap_iconic ) { bool was_set = !cap_iconic.isEmpty(); cap_iconic = s; @@ -2378,7 +2419,7 @@ void Client::getMotifHints() } void Client::readIcons( Window win, TQPixmap* icon, TQPixmap* miniicon ) - { + { // get the icons, allow scaling if( icon != NULL ) *icon = KWin::icon( win, 32, 32, TRUE, KWin::NETWM | KWin::WMHints ); @@ -2494,7 +2535,7 @@ Window Client::staticWmClientLeader(WId w) FALSE, XA_WINDOW, &type, &format, &nitems, &extra, &data ); XSetErrorHandler(oldHandler); - if (status == Success ) + if (status == Success ) { if (data && nitems > 0) result = *((Window*) data); @@ -2672,29 +2713,29 @@ void Client::setCursor( Position m ) { m = PositionCenter; } - switch ( m ) + switch ( m ) { case PositionTopLeft: case PositionBottomRight: - setCursor( tqsizeFDiagCursor ); + setCursor( TQt::sizeFDiagCursor ); break; case PositionBottomLeft: case PositionTopRight: - setCursor( tqsizeBDiagCursor ); + setCursor( TQt::sizeBDiagCursor ); break; case PositionTop: case PositionBottom: - setCursor( tqsizeVerCursor ); + setCursor( TQt::sizeVerCursor ); break; case PositionLeft: case PositionRight: - setCursor( tqsizeHorCursor ); + setCursor( TQt::sizeHorCursor ); break; default: if( buttonDown && isMovable()) - setCursor( tqsizeAllCursor ); + setCursor( TQt::sizeAllCursor ); else - setCursor( tqarrowCursor ); + setCursor( TQt::arrowCursor ); break; } } @@ -2946,7 +2987,7 @@ void Client::updateOpacity() } } } - + void Client::updateShadowSize() // extra syncscreen flag allows to avoid double syncs when active state changes (as it will usually change for two windows) { @@ -2967,7 +3008,7 @@ uint Client::ruleOpacityActive() { return rule_opacity_active;// != 0; } - + bool Client::getWindowOpacity() //query translucency settings from X, returns true if window opacity is set { unsigned char *data = 0; @@ -2985,12 +3026,12 @@ bool Client::getWindowOpacity() //query translucency settings from X, returns tr } return FALSE; } - + void Client::setCustomOpacityFlag(bool custom) { custom_opacity = custom; } - + uint Client::opacity() { return opacity_; @@ -3000,7 +3041,7 @@ int Client::opacityPercentage() { return int(100*((double)opacity_/0xffffffff)); } - + bool Client::touches(const Client* c) // checks if this client borders c, needed to test beep media player window state { @@ -3014,7 +3055,7 @@ bool Client::touches(const Client* c) return TRUE; return FALSE; } - + void Client::setDecoHashProperty(uint topHeight, uint rightWidth, uint bottomHeight, uint leftWidth) { long data = (topHeight < 255 ? topHeight : 255) << 24 | @@ -3028,7 +3069,7 @@ void Client::unsetDecoHashProperty() { XDeleteProperty( tqt_xdisplay(), frameId(), atoms->net_wm_window_decohash); } - + #ifndef NDEBUG kdbgstream& operator<<( kdbgstream& stream, const Client* cl ) { |