summaryrefslogtreecommitdiffstats
path: root/twin/client.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'twin/client.cpp')
-rw-r--r--twin/client.cpp173
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 )
{