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.103 2004/07/28 15:49:07 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 <kuniqueapplication.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 #include <dcopref.h> 00048 #if defined Q_WS_X11 && ! defined K_WS_QTONLY 00049 #include <kstartupinfo.h> 00050 #include <kxerrorhandler.h> 00051 00052 #include <X11/Xlib.h> 00053 #include <X11/Xatom.h> 00054 #include <X11/Xutil.h> 00055 00056 #include "netwm.h" 00057 00058 static bool atoms_created = false; 00059 extern Atom qt_wm_protocols; 00060 extern Time qt_x_time; 00061 extern Time qt_x_user_time; 00062 00063 static Atom net_wm_context_help; 00064 static Atom kde_wm_change_state; 00065 static void kwin_net_create_atoms() { 00066 if (!atoms_created){ 00067 const int max = 20; 00068 Atom* atoms[max]; 00069 const char* names[max]; 00070 Atom atoms_return[max]; 00071 int n = 0; 00072 00073 atoms[n] = &net_wm_context_help; 00074 names[n++] = "_NET_WM_CONTEXT_HELP"; 00075 00076 atoms[n] = &kde_wm_change_state; 00077 names[n++] = "_KDE_WM_CHANGE_STATE"; 00078 00079 // we need a const_cast for the shitty X API 00080 XInternAtoms( qt_xdisplay(), const_cast<char**>(names), n, false, atoms_return ); 00081 for (int i = 0; i < n; i++ ) 00082 *atoms[i] = atoms_return[i]; 00083 00084 atoms_created = True; 00085 } 00086 } 00087 #endif 00088 00089 /* 00090 Sends a client message to the ROOT window. 00091 */ 00092 static void sendClientMessageToRoot(Window w, Atom a, long x, long y = 0, long z = 0 ){ 00093 #if defined Q_WS_X11 && ! defined K_WS_QTONLY 00094 XEvent ev; 00095 long mask; 00096 00097 memset(&ev, 0, sizeof(ev)); 00098 ev.xclient.type = ClientMessage; 00099 ev.xclient.window = w; 00100 ev.xclient.message_type = a; 00101 ev.xclient.format = 32; 00102 ev.xclient.data.l[0] = x; 00103 ev.xclient.data.l[1] = y; 00104 ev.xclient.data.l[2] = z; 00105 mask = SubstructureRedirectMask; 00106 XSendEvent(qt_xdisplay(), qt_xrootwin(), False, mask, &ev); 00107 #endif 00108 } 00109 00110 /* 00111 Send a client message to window w 00112 */ 00113 static void sendClientMessage(Window w, Atom a, long x){ 00114 #if defined Q_WS_X11 && ! defined K_WS_QTONLY 00115 XEvent ev; 00116 long mask; 00117 00118 memset(&ev, 0, sizeof(ev)); 00119 ev.xclient.type = ClientMessage; 00120 ev.xclient.window = w; 00121 ev.xclient.message_type = a; 00122 ev.xclient.format = 32; 00123 ev.xclient.data.l[0] = x; 00124 ev.xclient.data.l[1] = CurrentTime; 00125 mask = 0L; 00126 if (w == qt_xrootwin()) 00127 mask = SubstructureRedirectMask; /* magic! */ 00128 XSendEvent(qt_xdisplay(), w, False, mask, &ev); 00129 #endif 00130 } 00131 00132 namespace 00133 { 00134 class ContextWidget : public QWidget 00135 { 00136 public: 00137 ContextWidget(); 00138 virtual bool x11Event( XEvent * ev); 00139 }; 00140 00141 ContextWidget::ContextWidget() 00142 : QWidget(0,0) 00143 { 00144 #if defined Q_WS_X11 && ! defined K_WS_QTONLY 00145 kwin_net_create_atoms(); 00146 kapp->installX11EventFilter( this ); 00147 QWhatsThis::enterWhatsThisMode(); 00148 QCursor c = *QApplication::overrideCursor(); 00149 QWhatsThis::leaveWhatsThisMode(); 00150 XGrabPointer( qt_xdisplay(), qt_xrootwin(), true, 00151 (uint)( ButtonPressMask | ButtonReleaseMask | 00152 PointerMotionMask | EnterWindowMask | 00153 LeaveWindowMask ), 00154 GrabModeAsync, GrabModeAsync, 00155 None, c.handle(), CurrentTime ); 00156 qApp->enter_loop(); 00157 #endif 00158 } 00159 00160 00161 bool ContextWidget::x11Event( XEvent * ev) 00162 { 00163 #if defined Q_WS_X11 && ! defined K_WS_QTONLY 00164 if ( ev->type == ButtonPress && ev->xbutton.button == Button1 ) { 00165 XUngrabPointer( qt_xdisplay(), ev->xbutton.time ); 00166 Window root; 00167 Window child = qt_xrootwin(); 00168 int root_x, root_y, lx, ly; 00169 uint state; 00170 Window w; 00171 do { 00172 w = child; 00173 XQueryPointer( qt_xdisplay(), w, &root, &child, 00174 &root_x, &root_y, &lx, &ly, &state ); 00175 } while ( child != None && child != w ); 00176 00177 ::sendClientMessage(w, qt_wm_protocols, net_wm_context_help); 00178 XEvent e = *ev; 00179 e.xbutton.window = w; 00180 e.xbutton.subwindow = w; 00181 e.xbutton.x = lx; 00182 e.xbutton.y = ly; 00183 XSendEvent( qt_xdisplay(), w, true, ButtonPressMask, &e ); 00184 qApp->exit_loop(); 00185 return true; 00186 } 00187 return false; 00188 #endif 00189 } 00190 } // namespace 00191 00192 void KWin::invokeContextHelp() 00193 { 00194 ContextWidget w; 00195 } 00196 00197 void KWin::setSystemTrayWindowFor( WId trayWin, WId forWin ) 00198 { 00199 #if defined Q_WS_X11 && ! defined K_WS_QTONLY 00200 NETWinInfo info( qt_xdisplay(), trayWin, qt_xrootwin(), 0 ); 00201 if ( !forWin ) 00202 forWin = qt_xrootwin(); 00203 info.setKDESystemTrayWinFor( forWin ); 00204 NETRootInfo rootinfo( qt_xdisplay(), NET::Supported ); 00205 if( !rootinfo.isSupported( NET::WMKDESystemTrayWinFor )) { 00206 DCOPRef ref( "kded", "kded" ); 00207 if( !ref.send( "loadModule", QCString( "kdetrayproxy" ))) 00208 kdWarning( 176 ) << "Loading of kdetrayproxy failed." << endl; 00209 } 00210 #endif 00211 } 00212 00213 void KWin::activateWindow( WId win, long time ) 00214 { 00215 #if defined Q_WS_X11 && ! defined K_WS_QTONLY 00216 NETRootInfo info( qt_xdisplay(), 0 ); 00217 if( time == 0 ) 00218 time = qt_x_user_time; 00219 info.setActiveWindow( win, NET::FromApplication, time, 00220 kapp->activeWindow() ? kapp->activeWindow()->winId() : 0 ); 00221 #endif // Q_WS_X11 ... 00222 KUniqueApplication::setHandleAutoStarted(); 00223 } 00224 00225 void KWin::forceActiveWindow( WId win, long time ) 00226 { 00227 #if defined Q_WS_X11 && ! defined K_WS_QTONLY 00228 NETRootInfo info( qt_xdisplay(), 0 ); 00229 if( time == 0 ) 00230 time = qt_x_time; 00231 info.setActiveWindow( win, NET::FromTool, time, 0 ); 00232 #endif // Q_WS_X11 ... 00233 KUniqueApplication::setHandleAutoStarted(); 00234 } 00235 00236 void KWin::setActiveWindow( WId win ) 00237 { 00238 #if defined Q_WS_X11 && ! defined K_WS_QTONLY 00239 NETRootInfo info( qt_xdisplay(), 0 ); 00240 info.setActiveWindow( win, NET::FromUnknown, 0, 0 ); 00241 #endif 00242 KUniqueApplication::setHandleAutoStarted(); 00243 } 00244 00245 void KWin::demandAttention( WId win, bool set ) 00246 { 00247 #if defined Q_WS_X11 && ! defined K_WS_QTONLY 00248 NETWinInfo info( qt_xdisplay(), win, qt_xrootwin(), 0 ); 00249 info.setState( set ? NET::DemandsAttention : 0, NET::DemandsAttention ); 00250 #endif 00251 } 00252 00253 void KWin::setUserTime( WId win, long time ) 00254 { 00255 #if defined Q_WS_X11 && ! defined K_WS_QTONLY 00256 NETWinInfo info( qt_xdisplay(), win, qt_xrootwin(), 0 ); 00257 info.setUserTime( time ); 00258 #endif 00259 } 00260 00261 KWin::WindowInfo KWin::windowInfo( WId win, unsigned long properties, unsigned long properties2 ) 00262 { 00263 return WindowInfo( win, properties, properties2 ); 00264 } 00265 00266 00267 WId KWin::transientFor( WId win ) 00268 { 00269 #if defined Q_WS_X11 && ! defined K_WS_QTONLY 00270 KXErrorHandler handler; // ignore badwindow 00271 Window transient_for = None; 00272 if( XGetTransientForHint( qt_xdisplay(), win, &transient_for )) 00273 return transient_for; 00274 // XGetTransientForHint() did sync 00275 return None; 00276 #else 00277 return 0L; 00278 #endif 00279 } 00280 00281 WId KWin::groupLeader( WId win ) 00282 { 00283 #if defined Q_WS_X11 && ! defined K_WS_QTONLY 00284 KXErrorHandler handler; // ignore badwindow 00285 XWMHints *hints = XGetWMHints( qt_xdisplay(), win ); 00286 Window window_group = None; 00287 if ( hints ) 00288 { 00289 if( hints->flags & WindowGroupHint ) 00290 window_group = hints->window_group; 00291 XFree( reinterpret_cast< char* >( hints )); 00292 } 00293 // XGetWMHints() did sync 00294 return window_group; 00295 #else 00296 return 0L; 00297 #endif 00298 } 00299 00300 // this one is deprecated, KWin::WindowInfo should be used instead 00301 KWin::Info KWin::info( WId win ) 00302 { 00303 Info w; 00304 #if defined Q_WS_X11 && ! defined K_WS_QTONLY 00305 NETWinInfo inf( qt_xdisplay(), win, qt_xrootwin(), 00306 NET::WMState | 00307 NET::WMStrut | 00308 NET::WMWindowType | 00309 NET::WMName | 00310 NET::WMVisibleName | 00311 NET::WMDesktop | 00312 NET::WMPid | 00313 NET::WMKDEFrameStrut | 00314 NET::XAWMState 00315 ); 00316 00317 w.win = win; 00318 w.state = inf.state(); 00319 w.mappingState = inf.mappingState(); 00320 w.strut = inf.strut(); 00321 w.windowType = inf.windowType(); 00322 if ( inf.name() ) { 00323 w.name = QString::fromUtf8( inf.name() ); 00324 } else { 00325 char* c = 0; 00326 if ( XFetchName( qt_xdisplay(), win, &c ) != 0 ) { 00327 w.name = QString::fromLocal8Bit( c ); 00328 XFree( c ); 00329 } 00330 } 00331 if ( inf.visibleName() ) 00332 w.visibleName = QString::fromUtf8( inf.visibleName() ); 00333 else 00334 w.visibleName = w.name; 00335 00336 w.desktop = inf.desktop(); 00337 w.onAllDesktops = inf.desktop() == NETWinInfo::OnAllDesktops; 00338 w.pid = inf.pid(); 00339 NETRect frame, geom; 00340 inf.kdeGeometry( frame, geom ); 00341 w.geometry.setRect( geom.pos.x, geom.pos.y, geom.size.width, geom.size.height ); 00342 w.frameGeometry.setRect( frame.pos.x, frame.pos.y, frame.size.width, frame.size.height ); 00343 #endif 00344 return w; 00345 } 00346 00347 QPixmap KWin::icon( WId win, int width, int height, bool scale ) 00348 { 00349 return icon( win, width, height, scale, NETWM | WMHints | ClassHint | XApp ); 00350 } 00351 00352 00353 QPixmap KWin::icon( WId win, int width, int height, bool scale, int flags ) 00354 { 00355 #if defined Q_WS_X11 && ! defined K_WS_QTONLY 00356 KXErrorHandler handler; // ignore badwindow 00357 #endif 00358 QPixmap result; 00359 #if defined Q_WS_X11 && ! defined K_WS_QTONLY 00360 if( flags & NETWM ) { 00361 NETWinInfo info( qt_xdisplay(), win, qt_xrootwin(), NET::WMIcon ); 00362 NETIcon ni = info.icon( width, height ); 00363 if ( ni.data && ni.size.width > 0 && ni.size.height > 0 ) { 00364 QImage img( (uchar*) ni.data, (int) ni.size.width, (int) ni.size.height, 32, 0, 0, QImage::IgnoreEndian ); 00365 img.setAlphaBuffer( true ); 00366 if ( scale && width > 0 && height > 0 &&img.size() != QSize( width, height ) && !img.isNull() ) 00367 img = img.smoothScale( width, height ); 00368 if ( !img.isNull() ) 00369 result.convertFromImage( img ); 00370 return result; 00371 } 00372 } 00373 00374 if( flags & WMHints ) { 00375 Pixmap p = None; 00376 Pixmap p_mask = None; 00377 00378 XWMHints *hints = XGetWMHints(qt_xdisplay(), win ); 00379 if (hints && (hints->flags & IconPixmapHint)){ 00380 p = hints->icon_pixmap; 00381 } 00382 if (hints && (hints->flags & IconMaskHint)){ 00383 p_mask = hints->icon_mask; 00384 } 00385 if (hints) 00386 XFree((char*)hints); 00387 00388 if (p != None){ 00389 Window root; 00390 int x, y; 00391 unsigned int w = 0; 00392 unsigned int h = 0; 00393 unsigned int border_w, depth; 00394 XGetGeometry(qt_xdisplay(), p, &root, 00395 &x, &y, &w, &h, &border_w, &depth); 00396 if (w > 0 && h > 0){ 00397 QPixmap pm(w, h, depth); 00398 // Always detach before doing something behind QPixmap's back. 00399 pm.detach(); 00400 XCopyArea(qt_xdisplay(), p, pm.handle(), 00401 qt_xget_temp_gc(qt_xscreen(), depth==1), 00402 0, 0, w, h, 0, 0); 00403 if (p_mask != None){ 00404 QBitmap bm(w, h); 00405 XCopyArea(qt_xdisplay(), p_mask, bm.handle(), 00406 qt_xget_temp_gc(qt_xscreen(), true), 00407 0, 0, w, h, 0, 0); 00408 pm.setMask(bm); 00409 } 00410 if ( scale && width > 0 && height > 0 && !pm.isNull() && 00411 ( (int) w != width || (int) h != height) ){ 00412 result.convertFromImage( pm.convertToImage().smoothScale( width, height ) ); 00413 } else { 00414 result = pm; 00415 } 00416 } 00417 } 00418 } 00419 00420 // Since width can be any arbitrary size, but the icons cannot, 00421 // take the nearest value for best results (ignoring 22 pixel 00422 // icons as they don't exist for apps): 00423 int iconWidth; 00424 if( width < 24 ) 00425 iconWidth = 16; 00426 else if( width < 40 ) 00427 iconWidth = 32; 00428 else 00429 iconWidth = 48; 00430 00431 if( flags & ClassHint ) { 00432 // Try to load the icon from the classhint if the app didn't specify 00433 // its own: 00434 if( result.isNull() ) { 00435 00436 XClassHint hint; 00437 if( XGetClassHint( qt_xdisplay(), win, &hint ) ) { 00438 QString className = hint.res_class; 00439 00440 QPixmap pm = KGlobal::instance()->iconLoader()->loadIcon( className.lower(), KIcon::Small, iconWidth, 00441 KIcon::DefaultState, 0, true ); 00442 if( scale && !pm.isNull() ) 00443 result.convertFromImage( pm.convertToImage().smoothScale( width, height ) ); 00444 else 00445 result = pm; 00446 00447 XFree( hint.res_name ); 00448 XFree( hint.res_class ); 00449 } 00450 } 00451 } 00452 00453 if( flags & XApp ) { 00454 // If the icon is still a null pixmap, load the 'xapp' icon 00455 // as a last resort: 00456 if ( result.isNull() ) { 00457 QPixmap pm = KGlobal::instance()->iconLoader()->loadIcon( "xapp", KIcon::Small, iconWidth, 00458 KIcon::DefaultState, 0, true ); 00459 if( scale && !pm.isNull() ) 00460 result.convertFromImage( pm.convertToImage().smoothScale( width, height ) ); 00461 else 00462 result = pm; 00463 } 00464 } 00465 #endif 00466 return result; 00467 } 00468 00469 void KWin::setIcons( WId win, const QPixmap& icon, const QPixmap& miniIcon ) 00470 { 00471 #if defined Q_WS_X11 && ! defined K_WS_QTONLY 00472 if ( icon.isNull() ) 00473 return; 00474 NETWinInfo info( qt_xdisplay(), win, qt_xrootwin(), 0 ); 00475 QImage img = icon.convertToImage().convertDepth( 32 ); 00476 NETIcon ni; 00477 ni.size.width = img.size().width(); 00478 ni.size.height = img.size().height(); 00479 ni.data = (unsigned char *) img.bits(); 00480 info.setIcon( ni, true ); 00481 if ( miniIcon.isNull() ) 00482 return; 00483 img = miniIcon.convertToImage().convertDepth( 32 ); 00484 ni.size.width = img.size().width(); 00485 ni.size.height = img.size().height(); 00486 ni.data = (unsigned char *) img.bits(); 00487 info.setIcon( ni, false ); 00488 #endif 00489 } 00490 00491 void KWin::setType( WId win, NET::WindowType windowType ) 00492 { 00493 #if defined Q_WS_X11 && ! defined K_WS_QTONLY 00494 NETWinInfo info( qt_xdisplay(), win, qt_xrootwin(), 0 ); 00495 info.setWindowType( windowType ); 00496 #endif 00497 } 00498 00499 void KWin::setState( WId win, unsigned long state ) 00500 { 00501 #if defined Q_WS_X11 && ! defined K_WS_QTONLY 00502 NETWinInfo info( qt_xdisplay(), win, qt_xrootwin(), NET::WMState ); 00503 info.setState( state, state ); 00504 #endif 00505 } 00506 00507 void KWin::clearState( WId win, unsigned long state ) 00508 { 00509 #if defined Q_WS_X11 && ! defined K_WS_QTONLY 00510 NETWinInfo info( qt_xdisplay(), win, qt_xrootwin(), NET::WMState ); 00511 info.setState( 0, state ); 00512 #endif 00513 } 00514 00515 void KWin::setOnAllDesktops( WId win, bool b ) 00516 { 00517 #if defined Q_WS_X11 && ! defined K_WS_QTONLY 00518 NETWinInfo info( qt_xdisplay(), win, qt_xrootwin(), NET::WMDesktop ); 00519 if ( b ) 00520 info.setDesktop( NETWinInfo::OnAllDesktops ); 00521 else if ( info.desktop() == NETWinInfo::OnAllDesktops ) { 00522 NETRootInfo rinfo( qt_xdisplay(), NET::CurrentDesktop ); 00523 info.setDesktop( rinfo.currentDesktop() ); 00524 } 00525 #endif 00526 } 00527 00528 void KWin::setOnDesktop( WId win, int desktop ) 00529 { 00530 #if defined Q_WS_X11 && ! defined K_WS_QTONLY 00531 NETWinInfo info( qt_xdisplay(), win, qt_xrootwin(), NET::WMDesktop ); 00532 info.setDesktop( desktop ); 00533 #endif 00534 } 00535 00536 void KWin::setExtendedStrut( WId win, int left_width, int left_start, int left_end, 00537 int right_width, int right_start, int right_end, int top_width, int top_start, int top_end, 00538 int bottom_width, int bottom_start, int bottom_end ) 00539 { 00540 #if defined Q_WS_X11 && ! defined K_WS_QTONLY 00541 NETWinInfo info( qt_xdisplay(), win, qt_xrootwin(), 0 ); 00542 NETExtendedStrut strut; 00543 strut.left_width = left_width; 00544 strut.right_width = right_width; 00545 strut.top_width = top_width; 00546 strut.bottom_width = bottom_width; 00547 strut.left_start = left_start; 00548 strut.left_end = left_end; 00549 strut.right_start = right_start; 00550 strut.right_end = right_end; 00551 strut.top_start = top_start; 00552 strut.top_end = top_end; 00553 strut.bottom_start = bottom_start; 00554 strut.bottom_end = bottom_end; 00555 info.setExtendedStrut( strut ); 00556 #endif 00557 } 00558 00559 void KWin::setStrut( WId win, int left, int right, int top, int bottom ) 00560 { 00561 #if defined Q_WS_X11 && ! defined K_WS_QTONLY 00562 NETWinInfo info( qt_xdisplay(), win, qt_xrootwin(), 0 ); 00563 NETStrut strut; 00564 strut.left = left; 00565 strut.right = right; 00566 strut.top = top; 00567 strut.bottom = bottom; 00568 info.setStrut( strut ); 00569 #endif 00570 } 00571 00572 int KWin::currentDesktop() 00573 { 00574 #if defined Q_WS_X11 && ! defined K_WS_QTONLY 00575 if (!qt_xdisplay()) 00576 #endif 00577 return 1; 00578 #if defined Q_WS_X11 && ! defined K_WS_QTONLY 00579 NETRootInfo info( qt_xdisplay(), NET::CurrentDesktop ); 00580 return info.currentDesktop(); 00581 #endif 00582 } 00583 00584 int KWin::numberOfDesktops() 00585 { 00586 #if defined Q_WS_X11 && ! defined K_WS_QTONLY 00587 if (!qt_xdisplay()) 00588 #endif 00589 return 0; 00590 #if defined Q_WS_X11 && ! defined K_WS_QTONLY 00591 NETRootInfo info( qt_xdisplay(), NET::NumberOfDesktops ); 00592 return info.numberOfDesktops(); 00593 #endif 00594 } 00595 00596 void KWin::setCurrentDesktop( int desktop ) 00597 { 00598 #if defined Q_WS_X11 && ! defined K_WS_QTONLY 00599 NETRootInfo info( qt_xdisplay(), NET::CurrentDesktop ); 00600 info.setCurrentDesktop( desktop ); 00601 #endif 00602 } 00603 00604 00605 void KWin::iconifyWindow( WId win, bool animation) 00606 { 00607 #if defined Q_WS_X11 && ! defined K_WS_QTONLY 00608 if ( !animation ) 00609 { 00610 kwin_net_create_atoms(); 00611 sendClientMessageToRoot( win, kde_wm_change_state, IconicState, 1 ); 00612 } 00613 XIconifyWindow( qt_xdisplay(), win, qt_xscreen() ); 00614 #endif 00615 } 00616 00617 00618 void KWin::deIconifyWindow( WId win, bool animation ) 00619 { 00620 #if defined Q_WS_X11 && ! defined K_WS_QTONLY 00621 if ( !animation ) 00622 { 00623 kwin_net_create_atoms(); 00624 sendClientMessageToRoot( win, kde_wm_change_state, NormalState, 1 ); 00625 } 00626 XMapWindow( qt_xdisplay(), win ); 00627 #endif 00628 } 00629 00630 void KWin::raiseWindow( WId win ) 00631 { 00632 #if defined Q_WS_X11 && ! defined K_WS_QTONLY 00633 NETRootInfo info( qt_xdisplay(), NET::Supported ); 00634 if( info.isSupported( NET::WM2RestackWindow )) 00635 info.restackRequest( win, None, Above ); 00636 else 00637 XRaiseWindow( qt_xdisplay(), win ); 00638 #endif 00639 } 00640 00641 void KWin::lowerWindow( WId win ) 00642 { 00643 #if defined Q_WS_X11 && ! defined K_WS_QTONLY 00644 NETRootInfo info( qt_xdisplay(), NET::Supported ); 00645 if( info.isSupported( NET::WM2RestackWindow )) 00646 info.restackRequest( win, None, Below ); 00647 else 00648 XLowerWindow( qt_xdisplay(), win ); 00649 #endif 00650 } 00651 00652 void KWin::appStarted() 00653 { 00654 #if defined Q_WS_X11 && ! defined K_WS_QTONLY 00655 KStartupInfo::appStarted(); 00656 #endif 00657 } 00658 00659 class KWin::WindowInfoPrivate 00660 { 00661 public: 00662 WindowInfoPrivate() 00663 #if defined Q_WS_X11 && ! defined K_WS_QTONLY 00664 : info( NULL ) 00665 #endif 00666 {} 00667 #if defined Q_WS_X11 && ! defined K_WS_QTONLY 00668 ~WindowInfoPrivate() { delete info; } 00669 NETWinInfo* info; 00670 #endif 00671 WId win_; 00672 QString name_; 00673 QString iconic_name_; 00674 QRect geometry_; 00675 QRect frame_geometry_; 00676 int ref; 00677 bool valid; 00678 private: 00679 WindowInfoPrivate( const WindowInfoPrivate& ); 00680 void operator=( const WindowInfoPrivate& ); 00681 }; 00682 00683 // KWin::info() should be updated too if something has to be changed here 00684 KWin::WindowInfo::WindowInfo( WId win, unsigned long properties, unsigned long properties2 ) 00685 { 00686 #if defined Q_WS_X11 && ! defined K_WS_QTONLY 00687 KXErrorHandler handler; 00688 d = new WindowInfoPrivate; 00689 d->ref = 1; 00690 if( properties == 0 ) 00691 properties = NET::WMState | 00692 NET::WMStrut | 00693 NET::WMWindowType | 00694 NET::WMName | 00695 NET::WMVisibleName | 00696 NET::WMIconName | 00697 NET::WMVisibleIconName | 00698 NET::WMDesktop | 00699 NET::WMPid | 00700 NET::WMKDEFrameStrut | 00701 NET::XAWMState | 00702 NET::WMGeometry; 00703 if( properties & NET::WMVisibleIconName ) 00704 properties |= NET::WMIconName | NET::WMVisibleName; // force, in case it will be used as a fallback 00705 if( properties & NET::WMVisibleName ) 00706 properties |= NET::WMName; // force, in case it will be used as a fallback 00707 if( properties2 & NET::WM2ExtendedStrut ) 00708 properties |= NET::WMStrut; // will be used as fallback 00709 properties |= NET::XAWMState; // force to get error detection for valid() 00710 unsigned long props[ 2 ] = { properties, properties2 }; 00711 d->info = new NETWinInfo( qt_xdisplay(), win, qt_xrootwin(), props, 2 ); 00712 d->win_ = win; 00713 if( properties & NET::WMName ) { 00714 if( d->info->name() && d->info->name()[ 0 ] != '\0' ) 00715 d->name_ = QString::fromUtf8( d->info->name() ); 00716 else 00717 d->name_ = readNameProperty( win, XA_WM_NAME ); 00718 } 00719 if( properties & NET::WMIconName ) { 00720 if( d->info->iconName() && d->info->iconName()[ 0 ] != '\0' ) 00721 d->iconic_name_ = QString::fromUtf8( d->info->iconName()); 00722 else 00723 d->iconic_name_ = readNameProperty( win, XA_WM_ICON_NAME ); 00724 } 00725 if( properties & ( NET::WMGeometry | NET::WMKDEFrameStrut )) { 00726 NETRect frame, geom; 00727 d->info->kdeGeometry( frame, geom ); 00728 d->geometry_.setRect( geom.pos.x, geom.pos.y, geom.size.width, geom.size.height ); 00729 d->frame_geometry_.setRect( frame.pos.x, frame.pos.y, frame.size.width, frame.size.height ); 00730 } 00731 d->valid = !handler.error( false ); // no sync - NETWinInfo did roundtrips 00732 #endif 00733 } 00734 00735 // this one is only to make QValueList<> or similar happy 00736 KWin::WindowInfo::WindowInfo() 00737 : d( NULL ) 00738 { 00739 } 00740 00741 KWin::WindowInfo::~WindowInfo() 00742 { 00743 if( d != NULL ) { 00744 if( --d->ref == 0 ) { 00745 delete d; 00746 } 00747 } 00748 } 00749 00750 KWin::WindowInfo::WindowInfo( const WindowInfo& wininfo ) 00751 : d( wininfo.d ) 00752 { 00753 if( d != NULL ) 00754 ++d->ref; 00755 } 00756 00757 KWin::WindowInfo& KWin::WindowInfo::operator=( const WindowInfo& wininfo ) 00758 { 00759 if( d != wininfo.d ) { 00760 if( d != NULL ) 00761 if( --d->ref == 0 ) 00762 delete d; 00763 d = wininfo.d; 00764 if( d != NULL ) 00765 ++d->ref; 00766 } 00767 return *this; 00768 } 00769 00770 bool KWin::WindowInfo::valid( bool withdrawn_is_valid ) const 00771 { 00772 if( !d->valid ) 00773 return false; 00774 if( !withdrawn_is_valid && mappingState() == NET::Withdrawn ) 00775 return false; 00776 return true; 00777 } 00778 00779 WId KWin::WindowInfo::win() const 00780 { 00781 return d->win_; 00782 } 00783 00784 unsigned long KWin::WindowInfo::state() const 00785 { 00786 #if defined Q_WS_X11 && ! defined K_WS_QTONLY 00787 kdWarning(( d->info->passedProperties()[ NETWinInfo::PROTOCOLS ] & NET::WMState ) == 0, 176 ) 00788 << "Pass NET::WMState to KWin::windowInfo()" << endl; 00789 return d->info->state(); 00790 #else 00791 return 0; 00792 #endif 00793 } 00794 00795 NET::MappingState KWin::WindowInfo::mappingState() const 00796 { 00797 #if defined Q_WS_X11 && ! defined K_WS_QTONLY 00798 kdWarning(( d->info->passedProperties()[ NETWinInfo::PROTOCOLS ] & NET::XAWMState ) == 0, 176 ) 00799 << "Pass NET::XAWMState to KWin::windowInfo()" << endl; 00800 return d->info->mappingState(); 00801 #else 00802 return 0; 00803 #endif 00804 } 00805 00806 NETExtendedStrut KWin::WindowInfo::extendedStrut() const 00807 { 00808 #if defined Q_WS_X11 && ! defined K_WS_QTONLY 00809 kdWarning(( d->info->passedProperties()[ NETWinInfo::PROTOCOLS2 ] & NET::WM2ExtendedStrut ) == 0, 176 ) 00810 << "Pass NET::WM2ExtendedStrut to second argument of KWin::windowInfo()" << endl; 00811 NETExtendedStrut ext = d->info->extendedStrut(); 00812 NETStrut str = d->info->strut(); 00813 if( ext.left_width == 0 && ext.right_width == 0 && ext.top_width == 0 && ext.bottom_width == 0 00814 && ( str.left != 0 || str.right != 0 || str.top != 0 || str.bottom != 0 )) { 00815 // build extended from simple 00816 if( str.left != 0 ) { 00817 ext.left_width = str.left; 00818 ext.left_start = 0; 00819 ext.left_end = XDisplayHeight( qt_xdisplay(), DefaultScreen( qt_xdisplay())); 00820 } 00821 if( str.right != 0 ) { 00822 ext.right_width = str.right; 00823 ext.right_start = 0; 00824 ext.right_end = XDisplayHeight( qt_xdisplay(), DefaultScreen( qt_xdisplay())); 00825 } 00826 if( str.top != 0 ) { 00827 ext.top_width = str.top; 00828 ext.top_start = 0; 00829 ext.top_end = XDisplayWidth( qt_xdisplay(), DefaultScreen( qt_xdisplay())); 00830 } 00831 if( str.bottom != 0 ) { 00832 ext.bottom_width = str.bottom; 00833 ext.bottom_start = 0; 00834 ext.bottom_end = XDisplayWidth( qt_xdisplay(), DefaultScreen( qt_xdisplay())); 00835 } 00836 } 00837 return ext; 00838 #else 00839 NETExtendedStrut n; 00840 return n; 00841 #endif 00842 } 00843 00844 NETStrut KWin::WindowInfo::strut() const 00845 { 00846 #if defined Q_WS_X11 && ! defined K_WS_QTONLY 00847 kdWarning(( d->info->passedProperties()[ NETWinInfo::PROTOCOLS ] & NET::WMStrut ) == 0, 176 ) 00848 << "Pass NET::WMStrut to KWin::windowInfo()" << endl; 00849 return d->info->strut(); 00850 #else 00851 NETStrut n; 00852 return n; 00853 #endif 00854 } 00855 00856 NET::WindowType KWin::WindowInfo::windowType( int supported_types ) const 00857 { 00858 #if defined Q_WS_X11 && ! defined K_WS_QTONLY 00859 kdWarning(( d->info->passedProperties()[ NETWinInfo::PROTOCOLS ] & NET::WMWindowType ) == 0, 176 ) 00860 << "Pass NET::WMWindowType to KWin::windowInfo()" << endl; 00861 return d->info->windowType( supported_types ); 00862 #else 00863 return 0; 00864 #endif 00865 } 00866 00867 QString KWin::WindowInfo::visibleNameWithState() const 00868 { 00869 QString s = visibleName(); 00870 if ( isMinimized() ) { 00871 s.prepend('('); 00872 s.append(')'); 00873 } 00874 return s; 00875 } 00876 00877 QString KWin::Info::visibleNameWithState() const 00878 { 00879 QString s = visibleName; 00880 if ( isMinimized() ) { 00881 s.prepend('('); 00882 s.append(')'); 00883 } 00884 return s; 00885 } 00886 00887 QString KWin::WindowInfo::visibleName() const 00888 { 00889 #if defined Q_WS_X11 && ! defined K_WS_QTONLY 00890 kdWarning(( d->info->passedProperties()[ NETWinInfo::PROTOCOLS ] & NET::WMVisibleName ) == 0, 176 ) 00891 << "Pass NET::WMVisibleName to KWin::windowInfo()" << endl; 00892 return d->info->visibleName() && d->info->visibleName()[ 0 ] != '\0' 00893 ? QString::fromUtf8(d->info->visibleName()) : name(); 00894 #else 00895 return QString("name"); 00896 #endif 00897 } 00898 00899 QString KWin::WindowInfo::name() const 00900 { 00901 #if defined Q_WS_X11 && ! defined K_WS_QTONLY 00902 kdWarning(( d->info->passedProperties()[ NETWinInfo::PROTOCOLS ] & NET::WMName ) == 0, 176 ) 00903 << "Pass NET::WMName to KWin::windowInfo()" << endl; 00904 return d->name_; 00905 #else 00906 return QString(); 00907 #endif 00908 } 00909 00910 QString KWin::WindowInfo::visibleIconNameWithState() const 00911 { 00912 QString s = visibleIconName(); 00913 if ( isMinimized() ) { 00914 s.prepend('('); 00915 s.append(')'); 00916 } 00917 return s; 00918 } 00919 00920 QString KWin::WindowInfo::visibleIconName() const 00921 { 00922 #if defined Q_WS_X11 && ! defined K_WS_QTONLY 00923 kdWarning(( d->info->passedProperties()[ NETWinInfo::PROTOCOLS ] & NET::WMVisibleIconName ) == 0, 176 ) 00924 << "Pass NET::WMVisibleIconName to KWin::windowInfo()" << endl; 00925 if( d->info->visibleIconName() && d->info->visibleIconName()[ 0 ] != '\0' ) 00926 return QString::fromUtf8( d->info->visibleIconName()); 00927 if( d->info->iconName() && d->info->iconName()[ 0 ] != '\0' ) 00928 return QString::fromUtf8( d->info->iconName()); 00929 if( !d->iconic_name_.isEmpty()) 00930 return d->iconic_name_; 00931 #endif 00932 return visibleName(); 00933 } 00934 00935 QString KWin::WindowInfo::iconName() const 00936 { 00937 #if defined Q_WS_X11 && ! defined K_WS_QTONLY 00938 kdWarning(( d->info->passedProperties()[ NETWinInfo::PROTOCOLS ] & NET::WMIconName ) == 0, 176 ) 00939 << "Pass NET::WMIconName to KWin::windowInfo()" << endl; 00940 if( d->info->iconName() && d->info->iconName()[ 0 ] != '\0' ) 00941 return QString::fromUtf8( d->info->iconName()); 00942 if( !d->iconic_name_.isEmpty()) 00943 return d->iconic_name_; 00944 #endif 00945 return name(); 00946 } 00947 00948 bool KWin::WindowInfo::isOnCurrentDesktop() const 00949 { 00950 #if defined Q_WS_X11 && ! defined K_WS_QTONLY 00951 return isOnDesktop( KWin::currentDesktop()); 00952 #else 00953 return false; 00954 #endif 00955 } 00956 00957 bool KWin::WindowInfo::isOnDesktop( int desktop ) const 00958 { 00959 #if defined Q_WS_X11 && ! defined K_WS_QTONLY 00960 kdWarning(( d->info->passedProperties()[ NETWinInfo::PROTOCOLS ] & NET::WMDesktop ) == 0, 176 ) 00961 << "Pass NET::WMDesktop to KWin::windowInfo()" << endl; 00962 return d->info->desktop() == desktop || d->info->desktop() == NET::OnAllDesktops; 00963 #else 00964 return false; 00965 #endif 00966 } 00967 00968 bool KWin::WindowInfo::onAllDesktops() const 00969 { 00970 #if defined Q_WS_X11 && ! defined K_WS_QTONLY 00971 kdWarning(( d->info->passedProperties()[ NETWinInfo::PROTOCOLS ] & NET::WMDesktop ) == 0, 176 ) 00972 << "Pass NET::WMDesktop to KWin::windowInfo()" << endl; 00973 return d->info->desktop() == NET::OnAllDesktops; 00974 #else 00975 return false; 00976 #endif 00977 } 00978 00979 int KWin::WindowInfo::desktop() const 00980 { 00981 #if defined Q_WS_X11 && ! defined K_WS_QTONLY 00982 kdWarning(( d->info->passedProperties()[ NETWinInfo::PROTOCOLS ] & NET::WMDesktop ) == 0, 176 ) 00983 << "Pass NET::WMDesktop to KWin::windowInfo()" << endl; 00984 return d->info->desktop(); 00985 #else 00986 return 1; 00987 #endif 00988 } 00989 00990 QRect KWin::WindowInfo::geometry() const 00991 { 00992 #if defined Q_WS_X11 && ! defined K_WS_QTONLY 00993 kdWarning(( d->info->passedProperties()[ NETWinInfo::PROTOCOLS ] & NET::WMGeometry ) == 0, 176 ) 00994 << "Pass NET::WMGeometry to KWin::windowInfo()" << endl; 00995 return d->geometry_; 00996 #else 00997 return QRect( 100, 100, 200, 200 );; 00998 #endif 00999 } 01000 01001 QRect KWin::WindowInfo::frameGeometry() const 01002 { 01003 kdWarning(( d->info->passedProperties()[ NETWinInfo::PROTOCOLS ] & NET::WMKDEFrameStrut ) == 0, 176 ) 01004 << "Pass NET::WMKDEFrameStrut to KWin::windowInfo()" << endl; 01005 return d->frame_geometry_; 01006 } 01007 01008 WId KWin::WindowInfo::transientFor() const 01009 { 01010 #if defined Q_WS_X11 && ! defined K_WS_QTONLY 01011 kdWarning(( d->info->passedProperties()[ NETWinInfo::PROTOCOLS2 ] & NET::WM2TransientFor ) == 0, 176 ) 01012 << "Pass NET::WM2TransientFor to KWin::windowInfo()" << endl; 01013 return d->info->transientFor(); 01014 #else 01015 return 0; 01016 #endif 01017 } 01018 01019 WId KWin::WindowInfo::groupLeader() const 01020 { 01021 #if defined Q_WS_X11 && ! defined K_WS_QTONLY 01022 kdWarning(( d->info->passedProperties()[ NETWinInfo::PROTOCOLS2 ] & NET::WM2GroupLeader ) == 0, 176 ) 01023 << "Pass NET::WM2GroupLeader to KWin::windowInfo()" << endl; 01024 return d->info->groupLeader(); 01025 #else 01026 return 0; 01027 #endif 01028 } 01029 01030 QCString KWin::WindowInfo::windowClassClass() const 01031 { 01032 #if defined Q_WS_X11 && ! defined K_WS_QTONLY 01033 kdWarning(( d->info->passedProperties()[ NETWinInfo::PROTOCOLS2 ] & NET::WM2WindowClass ) == 0, 176 ) 01034 << "Pass NET::WM2WindowClass to KWin::windowInfo()" << endl; 01035 return d->info->windowClassClass(); 01036 #else 01037 return 0; 01038 #endif 01039 } 01040 01041 QCString KWin::WindowInfo::windowClassName() const 01042 { 01043 #if defined Q_WS_X11 && ! defined K_WS_QTONLY 01044 kdWarning(( d->info->passedProperties()[ NETWinInfo::PROTOCOLS2 ] & NET::WM2WindowClass ) == 0, 176 ) 01045 << "Pass NET::WM2WindowClass to KWin::windowInfo()" << endl; 01046 return d->info->windowClassName(); 01047 #else 01048 return 0; 01049 #endif 01050 } 01051 01052 QCString KWin::WindowInfo::windowRole() const 01053 { 01054 #if defined Q_WS_X11 && ! defined K_WS_QTONLY 01055 kdWarning(( d->info->passedProperties()[ NETWinInfo::PROTOCOLS2 ] & NET::WM2WindowRole ) == 0, 176 ) 01056 << "Pass NET::WM2WindowRole to KWin::windowInfo()" << endl; 01057 return d->info->windowRole(); 01058 #else 01059 return 0; 01060 #endif 01061 } 01062 01063 QCString KWin::WindowInfo::clientMachine() const 01064 { 01065 #if defined Q_WS_X11 && ! defined K_WS_QTONLY 01066 kdWarning(( d->info->passedProperties()[ NETWinInfo::PROTOCOLS2 ] & NET::WM2ClientMachine ) == 0, 176 ) 01067 << "Pass NET::WM2ClientMachine to KWin::windowInfo()" << endl; 01068 return d->info->clientMachine(); 01069 #else 01070 return 0; 01071 #endif 01072 } 01073 01074 bool KWin::WindowInfo::actionSupported( NET::Action action ) const 01075 { 01076 #if defined Q_WS_X11 && ! defined K_WS_QTONLY 01077 kdWarning(( d->info->passedProperties()[ NETWinInfo::PROTOCOLS2 ] & NET::WM2AllowedActions ) == 0, 176 ) 01078 << "Pass NET::WM2AllowedActions to KWin::windowInfo()" << endl; 01079 if( allowedActionsSupported()) 01080 return d->info->allowedActions() & action; 01081 else 01082 #endif 01083 return true; // no idea if it's supported or not -> pretend it is 01084 } 01085 01086 // see NETWM spec section 7.6 01087 bool KWin::WindowInfo::isMinimized() const 01088 { 01089 #if defined Q_WS_X11 && ! defined K_WS_QTONLY 01090 if( mappingState() != NET::Iconic ) 01091 return false; 01092 // NETWM 1.2 compliant WM - uses NET::Hidden for minimized windows 01093 if(( state() & NET::Hidden ) != 0 01094 && ( state() & NET::Shaded ) == 0 ) // shaded may have NET::Hidden too 01095 return true; 01096 // older WMs use WithdrawnState for other virtual desktops 01097 // and IconicState only for minimized 01098 return icccmCompliantMappingState() ? false : true; 01099 #else 01100 return false; 01101 #endif 01102 } 01103 01104 bool KWin::Info::isMinimized() const 01105 { 01106 #if defined Q_WS_X11 && ! defined K_WS_QTONLY 01107 if( mappingState != NET::Iconic ) 01108 return false; 01109 // NETWM 1.2 compliant WM - uses NET::Hidden for minimized windows 01110 if(( state & NET::Hidden ) != 0 01111 && ( state & NET::Shaded ) == 0 ) // shaded may have NET::Hidden too 01112 return true; 01113 // older WMs use WithdrawnState for other virtual desktops 01114 // and IconicState only for minimized 01115 return icccmCompliantMappingState() ? false : true; 01116 #else 01117 return false; 01118 #endif 01119 } 01120 01121 bool KWin::Info::isIconified() const 01122 { 01123 return isMinimized(); 01124 } 01125 01126 bool KWin::icccmCompliantMappingState() 01127 { 01128 #if defined Q_WS_X11 && ! defined K_WS_QTONLY 01129 static enum { noidea, yes, no } wm_is_1_2_compliant = noidea; 01130 if( wm_is_1_2_compliant == noidea ) { 01131 NETRootInfo info( qt_xdisplay(), NET::Supported ); 01132 wm_is_1_2_compliant = info.isSupported( NET::Hidden ) ? yes : no; 01133 } 01134 return wm_is_1_2_compliant == yes; 01135 #else 01136 return false; 01137 #endif 01138 } 01139 01140 bool KWin::allowedActionsSupported() 01141 { 01142 #if defined Q_WS_X11 && ! defined K_WS_QTONLY 01143 static enum { noidea, yes, no } wm_supports_allowed_actions = noidea; 01144 if( wm_supports_allowed_actions == noidea ) { 01145 NETRootInfo info( qt_xdisplay(), NET::Supported ); 01146 wm_supports_allowed_actions = info.isSupported( NET::WM2AllowedActions ) ? yes : no; 01147 } 01148 return wm_supports_allowed_actions == yes; 01149 #else 01150 return false; 01151 #endif 01152 } 01153 01154 QString KWin::readNameProperty( WId win, unsigned long atom ) 01155 { 01156 #if defined Q_WS_X11 && ! defined K_WS_QTONLY 01157 XTextProperty tp; 01158 char **text = NULL; 01159 int count; 01160 #endif 01161 QString result; 01162 #if defined Q_WS_X11 && ! defined K_WS_QTONLY 01163 if ( XGetTextProperty( qt_xdisplay(), win, &tp, atom ) != 0 && tp.value != NULL ) { 01164 if ( XmbTextPropertyToTextList( qt_xdisplay(), &tp, &text, &count) == Success && 01165 text != NULL && count > 0 ) { 01166 result = QString::fromLocal8Bit( text[0] ); 01167 } else if ( tp.encoding == XA_STRING ) 01168 result = QString::fromLocal8Bit( (const char*) tp.value ); 01169 if( text != NULL ) 01170 XFreeStringList( text ); 01171 XFree( tp.value ); 01172 } 01173 #endif 01174 return result; 01175 } 01176 01177 //#endif
KDE Logo
This file is part of the documentation for kdecore Library Version 3.3.0.
Documentation copyright © 1996-2004 the KDE developers.
Generated on Wed Sep 29 09:43:12 2004 by doxygen 1.3.8 written by Dimitri van Heesch, © 1997-2003