kdecore Library API Documentation

kwin.cpp

00001 /* This file is part of the KDE libraries 00002 Copyright (C) 1999 Matthias Ettrich (ettrich@kde.org) 00003 00004 $Id: kwin.cpp,v 1.97.2.1 2004/04/23 08:52:11 lunakl Exp $ 00005 00006 This library is free software; you can redistribute it and/or 00007 modify it under the terms of the GNU Library General Public 00008 License as published by the Free Software Foundation; either 00009 version 2 of the License, or (at your option) any later version. 00010 00011 This library is distributed in the hope that it will be useful, 00012 but WITHOUT ANY WARRANTY; without even the implied warranty of 00013 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00014 Library General Public License for more details. 00015 00016 You should have received a copy of the GNU Library General Public License 00017 along with this library; see the file COPYING.LIB. If not, write to 00018 the Free Software Foundation, Inc., 59 Temple Place - Suite 330, 00019 Boston, MA 02111-1307, USA. 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 //#ifndef Q_WS_QWS 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> // schroder not needed at all ? 00049 #include <kxerrorhandler.h> // schroder 00050 00051 #include <X11/Xlib.h> // schroder 00052 #include <X11/Xatom.h> // schroder 00053 #include <X11/Xutil.h> // schroder 00054 00055 #include "netwm.h" // schroder 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 // we need a const_cast for the shitty X API 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 Sends a client message to the ROOT window. 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 Send a client message to window w 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; /* magic! */ 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 } // namespace 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; // ignore badwindow 00261 Window transient_for = None; 00262 if( XGetTransientForHint( qt_xdisplay(), win, &transient_for )) 00263 return transient_for; 00264 // XGetTransientForHint() did sync 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; // ignore badwindow 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 // XGetWMHints() did sync 00284 return window_group; 00285 #else 00286 return 0L; 00287 #endif 00288 } 00289 00290 // this one is deprecated, KWin::WindowInfo should be used instead 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; // ignore badwindow 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 // Always detach before doing something behind QPixmap's back. 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 // Since width can be any arbitrary size, but the icons cannot, 00411 // take the nearest value for best results (ignoring 22 pixel 00412 // icons as they don't exist for apps): 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 // Try to load the icon from the classhint if the app didn't specify 00423 // its own: 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 // If the icon is still a null pixmap, load the 'xapp' icon 00445 // as a last resort: 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 // KWin::info() should be updated too if something has to be changed here 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; // force, in case it will be used as a fallback 00672 if( properties & NET::WMVisibleName ) 00673 properties |= NET::WMName; // force, in case it will be used as a fallback 00674 properties |= NET::XAWMState; // force to get error detection for valid() 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 ); // no sync - NETWinInfo did roundtrips 00697 #endif 00698 } 00699 00700 // this one is only to make QValueList<> or similar happy 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; // no idea if it's supported or not -> pretend it is 00967 } 00968 00969 // see NETWM spec section 7.6 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 // NETWM 1.2 compliant WM - uses NET::Hidden for minimized windows 00976 if(( state() & NET::Hidden ) != 0 00977 && ( state() & NET::Shaded ) == 0 ) // shaded may have NET::Hidden too 00978 return true; 00979 // older WMs use WithdrawnState for other virtual desktops 00980 // and IconicState only for minimized 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 // NETWM 1.2 compliant WM - uses NET::Hidden for minimized windows 00993 if(( state & NET::Hidden ) != 0 00994 && ( state & NET::Shaded ) == 0 ) // shaded may have NET::Hidden too 00995 return true; 00996 // older WMs use WithdrawnState for other virtual desktops 00997 // and IconicState only for minimized 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 ( XmbTextPropertyToTextList( qt_xdisplay(), &tp, &text, &count) == Success && 01048 text != NULL && count > 0 ) { 01049 result = QString::fromLocal8Bit( text[0] ); 01050 } else if ( tp.encoding == XA_STRING ) 01051 result = QString::fromLocal8Bit( (const char*) tp.value ); 01052 if( text != NULL ) 01053 XFreeStringList( text ); 01054 XFree( tp.value ); 01055 } 01056 #endif 01057 return result; 01058 } 01059 01060 //#endif
KDE Logo
This file is part of the documentation for kdecore Library Version 3.2.3.
Documentation copyright © 1996-2004 the KDE developers.
Generated on Fri Aug 20 09:48:27 2004 by doxygen 1.3.7 written by Dimitri van Heesch, © 1997-2003