00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include <stdlib.h>
00023 #include <unistd.h>
00024
00025 #ifdef HAVE_SYSENT_H
00026 #include <sysent.h>
00027 #endif
00028
00029 #include <qapplication.h>
00030 #include <qbitmap.h>
00031 #include <qimage.h>
00032 #include <qwhatsthis.h>
00033 #include <qcstring.h>
00034
00035 #include "config.h"
00036
00037 #include "kwin.h"
00038 #include "kapplication.h"
00039
00040 #include <kglobal.h>
00041 #include <kiconloader.h>
00042 #include <kdebug.h>
00043
00044 #include <kdatastream.h>
00045 #include <klocale.h>
00046 #include <dcopclient.h>
00047 #if defined Q_WS_X11 && ! defined K_WS_QTONLY
00048 #include <kstartupinfo.h>
00049 #include <kxerrorhandler.h>
00050
00051 #include <X11/Xlib.h>
00052 #include <X11/Xatom.h>
00053 #include <X11/Xutil.h>
00054
00055 #include "netwm.h"
00056
00057 static bool atoms_created = false;
00058 extern Atom qt_wm_protocols;
00059 extern Time qt_x_time;
00060 extern Time qt_x_user_time;
00061
00062 static Atom net_wm_context_help;
00063 static Atom kde_wm_change_state;
00064 static void kwin_net_create_atoms() {
00065 if (!atoms_created){
00066 const int max = 20;
00067 Atom* atoms[max];
00068 const char* names[max];
00069 Atom atoms_return[max];
00070 int n = 0;
00071
00072 atoms[n] = &net_wm_context_help;
00073 names[n++] = "_NET_WM_CONTEXT_HELP";
00074
00075 atoms[n] = &kde_wm_change_state;
00076 names[n++] = "_KDE_WM_CHANGE_STATE";
00077
00078
00079 XInternAtoms( qt_xdisplay(), const_cast<char**>(names), n, false, atoms_return );
00080 for (int i = 0; i < n; i++ )
00081 *atoms[i] = atoms_return[i];
00082
00083 atoms_created = True;
00084 }
00085 }
00086 #endif
00087
00088
00089
00090
00091 static void sendClientMessageToRoot(Window w, Atom a, long x, long y = 0, long z = 0 ){
00092 #if defined Q_WS_X11 && ! defined K_WS_QTONLY
00093 XEvent ev;
00094 long mask;
00095
00096 memset(&ev, 0, sizeof(ev));
00097 ev.xclient.type = ClientMessage;
00098 ev.xclient.window = w;
00099 ev.xclient.message_type = a;
00100 ev.xclient.format = 32;
00101 ev.xclient.data.l[0] = x;
00102 ev.xclient.data.l[1] = y;
00103 ev.xclient.data.l[2] = z;
00104 mask = SubstructureRedirectMask;
00105 XSendEvent(qt_xdisplay(), qt_xrootwin(), False, mask, &ev);
00106 #endif
00107 }
00108
00109
00110
00111
00112 static void sendClientMessage(Window w, Atom a, long x){
00113 #if defined Q_WS_X11 && ! defined K_WS_QTONLY
00114 XEvent ev;
00115 long mask;
00116
00117 memset(&ev, 0, sizeof(ev));
00118 ev.xclient.type = ClientMessage;
00119 ev.xclient.window = w;
00120 ev.xclient.message_type = a;
00121 ev.xclient.format = 32;
00122 ev.xclient.data.l[0] = x;
00123 ev.xclient.data.l[1] = CurrentTime;
00124 mask = 0L;
00125 if (w == qt_xrootwin())
00126 mask = SubstructureRedirectMask;
00127 XSendEvent(qt_xdisplay(), w, False, mask, &ev);
00128 #endif
00129 }
00130
00131 namespace
00132 {
00133 class ContextWidget : public QWidget
00134 {
00135 public:
00136 ContextWidget();
00137 virtual bool x11Event( XEvent * ev);
00138 };
00139
00140 ContextWidget::ContextWidget()
00141 : QWidget(0,0)
00142 {
00143 #if defined Q_WS_X11 && ! defined K_WS_QTONLY
00144 kwin_net_create_atoms();
00145 kapp->installX11EventFilter( this );
00146 QWhatsThis::enterWhatsThisMode();
00147 QCursor c = *QApplication::overrideCursor();
00148 QWhatsThis::leaveWhatsThisMode();
00149 XGrabPointer( qt_xdisplay(), qt_xrootwin(), true,
00150 (uint)( ButtonPressMask | ButtonReleaseMask |
00151 PointerMotionMask | EnterWindowMask |
00152 LeaveWindowMask ),
00153 GrabModeAsync, GrabModeAsync,
00154 None, c.handle(), CurrentTime );
00155 qApp->enter_loop();
00156 #endif
00157 }
00158
00159
00160 bool ContextWidget::x11Event( XEvent * ev)
00161 {
00162 #if defined Q_WS_X11 && ! defined K_WS_QTONLY
00163 if ( ev->type == ButtonPress && ev->xbutton.button == Button1 ) {
00164 XUngrabPointer( qt_xdisplay(), ev->xbutton.time );
00165 Window root;
00166 Window child = qt_xrootwin();
00167 int root_x, root_y, lx, ly;
00168 uint state;
00169 Window w;
00170 do {
00171 w = child;
00172 XQueryPointer( qt_xdisplay(), w, &root, &child,
00173 &root_x, &root_y, &lx, &ly, &state );
00174 } while ( child != None && child != w );
00175
00176 ::sendClientMessage(w, qt_wm_protocols, net_wm_context_help);
00177 XEvent e = *ev;
00178 e.xbutton.window = w;
00179 e.xbutton.subwindow = w;
00180 e.xbutton.x = lx;
00181 e.xbutton.y = ly;
00182 XSendEvent( qt_xdisplay(), w, true, ButtonPressMask, &e );
00183 qApp->exit_loop();
00184 return true;
00185 }
00186 return false;
00187 #endif
00188 }
00189 }
00190
00191 void KWin::invokeContextHelp()
00192 {
00193 ContextWidget w;
00194 }
00195
00196 void KWin::setSystemTrayWindowFor( WId trayWin, WId forWin )
00197 {
00198 #if defined Q_WS_X11 && ! defined K_WS_QTONLY
00199 NETWinInfo info( qt_xdisplay(), trayWin, qt_xrootwin(), 0 );
00200 if ( !forWin )
00201 forWin = qt_xrootwin();
00202 info.setKDESystemTrayWinFor( forWin );
00203 #endif
00204 }
00205
00206 void KWin::activateWindow( WId win, long time )
00207 {
00208 #if defined Q_WS_X11 && ! defined K_WS_QTONLY
00209 NETRootInfo info( qt_xdisplay(), 0 );
00210 if( time == 0 )
00211 time = qt_x_user_time;
00212 info.setActiveWindow( win, NET::FromApplication, time,
00213 kapp->activeWindow() ? kapp->activeWindow()->winId() : 0 );
00214 #endif // Q_WS_X11 ...
00215 }
00216
00217 void KWin::forceActiveWindow( WId win, long time )
00218 {
00219 #if defined Q_WS_X11 && ! defined K_WS_QTONLY
00220 NETRootInfo info( qt_xdisplay(), 0 );
00221 if( time == 0 )
00222 time = qt_x_time;
00223 info.setActiveWindow( win, NET::FromTool, time, 0 );
00224 #endif // Q_WS_X11 ...
00225 }
00226
00227 void KWin::setActiveWindow( WId win )
00228 {
00229 #if defined Q_WS_X11 && ! defined K_WS_QTONLY
00230 NETRootInfo info( qt_xdisplay(), 0 );
00231 info.setActiveWindow( win, NET::FromUnknown, 0, 0 );
00232 #endif
00233 }
00234
00235 void KWin::demandAttention( WId win, bool set )
00236 {
00237 #if defined Q_WS_X11 && ! defined K_WS_QTONLY
00238 NETWinInfo info( qt_xdisplay(), win, qt_xrootwin(), 0 );
00239 info.setState( set ? NET::DemandsAttention : 0, NET::DemandsAttention );
00240 #endif
00241 }
00242
00243 void KWin::setUserTime( WId win, long time )
00244 {
00245 #if defined Q_WS_X11 && ! defined K_WS_QTONLY
00246 NETWinInfo info( qt_xdisplay(), win, qt_xrootwin(), 0 );
00247 info.setUserTime( time );
00248 #endif
00249 }
00250
00251 KWin::WindowInfo KWin::windowInfo( WId win, unsigned long properties, unsigned long properties2 )
00252 {
00253 return WindowInfo( win, properties, properties2 );
00254 }
00255
00256
00257 WId KWin::transientFor( WId win )
00258 {
00259 #if defined Q_WS_X11 && ! defined K_WS_QTONLY
00260 KXErrorHandler handler;
00261 Window transient_for = None;
00262 if( XGetTransientForHint( qt_xdisplay(), win, &transient_for ))
00263 return transient_for;
00264
00265 return None;
00266 #else
00267 return 0L;
00268 #endif
00269 }
00270
00271 WId KWin::groupLeader( WId win )
00272 {
00273 #if defined Q_WS_X11 && ! defined K_WS_QTONLY
00274 KXErrorHandler handler;
00275 XWMHints *hints = XGetWMHints( qt_xdisplay(), win );
00276 Window window_group = None;
00277 if ( hints )
00278 {
00279 if( hints->flags & WindowGroupHint )
00280 window_group = hints->window_group;
00281 XFree( reinterpret_cast< char* >( hints ));
00282 }
00283
00284 return window_group;
00285 #else
00286 return 0L;
00287 #endif
00288 }
00289
00290
00291 KWin::Info KWin::info( WId win )
00292 {
00293 Info w;
00294 #if defined Q_WS_X11 && ! defined K_WS_QTONLY
00295 NETWinInfo inf( qt_xdisplay(), win, qt_xrootwin(),
00296 NET::WMState |
00297 NET::WMStrut |
00298 NET::WMWindowType |
00299 NET::WMName |
00300 NET::WMVisibleName |
00301 NET::WMDesktop |
00302 NET::WMPid |
00303 NET::WMKDEFrameStrut |
00304 NET::XAWMState
00305 );
00306
00307 w.win = win;
00308 w.state = inf.state();
00309 w.mappingState = inf.mappingState();
00310 w.strut = inf.strut();
00311 w.windowType = inf.windowType();
00312 if ( inf.name() ) {
00313 w.name = QString::fromUtf8( inf.name() );
00314 } else {
00315 char* c = 0;
00316 if ( XFetchName( qt_xdisplay(), win, &c ) != 0 ) {
00317 w.name = QString::fromLocal8Bit( c );
00318 XFree( c );
00319 }
00320 }
00321 if ( inf.visibleName() )
00322 w.visibleName = QString::fromUtf8( inf.visibleName() );
00323 else
00324 w.visibleName = w.name;
00325
00326 w.desktop = inf.desktop();
00327 w.onAllDesktops = inf.desktop() == NETWinInfo::OnAllDesktops;
00328 w.pid = inf.pid();
00329 NETRect frame, geom;
00330 inf.kdeGeometry( frame, geom );
00331 w.geometry.setRect( geom.pos.x, geom.pos.y, geom.size.width, geom.size.height );
00332 w.frameGeometry.setRect( frame.pos.x, frame.pos.y, frame.size.width, frame.size.height );
00333 #endif
00334 return w;
00335 }
00336
00337 QPixmap KWin::icon( WId win, int width, int height, bool scale )
00338 {
00339 return icon( win, width, height, scale, NETWM | WMHints | ClassHint | XApp );
00340 }
00341
00342
00343 QPixmap KWin::icon( WId win, int width, int height, bool scale, int flags )
00344 {
00345 #if defined Q_WS_X11 && ! defined K_WS_QTONLY
00346 KXErrorHandler handler;
00347 #endif
00348 QPixmap result;
00349 #if defined Q_WS_X11 && ! defined K_WS_QTONLY
00350 if( flags & NETWM ) {
00351 NETWinInfo info( qt_xdisplay(), win, qt_xrootwin(), NET::WMIcon );
00352 NETIcon ni = info.icon( width, height );
00353 if ( ni.data && ni.size.width > 0 && ni.size.height > 0 ) {
00354 QImage img( (uchar*) ni.data, (int) ni.size.width, (int) ni.size.height, 32, 0, 0, QImage::IgnoreEndian );
00355 img.setAlphaBuffer( true );
00356 if ( scale && width > 0 && height > 0 &&img.size() != QSize( width, height ) && !img.isNull() )
00357 img = img.smoothScale( width, height );
00358 if ( !img.isNull() )
00359 result.convertFromImage( img );
00360 return result;
00361 }
00362 }
00363
00364 if( flags & WMHints ) {
00365 Pixmap p = None;
00366 Pixmap p_mask = None;
00367
00368 XWMHints *hints = XGetWMHints(qt_xdisplay(), win );
00369 if (hints && (hints->flags & IconPixmapHint)){
00370 p = hints->icon_pixmap;
00371 }
00372 if (hints && (hints->flags & IconMaskHint)){
00373 p_mask = hints->icon_mask;
00374 }
00375 if (hints)
00376 XFree((char*)hints);
00377
00378 if (p != None){
00379 Window root;
00380 int x, y;
00381 unsigned int w = 0;
00382 unsigned int h = 0;
00383 unsigned int border_w, depth;
00384 XGetGeometry(qt_xdisplay(), p, &root,
00385 &x, &y, &w, &h, &border_w, &depth);
00386 if (w > 0 && h > 0){
00387 QPixmap pm(w, h, depth);
00388
00389 pm.detach();
00390 XCopyArea(qt_xdisplay(), p, pm.handle(),
00391 qt_xget_temp_gc(qt_xscreen(), depth==1),
00392 0, 0, w, h, 0, 0);
00393 if (p_mask != None){
00394 QBitmap bm(w, h);
00395 XCopyArea(qt_xdisplay(), p_mask, bm.handle(),
00396 qt_xget_temp_gc(qt_xscreen(), true),
00397 0, 0, w, h, 0, 0);
00398 pm.setMask(bm);
00399 }
00400 if ( scale && width > 0 && height > 0 && !pm.isNull() &&
00401 ( (int) w != width || (int) h != height) ){
00402 result.convertFromImage( pm.convertToImage().smoothScale( width, height ) );
00403 } else {
00404 result = pm;
00405 }
00406 }
00407 }
00408 }
00409
00410
00411
00412
00413 int iconWidth;
00414 if( width < 24 )
00415 iconWidth = 16;
00416 else if( width < 40 )
00417 iconWidth = 32;
00418 else
00419 iconWidth = 48;
00420
00421 if( flags & ClassHint ) {
00422
00423
00424 if( result.isNull() ) {
00425
00426 XClassHint hint;
00427 if( XGetClassHint( qt_xdisplay(), win, &hint ) ) {
00428 QString className = hint.res_class;
00429
00430 QPixmap pm = KGlobal::instance()->iconLoader()->loadIcon( className.lower(), KIcon::Small, iconWidth,
00431 KIcon::DefaultState, 0, true );
00432 if( scale && !pm.isNull() )
00433 result.convertFromImage( pm.convertToImage().smoothScale( width, height ) );
00434 else
00435 result = pm;
00436
00437 XFree( hint.res_name );
00438 XFree( hint.res_class );
00439 }
00440 }
00441 }
00442
00443 if( flags & XApp ) {
00444
00445
00446 if ( result.isNull() ) {
00447 QPixmap pm = KGlobal::instance()->iconLoader()->loadIcon( "xapp", KIcon::Small, iconWidth,
00448 KIcon::DefaultState, 0, true );
00449 if( scale && !pm.isNull() )
00450 result.convertFromImage( pm.convertToImage().smoothScale( width, height ) );
00451 else
00452 result = pm;
00453 }
00454 }
00455 #endif
00456 return result;
00457 }
00458
00459 void KWin::setIcons( WId win, const QPixmap& icon, const QPixmap& miniIcon )
00460 {
00461 #if defined Q_WS_X11 && ! defined K_WS_QTONLY
00462 if ( icon.isNull() )
00463 return;
00464 NETWinInfo info( qt_xdisplay(), win, qt_xrootwin(), 0 );
00465 QImage img = icon.convertToImage().convertDepth( 32 );
00466 NETIcon ni;
00467 ni.size.width = img.size().width();
00468 ni.size.height = img.size().height();
00469 ni.data = (unsigned char *) img.bits();
00470 info.setIcon( ni, true );
00471 if ( miniIcon.isNull() )
00472 return;
00473 img = miniIcon.convertToImage().convertDepth( 32 );
00474 ni.size.width = img.size().width();
00475 ni.size.height = img.size().height();
00476 ni.data = (unsigned char *) img.bits();
00477 info.setIcon( ni, false );
00478 #endif
00479 }
00480
00481 void KWin::setType( WId win, NET::WindowType windowType )
00482 {
00483 #if defined Q_WS_X11 && ! defined K_WS_QTONLY
00484 NETWinInfo info( qt_xdisplay(), win, qt_xrootwin(), 0 );
00485 info.setWindowType( windowType );
00486 #endif
00487 }
00488
00489 void KWin::setState( WId win, unsigned long state )
00490 {
00491 #if defined Q_WS_X11 && ! defined K_WS_QTONLY
00492 NETWinInfo info( qt_xdisplay(), win, qt_xrootwin(), NET::WMState );
00493 info.setState( state, state );
00494 #endif
00495 }
00496
00497 void KWin::clearState( WId win, unsigned long state )
00498 {
00499 #if defined Q_WS_X11 && ! defined K_WS_QTONLY
00500 NETWinInfo info( qt_xdisplay(), win, qt_xrootwin(), NET::WMState );
00501 info.setState( 0, state );
00502 #endif
00503 }
00504
00505 void KWin::setOnAllDesktops( WId win, bool b )
00506 {
00507 #if defined Q_WS_X11 && ! defined K_WS_QTONLY
00508 NETWinInfo info( qt_xdisplay(), win, qt_xrootwin(), NET::WMDesktop );
00509 if ( b )
00510 info.setDesktop( NETWinInfo::OnAllDesktops );
00511 else if ( info.desktop() == NETWinInfo::OnAllDesktops ) {
00512 NETRootInfo rinfo( qt_xdisplay(), NET::CurrentDesktop );
00513 info.setDesktop( rinfo.currentDesktop() );
00514 }
00515 #endif
00516 }
00517
00518 void KWin::setOnDesktop( WId win, int desktop )
00519 {
00520 #if defined Q_WS_X11 && ! defined K_WS_QTONLY
00521 NETWinInfo info( qt_xdisplay(), win, qt_xrootwin(), NET::WMDesktop );
00522 info.setDesktop( desktop );
00523 #endif
00524 }
00525
00526 void KWin::setStrut( WId win, int left, int right, int top, int bottom )
00527 {
00528 #if defined Q_WS_X11 && ! defined K_WS_QTONLY
00529 NETWinInfo info( qt_xdisplay(), win, qt_xrootwin(), 0 );
00530 NETStrut strut;
00531 strut.left = left;
00532 strut.right = right;
00533 strut.top = top;
00534 strut.bottom = bottom;
00535 info.setStrut( strut );
00536 #endif
00537 }
00538
00539 int KWin::currentDesktop()
00540 {
00541 #if defined Q_WS_X11 && ! defined K_WS_QTONLY
00542 if (!qt_xdisplay())
00543 #endif
00544 return 1;
00545 #if defined Q_WS_X11 && ! defined K_WS_QTONLY
00546 NETRootInfo info( qt_xdisplay(), NET::CurrentDesktop );
00547 return info.currentDesktop();
00548 #endif
00549 }
00550
00551 int KWin::numberOfDesktops()
00552 {
00553 #if defined Q_WS_X11 && ! defined K_WS_QTONLY
00554 if (!qt_xdisplay())
00555 #endif
00556 return 0;
00557 #if defined Q_WS_X11 && ! defined K_WS_QTONLY
00558 NETRootInfo info( qt_xdisplay(), NET::NumberOfDesktops );
00559 return info.numberOfDesktops();
00560 #endif
00561 }
00562
00563 void KWin::setCurrentDesktop( int desktop )
00564 {
00565 #if defined Q_WS_X11 && ! defined K_WS_QTONLY
00566 NETRootInfo info( qt_xdisplay(), NET::CurrentDesktop );
00567 info.setCurrentDesktop( desktop );
00568 #endif
00569 }
00570
00571
00572 void KWin::iconifyWindow( WId win, bool animation)
00573 {
00574 #if defined Q_WS_X11 && ! defined K_WS_QTONLY
00575 if ( !animation )
00576 {
00577 kwin_net_create_atoms();
00578 sendClientMessageToRoot( win, kde_wm_change_state, IconicState, 1 );
00579 }
00580 XIconifyWindow( qt_xdisplay(), win, qt_xscreen() );
00581 #endif
00582 }
00583
00584
00585 void KWin::deIconifyWindow( WId win, bool animation )
00586 {
00587 #if defined Q_WS_X11 && ! defined K_WS_QTONLY
00588 if ( !animation )
00589 {
00590 kwin_net_create_atoms();
00591 sendClientMessageToRoot( win, kde_wm_change_state, NormalState, 1 );
00592 }
00593 XMapWindow( qt_xdisplay(), win );
00594 #endif
00595 }
00596
00597 void KWin::raiseWindow( WId win )
00598 {
00599 #if defined Q_WS_X11 && ! defined K_WS_QTONLY
00600 NETRootInfo info( qt_xdisplay(), NET::Supported );
00601 if( info.isSupported( NET::WM2RestackWindow ))
00602 info.restackRequest( win, None, Above );
00603 else
00604 XRaiseWindow( qt_xdisplay(), win );
00605 #endif
00606 }
00607
00608 void KWin::lowerWindow( WId win )
00609 {
00610 #if defined Q_WS_X11 && ! defined K_WS_QTONLY
00611 NETRootInfo info( qt_xdisplay(), NET::Supported );
00612 if( info.isSupported( NET::WM2RestackWindow ))
00613 info.restackRequest( win, None, Below );
00614 else
00615 XLowerWindow( qt_xdisplay(), win );
00616 #endif
00617 }
00618
00619 void KWin::appStarted()
00620 {
00621 #if defined Q_WS_X11 && ! defined K_WS_QTONLY
00622 KStartupInfo::appStarted();
00623 #endif
00624 }
00625
00626 class KWin::WindowInfoPrivate
00627 {
00628 public:
00629 WindowInfoPrivate()
00630 #if defined Q_WS_X11 && ! defined K_WS_QTONLY
00631 : info( NULL )
00632 #endif
00633 {}
00634 #if defined Q_WS_X11 && ! defined K_WS_QTONLY
00635 ~WindowInfoPrivate() { delete info; }
00636 NETWinInfo* info;
00637 #endif
00638 WId win_;
00639 QString name_;
00640 QString iconic_name_;
00641 QRect geometry_;
00642 QRect frame_geometry_;
00643 int ref;
00644 bool valid;
00645 private:
00646 WindowInfoPrivate( const WindowInfoPrivate& );
00647 void operator=( const WindowInfoPrivate& );
00648 };
00649
00650
00651 KWin::WindowInfo::WindowInfo( WId win, unsigned long properties, unsigned long properties2 )
00652 {
00653 #if defined Q_WS_X11 && ! defined K_WS_QTONLY
00654 KXErrorHandler handler;
00655 d = new WindowInfoPrivate;
00656 d->ref = 1;
00657 if( properties == 0 )
00658 properties = NET::WMState |
00659 NET::WMStrut |
00660 NET::WMWindowType |
00661 NET::WMName |
00662 NET::WMVisibleName |
00663 NET::WMIconName |
00664 NET::WMVisibleIconName |
00665 NET::WMDesktop |
00666 NET::WMPid |
00667 NET::WMKDEFrameStrut |
00668 NET::XAWMState |
00669 NET::WMGeometry;
00670 if( properties & NET::WMVisibleIconName )
00671 properties |= NET::WMIconName | NET::WMVisibleName;
00672 if( properties & NET::WMVisibleName )
00673 properties |= NET::WMName;
00674 properties |= NET::XAWMState;
00675 unsigned long props[ 2 ] = { properties, properties2 };
00676 d->info = new NETWinInfo( qt_xdisplay(), win, qt_xrootwin(), props, 2 );
00677 d->win_ = win;
00678 if( properties & NET::WMName ) {
00679 if( d->info->name() && d->info->name()[ 0 ] != '\0' )
00680 d->name_ = QString::fromUtf8( d->info->name() );
00681 else
00682 d->name_ = readNameProperty( win, XA_WM_NAME );
00683 }
00684 if( properties & NET::WMIconName ) {
00685 if( d->info->iconName() && d->info->iconName()[ 0 ] != '\0' )
00686 d->iconic_name_ = QString::fromUtf8( d->info->iconName());
00687 else
00688 d->iconic_name_ = readNameProperty( win, XA_WM_ICON_NAME );
00689 }
00690 if( properties & ( NET::WMGeometry | NET::WMKDEFrameStrut )) {
00691 NETRect frame, geom;
00692 d->info->kdeGeometry( frame, geom );
00693 d->geometry_.setRect( geom.pos.x, geom.pos.y, geom.size.width, geom.size.height );
00694 d->frame_geometry_.setRect( frame.pos.x, frame.pos.y, frame.size.width, frame.size.height );
00695 }
00696 d->valid = !handler.error( false );
00697 #endif
00698 }
00699
00700
00701 KWin::WindowInfo::WindowInfo()
00702 : d( NULL )
00703 {
00704 }
00705
00706 KWin::WindowInfo::~WindowInfo()
00707 {
00708 if( d != NULL ) {
00709 if( --d->ref == 0 ) {
00710 delete d;
00711 }
00712 }
00713 }
00714
00715 KWin::WindowInfo::WindowInfo( const WindowInfo& wininfo )
00716 : d( wininfo.d )
00717 {
00718 if( d != NULL )
00719 ++d->ref;
00720 }
00721
00722 KWin::WindowInfo& KWin::WindowInfo::operator=( const WindowInfo& wininfo )
00723 {
00724 if( d != wininfo.d ) {
00725 if( d != NULL )
00726 if( --d->ref == 0 )
00727 delete d;
00728 d = wininfo.d;
00729 if( d != NULL )
00730 ++d->ref;
00731 }
00732 return *this;
00733 }
00734
00735 bool KWin::WindowInfo::valid( bool withdrawn_is_valid ) const
00736 {
00737 if( !d->valid )
00738 return false;
00739 if( !withdrawn_is_valid && mappingState() == NET::Withdrawn )
00740 return false;
00741 return true;
00742 }
00743
00744 WId KWin::WindowInfo::win() const
00745 {
00746 return d->win_;
00747 }
00748
00749 unsigned long KWin::WindowInfo::state() const
00750 {
00751 #if defined Q_WS_X11 && ! defined K_WS_QTONLY
00752 kdWarning(( d->info->passedProperties()[ NETWinInfo::PROTOCOLS ] & NET::WMState ) == 0, 176 )
00753 << "Pass NET::WMState to KWin::windowInfo()" << endl;
00754 return d->info->state();
00755 #else
00756 return 0;
00757 #endif
00758 }
00759
00760 NET::MappingState KWin::WindowInfo::mappingState() const
00761 {
00762 #if defined Q_WS_X11 && ! defined K_WS_QTONLY
00763 kdWarning(( d->info->passedProperties()[ NETWinInfo::PROTOCOLS ] & NET::XAWMState ) == 0, 176 )
00764 << "Pass NET::XAWMState to KWin::windowInfo()" << endl;
00765 return d->info->mappingState();
00766 #else
00767 return 0;
00768 #endif
00769 }
00770
00771 NETStrut KWin::WindowInfo::strut() const
00772 {
00773 #if defined Q_WS_X11 && ! defined K_WS_QTONLY
00774 kdWarning(( d->info->passedProperties()[ NETWinInfo::PROTOCOLS ] & NET::WMStrut ) == 0, 176 )
00775 << "Pass NET::WMStrut to KWin::windowInfo()" << endl;
00776 return d->info->strut();
00777 #else
00778 NETStrut n;
00779 return n;
00780 #endif
00781 }
00782
00783 NET::WindowType KWin::WindowInfo::windowType( int supported_types ) const
00784 {
00785 #if defined Q_WS_X11 && ! defined K_WS_QTONLY
00786 kdWarning(( d->info->passedProperties()[ NETWinInfo::PROTOCOLS ] & NET::WMWindowType ) == 0, 176 )
00787 << "Pass NET::WMWindowType to KWin::windowInfo()" << endl;
00788 return d->info->windowType( supported_types );
00789 #else
00790 return 0;
00791 #endif
00792 }
00793
00794 QString KWin::WindowInfo::visibleNameWithState() const
00795 {
00796 QString s = visibleName();
00797 if ( isMinimized() ) {
00798 s.prepend('(');
00799 s.append(')');
00800 }
00801 return s;
00802 }
00803
00804 QString KWin::Info::visibleNameWithState() const
00805 {
00806 QString s = visibleName;
00807 if ( isMinimized() ) {
00808 s.prepend('(');
00809 s.append(')');
00810 }
00811 return s;
00812 }
00813
00814 QString KWin::WindowInfo::visibleName() const
00815 {
00816 #if defined Q_WS_X11 && ! defined K_WS_QTONLY
00817 kdWarning(( d->info->passedProperties()[ NETWinInfo::PROTOCOLS ] & NET::WMVisibleName ) == 0, 176 )
00818 << "Pass NET::WMVisibleName to KWin::windowInfo()" << endl;
00819 return d->info->visibleName() && d->info->visibleName()[ 0 ] != '\0'
00820 ? QString::fromUtf8(d->info->visibleName()) : name();
00821 #else
00822 return QString("name");
00823 #endif
00824 }
00825
00826 QString KWin::WindowInfo::name() const
00827 {
00828 #if defined Q_WS_X11 && ! defined K_WS_QTONLY
00829 kdWarning(( d->info->passedProperties()[ NETWinInfo::PROTOCOLS ] & NET::WMName ) == 0, 176 )
00830 << "Pass NET::WMName to KWin::windowInfo()" << endl;
00831 return d->name_;
00832 #else
00833 return QString();
00834 #endif
00835 }
00836
00837 QString KWin::WindowInfo::visibleIconNameWithState() const
00838 {
00839 QString s = visibleIconName();
00840 if ( isMinimized() ) {
00841 s.prepend('(');
00842 s.append(')');
00843 }
00844 return s;
00845 }
00846
00847 QString KWin::WindowInfo::visibleIconName() const
00848 {
00849 #if defined Q_WS_X11 && ! defined K_WS_QTONLY
00850 kdWarning(( d->info->passedProperties()[ NETWinInfo::PROTOCOLS ] & NET::WMVisibleIconName ) == 0, 176 )
00851 << "Pass NET::WMVisibleIconName to KWin::windowInfo()" << endl;
00852 if( d->info->visibleIconName() && d->info->visibleIconName()[ 0 ] != '\0' )
00853 return QString::fromUtf8( d->info->visibleIconName());
00854 if( d->info->iconName() && d->info->iconName()[ 0 ] != '\0' )
00855 return QString::fromUtf8( d->info->iconName());
00856 if( !d->iconic_name_.isEmpty())
00857 return d->iconic_name_;
00858 #endif
00859 return visibleName();
00860 }
00861
00862 QString KWin::WindowInfo::iconName() const
00863 {
00864 #if defined Q_WS_X11 && ! defined K_WS_QTONLY
00865 kdWarning(( d->info->passedProperties()[ NETWinInfo::PROTOCOLS ] & NET::WMIconName ) == 0, 176 )
00866 << "Pass NET::WMIconName to KWin::windowInfo()" << endl;
00867 if( d->info->iconName() && d->info->iconName()[ 0 ] != '\0' )
00868 return QString::fromUtf8( d->info->iconName());
00869 if( !d->iconic_name_.isEmpty())
00870 return d->iconic_name_;
00871 #endif
00872 return name();
00873 }
00874
00875 bool KWin::WindowInfo::isOnCurrentDesktop() const
00876 {
00877 #if defined Q_WS_X11 && ! defined K_WS_QTONLY
00878 return isOnDesktop( KWin::currentDesktop());
00879 #else
00880 return false;
00881 #endif
00882 }
00883
00884 bool KWin::WindowInfo::isOnDesktop( int desktop ) const
00885 {
00886 #if defined Q_WS_X11 && ! defined K_WS_QTONLY
00887 kdWarning(( d->info->passedProperties()[ NETWinInfo::PROTOCOLS ] & NET::WMDesktop ) == 0, 176 )
00888 << "Pass NET::WMDesktop to KWin::windowInfo()" << endl;
00889 return d->info->desktop() == desktop || d->info->desktop() == NET::OnAllDesktops;
00890 #else
00891 return false;
00892 #endif
00893 }
00894
00895 bool KWin::WindowInfo::onAllDesktops() const
00896 {
00897 #if defined Q_WS_X11 && ! defined K_WS_QTONLY
00898 kdWarning(( d->info->passedProperties()[ NETWinInfo::PROTOCOLS ] & NET::WMDesktop ) == 0, 176 )
00899 << "Pass NET::WMDesktop to KWin::windowInfo()" << endl;
00900 return d->info->desktop() == NET::OnAllDesktops;
00901 #else
00902 return false;
00903 #endif
00904 }
00905
00906 int KWin::WindowInfo::desktop() const
00907 {
00908 #if defined Q_WS_X11 && ! defined K_WS_QTONLY
00909 kdWarning(( d->info->passedProperties()[ NETWinInfo::PROTOCOLS ] & NET::WMDesktop ) == 0, 176 )
00910 << "Pass NET::WMDesktop to KWin::windowInfo()" << endl;
00911 return d->info->desktop();
00912 #else
00913 return 1;
00914 #endif
00915 }
00916
00917 QRect KWin::WindowInfo::geometry() const
00918 {
00919 #if defined Q_WS_X11 && ! defined K_WS_QTONLY
00920 kdWarning(( d->info->passedProperties()[ NETWinInfo::PROTOCOLS ] & NET::WMGeometry ) == 0, 176 )
00921 << "Pass NET::WMGeometry to KWin::windowInfo()" << endl;
00922 return d->geometry_;
00923 #else
00924 return QRect( 100, 100, 200, 200 );;
00925 #endif
00926 }
00927
00928 QRect KWin::WindowInfo::frameGeometry() const
00929 {
00930 kdWarning(( d->info->passedProperties()[ NETWinInfo::PROTOCOLS ] & NET::WMKDEFrameStrut ) == 0, 176 )
00931 << "Pass NET::WMKDEFrameStrut to KWin::windowInfo()" << endl;
00932 return d->frame_geometry_;
00933 }
00934
00935 WId KWin::WindowInfo::transientFor() const
00936 {
00937 #if defined Q_WS_X11 && ! defined K_WS_QTONLY
00938 kdWarning(( d->info->passedProperties()[ NETWinInfo::PROTOCOLS2 ] & NET::WM2TransientFor ) == 0, 176 )
00939 << "Pass NET::WM2TransientFor to KWin::windowInfo()" << endl;
00940 return d->info->transientFor();
00941 #else
00942 return 0;
00943 #endif
00944 }
00945
00946 WId KWin::WindowInfo::groupLeader() const
00947 {
00948 #if defined Q_WS_X11 && ! defined K_WS_QTONLY
00949 kdWarning(( d->info->passedProperties()[ NETWinInfo::PROTOCOLS2 ] & NET::WM2GroupLeader ) == 0, 176 )
00950 << "Pass NET::WM2GroupLeader to KWin::windowInfo()" << endl;
00951 return d->info->groupLeader();
00952 #else
00953 return 0;
00954 #endif
00955 }
00956
00957 bool KWin::WindowInfo::actionSupported( NET::Action action ) const
00958 {
00959 #if defined Q_WS_X11 && ! defined K_WS_QTONLY
00960 kdWarning(( d->info->passedProperties()[ NETWinInfo::PROTOCOLS2 ] & NET::WM2AllowedActions ) == 0, 176 )
00961 << "Pass NET::WM2AllowedActions to KWin::windowInfo()" << endl;
00962 if( allowedActionsSupported())
00963 return d->info->allowedActions() & action;
00964 else
00965 #endif
00966 return true;
00967 }
00968
00969
00970 bool KWin::WindowInfo::isMinimized() const
00971 {
00972 #if defined Q_WS_X11 && ! defined K_WS_QTONLY
00973 if( mappingState() != NET::Iconic )
00974 return false;
00975
00976 if(( state() & NET::Hidden ) != 0
00977 && ( state() & NET::Shaded ) == 0 )
00978 return true;
00979
00980
00981 return icccmCompliantMappingState() ? false : true;
00982 #else
00983 return false;
00984 #endif
00985 }
00986
00987 bool KWin::Info::isMinimized() const
00988 {
00989 #if defined Q_WS_X11 && ! defined K_WS_QTONLY
00990 if( mappingState != NET::Iconic )
00991 return false;
00992
00993 if(( state & NET::Hidden ) != 0
00994 && ( state & NET::Shaded ) == 0 )
00995 return true;
00996
00997
00998 return icccmCompliantMappingState() ? false : true;
00999 #else
01000 return false;
01001 #endif
01002 }
01003
01004 bool KWin::Info::isIconified() const
01005 {
01006 return isMinimized();
01007 }
01008
01009 bool KWin::icccmCompliantMappingState()
01010 {
01011 #if defined Q_WS_X11 && ! defined K_WS_QTONLY
01012 static enum { noidea, yes, no } wm_is_1_2_compliant = noidea;
01013 if( wm_is_1_2_compliant == noidea ) {
01014 NETRootInfo info( qt_xdisplay(), NET::Supported );
01015 wm_is_1_2_compliant = info.isSupported( NET::Hidden ) ? yes : no;
01016 }
01017 return wm_is_1_2_compliant == yes;
01018 #else
01019 return false;
01020 #endif
01021 }
01022
01023 bool KWin::allowedActionsSupported()
01024 {
01025 #if defined Q_WS_X11 && ! defined K_WS_QTONLY
01026 static enum { noidea, yes, no } wm_supports_allowed_actions = noidea;
01027 if( wm_supports_allowed_actions == noidea ) {
01028 NETRootInfo info( qt_xdisplay(), NET::Supported );
01029 wm_supports_allowed_actions = info.isSupported( NET::WM2AllowedActions ) ? yes : no;
01030 }
01031 return wm_supports_allowed_actions == yes;
01032 #else
01033 return false;
01034 #endif
01035 }
01036
01037 QString KWin::readNameProperty( WId win, unsigned long atom )
01038 {
01039 #if defined Q_WS_X11 && ! defined K_WS_QTONLY
01040 XTextProperty tp;
01041 char **text = NULL;
01042 int count;
01043 #endif
01044 QString result;
01045 #if defined Q_WS_X11 && ! defined K_WS_QTONLY
01046 if ( XGetTextProperty( qt_xdisplay(), win, &tp, atom ) != 0 && tp.value != NULL ) {
01047 if ( tp.encoding == XA_STRING )
01048 result = QString::fromLocal8Bit( (const char*) tp.value );
01049 else if ( XmbTextPropertyToTextList( qt_xdisplay(), &tp, &text, &count) == Success &&
01050 text != NULL && count > 0 ) {
01051 result = QString::fromLocal8Bit( text[0] );
01052 }
01053 if( text != NULL )
01054 XFreeStringList( text );
01055 XFree( tp.value );
01056 }
01057 #endif
01058 return result;
01059 }
01060
01061